on 633e7b8 help sign in
bridge/src/lib/useEthereumTransaction.js
177 lines 4.2 kB history raw
1import { useCallback, useEffect, useState } from 'react';
2import { Just } from 'folktale/maybe';
4import { useNetwork } from 'store/network';
5import { useWallet } from 'store/wallet';
7import {
8 signTransaction,
9 sendSignedTransaction,
10 waitForTransactionConfirm,
11 hexify,
12} from './txn';
13import * as need from './need';
14import { toHex, toWei, fromWei } from 'web3-utils';
16const STATE = {
17 NONE: 'NONE',
18 SIGNED: 'SIGNED',
19 BROADCASTED: 'BROADCASTED',
20 CONFIRMED: 'CONFIRMED',
21};
23/**
24 * manage the state around sending and confirming an ethereum transaction
25 * @param {number} initialGasLimit
26 */
27export default function useEthereumTransaction(initialGasLimit = 0) {
28 const { wallet, walletType, walletHdPath } = useWallet();
29 const { web3, networkType } = useNetwork();
30 const _web3 = need.web3(web3);
31 const _wallet = need.wallet(wallet);
33 const [error, _setError] = useState();
34 const setError = useCallback(
35 error => {
36 _setError(error);
37 if (error) {
38 console.error(error);
39 }
40 },
41 [_setError]
42 );
43 const [state, setState] = useState(STATE.NONE);
44 const [chainId, setChainId] = useState();
45 const [nonce, setNonce] = useState();
46 const [gasPrice, setGasPrice] = useState(20); // gwei
47 const [gasLimit] = useState(initialGasLimit);
48 const [unsignedTransaction, setUnsignedTransaction] = useState();
49 const [signedTransaction, setSignedTransaction] = useState();
50 const [txHash, setTxHash] = useState();
52 const initializing = nonce === undefined || chainId === undefined;
53 const constructed = !!unsignedTransaction;
54 const signed = state === STATE.SIGNED;
55 const broadcasted = state === STATE.BROADCASTED;
56 const confirmed = state === STATE.CONFIRMED;
58 const inputsLocked = signed || broadcasted || confirmed;
60 const canSign = !initializing && constructed;
62 const construct = useCallback(txn => setUnsignedTransaction(txn), [
63 setUnsignedTransaction,
64 ]);
66 const generateAndSign = useCallback(async () => {
67 try {
68 setError(undefined);
69 // TODO: set varaibles
70 // txn.gas = toHex(gasLimit);
71 // txn.gasPrice = toHex(toWei(gasPrice, 'gwei'));
73 const txn = await signTransaction({
74 wallet: _wallet,
75 walletType,
76 walletHdPath,
77 networkType,
78 txn: unsignedTransaction,
79 nonce,
80 chainId,
81 gasPrice,
82 gasLimit,
83 });
85 setSignedTransaction(txn);
86 setState(STATE.SIGNED);
87 } catch (error) {
88 setError(error);
89 }
90 }, [
91 _wallet,
92 chainId,
93 gasLimit,
94 gasPrice,
95 networkType,
96 nonce,
97 setError,
98 unsignedTransaction,
99 walletHdPath,
100 walletType,
101 ]);
103 const broadcast = useCallback(async () => {
104 try {
105 setError(undefined);
106 const txHash = await sendSignedTransaction(
107 _web3,
108 signedTransaction,
109 /* doubtNonceError */ false
110 );
112 setState(STATE.BROADCASTED);
113 setTxHash(txHash);
115 await waitForTransactionConfirm(_web3, txHash);
117 setState(STATE.CONFIRMED);
118 } catch (error) {
119 setError(error);
120 }
121 }, [_web3, setError, signedTransaction]);
123 const reset = useCallback(() => {
124 setState(STATE.NONE);
125 setError(undefined);
126 setGasPrice(0);
127 setSignedTransaction(undefined);
128 }, [setError]);
130 useEffect(() => {
131 (async () => {
132 try {
133 setError(undefined);
134 const [nonce, chainId, estimatedGasPrice] = await Promise.all([
135 _web3.eth.getTransactionCount(_wallet.address),
136 _web3.eth.net.getId(),
137 _web3.eth.getGasPrice(),
138 ]);
140 setNonce(nonce);
141 setChainId(chainId);
142 setGasPrice(fromWei(estimatedGasPrice, 'gwei'));
143 } catch (error) {
144 setError(error);
145 }
146 })();
147 }, [_wallet.address, _web3.eth, setError]);
149 return {
150 initializing,
151 construct,
152 constructed,
153 canSign,
154 generateAndSign,
155 signed,
156 broadcast,
157 broadcasted,
158 confirmed,
159 reset,
160 error,
161 inputsLocked,
162 txHash,
163 bind: {
164 constructed,
165 canSign,
166 generateAndSign,
167 signed,
168 broadcast,
169 broadcasted,
170 confirmed,
171 reset,
172 error,
173 setGasPrice,
174 txHash,
175 },
176 };