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.
Files changed (256) hide show
  1. package/dist/aave.d.ts.map +1 -1
  2. package/dist/analytics.d.ts +12 -2
  3. package/dist/analytics.d.ts.map +1 -1
  4. package/dist/apiClient.d.ts +1 -1
  5. package/dist/apiClient.d.ts.map +1 -1
  6. package/dist/{ccip-D3gTQONK.js → ccip-BbfANth7.js} +12 -12
  7. package/dist/cctp.d.ts.map +1 -1
  8. package/dist/cctpqueue.d.ts +3 -3
  9. package/dist/cctpqueue.d.ts.map +1 -1
  10. package/dist/chains.d.ts.map +1 -1
  11. package/dist/config.d.ts +18 -5
  12. package/dist/config.d.ts.map +1 -1
  13. package/dist/constants.d.ts +6 -5
  14. package/dist/constants.d.ts.map +1 -1
  15. package/dist/contractUtils.d.ts +2 -0
  16. package/dist/contractUtils.d.ts.map +1 -1
  17. package/dist/customChains.d.ts +24 -0
  18. package/dist/customChains.d.ts.map +1 -0
  19. package/dist/gasless.d.ts +19 -7
  20. package/dist/gasless.d.ts.map +1 -1
  21. package/dist/{index-CnUM7lKf.js → index-WpIVoh3X.js} +36741 -31761
  22. package/dist/index.d.ts +5 -3
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +405 -394
  25. package/dist/indexerClient.d.ts +10 -0
  26. package/dist/indexerClient.d.ts.map +1 -1
  27. package/dist/intentEntrypoint.d.ts +122 -0
  28. package/dist/intentEntrypoint.d.ts.map +1 -0
  29. package/dist/intents.d.ts +5 -3
  30. package/dist/intents.d.ts.map +1 -1
  31. package/dist/metaTxnMonitor.d.ts.map +1 -1
  32. package/dist/morpho.d.ts.map +1 -1
  33. package/dist/pools.d.ts +3 -1
  34. package/dist/pools.d.ts.map +1 -1
  35. package/dist/prepareSend.d.ts +18 -9
  36. package/dist/prepareSend.d.ts.map +1 -1
  37. package/dist/prices.d.ts +1 -1
  38. package/dist/prices.d.ts.map +1 -1
  39. package/dist/relaySdk.d.ts.map +1 -1
  40. package/dist/relayer.d.ts.map +1 -1
  41. package/dist/toast.d.ts +9 -0
  42. package/dist/toast.d.ts.map +1 -0
  43. package/dist/tokenBalances.d.ts +6 -2
  44. package/dist/tokenBalances.d.ts.map +1 -1
  45. package/dist/tokens.d.ts.map +1 -1
  46. package/dist/trails.d.ts +6 -5
  47. package/dist/trails.d.ts.map +1 -1
  48. package/dist/trailsClient.d.ts +12 -0
  49. package/dist/trailsClient.d.ts.map +1 -0
  50. package/dist/trailsRouter.d.ts +22 -0
  51. package/dist/trailsRouter.d.ts.map +1 -0
  52. package/dist/transactions.d.ts +8 -1
  53. package/dist/transactions.d.ts.map +1 -1
  54. package/dist/wallets.d.ts.map +1 -1
  55. package/dist/widget/components/AccountActionsDropdown.d.ts.map +1 -1
  56. package/dist/widget/components/AccountIntentTransactionHistory.d.ts.map +1 -1
  57. package/dist/widget/components/AccountSettings.d.ts +7 -0
  58. package/dist/widget/components/AccountSettings.d.ts.map +1 -0
  59. package/dist/widget/components/ChainList.d.ts +0 -1
  60. package/dist/widget/components/ChainList.d.ts.map +1 -1
  61. package/dist/widget/components/ClassicSwap.d.ts +46 -0
  62. package/dist/widget/components/ClassicSwap.d.ts.map +1 -0
  63. package/dist/widget/components/ConfigDisplay.d.ts.map +1 -1
  64. package/dist/widget/components/ConnectWallet.d.ts.map +1 -1
  65. package/dist/widget/components/ConnectedWallets.d.ts +9 -0
  66. package/dist/widget/components/ConnectedWallets.d.ts.map +1 -0
  67. package/dist/widget/components/DebugMenu.d.ts.map +1 -1
  68. package/dist/widget/components/DebugScreensList.d.ts.map +1 -1
  69. package/dist/widget/components/DebugToast.d.ts +3 -0
  70. package/dist/widget/components/DebugToast.d.ts.map +1 -0
  71. package/dist/widget/components/Earn.d.ts.map +1 -1
  72. package/dist/widget/components/EarnPools.d.ts.map +1 -1
  73. package/dist/widget/components/FeeOption.d.ts +22 -0
  74. package/dist/widget/components/FeeOption.d.ts.map +1 -0
  75. package/dist/widget/components/FeeOptions.d.ts +13 -17
  76. package/dist/widget/components/FeeOptions.d.ts.map +1 -1
  77. package/dist/widget/components/Fund.d.ts +44 -0
  78. package/dist/widget/components/Fund.d.ts.map +1 -0
  79. package/dist/widget/components/FundMethods.d.ts +1 -1
  80. package/dist/widget/components/FundMethods.d.ts.map +1 -1
  81. package/dist/widget/components/FundSendForm.d.ts.map +1 -1
  82. package/dist/widget/components/Identicon.d.ts +9 -0
  83. package/dist/widget/components/Identicon.d.ts.map +1 -0
  84. package/dist/widget/components/MeshConnectExchanges.d.ts +5 -2
  85. package/dist/widget/components/MeshConnectExchanges.d.ts.map +1 -1
  86. package/dist/widget/components/MeshConnectFlow.d.ts +2 -0
  87. package/dist/widget/components/MeshConnectFlow.d.ts.map +1 -1
  88. package/dist/widget/components/NativeGasOption.d.ts +12 -0
  89. package/dist/widget/components/NativeGasOption.d.ts.map +1 -0
  90. package/dist/widget/components/Pay.d.ts +46 -0
  91. package/dist/widget/components/Pay.d.ts.map +1 -0
  92. package/dist/widget/components/PaySendForm.d.ts.map +1 -1
  93. package/dist/widget/components/QuoteDetails.d.ts.map +1 -1
  94. package/dist/widget/components/Receive.d.ts.map +1 -1
  95. package/dist/widget/components/RecentTokens.d.ts.map +1 -1
  96. package/dist/widget/components/Recipients.d.ts +9 -0
  97. package/dist/widget/components/Recipients.d.ts.map +1 -0
  98. package/dist/widget/components/RefundWarning.d.ts +9 -0
  99. package/dist/widget/components/RefundWarning.d.ts.map +1 -0
  100. package/dist/widget/components/SimpleSwap.d.ts.map +1 -1
  101. package/dist/widget/components/Swap.d.ts.map +1 -1
  102. package/dist/widget/components/SwapSettings.d.ts +1 -5
  103. package/dist/widget/components/SwapSettings.d.ts.map +1 -1
  104. package/dist/widget/components/ThemeProvider.d.ts.map +1 -1
  105. package/dist/widget/components/ThemeSyncer.d.ts +6 -0
  106. package/dist/widget/components/ThemeSyncer.d.ts.map +1 -0
  107. package/dist/widget/components/Toast.d.ts +24 -0
  108. package/dist/widget/components/Toast.d.ts.map +1 -0
  109. package/dist/widget/components/TokenList.d.ts.map +1 -1
  110. package/dist/widget/components/TokenSelector.d.ts.map +1 -1
  111. package/dist/widget/components/TransactionDetails.d.ts.map +1 -1
  112. package/dist/widget/components/TruncatedAddress.d.ts +2 -0
  113. package/dist/widget/components/TruncatedAddress.d.ts.map +1 -1
  114. package/dist/widget/components/UserPreferences.d.ts +7 -0
  115. package/dist/widget/components/UserPreferences.d.ts.map +1 -0
  116. package/dist/widget/hooks/useBack.d.ts +2 -0
  117. package/dist/widget/hooks/useBack.d.ts.map +1 -1
  118. package/dist/widget/hooks/useBalanceVisible.d.ts +1 -0
  119. package/dist/widget/hooks/useBalanceVisible.d.ts.map +1 -1
  120. package/dist/widget/hooks/useCheckout.d.ts.map +1 -1
  121. package/dist/widget/hooks/useCurrentScreen.d.ts +1 -1
  122. package/dist/widget/hooks/useCurrentScreen.d.ts.map +1 -1
  123. package/dist/widget/hooks/useDebugScreens.d.ts +1 -1
  124. package/dist/widget/hooks/useDebugScreens.d.ts.map +1 -1
  125. package/dist/widget/hooks/useDefaultTokenSelection.d.ts +54 -0
  126. package/dist/widget/hooks/useDefaultTokenSelection.d.ts.map +1 -0
  127. package/dist/widget/hooks/useIntentTransactionHistory.d.ts.map +1 -1
  128. package/dist/widget/hooks/usePayMessage.d.ts +34 -0
  129. package/dist/widget/hooks/usePayMessage.d.ts.map +1 -0
  130. package/dist/widget/hooks/useRecipients.d.ts +17 -0
  131. package/dist/widget/hooks/useRecipients.d.ts.map +1 -0
  132. package/dist/widget/hooks/useSelectedFeeToken.d.ts +32 -0
  133. package/dist/widget/hooks/useSelectedFeeToken.d.ts.map +1 -0
  134. package/dist/widget/hooks/useSelectedMeshExchange.d.ts +14 -0
  135. package/dist/widget/hooks/useSelectedMeshExchange.d.ts.map +1 -0
  136. package/dist/widget/hooks/useSelectedRecipient.d.ts +12 -0
  137. package/dist/widget/hooks/useSelectedRecipient.d.ts.map +1 -0
  138. package/dist/widget/hooks/useSendForm.d.ts +10 -13
  139. package/dist/widget/hooks/useSendForm.d.ts.map +1 -1
  140. package/dist/widget/hooks/useSwapAmount.d.ts +13 -0
  141. package/dist/widget/hooks/useSwapAmount.d.ts.map +1 -0
  142. package/dist/widget/hooks/useSwapSettings.d.ts +16 -0
  143. package/dist/widget/hooks/useSwapSettings.d.ts.map +1 -0
  144. package/dist/widget/hooks/useTargetAmount.d.ts +5 -0
  145. package/dist/widget/hooks/useTargetAmount.d.ts.map +1 -0
  146. package/dist/widget/hooks/useTheme.d.ts +14 -0
  147. package/dist/widget/hooks/useTheme.d.ts.map +1 -0
  148. package/dist/widget/hooks/useTokenList.d.ts.map +1 -1
  149. package/dist/widget/index.js +2 -2
  150. package/dist/widget/widget.d.ts +9 -0
  151. package/dist/widget/widget.d.ts.map +1 -1
  152. package/package.json +38 -36
  153. package/src/aave.ts +6 -1
  154. package/src/analytics.ts +109 -53
  155. package/src/apiClient.ts +1 -1
  156. package/src/cctp.ts +6 -2
  157. package/src/cctpqueue.ts +7 -7
  158. package/src/chains.ts +18 -0
  159. package/src/config.ts +63 -17
  160. package/src/constants.ts +20 -16
  161. package/src/contractUtils.ts +33 -2
  162. package/src/customChains.ts +24 -0
  163. package/src/gasless.ts +162 -109
  164. package/src/index.ts +11 -1
  165. package/src/indexerClient.ts +73 -1
  166. package/src/intentEntrypoint.ts +218 -0
  167. package/src/intents.ts +85 -54
  168. package/src/metaTxnMonitor.ts +1 -0
  169. package/src/morpho.ts +13 -2
  170. package/src/pools.ts +68 -86
  171. package/src/prepareSend.ts +1719 -967
  172. package/src/prices.ts +51 -7
  173. package/src/relaySdk.ts +6 -4
  174. package/src/relayer.ts +6 -3
  175. package/src/toast.ts +110 -0
  176. package/src/tokenBalances.ts +112 -20
  177. package/src/tokens.ts +70 -7
  178. package/src/trails.ts +81 -80
  179. package/src/trailsClient.ts +48 -0
  180. package/src/{proxyCaller.ts → trailsRouter.ts} +25 -20
  181. package/src/transactions.ts +30 -88
  182. package/src/umd.tsx +1 -1
  183. package/src/wallets.ts +2 -1
  184. package/src/widget/assets/sequence-logo.svg +15 -0
  185. package/src/widget/compiled.css +2 -2
  186. package/src/widget/components/AccountActionsDropdown.tsx +18 -159
  187. package/src/widget/components/AccountIntentTransactionHistory.tsx +346 -63
  188. package/src/widget/components/AccountSettings.tsx +102 -0
  189. package/src/widget/components/ChainFilterDropdown.tsx +1 -1
  190. package/src/widget/components/ChainList.tsx +10 -20
  191. package/src/widget/components/ClassicSwap.tsx +921 -0
  192. package/src/widget/components/ConfigDisplay.tsx +41 -5
  193. package/src/widget/components/ConnectWallet.tsx +168 -11
  194. package/src/widget/components/ConnectedWallets.tsx +342 -0
  195. package/src/widget/components/DebugMenu.tsx +2 -0
  196. package/src/widget/components/DebugScreensList.tsx +3 -0
  197. package/src/widget/components/DebugToast.tsx +63 -0
  198. package/src/widget/components/Earn.tsx +112 -143
  199. package/src/widget/components/EarnPools.tsx +2 -4
  200. package/src/widget/components/EarnPoolsFilters.tsx +6 -6
  201. package/src/widget/components/FeeOption.tsx +78 -0
  202. package/src/widget/components/FeeOptions.tsx +192 -127
  203. package/src/widget/components/Fund.tsx +1236 -0
  204. package/src/widget/components/FundMethods.tsx +4 -4
  205. package/src/widget/components/FundSendForm.tsx +1 -34
  206. package/src/widget/components/Identicon.tsx +158 -0
  207. package/src/widget/components/MeshConnectExchanges.tsx +32 -3
  208. package/src/widget/components/MeshConnectFlow.tsx +23 -4
  209. package/src/widget/components/NativeGasOption.tsx +99 -0
  210. package/src/widget/components/Pay.tsx +1092 -0
  211. package/src/widget/components/PaySendForm.tsx +1 -38
  212. package/src/widget/components/QuoteDetails.tsx +1 -30
  213. package/src/widget/components/Receipt.tsx +1 -1
  214. package/src/widget/components/Receive.tsx +4 -2
  215. package/src/widget/components/RecentTokens.tsx +2 -1
  216. package/src/widget/components/Recipients.tsx +448 -0
  217. package/src/widget/components/RefundWarning.tsx +61 -0
  218. package/src/widget/components/ScreenHeader.tsx +1 -1
  219. package/src/widget/components/SimpleSwap.tsx +74 -58
  220. package/src/widget/components/Swap.tsx +35 -853
  221. package/src/widget/components/SwapSettings.tsx +5 -11
  222. package/src/widget/components/ThemeProvider.tsx +32 -0
  223. package/src/widget/components/ThemeSyncer.tsx +47 -0
  224. package/src/widget/components/Toast.tsx +315 -0
  225. package/src/widget/components/TokenList.tsx +2 -34
  226. package/src/widget/components/TokenSelector.tsx +14 -3
  227. package/src/widget/components/TransactionDetails.tsx +153 -13
  228. package/src/widget/components/TransferPendingVertical.tsx +1 -1
  229. package/src/widget/components/TruncatedAddress.tsx +5 -1
  230. package/src/widget/components/UserPreferences.tsx +155 -0
  231. package/src/widget/components/WalletList.tsx +1 -1
  232. package/src/widget/hooks/useBack.tsx +4 -0
  233. package/src/widget/hooks/useBalanceVisible.tsx +40 -2
  234. package/src/widget/hooks/useCheckout.ts +13 -0
  235. package/src/widget/hooks/useCurrentScreen.tsx +4 -0
  236. package/src/widget/hooks/useDebugScreens.ts +12 -2
  237. package/src/widget/hooks/useDefaultTokenSelection.tsx +471 -0
  238. package/src/widget/hooks/useIntentTransactionHistory.ts +212 -0
  239. package/src/widget/hooks/usePayMessage.tsx +370 -0
  240. package/src/widget/hooks/useRecipients.ts +168 -0
  241. package/src/widget/hooks/useSelectedFeeToken.tsx +299 -0
  242. package/src/widget/hooks/useSelectedMeshExchange.tsx +46 -0
  243. package/src/widget/hooks/useSelectedRecipient.tsx +48 -0
  244. package/src/widget/hooks/useSendForm.ts +257 -49
  245. package/src/widget/hooks/useSwapAmount.tsx +50 -0
  246. package/src/widget/hooks/useSwapSettings.tsx +100 -0
  247. package/src/widget/hooks/useTargetAmount.ts +23 -0
  248. package/src/widget/hooks/useTheme.tsx +80 -0
  249. package/src/widget/hooks/useTokenList.ts +20 -11
  250. package/src/widget/index.css +45 -21
  251. package/src/widget/widget.tsx +294 -136
  252. package/dist/address.d.ts +0 -2
  253. package/dist/address.d.ts.map +0 -1
  254. package/dist/proxyCaller.d.ts +0 -21
  255. package/dist/proxyCaller.d.ts.map +0 -1
  256. 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
+ }