Update with latest dapps
This commit is contained in:
parent
45f91facf1
commit
696089c479
583
js/package-lock.json
generated
583
js/package-lock.json
generated
@ -13,10 +13,10 @@
|
||||
}
|
||||
},
|
||||
"@parity/api": {
|
||||
"version": "github:paritytech/js-api#ade4a6750292a2918676039ea53eea20c4c728bc",
|
||||
"version": "github:paritytech/js-api#bd566a070313ae35939014219b58bb93f3c3a145",
|
||||
"requires": {
|
||||
"@parity/abi": "github:paritytech/js-abi#414765a476d88b6fb9f3398c99a946021957d07a",
|
||||
"@parity/jsonrpc": "github:paritytech/js-jsonrpc#89a6e441370f55d8fe995e27007f60da29b6672b",
|
||||
"@parity/jsonrpc": "github:paritytech/js-jsonrpc#e271aa9d158fa90a57cc4e6b4ad2993f9fbb8ad4",
|
||||
"@parity/wordlist": "1.1.0",
|
||||
"bignumber.js": "3.0.1",
|
||||
"blockies": "0.0.2",
|
||||
@ -47,14 +47,14 @@
|
||||
"@parity/dapp-account": {
|
||||
"version": "github:paritytech/dapp-account#be1279faf2ac430ec44ab2d4769ca68eacdac9b6",
|
||||
"requires": {
|
||||
"@parity/api": "github:paritytech/js-api#ade4a6750292a2918676039ea53eea20c4c728bc",
|
||||
"@parity/api": "github:paritytech/js-api#bd566a070313ae35939014219b58bb93f3c3a145",
|
||||
"@parity/dapp-accounts": "github:paritytech/dapp-accounts#235036f3e726e206391b15cf8c3e9d8956bc121d",
|
||||
"@parity/dapp-address": "github:paritytech/dapp-address#8e1431a2e57d2fe8805fc184848148f8dce34210",
|
||||
"@parity/dapp-vaults": "github:paritytech/dapp-vaults#de86d2bf21f1d0283b7f9fd7b3159a280e321818",
|
||||
"@parity/parity.js": "1.8.7",
|
||||
"@parity/shapeshift": "github:paritytech/js-shapeshift#59d71436b678390a3abdea37d58b5ff06edfd750",
|
||||
"@parity/shared": "github:paritytech/js-shared#49f3719ffc732962efc9017daf0e30bd384bfbc2",
|
||||
"@parity/ui": "github:paritytech/js-ui#7f7235fe696defd547ace030041f2f52c842c7dc",
|
||||
"@parity/shapeshift": "github:paritytech/js-shapeshift#9de4790c8f6ac282e10af5738dd0a687a97fc419",
|
||||
"@parity/shared": "github:paritytech/js-shared#1d61c148190a141145b030b2328e2f373c830a2b",
|
||||
"@parity/ui": "github:paritytech/js-ui#82f4c63d6a5eeba95149254accb82f7a54c0104a",
|
||||
"happypack": "3.1.0",
|
||||
"lodash": "4.17.2",
|
||||
"oo7": "0.5.3",
|
||||
@ -69,10 +69,10 @@
|
||||
"@parity/dapp-accounts": {
|
||||
"version": "github:paritytech/dapp-accounts#235036f3e726e206391b15cf8c3e9d8956bc121d",
|
||||
"requires": {
|
||||
"@parity/api": "github:paritytech/js-api#ade4a6750292a2918676039ea53eea20c4c728bc",
|
||||
"@parity/api": "github:paritytech/js-api#bd566a070313ae35939014219b58bb93f3c3a145",
|
||||
"@parity/dapp-vaults": "github:paritytech/dapp-vaults#de86d2bf21f1d0283b7f9fd7b3159a280e321818",
|
||||
"@parity/shared": "github:paritytech/js-shared#49f3719ffc732962efc9017daf0e30bd384bfbc2",
|
||||
"@parity/ui": "github:paritytech/js-ui#7f7235fe696defd547ace030041f2f52c842c7dc",
|
||||
"@parity/shared": "github:paritytech/js-shared#1d61c148190a141145b030b2328e2f373c830a2b",
|
||||
"@parity/ui": "github:paritytech/js-ui#82f4c63d6a5eeba95149254accb82f7a54c0104a",
|
||||
"file-saver": "1.3.3",
|
||||
"react": "15.6.1",
|
||||
"react-dom": "15.6.1",
|
||||
@ -85,29 +85,29 @@
|
||||
"@parity/dapp-address": {
|
||||
"version": "github:paritytech/dapp-address#8e1431a2e57d2fe8805fc184848148f8dce34210",
|
||||
"requires": {
|
||||
"@parity/api": "github:paritytech/js-api#ade4a6750292a2918676039ea53eea20c4c728bc",
|
||||
"@parity/api": "github:paritytech/js-api#bd566a070313ae35939014219b58bb93f3c3a145",
|
||||
"@parity/dapp-account": "github:paritytech/dapp-account#be1279faf2ac430ec44ab2d4769ca68eacdac9b6",
|
||||
"@parity/dapp-addresses": "github:paritytech/dapp-addresses#b1ecac83d0d2921ad882695dc0f4fbfc7e442cf2",
|
||||
"@parity/shared": "github:paritytech/js-shared#49f3719ffc732962efc9017daf0e30bd384bfbc2",
|
||||
"@parity/ui": "github:paritytech/js-ui#7f7235fe696defd547ace030041f2f52c842c7dc",
|
||||
"@parity/shared": "github:paritytech/js-shared#1d61c148190a141145b030b2328e2f373c830a2b",
|
||||
"@parity/ui": "github:paritytech/js-ui#82f4c63d6a5eeba95149254accb82f7a54c0104a",
|
||||
"recharts": "0.15.2"
|
||||
}
|
||||
},
|
||||
"@parity/dapp-addresses": {
|
||||
"version": "github:paritytech/dapp-addresses#b1ecac83d0d2921ad882695dc0f4fbfc7e442cf2",
|
||||
"requires": {
|
||||
"@parity/api": "github:paritytech/js-api#ade4a6750292a2918676039ea53eea20c4c728bc",
|
||||
"@parity/api": "github:paritytech/js-api#bd566a070313ae35939014219b58bb93f3c3a145",
|
||||
"@parity/dapp-accounts": "github:paritytech/dapp-accounts#235036f3e726e206391b15cf8c3e9d8956bc121d",
|
||||
"@parity/shared": "github:paritytech/js-shared#49f3719ffc732962efc9017daf0e30bd384bfbc2",
|
||||
"@parity/ui": "github:paritytech/js-ui#7f7235fe696defd547ace030041f2f52c842c7dc",
|
||||
"@parity/shared": "github:paritytech/js-shared#1d61c148190a141145b030b2328e2f373c830a2b",
|
||||
"@parity/ui": "github:paritytech/js-ui#82f4c63d6a5eeba95149254accb82f7a54c0104a",
|
||||
"recharts": "0.15.2"
|
||||
}
|
||||
},
|
||||
"@parity/dapp-chaindeploy": {
|
||||
"version": "github:paritytech/dapp-chaindeploy#dfb12d38e9c0c8a540be0a51681a36685b812963",
|
||||
"requires": {
|
||||
"@parity/api": "github:paritytech/js-api#ade4a6750292a2918676039ea53eea20c4c728bc",
|
||||
"@parity/shared": "github:paritytech/js-shared#49f3719ffc732962efc9017daf0e30bd384bfbc2",
|
||||
"@parity/api": "github:paritytech/js-api#bd566a070313ae35939014219b58bb93f3c3a145",
|
||||
"@parity/shared": "github:paritytech/js-shared#1d61c148190a141145b030b2328e2f373c830a2b",
|
||||
"react": "15.6.1",
|
||||
"react-dom": "15.6.1"
|
||||
}
|
||||
@ -115,51 +115,60 @@
|
||||
"@parity/dapp-contract": {
|
||||
"version": "github:paritytech/dapp-contract#311caba0c0ae14ec84c2cb6ea395990dd4af5d60",
|
||||
"requires": {
|
||||
"@parity/api": "github:paritytech/js-api#ade4a6750292a2918676039ea53eea20c4c728bc",
|
||||
"@parity/api": "github:paritytech/js-api#bd566a070313ae35939014219b58bb93f3c3a145",
|
||||
"@parity/dapp-account": "github:paritytech/dapp-account#be1279faf2ac430ec44ab2d4769ca68eacdac9b6",
|
||||
"@parity/dapp-address": "github:paritytech/dapp-address#8e1431a2e57d2fe8805fc184848148f8dce34210",
|
||||
"@parity/shared": "github:paritytech/js-shared#49f3719ffc732962efc9017daf0e30bd384bfbc2",
|
||||
"@parity/ui": "github:paritytech/js-ui#7f7235fe696defd547ace030041f2f52c842c7dc",
|
||||
"@parity/shared": "github:paritytech/js-shared#1d61c148190a141145b030b2328e2f373c830a2b",
|
||||
"@parity/ui": "github:paritytech/js-ui#82f4c63d6a5eeba95149254accb82f7a54c0104a",
|
||||
"recharts": "0.15.2"
|
||||
}
|
||||
},
|
||||
"@parity/dapp-contracts": {
|
||||
"version": "github:paritytech/dapp-contracts#d96a451a540cb46d4fc1300b90c91ebf1421213d",
|
||||
"requires": {
|
||||
"@parity/api": "github:paritytech/js-api#ade4a6750292a2918676039ea53eea20c4c728bc",
|
||||
"@parity/api": "github:paritytech/js-api#bd566a070313ae35939014219b58bb93f3c3a145",
|
||||
"@parity/dapp-account": "github:paritytech/dapp-account#be1279faf2ac430ec44ab2d4769ca68eacdac9b6",
|
||||
"@parity/dapp-accounts": "github:paritytech/dapp-accounts#235036f3e726e206391b15cf8c3e9d8956bc121d",
|
||||
"@parity/shared": "github:paritytech/js-shared#49f3719ffc732962efc9017daf0e30bd384bfbc2",
|
||||
"@parity/ui": "github:paritytech/js-ui#7f7235fe696defd547ace030041f2f52c842c7dc",
|
||||
"@parity/shared": "github:paritytech/js-shared#1d61c148190a141145b030b2328e2f373c830a2b",
|
||||
"@parity/ui": "github:paritytech/js-ui#82f4c63d6a5eeba95149254accb82f7a54c0104a",
|
||||
"recharts": "0.15.2"
|
||||
}
|
||||
},
|
||||
"@parity/dapp-dapp-accounts": {
|
||||
"version": "github:paritytech/dapp-dapp-accounts#c2e748cfcbd3e4deb09cdf1bab5634576b961010",
|
||||
"requires": {
|
||||
"@parity/api": "github:paritytech/js-api#ade4a6750292a2918676039ea53eea20c4c728bc",
|
||||
"@parity/shared": "github:paritytech/js-shared#49f3719ffc732962efc9017daf0e30bd384bfbc2",
|
||||
"@parity/ui": "github:paritytech/js-ui#7f7235fe696defd547ace030041f2f52c842c7dc",
|
||||
"@parity/api": "github:paritytech/js-api#bd566a070313ae35939014219b58bb93f3c3a145",
|
||||
"@parity/shared": "github:paritytech/js-shared#1d61c148190a141145b030b2328e2f373c830a2b",
|
||||
"@parity/ui": "github:paritytech/js-ui#82f4c63d6a5eeba95149254accb82f7a54c0104a",
|
||||
"recharts": "0.15.2"
|
||||
}
|
||||
},
|
||||
"@parity/dapp-dapp-methods": {
|
||||
"version": "github:paritytech/dapp-dapp-methods#c38f3f7ad253fe675f24ec442bf8d763325aa058",
|
||||
"requires": {
|
||||
"@parity/api": "github:paritytech/js-api#ade4a6750292a2918676039ea53eea20c4c728bc",
|
||||
"@parity/shared": "github:paritytech/js-shared#49f3719ffc732962efc9017daf0e30bd384bfbc2",
|
||||
"@parity/ui": "github:paritytech/js-ui#7f7235fe696defd547ace030041f2f52c842c7dc",
|
||||
"@parity/api": "github:paritytech/js-api#bd566a070313ae35939014219b58bb93f3c3a145",
|
||||
"@parity/shared": "github:paritytech/js-shared#1d61c148190a141145b030b2328e2f373c830a2b",
|
||||
"@parity/ui": "github:paritytech/js-ui#82f4c63d6a5eeba95149254accb82f7a54c0104a",
|
||||
"recharts": "0.15.2"
|
||||
}
|
||||
},
|
||||
"@parity/dapp-dappreg": {
|
||||
"version": "github:paritytech/dapp-dappreg#698d4083d88f4ea83a358bb91aa088a5b270f03c",
|
||||
"requires": {
|
||||
"@parity/api": "github:paritytech/js-api#bd566a070313ae35939014219b58bb93f3c3a145",
|
||||
"@parity/shared": "github:paritytech/js-shared#1d61c148190a141145b030b2328e2f373c830a2b",
|
||||
"@parity/ui": "github:paritytech/js-ui#82f4c63d6a5eeba95149254accb82f7a54c0104a",
|
||||
"recharts": "0.15.2"
|
||||
}
|
||||
},
|
||||
"@parity/dapp-develop": {
|
||||
"version": "github:paritytech/dapp-develop#899c49dd7d384ebd1ebcbf3c42291acbdc257c10",
|
||||
"version": "github:paritytech/dapp-develop#0af0cc92d3daf7260d0ea294a9519b809c6f00ac",
|
||||
"requires": {
|
||||
"@parity/api": "github:paritytech/js-api#ade4a6750292a2918676039ea53eea20c4c728bc",
|
||||
"@parity/api": "github:paritytech/js-api#bd566a070313ae35939014219b58bb93f3c3a145",
|
||||
"@parity/dapp-contracts": "github:paritytech/dapp-contracts#d96a451a540cb46d4fc1300b90c91ebf1421213d",
|
||||
"@parity/parity.js": "1.8.7",
|
||||
"@parity/shared": "github:paritytech/js-shared#49f3719ffc732962efc9017daf0e30bd384bfbc2",
|
||||
"@parity/ui": "github:paritytech/js-ui#7f7235fe696defd547ace030041f2f52c842c7dc",
|
||||
"@parity/shared": "github:paritytech/js-shared#1d61c148190a141145b030b2328e2f373c830a2b",
|
||||
"@parity/ui": "github:paritytech/js-ui#82f4c63d6a5eeba95149254accb82f7a54c0104a",
|
||||
"oo7": "0.5.3",
|
||||
"oo7-parity": "0.6.8",
|
||||
"oo7-react": "0.4.5",
|
||||
@ -168,210 +177,162 @@
|
||||
}
|
||||
},
|
||||
"@parity/dapp-githubhint": {
|
||||
"version": "github:paritytech/dapp-githubhint#10b394b8cd4f90bc83b9b0da7dfbe034f8cd9f33",
|
||||
"version": "github:paritytech/dapp-githubhint#bcc95b587d428f3dd7ea329f4dae5b2eb904f07f",
|
||||
"requires": {
|
||||
"@parity/api": "github:paritytech/js-api#ade4a6750292a2918676039ea53eea20c4c728bc",
|
||||
"@parity/shared": "github:paritytech/js-shared#9bb1d291d8752a827613889498e380fcd3afa8da",
|
||||
"@parity/api": "github:paritytech/js-api#bd566a070313ae35939014219b58bb93f3c3a145",
|
||||
"@parity/shared": "github:paritytech/js-shared#1d61c148190a141145b030b2328e2f373c830a2b",
|
||||
"moment": "2.17.0",
|
||||
"react": "15.6.1",
|
||||
"react-dom": "15.6.1",
|
||||
"react-tap-event-plugin": "2.0.1"
|
||||
}
|
||||
},
|
||||
"@parity/dapp-home": {
|
||||
"version": "github:paritytech/dapp-home#f4f7f0044f68641f710d96bee244c0f41f780e80",
|
||||
"requires": {
|
||||
"@parity/api": "github:paritytech/js-api#bd566a070313ae35939014219b58bb93f3c3a145",
|
||||
"@parity/dapp-web": "github:paritytech/dapp-web#a431e9d4177a4a19d85fc1adc1539368f3808a8b",
|
||||
"@parity/shared": "github:paritytech/js-shared#1d61c148190a141145b030b2328e2f373c830a2b",
|
||||
"@parity/ui": "github:paritytech/js-ui#82f4c63d6a5eeba95149254accb82f7a54c0104a",
|
||||
"react-markdown": "2.4.4",
|
||||
"recharts": "0.15.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@parity/api": {
|
||||
"version": "github:paritytech/js-api#ade4a6750292a2918676039ea53eea20c4c728bc",
|
||||
"react-markdown": {
|
||||
"version": "2.4.4",
|
||||
"resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-2.4.4.tgz",
|
||||
"integrity": "sha1-JtglQ40pLnym4pL+diAeHb8s/u4=",
|
||||
"requires": {
|
||||
"@parity/abi": "github:paritytech/js-abi#414765a476d88b6fb9f3398c99a946021957d07a",
|
||||
"@parity/jsonrpc": "github:paritytech/js-jsonrpc#89a6e441370f55d8fe995e27007f60da29b6672b",
|
||||
"@parity/wordlist": "1.1.0",
|
||||
"bignumber.js": "3.0.1",
|
||||
"blockies": "0.0.2",
|
||||
"es6-error": "4.0.0",
|
||||
"ethereumjs-tx": "1.3.3",
|
||||
"eventemitter3": "2.0.3",
|
||||
"isomorphic-fetch": "2.2.1",
|
||||
"js-sha3": "0.5.5",
|
||||
"keythereum": "0.4.6",
|
||||
"lodash": "4.17.4",
|
||||
"node-fetch": "1.6.3",
|
||||
"secp256k1": "3.2.5",
|
||||
"store": "2.0.12"
|
||||
"commonmark": "0.24.0",
|
||||
"commonmark-react-renderer": "4.3.3",
|
||||
"in-publish": "2.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@parity/ledger": {
|
||||
"version": "github:paritytech/js-ledger#c363adfb9192aa56b7b498b0ad90bc4032bcd6ab",
|
||||
"@parity/dapp-localtx": {
|
||||
"version": "github:paritytech/dapp-localtx#6d20868fadb820aff210097fac110e50cb966dc5",
|
||||
"requires": {
|
||||
"u2f-api": "0.0.9",
|
||||
"u2f-api-polyfill": "0.4.3"
|
||||
"@parity/api": "github:paritytech/js-api#bd566a070313ae35939014219b58bb93f3c3a145",
|
||||
"@parity/shared": "github:paritytech/js-shared#1d61c148190a141145b030b2328e2f373c830a2b",
|
||||
"@parity/ui": "github:paritytech/js-ui#82f4c63d6a5eeba95149254accb82f7a54c0104a",
|
||||
"recharts": "0.15.2"
|
||||
}
|
||||
},
|
||||
"@parity/shared": {
|
||||
"version": "github:paritytech/js-shared#9bb1d291d8752a827613889498e380fcd3afa8da",
|
||||
"@parity/dapp-playground": {
|
||||
"version": "github:paritytech/dapp-playground#a43f3b3bfe8faa83ae00b67bf5b0eee26924f2f3",
|
||||
"requires": {
|
||||
"@parity/ledger": "github:paritytech/js-ledger#c363adfb9192aa56b7b498b0ad90bc4032bcd6ab",
|
||||
"loglevel": "1.4.1",
|
||||
"mobx": "2.6.4",
|
||||
"mobx-react": "4.0.3",
|
||||
"promise-worker": "1.1.1",
|
||||
"push.js": "0.0.11",
|
||||
"react-redux": "4.4.6",
|
||||
"redux": "3.6.0",
|
||||
"redux-actions": "1.1.0",
|
||||
"redux-thunk": "2.1.0",
|
||||
"scryptsy": "2.0.0",
|
||||
"serviceworker-webpack-plugin": "0.2.0",
|
||||
"solc": "github:ngotchac/solc-js#04eb38cc3003fba8cb3656653a7941ed36408818",
|
||||
"worker-loader": "0.8.1",
|
||||
"yargs": "6.6.0"
|
||||
"@parity/api": "github:paritytech/js-api#bd566a070313ae35939014219b58bb93f3c3a145",
|
||||
"@parity/shared": "github:paritytech/js-shared#1d61c148190a141145b030b2328e2f373c830a2b",
|
||||
"@parity/ui": "github:paritytech/js-ui#82f4c63d6a5eeba95149254accb82f7a54c0104a",
|
||||
"recharts": "0.15.2"
|
||||
}
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.4",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
|
||||
"integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
|
||||
},
|
||||
"store": {
|
||||
"version": "2.0.12",
|
||||
"resolved": "https://registry.npmjs.org/store/-/store-2.0.12.tgz",
|
||||
"integrity": "sha1-jFNOKguDH3K3X8XxEZhXxE711ZM="
|
||||
"@parity/dapp-registry": {
|
||||
"version": "github:paritytech/dapp-registry#2426ae6a1c447a18dfa7cc3c6504904426cd41ae",
|
||||
"requires": {
|
||||
"@parity/api": "github:paritytech/js-api#bd566a070313ae35939014219b58bb93f3c3a145",
|
||||
"@parity/shared": "github:paritytech/js-shared#1d61c148190a141145b030b2328e2f373c830a2b",
|
||||
"@parity/ui": "github:paritytech/js-ui#82f4c63d6a5eeba95149254accb82f7a54c0104a",
|
||||
"material-ui": "0.16.5",
|
||||
"recharts": "0.15.2"
|
||||
}
|
||||
},
|
||||
"@parity/dapp-settings": {
|
||||
"version": "github:paritytech/dapp-settings#b5e2877825401f73945b8e82f7a383d118adadd6",
|
||||
"requires": {
|
||||
"@parity/api": "github:paritytech/js-api#bd566a070313ae35939014219b58bb93f3c3a145",
|
||||
"@parity/shared": "github:paritytech/js-shared#1d61c148190a141145b030b2328e2f373c830a2b",
|
||||
"@parity/ui": "github:paritytech/js-ui#82f4c63d6a5eeba95149254accb82f7a54c0104a",
|
||||
"recharts": "0.15.2"
|
||||
}
|
||||
},
|
||||
"@parity/dapp-signaturereg": {
|
||||
"version": "github:paritytech/dapp-signaturereg#79b17073c1034b2c7f515833475bc374a8c84692",
|
||||
"requires": {
|
||||
"@parity/api": "github:paritytech/js-api#bd566a070313ae35939014219b58bb93f3c3a145",
|
||||
"@parity/shared": "github:paritytech/js-shared#1d61c148190a141145b030b2328e2f373c830a2b",
|
||||
"moment": "2.17.0",
|
||||
"react": "15.6.1",
|
||||
"react-dom": "15.6.1",
|
||||
"react-tap-event-plugin": "2.0.1"
|
||||
}
|
||||
},
|
||||
"@parity/dapp-signer": {
|
||||
"version": "github:paritytech/dapp-signer#2ea607e6c994513d8dbe72dc9934cdb360f8c269",
|
||||
"requires": {
|
||||
"@parity/api": "github:paritytech/js-api#bd566a070313ae35939014219b58bb93f3c3a145",
|
||||
"@parity/shared": "github:paritytech/js-shared#1d61c148190a141145b030b2328e2f373c830a2b",
|
||||
"@parity/ui": "github:paritytech/js-ui#82f4c63d6a5eeba95149254accb82f7a54c0104a",
|
||||
"recharts": "0.15.2"
|
||||
}
|
||||
},
|
||||
"@parity/dapp-status": {
|
||||
"version": "github:paritytech/dapp-status#2f2d8de2d86d1fff693795a1897e40876397ed8b",
|
||||
"requires": {
|
||||
"@parity/api": "github:paritytech/js-api#bd566a070313ae35939014219b58bb93f3c3a145",
|
||||
"@parity/shared": "github:paritytech/js-shared#1d61c148190a141145b030b2328e2f373c830a2b",
|
||||
"@parity/ui": "github:paritytech/js-ui#82f4c63d6a5eeba95149254accb82f7a54c0104a",
|
||||
"bytes": "2.4.0",
|
||||
"format-number": "2.0.1",
|
||||
"recharts": "0.15.2"
|
||||
}
|
||||
},
|
||||
"@parity/dapp-tokendeploy": {
|
||||
"version": "github:paritytech/dapp-tokendeploy#cc83829402471eba78e5c6d46394feedee3ea619",
|
||||
"requires": {
|
||||
"@parity/api": "github:paritytech/js-api#bd566a070313ae35939014219b58bb93f3c3a145",
|
||||
"@parity/shared": "github:paritytech/js-shared#1d61c148190a141145b030b2328e2f373c830a2b",
|
||||
"@parity/ui": "github:paritytech/js-ui#82f4c63d6a5eeba95149254accb82f7a54c0104a",
|
||||
"recharts": "0.15.2"
|
||||
}
|
||||
},
|
||||
"@parity/dapp-tokenreg": {
|
||||
"version": "github:paritytech/dapp-tokenreg#67f6dfb798e68593f688b67935e1a4b223fa4c63",
|
||||
"requires": {
|
||||
"@parity/api": "github:paritytech/js-api#bd566a070313ae35939014219b58bb93f3c3a145",
|
||||
"@parity/shared": "github:paritytech/js-shared#1d61c148190a141145b030b2328e2f373c830a2b",
|
||||
"material-ui": "0.16.5",
|
||||
"react": "15.6.1",
|
||||
"react-dom": "15.6.1",
|
||||
"react-tap-event-plugin": "2.0.1",
|
||||
"recharts": "0.15.2"
|
||||
}
|
||||
},
|
||||
"@parity/dapp-vaults": {
|
||||
"version": "github:paritytech/dapp-vaults#de86d2bf21f1d0283b7f9fd7b3159a280e321818",
|
||||
"requires": {
|
||||
"@parity/api": "github:paritytech/js-api#ade4a6750292a2918676039ea53eea20c4c728bc",
|
||||
"@parity/shared": "github:paritytech/js-shared#49f3719ffc732962efc9017daf0e30bd384bfbc2",
|
||||
"@parity/ui": "github:paritytech/js-ui#7f7235fe696defd547ace030041f2f52c842c7dc",
|
||||
"@parity/api": "github:paritytech/js-api#bd566a070313ae35939014219b58bb93f3c3a145",
|
||||
"@parity/shared": "github:paritytech/js-shared#1d61c148190a141145b030b2328e2f373c830a2b",
|
||||
"@parity/ui": "github:paritytech/js-ui#82f4c63d6a5eeba95149254accb82f7a54c0104a",
|
||||
"recharts": "0.15.2"
|
||||
}
|
||||
},
|
||||
"@parity/dapp-wallet": {
|
||||
"version": "github:paritytech/dapp-wallet#711f4381cef112e8d11f0cd6cbfa15d87eea0b54",
|
||||
"version": "github:paritytech/dapp-wallet#22315cb2dae87d34be1f7cb3b3bf26ca8d7e2dab",
|
||||
"requires": {
|
||||
"@parity/api": "github:paritytech/js-api#ade4a6750292a2918676039ea53eea20c4c728bc",
|
||||
"@parity/api": "github:paritytech/js-api#bd566a070313ae35939014219b58bb93f3c3a145",
|
||||
"@parity/dapp-account": "github:paritytech/dapp-account#be1279faf2ac430ec44ab2d4769ca68eacdac9b6",
|
||||
"@parity/dapp-address": "github:paritytech/dapp-address#8e1431a2e57d2fe8805fc184848148f8dce34210",
|
||||
"@parity/shared": "github:paritytech/js-shared#9bb1d291d8752a827613889498e380fcd3afa8da",
|
||||
"@parity/ui": "github:paritytech/js-ui#037782bd16e8abf1c169143aa61749a44b94489b",
|
||||
"@parity/shared": "github:paritytech/js-shared#1d61c148190a141145b030b2328e2f373c830a2b",
|
||||
"@parity/ui": "github:paritytech/js-ui#82f4c63d6a5eeba95149254accb82f7a54c0104a",
|
||||
"recharts": "0.15.2"
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@parity/shared": {
|
||||
"version": "github:paritytech/js-shared#9bb1d291d8752a827613889498e380fcd3afa8da",
|
||||
"@parity/dapp-web": {
|
||||
"version": "github:paritytech/dapp-web#a431e9d4177a4a19d85fc1adc1539368f3808a8b",
|
||||
"requires": {
|
||||
"@parity/ledger": "github:paritytech/js-ledger#c363adfb9192aa56b7b498b0ad90bc4032bcd6ab",
|
||||
"loglevel": "1.4.1",
|
||||
"mobx": "2.6.4",
|
||||
"mobx-react": "4.0.3",
|
||||
"promise-worker": "1.1.1",
|
||||
"push.js": "0.0.11",
|
||||
"react-redux": "4.4.6",
|
||||
"redux": "3.6.0",
|
||||
"redux-actions": "1.1.0",
|
||||
"redux-thunk": "2.1.0",
|
||||
"scryptsy": "2.0.0",
|
||||
"serviceworker-webpack-plugin": "0.2.0",
|
||||
"solc": "github:ngotchac/solc-js#04eb38cc3003fba8cb3656653a7941ed36408818",
|
||||
"worker-loader": "0.8.1",
|
||||
"yargs": "6.6.0"
|
||||
}
|
||||
},
|
||||
"@parity/ui": {
|
||||
"version": "github:paritytech/js-ui#037782bd16e8abf1c169143aa61749a44b94489b",
|
||||
"requires": {
|
||||
"@parity/api": "github:paritytech/js-api#1c7cc5561c4e8db0d0b58f22d8bc8baa243909a5",
|
||||
"@parity/etherscan": "github:paritytech/js-etherscan#efe859ac7d2a8a3cc05e01c689b7fa58f47f8b87",
|
||||
"@parity/shared": "github:paritytech/js-shared#a83c71946d30d5b3bf976860a676add29c48ee24",
|
||||
"bignumber.js": "3.0.1",
|
||||
"brace": "0.9.0",
|
||||
"date-difference": "1.0.0",
|
||||
"eventemitter3": "2.0.3",
|
||||
"file-saver": "1.3.3",
|
||||
"geopattern": "1.2.3",
|
||||
"js-sha3": "0.5.5",
|
||||
"keycode": "2.1.9",
|
||||
"lodash": "4.17.2",
|
||||
"mobx": "2.6.4",
|
||||
"mobx-react": "4.0.3",
|
||||
"moment": "2.17.0",
|
||||
"qrcode-generator": "1.2.0",
|
||||
"react": "15.6.1",
|
||||
"react-ace": "4.1.0",
|
||||
"react-copy-to-clipboard": "4.2.3",
|
||||
"react-datetime": "2.8.10",
|
||||
"react-dom": "15.6.1",
|
||||
"react-dropzone": "3.7.3",
|
||||
"react-event-listener": "0.4.5",
|
||||
"react-intl": "2.1.5",
|
||||
"react-portal": "3.0.0",
|
||||
"react-qr-reader": "1.1.3",
|
||||
"react-router": "3.0.0",
|
||||
"react-router-redux": "4.0.7",
|
||||
"react-tap-event-plugin": "2.0.1",
|
||||
"react-tooltip": "3.2.2",
|
||||
"recharts": "0.15.2",
|
||||
"redux": "3.6.0",
|
||||
"semantic-ui-css": "2.2.11",
|
||||
"semantic-ui-react": "0.71.2",
|
||||
"zxcvbn": "4.4.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@parity/api": {
|
||||
"version": "github:paritytech/js-api#1c7cc5561c4e8db0d0b58f22d8bc8baa243909a5",
|
||||
"requires": {
|
||||
"@parity/abi": "github:paritytech/js-abi#414765a476d88b6fb9f3398c99a946021957d07a",
|
||||
"@parity/jsonrpc": "github:paritytech/js-jsonrpc#89a6e441370f55d8fe995e27007f60da29b6672b",
|
||||
"@parity/wordlist": "1.1.0",
|
||||
"bignumber.js": "3.0.1",
|
||||
"blockies": "0.0.2",
|
||||
"es6-error": "4.0.0",
|
||||
"ethereumjs-tx": "1.3.3",
|
||||
"eventemitter3": "2.0.3",
|
||||
"isomorphic-fetch": "2.2.1",
|
||||
"js-sha3": "0.5.5",
|
||||
"keythereum": "0.4.6",
|
||||
"lodash": "4.17.4",
|
||||
"node-fetch": "1.6.3",
|
||||
"secp256k1": "3.2.5",
|
||||
"store": "2.0.12"
|
||||
},
|
||||
"dependencies": {
|
||||
"lodash": {
|
||||
"version": "4.17.4",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
|
||||
"integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
|
||||
}
|
||||
}
|
||||
},
|
||||
"@parity/shared": {
|
||||
"version": "github:paritytech/js-shared#a83c71946d30d5b3bf976860a676add29c48ee24",
|
||||
"requires": {
|
||||
"mobx": "2.6.4",
|
||||
"mobx-react": "4.0.3",
|
||||
"push.js": "0.0.11",
|
||||
"react-redux": "4.4.6",
|
||||
"redux": "3.6.0",
|
||||
"redux-actions": "1.1.0",
|
||||
"redux-thunk": "2.1.0",
|
||||
"scryptsy": "2.0.0",
|
||||
"solc": "github:ngotchac/solc-js#04eb38cc3003fba8cb3656653a7941ed36408818",
|
||||
"yargs": "6.6.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"store": {
|
||||
"version": "2.0.12",
|
||||
"resolved": "https://registry.npmjs.org/store/-/store-2.0.12.tgz",
|
||||
"integrity": "sha1-jFNOKguDH3K3X8XxEZhXxE711ZM="
|
||||
}
|
||||
"@parity/api": "github:paritytech/js-api#bd566a070313ae35939014219b58bb93f3c3a145",
|
||||
"@parity/shared": "github:paritytech/js-shared#1d61c148190a141145b030b2328e2f373c830a2b",
|
||||
"@parity/ui": "github:paritytech/js-ui#82f4c63d6a5eeba95149254accb82f7a54c0104a",
|
||||
"base32.js": "0.1.0",
|
||||
"recharts": "0.15.2"
|
||||
}
|
||||
},
|
||||
"@parity/etherscan": {
|
||||
"version": "github:paritytech/js-etherscan#efe859ac7d2a8a3cc05e01c689b7fa58f47f8b87",
|
||||
"version": "github:paritytech/js-etherscan#12e9ce901609a9ee84907034fe1da34c18e7f358",
|
||||
"requires": {
|
||||
"@parity/api": "github:paritytech/js-api#1c7cc5561c4e8db0d0b58f22d8bc8baa243909a5",
|
||||
"@parity/api": "github:paritytech/js-api#bd566a070313ae35939014219b58bb93f3c3a145",
|
||||
"bignumber.js": "3.0.1",
|
||||
"es6-promise": "4.1.1",
|
||||
"node-fetch": "1.6.3",
|
||||
@ -379,41 +340,11 @@
|
||||
"whatwg-fetch": "2.0.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@parity/api": {
|
||||
"version": "github:paritytech/js-api#1c7cc5561c4e8db0d0b58f22d8bc8baa243909a5",
|
||||
"requires": {
|
||||
"@parity/abi": "github:paritytech/js-abi#414765a476d88b6fb9f3398c99a946021957d07a",
|
||||
"@parity/jsonrpc": "github:paritytech/js-jsonrpc#89a6e441370f55d8fe995e27007f60da29b6672b",
|
||||
"@parity/wordlist": "1.1.0",
|
||||
"bignumber.js": "3.0.1",
|
||||
"blockies": "0.0.2",
|
||||
"es6-error": "4.0.0",
|
||||
"ethereumjs-tx": "1.3.3",
|
||||
"eventemitter3": "2.0.3",
|
||||
"isomorphic-fetch": "2.2.1",
|
||||
"js-sha3": "0.5.5",
|
||||
"keythereum": "0.4.6",
|
||||
"lodash": "4.17.4",
|
||||
"node-fetch": "1.6.3",
|
||||
"secp256k1": "3.2.5",
|
||||
"store": "2.0.12"
|
||||
}
|
||||
},
|
||||
"es6-promise": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.1.1.tgz",
|
||||
"integrity": "sha512-OaU1hHjgJf+b0NzsxCg7NdIYERD6Hy/PEmFLTjw+b65scuisG3Kt4QoTvJ66BBkPZ581gr0kpoVzKnxniM8nng=="
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.4",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
|
||||
"integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
|
||||
},
|
||||
"store": {
|
||||
"version": "2.0.12",
|
||||
"resolved": "https://registry.npmjs.org/store/-/store-2.0.12.tgz",
|
||||
"integrity": "sha1-jFNOKguDH3K3X8XxEZhXxE711ZM="
|
||||
},
|
||||
"whatwg-fetch": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz",
|
||||
@ -422,7 +353,7 @@
|
||||
}
|
||||
},
|
||||
"@parity/jsonrpc": {
|
||||
"version": "github:paritytech/js-jsonrpc#89a6e441370f55d8fe995e27007f60da29b6672b"
|
||||
"version": "github:paritytech/js-jsonrpc#e271aa9d158fa90a57cc4e6b4ad2993f9fbb8ad4"
|
||||
},
|
||||
"@parity/ledger": {
|
||||
"version": "github:paritytech/js-ledger#c363adfb9192aa56b7b498b0ad90bc4032bcd6ab",
|
||||
@ -449,15 +380,16 @@
|
||||
}
|
||||
},
|
||||
"@parity/shapeshift": {
|
||||
"version": "github:paritytech/js-shapeshift#59d71436b678390a3abdea37d58b5ff06edfd750",
|
||||
"version": "github:paritytech/js-shapeshift#9de4790c8f6ac282e10af5738dd0a687a97fc419",
|
||||
"requires": {
|
||||
"node-fetch": "1.6.3"
|
||||
}
|
||||
},
|
||||
"@parity/shared": {
|
||||
"version": "github:paritytech/js-shared#49f3719ffc732962efc9017daf0e30bd384bfbc2",
|
||||
"version": "github:paritytech/js-shared#1d61c148190a141145b030b2328e2f373c830a2b",
|
||||
"requires": {
|
||||
"@parity/ledger": "github:paritytech/js-ledger#c363adfb9192aa56b7b498b0ad90bc4032bcd6ab",
|
||||
"eventemitter3": "2.0.3",
|
||||
"loglevel": "1.4.1",
|
||||
"mobx": "2.6.4",
|
||||
"mobx-react": "4.0.3",
|
||||
@ -471,16 +403,17 @@
|
||||
"serviceworker-webpack-plugin": "0.2.0",
|
||||
"solc": "github:ngotchac/solc-js#04eb38cc3003fba8cb3656653a7941ed36408818",
|
||||
"sw-toolbox": "3.6.0",
|
||||
"useragent.js": "0.5.6",
|
||||
"worker-loader": "0.8.1",
|
||||
"yargs": "6.6.0"
|
||||
}
|
||||
},
|
||||
"@parity/ui": {
|
||||
"version": "github:paritytech/js-ui#7f7235fe696defd547ace030041f2f52c842c7dc",
|
||||
"version": "github:paritytech/js-ui#82f4c63d6a5eeba95149254accb82f7a54c0104a",
|
||||
"requires": {
|
||||
"@parity/api": "github:paritytech/js-api#1c7cc5561c4e8db0d0b58f22d8bc8baa243909a5",
|
||||
"@parity/etherscan": "github:paritytech/js-etherscan#efe859ac7d2a8a3cc05e01c689b7fa58f47f8b87",
|
||||
"@parity/shared": "github:paritytech/js-shared#a83c71946d30d5b3bf976860a676add29c48ee24",
|
||||
"@parity/api": "github:paritytech/js-api#bd566a070313ae35939014219b58bb93f3c3a145",
|
||||
"@parity/etherscan": "github:paritytech/js-etherscan#12e9ce901609a9ee84907034fe1da34c18e7f358",
|
||||
"@parity/shared": "github:paritytech/js-shared#1d61c148190a141145b030b2328e2f373c830a2b",
|
||||
"bignumber.js": "3.0.1",
|
||||
"brace": "0.9.0",
|
||||
"date-difference": "1.0.0",
|
||||
@ -514,55 +447,6 @@
|
||||
"semantic-ui-css": "2.2.11",
|
||||
"semantic-ui-react": "0.71.2",
|
||||
"zxcvbn": "4.4.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@parity/api": {
|
||||
"version": "github:paritytech/js-api#1c7cc5561c4e8db0d0b58f22d8bc8baa243909a5",
|
||||
"requires": {
|
||||
"@parity/abi": "github:paritytech/js-abi#414765a476d88b6fb9f3398c99a946021957d07a",
|
||||
"@parity/jsonrpc": "github:paritytech/js-jsonrpc#89a6e441370f55d8fe995e27007f60da29b6672b",
|
||||
"@parity/wordlist": "1.1.0",
|
||||
"bignumber.js": "3.0.1",
|
||||
"blockies": "0.0.2",
|
||||
"es6-error": "4.0.0",
|
||||
"ethereumjs-tx": "1.3.3",
|
||||
"eventemitter3": "2.0.3",
|
||||
"isomorphic-fetch": "2.2.1",
|
||||
"js-sha3": "0.5.5",
|
||||
"keythereum": "0.4.6",
|
||||
"lodash": "4.17.4",
|
||||
"node-fetch": "1.6.3",
|
||||
"secp256k1": "3.2.5",
|
||||
"store": "2.0.12"
|
||||
},
|
||||
"dependencies": {
|
||||
"lodash": {
|
||||
"version": "4.17.4",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
|
||||
"integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
|
||||
}
|
||||
}
|
||||
},
|
||||
"@parity/shared": {
|
||||
"version": "github:paritytech/js-shared#a83c71946d30d5b3bf976860a676add29c48ee24",
|
||||
"requires": {
|
||||
"mobx": "2.6.4",
|
||||
"mobx-react": "4.0.3",
|
||||
"push.js": "0.0.11",
|
||||
"react-redux": "4.4.6",
|
||||
"redux": "3.6.0",
|
||||
"redux-actions": "1.1.0",
|
||||
"redux-thunk": "2.1.0",
|
||||
"scryptsy": "2.0.0",
|
||||
"solc": "github:ngotchac/solc-js#04eb38cc3003fba8cb3656653a7941ed36408818",
|
||||
"yargs": "6.6.0"
|
||||
}
|
||||
},
|
||||
"store": {
|
||||
"version": "2.0.12",
|
||||
"resolved": "https://registry.npmjs.org/store/-/store-2.0.12.tgz",
|
||||
"integrity": "sha1-jFNOKguDH3K3X8XxEZhXxE711ZM="
|
||||
}
|
||||
}
|
||||
},
|
||||
"@parity/wordlist": {
|
||||
@ -2554,6 +2438,11 @@
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
||||
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
|
||||
},
|
||||
"base32.js": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/base32.js/-/base32.js-0.1.0.tgz",
|
||||
"integrity": "sha1-tYLexpPC8R6JPPBk7mrFthMaIgI="
|
||||
},
|
||||
"base64-js": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.1.tgz",
|
||||
@ -2768,6 +2657,11 @@
|
||||
"hoek": "2.16.3"
|
||||
}
|
||||
},
|
||||
"bowser": {
|
||||
"version": "1.7.1",
|
||||
"resolved": "https://registry.npmjs.org/bowser/-/bowser-1.7.1.tgz",
|
||||
"integrity": "sha1-pN6PGKGg3JUx6yqSoVIftqm6lqU="
|
||||
},
|
||||
"brace": {
|
||||
"version": "0.9.0",
|
||||
"resolved": "https://registry.npmjs.org/brace/-/brace-0.9.0.tgz",
|
||||
@ -2957,10 +2851,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"bytes": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-2.5.0.tgz",
|
||||
"integrity": "sha1-TJQj6i0lLCcMQbK97+/5u2tiwGo=",
|
||||
"dev": true
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-2.4.0.tgz",
|
||||
"integrity": "sha1-fZcZb51br39pNeJZhVSe3SpsIzk="
|
||||
},
|
||||
"caller-path": {
|
||||
"version": "0.1.0",
|
||||
@ -3153,6 +3046,11 @@
|
||||
"supports-color": "2.0.0"
|
||||
}
|
||||
},
|
||||
"change-emitter": {
|
||||
"version": "0.1.6",
|
||||
"resolved": "https://registry.npmjs.org/change-emitter/-/change-emitter-0.1.6.tgz",
|
||||
"integrity": "sha1-6LL+PX8at9aaMhma/5HqaTFAlRU="
|
||||
},
|
||||
"check-error": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz",
|
||||
@ -3523,6 +3421,14 @@
|
||||
"on-headers": "1.0.1",
|
||||
"safe-buffer": "5.1.1",
|
||||
"vary": "1.1.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"bytes": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-2.5.0.tgz",
|
||||
"integrity": "sha1-TJQj6i0lLCcMQbK97+/5u2tiwGo=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"concat-map": {
|
||||
@ -4191,7 +4097,7 @@
|
||||
"create-hmac": "1.1.6",
|
||||
"diffie-hellman": "5.0.2",
|
||||
"inherits": "2.0.3",
|
||||
"pbkdf2": "3.0.12",
|
||||
"pbkdf2": "3.0.13",
|
||||
"public-encrypt": "4.0.0",
|
||||
"randombytes": "2.0.5"
|
||||
}
|
||||
@ -8322,6 +8228,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"hyphenate-style-name": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.2.tgz",
|
||||
"integrity": "sha1-MRYKNpMK2vH8BMYHT360FGXU7Es="
|
||||
},
|
||||
"iconv-lite": {
|
||||
"version": "0.4.18",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.18.tgz",
|
||||
@ -8586,6 +8497,15 @@
|
||||
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz",
|
||||
"integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4="
|
||||
},
|
||||
"inline-style-prefixer": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/inline-style-prefixer/-/inline-style-prefixer-2.0.5.tgz",
|
||||
"integrity": "sha1-wVPH6I/YT+9cYC6VqBaLJ3BnH+c=",
|
||||
"requires": {
|
||||
"bowser": "1.7.1",
|
||||
"hyphenate-style-name": "1.0.2"
|
||||
}
|
||||
},
|
||||
"inquirer": {
|
||||
"version": "0.12.0",
|
||||
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz",
|
||||
@ -10224,8 +10144,7 @@
|
||||
"lodash.merge": {
|
||||
"version": "4.6.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.0.tgz",
|
||||
"integrity": "sha1-aYhLoUSsM/5plzemCG3v+t0PicU=",
|
||||
"dev": true
|
||||
"integrity": "sha1-aYhLoUSsM/5plzemCG3v+t0PicU="
|
||||
},
|
||||
"lodash.pick": {
|
||||
"version": "4.4.0",
|
||||
@ -10282,6 +10201,11 @@
|
||||
"lodash._reinterpolate": "3.0.0"
|
||||
}
|
||||
},
|
||||
"lodash.throttle": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz",
|
||||
"integrity": "sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ="
|
||||
},
|
||||
"lodash.uniq": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
|
||||
@ -10439,6 +10363,35 @@
|
||||
"integrity": "sha1-ssbGGPzOzk74bE/Gy4p8v1rtqNc=",
|
||||
"dev": true
|
||||
},
|
||||
"material-ui": {
|
||||
"version": "0.16.5",
|
||||
"resolved": "https://registry.npmjs.org/material-ui/-/material-ui-0.16.5.tgz",
|
||||
"integrity": "sha1-u4ZhqsfKyMsiOj529PV+4YpK78E=",
|
||||
"requires": {
|
||||
"babel-runtime": "6.25.0",
|
||||
"inline-style-prefixer": "2.0.5",
|
||||
"keycode": "2.1.9",
|
||||
"lodash.merge": "4.6.0",
|
||||
"lodash.throttle": "4.1.1",
|
||||
"react-addons-create-fragment": "15.6.0",
|
||||
"react-addons-transition-group": "15.6.0",
|
||||
"react-event-listener": "0.4.5",
|
||||
"recompose": "0.20.2",
|
||||
"simple-assign": "0.1.0",
|
||||
"warning": "3.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"babel-runtime": {
|
||||
"version": "6.25.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.25.0.tgz",
|
||||
"integrity": "sha1-M7mOql1IK7AajRqmtDetKwGuxBw=",
|
||||
"requires": {
|
||||
"core-js": "2.4.1",
|
||||
"regenerator-runtime": "0.10.5"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"math-expression-evaluator": {
|
||||
"version": "1.2.17",
|
||||
"resolved": "https://registry.npmjs.org/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz",
|
||||
@ -11468,7 +11421,7 @@
|
||||
"browserify-aes": "1.0.6",
|
||||
"create-hash": "1.1.3",
|
||||
"evp_bytestokey": "1.0.0",
|
||||
"pbkdf2": "3.0.12"
|
||||
"pbkdf2": "3.0.13"
|
||||
}
|
||||
},
|
||||
"parse-github-repo-url": {
|
||||
@ -11583,9 +11536,9 @@
|
||||
}
|
||||
},
|
||||
"pbkdf2": {
|
||||
"version": "3.0.12",
|
||||
"resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.12.tgz",
|
||||
"integrity": "sha1-vjZ4XFBn6kjYBv+SMojF91C2uKI=",
|
||||
"version": "3.0.13",
|
||||
"resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.13.tgz",
|
||||
"integrity": "sha512-+dCHxDH+djNtjgWmvVC/my3SYBAKpKNqKSjLkp+GtWWYe4XPE+e/PSD2aCanlEZZnqPk2uekTKNC/ccbwd2X2Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"create-hash": "1.1.3",
|
||||
@ -12879,6 +12832,16 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"react-addons-create-fragment": {
|
||||
"version": "15.6.0",
|
||||
"resolved": "https://registry.npmjs.org/react-addons-create-fragment/-/react-addons-create-fragment-15.6.0.tgz",
|
||||
"integrity": "sha1-r5GiKx+wld0B8a+6Q7/Q71idiyA=",
|
||||
"requires": {
|
||||
"fbjs": "0.8.14",
|
||||
"loose-envify": "1.3.1",
|
||||
"object-assign": "4.1.1"
|
||||
}
|
||||
},
|
||||
"react-addons-perf": {
|
||||
"version": "15.4.2",
|
||||
"resolved": "https://registry.npmjs.org/react-addons-perf/-/react-addons-perf-15.4.2.tgz",
|
||||
@ -13343,6 +13306,24 @@
|
||||
"resolve": "1.4.0"
|
||||
}
|
||||
},
|
||||
"recompose": {
|
||||
"version": "0.20.2",
|
||||
"resolved": "https://registry.npmjs.org/recompose/-/recompose-0.20.2.tgz",
|
||||
"integrity": "sha1-ET1qx+KcpmTP/+wWtoHd3fFSULw=",
|
||||
"requires": {
|
||||
"change-emitter": "0.1.6",
|
||||
"fbjs": "0.8.14",
|
||||
"hoist-non-react-statics": "1.2.0",
|
||||
"symbol-observable": "0.2.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"symbol-observable": {
|
||||
"version": "0.2.4",
|
||||
"resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-0.2.4.tgz",
|
||||
"integrity": "sha1-lag9smGG1q9+ehjb2XYKL4bQj0A="
|
||||
}
|
||||
}
|
||||
},
|
||||
"redbox-react": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/redbox-react/-/redbox-react-1.5.0.tgz",
|
||||
@ -14030,6 +14011,7 @@
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/serviceworker-webpack-plugin/-/serviceworker-webpack-plugin-0.2.0.tgz",
|
||||
"integrity": "sha1-beneyC7RRMdUxvFbND57h2SsWyg=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"minimatch": "3.0.4"
|
||||
}
|
||||
@ -14095,6 +14077,11 @@
|
||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
|
||||
"integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0="
|
||||
},
|
||||
"simple-assign": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/simple-assign/-/simple-assign-0.1.0.tgz",
|
||||
"integrity": "sha1-F/0wZqXz13OPUDIbsPFMooHMS6o="
|
||||
},
|
||||
"simple-get": {
|
||||
"version": "1.4.3",
|
||||
"resolved": "https://registry.npmjs.org/simple-get/-/simple-get-1.4.3.tgz",
|
||||
|
@ -162,10 +162,22 @@
|
||||
"@parity/dapp-contracts": "paritytech/dapp-contracts",
|
||||
"@parity/dapp-dapp-accounts": "paritytech/dapp-dapp-accounts",
|
||||
"@parity/dapp-dapp-methods": "paritytech/dapp-dapp-methods",
|
||||
"@parity/dapp-dappreg": "paritytech/dapp-dappreg",
|
||||
"@parity/dapp-develop": "paritytech/dapp-develop",
|
||||
"@parity/dapp-githubhint": "paritytech/dapp-githubhint",
|
||||
"@parity/dapp-home": "paritytech/dapp-home",
|
||||
"@parity/dapp-localtx": "paritytech/dapp-localtx",
|
||||
"@parity/dapp-playground": "paritytech/dapp-playground",
|
||||
"@parity/dapp-registry": "paritytech/dapp-registry",
|
||||
"@parity/dapp-settings": "paritytech/dapp-settings",
|
||||
"@parity/dapp-signaturereg": "paritytech/dapp-signaturereg",
|
||||
"@parity/dapp-signer": "paritytech/dapp-signer",
|
||||
"@parity/dapp-status": "paritytech/dapp-status",
|
||||
"@parity/dapp-tokendeploy": "paritytech/dapp-tokendeploy",
|
||||
"@parity/dapp-tokenreg": "paritytech/dapp-tokenreg",
|
||||
"@parity/dapp-vaults": "paritytech/dapp-vaults",
|
||||
"@parity/dapp-wallet": "paritytech/dapp-wallet",
|
||||
"@parity/dapp-web": "paritytech/dapp-web",
|
||||
"@parity/shared": "paritytech/js-shared",
|
||||
"@parity/ui": "paritytech/js-ui",
|
||||
"es6-error": "4.0.0",
|
||||
|
@ -19,7 +19,7 @@ import { observer } from 'mobx-react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import DappsStore from '../Dapps/dappsStore';
|
||||
import DappsStore from '@parity/shared/mobx/dappsStore';
|
||||
|
||||
import styles from './dapp.css';
|
||||
|
||||
|
@ -20,7 +20,7 @@ import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import { Button } from '@parity/ui';
|
||||
|
||||
import DappsStore from '../../Dapps/dappsStore';
|
||||
import DappsStore from '@parity/shared/mobx/dappsStore';
|
||||
|
||||
export default function Request ({ appId, className, approveRequest, denyRequest, queueId, request: { from, method } }) {
|
||||
const _onApprove = () => approveRequest(queueId, false);
|
||||
|
@ -20,7 +20,7 @@ import store from 'store';
|
||||
|
||||
import { sha3 } from '@parity/api/util/sha3';
|
||||
|
||||
import VisibleStore from '../Dapps/dappsStore';
|
||||
import VisibleStore from '@parity/shared/mobx/dappsStore';
|
||||
import filteredRequests from './filteredRequests';
|
||||
|
||||
const LS_PERMISSIONS = '_parity::dapps::methods';
|
||||
|
@ -1,204 +0,0 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import BigNumber from 'bignumber.js';
|
||||
import sinon from 'sinon';
|
||||
import localStore from 'store';
|
||||
|
||||
import Contracts from '@parity/shared/contracts';
|
||||
|
||||
import Store, { LS_KEY_DISPLAY } from './dappsStore';
|
||||
|
||||
const APPID_DAPPREG = '0x7bbc4f1a27628781b96213e781a1b8eec6982c1db8fac739af6e4c5a55862c03';
|
||||
const APPID_GHH = '0x058740ee9a5a3fb9f1cfa10752baec87e09cc45cd7027fd54708271aca300c75';
|
||||
const APPID_LOCALTX = '0xae74ad174b95cdbd01c88ac5b73a296d33e9088fc2a200e76bcedf3a94a7815d';
|
||||
const APPID_TOKENDEPLOY = '0xf9f2d620c2e08f83e45555247146c62185e4ab7cf82a4b9002a265a0d020348f';
|
||||
|
||||
let globalContractsGet;
|
||||
|
||||
function stubGlobals () {
|
||||
globalContractsGet = Contracts.get;
|
||||
|
||||
Contracts.get = () => {
|
||||
return {
|
||||
dappReg: {
|
||||
at: sinon.stub().resolves([[0, 1, 2, 3], 'appOwner']),
|
||||
count: sinon.stub().resolves(new BigNumber(1)),
|
||||
getContract: sinon.stub().resolves({}),
|
||||
getContent: sinon.stub().resolves([0, 1, 2, 3]),
|
||||
getImage: sinon.stub().resolves([0, 1, 2, 3]),
|
||||
getManifest: sinon.stub().resolves([0, 1, 2, 3])
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
function restoreGlobals () {
|
||||
Contracts.get = globalContractsGet;
|
||||
}
|
||||
|
||||
let api;
|
||||
let store;
|
||||
|
||||
function create () {
|
||||
api = {
|
||||
parity: {
|
||||
dappsList: () => Promise.resolve([])
|
||||
}
|
||||
};
|
||||
store = new Store(api);
|
||||
|
||||
return store;
|
||||
}
|
||||
|
||||
describe('Dapps/DappStore', () => {
|
||||
beforeEach(() => {
|
||||
stubGlobals();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
restoreGlobals();
|
||||
});
|
||||
|
||||
describe('@action', () => {
|
||||
const defaultViews = {
|
||||
[APPID_TOKENDEPLOY]: { visible: false },
|
||||
[APPID_DAPPREG]: { visible: true }
|
||||
};
|
||||
|
||||
describe('setDisplayApps', () => {
|
||||
beforeEach(() => {
|
||||
create();
|
||||
store.setDisplayApps(defaultViews);
|
||||
});
|
||||
|
||||
it('sets from empty start', () => {
|
||||
expect(store.displayApps).to.deep.equal(defaultViews);
|
||||
});
|
||||
|
||||
it('overrides single keys, keeping existing', () => {
|
||||
store.setDisplayApps({ [APPID_TOKENDEPLOY]: { visible: true } });
|
||||
|
||||
expect(store.displayApps).to.deep.equal(
|
||||
Object.assign({}, defaultViews, { [APPID_TOKENDEPLOY]: { visible: true } })
|
||||
);
|
||||
});
|
||||
|
||||
it('extends with new keys, keeping existing', () => {
|
||||
store.setDisplayApps({ 'test': { visible: true } });
|
||||
|
||||
expect(store.displayApps).to.deep.equal(
|
||||
Object.assign({}, defaultViews, { 'test': { visible: true } })
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('hideApp/showApp', () => {
|
||||
beforeEach(() => {
|
||||
localStore.set(LS_KEY_DISPLAY, defaultViews);
|
||||
|
||||
create().readDisplayApps();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
localStore.set(LS_KEY_DISPLAY, {});
|
||||
});
|
||||
|
||||
it('disables visibility', () => {
|
||||
store.hideApp(APPID_DAPPREG);
|
||||
|
||||
expect(store.displayApps[APPID_DAPPREG].visible).to.be.false;
|
||||
expect(localStore.get(LS_KEY_DISPLAY)).to.deep.equal(
|
||||
Object.assign({}, defaultViews, { [APPID_DAPPREG]: { visible: false } })
|
||||
);
|
||||
});
|
||||
|
||||
it('enables visibility', () => {
|
||||
store.showApp(APPID_TOKENDEPLOY);
|
||||
|
||||
expect(store.displayApps[APPID_TOKENDEPLOY].visible).to.be.true;
|
||||
expect(localStore.get(LS_KEY_DISPLAY)).to.deep.equal(
|
||||
Object.assign({}, defaultViews, { [APPID_TOKENDEPLOY]: { visible: true } })
|
||||
);
|
||||
});
|
||||
|
||||
it('keeps visibility state', () => {
|
||||
store.hideApp(APPID_TOKENDEPLOY);
|
||||
store.showApp(APPID_DAPPREG);
|
||||
|
||||
expect(store.displayApps[APPID_TOKENDEPLOY].visible).to.be.false;
|
||||
expect(store.displayApps[APPID_DAPPREG].visible).to.be.true;
|
||||
expect(localStore.get(LS_KEY_DISPLAY)).to.deep.equal(defaultViews);
|
||||
});
|
||||
});
|
||||
|
||||
describe('readDisplayApps/writeDisplayApps', () => {
|
||||
beforeEach(() => {
|
||||
localStore.set(LS_KEY_DISPLAY, defaultViews);
|
||||
|
||||
create().readDisplayApps();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
localStore.set(LS_KEY_DISPLAY, {});
|
||||
});
|
||||
|
||||
it('loads visibility from storage', () => {
|
||||
expect(store.displayApps).to.deep.equal(defaultViews);
|
||||
});
|
||||
|
||||
it('saves visibility to storage', () => {
|
||||
store.setDisplayApps({ [APPID_TOKENDEPLOY]: { visible: true } });
|
||||
store.writeDisplayApps();
|
||||
|
||||
expect(localStore.get(LS_KEY_DISPLAY)).to.deep.equal(
|
||||
Object.assign({}, defaultViews, { [APPID_TOKENDEPLOY]: { visible: true } })
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('saved views', () => {
|
||||
beforeEach(() => {
|
||||
localStore.set(LS_KEY_DISPLAY, {
|
||||
[APPID_TOKENDEPLOY]: { visible: false },
|
||||
[APPID_DAPPREG]: { visible: true }
|
||||
});
|
||||
|
||||
return create().loadAllApps();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
localStore.set(LS_KEY_DISPLAY, {});
|
||||
});
|
||||
|
||||
it('disables based on saved keys', () => {
|
||||
expect(store.displayApps[APPID_TOKENDEPLOY].visible).to.be.false;
|
||||
});
|
||||
|
||||
it('enables based on saved keys', () => {
|
||||
expect(store.displayApps[APPID_DAPPREG].visible).to.be.true;
|
||||
});
|
||||
|
||||
it('keeps non-sepcified disabled keys', () => {
|
||||
expect(store.displayApps[APPID_GHH].visible).to.be.false;
|
||||
});
|
||||
|
||||
it('keeps non-specified enabled keys', () => {
|
||||
expect(store.displayApps[APPID_LOCALTX].visible).to.be.true;
|
||||
});
|
||||
});
|
||||
});
|
@ -23,7 +23,7 @@ import PropTypes from 'prop-types';
|
||||
|
||||
import { Checkbox, DappCard, Page, SectionList } from '@parity/ui';
|
||||
|
||||
import DappsStore from './dappsStore';
|
||||
import DappsStore from '@parity/shared/mobx/dappsStore';
|
||||
|
||||
import styles from './dapps.css';
|
||||
|
||||
|
@ -1,306 +0,0 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import EventEmitter from 'eventemitter3';
|
||||
import { action, computed, observable, transaction } from 'mobx';
|
||||
import store from 'store';
|
||||
|
||||
import Contracts from '@parity/shared/contracts';
|
||||
import { fetchBuiltinApps, fetchLocalApps, fetchRegistryAppIds, fetchRegistryApp, subscribeToChanges } from '@parity/shared/util/dapps';
|
||||
|
||||
const LS_KEY_DISPLAY = 'displayApps';
|
||||
const LS_KEY_EXTERNAL_ACCEPT = 'acceptExternal';
|
||||
const BUILTIN_APPS_KEY = 'BUILTIN_APPS_KEY';
|
||||
|
||||
let instance = null;
|
||||
|
||||
export default class DappsStore extends EventEmitter {
|
||||
@observable apps = [];
|
||||
@observable displayApps = {};
|
||||
@observable modalOpen = false;
|
||||
@observable externalOverlayVisible = true;
|
||||
|
||||
_api = null;
|
||||
_subscriptions = {};
|
||||
_cachedApps = {};
|
||||
_manifests = {};
|
||||
_registryAppsIds = null;
|
||||
|
||||
constructor (api) {
|
||||
super();
|
||||
|
||||
this._api = api;
|
||||
|
||||
this.readDisplayApps();
|
||||
this.loadExternalOverlay();
|
||||
this.subscribeToChanges();
|
||||
}
|
||||
|
||||
static get (api) {
|
||||
if (!instance) {
|
||||
instance = new DappsStore(api);
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
@computed get allApps () {
|
||||
return this.apps;
|
||||
}
|
||||
|
||||
@computed get sortedBuiltin () {
|
||||
return this.apps.filter((app) => app.type === 'builtin');
|
||||
}
|
||||
|
||||
@computed get sortedLocal () {
|
||||
return this.apps.filter((app) => app.type === 'local');
|
||||
}
|
||||
|
||||
@computed get sortedNetwork () {
|
||||
return this.apps.filter((app) => app.type === 'network');
|
||||
}
|
||||
|
||||
@computed get visibleApps () {
|
||||
return this.apps.filter((app) => this.displayApps[app.id] && this.displayApps[app.id].visible);
|
||||
}
|
||||
|
||||
@computed get visibleBuiltin () {
|
||||
return this.visibleApps.filter((app) => !app.noselect && app.type === 'builtin');
|
||||
}
|
||||
|
||||
@computed get visibleLocal () {
|
||||
return this.visibleApps.filter((app) => app.type === 'local');
|
||||
}
|
||||
|
||||
@computed get visibleNetwork () {
|
||||
return this.visibleApps.filter((app) => app.type === 'network');
|
||||
}
|
||||
|
||||
@computed get visibleViews () {
|
||||
return this.visibleApps.filter((app) => !app.noselect && app.type === 'view');
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to find the app from the local (local or builtin)
|
||||
* apps, else fetch from the node
|
||||
*/
|
||||
loadApp (id) {
|
||||
const { dappReg } = Contracts.get(this._api);
|
||||
|
||||
return this
|
||||
.loadLocalApps()
|
||||
.then(() => {
|
||||
const app = this.apps.find((app) => app.id === id);
|
||||
|
||||
if (app) {
|
||||
return app;
|
||||
}
|
||||
|
||||
return this.fetchRegistryApp(dappReg, id, true);
|
||||
})
|
||||
.then((app) => {
|
||||
this.emit('loaded', app);
|
||||
return app;
|
||||
});
|
||||
}
|
||||
|
||||
loadLocalApps () {
|
||||
return Promise
|
||||
.all([
|
||||
this.fetchBuiltinApps().then((apps) => this.addApps(apps)),
|
||||
this.fetchLocalApps().then((apps) => this.addApps(apps))
|
||||
]);
|
||||
}
|
||||
|
||||
loadAllApps () {
|
||||
const { dappReg } = Contracts.get(this._api);
|
||||
|
||||
return Promise
|
||||
.all([
|
||||
this.loadLocalApps(),
|
||||
this.fetchRegistryApps(dappReg).then((apps) => this.addApps(apps))
|
||||
])
|
||||
.then(this.writeDisplayApps);
|
||||
}
|
||||
|
||||
subscribeToChanges () {
|
||||
const { dappReg } = Contracts.get(this._api);
|
||||
|
||||
// Unsubscribe from previous subscriptions, if any
|
||||
if (this._subscriptions.block) {
|
||||
this._api.unsubscribe(this._subscriptions.block);
|
||||
}
|
||||
|
||||
if (this._subscriptions.filter) {
|
||||
this._api.eth.uninstallFilter(this._subscriptions.filter);
|
||||
}
|
||||
|
||||
// Subscribe to dapps reg changes
|
||||
subscribeToChanges(this._api, dappReg, (appIds) => {
|
||||
const updates = appIds.map((appId) => {
|
||||
return this.fetchRegistryApp(dappReg, appId, true);
|
||||
});
|
||||
|
||||
Promise
|
||||
.all(updates)
|
||||
.then((apps) => {
|
||||
this.addApps(apps);
|
||||
});
|
||||
}).then((subscriptions) => {
|
||||
this._subscriptions = subscriptions;
|
||||
});
|
||||
}
|
||||
|
||||
fetchBuiltinApps (force = false) {
|
||||
if (!force && this._cachedApps[BUILTIN_APPS_KEY] !== undefined) {
|
||||
return Promise.resolve(this._cachedApps[BUILTIN_APPS_KEY]);
|
||||
}
|
||||
|
||||
this._cachedApps[BUILTIN_APPS_KEY] = fetchBuiltinApps(this._api)
|
||||
.then((apps) => {
|
||||
this._cachedApps[BUILTIN_APPS_KEY] = apps;
|
||||
return apps;
|
||||
});
|
||||
|
||||
return Promise.resolve(this._cachedApps[BUILTIN_APPS_KEY]);
|
||||
}
|
||||
|
||||
fetchLocalApps () {
|
||||
return fetchLocalApps(this._api);
|
||||
}
|
||||
|
||||
fetchRegistryAppIds (force = false) {
|
||||
if (!force && this._registryAppsIds) {
|
||||
return Promise.resolve(this._registryAppsIds);
|
||||
}
|
||||
|
||||
this._registryAppsIds = fetchRegistryAppIds(this._api)
|
||||
.then((appIds) => {
|
||||
this._registryAppsIds = appIds;
|
||||
return this._registryAppsIds;
|
||||
});
|
||||
|
||||
return Promise.resolve(this._registryAppsIds);
|
||||
}
|
||||
|
||||
fetchRegistryApp (dappReg, appId, force = false) {
|
||||
if (!force && this._cachedApps[appId] !== undefined) {
|
||||
return Promise.resolve(this._cachedApps[appId]);
|
||||
}
|
||||
|
||||
this._cachedApps[appId] = fetchRegistryApp(this._api, dappReg, appId)
|
||||
.then((dapp) => {
|
||||
this._cachedApps[appId] = dapp;
|
||||
return dapp;
|
||||
});
|
||||
|
||||
return Promise.resolve(this._cachedApps[appId]);
|
||||
}
|
||||
|
||||
fetchRegistryApps (dappReg) {
|
||||
return this
|
||||
.fetchRegistryAppIds()
|
||||
.then((appIds) => {
|
||||
const promises = appIds.map((appId) => {
|
||||
// Fetch the Dapp and display it ASAP
|
||||
return this
|
||||
.fetchRegistryApp(dappReg, appId)
|
||||
.then((app) => {
|
||||
if (app) {
|
||||
this.addApps([ app ]);
|
||||
}
|
||||
|
||||
return app;
|
||||
});
|
||||
});
|
||||
|
||||
return Promise.all(promises);
|
||||
});
|
||||
}
|
||||
|
||||
@action openModal = () => {
|
||||
this.modalOpen = true;
|
||||
}
|
||||
|
||||
@action closeModal = () => {
|
||||
this.modalOpen = false;
|
||||
}
|
||||
|
||||
@action closeExternalOverlay = () => {
|
||||
this.externalOverlayVisible = false;
|
||||
store.set(LS_KEY_EXTERNAL_ACCEPT, true);
|
||||
}
|
||||
|
||||
@action loadExternalOverlay () {
|
||||
this.externalOverlayVisible = !(store.get(LS_KEY_EXTERNAL_ACCEPT) || false);
|
||||
}
|
||||
|
||||
@action hideApp = (id) => {
|
||||
this.setDisplayApps({ [id]: { visible: false } });
|
||||
this.writeDisplayApps();
|
||||
}
|
||||
|
||||
@action showApp = (id) => {
|
||||
this.setDisplayApps({ [id]: { visible: true } });
|
||||
this.writeDisplayApps();
|
||||
}
|
||||
|
||||
@action readDisplayApps = () => {
|
||||
this.displayApps = store.get(LS_KEY_DISPLAY) || {};
|
||||
}
|
||||
|
||||
@action writeDisplayApps = () => {
|
||||
store.set(LS_KEY_DISPLAY, this.displayApps);
|
||||
}
|
||||
|
||||
@action setDisplayApps = (displayApps) => {
|
||||
this.displayApps = Object.assign({}, this.displayApps, displayApps);
|
||||
};
|
||||
|
||||
@action addApps = (_apps = []) => {
|
||||
transaction(() => {
|
||||
const apps = _apps.filter((app) => app);
|
||||
|
||||
// Get new apps IDs if available
|
||||
const newAppsIds = apps
|
||||
.map((app) => app.id)
|
||||
.filter((id) => id);
|
||||
|
||||
this.apps = this.apps
|
||||
.filter((app) => !app.id || !newAppsIds.includes(app.id))
|
||||
.concat(apps || [])
|
||||
.sort((a, b) => a.name.localeCompare(b.name));
|
||||
|
||||
const visibility = {};
|
||||
|
||||
apps.forEach((app) => {
|
||||
if (!this.displayApps[app.id]) {
|
||||
visibility[app.id] = { visible: app.visible };
|
||||
}
|
||||
});
|
||||
|
||||
this.setDisplayApps(visibility);
|
||||
});
|
||||
}
|
||||
|
||||
getAppById = (id) => {
|
||||
return this.apps.find((app) => app.id === id);
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
LS_KEY_DISPLAY
|
||||
};
|
@ -21,7 +21,7 @@ import { FormattedMessage } from 'react-intl';
|
||||
import { Button } from '@parity/ui';
|
||||
import { CloseIcon, CheckIcon } from '@parity/ui/Icons';
|
||||
|
||||
import Store from './store';
|
||||
import Store from '@parity/shared/mobx/extensionStore';
|
||||
import styles from './extension.css';
|
||||
|
||||
@observer
|
||||
|
@ -1,116 +0,0 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/* global chrome */
|
||||
|
||||
import { action, computed, observable } from 'mobx';
|
||||
|
||||
import store from 'store';
|
||||
import browser from 'useragent.js/lib/browser';
|
||||
|
||||
import { DOMAIN } from '@parity/shared/util/constants';
|
||||
|
||||
const A_DAY = 24 * 60 * 60 * 1000;
|
||||
const NEXT_DISPLAY = '_parity::extensionWarning::nextDisplay';
|
||||
|
||||
// 'https://chrome.google.com/webstore/detail/parity-ethereum-integrati/himekenlppkgeaoeddcliojfddemadig';
|
||||
const EXTENSION_PAGE = 'https://chrome.google.com/webstore/detail/himekenlppkgeaoeddcliojfddemadig';
|
||||
|
||||
let instance;
|
||||
|
||||
export default class Store {
|
||||
@observable hasExtension = false;
|
||||
@observable isInstalling = false;
|
||||
@observable nextDisplay = 0;
|
||||
@observable shouldInstall = false;
|
||||
|
||||
constructor () {
|
||||
this.nextDisplay = store.get(NEXT_DISPLAY) || 0;
|
||||
this.testInstall();
|
||||
}
|
||||
|
||||
@computed get showWarning () {
|
||||
return !this.isInstalling && this.shouldInstall && (Date.now() > this.nextDisplay);
|
||||
}
|
||||
|
||||
@action setExtensionActive = () => {
|
||||
this.hasExtension = true;
|
||||
}
|
||||
|
||||
@action setInstalling = (isInstalling) => {
|
||||
this.isInstalling = isInstalling;
|
||||
}
|
||||
|
||||
@action snoozeWarning = (sleep = A_DAY) => {
|
||||
this.nextDisplay = Date.now() + sleep;
|
||||
store.set(NEXT_DISPLAY, this.nextDisplay);
|
||||
}
|
||||
|
||||
@action testInstall = () => {
|
||||
this.shouldInstall = this.readStatus();
|
||||
}
|
||||
|
||||
readStatus = () => {
|
||||
const hasExtension = Symbol.for('parity.extension') in window;
|
||||
const ua = browser.analyze(navigator.userAgent || '');
|
||||
|
||||
if (hasExtension) {
|
||||
this.setExtensionActive();
|
||||
return false;
|
||||
}
|
||||
|
||||
return (ua || {}).name.toLowerCase() === 'chrome';
|
||||
}
|
||||
|
||||
installExtension = () => {
|
||||
this.setInstalling(true);
|
||||
|
||||
if (window.location.hostname.toString().endsWith(DOMAIN)) {
|
||||
return this.inlineInstall()
|
||||
.catch((error) => {
|
||||
console.warn('Unable to perform direct install', error);
|
||||
window.open(EXTENSION_PAGE, '_blank');
|
||||
});
|
||||
}
|
||||
|
||||
window.open(EXTENSION_PAGE, '_blank');
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
|
||||
inlineInstall = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const link = document.createElement('link');
|
||||
|
||||
link.setAttribute('rel', 'chrome-webstore-item');
|
||||
link.setAttribute('href', EXTENSION_PAGE);
|
||||
document.querySelector('head').appendChild(link);
|
||||
|
||||
if (chrome && chrome.webstore && chrome.webstore.install) {
|
||||
chrome.webstore.install(EXTENSION_PAGE, resolve, reject);
|
||||
} else {
|
||||
reject(new Error('Direct installation failed.'));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static get () {
|
||||
if (!instance) {
|
||||
instance = new Store();
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
}
|
@ -29,7 +29,7 @@ import { CancelIcon, FingerprintIcon } from '@parity/ui/Icons';
|
||||
|
||||
import imagesEthcoreBlock from '@parity/shared/assets/images/parity-logo-white-no-text.svg';
|
||||
|
||||
import DappsStore from '../Dapps/dappsStore';
|
||||
import DappsStore from '@parity/shared/mobx/dappsStore';
|
||||
import Signer from '../Signer/Embedded';
|
||||
|
||||
import AccountStore from './accountStore';
|
||||
|
@ -23,10 +23,9 @@ import { bindActionCreators } from 'redux';
|
||||
|
||||
import * as RequestsActions from '@parity/shared/redux/providers/signerActions';
|
||||
import { Container } from '@parity/ui';
|
||||
import RequestPending from '@parity/ui/Signer/RequestPending';
|
||||
|
||||
import Store from '../store';
|
||||
|
||||
import RequestPending from '../components/RequestPending';
|
||||
import Store from '@parity/shared/mobx/signerStore';
|
||||
|
||||
import styles from './embedded.css';
|
||||
|
||||
|
@ -1,20 +0,0 @@
|
||||
/* Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
/* This file is part of Parity.
|
||||
/*
|
||||
/* Parity is free software: you can redistribute it and/or modify
|
||||
/* it under the terms of the GNU General Public License as published by
|
||||
/* the Free Software Foundation, either version 3 of the License, or
|
||||
/* (at your option) any later version.
|
||||
/*
|
||||
/* Parity is distributed in the hope that it will be useful,
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
/* GNU General Public License for more details.
|
||||
/*
|
||||
/* You should have received a copy of the GNU General Public License
|
||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
.container {
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
}
|
@ -1,106 +0,0 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
import { Link } from 'react-router';
|
||||
|
||||
import styles from './accountLink.css';
|
||||
|
||||
class AccountLink extends Component {
|
||||
static propTypes = {
|
||||
accountAddresses: PropTypes.array.isRequired,
|
||||
address: PropTypes.string.isRequired,
|
||||
className: PropTypes.string,
|
||||
children: PropTypes.node,
|
||||
externalLink: PropTypes.string.isRequired
|
||||
}
|
||||
|
||||
state = {
|
||||
link: null
|
||||
};
|
||||
|
||||
componentWillMount () {
|
||||
const { address, externalLink } = this.props;
|
||||
|
||||
this.updateLink(address, externalLink);
|
||||
}
|
||||
|
||||
componentWillReceiveProps (nextProps) {
|
||||
const { address, externalLink } = nextProps;
|
||||
|
||||
this.updateLink(address, externalLink);
|
||||
}
|
||||
|
||||
render () {
|
||||
const { children, address, className, externalLink } = this.props;
|
||||
|
||||
if (externalLink) {
|
||||
return (
|
||||
<a
|
||||
href={ this.state.link }
|
||||
target='_blank'
|
||||
className={ `${styles.container} ${className}` }
|
||||
>
|
||||
{ children || address }
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Link
|
||||
className={ `${styles.container} ${className}` }
|
||||
to={ this.state.link }
|
||||
>
|
||||
{ children || address }
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
updateLink (address, externalLink) {
|
||||
const { accountAddresses } = this.props;
|
||||
const isAccount = accountAddresses.includes(address);
|
||||
|
||||
let link = isAccount
|
||||
? `/accounts/${address}`
|
||||
: `/addresses/${address}`;
|
||||
|
||||
if (externalLink) {
|
||||
const path = externalLink.replace(/\/+$/, '');
|
||||
|
||||
link = `${path}/#${link}`;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
link
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function mapStateToProps (initState) {
|
||||
const { accounts } = initState.personal;
|
||||
const accountAddresses = Object.keys(accounts);
|
||||
|
||||
return () => {
|
||||
return { accountAddresses };
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
null
|
||||
)(AccountLink);
|
@ -1,17 +0,0 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './accountLink';
|
@ -1,50 +0,0 @@
|
||||
/* Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
/* This file is part of Parity.
|
||||
/*
|
||||
/* Parity is free software: you can redistribute it and/or modify
|
||||
/* it under the terms of the GNU General Public License as published by
|
||||
/* the Free Software Foundation, either version 3 of the License, or
|
||||
/* (at your option) any later version.
|
||||
/*
|
||||
/* Parity is distributed in the hope that it will be useful,
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
/* GNU General Public License for more details.
|
||||
/*
|
||||
/* You should have received a copy of the GNU General Public License
|
||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
.acc {
|
||||
text-align: center;
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.acc > * {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.address {
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
.acc img {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
vertical-align: middle;
|
||||
margin-right: 3px;
|
||||
}
|
||||
|
||||
.name {
|
||||
white-space: nowrap;
|
||||
display: block;
|
||||
vertical-align: middle;
|
||||
text-transform: uppercase;
|
||||
|
||||
span {
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
@ -1,130 +0,0 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { IdentityIcon, IdentityName } from '@parity/ui';
|
||||
|
||||
import AccountLink from './AccountLink';
|
||||
|
||||
import styles from './account.css';
|
||||
|
||||
export default class Account extends Component {
|
||||
static propTypes = {
|
||||
address: PropTypes.string.isRequired,
|
||||
className: PropTypes.string,
|
||||
disabled: PropTypes.bool,
|
||||
externalLink: PropTypes.string.isRequired,
|
||||
netVersion: PropTypes.string.isRequired,
|
||||
balance: PropTypes.object // eth BigNumber, not required since it mght take time to fetch
|
||||
};
|
||||
|
||||
state = {
|
||||
balanceDisplay: '?'
|
||||
};
|
||||
|
||||
componentWillMount () {
|
||||
this.updateBalanceDisplay(this.props.balance);
|
||||
}
|
||||
|
||||
componentWillReceiveProps (nextProps) {
|
||||
if (nextProps.balance === this.props.balance) {
|
||||
return;
|
||||
}
|
||||
this.updateBalanceDisplay(nextProps.balance);
|
||||
}
|
||||
|
||||
updateBalanceDisplay (balance) {
|
||||
this.setState({
|
||||
balanceDisplay: balance ? balance.div(1e18).toFormat(3) : '?'
|
||||
});
|
||||
}
|
||||
|
||||
render () {
|
||||
const { address, className, disabled, externalLink, netVersion } = this.props;
|
||||
|
||||
return (
|
||||
<div className={ `${styles.acc} ${className}` }>
|
||||
<AccountLink
|
||||
address={ address }
|
||||
externalLink={ externalLink }
|
||||
netVersion={ netVersion }
|
||||
>
|
||||
<IdentityIcon
|
||||
center
|
||||
disabled={ disabled }
|
||||
address={ address }
|
||||
/>
|
||||
</AccountLink>
|
||||
{ this.renderName() }
|
||||
{ this.renderBalance() }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderBalance () {
|
||||
const { balanceDisplay } = this.state;
|
||||
|
||||
return (
|
||||
<span> <strong>{ balanceDisplay }</strong> <small>ETH</small></span>
|
||||
);
|
||||
}
|
||||
|
||||
renderName () {
|
||||
const { address, externalLink, netVersion } = this.props;
|
||||
const name = <IdentityName address={ address } empty />;
|
||||
|
||||
if (!name) {
|
||||
return (
|
||||
<AccountLink
|
||||
address={ address }
|
||||
externalLink={ externalLink }
|
||||
netVersion={ netVersion }
|
||||
>
|
||||
[{ this.shortAddress(address) }]
|
||||
</AccountLink>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<AccountLink
|
||||
address={ address }
|
||||
externalLink={ externalLink }
|
||||
netVersion={ netVersion }
|
||||
>
|
||||
<span>
|
||||
<span className={ styles.name }>{ name }</span>
|
||||
<span className={ styles.address }>[{ this.tinyAddress(address) }]</span>
|
||||
</span>
|
||||
</AccountLink>
|
||||
);
|
||||
}
|
||||
|
||||
tinyAddress () {
|
||||
const { address } = this.props;
|
||||
const len = address.length;
|
||||
|
||||
return address.slice(2, 4) + '..' + address.slice(len - 2);
|
||||
}
|
||||
|
||||
shortAddress () {
|
||||
const { address } = this.props;
|
||||
const len = address.length;
|
||||
|
||||
return address.slice(2, 8) + '..' + address.slice(len - 7);
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './account';
|
@ -1,185 +0,0 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { observer } from 'mobx-react';
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import Account from '../Account';
|
||||
import TransactionPendingForm from '../TransactionPendingForm';
|
||||
import RequestOrigin from '../RequestOrigin';
|
||||
|
||||
import styles from '../SignRequest/signRequest.css';
|
||||
|
||||
@observer
|
||||
class DecryptRequest extends Component {
|
||||
static contextTypes = {
|
||||
api: PropTypes.object
|
||||
};
|
||||
|
||||
static propTypes = {
|
||||
accounts: PropTypes.object.isRequired,
|
||||
address: PropTypes.string.isRequired,
|
||||
data: PropTypes.string.isRequired,
|
||||
id: PropTypes.object.isRequired,
|
||||
isFinished: PropTypes.bool.isRequired,
|
||||
netVersion: PropTypes.string.isRequired,
|
||||
signerStore: PropTypes.object.isRequired,
|
||||
|
||||
className: PropTypes.string,
|
||||
focus: PropTypes.bool,
|
||||
isSending: PropTypes.bool,
|
||||
onConfirm: PropTypes.func,
|
||||
onReject: PropTypes.func,
|
||||
origin: PropTypes.any,
|
||||
status: PropTypes.string
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
focus: false,
|
||||
origin: {
|
||||
type: 'unknown',
|
||||
details: ''
|
||||
}
|
||||
};
|
||||
|
||||
componentWillMount () {
|
||||
const { address, signerStore } = this.props;
|
||||
|
||||
signerStore.fetchBalance(address);
|
||||
}
|
||||
|
||||
render () {
|
||||
const { className } = this.props;
|
||||
|
||||
return (
|
||||
<div className={ `${styles.container} ${className}` }>
|
||||
{ this.renderDetails() }
|
||||
{ this.renderActions() }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderDetails () {
|
||||
const { api } = this.context;
|
||||
const { address, data, netVersion, origin, signerStore } = this.props;
|
||||
const { balances, externalLink } = signerStore;
|
||||
|
||||
const balance = balances[address];
|
||||
|
||||
if (!balance) {
|
||||
return <div />;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={ styles.signDetails }>
|
||||
<div className={ styles.address }>
|
||||
<Account
|
||||
address={ address }
|
||||
balance={ balance }
|
||||
className={ styles.account }
|
||||
externalLink={ externalLink }
|
||||
netVersion={ netVersion }
|
||||
/>
|
||||
<RequestOrigin origin={ origin } />
|
||||
</div>
|
||||
<div className={ styles.info } title={ api.util.sha3(data) }>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id='signer.decryptRequest.request'
|
||||
defaultMessage='A request to decrypt data using your account:'
|
||||
/>
|
||||
</p>
|
||||
|
||||
<div className={ styles.signData }>
|
||||
<p>{ data }</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderActions () {
|
||||
const { accounts, address, focus, isFinished, status, data } = this.props;
|
||||
const account = accounts[address];
|
||||
|
||||
if (isFinished) {
|
||||
if (status === 'confirmed') {
|
||||
return (
|
||||
<div className={ styles.actions }>
|
||||
<span className={ styles.isConfirmed }>
|
||||
<FormattedMessage
|
||||
id='signer.decryptRequest.state.confirmed'
|
||||
defaultMessage='Confirmed'
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={ styles.actions }>
|
||||
<span className={ styles.isRejected }>
|
||||
<FormattedMessage
|
||||
id='signer.decryptRequest.state.rejected'
|
||||
defaultMessage='Rejected'
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<TransactionPendingForm
|
||||
account={ account }
|
||||
address={ address }
|
||||
focus={ focus }
|
||||
isSending={ this.props.isSending }
|
||||
netVersion={ this.props.netVersion }
|
||||
onConfirm={ this.onConfirm }
|
||||
onReject={ this.onReject }
|
||||
className={ styles.actions }
|
||||
dataToSign={ { decrypt: data } }
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
onConfirm = (data) => {
|
||||
const { id } = this.props;
|
||||
const { password, decrypted, wallet } = data;
|
||||
|
||||
this.props.onConfirm({ id, password, decrypted, wallet });
|
||||
}
|
||||
|
||||
onReject = () => {
|
||||
this.props.onReject(this.props.id);
|
||||
}
|
||||
}
|
||||
|
||||
function mapStateToProps (state) {
|
||||
const { accounts } = state.personal;
|
||||
|
||||
return {
|
||||
accounts
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
null
|
||||
)(DecryptRequest);
|
@ -1,17 +0,0 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './decryptRequest';
|
@ -1,17 +0,0 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './requestOrigin';
|
@ -1,43 +0,0 @@
|
||||
/* Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
/* This file is part of Parity.
|
||||
/*
|
||||
/* Parity is free software: you can redistribute it and/or modify
|
||||
/* it under the terms of the GNU General Public License as published by
|
||||
/* the Free Software Foundation, either version 3 of the License, or
|
||||
/* (at your option) any later version.
|
||||
/*
|
||||
/* Parity is distributed in the hope that it will be useful,
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
/* GNU General Public License for more details.
|
||||
/*
|
||||
/* You should have received a copy of the GNU General Public License
|
||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
.container {
|
||||
text-align: left;
|
||||
margin: 3em .5em;
|
||||
opacity: 0.6;
|
||||
font-size: 0.8em;
|
||||
|
||||
.unknown {
|
||||
color: #e44;
|
||||
}
|
||||
|
||||
.url {
|
||||
max-width: 100%;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.hash {
|
||||
margin-left: .5em;
|
||||
}
|
||||
|
||||
.hash, .url {
|
||||
margin-bottom: -.2em;
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
@ -1,171 +0,0 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import IdentityIcon from '@parity/ui/IdentityIcon';
|
||||
|
||||
import styles from './requestOrigin.css';
|
||||
|
||||
export default class RequestOrigin extends Component {
|
||||
static contextTypes = {
|
||||
api: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
static propTypes = {
|
||||
origin: PropTypes.shape({
|
||||
type: PropTypes.oneOf(['unknown', 'dapp', 'rpc', 'ipc', 'signer']),
|
||||
details: PropTypes.oneOfType([
|
||||
PropTypes.string,
|
||||
PropTypes.shape({
|
||||
session: PropTypes.string.isRequired
|
||||
})
|
||||
]).isRequired
|
||||
}).isRequired
|
||||
};
|
||||
|
||||
render () {
|
||||
const { origin } = this.props;
|
||||
|
||||
return (
|
||||
<div className={ styles.container }>
|
||||
Requested { this.renderOrigin(origin) }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderOrigin (origin) {
|
||||
if (origin.type === 'unknown') {
|
||||
return (
|
||||
<span className={ styles.unknown }>
|
||||
<FormattedMessage
|
||||
id='signer.requestOrigin.unknownInterface'
|
||||
defaultMessage='via unknown interface'
|
||||
/>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
if (origin.type === 'dapp') {
|
||||
return (
|
||||
<span>
|
||||
<FormattedMessage
|
||||
id='signer.requestOrigin.dapp'
|
||||
defaultMessage='by a dapp at {url}'
|
||||
values={ {
|
||||
url: (
|
||||
<span className={ styles.url }>
|
||||
{
|
||||
origin.details || (
|
||||
<FormattedMessage
|
||||
id='signer.requestOrigin.unknownUrl'
|
||||
defaultMessage='unknown URL'
|
||||
/>
|
||||
)
|
||||
}
|
||||
</span>
|
||||
)
|
||||
} }
|
||||
/>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
if (origin.type === 'rpc') {
|
||||
return (
|
||||
<span>
|
||||
<FormattedMessage
|
||||
id='signer.requestOrigin.rpc'
|
||||
defaultMessage='via RPC {url}'
|
||||
values={ {
|
||||
url: (
|
||||
<span className={ styles.url }>
|
||||
({
|
||||
origin.details || (
|
||||
<FormattedMessage
|
||||
id='signer.requestOrigin.unknownRpc'
|
||||
defaultMessage='unidentified'
|
||||
/>
|
||||
)
|
||||
})
|
||||
</span>
|
||||
)
|
||||
} }
|
||||
/>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
if (origin.type === 'ipc') {
|
||||
return (
|
||||
<span>
|
||||
<FormattedMessage
|
||||
id='signer.requestOrigin.ipc'
|
||||
defaultMessage='via IPC session'
|
||||
/>
|
||||
<span
|
||||
className={ styles.hash }
|
||||
title={ origin.details }
|
||||
>
|
||||
<IdentityIcon
|
||||
address={ origin.details }
|
||||
tiny
|
||||
/>
|
||||
</span>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
if (origin.type === 'signer') {
|
||||
const session = origin.details && origin.details.session || origin.details;
|
||||
|
||||
return this.renderSigner(session);
|
||||
}
|
||||
}
|
||||
|
||||
renderSigner (session) {
|
||||
if (session.substr(2) === this.context.api.transport.sessionHash) {
|
||||
return (
|
||||
<span title={ session }>
|
||||
<FormattedMessage
|
||||
id='signer.requestOrigin.signerCurrent'
|
||||
defaultMessage='via current tab'
|
||||
/>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<span>
|
||||
<FormattedMessage
|
||||
id='signer.requestOrigin.signerUI'
|
||||
defaultMessage='via UI session'
|
||||
/>
|
||||
<span
|
||||
className={ styles.hash }
|
||||
title={ `UI Session id: ${session}` }
|
||||
>
|
||||
<IdentityIcon
|
||||
address={ session }
|
||||
tiny
|
||||
/>
|
||||
</span>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
}
|
@ -1,72 +0,0 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { shallow } from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import RequestOrigin from './';
|
||||
|
||||
const context = {
|
||||
context: {
|
||||
api: {
|
||||
transport: {
|
||||
sessionHash: '1234'
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
describe('views/Signer/components/RequestOrigin', () => {
|
||||
it('renders unknown', () => {
|
||||
expect(shallow(
|
||||
<RequestOrigin origin={ { type: 'unknown', details: '' } } />,
|
||||
context
|
||||
).find('FormattedMessage').props().id).to.equal('signer.requestOrigin.unknownInterface');
|
||||
});
|
||||
|
||||
it('renders dapps', () => {
|
||||
expect(shallow(
|
||||
<RequestOrigin origin={ { type: 'dapp', details: 'http://parity.io' } } />,
|
||||
context
|
||||
).find('FormattedMessage').props().id).to.equal('signer.requestOrigin.dapp');
|
||||
});
|
||||
|
||||
it('renders rpc', () => {
|
||||
expect(shallow(
|
||||
<RequestOrigin origin={ { type: 'rpc', details: '' } } />,
|
||||
context
|
||||
).find('FormattedMessage').props().id).to.equal('signer.requestOrigin.rpc');
|
||||
});
|
||||
|
||||
it('renders ipc', () => {
|
||||
expect(shallow(
|
||||
<RequestOrigin origin={ { type: 'ipc', details: '0x1234' } } />,
|
||||
context
|
||||
).find('FormattedMessage').props().id).to.equal('signer.requestOrigin.ipc');
|
||||
});
|
||||
|
||||
it('renders signer', () => {
|
||||
expect(shallow(
|
||||
<RequestOrigin origin={ { type: 'signer', details: '0x12345' } } />,
|
||||
context
|
||||
).find('FormattedMessage').props().id).to.equal('signer.requestOrigin.signerUI');
|
||||
|
||||
expect(shallow(
|
||||
<RequestOrigin origin={ { type: 'signer', details: '0x1234' } } />,
|
||||
context
|
||||
).find('FormattedMessage').props().id).to.equal('signer.requestOrigin.signerCurrent');
|
||||
});
|
||||
});
|
@ -1,17 +0,0 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './requestPending';
|
@ -1,126 +0,0 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import DecryptRequest from '../DecryptRequest';
|
||||
import SignRequest from '../SignRequest';
|
||||
import TransactionPending from '../TransactionPending';
|
||||
|
||||
export default class RequestPending extends Component {
|
||||
static propTypes = {
|
||||
className: PropTypes.string,
|
||||
date: PropTypes.instanceOf(Date).isRequired,
|
||||
focus: PropTypes.bool,
|
||||
gasLimit: PropTypes.object.isRequired,
|
||||
id: PropTypes.object.isRequired,
|
||||
isSending: PropTypes.bool.isRequired,
|
||||
netVersion: PropTypes.string.isRequired,
|
||||
onConfirm: PropTypes.func.isRequired,
|
||||
onReject: PropTypes.func.isRequired,
|
||||
origin: PropTypes.object.isRequired,
|
||||
payload: PropTypes.oneOfType([
|
||||
PropTypes.shape({ decrypt: PropTypes.object.isRequired }),
|
||||
PropTypes.shape({ sendTransaction: PropTypes.object.isRequired }),
|
||||
PropTypes.shape({ sign: PropTypes.object.isRequired }),
|
||||
PropTypes.shape({ signTransaction: PropTypes.object.isRequired })
|
||||
]).isRequired,
|
||||
signerStore: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
focus: false,
|
||||
isSending: false
|
||||
};
|
||||
|
||||
render () {
|
||||
const { className, date, focus, gasLimit, id, isSending, netVersion, onReject, payload, signerStore, origin } = this.props;
|
||||
|
||||
if (payload.sign) {
|
||||
const { sign } = payload;
|
||||
|
||||
return (
|
||||
<SignRequest
|
||||
address={ sign.address }
|
||||
className={ className }
|
||||
focus={ focus }
|
||||
data={ sign.data }
|
||||
id={ id }
|
||||
isFinished={ false }
|
||||
isSending={ isSending }
|
||||
netVersion={ netVersion }
|
||||
onConfirm={ this.onConfirm }
|
||||
onReject={ onReject }
|
||||
origin={ origin }
|
||||
signerStore={ signerStore }
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (payload.decrypt) {
|
||||
const { decrypt } = payload;
|
||||
|
||||
return (
|
||||
<DecryptRequest
|
||||
address={ decrypt.address }
|
||||
className={ className }
|
||||
focus={ focus }
|
||||
data={ decrypt.msg }
|
||||
id={ id }
|
||||
isFinished={ false }
|
||||
isSending={ isSending }
|
||||
netVersion={ netVersion }
|
||||
onConfirm={ this.onConfirm }
|
||||
onReject={ onReject }
|
||||
origin={ origin }
|
||||
signerStore={ signerStore }
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
const transaction = payload.sendTransaction || payload.signTransaction;
|
||||
|
||||
if (transaction) {
|
||||
return (
|
||||
<TransactionPending
|
||||
className={ className }
|
||||
date={ date }
|
||||
focus={ focus }
|
||||
gasLimit={ gasLimit }
|
||||
id={ id }
|
||||
isSending={ isSending }
|
||||
netVersion={ netVersion }
|
||||
onConfirm={ this.onConfirm }
|
||||
onReject={ onReject }
|
||||
origin={ origin }
|
||||
signerStore={ signerStore }
|
||||
transaction={ transaction }
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
console.error('RequestPending: Unknown payload', payload);
|
||||
return null;
|
||||
}
|
||||
|
||||
onConfirm = (data) => {
|
||||
const { onConfirm, payload } = this.props;
|
||||
|
||||
data.payload = payload;
|
||||
onConfirm(data);
|
||||
};
|
||||
}
|
@ -1,132 +0,0 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import BigNumber from 'bignumber.js';
|
||||
import { shallow } from 'enzyme';
|
||||
import React from 'react';
|
||||
import sinon from 'sinon';
|
||||
|
||||
import RequestPending from './';
|
||||
|
||||
const ADDRESS = '0x1234567890123456789012345678901234567890';
|
||||
const TRANSACTION = {
|
||||
from: ADDRESS,
|
||||
gas: new BigNumber(21000),
|
||||
gasPrice: new BigNumber(20000000),
|
||||
value: new BigNumber(1)
|
||||
};
|
||||
const PAYLOAD_SENDTX = {
|
||||
sendTransaction: TRANSACTION
|
||||
};
|
||||
const PAYLOAD_SIGN = {
|
||||
sign: {
|
||||
address: ADDRESS,
|
||||
data: 'testing'
|
||||
}
|
||||
};
|
||||
const PAYLOAD_SIGNTX = {
|
||||
signTransaction: TRANSACTION
|
||||
};
|
||||
const PAYLOAD_DECRYPT = {
|
||||
decrypt: {
|
||||
address: ADDRESS,
|
||||
msg: 'testing'
|
||||
}
|
||||
};
|
||||
|
||||
let component;
|
||||
let onConfirm;
|
||||
let onReject;
|
||||
|
||||
function render (payload) {
|
||||
onConfirm = sinon.stub();
|
||||
onReject = sinon.stub();
|
||||
|
||||
component = shallow(
|
||||
<RequestPending
|
||||
date={ new Date() }
|
||||
gasLimit={ new BigNumber(100000) }
|
||||
id={ new BigNumber(123) }
|
||||
isSending={ false }
|
||||
netVersion='42'
|
||||
onConfirm={ onConfirm }
|
||||
onReject={ onReject }
|
||||
origin={ {} }
|
||||
payload={ payload }
|
||||
store={ {} }
|
||||
/>
|
||||
);
|
||||
|
||||
return component;
|
||||
}
|
||||
|
||||
describe('views/Signer/RequestPending', () => {
|
||||
describe('sendTransaction', () => {
|
||||
beforeEach(() => {
|
||||
render(PAYLOAD_SENDTX);
|
||||
});
|
||||
|
||||
it('renders defaults', () => {
|
||||
expect(component).to.be.ok;
|
||||
});
|
||||
|
||||
it('renders TransactionPending component', () => {
|
||||
expect(component.find('Connect(TransactionPending)')).to.have.length(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('sign', () => {
|
||||
beforeEach(() => {
|
||||
render(PAYLOAD_SIGN);
|
||||
});
|
||||
|
||||
it('renders defaults', () => {
|
||||
expect(component).to.be.ok;
|
||||
});
|
||||
|
||||
it('renders SignRequest component', () => {
|
||||
expect(component.find('Connect(SignRequest)')).to.have.length(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('signTransaction', () => {
|
||||
beforeEach(() => {
|
||||
render(PAYLOAD_SIGNTX);
|
||||
});
|
||||
|
||||
it('renders defaults', () => {
|
||||
expect(component).to.be.ok;
|
||||
});
|
||||
|
||||
it('renders TransactionPending component', () => {
|
||||
expect(component.find('Connect(TransactionPending)')).to.have.length(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('decrypt', () => {
|
||||
beforeEach(() => {
|
||||
render(PAYLOAD_DECRYPT);
|
||||
});
|
||||
|
||||
it('renders defaults', () => {
|
||||
expect(component).to.be.ok;
|
||||
});
|
||||
|
||||
it('renders DecryptRequest component', () => {
|
||||
expect(component.find('Connect(DecryptRequest)')).to.have.length(1);
|
||||
});
|
||||
});
|
||||
});
|
@ -1,17 +0,0 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './signRequest';
|
@ -1,91 +0,0 @@
|
||||
/* Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
/* This file is part of Parity.
|
||||
/*
|
||||
/* Parity is free software: you can redistribute it and/or modify
|
||||
/* it under the terms of the GNU General Public License as published by
|
||||
/* the Free Software Foundation, either version 3 of the License, or
|
||||
/* (at your option) any later version.
|
||||
/*
|
||||
/* Parity is distributed in the hope that it will be useful,
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
/* GNU General Public License for more details.
|
||||
/*
|
||||
/* You should have received a copy of the GNU General Public License
|
||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
@import '../../_layout.css';
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
padding: 1.5em 1em 1.5em 0;
|
||||
}
|
||||
|
||||
.actions, .signDetails {
|
||||
vertical-align: middle;
|
||||
min-height: $pendingHeight;
|
||||
}
|
||||
|
||||
.signData {
|
||||
border: 0.25em solid red;
|
||||
margin-left: 2em;
|
||||
padding: 0.5em;
|
||||
overflow: auto;
|
||||
max-height: 6em;
|
||||
max-width: calc(100% - 2em);
|
||||
}
|
||||
|
||||
.signData > p {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.signDetails {
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.account img {
|
||||
display: inline-block;
|
||||
height: 50px;
|
||||
margin: 5px;
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
.address, .info {
|
||||
box-sizing: border-box;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.address {
|
||||
width: 40%;
|
||||
}
|
||||
|
||||
.info {
|
||||
color: #E53935;
|
||||
width: 60%;
|
||||
}
|
||||
|
||||
.info p:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
/* TODO [todr] copy&paste from transactions */
|
||||
.isConfirmed {
|
||||
color: green;
|
||||
}
|
||||
|
||||
.isRejected {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.txHash {
|
||||
display: block;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.actions {
|
||||
display: inline-block;
|
||||
min-height: $finishedHeight;
|
||||
}
|
@ -1,232 +0,0 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { observer } from 'mobx-react';
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import HardwareStore from '@parity/shared/mobx/hardwareStore';
|
||||
|
||||
import Account from '../Account';
|
||||
import TransactionPendingForm from '../TransactionPendingForm';
|
||||
import RequestOrigin from '../RequestOrigin';
|
||||
|
||||
import styles from './signRequest.css';
|
||||
|
||||
function isAscii (data) {
|
||||
for (var i = 2; i < data.length; i += 2) {
|
||||
let n = parseInt(data.substr(i, 2), 16);
|
||||
|
||||
if (n < 32 || n >= 128) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@observer
|
||||
class SignRequest extends Component {
|
||||
static contextTypes = {
|
||||
api: PropTypes.object
|
||||
};
|
||||
|
||||
static propTypes = {
|
||||
accounts: PropTypes.object.isRequired,
|
||||
address: PropTypes.string.isRequired,
|
||||
data: PropTypes.string.isRequired,
|
||||
id: PropTypes.object.isRequired,
|
||||
isFinished: PropTypes.bool.isRequired,
|
||||
netVersion: PropTypes.string.isRequired,
|
||||
signerStore: PropTypes.object.isRequired,
|
||||
|
||||
className: PropTypes.string,
|
||||
focus: PropTypes.bool,
|
||||
isSending: PropTypes.bool,
|
||||
onConfirm: PropTypes.func,
|
||||
onReject: PropTypes.func,
|
||||
origin: PropTypes.any,
|
||||
status: PropTypes.string
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
focus: false,
|
||||
origin: {
|
||||
type: 'unknown',
|
||||
details: ''
|
||||
}
|
||||
};
|
||||
|
||||
hardwareStore = HardwareStore.get(this.context.api);
|
||||
|
||||
componentWillMount () {
|
||||
const { address, signerStore } = this.props;
|
||||
|
||||
signerStore.fetchBalance(address);
|
||||
}
|
||||
|
||||
render () {
|
||||
const { className } = this.props;
|
||||
|
||||
return (
|
||||
<div className={ `${styles.container} ${className}` }>
|
||||
{ this.renderDetails() }
|
||||
{ this.renderActions() }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderAsciiDetails (ascii) {
|
||||
return (
|
||||
<div className={ styles.signData }>
|
||||
<p>{ascii}</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderBinaryDetails (data) {
|
||||
return (
|
||||
<div className={ styles.signData }>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id='signer.signRequest.unknownBinary'
|
||||
defaultMessage='(Unknown binary data)'
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderDetails () {
|
||||
const { api } = this.context;
|
||||
const { address, data, netVersion, origin, signerStore } = this.props;
|
||||
const { balances, externalLink } = signerStore;
|
||||
|
||||
const balance = balances[address];
|
||||
|
||||
if (!balance) {
|
||||
return <div />;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={ styles.signDetails }>
|
||||
<div className={ styles.address }>
|
||||
<Account
|
||||
address={ address }
|
||||
balance={ balance }
|
||||
className={ styles.account }
|
||||
externalLink={ externalLink }
|
||||
netVersion={ netVersion }
|
||||
/>
|
||||
<RequestOrigin origin={ origin } />
|
||||
</div>
|
||||
<div className={ styles.info } title={ api.util.sha3(data) }>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id='signer.signRequest.request'
|
||||
defaultMessage='A request to sign data using your account:'
|
||||
/>
|
||||
</p>
|
||||
{
|
||||
isAscii(data)
|
||||
? this.renderAsciiDetails(api.util.hexToAscii(data))
|
||||
: this.renderBinaryDetails(data)
|
||||
}
|
||||
<p>
|
||||
<strong>
|
||||
<FormattedMessage
|
||||
id='signer.signRequest.warning'
|
||||
defaultMessage='WARNING: This consequences of doing this may be grave. Confirm the request only if you are sure.'
|
||||
/>
|
||||
</strong>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderActions () {
|
||||
const { accounts, address, focus, isFinished, status, data } = this.props;
|
||||
const account = accounts[address] || {};
|
||||
const disabled = account.hardware && !this.hardwareStore.isConnected(address);
|
||||
|
||||
if (isFinished) {
|
||||
if (status === 'confirmed') {
|
||||
return (
|
||||
<div className={ styles.actions }>
|
||||
<span className={ styles.isConfirmed }>
|
||||
<FormattedMessage
|
||||
id='signer.signRequest.state.confirmed'
|
||||
defaultMessage='Confirmed'
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={ styles.actions }>
|
||||
<span className={ styles.isRejected }>
|
||||
<FormattedMessage
|
||||
id='signer.signRequest.state.rejected'
|
||||
defaultMessage='Rejected'
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<TransactionPendingForm
|
||||
account={ account }
|
||||
address={ address }
|
||||
disabled={ disabled }
|
||||
focus={ focus }
|
||||
isSending={ this.props.isSending }
|
||||
netVersion={ this.props.netVersion }
|
||||
onConfirm={ this.onConfirm }
|
||||
onReject={ this.onReject }
|
||||
className={ styles.actions }
|
||||
dataToSign={ { data } }
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
onConfirm = (data) => {
|
||||
const { id } = this.props;
|
||||
const { password, dataSigned, wallet } = data;
|
||||
|
||||
this.props.onConfirm({ id, password, dataSigned, wallet });
|
||||
}
|
||||
|
||||
onReject = () => {
|
||||
this.props.onReject(this.props.id);
|
||||
}
|
||||
}
|
||||
|
||||
function mapStateToProps (state) {
|
||||
const { accounts } = state.personal;
|
||||
|
||||
return {
|
||||
accounts
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
null
|
||||
)(SignRequest);
|
@ -1,72 +0,0 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { shallow } from 'enzyme';
|
||||
import React from 'react';
|
||||
import sinon from 'sinon';
|
||||
|
||||
import SignRequest from './';
|
||||
|
||||
let component;
|
||||
let reduxStore;
|
||||
let signerStore;
|
||||
|
||||
function createSignerStore () {
|
||||
return {
|
||||
balances: {},
|
||||
fetchBalance: sinon.stub()
|
||||
};
|
||||
}
|
||||
|
||||
function createReduxStore () {
|
||||
return {
|
||||
dispatch: sinon.stub(),
|
||||
subscribe: sinon.stub(),
|
||||
getState: () => {
|
||||
return {
|
||||
personal: {
|
||||
accounts: {}
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function render () {
|
||||
reduxStore = createReduxStore();
|
||||
signerStore = createSignerStore();
|
||||
|
||||
component = shallow(
|
||||
<SignRequest signerStore={ signerStore } />,
|
||||
{
|
||||
context: {
|
||||
store: reduxStore
|
||||
}
|
||||
}
|
||||
).find('SignRequest').shallow();
|
||||
|
||||
return component;
|
||||
}
|
||||
|
||||
describe('views/Signer/components/SignRequest', () => {
|
||||
beforeEach(() => {
|
||||
render();
|
||||
});
|
||||
|
||||
it('renders', () => {
|
||||
expect(component).to.be.ok;
|
||||
});
|
||||
});
|
@ -1,17 +0,0 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './transactionMainDetails';
|
@ -1,80 +0,0 @@
|
||||
/* Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
/* This file is part of Parity.
|
||||
/*
|
||||
/* Parity is free software: you can redistribute it and/or modify
|
||||
/* it under the terms of the GNU General Public License as published by
|
||||
/* the Free Software Foundation, either version 3 of the License, or
|
||||
/* (at your option) any later version.
|
||||
/*
|
||||
/* Parity is distributed in the hope that it will be useful,
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
/* GNU General Public License for more details.
|
||||
/*
|
||||
/* You should have received a copy of the GNU General Public License
|
||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
@import '../../_layout.css';
|
||||
|
||||
.account {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.contractIcon {
|
||||
background: #eee;
|
||||
width: 50px !important;
|
||||
height: 50px !important;
|
||||
box-sizing: border-box;
|
||||
border-radius: 50%;
|
||||
padding: 13px;
|
||||
}
|
||||
|
||||
.editButtonRow {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.from {
|
||||
display: inline-block;
|
||||
width: 40%;
|
||||
vertical-align: top;
|
||||
|
||||
.account {
|
||||
img {
|
||||
display: inline-block;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
span {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.method {
|
||||
display: inline-block;
|
||||
width: 60%;
|
||||
vertical-align: top;
|
||||
line-height: 1em;
|
||||
}
|
||||
|
||||
.tx {
|
||||
position: relative;
|
||||
text-align: center;
|
||||
margin: 0 -75px;
|
||||
width: 150px;
|
||||
top: -20px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.total {
|
||||
font-size: 0.6em;
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
.transaction {
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
}
|
@ -1,202 +0,0 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import ReactTooltip from 'react-tooltip';
|
||||
|
||||
import { Button, MethodDecoding } from '@parity/ui';
|
||||
import { GasIcon } from '@parity/ui/Icons';
|
||||
|
||||
import * as tUtil from '../util/transaction';
|
||||
import Account from '../Account';
|
||||
import RequestOrigin from '../RequestOrigin';
|
||||
|
||||
import styles from './transactionMainDetails.css';
|
||||
|
||||
export default class TransactionMainDetails extends Component {
|
||||
static propTypes = {
|
||||
children: PropTypes.node,
|
||||
disabled: PropTypes.bool,
|
||||
externalLink: PropTypes.string.isRequired,
|
||||
from: PropTypes.string.isRequired,
|
||||
fromBalance: PropTypes.object,
|
||||
gasStore: PropTypes.object,
|
||||
id: PropTypes.object.isRequired,
|
||||
netVersion: PropTypes.string.isRequired,
|
||||
origin: PropTypes.any,
|
||||
totalValue: PropTypes.object.isRequired,
|
||||
transaction: PropTypes.object.isRequired,
|
||||
value: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
origin: {
|
||||
type: 'unknown',
|
||||
details: ''
|
||||
}
|
||||
};
|
||||
|
||||
componentWillMount () {
|
||||
const { totalValue, value } = this.props;
|
||||
|
||||
this.updateDisplayValues(value, totalValue);
|
||||
}
|
||||
|
||||
componentWillReceiveProps (nextProps) {
|
||||
const { totalValue, value } = nextProps;
|
||||
|
||||
this.updateDisplayValues(value, totalValue);
|
||||
}
|
||||
|
||||
render () {
|
||||
const { children, disabled, externalLink, from, fromBalance, gasStore, netVersion, transaction, origin } = this.props;
|
||||
|
||||
return (
|
||||
<div className={ styles.transaction }>
|
||||
<div className={ styles.from }>
|
||||
<div className={ styles.account }>
|
||||
<Account
|
||||
address={ from }
|
||||
balance={ fromBalance }
|
||||
disabled={ disabled }
|
||||
externalLink={ externalLink }
|
||||
netVersion={ netVersion }
|
||||
/>
|
||||
</div>
|
||||
<RequestOrigin origin={ origin } />
|
||||
</div>
|
||||
<div className={ styles.method }>
|
||||
<MethodDecoding
|
||||
address={ from }
|
||||
historic={ false }
|
||||
transaction={
|
||||
gasStore
|
||||
? gasStore.overrideTransaction(transaction)
|
||||
: transaction
|
||||
}
|
||||
/>
|
||||
{ this.renderEditTx() }
|
||||
</div>
|
||||
{ children }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderEditTx () {
|
||||
const { gasStore } = this.props;
|
||||
|
||||
if (!gasStore) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={ styles.editButtonRow }>
|
||||
<Button
|
||||
icon={ <GasIcon /> }
|
||||
label={
|
||||
<FormattedMessage
|
||||
id='signer.mainDetails.editTx'
|
||||
defaultMessage='Edit conditions/gas/gasPrice'
|
||||
/>
|
||||
}
|
||||
onClick={ this.toggleGasEditor }
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderTotalValue () {
|
||||
const { id } = this.props;
|
||||
const { feeEth, totalValueDisplay, totalValueDisplayWei } = this.state;
|
||||
const labelId = `totalValue${id}`;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div
|
||||
className={ styles.total }
|
||||
data-effect='solid'
|
||||
data-for={ labelId }
|
||||
data-place='bottom'
|
||||
data-tip
|
||||
>
|
||||
{ totalValueDisplay } <small>ETH</small>
|
||||
</div>
|
||||
<ReactTooltip id={ labelId }>
|
||||
<FormattedMessage
|
||||
id='signer.mainDetails.tooltips.total1'
|
||||
defaultMessage='The value of the transaction including the mining fee is {total} {type}.'
|
||||
values={ {
|
||||
total: <strong>{ totalValueDisplayWei }</strong>,
|
||||
type: <small>WEI</small>
|
||||
} }
|
||||
/>
|
||||
<br />
|
||||
<FormattedMessage
|
||||
id='signer.mainDetails.tooltips.total2'
|
||||
defaultMessage='(This includes a mining fee of {fee} {token})'
|
||||
values={ {
|
||||
fee: <strong>{ feeEth }</strong>,
|
||||
token: <small>ETH</small>
|
||||
} }
|
||||
/>
|
||||
</ReactTooltip>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderValue () {
|
||||
const { id } = this.props;
|
||||
const { valueDisplay, valueDisplayWei } = this.state;
|
||||
const labelId = `value${id}`;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div
|
||||
data-effect='solid'
|
||||
data-for={ labelId }
|
||||
data-tip
|
||||
>
|
||||
<strong>{ valueDisplay } </strong>
|
||||
<small>ETH</small>
|
||||
</div>
|
||||
<ReactTooltip id={ labelId }>
|
||||
<FormattedMessage
|
||||
id='signer.mainDetails.tooltips.value1'
|
||||
defaultMessage='The value of the transaction.'
|
||||
/>
|
||||
<br />
|
||||
<strong>{ valueDisplayWei }</strong> <small>WEI</small>
|
||||
</ReactTooltip>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
updateDisplayValues (value, totalValue) {
|
||||
this.setState({
|
||||
feeEth: tUtil.calcFeeInEth(totalValue, value),
|
||||
totalValueDisplay: tUtil.getTotalValueDisplay(totalValue),
|
||||
totalValueDisplayWei: tUtil.getTotalValueDisplayWei(totalValue),
|
||||
valueDisplay: tUtil.getValueDisplay(value),
|
||||
valueDisplayWei: tUtil.getValueDisplayWei(value)
|
||||
});
|
||||
}
|
||||
|
||||
toggleGasEditor = () => {
|
||||
this.props.gasStore.setEditing(true);
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './transactionPending';
|
@ -1,27 +0,0 @@
|
||||
/* Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
/* This file is part of Parity.
|
||||
/*
|
||||
/* Parity is free software: you can redistribute it and/or modify
|
||||
/* it under the terms of the GNU General Public License as published by
|
||||
/* the Free Software Foundation, either version 3 of the License, or
|
||||
/* (at your option) any later version.
|
||||
/*
|
||||
/* Parity is distributed in the hope that it will be useful,
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
/* GNU General Public License for more details.
|
||||
/*
|
||||
/* You should have received a copy of the GNU General Public License
|
||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
@import '../../_layout.css';
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
padding: 1.5em 1em 1.5em 0;
|
||||
|
||||
& > * {
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
@ -1,204 +0,0 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { observer } from 'mobx-react';
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import HardwareStore from '@parity/shared/mobx/hardwareStore';
|
||||
import { Button, GasPriceEditor } from '@parity/ui';
|
||||
|
||||
import TransactionMainDetails from '../TransactionMainDetails';
|
||||
import TransactionPendingForm from '../TransactionPendingForm';
|
||||
|
||||
import styles from './transactionPending.css';
|
||||
|
||||
import * as tUtil from '../util/transaction';
|
||||
|
||||
@observer
|
||||
class TransactionPending extends Component {
|
||||
static contextTypes = {
|
||||
api: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
static propTypes = {
|
||||
accounts: PropTypes.object.isRequired,
|
||||
className: PropTypes.string,
|
||||
date: PropTypes.instanceOf(Date).isRequired,
|
||||
focus: PropTypes.bool,
|
||||
gasLimit: PropTypes.object,
|
||||
id: PropTypes.object.isRequired,
|
||||
isSending: PropTypes.bool.isRequired,
|
||||
netVersion: PropTypes.string.isRequired,
|
||||
nonce: PropTypes.number,
|
||||
onConfirm: PropTypes.func.isRequired,
|
||||
onReject: PropTypes.func.isRequired,
|
||||
origin: PropTypes.any,
|
||||
signerStore: PropTypes.object.isRequired,
|
||||
transaction: PropTypes.shape({
|
||||
condition: PropTypes.object,
|
||||
data: PropTypes.string,
|
||||
from: PropTypes.string.isRequired,
|
||||
gas: PropTypes.object.isRequired,
|
||||
gasPrice: PropTypes.object.isRequired,
|
||||
to: PropTypes.string,
|
||||
value: PropTypes.object.isRequired
|
||||
}).isRequired
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
focus: false,
|
||||
origin: {
|
||||
type: 'unknown',
|
||||
details: ''
|
||||
}
|
||||
};
|
||||
|
||||
gasStore = new GasPriceEditor.Store(this.context.api, {
|
||||
condition: this.props.transaction.condition,
|
||||
gas: this.props.transaction.gas.toFixed(),
|
||||
gasLimit: this.props.gasLimit,
|
||||
gasPrice: this.props.transaction.gasPrice.toFixed()
|
||||
});
|
||||
|
||||
hardwareStore = HardwareStore.get(this.context.api);
|
||||
|
||||
componentWillMount () {
|
||||
const { signerStore, transaction } = this.props;
|
||||
const { from, gas, gasPrice, to, value } = transaction;
|
||||
|
||||
const fee = tUtil.getFee(gas, gasPrice); // BigNumber object
|
||||
const gasPriceEthmDisplay = tUtil.getEthmFromWeiDisplay(gasPrice);
|
||||
const gasToDisplay = tUtil.getGasDisplay(gas);
|
||||
const totalValue = tUtil.getTotalValue(fee, value);
|
||||
|
||||
this.setState({ gasPriceEthmDisplay, totalValue, gasToDisplay });
|
||||
this.gasStore.setEthValue(value);
|
||||
signerStore.fetchBalances([from, to]);
|
||||
}
|
||||
|
||||
render () {
|
||||
return this.gasStore.isEditing
|
||||
? this.renderTxEditor()
|
||||
: this.renderTransaction();
|
||||
}
|
||||
|
||||
renderTransaction () {
|
||||
const transaction = this.gasStore.overrideTransaction(this.props.transaction);
|
||||
|
||||
const { accounts, className, focus, id, isSending, netVersion, origin, signerStore } = this.props;
|
||||
const { totalValue } = this.state;
|
||||
const { balances, externalLink } = signerStore;
|
||||
const { from, value } = transaction;
|
||||
const fromBalance = balances[from];
|
||||
const account = accounts[from] || {};
|
||||
const disabled = account.hardware && !this.hardwareStore.isConnected(from);
|
||||
|
||||
return (
|
||||
<div className={ `${styles.container} ${className}` }>
|
||||
<TransactionMainDetails
|
||||
className={ styles.transactionDetails }
|
||||
disabled={ disabled }
|
||||
externalLink={ externalLink }
|
||||
from={ from }
|
||||
fromBalance={ fromBalance }
|
||||
gasStore={ this.gasStore }
|
||||
id={ id }
|
||||
netVersion={ netVersion }
|
||||
origin={ origin }
|
||||
totalValue={ totalValue }
|
||||
transaction={ transaction }
|
||||
value={ value }
|
||||
/>
|
||||
<TransactionPendingForm
|
||||
account={ account }
|
||||
address={ from }
|
||||
disabled={ disabled }
|
||||
focus={ focus }
|
||||
isSending={ isSending }
|
||||
netVersion={ netVersion }
|
||||
onConfirm={ this.onConfirm }
|
||||
onReject={ this.onReject }
|
||||
dataToSign={ { transaction } }
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderTxEditor () {
|
||||
const { className } = this.props;
|
||||
|
||||
return (
|
||||
<div className={ `${styles.container} ${className}` }>
|
||||
<GasPriceEditor store={ this.gasStore }>
|
||||
<Button
|
||||
label={
|
||||
<FormattedMessage
|
||||
id='signer.txPending.buttons.viewToggle'
|
||||
defaultMessage='view transaction'
|
||||
/>
|
||||
}
|
||||
onClick={ this.toggleGasEditor }
|
||||
/>
|
||||
</GasPriceEditor>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
onConfirm = (data) => {
|
||||
const { id, transaction } = this.props;
|
||||
const { password, txSigned, wallet } = data;
|
||||
const { condition, gas, gasPrice } = this.gasStore.overrideTransaction(transaction);
|
||||
|
||||
const options = {
|
||||
gas,
|
||||
gasPrice,
|
||||
id,
|
||||
password,
|
||||
txSigned,
|
||||
wallet
|
||||
};
|
||||
|
||||
if (condition && (condition.block || condition.time)) {
|
||||
options.condition = condition;
|
||||
}
|
||||
|
||||
this.props.onConfirm(options);
|
||||
}
|
||||
|
||||
onReject = () => {
|
||||
this.props.onReject(this.props.id);
|
||||
}
|
||||
|
||||
toggleGasEditor = () => {
|
||||
this.gasStore.setEditing(false);
|
||||
}
|
||||
}
|
||||
|
||||
function mapStateToProps (state) {
|
||||
const { accounts } = state.personal;
|
||||
|
||||
return {
|
||||
accounts
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
null
|
||||
)(TransactionPending);
|
@ -1,17 +0,0 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './transactionPendingForm';
|
@ -1,44 +0,0 @@
|
||||
/* Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
/* This file is part of Parity.
|
||||
/*
|
||||
/* Parity is free software: you can redistribute it and/or modify
|
||||
/* it under the terms of the GNU General Public License as published by
|
||||
/* the Free Software Foundation, either version 3 of the License, or
|
||||
/* (at your option) any later version.
|
||||
/*
|
||||
/* Parity is distributed in the hope that it will be useful,
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
/* GNU General Public License for more details.
|
||||
/*
|
||||
/* You should have received a copy of the GNU General Public License
|
||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
@import '../../_layout.css';
|
||||
|
||||
.container {
|
||||
box-sizing: border-box;
|
||||
padding: 1em 0 0 2em;
|
||||
flex: 0 0 $statusWidth;
|
||||
}
|
||||
|
||||
.rejectToggle {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
color: #00e;
|
||||
opacity: .7;
|
||||
transition: opacity .5s;
|
||||
}
|
||||
|
||||
.rejectToggle:hover {
|
||||
opacity: 1;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.rejectToggle svg {
|
||||
position: relative;
|
||||
width: 18px !important;
|
||||
height: 18px !important;
|
||||
top: 3px;
|
||||
}
|
@ -1,137 +0,0 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import { PrevIcon } from '@parity/ui/Icons';
|
||||
|
||||
import TransactionPendingFormConfirm from '../TransactionPendingFormConfirm';
|
||||
import TransactionPendingFormReject from '../TransactionPendingFormReject';
|
||||
|
||||
import styles from './transactionPendingForm.css';
|
||||
|
||||
export default class TransactionPendingForm extends Component {
|
||||
static propTypes = {
|
||||
account: PropTypes.object,
|
||||
address: PropTypes.string.isRequired,
|
||||
className: PropTypes.string,
|
||||
disabled: PropTypes.bool,
|
||||
focus: PropTypes.bool,
|
||||
netVersion: PropTypes.string.isRequired,
|
||||
isSending: PropTypes.bool.isRequired,
|
||||
onConfirm: PropTypes.func.isRequired,
|
||||
onReject: PropTypes.func.isRequired,
|
||||
dataToSign: PropTypes.oneOfType([
|
||||
PropTypes.shape({
|
||||
transaction: PropTypes.object.isRequired
|
||||
}),
|
||||
PropTypes.shape({
|
||||
data: PropTypes.string.isRequired
|
||||
}),
|
||||
PropTypes.shape({
|
||||
decrypt: PropTypes.string.isRequired
|
||||
})
|
||||
]).isRequired
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
account: {},
|
||||
focus: false
|
||||
};
|
||||
|
||||
state = {
|
||||
isRejectOpen: false
|
||||
};
|
||||
|
||||
render () {
|
||||
const { className } = this.props;
|
||||
|
||||
return (
|
||||
<div className={ `${styles.container} ${className}` }>
|
||||
{ this.renderForm() }
|
||||
{ this.renderRejectToggle() }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderForm () {
|
||||
const { account, address, disabled, focus, isSending, netVersion, onConfirm, onReject, dataToSign } = this.props;
|
||||
|
||||
if (this.state.isRejectOpen) {
|
||||
return (
|
||||
<TransactionPendingFormReject onReject={ onReject } />
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<TransactionPendingFormConfirm
|
||||
address={ address }
|
||||
account={ account }
|
||||
disabled={ disabled }
|
||||
focus={ focus }
|
||||
netVersion={ netVersion }
|
||||
isSending={ isSending }
|
||||
onConfirm={ onConfirm }
|
||||
dataToSign={ dataToSign }
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
renderRejectToggle () {
|
||||
const { isRejectOpen } = this.state;
|
||||
let html;
|
||||
|
||||
if (!isRejectOpen) {
|
||||
html = (
|
||||
<span>
|
||||
<FormattedMessage
|
||||
id='signer.txPendingForm.reject'
|
||||
defaultMessage='reject request'
|
||||
/>
|
||||
</span>
|
||||
);
|
||||
} else {
|
||||
html = (
|
||||
<span>
|
||||
<PrevIcon />
|
||||
<FormattedMessage
|
||||
id='signer.txPendingForm.changedMind'
|
||||
defaultMessage="I've changed my mind"
|
||||
/>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<a
|
||||
className={ styles.rejectToggle }
|
||||
onClick={ this.onToggleReject }
|
||||
>
|
||||
{ html }
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
||||
onToggleReject = () => {
|
||||
const { isRejectOpen } = this.state;
|
||||
|
||||
this.setState({
|
||||
isRejectOpen: !isRejectOpen
|
||||
});
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './transactionPendingFormConfirm';
|
@ -1,48 +0,0 @@
|
||||
/* Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
/* This file is part of Parity.
|
||||
/*
|
||||
/* Parity is free software: you can redistribute it and/or modify
|
||||
/* it under the terms of the GNU General Public License as published by
|
||||
/* the Free Software Foundation, either version 3 of the License, or
|
||||
/* (at your option) any later version.
|
||||
/*
|
||||
/* Parity is distributed in the hope that it will be useful,
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
/* GNU General Public License for more details.
|
||||
/*
|
||||
/* You should have received a copy of the GNU General Public License
|
||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
.confirmForm {
|
||||
margin-top: -2em;
|
||||
}
|
||||
|
||||
.confirmButton {
|
||||
display: block !important;
|
||||
margin-bottom: 10px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.signerIcon {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.passwordHint {
|
||||
font-size: 0.75em;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
margin-bottom: 0.75em;
|
||||
}
|
||||
|
||||
.passwordHint span {
|
||||
opacity: 0.85;
|
||||
}
|
||||
|
||||
.fileInput input {
|
||||
top: 22px;
|
||||
}
|
||||
|
||||
.qr {
|
||||
margin-bottom: 0.5em;
|
||||
text-align: center;
|
||||
}
|
@ -1,580 +0,0 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import keycode from 'keycode';
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import ReactTooltip from 'react-tooltip';
|
||||
|
||||
import { generateTxQr, generateDecryptQr, generateDataQr } from '@parity/shared/util/qrscan';
|
||||
import { Button, Form, Input, IdentityIcon, QrCode, QrScan } from '@parity/ui';
|
||||
|
||||
import styles from './transactionPendingFormConfirm.css';
|
||||
|
||||
const QR_VISIBLE = 1;
|
||||
const QR_SCAN = 2;
|
||||
const QR_COMPLETED = 3;
|
||||
|
||||
export default class TransactionPendingFormConfirm extends Component {
|
||||
static contextTypes = {
|
||||
api: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
static propTypes = {
|
||||
account: PropTypes.object,
|
||||
address: PropTypes.string.isRequired,
|
||||
disabled: PropTypes.bool,
|
||||
focus: PropTypes.bool,
|
||||
netVersion: PropTypes.string.isRequired,
|
||||
isSending: PropTypes.bool.isRequired,
|
||||
onConfirm: PropTypes.func.isRequired,
|
||||
dataToSign: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
account: {},
|
||||
focus: false
|
||||
};
|
||||
|
||||
id = Math.random(); // for tooltip
|
||||
|
||||
state = {
|
||||
password: '',
|
||||
qrState: QR_VISIBLE,
|
||||
qr: {},
|
||||
wallet: null,
|
||||
walletError: null
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
this.focus();
|
||||
}
|
||||
|
||||
componentWillMount () {
|
||||
this.readNonce();
|
||||
this.subscribeNonce();
|
||||
}
|
||||
|
||||
componentWillUnmount () {
|
||||
this.unsubscribeNonce();
|
||||
}
|
||||
|
||||
componentWillReceiveProps (nextProps) {
|
||||
if (!this.props.focus && nextProps.focus) {
|
||||
this.focus(nextProps);
|
||||
}
|
||||
}
|
||||
|
||||
focus (props = this.props) {
|
||||
if (props.focus) {
|
||||
const textNode = ReactDOM.findDOMNode(this.refs.input);
|
||||
|
||||
if (!textNode) {
|
||||
return;
|
||||
}
|
||||
|
||||
const inputNode = textNode.querySelector('input');
|
||||
|
||||
inputNode && inputNode.focus();
|
||||
}
|
||||
}
|
||||
|
||||
getPasswordHint () {
|
||||
const { account } = this.props;
|
||||
const accountHint = account.meta && account.meta.passwordHint;
|
||||
|
||||
if (accountHint) {
|
||||
return accountHint;
|
||||
}
|
||||
|
||||
const { wallet } = this.state;
|
||||
const walletHint = wallet && wallet.meta && wallet.meta.passwordHint;
|
||||
|
||||
return walletHint || null;
|
||||
}
|
||||
|
||||
// TODO: Now that we have 3 types, it would make sense splitting each into their own
|
||||
// sub-module and having the consistent bits combined (e.g. i18n, layouts)
|
||||
render () {
|
||||
const { account, address, disabled, isSending } = this.props;
|
||||
const { wallet, walletError } = this.state;
|
||||
const isAccount = account.external || account.hardware || account.uuid;
|
||||
const isWalletOk = isAccount || (walletError === null && wallet !== null);
|
||||
const confirmText = this.renderConfirmButton();
|
||||
const confirmButton = confirmText
|
||||
? (
|
||||
<div
|
||||
data-effect='solid'
|
||||
data-for={ `transactionConfirmForm${this.id}` }
|
||||
data-place='bottom'
|
||||
data-tip
|
||||
>
|
||||
<Button
|
||||
className={ styles.confirmButton }
|
||||
disabled={ disabled || isSending || !isWalletOk }
|
||||
fullWidth
|
||||
icon={
|
||||
<IdentityIcon
|
||||
address={ address }
|
||||
button
|
||||
className={ styles.signerIcon }
|
||||
/>
|
||||
}
|
||||
label={ confirmText }
|
||||
onClick={ this.onConfirm }
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
: null;
|
||||
|
||||
return (
|
||||
<div className={ styles.confirmForm }>
|
||||
<Form>
|
||||
{ this.renderKeyInput() }
|
||||
{ this.renderQrCode() }
|
||||
{ this.renderQrScanner() }
|
||||
{ this.renderPassword() }
|
||||
{ this.renderHint() }
|
||||
{ confirmButton }
|
||||
{ this.renderTooltip() }
|
||||
</Form>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderConfirmButton () {
|
||||
const { account, isSending } = this.props;
|
||||
const { qrState } = this.state;
|
||||
|
||||
if (account.external) {
|
||||
switch (qrState) {
|
||||
case QR_VISIBLE:
|
||||
return (
|
||||
<FormattedMessage
|
||||
id='signer.txPendingConfirm.buttons.scanSigned'
|
||||
defaultMessage='Scan Signed QR'
|
||||
/>
|
||||
);
|
||||
|
||||
case QR_SCAN:
|
||||
case QR_COMPLETED:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return isSending
|
||||
? (
|
||||
<FormattedMessage
|
||||
id='signer.txPendingConfirm.buttons.confirmBusy'
|
||||
defaultMessage='Confirming...'
|
||||
/>
|
||||
)
|
||||
: (
|
||||
<FormattedMessage
|
||||
id='signer.txPendingConfirm.buttons.confirmRequest'
|
||||
defaultMessage='Confirm Request'
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
renderPassword () {
|
||||
const { account } = this.props;
|
||||
const { password } = this.state;
|
||||
|
||||
if (account.hardware || account.external) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const isAccount = account.uuid;
|
||||
|
||||
return (
|
||||
<Input
|
||||
hint={
|
||||
isAccount
|
||||
? (
|
||||
<FormattedMessage
|
||||
id='signer.txPendingConfirm.password.unlock.hint'
|
||||
defaultMessage='unlock the account'
|
||||
/>
|
||||
)
|
||||
: (
|
||||
<FormattedMessage
|
||||
id='signer.txPendingConfirm.password.decrypt.hint'
|
||||
defaultMessage='decrypt the key'
|
||||
/>
|
||||
)
|
||||
}
|
||||
label={
|
||||
isAccount
|
||||
? (
|
||||
<FormattedMessage
|
||||
id='signer.txPendingConfirm.password.unlock.label'
|
||||
defaultMessage='Account Password'
|
||||
/>
|
||||
)
|
||||
: (
|
||||
<FormattedMessage
|
||||
id='signer.txPendingConfirm.password.decrypt.label'
|
||||
defaultMessage='Key Password'
|
||||
/>
|
||||
)
|
||||
}
|
||||
onChange={ this.onModifyPassword }
|
||||
onKeyDown={ this.onKeyDown }
|
||||
ref='input'
|
||||
type='password'
|
||||
value={ password }
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
renderHint () {
|
||||
const { account, disabled, isSending } = this.props;
|
||||
const { qrState } = this.state;
|
||||
|
||||
if (account.external) {
|
||||
switch (qrState) {
|
||||
case QR_VISIBLE:
|
||||
return (
|
||||
<div className={ styles.passwordHint }>
|
||||
<FormattedMessage
|
||||
id='signer.sending.external.scanTx'
|
||||
defaultMessage='Please scan the transaction QR on your external device'
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
case QR_SCAN:
|
||||
return (
|
||||
<div className={ styles.passwordHint }>
|
||||
<FormattedMessage
|
||||
id='signer.sending.external.scanSigned'
|
||||
defaultMessage='Scan the QR code of the signed transaction from your external device'
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
case QR_COMPLETED:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
if (account.hardware) {
|
||||
if (isSending) {
|
||||
return (
|
||||
<div className={ styles.passwordHint }>
|
||||
<FormattedMessage
|
||||
id='signer.sending.hardware.confirm'
|
||||
defaultMessage='Please confirm the transaction on your attached hardware device'
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
} else if (disabled) {
|
||||
return (
|
||||
<div className={ styles.passwordHint }>
|
||||
<FormattedMessage
|
||||
id='signer.sending.hardware.connect'
|
||||
defaultMessage='Please attach your hardware device before confirming the transaction'
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const passwordHint = this.getPasswordHint();
|
||||
|
||||
if (!passwordHint) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={ styles.passwordHint }>
|
||||
<FormattedMessage
|
||||
id='signer.txPendingConfirm.passwordHint'
|
||||
defaultMessage='(hint) {passwordHint}'
|
||||
values={ {
|
||||
passwordHint
|
||||
} }
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// TODO: Split into sub-scomponent
|
||||
renderQrCode () {
|
||||
const { account } = this.props;
|
||||
const { qrState, qr } = this.state;
|
||||
|
||||
if (!account.external || qrState !== QR_VISIBLE || !qr.value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<QrCode
|
||||
className={ styles.qr }
|
||||
value={ qr.value }
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// TODO: Split into sub-scomponent
|
||||
renderQrScanner () {
|
||||
const { account } = this.props;
|
||||
const { qrState } = this.state;
|
||||
|
||||
if (!account.external || qrState !== QR_SCAN) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<QrScan
|
||||
className={ styles.camera }
|
||||
onScan={ this.onScan }
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
renderKeyInput () {
|
||||
const { account } = this.props;
|
||||
const { walletError } = this.state;
|
||||
|
||||
if (account.uuid || account.wallet || account.hardware || account.external) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Input
|
||||
className={ styles.fileInput }
|
||||
error={ walletError }
|
||||
hint={
|
||||
<FormattedMessage
|
||||
id='signer.txPendingConfirm.selectKey.hint'
|
||||
defaultMessage='The keyfile to use for this account'
|
||||
/>
|
||||
}
|
||||
label={
|
||||
<FormattedMessage
|
||||
id='signer.txPendingConfirm.selectKey.label'
|
||||
defaultMessage='Select Local Key'
|
||||
/>
|
||||
}
|
||||
onChange={ this.onKeySelect }
|
||||
type='file'
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
renderTooltip () {
|
||||
const { account } = this.props;
|
||||
|
||||
if (this.state.password.length || account.hardware || account.external) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<ReactTooltip id={ `transactionConfirmForm${this.id}` }>
|
||||
<FormattedMessage
|
||||
id='signer.txPendingConfirm.tooltips.password'
|
||||
defaultMessage='Please provide a password for this account'
|
||||
/>
|
||||
</ReactTooltip>
|
||||
);
|
||||
}
|
||||
|
||||
onScan = (signature) => {
|
||||
const { chainId, rlp, tx, data, decrypt } = this.state.qr;
|
||||
|
||||
if (!signature) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (signature && signature.substr(0, 2) !== '0x') {
|
||||
signature = `0x${signature}`;
|
||||
}
|
||||
|
||||
this.setState({ qrState: QR_COMPLETED });
|
||||
|
||||
if (tx) {
|
||||
this.props.onConfirm({
|
||||
txSigned: {
|
||||
chainId,
|
||||
rlp,
|
||||
signature,
|
||||
tx
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (decrypt) {
|
||||
this.props.onConfirm({
|
||||
decrypted: {
|
||||
decrypt,
|
||||
msg: signature
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
this.props.onConfirm({
|
||||
dataSigned: {
|
||||
data,
|
||||
signature
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onKeySelect = (event) => {
|
||||
// Check that file have been selected
|
||||
if (event.target.files.length === 0) {
|
||||
return this.setState({
|
||||
wallet: null,
|
||||
walletError: null
|
||||
});
|
||||
}
|
||||
|
||||
const fileReader = new FileReader();
|
||||
|
||||
fileReader.onload = (e) => {
|
||||
try {
|
||||
const wallet = JSON.parse(e.target.result);
|
||||
|
||||
try {
|
||||
if (wallet && typeof wallet.meta === 'string') {
|
||||
wallet.meta = JSON.parse(wallet.meta);
|
||||
}
|
||||
} catch (e) {}
|
||||
|
||||
this.setState({
|
||||
wallet,
|
||||
walletError: null
|
||||
});
|
||||
} catch (error) {
|
||||
this.setState({
|
||||
wallet: null,
|
||||
walletError: (
|
||||
<FormattedMessage
|
||||
id='signer.txPendingConfirm.errors.invalidWallet'
|
||||
defaultMessage='Given wallet file is invalid.'
|
||||
/>
|
||||
)
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
fileReader.readAsText(event.target.files[0]);
|
||||
}
|
||||
|
||||
onModifyPassword = (event) => {
|
||||
const password = event.target.value;
|
||||
|
||||
this.setState({
|
||||
password
|
||||
});
|
||||
}
|
||||
|
||||
onConfirm = () => {
|
||||
const { account } = this.props;
|
||||
const { password, qrState, wallet } = this.state;
|
||||
|
||||
if (account.external && qrState === QR_VISIBLE) {
|
||||
return this.setState({ qrState: QR_SCAN });
|
||||
}
|
||||
|
||||
this.props.onConfirm({
|
||||
password,
|
||||
wallet
|
||||
});
|
||||
}
|
||||
|
||||
generateQr = () => {
|
||||
const { api } = this.context;
|
||||
const { netVersion, dataToSign } = this.props;
|
||||
const { transaction, data, decrypt } = dataToSign;
|
||||
const setState = qr => {
|
||||
this.setState({ qr });
|
||||
};
|
||||
|
||||
if (transaction) {
|
||||
generateTxQr(api, netVersion, transaction).then(setState);
|
||||
return;
|
||||
}
|
||||
|
||||
if (decrypt) {
|
||||
generateDecryptQr(decrypt).then(setState);
|
||||
return;
|
||||
}
|
||||
|
||||
generateDataQr(data).then(setState);
|
||||
}
|
||||
|
||||
onKeyDown = (event) => {
|
||||
const codeName = keycode(event);
|
||||
|
||||
if (codeName !== 'enter') {
|
||||
return;
|
||||
}
|
||||
|
||||
this.onConfirm();
|
||||
}
|
||||
|
||||
// FIXME: Sadly the API subscription channels currently does not allow for specific values,
|
||||
// rather it can only do general queries where parameters are not specified. Hence we are
|
||||
// polling for the nonce here. Since we are moving to node-based subscriptions on the API layer,
|
||||
// this can be optimised when the subscription mechanism is reworked to conform.
|
||||
subscribeNonce () {
|
||||
const nonceTimerId = setInterval(this.readNonce, 1000);
|
||||
|
||||
this.setState({ nonceTimerId });
|
||||
}
|
||||
|
||||
unsubscribeNonce () {
|
||||
const { nonceTimerId } = this.state;
|
||||
|
||||
if (!nonceTimerId) {
|
||||
return;
|
||||
}
|
||||
|
||||
clearInterval(nonceTimerId);
|
||||
}
|
||||
|
||||
readNonce = () => {
|
||||
const { api } = this.context;
|
||||
const { account, dataToSign } = this.props;
|
||||
const { qr } = this.state;
|
||||
|
||||
if ((dataToSign.data || dataToSign.decrypt) && qr && !qr.value) {
|
||||
this.generateQr();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!account || !account.external || !api.transport.isConnected || !dataToSign.transaction) {
|
||||
return;
|
||||
}
|
||||
|
||||
return api.parity
|
||||
.nextNonce(account.address)
|
||||
.then((newNonce) => {
|
||||
const { nonce } = this.state.qr;
|
||||
|
||||
if (!nonce || !newNonce.eq(nonce)) {
|
||||
this.generateQr();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -1,139 +0,0 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { shallow } from 'enzyme';
|
||||
import React from 'react';
|
||||
import sinon from 'sinon';
|
||||
|
||||
import TransactionPendingFormConfirm from './';
|
||||
|
||||
const ADDR_NORMAL = '0x0123456789012345678901234567890123456789';
|
||||
const ADDR_WALLET = '0x1234567890123456789012345678901234567890';
|
||||
const ADDR_HARDWARE = '0x2345678901234567890123456789012345678901';
|
||||
const ADDR_SIGN = '0x3456789012345678901234567890123456789012';
|
||||
const ACCOUNTS = {
|
||||
[ADDR_NORMAL]: {
|
||||
address: ADDR_NORMAL,
|
||||
uuid: ADDR_NORMAL
|
||||
},
|
||||
[ADDR_WALLET]: {
|
||||
address: ADDR_WALLET,
|
||||
wallet: true
|
||||
},
|
||||
[ADDR_HARDWARE]: {
|
||||
address: ADDR_HARDWARE,
|
||||
hardware: true
|
||||
}
|
||||
};
|
||||
|
||||
let component;
|
||||
let instance;
|
||||
let onConfirm;
|
||||
|
||||
function render (address) {
|
||||
onConfirm = sinon.stub();
|
||||
|
||||
component = shallow(
|
||||
<TransactionPendingFormConfirm
|
||||
account={ ACCOUNTS[address] }
|
||||
address={ address }
|
||||
onConfirm={ onConfirm }
|
||||
isSending={ false }
|
||||
dataToSign={ {} }
|
||||
/>
|
||||
);
|
||||
instance = component.instance();
|
||||
|
||||
return component;
|
||||
}
|
||||
|
||||
describe('views/Signer/TransactionPendingFormConfirm', () => {
|
||||
describe('normal accounts', () => {
|
||||
beforeEach(() => {
|
||||
render(ADDR_NORMAL);
|
||||
});
|
||||
|
||||
it('renders defaults', () => {
|
||||
expect(component).to.be.ok;
|
||||
});
|
||||
|
||||
it('does not render the key input', () => {
|
||||
expect(instance.renderKeyInput()).to.be.null;
|
||||
});
|
||||
|
||||
it('renders the password', () => {
|
||||
expect(instance.renderPassword()).not.to.be.null;
|
||||
});
|
||||
});
|
||||
|
||||
describe('hardware accounts', () => {
|
||||
beforeEach(() => {
|
||||
render(ADDR_HARDWARE);
|
||||
});
|
||||
|
||||
it('renders defaults', () => {
|
||||
expect(component).to.be.ok;
|
||||
});
|
||||
|
||||
it('does not render the key input', () => {
|
||||
expect(instance.renderKeyInput()).to.be.null;
|
||||
});
|
||||
|
||||
it('does not render the password', () => {
|
||||
expect(instance.renderPassword()).to.be.null;
|
||||
});
|
||||
});
|
||||
|
||||
describe('wallet accounts', () => {
|
||||
beforeEach(() => {
|
||||
render(ADDR_WALLET);
|
||||
});
|
||||
|
||||
it('renders defaults', () => {
|
||||
expect(component).to.be.ok;
|
||||
});
|
||||
|
||||
it('does not render the key input', () => {
|
||||
expect(instance.renderKeyInput()).to.be.null;
|
||||
});
|
||||
|
||||
it('renders the password', () => {
|
||||
expect(instance.renderPassword()).not.to.be.null;
|
||||
});
|
||||
});
|
||||
|
||||
describe('signing accounts', () => {
|
||||
beforeEach(() => {
|
||||
render(ADDR_SIGN);
|
||||
});
|
||||
|
||||
it('renders defaults', () => {
|
||||
expect(component).to.be.ok;
|
||||
});
|
||||
|
||||
it('renders the key input', () => {
|
||||
expect(instance.renderKeyInput()).not.to.be.null;
|
||||
});
|
||||
|
||||
it('renders the password', () => {
|
||||
expect(instance.renderPassword()).not.to.be.null;
|
||||
});
|
||||
|
||||
it('renders the hint', () => {
|
||||
expect(instance.renderHint()).to.be.null;
|
||||
});
|
||||
});
|
||||
});
|
@ -1,17 +0,0 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './transactionPendingFormReject';
|
@ -1,26 +0,0 @@
|
||||
/* Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
/* This file is part of Parity.
|
||||
/*
|
||||
/* Parity is free software: you can redistribute it and/or modify
|
||||
/* it under the terms of the GNU General Public License as published by
|
||||
/* the Free Software Foundation, either version 3 of the License, or
|
||||
/* (at your option) any later version.
|
||||
/*
|
||||
/* Parity is distributed in the hope that it will be useful,
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
/* GNU General Public License for more details.
|
||||
/*
|
||||
/* You should have received a copy of the GNU General Public License
|
||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* the rejection button itself, once .reject has been pressed */
|
||||
.rejectButton {
|
||||
display: block !important;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.rejectText {
|
||||
margin-bottom: 10px;
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import { Button } from '@parity/ui';
|
||||
|
||||
import styles from './transactionPendingFormReject.css';
|
||||
|
||||
export default class TransactionPendingFormReject extends Component {
|
||||
static propTypes = {
|
||||
onReject: PropTypes.func.isRequired,
|
||||
className: PropTypes.string
|
||||
};
|
||||
|
||||
render () {
|
||||
const { onReject } = this.props;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className={ styles.rejectText }>
|
||||
<FormattedMessage
|
||||
id='signer.txPendingReject.info'
|
||||
defaultMessage='Are you sure you want to reject request?'
|
||||
/>
|
||||
<br />
|
||||
<strong>
|
||||
<FormattedMessage
|
||||
id='signer.txPendingReject.undone'
|
||||
defaultMessage='This cannot be undone'
|
||||
/>
|
||||
</strong>
|
||||
</div>
|
||||
<Button
|
||||
onClick={ onReject }
|
||||
className={ styles.rejectButton }
|
||||
fullWidth
|
||||
label={
|
||||
<FormattedMessage
|
||||
id='signer.txPendingReject.buttons.reject'
|
||||
defaultMessage='Reject Request'
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './txHashLink';
|
@ -1,43 +0,0 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { txLink } from '@parity/etherscan/links';
|
||||
|
||||
export default class TxHashLink extends Component {
|
||||
static propTypes = {
|
||||
children: PropTypes.node,
|
||||
className: PropTypes.string,
|
||||
netVersion: PropTypes.string.isRequired,
|
||||
txHash: PropTypes.string.isRequired
|
||||
}
|
||||
|
||||
render () {
|
||||
const { children, className, netVersion, txHash } = this.props;
|
||||
|
||||
return (
|
||||
<a
|
||||
className={ className }
|
||||
href={ txLink(txHash, false, netVersion) }
|
||||
target='_blank'
|
||||
>
|
||||
{ children || txHash }
|
||||
</a>
|
||||
);
|
||||
}
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
const isLogging = process.env.LOGGING;
|
||||
|
||||
export default logger();
|
||||
|
||||
function logger () {
|
||||
return isLogging ? devLogger() : prodLogger();
|
||||
}
|
||||
|
||||
function prodLogger () {
|
||||
return {
|
||||
log: noop,
|
||||
info: noop,
|
||||
error: noop,
|
||||
warn: noop
|
||||
};
|
||||
}
|
||||
|
||||
function devLogger () {
|
||||
return console;
|
||||
}
|
||||
|
||||
function noop () {}
|
21
js/src/Signer/components/util/react.js
vendored
21
js/src/Signer/components/util/react.js
vendored
@ -1,21 +0,0 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { isValidElement } from 'react';
|
||||
|
||||
export function isReactComponent (componentOrElem) {
|
||||
return isValidElement(componentOrElem) && typeof componentOrElem.type === 'function';
|
||||
}
|
@ -1,115 +0,0 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import BigNumber from 'bignumber.js';
|
||||
|
||||
const WEI_TO_ETH_MULTIPLIER = 0.000000000000000001;
|
||||
const WEI_TO_SZABU_MULTIPLIER = 0.000000000001;
|
||||
|
||||
export const getShortData = _getShortData;
|
||||
// calculations
|
||||
export const getFee = _getFee;
|
||||
export const calcFeeInEth = _calcFeeInEth;
|
||||
export const getTotalValue = _getTotalValue;
|
||||
// displays
|
||||
export const getSzaboFromWeiDisplay = _getSzaboFromWeiDisplay;
|
||||
export const getValueDisplay = _getValueDisplay;
|
||||
export const getValueDisplayWei = _getValueDisplayWei;
|
||||
export const getTotalValueDisplay = _getTotalValueDisplay;
|
||||
export const getTotalValueDisplayWei = _getTotalValueDisplayWei;
|
||||
export const getEthmFromWeiDisplay = _getEthmFromWeiDisplay;
|
||||
export const getGasDisplay = _getGasDisplay;
|
||||
|
||||
function _getShortData (data) {
|
||||
if (data.length <= 3) {
|
||||
return data;
|
||||
}
|
||||
return data.substr(0, 3) + '...';
|
||||
}
|
||||
|
||||
/*
|
||||
* @param {hex string} gas
|
||||
* @param {wei hex string} gasPrice
|
||||
* @return {BigNumber} fee in wei
|
||||
*/
|
||||
function _getFee (gas, gasPrice) {
|
||||
gas = new BigNumber(gas);
|
||||
gasPrice = new BigNumber(gasPrice);
|
||||
return gasPrice.times(gas);
|
||||
}
|
||||
|
||||
function _calcFeeInEth (totalValue, value) {
|
||||
let fee = new BigNumber(totalValue).sub(new BigNumber(value));
|
||||
|
||||
return fee.times(WEI_TO_ETH_MULTIPLIER).toFormat(7);
|
||||
}
|
||||
|
||||
/*
|
||||
* @param {wei BigNumber} fee
|
||||
* @param {wei hex string} value
|
||||
* @return {BigNumber} total value in wei
|
||||
*/
|
||||
function _getTotalValue (fee, value) {
|
||||
value = new BigNumber(value);
|
||||
return fee.plus(value);
|
||||
}
|
||||
|
||||
/*
|
||||
* @param {wei hex string} gasPrice
|
||||
* @return {string} szabo gas price with unit [szabo] i.e. 21,423 [szabo]
|
||||
*/
|
||||
function _getSzaboFromWeiDisplay (gasPrice) {
|
||||
gasPrice = new BigNumber(gasPrice);
|
||||
return gasPrice.times(WEI_TO_SZABU_MULTIPLIER).toPrecision(5);
|
||||
}
|
||||
|
||||
/*
|
||||
* @param {wei hex string} value
|
||||
* @return {string} value in WEI nicely formatted
|
||||
*/
|
||||
function _getValueDisplay (value) {
|
||||
value = new BigNumber(value);
|
||||
return value.times(WEI_TO_ETH_MULTIPLIER).toFormat(5);
|
||||
}
|
||||
|
||||
function _getValueDisplayWei (value) {
|
||||
value = new BigNumber(value);
|
||||
return value.toFormat(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* @param {wei hex string} totalValue
|
||||
* @return {string} total value (including fee) with units i.e. 1.32 [eth]
|
||||
*/
|
||||
function _getTotalValueDisplay (totalValue) {
|
||||
totalValue = new BigNumber(totalValue);
|
||||
return totalValue.times(WEI_TO_ETH_MULTIPLIER).toFormat(5);
|
||||
}
|
||||
|
||||
function _getTotalValueDisplayWei (totalValue) {
|
||||
totalValue = new BigNumber(totalValue);
|
||||
return totalValue.toFormat(0);
|
||||
}
|
||||
|
||||
function _getEthmFromWeiDisplay (weiHexString) {
|
||||
const value = new BigNumber(weiHexString);
|
||||
|
||||
return value.times(WEI_TO_ETH_MULTIPLIER).times(1e7).toFixed(5);
|
||||
}
|
||||
|
||||
function _getGasDisplay (gas) {
|
||||
return new BigNumber(gas).times(1e-7).toFormat(4);
|
||||
}
|
@ -1,79 +0,0 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import BigNumber from 'bignumber.js';
|
||||
import { getShortData, getFee, getTotalValue } from './transaction';
|
||||
|
||||
describe('Signer/components/util/transaction', () => {
|
||||
describe('getEstimatedMiningTime', () => {
|
||||
it('should return estimated mining time', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('getShortData', () => {
|
||||
it('should return short data', () => {
|
||||
// given
|
||||
const data = '0xh87dY78';
|
||||
|
||||
// when
|
||||
const res = getShortData(data);
|
||||
|
||||
// then
|
||||
expect(res).to.equal('0xh...');
|
||||
});
|
||||
|
||||
it('should return data as is', () => {
|
||||
// given
|
||||
const data = '0x0';
|
||||
|
||||
// when
|
||||
const shortData = getShortData(data);
|
||||
|
||||
// then
|
||||
expect(shortData).to.equal('0x0');
|
||||
});
|
||||
});
|
||||
|
||||
describe('getFee', () => {
|
||||
it('should return wei BigNumber object equals to gas * gasPrice', () => {
|
||||
// given
|
||||
const gas = '0x76c0'; // 30400
|
||||
const gasPrice = '0x9184e72a000'; // 10000000000000 wei
|
||||
|
||||
// when
|
||||
const fee = getFee(gas, gasPrice);
|
||||
|
||||
// then
|
||||
expect(fee).to.be.an.instanceOf(BigNumber);
|
||||
expect(fee.toString()).to.be.equal('304000000000000000'); // converting to string due to https://github.com/MikeMcl/bignumber.js/issues/11
|
||||
});
|
||||
});
|
||||
|
||||
describe('getTotalValue', () => {
|
||||
it('should return wei BigNumber totalValue equals to value + fee', () => {
|
||||
// given
|
||||
const fee = new BigNumber(304000000000000000); // wei
|
||||
const value = '0x9184e72a'; // 2441406250 wei
|
||||
|
||||
// when
|
||||
const totalValue = getTotalValue(fee, value);
|
||||
|
||||
// then
|
||||
expect(totalValue).to.be.an.instanceOf(BigNumber);
|
||||
expect(totalValue.toString()).to.be.equal('304000002441406250'); // converting to string due to https://github.com/MikeMcl/bignumber.js/issues/11
|
||||
});
|
||||
});
|
||||
});
|
@ -1,107 +0,0 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { isEqual } from 'lodash';
|
||||
import { action, observable } from 'mobx';
|
||||
|
||||
export default class SignerStore {
|
||||
@observable balances = {};
|
||||
@observable localHashes = [];
|
||||
|
||||
externalLink = '';
|
||||
|
||||
constructor (api, withLocalTransactions = false, externalLink = '') {
|
||||
this._api = api;
|
||||
this._timeoutId = 0;
|
||||
this.externalLink = externalLink;
|
||||
|
||||
if (withLocalTransactions) {
|
||||
this.fetchLocalTransactions();
|
||||
}
|
||||
}
|
||||
|
||||
@action setBalance = (address, balance) => {
|
||||
this.setBalances({ [address]: balance });
|
||||
}
|
||||
|
||||
@action setBalances = (balances) => {
|
||||
this.balances = Object.assign({}, this.balances, balances);
|
||||
}
|
||||
|
||||
@action setLocalHashes = (localHashes = []) => {
|
||||
// Use slice to make sure they are both Arrays (MobX uses Objects for Observable Arrays)
|
||||
if (!isEqual(localHashes.slice(), this.localHashes.slice())) {
|
||||
this.localHashes = localHashes;
|
||||
}
|
||||
}
|
||||
|
||||
@action unsubscribe () {
|
||||
if (this._timeoutId) {
|
||||
clearTimeout(this._timeoutId);
|
||||
}
|
||||
}
|
||||
|
||||
fetchBalance (address) {
|
||||
this._api.eth
|
||||
.getBalance(address)
|
||||
.then((balance) => {
|
||||
this.setBalance(address, balance);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.warn('Store:fetchBalance', error);
|
||||
});
|
||||
}
|
||||
|
||||
fetchBalances (_addresses) {
|
||||
const addresses = _addresses.filter((address) => address) || [];
|
||||
|
||||
if (!addresses.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
Promise
|
||||
.all(addresses.map((address) => this._api.eth.getBalance(address)))
|
||||
.then((_balances) => {
|
||||
this.setBalances(
|
||||
addresses.reduce((balances, address, index) => {
|
||||
balances[address] = _balances[index];
|
||||
return balances;
|
||||
}, {})
|
||||
);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.warn('Store:fetchBalances', error);
|
||||
});
|
||||
}
|
||||
|
||||
fetchLocalTransactions = () => {
|
||||
const nextTimeout = () => {
|
||||
this._timeoutId = setTimeout(this.fetchLocalTransactions, 1500);
|
||||
};
|
||||
|
||||
this._api.parity
|
||||
.localTransactions()
|
||||
.then((localTransactions) => {
|
||||
const keys = Object
|
||||
.keys(localTransactions)
|
||||
.filter((key) => localTransactions[key].status !== 'canceled');
|
||||
|
||||
this.setLocalHashes(keys);
|
||||
})
|
||||
.then(() => nextTimeout())
|
||||
.catch(() => nextTimeout());
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user