0xtrails 0.13.0 → 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 (307) hide show
  1. package/dist/{ccip-Cg9-lJ6K.js → ccip-CT_An6eM.js} +39 -39
  2. package/dist/chains.d.ts +4 -3
  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/error.d.ts +1 -0
  8. package/dist/error.d.ts.map +1 -1
  9. package/dist/gasless.d.ts +1 -2
  10. package/dist/gasless.d.ts.map +1 -1
  11. package/dist/{index-DEojZg7b.js → index-RfqL5Foz.js} +56672 -43550
  12. package/dist/index.d.ts +5 -2
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +385 -333
  15. package/dist/intents.d.ts +8 -2
  16. package/dist/intents.d.ts.map +1 -1
  17. package/dist/keyMachineClient.d.ts +9 -0
  18. package/dist/keyMachineClient.d.ts.map +1 -0
  19. package/dist/keymachine/index.d.ts +14 -0
  20. package/dist/keymachine/index.d.ts.map +1 -0
  21. package/dist/keymachine/key-machine.gen.d.ts +461 -0
  22. package/dist/keymachine/key-machine.gen.d.ts.map +1 -0
  23. package/dist/onramp/MeshConnectFlow.d.ts +18 -0
  24. package/dist/onramp/MeshConnectFlow.d.ts.map +1 -0
  25. package/dist/onramp/MeshConnectIframe.d.ts +13 -0
  26. package/dist/onramp/MeshConnectIframe.d.ts.map +1 -0
  27. package/dist/onramp/SendFromExchangeButton.d.ts +16 -0
  28. package/dist/onramp/SendFromExchangeButton.d.ts.map +1 -0
  29. package/dist/onramp/TrailsOnRampProvider.d.ts +31 -0
  30. package/dist/onramp/TrailsOnRampProvider.d.ts.map +1 -0
  31. package/dist/onramp/index.d.ts +13 -0
  32. package/dist/onramp/index.d.ts.map +1 -0
  33. package/dist/onramp/meshconnect.d.ts +30 -0
  34. package/dist/onramp/meshconnect.d.ts.map +1 -0
  35. package/dist/onramp/trailsOnramp.d.ts +24 -0
  36. package/dist/onramp/trailsOnramp.d.ts.map +1 -0
  37. package/dist/onramp-client/index.d.ts +3 -3
  38. package/dist/onramp-client/index.d.ts.map +1 -1
  39. package/dist/paymasterSend.d.ts.map +1 -1
  40. package/dist/prepareSend.d.ts.map +1 -1
  41. package/dist/query/balance.fetchers.d.ts +31 -2
  42. package/dist/query/balance.fetchers.d.ts.map +1 -1
  43. package/dist/query/balance.hooks.d.ts +21 -2
  44. package/dist/query/balance.hooks.d.ts.map +1 -1
  45. package/dist/query/balance.queries.d.ts +18 -1
  46. package/dist/query/balance.queries.d.ts.map +1 -1
  47. package/dist/query/chains.queries.d.ts.map +1 -1
  48. package/dist/query/meld.fetchers.d.ts +1 -1
  49. package/dist/query/meld.fetchers.d.ts.map +1 -1
  50. package/dist/query/meld.hooks.d.ts +3 -3
  51. package/dist/query/meld.hooks.d.ts.map +1 -1
  52. package/dist/query/meld.queries.d.ts +1 -1
  53. package/dist/query/meld.queries.d.ts.map +1 -1
  54. package/dist/query/price.fetchers.d.ts +15 -0
  55. package/dist/query/price.fetchers.d.ts.map +1 -0
  56. package/dist/query/price.hooks.d.ts +352 -0
  57. package/dist/query/price.hooks.d.ts.map +1 -0
  58. package/dist/query/price.queries.d.ts +34 -0
  59. package/dist/query/price.queries.d.ts.map +1 -0
  60. package/dist/query/tokenList.queries.d.ts +54 -0
  61. package/dist/query/tokenList.queries.d.ts.map +1 -0
  62. package/dist/recover.d.ts +6 -4
  63. package/dist/recover.d.ts.map +1 -1
  64. package/dist/tokens.d.ts +13 -0
  65. package/dist/tokens.d.ts.map +1 -1
  66. package/dist/transactionIntent/deposits/depositOrchestrator.d.ts +2 -2
  67. package/dist/transactionIntent/deposits/depositOrchestrator.d.ts.map +1 -1
  68. package/dist/transactionIntent/deposits/gaslessDeposit.d.ts +2 -2
  69. package/dist/transactionIntent/deposits/gaslessDeposit.d.ts.map +1 -1
  70. package/dist/transactionIntent/deposits/standardDeposit.d.ts +1 -1
  71. package/dist/transactionIntent/deposits/standardDeposit.d.ts.map +1 -1
  72. package/dist/transactionIntent/handlers/intentHandler.d.ts.map +1 -1
  73. package/dist/transactionIntent/helpers/transactionStateHelpers.d.ts.map +1 -1
  74. package/dist/transactionIntent/quote/normalizeQuote.d.ts.map +1 -1
  75. package/dist/transactionIntent/types.d.ts +1 -1
  76. package/dist/transactionIntent/types.d.ts.map +1 -1
  77. package/dist/transactions.d.ts +4 -0
  78. package/dist/transactions.d.ts.map +1 -1
  79. package/dist/umd/trails.min.js +291 -202
  80. package/dist/utils/format.d.ts +7 -0
  81. package/dist/utils/format.d.ts.map +1 -1
  82. package/dist/walletUtils.d.ts +2 -1
  83. package/dist/walletUtils.d.ts.map +1 -1
  84. package/dist/wallets.d.ts +13 -54
  85. package/dist/wallets.d.ts.map +1 -1
  86. package/dist/widget/components/AccountIntentTransactionHistory.d.ts.map +1 -1
  87. package/dist/widget/components/ClassicSwap.d.ts.map +1 -1
  88. package/dist/widget/components/ConnectWallet.d.ts.map +1 -1
  89. package/dist/widget/components/ConnectedWallets.d.ts.map +1 -1
  90. package/dist/widget/components/DirectTransfer.d.ts +1 -1
  91. package/dist/widget/components/DirectTransfer.d.ts.map +1 -1
  92. package/dist/widget/components/EarnPools.d.ts.map +1 -1
  93. package/dist/widget/components/ExecutionStatusBadge.d.ts.map +1 -1
  94. package/dist/widget/components/Fund.d.ts.map +1 -1
  95. package/dist/widget/components/FundMethods.d.ts.map +1 -1
  96. package/dist/widget/components/HighPriceImpactBlock.d.ts +7 -0
  97. package/dist/widget/components/HighPriceImpactBlock.d.ts.map +1 -0
  98. package/dist/widget/components/MeldHistory.d.ts.map +1 -1
  99. package/dist/widget/components/MeshExchangeSelection.d.ts +11 -0
  100. package/dist/widget/components/MeshExchangeSelection.d.ts.map +1 -0
  101. package/dist/widget/components/OnrampHistoryRow.d.ts +1 -1
  102. package/dist/widget/components/OnrampHistoryRow.d.ts.map +1 -1
  103. package/dist/widget/components/OnrampProviderConfirmation.d.ts.map +1 -1
  104. package/dist/widget/components/Pay.d.ts.map +1 -1
  105. package/dist/widget/components/PoolDeposit.d.ts.map +1 -1
  106. package/dist/widget/components/PoolWithdraw.d.ts.map +1 -1
  107. package/dist/widget/components/QRCodeWalletSelect.d.ts +1 -1
  108. package/dist/widget/components/QRCodeWalletSelect.d.ts.map +1 -1
  109. package/dist/widget/components/QuoteDetails.d.ts.map +1 -1
  110. package/dist/widget/components/Receipt.d.ts.map +1 -1
  111. package/dist/widget/components/Recipients.d.ts.map +1 -1
  112. package/dist/widget/components/RefundWarning.d.ts.map +1 -1
  113. package/dist/widget/components/TokenSelector.d.ts.map +1 -1
  114. package/dist/widget/components/TransactionDetails.d.ts.map +1 -1
  115. package/dist/widget/components/TransactionHistoryItem.d.ts +2 -0
  116. package/dist/widget/components/TransactionHistoryItem.d.ts.map +1 -1
  117. package/dist/widget/components/TransferPendingVertical.d.ts +1 -0
  118. package/dist/widget/components/TransferPendingVertical.d.ts.map +1 -1
  119. package/dist/widget/components/WaasFeeOptions.d.ts.map +1 -1
  120. package/dist/widget/components/WalletConnect.d.ts.map +1 -1
  121. package/dist/widget/components/WalletImage.d.ts.map +1 -1
  122. package/dist/widget/components/WalletList.d.ts.map +1 -1
  123. package/dist/widget/components/Withdraw.d.ts.map +1 -1
  124. package/dist/widget/css/compiled.css +1 -1
  125. package/dist/widget/hooks/useAddressWalletIcon.d.ts.map +1 -1
  126. package/dist/widget/hooks/useCombinedHistory.d.ts +6 -5
  127. package/dist/widget/hooks/useCombinedHistory.d.ts.map +1 -1
  128. package/dist/widget/hooks/useCustomTokenSearch.d.ts +6 -1
  129. package/dist/widget/hooks/useCustomTokenSearch.d.ts.map +1 -1
  130. package/dist/widget/hooks/useDefaultDestinationToken.d.ts.map +1 -1
  131. package/dist/widget/hooks/useDefaultOriginToken.d.ts.map +1 -1
  132. package/dist/widget/hooks/useFiatOnRampCurrencies.d.ts +1 -1
  133. package/dist/widget/hooks/useFiatOnRampCurrencies.d.ts.map +1 -1
  134. package/dist/widget/hooks/useGetIntent.d.ts +3 -2
  135. package/dist/widget/hooks/useGetIntent.d.ts.map +1 -1
  136. package/dist/widget/hooks/useIntentReceiptBalances.d.ts +1 -1
  137. package/dist/widget/hooks/useIntentReceiptBalances.d.ts.map +1 -1
  138. package/dist/widget/hooks/useIntentTransactionHistory.d.ts +3 -2
  139. package/dist/widget/hooks/useIntentTransactionHistory.d.ts.map +1 -1
  140. package/dist/widget/hooks/useMeldTransactionHistory.d.ts +1 -1
  141. package/dist/widget/hooks/useMeldTransactionHistory.d.ts.map +1 -1
  142. package/dist/widget/hooks/useMeldTransactionStatus.d.ts +1 -1
  143. package/dist/widget/hooks/useMeldTransactionStatus.d.ts.map +1 -1
  144. package/dist/widget/hooks/useOnRampQuote.d.ts +1 -1
  145. package/dist/widget/hooks/useOnRampQuote.d.ts.map +1 -1
  146. package/dist/widget/hooks/useOnRampTransactionStatus.d.ts +1 -1
  147. package/dist/widget/hooks/useOnRampTransactionStatus.d.ts.map +1 -1
  148. package/dist/widget/hooks/useQuote.d.ts +2 -2
  149. package/dist/widget/hooks/useQuote.d.ts.map +1 -1
  150. package/dist/widget/hooks/useSelectedFundMethod.d.ts +7 -0
  151. package/dist/widget/hooks/useSelectedFundMethod.d.ts.map +1 -1
  152. package/dist/widget/hooks/useSendForm.d.ts +0 -1
  153. package/dist/widget/hooks/useSendForm.d.ts.map +1 -1
  154. package/dist/widget/hooks/useTokenList.d.ts +7 -1
  155. package/dist/widget/hooks/useTokenList.d.ts.map +1 -1
  156. package/dist/widget/hooks/useViewManager.d.ts +1 -1
  157. package/dist/widget/hooks/useViewManager.d.ts.map +1 -1
  158. package/dist/widget/index.js +1 -1
  159. package/dist/widget/providers/TrailsProvider.d.ts +2 -0
  160. package/dist/widget/providers/TrailsProvider.d.ts.map +1 -1
  161. package/dist/widget/utils/createWagmiConfig.d.ts +2 -2
  162. package/dist/widget/utils/createWagmiConfig.d.ts.map +1 -1
  163. package/dist/widget/utils/fundMethodSwitchState.d.ts +1 -0
  164. package/dist/widget/utils/fundMethodSwitchState.d.ts.map +1 -1
  165. package/dist/widget/utils/historyFilters.d.ts +13 -0
  166. package/dist/widget/utils/historyFilters.d.ts.map +1 -0
  167. package/dist/widget/utils/meldProviderUtils.d.ts +1 -1
  168. package/dist/widget/utils/meldProviderUtils.d.ts.map +1 -1
  169. package/dist/widget/utils/meshSupportedTokens.d.ts +4 -0
  170. package/dist/widget/utils/meshSupportedTokens.d.ts.map +1 -0
  171. package/dist/widget/utils/onrampConfig.d.ts +11 -0
  172. package/dist/widget/utils/onrampConfig.d.ts.map +1 -0
  173. package/dist/widget/utils/statusLabel.d.ts +2 -0
  174. package/dist/widget/utils/statusLabel.d.ts.map +1 -0
  175. package/dist/widget/utils/trailsOnrampConfig.d.ts +18 -0
  176. package/dist/widget/utils/trailsOnrampConfig.d.ts.map +1 -0
  177. package/dist/widget/widget.d.ts +24 -8
  178. package/dist/widget/widget.d.ts.map +1 -1
  179. package/package.json +9 -7
  180. package/src/chains.ts +26 -9
  181. package/src/constants.ts +2 -0
  182. package/src/customTokens.ts +22 -7
  183. package/src/error.ts +7 -0
  184. package/src/gasless.ts +5 -2
  185. package/src/index.ts +8 -5
  186. package/src/intents.ts +56 -60
  187. package/src/keyMachineClient.ts +29 -0
  188. package/src/keymachine/index.ts +175 -0
  189. package/src/keymachine/key-machine.gen.ts +993 -0
  190. package/src/onramp/MeshConnectFlow.tsx +86 -0
  191. package/src/onramp/MeshConnectIframe.tsx +661 -0
  192. package/src/onramp/SendFromExchangeButton.tsx +81 -0
  193. package/src/onramp/TrailsOnRampProvider.tsx +59 -0
  194. package/src/onramp/index.ts +31 -0
  195. package/src/onramp/meshconnect.ts +277 -0
  196. package/src/onramp/trailsOnramp.tsx +130 -0
  197. package/src/onramp-client/index.ts +4 -6
  198. package/src/paymasterSend.ts +0 -5
  199. package/src/prepareSend.ts +45 -44
  200. package/src/query/balance.fetchers.ts +172 -17
  201. package/src/query/balance.hooks.ts +69 -6
  202. package/src/query/balance.queries.ts +63 -0
  203. package/src/query/chains.queries.ts +1 -6
  204. package/src/query/meld.fetchers.ts +1 -1
  205. package/src/query/meld.hooks.ts +1 -1
  206. package/src/query/meld.queries.ts +1 -1
  207. package/src/query/price.fetchers.ts +53 -0
  208. package/src/query/price.hooks.ts +46 -0
  209. package/src/query/price.queries.ts +364 -0
  210. package/src/query/tokenList.queries.ts +118 -0
  211. package/src/recover.ts +89 -26
  212. package/src/tokens.ts +108 -26
  213. package/src/transactionIntent/deposits/depositOrchestrator.ts +11 -11
  214. package/src/transactionIntent/deposits/gaslessDeposit.ts +38 -39
  215. package/src/transactionIntent/deposits/standardDeposit.ts +5 -30
  216. package/src/transactionIntent/handlers/intentHandler.ts +29 -12
  217. package/src/transactionIntent/helpers/transactionStateHelpers.ts +5 -2
  218. package/src/transactionIntent/quote/normalizeQuote.ts +11 -5
  219. package/src/transactionIntent/types.ts +1 -1
  220. package/src/transactions.ts +5 -1
  221. package/src/utils/format.ts +85 -1
  222. package/src/walletUtils.ts +2 -1
  223. package/src/wallets.ts +184 -380
  224. package/src/widget/compiled.css +1 -1
  225. package/src/widget/components/AccountIntentTransactionHistory.tsx +134 -109
  226. package/src/widget/components/ClassicSwap.tsx +26 -24
  227. package/src/widget/components/ConnectWallet.tsx +4 -2
  228. package/src/widget/components/ConnectedWallets.tsx +2 -5
  229. package/src/widget/components/DirectTransfer.tsx +5 -2
  230. package/src/widget/components/EarnPools.tsx +1 -2
  231. package/src/widget/components/ExecutionStatusBadge.tsx +10 -4
  232. package/src/widget/components/Fund.tsx +169 -110
  233. package/src/widget/components/FundMethods.tsx +5 -9
  234. package/src/widget/components/HighPriceImpactBlock.tsx +44 -0
  235. package/src/widget/components/MeldHistory.tsx +4 -28
  236. package/src/widget/components/MeshExchangeSelection.tsx +218 -0
  237. package/src/widget/components/OnrampHistoryRow.tsx +3 -27
  238. package/src/widget/components/OnrampProviderConfirmation.tsx +0 -25
  239. package/src/widget/components/Pay.tsx +20 -36
  240. package/src/widget/components/PoolDeposit.tsx +14 -24
  241. package/src/widget/components/PoolWithdraw.tsx +1 -63
  242. package/src/widget/components/QRCodeWalletSelect.tsx +5 -2
  243. package/src/widget/components/QuoteDetails.tsx +113 -106
  244. package/src/widget/components/Receipt.tsx +0 -11
  245. package/src/widget/components/Recipients.tsx +2 -1
  246. package/src/widget/components/RefundWarning.tsx +5 -10
  247. package/src/widget/components/ThemeProvider.tsx +4 -4
  248. package/src/widget/components/TokenSelector.tsx +85 -16
  249. package/src/widget/components/TransactionDetails.tsx +46 -0
  250. package/src/widget/components/TransactionHistoryItem.tsx +14 -23
  251. package/src/widget/components/TransferPendingVertical.tsx +17 -11
  252. package/src/widget/components/WaasFeeOptions.tsx +4 -42
  253. package/src/widget/components/WalletConnect.tsx +2 -5
  254. package/src/widget/components/WalletImage.tsx +6 -18
  255. package/src/widget/components/WalletList.tsx +1 -1
  256. package/src/widget/components/Withdraw.tsx +22 -23
  257. package/src/widget/hooks/useAddressWalletIcon.ts +2 -1
  258. package/src/widget/hooks/useAmountUsd.ts +1 -1
  259. package/src/widget/hooks/useCombinedHistory.ts +37 -93
  260. package/src/widget/hooks/useCustomTokenSearch.tsx +63 -33
  261. package/src/widget/hooks/useDefaultDestinationToken.tsx +2 -5
  262. package/src/widget/hooks/useDefaultOriginToken.tsx +2 -5
  263. package/src/widget/hooks/useFiatOnRampCurrencies.ts +1 -1
  264. package/src/widget/hooks/useGetIntent.ts +5 -4
  265. package/src/widget/hooks/useIntentReceiptBalances.ts +3 -3
  266. package/src/widget/hooks/useIntentTransactionHistory.ts +24 -47
  267. package/src/widget/hooks/useMeldTransactionHistory.ts +4 -2
  268. package/src/widget/hooks/useMeldTransactionStatus.ts +13 -11
  269. package/src/widget/hooks/useOnRampQuote.ts +3 -3
  270. package/src/widget/hooks/useOnRampTransactionStatus.ts +8 -6
  271. package/src/widget/hooks/useQuote.ts +56 -48
  272. package/src/widget/hooks/useSelectedFundMethod.tsx +14 -1
  273. package/src/widget/hooks/useSendForm.ts +52 -31
  274. package/src/widget/hooks/useTokenList.ts +209 -140
  275. package/src/widget/hooks/useTrailsSendTransaction.ts +1 -1
  276. package/src/widget/hooks/useViewManager.tsx +1 -0
  277. package/src/widget/providers/TrailsProvider.tsx +5 -0
  278. package/src/widget/styles.ts +1 -1
  279. package/src/widget/utils/createWagmiConfig.ts +7 -2
  280. package/src/widget/utils/fundMethodSwitchState.ts +2 -0
  281. package/src/widget/utils/historyFilters.ts +157 -0
  282. package/src/widget/utils/meldProviderUtils.ts +8 -2
  283. package/src/widget/utils/meshSupportedTokens.ts +28 -0
  284. package/src/widget/utils/onrampConfig.ts +15 -0
  285. package/src/widget/utils/statusLabel.ts +3 -0
  286. package/src/widget/utils/trailsOnrampConfig.ts +39 -0
  287. package/src/widget/widget.tsx +235 -185
  288. package/dist/onramp-client/trails-onramp.gen.d.ts +0 -570
  289. package/dist/onramp-client/trails-onramp.gen.d.ts.map +0 -1
  290. package/dist/prices.d.ts +0 -34
  291. package/dist/prices.d.ts.map +0 -1
  292. package/dist/useGasEstimation.d.ts +0 -34
  293. package/dist/useGasEstimation.d.ts.map +0 -1
  294. package/dist/widget/hooks/useCustomTokenFetch.d.ts +0 -19
  295. package/dist/widget/hooks/useCustomTokenFetch.d.ts.map +0 -1
  296. package/dist/widget/hooks/useTokenWithFreshBalance.d.ts +0 -18
  297. package/dist/widget/hooks/useTokenWithFreshBalance.d.ts.map +0 -1
  298. package/src/onramp-client/trails-onramp.gen.ts +0 -1320
  299. package/src/prices.ts +0 -528
  300. package/src/useGasEstimation.ts +0 -147
  301. package/src/widget/assets/Binance_Icon_Logo.svg +0 -14
  302. package/src/widget/assets/Bitfinex_Icon_Logo.svg +0 -5
  303. package/src/widget/assets/Coinbase_Icon_Logo.svg +0 -1
  304. package/src/widget/assets/WalletConnect-logo-blue-bg.svg +0 -11
  305. package/src/widget/assets/sequence-logo.svg +0 -15
  306. package/src/widget/hooks/useCustomTokenFetch.tsx +0 -74
  307. package/src/widget/hooks/useTokenWithFreshBalance.ts +0 -246
@@ -6,6 +6,7 @@ import React, {
6
6
  useCallback,
7
7
  useEffect,
8
8
  useImperativeHandle,
9
+ useMemo,
9
10
  useRef,
10
11
  useState,
11
12
  } from "react"
@@ -17,6 +18,7 @@ import {
17
18
  } from "./providers/WidgetProviderTree.js"
18
19
  import { createWagmiConfig } from "./utils/createWagmiConfig.js"
19
20
  import { ShadowPortal } from "./components/ShadowPortal.js"
21
+ import { QuoteDetails } from "./components/QuoteDetails.js"
20
22
  import type { Chain, WalletClient, EIP1193Provider } from "viem"
21
23
  import {
22
24
  createWalletClient,
@@ -84,14 +86,18 @@ import type { Theme } from "../theme.js"
84
86
  import type { Token } from "../tokens.js"
85
87
  import { getWethAddress } from "../tokens.js"
86
88
  import type { IntentTransaction } from "@0xtrails/api"
89
+ import {
90
+ getQRCodeWallets,
91
+ getWalletIdFromRdns,
92
+ wagmiConnectorToWalletId,
93
+ } from "@0xtrails/wallet-registry"
87
94
  import type { TransactionState } from "../transactions.js"
95
+ import { useOnrampClient } from "../onrampClient.js"
88
96
  import {
89
- useQRCodeWallets,
90
97
  useWallets,
91
98
  getWalletConnectConnector,
92
99
  getConnectorsInternal,
93
- wagmiConnectorToWalletId,
94
- WALLET_RDNS_MAP,
100
+ type WalletConnector,
95
101
  } from "../wallets.js"
96
102
  // import { useOpenConnectModal } from "@0xsequence/connect"
97
103
  import {
@@ -112,6 +118,7 @@ import Footer from "./components/Footer.js"
112
118
  import { Fund } from "./components/Fund.js"
113
119
  import { Withdraw } from "./components/Withdraw.js"
114
120
  import FundMethods from "./components/FundMethods.js"
121
+ import { MeshExchangeSelection } from "./components/MeshExchangeSelection.js"
115
122
  import OnrampPaymentMethods from "./components/OnrampPaymentMethods.js"
116
123
  import Modal from "./components/Modal.js"
117
124
  import { Pay } from "./components/Pay.js"
@@ -136,6 +143,9 @@ import { WalletList } from "./components/WalletList.js"
136
143
  import { useCheckout } from "./hooks/useCheckout.js"
137
144
  import { useDebugScreens } from "./hooks/useDebugScreens.js"
138
145
  import { useExternalFundingReceiptSync } from "./hooks/useExternalFundingReceiptSync.js"
146
+ import { getWidgetOnrampConfig } from "./utils/trailsOnrampConfig.js"
147
+ import type { TrailsOnRampConfig } from "../onramp/TrailsOnRampProvider.js"
148
+ import { trailsOnramp, type OnrampFactory } from "../onramp/trailsOnramp.js"
139
149
  import { useScreenTracking } from "./hooks/useScreenTracking.js"
140
150
  import { useEarnPool } from "./hooks/useEarnPool.js"
141
151
 
@@ -177,7 +187,7 @@ import {
177
187
  } from "../utils/address.js"
178
188
  import { isWalletConnectConnector } from "../walletUtils.js"
179
189
  import type { SendOptions, SwapReturn } from "./hooks/useQuote.js"
180
- import { hasFailedOrAbortedTransaction } from "./utils/transactionFailure.js"
190
+ import { hasAnyFailedOrAbortedTransactions } from "./utils/transactionFailure.js"
181
191
  import {
182
192
  shouldClearTransferFlowOnNavigate,
183
193
  shouldRedirectToConnect,
@@ -202,6 +212,7 @@ export type FundMethodListOption =
202
212
  | "connected-wallet"
203
213
  | "crypto-transfer"
204
214
  | "cc-onramp"
215
+ | "exchange"
205
216
  | "exchange-onramp"
206
217
 
207
218
  export const WidgetFundMethod = {
@@ -219,6 +230,7 @@ export type TrailsWidgetProps = {
219
230
  trailsApiUrl?: string
220
231
  trailsAppUrl?: string
221
232
  sequenceNodeGatewayUrl?: string
233
+ sequenceMetadataUrl?: string
222
234
  sequenceApiUrl?: string
223
235
  toAddress?: string | null
224
236
  toAmount?: string | null
@@ -322,7 +334,10 @@ export type TrailsWidgetProps = {
322
334
  * - "connected-wallet"
323
335
  * - "crypto-transfer"
324
336
  * - "cc-onramp"
325
- * - "exchange-onramp"
337
+ * - "exchange"
338
+ *
339
+ * Preferred values: "connected-wallet", "crypto-transfer", "exchange", "cc-onramp".
340
+ * Legacy alias "exchange-onramp" is still accepted.
326
341
  *
327
342
  * @example ["connected-wallet", "crypto-transfer"]
328
343
  */
@@ -348,27 +363,40 @@ export type TrailsWidgetProps = {
348
363
  payMessage?: string
349
364
  isSmartWallet?: boolean
350
365
  /**
351
- * Optional onramp factory function (e.g., trailsOnramp from @0xtrails/onramp)
352
- * If provided, enables exchange funding options in the widget
366
+ * Optional onramp configuration or factory.
367
+ * If provided, enables exchange funding options in the widget.
353
368
  *
354
369
  * @example
355
370
  * ```tsx
356
- * import { trailsOnramp } from "@0xtrails/onramp"
357
- * <TrailsWidget onramp={trailsOnramp({ config: { exchanges: ['coinbase'] } })} />
371
+ * <TrailsWidget
372
+ * onramp={{
373
+ * mesh: {
374
+ * environment: "production",
375
+ * },
376
+ * }}
377
+ * />
358
378
  * ```
359
379
  */
360
- onramp?: (handlers: {
361
- setCurrentScreen: (screen: Screen) => void
362
- onComplete?: (transferData: OnrampTransferResult) => void
363
- onError?: (error: unknown) => void
364
- onBack?: () => void
365
- toTokenSymbol?: string
366
- toTokenAmount?: string
367
- toChainId?: number
368
- toRecipientAddress?: string
369
- toAmountUsd?: number
370
- apiKey?: string
371
- }) => React.ReactElement
380
+ onramp?:
381
+ | TrailsOnRampConfig
382
+ | ((handlers: {
383
+ setCurrentScreen: (screen: Screen) => void
384
+ onComplete?: (transferData: OnrampTransferResult) => void
385
+ onError?: (error: unknown) => void
386
+ onBack?: () => void
387
+ toTokenSymbol?: string
388
+ toTokenAmount?: string
389
+ toChainId?: number
390
+ toRecipientAddress?: string
391
+ toAmountUsd?: number
392
+ selectedExchange?: {
393
+ integrationId: string
394
+ exchangeKey: string
395
+ exchangeName: string
396
+ }
397
+ apiKey?: string
398
+ hostname?: string
399
+ }) => React.ReactElement)
372
400
  }
373
401
 
374
402
  export interface TrailsWidgetRef {
@@ -509,28 +537,15 @@ const useTransactionState = (
509
537
  const [destinationConfirmationCalled, setDestinationConfirmationCalled] =
510
538
  useState(false)
511
539
 
512
- // Use refs to store the latest callback functions to avoid dependency issues
513
- const onOriginConfirmationRef = useRef(onOriginConfirmation)
514
- const onDestinationConfirmationRef = useRef(onDestinationConfirmation)
515
-
516
- // Update refs when callbacks change
517
- useEffect(() => {
518
- onOriginConfirmationRef.current = onOriginConfirmation
519
- }, [onOriginConfirmation])
520
-
521
- useEffect(() => {
522
- onDestinationConfirmationRef.current = onDestinationConfirmation
523
- }, [onDestinationConfirmation])
524
-
525
540
  useEffect(() => {
526
541
  if (
527
- onOriginConfirmationRef.current &&
542
+ onOriginConfirmation &&
528
543
  originTxHash &&
529
544
  originChainId &&
530
545
  !originConfirmationCalled
531
546
  ) {
532
547
  try {
533
- onOriginConfirmationRef.current({
548
+ onOriginConfirmation({
534
549
  txHash: originTxHash,
535
550
  chainId: originChainId,
536
551
  sessionId: getSessionId(),
@@ -543,17 +558,22 @@ const useTransactionState = (
543
558
  }
544
559
  setOriginConfirmationCalled(true)
545
560
  }
546
- }, [originTxHash, originChainId, originConfirmationCalled])
561
+ }, [
562
+ originTxHash,
563
+ originChainId,
564
+ originConfirmationCalled,
565
+ onOriginConfirmation,
566
+ ])
547
567
 
548
568
  useEffect(() => {
549
569
  if (
550
- onDestinationConfirmationRef.current &&
570
+ onDestinationConfirmation &&
551
571
  destinationTxHash &&
552
572
  destinationChainId &&
553
573
  !destinationConfirmationCalled
554
574
  ) {
555
575
  try {
556
- onDestinationConfirmationRef.current({
576
+ onDestinationConfirmation({
557
577
  txHash: destinationTxHash,
558
578
  chainId: destinationChainId,
559
579
  sessionId: getSessionId(),
@@ -566,7 +586,12 @@ const useTransactionState = (
566
586
  }
567
587
  setDestinationConfirmationCalled(true)
568
588
  }
569
- }, [destinationTxHash, destinationChainId, destinationConfirmationCalled])
589
+ }, [
590
+ destinationTxHash,
591
+ destinationChainId,
592
+ destinationConfirmationCalled,
593
+ onDestinationConfirmation,
594
+ ])
570
595
 
571
596
  // Monitor transaction states for completion - this runs regardless of which screen is active
572
597
  useEffect(() => {
@@ -660,8 +685,9 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
660
685
  } = useWidgetProps()
661
686
  const { address, chainId, connector } = useAccount()
662
687
  const connectors = useConnectors()
663
- const { trailsApiKey } = useTrails()
664
- const qrCodeWallets = useQRCodeWallets()
688
+ const { trailsApiKey, trailsApiUrl } = useTrails()
689
+ const onrampClient = useOnrampClient()
690
+ const qrCodeWallets = useMemo(() => getQRCodeWallets(), [])
665
691
  // const { setOpenConnectModal } = useOpenConnectModal()
666
692
 
667
693
  // Check if the current connector is a Sequence wallet
@@ -676,7 +702,15 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
676
702
  const { wallets: allWallets } = useWallets()
677
703
  const { selectedToken, setSelectedToken, clearSelectedToken } =
678
704
  useSelectedToken()
679
- const { onramp: onrampFactory } = useWidgetProps()
705
+ const { onramp } = useWidgetProps()
706
+ const meshOnrampConfig = getWidgetOnrampConfig(onramp)
707
+ const onrampFactory: OnrampFactory | undefined =
708
+ typeof onramp === "function"
709
+ ? (onramp as OnrampFactory)
710
+ : meshOnrampConfig
711
+ ? trailsOnramp({ config: meshOnrampConfig })
712
+ : undefined
713
+ const meshEnvironment = meshOnrampConfig?.mesh?.environment ?? "production"
680
714
 
681
715
  // Modal state is managed by TrailsModalProvider
682
716
  const {
@@ -813,7 +847,12 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
813
847
  const [previousAddress, setPreviousAddress] = useState<string | undefined>(
814
848
  address,
815
849
  )
816
- const { selectedFundMethod, setSelectedFundMethod } = useSelectedFundMethod()
850
+ const {
851
+ selectedFundMethod,
852
+ selectedMeshExchange,
853
+ setSelectedFundMethod,
854
+ setSelectedMeshExchange,
855
+ } = useSelectedFundMethod()
817
856
  const fundMethodSelectionStartRef = useRef(selectedFundMethod)
818
857
  const clearStateForFundMethodSwitch = useCallback(
819
858
  (nextMethod: typeof selectedFundMethod) => {
@@ -826,6 +865,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
826
865
  setSellAmount,
827
866
  setBuyAmount,
828
867
  setPrepareSendQuote,
868
+ setSelectedMeshExchange,
829
869
  },
830
870
  )
831
871
 
@@ -833,7 +873,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
833
873
  fundMethodSelectionStartRef.current = nextMethod
834
874
  }
835
875
  },
836
- [clearSelectedToken, setSellAmount, setBuyAmount],
876
+ [clearSelectedToken, setSellAmount, setBuyAmount, setSelectedMeshExchange],
837
877
  )
838
878
  const { selectedPool, setSelectedPool } = useEarnPool()
839
879
  const [selectedWalletId, setSelectedWalletId] = useState<string | null>(
@@ -1002,8 +1042,8 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
1002
1042
 
1003
1043
  const defaultButtonText = modeToButtonText[currentMode] ?? "Pay"
1004
1044
 
1005
- // Validate widget props
1006
- useEffect(() => {
1045
+ // Validate widget props from current props/mode only.
1046
+ const propValidationError = useMemo(() => {
1007
1047
  const isValidToAmount = isValidNumeric(toAmount)
1008
1048
  const isValidToChainId = isValidInteger(toChainId)
1009
1049
  const isValidToToken = isValidToToToken(toToken)
@@ -1031,8 +1071,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
1031
1071
  isValidToAddress &&
1032
1072
  isValidPaymasterUrls
1033
1073
  ) {
1034
- setError(null)
1035
- return
1074
+ return null
1036
1075
  }
1037
1076
 
1038
1077
  // Validate toAmount - must be numeric if provided
@@ -1041,8 +1080,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
1041
1080
  "[trails-sdk] Invalid toAmount prop: must be numeric. Received:",
1042
1081
  toAmount,
1043
1082
  )
1044
- setError("Invalid toAmount: must be a numeric value")
1045
- return
1083
+ return "Invalid toAmount: must be a numeric value"
1046
1084
  }
1047
1085
 
1048
1086
  // Validate toChainId - must be numeric if provided
@@ -1051,8 +1089,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
1051
1089
  "[trails-sdk] Invalid toChainId prop: must be numeric. Received:",
1052
1090
  toChainId,
1053
1091
  )
1054
- setError("Invalid toChainId: must be a numeric value")
1055
- return
1092
+ return "Invalid toChainId: must be a numeric value"
1056
1093
  }
1057
1094
 
1058
1095
  // Validate toToken - must be "ETH", "USDC", or a valid hex address
@@ -1061,10 +1098,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
1061
1098
  "[trails-sdk] Invalid toToken prop: must be a valid token symbol or a valid hex address. Received:",
1062
1099
  toToken,
1063
1100
  )
1064
- setError(
1065
- "Invalid toToken: must be a valid token symbol or a valid hex address",
1066
- )
1067
- return
1101
+ return "Invalid toToken: must be a valid token symbol or a valid hex address"
1068
1102
  }
1069
1103
 
1070
1104
  if (!isValidToAddress) {
@@ -1072,8 +1106,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
1072
1106
  "[trails-sdk] Invalid toAddress prop: must be a valid hex address. Received:",
1073
1107
  toAddress,
1074
1108
  )
1075
- setError("Invalid toAddress: must be a valid hex address")
1076
- return
1109
+ return "Invalid toAddress: must be a valid hex address"
1077
1110
  }
1078
1111
 
1079
1112
  // Validate paymasterUrls
@@ -1082,29 +1115,28 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
1082
1115
  "[trails-sdk] Invalid paymasterUrls prop: url must be a valid URL. Received:",
1083
1116
  invalidPaymasterUrl,
1084
1117
  )
1085
- setError("Invalid paymasterUrls: url must be a valid URL")
1086
- return
1118
+ return "Invalid paymasterUrls: url must be a valid URL"
1087
1119
  }
1088
1120
 
1089
1121
  if (currentMode === "fund") {
1090
1122
  if (toAmount) {
1091
- setError("toAmount is not allowed in fund mode")
1092
- return
1123
+ return "toAmount is not allowed in fund mode"
1093
1124
  }
1094
1125
  if (!toToken) {
1095
- setError("toToken is required in fund mode")
1096
- return
1126
+ return "toToken is required in fund mode"
1097
1127
  }
1098
1128
  }
1099
1129
 
1100
1130
  if (currentMode === "pay") {
1101
1131
  if (!toToken) {
1102
- setError("toToken is required in pay mode")
1103
- return
1132
+ return "toToken is required in pay mode"
1104
1133
  }
1105
1134
  }
1135
+ return null
1106
1136
  }, [toAmount, toChainId, toToken, currentMode, toAddress, paymasterUrls])
1107
1137
 
1138
+ const displayError = propValidationError || error
1139
+
1108
1140
  const walletClient = useWalletManager(address, chainId, connector)
1109
1141
 
1110
1142
  // Function to save wallet ID to localStorage
@@ -1242,12 +1274,28 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
1242
1274
  handleTransferComplete,
1243
1275
  )
1244
1276
 
1245
- // Auto-navigate from pending receipt when first transaction is aborted or failed
1246
- const firstTx = transactionStates?.[0]
1247
- useScreenGuard(
1248
- screen === "pending" && !!firstTx && hasFailedOrAbortedTransaction(firstTx),
1249
- "receipt",
1277
+ const effectivePrepareSendQuote = hostTransactionQuote ?? prepareSendQuote
1278
+ const effectiveTransactionStates =
1279
+ hostTransactionStates.length > 0 ? hostTransactionStates : transactionStates
1280
+ const hostCompletionSeconds = useMemo(() => {
1281
+ if (
1282
+ hostTransactionState.status !== "success" ||
1283
+ !hostTransactionTimestamp
1284
+ ) {
1285
+ return null
1286
+ }
1287
+
1288
+ return Math.max(0, toSeconds(elapsed(hostTransactionTimestamp)))
1289
+ }, [hostTransactionState.status, hostTransactionTimestamp])
1290
+ const displayTotalCompletionSeconds =
1291
+ hostCompletionSeconds ?? totalCompletionSeconds
1292
+
1293
+ // Auto-navigate from pending → receipt when any transaction is aborted or failed.
1294
+ // This prevents the tracker from staying on pending when non-first steps fail.
1295
+ const hasFailedTransactionState = hasAnyFailedOrAbortedTransactions(
1296
+ effectiveTransactionStates,
1250
1297
  )
1298
+ useScreenGuard(screen === "pending" && hasFailedTransactionState, "receipt")
1251
1299
 
1252
1300
  const { checkoutOnHandlers } = useCheckout({
1253
1301
  onCheckoutStart,
@@ -1267,12 +1315,12 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
1267
1315
  useExternalFundingReceiptSync({
1268
1316
  enabled:
1269
1317
  isExternalFundingMethod(selectedFundMethod) &&
1270
- !!prepareSendQuote?.intentId &&
1318
+ !!effectivePrepareSendQuote?.intentId &&
1271
1319
  (screen === "direct-transfer-screen" ||
1272
1320
  screen === "onramp-confirmation" ||
1273
1321
  screen === "pending"),
1274
- intentId: prepareSendQuote?.intentId ?? undefined,
1275
- fallbackTransactionStates: prepareSendQuote?.transactionStates,
1322
+ intentId: effectivePrepareSendQuote?.intentId ?? undefined,
1323
+ fallbackTransactionStates: effectivePrepareSendQuote?.transactionStates,
1276
1324
  setTransactionStates,
1277
1325
  onStatusUpdate: checkoutOnHandlers?.triggerCheckoutStatusUpdate,
1278
1326
  onFundingObserved: () => {
@@ -1352,28 +1400,6 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
1352
1400
  navigate,
1353
1401
  ])
1354
1402
 
1355
- useEffect(() => {
1356
- if (!hostTransactionQuote) {
1357
- return
1358
- }
1359
- setPrepareSendQuote(hostTransactionQuote)
1360
- }, [hostTransactionQuote])
1361
-
1362
- useEffect(() => {
1363
- if (hostTransactionStates.length === 0) {
1364
- return
1365
- }
1366
- setTransactionStates(hostTransactionStates)
1367
- }, [hostTransactionStates, setTransactionStates])
1368
-
1369
- useEffect(() => {
1370
- if (hostTransactionState.status === "success" && hostTransactionTimestamp) {
1371
- setTotalCompletionSeconds(
1372
- Math.max(0, toSeconds(elapsed(hostTransactionTimestamp))),
1373
- )
1374
- }
1375
- }, [hostTransactionState.status, hostTransactionTimestamp])
1376
-
1377
1403
  // Handle account changes - navigate back to token list for specific screens
1378
1404
  useEffect(() => {
1379
1405
  if (previousAddress && address && previousAddress !== address) {
@@ -1442,7 +1468,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
1442
1468
 
1443
1469
  const handleConnectWallet = async (
1444
1470
  walletId: string,
1445
- providedConnector?: Connector,
1471
+ providedConnector?: WalletConnector,
1446
1472
  ) => {
1447
1473
  try {
1448
1474
  setError(null)
@@ -1457,7 +1483,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
1457
1483
  const eip6963Connector = connectors.find((c) => {
1458
1484
  if (c.type !== "injected") return false
1459
1485
  const rdns = (c as EIP6963Connector).info?.rdns
1460
- if (rdns && WALLET_RDNS_MAP[rdns] === walletId) {
1486
+ if (getWalletIdFromRdns(rdns) === walletId) {
1461
1487
  logger.console.log(
1462
1488
  `[trails-sdk] Found EIP-6963 connector for ${walletId} with rdns ${rdns}`,
1463
1489
  )
@@ -2043,7 +2069,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
2043
2069
  )
2044
2070
  logger.console.log("[trails-sdk] handleOnrampComplete state:", {
2045
2071
  hasOnrampContinueSend: !!onrampContinueSend,
2046
- hasPrepareSendQuote: !!prepareSendQuote,
2072
+ hasPrepareSendQuote: !!effectivePrepareSendQuote,
2047
2073
  screen,
2048
2074
  onrampContinueSendInProgress,
2049
2075
  })
@@ -2092,11 +2118,11 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
2092
2118
  logger.console.log(
2093
2119
  "[trails-sdk] No onrampContinueSend callback, showing pending screen",
2094
2120
  )
2095
- if (prepareSendQuote) {
2121
+ if (effectivePrepareSendQuote) {
2096
2122
  logger.console.log(
2097
2123
  "[trails-sdk] Setting transaction states from prepareSendQuote",
2098
2124
  )
2099
- setTransactionStates(prepareSendQuote.transactionStates)
2125
+ setTransactionStates(effectivePrepareSendQuote.transactionStates)
2100
2126
  }
2101
2127
  }
2102
2128
  }
@@ -2229,59 +2255,6 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
2229
2255
  }
2230
2256
  }
2231
2257
 
2232
- const _handleNavigateToOnramp = (
2233
- props: {
2234
- toTokenSymbol: string
2235
- toTokenAmount: string
2236
- toChainId: number
2237
- toRecipientAddress: string
2238
- toAmountUsd?: number
2239
- },
2240
- onRampMethod?: string,
2241
- quote?: PrepareSendQuote | null,
2242
- continueSend?: () => Promise<void>,
2243
- ) => {
2244
- setPrepareSendQuote(quote ?? null)
2245
- setOnrampProps(props)
2246
- setOnrampContinueSend(() => continueSend || null)
2247
-
2248
- // Render onramp component directly - it manages its own routing
2249
- const targetScreen =
2250
- onRampMethod && onRampMethod === "onramp-meld"
2251
- ? "onramp-meld"
2252
- : "onramp-mesh"
2253
- navigate(targetScreen)
2254
-
2255
- if (
2256
- targetScreen === "onramp-meld" &&
2257
- continueSend &&
2258
- !onrampContinueSendInProgress
2259
- ) {
2260
- logger.console.log(
2261
- "[trails-sdk] Starting intent execution after navigating to onramp-meld screen",
2262
- )
2263
- setOnrampContinueSendInProgress(true)
2264
- // Call asynchronously to avoid blocking navigation
2265
- Promise.resolve()
2266
- .then(() => continueSend())
2267
- .then(() => {
2268
- logger.console.log(
2269
- "[trails-sdk] onrampContinueSend completed successfully",
2270
- )
2271
- })
2272
- .catch((error) => {
2273
- logger.console.error(
2274
- "[trails-sdk] Error executing intent after onramp deposit:",
2275
- error,
2276
- )
2277
- handleSendError(error as Error)
2278
- })
2279
- .finally(() => {
2280
- setOnrampContinueSendInProgress(false)
2281
- })
2282
- }
2283
- }
2284
-
2285
2258
  const handleSendError = (error: Error | string | null) => {
2286
2259
  if (error) {
2287
2260
  logger.console.error("[trails-sdk] Error sending transaction", error)
@@ -2345,6 +2318,11 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
2345
2318
  })()
2346
2319
  return
2347
2320
  }
2321
+
2322
+ if (selectedFundMethod === "onramp-mesh") {
2323
+ return
2324
+ }
2325
+
2348
2326
  navigate("wallet-confirmation")
2349
2327
  }
2350
2328
 
@@ -2511,15 +2489,69 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
2511
2489
  }
2512
2490
  }}
2513
2491
  onSelectOnrampExchange={() => {
2492
+ clearSelectedToken()
2493
+ setSellAmount("")
2494
+ setBuyAmount("")
2495
+ setPrepareSendQuote(null)
2496
+ setSelectedMeshExchange(null)
2514
2497
  clearStateForFundMethodSwitch("onramp-mesh")
2515
2498
  if (currentMode === "fund") {
2516
- navigate("fund-form")
2499
+ navigate("mesh-exchanges")
2517
2500
  } else {
2518
2501
  goHome()
2519
2502
  }
2520
2503
  }}
2521
2504
  />
2522
2505
  )
2506
+ case "mesh-exchanges":
2507
+ return (
2508
+ <MeshExchangeSelection
2509
+ onBack={() => navigate("fund-methods")}
2510
+ onSelectExchange={async (exchange) => {
2511
+ if (
2512
+ selectedToken &&
2513
+ selectedToken.chainId !== undefined &&
2514
+ trailsApiKey &&
2515
+ trailsApiUrl
2516
+ ) {
2517
+ try {
2518
+ const response = await onrampClient.getMeshSupportedTokens({
2519
+ environment: meshEnvironment,
2520
+ integrationId: exchange.integrationId,
2521
+ chainIds: [selectedToken.chainId.toString()],
2522
+ })
2523
+
2524
+ const isSupported = (response.tokens || []).some(
2525
+ (token) =>
2526
+ Number(token.chainId) === selectedToken.chainId &&
2527
+ token.symbol?.toUpperCase() ===
2528
+ selectedToken.symbol?.toUpperCase(),
2529
+ )
2530
+
2531
+ if (!isSupported) {
2532
+ clearSelectedToken()
2533
+ setSellAmount("")
2534
+ setBuyAmount("")
2535
+ setPrepareSendQuote(null)
2536
+ }
2537
+ } catch (error) {
2538
+ logger.console.warn(
2539
+ "[trails-sdk] Failed to validate Mesh exchange token support, clearing selected token:",
2540
+ error,
2541
+ )
2542
+ clearSelectedToken()
2543
+ setSellAmount("")
2544
+ setBuyAmount("")
2545
+ setPrepareSendQuote(null)
2546
+ }
2547
+ }
2548
+
2549
+ setSelectedFundMethod("onramp-mesh")
2550
+ setSelectedMeshExchange(exchange)
2551
+ navigate("fund-form", { backTarget: "mesh-exchanges" })
2552
+ }}
2553
+ />
2554
+ )
2523
2555
  case "payment-methods":
2524
2556
  return (
2525
2557
  <PaymentMethods
@@ -2713,7 +2745,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
2713
2745
  // Navigate to pending screen when intent is executed
2714
2746
  navigate("pending")
2715
2747
  }}
2716
- quote={prepareSendQuote}
2748
+ quote={effectivePrepareSendQuote}
2717
2749
  onRampQuote={onrampProviderQuote}
2718
2750
  widgetCreationParams={widgetCreationParams}
2719
2751
  onCreateWidgetSession={createWidgetSession}
@@ -2748,7 +2780,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
2748
2780
  onRetry={
2749
2781
  isHookInitiated ? handleHookRetry : handleWalletConfirmRetry
2750
2782
  }
2751
- quote={prepareSendQuote}
2783
+ quote={effectivePrepareSendQuote}
2752
2784
  onRampQuote={onrampProviderQuote}
2753
2785
  />
2754
2786
  )
@@ -2775,7 +2807,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
2775
2807
  }
2776
2808
  }}
2777
2809
  onChangeWallet={() => navigate("qr-code-wallet-select")}
2778
- quote={prepareSendQuote}
2810
+ quote={effectivePrepareSendQuote}
2779
2811
  selectedWalletId={qrCodeWalletId}
2780
2812
  walletOptions={qrCodeWallets}
2781
2813
  onIntentExecuted={() => navigate("pending")}
@@ -2785,9 +2817,10 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
2785
2817
  return (
2786
2818
  <TransferPending
2787
2819
  onElapsedTime={handleElapsedTime}
2788
- transactionStates={transactionStates}
2789
- quote={prepareSendQuote}
2820
+ transactionStates={effectiveTransactionStates}
2821
+ quote={effectivePrepareSendQuote}
2790
2822
  onRampQuote={onrampProviderQuote}
2823
+ fundMethod={selectedFundMethod}
2791
2824
  timestamp={hostTransactionTimestamp ?? undefined}
2792
2825
  onContinue={() => {
2793
2826
  logger.console.log("[trails-sdk] onContinue called")
@@ -2810,9 +2843,9 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
2810
2843
  onSendAnother={receiptOnSendAnother}
2811
2844
  onClose={handleCloseModal}
2812
2845
  renderInline={renderInline}
2813
- transactionStates={transactionStates}
2814
- totalCompletionSeconds={totalCompletionSeconds ?? undefined}
2815
- quote={prepareSendQuote}
2846
+ transactionStates={effectiveTransactionStates}
2847
+ totalCompletionSeconds={displayTotalCompletionSeconds ?? undefined}
2848
+ quote={effectivePrepareSendQuote}
2816
2849
  showCloseButton={false}
2817
2850
  actionButtonText={receiptActionText}
2818
2851
  onRampQuote={onrampProviderQuote}
@@ -2862,22 +2895,39 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
2862
2895
  try {
2863
2896
  return (
2864
2897
  <div className="flex flex-col h-full">
2865
- {onrampFactory({
2866
- setCurrentScreen: (screen) => {
2867
- navigate(screen)
2868
- },
2869
- onComplete: handleOnrampComplete,
2870
- onError: (error) => {
2871
- logger.console.error("[trails-sdk] Onramp error:", error)
2872
- },
2873
- onBack: handleBack,
2874
- toTokenSymbol: onrampProps?.toTokenSymbol,
2875
- toTokenAmount: onrampProps?.toTokenAmount,
2876
- toChainId: onrampProps?.toChainId,
2877
- toRecipientAddress: onrampProps?.toRecipientAddress,
2878
- toAmountUsd: onrampProps?.toAmountUsd,
2879
- apiKey: trailsApiKey,
2880
- })}
2898
+ <div className="flex-1 min-h-0">
2899
+ {onrampFactory({
2900
+ setCurrentScreen: (screen) => {
2901
+ navigate(screen as Screen)
2902
+ },
2903
+ onComplete: (transferData) => {
2904
+ void handleOnrampComplete(
2905
+ transferData as OnrampTransferResult,
2906
+ )
2907
+ },
2908
+ onError: (error) => {
2909
+ logger.console.error("[trails-sdk] Onramp error:", error)
2910
+ },
2911
+ onBack: handleBack,
2912
+ toTokenSymbol: onrampProps?.toTokenSymbol,
2913
+ toTokenAmount: onrampProps?.toTokenAmount,
2914
+ toChainId: onrampProps?.toChainId,
2915
+ toRecipientAddress: onrampProps?.toRecipientAddress,
2916
+ toAmountUsd: onrampProps?.toAmountUsd,
2917
+ selectedExchange: selectedMeshExchange || undefined,
2918
+ apiKey: trailsApiKey,
2919
+ hostname: trailsApiUrl,
2920
+ })}
2921
+ </div>
2922
+ {effectivePrepareSendQuote && (
2923
+ <div className="mt-4">
2924
+ <QuoteDetails
2925
+ quote={effectivePrepareSendQuote}
2926
+ showContent={true}
2927
+ compact={true}
2928
+ />
2929
+ </div>
2930
+ )}
2881
2931
  </div>
2882
2932
  )
2883
2933
  } catch (error) {
@@ -2968,7 +3018,6 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
2968
3018
  id: wallet.id,
2969
3019
  name: wallet.name,
2970
3020
  icon: wallet.icon,
2971
- connector: wallet.connector,
2972
3021
  }))}
2973
3022
  />
2974
3023
  )
@@ -3085,7 +3134,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
3085
3134
  }}
3086
3135
  selectedWalletId={selectedWalletId || ""}
3087
3136
  isConnecting={isConnecting}
3088
- error={error}
3137
+ error={displayError}
3089
3138
  showRetry={showWalletConnectionRetry}
3090
3139
  />
3091
3140
  )
@@ -3163,14 +3212,14 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
3163
3212
  >
3164
3213
  {renderScreenContent()}
3165
3214
  {/* Error Display */}
3166
- {error && (
3215
+ {displayError && (
3167
3216
  <div className="mt-2">
3168
3217
  <ErrorDisplay
3169
3218
  errorPrettified={getPrettifiedErrorMessage(
3170
- error,
3219
+ displayError,
3171
3220
  "An error occurred",
3172
3221
  )}
3173
- error={error}
3222
+ error={displayError}
3174
3223
  severity="error"
3175
3224
  />
3176
3225
  </div>
@@ -3294,6 +3343,7 @@ export const TrailsWidget = forwardRef<TrailsWidgetRef, TrailsWidgetProps>(
3294
3343
  sequenceApiUrl: props.sequenceApiUrl,
3295
3344
  sequenceIndexerUrl: props.sequenceIndexerUrl,
3296
3345
  sequenceNodeGatewayUrl: props.sequenceNodeGatewayUrl,
3346
+ sequenceMetadataUrl: props.sequenceMetadataUrl,
3297
3347
  walletConnectProjectId: props.walletConnectProjectId,
3298
3348
  slippageTolerance: props.slippageTolerance
3299
3349
  ? String(props.slippageTolerance)