diff --git a/package-lock.json b/package-lock.json index fb5902cd..2207bed9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2485,10 +2485,9 @@ "dev": true }, "aes-js": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-0.2.4.tgz", - "integrity": "sha1-lLiBq3FyhtAV+iGeCPtmcJ3aWj0=", - "dev": true + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.1.1.tgz", + "integrity": "sha512-cEA0gBelItZZV7iBiL8ApCiNgc+gBWJJ4uoORhbu6vOqAJ0UL9wIlxr4RI7ij9SSVzy6AnPwiu37kVYiHCl3nw==" }, "after": { "version": "0.8.2", @@ -4695,7 +4694,6 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.4.tgz", "integrity": "sha512-UYOadoSIkEI/VrRGSG6qp93rp2WdokiAiNYDfGW5qURAY8GiAQkvMbwNNSDYiVJopqv4gCna7xqf4rrNGp+5AA==", - "dev": true, "requires": { "safe-buffer": "^5.0.1" } @@ -4769,8 +4767,7 @@ "bindings": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.3.0.tgz", - "integrity": "sha512-DpLh5EzMR2kzvX1KIlVC0VkC3iZtHKTgdtZ0a3pglBZdaQFjt5S9g9xd1lE+YvXyfd6mtCeRnrUfOLYiTMlNSw==", - "dev": true + "integrity": "sha512-DpLh5EzMR2kzvX1KIlVC0VkC3iZtHKTgdtZ0a3pglBZdaQFjt5S9g9xd1lE+YvXyfd6mtCeRnrUfOLYiTMlNSw==" }, "bip39": { "version": "2.5.0", @@ -4789,7 +4786,6 @@ "version": "1.1.5", "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz", "integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=", - "dev": true, "requires": { "safe-buffer": "^5.0.1" } @@ -5139,11 +5135,20 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", - "dev": true, "requires": { "base-x": "^3.0.2" } }, + "bs58check": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", + "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", + "requires": { + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" + } + }, "bser": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/bser/-/bser-2.0.0.tgz", @@ -5853,7 +5858,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/coinstring/-/coinstring-2.3.0.tgz", "integrity": "sha1-zbYzY6lhUCQEolr7gsLibV/2J6Q=", - "dev": true, "requires": { "bs58": "^2.0.1", "create-hash": "^1.1.1" @@ -5862,8 +5866,7 @@ "bs58": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/bs58/-/bs58-2.0.1.tgz", - "integrity": "sha1-VZCNWPGYKrogCPob7Y+RmYopv40=", - "dev": true + "integrity": "sha1-VZCNWPGYKrogCPob7Y+RmYopv40=" } } }, @@ -7157,7 +7160,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/drbg.js/-/drbg.js-1.0.1.tgz", "integrity": "sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=", - "dev": true, "requires": { "browserify-aes": "^1.0.6", "create-hash": "^1.1.2", @@ -8400,7 +8402,6 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz", "integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==", - "dev": true, "requires": { "bn.js": "^4.11.0", "create-hash": "^1.1.2", @@ -8439,63 +8440,24 @@ } }, "ethereumjs-wallet": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/ethereumjs-wallet/-/ethereumjs-wallet-0.6.0.tgz", - "integrity": "sha1-gnY7Fpfuenlr5xVdqd+0my+Yz9s=", - "dev": true, + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/ethereumjs-wallet/-/ethereumjs-wallet-0.6.2.tgz", + "integrity": "sha512-DHEKPV9lYORM7dL8602dkb+AgdfzCYz2lxpdYQoD3OwG355LLDuivW9rGuLpDMCry/ORyBYV6n+QCo/71SwACg==", "requires": { - "aes-js": "^0.2.3", - "bs58check": "^1.0.8", - "ethereumjs-util": "^4.4.0", - "hdkey": "^0.7.0", + "aes-js": "^3.1.1", + "bs58check": "^2.1.2", + "ethereumjs-util": "^5.2.0", + "hdkey": "^1.0.0", + "safe-buffer": "^5.1.2", "scrypt.js": "^0.2.0", - "utf8": "^2.1.1", - "uuid": "^2.0.1" + "utf8": "^3.0.0", + "uuid": "^3.3.2" }, "dependencies": { - "base-x": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-1.1.0.tgz", - "integrity": "sha1-QtPXF0dPnqAiB/bRqh9CaRPut6w=", - "dev": true - }, - "bs58": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-3.1.0.tgz", - "integrity": "sha1-1MJjiL9IBMrHFBQbGUWqR+XrJI4=", - "dev": true, - "requires": { - "base-x": "^1.1.0" - } - }, - "bs58check": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-1.3.4.tgz", - "integrity": "sha1-xSVABzdJEXcU+gQsMEfrj5FRy/g=", - "dev": true, - "requires": { - "bs58": "^3.1.0", - "create-hash": "^1.1.0" - } - }, - "ethereumjs-util": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-4.5.0.tgz", - "integrity": "sha1-PpQosxfuvaPXJg2FT93alUsfG8Y=", - "dev": true, - "requires": { - "bn.js": "^4.8.0", - "create-hash": "^1.1.2", - "keccakjs": "^0.2.0", - "rlp": "^2.0.0", - "secp256k1": "^3.0.1" - } - }, - "uuid": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz", - "integrity": "sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho=", - "dev": true + "utf8": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", + "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==" } } }, @@ -8513,7 +8475,6 @@ "version": "0.1.6", "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz", "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==", - "dev": true, "requires": { "is-hex-prefixed": "1.0.0", "strip-hex-prefix": "1.0.0" @@ -10513,12 +10474,12 @@ } }, "hdkey": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/hdkey/-/hdkey-0.7.1.tgz", - "integrity": "sha1-yu5L6BqneSHpCbjSKN0PKayu5jI=", - "dev": true, + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/hdkey/-/hdkey-1.1.0.tgz", + "integrity": "sha512-E7aU8pNlWUJbXGjTz/+lKf1LkMcA3hUrC5ZleeizrmLSd++kvf8mSOe3q8CmBDA9j4hdfXO5iY6hGiTUCOV2jQ==", "requires": { "coinstring": "^2.0.0", + "safe-buffer": "^5.1.1", "secp256k1": "^3.0.1" } }, @@ -13536,7 +13497,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/keccak/-/keccak-1.4.0.tgz", "integrity": "sha512-eZVaCpblK5formjPjeTBik7TAg+pqnDrMHIffSvi9Lh7PQgM1+hSzakUeZFCk9DVVG0dacZJuaz2ntwlzZUIBw==", - "dev": true, "requires": { "bindings": "^1.2.1", "inherits": "^2.0.3", @@ -20544,7 +20504,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.1.0.tgz", "integrity": "sha512-93U7IKH5j7nmXFVg19MeNBGzQW5uXW1pmCuKY8veeKIhYTE32C2d0mOegfiIAfXcHOKJjjPlJisn8iHDF5AezA==", - "dev": true, "requires": { "safe-buffer": "^5.1.1" } @@ -20877,7 +20836,6 @@ "version": "6.0.3", "resolved": "https://registry.npmjs.org/scrypt/-/scrypt-6.0.3.tgz", "integrity": "sha1-BOAUpWgrU/pQwtXM4WfXGcBthw0=", - "dev": true, "requires": { "nan": "^2.0.8" } @@ -20886,7 +20844,6 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/scrypt.js/-/scrypt.js-0.2.0.tgz", "integrity": "sha1-r40UZbcemZARC+38WTuUeeA6ito=", - "dev": true, "requires": { "scrypt": "^6.0.2", "scryptsy": "^1.2.1" @@ -20896,7 +20853,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/scryptsy/-/scryptsy-1.2.1.tgz", "integrity": "sha1-oyJfpLJST4AnAHYeKFW987LZIWM=", - "dev": true, "requires": { "pbkdf2": "^3.0.3" } @@ -20926,7 +20882,6 @@ "version": "3.5.0", "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.5.0.tgz", "integrity": "sha512-e5QIJl8W7Y4tT6LHffVcZAxJjvpgE5Owawv6/XCYPQljE9aP2NFFddQ8OYMKhdLshNu88FfL3qCN3/xYkXGRsA==", - "dev": true, "requires": { "bindings": "^1.2.1", "bip66": "^1.1.3", @@ -23545,17 +23500,92 @@ "web3-provider-engine": "^14.0.5" }, "dependencies": { + "aes-js": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-0.2.4.tgz", + "integrity": "sha1-lLiBq3FyhtAV+iGeCPtmcJ3aWj0=", + "dev": true + }, + "base-x": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-1.1.0.tgz", + "integrity": "sha1-QtPXF0dPnqAiB/bRqh9CaRPut6w=", + "dev": true + }, "bignumber.js": { "version": "git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2", "from": "bignumber.js@git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2", "dev": true }, + "bs58": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-3.1.0.tgz", + "integrity": "sha1-1MJjiL9IBMrHFBQbGUWqR+XrJI4=", + "dev": true, + "requires": { + "base-x": "^1.1.0" + } + }, + "bs58check": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-1.3.4.tgz", + "integrity": "sha1-xSVABzdJEXcU+gQsMEfrj5FRy/g=", + "dev": true, + "requires": { + "bs58": "^3.1.0", + "create-hash": "^1.1.0" + } + }, "crypto-js": { "version": "3.1.8", "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.1.8.tgz", "integrity": "sha1-cV8HC/YBTyrpkqmLOSkli3E/CNU=", "dev": true }, + "ethereumjs-util": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-4.5.0.tgz", + "integrity": "sha1-PpQosxfuvaPXJg2FT93alUsfG8Y=", + "dev": true, + "requires": { + "bn.js": "^4.8.0", + "create-hash": "^1.1.2", + "keccakjs": "^0.2.0", + "rlp": "^2.0.0", + "secp256k1": "^3.0.1" + } + }, + "ethereumjs-wallet": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/ethereumjs-wallet/-/ethereumjs-wallet-0.6.0.tgz", + "integrity": "sha1-gnY7Fpfuenlr5xVdqd+0my+Yz9s=", + "dev": true, + "requires": { + "aes-js": "^0.2.3", + "bs58check": "^1.0.8", + "ethereumjs-util": "^4.4.0", + "hdkey": "^0.7.0", + "scrypt.js": "^0.2.0", + "utf8": "^2.1.1", + "uuid": "^2.0.1" + } + }, + "hdkey": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/hdkey/-/hdkey-0.7.1.tgz", + "integrity": "sha1-yu5L6BqneSHpCbjSKN0PKayu5jI=", + "dev": true, + "requires": { + "coinstring": "^2.0.0", + "secp256k1": "^3.0.1" + } + }, + "uuid": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz", + "integrity": "sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho=", + "dev": true + }, "web3": { "version": "0.18.4", "resolved": "https://registry.npmjs.org/web3/-/web3-0.18.4.tgz", @@ -24223,8 +24253,7 @@ "uuid": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", - "dev": true + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" }, "validate-npm-package-license": { "version": "3.0.3", diff --git a/package.json b/package.json index 0f2a6e34..1b32b1d4 100644 --- a/package.json +++ b/package.json @@ -83,6 +83,8 @@ "bignumber.js": "5.0.0", "connected-react-router": "4.4.1", "cross-env": "^5.1.6", + "ethereumjs-util": "^5.2.0", + "ethereumjs-wallet": "^0.6.2", "ethjs-abi": "0.2.1", "extract-text-webpack-plugin": "^3.0.2", "history": "4.7.2", diff --git a/src/api/contracts.ts b/src/api/contracts.ts index 178f1938..62ff4b90 100644 --- a/src/api/contracts.ts +++ b/src/api/contracts.ts @@ -140,8 +140,10 @@ const getPromisedIntances = () => Promise.all(Contracts.map(contr => contr.deplo let contractsAPI: ContractsMap -export const promisedContractsMap = async (provider?: Provider) => { - if (contractsAPI) return contractsAPI +export const promisedContractsMap = async (provider?: Provider, overwrite?: boolean) => { + // overwrite is used to tell the API whether or not + // to overwrite the current provider (useful when changing wallets) + if (contractsAPI && !overwrite) return contractsAPI contractsAPI = await init(provider) return contractsAPI diff --git a/src/api/index.ts b/src/api/index.ts index 330c4c8b..75c8698d 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -11,10 +11,10 @@ import { AuctionStatus, ETH_ADDRESS, FIXED_DECIMALS } from 'globals' import { lastArrVal } from 'utils' let API: dutchXAPI -export const dxAPI = /* (window as any).AP = */ async (provider?: Provider) => { - if (API) return API +export const dxAPI = /* (window as any).AP = */ async (provider?: Provider, overwrite?: boolean) => { + if (API && !overwrite) return API - API = await initAPI(provider) + API = await initAPI(provider, overwrite) return API } @@ -1120,10 +1120,12 @@ export const getAvailableAuctionsFromAllTokens = async (tokensJSON: DefaultToken return auctionPairs } -async function initAPI(provider: Provider): Promise { +async function initAPI(provider: Provider, overwrite?: boolean): Promise { try { const [web3, Tokens, DutchX] = await Promise.all([ - promisedWeb3(provider), + // overwrite is used to tell the API whether or not + // to overwrite the current provider (useful when changing wallets) + promisedWeb3(provider, overwrite), promisedTokens(), promisedDutchX(), ]) diff --git a/src/api/web3Provider.ts b/src/api/web3Provider.ts index f5df024f..4f5c4373 100644 --- a/src/api/web3Provider.ts +++ b/src/api/web3Provider.ts @@ -11,8 +11,10 @@ const setupWeb3 = async (provider: Provider) => { let web3API: ProviderInterface -export const promisedWeb3 = async (provider?: Provider) => { - if (web3API) return web3API +export const promisedWeb3 = async (provider?: Provider, overwrite?: boolean) => { + // overwrite is used to tell the API whether or not + // to overwrite the current provider (useful when changing wallets) + if (web3API && !overwrite) return web3API web3API = await init(provider) return web3API diff --git a/src/components/MenuWallet/index.tsx b/src/components/MenuWallet/index.tsx index 86a15e5e..54e51295 100644 --- a/src/components/MenuWallet/index.tsx +++ b/src/components/MenuWallet/index.tsx @@ -42,17 +42,17 @@ export class MenuWallet extends React.Component { } render () { - const { - account, - addressToSymbolDecimal, - balance, - dxBalances, - dxBalancesAvailable, - hasTokenBalances, - network, - providerName, - tokens, - withdrawFromDutchX + const { + account, + addressToSymbolDecimal, + balance, + dxBalances, + dxBalancesAvailable, + hasTokenBalances, + network, + providerName, + tokens, + withdrawFromDutchX, } = this.props return (
= ({

}
+export class PrivateKeyApproval extends React.Component { + state = { + gasPrice: toDecimal(this.props.modalProps.txParams.gasPrice) as number, + gasLimit: toDecimal(this.props.modalProps.txParams.gas) as number, + } + + handleGasPriceChange = (e: any) => { + return this.setState({ + gasPrice: e.target.value, + }) + } + + handleGasChange = (e: any) => this.setState({ gasLimit: e.target.value }) + + render() { + const { modalProps: { header, body, buttons, onClick, txParams } } = this.props, { gasPrice, gasLimit } = this.state + return ( +
+

{header || 'Please choose Token Approval amount'}

+

+ { body || 'Please see below.' } +

+ {txParams && + <> +
+
    +
  • From: {txParams.from}
  • +
  • To: {txParams.to}
  • +
  • Value: {toDecimal(txParams.value)}
  • +
  • Data: {txParams.data}
  • + +
  • Gas Price: + +
  • +
  • Gas Limit: + +
  • +
+
+

Processing the transaction may take a while.

+ + } +
+
+ + {buttons && buttons.button1.buttonDesc1 &&

+ {buttons && buttons.button1.buttonDesc1 || `You\'ll allow ${COMPANY_NAME} to take just the amount of the current operation. Note that you\'ll have to sign a transfer confirmation and an order confirmation for future trades.`} +

} +
+ +
+ + {buttons && buttons.button2.buttonDesc2 &&

+ {buttons && buttons.button2.buttonDesc2 || `You\'ll allow ${COMPANY_NAME} to also take your bidding token for future trades. ${COMPANY_NAME} won\'t take any tokens until also confirm your order. You will use the same amount of funds but save transaction cost on future trades.`} +

} +
+
+
+ ) + } +} + const blockModalStyle: CSSProperties = { fontSize: 16, fontWeight: 100 } const disabledReasons = { diff --git a/src/containers/WalletIntegration/index.tsx b/src/containers/WalletIntegration/index.tsx index ae74c7fc..9ba783af 100644 --- a/src/containers/WalletIntegration/index.tsx +++ b/src/containers/WalletIntegration/index.tsx @@ -31,6 +31,8 @@ interface WalletIntegrationState { noProvidersDetected: boolean; setupComplete: boolean; web3: any; + + privateKey: string; } class WalletIntegration extends React.Component { @@ -40,6 +42,8 @@ class WalletIntegration extends React.Component { // interface with contracts & connect entire DX API - await connectContracts(web3.currentProvider) - return connectDXAPI(web3.currentProvider) + await connectContracts(web3.currentProvider, true) + return connectDXAPI(web3.currentProvider, true) } - setActiveAndInitProvider = async (providerInfo: string) => { + setActiveAndInitProvider = async (providerInfo: string, privateKey?: string) => { const { setActiveProvider } = this.props - const web3 = await Providers[providerInfo].initialize() + const web3 = await Providers[providerInfo].initialize(privateKey) setActiveProvider(providerInfo) this.setState({ web3 }) } - initAppWithProvider = async (providerInfo: string) => { + initAppWithProvider = async (providerInfo: string, privateKey?: string) => { try { this.setState({ initialising: true, error: undefined }) // initialize providers and return specific Web3 instances - await this.setActiveAndInitProvider(providerInfo) + await this.setActiveAndInitProvider(providerInfo, privateKey) // interface with contracts & connect entire DX API await this.initiateAPI(this.state.web3) @@ -86,6 +90,14 @@ class WalletIntegration extends React.Component this.setState({ privateKey: value }) + handlePrivateKeySubmit = async (e: any, provider: string) => { + e.preventDefault() + + await this.initAppWithProvider(provider, this.state.privateKey) + return this.setState({ privateKey: undefined }) + } + walletSelector = () => { return (
@@ -100,6 +112,22 @@ class WalletIntegration extends React.Component {Object.keys(Providers).map((provider: 'INJECTED_WALLET' | 'LEDGER', i: number) => { const providerInfo = Providers[provider].providerName || provider + // FOr PrivateKey wallet + if (Providers[provider].keyName === 'PRIVATE_KEY_WALLET') { + return ( +
+

{providerInfo}

+
+
this.handlePrivateKeySubmit(e, provider)} + > + + +
+
+ ) + } + // FOr others return (
diff --git a/src/integrations/provider/index.ts b/src/integrations/provider/index.ts index 8651ae9e..9941b28a 100644 --- a/src/integrations/provider/index.ts +++ b/src/integrations/provider/index.ts @@ -2,19 +2,22 @@ import Web3 from 'web3' // import Transport from '@ledgerhq/hw-transport' // import TransportU2F from '@ledgerhq/hw-transport-u2f' // import createLedgerSubprovider from '@ledgerhq/web3-subprovider' -// import ProviderEngine from 'web3-provider-engine' -// import FetchSubprovider from 'web3-provider-engine/subproviders/fetch' -// import RpcSubprovider from 'web3-provider-engine/subproviders/rpc.js' +// @ts-ignore +import ProviderEngine from 'web3-provider-engine' +// @ts-ignore +import FetchSubprovider from 'web3-provider-engine/subproviders/fetch' +// @ts-ignore +import RpcSubprovider from 'web3-provider-engine/subproviders/rpc.js' // import Eth from '@ledgerhq/hw-app-eth' import { getTime } from 'api' -import { promisify } from 'utils' +import { promisify, customValidateTransaction } from 'utils' import { Balance } from 'types' import { WalletProvider } from 'integrations/types' -import { ETHEREUM_NETWORKS, networkById/* , network2RPCURL */ } from 'globals' +import { ETHEREUM_NETWORKS, networkById, network2RPCURL } from 'globals' export const getAccount = async (provider: WalletProvider): Promise => { const [account] = await promisify(provider.web3.eth.getAccounts, provider.web3.eth)() @@ -52,7 +55,7 @@ export const grabProviderState = async (provider: WalletProvider) => { // ==================================================================================== // Ledger Wallet info only -// const rpcUrl = network2RPCURL.RINKEBY +const rpcUrl = network2RPCURL.UNKNOWN // const networkId = 4 // parseInt(process.env.REACT_APP_NETWORK_ID || "1337", 10); // ==================================================================================== @@ -87,6 +90,43 @@ const Providers = { return this.web3 }, }, + // Private Key Wallet + PRIVATE_KEY_WALLET: { + priority: 1, + providerName: 'Private Key Wallet', + providerType: 'PRIVATE_KEY_WALLET', + keyName: 'PRIVATE_KEY_WALLET', + + checkAvailability() { + return this.walletAvailable = true + }, + + initialize(privateKey: string) { + if (!this.checkAvailability()) return + + const walletSetup = require('ethereumjs-wallet') + const ethUtils = require('ethereumjs-util') + const WalletSubprovider = require('ethereumjs-wallet/provider-engine') + const privKey = ethUtils.toBuffer(privateKey) + const wallet = walletSetup.fromPrivateKey(privKey) + const engine = new ProviderEngine() + + const customWalletSubprovider = new WalletSubprovider(wallet) + + customWalletSubprovider.validateTransaction = customValidateTransaction + + engine.addProvider(customWalletSubprovider) + engine.addProvider(new RpcSubprovider({ rpcUrl })) + engine.addProvider(new FetchSubprovider({ rpcUrl })) + engine.start() + + this.web3 = new Web3(engine) + + this.state = {} + + return this.web3 + }, + }, // Hardware Provider - LEDGER /* LEDGER: { priority: 80, diff --git a/src/integrations/walletIntegration.ts b/src/integrations/walletIntegration.ts index 9fb1aaab..201b9e96 100644 --- a/src/integrations/walletIntegration.ts +++ b/src/integrations/walletIntegration.ts @@ -18,6 +18,7 @@ export default async function walletIntegration(store: Store) { } Object.keys(Providers).forEach((providerKey) => { + console.log('TCL: walletIntegration -> providerKey', providerKey) const provider: WalletProvider = Providers[providerKey] provider.checkAvailability() diff --git a/src/styles/components/buttons/_buttons.scss b/src/styles/components/buttons/_buttons.scss index 0c2f0db3..4fc6ff8b 100644 --- a/src/styles/components/buttons/_buttons.scss +++ b/src/styles/components/buttons/_buttons.scss @@ -155,3 +155,18 @@ a.buttonCTA { width: 35%; max-width: 112px; } + +#walletChooserInput, #walletChooserSubmitButton { + border: none; + color: white; + font-weight: bold; + padding: 5px; +} + +#walletChooserInput { + background: #0000007a; +} + +#walletChooserSubmitButton { + background: black; +} diff --git a/src/styles/components/icons/_tokenIcons.scss b/src/styles/components/icons/_tokenIcons.scss index 6a01010c..437d3876 100644 --- a/src/styles/components/icons/_tokenIcons.scss +++ b/src/styles/components/icons/_tokenIcons.scss @@ -67,11 +67,11 @@ $defaultTokenSize_mobile: 36px 70px; // Mobile, placing it here to override, until code is re-structured: -[data-coin] { +[data-coin] { @media #{$mobile} { border-radius: 90px; height: 90px; width: 90px; background-size: $defaultTokenSize_mobile; } -} \ No newline at end of file +} diff --git a/src/styles/components/modals/_modals.scss b/src/styles/components/modals/_modals.scss index bb3e2128..a03cf740 100644 --- a/src/styles/components/modals/_modals.scss +++ b/src/styles/components/modals/_modals.scss @@ -196,7 +196,7 @@ $modal-max-width: 800px; font-size: 1em; word-break: break-all; - @media #{$mobile} { + @media #{$mobile} { flex-wrap: wrap; flex-direction: column; } @@ -229,7 +229,7 @@ $modal-max-width: 800px; flex: 1; margin: 12px 12px 0; - @media #{$mobile} { + @media #{$mobile} { display: none; } } diff --git a/src/styles/components/navbar/_navbar.scss b/src/styles/components/navbar/_navbar.scss index c416656e..88ce77e5 100644 --- a/src/styles/components/navbar/_navbar.scss +++ b/src/styles/components/navbar/_navbar.scss @@ -397,6 +397,20 @@ header { max-width: 100%; } + &:first-of-type { + min-width: 23px; + max-width: 23px; + padding: 8px 8px 8px 10px; + + @media #{$mobile} { + min-width: 45px; + } + } + + > img { + max-width: 100%; + } + @media #{$mobile} { box-sizing: border-box; border-radius: 0; @@ -516,7 +530,7 @@ header { font-weight: bold; margin: 0 auto; - @media #{$mobile} { + @media #{$mobile} { font-size: 1.1em; } } diff --git a/src/styles/components/walletChooser/_walletChooser.scss b/src/styles/components/walletChooser/_walletChooser.scss index ded5ca02..abb8344d 100644 --- a/src/styles/components/walletChooser/_walletChooser.scss +++ b/src/styles/components/walletChooser/_walletChooser.scss @@ -29,10 +29,10 @@ border-radius: 2px; min-height: 300px; - &.ready { - background: $white; - box-shadow: 0 15px 35px rgba(50, 50, 93, 0.1), 0 5px 15px rgba(0, 0, 0, 0.07); - } + &.ready { + background: $white; + box-shadow: 0 15px 35px rgba(50, 50, 93, 0.1), 0 5px 15px rgba(0, 0, 0, 0.07); + } } > h3 { @@ -56,29 +56,29 @@ transition: all 0.2s ease-in; margin: 3px; - @media #{$mobile} { + @media #{$mobile} { max-width: 47%; flex: 1; } - &:hover { - border: 1px solid $brandPrimary; - transform: translateY(-1px); - box-shadow: 0 7px 14px rgba(50, 50, 93, 0.1), 0 3px 6px rgba(0, 0, 0, 0.08); - } + &:hover { + border: 1px solid $brandPrimary; + transform: translateY(-1px); + box-shadow: 0 7px 14px rgba(50, 50, 93, 0.1), 0 3px 6px rgba(0, 0, 0, 0.08); + } - > img { - width: 120px; - height: 120px; - object-fit: contain; - } + > img { + width: 120px; + height: 120px; + object-fit: contain; + } - > h4 { - margin: 0; - width: 100%; - text-align: center; - color: $blackShade; - font-size: 1.2em; - } + > h4 { + margin: 0; + width: 100%; + text-align: center; + color: $blackShade; + font-size: 1.2em; + } } } diff --git a/src/styles/core/_base.scss b/src/styles/core/_base.scss index 0c5649b2..65ce6af4 100644 --- a/src/styles/core/_base.scss +++ b/src/styles/core/_base.scss @@ -78,6 +78,7 @@ section.home, section.auction { section.home { margin: 20px auto; + @media #{$desktop} { padding: 0 30px 90px; } diff --git a/src/styles/core/_fonts.scss b/src/styles/core/_fonts.scss index c63394e8..d4506c1b 100644 --- a/src/styles/core/_fonts.scss +++ b/src/styles/core/_fonts.scss @@ -52,4 +52,4 @@ @font-face { font-family: "Megrim"; src: url('#{$fonts}/other/Megrim.ttf') format('truetype'); -} \ No newline at end of file +} diff --git a/src/styles/core/_variables.scss b/src/styles/core/_variables.scss index 80512fcd..de931302 100644 --- a/src/styles/core/_variables.scss +++ b/src/styles/core/_variables.scss @@ -89,6 +89,6 @@ $brandPrimary: $blue; // Primary color $brandPrimaryShade: $blueShade; // Primary color // Modals -$modalColor: rgba(0, 72, 130, 1);; -$modalColorOpacity: rgba(0, 72, 130, .9);; -$boxShadowContainer: 0 15px 35px rgba(50,50,93,.1), 0 5px 15px rgba(0,0,0,.07); \ No newline at end of file +$modalColor: rgba(0, 72, 130, 1); +$modalColorOpacity: rgba(0, 72, 130, .9); +$boxShadowContainer: 0 15px 35px rgba(50,50,93,.1), 0 5px 15px rgba(0,0,0,.07); diff --git a/src/types/index.d.ts b/src/types/index.d.ts index 8502cc9e..71760325 100644 --- a/src/types/index.d.ts +++ b/src/types/index.d.ts @@ -96,6 +96,12 @@ export interface Modal { feeRatio?: string | number, sellAmountAfterFee?: BigNumber, }, + txParams?: { + from: string, + to: string, + value: string, + data: string, + } onClick?: (choice: string) => any, button?: boolean, error?: string, diff --git a/src/utils/index.ts b/src/utils/index.ts index e3830866..76a8020a 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1,8 +1,11 @@ import Web3 from 'web3' +import { toHex } from 'web3/lib/utils/utils.js' import { promisedWeb3 } from 'api/web3Provider' import { logDecoder } from 'ethjs-abi' + import { store } from 'components/App' +import { openModal } from 'actions' import { DefaultTokenList, ProviderInterface, DefaultTokenObject, Receipt, ABI, Web3EventLog, TransactionObject } from 'api/types' import { Account } from 'types' @@ -217,6 +220,40 @@ export const web3CompatibleNetwork = async () => { export const lastArrVal = (arr: Array) => arr[arr.length - 1] +// for users using Custom Private Key as wallet +export async function customValidateTransaction(txParams: any, cb: Function) { + console.log('TCL: initialize -> txParams', txParams) + // here, instead of prompt, use a modal and txParams to populate and show + // users what the fuuuuuck theyre signing, ayy + const promisedChoice: Promise = new Promise(accept => { + store.dispatch(openModal({ + modalName: 'PrivateKeyApproval', + modalProps: { + header: 'Private Key Transaction Confirmation', + body: '', + buttons: { + button2: { + buttonTitle2: 'Confirm', + }, + button1: { + buttonTitle1: 'Cancel', + }, + }, + onClick: accept, + txParams, + }, + })) + }) + const choice: any = await promisedChoice + // @ts-ignore + if (choice === 'MIN') store.dispatch(errorHandling(new Error('User canceled transaction'))) + else { + txParams.gas = toHex(choice.gasLimit) + txParams.gasPrice = toHex(choice.gasPrice) + return cb() + } +} + export const estimateGas = async ( { cb, mainParams, txParams }: { cb: Function & { estimateGas?: Function }, mainParams?: any, txParams?: TransactionObject }, type?: null | 'sendTransaction' | 'call',