From 36881d66568ea4bbb75d8dec74bf0f1a71b8ebb3 Mon Sep 17 00:00:00 2001 From: samuelea Date: Fri, 24 Oct 2025 21:17:46 -0400 Subject: [PATCH 1/6] modified sendTransactions function --- packages/connect/src/utils/transactions.ts | 176 +++++++++++---------- 1 file changed, 96 insertions(+), 80 deletions(-) diff --git a/packages/connect/src/utils/transactions.ts b/packages/connect/src/utils/transactions.ts index 7111e9df1..7ae4caed8 100644 --- a/packages/connect/src/utils/transactions.ts +++ b/packages/connect/src/utils/transactions.ts @@ -46,7 +46,9 @@ export const sendTransactions = async ({ indexerClient, transactionConfirmations = TRANSACTION_CONFIRMATIONS_DEFAULT, waitConfirmationForLastTransaction = true -}: SendTransactionsInput): Promise => { +}: SendTransactionsInput): Promise<(() => Promise)[]> => { + const returnedTransactions: (() => Promise)[] = [] + const walletClientChainId = await walletClient.getChainId() if (walletClientChainId !== chainId) { @@ -63,105 +65,115 @@ export const sendTransactions = async ({ // Sequence WaaS if (isEmbeddedWallet) { - // waas connector logic - const resp = await sequenceWaaS.feeOptions({ - transactions: transactions, - network: chainId - }) + const triggerEmbeddedWalletPromise = async (): Promise => { + // waas connector logic + const resp = await sequenceWaaS.feeOptions({ + transactions: transactions, + network: chainId + }) - const isSponsored = resp.data.feeOptions.length == 0 + const isSponsored = resp.data.feeOptions.length == 0 - let transactionsFeeOption - const transactionsFeeQuote = resp.data.feeQuote + let transactionsFeeOption + const transactionsFeeQuote = resp.data.feeQuote - const balances = await indexerClient.getTokenBalancesDetails({ - filter: { - accountAddresses: [senderAddress], - omitNativeBalances: false - } - }) + const balances = await indexerClient.getTokenBalancesDetails({ + filter: { + accountAddresses: [senderAddress], + omitNativeBalances: false + } + }) - for (const feeOption of resp.data.feeOptions) { - const isNativeToken = feeOption.token.contractAddress == null + for (const feeOption of resp.data.feeOptions) { + const isNativeToken = feeOption.token.contractAddress == null - if (isNativeToken) { - const nativeTokenBalance = balances.nativeBalances?.[0].balance || '0' - if (BigInt(nativeTokenBalance) >= BigInt(feeOption.value)) { - transactionsFeeOption = feeOption - break - } - } else { - const erc20TokenBalance = balances.balances.find(b => - compareAddress(b.contractAddress, feeOption.token.contractAddress || '') - ) - const erc20TokenBalanceValue = erc20TokenBalance?.balance || '0' - if (BigInt(erc20TokenBalanceValue) >= BigInt(feeOption.value)) { - transactionsFeeOption = feeOption - break + if (isNativeToken) { + const nativeTokenBalance = balances.nativeBalances?.[0].balance || '0' + if (BigInt(nativeTokenBalance) >= BigInt(feeOption.value)) { + transactionsFeeOption = feeOption + break + } + } else { + const erc20TokenBalance = balances.balances.find(b => + compareAddress(b.contractAddress, feeOption.token.contractAddress || '') + ) + const erc20TokenBalanceValue = erc20TokenBalance?.balance || '0' + if (BigInt(erc20TokenBalanceValue) >= BigInt(feeOption.value)) { + transactionsFeeOption = feeOption + break + } } } - } - if (!transactionsFeeOption && !isSponsored) { - throw new FeeOptionInsufficientFundsError( - `Transaction fee option with valid user balance not found: ${resp.data.feeOptions.map(f => f.token.symbol).join(', ')}`, - resp.data.feeOptions - ) - } + if (!transactionsFeeOption && !isSponsored) { + throw new FeeOptionInsufficientFundsError( + `Transaction fee option with valid user balance not found: ${resp.data.feeOptions.map(f => f.token.symbol).join(', ')}`, + resp.data.feeOptions + ) + } - const response = await sequenceWaaS.sendTransaction({ - transactions, - transactionsFeeOption, - transactionsFeeQuote, - network: chainId - }) + const response = await sequenceWaaS.sendTransaction({ + transactions, + transactionsFeeOption, + transactionsFeeQuote, + network: chainId + }) - if (response.code === 'transactionFailed') { - throw new Error(response.data.error) - } + if (response.code === 'transactionFailed') { + throw new Error(response.data.error) + } - const txnHash = response.data.txHash + const txnHash = response.data.txHash - if (waitConfirmationForLastTransaction) { - const { txnStatus } = await waitForTransactionReceipt({ - indexerClient, - txnHash: txnHash as Hex, - publicClient, - confirmations: transactionConfirmations - }) + if (waitConfirmationForLastTransaction) { + const { txnStatus } = await waitForTransactionReceipt({ + indexerClient, + txnHash: txnHash as Hex, + publicClient, + confirmations: transactionConfirmations + }) - if (txnStatus === TransactionStatus.FAILED) { - throw new Error('Transaction failed') + if (txnStatus === TransactionStatus.FAILED) { + throw new Error('Transaction failed') + } } + + return txnHash } - return txnHash + returnedTransactions.push(triggerEmbeddedWalletPromise) // Sequence-Based Connector } else if (isSequenceUniversalWallet) { - const wallet = sequence.getWallet() - const signer = wallet.getSigner() - const response = await signer.sendTransaction(transactions) - - if (waitConfirmationForLastTransaction) { - const { txnStatus } = await waitForTransactionReceipt({ - indexerClient, - txnHash: response.hash as Hex, - publicClient, - confirmations: transactionConfirmations - }) + const triggerSequenceUniversalWalletPromise = async () => { + const wallet = sequence.getWallet() + const signer = wallet.getSigner() + const response = await signer.sendTransaction(transactions) + + if (waitConfirmationForLastTransaction) { + const { txnStatus } = await waitForTransactionReceipt({ + indexerClient, + txnHash: response.hash as Hex, + publicClient, + confirmations: transactionConfirmations + }) - if (txnStatus === TransactionStatus.FAILED) { - throw new Error('Transaction failed') + if (txnStatus === TransactionStatus.FAILED) { + throw new Error('Transaction failed') + } } + + return response.hash } - return response.hash + returnedTransactions.push(triggerSequenceUniversalWalletPromise) // Other connectors (metamask, eip-6963, etc...) } else { - let txHash: string = '' - // We fire the transactions one at a time since the cannot be batched - for (const [index, transaction] of transactions.entries()) { + interface TriggerOtherConnectorsPromiseInput { + transaction: Transaction + isLastTransaction: boolean + } + const triggerOtherConnectorTransaction = async ({ transaction, isLastTransaction }: TriggerOtherConnectorsPromiseInput) => { const txnHash = await walletClient.sendTransaction({ account: senderAddress, to: transaction.to, @@ -170,8 +182,6 @@ export const sendTransactions = async ({ chain: undefined }) - const isLastTransaction = index === transactions.length - 1 - if (!isLastTransaction || (isLastTransaction && waitConfirmationForLastTransaction)) { const { txnStatus } = await waitForTransactionReceipt({ indexerClient, @@ -185,12 +195,18 @@ export const sendTransactions = async ({ } } - // The transaction hash of the last transaction is the one that should be returned - txHash = txnHash + return txnHash } - return txHash + for (const [index, transaction] of transactions.entries()) { + const isLastTransaction = index === transactions.length - 1 + const triggerOtherConnectorTransactionPromise = () => triggerOtherConnectorTransaction({ transaction, isLastTransaction }) + + returnedTransactions.push(triggerOtherConnectorTransactionPromise) + } } + + return returnedTransactions } interface WaitForTransactionReceiptInput { From b911c552ceea5f80073ccd1d447cc9658a93014c Mon Sep 17 00:00:00 2001 From: samuelea Date: Wed, 29 Oct 2025 17:12:53 -0400 Subject: [PATCH 2/6] integrate tx counter --- packages/checkout/src/hooks/index.ts | 2 + .../hooks/useCheckoutUI/useCryptoPayment.tsx | 30 +++++++-- .../src/hooks/useTransactionCounter.ts | 31 +++++++++ .../PayWithCrypto/index.tsx | 64 ++++++++++++++++++- packages/checkout/src/views/Swap/index.tsx | 13 +++- .../src/views/SwapCoin/SwapList.tsx | 12 +++- 6 files changed, 143 insertions(+), 9 deletions(-) create mode 100644 packages/checkout/src/hooks/useTransactionCounter.ts diff --git a/packages/checkout/src/hooks/index.ts b/packages/checkout/src/hooks/index.ts index 4ca6765fd..d75718c55 100644 --- a/packages/checkout/src/hooks/index.ts +++ b/packages/checkout/src/hooks/index.ts @@ -10,3 +10,5 @@ export * from './useCheckoutOptionsSalesContract.js' export * from './useERC1155SaleContractCheckout.js' export * from './useSkipOnCloseCallback.js' export * from './useFortePaymentIntent.js' +export * from './useAddFundsModal.js' +export * from './useTransactionCounter.js' diff --git a/packages/checkout/src/hooks/useCheckoutUI/useCryptoPayment.tsx b/packages/checkout/src/hooks/useCheckoutUI/useCryptoPayment.tsx index c77ba6e6c..aec1480a7 100644 --- a/packages/checkout/src/hooks/useCheckoutUI/useCryptoPayment.tsx +++ b/packages/checkout/src/hooks/useCheckoutUI/useCryptoPayment.tsx @@ -238,7 +238,8 @@ export const useCryptoPayment = ({ } ] - const txHash = await sendTransactions({ + let txHash = '' + const txs = await sendTransactions({ chainId, senderAddress: userAddress, publicClient, @@ -250,7 +251,17 @@ export const useCryptoPayment = ({ waitConfirmationForLastTransaction: false }) - onSuccess?.(txHash) + for (const [index, tx] of txs.entries()) { + const currentTxHash = await tx() + + const isLastTransaction = index === txs.length - 1 + + if (isLastTransaction) { + onSuccess?.(currentTxHash) + txHash = currentTxHash + } + } + return txHash } else { const swapOption = swapRoutes @@ -322,7 +333,8 @@ export const useCryptoPayment = ({ } ] - const txHash = await sendTransactions({ + let txHash = '' + const txs = await sendTransactions({ chainId, senderAddress: userAddress, publicClient, @@ -334,7 +346,17 @@ export const useCryptoPayment = ({ waitConfirmationForLastTransaction: false }) - onSuccess?.(txHash) + for (const [index, tx] of txs.entries()) { + const currentTxHash = await tx() + + const isLastTransaction = index === txs.length - 1 + + if (isLastTransaction) { + onSuccess?.(txHash) + txHash = currentTxHash + } + } + return txHash } } catch (error) { diff --git a/packages/checkout/src/hooks/useTransactionCounter.ts b/packages/checkout/src/hooks/useTransactionCounter.ts new file mode 100644 index 000000000..1f48ad8e5 --- /dev/null +++ b/packages/checkout/src/hooks/useTransactionCounter.ts @@ -0,0 +1,31 @@ +import { useState } from 'react' + +export const useTransactionCounter = () => { + const [transactionCount, setTransactionCount] = useState(1) + const [maxTransactions, setMaxTransactions] = useState(0) + + const initializeTransactionCounter = (maxTransactions: number) => { + setTransactionCount(1) + setMaxTransactions(maxTransactions) + } + + const resetTransactionCounter = () => { + setTransactionCount(1) + setMaxTransactions(0) + } + + const incrementTransactionCount = () => { + setTransactionCount(transactionCount + 1) + } + + const isTransactionCounterInitialized = maxTransactions > 0 + + return { + transactionCount, + maxTransactions, + incrementTransactionCount, + initializeTransactionCounter, + resetTransactionCounter, + isTransactionCounterInitialized + } +} diff --git a/packages/checkout/src/views/Checkout/PaymentMethodSelect/PayWithCrypto/index.tsx b/packages/checkout/src/views/Checkout/PaymentMethodSelect/PayWithCrypto/index.tsx index 060717f1e..5f21dcadd 100644 --- a/packages/checkout/src/views/Checkout/PaymentMethodSelect/PayWithCrypto/index.tsx +++ b/packages/checkout/src/views/Checkout/PaymentMethodSelect/PayWithCrypto/index.tsx @@ -26,7 +26,7 @@ import { ERC_20_CONTRACT_ABI } from '../../../../constants/abi.js' import { EVENT_SOURCE } from '../../../../constants/index.js' import { type PaymentMethodSelectionParams } from '../../../../contexts/NavigationCheckout.js' import type { SelectPaymentSettings } from '../../../../contexts/SelectPaymentModal.js' -import { useAddFundsModal } from '../../../../hooks/index.js' +import { useAddFundsModal, useTransactionCounter } from '../../../../hooks/index.js' import { useSelectPaymentModal, useTransactionStatusModal } from '../../../../hooks/index.js' import { useNavigationCheckout } from '../../../../hooks/useNavigationCheckout.js' @@ -48,6 +48,14 @@ export const PayWithCryptoTab = ({ skipOnCloseCallback, isSwitchingChainRef }: P const { analytics } = useAnalyticsContext() const [isError, setIsError] = useState(false) const { navigation, setNavigation } = useNavigationCheckout() + const { + initializeTransactionCounter, + incrementTransactionCount, + transactionCount, + maxTransactions, + isTransactionCounterInitialized, + resetTransactionCounter + } = useTransactionCounter() const { chain, @@ -239,6 +247,7 @@ export const PayWithCryptoTab = ({ skipOnCloseCallback, isSwitchingChainRef }: P setIsPurchasing(true) setIsError(false) + resetTransactionCounter() try { if (connectedChainId != chainId) { @@ -275,7 +284,7 @@ export const PayWithCryptoTab = ({ skipOnCloseCallback, isSwitchingChainRef }: P } ] - const txHash = await sendTransactions({ + const txs = await sendTransactions({ chainId, senderAddress: userAddress, publicClient, @@ -287,6 +296,21 @@ export const PayWithCryptoTab = ({ skipOnCloseCallback, isSwitchingChainRef }: P waitConfirmationForLastTransaction: false }) + initializeTransactionCounter(txs.length) + + let txHash = '' + for (const [index, tx] of txs.entries()) { + const currentTxHash = await tx() + incrementTransactionCount() + + const isLastTransaction = index === txs.length - 1 + + if (isLastTransaction) { + onSuccess?.(currentTxHash) + txHash = currentTxHash + } + } + analytics?.track({ event: 'SEND_TRANSACTION_REQUEST', props: { @@ -362,6 +386,7 @@ export const PayWithCryptoTab = ({ skipOnCloseCallback, isSwitchingChainRef }: P setIsPurchasing(true) setIsError(false) + resetTransactionCounter() try { if (connectedChainId != chainId) { @@ -423,7 +448,7 @@ export const PayWithCryptoTab = ({ skipOnCloseCallback, isSwitchingChainRef }: P } ] - const txHash = await sendTransactions({ + const txs = await sendTransactions({ chainId, senderAddress: userAddress, publicClient, @@ -435,6 +460,23 @@ export const PayWithCryptoTab = ({ skipOnCloseCallback, isSwitchingChainRef }: P waitConfirmationForLastTransaction: false }) + initializeTransactionCounter(txs.length) + + let txHash = '' + for (const [index, tx] of txs.entries()) { + const currentTxHash = await tx() + incrementTransactionCount() + + const isLastTransaction = index === txs.length - 1 + + if (isLastTransaction) { + onSuccess?.(currentTxHash) + txHash = currentTxHash + } else { + // increment tx amount counter..... + } + } + analytics?.track({ event: 'SEND_TRANSACTION_REQUEST', props: { @@ -548,6 +590,21 @@ export const PayWithCryptoTab = ({ skipOnCloseCallback, isSwitchingChainRef }: P ) } + const TransactionCounterInfo = () => { + return ( +
+ + {`${transactionCount} / ${maxTransactions}`} + {isTransactionCounterInitialized && ( + + "counter initialized" + + )} + +
+ ) + } + if (isLoading) { return (
@@ -650,6 +707,7 @@ export const PayWithCryptoTab = ({ skipOnCloseCallback, isSwitchingChainRef }: P return (
+
{ await walletClient.switchChain({ id: chainId }) } - const txHash = await sendTransactions({ + const txs = await sendTransactions({ connector, walletClient, publicClient, @@ -248,6 +248,17 @@ export const Swap = () => { transactions: [...getSwapTransactions(), ...(postSwapTransactions ?? [])] }) + let txHash = '' + for (const [index, tx] of txs.entries()) { + const currentTxHash = await tx() + + const isLastTransaction = index === txs.length - 1 + if (isLastTransaction) { + onSuccess?.(currentTxHash) + txHash = currentTxHash + } + } + closeSwapModal() openTransactionStatusModal({ chainId, diff --git a/packages/wallet-widget/src/views/SwapCoin/SwapList.tsx b/packages/wallet-widget/src/views/SwapCoin/SwapList.tsx index 5d5eed65d..114a546b7 100644 --- a/packages/wallet-widget/src/views/SwapCoin/SwapList.tsx +++ b/packages/wallet-widget/src/views/SwapCoin/SwapList.tsx @@ -168,7 +168,7 @@ export const SwapList = ({ chainId, contractAddress, amount, slippageBps }: Swap await walletClient.switchChain({ id: chainId }) } - const txHash = await sendTransactions({ + const txs = await sendTransactions({ connector, walletClient, publicClient, @@ -177,6 +177,16 @@ export const SwapList = ({ chainId, contractAddress, amount, slippageBps }: Swap senderAddress: userAddress, transactions: [...getSwapTransactions()] }) + let txHash = '' + for (const [index, tx] of txs.entries()) { + const currentTxHash = await tx() + + const isLastTransaction = index === txs.length - 1 + + if (isLastTransaction) { + txHash = currentTxHash + } + } analytics?.track({ event: 'SEND_TRANSACTION_REQUEST', From fedfe7e5dcb4bc479c95cd6e3e2826a5a60aa05b Mon Sep 17 00:00:00 2001 From: samuelea Date: Thu, 30 Oct 2025 12:05:53 -0400 Subject: [PATCH 3/6] added multiple transaction tracking for price section --- .../src/hooks/useTransactionCounter.ts | 10 ++--- .../PayWithCrypto/index.tsx | 37 ++++++++++--------- 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/packages/checkout/src/hooks/useTransactionCounter.ts b/packages/checkout/src/hooks/useTransactionCounter.ts index 1f48ad8e5..1ae2c79b9 100644 --- a/packages/checkout/src/hooks/useTransactionCounter.ts +++ b/packages/checkout/src/hooks/useTransactionCounter.ts @@ -1,27 +1,27 @@ import { useState } from 'react' export const useTransactionCounter = () => { - const [transactionCount, setTransactionCount] = useState(1) + const [currentTransactionNumber, setCurrentTransactionNumber] = useState(1) const [maxTransactions, setMaxTransactions] = useState(0) const initializeTransactionCounter = (maxTransactions: number) => { - setTransactionCount(1) + setCurrentTransactionNumber(1) setMaxTransactions(maxTransactions) } const resetTransactionCounter = () => { - setTransactionCount(1) + setCurrentTransactionNumber(1) setMaxTransactions(0) } const incrementTransactionCount = () => { - setTransactionCount(transactionCount + 1) + setCurrentTransactionNumber(currentTransactionNumber + 1) } const isTransactionCounterInitialized = maxTransactions > 0 return { - transactionCount, + currentTransactionNumber, maxTransactions, incrementTransactionCount, initializeTransactionCounter, diff --git a/packages/checkout/src/views/Checkout/PaymentMethodSelect/PayWithCrypto/index.tsx b/packages/checkout/src/views/Checkout/PaymentMethodSelect/PayWithCrypto/index.tsx index 5f21dcadd..50fd24901 100644 --- a/packages/checkout/src/views/Checkout/PaymentMethodSelect/PayWithCrypto/index.tsx +++ b/packages/checkout/src/views/Checkout/PaymentMethodSelect/PayWithCrypto/index.tsx @@ -51,7 +51,7 @@ export const PayWithCryptoTab = ({ skipOnCloseCallback, isSwitchingChainRef }: P const { initializeTransactionCounter, incrementTransactionCount, - transactionCount, + currentTransactionNumber, maxTransactions, isTransactionCounterInitialized, resetTransactionCounter @@ -364,6 +364,7 @@ export const PayWithCryptoTab = ({ skipOnCloseCallback, isSwitchingChainRef }: P setIsError(true) } + resetTransactionCounter() setIsPurchasing(false) } @@ -531,6 +532,7 @@ export const PayWithCryptoTab = ({ skipOnCloseCallback, isSwitchingChainRef }: P } setIsPurchasing(false) + resetTransactionCounter() } const onClickPurchase = () => { @@ -590,21 +592,6 @@ export const PayWithCryptoTab = ({ skipOnCloseCallback, isSwitchingChainRef }: P ) } - const TransactionCounterInfo = () => { - return ( -
- - {`${transactionCount} / ${maxTransactions}`} - {isTransactionCounterInitialized && ( - - "counter initialized" - - )} - -
- ) - } - if (isLoading) { return (
@@ -669,6 +656,23 @@ export const PayWithCryptoTab = ({ skipOnCloseCallback, isSwitchingChainRef }: P } const PriceSection = () => { + if (isTransactionCounterInitialized) { + const descriptionText = + maxTransactions > 1 + ? `Confirming transaction ${currentTransactionNumber} of ${maxTransactions}` + : `Confirming transaction` + return ( +
+
+ + {descriptionText} + +
+ +
+ ) + } + if (isFree) { return (
@@ -707,7 +711,6 @@ export const PayWithCryptoTab = ({ skipOnCloseCallback, isSwitchingChainRef }: P return (
-
Date: Thu, 30 Oct 2025 14:53:16 -0400 Subject: [PATCH 4/6] clean up --- .../Checkout/PaymentMethodSelect/PayWithCrypto/index.tsx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/checkout/src/views/Checkout/PaymentMethodSelect/PayWithCrypto/index.tsx b/packages/checkout/src/views/Checkout/PaymentMethodSelect/PayWithCrypto/index.tsx index 50fd24901..fbc0087ea 100644 --- a/packages/checkout/src/views/Checkout/PaymentMethodSelect/PayWithCrypto/index.tsx +++ b/packages/checkout/src/views/Checkout/PaymentMethodSelect/PayWithCrypto/index.tsx @@ -247,7 +247,6 @@ export const PayWithCryptoTab = ({ skipOnCloseCallback, isSwitchingChainRef }: P setIsPurchasing(true) setIsError(false) - resetTransactionCounter() try { if (connectedChainId != chainId) { @@ -387,7 +386,6 @@ export const PayWithCryptoTab = ({ skipOnCloseCallback, isSwitchingChainRef }: P setIsPurchasing(true) setIsError(false) - resetTransactionCounter() try { if (connectedChainId != chainId) { @@ -473,8 +471,6 @@ export const PayWithCryptoTab = ({ skipOnCloseCallback, isSwitchingChainRef }: P if (isLastTransaction) { onSuccess?.(currentTxHash) txHash = currentTxHash - } else { - // increment tx amount counter..... } } From 00167c13fca2e1766a67d4758b0975ea0b4cea5d Mon Sep 17 00:00:00 2001 From: samuelea Date: Thu, 30 Oct 2025 15:10:08 -0400 Subject: [PATCH 5/6] closure fix --- packages/checkout/src/hooks/useTransactionCounter.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/checkout/src/hooks/useTransactionCounter.ts b/packages/checkout/src/hooks/useTransactionCounter.ts index 1ae2c79b9..bfa84b232 100644 --- a/packages/checkout/src/hooks/useTransactionCounter.ts +++ b/packages/checkout/src/hooks/useTransactionCounter.ts @@ -15,7 +15,7 @@ export const useTransactionCounter = () => { } const incrementTransactionCount = () => { - setCurrentTransactionNumber(currentTransactionNumber + 1) + setCurrentTransactionNumber(prev => prev + 1) } const isTransactionCounterInitialized = maxTransactions > 0 From 9f3b6902bb986a3efacebfa75ccbc8beefd94a5c Mon Sep 17 00:00:00 2001 From: samuelea Date: Tue, 4 Nov 2025 10:33:21 -0500 Subject: [PATCH 6/6] added error messages --- .../hooks/useCheckoutUI/useCryptoPayment.tsx | 22 ++++++++++++++++--- .../PayWithCrypto/index.tsx | 20 +++++++++++++++-- packages/checkout/src/views/Swap/index.tsx | 11 +++++++++- .../src/views/SwapCoin/SwapList.tsx | 12 +++++++++- 4 files changed, 58 insertions(+), 7 deletions(-) diff --git a/packages/checkout/src/hooks/useCheckoutUI/useCryptoPayment.tsx b/packages/checkout/src/hooks/useCheckoutUI/useCryptoPayment.tsx index aec1480a7..70c26b9b9 100644 --- a/packages/checkout/src/hooks/useCheckoutUI/useCryptoPayment.tsx +++ b/packages/checkout/src/hooks/useCheckoutUI/useCryptoPayment.tsx @@ -238,7 +238,7 @@ export const useCryptoPayment = ({ } ] - let txHash = '' + let txHash: string | undefined const txs = await sendTransactions({ chainId, senderAddress: userAddress, @@ -251,6 +251,10 @@ export const useCryptoPayment = ({ waitConfirmationForLastTransaction: false }) + if (txs.length === 0) { + throw new Error('No transactions to send') + } + for (const [index, tx] of txs.entries()) { const currentTxHash = await tx() @@ -262,6 +266,10 @@ export const useCryptoPayment = ({ } } + if (!txHash) { + throw new Error('Transaction hash is not available') + } + return txHash } else { const swapOption = swapRoutes @@ -333,7 +341,7 @@ export const useCryptoPayment = ({ } ] - let txHash = '' + let txHash: string | undefined const txs = await sendTransactions({ chainId, senderAddress: userAddress, @@ -346,17 +354,25 @@ export const useCryptoPayment = ({ waitConfirmationForLastTransaction: false }) + if (txs.length === 0) { + throw new Error('No transactions to send') + } + for (const [index, tx] of txs.entries()) { const currentTxHash = await tx() const isLastTransaction = index === txs.length - 1 if (isLastTransaction) { - onSuccess?.(txHash) + onSuccess?.(currentTxHash) txHash = currentTxHash } } + if (!txHash) { + throw new Error('Transaction hash is not available') + } + return txHash } } catch (error) { diff --git a/packages/checkout/src/views/Checkout/PaymentMethodSelect/PayWithCrypto/index.tsx b/packages/checkout/src/views/Checkout/PaymentMethodSelect/PayWithCrypto/index.tsx index fbc0087ea..c7e6e46a1 100644 --- a/packages/checkout/src/views/Checkout/PaymentMethodSelect/PayWithCrypto/index.tsx +++ b/packages/checkout/src/views/Checkout/PaymentMethodSelect/PayWithCrypto/index.tsx @@ -295,9 +295,13 @@ export const PayWithCryptoTab = ({ skipOnCloseCallback, isSwitchingChainRef }: P waitConfirmationForLastTransaction: false }) + if (txs.length === 0) { + throw new Error('No transactions to send') + } + initializeTransactionCounter(txs.length) - let txHash = '' + let txHash: string | undefined for (const [index, tx] of txs.entries()) { const currentTxHash = await tx() incrementTransactionCount() @@ -310,6 +314,10 @@ export const PayWithCryptoTab = ({ skipOnCloseCallback, isSwitchingChainRef }: P } } + if (!txHash) { + throw new Error('Transaction hash is not available') + } + analytics?.track({ event: 'SEND_TRANSACTION_REQUEST', props: { @@ -459,9 +467,13 @@ export const PayWithCryptoTab = ({ skipOnCloseCallback, isSwitchingChainRef }: P waitConfirmationForLastTransaction: false }) + if (txs.length === 0) { + throw new Error('No transactions to send') + } + initializeTransactionCounter(txs.length) - let txHash = '' + let txHash: string | undefined for (const [index, tx] of txs.entries()) { const currentTxHash = await tx() incrementTransactionCount() @@ -474,6 +486,10 @@ export const PayWithCryptoTab = ({ skipOnCloseCallback, isSwitchingChainRef }: P } } + if (!txHash) { + throw new Error('Transaction hash is not available') + } + analytics?.track({ event: 'SEND_TRANSACTION_REQUEST', props: { diff --git a/packages/checkout/src/views/Swap/index.tsx b/packages/checkout/src/views/Swap/index.tsx index b9f815db3..be860a080 100644 --- a/packages/checkout/src/views/Swap/index.tsx +++ b/packages/checkout/src/views/Swap/index.tsx @@ -248,7 +248,12 @@ export const Swap = () => { transactions: [...getSwapTransactions(), ...(postSwapTransactions ?? [])] }) - let txHash = '' + if (txs.length === 0) { + throw new Error('No transactions to send') + } + + let txHash: string | undefined + for (const [index, tx] of txs.entries()) { const currentTxHash = await tx() @@ -259,6 +264,10 @@ export const Swap = () => { } } + if (!txHash) { + throw new Error('Transaction hash is not available') + } + closeSwapModal() openTransactionStatusModal({ chainId, diff --git a/packages/wallet-widget/src/views/SwapCoin/SwapList.tsx b/packages/wallet-widget/src/views/SwapCoin/SwapList.tsx index 114a546b7..b99f57129 100644 --- a/packages/wallet-widget/src/views/SwapCoin/SwapList.tsx +++ b/packages/wallet-widget/src/views/SwapCoin/SwapList.tsx @@ -177,7 +177,13 @@ export const SwapList = ({ chainId, contractAddress, amount, slippageBps }: Swap senderAddress: userAddress, transactions: [...getSwapTransactions()] }) - let txHash = '' + + if (txs.length === 0) { + throw new Error('No transactions to send') + } + + let txHash: string | undefined + for (const [index, tx] of txs.entries()) { const currentTxHash = await tx() @@ -188,6 +194,10 @@ export const SwapList = ({ chainId, contractAddress, amount, slippageBps }: Swap } } + if (!txHash) { + throw new Error('Transaction hash is not available') + } + analytics?.track({ event: 'SEND_TRANSACTION_REQUEST', props: {