0xtrails 0.13.1 → 0.13.2

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 (229) hide show
  1. package/dist/{ccip-DStzFCYT.js → ccip-CT_An6eM.js} +28 -28
  2. package/dist/chains.d.ts +1 -1
  3. package/dist/chains.d.ts.map +1 -1
  4. package/dist/constants.d.ts +1 -0
  5. package/dist/constants.d.ts.map +1 -1
  6. package/dist/customTokens.d.ts.map +1 -1
  7. package/dist/{index-HY9_ppit.js → index-RfqL5Foz.js} +56523 -43196
  8. package/dist/index.d.ts +1 -0
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +383 -332
  11. package/dist/intents.d.ts +8 -2
  12. package/dist/intents.d.ts.map +1 -1
  13. package/dist/keyMachineClient.d.ts +9 -0
  14. package/dist/keyMachineClient.d.ts.map +1 -0
  15. package/dist/keymachine/index.d.ts +14 -0
  16. package/dist/keymachine/index.d.ts.map +1 -0
  17. package/dist/keymachine/key-machine.gen.d.ts +461 -0
  18. package/dist/keymachine/key-machine.gen.d.ts.map +1 -0
  19. package/dist/onramp/MeshConnectFlow.d.ts +18 -0
  20. package/dist/onramp/MeshConnectFlow.d.ts.map +1 -0
  21. package/dist/onramp/MeshConnectIframe.d.ts +13 -0
  22. package/dist/onramp/MeshConnectIframe.d.ts.map +1 -0
  23. package/dist/onramp/SendFromExchangeButton.d.ts +16 -0
  24. package/dist/onramp/SendFromExchangeButton.d.ts.map +1 -0
  25. package/dist/onramp/TrailsOnRampProvider.d.ts +31 -0
  26. package/dist/onramp/TrailsOnRampProvider.d.ts.map +1 -0
  27. package/dist/onramp/index.d.ts +13 -0
  28. package/dist/onramp/index.d.ts.map +1 -0
  29. package/dist/onramp/meshconnect.d.ts +30 -0
  30. package/dist/onramp/meshconnect.d.ts.map +1 -0
  31. package/dist/onramp/trailsOnramp.d.ts +24 -0
  32. package/dist/onramp/trailsOnramp.d.ts.map +1 -0
  33. package/dist/onramp-client/index.d.ts +3 -3
  34. package/dist/onramp-client/index.d.ts.map +1 -1
  35. package/dist/prepareSend.d.ts.map +1 -1
  36. package/dist/query/balance.fetchers.d.ts +27 -0
  37. package/dist/query/balance.fetchers.d.ts.map +1 -1
  38. package/dist/query/balance.hooks.d.ts +19 -0
  39. package/dist/query/balance.hooks.d.ts.map +1 -1
  40. package/dist/query/balance.queries.d.ts +18 -1
  41. package/dist/query/balance.queries.d.ts.map +1 -1
  42. package/dist/query/chains.queries.d.ts.map +1 -1
  43. package/dist/query/meld.fetchers.d.ts +1 -1
  44. package/dist/query/meld.fetchers.d.ts.map +1 -1
  45. package/dist/query/meld.hooks.d.ts +3 -3
  46. package/dist/query/meld.hooks.d.ts.map +1 -1
  47. package/dist/query/meld.queries.d.ts +1 -1
  48. package/dist/query/meld.queries.d.ts.map +1 -1
  49. package/dist/query/tokenList.queries.d.ts +54 -0
  50. package/dist/query/tokenList.queries.d.ts.map +1 -0
  51. package/dist/recover.d.ts +3 -1
  52. package/dist/recover.d.ts.map +1 -1
  53. package/dist/tokens.d.ts +13 -0
  54. package/dist/tokens.d.ts.map +1 -1
  55. package/dist/transactionIntent/deposits/depositOrchestrator.d.ts +2 -2
  56. package/dist/transactionIntent/deposits/depositOrchestrator.d.ts.map +1 -1
  57. package/dist/transactionIntent/deposits/gaslessDeposit.d.ts +2 -2
  58. package/dist/transactionIntent/deposits/gaslessDeposit.d.ts.map +1 -1
  59. package/dist/transactionIntent/deposits/standardDeposit.d.ts +1 -1
  60. package/dist/transactionIntent/deposits/standardDeposit.d.ts.map +1 -1
  61. package/dist/transactionIntent/handlers/intentHandler.d.ts.map +1 -1
  62. package/dist/transactionIntent/helpers/transactionStateHelpers.d.ts.map +1 -1
  63. package/dist/transactionIntent/quote/normalizeQuote.d.ts.map +1 -1
  64. package/dist/transactionIntent/types.d.ts +1 -1
  65. package/dist/transactionIntent/types.d.ts.map +1 -1
  66. package/dist/transactions.d.ts +3 -0
  67. package/dist/transactions.d.ts.map +1 -1
  68. package/dist/umd/trails.min.js +291 -202
  69. package/dist/walletUtils.d.ts +2 -1
  70. package/dist/walletUtils.d.ts.map +1 -1
  71. package/dist/wallets.d.ts +13 -54
  72. package/dist/wallets.d.ts.map +1 -1
  73. package/dist/widget/components/ClassicSwap.d.ts.map +1 -1
  74. package/dist/widget/components/ConnectWallet.d.ts.map +1 -1
  75. package/dist/widget/components/ConnectedWallets.d.ts.map +1 -1
  76. package/dist/widget/components/DirectTransfer.d.ts +1 -1
  77. package/dist/widget/components/DirectTransfer.d.ts.map +1 -1
  78. package/dist/widget/components/Fund.d.ts.map +1 -1
  79. package/dist/widget/components/FundMethods.d.ts.map +1 -1
  80. package/dist/widget/components/MeshExchangeSelection.d.ts +11 -0
  81. package/dist/widget/components/MeshExchangeSelection.d.ts.map +1 -0
  82. package/dist/widget/components/OnrampHistoryRow.d.ts +1 -1
  83. package/dist/widget/components/OnrampHistoryRow.d.ts.map +1 -1
  84. package/dist/widget/components/Pay.d.ts.map +1 -1
  85. package/dist/widget/components/PoolDeposit.d.ts.map +1 -1
  86. package/dist/widget/components/QRCodeWalletSelect.d.ts +1 -1
  87. package/dist/widget/components/QRCodeWalletSelect.d.ts.map +1 -1
  88. package/dist/widget/components/QuoteDetails.d.ts.map +1 -1
  89. package/dist/widget/components/Recipients.d.ts.map +1 -1
  90. package/dist/widget/components/RefundWarning.d.ts.map +1 -1
  91. package/dist/widget/components/TokenSelector.d.ts.map +1 -1
  92. package/dist/widget/components/TransactionDetails.d.ts.map +1 -1
  93. package/dist/widget/components/TransferPendingVertical.d.ts +1 -0
  94. package/dist/widget/components/TransferPendingVertical.d.ts.map +1 -1
  95. package/dist/widget/components/WalletConnect.d.ts.map +1 -1
  96. package/dist/widget/components/WalletImage.d.ts.map +1 -1
  97. package/dist/widget/components/WalletList.d.ts.map +1 -1
  98. package/dist/widget/components/Withdraw.d.ts.map +1 -1
  99. package/dist/widget/css/compiled.css +1 -1
  100. package/dist/widget/hooks/useAddressWalletIcon.d.ts.map +1 -1
  101. package/dist/widget/hooks/useCustomTokenSearch.d.ts +6 -1
  102. package/dist/widget/hooks/useCustomTokenSearch.d.ts.map +1 -1
  103. package/dist/widget/hooks/useDefaultDestinationToken.d.ts.map +1 -1
  104. package/dist/widget/hooks/useDefaultOriginToken.d.ts.map +1 -1
  105. package/dist/widget/hooks/useFiatOnRampCurrencies.d.ts +1 -1
  106. package/dist/widget/hooks/useFiatOnRampCurrencies.d.ts.map +1 -1
  107. package/dist/widget/hooks/useIntentTransactionHistory.d.ts.map +1 -1
  108. package/dist/widget/hooks/useQuote.d.ts +1 -1
  109. package/dist/widget/hooks/useQuote.d.ts.map +1 -1
  110. package/dist/widget/hooks/useSelectedFundMethod.d.ts +7 -0
  111. package/dist/widget/hooks/useSelectedFundMethod.d.ts.map +1 -1
  112. package/dist/widget/hooks/useSendForm.d.ts.map +1 -1
  113. package/dist/widget/hooks/useTokenList.d.ts +7 -1
  114. package/dist/widget/hooks/useTokenList.d.ts.map +1 -1
  115. package/dist/widget/hooks/useViewManager.d.ts +1 -1
  116. package/dist/widget/hooks/useViewManager.d.ts.map +1 -1
  117. package/dist/widget/index.js +1 -1
  118. package/dist/widget/providers/TrailsProvider.d.ts +2 -0
  119. package/dist/widget/providers/TrailsProvider.d.ts.map +1 -1
  120. package/dist/widget/utils/createWagmiConfig.d.ts +2 -2
  121. package/dist/widget/utils/createWagmiConfig.d.ts.map +1 -1
  122. package/dist/widget/utils/fundMethodSwitchState.d.ts +1 -0
  123. package/dist/widget/utils/fundMethodSwitchState.d.ts.map +1 -1
  124. package/dist/widget/utils/meldProviderUtils.d.ts +1 -1
  125. package/dist/widget/utils/meldProviderUtils.d.ts.map +1 -1
  126. package/dist/widget/utils/meshSupportedTokens.d.ts +4 -0
  127. package/dist/widget/utils/meshSupportedTokens.d.ts.map +1 -0
  128. package/dist/widget/utils/onrampConfig.d.ts +11 -0
  129. package/dist/widget/utils/onrampConfig.d.ts.map +1 -0
  130. package/dist/widget/utils/trailsOnrampConfig.d.ts +18 -0
  131. package/dist/widget/utils/trailsOnrampConfig.d.ts.map +1 -0
  132. package/dist/widget/widget.d.ts +24 -8
  133. package/dist/widget/widget.d.ts.map +1 -1
  134. package/package.json +9 -7
  135. package/src/chains.ts +9 -4
  136. package/src/constants.ts +2 -0
  137. package/src/customTokens.ts +21 -0
  138. package/src/index.ts +1 -0
  139. package/src/intents.ts +49 -41
  140. package/src/keyMachineClient.ts +29 -0
  141. package/src/keymachine/index.ts +175 -0
  142. package/src/keymachine/key-machine.gen.ts +993 -0
  143. package/src/onramp/MeshConnectFlow.tsx +86 -0
  144. package/src/onramp/MeshConnectIframe.tsx +661 -0
  145. package/src/onramp/SendFromExchangeButton.tsx +81 -0
  146. package/src/onramp/TrailsOnRampProvider.tsx +59 -0
  147. package/src/onramp/index.ts +31 -0
  148. package/src/onramp/meshconnect.ts +277 -0
  149. package/src/onramp/trailsOnramp.tsx +130 -0
  150. package/src/onramp-client/index.ts +4 -6
  151. package/src/prepareSend.ts +45 -44
  152. package/src/query/balance.fetchers.ts +134 -4
  153. package/src/query/balance.hooks.ts +61 -2
  154. package/src/query/balance.queries.ts +63 -0
  155. package/src/query/chains.queries.ts +1 -6
  156. package/src/query/meld.fetchers.ts +1 -1
  157. package/src/query/meld.hooks.ts +1 -1
  158. package/src/query/meld.queries.ts +1 -1
  159. package/src/query/tokenList.queries.ts +118 -0
  160. package/src/recover.ts +86 -23
  161. package/src/tokens.ts +108 -26
  162. package/src/transactionIntent/deposits/depositOrchestrator.ts +11 -11
  163. package/src/transactionIntent/deposits/gaslessDeposit.ts +38 -38
  164. package/src/transactionIntent/deposits/standardDeposit.ts +0 -4
  165. package/src/transactionIntent/handlers/intentHandler.ts +28 -11
  166. package/src/transactionIntent/helpers/transactionStateHelpers.ts +5 -2
  167. package/src/transactionIntent/quote/normalizeQuote.ts +11 -5
  168. package/src/transactionIntent/types.ts +1 -1
  169. package/src/transactions.ts +3 -0
  170. package/src/walletUtils.ts +2 -1
  171. package/src/wallets.ts +184 -380
  172. package/src/widget/compiled.css +1 -1
  173. package/src/widget/components/ClassicSwap.tsx +22 -5
  174. package/src/widget/components/ConnectWallet.tsx +4 -2
  175. package/src/widget/components/ConnectedWallets.tsx +2 -5
  176. package/src/widget/components/DirectTransfer.tsx +5 -2
  177. package/src/widget/components/Fund.tsx +144 -12
  178. package/src/widget/components/FundMethods.tsx +5 -9
  179. package/src/widget/components/MeldHistory.tsx +1 -1
  180. package/src/widget/components/MeshExchangeSelection.tsx +218 -0
  181. package/src/widget/components/OnrampHistoryRow.tsx +1 -1
  182. package/src/widget/components/Pay.tsx +20 -36
  183. package/src/widget/components/PoolDeposit.tsx +13 -22
  184. package/src/widget/components/QRCodeWalletSelect.tsx +5 -2
  185. package/src/widget/components/QuoteDetails.tsx +77 -68
  186. package/src/widget/components/Recipients.tsx +2 -1
  187. package/src/widget/components/RefundWarning.tsx +5 -10
  188. package/src/widget/components/TokenSelector.tsx +85 -16
  189. package/src/widget/components/TransactionDetails.tsx +46 -0
  190. package/src/widget/components/TransferPendingVertical.tsx +27 -19
  191. package/src/widget/components/WalletConnect.tsx +2 -5
  192. package/src/widget/components/WalletImage.tsx +6 -18
  193. package/src/widget/components/WalletList.tsx +1 -1
  194. package/src/widget/components/Withdraw.tsx +22 -4
  195. package/src/widget/hooks/useAddressWalletIcon.ts +2 -1
  196. package/src/widget/hooks/useCustomTokenSearch.tsx +63 -33
  197. package/src/widget/hooks/useDefaultDestinationToken.tsx +2 -5
  198. package/src/widget/hooks/useDefaultOriginToken.tsx +2 -5
  199. package/src/widget/hooks/useFiatOnRampCurrencies.ts +1 -1
  200. package/src/widget/hooks/useIntentTransactionHistory.ts +5 -0
  201. package/src/widget/hooks/useMeldTransactionStatus.ts +1 -1
  202. package/src/widget/hooks/useQuote.ts +51 -45
  203. package/src/widget/hooks/useSelectedFundMethod.tsx +14 -1
  204. package/src/widget/hooks/useSendForm.ts +26 -10
  205. package/src/widget/hooks/useTokenList.ts +208 -139
  206. package/src/widget/hooks/useViewManager.tsx +1 -0
  207. package/src/widget/providers/TrailsProvider.tsx +5 -0
  208. package/src/widget/styles.ts +1 -1
  209. package/src/widget/utils/createWagmiConfig.ts +7 -2
  210. package/src/widget/utils/fundMethodSwitchState.ts +2 -0
  211. package/src/widget/utils/meldProviderUtils.ts +8 -2
  212. package/src/widget/utils/meshSupportedTokens.ts +28 -0
  213. package/src/widget/utils/onrampConfig.ts +15 -0
  214. package/src/widget/utils/trailsOnrampConfig.ts +39 -0
  215. package/src/widget/widget.tsx +164 -98
  216. package/dist/onramp-client/trails-onramp.gen.d.ts +0 -570
  217. package/dist/onramp-client/trails-onramp.gen.d.ts.map +0 -1
  218. package/dist/widget/hooks/useCustomTokenFetch.d.ts +0 -19
  219. package/dist/widget/hooks/useCustomTokenFetch.d.ts.map +0 -1
  220. package/dist/widget/hooks/useTokenWithFreshBalance.d.ts +0 -18
  221. package/dist/widget/hooks/useTokenWithFreshBalance.d.ts.map +0 -1
  222. package/src/onramp-client/trails-onramp.gen.ts +0 -1320
  223. package/src/widget/assets/Binance_Icon_Logo.svg +0 -14
  224. package/src/widget/assets/Bitfinex_Icon_Logo.svg +0 -5
  225. package/src/widget/assets/Coinbase_Icon_Logo.svg +0 -1
  226. package/src/widget/assets/WalletConnect-logo-blue-bg.svg +0 -11
  227. package/src/widget/assets/sequence-logo.svg +0 -15
  228. package/src/widget/hooks/useCustomTokenFetch.tsx +0 -74
  229. package/src/widget/hooks/useTokenWithFreshBalance.ts +0 -246
@@ -25,9 +25,9 @@ import { useViewManager } from "../hooks/useViewManager.js"
25
25
  import { useOriginSelectedToken } from "../hooks/useOriginSelectedToken.js"
26
26
  import type { ProcessedFeeOption } from "../hooks/useSelectedFeeOption.js"
27
27
  import type { OnCompleteProps } from "../hooks/useSendForm.js"
28
+ import { useDefaultOriginToken } from "../hooks/useDefaultOriginToken.js"
28
29
  import { useSendForm } from "../hooks/useSendForm.js"
29
- import { useTokenList } from "../hooks/useTokenList.js"
30
- import { useTokenWithFreshBalance } from "../hooks/useTokenWithFreshBalance.js"
30
+ import { useAccountTokenBalanceOnchain } from "../../query/balance.hooks.js"
31
31
  import { ChainList } from "./ChainList.js"
32
32
  import { DynamicSizeInputField } from "./DynamicSizeInputField.js"
33
33
  import { EarnPools } from "./EarnPools.js"
@@ -96,24 +96,19 @@ export const PoolDeposit: React.FC<PoolDepositProps> = ({
96
96
  const {
97
97
  token: freshOriginToken,
98
98
  isLoadingBalance: isLoadingFreshOriginBalance,
99
- } = useTokenWithFreshBalance(originToken, account?.address)
99
+ } = useAccountTokenBalanceOnchain(originToken, account?.address)
100
100
 
101
101
  const { selectedPool, setSelectedPool } = useEarnPool()
102
102
 
103
+ const { defaultOriginToken, isLoading: isLoadingOriginDefaults } =
104
+ useDefaultOriginToken()
105
+
103
106
  const [showEarnPools, setShowEarnPools] = useState(false)
104
107
  const [showOriginTokenSelector, setShowOriginTokenSelector] = useState(false)
105
108
  const [showOriginChainList, setShowOriginChainList] = useState(false)
106
109
  const [amount, setAmount] = useState("")
107
110
  const inputRef = useRef<HTMLInputElement>(null)
108
111
 
109
- // Get sorted tokens to auto-select the highest USD value token
110
- const { filteredTokensFormatted, isLoadingTokens } = useTokenList({
111
- onContinue: () => {}, // Not used for auto-selection
112
- onError: () => {}, // Not used for auto-selection
113
- fundMethod: undefined,
114
- allSupportedTokens: false,
115
- })
116
-
117
112
  // Memoized generated calldata
118
113
  const generatedDepositCalldata = useMemo(() => {
119
114
  if (!selectedPool || !amount || !walletClient || Number(amount) <= 0) {
@@ -232,19 +227,15 @@ export const PoolDeposit: React.FC<PoolDepositProps> = ({
232
227
  chainId: originToken?.chainId,
233
228
  })
234
229
 
235
- // Auto-select the highest USD value token as origin token
236
230
  useEffect(() => {
237
- if (
238
- !originToken &&
239
- !isLoadingTokens &&
240
- filteredTokensFormatted?.length > 0
241
- ) {
242
- const highestValueToken = filteredTokensFormatted[0] // First token is highest USD value
243
- if (highestValueToken && Number(highestValueToken.balanceUsd) > 0) {
244
- setOriginToken(highestValueToken)
245
- }
231
+ if (!originToken && !isLoadingOriginDefaults && defaultOriginToken) {
232
+ logger.console.log(
233
+ "[trails-sdk] Auto-selecting origin token:",
234
+ defaultOriginToken,
235
+ )
236
+ setOriginToken(defaultOriginToken as any)
246
237
  }
247
- }, [originToken, isLoadingTokens, filteredTokensFormatted, setOriginToken])
238
+ }, [originToken, isLoadingOriginDefaults, defaultOriginToken, setOriginToken])
248
239
 
249
240
  // Auto-focus input field on component mount
250
241
  useEffect(() => {
@@ -1,5 +1,8 @@
1
+ import {
2
+ getQRCodeWallets,
3
+ type QRCodeWalletOption,
4
+ } from "@0xtrails/wallet-registry"
1
5
  import type React from "react"
2
- import { useQRCodeWallets, type QRCodeWalletOption } from "../../wallets.js"
3
6
  import { ScreenHeader } from "./ScreenHeader.js"
4
7
 
5
8
  interface QRCodeWalletSelectProps {
@@ -19,7 +22,7 @@ export const QRCodeWalletSelect: React.FC<QRCodeWalletSelectProps> = ({
19
22
  title = "Which wallet will scan the QR code?",
20
23
  disabled = false,
21
24
  }) => {
22
- const defaultQrCodeWallets = useQRCodeWallets()
25
+ const defaultQrCodeWallets = getQRCodeWallets()
23
26
  const defaultWalletOptions = walletOptions || defaultQrCodeWallets
24
27
  return (
25
28
  <div className="space-y-6">
@@ -166,6 +166,13 @@ export const QuoteDetails: React.FC<QuoteDetailsProps> = ({
166
166
  return parseFloat(quote.slippageTolerance) * 100
167
167
  }, [quote?.slippageTolerance])
168
168
 
169
+ const protocolVersionDisplay = useMemo(() => {
170
+ const normalized = (quote?.intentProtocol || "v1")
171
+ .replace("_", ".")
172
+ .toUpperCase()
173
+ return normalized.startsWith("V") ? normalized : `V${normalized}`
174
+ }, [quote?.intentProtocol])
175
+
169
176
  if (!showContent) return null
170
177
 
171
178
  return (
@@ -994,38 +1001,40 @@ export const QuoteDetails: React.FC<QuoteDetailsProps> = ({
994
1001
  {/* Custom Calldata */}
995
1002
  {quote?.destinationCalldata && (
996
1003
  <div className="space-y-2">
997
- <button
998
- type="button"
999
- onClick={() => {
1000
- setShowCalldata(!showCalldata)
1001
- // Auto-scroll to calldata when expanding
1002
- if (!showCalldata) {
1003
- setTimeout(() => {
1004
- if (calldataRef.current) {
1005
- calldataRef.current.scrollIntoView({
1006
- behavior: "smooth",
1007
- block: "nearest",
1008
- })
1009
- }
1010
- }, 150) // Delay to let the expansion animation start
1004
+ <div className="space-y-0.5">
1005
+ <button
1006
+ type="button"
1007
+ onClick={() => {
1008
+ setShowCalldata(!showCalldata)
1009
+ // Auto-scroll to calldata when expanding
1010
+ if (!showCalldata) {
1011
+ setTimeout(() => {
1012
+ if (calldataRef.current) {
1013
+ calldataRef.current.scrollIntoView({
1014
+ behavior: "smooth",
1015
+ block: "nearest",
1016
+ })
1017
+ }
1018
+ }, 150) // Delay to let the expansion animation start
1019
+ }
1020
+ }}
1021
+ className="flex items-center gap-1 text-xs hover:underline cursor-pointer transition-colors duration-200 text-gray-600 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300"
1022
+ aria-label={
1023
+ showCalldata
1024
+ ? "Hide custom calldata"
1025
+ : "Show custom calldata"
1011
1026
  }
1012
- }}
1013
- className="flex items-center gap-1 text-xs hover:underline cursor-pointer transition-colors duration-200 text-gray-600 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300"
1014
- aria-label={
1015
- showCalldata
1016
- ? "Hide custom calldata"
1017
- : "Show custom calldata"
1018
- }
1019
- >
1020
- <span className="text-[10px]">
1021
- Includes custom destination calldata
1022
- </span>
1023
- <ChevronDown
1024
- className={`size-3 transition-transform duration-300 ease-out ${
1025
- showCalldata ? "rotate-180" : ""
1026
- }`}
1027
- />
1028
- </button>
1027
+ >
1028
+ <span className="text-[10px]">
1029
+ Includes custom destination calldata
1030
+ </span>
1031
+ <ChevronDown
1032
+ className={`size-3 transition-transform duration-300 ease-out ${
1033
+ showCalldata ? "rotate-180" : ""
1034
+ }`}
1035
+ />
1036
+ </button>
1037
+ </div>
1029
1038
  <div
1030
1039
  ref={calldataRef}
1031
1040
  className={`overflow-hidden transition-all duration-300 ease-out ${
@@ -1135,49 +1144,43 @@ export const QuoteDetails: React.FC<QuoteDetailsProps> = ({
1135
1144
  )}
1136
1145
  </span>
1137
1146
  </div>
1138
- {hasLiveStates && (
1147
+ {hasLiveStates && hasTxHash && txExplorerUrl && (
1139
1148
  <div className="mt-1 flex justify-between items-center">
1140
1149
  <span className="text-xs text-gray-600 dark:text-gray-400">
1141
1150
  Hash
1142
1151
  </span>
1143
- {hasTxHash && txExplorerUrl ? (
1144
- <a
1145
- href={txExplorerUrl}
1146
- target="_blank"
1147
- rel="noopener noreferrer"
1148
- className="text-xs flex items-center gap-1 hover:underline text-blue-600 hover:text-blue-700 dark:text-blue-400 dark:hover:text-blue-300"
1149
- >
1150
- {txHasMetaError && (
1151
- <svg
1152
- className="w-4 h-4 text-orange-500"
1153
- fill="none"
1154
- viewBox="0 0 24 24"
1155
- stroke="currentColor"
1156
- >
1157
- <title>
1158
- An internal meta transaction failure
1159
- occurred
1160
- </title>
1161
- <path
1162
- strokeLinecap="round"
1163
- strokeLinejoin="round"
1164
- strokeWidth={2}
1165
- d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 16.5c-.77.833.192 2.5 1.732 2.5z"
1166
- />
1167
- </svg>
1152
+ <a
1153
+ href={txExplorerUrl}
1154
+ target="_blank"
1155
+ rel="noopener noreferrer"
1156
+ className="text-xs flex items-center gap-1 hover:underline text-blue-600 hover:text-blue-700 dark:text-blue-400 dark:hover:text-blue-300"
1157
+ >
1158
+ {txHasMetaError && (
1159
+ <svg
1160
+ className="w-4 h-4 text-orange-500"
1161
+ fill="none"
1162
+ viewBox="0 0 24 24"
1163
+ stroke="currentColor"
1164
+ >
1165
+ <title>
1166
+ An internal meta transaction failure
1167
+ occurred
1168
+ </title>
1169
+ <path
1170
+ strokeLinecap="round"
1171
+ strokeLinejoin="round"
1172
+ strokeWidth={2}
1173
+ d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 16.5c-.77.833.192 2.5 1.732 2.5z"
1174
+ />
1175
+ </svg>
1176
+ )}
1177
+ <span>
1178
+ {truncateAddress(
1179
+ liveTxState.transactionHash,
1168
1180
  )}
1169
- <span>
1170
- {truncateAddress(
1171
- liveTxState.transactionHash,
1172
- )}
1173
- </span>
1174
- <ExternalLink className="w-3 h-3" />
1175
- </a>
1176
- ) : (
1177
- <span className="text-xs text-gray-400 dark:text-gray-500">
1178
- ...
1179
1181
  </span>
1180
- )}
1182
+ <ExternalLink className="w-3 h-3" />
1183
+ </a>
1181
1184
  </div>
1182
1185
  )}
1183
1186
  </div>
@@ -1188,6 +1191,12 @@ export const QuoteDetails: React.FC<QuoteDetailsProps> = ({
1188
1191
  )
1189
1192
  })()}
1190
1193
 
1194
+ {protocolVersionDisplay.length > 0 && (
1195
+ <div className="pt-1 text-[10px] opacity-50 text-gray-600 dark:text-gray-400">
1196
+ Protocol version: {protocolVersionDisplay}
1197
+ </div>
1198
+ )}
1199
+
1191
1200
  {/* Children content */}
1192
1201
  {children && <div className="mb-0">{children}</div>}
1193
1202
  </div>
@@ -1,4 +1,5 @@
1
1
  import { Plus, X } from "lucide-react"
2
+ import { wagmiConnectorToWalletId } from "@0xtrails/wallet-registry"
2
3
  import type React from "react"
3
4
  import { useCallback, useEffect, useState } from "react"
4
5
  import { isAddress } from "viem"
@@ -6,7 +7,7 @@ import { useAccount, useConnections } from "wagmi"
6
7
  import { useResolveEnsAddress, useResolveEnsName } from "../../ens.js"
7
8
  import { logger } from "../../logger.js"
8
9
  import { addressEqual, truncateAddress } from "../../utils/address.js"
9
- import { useWallets, wagmiConnectorToWalletId } from "../../wallets.js"
10
+ import { useWallets } from "../../wallets.js"
10
11
  import {
11
12
  useViewManager,
12
13
  type Mode,
@@ -9,17 +9,15 @@ interface RefundWarningProps {
9
9
  }
10
10
 
11
11
  export const RefundWarning: React.FC<RefundWarningProps> = ({
12
- fundMethod,
13
12
  isSenderContractOnOrigin,
14
13
  isSenderContractOnDestination,
15
14
  isSequenceWallet = false,
16
15
  }) => {
17
16
  // Determine if we should show the warning
18
17
  const shouldShowWarning =
19
- fundMethod === "onramp-mesh" ||
20
- (isSenderContractOnOrigin &&
21
- !isSenderContractOnDestination &&
22
- !isSequenceWallet)
18
+ isSenderContractOnOrigin &&
19
+ !isSenderContractOnDestination &&
20
+ !isSequenceWallet
23
21
 
24
22
  if (!shouldShowWarning) {
25
23
  return null
@@ -27,16 +25,13 @@ export const RefundWarning: React.FC<RefundWarningProps> = ({
27
25
 
28
26
  // Determine the warning message
29
27
  let warningMessage = ""
30
- if (fundMethod === "onramp-mesh") {
31
- warningMessage =
32
- "Using exchange funding may result in loss of funds if the transaction fails and the sender address cannot accept refunds on the origin chain."
33
- } else if (isSenderContractOnOrigin && !isSenderContractOnDestination) {
28
+ if (isSenderContractOnOrigin && !isSenderContractOnDestination) {
34
29
  warningMessage =
35
30
  "The sender is a contract address. Funds may be lost if the transaction fails and the contract cannot accept refunds on the destination chain."
36
31
  }
37
32
 
38
33
  return (
39
- <div className="px-2 py-3 rounded-lg bg-amber-500/10 border border-solid border-amber-500/30">
34
+ <div className="mb-2 px-2 py-3 rounded-lg bg-amber-500/10 border border-solid border-amber-500/30">
40
35
  <div className="flex items-start space-x-2">
41
36
  <svg
42
37
  className="w-4 h-4 text-amber-500 flex-shrink-0 mt-0.5"
@@ -11,6 +11,7 @@ import {
11
11
  useRef,
12
12
  useState,
13
13
  } from "react"
14
+ import { isAddress } from "viem"
14
15
  import { useAccount } from "wagmi"
15
16
  import { getChainInfo } from "../../chains.js"
16
17
  import type { Token } from "../../tokens.js"
@@ -24,7 +25,6 @@ import {
24
25
  import { isValueZero } from "../../utils.js"
25
26
  import { useBalanceVisible } from "../hooks/useBalanceVisible.js"
26
27
  import { useChainFilter } from "../hooks/useChainFilter.js"
27
- import { useCustomTokenSearch } from "../hooks/useCustomTokenSearch.js"
28
28
  import { useTokenList } from "../hooks/useTokenList.js"
29
29
  import { useSupportedChains } from "../../query/chains.hooks.js"
30
30
  import { ChainFilterDropdown } from "./ChainFilterDropdown.js"
@@ -409,10 +409,13 @@ export const TokenSelector: React.FC<TokenSelectorProps> = ({
409
409
  setSearchQuery,
410
410
  handleTokenSelect,
411
411
  filteredTokens,
412
+ chainFilteredTokens: rawChainFilteredTokens,
413
+ foundTokensAllChains,
412
414
  isLoadingTokens,
415
+ isLoadingCustomToken,
413
416
  isSearching,
417
+ customTokenError,
414
418
  isTokenSelected,
415
- filteredTokensFormatted,
416
419
  balanceError,
417
420
  } = useTokenList({
418
421
  onContinue: onTokenSelect, // Use onTokenSelect for the hook
@@ -428,20 +431,25 @@ export const TokenSelector: React.FC<TokenSelectorProps> = ({
428
431
  } = useChainFilter()
429
432
  const { data: supportedChains = [] } = useSupportedChains()
430
433
 
431
- // Handle custom token search and integration
432
- // Only enable custom token search after initial load is complete
433
- const {
434
- chainFilteredTokens: rawChainFilteredTokens,
435
- isLoadingCustomToken,
436
- customTokenError,
437
- } = useCustomTokenSearch({
438
- searchQuery: hasInitiallyLoaded ? searchQuery : "", // Disable during initial load
439
- filteredTokensFormatted,
440
- filterByChainId,
441
- })
442
-
443
434
  const chainFilteredTokens = useDeferredValue(rawChainFilteredTokens)
444
435
 
436
+ // When searching by address with a chain filter active, the token may not
437
+ // exist on the selected chain but may have been found on other chains.
438
+ // Compute those "other chain" results so we can offer them to the user.
439
+ const tokensFoundOnOtherChains = useMemo(() => {
440
+ if (
441
+ filterByChainId === null ||
442
+ chainFilteredTokens.length > 0 ||
443
+ foundTokensAllChains.length === 0 ||
444
+ !isAddress(searchQuery.trim())
445
+ ) {
446
+ return []
447
+ }
448
+ return foundTokensAllChains.filter(
449
+ (t) => (t.chainId || 0) !== filterByChainId,
450
+ )
451
+ }, [filterByChainId, chainFilteredTokens, foundTokensAllChains, searchQuery])
452
+
445
453
  // Track when initial load is complete
446
454
  useEffect(() => {
447
455
  if (!isLoadingTokens && !hasInitiallyLoaded) {
@@ -638,8 +646,69 @@ export const TokenSelector: React.FC<TokenSelectorProps> = ({
638
646
  filteredTokens.length === 0 &&
639
647
  chainFilteredTokens.length === 0 &&
640
648
  errorMessage && (
641
- <div className="text-center py-4 rounded-lg trails-bg-secondary">
642
- <p className="text-gray-500 dark:text-gray-400">{errorMessage}</p>
649
+ <div className="space-y-3">
650
+ <div className="text-center py-4 rounded-lg trails-bg-secondary">
651
+ <p className="text-gray-500 dark:text-gray-400">{errorMessage}</p>
652
+ </div>
653
+
654
+ {/* Show tokens found on other chains when address search has results on non-selected chains */}
655
+ {tokensFoundOnOtherChains.length > 0 && (
656
+ <div className="space-y-2">
657
+ <p className="text-xs font-medium text-gray-500 dark:text-gray-400 px-2">
658
+ {tokensFoundOnOtherChains.length === 1
659
+ ? "Found on another chain"
660
+ : `Found on ${tokensFoundOnOtherChains.length} other chains`}
661
+ </p>
662
+ <div className="max-h-48 overflow-y-auto trails-scrollbar">
663
+ {tokensFoundOnOtherChains.map((token) => {
664
+ const chainInfo = getChainInfo(token.chainId || 0)
665
+ const chainName =
666
+ token.chainName ||
667
+ chainInfo?.name ||
668
+ `Chain ${token.chainId || 0}`
669
+ return (
670
+ <div
671
+ key={`${token.chainId}-${token.contractAddress}`}
672
+ onClick={() => handleTokenSelectWithReset(token)}
673
+ onKeyDown={(e) => {
674
+ if (e.key === "Enter" || e.key === " ") {
675
+ e.preventDefault()
676
+ handleTokenSelectWithReset(token)
677
+ }
678
+ }}
679
+ className="w-full py-2 px-4 flex items-center space-x-3 transition-all duration-200 trails-list-item trails-border-radius-list-button cursor-pointer"
680
+ >
681
+ <div className="relative shrink-0 mr-2">
682
+ <div className="rounded-full flex items-center justify-center bg-gray-100 dark:bg-gray-700">
683
+ {token.contractAddress ? (
684
+ <TokenImage
685
+ symbol={token.symbol}
686
+ imageUrl={token.imageUrl}
687
+ chainId={token.chainId}
688
+ contractAddress={token.contractAddress}
689
+ size={32}
690
+ />
691
+ ) : (
692
+ <span className="text-base font-medium text-gray-600 dark:text-gray-300">
693
+ {token.symbol}
694
+ </span>
695
+ )}
696
+ </div>
697
+ </div>
698
+ <div className="flex-1 min-w-0 text-left">
699
+ <h3 className="text-sm font-medium truncate text-gray-900 dark:text-white">
700
+ {token.name}
701
+ </h3>
702
+ <span className="text-xs text-gray-500 dark:text-gray-400">
703
+ {token.symbol} on {chainName}
704
+ </span>
705
+ </div>
706
+ </div>
707
+ )
708
+ })}
709
+ </div>
710
+ </div>
711
+ )}
643
712
  </div>
644
713
  )}
645
714
 
@@ -95,6 +95,52 @@ export const TransactionDetails: React.FC<TransactionDetailsProps> = ({
95
95
  </div>
96
96
  )}
97
97
 
98
+ {/* Refund Transaction Hash */}
99
+ {isDisplayableTransactionHash(transaction.refundTransactionHash) &&
100
+ (transaction.refundTransactionChainId || transaction.originChainId) && (
101
+ <div className="flex justify-between items-center">
102
+ <span className="text-xs text-gray-600 dark:text-gray-400">
103
+ Refund Tx:
104
+ </span>
105
+ <a
106
+ href={getExplorerUrl({
107
+ txHash: transaction.refundTransactionHash,
108
+ chainId:
109
+ transaction.refundTransactionChainId ||
110
+ transaction.originChainId ||
111
+ 0,
112
+ })}
113
+ target="_blank"
114
+ rel="noopener noreferrer"
115
+ className="text-xs font-mono hover:underline flex items-center gap-1 text-gray-900 dark:text-gray-100"
116
+ >
117
+ <ChainImage
118
+ chainId={
119
+ transaction.refundTransactionChainId ||
120
+ transaction.originChainId ||
121
+ 0
122
+ }
123
+ size={16}
124
+ />
125
+ {truncateAddress(transaction.refundTransactionHash)}
126
+ <svg
127
+ aria-hidden="true"
128
+ className="w-3 h-3"
129
+ fill="none"
130
+ stroke="currentColor"
131
+ viewBox="0 0 24 24"
132
+ >
133
+ <path
134
+ strokeLinecap="round"
135
+ strokeLinejoin="round"
136
+ strokeWidth={2}
137
+ d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"
138
+ />
139
+ </svg>
140
+ </a>
141
+ </div>
142
+ )}
143
+
98
144
  {/* Origin Token - Moved before Origin Intent */}
99
145
  {transaction.originToken && (
100
146
  <div className="flex justify-between items-start">
@@ -1,6 +1,7 @@
1
1
  import { ChevronRight, ExternalLink } from "lucide-react"
2
2
  import type React from "react"
3
- import { useEffect, useMemo, useState } from "react"
3
+ import { useEffect, useState } from "react"
4
+ import { mainnet } from "viem/chains"
4
5
  import { TRAILS_SUPPORT_URL } from "../../constants.js"
5
6
  import type { PrepareSendQuote } from "../../prepareSend.js"
6
7
  import type { TransactionState } from "../../transactions.js"
@@ -29,7 +30,7 @@ const isOFTRoute = (routeProviders?: { id: string }[]): boolean => {
29
30
  const OFT_TIMEOUT_MS = 60 * MINUTE_MS // 1 hour for OFT routes
30
31
  const DEFAULT_TIMEOUT_MS = MINUTE_MS // 1 minute for normal routes
31
32
  const MAINNET_TIMEOUT_MS = 2 * MINUTE_MS // 2 minutes for Ethereum mainnet routes
32
- const ETHEREUM_MAINNET_CHAIN_ID = 1
33
+ const MESH_ONRAMP_TIMEOUT_MS = 3 * MINUTE_MS // 3 minutes for Mesh onramp
33
34
 
34
35
  // Checkmark icon for completed steps
35
36
  const CheckmarkIcon = () => (
@@ -108,6 +109,7 @@ interface TransferPendingProps {
108
109
  timestamp?: number
109
110
  onContinue?: () => void
110
111
  onRampQuote?: OnrampQuote | null
112
+ fundMethod?: string | null
111
113
  }
112
114
 
113
115
  export const TransferPending: React.FC<TransferPendingProps> = ({
@@ -117,6 +119,7 @@ export const TransferPending: React.FC<TransferPendingProps> = ({
117
119
  onRampQuote,
118
120
  timestamp,
119
121
  onContinue,
122
+ fundMethod,
120
123
  }) => {
121
124
  const { mode } = useViewManager()
122
125
  const [showContent, setShowContent] = useState(false)
@@ -128,25 +131,28 @@ export const TransferPending: React.FC<TransferPendingProps> = ({
128
131
  null,
129
132
  )
130
133
  const isOFT = isOFTRoute(quote?.routeProviders)
131
- const isMainnetOrigin = quote?.originChain?.id === ETHEREUM_MAINNET_CHAIN_ID
134
+ const isMainnetOrigin = quote?.originChain?.id === mainnet.id
132
135
 
133
136
  const showContinueButton =
134
137
  hasAnyFailedOrAbortedTransactions(transactionStates) && onContinue
135
138
 
136
139
  // Timeout warning: OFT routes can take significantly longer than standard routes.
137
140
  useEffect(() => {
138
- const timeoutMs = isOFT
139
- ? OFT_TIMEOUT_MS
140
- : isMainnetOrigin
141
- ? MAINNET_TIMEOUT_MS
142
- : DEFAULT_TIMEOUT_MS
141
+ const timeoutMs =
142
+ fundMethod === "onramp-mesh"
143
+ ? MESH_ONRAMP_TIMEOUT_MS
144
+ : isOFT
145
+ ? OFT_TIMEOUT_MS
146
+ : isMainnetOrigin
147
+ ? MAINNET_TIMEOUT_MS
148
+ : DEFAULT_TIMEOUT_MS
143
149
 
144
150
  const timeoutTimer = setTimeout(() => {
145
151
  setShowTimeoutWarning(true)
146
152
  }, timeoutMs)
147
153
 
148
154
  return () => clearTimeout(timeoutTimer)
149
- }, [isOFT, isMainnetOrigin])
155
+ }, [fundMethod, isMainnetOrigin, isOFT])
150
156
  useEffect(() => {
151
157
  const depositConfirmed = transactionStates?.[0]?.state === "confirmed"
152
158
 
@@ -181,16 +187,18 @@ export const TransferPending: React.FC<TransferPendingProps> = ({
181
187
  }
182
188
  }, [])
183
189
 
184
- const activePendingIndex = useMemo(
185
- () => transactionStates.findIndex((tx) => tx.state === "pending"),
186
- [transactionStates],
187
- )
188
- const [prevActivePendingIndex, setPrevActivePendingIndex] =
189
- useState(activePendingIndex)
190
- if (activePendingIndex !== prevActivePendingIndex) {
191
- setPrevActivePendingIndex(activePendingIndex)
192
- setActivePendingTimer(0)
193
- }
190
+ const [activePendingIndex, setActivePendingIndex] = useState(-1)
191
+
192
+ useEffect(() => {
193
+ const newActiveIndex = transactionStates.findIndex(
194
+ (tx) => tx.state === "pending",
195
+ )
196
+
197
+ if (newActiveIndex !== activePendingIndex) {
198
+ setActivePendingIndex(newActiveIndex)
199
+ setActivePendingTimer(0)
200
+ }
201
+ }, [transactionStates, activePendingIndex])
194
202
 
195
203
  // Add CSS animation for draw effect
196
204
  useEffect(() => {
@@ -1,12 +1,9 @@
1
+ import { getWalletIcon, getWalletName } from "@0xtrails/wallet-registry"
1
2
  import { type FC, useEffect, useMemo, useState } from "react"
2
3
  import { useAccount, useConnect, useDisconnect } from "wagmi"
3
4
  import { logger } from "../../logger.js"
4
5
  import { isWalletConnectConnector as checkIsWalletConnectConnector } from "../../walletUtils.js"
5
- import {
6
- getWalletIcon,
7
- getWalletName,
8
- useWalletConfigs,
9
- } from "../../wallets.js"
6
+ import { useWalletConfigs } from "../../wallets.js"
10
7
  import { useConnector } from "../hooks/useConnector.js"
11
8
  import { useIsMobile } from "../hooks/useIsMobile.js"
12
9
  import { useWalletConnectUri } from "../hooks/useWalletConnectUri.js"