0xtrails 0.6.6 → 0.7.0

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 (365) hide show
  1. package/dist/aave.d.ts +10 -2
  2. package/dist/aave.d.ts.map +1 -1
  3. package/dist/analytics.d.ts +26 -0
  4. package/dist/analytics.d.ts.map +1 -1
  5. package/dist/{ccip-CbJrlK-L.js → ccip-fConRNoG.js} +21 -21
  6. package/dist/chains.d.ts +23 -8
  7. package/dist/chains.d.ts.map +1 -1
  8. package/dist/constants.d.ts +5 -5
  9. package/dist/constants.d.ts.map +1 -1
  10. package/dist/customTokens.d.ts +12 -0
  11. package/dist/customTokens.d.ts.map +1 -0
  12. package/dist/decoders.d.ts +2 -2
  13. package/dist/decoders.d.ts.map +1 -1
  14. package/dist/error.d.ts.map +1 -1
  15. package/dist/fees.d.ts +37 -2
  16. package/dist/fees.d.ts.map +1 -1
  17. package/dist/gasless.d.ts +15 -36
  18. package/dist/gasless.d.ts.map +1 -1
  19. package/dist/{index-w7_dK4c5.js → index-BbajxCG_.js} +59269 -77146
  20. package/dist/index.d.ts +8 -6
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +828 -359
  23. package/dist/indexerClient.d.ts.map +1 -1
  24. package/dist/intentReceiptMonitor.d.ts +1 -1
  25. package/dist/intentReceiptMonitor.d.ts.map +1 -1
  26. package/dist/intentReceiptPoller.d.ts +1 -1
  27. package/dist/intentReceiptPoller.d.ts.map +1 -1
  28. package/dist/intents.d.ts +3 -2
  29. package/dist/intents.d.ts.map +1 -1
  30. package/dist/mode.d.ts +1 -1
  31. package/dist/mode.d.ts.map +1 -1
  32. package/dist/mutations.d.ts +2 -2
  33. package/dist/mutations.d.ts.map +1 -1
  34. package/dist/prepareSend.d.ts +2 -2
  35. package/dist/prepareSend.d.ts.map +1 -1
  36. package/dist/prices.d.ts +1 -1
  37. package/dist/prices.d.ts.map +1 -1
  38. package/dist/sequenceWallet.d.ts +2 -2
  39. package/dist/sequenceWallet.d.ts.map +1 -1
  40. package/dist/time.d.ts +6 -0
  41. package/dist/time.d.ts.map +1 -1
  42. package/dist/tokenBalances.d.ts +40 -25
  43. package/dist/tokenBalances.d.ts.map +1 -1
  44. package/dist/tokens.d.ts +54 -14
  45. package/dist/tokens.d.ts.map +1 -1
  46. package/dist/trailsClient.d.ts +1 -1
  47. package/dist/trailsClient.d.ts.map +1 -1
  48. package/dist/trailsRouter.d.ts +2 -1
  49. package/dist/trailsRouter.d.ts.map +1 -1
  50. package/dist/transactionIntent/deposits/depositOrchestrator.d.ts +3 -2
  51. package/dist/transactionIntent/deposits/depositOrchestrator.d.ts.map +1 -1
  52. package/dist/transactionIntent/deposits/gaslessDeposit.d.ts +2 -1
  53. package/dist/transactionIntent/deposits/gaslessDeposit.d.ts.map +1 -1
  54. package/dist/transactionIntent/execution/transactionState.d.ts +1 -1
  55. package/dist/transactionIntent/execution/transactionState.d.ts.map +1 -1
  56. package/dist/transactionIntent/handlers/crossChain.d.ts +5 -3
  57. package/dist/transactionIntent/handlers/crossChain.d.ts.map +1 -1
  58. package/dist/transactionIntent/handlers/sameChainSameToken.d.ts +5 -3
  59. package/dist/transactionIntent/handlers/sameChainSameToken.d.ts.map +1 -1
  60. package/dist/transactionIntent/quote/feeExtractors.d.ts +1 -6
  61. package/dist/transactionIntent/quote/feeExtractors.d.ts.map +1 -1
  62. package/dist/transactionIntent/quote/normalizeQuote.d.ts +4 -2
  63. package/dist/transactionIntent/quote/normalizeQuote.d.ts.map +1 -1
  64. package/dist/transactionIntent/quote/quoteHelpers.d.ts +1 -1
  65. package/dist/transactionIntent/quote/quoteHelpers.d.ts.map +1 -1
  66. package/dist/transactionIntent/types.d.ts +28 -5
  67. package/dist/transactionIntent/types.d.ts.map +1 -1
  68. package/dist/transactionIntent/utils/testnetHelpers.d.ts +0 -1
  69. package/dist/transactionIntent/utils/testnetHelpers.d.ts.map +1 -1
  70. package/dist/transactionIntent/validators.d.ts +0 -2
  71. package/dist/transactionIntent/validators.d.ts.map +1 -1
  72. package/dist/transactions.d.ts +2 -2
  73. package/dist/transactions.d.ts.map +1 -1
  74. package/dist/utils.d.ts +7 -0
  75. package/dist/utils.d.ts.map +1 -1
  76. package/dist/wallets.d.ts +1 -0
  77. package/dist/wallets.d.ts.map +1 -1
  78. package/dist/widget/components/AccountIntentTransactionHistory.d.ts.map +1 -1
  79. package/dist/widget/components/AddressWalletIcon.d.ts +6 -0
  80. package/dist/widget/components/AddressWalletIcon.d.ts.map +1 -0
  81. package/dist/widget/components/ChainFilterDropdown.d.ts +2 -6
  82. package/dist/widget/components/ChainFilterDropdown.d.ts.map +1 -1
  83. package/dist/widget/components/ChainImage.d.ts.map +1 -1
  84. package/dist/widget/components/ChainList.d.ts +0 -5
  85. package/dist/widget/components/ChainList.d.ts.map +1 -1
  86. package/dist/widget/components/ClassicSwap.d.ts +6 -6
  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/DebugMenu.d.ts +1 -1
  91. package/dist/widget/components/DebugMenu.d.ts.map +1 -1
  92. package/dist/widget/components/DebugScreensList.d.ts.map +1 -1
  93. package/dist/widget/components/DepositTracker.d.ts.map +1 -1
  94. package/dist/widget/components/Earn.d.ts +5 -5
  95. package/dist/widget/components/Earn.d.ts.map +1 -1
  96. package/dist/widget/components/FeeOption.d.ts +1 -1
  97. package/dist/widget/components/FeeOption.d.ts.map +1 -1
  98. package/dist/widget/components/FeeOptions.d.ts +2 -2
  99. package/dist/widget/components/FeeOptions.d.ts.map +1 -1
  100. package/dist/widget/components/Footer.d.ts +1 -1
  101. package/dist/widget/components/Footer.d.ts.map +1 -1
  102. package/dist/widget/components/Fund.d.ts +5 -5
  103. package/dist/widget/components/Fund.d.ts.map +1 -1
  104. package/dist/widget/components/FundMethods.d.ts +0 -1
  105. package/dist/widget/components/FundMethods.d.ts.map +1 -1
  106. package/dist/widget/components/FundSwap.d.ts +6 -6
  107. package/dist/widget/components/FundSwap.d.ts.map +1 -1
  108. package/dist/widget/components/HookModalContent.d.ts +8 -0
  109. package/dist/widget/components/HookModalContent.d.ts.map +1 -0
  110. package/dist/widget/components/OriginSelectionAmount.d.ts +11 -0
  111. package/dist/widget/components/OriginSelectionAmount.d.ts.map +1 -0
  112. package/dist/widget/components/Pay.d.ts +5 -5
  113. package/dist/widget/components/Pay.d.ts.map +1 -1
  114. package/dist/widget/components/PoolDeposit.d.ts +5 -5
  115. package/dist/widget/components/PoolDeposit.d.ts.map +1 -1
  116. package/dist/widget/components/PoolWithdraw.d.ts +3 -3
  117. package/dist/widget/components/PoolWithdraw.d.ts.map +1 -1
  118. package/dist/widget/components/QuoteDetails.d.ts.map +1 -1
  119. package/dist/widget/components/Receipt.d.ts +2 -1
  120. package/dist/widget/components/Receipt.d.ts.map +1 -1
  121. package/dist/widget/components/RecentTokens.d.ts +4 -4
  122. package/dist/widget/components/RecentTokens.d.ts.map +1 -1
  123. package/dist/widget/components/RecipientSelectorButton.d.ts.map +1 -1
  124. package/dist/widget/components/ShadowPortal.d.ts +6 -0
  125. package/dist/widget/components/ShadowPortal.d.ts.map +1 -0
  126. package/dist/widget/components/Swap.d.ts +6 -6
  127. package/dist/widget/components/Swap.d.ts.map +1 -1
  128. package/dist/widget/components/ThemeProvider.d.ts +1 -1
  129. package/dist/widget/components/ThemeProvider.d.ts.map +1 -1
  130. package/dist/widget/components/TokenList.d.ts +3 -4
  131. package/dist/widget/components/TokenList.d.ts.map +1 -1
  132. package/dist/widget/components/TokenSelector.d.ts +3 -4
  133. package/dist/widget/components/TokenSelector.d.ts.map +1 -1
  134. package/dist/widget/components/Tooltip.d.ts +6 -1
  135. package/dist/widget/components/Tooltip.d.ts.map +1 -1
  136. package/dist/widget/components/TrailsHookModal.d.ts +10 -0
  137. package/dist/widget/components/TrailsHookModal.d.ts.map +1 -0
  138. package/dist/widget/components/WaasFeeOptions.d.ts +3 -0
  139. package/dist/widget/components/WaasFeeOptions.d.ts.map +1 -1
  140. package/dist/widget/components/WalletConfirmation.d.ts.map +1 -1
  141. package/dist/widget/components/WalletConnect.d.ts.map +1 -1
  142. package/dist/widget/components/WidgetProviders.d.ts +14 -0
  143. package/dist/widget/components/WidgetProviders.d.ts.map +1 -0
  144. package/dist/widget/css/compiled.css +1 -1
  145. package/dist/widget/hooks/useAddressWalletIcon.d.ts +10 -0
  146. package/dist/widget/hooks/useAddressWalletIcon.d.ts.map +1 -0
  147. package/dist/widget/hooks/useBalanceVisible.d.ts +1 -1
  148. package/dist/widget/hooks/useBalanceVisible.d.ts.map +1 -1
  149. package/dist/widget/hooks/useChainFilter.d.ts +1 -1
  150. package/dist/widget/hooks/useChainFilter.d.ts.map +1 -1
  151. package/dist/widget/hooks/useCheckout.d.ts +13 -1
  152. package/dist/widget/hooks/useCheckout.d.ts.map +1 -1
  153. package/dist/widget/hooks/useConnector.d.ts +4 -0
  154. package/dist/widget/hooks/useConnector.d.ts.map +1 -0
  155. package/dist/widget/hooks/useCurrentScreen.d.ts +1 -1
  156. package/dist/widget/hooks/useCurrentScreen.d.ts.map +1 -1
  157. package/dist/widget/hooks/useCustomTokenFetch.d.ts +19 -0
  158. package/dist/widget/hooks/useCustomTokenFetch.d.ts.map +1 -0
  159. package/dist/widget/hooks/useCustomTokenSearch.d.ts +20 -0
  160. package/dist/widget/hooks/useCustomTokenSearch.d.ts.map +1 -0
  161. package/dist/widget/hooks/useDebounce.d.ts +10 -0
  162. package/dist/widget/hooks/useDebounce.d.ts.map +1 -0
  163. package/dist/widget/hooks/useDebugScreens.d.ts +7 -2
  164. package/dist/widget/hooks/useDebugScreens.d.ts.map +1 -1
  165. package/dist/widget/hooks/useDefaultTokenSelection.d.ts +3 -19
  166. package/dist/widget/hooks/useDefaultTokenSelection.d.ts.map +1 -1
  167. package/dist/widget/hooks/useDestinationSelectedToken.d.ts +1 -14
  168. package/dist/widget/hooks/useDestinationSelectedToken.d.ts.map +1 -1
  169. package/dist/widget/hooks/useEarnPool.d.ts +1 -1
  170. package/dist/widget/hooks/useEarnPool.d.ts.map +1 -1
  171. package/dist/widget/hooks/useIntentTransactionHistory.d.ts.map +1 -1
  172. package/dist/widget/hooks/useIsMobile.d.ts +5 -0
  173. package/dist/widget/hooks/useIsMobile.d.ts.map +1 -0
  174. package/dist/widget/hooks/useMode.d.ts +2 -2
  175. package/dist/widget/hooks/useMode.d.ts.map +1 -1
  176. package/dist/widget/hooks/useOriginSelectedToken.d.ts +2 -15
  177. package/dist/widget/hooks/useOriginSelectedToken.d.ts.map +1 -1
  178. package/dist/widget/hooks/usePayMessage.d.ts.map +1 -1
  179. package/dist/widget/hooks/usePriceImpactWarning.d.ts +1 -1
  180. package/dist/widget/hooks/usePriceImpactWarning.d.ts.map +1 -1
  181. package/dist/widget/hooks/useQuote.d.ts +173 -4
  182. package/dist/widget/hooks/useQuote.d.ts.map +1 -1
  183. package/dist/widget/hooks/useRecentTokens.d.ts +3 -3
  184. package/dist/widget/hooks/useRecentTokens.d.ts.map +1 -1
  185. package/dist/widget/hooks/useRecipients.d.ts +1 -1
  186. package/dist/widget/hooks/useRecipients.d.ts.map +1 -1
  187. package/dist/widget/hooks/useSelectedFeeOption.d.ts +2 -2
  188. package/dist/widget/hooks/useSelectedFeeOption.d.ts.map +1 -1
  189. package/dist/widget/hooks/useSelectedFundMethod.d.ts +1 -1
  190. package/dist/widget/hooks/useSelectedFundMethod.d.ts.map +1 -1
  191. package/dist/widget/hooks/useSelectedRecipient.d.ts +1 -1
  192. package/dist/widget/hooks/useSelectedRecipient.d.ts.map +1 -1
  193. package/dist/widget/hooks/useSendForm.d.ts +9 -31
  194. package/dist/widget/hooks/useSendForm.d.ts.map +1 -1
  195. package/dist/widget/hooks/useSwapAmount.d.ts +1 -1
  196. package/dist/widget/hooks/useSwapAmount.d.ts.map +1 -1
  197. package/dist/widget/hooks/useTheme.d.ts +1 -1
  198. package/dist/widget/hooks/useTheme.d.ts.map +1 -1
  199. package/dist/widget/hooks/useTokenList.d.ts +7 -31
  200. package/dist/widget/hooks/useTokenList.d.ts.map +1 -1
  201. package/dist/widget/hooks/useTrailsSendTransaction.d.ts +83 -0
  202. package/dist/widget/hooks/useTrailsSendTransaction.d.ts.map +1 -0
  203. package/dist/widget/hooks/useWalletConnectUri.d.ts +11 -0
  204. package/dist/widget/hooks/useWalletConnectUri.d.ts.map +1 -0
  205. package/dist/widget/hooks/useWidgetProps.d.ts +5 -0
  206. package/dist/widget/hooks/useWidgetProps.d.ts.map +1 -1
  207. package/dist/widget/index.d.ts +2 -0
  208. package/dist/widget/index.d.ts.map +1 -1
  209. package/dist/widget/index.js +8 -5
  210. package/dist/widget/providers/TrailsModalProvider.d.ts +65 -0
  211. package/dist/widget/providers/TrailsModalProvider.d.ts.map +1 -0
  212. package/dist/widget/providers/TrailsProvider.d.ts +1 -1
  213. package/dist/widget/providers/TrailsProvider.d.ts.map +1 -1
  214. package/dist/widget/types.d.ts +11 -18
  215. package/dist/widget/types.d.ts.map +1 -1
  216. package/dist/widget/widget.d.ts +20 -11
  217. package/dist/widget/widget.d.ts.map +1 -1
  218. package/package.json +45 -49
  219. package/src/aave.ts +387 -138
  220. package/src/analytics.ts +208 -2
  221. package/src/chains.ts +65 -64
  222. package/src/constants.ts +18 -14
  223. package/src/customTokens.ts +151 -0
  224. package/src/decoders.ts +4 -7
  225. package/src/error.ts +7 -3
  226. package/src/fees.ts +239 -125
  227. package/src/gasless.ts +54 -108
  228. package/src/index.ts +29 -9
  229. package/src/indexerClient.ts +2 -0
  230. package/src/intentReceiptMonitor.ts +1 -4
  231. package/src/intentReceiptPoller.ts +2 -2
  232. package/src/intents.ts +16 -5
  233. package/src/mode.ts +1 -1
  234. package/src/mutations.ts +7 -3
  235. package/src/prepareSend.ts +19 -14
  236. package/src/prices.ts +1 -1
  237. package/src/sequenceWallet.ts +2 -2
  238. package/src/time.ts +28 -0
  239. package/src/tokenBalances.ts +348 -153
  240. package/src/tokens.ts +393 -142
  241. package/src/trailsClient.ts +1 -1
  242. package/src/trailsRouter.ts +4 -5
  243. package/src/transactionIntent/deposits/depositOrchestrator.ts +6 -2
  244. package/src/transactionIntent/deposits/gaslessDeposit.ts +13 -7
  245. package/src/transactionIntent/deposits/standardDeposit.ts +1 -1
  246. package/src/transactionIntent/execution/transactionState.ts +1 -1
  247. package/src/transactionIntent/handlers/crossChain.ts +75 -37
  248. package/src/transactionIntent/handlers/sameChainSameToken.ts +66 -20
  249. package/src/transactionIntent/quote/feeExtractors.ts +1 -29
  250. package/src/transactionIntent/quote/normalizeQuote.ts +99 -7
  251. package/src/transactionIntent/quote/quoteHelpers.ts +1 -1
  252. package/src/transactionIntent/types.ts +31 -6
  253. package/src/transactionIntent/utils/testnetHelpers.ts +0 -5
  254. package/src/transactionIntent/validators.ts +0 -30
  255. package/src/transactions.ts +3 -3
  256. package/src/utils.ts +18 -0
  257. package/src/wallets.ts +32 -10
  258. package/src/widget/compiled.css +1 -1
  259. package/src/widget/components/AccountIntentTransactionHistory.tsx +2 -1
  260. package/src/widget/components/AccountIntentTransactionHistoryButton.tsx +2 -2
  261. package/src/widget/components/AddressWalletIcon.tsx +29 -0
  262. package/src/widget/components/ChainFilterDropdown.tsx +2 -8
  263. package/src/widget/components/ChainImage.tsx +8 -5
  264. package/src/widget/components/ChainList.tsx +6 -8
  265. package/src/widget/components/ClassicSwap.tsx +93 -85
  266. package/src/widget/components/ConnectWallet.tsx +1 -2
  267. package/src/widget/components/ConnectedWallets.tsx +17 -4
  268. package/src/widget/components/DebugMenu.tsx +2 -2
  269. package/src/widget/components/DebugScreensList.tsx +0 -1
  270. package/src/widget/components/DepositTracker.tsx +20 -34
  271. package/src/widget/components/Earn.tsx +7 -6
  272. package/src/widget/components/FeeOption.tsx +4 -4
  273. package/src/widget/components/FeeOptions.tsx +19 -39
  274. package/src/widget/components/Footer.tsx +1 -1
  275. package/src/widget/components/Fund.tsx +23 -119
  276. package/src/widget/components/FundMethods.tsx +9 -6
  277. package/src/widget/components/FundSwap.tsx +6 -5
  278. package/src/widget/components/FundingMethodSelectorButton.tsx +2 -2
  279. package/src/widget/components/HookModalContent.tsx +306 -0
  280. package/src/widget/components/Modal.tsx +1 -1
  281. package/src/widget/components/OriginSelectionAmount.tsx +135 -0
  282. package/src/widget/components/Pay.tsx +66 -124
  283. package/src/widget/components/PoolDeposit.tsx +11 -55
  284. package/src/widget/components/PoolWithdraw.tsx +3 -3
  285. package/src/widget/components/QuoteDetails.tsx +473 -728
  286. package/src/widget/components/Receipt.tsx +74 -7
  287. package/src/widget/components/RecentTokens.tsx +8 -8
  288. package/src/widget/components/RecipientSelectorButton.tsx +4 -2
  289. package/src/widget/components/ScreenHeader.tsx +2 -2
  290. package/src/widget/components/SearchInputField.tsx +1 -1
  291. package/src/widget/components/ShadowPortal.tsx +58 -0
  292. package/src/widget/components/Swap.tsx +6 -5
  293. package/src/widget/components/ThemeProvider.tsx +1 -1
  294. package/src/widget/components/TokenList.tsx +3 -4
  295. package/src/widget/components/TokenSelector.tsx +211 -80
  296. package/src/widget/components/Tooltip.tsx +18 -7
  297. package/src/widget/components/TrailsHookModal.tsx +118 -0
  298. package/src/widget/components/WaasFeeOptions.tsx +333 -138
  299. package/src/widget/components/WalletConfirmation.tsx +7 -2
  300. package/src/widget/components/WalletConnect.tsx +197 -235
  301. package/src/widget/components/WidgetProviders.tsx +75 -0
  302. package/src/widget/hooks/useAddressWalletIcon.ts +53 -0
  303. package/src/widget/hooks/useBalanceVisible.tsx +1 -1
  304. package/src/widget/hooks/useChainFilter.tsx +1 -1
  305. package/src/widget/hooks/useCheckout.ts +13 -1
  306. package/src/widget/hooks/useConnector.tsx +18 -0
  307. package/src/widget/hooks/useCurrentScreen.tsx +3 -3
  308. package/src/widget/hooks/useCustomTokenFetch.tsx +72 -0
  309. package/src/widget/hooks/useCustomTokenSearch.tsx +402 -0
  310. package/src/widget/hooks/useDebounce.ts +25 -0
  311. package/src/widget/hooks/useDebugScreens.ts +26 -10
  312. package/src/widget/hooks/useDefaultTokenSelection.tsx +99 -143
  313. package/src/widget/hooks/useDestinationSelectedToken.tsx +1 -14
  314. package/src/widget/hooks/useEarnPool.tsx +1 -1
  315. package/src/widget/hooks/useIntentTransactionHistory.ts +20 -11
  316. package/src/widget/hooks/useIsMobile.tsx +50 -0
  317. package/src/widget/hooks/useMode.ts +2 -3
  318. package/src/widget/hooks/useOriginSelectedToken.tsx +2 -15
  319. package/src/widget/hooks/usePayMessage.tsx +31 -11
  320. package/src/widget/hooks/usePriceImpactWarning.ts +1 -1
  321. package/src/widget/hooks/useQuote.ts +189 -6
  322. package/src/widget/hooks/useRecentTokens.ts +6 -6
  323. package/src/widget/hooks/useRecipients.ts +1 -1
  324. package/src/widget/hooks/useSelectedFeeOption.tsx +2 -2
  325. package/src/widget/hooks/useSelectedFundMethod.tsx +1 -1
  326. package/src/widget/hooks/useSelectedRecipient.tsx +1 -1
  327. package/src/widget/hooks/useSendForm.ts +328 -152
  328. package/src/widget/hooks/useSwapAmount.tsx +1 -1
  329. package/src/widget/hooks/useTheme.tsx +1 -1
  330. package/src/widget/hooks/useTokenList.ts +672 -400
  331. package/src/widget/hooks/useTrailsSendTransaction.ts +949 -0
  332. package/src/widget/hooks/useWalletConnectUri.tsx +228 -0
  333. package/src/widget/hooks/useWidgetProps.tsx +3 -1
  334. package/src/widget/index.tsx +12 -0
  335. package/src/widget/providers/TrailsModalProvider.tsx +195 -0
  336. package/src/widget/providers/TrailsProvider.tsx +9 -3
  337. package/src/widget/types.ts +12 -20
  338. package/src/widget/widget.tsx +598 -385
  339. package/dist/cctp.d.ts +0 -3
  340. package/dist/cctp.d.ts.map +0 -1
  341. package/dist/lifi.d.ts +0 -4
  342. package/dist/lifi.d.ts.map +0 -1
  343. package/dist/meshconnect.d.ts +0 -171
  344. package/dist/meshconnect.d.ts.map +0 -1
  345. package/dist/relaySdk.d.ts +0 -87
  346. package/dist/relaySdk.d.ts.map +0 -1
  347. package/dist/widget/components/MeshConnectExchanges.d.ts +0 -7
  348. package/dist/widget/components/MeshConnectExchanges.d.ts.map +0 -1
  349. package/dist/widget/components/MeshConnectFlow.d.ts +0 -13
  350. package/dist/widget/components/MeshConnectFlow.d.ts.map +0 -1
  351. package/dist/widget/components/MeshConnectIframe.d.ts +0 -15
  352. package/dist/widget/components/MeshConnectIframe.d.ts.map +0 -1
  353. package/dist/widget/components/Receive.d.ts +0 -12
  354. package/dist/widget/components/Receive.d.ts.map +0 -1
  355. package/dist/widget/hooks/useSelectedMeshExchange.d.ts +0 -14
  356. package/dist/widget/hooks/useSelectedMeshExchange.d.ts.map +0 -1
  357. package/src/cctp.ts +0 -54
  358. package/src/lifi.ts +0 -108
  359. package/src/meshconnect.ts +0 -531
  360. package/src/relaySdk.ts +0 -703
  361. package/src/widget/components/MeshConnectExchanges.tsx +0 -290
  362. package/src/widget/components/MeshConnectFlow.tsx +0 -90
  363. package/src/widget/components/MeshConnectIframe.tsx +0 -500
  364. package/src/widget/components/Receive.tsx +0 -175
  365. package/src/widget/hooks/useSelectedMeshExchange.tsx +0 -46
@@ -1,8 +1,6 @@
1
- import { AaveClient, AaveProvider } from "@aave/react"
2
1
  import { QueryClient, QueryClientProvider } from "@tanstack/react-query"
3
2
  import { AnimatePresence, motion } from "motion/react"
4
3
  import React, {
5
- createContext,
6
4
  forwardRef,
7
5
  StrictMode,
8
6
  useCallback,
@@ -13,9 +11,16 @@ import React, {
13
11
  useRef,
14
12
  useState,
15
13
  } from "react"
16
- import { createPortal } from "react-dom"
14
+ import { ShadowPortal } from "./components/ShadowPortal.js"
17
15
  import type { Chain, WalletClient } from "viem"
18
- import { createWalletClient, custom, defineChain, http, isAddress } from "viem"
16
+ import {
17
+ createWalletClient,
18
+ custom,
19
+ defineChain,
20
+ http,
21
+ isAddress,
22
+ zeroAddress,
23
+ } from "viem"
19
24
  import type { Connector } from "wagmi"
20
25
  import {
21
26
  createConfig,
@@ -55,9 +60,9 @@ import { usePools } from "../pools.js"
55
60
  import type { PrepareSendQuote } from "../prepareSend.js"
56
61
  import { isValidInteger, isValidNumeric } from "../prices.js"
57
62
  import type { Theme } from "../theme.js"
58
- import type { SupportedToken } from "../tokens.js"
63
+ import type { Token } from "../tokens.js"
59
64
  import { getWethAddress } from "../tokens.js"
60
- import type { IntentTransaction } from "@0xsequence/trails-api"
65
+ import type { IntentTransaction } from "@0xtrails/api"
61
66
  import type { TransactionState } from "../transactions.js"
62
67
  import {
63
68
  useQRCodeWallets,
@@ -69,7 +74,6 @@ import {
69
74
  import { generateAaveDepositCalldata } from "../aave.js"
70
75
  import { DEFAULT_MODE } from "../constants.js"
71
76
  import { generateMorphoDepositCalldata } from "../morpho.js"
72
- import css from "./compiled.css?inline"
73
77
  import { AccountIntentTransactionHistory } from "./components/AccountIntentTransactionHistory.js"
74
78
  import { AccountSettings } from "./components/AccountSettings.js"
75
79
  import { ChainList } from "./components/ChainList.js"
@@ -81,115 +85,50 @@ import { ErrorDisplay } from "./components/ErrorDisplay.js"
81
85
  import Footer from "./components/Footer.js"
82
86
  import FundMethods from "./components/FundMethods.js"
83
87
  import { Fund } from "./components/FundSwap.js"
84
- import { MeshConnectExchanges } from "./components/MeshConnectExchanges.js"
85
- import { MeshConnectFlow } from "./components/MeshConnectFlow.js"
86
- import type { MeshConnectProps } from "./components/MeshConnectIframe.js"
87
88
  import Modal from "./components/Modal.js"
88
89
  import { Pay } from "./components/Pay.js"
89
90
  import QRCodeDeposit from "./components/QRCodeDeposit.js"
90
91
  import QRCodeOptions from "./components/QRCodeOptions.js"
91
92
  import QRCodeWalletSelect from "./components/QRCodeWalletSelect.js"
92
93
  import Receipt from "./components/Receipt.js"
93
- import { Receive } from "./components/Receive.js"
94
94
  import { Recipients } from "./components/Recipients.js"
95
95
  import { Swap } from "./components/Swap.js"
96
96
  import { ThemeProvider } from "./components/ThemeProvider.js"
97
97
  import { ThemeSyncer } from "./components/ThemeSyncer.js"
98
- import { ToastProvider } from "./components/Toast.js"
99
98
  import TokenList from "./components/TokenList.js"
99
+ import OriginSelectionAmount from "./components/OriginSelectionAmount.js"
100
100
  import TransferPending from "./components/TransferPendingVertical.js"
101
101
  import { UserPreferences } from "./components/UserPreferences.js"
102
102
  import WalletConfirmation from "./components/WalletConfirmation.js"
103
103
  import WalletConnectScreen from "./components/WalletConnect.js"
104
104
  import WalletConnectionPending from "./components/WalletConnectionPending.js"
105
105
  import { WalletList } from "./components/WalletList.js"
106
- import { BackProvider, useBack } from "./hooks/useBack.js"
107
- import { BalanceVisibleProvider } from "./hooks/useBalanceVisible.js"
108
- import { ChainFilterProvider } from "./hooks/useChainFilter.js"
106
+ import { useBack } from "./hooks/useBack.js"
109
107
  import { useCheckout } from "./hooks/useCheckout.js"
110
- import {
111
- CurrentScreenProvider,
112
- useCurrentScreen,
113
- type Screen,
114
- } from "./hooks/useCurrentScreen.js"
108
+ import { useCurrentScreen } from "./hooks/useCurrentScreen.js"
115
109
  import { useDebugScreens } from "./hooks/useDebugScreens.js"
116
- import { DefaultTokenSelectionProvider } from "./hooks/useDefaultTokenSelection.js"
117
- import { DestinationSelectedTokenProvider } from "./hooks/useDestinationSelectedToken.js"
118
- import { EarnPoolProvider, useEarnPool } from "./hooks/useEarnPool.js"
110
+ import { useEarnPool } from "./hooks/useEarnPool.js"
119
111
  import { useInitialRedirect } from "./hooks/useInitialRedirect.js"
120
112
  import { useIsSequenceWallet } from "./hooks/useIsSequenceWallet.js"
121
113
  import { ModeProvider } from "./hooks/useMode.js"
122
- import {
123
- OriginSelectedTokenProvider as SelectedTokenProvider,
124
- useOriginSelectedToken as useSelectedToken,
125
- type Token,
126
- } from "./hooks/useOriginSelectedToken.js"
114
+ import { useOriginSelectedToken as useSelectedToken } from "./hooks/useOriginSelectedToken.js"
127
115
  import { PriceImpactWarningProvider } from "./hooks/usePriceImpactWarning.js"
128
116
  import { useRecentTokens } from "./hooks/useRecentTokens.js"
129
- import {
130
- SelectedFeeOptionProvider,
131
- useSelectedFeeOption,
132
- } from "./hooks/useSelectedFeeOption.js"
133
- import {
134
- SelectedFundMethodProvider,
135
- useSelectedFundMethod,
136
- } from "./hooks/useSelectedFundMethod.js"
137
- import {
138
- SelectedMeshExchangeProvider,
139
- useSelectedMeshExchange,
140
- } from "./hooks/useSelectedMeshExchange.js"
141
- import {
142
- SelectedRecipientProvider,
143
- useSelectedRecipient,
144
- } from "./hooks/useSelectedRecipient.js"
117
+ import { useSelectedFeeOption } from "./hooks/useSelectedFeeOption.js"
118
+ import { useSelectedFundMethod } from "./hooks/useSelectedFundMethod.js"
119
+ import { useSelectedRecipient } from "./hooks/useSelectedRecipient.js"
145
120
  import type { OnCompleteProps } from "./hooks/useSendForm.js"
146
- import { SwapAmountProvider } from "./hooks/useSwapAmount.js"
147
121
  import { useTargetAmount } from "./hooks/useTargetAmount.js"
148
- import { ThemeProvider as ThemePreferenceProvider } from "./hooks/useTheme.js"
149
- import {
150
- useWalletConnectionContext,
151
- WalletConnectionProvider,
152
- } from "./hooks/useWalletConnectionContext.js"
153
- import { useWidgetProps, WidgetPropsProvider } from "./hooks/useWidgetProps.js"
122
+ import { useWalletConnectionContext } from "./hooks/useWalletConnectionContext.js"
123
+ import { useWidgetProps } from "./hooks/useWidgetProps.js"
124
+ import { WidgetProviders } from "./components/WidgetProviders.js"
154
125
  import {
155
126
  TrailsProvider,
127
+ TrailsContext,
156
128
  useTrails,
157
129
  type TrailsProviderProps,
158
130
  } from "./providers/TrailsProvider.js"
159
-
160
- export const aaveClient = AaveClient.create()
161
-
162
- // Modal Context
163
- interface ModalContextType {
164
- closeModal: () => void
165
- isModalOpen: boolean
166
- }
167
-
168
- const ModalContext = createContext<ModalContextType | null>(null)
169
-
170
- // Modal Provider Component
171
- const ModalProvider: React.FC<{
172
- children: React.ReactNode
173
- closeModal: () => void
174
- isModalOpen: boolean
175
- }> = ({ children, closeModal, isModalOpen }) => (
176
- <ModalContext.Provider value={{ closeModal, isModalOpen }}>
177
- {children}
178
- </ModalContext.Provider>
179
- )
180
-
181
- // useModal Hook
182
- export const useModal = (): ModalContextType => {
183
- const context = useContext(ModalContext)
184
- if (!context) {
185
- // Return a no-op function when not in modal context (e.g., renderInline)
186
- return {
187
- closeModal: () => {},
188
- isModalOpen: false,
189
- }
190
- }
191
- return context
192
- }
131
+ import { useTrailsModal } from "./providers/TrailsModalProvider.js"
193
132
 
194
133
  // Validate toToken - must be "ETH", "USDC", or a valid hex address
195
134
  const isValidToToToken = (toToken: string | null | undefined) => {
@@ -276,6 +215,26 @@ export type TrailsWidgetProps = {
276
215
  appDescription?: string
277
216
  payMessage?: string
278
217
  isSmartWallet?: boolean
218
+ /**
219
+ * Optional onramp factory function (e.g., trailsOnramp from @0xtrails/onramp)
220
+ * If provided, enables exchange funding options in the widget
221
+ *
222
+ * @example
223
+ * ```tsx
224
+ * import { trailsOnramp } from "@0xtrails/onramp"
225
+ * <TrailsWidget onramp={trailsOnramp({ config: { exchanges: ['coinbase'] } })} />
226
+ * ```
227
+ */
228
+ onramp?: (handlers: {
229
+ setCurrentScreen: (screen: string) => void
230
+ onComplete?: (transferData: any) => void
231
+ onError?: (error: unknown) => void
232
+ onBack?: () => void
233
+ toTokenSymbol?: string
234
+ toTokenAmount?: string
235
+ toChainId?: number
236
+ toRecipientAddress?: string
237
+ }) => React.ReactElement
279
238
  }
280
239
 
281
240
  export interface TrailsWidgetRef {
@@ -451,11 +410,8 @@ const useTransactionState = (
451
410
  const allConfirmed = transactionStates.every(
452
411
  (tx: TransactionState) => tx.state === "confirmed",
453
412
  )
454
- const hasFailures = transactionStates.some(
455
- (tx: TransactionState) => tx.state === "failed",
456
- )
457
413
 
458
- if (allConfirmed && !hasFailures && onComplete) {
414
+ if (allConfirmed && onComplete) {
459
415
  logger.console.log(
460
416
  "[trails-sdk] All transactions confirmed, triggering completion",
461
417
  )
@@ -546,8 +502,32 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
546
502
  const { recentTokens, addRecentToken } = useRecentTokens(address)
547
503
  const { wallets: allWallets } = useWallets()
548
504
  const { selectedToken, setSelectedToken } = useSelectedToken()
549
- const { selectedExchange } = useSelectedMeshExchange()
550
- const [isModalOpen, setIsModalOpen] = useState(false)
505
+ const { onramp: onrampFactory } = useWidgetProps()
506
+
507
+ // Modal state is managed by TrailsModalProvider
508
+ const {
509
+ isModalOpen,
510
+ openModal: openTrailsModal,
511
+ closeModal: closeTrailsModal,
512
+ pendingSelection,
513
+ setPendingSelection,
514
+ hostTransactionState,
515
+ setHostTransactionState,
516
+ hostTransactionQuote,
517
+ hostTransactionStates,
518
+ hostTransactionTimestamp,
519
+ resetHostTransactionState,
520
+ receiptActionButtonText,
521
+ onReceiptAction,
522
+ retryTransactionRef,
523
+ } = useTrailsModal()
524
+
525
+ useEffect(() => {
526
+ logger.console.log(
527
+ "[trails-sdk] [TrailsWidget] isModalOpen changed:",
528
+ isModalOpen,
529
+ )
530
+ }, [isModalOpen])
551
531
  const [currentMode, setCurrentMode] = useState<Mode>(mode)
552
532
  const { currentScreen, setCurrentScreen } = useCurrentScreen()
553
533
  const { goBack, clearHistory, setCurrentScreenWithBack, getPreviousScreen } =
@@ -608,8 +588,6 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
608
588
  const getInitialScreenForMode = useCallback((mode: Mode) => {
609
589
  if (mode === "swap") {
610
590
  return "swap"
611
- } else if (mode === "receive") {
612
- return "receive"
613
591
  } else if (mode === "earn") {
614
592
  return "earn"
615
593
  } else if (mode === "fund") {
@@ -659,9 +637,6 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
659
637
  if (currentMode === "earn") {
660
638
  return "Earn"
661
639
  }
662
- if (currentMode === "receive") {
663
- return "Receive"
664
- }
665
640
  if (currentMode === "pay") {
666
641
  return "Pay"
667
642
  }
@@ -795,8 +770,19 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
795
770
  }
796
771
  }
797
772
 
798
- const [meshConnectProps, setMeshConnectProps] =
799
- useState<Partial<MeshConnectProps> | null>(null)
773
+ const [onrampProps, setOnrampProps] = useState<{
774
+ toTokenSymbol?: string
775
+ toTokenAmount?: string
776
+ toChainId?: number
777
+ toRecipientAddress?: string
778
+ } | null>(null)
779
+
780
+ // Store callback to continue send after onramp completes
781
+ const [onrampContinueSend, setOnrampContinueSend] = useState<
782
+ (() => Promise<void>) | null
783
+ >(null)
784
+ const [onrampContinueSendInProgress, setOnrampContinueSendInProgress] =
785
+ useState(false)
800
786
 
801
787
  // Hook to auto-select pool when mode is "earn" and toAddress is specified
802
788
  const useAutoSelectPool = (
@@ -931,7 +917,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
931
917
  setShowWalletConnectionRetry,
932
918
  setError,
933
919
  setIsConnecting,
934
- setMeshConnectProps,
920
+ setOnrampProps,
935
921
  isConnected,
936
922
  })
937
923
 
@@ -955,6 +941,71 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
955
941
  })
956
942
  }, [currentScreen, address])
957
943
 
944
+ useEffect(() => {
945
+ const status = hostTransactionState.status
946
+ if (status === "idle") {
947
+ return
948
+ }
949
+
950
+ if (!isModalOpen) {
951
+ openTrailsModal()
952
+ }
953
+
954
+ switch (status) {
955
+ case "awaiting-origin":
956
+ setCurrentScreen("select-origin-token")
957
+ break
958
+ case "awaiting-amount":
959
+ setCurrentScreen("select-origin-amount")
960
+ break
961
+ case "confirmation":
962
+ setCurrentScreen("wallet-confirmation")
963
+ break
964
+ case "pending":
965
+ setCurrentScreen("pending")
966
+ break
967
+ case "success":
968
+ case "error":
969
+ if (hostTransactionStates.length > 0) {
970
+ setCurrentScreen("receipt")
971
+ } else {
972
+ setCurrentScreen("pending")
973
+ }
974
+ break
975
+ default:
976
+ setCurrentScreen("pending")
977
+ break
978
+ }
979
+ }, [
980
+ hostTransactionState.status,
981
+ hostTransactionStates.length,
982
+ isModalOpen,
983
+ openTrailsModal,
984
+ setCurrentScreen,
985
+ ])
986
+
987
+ useEffect(() => {
988
+ if (!hostTransactionQuote) {
989
+ return
990
+ }
991
+ setPrepareSendQuote(hostTransactionQuote)
992
+ }, [hostTransactionQuote])
993
+
994
+ useEffect(() => {
995
+ if (hostTransactionStates.length === 0) {
996
+ return
997
+ }
998
+ setTransactionStates(hostTransactionStates)
999
+ }, [hostTransactionStates, setTransactionStates])
1000
+
1001
+ useEffect(() => {
1002
+ if (hostTransactionState.status === "success" && hostTransactionTimestamp) {
1003
+ setTotalCompletionSeconds(
1004
+ Math.max(0, Math.floor((Date.now() - hostTransactionTimestamp) / 1000)),
1005
+ )
1006
+ }
1007
+ }, [hostTransactionState.status, hostTransactionTimestamp])
1008
+
958
1009
  // Update analytics project access key when it changes
959
1010
  useEffect(() => {
960
1011
  if (trailsApiKey) {
@@ -1048,7 +1099,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
1048
1099
  }
1049
1100
  }, [selectedPool, currentMode, generatedCalldata])
1050
1101
 
1051
- const handleWalletConnect = async (walletId: string) => {
1102
+ const handleConnectWallet = async (walletId: string) => {
1052
1103
  try {
1053
1104
  setError(null)
1054
1105
  setIsConnecting(true)
@@ -1108,7 +1159,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
1108
1159
  "[trails-sdk] Switching back to original active wallet:",
1109
1160
  address,
1110
1161
  )
1111
- await switchAccount({ connector: originalConnector })
1162
+ switchAccount({ connector: originalConnector })
1112
1163
  } catch (switchError) {
1113
1164
  logger.console.error(
1114
1165
  "[trails-sdk] Failed to switch back to original wallet:",
@@ -1205,11 +1256,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
1205
1256
  logger.console.error("[trails-sdk] Failed to disconnect:", error)
1206
1257
  }
1207
1258
 
1208
- if (currentMode === "receive") {
1209
- setCurrentScreen("receive")
1210
- } else {
1211
- setCurrentScreen("connect")
1212
- }
1259
+ setCurrentScreen("connect")
1213
1260
  }
1214
1261
 
1215
1262
  const handleContinue = async () => {
@@ -1234,7 +1281,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
1234
1281
  "[trails-sdk] Switching back to original active wallet after WalletConnect:",
1235
1282
  originalAddress,
1236
1283
  )
1237
- await switchAccount({ connector: originalConnector })
1284
+ switchAccount({ connector: originalConnector })
1238
1285
  } catch (switchError) {
1239
1286
  logger.console.error(
1240
1287
  "[trails-sdk] Failed to switch back to original wallet after WalletConnect:",
@@ -1257,8 +1304,6 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
1257
1304
  // Normal flow - navigate based on mode
1258
1305
  if (currentMode === "swap") {
1259
1306
  setCurrentScreen("swap")
1260
- } else if (currentMode === "receive") {
1261
- setCurrentScreen("receive")
1262
1307
  } else if (currentMode === "earn") {
1263
1308
  setCurrentScreen("earn")
1264
1309
  } else if (currentMode === "fund") {
@@ -1276,6 +1321,36 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
1276
1321
  setError(null)
1277
1322
  setSelectedToken(token)
1278
1323
 
1324
+ // Check if there's a pending selection request from useTrailsSendTransaction
1325
+ if (pendingSelection) {
1326
+ if (pendingSelection.requireAmountInput) {
1327
+ setHostTransactionState((prev) => ({
1328
+ ...prev,
1329
+ status: "awaiting-amount",
1330
+ }))
1331
+ handleTrackToken(token)
1332
+ return
1333
+ }
1334
+ const originAddress = token.contractAddress || zeroAddress
1335
+ const chainId = token.chainId ?? 0
1336
+ try {
1337
+ pendingSelection.resolve({
1338
+ fromTokenAddress: originAddress,
1339
+ fromChainId: chainId,
1340
+ })
1341
+ } catch (error) {
1342
+ logger.console.error(
1343
+ "[trails-sdk] Error resolving pending selection:",
1344
+ error,
1345
+ )
1346
+ pendingSelection.reject(error as Error)
1347
+ } finally {
1348
+ setPendingSelection(undefined)
1349
+ }
1350
+ handleTrackToken(token)
1351
+ return
1352
+ }
1353
+
1279
1354
  // For earn mode, check if we have toAddress and toChainId specified
1280
1355
  if (currentMode === "earn") {
1281
1356
  if (toAddress && toChainId) {
@@ -1290,8 +1365,6 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
1290
1365
  }
1291
1366
  } else if (currentMode === "swap") {
1292
1367
  setCurrentScreen("swap")
1293
- } else if (currentMode === "receive") {
1294
- setCurrentScreen("send-form")
1295
1368
  } else {
1296
1369
  setCurrentScreen(currentMode === "fund" ? "fund-form" : "send-form")
1297
1370
  }
@@ -1302,45 +1375,83 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
1302
1375
  }
1303
1376
  }
1304
1377
 
1305
- const handleRecentTokenSelect = (supportedToken: SupportedToken) => {
1306
- // Convert SupportedToken back to Token format for consistency
1307
- const token: Token = {
1308
- id: Math.random(), // Temporary ID
1309
- name: supportedToken.name,
1310
- symbol: supportedToken.symbol,
1311
- balance: "0", // We don't have balance info for recent tokens
1312
- imageUrl: supportedToken.imageUrl,
1313
- chainId: supportedToken.chainId,
1314
- contractAddress: supportedToken.contractAddress,
1315
- contractInfo: {
1316
- decimals: supportedToken.decimals,
1317
- symbol: supportedToken.symbol,
1318
- name: supportedToken.name,
1319
- },
1320
- }
1321
-
1378
+ const handleRecentTokenSelect = (token: Token) => {
1322
1379
  handleTokenSelect(token)
1323
1380
  }
1324
1381
 
1325
1382
  const handleTrackToken = (token: Token) => {
1326
1383
  // Track the token in recent tokens
1327
1384
  const chainInfo = getChainInfo(token.chainId)
1328
- const decimals = token.contractInfo?.decimals || (token as any).decimals
1329
- const supportedToken: SupportedToken = {
1330
- id: `${token.symbol}-${chainInfo?.name || token.chainId}`,
1385
+ const decimals = token.decimals || 18
1386
+ // Convert to Token for addRecentToken (which now accepts Token)
1387
+ const trailsToken: Token = {
1331
1388
  symbol: token.symbol,
1332
1389
  name: token.name,
1390
+ decimals: decimals,
1333
1391
  contractAddress: token.contractAddress,
1334
- decimals,
1392
+ tokenId: `${token.symbol}-${chainInfo?.name || token.chainId}`,
1335
1393
  chainId: token.chainId,
1336
1394
  chainName: chainInfo?.name || `Chain ${token.chainId}`,
1337
1395
  imageUrl: token.imageUrl,
1338
1396
  }
1339
- addRecentToken(supportedToken)
1397
+ addRecentToken(trailsToken)
1398
+ }
1399
+
1400
+ const handleOriginAmountSubmit = (amount: string) => {
1401
+ if (pendingSelection && selectedToken) {
1402
+ try {
1403
+ pendingSelection.resolve({
1404
+ fromTokenAddress: selectedToken.contractAddress || zeroAddress,
1405
+ fromChainId: selectedToken.chainId ?? 0,
1406
+ fromAmount: amount,
1407
+ })
1408
+ setPendingSelection(undefined)
1409
+ } catch (error) {
1410
+ logger.console.error(
1411
+ "[trails-sdk] Error resolving pending selection amount:",
1412
+ error,
1413
+ )
1414
+ pendingSelection.reject(error as Error)
1415
+ setPendingSelection(undefined)
1416
+ }
1417
+ }
1340
1418
  }
1341
1419
 
1342
1420
  const handleOnSend = async (amount: string, recipient: string) => {
1343
1421
  logger.console.log("[trails-sdk] handleOnSend", amount, recipient)
1422
+
1423
+ // Check if there's a pending selection request from useTrailsSendTransaction
1424
+ if (pendingSelection && selectedToken) {
1425
+ try {
1426
+ // Convert amount to token units (it's already in token units from the form)
1427
+ const amountInTokenUnits = amount
1428
+
1429
+ // Resolve the pending selection with the selected token and amount
1430
+ pendingSelection.resolve({
1431
+ fromTokenAddress: selectedToken.contractAddress || zeroAddress,
1432
+ fromChainId: selectedToken.chainId ?? 0,
1433
+ fromAmount: amountInTokenUnits,
1434
+ })
1435
+
1436
+ setPendingSelection(undefined)
1437
+ return
1438
+ } catch (error) {
1439
+ logger.console.error(
1440
+ "[trails-sdk] Error resolving pending selection:",
1441
+ error,
1442
+ )
1443
+ if (pendingSelection) {
1444
+ pendingSelection.reject(error as Error)
1445
+ setPendingSelection(undefined)
1446
+ }
1447
+ return
1448
+ }
1449
+ }
1450
+
1451
+ // Normal flow: onSend is just a notification callback that the origin transaction was sent
1452
+ // The actual transaction sending is handled by useSendForm internally
1453
+ // Return resolved promise to ensure async function completes properly
1454
+ return Promise.resolve()
1344
1455
  }
1345
1456
 
1346
1457
  const handleSendAnother = () => {
@@ -1370,6 +1481,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
1370
1481
  // Clear selected fee option, but localStorage preference is preserved
1371
1482
  // Auto-selection will use the preference when fee options render next time
1372
1483
  clearSelectedFeeOption()
1484
+ resetHostTransactionState()
1373
1485
  }, [
1374
1486
  setSelectedFundMethod,
1375
1487
  setDestinationTxHash,
@@ -1382,6 +1494,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
1382
1494
  setCurrentScreen,
1383
1495
  clearHistory,
1384
1496
  clearSelectedFeeOption,
1497
+ resetHostTransactionState,
1385
1498
  ])
1386
1499
 
1387
1500
  // Update the currentScreen state when when the widget receives an updated 'mode' prop passed in by the consuming app.
@@ -1391,16 +1504,57 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
1391
1504
  setCurrentScreen(initialScreen)
1392
1505
  }, [currentMode, getInitialScreenForMode, setCurrentScreen])
1393
1506
 
1507
+ // When pendingSelection exists (from useTrailsSendTransaction),
1508
+ // open the modal and navigate to select-origin-token screen
1509
+ useEffect(() => {
1510
+ if (pendingSelection) {
1511
+ // Open modal if not already open
1512
+ if (!isModalOpen) {
1513
+ openTrailsModal()
1514
+ }
1515
+ // Navigate to select-origin-token screen
1516
+ if (currentScreen !== "select-origin-token") {
1517
+ setCurrentScreen("select-origin-token")
1518
+ }
1519
+ }
1520
+ }, [
1521
+ pendingSelection,
1522
+ isModalOpen,
1523
+ currentScreen,
1524
+ setCurrentScreen,
1525
+ openTrailsModal,
1526
+ ])
1527
+
1394
1528
  const handleOpenModal = useCallback(() => {
1395
- setIsModalOpen(true)
1529
+ openTrailsModal()
1396
1530
  onOpen?.()
1397
- }, [onOpen])
1531
+ }, [openTrailsModal, onOpen])
1398
1532
 
1399
1533
  const handleCloseModal = useCallback(() => {
1400
- setIsModalOpen(false)
1534
+ if (pendingSelection) {
1535
+ logger.console.log(
1536
+ "[trails-sdk] handleCloseModal called, rejecting pending selection",
1537
+ )
1538
+ pendingSelection.reject(new Error("Modal closed by user"))
1539
+ setPendingSelection(undefined)
1540
+ } else {
1541
+ logger.console.log(
1542
+ "[trails-sdk] handleCloseModal called, no pending selection",
1543
+ )
1544
+ }
1545
+ logger.console.log("[trails-sdk] handleCloseModal called, closing modal")
1546
+ closeTrailsModal()
1401
1547
  resetState()
1548
+ resetHostTransactionState()
1402
1549
  onClose?.()
1403
- }, [resetState, onClose])
1550
+ }, [
1551
+ closeTrailsModal,
1552
+ resetState,
1553
+ resetHostTransactionState,
1554
+ onClose,
1555
+ pendingSelection,
1556
+ setPendingSelection,
1557
+ ])
1404
1558
 
1405
1559
  // Expose modal control methods via ref
1406
1560
  useImperativeHandle(
@@ -1454,18 +1608,63 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
1454
1608
  setCurrentScreen("receipt")
1455
1609
  }
1456
1610
 
1457
- function handleMeshConnectComplete(transferData: any) {
1458
- logger.console.log(
1459
- "[trails-sdk] Mesh Connect transfer completed:",
1460
- transferData,
1461
- )
1611
+ async function handleOnrampComplete(transferData: any) {
1612
+ logger.console.log("[trails-sdk] Onramp transfer completed:", transferData)
1462
1613
  logger.console.log(
1463
1614
  "[trails-sdk] Using real transaction states from prepareSendQuote",
1464
1615
  )
1465
- if (prepareSendQuote) {
1466
- setTransactionStates(prepareSendQuote.transactionStates)
1616
+ logger.console.log("[trails-sdk] handleOnrampComplete state:", {
1617
+ hasOnrampContinueSend: !!onrampContinueSend,
1618
+ hasPrepareSendQuote: !!prepareSendQuote,
1619
+ currentScreen,
1620
+ onrampContinueSendInProgress,
1621
+ })
1622
+
1623
+ // Prevent multiple simultaneous calls
1624
+ if (onrampContinueSendInProgress) {
1625
+ logger.console.warn(
1626
+ "[trails-sdk] onrampContinueSend already in progress, ignoring duplicate call",
1627
+ )
1628
+ return
1467
1629
  }
1630
+
1631
+ // Navigate away from onramp screen immediately
1632
+ logger.console.log("[trails-sdk] Navigating away from onramp screen")
1468
1633
  setCurrentScreen("pending")
1634
+
1635
+ // Continue with the send flow after onramp completes
1636
+ if (onrampContinueSend) {
1637
+ logger.console.log(
1638
+ "[trails-sdk] Continuing send flow after onramp completion",
1639
+ )
1640
+ setOnrampContinueSendInProgress(true)
1641
+ try {
1642
+ await onrampContinueSend()
1643
+ logger.console.log(
1644
+ "[trails-sdk] onrampContinueSend completed successfully",
1645
+ )
1646
+ } catch (error) {
1647
+ logger.console.error(
1648
+ "[trails-sdk] Error continuing send after onramp:",
1649
+ error,
1650
+ )
1651
+ handleSendError(error as Error)
1652
+ } finally {
1653
+ setOnrampContinueSend(null)
1654
+ setOnrampContinueSendInProgress(false)
1655
+ }
1656
+ } else {
1657
+ // Fallback: just show pending screen if no continue callback
1658
+ logger.console.log(
1659
+ "[trails-sdk] No onrampContinueSend callback, showing pending screen",
1660
+ )
1661
+ if (prepareSendQuote) {
1662
+ logger.console.log(
1663
+ "[trails-sdk] Setting transaction states from prepareSendQuote",
1664
+ )
1665
+ setTransactionStates(prepareSendQuote.transactionStates)
1666
+ }
1667
+ }
1469
1668
  }
1470
1669
 
1471
1670
  function handleTransactionStateChange(
@@ -1545,12 +1744,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
1545
1744
  }
1546
1745
  }
1547
1746
 
1548
- const handleSelectExchangeList = () => {
1549
- setSelectedFundMethod("exchange")
1550
- setCurrentScreen("mesh-connect-exchanges")
1551
- }
1552
-
1553
- const handleNavigateToMeshConnect = (
1747
+ const handleNavigateToOnramp = (
1554
1748
  props: {
1555
1749
  toTokenSymbol: string
1556
1750
  toTokenAmount: string
@@ -1558,10 +1752,13 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
1558
1752
  toRecipientAddress: string
1559
1753
  },
1560
1754
  quote?: PrepareSendQuote | null,
1755
+ continueSend?: () => Promise<void>,
1561
1756
  ) => {
1562
1757
  setPrepareSendQuote(quote ?? null)
1563
- setMeshConnectProps(props)
1564
- setCurrentScreen("mesh-connect")
1758
+ setOnrampProps(props)
1759
+ setOnrampContinueSend(() => continueSend || null)
1760
+ // Render onramp component directly - it manages its own routing
1761
+ setCurrentScreen("onramp")
1565
1762
  }
1566
1763
 
1567
1764
  const handleSendError = (error: Error | string | null) => {
@@ -1571,14 +1768,14 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
1571
1768
  const errorMessage = getFullErrorMessage(error)
1572
1769
  const isRejected = getIsUserRejectionError(error)
1573
1770
  const isBalanceTooLow = getIsBalanceTooLowError(error)
1574
- const isApiError = getIsApiError(error)
1771
+ const isApiErr = getIsApiError(error)
1575
1772
  const isRateLimited = getIsRateLimitedError(error)
1576
1773
 
1577
1774
  if (isRateLimited) {
1578
1775
  // no-op
1579
1776
  } else if (isRejected) {
1580
1777
  setShowWalletConfirmRetry(true)
1581
- } else if (isBalanceTooLow || isApiError) {
1778
+ } else if (isBalanceTooLow || isApiErr) {
1582
1779
  setShowWalletConfirmRetry(true)
1583
1780
  setError(errorMessage)
1584
1781
  } else {
@@ -1653,7 +1850,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
1653
1850
  )
1654
1851
  // Auto-trigger connection
1655
1852
  setTimeout(() => {
1656
- handleWalletConnect(walletId)
1853
+ handleConnectWallet(walletId)
1657
1854
  }, 100)
1658
1855
  }
1659
1856
  }}
@@ -1670,7 +1867,6 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
1670
1867
  <FundMethods
1671
1868
  onBack={() => goHome()}
1672
1869
  onSelectWalletConnect={handleSelectWalletConnect}
1673
- onSelectExchangeList={handleSelectExchangeList}
1674
1870
  onSelectConnectedAccount={() => {
1675
1871
  setSelectedFundMethod("connected-account")
1676
1872
  setCurrentScreen("home")
@@ -1706,14 +1902,33 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
1706
1902
  onNavigateToFundMethods={() => setCurrentScreen("fund-methods")}
1707
1903
  />
1708
1904
  )
1905
+ case "select-origin-token":
1906
+ return (
1907
+ <TokenList
1908
+ onContinue={handleTokenSelect}
1909
+ onBack={handleCloseModal}
1910
+ targetAmountUsd={null}
1911
+ targetAmountUsdFormatted={null}
1912
+ onError={handleTokenListError}
1913
+ recentTokens={recentTokens}
1914
+ onRecentTokenSelect={handleRecentTokenSelect}
1915
+ fundMethod={null}
1916
+ renderInline={false}
1917
+ />
1918
+ )
1919
+ case "select-origin-amount":
1920
+ return (
1921
+ <OriginSelectionAmount
1922
+ token={selectedToken}
1923
+ onBack={() => setCurrentScreen("select-origin-token")}
1924
+ onCancel={handleCloseModal}
1925
+ onSubmit={handleOriginAmountSubmit}
1926
+ />
1927
+ )
1709
1928
  case "send-form":
1710
1929
  return (
1711
1930
  <Pay
1712
- onBack={
1713
- currentMode === "receive"
1714
- ? () => setCurrentScreen("receive")
1715
- : undefined
1716
- }
1931
+ onBack={undefined}
1717
1932
  selectedToken={selectedToken}
1718
1933
  onSend={handleOnSend}
1719
1934
  onWaitingForWalletConfirm={handleWaitingForWalletConfirm}
@@ -1747,7 +1962,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
1747
1962
  setWalletConfirmRetryHandler={setWalletConfirmRetryHandler}
1748
1963
  quoteProvider={quoteProvider}
1749
1964
  fundMethod={selectedFundMethod}
1750
- onNavigateToMeshConnect={handleNavigateToMeshConnect}
1965
+ onNavigateToOnramp={handleNavigateToOnramp}
1751
1966
  onAmountUpdate={(amount: string) => {
1752
1967
  if (
1753
1968
  selectedPool &&
@@ -1802,23 +2017,44 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
1802
2017
  setWalletConfirmRetryHandler={setWalletConfirmRetryHandler}
1803
2018
  quoteProvider={quoteProvider}
1804
2019
  fundMethod={selectedFundMethod}
1805
- onNavigateToMeshConnect={handleNavigateToMeshConnect}
2020
+ onNavigateToOnramp={handleNavigateToOnramp}
1806
2021
  checkoutOnHandlers={checkoutOnHandlers}
1807
2022
  recentTokens={recentTokens}
1808
2023
  onRecentTokenSelect={handleRecentTokenSelect}
1809
2024
  onTrackToken={handleTrackToken}
1810
2025
  />
1811
2026
  )
1812
- case "wallet-confirmation":
2027
+ case "wallet-confirmation": {
2028
+ // For hook-initiated transactions, use retryEnabled from hostTransactionState
2029
+ const isHookInitiated = hostTransactionState.status !== "idle"
2030
+ const retryEnabled = isHookInitiated
2031
+ ? (hostTransactionState.retryEnabled ?? false)
2032
+ : showWalletConfirmRetry
2033
+
2034
+ // For hook-initiated retry, call the retry function from ref
2035
+ const handleHookRetry = () => {
2036
+ if (retryTransactionRef.current) {
2037
+ // Reset retry flag before retrying
2038
+ setHostTransactionState((prev) => ({
2039
+ ...prev,
2040
+ retryEnabled: false,
2041
+ }))
2042
+ retryTransactionRef.current()
2043
+ }
2044
+ }
2045
+
1813
2046
  return (
1814
2047
  <WalletConfirmation
1815
2048
  onBack={handleBack}
1816
2049
  onComplete={handleWalletConfirmComplete}
1817
- retryEnabled={showWalletConfirmRetry}
1818
- onRetry={handleWalletConfirmRetry}
2050
+ retryEnabled={retryEnabled}
2051
+ onRetry={
2052
+ isHookInitiated ? handleHookRetry : handleWalletConfirmRetry
2053
+ }
1819
2054
  quote={prepareSendQuote}
1820
2055
  />
1821
2056
  )
2057
+ }
1822
2058
  case "qr-code-wallet-select":
1823
2059
  return (
1824
2060
  <QRCodeWalletSelect
@@ -1846,36 +2082,125 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
1846
2082
  onElapsedTime={handleElapsedTime}
1847
2083
  transactionStates={transactionStates}
1848
2084
  quote={prepareSendQuote}
2085
+ timestamp={hostTransactionTimestamp ?? undefined}
1849
2086
  onContinue={() => {
1850
2087
  logger.console.log("[trails-sdk] onContinue called")
1851
2088
  setCurrentScreen("receipt")
1852
2089
  }}
1853
2090
  />
1854
2091
  )
1855
- case "receipt":
2092
+ case "receipt": {
2093
+ // For hook-initiated transactions, use custom receipt action if provided
2094
+ const isHookInitiated = hostTransactionState.status !== "idle"
2095
+ const receiptOnSendAnother = isHookInitiated
2096
+ ? (onReceiptAction ?? undefined)
2097
+ : handleSendAnother
2098
+ const receiptActionText = isHookInitiated
2099
+ ? (receiptActionButtonText ?? undefined)
2100
+ : undefined
2101
+
1856
2102
  return (
1857
2103
  <Receipt
1858
- onSendAnother={handleSendAnother}
2104
+ onSendAnother={receiptOnSendAnother}
1859
2105
  onClose={handleCloseModal}
1860
2106
  renderInline={renderInline}
1861
2107
  transactionStates={transactionStates}
1862
2108
  totalCompletionSeconds={totalCompletionSeconds ?? undefined}
1863
2109
  quote={prepareSendQuote}
1864
2110
  showCloseButton={false}
2111
+ actionButtonText={receiptActionText}
1865
2112
  />
1866
2113
  )
1867
- case "mesh-connect":
1868
- return (
1869
- <MeshConnectFlow
1870
- onBack={handleBack}
1871
- onComplete={handleMeshConnectComplete}
1872
- toTokenSymbol={meshConnectProps?.toTokenSymbol}
1873
- toTokenAmount={meshConnectProps?.toTokenAmount}
1874
- toChainId={meshConnectProps?.toChainId}
1875
- toRecipientAddress={meshConnectProps?.toRecipientAddress}
1876
- selectedExchange={selectedExchange}
1877
- />
1878
- )
2114
+ }
2115
+ case "onramp":
2116
+ logger.console.log("[trails-sdk] Rendering onramp screen", {
2117
+ onrampFactory: !!onrampFactory,
2118
+ onrampProps,
2119
+ })
2120
+
2121
+ // Check if onramp factory function is provided
2122
+ if (!onrampFactory) {
2123
+ // Factory not provided - show fallback UI
2124
+ return (
2125
+ <div className="flex flex-col h-full p-4">
2126
+ <div className="flex items-center mb-4">
2127
+ <button
2128
+ type="button"
2129
+ onClick={handleBack}
2130
+ className="flex h-8 w-8 justify-center items-center rounded-full bg-gray-50 dark:bg-gray-700 cursor-pointer transition-colors text-gray-900 dark:text-gray-200 hover:bg-gray-100 dark:hover:bg-gray-600 mr-2"
2131
+ title="Back"
2132
+ >
2133
+
2134
+ </button>
2135
+ <h2 className="text-lg font-semibold text-gray-900 dark:text-white">
2136
+ Exchange Funding
2137
+ </h2>
2138
+ </div>
2139
+ <div className="flex-1 flex items-center justify-center">
2140
+ <div className="text-center p-4 border border-solid border-gray-200 dark:border-gray-700 rounded-lg">
2141
+ <p className="text-gray-600 dark:text-gray-400 mb-2">
2142
+ Exchange funding is not available.
2143
+ </p>
2144
+ <p className="text-sm text-gray-500 dark:text-gray-500">
2145
+ Please provide an onramp factory function to enable this
2146
+ feature.
2147
+ </p>
2148
+ </div>
2149
+ </div>
2150
+ </div>
2151
+ )
2152
+ }
2153
+
2154
+ // Call the factory function with handlers to get the component
2155
+ try {
2156
+ return (
2157
+ <div className="flex flex-col h-full">
2158
+ {onrampFactory({
2159
+ setCurrentScreen: (screen: string) => {
2160
+ setCurrentScreen(screen as any)
2161
+ },
2162
+ onComplete: handleOnrampComplete,
2163
+ onError: (error) => {
2164
+ logger.console.error("[trails-sdk] Onramp error:", error)
2165
+ },
2166
+ onBack: handleBack,
2167
+ toTokenSymbol: onrampProps?.toTokenSymbol,
2168
+ toTokenAmount: onrampProps?.toTokenAmount,
2169
+ toChainId: onrampProps?.toChainId,
2170
+ toRecipientAddress: onrampProps?.toRecipientAddress,
2171
+ })}
2172
+ </div>
2173
+ )
2174
+ } catch (error) {
2175
+ logger.console.error("[trails-sdk] Error rendering onramp:", error)
2176
+ return (
2177
+ <div className="flex flex-col h-full p-4">
2178
+ <div className="flex items-center mb-4">
2179
+ <button
2180
+ type="button"
2181
+ onClick={handleBack}
2182
+ className="flex h-8 w-8 justify-center items-center rounded-full bg-gray-50 dark:bg-gray-700 cursor-pointer transition-colors text-gray-900 dark:text-gray-200 hover:bg-gray-100 dark:hover:bg-gray-600 mr-2"
2183
+ title="Back"
2184
+ >
2185
+
2186
+ </button>
2187
+ <h2 className="text-lg font-semibold text-gray-900 dark:text-white">
2188
+ Exchange Funding
2189
+ </h2>
2190
+ </div>
2191
+ <div className="flex-1 flex items-center justify-center">
2192
+ <div className="text-center p-4 border border-solid border-red-200 dark:border-red-700 rounded-lg">
2193
+ <p className="text-red-600 dark:text-red-400 mb-2">
2194
+ Error loading exchange funding.
2195
+ </p>
2196
+ <p className="text-sm text-red-500 dark:text-red-500">
2197
+ {error instanceof Error ? error.message : "Unknown error"}
2198
+ </p>
2199
+ </div>
2200
+ </div>
2201
+ </div>
2202
+ )
2203
+ }
1879
2204
  case "wallet-connect":
1880
2205
  return (
1881
2206
  <WalletConnectScreen
@@ -1894,6 +2219,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
1894
2219
  "[trails-sdk] Wallet selected from wallet-list:",
1895
2220
  walletId,
1896
2221
  )
2222
+
1897
2223
  if (
1898
2224
  allWallets.find((w) => w.id === walletId)?.connector ===
1899
2225
  walletConnectConnector
@@ -1919,7 +2245,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
1919
2245
  }, 100)
1920
2246
  // Auto-trigger connection
1921
2247
  setTimeout(() => {
1922
- handleWalletConnect(walletId)
2248
+ handleConnectWallet(walletId)
1923
2249
  }, 100)
1924
2250
  }
1925
2251
  }}
@@ -1947,7 +2273,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
1947
2273
  setWalletConfirmRetryHandler={setWalletConfirmRetryHandler}
1948
2274
  quoteProvider={quoteProvider}
1949
2275
  fundMethod={selectedFundMethod}
1950
- onNavigateToMeshConnect={handleNavigateToMeshConnect}
2276
+ onNavigateToOnramp={handleNavigateToOnramp}
1951
2277
  checkoutOnHandlers={checkoutOnHandlers}
1952
2278
  recentTokens={recentTokens}
1953
2279
  onRecentTokenSelect={handleRecentTokenSelect}
@@ -1987,7 +2313,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
1987
2313
  setWalletConfirmRetryHandler={setWalletConfirmRetryHandler}
1988
2314
  quoteProvider={quoteProvider}
1989
2315
  fundMethod={selectedFundMethod}
1990
- onNavigateToMeshConnect={handleNavigateToMeshConnect}
2316
+ onNavigateToOnramp={handleNavigateToOnramp}
1991
2317
  onAmountUpdate={undefined}
1992
2318
  checkoutOnHandlers={checkoutOnHandlers}
1993
2319
  recentTokens={recentTokens}
@@ -1995,16 +2321,6 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
1995
2321
  onTrackToken={handleTrackToken}
1996
2322
  />
1997
2323
  )
1998
- case "receive":
1999
- return (
2000
- <Receive
2001
- accountAddress={toAddress || ""}
2002
- isConnected={isConnected}
2003
- onConnectWallet={() => setCurrentScreen("connect")}
2004
- onPay={() => setCurrentScreen("send-form")}
2005
- toChainId={toChainId ? Number(toChainId) : undefined}
2006
- />
2007
- )
2008
2324
  case "wallet-connection-pending":
2009
2325
  return (
2010
2326
  <WalletConnectionPending
@@ -2012,7 +2328,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
2012
2328
  onRetry={() => {
2013
2329
  if (selectedWalletId) {
2014
2330
  setShowWalletConnectionRetry(false)
2015
- handleWalletConnect(selectedWalletId)
2331
+ handleConnectWallet(selectedWalletId)
2016
2332
  }
2017
2333
  }}
2018
2334
  selectedWalletId={selectedWalletId || ""}
@@ -2047,8 +2363,6 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
2047
2363
  disconnectHandler={handleWalletDisconnect}
2048
2364
  />
2049
2365
  )
2050
- case "mesh-connect-exchanges":
2051
- return <MeshConnectExchanges onBack={handleBack} />
2052
2366
  case "home": {
2053
2367
  // Navigation handled by useEffect above, otherwise it would cause a loop
2054
2368
  return null
@@ -2060,70 +2374,68 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
2060
2374
 
2061
2375
  const renderScreen = () => {
2062
2376
  return (
2063
- <ModalProvider closeModal={handleCloseModal} isModalOpen={isModalOpen}>
2064
- <ModeProvider
2377
+ <ModeProvider
2378
+ value={{
2379
+ mode: currentMode,
2380
+ }}
2381
+ >
2382
+ <PriceImpactWarningProvider
2065
2383
  value={{
2066
- mode: currentMode,
2384
+ thresholdBps: priceImpactWarningThresholdBps,
2385
+ warningMessage: priceImpactWarningMessage,
2386
+ fallbackBridgeUrl: priceImpactFallbackBridgeUrl,
2067
2387
  }}
2068
2388
  >
2069
- <PriceImpactWarningProvider
2070
- value={{
2071
- thresholdBps: priceImpactWarningThresholdBps,
2072
- warningMessage: priceImpactWarningMessage,
2073
- fallbackBridgeUrl: priceImpactFallbackBridgeUrl,
2389
+ <motion.div
2390
+ initial={{ opacity: 0, scale: 0.95 }}
2391
+ animate={{ opacity: 1, scale: 1 }}
2392
+ exit={{ opacity: 0, scale: 0.95 }}
2393
+ transition={{
2394
+ type: "spring",
2395
+ stiffness: 200,
2396
+ damping: 30,
2397
+ mass: 1,
2074
2398
  }}
2399
+ className="flex flex-col min-h-[400px] shadow-xl p-4 sm:p-6 relative w-full max-w-[400px] min-w-0 sm:w-[400px] mx-auto custom-scrollbar trails-bg-primary trails-text-primary trails-font trails-border-radius-widget trails-widget-border"
2400
+ layout
2401
+ layoutId="modal-container"
2402
+ onClick={(e) => e.stopPropagation()}
2075
2403
  >
2076
- <motion.div
2077
- initial={{ opacity: 0, scale: 0.95 }}
2078
- animate={{ opacity: 1, scale: 1 }}
2079
- exit={{ opacity: 0, scale: 0.95 }}
2080
- transition={{
2081
- type: "spring",
2082
- stiffness: 200,
2083
- damping: 30,
2084
- mass: 1,
2085
- }}
2086
- className="flex flex-col min-h-[400px] shadow-xl p-4 sm:p-6 relative w-full sm:w-[400px] mx-auto custom-scrollbar trails-bg-primary trails-text-primary trails-font trails-border-radius-widget trails-widget-border"
2087
- layout
2088
- layoutId="modal-container"
2089
- onClick={(e) => e.stopPropagation()}
2090
- >
2091
- <AnimatePresence mode="wait">
2092
- <motion.div
2093
- key={currentScreen}
2094
- initial={{ opacity: 0, x: 20 }}
2095
- animate={{ opacity: 1, x: 0 }}
2096
- exit={{ opacity: 0, x: -20 }}
2097
- transition={{
2098
- type: "spring",
2099
- stiffness: 500,
2100
- damping: 30,
2101
- mass: 0.6,
2102
- }}
2103
- className="flex-1 flex flex-col w-full"
2104
- layout
2105
- >
2106
- {renderScreenContent()}
2107
- {/* Error Display */}
2108
- {error && (
2109
- <div className="mt-2">
2110
- <ErrorDisplay
2111
- errorPrettified={getPrettifiedErrorMessage(
2112
- error,
2113
- "An error occured",
2114
- )}
2115
- error={error}
2116
- severity="error"
2117
- />
2118
- </div>
2119
- )}
2120
- </motion.div>
2121
- </AnimatePresence>
2122
- <Footer onDebugScreenSelect={handleDebugScreenSelect} />
2123
- </motion.div>
2124
- </PriceImpactWarningProvider>
2125
- </ModeProvider>
2126
- </ModalProvider>
2404
+ <AnimatePresence mode="wait">
2405
+ <motion.div
2406
+ key={currentScreen}
2407
+ initial={{ opacity: 0, x: 20 }}
2408
+ animate={{ opacity: 1, x: 0 }}
2409
+ exit={{ opacity: 0, x: -20 }}
2410
+ transition={{
2411
+ type: "spring",
2412
+ stiffness: 500,
2413
+ damping: 30,
2414
+ mass: 0.6,
2415
+ }}
2416
+ className="flex-1 flex flex-col w-full min-w-0"
2417
+ layout
2418
+ >
2419
+ {renderScreenContent()}
2420
+ {/* Error Display */}
2421
+ {error && (
2422
+ <div className="mt-2">
2423
+ <ErrorDisplay
2424
+ errorPrettified={getPrettifiedErrorMessage(
2425
+ error,
2426
+ "An error occured",
2427
+ )}
2428
+ error={error}
2429
+ severity="error"
2430
+ />
2431
+ </div>
2432
+ )}
2433
+ </motion.div>
2434
+ </AnimatePresence>
2435
+ <Footer onDebugScreenSelect={handleDebugScreenSelect} />
2436
+ </motion.div>
2437
+ </PriceImpactWarningProvider>
2438
+ </ModeProvider>
2127
2439
  )
2128
2440
  }
2129
2441
 
@@ -2166,48 +2478,11 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
2166
2478
 
2167
2479
  const WidgetInner = forwardRef<TrailsWidgetRef, TrailsWidgetProps>(
2168
2480
  (props, ref) => {
2169
- // Calculate initial screen based on mode and connection state
2170
- // Note: We can't use useAccount here as it needs to be inside WagmiProvider
2171
- // So we'll use a default and let the WidgetContent handle the logic
2172
- const initialScreen: Screen = "home"
2173
-
2174
2481
  return (
2175
- <WidgetPropsProvider props={props}>
2176
- <ToastProvider>
2177
- <CurrentScreenProvider initialScreen={initialScreen}>
2178
- <BackProvider>
2179
- <WalletConnectionProvider>
2180
- <SelectedTokenProvider>
2181
- <DestinationSelectedTokenProvider>
2182
- <SelectedFeeOptionProvider>
2183
- <SelectedRecipientProvider>
2184
- <SwapAmountProvider>
2185
- <ChainFilterProvider>
2186
- <BalanceVisibleProvider>
2187
- <ThemePreferenceProvider>
2188
- <SelectedFundMethodProvider>
2189
- <ThemeSyncer />
2190
- <EarnPoolProvider>
2191
- <SelectedMeshExchangeProvider>
2192
- <DefaultTokenSelectionProvider>
2193
- <WidgetContent ref={ref} />
2194
- </DefaultTokenSelectionProvider>
2195
- </SelectedMeshExchangeProvider>
2196
- </EarnPoolProvider>
2197
- </SelectedFundMethodProvider>
2198
- </ThemePreferenceProvider>
2199
- </BalanceVisibleProvider>
2200
- </ChainFilterProvider>
2201
- </SwapAmountProvider>
2202
- </SelectedRecipientProvider>
2203
- </SelectedFeeOptionProvider>
2204
- </DestinationSelectedTokenProvider>
2205
- </SelectedTokenProvider>
2206
- </WalletConnectionProvider>
2207
- </BackProvider>
2208
- </CurrentScreenProvider>
2209
- </ToastProvider>
2210
- </WidgetPropsProvider>
2482
+ <WidgetProviders props={props}>
2483
+ <ThemeSyncer />
2484
+ <WidgetContent ref={ref} />
2485
+ </WidgetProviders>
2211
2486
  )
2212
2487
  },
2213
2488
  )
@@ -2215,6 +2490,8 @@ const WidgetInner = forwardRef<TrailsWidgetRef, TrailsWidgetProps>(
2215
2490
  export const TrailsWidget = forwardRef<TrailsWidgetRef, TrailsWidgetProps>(
2216
2491
  (props, ref) => {
2217
2492
  const wagmiContext = useContext(WagmiContext)
2493
+ const trailsContext = useContext(TrailsContext)
2494
+ const hasParentTrailsProvider = Boolean(trailsContext)
2218
2495
 
2219
2496
  // Validate required props
2220
2497
  if (!props.apiKey) {
@@ -2276,48 +2553,34 @@ export const TrailsWidget = forwardRef<TrailsWidgetRef, TrailsWidgetProps>(
2276
2553
  debug: props.debug,
2277
2554
  }
2278
2555
 
2279
- // Create content with only the providers that don't exist in parent
2280
- const content = (() => {
2281
- const widgetContent = (
2282
- <ThemeProvider initialTheme={props.theme}>
2283
- <WidgetInner {...props} ref={ref} />
2284
- </ThemeProvider>
2285
- )
2556
+ const shouldWrapWithWagmiProvider = props.decoupleWagmi || !wagmiContext
2557
+ const shouldWrapWithTrailsProvider = !hasParentTrailsProvider
2286
2558
 
2287
- if (props.decoupleWagmi) {
2288
- return (
2289
- <TrailsProvider config={trailsConfig}>
2290
- <AaveProvider client={aaveClient}>
2291
- <QueryClientProvider client={queryClient}>
2292
- <WagmiProvider config={wagmiConfig}>
2293
- {widgetContent}
2294
- </WagmiProvider>
2295
- </QueryClientProvider>
2296
- </AaveProvider>
2297
- </TrailsProvider>
2298
- )
2299
- }
2559
+ const widgetContent = (
2560
+ <ThemeProvider initialTheme={props.theme}>
2561
+ <WidgetInner {...props} ref={ref} />
2562
+ </ThemeProvider>
2563
+ )
2300
2564
 
2301
- const baseContent = (
2302
- <TrailsProvider config={trailsConfig}>
2303
- <AaveProvider client={aaveClient}>
2304
- <QueryClientProvider client={queryClient}>
2305
- {wagmiContext ? (
2306
- // WagmiProvider exists in parent, don't wrap
2307
- widgetContent
2308
- ) : (
2309
- // WagmiProvider missing, wrap with it
2310
- <WagmiProvider config={wagmiConfig}>
2311
- {widgetContent}
2312
- </WagmiProvider>
2313
- )}
2314
- </QueryClientProvider>
2315
- </AaveProvider>
2316
- </TrailsProvider>
2317
- )
2565
+ const wagmiWrappedContent = shouldWrapWithWagmiProvider ? (
2566
+ <WagmiProvider config={wagmiConfig}>{widgetContent}</WagmiProvider>
2567
+ ) : (
2568
+ widgetContent
2569
+ )
2570
+
2571
+ const queryClientWrappedContent = (
2572
+ <QueryClientProvider client={queryClient}>
2573
+ {wagmiWrappedContent}
2574
+ </QueryClientProvider>
2575
+ )
2318
2576
 
2319
- return baseContent
2320
- })()
2577
+ const content = shouldWrapWithTrailsProvider ? (
2578
+ <TrailsProvider config={trailsConfig}>
2579
+ {queryClientWrappedContent}
2580
+ </TrailsProvider>
2581
+ ) : (
2582
+ queryClientWrappedContent
2583
+ )
2321
2584
 
2322
2585
  const customCss = useMemo(() => {
2323
2586
  if (props.customCss instanceof Object) {
@@ -2338,56 +2601,6 @@ export const TrailsWidget = forwardRef<TrailsWidgetRef, TrailsWidgetProps>(
2338
2601
  },
2339
2602
  )
2340
2603
 
2341
- export function ShadowPortal({
2342
- children,
2343
- customCss,
2344
- }: {
2345
- children: React.ReactNode
2346
- customCss?: string | Record<string, string>
2347
- }): React.JSX.Element {
2348
- const hostRef = useRef<HTMLDivElement>(null)
2349
- const [shadowRoot, setShadowRoot] = useState<ShadowRoot | null>(null)
2350
-
2351
- useEffect(() => {
2352
- if (hostRef.current && !hostRef.current.shadowRoot) {
2353
- const shadow = hostRef.current.attachShadow({ mode: "open" })
2354
- setShadowRoot(shadow)
2355
-
2356
- // Inject <style> tag with your widget's CSS
2357
- const styleTag = document.createElement("style")
2358
- styleTag.textContent = css
2359
- shadow.appendChild(styleTag)
2360
- }
2361
- }, [])
2362
-
2363
- // Update custom CSS when it changes
2364
- useEffect(() => {
2365
- if (shadowRoot) {
2366
- // Remove any existing custom CSS
2367
- const existingCustomStyles = shadowRoot.querySelectorAll(
2368
- 'style[id="custom-css"]',
2369
- )
2370
- existingCustomStyles.forEach((style) => {
2371
- style.remove()
2372
- })
2373
-
2374
- // Inject new custom CSS if provided
2375
- if (customCss) {
2376
- const customStyleTag = document.createElement("style")
2377
- customStyleTag.id = "custom-css"
2378
- customStyleTag.textContent = `:root, [data-theme="light"], [data-theme="dark"] { ${customCss} }`
2379
- shadowRoot.appendChild(customStyleTag)
2380
- }
2381
- }
2382
- }, [customCss, shadowRoot])
2383
-
2384
- return (
2385
- <div ref={hostRef}>
2386
- {shadowRoot ? createPortal(children, shadowRoot) : null}
2387
- </div>
2388
- )
2389
- }
2390
-
2391
2604
  // Export standalone functions for modal control
2392
2605
  export const createModalController = (
2393
2606
  ref: React.RefObject<TrailsWidgetRef>,