on master help sign in
ux: sign transactions with connected WC peer

- adds support to existing signTransaction flow for WC - upgrades ethereumjs Transaction dep from 1.x --> 5.x

commit04ba8989c0ac7ef55e958437a45d28614da1bf09 authortomholford <tomholford@users.noreply.github.com> dateTue 10 Aug 2021, 21:52 (5 years ago) parenta7d0e3a
5 files changed+121−88
package-lock.json+95−32 package.json+1−1 src/lib/WalletConnect.ts+11−43 src/lib/txn.js → src/lib/txn.ts+13−5 src/lib/useWalletConnect.ts+1−7
package-lock.json+95−32
@@ -2164,6 +2164,80 @@
21642164 }
21652165 }
21662166 },
2167+ "@ethereumjs/common": {
2168+ "version": "2.4.0",
2169+ "resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-2.4.0.tgz",
2170+ "integrity": "sha512-UdkhFWzWcJCZVsj1O/H8/oqj/0RVYjLc1OhPjBrQdALAkQHpCp8xXI4WLnuGTADqTdJZww0NtgwG+TRPkXt27w==",
2171+ "requires": {
2172+ "crc-32": "^1.2.0",
2173+ "ethereumjs-util": "^7.1.0"
2174+ },
2175+ "dependencies": {
2176+ "@types/bn.js": {
2177+ "version": "5.1.0",
2178+ "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz",
2179+ "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==",
2180+ "requires": {
2181+ "@types/node": "*"
2182+ }
2183+ },
2184+ "bn.js": {
2185+ "version": "5.2.0",
2186+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz",
2187+ "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw=="
2188+ },
2189+ "ethereumjs-util": {
2190+ "version": "7.1.0",
2191+ "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.0.tgz",
2192+ "integrity": "sha512-kR+vhu++mUDARrsMMhsjjzPduRVAeundLGXucGRHF3B4oEltOUspfgCVco4kckucj3FMlLaZHUl9n7/kdmr6Tw==",
2193+ "requires": {
2194+ "@types/bn.js": "^5.1.0",
2195+ "bn.js": "^5.1.2",
2196+ "create-hash": "^1.1.2",
2197+ "ethereum-cryptography": "^0.1.3",
2198+ "ethjs-util": "0.1.6",
2199+ "rlp": "^2.2.4"
2200+ }
2201+ }
2202+ }
2203+ },
2204+ "@ethereumjs/tx": {
2205+ "version": "3.3.0",
2206+ "resolved": "https://registry.npmjs.org/@ethereumjs/tx/-/tx-3.3.0.tgz",
2207+ "integrity": "sha512-yTwEj2lVzSMgE6Hjw9Oa1DZks/nKTWM8Wn4ykDNapBPua2f4nXO3qKnni86O6lgDj5fVNRqbDsD0yy7/XNGDEA==",
2208+ "requires": {
2209+ "@ethereumjs/common": "^2.4.0",
2210+ "ethereumjs-util": "^7.1.0"
2211+ },
2212+ "dependencies": {
2213+ "@types/bn.js": {
2214+ "version": "5.1.0",
2215+ "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz",
2216+ "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==",
2217+ "requires": {
2218+ "@types/node": "*"
2219+ }
2220+ },
2221+ "bn.js": {
2222+ "version": "5.2.0",
2223+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz",
2224+ "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw=="
2225+ },
2226+ "ethereumjs-util": {
2227+ "version": "7.1.0",
2228+ "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.0.tgz",
2229+ "integrity": "sha512-kR+vhu++mUDARrsMMhsjjzPduRVAeundLGXucGRHF3B4oEltOUspfgCVco4kckucj3FMlLaZHUl9n7/kdmr6Tw==",
2230+ "requires": {
2231+ "@types/bn.js": "^5.1.0",
2232+ "bn.js": "^5.1.2",
2233+ "create-hash": "^1.1.2",
2234+ "ethereum-cryptography": "^0.1.3",
2235+ "ethjs-util": "0.1.6",
2236+ "rlp": "^2.2.4"
2237+ }
2238+ }
2239+ }
2240+ },
21672241 "@ethersproject/abi": {
21682242 "version": "5.4.0",
21692243 "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.4.0.tgz",
@@ -10264,7 +10338,7 @@
1026410338 "dependencies": {
1026510339 "openzeppelin-solidity": {
1026610340 "version": "1.12.0",
10267− "resolved": false,
10341+ "resolved": "https://registry.npmjs.org/openzeppelin-solidity/-/openzeppelin-solidity-1.12.0.tgz",
1026810342 "integrity": "sha512-WlorzMXIIurugiSdw121RVD5qA3EfSI7GybTn+/Du0mPNgairjt29NpVTAaH8eLjAeAwlw46y7uQKy0NYem/gA=="
1026910343 }
1027010344 }
@@ -10310,7 +10384,7 @@
1031010384 "dependencies": {
1031110385 "openzeppelin-solidity": {
1031210386 "version": "1.12.0",
10313− "resolved": false,
10387+ "resolved": "https://registry.npmjs.org/openzeppelin-solidity/-/openzeppelin-solidity-1.12.0.tgz",
1031410388 "integrity": "sha512-WlorzMXIIurugiSdw121RVD5qA3EfSI7GybTn+/Du0mPNgairjt29NpVTAaH8eLjAeAwlw46y7uQKy0NYem/gA=="
1031510389 },
1031610390 "truffle": {
@@ -12911,6 +12985,15 @@
1291112985 }
1291212986 }
1291312987 },
12988+ "crc-32": {
12989+ "version": "1.2.0",
12990+ "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.0.tgz",
12991+ "integrity": "sha512-1uBwHxF+Y/4yF5G48fwnKq6QsIXheor3ZLPT80yGBV1oEUwpPojlEhQbWKVw1VwcTQyMGHK1/XMmTjmlsmTTGA==",
12992+ "requires": {
12993+ "exit-on-epipe": "~1.0.1",
12994+ "printj": "~1.1.0"
12995+ }
12996+ },
1291412997 "create-ecdh": {
1291512998 "version": "4.0.4",
1291612999 "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz",
@@ -15183,11 +15266,6 @@
1518315266 }
1518415267 }
1518515268 },
15186− "ethereum-common": {
15187− "version": "0.0.18",
15188− "resolved": "https://registry.npmjs.org/ethereum-common/-/ethereum-common-0.0.18.tgz",
15189− "integrity": "sha1-L9w1dvIykDNYl26znaeDIT/5Uj8="
15190− },
1519115269 "ethereum-cryptography": {
1519215270 "version": "0.1.3",
1519315271 "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz",
@@ -15241,31 +15319,6 @@
1524115319 "resolved": "https://registry.npmjs.org/ethereumjs-common/-/ethereumjs-common-1.5.2.tgz",
1524215320 "integrity": "sha512-hTfZjwGX52GS2jcVO6E2sx4YuFnf0Fhp5ylo4pEPhEffNln7vS59Hr5sLnp3/QCazFLluuBZ+FZ6J5HTp0EqCA=="
1524315321 },
15244− "ethereumjs-tx": {
15245− "version": "1.3.7",
15246− "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-1.3.7.tgz",
15247− "integrity": "sha512-wvLMxzt1RPhAQ9Yi3/HKZTn0FZYpnsmQdbKYfUUpi4j1SEIcbkd9tndVjcPrufY3V7j2IebOpC00Zp2P/Ay2kA==",
15248− "requires": {
15249− "ethereum-common": "^0.0.18",
15250− "ethereumjs-util": "^5.0.0"
15251− },
15252− "dependencies": {
15253− "ethereumjs-util": {
15254− "version": "5.2.1",
15255− "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz",
15256− "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==",
15257− "requires": {
15258− "bn.js": "^4.11.0",
15259− "create-hash": "^1.1.2",
15260− "elliptic": "^6.5.2",
15261− "ethereum-cryptography": "^0.1.3",
15262− "ethjs-util": "^0.1.3",
15263− "rlp": "^2.0.0",
15264− "safe-buffer": "^5.1.1"
15265− }
15266− }
15267− }
15268− },
1526915322 "ethereumjs-util": {
1527015323 "version": "7.0.10",
1527115324 "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.0.10.tgz",
@@ -15598,6 +15651,11 @@
1559815651 "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
1559915652 "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw="
1560015653 },
15654+ "exit-on-epipe": {
15655+ "version": "1.0.1",
15656+ "resolved": "https://registry.npmjs.org/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz",
15657+ "integrity": "sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw=="
15658+ },
1560115659 "expand-brackets": {
1560215660 "version": "0.1.5",
1560315661 "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz",
@@ -28353,6 +28411,11 @@
2835328411 }
2835428412 }
2835528413 },
28414+ "printj": {
28415+ "version": "1.1.2",
28416+ "resolved": "https://registry.npmjs.org/printj/-/printj-1.1.2.tgz",
28417+ "integrity": "sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ=="
28418+ },
2835628419 "private": {
2835728420 "version": "0.1.8",
2835828421 "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz",
package.json+1−1
@@ -15,6 +15,7 @@
1515 },
1616 "proxy": "http://localhost:4000",
1717 "dependencies": {
18+ "@ethereumjs/tx": "^3.3.0",
1819 "@ledgerhq/hw-app-eth": "^6.0.2",
1920 "@ledgerhq/hw-transport-u2f": "^5.36.0-deprecated",
2021 "@reach/disclosure": "^0.15.0",
@@ -46,7 +47,6 @@
4647 "classnames": "^2.2.6",
4748 "copy-to-clipboard": "^3.2.0",
4849 "ethereum-blockies-base64": "^1.0.2",
49− "ethereumjs-tx": "^1.3.7",
5050 "ethereumjs-util": "^7.0.10",
5151 "file-saver": "^2.0.0",
5252 "final-form": "^4.18.4",
src/lib/WalletConnect.ts+11−43
@@ -1,59 +1,27 @@
11import { ITxData } from '@walletconnect/types';
2−import Tx from 'ethereumjs-tx';
3−import { sanitizeHex } from './utils/address';
2+import { Transaction } from '@ethereumjs/tx';
3+import { stripHexPrefix } from './utils/address';
44
55type SignWalletConnectTransactionArgs = {
6− txn: Tx;
76 from: string;
7+ txn: Transaction;
88 txnSigner: (args: ITxData) => Promise<string>;
99};
1010
1111const walletConnectSignTransaction = async ({
12− txn,
1312 from,
13+ txn,
1414 txnSigner,
1515}: SignWalletConnectTransactionArgs) => {
16− console.log(txn);
17−
18− // example from:
19− // https://docs.walletconnect.org/quick-start/dapps/client#sign-transaction-eth_signtransaction
20− // const formattedWCTx = {
21− // from: '0xbc28Ea04101F03aA7a94C1379bc3AB32E65e62d3', // Required
22− // to: '0x89D24A7b4cCB1b6fAA2625Fe562bDd9A23260359', // Required (for non contract deployments)
23− // data: '0x', // Required
24− // gasPrice: '0x02540be400', // Optional
25− // gas: '0x9c40', // Optional
26− // value: '0x00', // Optional
27− // nonce: '0x0114', // Optional
28− // };
29−
30− const txnValue =
31− txn.value.toString('hex') === '' ? '00' : txn.value.toString('hex');
32−
33− const formattedWCTx = {
34− from: from,
35− to: sanitizeHex(txn.to.toString('hex')),
36− data: sanitizeHex(txn.data.toString('hex')),
37− gasPrice: sanitizeHex(txn.gasPrice.toString('hex')),
38− gas: sanitizeHex(txn.gasLimit.toString('hex')),
39− value: sanitizeHex(txnValue),
40− nonce: sanitizeHex(
41− txn.nonce.length === 0 ? '00' : txn.nonce.toString('hex')
42− ),
43− };
44−
45− console.log(formattedWCTx);
46−
47− const sig = await txnSigner(formattedWCTx);
48−
49− console.log(sig);
16+ let wcFormattedTx = txn.toJSON();
17+ wcFormattedTx.from = from;
18+ wcFormattedTx.gas = wcFormattedTx.gasLimit;
5019
51− // TODO: update passed in txn with signed data
52− // txn.v = Buffer.from(payload.v.slice(2), 'hex');
53− // txn.r = Buffer.from(payload.r.slice(2), 'hex');
54− // txn.s = Buffer.from(payload.s.slice(2), 'hex');
20+ const signature = await txnSigner(wcFormattedTx);
21+ const serializedTx = Buffer.from(stripHexPrefix(signature), 'hex');
22+ const signedTx = Transaction.fromSerializedTx(serializedTx);
5523
56− return txn;
24+ return signedTx;
5725};
5826
5927export { walletConnectSignTransaction };
src/lib/txn.js → src/lib/txn.tsrenamed+13−5
@@ -1,4 +1,5 @@
1−import Tx from 'ethereumjs-tx';
1+import Common, { Chain, Hardfork } from '@ethereumjs/common';
2+import { Transaction } from '@ethereumjs/tx';
23import { toHex } from 'web3-utils';
34import { safeFromWei, safeToWei } from './lib';
45import retry from 'async-retry';
@@ -36,8 +37,9 @@ const signTransaction = async ({
3637 chainId = toHex(chainId);
3738 gasPrice = toHex(safeToWei(gasPrice, 'gwei'));
3839 gasLimit = toHex(gasLimit);
40+ const from = wallet.address;
3941
40− const txParams = { nonce, chainId, gasPrice, gasLimit };
42+ const txParams = { nonce, chainId, gasPrice, gasLimit, from };
4143
4244 // NB (jtobin)
4345 //
@@ -84,7 +86,13 @@ const signTransaction = async ({
8486
8587 const utx = Object.assign(txn, signingParams);
8688
87− const stx = new Tx(utx);
89+ const chain =
90+ networkType === NETWORK_TYPES.ROPSTEN ? Chain.Ropsten : Chain.Mainnet;
91+ const common = new Common({
92+ chain: chain,
93+ hardfork: Hardfork.MuirGlacier,
94+ });
95+ let stx = Transaction.fromTxData(utx, { common, freeze: false });
8896
8997 //TODO should try-catch and display error message to user,
9098 // ie ledger's "pls enable contract data"
@@ -96,9 +104,9 @@ const signTransaction = async ({
96104 } else if (walletType === WALLET_TYPES.METAMASK) {
97105 return metamaskSignTransaction(utx, wallet.address);
98106 } else if (walletType === WALLET_TYPES.WALLET_CONNECT) {
99− await walletConnectSignTransaction({
107+ stx = await walletConnectSignTransaction({
108+ from,
100109 txn: stx,
101− from: wallet.address,
102110 txnSigner,
103111 });
104112 } else {
src/lib/useWalletConnect.ts+1−7
@@ -76,13 +76,7 @@ export const useWalletConnect = () => {
7676 await connector.killSession();
7777 };
7878
79− type AuthenticateArgs = {
80− hdPath?: string;
81− };
82−
83− const authenticate = async ({
84− hdPath = DEFAULT_HD_PATH,
85− }: AuthenticateArgs) => {
79+ const authenticate = async ({ hdPath = DEFAULT_HD_PATH }) => {
8680 if (!(address && connector)) {
8781 return;
8882 }