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
package/src/analytics.ts
CHANGED
|
@@ -286,13 +286,17 @@ abstract class BaseAnalytics {
|
|
|
286
286
|
originChainId?: number
|
|
287
287
|
destinationChainId?: number
|
|
288
288
|
originTokenAddress?: string
|
|
289
|
+
originTokenAmount?: string
|
|
290
|
+
originTokenDecimals?: number
|
|
289
291
|
destinationTokenSymbol?: string
|
|
290
292
|
destinationTokenAddress?: string
|
|
291
293
|
destinationTokenAmount?: string
|
|
294
|
+
destinationTokenDecimals?: number
|
|
292
295
|
mode?: string
|
|
293
296
|
fundMethod?: string
|
|
294
297
|
sourceTokenPriceUsd?: string
|
|
295
298
|
destinationTokenPriceUsd?: string
|
|
299
|
+
tradeType?: string
|
|
296
300
|
}) {
|
|
297
301
|
resetCheckoutId()
|
|
298
302
|
|
|
@@ -310,24 +314,207 @@ abstract class BaseAnalytics {
|
|
|
310
314
|
}),
|
|
311
315
|
destinationChainId: data.destinationChainId?.toString(),
|
|
312
316
|
originChainId: data.originChainId?.toString(),
|
|
317
|
+
originTokenAmount: data.originTokenAmount?.toString(),
|
|
318
|
+
originTokenDecimals: data.originTokenDecimals?.toString(),
|
|
313
319
|
destinationTokenAmount: data.destinationTokenAmount?.toString(),
|
|
320
|
+
destinationTokenDecimals: data.destinationTokenDecimals?.toString(),
|
|
314
321
|
sourceTokenPriceUsd: data.sourceTokenPriceUsd?.toString(),
|
|
315
322
|
destinationTokenPriceUsd: data.destinationTokenPriceUsd?.toString(),
|
|
323
|
+
tradeType: data.tradeType,
|
|
316
324
|
},
|
|
317
325
|
})
|
|
318
326
|
}
|
|
319
327
|
|
|
328
|
+
/**
|
|
329
|
+
* Validates USD amounts are reasonable before sending to analytics
|
|
330
|
+
* Returns undefined if the value is invalid or suspicious
|
|
331
|
+
*/
|
|
332
|
+
private validateUsdAmount(
|
|
333
|
+
usdAmount: string | number | undefined | null,
|
|
334
|
+
context: {
|
|
335
|
+
rawAmount?: string
|
|
336
|
+
formattedAmount?: string
|
|
337
|
+
decimals?: number
|
|
338
|
+
priceUsd?: string | number | null
|
|
339
|
+
tokenSymbol?: string
|
|
340
|
+
},
|
|
341
|
+
): string | undefined {
|
|
342
|
+
if (!usdAmount) return undefined
|
|
343
|
+
|
|
344
|
+
const numValue = Number(usdAmount)
|
|
345
|
+
|
|
346
|
+
// Check for invalid numbers
|
|
347
|
+
if (!Number.isFinite(numValue) || Number.isNaN(numValue) || numValue < 0) {
|
|
348
|
+
logger.console.warn(
|
|
349
|
+
"[trails-sdk] Invalid USD amount detected, not sending to analytics:",
|
|
350
|
+
{
|
|
351
|
+
usdAmount,
|
|
352
|
+
context,
|
|
353
|
+
},
|
|
354
|
+
)
|
|
355
|
+
return undefined
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// Check for suspiciously large values (more than 1 billion USD)
|
|
359
|
+
const MAX_REASONABLE_USD = 1_000_000_000
|
|
360
|
+
if (numValue > MAX_REASONABLE_USD) {
|
|
361
|
+
logger.console.warn(
|
|
362
|
+
"[trails-sdk] Suspiciously large USD amount detected, not sending to analytics:",
|
|
363
|
+
{
|
|
364
|
+
usdAmount,
|
|
365
|
+
context,
|
|
366
|
+
},
|
|
367
|
+
)
|
|
368
|
+
return undefined
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
// Validate raw amount matches formatted amount (using decimals)
|
|
372
|
+
// This catches cases where wrong decimals were used
|
|
373
|
+
if (
|
|
374
|
+
context.rawAmount &&
|
|
375
|
+
context.formattedAmount &&
|
|
376
|
+
context.decimals !== undefined &&
|
|
377
|
+
context.decimals >= 0 &&
|
|
378
|
+
context.decimals <= 18
|
|
379
|
+
) {
|
|
380
|
+
try {
|
|
381
|
+
const rawAmountBig = BigInt(context.rawAmount)
|
|
382
|
+
const decimals = context.decimals
|
|
383
|
+
const divisor = BigInt(10 ** decimals)
|
|
384
|
+
const expectedFormatted = Number(rawAmountBig) / Number(divisor)
|
|
385
|
+
const actualFormatted = Number(context.formattedAmount)
|
|
386
|
+
const ratio = actualFormatted / expectedFormatted
|
|
387
|
+
|
|
388
|
+
// If formatted amount is more than 2x or less than 0.5x the expected value, it's suspicious
|
|
389
|
+
// (allowing some tolerance for rounding differences)
|
|
390
|
+
if (ratio > 2 || ratio < 0.5) {
|
|
391
|
+
logger.console.warn(
|
|
392
|
+
"[trails-sdk] Formatted amount doesn't match raw amount with decimals, not sending USD to analytics:",
|
|
393
|
+
{
|
|
394
|
+
usdAmount,
|
|
395
|
+
rawAmount: context.rawAmount,
|
|
396
|
+
formattedAmount: context.formattedAmount,
|
|
397
|
+
decimals: context.decimals,
|
|
398
|
+
expectedFormatted,
|
|
399
|
+
actualFormatted,
|
|
400
|
+
ratio,
|
|
401
|
+
context,
|
|
402
|
+
},
|
|
403
|
+
)
|
|
404
|
+
return undefined
|
|
405
|
+
}
|
|
406
|
+
} catch (err) {
|
|
407
|
+
// If parsing fails, log but don't block (might be edge case)
|
|
408
|
+
logger.console.warn(
|
|
409
|
+
"[trails-sdk] Error validating raw amount against formatted amount:",
|
|
410
|
+
err,
|
|
411
|
+
)
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
// If we have formatted amount and price, validate the calculation makes sense
|
|
416
|
+
if (
|
|
417
|
+
context.formattedAmount &&
|
|
418
|
+
context.priceUsd &&
|
|
419
|
+
Number(context.formattedAmount) > 0 &&
|
|
420
|
+
Number(context.priceUsd) > 0
|
|
421
|
+
) {
|
|
422
|
+
const expectedUsd =
|
|
423
|
+
Number(context.formattedAmount) * Number(context.priceUsd)
|
|
424
|
+
const ratio = numValue / expectedUsd
|
|
425
|
+
|
|
426
|
+
// If the actual USD is more than 10x or less than 0.1x the expected value, it's suspicious
|
|
427
|
+
if (ratio > 10 || ratio < 0.1) {
|
|
428
|
+
logger.console.warn(
|
|
429
|
+
"[trails-sdk] USD amount doesn't match expected calculation, not sending to analytics:",
|
|
430
|
+
{
|
|
431
|
+
usdAmount,
|
|
432
|
+
expectedUsd,
|
|
433
|
+
ratio,
|
|
434
|
+
context,
|
|
435
|
+
},
|
|
436
|
+
)
|
|
437
|
+
return undefined
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
return numValue.toString()
|
|
442
|
+
}
|
|
443
|
+
|
|
320
444
|
trackPaymentCompleted(data: {
|
|
321
445
|
userAddress?: string
|
|
322
446
|
intentAddress?: string
|
|
323
447
|
mode?: string
|
|
324
448
|
fundMethod?: string
|
|
449
|
+
originTokenAddress?: string
|
|
450
|
+
originTokenSymbol?: string
|
|
451
|
+
originTokenAmount?: string
|
|
452
|
+
originTokenAmountFormatted?: string
|
|
453
|
+
depositTokenAmount?: string
|
|
454
|
+
depositTokenAmountFormatted?: string
|
|
325
455
|
depositTokenAmountUsd?: string
|
|
456
|
+
destinationTokenAmount?: string
|
|
457
|
+
destinationTokenAmountFormatted?: string
|
|
326
458
|
destinationTokenAmountUsd?: string
|
|
459
|
+
originTokenDecimals?: number
|
|
460
|
+
destinationTokenDecimals?: number
|
|
327
461
|
originChainId?: number
|
|
328
462
|
destinationChainId?: number
|
|
463
|
+
tradeType?: string
|
|
464
|
+
sourceTokenPriceUsd?: string | number | null
|
|
465
|
+
destinationTokenPriceUsd?: string | number | null
|
|
329
466
|
[key: string]: any
|
|
330
467
|
}) {
|
|
468
|
+
// Validate USD amounts before sending
|
|
469
|
+
const validatedDepositTokenAmountUsd = this.validateUsdAmount(
|
|
470
|
+
data.depositTokenAmountUsd,
|
|
471
|
+
{
|
|
472
|
+
rawAmount: data.depositTokenAmount,
|
|
473
|
+
formattedAmount: data.depositTokenAmountFormatted,
|
|
474
|
+
decimals: data.originTokenDecimals,
|
|
475
|
+
priceUsd: data.sourceTokenPriceUsd,
|
|
476
|
+
tokenSymbol: data.originTokenSymbol,
|
|
477
|
+
},
|
|
478
|
+
)
|
|
479
|
+
|
|
480
|
+
const validatedDestinationTokenAmountUsd = this.validateUsdAmount(
|
|
481
|
+
data.destinationTokenAmountUsd,
|
|
482
|
+
{
|
|
483
|
+
rawAmount: data.destinationTokenAmount,
|
|
484
|
+
formattedAmount: data.destinationTokenAmountFormatted,
|
|
485
|
+
decimals: data.destinationTokenDecimals,
|
|
486
|
+
priceUsd: data.destinationTokenPriceUsd,
|
|
487
|
+
tokenSymbol: data.destinationTokenSymbol,
|
|
488
|
+
},
|
|
489
|
+
)
|
|
490
|
+
|
|
491
|
+
// Cross-validate: destination USD shouldn't be wildly different from deposit USD
|
|
492
|
+
// (unless there's a huge price difference, but even then, 100x difference is suspicious)
|
|
493
|
+
let finalDestinationTokenAmountUsd = validatedDestinationTokenAmountUsd
|
|
494
|
+
if (validatedDepositTokenAmountUsd && validatedDestinationTokenAmountUsd) {
|
|
495
|
+
const depositUsd = Number(validatedDepositTokenAmountUsd)
|
|
496
|
+
const destUsd = Number(validatedDestinationTokenAmountUsd)
|
|
497
|
+
const ratio = destUsd / depositUsd
|
|
498
|
+
|
|
499
|
+
// If destination USD is more than 100x or less than 0.01x the deposit USD, it's suspicious
|
|
500
|
+
if (ratio > 100 || ratio < 0.01) {
|
|
501
|
+
logger.console.warn(
|
|
502
|
+
"[trails-sdk] Suspicious USD ratio between deposit and destination, not sending destination USD:",
|
|
503
|
+
{
|
|
504
|
+
depositTokenAmountUsd: validatedDepositTokenAmountUsd,
|
|
505
|
+
destinationTokenAmountUsd: validatedDestinationTokenAmountUsd,
|
|
506
|
+
ratio,
|
|
507
|
+
depositTokenAmount: data.depositTokenAmount,
|
|
508
|
+
destinationTokenAmount: data.destinationTokenAmount,
|
|
509
|
+
originTokenSymbol: data.originTokenSymbol,
|
|
510
|
+
destinationTokenSymbol: data.destinationTokenSymbol,
|
|
511
|
+
},
|
|
512
|
+
)
|
|
513
|
+
// Don't send the suspicious destination USD value
|
|
514
|
+
finalDestinationTokenAmountUsd = undefined
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
|
|
331
518
|
this.track({
|
|
332
519
|
event: EventType.PAYMENT_COMPLETED,
|
|
333
520
|
props: {
|
|
@@ -342,8 +529,23 @@ abstract class BaseAnalytics {
|
|
|
342
529
|
...(data.intentAddress && {
|
|
343
530
|
intentAddress: data.intentAddress,
|
|
344
531
|
}),
|
|
345
|
-
|
|
346
|
-
|
|
532
|
+
originTokenAddress: data.originTokenAddress,
|
|
533
|
+
originTokenSymbol: data.originTokenSymbol,
|
|
534
|
+
originTokenAmount: data.originTokenAmount?.toString(),
|
|
535
|
+
originTokenAmountFormatted: data.originTokenAmountFormatted?.toString(),
|
|
536
|
+
depositTokenAmount: data.depositTokenAmount?.toString(),
|
|
537
|
+
depositTokenAmountFormatted:
|
|
538
|
+
data.depositTokenAmountFormatted?.toString(),
|
|
539
|
+
depositTokenAmountUsd: validatedDepositTokenAmountUsd,
|
|
540
|
+
destinationTokenAmount: data.destinationTokenAmount?.toString(),
|
|
541
|
+
destinationTokenAmountFormatted:
|
|
542
|
+
data.destinationTokenAmountFormatted?.toString(),
|
|
543
|
+
destinationTokenAmountUsd: finalDestinationTokenAmountUsd,
|
|
544
|
+
originTokenDecimals: data.originTokenDecimals?.toString(),
|
|
545
|
+
destinationTokenDecimals: data.destinationTokenDecimals?.toString(),
|
|
546
|
+
tradeType: data.tradeType,
|
|
547
|
+
sourceTokenPriceUsd: data.sourceTokenPriceUsd?.toString(),
|
|
548
|
+
destinationTokenPriceUsd: data.destinationTokenPriceUsd?.toString(),
|
|
347
549
|
},
|
|
348
550
|
})
|
|
349
551
|
resetCheckoutId()
|
|
@@ -1049,13 +1251,17 @@ export const trackPaymentStarted = (data: {
|
|
|
1049
1251
|
originChainId?: number
|
|
1050
1252
|
destinationChainId?: number
|
|
1051
1253
|
originTokenAddress?: string
|
|
1254
|
+
originTokenAmount?: string
|
|
1255
|
+
originTokenDecimals?: number
|
|
1052
1256
|
destinationTokenAddress?: string
|
|
1053
1257
|
destinationTokenSymbol?: string
|
|
1054
1258
|
destinationTokenAmount?: string
|
|
1259
|
+
destinationTokenDecimals?: number
|
|
1055
1260
|
mode?: string
|
|
1056
1261
|
fundMethod?: string
|
|
1057
1262
|
sourceTokenPriceUsd?: string
|
|
1058
1263
|
destinationTokenPriceUsd?: string
|
|
1264
|
+
tradeType?: string
|
|
1059
1265
|
}) => {
|
|
1060
1266
|
const analytics = getAnalytics()
|
|
1061
1267
|
analytics.trackPaymentStarted(data)
|
package/src/chains.ts
CHANGED
|
@@ -36,10 +36,9 @@ import {
|
|
|
36
36
|
xaiTestnet,
|
|
37
37
|
etherlinkTestnet,
|
|
38
38
|
somniaTestnet,
|
|
39
|
+
monad,
|
|
40
|
+
monadTestnet,
|
|
39
41
|
} from "viem/chains"
|
|
40
|
-
import { getRelaySupportedChains } from "./relaySdk.js"
|
|
41
|
-
import { getLifiSupportedChains } from "./lifi.js"
|
|
42
|
-
import type { QuoteProvider } from "./intents.js"
|
|
43
42
|
import { somnia } from "./customChains.js"
|
|
44
43
|
|
|
45
44
|
// Extended Chain type with imageUrl
|
|
@@ -47,12 +46,34 @@ export interface Chain extends ViemChain {
|
|
|
47
46
|
imageUrl?: string
|
|
48
47
|
}
|
|
49
48
|
|
|
49
|
+
/**
|
|
50
|
+
* Simplified chain info type for UI components.
|
|
51
|
+
* Uses `chainId` instead of `id` for consistency with component props.
|
|
52
|
+
*/
|
|
53
|
+
export interface ChainListItem {
|
|
54
|
+
chainId: number
|
|
55
|
+
name: string
|
|
56
|
+
imageUrl?: string
|
|
57
|
+
}
|
|
58
|
+
|
|
50
59
|
// Function to get chain image URL
|
|
51
60
|
export function getChainImageUrl(chainId: number): string {
|
|
52
61
|
// Use Sequence's chain image assets
|
|
53
62
|
return `https://assets.sequence.info/images/networks/large/${chainId}.webp`
|
|
54
63
|
}
|
|
55
64
|
|
|
65
|
+
/**
|
|
66
|
+
* Hook to get chain image URL for a given chain ID
|
|
67
|
+
* @param chainId - The chain ID to get the image URL for
|
|
68
|
+
* @returns Chain image URL or empty string if chainId is not provided
|
|
69
|
+
*/
|
|
70
|
+
export function useChainImageUrl(chainId?: number): string {
|
|
71
|
+
return React.useMemo(() => {
|
|
72
|
+
if (!chainId) return ""
|
|
73
|
+
return getChainImageUrl(chainId)
|
|
74
|
+
}, [chainId])
|
|
75
|
+
}
|
|
76
|
+
|
|
56
77
|
export function getAllChains(): Chain[] {
|
|
57
78
|
return [
|
|
58
79
|
arbitrum,
|
|
@@ -86,6 +107,8 @@ export function getAllChains(): Chain[] {
|
|
|
86
107
|
xaiTestnet,
|
|
87
108
|
etherlinkTestnet,
|
|
88
109
|
somniaTestnet,
|
|
110
|
+
monad,
|
|
111
|
+
monadTestnet,
|
|
89
112
|
]
|
|
90
113
|
}
|
|
91
114
|
|
|
@@ -136,6 +159,7 @@ function getSequenceRpcUrls(
|
|
|
136
159
|
"etherlink",
|
|
137
160
|
sequenceNodeGatewayUrl,
|
|
138
161
|
),
|
|
162
|
+
[monad.id]: getSequenceRpcUrlFromSlug("monad", sequenceNodeGatewayUrl),
|
|
139
163
|
}
|
|
140
164
|
}
|
|
141
165
|
|
|
@@ -235,6 +259,7 @@ export const supportedSequenceChains: Record<number, Chain> = {
|
|
|
235
259
|
[xai.id]: getChainInfo(xai.id)!,
|
|
236
260
|
[katana.id]: getChainInfo(katana.id)!,
|
|
237
261
|
[etherlink.id]: getChainInfo(etherlink.id)!,
|
|
262
|
+
[monad.id]: getChainInfo(monad.id)!,
|
|
238
263
|
}
|
|
239
264
|
|
|
240
265
|
export const supportedSequenceTestnetChains: Record<number, Chain> = {
|
|
@@ -252,6 +277,7 @@ export const supportedSequenceTestnetChains: Record<number, Chain> = {
|
|
|
252
277
|
[xaiTestnet.id]: getChainInfo(xaiTestnet.id)!,
|
|
253
278
|
[etherlinkTestnet.id]: getChainInfo(etherlinkTestnet.id)!,
|
|
254
279
|
[somniaTestnet.id]: getChainInfo(somniaTestnet.id)!,
|
|
280
|
+
[monadTestnet.id]: getChainInfo(monadTestnet.id)!,
|
|
255
281
|
}
|
|
256
282
|
|
|
257
283
|
export const mainnetChainsToTestnetChains: Record<number, Chain> = {
|
|
@@ -271,6 +297,7 @@ export const mainnetChainsToTestnetChains: Record<number, Chain> = {
|
|
|
271
297
|
[apeChain.id]: sepolia,
|
|
272
298
|
[etherlink.id]: etherlinkTestnet,
|
|
273
299
|
[somnia.id]: somniaTestnet,
|
|
300
|
+
[monad.id]: monadTestnet,
|
|
274
301
|
}
|
|
275
302
|
|
|
276
303
|
// Helper to get chain info
|
|
@@ -351,23 +378,24 @@ export async function getSupportedSequenceChains(): Promise<Chain[]> {
|
|
|
351
378
|
}
|
|
352
379
|
|
|
353
380
|
// Chain order for sorting (in the desired display order)
|
|
354
|
-
const CHAIN_ORDER = [
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
381
|
+
const CHAIN_ORDER: number[] = [
|
|
382
|
+
mainnet.id,
|
|
383
|
+
base.id,
|
|
384
|
+
arbitrum.id,
|
|
385
|
+
polygon.id,
|
|
386
|
+
katana.id,
|
|
387
|
+
bsc.id,
|
|
388
|
+
optimism.id,
|
|
389
|
+
avalanche.id,
|
|
390
|
+
arbitrumNova.id,
|
|
391
|
+
etherlink.id,
|
|
392
|
+
gnosis.id,
|
|
393
|
+
b3.id,
|
|
394
|
+
apeChain.id,
|
|
395
|
+
soneium.id,
|
|
396
|
+
somnia.id,
|
|
397
|
+
xai.id,
|
|
398
|
+
monad.id,
|
|
371
399
|
]
|
|
372
400
|
|
|
373
401
|
// Mapping of chain ID to normalized display name
|
|
@@ -397,7 +425,7 @@ export function getNormalizedChainName(
|
|
|
397
425
|
* @returns The sorted list of chains
|
|
398
426
|
*/
|
|
399
427
|
export function sortChainsByOrder(chainList: Chain[]): Chain[] {
|
|
400
|
-
return chainList.sort((a, b) => {
|
|
428
|
+
return chainList.sort((a: Chain, b: Chain) => {
|
|
401
429
|
const aIndex = CHAIN_ORDER.indexOf(a.id)
|
|
402
430
|
const bIndex = CHAIN_ORDER.indexOf(b.id)
|
|
403
431
|
|
|
@@ -415,58 +443,19 @@ export function sortChainsByOrder(chainList: Chain[]): Chain[] {
|
|
|
415
443
|
})
|
|
416
444
|
}
|
|
417
445
|
|
|
418
|
-
export async function
|
|
419
|
-
const relayChains = await getRelaySupportedChains()
|
|
420
|
-
const lifiChains = await getLifiSupportedChains()
|
|
421
|
-
const allChains = [...relayChains, ...lifiChains]
|
|
422
|
-
return allChains.filter(
|
|
423
|
-
(chain, index, self) => index === self.findIndex((c) => c.id === chain.id),
|
|
424
|
-
)
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
export async function getSupportedChains({
|
|
428
|
-
quoteProvider,
|
|
429
|
-
}: {
|
|
430
|
-
quoteProvider?: QuoteProvider | string
|
|
431
|
-
} = {}): Promise<Chain[]> {
|
|
432
|
-
let quoteProviderChains: Chain[] = []
|
|
433
|
-
if (quoteProvider === "relay") {
|
|
434
|
-
quoteProviderChains = await getRelaySupportedChains()
|
|
435
|
-
} else if (quoteProvider === "lifi") {
|
|
436
|
-
quoteProviderChains = await getLifiSupportedChains()
|
|
437
|
-
} else {
|
|
438
|
-
quoteProviderChains = await getAllQuoteProviderChains()
|
|
439
|
-
}
|
|
440
|
-
|
|
446
|
+
export async function getSupportedChains(): Promise<Chain[]> {
|
|
441
447
|
const sequenceChains = await getSupportedSequenceChains()
|
|
442
|
-
|
|
443
|
-
// Find intersection of sequence chains and relay chains
|
|
444
|
-
const supportedChains = sequenceChains.filter((sequenceChain) =>
|
|
445
|
-
quoteProviderChains.some(
|
|
446
|
-
(quoteProviderChain) => quoteProviderChain.id === sequenceChain.id,
|
|
447
|
-
),
|
|
448
|
-
)
|
|
449
|
-
|
|
450
|
-
// Ensure unique chain IDs by filtering duplicates
|
|
451
|
-
const uniqueChains = supportedChains.filter(
|
|
452
|
-
(chain, index, self) => index === self.findIndex((c) => c.id === chain.id),
|
|
453
|
-
)
|
|
454
|
-
|
|
455
448
|
// Sort chains by predefined order
|
|
456
|
-
return sortChainsByOrder(
|
|
449
|
+
return sortChainsByOrder(sequenceChains)
|
|
457
450
|
}
|
|
458
451
|
|
|
459
|
-
export function useSupportedChains({
|
|
460
|
-
quoteProvider,
|
|
461
|
-
}: {
|
|
462
|
-
quoteProvider?: QuoteProvider | string
|
|
463
|
-
} = {}): {
|
|
452
|
+
export function useSupportedChains(): {
|
|
464
453
|
supportedChains: Chain[]
|
|
465
454
|
isLoadingChains: boolean
|
|
466
455
|
} {
|
|
467
456
|
const { data: supportedChains = [], isLoading: isLoadingChains } = useQuery({
|
|
468
457
|
queryKey: ["supportedChains"],
|
|
469
|
-
queryFn: () => getSupportedChains(
|
|
458
|
+
queryFn: () => getSupportedChains(),
|
|
470
459
|
staleTime: 60 * 60 * 1000, // 1 hour - chains rarely change
|
|
471
460
|
gcTime: 24 * 60 * 60 * 1000, // 24 hours - keep in cache for a full day
|
|
472
461
|
refetchOnWindowFocus: false, // Don't refetch when window regains focus
|
|
@@ -483,3 +472,15 @@ export function getIsTestnetChainId(chainId: number): boolean {
|
|
|
483
472
|
const testnetChainIds = Object.keys(supportedSequenceTestnetChains)
|
|
484
473
|
return testnetChainIds.includes(chainId.toString())
|
|
485
474
|
}
|
|
475
|
+
|
|
476
|
+
/**
|
|
477
|
+
* Hook to get chain info for a given chain ID
|
|
478
|
+
* @param chainId - The chain ID to get info for
|
|
479
|
+
* @returns Chain info or null if not found
|
|
480
|
+
*/
|
|
481
|
+
export function useChainInfo(chainId?: number): Chain | null {
|
|
482
|
+
return React.useMemo(() => {
|
|
483
|
+
if (!chainId) return null
|
|
484
|
+
return getChainInfo(chainId)
|
|
485
|
+
}, [chainId])
|
|
486
|
+
}
|
package/src/constants.ts
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
|
-
import type { TrailsAddressOverrides } from "@
|
|
1
|
+
import type { TrailsAddressOverrides, TrailsContracts } from "@0xtrails/api"
|
|
2
2
|
import type { Context as ContextLike } from "@0xsequence/wallet-primitives"
|
|
3
3
|
import type { Address } from "ox"
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
// Sequence Wallet V3 `rc-4` contract addresses
|
|
6
|
+
export const SEQUENCE_V3_CONTRACT_ADDRESSES: ContextLike.Context & {
|
|
7
|
+
guestModule?: Address.Address
|
|
8
|
+
} = {
|
|
6
9
|
factory: "0x00000000000018A77519fcCCa060c2537c9D6d3F" as Address.Address,
|
|
7
|
-
stage1: "
|
|
8
|
-
stage2: "
|
|
10
|
+
stage1: "0x0000000000003DF093bc4257E6dCE45D937EF161" as Address.Address,
|
|
11
|
+
stage2: "0x10bE1Abf3cD0918bb1079ECc6b8220c177F34088" as Address.Address,
|
|
12
|
+
guestModule: "0x0000000000601fcA38f0cCA649453F6739436d6C" as Address.Address,
|
|
9
13
|
creationCode:
|
|
10
14
|
"0x6041600e3d396021805130553df33d3d36153402601f57363d3d373d363d30545af43d82803e903d91601f57fd5bf3" as Address.Address,
|
|
11
15
|
}
|
|
@@ -16,16 +20,16 @@ export const SEQUENCE_V3_CONTRACT_ADDRESSES_OVERRIDES: TrailsAddressOverrides =
|
|
|
16
20
|
sequenceWalletMainModuleAddress: SEQUENCE_V3_CONTRACT_ADDRESSES.stage1,
|
|
17
21
|
sequenceWalletMainModuleUpgradableAddress:
|
|
18
22
|
SEQUENCE_V3_CONTRACT_ADDRESSES.stage2,
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
export const
|
|
25
|
-
"
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
23
|
+
sequenceWalletGuestModuleAddress:
|
|
24
|
+
SEQUENCE_V3_CONTRACT_ADDRESSES.guestModule,
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Trails `rc-3` contract addresses
|
|
28
|
+
export const TRAILS_CONTRACTS: TrailsContracts = {
|
|
29
|
+
trailsIntentEntrypointAddress: "0x91E9e3Fe369CF005dB2857Ef24955A66d1E692Cf",
|
|
30
|
+
trailsRouterAddress: "0xF8A739B9F24E297a98b7aba7A9cdFDBD457F6fF8",
|
|
31
|
+
trailsRouterShimAddress: "0x1306aF05bA556839885B9B8c758f1d2F33d3571E",
|
|
32
|
+
}
|
|
29
33
|
|
|
30
34
|
export const PROD_SEQUENCE_NODE_GATEWAY_URL = "https://nodes.sequence.app"
|
|
31
35
|
export const PROD_SEQUENCE_INDEXER_URL = "https://indexer.sequence.app"
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { useState, useCallback, useEffect } from "react"
|
|
2
|
+
import type { Token } from "./tokens.js"
|
|
3
|
+
import { logger } from "./logger.js"
|
|
4
|
+
|
|
5
|
+
const cacheVersion = "01"
|
|
6
|
+
|
|
7
|
+
// Custom tokens storage key
|
|
8
|
+
const CUSTOM_TOKENS_KEY = `trails-sdk:custom-tokens:${cacheVersion}`
|
|
9
|
+
|
|
10
|
+
// Custom tokens storage utilities
|
|
11
|
+
function getCustomTokensFromStorage(): Token[] {
|
|
12
|
+
if (typeof window === "undefined") return []
|
|
13
|
+
|
|
14
|
+
try {
|
|
15
|
+
const cached = localStorage.getItem(CUSTOM_TOKENS_KEY)
|
|
16
|
+
if (!cached) return []
|
|
17
|
+
|
|
18
|
+
const parsed = JSON.parse(cached) as Token[]
|
|
19
|
+
// Validate that it's an array
|
|
20
|
+
if (!Array.isArray(parsed)) {
|
|
21
|
+
logger.console.warn(
|
|
22
|
+
"[trails-sdk] Invalid custom tokens format in localStorage, clearing",
|
|
23
|
+
)
|
|
24
|
+
localStorage.removeItem(CUSTOM_TOKENS_KEY)
|
|
25
|
+
return []
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Validate each token has required fields
|
|
29
|
+
return parsed.filter((token) => {
|
|
30
|
+
const isValid =
|
|
31
|
+
token &&
|
|
32
|
+
typeof token.contractAddress === "string" &&
|
|
33
|
+
typeof token.symbol === "string" &&
|
|
34
|
+
typeof token.name === "string" &&
|
|
35
|
+
typeof token.decimals === "number"
|
|
36
|
+
if (!isValid) {
|
|
37
|
+
logger.console.warn(
|
|
38
|
+
"[trails-sdk] Invalid custom token found, skipping:",
|
|
39
|
+
token,
|
|
40
|
+
)
|
|
41
|
+
}
|
|
42
|
+
return isValid
|
|
43
|
+
}) as Token[]
|
|
44
|
+
} catch (error) {
|
|
45
|
+
logger.console.error(
|
|
46
|
+
"[trails-sdk] Error reading custom tokens from localStorage:",
|
|
47
|
+
error,
|
|
48
|
+
)
|
|
49
|
+
// Clear corrupted data
|
|
50
|
+
try {
|
|
51
|
+
localStorage.removeItem(CUSTOM_TOKENS_KEY)
|
|
52
|
+
} catch {
|
|
53
|
+
// Ignore errors when clearing
|
|
54
|
+
}
|
|
55
|
+
return []
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function saveCustomTokensToStorage(tokens: Token[]): void {
|
|
60
|
+
if (typeof window === "undefined") return
|
|
61
|
+
|
|
62
|
+
try {
|
|
63
|
+
localStorage.setItem(CUSTOM_TOKENS_KEY, JSON.stringify(tokens))
|
|
64
|
+
} catch (error) {
|
|
65
|
+
logger.console.error(
|
|
66
|
+
"[trails-sdk] Error saving custom tokens to localStorage:",
|
|
67
|
+
error,
|
|
68
|
+
)
|
|
69
|
+
// Handle quota exceeded error gracefully
|
|
70
|
+
if (error instanceof DOMException && error.name === "QuotaExceededError") {
|
|
71
|
+
logger.console.warn(
|
|
72
|
+
"[trails-sdk] localStorage quota exceeded, cannot save custom tokens",
|
|
73
|
+
)
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Hook to manage custom tokens stored in localStorage
|
|
80
|
+
* Custom tokens persist across sessions and are merged with supported tokens
|
|
81
|
+
*/
|
|
82
|
+
export function useCustomTokens(): {
|
|
83
|
+
customTokens: Token[]
|
|
84
|
+
addCustomToken: (token: Token) => void
|
|
85
|
+
removeCustomToken: (chainId: number, contractAddress: string) => void
|
|
86
|
+
clearCustomTokens: () => void
|
|
87
|
+
} {
|
|
88
|
+
const [customTokens, setCustomTokens] = useState<Token[]>(() => {
|
|
89
|
+
return getCustomTokensFromStorage()
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
// Sync with localStorage on mount
|
|
93
|
+
useEffect(() => {
|
|
94
|
+
const stored = getCustomTokensFromStorage()
|
|
95
|
+
setCustomTokens(stored)
|
|
96
|
+
}, [])
|
|
97
|
+
|
|
98
|
+
const addCustomToken = useCallback((token: Token) => {
|
|
99
|
+
setCustomTokens((prev) => {
|
|
100
|
+
// Check if token already exists (same chainId + contractAddress)
|
|
101
|
+
const tokenKey = `${token.chainId || 0}-${token.contractAddress.toLowerCase()}`
|
|
102
|
+
const existingIndex = prev.findIndex(
|
|
103
|
+
(t) =>
|
|
104
|
+
`${t.chainId || 0}-${t.contractAddress.toLowerCase()}` === tokenKey,
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
// Ensure isCustomToken is set to true
|
|
108
|
+
const tokenWithFlag = { ...token, isCustomToken: true }
|
|
109
|
+
|
|
110
|
+
let updated: Token[]
|
|
111
|
+
if (existingIndex >= 0) {
|
|
112
|
+
// Update existing token
|
|
113
|
+
updated = [...prev]
|
|
114
|
+
updated[existingIndex] = tokenWithFlag
|
|
115
|
+
} else {
|
|
116
|
+
// Add new token
|
|
117
|
+
updated = [...prev, tokenWithFlag]
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
saveCustomTokensToStorage(updated)
|
|
121
|
+
return updated
|
|
122
|
+
})
|
|
123
|
+
}, [])
|
|
124
|
+
|
|
125
|
+
const removeCustomToken = useCallback(
|
|
126
|
+
(chainId: number, contractAddress: string) => {
|
|
127
|
+
setCustomTokens((prev) => {
|
|
128
|
+
const updated = prev.filter(
|
|
129
|
+
(t) =>
|
|
130
|
+
t.chainId !== chainId ||
|
|
131
|
+
t.contractAddress.toLowerCase() !== contractAddress.toLowerCase(),
|
|
132
|
+
)
|
|
133
|
+
saveCustomTokensToStorage(updated)
|
|
134
|
+
return updated
|
|
135
|
+
})
|
|
136
|
+
},
|
|
137
|
+
[],
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
const clearCustomTokens = useCallback(() => {
|
|
141
|
+
setCustomTokens([])
|
|
142
|
+
saveCustomTokensToStorage([])
|
|
143
|
+
}, [])
|
|
144
|
+
|
|
145
|
+
return {
|
|
146
|
+
customTokens,
|
|
147
|
+
addCustomToken,
|
|
148
|
+
removeCustomToken,
|
|
149
|
+
clearCustomTokens,
|
|
150
|
+
}
|
|
151
|
+
}
|