@@ -66,14 +66,14 @@ export default function useEthereumTransaction(
66 const [nonce, setNonce] = useState();
66 const [nonce, setNonce] = useState();
67 const { gasPrice, setGasPrice, resetGasPrice } = useGasPrice(initialGasPrice);
67 const { gasPrice, setGasPrice, resetGasPrice } = useGasPrice(initialGasPrice);
68 const [gasLimit] = useState(initialGasLimit);
68 const [gasLimit] = useState(initialGasLimit);
69− const [unsignedTransaction, setUnsignedTransaction] = useState();
69+ const [unsignedTransactions, setUnsignedTransactions] = useState();
70− const [signedTransaction, setSignedTransaction] = useState();
70+ const [signedTransactions, setSignedTransactions] = useState();
71− const [txHash, setTxHash] = useState();
71+ const [txHashes, setTxHashes] = useState();
72 const [needFunds, setNeedFunds] = useState();
72 const [needFunds, setNeedFunds] = useState();
73 const [confirmationProgress, setConfirmationProgress] = useState(0.0);
73 const [confirmationProgress, setConfirmationProgress] = useState(0.0);
75 const initializing = nonce === undefined || chainId === undefined;
75 const initializing = nonce === undefined || chainId === undefined;
76− const constructed = !!unsignedTransaction;
76+ const constructed = !!unsignedTransactions;
77 const isDefaultState = state === STATE.NONE;
77 const isDefaultState = state === STATE.NONE;
78 const signed = state === STATE.SIGNED;
78 const signed = state === STATE.SIGNED;
79 const broadcasted = state === STATE.BROADCASTED;
79 const broadcasted = state === STATE.BROADCASTED;
@@ -88,31 +88,39 @@ export default function useEthereumTransaction(
89 const construct = useCallback(
89 const construct = useCallback(
90 async (...args) =>
90 async (...args) =>
91− setUnsignedTransaction(await transactionBuilder(...args)),
91+ setUnsignedTransactions(await transactionBuilder(...args)),
92 [transactionBuilder]
92 [transactionBuilder]
95− const unconstruct = useCallback(() => setUnsignedTransaction(undefined), [
95+ const unconstruct = useCallback(() => setUnsignedTransactions(undefined), [
96− setUnsignedTransaction,
96+ setUnsignedTransactions,
99 const generateAndSign = useCallback(async () => {
99 const generateAndSign = useCallback(async () => {
101 setError(undefined);
101 setError(undefined);
103+ const utxs = Array.isArray(unsignedTransactions)
104+ ? unsignedTransactions
105+ : [unsignedTransactions];
107+ const txns = await Promise.all(
108+ utxs.map((utx, i) =>
103− const txn = await signTransaction({
109+ signTransaction({
104− wallet: _wallet,
110+ wallet: _wallet,
105− walletType,
111+ walletType,
106− walletHdPath,
112+ walletHdPath,
107− networkType,
113+ networkType,
108− txn: unsignedTransaction,
114+ txn: utx,
109− nonce,
115+ nonce: nonce + i,
110− chainId,
116+ chainId,
111− gasPrice: gasPrice.toFixed(0),
117+ gasPrice: gasPrice.toFixed(0),
112− gasLimit,
118+ gasLimit,
115− setSignedTransaction(txn);
121+ );
123+ setSignedTransactions(txns);
116 setState(STATE.SIGNED);
124 setState(STATE.SIGNED);
117 } catch (error) {
125 } catch (error) {
118 setError(error);
126 setError(error);
@@ -125,7 +133,7 @@ export default function useEthereumTransaction(
125 networkType,
133 networkType,
127 setError,
135 setError,
128− unsignedTransaction,
136+ unsignedTransactions,
129 walletHdPath,
137 walletHdPath,
130 walletType,
138 walletType,
@@ -135,10 +143,12 @@ export default function useEthereumTransaction(
135 setConfirmationProgress(0.0);
143 setConfirmationProgress(0.0);
136 setError(undefined);
144 setError(undefined);
138− const rawTx = hexify(signedTransaction.serialize());
146+ const rawTxs = signedTransactions.map(stx => hexify(stx.serialize()));
139− const costGwei = toBN(gasLimit).mul(toBN(gasPrice));
140− const cost = toWei(costGwei.toString(), 'gwei');
148+ const costGwei = toBN(gasLimit)
149+ .mul(toBN(gasPrice))
150+ .mul(toBN(rawTxs.length));
151+ const cost = toWei(costGwei.toString(), 'gwei');
142 let usedTank = false;
152 let usedTank = false;
143 // if this ethereum transaction is being executed by a specific point
153 // if this ethereum transaction is being executed by a specific point
144 // see if we can use the tank
154 // see if we can use the tank
@@ -148,27 +158,35 @@ export default function useEthereumTransaction(
148 pointCursor.value,
158 pointCursor.value,
149 _wallet.address,
159 _wallet.address,
151− [rawTx],
161+ rawTxs,
152 (address, minBalance, balance) =>
162 (address, minBalance, balance) =>
153 setNeedFunds({ address, minBalance, balance }),
163 setNeedFunds({ address, minBalance, balance }),
154 () => setNeedFunds(undefined)
164 () => setNeedFunds(undefined)
168+ const txHashes = await signedTransactions.reduce(
158− const txHash = await sendSignedTransaction(
171+ sendSignedTransaction(
160− signedTransaction,
173+ stx,
161− /* doubtNonceError */ usedTank
174+ /* doubtNonceError */ usedTank
175+ ).then(hash => [...hashes, hash])
180+ setTxHashes(txHashes);
164 setState(STATE.BROADCASTED);
181 setState(STATE.BROADCASTED);
167 await timeout(PROGRESS_ANIMATION_DELAY_MS);
183 await timeout(PROGRESS_ANIMATION_DELAY_MS);
169 setConfirmationProgress(0.2);
185 setConfirmationProgress(0.2);
171− await waitForTransactionConfirm(_web3, txHash);
188+ txHashes.map(txHash => waitForTransactionConfirm(_web3, txHash))
173 setConfirmationProgress(0.9);
191 setConfirmationProgress(0.9);
@@ -183,12 +201,12 @@ export default function useEthereumTransaction(
183 gasPrice,
201 gasPrice,
184 pointCursor,
202 pointCursor,
185 setError,
203 setError,
186− signedTransaction,
204+ signedTransactions,
189 const reset = useCallback(() => {
207 const reset = useCallback(() => {
190− setTxHash(undefined);
208+ setTxHashes(undefined);
191− setSignedTransaction(undefined);
209+ setSignedTransactions(undefined);
192 setNonce(undefined);
210 setNonce(undefined);
193 setChainId(undefined);
211 setChainId(undefined);
194 resetGasPrice();
212 resetGasPrice();
@@ -283,8 +301,8 @@ export default function useEthereumTransaction(
284 inputsLocked,
302 inputsLocked,
285 confirmationProgress,
303 confirmationProgress,
286− txHash,
304+ txHashes,
287− signedTransaction,
305+ signedTransactions,
288 gasPrice,
306 gasPrice,
289 setGasPrice,
307 setGasPrice,
290 resetGasPrice,
308 resetGasPrice,