From 3ecb44f6b761dee3b991be572c986ddb05eaa3bc Mon Sep 17 00:00:00 2001 From: Memo Khoury Date: Mon, 16 Dec 2024 21:11:04 +0000 Subject: [PATCH 01/12] Added tooltip --- .../bridge/bridge/BridgeView.module.css | 64 +++++++++++++++---- .../components/bridge/bridge/BridgeView.tsx | 26 ++++++-- .../bridge/bridge/MultiTokenApproval.tsx | 7 +- .../bridge/bridge/TransactionSummary.tsx | 25 ++++---- .../src/components/bridge/history/Deposit.tsx | 1 - .../src/hooks/useBridger.ts | 62 +++++++++--------- .../src/hooks/useCoinGeckoAPI.ts | 1 + 7 files changed, 120 insertions(+), 66 deletions(-) diff --git a/webapps/world-builder-dashboard/src/components/bridge/bridge/BridgeView.module.css b/webapps/world-builder-dashboard/src/components/bridge/bridge/BridgeView.module.css index a55e1959..873cbb69 100644 --- a/webapps/world-builder-dashboard/src/components/bridge/bridge/BridgeView.module.css +++ b/webapps/world-builder-dashboard/src/components/bridge/bridge/BridgeView.module.css @@ -26,7 +26,8 @@ font-size: 18px; font-style: normal; font-weight: 600; - line-height: 28px; /* 155.556% */ + line-height: 28px; + /* 155.556% */ } .subtitle { @@ -34,7 +35,8 @@ font-size: 14px; font-style: normal; font-weight: 400; - line-height: 20px; /* 142.857% */ + line-height: 20px; + /* 142.857% */ } .directionContainer { @@ -116,7 +118,8 @@ font-size: 14px; font-style: normal; font-weight: 500; - line-height: 20px; /* 142.857% */ + line-height: 20px; + /* 142.857% */ } .valueBlockContainer { @@ -159,7 +162,8 @@ font-size: 12px; font-style: normal; font-weight: 500; - line-height: 18px; /* 150% */ + line-height: 18px; + /* 150% */ transition: all ease-in-out 1s; } @@ -190,13 +194,14 @@ /* Shadow/xs */ box-shadow: 0 1px 2px 0 rgba(16, 24, 40, 0.05); - color: var(--Gray-700, #344054); + color: var(--Gray-700, #344054); /* Text sm/Semibold */ font-size: 14px; font-style: normal; font-weight: 600; - line-height: 20px; /* 142.857% */ + line-height: 20px; + /* 142.857% */ } .balanceContainer { @@ -211,7 +216,8 @@ font-size: 12px; font-style: normal; font-weight: 500; - line-height: 18px; /* 150% */ + line-height: 18px; + /* 150% */ border: none; background: transparent; cursor: pointer; @@ -226,25 +232,57 @@ font-size: 12px; font-style: normal; font-weight: 500; - line-height: 18px; /* 150% */ + line-height: 18px; + /* 150% */ +} + +.manualGasMessageContainer { + display: flex; + padding: 2px 8px; + justify-content: center; + align-items: center; + gap: 4px; + align-self: stretch; + border-radius: 16px; + background: #B54708; +} + +.manualGasMessageText { + color: #FFFAEB; + text-align: center; + + /* Text xs/Medium */ + font-family: Inter; + font-size: 12px; + font-style: normal; + font-weight: 500; + line-height: 18px; + /* 150% */ +} + +.manualGasMessageTooltip { + background: #B54708; } @media (max-width: 1199px) { - .container { - width: 100%; - padding: 15px; - } + .container { + width: 100%; + padding: 15px; + } + .networksContainer { flex-direction: column; gap: 20px; } + .networkSelect { flex-direction: row; align-items: center; width: 100%; gap: 12px } + .arrowIcon { display: none; } -} +} \ No newline at end of file diff --git a/webapps/world-builder-dashboard/src/components/bridge/bridge/BridgeView.tsx b/webapps/world-builder-dashboard/src/components/bridge/bridge/BridgeView.tsx index b5f75adc..9da4bb49 100644 --- a/webapps/world-builder-dashboard/src/components/bridge/bridge/BridgeView.tsx +++ b/webapps/world-builder-dashboard/src/components/bridge/bridge/BridgeView.tsx @@ -30,6 +30,8 @@ import { DepositDirection } from '@/pages/BridgePage/BridgePage' import { getStakeNativeTxData } from '@/utils/bridge/stakeContractInfo' import { getTokensForNetwork, Token } from '@/utils/tokens' import { useBridger } from '@/hooks/useBridger' +import IconAlertCircle from '@/assets/IconAlertCircle' +import { Tooltip } from 'summon-ui/mantine' const BridgeView = ({ direction, @@ -75,6 +77,7 @@ const BridgeView = ({ }) const { data: coinUSDRate, isFetching: isCoinFetching } = useUSDPriceOfToken(selectedBridgeToken.geckoId ?? '') + const { data: ethRate } = useUSDPriceOfToken('ethereum') const handleTokenChange = async (token: Token) => { setSelectedBridgeToken(token) } @@ -260,13 +263,7 @@ const BridgeView = ({ childFee={Number(estimatedFee.data?.childFee ?? 0)} isEstimatingFee={estimatedFee.isLoading} value={Number(value)} - ethRate={ - selectedBridgeToken.symbol === 'TG7T' || selectedBridgeToken.symbol === 'G7' - ? 1 - : isCoinFetching - ? 0.0 - : coinUSDRate[selectedBridgeToken?.geckoId ?? ''].usd - } + ethRate={ethRate?.ethereum?.usd ?? 0} tokenRate={ selectedBridgeToken.symbol === 'TG7T' || selectedBridgeToken.symbol === 'G7' ? 1 @@ -285,6 +282,21 @@ const BridgeView = ({ selectedHighChain={selectedHighNetwork} /> {networkErrorMessage &&
{networkErrorMessage}
} + {direction === 'DEPOSIT' &&
+
+ May need manual gas completion on {selectedHighNetwork.displayName} +
+ + + +
} = ({ showAppr const currentToken = tokens[currentTokenIndex] if (currentTokenIndex === 1) { const gasFeeAmount = ethers.utils.parseUnits( - (gasFees[1] === '0' ? amount : gasFees[1]) || amount, + (gasFees[1] === '0' ? amount : gasFees[1]) || amount, currentToken.decimals || 18 ) return gasFeeAmount @@ -64,7 +64,7 @@ export const MultiTokenApproval: React.FC = ({ showAppr if (!allowanceInitialized && currentTokenIndex === 1) { const currentToken = tokens[currentTokenIndex] const gasFeeAmount = ethers.utils.parseUnits( - (gasFees[1] === '0' ? amount : gasFees[1]) || amount, + (gasFees[1] === '0' ? amount : gasFees[1]) || amount, currentToken.decimals || 18 ) setNewAllowance(gasFeeAmount) @@ -138,7 +138,8 @@ export const MultiTokenApproval: React.FC = ({ showAppr setShowApproval(false)} className={styles.closeButton} stroke="#fff" /> -
Approve the token you want to bridge
+
This sets a limit to the amount of tokens that can be processed through the bridge. +
{tokens.length > 1 && ( <> diff --git a/webapps/world-builder-dashboard/src/components/bridge/bridge/TransactionSummary.tsx b/webapps/world-builder-dashboard/src/components/bridge/bridge/TransactionSummary.tsx index 12ad5bd0..d79b4071 100644 --- a/webapps/world-builder-dashboard/src/components/bridge/bridge/TransactionSummary.tsx +++ b/webapps/world-builder-dashboard/src/components/bridge/bridge/TransactionSummary.tsx @@ -23,10 +23,10 @@ interface TransactionSummaryProps { value: number nativeBalance: number ethRate: number + tokenRate: number tokenSymbol: string gasNativeTokenSymbol: string gasChildNativeTokenSymbol: string - tokenRate: number direction: 'DEPOSIT' | 'WITHDRAW' selectedLowChain: NetworkInterface selectedHighChain: NetworkInterface @@ -62,6 +62,7 @@ const TransactionSummary: React.FC = ({ } const isXsScreen = useMediaQuery(`(max-width: ${mantineBreakpoints.xs})`) + console.log(isEstimatingFee) return (
@@ -97,7 +98,7 @@ const TransactionSummary: React.FC = ({ <>
Estimated gas fee on {selectedLowChain.displayName}
- {!!fee ? ( + {!isEstimatingFee ? (
= ({ )}
) : ( -
{isEstimatingFee ? 'Estimating...' : `Can't estimate fee`}
+
Estimating...
)}
Estimated gas fee on {selectedHighChain.displayName}
- {!!childFee ? ( + {!isEstimatingFee ? (
= ({ )}
) : ( -
{isEstimatingFee ? 'Estimating...' : `Can't estimate fee`}
+
Estimating...
)}
@@ -136,25 +137,25 @@ const TransactionSummary: React.FC = ({ <>
Estimated gas fee on {selectedHighChain.displayName}
- {!!childFee ? ( + {!isEstimatingFee ? (
{`${childFee.toFixed(18).replace(/\.?0+$/, '')} ${gasChildNativeTokenSymbol}`}
- {!!(childFee * tokenRate) && ( + {!!(childFee * ethRate) && (
- {formatCurrency(childFee * tokenRate)} + {formatCurrency(childFee * ethRate)}
)}
) : ( -
{isEstimatingFee ? 'Estimating...' : `Can't estimate fee`}
+
Estimating...
)}
Estimated gas fee on {selectedLowChain.displayName}
- {!!fee ? ( + {!isEstimatingFee ? (
= ({ )}
) : ( -
{isEstimatingFee ? 'Estimating...' : `Can't estimate fee`}
+
Estimating...
)}
@@ -177,7 +178,7 @@ const TransactionSummary: React.FC = ({
You will receive
{`${value} ${tokenSymbol}`}
- {tokenRate > 0 &&
{formatCurrency(value * tokenRate)}
} + {tokenRate > 0 &&
{formatCurrency(value * (tokenSymbol === 'ETH' || tokenSymbol === 'G7' || tokenSymbol === 'TG7T' ? ethRate : tokenRate))}
}
diff --git a/webapps/world-builder-dashboard/src/components/bridge/history/Deposit.tsx b/webapps/world-builder-dashboard/src/components/bridge/history/Deposit.tsx index 33bbddf1..b4e49c91 100644 --- a/webapps/world-builder-dashboard/src/components/bridge/history/Deposit.tsx +++ b/webapps/world-builder-dashboard/src/components/bridge/history/Deposit.tsx @@ -30,7 +30,6 @@ const Deposit: React.FC = ({ deposit }) => { const { data: highNetworkTimestamp } = getHighNetworkTimestamp({ txRecord: deposit, transferStatus: transferStatus }) const { data: transactionInputs, isLoading: isLoadingInputs } = getTransactionInputs({ txRecord: deposit }) const finalTransactionInputs = transactionInputs || deposit.transactionInputs - return ( <> {isLoading && smallView ? ( diff --git a/webapps/world-builder-dashboard/src/hooks/useBridger.ts b/webapps/world-builder-dashboard/src/hooks/useBridger.ts index d0e7e640..2b7a4249 100644 --- a/webapps/world-builder-dashboard/src/hooks/useBridger.ts +++ b/webapps/world-builder-dashboard/src/hooks/useBridger.ts @@ -50,10 +50,10 @@ export const useBridger = () => { tokenInformation?: { decimalPlaces?: number } }) => { return useQuery( - ['estimatedFee', bridger, connectedAccount, value], + ['estimatedFee', value, direction, selectedLowNetwork.chainId, selectedHighNetwork.chainId], async () => { - if (!bridger || !connectedAccount || !value) { - return { parentFee: '0', childFee: '0', totalFee: '0' } + if (!bridger || !value || !tokenInformation) { + return null } try { @@ -64,14 +64,10 @@ export const useBridger = () => { selectedLowNetwork.rpcs[0] : selectedHighNetwork.rpcs[0] - console.log("Origin provider:", originProvider) - const destinationProvider = direction === 'DEPOSIT' ? selectedHighNetwork.rpcs[0] : selectedLowNetwork.rpcs[0] - console.log("Destination provider:", destinationProvider) - if (!originProvider) { console.warn("Missing origin provider, returning zero fees") return { parentFee: '0', childFee: '0', totalFee: '0' } @@ -88,7 +84,7 @@ export const useBridger = () => { const gasAndFee = await bridger.getGasAndFeeEstimation( parsedValue, originProvider, - connectedAccount, + connectedAccount ?? '', destinationProvider ) @@ -107,15 +103,21 @@ export const useBridger = () => { }) } catch (e) { console.error('Fee estimation failed:', e) - return { parentFee: '0', childFee: '0', totalFee: '0' } + return { + parentFee: direction === 'DEPOSIT' + ? '0.01' + : '0.001', + childFee: '0.001', + totalFee: direction === 'DEPOSIT' + ? '0.011' + : '0.002' + }; } }, { enabled: !!connectedAccount && !!selectedLowNetwork && !!selectedHighNetwork && !!value && !!bridger, retry: 2, - retryDelay: 1000, - staleTime: 30000, - cacheTime: 60000, + keepPreviousData: true } ) } @@ -132,27 +134,27 @@ export const useBridger = () => { selectedLowNetwork: NetworkInterface selectedHighNetwork: NetworkInterface connectedAccount: string - }) => { + }) => { return useQuery( - ['allowances', bridger, direction, selectedLowNetwork.chainId, selectedHighNetwork.chainId, connectedAccount], - async () => { - if (!bridger || !connectedAccount) return null - - const rpc = direction === 'DEPOSIT' ? selectedLowNetwork.rpcs[0] : selectedHighNetwork.rpcs[0] - - const bridgeTokenAllowance = await bridger.getAllowance(rpc, connectedAccount) - const nativeTokenAllowance = await bridger.getNativeAllowance(rpc, connectedAccount) - - return { - bridgeTokenAllowance, - nativeTokenAllowance + ['allowances', bridger, direction, selectedLowNetwork.chainId, selectedHighNetwork.chainId, connectedAccount], + async () => { + if (!bridger || !connectedAccount) return null + + const rpc = direction === 'DEPOSIT' ? selectedLowNetwork.rpcs[0] : selectedHighNetwork.rpcs[0] + + const bridgeTokenAllowance = await bridger.getAllowance(rpc, connectedAccount) + const nativeTokenAllowance = await bridger.getNativeAllowance(rpc, connectedAccount) + + return { + bridgeTokenAllowance, + nativeTokenAllowance + } + }, + { + enabled: !!bridger && !!connectedAccount } - }, - { - enabled: !!bridger && !!connectedAccount - } ) - } + } return { getEstimatedFee, diff --git a/webapps/world-builder-dashboard/src/hooks/useCoinGeckoAPI.ts b/webapps/world-builder-dashboard/src/hooks/useCoinGeckoAPI.ts index dd1bc4a3..b1d73ffe 100644 --- a/webapps/world-builder-dashboard/src/hooks/useCoinGeckoAPI.ts +++ b/webapps/world-builder-dashboard/src/hooks/useCoinGeckoAPI.ts @@ -13,6 +13,7 @@ export const useCoinGeckoAPI = () => { throw new Error(`Error: ${res.statusText}`) } const data = await res.json() + console.log('data', data) return data }, { From 1cb5fe667643fe48dd51e282b91884712a7f3b6e Mon Sep 17 00:00:00 2001 From: Memo Khoury Date: Mon, 16 Dec 2024 21:23:05 +0000 Subject: [PATCH 02/12] update on dropdown --- .../src/components/bridge/history/Deposit.tsx | 80 ++++++++++++++++--- 1 file changed, 70 insertions(+), 10 deletions(-) diff --git a/webapps/world-builder-dashboard/src/components/bridge/history/Deposit.tsx b/webapps/world-builder-dashboard/src/components/bridge/history/Deposit.tsx index b4e49c91..6d12d285 100644 --- a/webapps/world-builder-dashboard/src/components/bridge/history/Deposit.tsx +++ b/webapps/world-builder-dashboard/src/components/bridge/history/Deposit.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import React, { useState } from 'react' import { getHighNetworks, getLowNetworks } from '../../../../constants' import DepositMobile from './DepositMobile' import styles from './WithdrawTransactions.module.css' @@ -30,6 +30,9 @@ const Deposit: React.FC = ({ deposit }) => { const { data: highNetworkTimestamp } = getHighNetworkTimestamp({ txRecord: deposit, transferStatus: transferStatus }) const { data: transactionInputs, isLoading: isLoadingInputs } = getTransactionInputs({ txRecord: deposit }) const finalTransactionInputs = transactionInputs || deposit.transactionInputs + const [collapseExecuted, setCollapseExecuted] = useState(false) + const [hovered, setHovered] = useState(false) + return ( <> {isLoading && smallView ? ( @@ -49,15 +52,36 @@ const Deposit: React.FC = ({ deposit }) => { /> ) : ( <> -
+
setCollapseExecuted(!collapseExecuted)} + style={{ + cursor: 'pointer', + backgroundColor: hovered ? '#393939' : 'initial' + }} + onMouseEnter={() => setHovered(true)} + onMouseLeave={() => setHovered(false)} + >
Deposit -
-
{timeAgo(deposit.lowNetworkTimestamp)}
+
setCollapseExecuted(!collapseExecuted)} + style={{ + cursor: 'pointer', + backgroundColor: hovered ? '#393939' : 'initial' + }} + onMouseEnter={() => setHovered(true)} + onMouseLeave={() => setHovered(false)}>{timeAgo(deposit.lowNetworkTimestamp)}
{!isLoadingInputs && finalTransactionInputs?.tokenSymbol ? ( -
+
setCollapseExecuted(!collapseExecuted)} + style={{ + cursor: 'pointer', + backgroundColor: hovered ? '#393939' : 'initial' + }} + onMouseEnter={() => setHovered(true)} + onMouseLeave={() => setHovered(false)}> {`${finalTransactionInputs.tokenSymbol === 'USDC' ? ethers.utils.formatUnits(finalTransactionInputs.amount, 6) : deposit.amount} ${finalTransactionInputs.tokenSymbol}`} @@ -69,8 +93,24 @@ const Deposit: React.FC = ({ deposit }) => {
)} -
{depositInfo.from}
-
{depositInfo.to}
+
setCollapseExecuted(!collapseExecuted)} + style={{ + cursor: 'pointer', + backgroundColor: hovered ? '#393939' : 'initial' + }} + onMouseEnter={() => setHovered(true)} + onMouseLeave={() => setHovered(false)}>{depositInfo.from}
+
setCollapseExecuted(!collapseExecuted)} + style={{ + cursor: 'pointer', + backgroundColor: hovered ? '#393939' : 'initial' + }} + onMouseEnter={() => setHovered(true)} + onMouseLeave={() => setHovered(false)} + className={styles.gridItem}>{depositInfo.to}
<> {/* First column */} {isLoading || transferStatus?.status === undefined ? ( @@ -83,7 +123,13 @@ const Deposit: React.FC = ({ deposit }) => { target={'_blank'} className={styles.explorerLink} > -
+
setCollapseExecuted(!collapseExecuted)} + style={{ + cursor: 'pointer', + backgroundColor: hovered ? '#393939' : 'initial' + }} + onMouseEnter={() => setHovered(true)} + onMouseLeave={() => setHovered(false)}> {transferStatus?.status === BridgeTransferStatus.DEPOSIT_ERC20_REDEEMED || transferStatus?.status === BridgeTransferStatus.DEPOSIT_GAS_DEPOSITED || transferStatus?.status === BridgeTransferStatus.DEPOSIT_ERC20_FUNDS_DEPOSITED_ON_CHILD ? ( @@ -103,11 +149,25 @@ const Deposit: React.FC = ({ deposit }) => { {/* Second column */} {isLoading || transferStatus?.status === undefined || !highNetworkTimestamp ? ( -
+
setCollapseExecuted(!collapseExecuted)} + style={{ + cursor: 'pointer', + backgroundColor: hovered ? '#393939' : 'initial' + }} + onMouseEnter={() => setHovered(true)} + onMouseLeave={() => setHovered(false)}>
Loading
) : ( -
+
setCollapseExecuted(!collapseExecuted)} + style={{ + cursor: 'pointer', + backgroundColor: hovered ? '#393939' : 'initial' + }} + onMouseEnter={() => setHovered(true)} + onMouseLeave={() => setHovered(false)}> {transferStatus?.status === BridgeTransferStatus.DEPOSIT_ERC20_REDEEMED || transferStatus?.status === BridgeTransferStatus.DEPOSIT_GAS_DEPOSITED || transferStatus?.status === BridgeTransferStatus.DEPOSIT_ERC20_FUNDS_DEPOSITED_ON_CHILD ? ( From 11c8171c884f6ff9ea8b011b8709d9ca82098463 Mon Sep 17 00:00:00 2001 From: Memo Khoury Date: Tue, 17 Dec 2024 15:28:17 +0000 Subject: [PATCH 03/12] update --- webapps/world-builder-dashboard/package-lock.json | 8 ++++---- webapps/world-builder-dashboard/package.json | 2 +- .../src/components/bridge/bridge/ActionButton.tsx | 8 ++++++-- .../src/components/bridge/bridge/BridgeView.tsx | 4 ++-- .../src/utils/bridge/depositERC20ArbitrumSDK.ts | 1 + 5 files changed, 14 insertions(+), 9 deletions(-) diff --git a/webapps/world-builder-dashboard/package-lock.json b/webapps/world-builder-dashboard/package-lock.json index 3061befb..1b0c46c3 100644 --- a/webapps/world-builder-dashboard/package-lock.json +++ b/webapps/world-builder-dashboard/package-lock.json @@ -16,7 +16,7 @@ "clsx": "^1.2.1", "dayjs": "^1.11.11", "dotenv": "^16.4.7", - "game7-bridge-sdk": "^0.0.69", + "game7-bridge-sdk": "^0.0.72", "history": "^5.3.0", "prettier-plugin-tailwindcss": "^0.6.5", "react": "^18.2.0", @@ -6893,9 +6893,9 @@ } }, "node_modules/game7-bridge-sdk": { - "version": "0.0.69", - "resolved": "https://registry.npmjs.org/game7-bridge-sdk/-/game7-bridge-sdk-0.0.69.tgz", - "integrity": "sha512-NDEfCMJ23TwBMfSyvhJRks7hOASW+Qo13o2o6mI9yKcPlDccbH0SegCW3rqAO2f+hAbo1t1eg+Ww4V0Ua7yv4g==", + "version": "0.0.72", + "resolved": "https://registry.npmjs.org/game7-bridge-sdk/-/game7-bridge-sdk-0.0.72.tgz", + "integrity": "sha512-NlGao/R+QZfH6GPLhbhEAvBkaEFmnO67xnHDxr3jAMvo3jMtmm7aby8Y8S1cmN0q8w8RyuYhnz0FBPTWUdgiQA==", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/webapps/world-builder-dashboard/package.json b/webapps/world-builder-dashboard/package.json index 75237cd3..ecba79bf 100644 --- a/webapps/world-builder-dashboard/package.json +++ b/webapps/world-builder-dashboard/package.json @@ -19,7 +19,7 @@ "clsx": "^1.2.1", "dayjs": "^1.11.11", "dotenv": "^16.4.7", - "game7-bridge-sdk": "^0.0.70", + "game7-bridge-sdk": "^0.0.72", "history": "^5.3.0", "prettier-plugin-tailwindcss": "^0.6.5", "react": "^18.2.0", diff --git a/webapps/world-builder-dashboard/src/components/bridge/bridge/ActionButton.tsx b/webapps/world-builder-dashboard/src/components/bridge/bridge/ActionButton.tsx index 7e185179..0fdfe91a 100644 --- a/webapps/world-builder-dashboard/src/components/bridge/bridge/ActionButton.tsx +++ b/webapps/world-builder-dashboard/src/components/bridge/bridge/ActionButton.tsx @@ -175,6 +175,7 @@ const ActionButton: React.FC = ({ connectedAccount: connectedAccount }) if (bridger?.isDeposit) { + const isCCTP = bridger?.isCctp const tx = await bridger?.transfer({ amount: amountToSend, signer, destinationProvider }) await tx?.wait() return { @@ -190,9 +191,11 @@ const ActionButton: React.FC = ({ status: destinationTokenAddress === ZERO_ADDRESS ? BridgeTransferStatus.DEPOSIT_GAS_PENDING - : BridgeTransferStatus.DEPOSIT_ERC20_NOT_YET_CREATED + : BridgeTransferStatus.DEPOSIT_ERC20_NOT_YET_CREATED, + isCCTP: isCCTP } } else { + const isCCTP = bridger?.isCctp const tx = await bridger?.transfer({ amount: amountToSend, signer, destinationProvider }) await tx?.wait() return { @@ -204,7 +207,8 @@ const ActionButton: React.FC = ({ highNetworkTimestamp: Date.now() / 1000, challengePeriod: selectedNetworkType === 'Testnet' ? 60 * 60 : 60 * 60 * 24 * 7, symbol: symbol, - status: BridgeTransferStatus.WITHDRAW_UNCONFIRMED + status: BridgeTransferStatus.WITHDRAW_UNCONFIRMED, + isCCTP: isCCTP } } }, diff --git a/webapps/world-builder-dashboard/src/components/bridge/bridge/BridgeView.tsx b/webapps/world-builder-dashboard/src/components/bridge/bridge/BridgeView.tsx index 9da4bb49..9f437244 100644 --- a/webapps/world-builder-dashboard/src/components/bridge/bridge/BridgeView.tsx +++ b/webapps/world-builder-dashboard/src/components/bridge/bridge/BridgeView.tsx @@ -13,7 +13,7 @@ import { import styles from './BridgeView.module.css' import { ethers } from 'ethers' // G7 SDK -import { Bridger } from 'game7-bridge-sdk' +import { Bridger, getBridger } from 'game7-bridge-sdk' // Components import ActionButton from '@/components/bridge/bridge/ActionButton' import BridgeMessage from '@/components/bridge/bridge/BridgeMessage' @@ -125,7 +125,7 @@ const BridgeView = ({ ) ?? null setSelectedNativeToken(token) } - const _bridger: Bridger = new Bridger(originChainId, destinationChainId, selectedBridgeToken.tokenAddressMap) + const _bridger: Bridger = getBridger(originChainId, destinationChainId, selectedBridgeToken.tokenAddressMap) setBridger(_bridger) } catch (e) { diff --git a/webapps/world-builder-dashboard/src/utils/bridge/depositERC20ArbitrumSDK.ts b/webapps/world-builder-dashboard/src/utils/bridge/depositERC20ArbitrumSDK.ts index 9bd37793..5c3fb85e 100644 --- a/webapps/world-builder-dashboard/src/utils/bridge/depositERC20ArbitrumSDK.ts +++ b/webapps/world-builder-dashboard/src/utils/bridge/depositERC20ArbitrumSDK.ts @@ -42,6 +42,7 @@ export interface TransactionRecord { ETA?: number tokenAddress?: string transactionInputs?: BridgeTransferInfo + isCCTP?: boolean } export const depositERC20ArbitrumSDK = async ( From 9222b094754c9cb51876d1d141e20d69d373a6a8 Mon Sep 17 00:00:00 2001 From: Memo Khoury Date: Tue, 17 Dec 2024 16:17:18 +0000 Subject: [PATCH 04/12] fix error of withdrawals coming back undef. --- .../src/components/bridge/history/Deposit.tsx | 1 - .../src/hooks/useBridgeTransfer.ts | 33 ++++++++++--------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/webapps/world-builder-dashboard/src/components/bridge/history/Deposit.tsx b/webapps/world-builder-dashboard/src/components/bridge/history/Deposit.tsx index 6d12d285..d6a01676 100644 --- a/webapps/world-builder-dashboard/src/components/bridge/history/Deposit.tsx +++ b/webapps/world-builder-dashboard/src/components/bridge/history/Deposit.tsx @@ -32,7 +32,6 @@ const Deposit: React.FC = ({ deposit }) => { const finalTransactionInputs = transactionInputs || deposit.transactionInputs const [collapseExecuted, setCollapseExecuted] = useState(false) const [hovered, setHovered] = useState(false) - return ( <> {isLoading && smallView ? ( diff --git a/webapps/world-builder-dashboard/src/hooks/useBridgeTransfer.ts b/webapps/world-builder-dashboard/src/hooks/useBridgeTransfer.ts index d82324cb..6ec6fa44 100644 --- a/webapps/world-builder-dashboard/src/hooks/useBridgeTransfer.ts +++ b/webapps/world-builder-dashboard/src/hooks/useBridgeTransfer.ts @@ -3,7 +3,7 @@ import { useQuery } from 'react-query' import { useNavigate } from 'react-router-dom' import { getNetworks, L1_MAIN_NETWORK, L1_NETWORK, L2_MAIN_NETWORK, L2_NETWORK } from '../../constants' import { ethers } from 'ethers' -import { BridgeTransfer, BridgeTransferStatus } from 'game7-bridge-sdk' +import { BridgeTransfer, BridgeTransferStatus, getBridgeTransfer } from 'game7-bridge-sdk' import { useBlockchainContext } from '@/contexts/BlockchainContext' import { useBridgeNotificationsContext } from '@/contexts/BridgeNotificationsContext' import { TransactionRecord } from '@/utils/bridge/depositERC20ArbitrumSDK' @@ -65,15 +65,16 @@ export const useBridgeTransfer = () => { return useQuery( ['transferData', txHash], async () => { - const _bridgeTransfer = new BridgeTransfer({ - txHash: txHash ?? '', - destinationNetworkChainId: destinationChainId ?? 0, - originNetworkChainId: originChainId ?? 0, - destinationSignerOrProviderOrRpc: destinationRpc, - originSignerOrProviderOrRpc: originRpc - }) try { + const _bridgeTransfer: BridgeTransfer = await getBridgeTransfer({ + txHash: txHash ?? '', + destinationNetworkChainId: destinationChainId ?? 0, + originNetworkChainId: originChainId ?? 0, + destinationSignerOrProviderOrRpc: destinationRpc, + originSignerOrProviderOrRpc: originRpc + }, txRecord.isCCTP) + console.log(_bridgeTransfer) // Fetch status with retry logic status = await retryWithExponentialBackoff(async () => await _bridgeTransfer.getStatus()) @@ -95,7 +96,7 @@ export const useBridgeTransfer = () => { return status } catch (error) { - console.error('Error fetching status:', error) + console.log('Error fetching status:', error, originChainId, destinationChainId, txRecord.tokenAddress, txHash) // Fallback to cached status if available const transactions = getCachedTransactions(connectedAccount ?? '', selectedNetworkType) @@ -129,7 +130,7 @@ export const useBridgeTransfer = () => { const cachedTx = getCachedTransactions(connectedAccount ?? '', selectedNetworkType).find((t: any) => t.type === 'DEPOSIT' ? t.lowNetworkHash === txHash : t.highNetworkHash === txHash ) - + return shouldFetchStatus(cachedTx) ? 1 * 60 * 1000 : false }, refetchOnWindowFocus: false, @@ -168,7 +169,7 @@ export const useBridgeTransfer = () => { const signer = provider.getSigner() // Bridge Transfer execute - const _bridgeTransfer = new BridgeTransfer({ + const _bridgeTransfer: BridgeTransfer = await getBridgeTransfer({ txHash: withdrawal.highNetworkHash || '', destinationNetworkChainId: withdrawal.lowNetworkChainId ?? 0, originNetworkChainId: withdrawal.highNetworkChainId ?? 0, @@ -178,7 +179,7 @@ export const useBridgeTransfer = () => { originSignerOrProviderOrRpc: getNetworks(selectedNetworkType)?.find( (n) => n.chainId === withdrawal.highNetworkChainId )?.rpcs[0] - }) + }, withdrawal.isCCTP) const res = await _bridgeTransfer?.execute(signer) return { res, withdrawal } }, @@ -237,13 +238,13 @@ export const useBridgeTransfer = () => { return txRecord.transactionInputs } - const _bridgeTransfer = new BridgeTransfer({ + const _bridgeTransfer: BridgeTransfer = await getBridgeTransfer({ txHash: txHash ?? '', destinationNetworkChainId: destinationChainId ?? 0, originNetworkChainId: originChainId ?? 0, destinationSignerOrProviderOrRpc: destinationRpc, originSignerOrProviderOrRpc: originRpc - }) + }, txRecord.isCCTP) const transactionInputs = await _bridgeTransfer.getInfo() @@ -270,11 +271,11 @@ export const useBridgeTransfer = () => { const cachedTransaction = transactions.find((t: any) => isDeposit ? t.lowNetworkHash === txRecord.lowNetworkHash : t.highNetworkHash === txRecord.highNetworkHash ) - + if (cachedTransaction?.transactionInputs) { return cachedTransaction.transactionInputs } - + return null }, staleTime: 2 * 60 * 1000, From 4a72d23e966bd9d65e1ca752774f70810ead3467 Mon Sep 17 00:00:00 2001 From: Memo Khoury Date: Tue, 17 Dec 2024 19:44:41 +0000 Subject: [PATCH 05/12] so the cctp wont rescue me but let me be me so lets just see --- .../components/bridge/bridge/ActionButton.tsx | 18 +- .../components/bridge/bridge/BridgeView.tsx | 1 + .../bridge/bridge/TransactionSummary.tsx | 3 +- .../src/components/bridge/history/Deposit.tsx | 261 +++++++++++------- .../bridge/history/HistoryDesktop.tsx | 1 + .../components/bridge/history/Withdrawal.tsx | 3 +- .../src/hooks/useBridgeTransfer.ts | 118 ++++---- 7 files changed, 245 insertions(+), 160 deletions(-) diff --git a/webapps/world-builder-dashboard/src/components/bridge/bridge/ActionButton.tsx b/webapps/world-builder-dashboard/src/components/bridge/bridge/ActionButton.tsx index 0fdfe91a..445909b0 100644 --- a/webapps/world-builder-dashboard/src/components/bridge/bridge/ActionButton.tsx +++ b/webapps/world-builder-dashboard/src/components/bridge/bridge/ActionButton.tsx @@ -98,7 +98,7 @@ const ActionButton: React.FC = ({ const needsBridgeTokenApproval = bridgeAllowance?.lt(amountBN) const gasFeesAmount = gasFees?.[1] ? ethers.utils.parseUnits(gasFees[1], 18) : amountBN const needsNativeTokenApproval = nativeAllowance !== null ? nativeAllowance?.lt(gasFeesAmount) : false - + if (needsBridgeTokenApproval || needsNativeTokenApproval) { setStartingTokenIndex(needsBridgeTokenApproval ? 0 : 1) setShowApproval(true) @@ -175,7 +175,7 @@ const ActionButton: React.FC = ({ connectedAccount: connectedAccount }) if (bridger?.isDeposit) { - const isCCTP = bridger?.isCctp + const isCCTP = bridger?.isCctp() const tx = await bridger?.transfer({ amount: amountToSend, signer, destinationProvider }) await tx?.wait() return { @@ -191,11 +191,13 @@ const ActionButton: React.FC = ({ status: destinationTokenAddress === ZERO_ADDRESS ? BridgeTransferStatus.DEPOSIT_GAS_PENDING - : BridgeTransferStatus.DEPOSIT_ERC20_NOT_YET_CREATED, + : isCCTP + ? BridgeTransferStatus.CCTP_PENDING + : BridgeTransferStatus.DEPOSIT_ERC20_NOT_YET_CREATED, isCCTP: isCCTP } } else { - const isCCTP = bridger?.isCctp + const isCCTP = bridger?.isCctp() const tx = await bridger?.transfer({ amount: amountToSend, signer, destinationProvider }) await tx?.wait() return { @@ -207,7 +209,10 @@ const ActionButton: React.FC = ({ highNetworkTimestamp: Date.now() / 1000, challengePeriod: selectedNetworkType === 'Testnet' ? 60 * 60 : 60 * 60 * 24 * 7, symbol: symbol, - status: BridgeTransferStatus.WITHDRAW_UNCONFIRMED, + status: + isCCTP + ? BridgeTransferStatus.CCTP_PENDING + : BridgeTransferStatus.WITHDRAW_UNCONFIRMED, isCCTP: isCCTP } } @@ -223,6 +228,7 @@ const ActionButton: React.FC = ({ if (transactionsString) { transactions = JSON.parse(transactionsString) } + console.log(record) transactions.push(record) localStorage.setItem( `bridge-${connectedAccount}-transactions-${selectedNetworkType}`, @@ -287,7 +293,7 @@ const ActionButton: React.FC = ({ (isDisabled || Number(amount) < 0 || ((!L2L3message?.destination || !L2L3message.data) && Number(amount) === 0)) || - isLoadingAllowances + isLoadingAllowances } >
diff --git a/webapps/world-builder-dashboard/src/components/bridge/bridge/BridgeView.tsx b/webapps/world-builder-dashboard/src/components/bridge/bridge/BridgeView.tsx index 9f437244..bd746660 100644 --- a/webapps/world-builder-dashboard/src/components/bridge/bridge/BridgeView.tsx +++ b/webapps/world-builder-dashboard/src/components/bridge/bridge/BridgeView.tsx @@ -103,6 +103,7 @@ const BridgeView = ({ selectedHighNetwork, connectedAccount: connectedAccount ?? '' }) + console.log(allowances) useEffect(() => { if (selectedBridgeToken && connectedAccount && selectedHighNetwork && selectedLowNetwork) { diff --git a/webapps/world-builder-dashboard/src/components/bridge/bridge/TransactionSummary.tsx b/webapps/world-builder-dashboard/src/components/bridge/bridge/TransactionSummary.tsx index d79b4071..93af8451 100644 --- a/webapps/world-builder-dashboard/src/components/bridge/bridge/TransactionSummary.tsx +++ b/webapps/world-builder-dashboard/src/components/bridge/bridge/TransactionSummary.tsx @@ -62,8 +62,7 @@ const TransactionSummary: React.FC = ({ } const isXsScreen = useMediaQuery(`(max-width: ${mantineBreakpoints.xs})`) - console.log(isEstimatingFee) - + return (
Transaction Summary
diff --git a/webapps/world-builder-dashboard/src/components/bridge/history/Deposit.tsx b/webapps/world-builder-dashboard/src/components/bridge/history/Deposit.tsx index d6a01676..b699d069 100644 --- a/webapps/world-builder-dashboard/src/components/bridge/history/Deposit.tsx +++ b/webapps/world-builder-dashboard/src/components/bridge/history/Deposit.tsx @@ -24,8 +24,7 @@ const Deposit: React.FC = ({ deposit }) => { from: getLowNetworks(selectedNetworkType)?.find((n) => n.chainId === deposit.lowNetworkChainId)?.displayName ?? '', to: getHighNetworks(selectedNetworkType)?.find((n) => n.chainId === deposit.highNetworkChainId)?.displayName ?? '' } - - const { returnTransferData, getTransactionInputs, getHighNetworkTimestamp } = useBridgeTransfer() + const { returnTransferData, getTransactionInputs, getHighNetworkTimestamp, claim } = useBridgeTransfer() const { data: transferStatus, isLoading } = returnTransferData({ txRecord: deposit }) const { data: highNetworkTimestamp } = getHighNetworkTimestamp({ txRecord: deposit, transferStatus: transferStatus }) const { data: transactionInputs, isLoading: isLoadingInputs } = getTransactionInputs({ txRecord: deposit }) @@ -51,77 +50,31 @@ const Deposit: React.FC = ({ deposit }) => { /> ) : ( <> -
setCollapseExecuted(!collapseExecuted)} - style={{ - cursor: 'pointer', - backgroundColor: hovered ? '#393939' : 'initial' - }} - onMouseEnter={() => setHovered(true)} - onMouseLeave={() => setHovered(false)} - > -
- Deposit -
-
-
setCollapseExecuted(!collapseExecuted)} - style={{ - cursor: 'pointer', - backgroundColor: hovered ? '#393939' : 'initial' - }} - onMouseEnter={() => setHovered(true)} - onMouseLeave={() => setHovered(false)}>{timeAgo(deposit.lowNetworkTimestamp)}
- {!isLoadingInputs && finalTransactionInputs?.tokenSymbol ? ( -
setCollapseExecuted(!collapseExecuted)} - style={{ - cursor: 'pointer', - backgroundColor: hovered ? '#393939' : 'initial' - }} - onMouseEnter={() => setHovered(true)} - onMouseLeave={() => setHovered(false)}> - {`${finalTransactionInputs.tokenSymbol === 'USDC' - ? ethers.utils.formatUnits(finalTransactionInputs.amount, 6) - : deposit.amount} ${finalTransactionInputs.tokenSymbol}`} -
- ) : ( -
-
- Loading -
-
- )} -
setCollapseExecuted(!collapseExecuted)} - style={{ - cursor: 'pointer', - backgroundColor: hovered ? '#393939' : 'initial' - }} - onMouseEnter={() => setHovered(true)} - onMouseLeave={() => setHovered(false)}>{depositInfo.from}
-
setCollapseExecuted(!collapseExecuted)} - style={{ - cursor: 'pointer', - backgroundColor: hovered ? '#393939' : 'initial' - }} - onMouseEnter={() => setHovered(true)} - onMouseLeave={() => setHovered(false)} - className={styles.gridItem}>{depositInfo.to}
- <> - {/* First column */} - {isLoading || transferStatus?.status === undefined ? ( -
-
Loading
-
- ) : ( - +
setCollapseExecuted(!collapseExecuted)} + style={{ + cursor: 'pointer', + backgroundColor: hovered ? '#393939' : 'initial' + }} + onMouseEnter={() => setHovered(true)} + onMouseLeave={() => setHovered(false)} > +
+ Deposit +
+
+
setCollapseExecuted(!collapseExecuted)} + style={{ + cursor: 'pointer', + backgroundColor: hovered ? '#393939' : 'initial' + }} + onMouseEnter={() => setHovered(true)} + onMouseLeave={() => setHovered(false)}>{timeAgo(deposit.lowNetworkTimestamp)}
+ {!isLoadingInputs && finalTransactionInputs?.tokenSymbol ? (
setCollapseExecuted(!collapseExecuted)} style={{ cursor: 'pointer', @@ -129,50 +82,154 @@ const Deposit: React.FC = ({ deposit }) => { }} onMouseEnter={() => setHovered(true)} onMouseLeave={() => setHovered(false)}> - {transferStatus?.status === BridgeTransferStatus.DEPOSIT_ERC20_REDEEMED || - transferStatus?.status === BridgeTransferStatus.DEPOSIT_GAS_DEPOSITED || - transferStatus?.status === BridgeTransferStatus.DEPOSIT_ERC20_FUNDS_DEPOSITED_ON_CHILD ? ( -
- Completed - -
- ) : ( -
- Pending - -
- )} + {`${finalTransactionInputs.tokenSymbol === 'USDC' + ? ethers.utils.formatUnits(finalTransactionInputs.amount, 6) + : deposit.amount} ${finalTransactionInputs.tokenSymbol}`}
-
- )} - - {/* Second column */} - {isLoading || transferStatus?.status === undefined || !highNetworkTimestamp ? ( -
+
+ Loading +
+
+ )} +
setCollapseExecuted(!collapseExecuted)} style={{ cursor: 'pointer', backgroundColor: hovered ? '#393939' : 'initial' }} onMouseEnter={() => setHovered(true)} - onMouseLeave={() => setHovered(false)}> -
Loading
-
- ) : ( -
setHovered(false)}>{depositInfo.from}
+
setCollapseExecuted(!collapseExecuted)} style={{ cursor: 'pointer', backgroundColor: hovered ? '#393939' : 'initial' }} onMouseEnter={() => setHovered(true)} - onMouseLeave={() => setHovered(false)}> - {transferStatus?.status === BridgeTransferStatus.DEPOSIT_ERC20_REDEEMED || - transferStatus?.status === BridgeTransferStatus.DEPOSIT_GAS_DEPOSITED || - transferStatus?.status === BridgeTransferStatus.DEPOSIT_ERC20_FUNDS_DEPOSITED_ON_CHILD ? ( - <>{timeAgo(highNetworkTimestamp)} + onMouseLeave={() => setHovered(false)} + className={styles.gridItem}>{depositInfo.to}
+
setCollapseExecuted(!collapseExecuted)} + style={{ + cursor: 'pointer', + backgroundColor: hovered ? '#393939' : 'initial' + }} + onMouseEnter={() => setHovered(true)} + onMouseLeave={() => setHovered(false)} + > + +
setCollapseExecuted(!collapseExecuted)}> + Completed + +
+
+
+
setCollapseExecuted(!collapseExecuted)} + style={{ + cursor: 'pointer', + backgroundColor: hovered ? '#393939' : 'initial' + }} + onMouseEnter={() => setHovered(true)} + onMouseLeave={() => setHovered(false)} + > +
{timeAgo(deposit?.completionTimestamp)}
+
+ + ) : ( + <> +
+
+ Deposit +
+
+
+ {timeAgo(deposit.lowNetworkTimestamp)} +
+ {!isLoadingInputs && finalTransactionInputs?.tokenSymbol ? ( +
+ {`${finalTransactionInputs.tokenSymbol === 'USDC' + ? ethers.utils.formatUnits(finalTransactionInputs.amount, 6) + : deposit.amount} ${finalTransactionInputs.tokenSymbol}`} +
+ ) : ( +
+
+ Loading +
+
+ )} +
{depositInfo.from}
+
{depositInfo.to}
+ + )} + <> + {isLoading || transferStatus?.status === undefined ? ( +
+
Loading
+
+ ) : ( + +
+
+ Completed + +
+
+
+ )} + {isLoading || transferStatus?.status === undefined || !highNetworkTimestamp ? ( +
+
Loading
+
+ ) : ( +
+ {transferStatus?.status === BridgeTransferStatus.CCTP_COMPLETE ? ( + <> + +
+ +
+ ) : ( - <>{ETA(deposit.lowNetworkTimestamp, deposit.retryableCreationTimeout ?? 15 * 60)} + transferStatus?.status === BridgeTransferStatus.DEPOSIT_ERC20_REDEEMED || + transferStatus?.status === BridgeTransferStatus.DEPOSIT_GAS_DEPOSITED || + transferStatus?.status === BridgeTransferStatus.DEPOSIT_ERC20_FUNDS_DEPOSITED_ON_CHILD ? ( + <>{timeAgo(highNetworkTimestamp)} + ) : ( + <>{ETA(deposit.lowNetworkTimestamp, deposit.retryableCreationTimeout ?? 15 * 60)} + ) )}
)} diff --git a/webapps/world-builder-dashboard/src/components/bridge/history/HistoryDesktop.tsx b/webapps/world-builder-dashboard/src/components/bridge/history/HistoryDesktop.tsx index 2e8d0098..a64250b3 100644 --- a/webapps/world-builder-dashboard/src/components/bridge/history/HistoryDesktop.tsx +++ b/webapps/world-builder-dashboard/src/components/bridge/history/HistoryDesktop.tsx @@ -75,6 +75,7 @@ const HistoryDesktop: React.FC = () => { useEffect(() => { const localTransactions = messages || [] const formattedApiTransactions = apiTransactions ? apiTransactions.map(mapAPIDataToTransactionRecord) : [] + console.log(localTransactions) const combinedTransactions = mergeTransactions(formattedApiTransactions, localTransactions) // Retrieve existing transactions from localStorage diff --git a/webapps/world-builder-dashboard/src/components/bridge/history/Withdrawal.tsx b/webapps/world-builder-dashboard/src/components/bridge/history/Withdrawal.tsx index dd893bbf..22dbdf06 100644 --- a/webapps/world-builder-dashboard/src/components/bridge/history/Withdrawal.tsx +++ b/webapps/world-builder-dashboard/src/components/bridge/history/Withdrawal.tsx @@ -13,6 +13,7 @@ import { ETA, timeAgo } from '@/utils/timeFormat' import { getBlockExplorerUrl } from '@/utils/web3utils' import { ChildToParentMessageStatus } from '@arbitrum/sdk' import { useMediaQuery } from '@mantine/hooks' +import { BridgeTransferStatus } from 'game7-bridge-sdk' interface WithdrawalProps { withdrawal: TransactionRecord @@ -309,7 +310,7 @@ const Withdrawal: React.FC = ({ withdrawal }) => { )}
{status?.data?.from ?? ''}
{status?.data?.to ?? ''}
- {transferStatus && transferStatus?.status === ChildToParentMessageStatus.CONFIRMED && ( + {transferStatus && (transferStatus?.status === ChildToParentMessageStatus.CONFIRMED || transferStatus?.status === BridgeTransferStatus.CCTP_COMPLETE) && ( <>
{ destinationSignerOrProviderOrRpc: destinationRpc, originSignerOrProviderOrRpc: originRpc }, txRecord.isCCTP) - console.log(_bridgeTransfer) // Fetch status with retry logic status = await retryWithExponentialBackoff(async () => await _bridgeTransfer.getStatus()) @@ -145,15 +143,27 @@ export const useBridgeTransfer = () => { const queryClient = useQueryClient() const claim = useMutation( - async (withdrawal: TransactionRecord | undefined) => { - if (!withdrawal) { + async (txRecord: TransactionRecord) => { + const isDeposit = txRecord.type === 'DEPOSIT' + const txHash = isDeposit ? txRecord.lowNetworkHash : txRecord.highNetworkHash + const destinationChainId = isDeposit ? txRecord.highNetworkChainId : txRecord.lowNetworkChainId + const originChainId = isDeposit ? txRecord.lowNetworkChainId : txRecord.highNetworkChainId + const destinationRpc = getNetworks(selectedNetworkType)?.find((n) => n.chainId === destinationChainId)?.rpcs[0] + const originRpc = getNetworks(selectedNetworkType)?.find((n) => n.chainId === originChainId)?.rpcs[0] + if (!txRecord) { throw new Error('transaction hash is undefined') } let targetChain - if (selectedNetworkType === 'Testnet') - targetChain = withdrawal.highNetworkChainId === L2_NETWORK.chainId ? L1_NETWORK : L2_NETWORK - else targetChain = withdrawal.highNetworkChainId === L2_MAIN_NETWORK.chainId ? L1_MAIN_NETWORK : L2_MAIN_NETWORK + if (selectedNetworkType === 'Testnet' ) + targetChain = originChainId === L2_NETWORK.chainId ? L1_NETWORK : L2_NETWORK + else { + if (isDeposit && txRecord.isCCTP && txRecord.isCCTP === true) { + targetChain = L2_MAIN_NETWORK + } else { + targetChain = originChainId === L2_MAIN_NETWORK.chainId ? L1_MAIN_NETWORK : L2_MAIN_NETWORK + } + } let provider if (window.ethereum) { @@ -170,35 +180,36 @@ export const useBridgeTransfer = () => { // Bridge Transfer execute const _bridgeTransfer: BridgeTransfer = await getBridgeTransfer({ - txHash: withdrawal.highNetworkHash || '', - destinationNetworkChainId: withdrawal.lowNetworkChainId ?? 0, - originNetworkChainId: withdrawal.highNetworkChainId ?? 0, - destinationSignerOrProviderOrRpc: getNetworks(selectedNetworkType)?.find( - (n) => n.chainId === withdrawal.lowNetworkChainId - )?.rpcs[0], - originSignerOrProviderOrRpc: getNetworks(selectedNetworkType)?.find( - (n) => n.chainId === withdrawal.highNetworkChainId - )?.rpcs[0] - }, withdrawal.isCCTP) + txHash: txHash ?? '', + destinationNetworkChainId: destinationChainId ?? 0, + originNetworkChainId: originChainId ?? 0, + destinationSignerOrProviderOrRpc: destinationRpc, + originSignerOrProviderOrRpc: originRpc + }, txRecord.isCCTP) const res = await _bridgeTransfer?.execute(signer) - return { res, withdrawal } + return { res, txRecord } }, { - onSuccess: ({ res, withdrawal }) => { + onSuccess: ({ res, txRecord }) => { + const isDeposit = txRecord.type === 'DEPOSIT' + const txHash = isDeposit ? txRecord.lowNetworkHash : txRecord.highNetworkHash try { const transactionsString = localStorage.getItem( `bridge-${connectedAccount}-transactions-${selectedNetworkType}` ) let transactions = transactionsString ? JSON.parse(transactionsString) : [] const newTransactions: TransactionRecord[] = transactions.map((t: TransactionRecord) => { - if (t.highNetworkHash === withdrawal.highNetworkHash) { + if (isDeposit ? t.lowNetworkHash === txHash : t.highNetworkHash === txHash) { return { ...t, - completionTimestamp: Date.now() / 1000, - lowNetworkTimestamp: Date.now() / 1000, + completionTimestamp: isDeposit ? t.completionTimestamp : Date.now() / 1000, + lowNetworkTimestamp: isDeposit ? t.lowNetworkTimestamp : Date.now() / 1000, newTransaction: true, - lowNetworkHash: res?.transactionHash, - status: BridgeTransferStatus.WITHDRAW_EXECUTED + highNetworkHash: isDeposit ? res?.transactionHash : t.highNetworkHash, + lowNetworkHash: !isDeposit ? res?.transactionHash : t.lowNetworkHash, + status: txRecord.isCCTP + ? BridgeTransferStatus.CCTP_REDEEMED + : !isDeposit ? BridgeTransferStatus.WITHDRAW_EXECUTED : BridgeTransferStatus.DEPOSIT_ERC20_REDEEMED } } return { ...t } @@ -211,7 +222,7 @@ export const useBridgeTransfer = () => { console.log(e) } refetchNewNotifications(connectedAccount ?? '') - queryClient.refetchQueries(['transferData', withdrawal?.highNetworkHash]) + queryClient.refetchQueries(['transferData', isDeposit ? txRecord.lowNetworkHash : txRecord.highNetworkHash]) queryClient.refetchQueries(['incomingMessages']) queryClient.refetchQueries(['ERC20Balance']) queryClient.refetchQueries(['nativeBalance']) @@ -234,36 +245,45 @@ export const useBridgeTransfer = () => { return useQuery( ['transactionInputs', txHash], async () => { - if (txRecord.transactionInputs) { - return txRecord.transactionInputs - } + try { + if (txRecord.transactionInputs) { + return txRecord.transactionInputs + } - const _bridgeTransfer: BridgeTransfer = await getBridgeTransfer({ - txHash: txHash ?? '', - destinationNetworkChainId: destinationChainId ?? 0, - originNetworkChainId: originChainId ?? 0, - destinationSignerOrProviderOrRpc: destinationRpc, - originSignerOrProviderOrRpc: originRpc - }, txRecord.isCCTP) + const _bridgeTransfer: BridgeTransfer = await getBridgeTransfer({ + txHash: txHash ?? '', + destinationNetworkChainId: destinationChainId ?? 0, + originNetworkChainId: originChainId ?? 0, + destinationSignerOrProviderOrRpc: destinationRpc, + originSignerOrProviderOrRpc: originRpc + }, txRecord.isCCTP) - const transactionInputs = await _bridgeTransfer.getInfo() + const transactionInputs = await _bridgeTransfer.getInfo() - const transactions = getCachedTransactions(connectedAccount ?? '', selectedNetworkType) + const transactions = getCachedTransactions(connectedAccount ?? '', selectedNetworkType) - // Update the cache with the latest status - const newTransactions = transactions.map((t: any) => { - const isSameHash = isDeposit - ? t.lowNetworkHash === txRecord.lowNetworkHash - : t.highNetworkHash === txRecord.highNetworkHash + // Update the cache with the latest status + const newTransactions = transactions.map((t: any) => { + const isSameHash = isDeposit + ? t.lowNetworkHash === txRecord.lowNetworkHash + : t.highNetworkHash === txRecord.highNetworkHash - return isSameHash ? { ...t, transactionInputs: transactionInputs } : t - }) + return isSameHash ? { ...t, transactionInputs: transactionInputs } : t + }) - localStorage.setItem( - `bridge-${connectedAccount}-transactions-${selectedNetworkType}`, - JSON.stringify(newTransactions) - ) - return transactionInputs + localStorage.setItem( + `bridge-${connectedAccount}-transactions-${selectedNetworkType}`, + JSON.stringify(newTransactions) + ) + return transactionInputs + } catch (error) { + // Return cached transaction if an error occurs + const transactions = getCachedTransactions(connectedAccount ?? '', selectedNetworkType) + const cachedTransaction = transactions.find((t: any) => + isDeposit ? t.lowNetworkHash === txRecord.lowNetworkHash : t.highNetworkHash === txRecord.highNetworkHash + ) + return cachedTransaction?.transactionInputs || null + } }, { placeholderData: () => { From f357d1d7f27e070946627e08f32d145c860b2b2e Mon Sep 17 00:00:00 2001 From: Memo Khoury Date: Tue, 17 Dec 2024 19:50:23 +0000 Subject: [PATCH 06/12] update deposit --- .../src/components/bridge/history/Deposit.tsx | 113 ++++++++++++++---- 1 file changed, 90 insertions(+), 23 deletions(-) diff --git a/webapps/world-builder-dashboard/src/components/bridge/history/Deposit.tsx b/webapps/world-builder-dashboard/src/components/bridge/history/Deposit.tsx index b699d069..071d2e7b 100644 --- a/webapps/world-builder-dashboard/src/components/bridge/history/Deposit.tsx +++ b/webapps/world-builder-dashboard/src/components/bridge/history/Deposit.tsx @@ -5,7 +5,6 @@ import styles from './WithdrawTransactions.module.css' import { ethers } from 'ethers' import { BridgeTransferStatus } from 'game7-bridge-sdk' import { useMediaQuery } from 'summon-ui/mantine' -import IconArrowNarrowDown from '@/assets/IconArrowNarrowDown' import IconLinkExternal02 from '@/assets/IconLinkExternal02' import { useBlockchainContext } from '@/contexts/BlockchainContext' import { useBridgeTransfer } from '@/hooks/useBridgeTransfer' @@ -111,39 +110,107 @@ const Deposit: React.FC = ({ deposit }) => { onMouseEnter={() => setHovered(true)} onMouseLeave={() => setHovered(false)} className={styles.gridItem}>{depositInfo.to}
-
setCollapseExecuted(!collapseExecuted)} - style={{ - cursor: 'pointer', - backgroundColor: hovered ? '#393939' : 'initial' - }} - onMouseEnter={() => setHovered(true)} - onMouseLeave={() => setHovered(false)} - > + +
setCollapseExecuted(!collapseExecuted)} + style={{ + cursor: 'pointer', + backgroundColor: hovered ? '#393939' : 'initial' + }} + onMouseEnter={() => setHovered(true)} + onMouseLeave={() => setHovered(false)} + > +
{timeAgo(deposit?.completionTimestamp)}
+
+ {collapseExecuted && ( + <> + + {/* INITIATE */} +
+
Initiate
+
+
{timeAgo(deposit?.lowNetworkTimestamp)}
+ {transactionInputs?.tokenSymbol ? ( +
+ {`${transactionInputs.tokenSymbol === 'USDC' ? ethers.utils.formatUnits(transactionInputs.amount, 6) : deposit.amount} ${transactionInputs.tokenSymbol}`} +
+ ) : ( +
+
Loading
+
+ )} +
{depositInfo.from ?? ''}
+
{depositInfo.to ?? ''}
+ +
+
{timeAgo(deposit?.highNetworkTimestamp)}
+
+ + {/* FINALIZE */} +
+
Finalize
+
+
{timeAgo(deposit?.highNetworkTimestamp)}
+ {transactionInputs?.tokenSymbol ? ( +
+ {`${transactionInputs.tokenSymbol === 'USDC' ? ethers.utils.formatUnits(transactionInputs.amount, 6) : deposit.amount} ${transactionInputs.tokenSymbol}`} +
+ ) : ( +
+
Loading
+
+ )} +
{depositInfo.from ?? ''}
+
{depositInfo.to ?? ''}
+
- -
setCollapseExecuted(!collapseExecuted)} - style={{ - cursor: 'pointer', - backgroundColor: hovered ? '#393939' : 'initial' - }} - onMouseEnter={() => setHovered(true)} - onMouseLeave={() => setHovered(false)} - > -
{timeAgo(deposit?.completionTimestamp)}
+
+
{timeAgo(deposit?.highNetworkTimestamp)}
+ + )} ) : ( <> From aff4eb6ae7b2f56ab320f0573e18fbfc886974b9 Mon Sep 17 00:00:00 2001 From: Memo Khoury Date: Tue, 17 Dec 2024 20:02:51 +0000 Subject: [PATCH 07/12] update --- .../src/components/bridge/history/Deposit.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webapps/world-builder-dashboard/src/components/bridge/history/Deposit.tsx b/webapps/world-builder-dashboard/src/components/bridge/history/Deposit.tsx index 071d2e7b..7eb4a26c 100644 --- a/webapps/world-builder-dashboard/src/components/bridge/history/Deposit.tsx +++ b/webapps/world-builder-dashboard/src/components/bridge/history/Deposit.tsx @@ -252,7 +252,7 @@ const Deposit: React.FC = ({ deposit }) => { >
- Completed + Pending
From 7fae955e4d6b780afb7b5d0970bec35131337d2c Mon Sep 17 00:00:00 2001 From: Memo Khoury Date: Wed, 18 Dec 2024 13:21:39 +0000 Subject: [PATCH 08/12] update --- .../world-builder-dashboard/package-lock.json | 8 ++-- webapps/world-builder-dashboard/package.json | 2 +- .../patches/game7-bridge-sdk+0.0.74.patch | 20 ++++++++++ .../src/components/bridge/history/Deposit.tsx | 37 +++++++++---------- .../components/bridge/history/Withdrawal.tsx | 4 +- .../src/hooks/useBridgeTransfer.ts | 13 +++++-- 6 files changed, 55 insertions(+), 29 deletions(-) create mode 100644 webapps/world-builder-dashboard/patches/game7-bridge-sdk+0.0.74.patch diff --git a/webapps/world-builder-dashboard/package-lock.json b/webapps/world-builder-dashboard/package-lock.json index 1b0c46c3..e86693f3 100644 --- a/webapps/world-builder-dashboard/package-lock.json +++ b/webapps/world-builder-dashboard/package-lock.json @@ -16,7 +16,7 @@ "clsx": "^1.2.1", "dayjs": "^1.11.11", "dotenv": "^16.4.7", - "game7-bridge-sdk": "^0.0.72", + "game7-bridge-sdk": "^0.0.74", "history": "^5.3.0", "prettier-plugin-tailwindcss": "^0.6.5", "react": "^18.2.0", @@ -6893,9 +6893,9 @@ } }, "node_modules/game7-bridge-sdk": { - "version": "0.0.72", - "resolved": "https://registry.npmjs.org/game7-bridge-sdk/-/game7-bridge-sdk-0.0.72.tgz", - "integrity": "sha512-NlGao/R+QZfH6GPLhbhEAvBkaEFmnO67xnHDxr3jAMvo3jMtmm7aby8Y8S1cmN0q8w8RyuYhnz0FBPTWUdgiQA==", + "version": "0.0.74", + "resolved": "https://registry.npmjs.org/game7-bridge-sdk/-/game7-bridge-sdk-0.0.74.tgz", + "integrity": "sha512-pD5YbCUaK4i06un+SCn1ArTpNoL/H4jmynptk5wPtVE+UDK3dspZGexgj/0VCHr42pR76EdSBz02K0I2Q2A6Yg==", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/webapps/world-builder-dashboard/package.json b/webapps/world-builder-dashboard/package.json index ecba79bf..40eb6cbb 100644 --- a/webapps/world-builder-dashboard/package.json +++ b/webapps/world-builder-dashboard/package.json @@ -19,7 +19,7 @@ "clsx": "^1.2.1", "dayjs": "^1.11.11", "dotenv": "^16.4.7", - "game7-bridge-sdk": "^0.0.72", + "game7-bridge-sdk": "^0.0.74", "history": "^5.3.0", "prettier-plugin-tailwindcss": "^0.6.5", "react": "^18.2.0", diff --git a/webapps/world-builder-dashboard/patches/game7-bridge-sdk+0.0.74.patch b/webapps/world-builder-dashboard/patches/game7-bridge-sdk+0.0.74.patch new file mode 100644 index 00000000..f5950560 --- /dev/null +++ b/webapps/world-builder-dashboard/patches/game7-bridge-sdk+0.0.74.patch @@ -0,0 +1,20 @@ +diff --git a/node_modules/game7-bridge-sdk/dist/bridgeTransfer.js b/node_modules/game7-bridge-sdk/dist/bridgeTransfer.js +index 9ab8926..24a757a 100644 +--- a/node_modules/game7-bridge-sdk/dist/bridgeTransfer.js ++++ b/node_modules/game7-bridge-sdk/dist/bridgeTransfer.js +@@ -272,11 +272,15 @@ export class BridgeTransfer { + execute(signer) { + return __awaiter(this, void 0, void 0, function* () { + if (!this.childTransactionReceipt) { ++ console.log('here before originreceipt') + const originReceipt = yield this.originProvider.getTransactionReceipt(this.txHash); + this.childTransactionReceipt = new ChildTransactionReceipt(originReceipt); ++ console.log('here after originreceipt') + } ++ console.log('here') + const messages = (yield this.childTransactionReceipt.getChildToParentMessages(signer)); + const message = messages[0]; ++ console.log(message); + const res = yield message.execute(this.originProvider); + return yield res.wait(); + }); diff --git a/webapps/world-builder-dashboard/src/components/bridge/history/Deposit.tsx b/webapps/world-builder-dashboard/src/components/bridge/history/Deposit.tsx index 7eb4a26c..7ff35b96 100644 --- a/webapps/world-builder-dashboard/src/components/bridge/history/Deposit.tsx +++ b/webapps/world-builder-dashboard/src/components/bridge/history/Deposit.tsx @@ -251,14 +251,27 @@ const Deposit: React.FC = ({ deposit }) => { className={styles.explorerLink} >
-
- Pending - -
+ {transferStatus?.status === BridgeTransferStatus.DEPOSIT_ERC20_REDEEMED || + transferStatus?.status === BridgeTransferStatus.DEPOSIT_GAS_DEPOSITED ? ( +
+ Completed + +
+ ) : transferStatus?.status === BridgeTransferStatus.DEPOSIT_ERC20_FUNDS_DEPOSITED_ON_CHILD || transferStatus?.status === BridgeTransferStatus.CCTP_COMPLETE ? ( +
+ Claimable + +
+ ) : ( +
+ Pending + +
+ )}
)} - {isLoading || transferStatus?.status === undefined || !highNetworkTimestamp ? ( + {isLoading || transferStatus?.status === undefined && !highNetworkTimestamp ? (
Loading
@@ -266,19 +279,6 @@ const Deposit: React.FC = ({ deposit }) => {
{transferStatus?.status === BridgeTransferStatus.CCTP_COMPLETE ? ( <> - -
-
) : ( transferStatus?.status === BridgeTransferStatus.DEPOSIT_ERC20_REDEEMED || diff --git a/webapps/world-builder-dashboard/src/components/bridge/history/Withdrawal.tsx b/webapps/world-builder-dashboard/src/components/bridge/history/Withdrawal.tsx index 22dbdf06..51c7e0e9 100644 --- a/webapps/world-builder-dashboard/src/components/bridge/history/Withdrawal.tsx +++ b/webapps/world-builder-dashboard/src/components/bridge/history/Withdrawal.tsx @@ -265,7 +265,7 @@ const Withdrawal: React.FC = ({ withdrawal }) => { {`${transactionInputs.tokenSymbol === 'USDC' ? ethers.utils.formatUnits(transactionInputs.amount, 6) : withdrawal.amount} ${transactionInputs.tokenSymbol}`}
) : ( -
+
Loading
)} @@ -336,7 +336,7 @@ const Withdrawal: React.FC = ({ withdrawal }) => {
)} - {transferStatus && transferStatus?.status === ChildToParentMessageStatus.UNCONFIRMED && ( + {transferStatus && (transferStatus?.status === ChildToParentMessageStatus.UNCONFIRMED || transferStatus?.status === BridgeTransferStatus.CCTP_PENDING) && ( <>
{ destinationSignerOrProviderOrRpc: destinationRpc, originSignerOrProviderOrRpc: originRpc }, txRecord.isCCTP) + // Fetch status with retry logic status = await retryWithExponentialBackoff(async () => await _bridgeTransfer.getStatus()) @@ -155,8 +156,14 @@ export const useBridgeTransfer = () => { } let targetChain - if (selectedNetworkType === 'Testnet' ) - targetChain = originChainId === L2_NETWORK.chainId ? L1_NETWORK : L2_NETWORK + if (selectedNetworkType === 'Testnet' ) { + if (isDeposit && txRecord.isCCTP && txRecord.isCCTP === true) { + targetChain = L2_NETWORK + } else { + targetChain = originChainId === L2_NETWORK.chainId ? L1_NETWORK : L2_NETWORK + } + console.log('targetChain', targetChain) + } else { if (isDeposit && txRecord.isCCTP && txRecord.isCCTP === true) { targetChain = L2_MAIN_NETWORK @@ -164,7 +171,6 @@ export const useBridgeTransfer = () => { targetChain = originChainId === L2_MAIN_NETWORK.chainId ? L1_MAIN_NETWORK : L2_MAIN_NETWORK } } - let provider if (window.ethereum) { provider = new ethers.providers.Web3Provider(window.ethereum) @@ -186,6 +192,7 @@ export const useBridgeTransfer = () => { destinationSignerOrProviderOrRpc: destinationRpc, originSignerOrProviderOrRpc: originRpc }, txRecord.isCCTP) + const res = await _bridgeTransfer?.execute(signer) return { res, txRecord } }, From 9b22fbe7365f80fc9b45fadb418dcdb30e171df3 Mon Sep 17 00:00:00 2001 From: Memo Khoury Date: Wed, 18 Dec 2024 14:34:42 +0000 Subject: [PATCH 09/12] fix structure of deposit and withdrawal --- .../src/components/bridge/history/Deposit.tsx | 130 +++++++++--------- .../components/bridge/history/Withdrawal.tsx | 6 +- .../src/hooks/useBridgeTransfer.ts | 5 +- 3 files changed, 74 insertions(+), 67 deletions(-) diff --git a/webapps/world-builder-dashboard/src/components/bridge/history/Deposit.tsx b/webapps/world-builder-dashboard/src/components/bridge/history/Deposit.tsx index 7ff35b96..cf243444 100644 --- a/webapps/world-builder-dashboard/src/components/bridge/history/Deposit.tsx +++ b/webapps/world-builder-dashboard/src/components/bridge/history/Deposit.tsx @@ -86,7 +86,14 @@ const Deposit: React.FC = ({ deposit }) => { : deposit.amount} ${finalTransactionInputs.tokenSymbol}`}
) : ( -
+
setCollapseExecuted(!collapseExecuted)} + style={{ + cursor: 'pointer', + backgroundColor: hovered ? '#393939' : 'initial' + }} + onMouseEnter={() => setHovered(true)} + onMouseLeave={() => setHovered(false)}>
Loading
@@ -145,7 +152,6 @@ const Deposit: React.FC = ({ deposit }) => {
{collapseExecuted && ( <> - {/* INITIATE */}
Initiate
@@ -237,69 +243,69 @@ const Deposit: React.FC = ({ deposit }) => { )}
{depositInfo.from}
{depositInfo.to}
- - )} - <> - {isLoading || transferStatus?.status === undefined ? ( -
-
Loading
-
- ) : ( -
-
- {transferStatus?.status === BridgeTransferStatus.DEPOSIT_ERC20_REDEEMED || - transferStatus?.status === BridgeTransferStatus.DEPOSIT_GAS_DEPOSITED ? ( -
- Completed - -
- ) : transferStatus?.status === BridgeTransferStatus.DEPOSIT_ERC20_FUNDS_DEPOSITED_ON_CHILD || transferStatus?.status === BridgeTransferStatus.CCTP_COMPLETE ? ( -
- Claimable - -
- ) : ( -
- - )} - {isLoading || transferStatus?.status === undefined && !highNetworkTimestamp ? ( -
-
Loading
-
- ) : ( -
- {transferStatus?.status === BridgeTransferStatus.CCTP_COMPLETE ? ( - <> - - + + )} + {isLoading || transferStatus?.status === undefined && !highNetworkTimestamp ? ( +
+
Loading
+
) : ( - transferStatus?.status === BridgeTransferStatus.DEPOSIT_ERC20_REDEEMED || - transferStatus?.status === BridgeTransferStatus.DEPOSIT_GAS_DEPOSITED || - transferStatus?.status === BridgeTransferStatus.DEPOSIT_ERC20_FUNDS_DEPOSITED_ON_CHILD ? ( - <>{timeAgo(highNetworkTimestamp)} - ) : ( - <>{ETA(deposit.lowNetworkTimestamp, deposit.retryableCreationTimeout ?? 15 * 60)} - ) +
+ {transferStatus?.status === BridgeTransferStatus.CCTP_COMPLETE ? ( + <> + + + ) : ( + transferStatus?.status === BridgeTransferStatus.DEPOSIT_ERC20_REDEEMED || + transferStatus?.status === BridgeTransferStatus.DEPOSIT_GAS_DEPOSITED || + transferStatus?.status === BridgeTransferStatus.DEPOSIT_ERC20_FUNDS_DEPOSITED_ON_CHILD ? ( + <>{timeAgo(highNetworkTimestamp)} + ) : ( + <>{ETA(deposit.lowNetworkTimestamp, deposit.retryableCreationTimeout ?? 15 * 60)} + ) + )} +
)} -
- )} - + + + )} )} diff --git a/webapps/world-builder-dashboard/src/components/bridge/history/Withdrawal.tsx b/webapps/world-builder-dashboard/src/components/bridge/history/Withdrawal.tsx index 51c7e0e9..b1e3315f 100644 --- a/webapps/world-builder-dashboard/src/components/bridge/history/Withdrawal.tsx +++ b/webapps/world-builder-dashboard/src/components/bridge/history/Withdrawal.tsx @@ -34,7 +34,7 @@ export const getStatus = ( highNetworkHash } = withdrawal const status = completionTimestamp - ? ChildToParentMessageStatus.EXECUTED + ? ChildToParentMessageStatus.EXECUTED || BridgeTransferStatus.CCTP_REDEEMED : claimableTimestamp ? ChildToParentMessageStatus.CONFIRMED : ChildToParentMessageStatus.UNCONFIRMED @@ -112,7 +112,7 @@ const Withdrawal: React.FC = ({ withdrawal }) => { ) : ( <> - {transferStatus && transferStatus?.status === ChildToParentMessageStatus.EXECUTED && ( + {transferStatus && (transferStatus?.status === BridgeTransferStatus.WITHDRAW_EXECUTED || transferStatus?.status === BridgeTransferStatus.CCTP_REDEEMED) && ( <>
= ({ withdrawal }) => { )} )} - {transferStatus && transferStatus?.status !== ChildToParentMessageStatus.EXECUTED && ( + {transferStatus && (transferStatus?.status !== BridgeTransferStatus.WITHDRAW_EXECUTED && transferStatus?.status !== BridgeTransferStatus.CCTP_REDEEMED) && ( <>
diff --git a/webapps/world-builder-dashboard/src/hooks/useBridgeTransfer.ts b/webapps/world-builder-dashboard/src/hooks/useBridgeTransfer.ts index a22e56cf..7f922fed 100644 --- a/webapps/world-builder-dashboard/src/hooks/useBridgeTransfer.ts +++ b/webapps/world-builder-dashboard/src/hooks/useBridgeTransfer.ts @@ -76,7 +76,6 @@ export const useBridgeTransfer = () => { // Fetch status with retry logic status = await retryWithExponentialBackoff(async () => await _bridgeTransfer.getStatus()) - const transactions = getCachedTransactions(connectedAccount ?? '', selectedNetworkType) // Update the cache with the latest status @@ -171,6 +170,7 @@ export const useBridgeTransfer = () => { targetChain = originChainId === L2_MAIN_NETWORK.chainId ? L1_MAIN_NETWORK : L2_MAIN_NETWORK } } + console.log(targetChain.chainId) let provider if (window.ethereum) { provider = new ethers.providers.Web3Provider(window.ethereum) @@ -192,7 +192,8 @@ export const useBridgeTransfer = () => { destinationSignerOrProviderOrRpc: destinationRpc, originSignerOrProviderOrRpc: originRpc }, txRecord.isCCTP) - + + await _bridgeTransfer.getStatus() const res = await _bridgeTransfer?.execute(signer) return { res, txRecord } }, From dc4bfe2e8dd321915eda5672fbaf42aa190f1680 Mon Sep 17 00:00:00 2001 From: Memo Khoury Date: Wed, 18 Dec 2024 15:50:22 +0000 Subject: [PATCH 10/12] claim on dep. looking good --- webapps/world-builder-dashboard/package-lock.json | 8 ++++---- webapps/world-builder-dashboard/package.json | 2 +- .../src/components/bridge/history/Deposit.tsx | 4 ++-- .../src/hooks/useBridgeTransfer.ts | 13 +++++++------ 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/webapps/world-builder-dashboard/package-lock.json b/webapps/world-builder-dashboard/package-lock.json index e86693f3..6c13e3f1 100644 --- a/webapps/world-builder-dashboard/package-lock.json +++ b/webapps/world-builder-dashboard/package-lock.json @@ -16,7 +16,7 @@ "clsx": "^1.2.1", "dayjs": "^1.11.11", "dotenv": "^16.4.7", - "game7-bridge-sdk": "^0.0.74", + "game7-bridge-sdk": "^0.0.75", "history": "^5.3.0", "prettier-plugin-tailwindcss": "^0.6.5", "react": "^18.2.0", @@ -6893,9 +6893,9 @@ } }, "node_modules/game7-bridge-sdk": { - "version": "0.0.74", - "resolved": "https://registry.npmjs.org/game7-bridge-sdk/-/game7-bridge-sdk-0.0.74.tgz", - "integrity": "sha512-pD5YbCUaK4i06un+SCn1ArTpNoL/H4jmynptk5wPtVE+UDK3dspZGexgj/0VCHr42pR76EdSBz02K0I2Q2A6Yg==", + "version": "0.0.75", + "resolved": "https://registry.npmjs.org/game7-bridge-sdk/-/game7-bridge-sdk-0.0.75.tgz", + "integrity": "sha512-7lzCkRjftLh+d8+OxEJwpUwBI28oFuHMGpVDXNQt+1/O1fuE8UoHQPxJA/gabjGD9NyAFWvqdX8+RioJsW52Jg==", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/webapps/world-builder-dashboard/package.json b/webapps/world-builder-dashboard/package.json index 40eb6cbb..6f0be71b 100644 --- a/webapps/world-builder-dashboard/package.json +++ b/webapps/world-builder-dashboard/package.json @@ -19,7 +19,7 @@ "clsx": "^1.2.1", "dayjs": "^1.11.11", "dotenv": "^16.4.7", - "game7-bridge-sdk": "^0.0.74", + "game7-bridge-sdk": "^0.0.75", "history": "^5.3.0", "prettier-plugin-tailwindcss": "^0.6.5", "react": "^18.2.0", diff --git a/webapps/world-builder-dashboard/src/components/bridge/history/Deposit.tsx b/webapps/world-builder-dashboard/src/components/bridge/history/Deposit.tsx index cf243444..3e858cbc 100644 --- a/webapps/world-builder-dashboard/src/components/bridge/history/Deposit.tsx +++ b/webapps/world-builder-dashboard/src/components/bridge/history/Deposit.tsx @@ -181,7 +181,7 @@ const Deposit: React.FC = ({ deposit }) => {
-
{timeAgo(deposit?.highNetworkTimestamp)}
+
{timeAgo(deposit?.completionTimestamp)}
{/* FINALIZE */} @@ -213,7 +213,7 @@ const Deposit: React.FC = ({ deposit }) => {
-
{timeAgo(deposit?.highNetworkTimestamp)}
+
{timeAgo(deposit?.completionTimestamp)}
)} diff --git a/webapps/world-builder-dashboard/src/hooks/useBridgeTransfer.ts b/webapps/world-builder-dashboard/src/hooks/useBridgeTransfer.ts index 7f922fed..60d91cbf 100644 --- a/webapps/world-builder-dashboard/src/hooks/useBridgeTransfer.ts +++ b/webapps/world-builder-dashboard/src/hooks/useBridgeTransfer.ts @@ -155,14 +155,14 @@ export const useBridgeTransfer = () => { } let targetChain - if (selectedNetworkType === 'Testnet' ) { + if (selectedNetworkType === 'Testnet') { if (isDeposit && txRecord.isCCTP && txRecord.isCCTP === true) { targetChain = L2_NETWORK } else { targetChain = originChainId === L2_NETWORK.chainId ? L1_NETWORK : L2_NETWORK } console.log('targetChain', targetChain) - } + } else { if (isDeposit && txRecord.isCCTP && txRecord.isCCTP === true) { targetChain = L2_MAIN_NETWORK @@ -192,15 +192,16 @@ export const useBridgeTransfer = () => { destinationSignerOrProviderOrRpc: destinationRpc, originSignerOrProviderOrRpc: originRpc }, txRecord.isCCTP) - + await _bridgeTransfer.getStatus() - const res = await _bridgeTransfer?.execute(signer) + const res: any = await _bridgeTransfer?.execute(signer) return { res, txRecord } }, { onSuccess: ({ res, txRecord }) => { const isDeposit = txRecord.type === 'DEPOSIT' const txHash = isDeposit ? txRecord.lowNetworkHash : txRecord.highNetworkHash + console.log('res', res) try { const transactionsString = localStorage.getItem( `bridge-${connectedAccount}-transactions-${selectedNetworkType}` @@ -213,8 +214,8 @@ export const useBridgeTransfer = () => { completionTimestamp: isDeposit ? t.completionTimestamp : Date.now() / 1000, lowNetworkTimestamp: isDeposit ? t.lowNetworkTimestamp : Date.now() / 1000, newTransaction: true, - highNetworkHash: isDeposit ? res?.transactionHash : t.highNetworkHash, - lowNetworkHash: !isDeposit ? res?.transactionHash : t.lowNetworkHash, + highNetworkHash: isDeposit ? txRecord.isCCTP ? res?.hash : res?.transactionHash : t.highNetworkHash, + lowNetworkHash: !isDeposit ? txRecord.isCCTP ? res?.hash : res?.transactionHash : t.lowNetworkHash, status: txRecord.isCCTP ? BridgeTransferStatus.CCTP_REDEEMED : !isDeposit ? BridgeTransferStatus.WITHDRAW_EXECUTED : BridgeTransferStatus.DEPOSIT_ERC20_REDEEMED From a80fb45e5f81b77722f692421b9bf66baf7fb8c3 Mon Sep 17 00:00:00 2001 From: Memo Khoury Date: Wed, 18 Dec 2024 16:20:01 +0000 Subject: [PATCH 11/12] ready to merge with staging --- .../src/components/bridge/history/Deposit.tsx | 14 +++- .../bridge/history/HistoryDesktop.tsx | 10 +-- .../history/WithdrawTransactions.module.css | 72 ++++++++++++++++--- .../components/bridge/history/Withdrawal.tsx | 2 + 4 files changed, 81 insertions(+), 17 deletions(-) diff --git a/webapps/world-builder-dashboard/src/components/bridge/history/Deposit.tsx b/webapps/world-builder-dashboard/src/components/bridge/history/Deposit.tsx index 3e858cbc..6be42d8c 100644 --- a/webapps/world-builder-dashboard/src/components/bridge/history/Deposit.tsx +++ b/webapps/world-builder-dashboard/src/components/bridge/history/Deposit.tsx @@ -11,6 +11,7 @@ import { useBridgeTransfer } from '@/hooks/useBridgeTransfer' import { TransactionRecord } from '@/utils/bridge/depositERC20ArbitrumSDK' import { ETA, timeAgo } from '@/utils/timeFormat' import { getBlockExplorerUrl } from '@/utils/web3utils' +import IconChevronDown from '@/assets/IconChevronDown' interface DepositProps { deposit: TransactionRecord @@ -150,6 +151,15 @@ const Deposit: React.FC = ({ deposit }) => { >
{timeAgo(deposit?.completionTimestamp)}
+
setCollapseExecuted(!collapseExecuted)} + style={{ + cursor: 'pointer', + backgroundColor: hovered ? '#393939' : 'initial' + }} + onMouseEnter={() => setHovered(true)} + onMouseLeave={() => setHovered(false)}> + +
{collapseExecuted && ( <> {/* INITIATE */} @@ -183,7 +193,7 @@ const Deposit: React.FC = ({ deposit }) => {
{timeAgo(deposit?.completionTimestamp)}
- +
{/* FINALIZE */}
Finalize
@@ -215,6 +225,7 @@ const Deposit: React.FC = ({ deposit }) => {
{timeAgo(deposit?.completionTimestamp)}
+
)} @@ -304,6 +315,7 @@ const Deposit: React.FC = ({ deposit }) => {
)} +
)} diff --git a/webapps/world-builder-dashboard/src/components/bridge/history/HistoryDesktop.tsx b/webapps/world-builder-dashboard/src/components/bridge/history/HistoryDesktop.tsx index a64250b3..08e9008b 100644 --- a/webapps/world-builder-dashboard/src/components/bridge/history/HistoryDesktop.tsx +++ b/webapps/world-builder-dashboard/src/components/bridge/history/HistoryDesktop.tsx @@ -11,7 +11,7 @@ import { useBridgeAPI } from '@/hooks/useBridgeAPI' import { useMessages } from '@/hooks/useL2ToL1MessageStatus' import { TransactionRecord } from '@/utils/bridge/depositERC20ArbitrumSDK' -interface HistoryDesktopProps {} +interface HistoryDesktopProps { } const mergeTransactions = (apiData: TransactionRecord[], localData: TransactionRecord[]): TransactionRecord[] => { const combinedData = new Map() @@ -69,16 +69,16 @@ const HistoryDesktop: React.FC = () => { const { useHistoryTransactions } = useBridgeAPI() const { data: apiTransactions } = useHistoryTransactions(connectedAccount) const [mergedTransactions, setMergedTransactions] = useState([]) - const headers = ['Type', 'Submitted', 'Token', 'From', 'To', 'Transaction', 'Status'] + const headers = ['Type', 'Submitted', 'Token', 'From', 'To', 'Transaction', 'Status', ''] // Merge transations only when API data is updated with new data useEffect(() => { const localTransactions = messages || [] const formattedApiTransactions = apiTransactions ? apiTransactions.map(mapAPIDataToTransactionRecord) : [] - console.log(localTransactions) + console.log(localTransactions) const combinedTransactions = mergeTransactions(formattedApiTransactions, localTransactions) // Retrieve existing transactions from localStorage - + // Check if the combined transactions are different from those in localStorage if ( combinedTransactions.length !== localTransactions.length || @@ -113,7 +113,7 @@ const HistoryDesktop: React.FC = () => {
{headers.map((h) => ( -
+
{h}
))} diff --git a/webapps/world-builder-dashboard/src/components/bridge/history/WithdrawTransactions.module.css b/webapps/world-builder-dashboard/src/components/bridge/history/WithdrawTransactions.module.css index 7b685162..872a2b30 100644 --- a/webapps/world-builder-dashboard/src/components/bridge/history/WithdrawTransactions.module.css +++ b/webapps/world-builder-dashboard/src/components/bridge/history/WithdrawTransactions.module.css @@ -57,7 +57,8 @@ font-size: 14px; font-style: normal; font-weight: 600; - line-height: 20px; /* 142.857% */ + line-height: 20px; + /* 142.857% */ /* Shadow/xs */ box-shadow: 0 1px 2px 0 rgba(16, 24, 40, 0.05); transition: background-color 0.2s ease-in-out; @@ -92,12 +93,27 @@ .withdrawsGrid { display: grid; - grid-template-columns: repeat(7, auto); + grid-template-columns: repeat(8, auto); width: 100%; overflow-y: auto; max-height: calc(100vh - 282px); } +.transactionsHeaderEmpty { + position: sticky; + top: 0; + z-index: 10; + display: flex; + width: 68px; + height: 44px; + padding: 12px 24px; + align-items: center; + gap: 12px; + align-self: stretch; + background: var(--Gray-60, #f9fafb); + color: var(--Gray-600, #475467); +} + .noTransactions { display: flex; padding: 40px 32px 48px 32px; @@ -112,7 +128,8 @@ font-size: 14px; font-style: normal; font-weight: 400; - line-height: 20px; /* 142.857% */ + line-height: 20px; + /* 142.857% */ grid-column: span 7; } @@ -130,7 +147,8 @@ font-size: 14px; font-style: normal; font-weight: 400; - line-height: 20px; /* 142.857% */ + line-height: 20px; + /* 142.857% */ border-bottom: 1px solid var(--Gray-200, #eaecf0); } @@ -147,7 +165,8 @@ font-size: 14px; font-style: normal; font-weight: 600; - line-height: 20px; /* 142.857% */ + line-height: 20px; + /* 142.857% */ } .gridItemChild { @@ -163,7 +182,8 @@ font-size: 14px; font-style: normal; font-weight: 400; - line-height: 20px; /* 142.857% */ + line-height: 20px; + /* 142.857% */ border-bottom: 1px solid var(--Gray-200, #eaecf0); } @@ -211,7 +231,8 @@ font-size: 12px; font-style: normal; font-weight: 500; - line-height: 18px; /* 150% */ + line-height: 18px; + /* 150% */ } .typeWithdrawal { @@ -231,7 +252,8 @@ font-size: 12px; font-style: normal; font-weight: 500; - line-height: 18px; /* 150% */ + line-height: 18px; + /* 150% */ } .typeCompleted { @@ -246,7 +268,8 @@ font-size: 12px; font-style: normal; font-weight: 500; - line-height: 18px; /* 150% */ + line-height: 18px; + /* 150% */ } .typeDeposit { @@ -265,7 +288,8 @@ font-size: 12px; font-style: normal; font-weight: 500; - line-height: 18px; /* 150% */ + line-height: 18px; + /* 150% */ } .pending, @@ -308,9 +332,11 @@ 0% { background-color: #393939; } + 50% { background-color: #4f4f4f; } + 100% { background-color: #393939; } @@ -356,7 +382,8 @@ font-size: 14px; font-style: normal; font-weight: 600; - line-height: 20px; /* 142.857% */ + line-height: 20px; + /* 142.857% */ cursor: pointer; white-space: nowrap; width: 100px; @@ -370,15 +397,19 @@ 0% { transform: rotate(0deg) scale(0.9); } + 25% { transform: rotate(90deg) scale(1.05); } + 50% { transform: rotate(180deg) scale(1.2); } + 75% { transform: rotate(270deg) scale(1.05); } + 100% { transform: rotate(360deg) scale(0.9); } @@ -396,3 +427,22 @@ .arrowUp { stroke: var(--Arrow-Up, #fff); } + +.emptyCell { + display: flex; + height: 72px; + padding: 16px 24px; + align-items: center; + gap: 12px; + border-bottom: 1px solid var(--Gray-200, #eaecf0); +} + +.emptyCellInitiate { + display: flex; + height: 72px; + padding: 16px 24px; + align-items: center; + gap: 12px; + border-bottom: 1px solid var(--Gray-200, #eaecf0); + background-color: var(--Base-White, #fff); +} \ No newline at end of file diff --git a/webapps/world-builder-dashboard/src/components/bridge/history/Withdrawal.tsx b/webapps/world-builder-dashboard/src/components/bridge/history/Withdrawal.tsx index b1e3315f..54403c7c 100644 --- a/webapps/world-builder-dashboard/src/components/bridge/history/Withdrawal.tsx +++ b/webapps/world-builder-dashboard/src/components/bridge/history/Withdrawal.tsx @@ -358,8 +358,10 @@ const Withdrawal: React.FC = ({ withdrawal }) => { )} )} + )} +
)} From 021df7bfa76662e6b473375f59eccab17b9f8344 Mon Sep 17 00:00:00 2001 From: Memo Khoury Date: Wed, 18 Dec 2024 16:42:40 +0000 Subject: [PATCH 12/12] add ui/ux --- .../src/assets/IconChevronUp.tsx | 9 +++++++++ .../src/components/bridge/history/Deposit.tsx | 12 +++++++++--- .../bridge/history/HistoryDesktop.tsx | 2 +- .../history/WithdrawTransactions.module.css | 1 + .../components/bridge/history/Withdrawal.tsx | 19 +++++++++++++++++-- 5 files changed, 37 insertions(+), 6 deletions(-) create mode 100644 webapps/world-builder-dashboard/src/assets/IconChevronUp.tsx diff --git a/webapps/world-builder-dashboard/src/assets/IconChevronUp.tsx b/webapps/world-builder-dashboard/src/assets/IconChevronUp.tsx new file mode 100644 index 00000000..14fcbf90 --- /dev/null +++ b/webapps/world-builder-dashboard/src/assets/IconChevronUp.tsx @@ -0,0 +1,9 @@ +import React from 'react' + +const IconChevronUp: React.FC> = (props) => ( + + + +) + +export default IconChevronUp; \ No newline at end of file diff --git a/webapps/world-builder-dashboard/src/components/bridge/history/Deposit.tsx b/webapps/world-builder-dashboard/src/components/bridge/history/Deposit.tsx index 6be42d8c..b753eac3 100644 --- a/webapps/world-builder-dashboard/src/components/bridge/history/Deposit.tsx +++ b/webapps/world-builder-dashboard/src/components/bridge/history/Deposit.tsx @@ -12,6 +12,8 @@ import { TransactionRecord } from '@/utils/bridge/depositERC20ArbitrumSDK' import { ETA, timeAgo } from '@/utils/timeFormat' import { getBlockExplorerUrl } from '@/utils/web3utils' import IconChevronDown from '@/assets/IconChevronDown' +import IconChevronUp from '@/assets/IconChevronUp' +import IconWithdrawalNodeCompleted from '@/assets/IconWithdrawalNodeCompleted' interface DepositProps { deposit: TransactionRecord @@ -62,6 +64,8 @@ const Deposit: React.FC = ({ deposit }) => { onMouseEnter={() => setHovered(true)} onMouseLeave={() => setHovered(false)} > + + {collapseExecuted && }
Deposit
@@ -151,14 +155,16 @@ const Deposit: React.FC = ({ deposit }) => { >
{timeAgo(deposit?.completionTimestamp)}
-
setCollapseExecuted(!collapseExecuted)} +
setCollapseExecuted(!collapseExecuted)} style={{ cursor: 'pointer', backgroundColor: hovered ? '#393939' : 'initial' }} onMouseEnter={() => setHovered(true)} - onMouseLeave={() => setHovered(false)}> - + onMouseLeave={() => setHovered(false)} + > + {!collapseExecuted ? : }
{collapseExecuted && ( <> diff --git a/webapps/world-builder-dashboard/src/components/bridge/history/HistoryDesktop.tsx b/webapps/world-builder-dashboard/src/components/bridge/history/HistoryDesktop.tsx index 08e9008b..bdaab331 100644 --- a/webapps/world-builder-dashboard/src/components/bridge/history/HistoryDesktop.tsx +++ b/webapps/world-builder-dashboard/src/components/bridge/history/HistoryDesktop.tsx @@ -113,7 +113,7 @@ const HistoryDesktop: React.FC = () => {
{headers.map((h) => ( -
+
{h}
))} diff --git a/webapps/world-builder-dashboard/src/components/bridge/history/WithdrawTransactions.module.css b/webapps/world-builder-dashboard/src/components/bridge/history/WithdrawTransactions.module.css index 872a2b30..7ee386d6 100644 --- a/webapps/world-builder-dashboard/src/components/bridge/history/WithdrawTransactions.module.css +++ b/webapps/world-builder-dashboard/src/components/bridge/history/WithdrawTransactions.module.css @@ -95,6 +95,7 @@ display: grid; grid-template-columns: repeat(8, auto); width: 100%; + max-width: 1096px; overflow-y: auto; max-height: calc(100vh - 282px); } diff --git a/webapps/world-builder-dashboard/src/components/bridge/history/Withdrawal.tsx b/webapps/world-builder-dashboard/src/components/bridge/history/Withdrawal.tsx index 54403c7c..6fd22bec 100644 --- a/webapps/world-builder-dashboard/src/components/bridge/history/Withdrawal.tsx +++ b/webapps/world-builder-dashboard/src/components/bridge/history/Withdrawal.tsx @@ -14,6 +14,8 @@ import { getBlockExplorerUrl } from '@/utils/web3utils' import { ChildToParentMessageStatus } from '@arbitrum/sdk' import { useMediaQuery } from '@mantine/hooks' import { BridgeTransferStatus } from 'game7-bridge-sdk' +import IconChevronDown from '@/assets/IconChevronDown' +import IconChevronUp from '@/assets/IconChevronUp' interface WithdrawalProps { withdrawal: TransactionRecord @@ -224,6 +226,17 @@ const Withdrawal: React.FC = ({ withdrawal }) => { >
{timeAgo(withdrawal?.completionTimestamp)}
+
setCollapseExecuted(!collapseExecuted)} + style={{ + cursor: 'pointer', + backgroundColor: hovered ? '#393939' : 'initial' + }} + onMouseEnter={() => setHovered(true)} + onMouseLeave={() => setHovered(false)} + > + {!collapseExecuted ? : } +
{collapseExecuted && ( <>
@@ -256,6 +269,7 @@ const Withdrawal: React.FC = ({ withdrawal }) => {
{timeAgo(withdrawal?.completionTimestamp)}
+
Finalize
@@ -286,6 +300,7 @@ const Withdrawal: React.FC = ({ withdrawal }) => {
{timeAgo(withdrawal?.completionTimestamp)}
+
)} @@ -334,6 +349,7 @@ const Withdrawal: React.FC = ({ withdrawal }) => { {claim.isLoading && !claim.isSuccess ? 'Claiming...' : 'Claim Now'}
+
)} {transferStatus && (transferStatus?.status === ChildToParentMessageStatus.UNCONFIRMED || transferStatus?.status === BridgeTransferStatus.CCTP_PENDING) && ( @@ -350,10 +366,10 @@ const Withdrawal: React.FC = ({ withdrawal }) => {
-
{ETA(withdrawal?.highNetworkTimestamp, withdrawal.challengePeriod)} left
+
)} @@ -361,7 +377,6 @@ const Withdrawal: React.FC = ({ withdrawal }) => { )} -
)}