Skip to content

Commit

Permalink
[Redesign] Replace explorer API with SDK route.track for in-progress …
Browse files Browse the repository at this point in the history
…widget (#2835)

* [Redesign] Using SDK traker for in-progress widget

Signed-off-by: Emre Bogazliyanlioglu <[email protected]>

* [Redesign] Fix React warnings

Signed-off-by: Emre Bogazliyanlioglu <[email protected]>

* Addressing the first round of feedback

Signed-off-by: Emre Bogazliyanlioglu <[email protected]>

---------

Signed-off-by: Emre Bogazliyanlioglu <[email protected]>
  • Loading branch information
emreboga authored Oct 16, 2024
1 parent 3f66f7a commit 67e1b1f
Show file tree
Hide file tree
Showing 10 changed files with 175 additions and 105 deletions.
4 changes: 4 additions & 0 deletions wormhole-connect/src/config/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
Wormhole as WormholeV2,
Chain,
TokenAddress as TokenAddressV2,
AttestationReceipt,
} from '@wormhole-foundation/sdk';

import {
Expand Down Expand Up @@ -305,10 +306,13 @@ export interface TransactionLocal {
tokenKey: string;
sourceChain: string;
destChain: string;
timestamp: number;
eta: number;
explorerInfo: {
name: string;
url: string;
apiUrl: string;
};
route: string;
receipt: routes.Receipt<AttestationReceipt>;
}
111 changes: 111 additions & 0 deletions wormhole-connect/src/hooks/useTrackTransferInProgress.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import { useEffect, useState } from 'react';
import { isCompleted, routes } from '@wormhole-foundation/sdk';

import config, { getWormholeContextV2 } from 'config';
import { sleep } from 'utils';

import type { AttestationReceipt } from '@wormhole-foundation/sdk';

const TRACK_INTERVAL = 5000;
const TRACK_INTERVAL_FAST = 1000;
const TRACK_TIMEOUT = 120 * 1000;

type Props = {
route: string;
receipt: routes.Receipt<AttestationReceipt>;
eta?: number;
};

type ReturnProps = {
isCompleted: boolean;
};

const useTrackTransferV2 = (props: Props): ReturnProps => {
const [completed, setCompleted] = useState(false);
const [receipt, setReceipt] = useState<routes.Receipt<AttestationReceipt>>();

const { eta, route: routeName } = props;

// Set initial receipt from the caller
useEffect(() => {
if (props.receipt) {
setReceipt(props.receipt);
}
}, [props.receipt]);

useEffect(() => {
let isActive = true;

let sleepTime = TRACK_INTERVAL;

if (eta && eta < 30_000) {
// Poll aggressively for very fast transfers
sleepTime = TRACK_INTERVAL_FAST;
}

const track = async () => {
if (!routeName || !receipt) {
return;
}

const route = config.routes.get(routeName);

if (!route) {
return;
}

const wh = await getWormholeContextV2();
const sdkRoute = new route.rc(wh);

let stateChanged = false;

while (isActive && !isCompleted(receipt) && !stateChanged) {
try {
// We need to consume all of the values the track generator yields in case any of them
// update the receipt state.
for await (const currentReceipt of sdkRoute.track(
receipt,
TRACK_TIMEOUT,
)) {
if (!isActive) {
break;
}

// When the receipt state is updated, we set the new receipt in the local state
// and break out of the loop.
// The hook will then be re-run and the new receipt will be used to continue tracking
// until the transfer is completed.
if (currentReceipt.state !== receipt.state) {
setReceipt(currentReceipt);

if (isCompleted(currentReceipt)) {
setCompleted(true);
stateChanged = true;
break;
}
}
}
} catch (e) {
console.error('Error tracking transfer:', e);
sleepTime = TRACK_INTERVAL; // Back off if we were polling aggressively
}

// Retry
// TODO: exponential backoff depending on the current state?
await sleep(sleepTime);
}
};

track();

return () => {
isActive = false;
};
}, [eta, receipt, routeName]);

return {
isCompleted: completed,
};
};

export default useTrackTransferV2;
4 changes: 2 additions & 2 deletions wormhole-connect/src/icons/TxComplete.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ const TxCompleteIcon = createSvgIcon(
xmlns="http://www.w3.org/2000/svg"
>
<path
fill-rule="evenodd"
clip-rule="evenodd"
fillRule="evenodd"
clipRule="evenodd"
d="M53.2079 105.5C82.2486 105.5 105.791 81.9949 105.791 53C105.791 24.0051 82.2486 0.5 53.2079 0.5C24.1672 0.5 0.625 24.0051 0.625 53C0.625 81.9949 24.1672 105.5 53.2079 105.5ZM53.207 102.097C80.3654 102.097 102.382 80.1157 102.382 53.0001C102.382 25.8844 80.3654 3.90283 53.207 3.90283C26.0485 3.90283 4.03223 25.8844 4.03223 53.0001C4.03223 80.1157 26.0485 102.097 53.207 102.097Z"
fill="currentColor"
/>
Expand Down
8 changes: 4 additions & 4 deletions wormhole-connect/src/icons/TxFailed.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,20 @@ const TxFailedIcon = createSvgIcon(
xmlns="http://www.w3.org/2000/svg"
>
<path
fill-rule="evenodd"
clip-rule="evenodd"
fillRule="evenodd"
clipRule="evenodd"
d="M52.5829 105C81.6236 105 105.166 81.4949 105.166 52.5C105.166 23.5051 81.6236 0 52.5829 0C23.5422 0 0 23.5051 0 52.5C0 81.4949 23.5422 105 52.5829 105ZM52.582 101.597C79.7404 101.597 101.757 79.6157 101.757 52.5001C101.757 25.3844 79.7404 3.40283 52.582 3.40283C25.4235 3.40283 3.40723 25.3844 3.40723 52.5001C3.40723 79.6157 25.4235 101.597 52.582 101.597Z"
fill="currentColor"
/>
<path
d="M65.7583 39.2417L39.2418 65.7582"
stroke="currentColor"
stroke-width="4"
strokeWidth="4"
/>
<path
d="M39.2417 39.2417L65.7582 65.7582"
stroke="currentColor"
stroke-width="4"
strokeWidth="4"
/>
</svg>,
'Alert',
Expand Down
4 changes: 2 additions & 2 deletions wormhole-connect/src/icons/TxReadyForClaim.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ const TxReadyForClaimIcon = createSvgIcon(
xmlns="http://www.w3.org/2000/svg"
>
<path
fill-rule="evenodd"
clip-rule="evenodd"
fillRule="evenodd"
clipRule="evenodd"
fill="currentColor"
d="M53.2,105.5c29,0,52.6-23.5,52.6-52.5S82.2.5,53.2.5.6,24,.6,53s23.5,52.5,52.6,52.5ZM53.2,102.1c27.2,0,49.2-22,49.2-49.1S80.4,3.9,53.2,3.9,4,25.9,4,53s22,49.1,49.2,49.1Z"
/>
Expand Down
6 changes: 3 additions & 3 deletions wormhole-connect/src/icons/TxWarning.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ const TxWarning = createSvgIcon(
<path
d="M53.5 36.625V57.7188M104.125 53.5C104.125 60.1482 102.816 66.7312 100.271 72.8733C97.7273 79.0155 93.9982 84.5963 89.2973 89.2973C84.5963 93.9982 79.0155 97.7273 72.8733 100.271C66.7312 102.816 60.1482 104.125 53.5 104.125C46.8518 104.125 40.2688 102.816 34.1267 100.271C27.9845 97.7273 22.4037 93.9982 17.7027 89.2973C13.0018 84.5963 9.27274 79.0155 6.7286 72.8733C4.18445 66.7312 2.875 60.1482 2.875 53.5C2.875 40.0734 8.20869 27.1967 17.7027 17.7027C27.1967 8.20869 40.0734 2.875 53.5 2.875C66.9266 2.875 79.8032 8.20869 89.2973 17.7027C98.7913 27.1967 104.125 40.0734 104.125 53.5ZM53.5 74.5938H53.545V74.6388H53.5V74.5938Z"
stroke="currentColor"
stroke-width="4"
stroke-linecap="round"
stroke-linejoin="round"
strokeWidth="4"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>,
'Alert',
Expand Down
10 changes: 8 additions & 2 deletions wormhole-connect/src/utils/inProgressTxCache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ import { TransactionLocal } from 'config/types';
const LOCAL_STORAGE_KEY = 'wormhole-connect:transactions:inprogress';
const LOCAL_STORAGE_MAX = 3;

// Bigint types cannot be serialized to a string
// That's why we need to provide a replacer function to handle it separately
// Please see for details: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/BigInt_not_serializable
const JSONReplacer = (_, value: any) =>
typeof value === 'bigint' ? value.toString() : value;

// Retrieves all in-progress transactions from localStorage
export const getTxsFromLocalStorage = ():
| Array<TransactionLocal>
Expand Down Expand Up @@ -51,7 +57,7 @@ export const addTxToLocalStorage = (
}

// Update the list
ls.setItem(LOCAL_STORAGE_KEY, JSON.stringify(newList));
ls.setItem(LOCAL_STORAGE_KEY, JSON.stringify(newList, JSONReplacer));
};

// Removes a transaction from localStorage
Expand All @@ -65,7 +71,7 @@ export const removeTxFromLocalStorage = (txHash: string) => {
if (removeIndex > -1) {
// remove the item and update localStorage
items.splice(removeIndex, 1);
ls.setItem(LOCAL_STORAGE_KEY, JSON.stringify(items));
ls.setItem(LOCAL_STORAGE_KEY, JSON.stringify(items, JSONReplacer));
}
}
};
29 changes: 17 additions & 12 deletions wormhole-connect/src/views/v2/Bridge/ReviewTransaction/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -246,8 +246,24 @@ const ReviewTransaction = (props: Props) => {
};
}

const txTimestamp = Date.now();

// Add the new transaction to local storage
addTxToLocalStorage({
txHash: txId,
amount,
tokenKey: sourceTokenConfig.key,
sourceChain: receipt.from,
destChain: receipt.to,
timestamp: txTimestamp,
eta: quote.eta || 0,
explorerInfo: getExplorerInfo(sdkRoute, txId),
receipt,
route,
});

// Set the start time of the transaction
dispatch(setTimestamp(Date.now()));
dispatch(setTimestamp(txTimestamp));

// TODO: SDKV2 set the tx details using on-chain data
// because they might be different than what we have in memory (relayer fee)
Expand Down Expand Up @@ -278,17 +294,6 @@ const ReviewTransaction = (props: Props) => {
}),
);

// Add the new transaction to local storage
addTxToLocalStorage({
txHash: txId,
amount,
tokenKey: sourceTokenConfig.key,
sourceChain: receipt.from,
destChain: receipt.to,
eta: quote.eta || 0,
explorerInfo: getExplorerInfo(sdkRoute, txId),
});

// Reset the amount for a successful transaction
dispatch(setAmount(''));

Expand Down
Loading

0 comments on commit 67e1b1f

Please sign in to comment.