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
@@ -1,150 +1,215 @@
1
- import { TokenImage } from "./TokenImage.js"
2
1
  import { ChevronDown } from "lucide-react"
3
2
  import type React from "react"
4
- import { useEffect, useMemo, useRef, useState } from "react"
5
- import { formatRawAmount } from "../../tokenBalances.js"
6
-
7
- export type FeeOption = {
8
- token: {
9
- chainId: number
10
- name: string
11
- symbol: string
12
- type: string
13
- decimals: number
14
- logoURL: string
15
- contractAddress: string | null
16
- tokenID: string | null
17
- }
18
- to: string
19
- value: string
20
- gasLimit: number
3
+ import { useRef, useState } from "react"
4
+ import { formatUsdAmountDisplay, formatRawAmount } from "../../tokenBalances.js"
5
+ import {
6
+ FeeOption,
7
+ type FeeOption as EnhancedFeeOptionType,
8
+ } from "./FeeOption.js"
9
+ import { logger } from "../../logger.js"
10
+ import { getChainInfo } from "../../chains.js"
11
+ import { TokenImage } from "./TokenImage.js"
12
+ import { getTokenImageUrl } from "../../tokens.js"
13
+ import { zeroAddress } from "viem"
14
+
15
+ // Original FeeOption type from useSendForm hook
16
+ type OriginalFeeOption = {
17
+ tokenAddress: string
18
+ tokenSymbol: string
19
+ tokenDecimals: number
20
+ amount: string
21
+ amountUSD: number
22
+ notEnoughBalance?: boolean
23
+ tokenImageUrl?: string
24
+ chainId?: number
21
25
  }
22
26
 
23
27
  interface FeeOptionsProps {
24
- options: FeeOption[]
25
- selectedOption?: FeeOption
26
- onSelect: (option: FeeOption) => void
28
+ feeOptions: OriginalFeeOption[]
29
+ selectedFeeToken: OriginalFeeOption | null
30
+ setSelectedFeeToken: (token: OriginalFeeOption | null) => void
31
+ chainId?: number
27
32
  }
28
33
 
29
- // Enable once we have a way to pay fees with other tokens
30
- const DISABLED_FEE_OPTIONS = true
31
-
32
34
  export const FeeOptions: React.FC<FeeOptionsProps> = ({
33
- options,
34
- selectedOption,
35
- onSelect,
35
+ feeOptions,
36
+ selectedFeeToken,
37
+ setSelectedFeeToken,
38
+ chainId,
36
39
  }) => {
37
- if (DISABLED_FEE_OPTIONS) return null
38
- const [isDropdownOpen, setIsDropdownOpen] = useState(false)
39
- const dropdownRef = useRef<HTMLDivElement>(null)
40
-
41
- const formattedFeeAmount = useMemo(() => {
42
- if (!selectedOption) return "0.00"
43
- return formatRawAmount(selectedOption.value, selectedOption.token.decimals)
44
- }, [selectedOption])
45
-
46
- // Calculate USD value of fee
47
- const feeUsdValue = useMemo(() => {
48
- if (!selectedOption) return ""
49
- return "" // TODO
50
- }, [selectedOption])
51
-
52
- // Set first option as default if none selected
53
- useEffect(() => {
54
- if (!selectedOption && options.length > 0) {
55
- onSelect(options[0]!)
56
- }
57
- }, [selectedOption, options, onSelect])
40
+ const [isOpen, setIsOpen] = useState(false)
41
+ const accordionRef = useRef<HTMLDivElement>(null)
58
42
 
59
- if (!options?.length) {
43
+ // Don't render if no fee options available
44
+ if (!feeOptions || feeOptions.length === 0) {
60
45
  return null
61
46
  }
62
47
 
48
+ // Enhance ALL fee options with formatted values and image URLs (including native gas)
49
+ const enhancedFeeOptions: EnhancedFeeOptionType[] = feeOptions.map(
50
+ (option) => ({
51
+ ...option,
52
+ amountFormatted: `${formatRawAmount(option.amount, option.tokenDecimals)} ${option.tokenSymbol}`,
53
+ amountUsdDisplay: formatUsdAmountDisplay(option.amountUSD),
54
+ tokenImageUrl: getTokenImageUrl({
55
+ chainId: option.chainId || chainId, // Use fee option's chain ID, fallback to prop
56
+ contractAddress: option.tokenAddress,
57
+ symbol: option.tokenSymbol,
58
+ }),
59
+ }),
60
+ )
61
+
62
+ // Find native gas option (zero address) for header display
63
+ const nativeGasOption = enhancedFeeOptions.find(
64
+ (opt) => opt.tokenAddress.toLowerCase() === zeroAddress.toLowerCase(),
65
+ )
66
+
67
+ const handleFeeTokenSelect = (option: EnhancedFeeOptionType) => {
68
+ // Convert back to original format for the parent component
69
+ const originalOption: OriginalFeeOption = {
70
+ tokenAddress: option.tokenAddress,
71
+ tokenSymbol: option.tokenSymbol,
72
+ tokenDecimals: option.tokenDecimals,
73
+ amount: option.amount,
74
+ amountUSD: option.amountUSD,
75
+ }
76
+
77
+ // For native gas (zero address), set to null to trigger non-gasless flow
78
+ if (option.tokenAddress.toLowerCase() === zeroAddress.toLowerCase()) {
79
+ setSelectedFeeToken(null)
80
+ logger.console.log(
81
+ "[trails-sdk] [FEE-SELECT] Selected native gas fee option",
82
+ )
83
+ } else {
84
+ setSelectedFeeToken(originalOption)
85
+ logger.console.log(
86
+ "[trails-sdk] [FEE-SELECT] Selected ERC20 fee option:",
87
+ originalOption,
88
+ )
89
+ }
90
+
91
+ setIsOpen(false)
92
+ }
93
+
94
+ // Get display text and image for selected option
95
+ const getSelectedDisplayText = () => {
96
+ if (
97
+ selectedFeeToken === null ||
98
+ selectedFeeToken?.tokenAddress?.toLowerCase() ===
99
+ zeroAddress.toLowerCase()
100
+ ) {
101
+ // Native gas selected - use native gas option data
102
+ const nativeSymbol =
103
+ nativeGasOption?.tokenSymbol ||
104
+ (chainId ? getNativeSymbol(chainId) : "ETH")
105
+ const nativeImageUrl = getTokenImageUrl({
106
+ chainId,
107
+ contractAddress: zeroAddress,
108
+ symbol: nativeSymbol,
109
+ })
110
+ const amountDisplay = nativeGasOption
111
+ ? `${formatRawAmount(nativeGasOption.amount, nativeGasOption.tokenDecimals)} ${nativeGasOption.tokenSymbol}`
112
+ : ""
113
+ const usdDisplay = nativeGasOption
114
+ ? formatUsdAmountDisplay(nativeGasOption.amountUSD)
115
+ : ""
116
+ return {
117
+ title: nativeSymbol,
118
+ amountDisplay,
119
+ usdDisplay,
120
+ symbol: nativeSymbol,
121
+ imageUrl: nativeImageUrl,
122
+ }
123
+ } else {
124
+ const tokenImageUrl = getTokenImageUrl({
125
+ chainId: selectedFeeToken.chainId || chainId, // Use fee token's chain ID, fallback to prop
126
+ contractAddress: selectedFeeToken.tokenAddress,
127
+ symbol: selectedFeeToken.tokenSymbol,
128
+ })
129
+ const amountDisplay = `${formatRawAmount(selectedFeeToken.amount, selectedFeeToken.tokenDecimals)} ${selectedFeeToken.tokenSymbol}`
130
+ const usdDisplay = formatUsdAmountDisplay(selectedFeeToken.amountUSD)
131
+ return {
132
+ title: selectedFeeToken.tokenSymbol,
133
+ amountDisplay,
134
+ usdDisplay,
135
+ symbol: selectedFeeToken.tokenSymbol,
136
+ imageUrl: tokenImageUrl,
137
+ }
138
+ }
139
+ }
140
+
141
+ // Helper function to get native symbol for a chain
142
+ const getNativeSymbol = (chainId: number) => {
143
+ const chainInfo = getChainInfo(chainId)
144
+ return chainInfo?.nativeCurrency.symbol || "ETH"
145
+ }
146
+
147
+ const selectedDisplay = getSelectedDisplayText()
148
+
63
149
  return (
64
- <div className="space-y-1" ref={dropdownRef}>
65
- <div className="flex items-center justify-between">
66
- <div className="block text-xs font-medium text-gray-700 dark:text-gray-300">
67
- Pay fee with
68
- </div>
69
- {selectedOption && (
70
- <div className="text-xs text-gray-500 dark:text-gray-400">
71
- Fee {formattedFeeAmount} {selectedOption.token.symbol}
72
- <div>
73
- {feeUsdValue && (
74
- <span className="ml-1 text-xs text-gray-500 dark:text-gray-400">
75
- ≈ {feeUsdValue}
76
- </span>
77
- )}
78
- </div>
150
+ <div className="space-y-1" ref={accordionRef}>
151
+ <div className="p-2">
152
+ <div className="flex justify-between items-center mb-2">
153
+ <div className="text-xs font-medium trails-text-primary">
154
+ Gas Fee Options
79
155
  </div>
80
- )}
81
- </div>
82
- <div className="relative flex justify-start">
156
+ <div className="text-xs trails-text-muted">
157
+ Choose how to pay for gas for transfer
158
+ </div>
159
+ </div>
160
+
161
+ {/* Accordion Header */}
83
162
  <button
84
163
  type="button"
85
- onClick={() => setIsDropdownOpen(!isDropdownOpen)}
86
- className="w-32 flex items-center px-3 py-2 border border-solid trails-border-radius-container hover:border-gray-400 cursor-pointer focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 text-sm bg-white border-gray-300 text-gray-900 dark:bg-gray-800 dark:border-gray-700 dark:text-white"
164
+ onClick={() => setIsOpen(!isOpen)}
165
+ className="w-full flex items-center justify-between p-1.5 trails-border-radius-input border trails-border-primary hover:trails-hover-bg transition-colors cursor-pointer"
87
166
  >
88
- {selectedOption ? (
89
- <>
90
- <TokenImage
91
- symbol={selectedOption.token.symbol}
92
- imageUrl={selectedOption.token.logoURL}
93
- size={16}
94
- />
95
- <span className="ml-1.5 flex-1 text-left">
96
- {selectedOption.token.symbol}
97
- </span>
98
- </>
99
- ) : (
100
- <span className="flex-1 text-left text-gray-400">
101
- Select Fee Token
102
- </span>
103
- )}
104
- <ChevronDown
105
- className={`h-4 w-4 ${
106
- isDropdownOpen ? "transform rotate-180" : ""
107
- }`}
108
- />
167
+ <div className="flex items-center space-x-2">
168
+ <TokenImage
169
+ imageUrl={selectedDisplay.imageUrl}
170
+ symbol={selectedDisplay.symbol}
171
+ chainId={selectedFeeToken?.chainId || chainId}
172
+ size={16}
173
+ />
174
+ <div className="text-left">
175
+ <div className="text-xs font-medium trails-text-primary">
176
+ {selectedDisplay.amountDisplay}
177
+ </div>
178
+ </div>
179
+ </div>
180
+ <div className="flex items-center space-x-2">
181
+ <div className="text-right">
182
+ <div className="text-xs font-medium trails-text-primary">
183
+ {selectedDisplay.usdDisplay}
184
+ </div>
185
+ </div>
186
+ <ChevronDown
187
+ className={`w-3 h-3 trails-text-muted transition-transform ${
188
+ isOpen ? "transform rotate-180" : ""
189
+ }`}
190
+ />
191
+ </div>
109
192
  </button>
110
193
 
111
- {isDropdownOpen && (
112
- <div className="absolute z-10 mt-1 border border-solid trails-border-radius-container shadow-lg w-32 bg-white border-gray-200 dark:bg-gray-800 dark:border-gray-700">
113
- {options.map((option) => (
114
- <button
115
- key={option.token.symbol}
116
- type="button"
117
- onClick={() => {
118
- console.log("[trails] selected fee option", option)
119
- onSelect(option)
120
- setIsDropdownOpen(false)
121
- }}
122
- className={`w-full flex items-center px-3 py-2 cursor-pointer text-sm ${
123
- selectedOption?.token.symbol === option.token.symbol
124
- ? "bg-gray-100 text-gray-900 dark:bg-gray-700 dark:text-white"
125
- : "text-gray-900 dark:text-white hover:bg-gray-50 dark:hover:bg-gray-700 hover:trails-hover-bg"
126
- }`}
127
- >
128
- <div
129
- className={`w-4 h-4 rounded-full flex items-center justify-center ${
130
- selectedOption?.token.symbol === option.token.symbol
131
- ? "bg-gray-200 dark:bg-gray-700"
132
- : "bg-gray-100 dark:bg-gray-600"
133
- }`}
134
- >
135
- <TokenImage
136
- symbol={option.token.symbol}
137
- imageUrl={option.token.logoURL}
138
- size={16}
139
- />
140
- </div>
141
- <span className="ml-1.5">{option.token.symbol}</span>
142
- {selectedOption?.token.symbol === option.token.symbol && (
143
- <span className="ml-auto text-gray-900 dark:text-white">
144
-
145
- </span>
146
- )}
147
- </button>
194
+ {/* Accordion Content */}
195
+ {isOpen && (
196
+ <div className="mt-2 space-y-1">
197
+ {/* All Fee Options (including native gas) */}
198
+ {enhancedFeeOptions.map((option, index) => (
199
+ <FeeOption
200
+ key={`${option.tokenAddress}-${index}`}
201
+ option={option}
202
+ isSelected={
203
+ option.tokenAddress.toLowerCase() ===
204
+ zeroAddress.toLowerCase()
205
+ ? selectedFeeToken === null ||
206
+ selectedFeeToken?.tokenAddress?.toLowerCase() ===
207
+ zeroAddress.toLowerCase()
208
+ : selectedFeeToken?.tokenAddress === option.tokenAddress
209
+ }
210
+ onClick={() => handleFeeTokenSelect(option)}
211
+ chainId={option.chainId || chainId}
212
+ />
148
213
  ))}
149
214
  </div>
150
215
  )}