on master help sign in
ux: [WIP] Sign txns with connected wallet
commita7d0e3a1d2dac85d10e10c0968dbb68e10595df0 authortomholford <tomholford@users.noreply.github.com> dateTue 10 Aug 2021, 09:40 (5 years ago) parentcedd040
7 files changed+181−62
package-lock.json+53−53 package.json+3−3 src/lib/WalletConnect.ts+59 src/lib/txn.js+8 src/lib/useEthereumTransaction.js+12 src/lib/useWalletConnect.ts+37−6 src/lib/utils/address.ts+9
package-lock.json+53−53
@@ -8783,46 +8783,46 @@
87838783 }
87848784 },
87858785 "@walletconnect/browser-utils": {
8786− "version": "1.5.1",
8787− "resolved": "https://registry.npmjs.org/@walletconnect/browser-utils/-/browser-utils-1.5.1.tgz",
8788− "integrity": "sha512-pH5xnTaFvOsrxgLlazKqFhfiUE0zxmErgcrwV2B4vFKHLf3/j1MPxZmOpnqC/VsMAUNcJr2/xrrHu4O1Jy7rPg==",
8786+ "version": "1.5.2",
8787+ "resolved": "https://registry.npmjs.org/@walletconnect/browser-utils/-/browser-utils-1.5.2.tgz",
8788+ "integrity": "sha512-nP7ktHwYmvHfXIbq7lGPoig8nO7HYi2dWE8UDxBlgNMs4mvzm2jyN6cm0JZ4xh5gO90/gQwbyuU33zLcZGUPhw==",
87898789 "requires": {
87908790 "@walletconnect/safe-json": "1.0.0",
8791− "@walletconnect/types": "^1.5.1",
8791+ "@walletconnect/types": "^1.5.2",
87928792 "@walletconnect/window-getters": "1.0.0",
87938793 "@walletconnect/window-metadata": "1.0.0",
87948794 "detect-browser": "5.2.0"
87958795 }
87968796 },
87978797 "@walletconnect/client": {
8798− "version": "1.5.1",
8799− "resolved": "https://registry.npmjs.org/@walletconnect/client/-/client-1.5.1.tgz",
8800− "integrity": "sha512-/NODRyToXmtNYfPZF3aPc9VGF1B8C6J+EmKtf4cKhAifir8S2XIWk7zLTHRm9DmSFuDF8hWQhTip14Bovp9WZw==",
8798+ "version": "1.5.2",
8799+ "resolved": "https://registry.npmjs.org/@walletconnect/client/-/client-1.5.2.tgz",
8800+ "integrity": "sha512-dAMK4zqNBZ88YpUQxTMt3RCS2ThTwecPmlq3MK76liLwrsGYRfnQ104GHZGI93rZEdcDWX04p5e3NsCXWMXcNw==",
88018801 "requires": {
8802− "@walletconnect/core": "^1.5.1",
8803− "@walletconnect/iso-crypto": "^1.5.1",
8804− "@walletconnect/types": "^1.5.1",
8805− "@walletconnect/utils": "^1.5.1"
8802+ "@walletconnect/core": "^1.5.2",
8803+ "@walletconnect/iso-crypto": "^1.5.2",
8804+ "@walletconnect/types": "^1.5.2",
8805+ "@walletconnect/utils": "^1.5.2"
88068806 }
88078807 },
88088808 "@walletconnect/core": {
8809− "version": "1.5.1",
8810− "resolved": "https://registry.npmjs.org/@walletconnect/core/-/core-1.5.1.tgz",
8811− "integrity": "sha512-WGcZS+22395s70C0lAJyc6FnE3F362AZ4S85mGD8JRlRTDiVxZ+nbyaU+6GRLq3MJK2W65Ffw6gMmwniUdVrEw==",
8809+ "version": "1.5.2",
8810+ "resolved": "https://registry.npmjs.org/@walletconnect/core/-/core-1.5.2.tgz",
8811+ "integrity": "sha512-uzrIbjzSHdPPeFSqwPYhp/VhyJKUODDc0STt+5R1A2orE1nh9Rb6XqSkBfLkOlf8pdKUObI95Lr0LH9TbSzF/A==",
88128812 "requires": {
8813− "@walletconnect/socket-transport": "^1.5.1",
8814− "@walletconnect/types": "^1.5.1",
8815− "@walletconnect/utils": "^1.5.1"
8813+ "@walletconnect/socket-transport": "^1.5.2",
8814+ "@walletconnect/types": "^1.5.2",
8815+ "@walletconnect/utils": "^1.5.2"
88168816 }
88178817 },
88188818 "@walletconnect/crypto": {
8819− "version": "1.0.0",
8820− "resolved": "https://registry.npmjs.org/@walletconnect/crypto/-/crypto-1.0.0.tgz",
8821− "integrity": "sha512-G2eQ7xD8q+8fDEtdULlLtGinmuqDTcG5oZ5xGaKkEqDEaHA56B1UV99GvISXbSHGCkFhPFWAokBK05AGQgzZeg==",
8819+ "version": "1.0.1",
8820+ "resolved": "https://registry.npmjs.org/@walletconnect/crypto/-/crypto-1.0.1.tgz",
8821+ "integrity": "sha512-IgUReNrycIFxkGgq8YT9HsosCkhutakWD9Q411PR0aJfxpEa/VKJeaLRtoz6DvJpztWStwhIHnAbBoOVR72a6g==",
88228822 "requires": {
88238823 "@walletconnect/encoding": "^1.0.0",
88248824 "@walletconnect/environment": "^1.0.0",
8825− "@walletconnect/randombytes": "^1.0.0",
8825+ "@walletconnect/randombytes": "^1.0.1",
88268826 "aes-js": "^3.1.2",
88278827 "hash.js": "^1.1.7"
88288828 },
@@ -8849,13 +8849,13 @@
88498849 "integrity": "sha512-4BwqyWy6KpSvkocSaV7WR3BlZfrxLbJSLkg+j7Gl6pTDE+U55lLhJvQaMuDVazXYxcjBsG09k7UlH7cGiUI5vQ=="
88508850 },
88518851 "@walletconnect/iso-crypto": {
8852− "version": "1.5.1",
8853− "resolved": "https://registry.npmjs.org/@walletconnect/iso-crypto/-/iso-crypto-1.5.1.tgz",
8854− "integrity": "sha512-OAak844/EBynQyg/TnoPCajkYw2rsVZOASAh+Bb7U7NMuyJ+xQ37RBLuL/a3BaGXS3t/mpJJ5RuHGzoU8USB+A==",
8852+ "version": "1.5.2",
8853+ "resolved": "https://registry.npmjs.org/@walletconnect/iso-crypto/-/iso-crypto-1.5.2.tgz",
8854+ "integrity": "sha512-tRd0+AfmOy0nwCqLx7oR3DyrsahgoyOAm/KqKzKu2eawnfG4dSaluUa/PxMjoC5r93K+ka7qmCq4k4m53qYiog==",
88558855 "requires": {
8856− "@walletconnect/crypto": "^1.0.0",
8857− "@walletconnect/types": "^1.5.1",
8858− "@walletconnect/utils": "^1.5.1"
8856+ "@walletconnect/crypto": "^1.0.1",
8857+ "@walletconnect/types": "^1.5.2",
8858+ "@walletconnect/utils": "^1.5.2"
88598859 }
88608860 },
88618861 "@walletconnect/jsonrpc-types": {
@@ -8881,22 +8881,22 @@
88818881 "integrity": "sha512-ZtKRio4uCZ1JUF7LIdecmZt7FOLnX72RPSY7aUVu7mj7CSfxDwUn6gBuK6WGtH+NZCldBqDl5DenI5fFSvkKYw=="
88828882 },
88838883 "@walletconnect/qrcode-modal": {
8884− "version": "1.5.1",
8885− "resolved": "https://registry.npmjs.org/@walletconnect/qrcode-modal/-/qrcode-modal-1.5.1.tgz",
8886− "integrity": "sha512-eu+CudCdfSRI8nCPGmzTQAFEF/BsqGf9wcE7fL9H8mv5Zpl86gbXKcBHekqr7fgnZ6wmkeDdRK7wLhHL3L6fpw==",
8884+ "version": "1.5.2",
8885+ "resolved": "https://registry.npmjs.org/@walletconnect/qrcode-modal/-/qrcode-modal-1.5.2.tgz",
8886+ "integrity": "sha512-ciWh7kfZQ4qX+YYfF6+qVqw1Z0kyITGnzH7K2jEIxgCI5jsKeKoMcIfucSGIODGrM7OWshB/oA19UFTRdj4GFg==",
88878887 "requires": {
8888− "@walletconnect/browser-utils": "^1.5.1",
8888+ "@walletconnect/browser-utils": "^1.5.2",
88898889 "@walletconnect/mobile-registry": "^1.4.0",
8890− "@walletconnect/types": "^1.5.1",
8890+ "@walletconnect/types": "^1.5.2",
88918891 "copy-to-clipboard": "^3.3.1",
88928892 "preact": "10.4.1",
88938893 "qrcode": "1.4.4"
88948894 }
88958895 },
88968896 "@walletconnect/randombytes": {
8897− "version": "1.0.0",
8898− "resolved": "https://registry.npmjs.org/@walletconnect/randombytes/-/randombytes-1.0.0.tgz",
8899− "integrity": "sha512-vP9HQIzz9PWH+ohQHqXeKZUbSivyTe3Le4c6oQPCExtw2P0ps4jKOyk4UGTxgcN2Rllj8ftPjiYQlQHKHXZuTA==",
8897+ "version": "1.0.1",
8898+ "resolved": "https://registry.npmjs.org/@walletconnect/randombytes/-/randombytes-1.0.1.tgz",
8899+ "integrity": "sha512-YJTyq69i0PtxVg7osEpKfvjTaWuAsR49QEcqGKZRKVQWMbGXBZ65fovemK/SRgtiFRv0V8PwsrlKSheqzfPNcg==",
89008900 "requires": {
89018901 "@walletconnect/encoding": "^1.0.0",
89028902 "@walletconnect/environment": "^1.0.0",
@@ -8909,12 +8909,12 @@
89098909 "integrity": "sha512-QJzp/S/86sUAgWY6eh5MKYmSfZaRpIlmCJdi5uG4DJlKkZrHEF7ye7gA+VtbVzvTtpM/gRwO2plQuiooIeXjfg=="
89108910 },
89118911 "@walletconnect/socket-transport": {
8912− "version": "1.5.1",
8913− "resolved": "https://registry.npmjs.org/@walletconnect/socket-transport/-/socket-transport-1.5.1.tgz",
8914− "integrity": "sha512-DSjXH539IvCdE2SRB94Jn270x9nJbNZmRRVwuY7KbGXaiU93qVD4QFl/O1+QLmrpdL/zA9L0mH8TWIP6PTGrHA==",
8912+ "version": "1.5.2",
8913+ "resolved": "https://registry.npmjs.org/@walletconnect/socket-transport/-/socket-transport-1.5.2.tgz",
8914+ "integrity": "sha512-eXafL2STkPocpYo0lDTpsQFIQ5ggCw78dXri9kqNhiSwRdLpjswGxt745V37enOXuFumz18MRXp3Og8yc+HIFQ==",
89158915 "requires": {
8916− "@walletconnect/types": "^1.5.1",
8917− "@walletconnect/utils": "^1.5.1",
8916+ "@walletconnect/types": "^1.5.2",
8917+ "@walletconnect/utils": "^1.5.2",
89188918 "ws": "7.3.0"
89198919 },
89208920 "dependencies": {
@@ -8926,19 +8926,19 @@
89268926 }
89278927 },
89288928 "@walletconnect/types": {
8929− "version": "1.5.1",
8930− "resolved": "https://registry.npmjs.org/@walletconnect/types/-/types-1.5.1.tgz",
8931− "integrity": "sha512-e3Tzy4NbNyM5yyLzKLNKRnMq4IZWjH0GsWQRNMl2WCSdssHPgSC4LQlxVtmMZt9NwceeGjmCZb4G25eD6hcbLA=="
8929+ "version": "1.5.2",
8930+ "resolved": "https://registry.npmjs.org/@walletconnect/types/-/types-1.5.2.tgz",
8931+ "integrity": "sha512-ygUIqrn+IyANuA3OKLX2GzVB18zUvoRTWX0llKeM0unSlrF7oEs8m5+H5NHLB9sDs00Jae7Eb+JvUaGa/VKIPw=="
89328932 },
89338933 "@walletconnect/utils": {
8934− "version": "1.5.1",
8935− "resolved": "https://registry.npmjs.org/@walletconnect/utils/-/utils-1.5.1.tgz",
8936− "integrity": "sha512-ME6LvPCH2jB4sCCvtTJc+ztZY7mBCUT+FijDNH/RIU4KM7+E+fhEzRsNcJM3FPREVEJepaZJkjWPmEVnXp2mkA==",
8934+ "version": "1.5.2",
8935+ "resolved": "https://registry.npmjs.org/@walletconnect/utils/-/utils-1.5.2.tgz",
8936+ "integrity": "sha512-3m7Ty7oe/jb2NbYj7IAli+cyqlpg4XZG1xGrzCcQEEG6bkijCyc4qd51amimyh38wPsXp+kq7C4I+WAPBd9TkA==",
89378937 "requires": {
8938− "@walletconnect/browser-utils": "^1.5.1",
8938+ "@walletconnect/browser-utils": "^1.5.2",
89398939 "@walletconnect/encoding": "^1.0.0",
89408940 "@walletconnect/jsonrpc-utils": "^1.0.0",
8941− "@walletconnect/types": "^1.5.1",
8941+ "@walletconnect/types": "^1.5.2",
89428942 "bn.js": "4.11.8",
89438943 "js-sha3": "0.8.0",
89448944 "query-string": "6.13.5"
@@ -10264,7 +10264,7 @@
1026410264 "dependencies": {
1026510265 "openzeppelin-solidity": {
1026610266 "version": "1.12.0",
10267− "resolved": "https://registry.npmjs.org/openzeppelin-solidity/-/openzeppelin-solidity-1.12.0.tgz",
10267+ "resolved": false,
1026810268 "integrity": "sha512-WlorzMXIIurugiSdw121RVD5qA3EfSI7GybTn+/Du0mPNgairjt29NpVTAaH8eLjAeAwlw46y7uQKy0NYem/gA=="
1026910269 }
1027010270 }
@@ -10310,7 +10310,7 @@
1031010310 "dependencies": {
1031110311 "openzeppelin-solidity": {
1031210312 "version": "1.12.0",
10313− "resolved": "https://registry.npmjs.org/openzeppelin-solidity/-/openzeppelin-solidity-1.12.0.tgz",
10313+ "resolved": false,
1031410314 "integrity": "sha512-WlorzMXIIurugiSdw121RVD5qA3EfSI7GybTn+/Du0mPNgairjt29NpVTAaH8eLjAeAwlw46y7uQKy0NYem/gA=="
1031510315 },
1031610316 "truffle": {
@@ -28596,9 +28596,9 @@
2859628596 }
2859728597 },
2859828598 "buffer-from": {
28599− "version": "1.1.1",
28600− "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
28601− "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A=="
28599+ "version": "1.1.2",
28600+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
28601+ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="
2860228602 },
2860328603 "camelcase": {
2860428604 "version": "5.3.1",
package.json+3−3
@@ -31,8 +31,8 @@
3131 "@types/styled-components": "^5.1.10",
3232 "@types/styled-system": "^5.1.11",
3333 "@types/styled-system__css": "^5.0.15",
34− "@walletconnect/client": "^1.5.1",
35− "@walletconnect/qrcode-modal": "^1.5.1",
34+ "@walletconnect/client": "^1.5.2",
35+ "@walletconnect/qrcode-modal": "^1.5.2",
3636 "@welldone-software/why-did-you-render": "^3.2.3",
3737 "async-retry": "^1.2.3",
3838 "azimuth-js": "^0.22.1",
@@ -101,7 +101,7 @@
101101 "start": "react-scripts start",
102102 "build": "react-scripts build",
103103 "build:ropsten": "REACT_APP_ROPSTEN=true react-scripts build",
104− "test": "react-scripts test --transformIgnorePatterns \"node_modules/(?!@tlon\/indigo-react)/\" --env=jsdom",
104+ "test": "react-scripts test --transformIgnorePatterns \"node_modules/(?!@tlon/indigo-react)/\" --env=jsdom",
105105 "eject": "react-scripts eject",
106106 "checksum": "cd build && find . -exec shasum -a256 {} ';' > ../checksums.txt && cd ..",
107107 "zip": "BRIDGE_VERSION=${REACT_APP_BRIDGE_VERSION:-$npm_package_version}; zip -ur bridge-$BRIDGE_VERSION.zip README.md bridge-https.py checksums.txt && cd build && zip -ur ../bridge-$BRIDGE_VERSION.zip ./* && cd ..",
src/lib/WalletConnect.tsnew file+59
@@ -0,0 +1,59 @@
1+import { ITxData } from '@walletconnect/types';
2+import Tx from 'ethereumjs-tx';
3+import { sanitizeHex } from './utils/address';
4+
5+type SignWalletConnectTransactionArgs = {
6+ txn: Tx;
7+ from: string;
8+ txnSigner: (args: ITxData) => Promise<string>;
9+};
10+
11+const walletConnectSignTransaction = async ({
12+ txn,
13+ from,
14+ txnSigner,
15+}: 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);
50+
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');
55+
56+ return txn;
57+};
58+
59+export { walletConnectSignTransaction };
src/lib/txn.js+8
@@ -6,6 +6,7 @@ import retry from 'async-retry';
66import { NETWORK_TYPES } from './network';
77import { ledgerSignTransaction } from './ledger';
88import { trezorSignTransaction } from './trezor';
9+import { walletConnectSignTransaction } from './WalletConnect';
910import { metamaskSignTransaction, FakeMetamaskTransaction } from './metamask';
1011import { addHexPrefix } from './utils/address';
1112import { CHECK_BLOCK_EVERY_MS, WALLET_TYPES } from './constants';
@@ -28,6 +29,7 @@ const signTransaction = async ({
2829 chainId, // number
2930 gasPrice, // string, in gwei
3031 gasLimit, // string | number
32+ txnSigner, // optionally inject a transaction signing function
3133}) => {
3234 // TODO: require these in txn object
3335 nonce = toHex(nonce);
@@ -93,6 +95,12 @@ const signTransaction = async ({
9395 await trezorSignTransaction(stx, walletHdPath);
9496 } else if (walletType === WALLET_TYPES.METAMASK) {
9597 return metamaskSignTransaction(utx, wallet.address);
98+ } else if (walletType === WALLET_TYPES.WALLET_CONNECT) {
99+ await walletConnectSignTransaction({
100+ txn: stx,
101+ from: wallet.address,
102+ txnSigner,
103+ });
96104 } else {
97105 stx.sign(wallet.privateKey);
98106 }
src/lib/useEthereumTransaction.js+12
@@ -10,6 +10,7 @@ import {
1010 GAS_LIMITS,
1111 DEFAULT_GAS_PRICE_GWEI,
1212 PROGRESS_ANIMATION_DELAY_MS,
13+ WALLET_TYPES,
1314} from './constants';
1415import {
1516 signTransaction,
@@ -23,6 +24,7 @@ import useDeepEqualReference from 'lib/useDeepEqualReference';
2324import useGasPrice from 'lib/useGasPrice';
2425import { timeout } from 'lib/timeout';
2526import { safeToWei, safeFromWei } from 'lib/lib';
27+import { useWalletConnect } from './useWalletConnect';
2628
2729const STATE = {
2830 NONE: 'NONE',
@@ -48,6 +50,7 @@ export default function useEthereumTransaction(
4850 const { wallet, walletType, walletHdPath } = useWallet();
4951 const { web3, networkType } = useNetwork();
5052 const { pointCursor } = usePointCursor();
53+ const { signTransaction: wcSign } = useWalletConnect();
5154
5255 const _web3 = need.web3(web3);
5356 const _wallet = need.wallet(wallet);
@@ -107,6 +110,12 @@ export default function useEthereumTransaction(
107110 ? unsignedTransactions
108111 : [unsignedTransactions];
109112
113+ // Due to React's Rules of Hooks, optionally inject the
114+ // WC transaction signing function
115+ // https://reactjs.org/docs/hooks-rules.html
116+ const txnSigner =
117+ walletType === WALLET_TYPES.WALLET_CONNECT ? wcSign : undefined;
118+
110119 const txns = await Promise.all(
111120 utxs.map((utx, i) =>
112121 signTransaction({
@@ -119,6 +128,7 @@ export default function useEthereumTransaction(
119128 chainId,
120129 gasPrice: gasPrice.toFixed(0),
121130 gasLimit,
131+ txnSigner,
122132 })
123133 )
124134 );
@@ -126,6 +136,7 @@ export default function useEthereumTransaction(
126136 setSignedTransactions(txns);
127137 setState(STATE.SIGNED);
128138 } catch (error) {
139+ console.error(error);
129140 setError(error);
130141 }
131142 }, [
@@ -139,6 +150,7 @@ export default function useEthereumTransaction(
139150 unsignedTransactions,
140151 walletHdPath,
141152 walletType,
153+ wcSign,
142154 ]);
143155
144156 const broadcast = useCallback(async () => {
src/lib/useWalletConnect.ts+37−6
@@ -1,5 +1,7 @@
11import WalletConnect from '@walletconnect/client';
22import QRCodeModal from '@walletconnect/qrcode-modal';
3+import { ITxData } from '@walletconnect/types';
4+
35import { useEffect, useState } from 'react';
46import { Just } from 'folktale/maybe';
57
@@ -58,12 +60,12 @@ export const useWalletConnect = () => {
5860 }, []);
5961
6062 // Behavior
61− const connect = () => {
63+ const connect = async () => {
6264 if (!connector || connector.connected) {
6365 return;
6466 }
6567
66− connector.createSession();
68+ await connector.createSession();
6769 };
6870
6971 const disconnect = async () => {
@@ -91,8 +93,6 @@ export const useWalletConnect = () => {
9193 walletType: WALLET_TYPES.WALLET_CONNECT,
9294 });
9395
94− // Inspired by the MetamaskWallet implementation :)
95− // TODO: We should refactor / unify how we handle wallets
9696 const wallet: WalletConnectWallet = {
9797 address,
9898 };
@@ -110,6 +110,37 @@ export const useWalletConnect = () => {
110110 return connector.connected;
111111 };
112112
113+ const signTransaction = async ({
114+ from,
115+ to,
116+ gas,
117+ gasPrice,
118+ value,
119+ data,
120+ nonce,
121+ }: ITxData): Promise<string> => {
122+ return new Promise((resolve, reject) => {
123+ if (!connector || !isConnected()) {
124+ reject(new Error('No connected wallet available for signing'));
125+ return;
126+ }
127+
128+ return connector
129+ .signTransaction({
130+ from,
131+ to,
132+ gas,
133+ gasPrice,
134+ value,
135+ data,
136+ nonce,
137+ })
138+ .then((txHash: string) => resolve(txHash))
139+ .catch((error: Error) => reject(error));
140+ });
141+ };
142+
143+ // Event Handlers
113144 const initConnectHandler = () => {
114145 if (!connector) {
115146 return;
@@ -152,8 +183,6 @@ export const useWalletConnect = () => {
152183 throw error;
153184 }
154185
155− // TODO: Confirm what should happen on update?
156− // For now, disconnect and logout
157186 disconnect();
158187 });
159188 };
@@ -185,6 +214,7 @@ export const useWalletConnect = () => {
185214 connector.off('connect');
186215 connector.off('disconnect');
187216 connector.off('session_update');
217+ connector.off('modal_closed');
188218 };
189219 // eslint-disable-next-line react-hooks/exhaustive-deps
190220 }, [connector]);
@@ -198,5 +228,6 @@ export const useWalletConnect = () => {
198228 isConnected,
199229 peerMeta,
200230 resetConnector,
231+ signTransaction,
201232 };
202233};
src/lib/utils/address.ts+9
@@ -37,3 +37,12 @@ export const eqAddr = (addr0, addr1) =>
3737export const publicToAddress = (publicKey: Buffer): string => {
3838 return toHex(pubToAddress(publicKey, true).toString('hex'));
3939};
40+
41+export function sanitizeHex(hex: string): string {
42+ hex = hex.substring(0, 2) === '0x' ? hex.substring(2) : hex;
43+ if (hex === '') {
44+ return '';
45+ }
46+ hex = hex.length % 2 !== 0 ? '0' + hex : hex;
47+ return '0x' + hex;
48+}