0xtrails 0.6.6 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/aave.d.ts +10 -2
- package/dist/aave.d.ts.map +1 -1
- package/dist/analytics.d.ts +26 -0
- package/dist/analytics.d.ts.map +1 -1
- package/dist/{ccip-CbJrlK-L.js → ccip-fConRNoG.js} +21 -21
- package/dist/chains.d.ts +23 -8
- package/dist/chains.d.ts.map +1 -1
- package/dist/constants.d.ts +5 -5
- package/dist/constants.d.ts.map +1 -1
- package/dist/customTokens.d.ts +12 -0
- package/dist/customTokens.d.ts.map +1 -0
- package/dist/decoders.d.ts +2 -2
- package/dist/decoders.d.ts.map +1 -1
- package/dist/error.d.ts.map +1 -1
- package/dist/fees.d.ts +37 -2
- package/dist/fees.d.ts.map +1 -1
- package/dist/gasless.d.ts +15 -36
- package/dist/gasless.d.ts.map +1 -1
- package/dist/{index-w7_dK4c5.js → index-BbajxCG_.js} +59269 -77146
- package/dist/index.d.ts +8 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +828 -359
- package/dist/indexerClient.d.ts.map +1 -1
- package/dist/intentReceiptMonitor.d.ts +1 -1
- package/dist/intentReceiptMonitor.d.ts.map +1 -1
- package/dist/intentReceiptPoller.d.ts +1 -1
- package/dist/intentReceiptPoller.d.ts.map +1 -1
- package/dist/intents.d.ts +3 -2
- package/dist/intents.d.ts.map +1 -1
- package/dist/mode.d.ts +1 -1
- package/dist/mode.d.ts.map +1 -1
- package/dist/mutations.d.ts +2 -2
- package/dist/mutations.d.ts.map +1 -1
- package/dist/prepareSend.d.ts +2 -2
- package/dist/prepareSend.d.ts.map +1 -1
- package/dist/prices.d.ts +1 -1
- package/dist/prices.d.ts.map +1 -1
- package/dist/sequenceWallet.d.ts +2 -2
- package/dist/sequenceWallet.d.ts.map +1 -1
- package/dist/time.d.ts +6 -0
- package/dist/time.d.ts.map +1 -1
- package/dist/tokenBalances.d.ts +40 -25
- package/dist/tokenBalances.d.ts.map +1 -1
- package/dist/tokens.d.ts +54 -14
- package/dist/tokens.d.ts.map +1 -1
- package/dist/trailsClient.d.ts +1 -1
- package/dist/trailsClient.d.ts.map +1 -1
- package/dist/trailsRouter.d.ts +2 -1
- package/dist/trailsRouter.d.ts.map +1 -1
- package/dist/transactionIntent/deposits/depositOrchestrator.d.ts +3 -2
- package/dist/transactionIntent/deposits/depositOrchestrator.d.ts.map +1 -1
- package/dist/transactionIntent/deposits/gaslessDeposit.d.ts +2 -1
- package/dist/transactionIntent/deposits/gaslessDeposit.d.ts.map +1 -1
- package/dist/transactionIntent/execution/transactionState.d.ts +1 -1
- package/dist/transactionIntent/execution/transactionState.d.ts.map +1 -1
- package/dist/transactionIntent/handlers/crossChain.d.ts +5 -3
- package/dist/transactionIntent/handlers/crossChain.d.ts.map +1 -1
- package/dist/transactionIntent/handlers/sameChainSameToken.d.ts +5 -3
- package/dist/transactionIntent/handlers/sameChainSameToken.d.ts.map +1 -1
- package/dist/transactionIntent/quote/feeExtractors.d.ts +1 -6
- package/dist/transactionIntent/quote/feeExtractors.d.ts.map +1 -1
- package/dist/transactionIntent/quote/normalizeQuote.d.ts +4 -2
- package/dist/transactionIntent/quote/normalizeQuote.d.ts.map +1 -1
- package/dist/transactionIntent/quote/quoteHelpers.d.ts +1 -1
- package/dist/transactionIntent/quote/quoteHelpers.d.ts.map +1 -1
- package/dist/transactionIntent/types.d.ts +28 -5
- package/dist/transactionIntent/types.d.ts.map +1 -1
- package/dist/transactionIntent/utils/testnetHelpers.d.ts +0 -1
- package/dist/transactionIntent/utils/testnetHelpers.d.ts.map +1 -1
- package/dist/transactionIntent/validators.d.ts +0 -2
- package/dist/transactionIntent/validators.d.ts.map +1 -1
- package/dist/transactions.d.ts +2 -2
- package/dist/transactions.d.ts.map +1 -1
- package/dist/utils.d.ts +7 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/wallets.d.ts +1 -0
- package/dist/wallets.d.ts.map +1 -1
- package/dist/widget/components/AccountIntentTransactionHistory.d.ts.map +1 -1
- package/dist/widget/components/AddressWalletIcon.d.ts +6 -0
- package/dist/widget/components/AddressWalletIcon.d.ts.map +1 -0
- package/dist/widget/components/ChainFilterDropdown.d.ts +2 -6
- package/dist/widget/components/ChainFilterDropdown.d.ts.map +1 -1
- package/dist/widget/components/ChainImage.d.ts.map +1 -1
- package/dist/widget/components/ChainList.d.ts +0 -5
- package/dist/widget/components/ChainList.d.ts.map +1 -1
- package/dist/widget/components/ClassicSwap.d.ts +6 -6
- package/dist/widget/components/ClassicSwap.d.ts.map +1 -1
- package/dist/widget/components/ConnectWallet.d.ts.map +1 -1
- package/dist/widget/components/ConnectedWallets.d.ts.map +1 -1
- package/dist/widget/components/DebugMenu.d.ts +1 -1
- package/dist/widget/components/DebugMenu.d.ts.map +1 -1
- package/dist/widget/components/DebugScreensList.d.ts.map +1 -1
- package/dist/widget/components/DepositTracker.d.ts.map +1 -1
- package/dist/widget/components/Earn.d.ts +5 -5
- package/dist/widget/components/Earn.d.ts.map +1 -1
- package/dist/widget/components/FeeOption.d.ts +1 -1
- package/dist/widget/components/FeeOption.d.ts.map +1 -1
- package/dist/widget/components/FeeOptions.d.ts +2 -2
- package/dist/widget/components/FeeOptions.d.ts.map +1 -1
- package/dist/widget/components/Footer.d.ts +1 -1
- package/dist/widget/components/Footer.d.ts.map +1 -1
- package/dist/widget/components/Fund.d.ts +5 -5
- package/dist/widget/components/Fund.d.ts.map +1 -1
- package/dist/widget/components/FundMethods.d.ts +0 -1
- package/dist/widget/components/FundMethods.d.ts.map +1 -1
- package/dist/widget/components/FundSwap.d.ts +6 -6
- package/dist/widget/components/FundSwap.d.ts.map +1 -1
- package/dist/widget/components/HookModalContent.d.ts +8 -0
- package/dist/widget/components/HookModalContent.d.ts.map +1 -0
- package/dist/widget/components/OriginSelectionAmount.d.ts +11 -0
- package/dist/widget/components/OriginSelectionAmount.d.ts.map +1 -0
- package/dist/widget/components/Pay.d.ts +5 -5
- package/dist/widget/components/Pay.d.ts.map +1 -1
- package/dist/widget/components/PoolDeposit.d.ts +5 -5
- package/dist/widget/components/PoolDeposit.d.ts.map +1 -1
- package/dist/widget/components/PoolWithdraw.d.ts +3 -3
- package/dist/widget/components/PoolWithdraw.d.ts.map +1 -1
- package/dist/widget/components/QuoteDetails.d.ts.map +1 -1
- package/dist/widget/components/Receipt.d.ts +2 -1
- package/dist/widget/components/Receipt.d.ts.map +1 -1
- package/dist/widget/components/RecentTokens.d.ts +4 -4
- package/dist/widget/components/RecentTokens.d.ts.map +1 -1
- package/dist/widget/components/RecipientSelectorButton.d.ts.map +1 -1
- package/dist/widget/components/ShadowPortal.d.ts +6 -0
- package/dist/widget/components/ShadowPortal.d.ts.map +1 -0
- package/dist/widget/components/Swap.d.ts +6 -6
- package/dist/widget/components/Swap.d.ts.map +1 -1
- package/dist/widget/components/ThemeProvider.d.ts +1 -1
- package/dist/widget/components/ThemeProvider.d.ts.map +1 -1
- package/dist/widget/components/TokenList.d.ts +3 -4
- package/dist/widget/components/TokenList.d.ts.map +1 -1
- package/dist/widget/components/TokenSelector.d.ts +3 -4
- package/dist/widget/components/TokenSelector.d.ts.map +1 -1
- package/dist/widget/components/Tooltip.d.ts +6 -1
- package/dist/widget/components/Tooltip.d.ts.map +1 -1
- package/dist/widget/components/TrailsHookModal.d.ts +10 -0
- package/dist/widget/components/TrailsHookModal.d.ts.map +1 -0
- package/dist/widget/components/WaasFeeOptions.d.ts +3 -0
- package/dist/widget/components/WaasFeeOptions.d.ts.map +1 -1
- package/dist/widget/components/WalletConfirmation.d.ts.map +1 -1
- package/dist/widget/components/WalletConnect.d.ts.map +1 -1
- package/dist/widget/components/WidgetProviders.d.ts +14 -0
- package/dist/widget/components/WidgetProviders.d.ts.map +1 -0
- package/dist/widget/css/compiled.css +1 -1
- package/dist/widget/hooks/useAddressWalletIcon.d.ts +10 -0
- package/dist/widget/hooks/useAddressWalletIcon.d.ts.map +1 -0
- package/dist/widget/hooks/useBalanceVisible.d.ts +1 -1
- package/dist/widget/hooks/useBalanceVisible.d.ts.map +1 -1
- package/dist/widget/hooks/useChainFilter.d.ts +1 -1
- package/dist/widget/hooks/useChainFilter.d.ts.map +1 -1
- package/dist/widget/hooks/useCheckout.d.ts +13 -1
- package/dist/widget/hooks/useCheckout.d.ts.map +1 -1
- package/dist/widget/hooks/useConnector.d.ts +4 -0
- package/dist/widget/hooks/useConnector.d.ts.map +1 -0
- package/dist/widget/hooks/useCurrentScreen.d.ts +1 -1
- package/dist/widget/hooks/useCurrentScreen.d.ts.map +1 -1
- package/dist/widget/hooks/useCustomTokenFetch.d.ts +19 -0
- package/dist/widget/hooks/useCustomTokenFetch.d.ts.map +1 -0
- package/dist/widget/hooks/useCustomTokenSearch.d.ts +20 -0
- package/dist/widget/hooks/useCustomTokenSearch.d.ts.map +1 -0
- package/dist/widget/hooks/useDebounce.d.ts +10 -0
- package/dist/widget/hooks/useDebounce.d.ts.map +1 -0
- package/dist/widget/hooks/useDebugScreens.d.ts +7 -2
- package/dist/widget/hooks/useDebugScreens.d.ts.map +1 -1
- package/dist/widget/hooks/useDefaultTokenSelection.d.ts +3 -19
- package/dist/widget/hooks/useDefaultTokenSelection.d.ts.map +1 -1
- package/dist/widget/hooks/useDestinationSelectedToken.d.ts +1 -14
- package/dist/widget/hooks/useDestinationSelectedToken.d.ts.map +1 -1
- package/dist/widget/hooks/useEarnPool.d.ts +1 -1
- package/dist/widget/hooks/useEarnPool.d.ts.map +1 -1
- package/dist/widget/hooks/useIntentTransactionHistory.d.ts.map +1 -1
- package/dist/widget/hooks/useIsMobile.d.ts +5 -0
- package/dist/widget/hooks/useIsMobile.d.ts.map +1 -0
- package/dist/widget/hooks/useMode.d.ts +2 -2
- package/dist/widget/hooks/useMode.d.ts.map +1 -1
- package/dist/widget/hooks/useOriginSelectedToken.d.ts +2 -15
- package/dist/widget/hooks/useOriginSelectedToken.d.ts.map +1 -1
- package/dist/widget/hooks/usePayMessage.d.ts.map +1 -1
- package/dist/widget/hooks/usePriceImpactWarning.d.ts +1 -1
- package/dist/widget/hooks/usePriceImpactWarning.d.ts.map +1 -1
- package/dist/widget/hooks/useQuote.d.ts +173 -4
- package/dist/widget/hooks/useQuote.d.ts.map +1 -1
- package/dist/widget/hooks/useRecentTokens.d.ts +3 -3
- package/dist/widget/hooks/useRecentTokens.d.ts.map +1 -1
- package/dist/widget/hooks/useRecipients.d.ts +1 -1
- package/dist/widget/hooks/useRecipients.d.ts.map +1 -1
- package/dist/widget/hooks/useSelectedFeeOption.d.ts +2 -2
- package/dist/widget/hooks/useSelectedFeeOption.d.ts.map +1 -1
- package/dist/widget/hooks/useSelectedFundMethod.d.ts +1 -1
- package/dist/widget/hooks/useSelectedFundMethod.d.ts.map +1 -1
- package/dist/widget/hooks/useSelectedRecipient.d.ts +1 -1
- package/dist/widget/hooks/useSelectedRecipient.d.ts.map +1 -1
- package/dist/widget/hooks/useSendForm.d.ts +9 -31
- package/dist/widget/hooks/useSendForm.d.ts.map +1 -1
- package/dist/widget/hooks/useSwapAmount.d.ts +1 -1
- package/dist/widget/hooks/useSwapAmount.d.ts.map +1 -1
- package/dist/widget/hooks/useTheme.d.ts +1 -1
- package/dist/widget/hooks/useTheme.d.ts.map +1 -1
- package/dist/widget/hooks/useTokenList.d.ts +7 -31
- package/dist/widget/hooks/useTokenList.d.ts.map +1 -1
- package/dist/widget/hooks/useTrailsSendTransaction.d.ts +83 -0
- package/dist/widget/hooks/useTrailsSendTransaction.d.ts.map +1 -0
- package/dist/widget/hooks/useWalletConnectUri.d.ts +11 -0
- package/dist/widget/hooks/useWalletConnectUri.d.ts.map +1 -0
- package/dist/widget/hooks/useWidgetProps.d.ts +5 -0
- package/dist/widget/hooks/useWidgetProps.d.ts.map +1 -1
- package/dist/widget/index.d.ts +2 -0
- package/dist/widget/index.d.ts.map +1 -1
- package/dist/widget/index.js +8 -5
- package/dist/widget/providers/TrailsModalProvider.d.ts +65 -0
- package/dist/widget/providers/TrailsModalProvider.d.ts.map +1 -0
- package/dist/widget/providers/TrailsProvider.d.ts +1 -1
- package/dist/widget/providers/TrailsProvider.d.ts.map +1 -1
- package/dist/widget/types.d.ts +11 -18
- package/dist/widget/types.d.ts.map +1 -1
- package/dist/widget/widget.d.ts +20 -11
- package/dist/widget/widget.d.ts.map +1 -1
- package/package.json +45 -49
- package/src/aave.ts +387 -138
- package/src/analytics.ts +208 -2
- package/src/chains.ts +65 -64
- package/src/constants.ts +18 -14
- package/src/customTokens.ts +151 -0
- package/src/decoders.ts +4 -7
- package/src/error.ts +7 -3
- package/src/fees.ts +239 -125
- package/src/gasless.ts +54 -108
- package/src/index.ts +29 -9
- package/src/indexerClient.ts +2 -0
- package/src/intentReceiptMonitor.ts +1 -4
- package/src/intentReceiptPoller.ts +2 -2
- package/src/intents.ts +16 -5
- package/src/mode.ts +1 -1
- package/src/mutations.ts +7 -3
- package/src/prepareSend.ts +19 -14
- package/src/prices.ts +1 -1
- package/src/sequenceWallet.ts +2 -2
- package/src/time.ts +28 -0
- package/src/tokenBalances.ts +348 -153
- package/src/tokens.ts +393 -142
- package/src/trailsClient.ts +1 -1
- package/src/trailsRouter.ts +4 -5
- package/src/transactionIntent/deposits/depositOrchestrator.ts +6 -2
- package/src/transactionIntent/deposits/gaslessDeposit.ts +13 -7
- package/src/transactionIntent/deposits/standardDeposit.ts +1 -1
- package/src/transactionIntent/execution/transactionState.ts +1 -1
- package/src/transactionIntent/handlers/crossChain.ts +75 -37
- package/src/transactionIntent/handlers/sameChainSameToken.ts +66 -20
- package/src/transactionIntent/quote/feeExtractors.ts +1 -29
- package/src/transactionIntent/quote/normalizeQuote.ts +99 -7
- package/src/transactionIntent/quote/quoteHelpers.ts +1 -1
- package/src/transactionIntent/types.ts +31 -6
- package/src/transactionIntent/utils/testnetHelpers.ts +0 -5
- package/src/transactionIntent/validators.ts +0 -30
- package/src/transactions.ts +3 -3
- package/src/utils.ts +18 -0
- package/src/wallets.ts +32 -10
- package/src/widget/compiled.css +1 -1
- package/src/widget/components/AccountIntentTransactionHistory.tsx +2 -1
- package/src/widget/components/AccountIntentTransactionHistoryButton.tsx +2 -2
- package/src/widget/components/AddressWalletIcon.tsx +29 -0
- package/src/widget/components/ChainFilterDropdown.tsx +2 -8
- package/src/widget/components/ChainImage.tsx +8 -5
- package/src/widget/components/ChainList.tsx +6 -8
- package/src/widget/components/ClassicSwap.tsx +93 -85
- package/src/widget/components/ConnectWallet.tsx +1 -2
- package/src/widget/components/ConnectedWallets.tsx +17 -4
- package/src/widget/components/DebugMenu.tsx +2 -2
- package/src/widget/components/DebugScreensList.tsx +0 -1
- package/src/widget/components/DepositTracker.tsx +20 -34
- package/src/widget/components/Earn.tsx +7 -6
- package/src/widget/components/FeeOption.tsx +4 -4
- package/src/widget/components/FeeOptions.tsx +19 -39
- package/src/widget/components/Footer.tsx +1 -1
- package/src/widget/components/Fund.tsx +23 -119
- package/src/widget/components/FundMethods.tsx +9 -6
- package/src/widget/components/FundSwap.tsx +6 -5
- package/src/widget/components/FundingMethodSelectorButton.tsx +2 -2
- package/src/widget/components/HookModalContent.tsx +306 -0
- package/src/widget/components/Modal.tsx +1 -1
- package/src/widget/components/OriginSelectionAmount.tsx +135 -0
- package/src/widget/components/Pay.tsx +66 -124
- package/src/widget/components/PoolDeposit.tsx +11 -55
- package/src/widget/components/PoolWithdraw.tsx +3 -3
- package/src/widget/components/QuoteDetails.tsx +473 -728
- package/src/widget/components/Receipt.tsx +74 -7
- package/src/widget/components/RecentTokens.tsx +8 -8
- package/src/widget/components/RecipientSelectorButton.tsx +4 -2
- package/src/widget/components/ScreenHeader.tsx +2 -2
- package/src/widget/components/SearchInputField.tsx +1 -1
- package/src/widget/components/ShadowPortal.tsx +58 -0
- package/src/widget/components/Swap.tsx +6 -5
- package/src/widget/components/ThemeProvider.tsx +1 -1
- package/src/widget/components/TokenList.tsx +3 -4
- package/src/widget/components/TokenSelector.tsx +211 -80
- package/src/widget/components/Tooltip.tsx +18 -7
- package/src/widget/components/TrailsHookModal.tsx +118 -0
- package/src/widget/components/WaasFeeOptions.tsx +333 -138
- package/src/widget/components/WalletConfirmation.tsx +7 -2
- package/src/widget/components/WalletConnect.tsx +197 -235
- package/src/widget/components/WidgetProviders.tsx +75 -0
- package/src/widget/hooks/useAddressWalletIcon.ts +53 -0
- package/src/widget/hooks/useBalanceVisible.tsx +1 -1
- package/src/widget/hooks/useChainFilter.tsx +1 -1
- package/src/widget/hooks/useCheckout.ts +13 -1
- package/src/widget/hooks/useConnector.tsx +18 -0
- package/src/widget/hooks/useCurrentScreen.tsx +3 -3
- package/src/widget/hooks/useCustomTokenFetch.tsx +72 -0
- package/src/widget/hooks/useCustomTokenSearch.tsx +402 -0
- package/src/widget/hooks/useDebounce.ts +25 -0
- package/src/widget/hooks/useDebugScreens.ts +26 -10
- package/src/widget/hooks/useDefaultTokenSelection.tsx +99 -143
- package/src/widget/hooks/useDestinationSelectedToken.tsx +1 -14
- package/src/widget/hooks/useEarnPool.tsx +1 -1
- package/src/widget/hooks/useIntentTransactionHistory.ts +20 -11
- package/src/widget/hooks/useIsMobile.tsx +50 -0
- package/src/widget/hooks/useMode.ts +2 -3
- package/src/widget/hooks/useOriginSelectedToken.tsx +2 -15
- package/src/widget/hooks/usePayMessage.tsx +31 -11
- package/src/widget/hooks/usePriceImpactWarning.ts +1 -1
- package/src/widget/hooks/useQuote.ts +189 -6
- package/src/widget/hooks/useRecentTokens.ts +6 -6
- package/src/widget/hooks/useRecipients.ts +1 -1
- package/src/widget/hooks/useSelectedFeeOption.tsx +2 -2
- package/src/widget/hooks/useSelectedFundMethod.tsx +1 -1
- package/src/widget/hooks/useSelectedRecipient.tsx +1 -1
- package/src/widget/hooks/useSendForm.ts +328 -152
- package/src/widget/hooks/useSwapAmount.tsx +1 -1
- package/src/widget/hooks/useTheme.tsx +1 -1
- package/src/widget/hooks/useTokenList.ts +672 -400
- package/src/widget/hooks/useTrailsSendTransaction.ts +949 -0
- package/src/widget/hooks/useWalletConnectUri.tsx +228 -0
- package/src/widget/hooks/useWidgetProps.tsx +3 -1
- package/src/widget/index.tsx +12 -0
- package/src/widget/providers/TrailsModalProvider.tsx +195 -0
- package/src/widget/providers/TrailsProvider.tsx +9 -3
- package/src/widget/types.ts +12 -20
- package/src/widget/widget.tsx +598 -385
- package/dist/cctp.d.ts +0 -3
- package/dist/cctp.d.ts.map +0 -1
- package/dist/lifi.d.ts +0 -4
- package/dist/lifi.d.ts.map +0 -1
- package/dist/meshconnect.d.ts +0 -171
- package/dist/meshconnect.d.ts.map +0 -1
- package/dist/relaySdk.d.ts +0 -87
- package/dist/relaySdk.d.ts.map +0 -1
- package/dist/widget/components/MeshConnectExchanges.d.ts +0 -7
- package/dist/widget/components/MeshConnectExchanges.d.ts.map +0 -1
- package/dist/widget/components/MeshConnectFlow.d.ts +0 -13
- package/dist/widget/components/MeshConnectFlow.d.ts.map +0 -1
- package/dist/widget/components/MeshConnectIframe.d.ts +0 -15
- package/dist/widget/components/MeshConnectIframe.d.ts.map +0 -1
- package/dist/widget/components/Receive.d.ts +0 -12
- package/dist/widget/components/Receive.d.ts.map +0 -1
- package/dist/widget/hooks/useSelectedMeshExchange.d.ts +0 -14
- package/dist/widget/hooks/useSelectedMeshExchange.d.ts.map +0 -1
- package/src/cctp.ts +0 -54
- package/src/lifi.ts +0 -108
- package/src/meshconnect.ts +0 -531
- package/src/relaySdk.ts +0 -703
- package/src/widget/components/MeshConnectExchanges.tsx +0 -290
- package/src/widget/components/MeshConnectFlow.tsx +0 -90
- package/src/widget/components/MeshConnectIframe.tsx +0 -500
- package/src/widget/components/Receive.tsx +0 -175
- package/src/widget/hooks/useSelectedMeshExchange.tsx +0 -46
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
getErrorString,
|
|
14
14
|
} from "../../error.js"
|
|
15
15
|
import { invalidateTokenBalancesCache } from "../../tokenBalances.js"
|
|
16
|
+
import type { TransactionState } from "../../transactions.js"
|
|
16
17
|
|
|
17
18
|
export type CheckoutCallbacks = {
|
|
18
19
|
onCheckoutStart?: (data: { sessionId: string }) => void
|
|
@@ -41,20 +42,31 @@ export type CheckoutCallbacks = {
|
|
|
41
42
|
}
|
|
42
43
|
|
|
43
44
|
export type CheckoutOnHandlers = {
|
|
45
|
+
/** Triggered when the intent transaction process starts. */
|
|
44
46
|
triggerCheckoutStart: () => void
|
|
47
|
+
/** Triggered when a quote is received. */
|
|
45
48
|
triggerCheckoutQuote: (quote: any) => void
|
|
49
|
+
/** Triggered when a signature is requested. */
|
|
46
50
|
triggerCheckoutSignatureRequest: () => void
|
|
51
|
+
/** Triggered when a signature is confirmed. */
|
|
47
52
|
triggerCheckoutSignatureConfirmed: () => void
|
|
53
|
+
/** Triggered when a signature is rejected. */
|
|
48
54
|
triggerCheckoutSignatureRejected: (error: unknown) => void
|
|
55
|
+
/** Triggered when a token approval is requested. */
|
|
49
56
|
triggerCheckoutApprovalRequest: () => void
|
|
57
|
+
/** Triggered when a token approval is confirmed. */
|
|
50
58
|
triggerCheckoutApprovalConfirmed: (transactionHash: `0x${string}`) => void
|
|
59
|
+
/** Triggered when a token approval is rejected. */
|
|
51
60
|
triggerCheckoutApprovalRejected: (error: unknown) => void
|
|
61
|
+
/** Triggered when the intent transaction process completes. */
|
|
52
62
|
triggerCheckoutComplete: (
|
|
53
63
|
txStatus: "success" | "fail",
|
|
54
64
|
accountAddress?: string,
|
|
55
65
|
) => void
|
|
66
|
+
/** Triggered when an error occurs. */
|
|
56
67
|
triggerCheckoutError: (error: unknown) => void
|
|
57
|
-
|
|
68
|
+
/** Triggered when the intent transaction states change. */
|
|
69
|
+
triggerCheckoutStatusUpdate: (transactionStates: TransactionState[]) => void
|
|
58
70
|
}
|
|
59
71
|
|
|
60
72
|
export type UseCheckoutProps = CheckoutCallbacks
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type Connector, useConnectors as useWagmiConnectors } from "wagmi"
|
|
2
|
+
|
|
3
|
+
export function useConnectors() {
|
|
4
|
+
const connectors = useWagmiConnectors()
|
|
5
|
+
return connectors ?? []
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function useConnector(id: string, uuid?: string) {
|
|
9
|
+
const connectors = useConnectors()
|
|
10
|
+
if (id === "injected" && uuid) {
|
|
11
|
+
return connectors.find((c) => c.id === id && c.name === uuid) as Connector
|
|
12
|
+
} else if (id === "injected") {
|
|
13
|
+
return connectors.find(
|
|
14
|
+
(c) => c.id === id && c.name.includes("Injected"),
|
|
15
|
+
) as Connector
|
|
16
|
+
}
|
|
17
|
+
return connectors.find((c) => c.id === id) as Connector | undefined
|
|
18
|
+
}
|
|
@@ -3,6 +3,8 @@ import { createContext, useContext, useState, type ReactNode } from "react"
|
|
|
3
3
|
export type Screen =
|
|
4
4
|
| "connect"
|
|
5
5
|
| "tokens"
|
|
6
|
+
| "select-origin-token"
|
|
7
|
+
| "select-origin-amount"
|
|
6
8
|
| "send-form"
|
|
7
9
|
| "fund-form"
|
|
8
10
|
| "fund-methods"
|
|
@@ -10,14 +12,12 @@ export type Screen =
|
|
|
10
12
|
| "earn-pools"
|
|
11
13
|
| "earn"
|
|
12
14
|
| "swap"
|
|
13
|
-
| "receive"
|
|
14
15
|
| "wallet-confirmation"
|
|
15
16
|
| "qr-code-wallet-select"
|
|
16
17
|
| "qr-code-deposit"
|
|
17
18
|
| "pending"
|
|
18
19
|
| "receipt"
|
|
19
|
-
| "
|
|
20
|
-
| "mesh-connect-exchanges"
|
|
20
|
+
| "onramp"
|
|
21
21
|
| "wallet-connect"
|
|
22
22
|
| "wallet-list"
|
|
23
23
|
| "wallet-connection-pending"
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { useQuery } from "@tanstack/react-query"
|
|
2
|
+
import { isAddress } from "viem"
|
|
3
|
+
import { getTokenInfo } from "../../tokens.js"
|
|
4
|
+
import { logger } from "../../logger.js"
|
|
5
|
+
import { useTrails } from "../providers/TrailsProvider.js"
|
|
6
|
+
|
|
7
|
+
interface UseCustomTokenFetchProps {
|
|
8
|
+
address: string | null
|
|
9
|
+
chainId: number | null
|
|
10
|
+
enabled?: boolean
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
interface UseCustomTokenFetchReturn {
|
|
14
|
+
tokenInfo: Awaited<ReturnType<typeof getTokenInfo>> | null
|
|
15
|
+
isLoading: boolean
|
|
16
|
+
error: Error | null
|
|
17
|
+
isValidAddress: boolean
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Hook to fetch token information for a custom address
|
|
22
|
+
* Reuses getTokenInfo from tokens.ts which handles caching and on-chain fetching
|
|
23
|
+
*/
|
|
24
|
+
export function useCustomTokenFetch({
|
|
25
|
+
address,
|
|
26
|
+
chainId,
|
|
27
|
+
enabled = true,
|
|
28
|
+
}: UseCustomTokenFetchProps): UseCustomTokenFetchReturn {
|
|
29
|
+
const isValidAddress = address ? isAddress(address) : false
|
|
30
|
+
const shouldFetch = enabled && isValidAddress && chainId !== null
|
|
31
|
+
const trailsConfig = useTrails()
|
|
32
|
+
|
|
33
|
+
const {
|
|
34
|
+
data: tokenInfo,
|
|
35
|
+
isLoading,
|
|
36
|
+
error,
|
|
37
|
+
} = useQuery({
|
|
38
|
+
queryKey: ["customToken", address?.toLowerCase(), chainId],
|
|
39
|
+
queryFn: async () => {
|
|
40
|
+
if (!address || !chainId) return null
|
|
41
|
+
|
|
42
|
+
try {
|
|
43
|
+
const info = await getTokenInfo(chainId, address, {
|
|
44
|
+
trailsApiKey: trailsConfig.trailsApiKey,
|
|
45
|
+
trailsApiUrl: trailsConfig.trailsApiUrl,
|
|
46
|
+
})
|
|
47
|
+
if (info) {
|
|
48
|
+
logger.console.log("[trails-sdk] Fetched custom token info:", info)
|
|
49
|
+
}
|
|
50
|
+
return info
|
|
51
|
+
} catch (err) {
|
|
52
|
+
logger.console.error(
|
|
53
|
+
"[trails-sdk] Error fetching custom token info:",
|
|
54
|
+
err,
|
|
55
|
+
)
|
|
56
|
+
throw err
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
enabled: shouldFetch,
|
|
60
|
+
staleTime: 5 * 60 * 1000, // 5 minutes - token info doesn't change often
|
|
61
|
+
gcTime: 24 * 60 * 60 * 1000, // 24 hours
|
|
62
|
+
retry: 1, // Only retry once for network errors
|
|
63
|
+
refetchOnWindowFocus: false,
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
return {
|
|
67
|
+
tokenInfo: tokenInfo ?? null,
|
|
68
|
+
isLoading,
|
|
69
|
+
error: error as Error | null,
|
|
70
|
+
isValidAddress,
|
|
71
|
+
}
|
|
72
|
+
}
|
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
import { useMemo, useEffect, useCallback } from "react"
|
|
2
|
+
import { isAddress } from "viem"
|
|
3
|
+
import { useAccount, useChainId } from "wagmi"
|
|
4
|
+
import { useQuery } from "@tanstack/react-query"
|
|
5
|
+
import { useSupportedChains } from "../../chains.js"
|
|
6
|
+
import { getChainInfo } from "../../chains.js"
|
|
7
|
+
import { useGetTokenImageUrl, getSupportedTokens } from "../../tokens.js"
|
|
8
|
+
import { useCustomTokens } from "../../customTokens.js"
|
|
9
|
+
// Removed convertTokenToSupportedToken import - addCustomToken now accepts Token directly
|
|
10
|
+
import { useCustomTokenFetch } from "./useCustomTokenFetch.js"
|
|
11
|
+
import type { Token } from "../../tokens.js"
|
|
12
|
+
import { logger } from "../../logger.js"
|
|
13
|
+
import { useAccountTokenBalance, formatRawAmount } from "../../tokenBalances.js"
|
|
14
|
+
import { useIndexerGatewayClient } from "../../indexerClient.js"
|
|
15
|
+
import { useTrailsClient } from "../../trailsClient.js"
|
|
16
|
+
import { useTrails } from "../providers/TrailsProvider.js"
|
|
17
|
+
|
|
18
|
+
interface UseCustomTokenSearchProps {
|
|
19
|
+
searchQuery: string
|
|
20
|
+
filteredTokensFormatted: Token[]
|
|
21
|
+
filterByChainId: number | null
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
interface UseCustomTokenSearchReturn {
|
|
25
|
+
chainFilteredTokens: Token[]
|
|
26
|
+
isLoadingCustomToken: boolean
|
|
27
|
+
customTokenError: Error | null
|
|
28
|
+
fetchChainId: number | null
|
|
29
|
+
isCustomToken: (chainId: number, contractAddress: string) => boolean
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Hook to handle custom token search and integration
|
|
34
|
+
* Detects addresses in search query, fetches token info, and merges with token list
|
|
35
|
+
*/
|
|
36
|
+
export function useCustomTokenSearch({
|
|
37
|
+
searchQuery,
|
|
38
|
+
filteredTokensFormatted,
|
|
39
|
+
filterByChainId,
|
|
40
|
+
}: UseCustomTokenSearchProps): UseCustomTokenSearchReturn {
|
|
41
|
+
const { address } = useAccount()
|
|
42
|
+
const connectedChainId = useChainId()
|
|
43
|
+
const { supportedChains } = useSupportedChains()
|
|
44
|
+
const { getTokenImageUrl } = useGetTokenImageUrl()
|
|
45
|
+
const { addCustomToken, customTokens } = useCustomTokens()
|
|
46
|
+
const trailsConfig = useTrails()
|
|
47
|
+
// Get official supported tokens (before merging with custom tokens) to check if token is truly custom
|
|
48
|
+
const { data: officialSupportedTokens = [] } = useQuery({
|
|
49
|
+
queryKey: [
|
|
50
|
+
"supportedTokens",
|
|
51
|
+
trailsConfig.trailsApiUrl,
|
|
52
|
+
trailsConfig.trailsApiKey,
|
|
53
|
+
],
|
|
54
|
+
queryFn: () =>
|
|
55
|
+
getSupportedTokens({
|
|
56
|
+
trailsApiKey: trailsConfig.trailsApiKey,
|
|
57
|
+
trailsApiUrl: trailsConfig.trailsApiUrl,
|
|
58
|
+
}),
|
|
59
|
+
staleTime: 60 * 60 * 1000, // 1 hour
|
|
60
|
+
gcTime: 24 * 60 * 60 * 1000, // 24 hours
|
|
61
|
+
refetchOnWindowFocus: false,
|
|
62
|
+
refetchOnReconnect: false,
|
|
63
|
+
})
|
|
64
|
+
const indexerGatewayClient = useIndexerGatewayClient()
|
|
65
|
+
const trailsClient = useTrailsClient()
|
|
66
|
+
|
|
67
|
+
// Detect if search query is a valid address
|
|
68
|
+
const searchAddress = useMemo(() => {
|
|
69
|
+
const trimmed = searchQuery.trim()
|
|
70
|
+
return isAddress(trimmed) ? trimmed : null
|
|
71
|
+
}, [searchQuery])
|
|
72
|
+
|
|
73
|
+
// Determine chain ID for fetching custom token
|
|
74
|
+
// Priority: filterByChainId > connectedChainId > first supported chain
|
|
75
|
+
const fetchChainId = useMemo(() => {
|
|
76
|
+
if (filterByChainId !== null) return filterByChainId
|
|
77
|
+
if (connectedChainId) return connectedChainId
|
|
78
|
+
// Fallback to first supported chain if available
|
|
79
|
+
return supportedChains.length > 0 ? supportedChains?.[0]?.id : null
|
|
80
|
+
}, [filterByChainId, connectedChainId, supportedChains])
|
|
81
|
+
|
|
82
|
+
// Check if the address already exists in the token list
|
|
83
|
+
// When chain filter is active, check if token exists on that specific chain
|
|
84
|
+
// Otherwise, check if it exists on any chain
|
|
85
|
+
// Also check custom tokens from localStorage
|
|
86
|
+
const addressExistsInList = useMemo(() => {
|
|
87
|
+
if (!searchAddress) return false
|
|
88
|
+
|
|
89
|
+
// First check custom tokens (from localStorage)
|
|
90
|
+
const existsInCustomTokens = customTokens.some((token) => {
|
|
91
|
+
const addressMatch =
|
|
92
|
+
token.contractAddress.toLowerCase() === searchAddress.toLowerCase()
|
|
93
|
+
if (filterByChainId !== null) {
|
|
94
|
+
return addressMatch && token.chainId === filterByChainId
|
|
95
|
+
}
|
|
96
|
+
return addressMatch
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
if (existsInCustomTokens) return true
|
|
100
|
+
|
|
101
|
+
// Then check filteredTokensFormatted
|
|
102
|
+
// If chain filter is active, check if token exists on that specific chain
|
|
103
|
+
if (filterByChainId !== null) {
|
|
104
|
+
return filteredTokensFormatted.some(
|
|
105
|
+
(token) =>
|
|
106
|
+
token.chainId === filterByChainId &&
|
|
107
|
+
token.contractAddress.toLowerCase() === searchAddress.toLowerCase(),
|
|
108
|
+
)
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Otherwise, check if it exists on any chain
|
|
112
|
+
return filteredTokensFormatted.some(
|
|
113
|
+
(token) =>
|
|
114
|
+
token.contractAddress.toLowerCase() === searchAddress.toLowerCase(),
|
|
115
|
+
)
|
|
116
|
+
}, [searchAddress, filteredTokensFormatted, filterByChainId, customTokens])
|
|
117
|
+
|
|
118
|
+
// Fetch custom token info when address is detected and not in list
|
|
119
|
+
const {
|
|
120
|
+
tokenInfo: customTokenInfo,
|
|
121
|
+
isLoading: isLoadingCustomToken,
|
|
122
|
+
error: customTokenError,
|
|
123
|
+
} = useCustomTokenFetch({
|
|
124
|
+
address: searchAddress && !addressExistsInList ? searchAddress : null,
|
|
125
|
+
chainId: fetchChainId ?? null,
|
|
126
|
+
enabled: !!searchAddress && !addressExistsInList && fetchChainId !== null,
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
// Fetch balance for newly fetched custom token
|
|
130
|
+
const {
|
|
131
|
+
tokenBalance: customTokenBalance,
|
|
132
|
+
isLoadingTokenBalance: isLoadingCustomTokenBalance,
|
|
133
|
+
} = useAccountTokenBalance({
|
|
134
|
+
account: address ?? undefined,
|
|
135
|
+
token: customTokenInfo?.contractAddress,
|
|
136
|
+
chainId: fetchChainId ?? undefined,
|
|
137
|
+
indexerGatewayClient: indexerGatewayClient ?? undefined,
|
|
138
|
+
trailsClient: trailsClient ?? undefined,
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
// Convert custom token to Token format
|
|
142
|
+
// Always include in search results, regardless of balance
|
|
143
|
+
const customTokenFormatted = useMemo((): Token | null => {
|
|
144
|
+
if (!customTokenInfo || !fetchChainId) return null
|
|
145
|
+
|
|
146
|
+
const chainInfo = getChainInfo(fetchChainId)
|
|
147
|
+
const chainName = chainInfo?.name || `Chain ${fetchChainId}`
|
|
148
|
+
const imageUrl = getTokenImageUrl({
|
|
149
|
+
chainId: fetchChainId,
|
|
150
|
+
contractAddress: customTokenInfo.contractAddress,
|
|
151
|
+
symbol: customTokenInfo.symbol,
|
|
152
|
+
})
|
|
153
|
+
|
|
154
|
+
const balance = customTokenBalance?.balance ?? "0"
|
|
155
|
+
const balanceFormatted =
|
|
156
|
+
customTokenBalance && customTokenInfo.decimals
|
|
157
|
+
? formatRawAmount(balance, customTokenInfo.decimals)
|
|
158
|
+
: "0"
|
|
159
|
+
const priceUsd = customTokenBalance?.priceUsd ?? 0
|
|
160
|
+
|
|
161
|
+
// Create Token with all required and optional properties
|
|
162
|
+
return {
|
|
163
|
+
symbol: customTokenInfo.symbol,
|
|
164
|
+
name: customTokenInfo.name,
|
|
165
|
+
decimals: customTokenInfo.decimals,
|
|
166
|
+
contractAddress: customTokenInfo.contractAddress,
|
|
167
|
+
chainId: fetchChainId,
|
|
168
|
+
chainName,
|
|
169
|
+
imageUrl,
|
|
170
|
+
balance,
|
|
171
|
+
balanceFormatted,
|
|
172
|
+
balanceDisplay: balanceFormatted,
|
|
173
|
+
balanceUsd: customTokenBalance?.balanceUsd,
|
|
174
|
+
balanceUsdFormatted: customTokenBalance?.balanceUsdFormatted,
|
|
175
|
+
balanceUsdDisplay: customTokenBalance?.balanceUsdFormatted,
|
|
176
|
+
priceUsd,
|
|
177
|
+
priceUsdFormatted: priceUsd.toFixed(2),
|
|
178
|
+
priceUsdDisplay: `$${priceUsd.toFixed(2)}`,
|
|
179
|
+
isCustomToken: true,
|
|
180
|
+
isSufficientBalance: true,
|
|
181
|
+
}
|
|
182
|
+
}, [customTokenInfo, fetchChainId, getTokenImageUrl, customTokenBalance])
|
|
183
|
+
|
|
184
|
+
// Add custom token to storage when successfully fetched
|
|
185
|
+
// Only save if it doesn't exist in the base supported tokens list
|
|
186
|
+
useEffect(() => {
|
|
187
|
+
if (customTokenInfo && !customTokenError && fetchChainId) {
|
|
188
|
+
// Check if token already exists in official supported tokens (before merging)
|
|
189
|
+
const existsInOfficialSupportedTokens = officialSupportedTokens.some(
|
|
190
|
+
(token) =>
|
|
191
|
+
token.chainId === fetchChainId &&
|
|
192
|
+
token.contractAddress.toLowerCase() ===
|
|
193
|
+
customTokenInfo.contractAddress.toLowerCase(),
|
|
194
|
+
)
|
|
195
|
+
|
|
196
|
+
// Only add to custom tokens if it's not an official supported token
|
|
197
|
+
if (!existsInOfficialSupportedTokens && customTokenInfo) {
|
|
198
|
+
// Add Token directly to storage
|
|
199
|
+
addCustomToken(customTokenInfo)
|
|
200
|
+
logger.console.log(
|
|
201
|
+
"[trails-sdk] Added custom token to storage:",
|
|
202
|
+
customTokenInfo,
|
|
203
|
+
)
|
|
204
|
+
} else {
|
|
205
|
+
logger.console.log(
|
|
206
|
+
"[trails-sdk] Token already exists in supported tokens, skipping custom token addition:",
|
|
207
|
+
{ address: customTokenInfo.contractAddress, chainId: fetchChainId },
|
|
208
|
+
)
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}, [
|
|
212
|
+
customTokenInfo,
|
|
213
|
+
customTokenError,
|
|
214
|
+
fetchChainId,
|
|
215
|
+
addCustomToken,
|
|
216
|
+
officialSupportedTokens,
|
|
217
|
+
])
|
|
218
|
+
|
|
219
|
+
// Show error if custom token fetch failed
|
|
220
|
+
useEffect(() => {
|
|
221
|
+
if (
|
|
222
|
+
customTokenError &&
|
|
223
|
+
searchAddress &&
|
|
224
|
+
!addressExistsInList &&
|
|
225
|
+
fetchChainId
|
|
226
|
+
) {
|
|
227
|
+
logger.console.error(
|
|
228
|
+
"[trails-sdk] Failed to fetch custom token:",
|
|
229
|
+
customTokenError,
|
|
230
|
+
)
|
|
231
|
+
// Error will be shown in the UI via the error message
|
|
232
|
+
}
|
|
233
|
+
}, [customTokenError, searchAddress, addressExistsInList, fetchChainId])
|
|
234
|
+
|
|
235
|
+
// Convert custom tokens from localStorage to TokenFormatted format
|
|
236
|
+
// Always include in search results, but prefer balance info from filteredTokensFormatted if available
|
|
237
|
+
const customTokensFormatted = useMemo(() => {
|
|
238
|
+
return customTokens
|
|
239
|
+
.filter((token) => {
|
|
240
|
+
// If searching by address, only include tokens that match the address
|
|
241
|
+
if (searchAddress) {
|
|
242
|
+
const addressMatch =
|
|
243
|
+
token.contractAddress.toLowerCase() === searchAddress.toLowerCase()
|
|
244
|
+
if (!addressMatch) return false
|
|
245
|
+
}
|
|
246
|
+
// Apply chain filter if active
|
|
247
|
+
if (filterByChainId !== null) {
|
|
248
|
+
return token.chainId === filterByChainId
|
|
249
|
+
}
|
|
250
|
+
return true
|
|
251
|
+
})
|
|
252
|
+
.map((token): Token => {
|
|
253
|
+
// Check if this token exists in filteredTokensFormatted (meaning it has a balance)
|
|
254
|
+
const tokenWithBalance = filteredTokensFormatted.find(
|
|
255
|
+
(t) =>
|
|
256
|
+
(t.chainId || 0) === (token.chainId || 0) &&
|
|
257
|
+
t.contractAddress.toLowerCase() ===
|
|
258
|
+
token.contractAddress.toLowerCase(),
|
|
259
|
+
)
|
|
260
|
+
|
|
261
|
+
const chainInfo = getChainInfo(token.chainId || 0)
|
|
262
|
+
const chainName = chainInfo?.name || `Chain ${token.chainId || 0}`
|
|
263
|
+
const imageUrl = getTokenImageUrl({
|
|
264
|
+
chainId: token.chainId || 0,
|
|
265
|
+
contractAddress: token.contractAddress,
|
|
266
|
+
symbol: token.symbol,
|
|
267
|
+
})
|
|
268
|
+
|
|
269
|
+
// If token exists in filteredTokensFormatted, use that data (has balance)
|
|
270
|
+
if (tokenWithBalance) {
|
|
271
|
+
return {
|
|
272
|
+
...tokenWithBalance,
|
|
273
|
+
chainName,
|
|
274
|
+
// Preserve isCustomToken flag from the custom token
|
|
275
|
+
isCustomToken: token.isCustomToken ?? true,
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// Otherwise, create a minimal token without balance (for search results)
|
|
280
|
+
return {
|
|
281
|
+
symbol: token.symbol,
|
|
282
|
+
name: token.name,
|
|
283
|
+
decimals: token.decimals,
|
|
284
|
+
contractAddress: token.contractAddress,
|
|
285
|
+
chainId: token.chainId,
|
|
286
|
+
chainName,
|
|
287
|
+
imageUrl,
|
|
288
|
+
isSufficientBalance: true,
|
|
289
|
+
isCustomToken: token.isCustomToken ?? true,
|
|
290
|
+
}
|
|
291
|
+
})
|
|
292
|
+
}, [
|
|
293
|
+
customTokens,
|
|
294
|
+
filterByChainId,
|
|
295
|
+
filteredTokensFormatted,
|
|
296
|
+
getTokenImageUrl,
|
|
297
|
+
searchAddress,
|
|
298
|
+
])
|
|
299
|
+
|
|
300
|
+
// Helper function to check if a token has a balance
|
|
301
|
+
const hasBalance = useCallback((token: Token): boolean => {
|
|
302
|
+
try {
|
|
303
|
+
const balance = token.balance || "0"
|
|
304
|
+
return BigInt(balance) > 0n
|
|
305
|
+
} catch {
|
|
306
|
+
return false
|
|
307
|
+
}
|
|
308
|
+
}, [])
|
|
309
|
+
|
|
310
|
+
// Apply chain filter to tokens and merge with custom tokens
|
|
311
|
+
// Custom tokens with no balance are placed at the bottom
|
|
312
|
+
const chainFilteredTokens = useMemo(() => {
|
|
313
|
+
let tokens = filteredTokensFormatted
|
|
314
|
+
|
|
315
|
+
// Apply chain filter
|
|
316
|
+
if (filterByChainId !== null) {
|
|
317
|
+
tokens = tokens.filter(
|
|
318
|
+
(token) => (token.chainId || 0) === filterByChainId,
|
|
319
|
+
)
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
// Create a set of existing token keys to avoid duplicates
|
|
323
|
+
const existingTokenKeys = new Set(
|
|
324
|
+
tokens.map(
|
|
325
|
+
(token) =>
|
|
326
|
+
`${token.chainId || 0}-${token.contractAddress.toLowerCase()}`,
|
|
327
|
+
),
|
|
328
|
+
)
|
|
329
|
+
|
|
330
|
+
// Separate custom tokens with and without balance
|
|
331
|
+
const customTokensWithBalance: Token[] = []
|
|
332
|
+
const customTokensWithoutBalance: Token[] = []
|
|
333
|
+
|
|
334
|
+
// Process custom tokens from localStorage
|
|
335
|
+
customTokensFormatted.forEach((customToken) => {
|
|
336
|
+
const key = `${customToken.chainId || 0}-${customToken.contractAddress.toLowerCase()}`
|
|
337
|
+
if (!existingTokenKeys.has(key)) {
|
|
338
|
+
if (hasBalance(customToken)) {
|
|
339
|
+
customTokensWithBalance.push(customToken)
|
|
340
|
+
} else {
|
|
341
|
+
customTokensWithoutBalance.push(customToken)
|
|
342
|
+
}
|
|
343
|
+
existingTokenKeys.add(key)
|
|
344
|
+
}
|
|
345
|
+
})
|
|
346
|
+
|
|
347
|
+
// Process newly fetched custom token
|
|
348
|
+
if (customTokenFormatted) {
|
|
349
|
+
const shouldInclude =
|
|
350
|
+
filterByChainId === null ||
|
|
351
|
+
customTokenFormatted.chainId === filterByChainId
|
|
352
|
+
|
|
353
|
+
if (shouldInclude) {
|
|
354
|
+
const key = `${customTokenFormatted.chainId || 0}-${customTokenFormatted.contractAddress.toLowerCase()}`
|
|
355
|
+
if (!existingTokenKeys.has(key)) {
|
|
356
|
+
if (hasBalance(customTokenFormatted)) {
|
|
357
|
+
customTokensWithBalance.push(customTokenFormatted)
|
|
358
|
+
} else {
|
|
359
|
+
customTokensWithoutBalance.push(customTokenFormatted)
|
|
360
|
+
}
|
|
361
|
+
existingTokenKeys.add(key)
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
// Combine: regular tokens + custom tokens with balance + custom tokens without balance (at bottom)
|
|
367
|
+
return [
|
|
368
|
+
...tokens,
|
|
369
|
+
...customTokensWithBalance,
|
|
370
|
+
...customTokensWithoutBalance,
|
|
371
|
+
]
|
|
372
|
+
}, [
|
|
373
|
+
filteredTokensFormatted,
|
|
374
|
+
filterByChainId,
|
|
375
|
+
customTokenFormatted,
|
|
376
|
+
customTokensFormatted,
|
|
377
|
+
hasBalance,
|
|
378
|
+
])
|
|
379
|
+
|
|
380
|
+
// Helper function to check if a token is a custom token
|
|
381
|
+
// Simply checks the isCustomToken property on the token
|
|
382
|
+
const isCustomToken = useCallback(
|
|
383
|
+
(chainId: number, contractAddress: string): boolean => {
|
|
384
|
+
// Check if token exists in customTokens with isCustomToken flag
|
|
385
|
+
return customTokens.some(
|
|
386
|
+
(token) =>
|
|
387
|
+
token.isCustomToken === true &&
|
|
388
|
+
(token.chainId || 0) === chainId &&
|
|
389
|
+
token.contractAddress.toLowerCase() === contractAddress.toLowerCase(),
|
|
390
|
+
)
|
|
391
|
+
},
|
|
392
|
+
[customTokens],
|
|
393
|
+
)
|
|
394
|
+
|
|
395
|
+
return {
|
|
396
|
+
chainFilteredTokens,
|
|
397
|
+
isLoadingCustomToken: isLoadingCustomToken || isLoadingCustomTokenBalance,
|
|
398
|
+
customTokenError,
|
|
399
|
+
fetchChainId: fetchChainId ?? null,
|
|
400
|
+
isCustomToken,
|
|
401
|
+
}
|
|
402
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { useEffect, useState } from "react"
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Debounce hook that delays updating a value until after a specified delay.
|
|
5
|
+
* Useful for reducing API calls during user input like search.
|
|
6
|
+
*
|
|
7
|
+
* @param value - The value to debounce
|
|
8
|
+
* @param delay - The delay in milliseconds (default: 300ms)
|
|
9
|
+
* @returns The debounced value
|
|
10
|
+
*/
|
|
11
|
+
export function useDebounce<T>(value: T, delay = 300): T {
|
|
12
|
+
const [debouncedValue, setDebouncedValue] = useState<T>(value)
|
|
13
|
+
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
const timer = setTimeout(() => {
|
|
16
|
+
setDebouncedValue(value)
|
|
17
|
+
}, delay)
|
|
18
|
+
|
|
19
|
+
return () => {
|
|
20
|
+
clearTimeout(timer)
|
|
21
|
+
}
|
|
22
|
+
}, [value, delay])
|
|
23
|
+
|
|
24
|
+
return debouncedValue
|
|
25
|
+
}
|
|
@@ -3,10 +3,13 @@ import { parseUnits } from "viem"
|
|
|
3
3
|
import { getNormalizedQuoteObject } from "../../prepareSend.js"
|
|
4
4
|
import type { PrepareSendQuote } from "../../prepareSend.js"
|
|
5
5
|
import type { TransactionState } from "../../transactions.js"
|
|
6
|
+
import { useTrails } from "../providers/TrailsProvider.js"
|
|
6
7
|
|
|
7
8
|
type Screen =
|
|
8
9
|
| "connect"
|
|
9
10
|
| "tokens"
|
|
11
|
+
| "select-origin-token"
|
|
12
|
+
| "select-origin-amount"
|
|
10
13
|
| "send-form"
|
|
11
14
|
| "fund-form"
|
|
12
15
|
| "fund-methods"
|
|
@@ -14,13 +17,12 @@ type Screen =
|
|
|
14
17
|
| "earn"
|
|
15
18
|
| "earn-pools"
|
|
16
19
|
| "swap"
|
|
17
|
-
| "receive"
|
|
18
20
|
| "wallet-confirmation"
|
|
19
21
|
| "qr-code-wallet-select"
|
|
20
22
|
| "qr-code-deposit"
|
|
21
23
|
| "pending"
|
|
22
24
|
| "receipt"
|
|
23
|
-
| "
|
|
25
|
+
| "onramp"
|
|
24
26
|
| "wallet-connect"
|
|
25
27
|
| "wallet-list"
|
|
26
28
|
| "wallet-connection-pending"
|
|
@@ -41,7 +43,14 @@ interface UseDebugScreensProps {
|
|
|
41
43
|
setShowWalletConnectionRetry: (show: boolean) => void
|
|
42
44
|
setError: (error: string | null) => void
|
|
43
45
|
setIsConnecting: (connecting: boolean) => void
|
|
44
|
-
|
|
46
|
+
setOnrampProps: (
|
|
47
|
+
props: {
|
|
48
|
+
toTokenSymbol?: string
|
|
49
|
+
toTokenAmount?: string
|
|
50
|
+
toChainId?: number
|
|
51
|
+
toRecipientAddress?: string
|
|
52
|
+
} | null,
|
|
53
|
+
) => void
|
|
45
54
|
isConnected: boolean
|
|
46
55
|
}
|
|
47
56
|
|
|
@@ -57,6 +66,7 @@ export const useDebugScreens = ({
|
|
|
57
66
|
setError,
|
|
58
67
|
isConnected,
|
|
59
68
|
}: UseDebugScreensProps) => {
|
|
69
|
+
const trailsConfig = useTrails()
|
|
60
70
|
const handleDebugScreenSelect = useCallback(
|
|
61
71
|
async (screen: string) => {
|
|
62
72
|
// Reset necessary state based on the target screen
|
|
@@ -89,6 +99,8 @@ export const useDebugScreens = ({
|
|
|
89
99
|
destinationTokenAddress: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",
|
|
90
100
|
destinationAmount: parseUnits("0.97", 6)?.toString(),
|
|
91
101
|
destinationTokenPriceUsd: "1",
|
|
102
|
+
trailsApiKey: trailsConfig.trailsApiKey,
|
|
103
|
+
trailsApiUrl: trailsConfig.trailsApiUrl,
|
|
92
104
|
})
|
|
93
105
|
|
|
94
106
|
switch (screen) {
|
|
@@ -104,6 +116,12 @@ export const useDebugScreens = ({
|
|
|
104
116
|
setCurrentScreen("tokens")
|
|
105
117
|
}
|
|
106
118
|
break
|
|
119
|
+
case "select-origin-token":
|
|
120
|
+
setCurrentScreen("select-origin-token")
|
|
121
|
+
break
|
|
122
|
+
case "select-origin-amount":
|
|
123
|
+
setCurrentScreen("select-origin-amount")
|
|
124
|
+
break
|
|
107
125
|
case "chain-list":
|
|
108
126
|
setSelectedToken(null)
|
|
109
127
|
setTransactionStates([])
|
|
@@ -536,7 +554,7 @@ export const useDebugScreens = ({
|
|
|
536
554
|
returnData: "0x",
|
|
537
555
|
} as any,
|
|
538
556
|
],
|
|
539
|
-
|
|
557
|
+
decodedTokenSweeperEvents: [
|
|
540
558
|
{
|
|
541
559
|
type: "Sweep",
|
|
542
560
|
token: "0x0000000000000000000000000000000000000000",
|
|
@@ -550,8 +568,8 @@ export const useDebugScreens = ({
|
|
|
550
568
|
|
|
551
569
|
setCurrentScreen("receipt")
|
|
552
570
|
break
|
|
553
|
-
case "
|
|
554
|
-
setCurrentScreen("
|
|
571
|
+
case "onramp":
|
|
572
|
+
setCurrentScreen("onramp")
|
|
555
573
|
break
|
|
556
574
|
case "wallet-connect":
|
|
557
575
|
setCurrentScreen("wallet-connect")
|
|
@@ -584,10 +602,6 @@ export const useDebugScreens = ({
|
|
|
584
602
|
setTransactionStates([])
|
|
585
603
|
setCurrentScreen("swap")
|
|
586
604
|
break
|
|
587
|
-
case "receive":
|
|
588
|
-
setCurrentMode("receive")
|
|
589
|
-
setCurrentScreen("receive")
|
|
590
|
-
break
|
|
591
605
|
case "account-history":
|
|
592
606
|
setCurrentScreen("account-history")
|
|
593
607
|
break
|
|
@@ -610,6 +624,8 @@ export const useDebugScreens = ({
|
|
|
610
624
|
setShowWalletConnectionRetry,
|
|
611
625
|
setError,
|
|
612
626
|
isConnected,
|
|
627
|
+
trailsConfig.trailsApiKey,
|
|
628
|
+
trailsConfig.trailsApiUrl,
|
|
613
629
|
],
|
|
614
630
|
)
|
|
615
631
|
|