on master help sign in
wc: make reticket flow work for walletconnect

The signing and sending callbacks weren't being threaded through. We get a bit crazy in ResetExecute. Other React state values are correctly set on-mount, but for some reason the WalletConnect connector might still be null. We're forced to add it as a dependency to the useEffect, and write an availability check to match.

commit22288764b736e57376e875936e3bd9262f281b41 authorFang <git@fang.io> dateFri 20 Aug 2021, 23:43 (5 years ago) parent40c7a3f
5 files changed+41−6
src/lib/reticket.js+4 src/lib/useEthereumTransaction.js+1 src/lib/useWalletConnect.ts+1−1 src/views/Activate/PassportTransfer.js+1 src/views/UrbitID/ResetKeys/ResetExecute.js+34−5
src/lib/reticket.js+4
@@ -42,6 +42,8 @@ export async function reticketPointBetweenWallets({
4242 onUpdate,
4343 transferEth = false,
4444 nextRevision = INITIAL_NETWORK_KEY_REVISION,
45+ txnSigner,
46+ txnSender,
4547}) {
4648 const askForFunding = (address, minBalance, balance) =>
4749 onUpdate({
@@ -171,6 +173,8 @@ export async function reticketPointBetweenWallets({
171173 chainId,
172174 gasPrice: gasPriceGwei,
173175 gasLimit: txs[i].gas,
176+ txnSigner,
177+ txnSender,
174178 });
175179 txPairs.push({
176180 raw: hexify(stx.serialize()),
src/lib/useEthereumTransaction.js+1
@@ -119,6 +119,7 @@ export default function useEthereumTransaction(
119119 // Due to React's Rules of Hooks, optionally inject the
120120 // WC transaction signing function
121121 // https://reactjs.org/docs/hooks-rules.html
122+ //TODO this is duplicated across relevant callsites, should refactor
122123 const txnSigner =
123124 walletType === WALLET_TYPES.WALLET_CONNECT ? wcSign : undefined;
124125 const txnSender =
src/lib/useWalletConnect.ts+1−1
@@ -168,7 +168,7 @@ export const useWalletConnect = () => {
168168 }: ITxData): Promise<string> => {
169169 return new Promise((resolve, reject) => {
170170 if (!connector || !isConnected()) {
171− reject(new Error('No connected wallet available for signing'));
171+ reject(new Error('No connected wallet available for sending'));
172172 return;
173173 }
174174
src/views/Activate/PassportTransfer.js+1
@@ -112,6 +112,7 @@ export default function PassportTransfer({ className, resetActivateRouter }) {
112112 networkType,
113113 onUpdate: handleUpdate,
114114 transferEth: true,
115+ //NOTE not passing wc function, we always have invite ticket wallet
115116 });
116117
117118 // set the global wallet
src/views/UrbitID/ResetKeys/ResetExecute.js+34−5
@@ -1,4 +1,4 @@
1−import React, { useState, useCallback } from 'react';
1+import React, { useState, useCallback, useEffect } from 'react';
22import { Just, Nothing } from 'folktale/maybe';
33import { Grid, H4, Text, ErrorText } from 'indigo-react';
44
@@ -7,7 +7,6 @@ import {
77 TRANSACTION_PROGRESS,
88} from 'lib/reticket';
99import * as need from 'lib/need';
10−import useLifecycle from 'lib/useLifecycle';
1110import { WALLET_TYPES } from 'lib/constants';
1211import { convertToInt } from 'lib/convertToInt';
1312import useBlockWindowClose from 'lib/useBlockWindowClose';
@@ -18,6 +17,8 @@ import { usePointCursor } from 'store/pointCursor';
1817import { usePointCache } from 'store/pointCache';
1918import { useHistory } from 'store/history';
2019
20+import { useWalletConnect } from 'lib/useWalletConnect';
21+
2122import { RestartButton, ForwardButton } from 'components/Buttons';
2223import WarningBox from 'components/WarningBox';
2324import LoadingBar from 'components/LoadingBar';
@@ -54,6 +55,11 @@ export default function ResetExecute({ newWallet, setNewWallet }) {
5455 } = useWallet();
5556 const { pointCursor } = usePointCursor();
5657 const { getDetails } = usePointCache();
58+ const {
59+ signTransaction: wcSign,
60+ sendTransaction: wcSend,
61+ connector,
62+ } = useWalletConnect();
5763
5864 const [generalError, setGeneralError] = useState();
5965 const [progress, setProgress] = useState(0);
@@ -63,11 +69,28 @@ export default function ResetExecute({ newWallet, setNewWallet }) {
6369 useBlockWindowClose();
6470
6571 // start reticketing transactions on mount
66− useLifecycle(() => {
72+ useEffect(() => {
6773 (async () => {
74+ // due to react shenanigans we may need to wait for the connector
75+ if (
76+ walletType === WALLET_TYPES.WALLET_CONNECT &&
77+ (!connector || !connector.connected)
78+ ) {
79+ setGeneralError(new Error('Awaiting WalletConnect connection...'));
80+ return;
81+ }
82+ setGeneralError();
83+
6884 const point = need.point(pointCursor);
6985 const details = need.details(getDetails(point));
7086 const networkRevision = convertToInt(details.keyRevisionNumber, 10);
87+
88+ // see also comment in useEthereumTransaction
89+ const txnSigner =
90+ walletType === WALLET_TYPES.WALLET_CONNECT ? wcSign : undefined;
91+ const txnSender =
92+ walletType === WALLET_TYPES.WALLET_CONNECT ? wcSend : undefined;
93+
7194 try {
7295 await reticketPointBetweenWallets({
7396 fromWallet: need.wallet(wallet),
@@ -80,13 +103,19 @@ export default function ResetExecute({ newWallet, setNewWallet }) {
80103 networkType,
81104 onUpdate: handleUpdate,
82105 nextRevision: networkRevision + 1,
106+ txnSigner,
107+ txnSender,
83108 });
84109 } catch (err) {
85110 console.error(err);
86111 setGeneralError(err);
87112 }
88113 })();
89− });
114+ //NOTE this was using useLifecycle previously (which is useEffect without
115+ // dependencies) and worked fine, but in the wc case we might need to
116+ // wait for the connector to get set due to react state shenanigans.
117+ // eslint-disable-next-line react-hooks/exhaustive-deps
118+ }, [connector]);
90119
91120 const goToRestart = useCallback(() => {
92121 reset();
@@ -99,7 +128,7 @@ export default function ResetExecute({ newWallet, setNewWallet }) {
99128 setWalletType(WALLET_TYPES.TICKET);
100129 setUrbitWallet(Just(newWallet.value.wallet));
101130 // (implicit) pointCursor stays the same
102− // rediect to point
131+ // redirect to point
103132 popTo(names.POINT);
104133 }, [resetWallet, setWalletType, setUrbitWallet, newWallet, popTo, names]);
105134