0xtrails 0.1.13 → 0.2.1
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.map +1 -1
- package/dist/analytics.d.ts +12 -2
- package/dist/analytics.d.ts.map +1 -1
- package/dist/apiClient.d.ts +1 -1
- package/dist/apiClient.d.ts.map +1 -1
- package/dist/{ccip-D3gTQONK.js → ccip-BbfANth7.js} +12 -12
- package/dist/cctp.d.ts.map +1 -1
- package/dist/cctpqueue.d.ts +3 -3
- package/dist/cctpqueue.d.ts.map +1 -1
- package/dist/chains.d.ts.map +1 -1
- package/dist/config.d.ts +18 -5
- package/dist/config.d.ts.map +1 -1
- package/dist/constants.d.ts +6 -5
- package/dist/constants.d.ts.map +1 -1
- package/dist/contractUtils.d.ts +2 -0
- package/dist/contractUtils.d.ts.map +1 -1
- package/dist/customChains.d.ts +24 -0
- package/dist/customChains.d.ts.map +1 -0
- package/dist/gasless.d.ts +19 -7
- package/dist/gasless.d.ts.map +1 -1
- package/dist/{index-CnUM7lKf.js → index-WpIVoh3X.js} +36741 -31761
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +405 -394
- package/dist/indexerClient.d.ts +10 -0
- package/dist/indexerClient.d.ts.map +1 -1
- package/dist/intentEntrypoint.d.ts +122 -0
- package/dist/intentEntrypoint.d.ts.map +1 -0
- package/dist/intents.d.ts +5 -3
- package/dist/intents.d.ts.map +1 -1
- package/dist/metaTxnMonitor.d.ts.map +1 -1
- package/dist/morpho.d.ts.map +1 -1
- package/dist/pools.d.ts +3 -1
- package/dist/pools.d.ts.map +1 -1
- package/dist/prepareSend.d.ts +18 -9
- 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/relaySdk.d.ts.map +1 -1
- package/dist/relayer.d.ts.map +1 -1
- package/dist/toast.d.ts +9 -0
- package/dist/toast.d.ts.map +1 -0
- package/dist/tokenBalances.d.ts +6 -2
- package/dist/tokenBalances.d.ts.map +1 -1
- package/dist/tokens.d.ts.map +1 -1
- package/dist/trails.d.ts +6 -5
- package/dist/trails.d.ts.map +1 -1
- package/dist/trailsClient.d.ts +12 -0
- package/dist/trailsClient.d.ts.map +1 -0
- package/dist/trailsRouter.d.ts +22 -0
- package/dist/trailsRouter.d.ts.map +1 -0
- package/dist/transactions.d.ts +8 -1
- package/dist/transactions.d.ts.map +1 -1
- package/dist/wallets.d.ts.map +1 -1
- package/dist/widget/components/AccountActionsDropdown.d.ts.map +1 -1
- package/dist/widget/components/AccountIntentTransactionHistory.d.ts.map +1 -1
- package/dist/widget/components/AccountSettings.d.ts +7 -0
- package/dist/widget/components/AccountSettings.d.ts.map +1 -0
- package/dist/widget/components/ChainList.d.ts +0 -1
- package/dist/widget/components/ChainList.d.ts.map +1 -1
- package/dist/widget/components/ClassicSwap.d.ts +46 -0
- package/dist/widget/components/ClassicSwap.d.ts.map +1 -0
- package/dist/widget/components/ConfigDisplay.d.ts.map +1 -1
- package/dist/widget/components/ConnectWallet.d.ts.map +1 -1
- package/dist/widget/components/ConnectedWallets.d.ts +9 -0
- package/dist/widget/components/ConnectedWallets.d.ts.map +1 -0
- package/dist/widget/components/DebugMenu.d.ts.map +1 -1
- package/dist/widget/components/DebugScreensList.d.ts.map +1 -1
- package/dist/widget/components/DebugToast.d.ts +3 -0
- package/dist/widget/components/DebugToast.d.ts.map +1 -0
- package/dist/widget/components/Earn.d.ts.map +1 -1
- package/dist/widget/components/EarnPools.d.ts.map +1 -1
- package/dist/widget/components/FeeOption.d.ts +22 -0
- package/dist/widget/components/FeeOption.d.ts.map +1 -0
- package/dist/widget/components/FeeOptions.d.ts +13 -17
- package/dist/widget/components/FeeOptions.d.ts.map +1 -1
- package/dist/widget/components/Fund.d.ts +44 -0
- package/dist/widget/components/Fund.d.ts.map +1 -0
- package/dist/widget/components/FundMethods.d.ts +1 -1
- package/dist/widget/components/FundMethods.d.ts.map +1 -1
- package/dist/widget/components/FundSendForm.d.ts.map +1 -1
- package/dist/widget/components/Identicon.d.ts +9 -0
- package/dist/widget/components/Identicon.d.ts.map +1 -0
- package/dist/widget/components/MeshConnectExchanges.d.ts +5 -2
- package/dist/widget/components/MeshConnectExchanges.d.ts.map +1 -1
- package/dist/widget/components/MeshConnectFlow.d.ts +2 -0
- package/dist/widget/components/MeshConnectFlow.d.ts.map +1 -1
- package/dist/widget/components/NativeGasOption.d.ts +12 -0
- package/dist/widget/components/NativeGasOption.d.ts.map +1 -0
- package/dist/widget/components/Pay.d.ts +46 -0
- package/dist/widget/components/Pay.d.ts.map +1 -0
- package/dist/widget/components/PaySendForm.d.ts.map +1 -1
- package/dist/widget/components/QuoteDetails.d.ts.map +1 -1
- package/dist/widget/components/Receive.d.ts.map +1 -1
- package/dist/widget/components/RecentTokens.d.ts.map +1 -1
- package/dist/widget/components/Recipients.d.ts +9 -0
- package/dist/widget/components/Recipients.d.ts.map +1 -0
- package/dist/widget/components/RefundWarning.d.ts +9 -0
- package/dist/widget/components/RefundWarning.d.ts.map +1 -0
- package/dist/widget/components/SimpleSwap.d.ts.map +1 -1
- package/dist/widget/components/Swap.d.ts.map +1 -1
- package/dist/widget/components/SwapSettings.d.ts +1 -5
- package/dist/widget/components/SwapSettings.d.ts.map +1 -1
- package/dist/widget/components/ThemeProvider.d.ts.map +1 -1
- package/dist/widget/components/ThemeSyncer.d.ts +6 -0
- package/dist/widget/components/ThemeSyncer.d.ts.map +1 -0
- package/dist/widget/components/Toast.d.ts +24 -0
- package/dist/widget/components/Toast.d.ts.map +1 -0
- package/dist/widget/components/TokenList.d.ts.map +1 -1
- package/dist/widget/components/TokenSelector.d.ts.map +1 -1
- package/dist/widget/components/TransactionDetails.d.ts.map +1 -1
- package/dist/widget/components/TruncatedAddress.d.ts +2 -0
- package/dist/widget/components/TruncatedAddress.d.ts.map +1 -1
- package/dist/widget/components/UserPreferences.d.ts +7 -0
- package/dist/widget/components/UserPreferences.d.ts.map +1 -0
- package/dist/widget/hooks/useBack.d.ts +2 -0
- package/dist/widget/hooks/useBack.d.ts.map +1 -1
- package/dist/widget/hooks/useBalanceVisible.d.ts +1 -0
- package/dist/widget/hooks/useBalanceVisible.d.ts.map +1 -1
- package/dist/widget/hooks/useCheckout.d.ts.map +1 -1
- package/dist/widget/hooks/useCurrentScreen.d.ts +1 -1
- package/dist/widget/hooks/useCurrentScreen.d.ts.map +1 -1
- package/dist/widget/hooks/useDebugScreens.d.ts +1 -1
- package/dist/widget/hooks/useDebugScreens.d.ts.map +1 -1
- package/dist/widget/hooks/useDefaultTokenSelection.d.ts +54 -0
- package/dist/widget/hooks/useDefaultTokenSelection.d.ts.map +1 -0
- package/dist/widget/hooks/useIntentTransactionHistory.d.ts.map +1 -1
- package/dist/widget/hooks/usePayMessage.d.ts +34 -0
- package/dist/widget/hooks/usePayMessage.d.ts.map +1 -0
- package/dist/widget/hooks/useRecipients.d.ts +17 -0
- package/dist/widget/hooks/useRecipients.d.ts.map +1 -0
- package/dist/widget/hooks/useSelectedFeeToken.d.ts +32 -0
- package/dist/widget/hooks/useSelectedFeeToken.d.ts.map +1 -0
- package/dist/widget/hooks/useSelectedMeshExchange.d.ts +14 -0
- package/dist/widget/hooks/useSelectedMeshExchange.d.ts.map +1 -0
- package/dist/widget/hooks/useSelectedRecipient.d.ts +12 -0
- package/dist/widget/hooks/useSelectedRecipient.d.ts.map +1 -0
- package/dist/widget/hooks/useSendForm.d.ts +10 -13
- package/dist/widget/hooks/useSendForm.d.ts.map +1 -1
- package/dist/widget/hooks/useSwapAmount.d.ts +13 -0
- package/dist/widget/hooks/useSwapAmount.d.ts.map +1 -0
- package/dist/widget/hooks/useSwapSettings.d.ts +16 -0
- package/dist/widget/hooks/useSwapSettings.d.ts.map +1 -0
- package/dist/widget/hooks/useTargetAmount.d.ts +5 -0
- package/dist/widget/hooks/useTargetAmount.d.ts.map +1 -0
- package/dist/widget/hooks/useTheme.d.ts +14 -0
- package/dist/widget/hooks/useTheme.d.ts.map +1 -0
- package/dist/widget/hooks/useTokenList.d.ts.map +1 -1
- package/dist/widget/index.js +2 -2
- package/dist/widget/widget.d.ts +9 -0
- package/dist/widget/widget.d.ts.map +1 -1
- package/package.json +38 -36
- package/src/aave.ts +6 -1
- package/src/analytics.ts +109 -53
- package/src/apiClient.ts +1 -1
- package/src/cctp.ts +6 -2
- package/src/cctpqueue.ts +7 -7
- package/src/chains.ts +18 -0
- package/src/config.ts +63 -17
- package/src/constants.ts +20 -16
- package/src/contractUtils.ts +33 -2
- package/src/customChains.ts +24 -0
- package/src/gasless.ts +162 -109
- package/src/index.ts +11 -1
- package/src/indexerClient.ts +73 -1
- package/src/intentEntrypoint.ts +218 -0
- package/src/intents.ts +85 -54
- package/src/metaTxnMonitor.ts +1 -0
- package/src/morpho.ts +13 -2
- package/src/pools.ts +68 -86
- package/src/prepareSend.ts +1719 -967
- package/src/prices.ts +51 -7
- package/src/relaySdk.ts +6 -4
- package/src/relayer.ts +6 -3
- package/src/toast.ts +110 -0
- package/src/tokenBalances.ts +112 -20
- package/src/tokens.ts +70 -7
- package/src/trails.ts +81 -80
- package/src/trailsClient.ts +48 -0
- package/src/{proxyCaller.ts → trailsRouter.ts} +25 -20
- package/src/transactions.ts +30 -88
- package/src/umd.tsx +1 -1
- package/src/wallets.ts +2 -1
- package/src/widget/assets/sequence-logo.svg +15 -0
- package/src/widget/compiled.css +2 -2
- package/src/widget/components/AccountActionsDropdown.tsx +18 -159
- package/src/widget/components/AccountIntentTransactionHistory.tsx +346 -63
- package/src/widget/components/AccountSettings.tsx +102 -0
- package/src/widget/components/ChainFilterDropdown.tsx +1 -1
- package/src/widget/components/ChainList.tsx +10 -20
- package/src/widget/components/ClassicSwap.tsx +921 -0
- package/src/widget/components/ConfigDisplay.tsx +41 -5
- package/src/widget/components/ConnectWallet.tsx +168 -11
- package/src/widget/components/ConnectedWallets.tsx +342 -0
- package/src/widget/components/DebugMenu.tsx +2 -0
- package/src/widget/components/DebugScreensList.tsx +3 -0
- package/src/widget/components/DebugToast.tsx +63 -0
- package/src/widget/components/Earn.tsx +112 -143
- package/src/widget/components/EarnPools.tsx +2 -4
- package/src/widget/components/EarnPoolsFilters.tsx +6 -6
- package/src/widget/components/FeeOption.tsx +78 -0
- package/src/widget/components/FeeOptions.tsx +192 -127
- package/src/widget/components/Fund.tsx +1236 -0
- package/src/widget/components/FundMethods.tsx +4 -4
- package/src/widget/components/FundSendForm.tsx +1 -34
- package/src/widget/components/Identicon.tsx +158 -0
- package/src/widget/components/MeshConnectExchanges.tsx +32 -3
- package/src/widget/components/MeshConnectFlow.tsx +23 -4
- package/src/widget/components/NativeGasOption.tsx +99 -0
- package/src/widget/components/Pay.tsx +1092 -0
- package/src/widget/components/PaySendForm.tsx +1 -38
- package/src/widget/components/QuoteDetails.tsx +1 -30
- package/src/widget/components/Receipt.tsx +1 -1
- package/src/widget/components/Receive.tsx +4 -2
- package/src/widget/components/RecentTokens.tsx +2 -1
- package/src/widget/components/Recipients.tsx +448 -0
- package/src/widget/components/RefundWarning.tsx +61 -0
- package/src/widget/components/ScreenHeader.tsx +1 -1
- package/src/widget/components/SimpleSwap.tsx +74 -58
- package/src/widget/components/Swap.tsx +35 -853
- package/src/widget/components/SwapSettings.tsx +5 -11
- package/src/widget/components/ThemeProvider.tsx +32 -0
- package/src/widget/components/ThemeSyncer.tsx +47 -0
- package/src/widget/components/Toast.tsx +315 -0
- package/src/widget/components/TokenList.tsx +2 -34
- package/src/widget/components/TokenSelector.tsx +14 -3
- package/src/widget/components/TransactionDetails.tsx +153 -13
- package/src/widget/components/TransferPendingVertical.tsx +1 -1
- package/src/widget/components/TruncatedAddress.tsx +5 -1
- package/src/widget/components/UserPreferences.tsx +155 -0
- package/src/widget/components/WalletList.tsx +1 -1
- package/src/widget/hooks/useBack.tsx +4 -0
- package/src/widget/hooks/useBalanceVisible.tsx +40 -2
- package/src/widget/hooks/useCheckout.ts +13 -0
- package/src/widget/hooks/useCurrentScreen.tsx +4 -0
- package/src/widget/hooks/useDebugScreens.ts +12 -2
- package/src/widget/hooks/useDefaultTokenSelection.tsx +471 -0
- package/src/widget/hooks/useIntentTransactionHistory.ts +212 -0
- package/src/widget/hooks/usePayMessage.tsx +370 -0
- package/src/widget/hooks/useRecipients.ts +168 -0
- package/src/widget/hooks/useSelectedFeeToken.tsx +299 -0
- package/src/widget/hooks/useSelectedMeshExchange.tsx +46 -0
- package/src/widget/hooks/useSelectedRecipient.tsx +48 -0
- package/src/widget/hooks/useSendForm.ts +257 -49
- package/src/widget/hooks/useSwapAmount.tsx +50 -0
- package/src/widget/hooks/useSwapSettings.tsx +100 -0
- package/src/widget/hooks/useTargetAmount.ts +23 -0
- package/src/widget/hooks/useTheme.tsx +80 -0
- package/src/widget/hooks/useTokenList.ts +20 -11
- package/src/widget/index.css +45 -21
- package/src/widget/widget.tsx +294 -136
- package/dist/address.d.ts +0 -2
- package/dist/address.d.ts.map +0 -1
- package/dist/proxyCaller.d.ts +0 -21
- package/dist/proxyCaller.d.ts.map +0 -1
- package/src/address.ts +0 -6
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
import React, {
|
|
2
|
+
createContext,
|
|
3
|
+
useContext,
|
|
4
|
+
useState,
|
|
5
|
+
useCallback,
|
|
6
|
+
useEffect,
|
|
7
|
+
useMemo,
|
|
8
|
+
type ReactNode,
|
|
9
|
+
} from "react"
|
|
10
|
+
import { logger } from "../../logger.js"
|
|
11
|
+
import { zeroAddress } from "viem"
|
|
12
|
+
|
|
13
|
+
// Define the FeeOption interface with balance check properties
|
|
14
|
+
export interface FeeOption {
|
|
15
|
+
tokenAddress: string
|
|
16
|
+
tokenSymbol: string
|
|
17
|
+
tokenDecimals: number
|
|
18
|
+
amount: string
|
|
19
|
+
amountUSD: number
|
|
20
|
+
notEnoughBalance?: boolean
|
|
21
|
+
tokenImageUrl?: string
|
|
22
|
+
chainId?: number
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Token type with balance information
|
|
26
|
+
export interface TokenWithBalance {
|
|
27
|
+
chainId: number
|
|
28
|
+
contractAddress?: string
|
|
29
|
+
balance?: string
|
|
30
|
+
imageUrl?: string
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
interface SelectedFeeTokenContextType {
|
|
34
|
+
selectedFeeToken: FeeOption | null
|
|
35
|
+
setSelectedFeeToken: (token: FeeOption | null) => void
|
|
36
|
+
clearSelectedFeeToken: () => void
|
|
37
|
+
processedFeeOptions: FeeOption[]
|
|
38
|
+
setRawFeeOptions: (
|
|
39
|
+
feeOptions: any[] | null | undefined,
|
|
40
|
+
originChainId: number | undefined,
|
|
41
|
+
availableTokens: TokenWithBalance[],
|
|
42
|
+
) => void
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const SelectedFeeTokenContext = createContext<
|
|
46
|
+
SelectedFeeTokenContextType | undefined
|
|
47
|
+
>(undefined)
|
|
48
|
+
|
|
49
|
+
interface SelectedFeeTokenProviderProps {
|
|
50
|
+
children: ReactNode
|
|
51
|
+
initialToken?: FeeOption | null
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export const SelectedFeeTokenProvider: React.FC<
|
|
55
|
+
SelectedFeeTokenProviderProps
|
|
56
|
+
> = ({ children, initialToken = null }) => {
|
|
57
|
+
const [selectedFeeToken, setSelectedFeeTokenInternalRaw] =
|
|
58
|
+
useState<FeeOption | null>(initialToken)
|
|
59
|
+
const [hasUserSelectedFeeOption, setHasUserSelectedFeeOption] =
|
|
60
|
+
useState(false)
|
|
61
|
+
const [rawFeeOptions, setRawFeeOptionsInternal] = useState<any[]>([])
|
|
62
|
+
const [originTokenChainId, setOriginTokenChainId] = useState<
|
|
63
|
+
number | undefined
|
|
64
|
+
>(undefined)
|
|
65
|
+
const [availableTokens, setAvailableTokens] = useState<TokenWithBalance[]>([])
|
|
66
|
+
|
|
67
|
+
// Wrapper to log all state changes to selectedFeeToken
|
|
68
|
+
const setSelectedFeeTokenInternal = useCallback(
|
|
69
|
+
(token: FeeOption | null) => {
|
|
70
|
+
logger.console.log(
|
|
71
|
+
"[trails-sdk] [FEE-SELECT] selectedFeeToken state changing:",
|
|
72
|
+
{
|
|
73
|
+
from: selectedFeeToken,
|
|
74
|
+
to: token,
|
|
75
|
+
fromNull: selectedFeeToken === null,
|
|
76
|
+
toNull: token === null,
|
|
77
|
+
stackTrace: new Error().stack?.split("\n").slice(2, 5).join("\n"), // Get call stack
|
|
78
|
+
},
|
|
79
|
+
)
|
|
80
|
+
setSelectedFeeTokenInternalRaw(token)
|
|
81
|
+
},
|
|
82
|
+
[selectedFeeToken],
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
// Wrapper to track when user makes an explicit selection
|
|
86
|
+
const setSelectedFeeToken = useCallback(
|
|
87
|
+
(token: FeeOption | null) => {
|
|
88
|
+
logger.console.log(
|
|
89
|
+
"[trails-sdk] [FEE-SELECT] setSelectedFeeToken called (user selection):",
|
|
90
|
+
{
|
|
91
|
+
token,
|
|
92
|
+
isNull: token === null,
|
|
93
|
+
isUndefined: token === undefined,
|
|
94
|
+
},
|
|
95
|
+
)
|
|
96
|
+
setSelectedFeeTokenInternal(token)
|
|
97
|
+
setHasUserSelectedFeeOption(true)
|
|
98
|
+
},
|
|
99
|
+
[setSelectedFeeTokenInternal],
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
const clearSelectedFeeToken = useCallback(() => {
|
|
103
|
+
logger.console.log("[trails-sdk] [FEE-SELECT] Clearing selected fee token")
|
|
104
|
+
setSelectedFeeTokenInternal(null)
|
|
105
|
+
setHasUserSelectedFeeOption(false)
|
|
106
|
+
}, [setSelectedFeeTokenInternal])
|
|
107
|
+
|
|
108
|
+
// Process raw fee options with balance checks
|
|
109
|
+
const processedFeeOptions = useMemo(() => {
|
|
110
|
+
if (!rawFeeOptions || rawFeeOptions.length === 0) {
|
|
111
|
+
return []
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
logger.console.log("[trails-sdk] [FEE-SELECT] Processing fee options:", {
|
|
115
|
+
rawFeeOptions,
|
|
116
|
+
originTokenChainId,
|
|
117
|
+
availableTokensCount: availableTokens.length,
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
// Add balance check and additional properties to each fee option
|
|
121
|
+
const feeOptionsWithBalanceCheck = rawFeeOptions.map((option: any) => {
|
|
122
|
+
// For native token (zero address), check if user has enough native balance
|
|
123
|
+
if (option.tokenAddress === zeroAddress) {
|
|
124
|
+
// Find the native token balance for the origin chain
|
|
125
|
+
const nativeTokenInfo = availableTokens.find(
|
|
126
|
+
(token) =>
|
|
127
|
+
token.contractAddress?.toLowerCase() ===
|
|
128
|
+
zeroAddress.toLowerCase() && token.chainId === originTokenChainId,
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
const nativeBalance = nativeTokenInfo?.balance || "0"
|
|
132
|
+
const requiredAmount = option.amount
|
|
133
|
+
const notEnoughBalance = BigInt(nativeBalance) < BigInt(requiredAmount)
|
|
134
|
+
|
|
135
|
+
return {
|
|
136
|
+
...option,
|
|
137
|
+
notEnoughBalance,
|
|
138
|
+
tokenImageUrl: nativeTokenInfo?.imageUrl,
|
|
139
|
+
chainId: originTokenChainId, // Native token is on the same chain as origin
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// For ERC-20 tokens, check user's token balances
|
|
144
|
+
const userTokenBalance = availableTokens.find(
|
|
145
|
+
(token) =>
|
|
146
|
+
token.contractAddress?.toLowerCase() ===
|
|
147
|
+
option.tokenAddress.toLowerCase() &&
|
|
148
|
+
token.chainId === originTokenChainId,
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
if (userTokenBalance) {
|
|
152
|
+
const userBalance = userTokenBalance.balance || "0"
|
|
153
|
+
const requiredAmount = option.amount
|
|
154
|
+
const notEnoughBalance = BigInt(userBalance) < BigInt(requiredAmount)
|
|
155
|
+
|
|
156
|
+
return {
|
|
157
|
+
...option,
|
|
158
|
+
notEnoughBalance,
|
|
159
|
+
tokenImageUrl: userTokenBalance.imageUrl,
|
|
160
|
+
chainId: userTokenBalance.chainId, // Use the actual token's chain ID
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// If token balance not found, assume insufficient balance
|
|
165
|
+
return {
|
|
166
|
+
...option,
|
|
167
|
+
notEnoughBalance: true,
|
|
168
|
+
tokenImageUrl: undefined,
|
|
169
|
+
chainId: originTokenChainId, // Fallback to origin chain
|
|
170
|
+
}
|
|
171
|
+
})
|
|
172
|
+
|
|
173
|
+
// Sort fee options: available options first, then disabled options at the bottom
|
|
174
|
+
const sortedFeeOptions = feeOptionsWithBalanceCheck.sort(
|
|
175
|
+
(a: FeeOption, b: FeeOption) => {
|
|
176
|
+
// If both have the same balance status, maintain original order
|
|
177
|
+
if (a.notEnoughBalance === b.notEnoughBalance) {
|
|
178
|
+
return 0
|
|
179
|
+
}
|
|
180
|
+
// Put available options (notEnoughBalance: false) before disabled options (notEnoughBalance: true)
|
|
181
|
+
return a.notEnoughBalance ? 1 : -1
|
|
182
|
+
},
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
logger.console.log(
|
|
186
|
+
"[trails-sdk] [FEE-SELECT] Processed and sorted fee options:",
|
|
187
|
+
sortedFeeOptions,
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
return sortedFeeOptions
|
|
191
|
+
}, [rawFeeOptions, originTokenChainId, availableTokens])
|
|
192
|
+
|
|
193
|
+
// Auto-select first fee option with sufficient balance (non-native token)
|
|
194
|
+
// Only auto-select on initial load, not when user explicitly chooses native gas
|
|
195
|
+
// If no ERC20 fee options are available, selectedFeeToken stays null (native gas)
|
|
196
|
+
useEffect(() => {
|
|
197
|
+
logger.console.log(
|
|
198
|
+
"[trails-sdk] [FEE-SELECT] Auto-selection useEffect triggered:",
|
|
199
|
+
{
|
|
200
|
+
processedFeeOptionsLength: processedFeeOptions.length,
|
|
201
|
+
hasUserSelectedFeeOption,
|
|
202
|
+
selectedFeeToken,
|
|
203
|
+
willAutoSelect:
|
|
204
|
+
processedFeeOptions.length > 0 &&
|
|
205
|
+
!hasUserSelectedFeeOption &&
|
|
206
|
+
!selectedFeeToken,
|
|
207
|
+
},
|
|
208
|
+
)
|
|
209
|
+
|
|
210
|
+
// Only auto-select if:
|
|
211
|
+
// 1. We have fee options
|
|
212
|
+
// 2. User hasn't made an explicit selection yet
|
|
213
|
+
// 3. No fee token is currently selected
|
|
214
|
+
if (
|
|
215
|
+
processedFeeOptions.length > 0 &&
|
|
216
|
+
!hasUserSelectedFeeOption &&
|
|
217
|
+
!selectedFeeToken
|
|
218
|
+
) {
|
|
219
|
+
// Find first non-native token option with sufficient balance
|
|
220
|
+
const firstValidOption = processedFeeOptions.find(
|
|
221
|
+
(option: FeeOption) =>
|
|
222
|
+
option.tokenAddress !== zeroAddress && !option.notEnoughBalance,
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
if (firstValidOption) {
|
|
226
|
+
logger.console.log(
|
|
227
|
+
"[trails-sdk] [FEE-SELECT] Auto-selecting first valid fee option:",
|
|
228
|
+
firstValidOption,
|
|
229
|
+
)
|
|
230
|
+
// Strip extra fields to match the format expected by prepareSend
|
|
231
|
+
const cleanOption: FeeOption = {
|
|
232
|
+
tokenAddress: firstValidOption.tokenAddress,
|
|
233
|
+
tokenSymbol: firstValidOption.tokenSymbol,
|
|
234
|
+
tokenDecimals: firstValidOption.tokenDecimals,
|
|
235
|
+
amount: firstValidOption.amount,
|
|
236
|
+
amountUSD: firstValidOption.amountUSD,
|
|
237
|
+
}
|
|
238
|
+
// Use internal setter to avoid marking as user selection
|
|
239
|
+
setSelectedFeeTokenInternal(cleanOption)
|
|
240
|
+
} else {
|
|
241
|
+
logger.console.log(
|
|
242
|
+
"[trails-sdk] [FEE-SELECT] No valid ERC20 fee options available, will use native gas",
|
|
243
|
+
)
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}, [
|
|
247
|
+
processedFeeOptions,
|
|
248
|
+
selectedFeeToken,
|
|
249
|
+
hasUserSelectedFeeOption,
|
|
250
|
+
setSelectedFeeTokenInternal,
|
|
251
|
+
])
|
|
252
|
+
|
|
253
|
+
// Function to set raw fee options and process them
|
|
254
|
+
const setRawFeeOptions = useCallback(
|
|
255
|
+
(
|
|
256
|
+
feeOptions: any[] | null | undefined,
|
|
257
|
+
originChainId: number | undefined,
|
|
258
|
+
tokens: TokenWithBalance[],
|
|
259
|
+
) => {
|
|
260
|
+
const apiFeeOptions = feeOptions ?? []
|
|
261
|
+
setRawFeeOptionsInternal(apiFeeOptions)
|
|
262
|
+
setOriginTokenChainId(originChainId)
|
|
263
|
+
setAvailableTokens(tokens)
|
|
264
|
+
|
|
265
|
+
logger.console.log("[trails-sdk] [FEE-SELECT] Raw fee options set:", {
|
|
266
|
+
feeOptionsCount: apiFeeOptions.length,
|
|
267
|
+
originChainId: originChainId,
|
|
268
|
+
tokensCount: tokens.length,
|
|
269
|
+
})
|
|
270
|
+
},
|
|
271
|
+
[],
|
|
272
|
+
)
|
|
273
|
+
|
|
274
|
+
const value: SelectedFeeTokenContextType = {
|
|
275
|
+
selectedFeeToken,
|
|
276
|
+
setSelectedFeeToken,
|
|
277
|
+
clearSelectedFeeToken,
|
|
278
|
+
processedFeeOptions,
|
|
279
|
+
setRawFeeOptions,
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
return (
|
|
283
|
+
<SelectedFeeTokenContext.Provider value={value}>
|
|
284
|
+
{children}
|
|
285
|
+
</SelectedFeeTokenContext.Provider>
|
|
286
|
+
)
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
export const useSelectedFeeToken = (): SelectedFeeTokenContextType => {
|
|
290
|
+
const context = useContext(SelectedFeeTokenContext)
|
|
291
|
+
|
|
292
|
+
if (context === undefined) {
|
|
293
|
+
throw new Error(
|
|
294
|
+
"useSelectedFeeToken must be used within a SelectedFeeTokenProvider",
|
|
295
|
+
)
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
return context
|
|
299
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { createContext, useContext, useState, useMemo } from "react"
|
|
2
|
+
|
|
3
|
+
export interface SelectedMeshExchange {
|
|
4
|
+
integrationId: string
|
|
5
|
+
exchangeName: string
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
interface SelectedMeshExchangeContextType {
|
|
9
|
+
selectedExchange: SelectedMeshExchange | null
|
|
10
|
+
setSelectedExchange: (exchange: SelectedMeshExchange | null) => void
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const SelectedMeshExchangeContext = createContext<
|
|
14
|
+
SelectedMeshExchangeContextType | undefined
|
|
15
|
+
>(undefined)
|
|
16
|
+
|
|
17
|
+
export const SelectedMeshExchangeProvider: React.FC<{
|
|
18
|
+
children: React.ReactNode
|
|
19
|
+
}> = ({ children }) => {
|
|
20
|
+
const [selectedExchange, setSelectedExchange] =
|
|
21
|
+
useState<SelectedMeshExchange | null>(null)
|
|
22
|
+
|
|
23
|
+
const value = useMemo(
|
|
24
|
+
() => ({
|
|
25
|
+
selectedExchange,
|
|
26
|
+
setSelectedExchange,
|
|
27
|
+
}),
|
|
28
|
+
[selectedExchange],
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
return (
|
|
32
|
+
<SelectedMeshExchangeContext.Provider value={value}>
|
|
33
|
+
{children}
|
|
34
|
+
</SelectedMeshExchangeContext.Provider>
|
|
35
|
+
)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export const useSelectedMeshExchange = () => {
|
|
39
|
+
const context = useContext(SelectedMeshExchangeContext)
|
|
40
|
+
if (context === undefined) {
|
|
41
|
+
throw new Error(
|
|
42
|
+
"useSelectedMeshExchange must be used within a SelectedMeshExchangeProvider",
|
|
43
|
+
)
|
|
44
|
+
}
|
|
45
|
+
return context
|
|
46
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import React, {
|
|
2
|
+
createContext,
|
|
3
|
+
useContext,
|
|
4
|
+
useState,
|
|
5
|
+
type ReactNode,
|
|
6
|
+
} from "react"
|
|
7
|
+
|
|
8
|
+
interface SelectedRecipientContextType {
|
|
9
|
+
selectedRecipient: string | null
|
|
10
|
+
setSelectedRecipient: (recipient: string | null) => void
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const SelectedRecipientContext = createContext<
|
|
14
|
+
SelectedRecipientContextType | undefined
|
|
15
|
+
>(undefined)
|
|
16
|
+
|
|
17
|
+
interface SelectedRecipientProviderProps {
|
|
18
|
+
children: ReactNode
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export const SelectedRecipientProvider: React.FC<
|
|
22
|
+
SelectedRecipientProviderProps
|
|
23
|
+
> = ({ children }) => {
|
|
24
|
+
const [selectedRecipient, setSelectedRecipient] = useState<string | null>(
|
|
25
|
+
null,
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<SelectedRecipientContext.Provider
|
|
30
|
+
value={{
|
|
31
|
+
selectedRecipient,
|
|
32
|
+
setSelectedRecipient,
|
|
33
|
+
}}
|
|
34
|
+
>
|
|
35
|
+
{children}
|
|
36
|
+
</SelectedRecipientContext.Provider>
|
|
37
|
+
)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export const useSelectedRecipient = () => {
|
|
41
|
+
const context = useContext(SelectedRecipientContext)
|
|
42
|
+
if (context === undefined) {
|
|
43
|
+
throw new Error(
|
|
44
|
+
"useSelectedRecipient must be used within a SelectedRecipientProvider",
|
|
45
|
+
)
|
|
46
|
+
}
|
|
47
|
+
return context
|
|
48
|
+
}
|