0xtrails 0.0.1 → 0.0.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 (359) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +42 -0
  3. package/dist/abi.d.ts +37 -0
  4. package/dist/abi.d.ts.map +1 -0
  5. package/dist/abi.js +36 -0
  6. package/dist/apiClient.d.ts +9 -0
  7. package/dist/apiClient.d.ts.map +1 -0
  8. package/dist/apiClient.js +18 -0
  9. package/dist/buffer.d.ts +3 -0
  10. package/dist/buffer.d.ts.map +1 -0
  11. package/dist/buffer.js +8 -0
  12. package/dist/cctp.d.ts +84 -0
  13. package/dist/cctp.d.ts.map +1 -0
  14. package/dist/cctp.js +401 -0
  15. package/dist/chainSwitch.d.ts +7 -0
  16. package/dist/chainSwitch.d.ts.map +1 -0
  17. package/dist/chainSwitch.js +33 -0
  18. package/dist/chains.d.ts +13 -0
  19. package/dist/chains.d.ts.map +1 -0
  20. package/dist/chains.js +95 -0
  21. package/dist/constants.d.ts +11 -0
  22. package/dist/constants.d.ts.map +1 -0
  23. package/dist/constants.js +16 -0
  24. package/dist/encoders.d.ts +7 -0
  25. package/dist/encoders.d.ts.map +1 -0
  26. package/dist/encoders.js +8 -0
  27. package/dist/error.d.ts +2 -0
  28. package/dist/error.d.ts.map +1 -0
  29. package/dist/error.js +12 -0
  30. package/dist/explorer.d.ts +12 -0
  31. package/dist/explorer.d.ts.map +1 -0
  32. package/dist/explorer.js +18 -0
  33. package/dist/gasless.d.ts +116 -0
  34. package/dist/gasless.d.ts.map +1 -0
  35. package/dist/gasless.js +297 -0
  36. package/dist/index.d.ts +13 -0
  37. package/dist/index.d.ts.map +1 -0
  38. package/dist/index.js +9 -0
  39. package/dist/indexerClient.d.ts +9 -0
  40. package/dist/indexerClient.d.ts.map +1 -0
  41. package/dist/indexerClient.js +18 -0
  42. package/dist/intents.d.ts +83 -0
  43. package/dist/intents.d.ts.map +1 -0
  44. package/dist/intents.js +288 -0
  45. package/dist/metaTxnMonitor.d.ts +14 -0
  46. package/dist/metaTxnMonitor.d.ts.map +1 -0
  47. package/dist/metaTxnMonitor.js +121 -0
  48. package/dist/metaTxns.d.ts +6 -0
  49. package/dist/metaTxns.d.ts.map +1 -0
  50. package/dist/metaTxns.js +4 -0
  51. package/dist/paymasterSend.d.ts +90 -0
  52. package/dist/paymasterSend.d.ts.map +1 -0
  53. package/dist/paymasterSend.js +329 -0
  54. package/dist/preconditions.d.ts +11 -0
  55. package/dist/preconditions.d.ts.map +1 -0
  56. package/dist/preconditions.js +29 -0
  57. package/dist/prepareSend.d.ts +102 -0
  58. package/dist/prepareSend.d.ts.map +1 -0
  59. package/dist/prepareSend.js +1080 -0
  60. package/dist/prices.d.ts +18 -0
  61. package/dist/prices.d.ts.map +1 -0
  62. package/dist/prices.js +142 -0
  63. package/dist/queryParams.d.ts +9 -0
  64. package/dist/queryParams.d.ts.map +1 -0
  65. package/dist/queryParams.js +66 -0
  66. package/dist/relaySdk.d.ts +65 -0
  67. package/dist/relaySdk.d.ts.map +1 -0
  68. package/dist/relaySdk.js +314 -0
  69. package/dist/relayer.d.ts +23 -0
  70. package/dist/relayer.d.ts.map +1 -0
  71. package/dist/relayer.js +230 -0
  72. package/dist/sendUserOp.d.ts +140 -0
  73. package/dist/sendUserOp.d.ts.map +1 -0
  74. package/dist/sendUserOp.js +388 -0
  75. package/dist/sequenceWallet.d.ts +79 -0
  76. package/dist/sequenceWallet.d.ts.map +1 -0
  77. package/dist/sequenceWallet.js +374 -0
  78. package/dist/theme.d.ts +3 -0
  79. package/dist/theme.d.ts.map +1 -0
  80. package/dist/theme.js +1 -0
  81. package/dist/toSimpleSmartAccount.d.ts +95 -0
  82. package/dist/toSimpleSmartAccount.d.ts.map +1 -0
  83. package/dist/toSimpleSmartAccount.js +373 -0
  84. package/dist/tokenBalances.d.ts +118 -0
  85. package/dist/tokenBalances.d.ts.map +1 -0
  86. package/dist/tokenBalances.js +492 -0
  87. package/dist/tokens.d.ts +50 -0
  88. package/dist/tokens.d.ts.map +1 -0
  89. package/dist/tokens.js +356 -0
  90. package/dist/trails.d.ts +128 -0
  91. package/dist/trails.d.ts.map +1 -0
  92. package/dist/trails.js +1031 -0
  93. package/dist/umd/trails.min.js +12610 -0
  94. package/dist/umd/trails.min.js.map +1 -0
  95. package/dist/umd.d.ts +24 -0
  96. package/dist/umd.d.ts.map +1 -0
  97. package/dist/utils.d.ts +5 -0
  98. package/dist/utils.d.ts.map +1 -0
  99. package/dist/utils.js +9 -0
  100. package/dist/widget/ConstantsUtil-B-_-u8aQ.js +6 -0
  101. package/dist/widget/add-hVLs3ldJ.js +20 -0
  102. package/dist/widget/all-wallets-Cwxnx4BT.js +11 -0
  103. package/dist/widget/app-store-CAAVQjW0.js +22 -0
  104. package/dist/widget/apple-C3BSbglw.js +23 -0
  105. package/dist/widget/arrow-bottom-circle-BGU9MmsZ.js +16 -0
  106. package/dist/widget/arrow-bottom-hS_SA8Gp.js +13 -0
  107. package/dist/widget/arrow-left-CJZanWz7.js +13 -0
  108. package/dist/widget/arrow-right-C1qL8EMd.js +13 -0
  109. package/dist/widget/arrow-top-CbuCmbQs.js +13 -0
  110. package/dist/widget/bank-CXBEEGbb.js +19 -0
  111. package/dist/widget/bin-Dqzv3zCZ.js +9 -0
  112. package/dist/widget/bitcoin-4y3sovZp.js +18 -0
  113. package/dist/widget/browser-DyOl4_8m.js +1413 -0
  114. package/dist/widget/browser-t7Fh0sEU.js +19 -0
  115. package/dist/widget/card-Bo4CZkTs.js +19 -0
  116. package/dist/widget/ccip-BynehMIN.js +232 -0
  117. package/dist/widget/checkmark-DV6OKvnY.js +16 -0
  118. package/dist/widget/checkmark-bold-CAp1-IQ2.js +13 -0
  119. package/dist/widget/chevron-bottom-BjzsVzk9.js +13 -0
  120. package/dist/widget/chevron-left-CQZBDCiR.js +13 -0
  121. package/dist/widget/chevron-right-Dhg4zeZM.js +13 -0
  122. package/dist/widget/chevron-top-CDQmfJef.js +13 -0
  123. package/dist/widget/chrome-store-BNaC_b6w.js +66 -0
  124. package/dist/widget/circle-BC_GBj91.js +9 -0
  125. package/dist/widget/clock-BmF8-4a0.js +13 -0
  126. package/dist/widget/close-Bf61nZ8o.js +13 -0
  127. package/dist/widget/coinPlaceholder-7cZW2058.js +13 -0
  128. package/dist/widget/compass-CFC3yhnW.js +13 -0
  129. package/dist/widget/components/ChainImage.d.ts +8 -0
  130. package/dist/widget/components/ChainImage.d.ts.map +1 -0
  131. package/dist/widget/components/ChainImage.js +6 -0
  132. package/dist/widget/components/ConnectWallet.d.ts +18 -0
  133. package/dist/widget/components/ConnectWallet.d.ts.map +1 -0
  134. package/dist/widget/components/ConnectWallet.js +66 -0
  135. package/dist/widget/components/DebugScreensDropdown.d.ts +9 -0
  136. package/dist/widget/components/DebugScreensDropdown.d.ts.map +1 -0
  137. package/dist/widget/components/DebugScreensDropdown.js +40 -0
  138. package/dist/widget/components/FeeOptions.d.ts +17 -0
  139. package/dist/widget/components/FeeOptions.d.ts.map +1 -0
  140. package/dist/widget/components/FeeOptions.js +65 -0
  141. package/dist/widget/components/Footer.d.ts +9 -0
  142. package/dist/widget/components/Footer.d.ts.map +1 -0
  143. package/dist/widget/components/Footer.js +13 -0
  144. package/dist/widget/components/GreenCheckAnimation.d.ts +2 -0
  145. package/dist/widget/components/GreenCheckAnimation.d.ts.map +1 -0
  146. package/dist/widget/components/GreenCheckAnimation.js +74 -0
  147. package/dist/widget/components/Modal.d.ts +11 -0
  148. package/dist/widget/components/Modal.d.ts.map +1 -0
  149. package/dist/widget/components/Modal.js +36 -0
  150. package/dist/widget/components/Receipt.d.ts +13 -0
  151. package/dist/widget/components/Receipt.d.ts.map +1 -0
  152. package/dist/widget/components/Receipt.js +36 -0
  153. package/dist/widget/components/SendForm.d.ts +44 -0
  154. package/dist/widget/components/SendForm.d.ts.map +1 -0
  155. package/dist/widget/components/SendForm.js +177 -0
  156. package/dist/widget/components/TokenImage.d.ts +10 -0
  157. package/dist/widget/components/TokenImage.d.ts.map +1 -0
  158. package/dist/widget/components/TokenImage.js +8 -0
  159. package/dist/widget/components/TokenList.d.ts +16 -0
  160. package/dist/widget/components/TokenList.d.ts.map +1 -0
  161. package/dist/widget/components/TokenList.js +39 -0
  162. package/dist/widget/components/TransferPending.d.ts +11 -0
  163. package/dist/widget/components/TransferPending.d.ts.map +1 -0
  164. package/dist/widget/components/TransferPending.js +77 -0
  165. package/dist/widget/components/TransferPendingVertical.d.ts +18 -0
  166. package/dist/widget/components/TransferPendingVertical.d.ts.map +1 -0
  167. package/dist/widget/components/TransferPendingVertical.js +183 -0
  168. package/dist/widget/components/WalletConfirmation.d.ts +18 -0
  169. package/dist/widget/components/WalletConfirmation.d.ts.map +1 -0
  170. package/dist/widget/components/WalletConfirmation.js +22 -0
  171. package/dist/widget/config.d.ts +4 -0
  172. package/dist/widget/config.d.ts.map +1 -0
  173. package/dist/widget/config.js +3 -0
  174. package/dist/widget/copy-e0xXvKN0.js +20 -0
  175. package/dist/widget/cursor-CqM3v0xJ.js +8 -0
  176. package/dist/widget/cursor-transparent-CUQpdsCG.js +17 -0
  177. package/dist/widget/desktop-DUDGIRpM.js +14 -0
  178. package/dist/widget/disconnect-DUFST9QQ.js +13 -0
  179. package/dist/widget/discord-C1cj365Z.js +22 -0
  180. package/dist/widget/email-BHhmb_lX.js +703 -0
  181. package/dist/widget/embedded-wallet-CuuC4eah.js +467 -0
  182. package/dist/widget/ethereum-CfmBVfeB.js +15 -0
  183. package/dist/widget/etherscan-BSiynDhW.js +11 -0
  184. package/dist/widget/exclamation-triangle-DEiFNpHw.js +9 -0
  185. package/dist/widget/extension-mRmfCDxo.js +13 -0
  186. package/dist/widget/external-link-B4xMIVnW.js +13 -0
  187. package/dist/widget/facebook-CBAZStBR.js +31 -0
  188. package/dist/widget/farcaster-LHDEDf5S.js +17 -0
  189. package/dist/widget/filters-CBijuvFv.js +13 -0
  190. package/dist/widget/github-C3ILD420.js +23 -0
  191. package/dist/widget/google-CSj73POX.js +23 -0
  192. package/dist/widget/help-circle-2hdG5IdB.js +17 -0
  193. package/dist/widget/hooks/useAmountUsd.d.ts +13 -0
  194. package/dist/widget/hooks/useAmountUsd.d.ts.map +1 -0
  195. package/dist/widget/hooks/useAmountUsd.js +35 -0
  196. package/dist/widget/hooks/useSendForm.d.ts +125 -0
  197. package/dist/widget/hooks/useSendForm.d.ts.map +1 -0
  198. package/dist/widget/hooks/useSendForm.js +450 -0
  199. package/dist/widget/hooks/useTokenList.d.ts +52 -0
  200. package/dist/widget/hooks/useTokenList.d.ts.map +1 -0
  201. package/dist/widget/hooks/useTokenList.js +252 -0
  202. package/dist/widget/id-ByYSrwsd.js +17 -0
  203. package/dist/widget/if-defined-DRXJEhv7.js +752 -0
  204. package/dist/widget/image-C90L4Rf6.js +9 -0
  205. package/dist/widget/index-B3SlQ9v3.js +46 -0
  206. package/dist/widget/index-B8LPuLXQ.js +78 -0
  207. package/dist/widget/index-BDbworWA.js +171 -0
  208. package/dist/widget/index-BTlDgFSK.js +98 -0
  209. package/dist/widget/index-BUCcjXbd.js +306 -0
  210. package/dist/widget/index-BZ34edi2.js +1055 -0
  211. package/dist/widget/index-BiCU29wK.js +147 -0
  212. package/dist/widget/index-BlmqIKsY.js +266 -0
  213. package/dist/widget/index-BlviH5nG.js +55 -0
  214. package/dist/widget/index-Bwd5X3fS.js +8306 -0
  215. package/dist/widget/index-C5gmknHK.js +78 -0
  216. package/dist/widget/index-CD6dBcRj.js +76 -0
  217. package/dist/widget/index-CDlhy529.js +63 -0
  218. package/dist/widget/index-CHXa5ke-.js +59 -0
  219. package/dist/widget/index-CK94R-H7.js +22498 -0
  220. package/dist/widget/index-CQzo3m3x.js +182 -0
  221. package/dist/widget/index-CRT8cAwG.js +325 -0
  222. package/dist/widget/index-CY7Lt2Yu.js +310 -0
  223. package/dist/widget/index-CiKfAu1E.js +79 -0
  224. package/dist/widget/index-CkCu6rMi.js +258 -0
  225. package/dist/widget/index-CngLTu_R.js +517 -0
  226. package/dist/widget/index-CsMV8-em.js +2577 -0
  227. package/dist/widget/index-Cu2Wva8v.js +200 -0
  228. package/dist/widget/index-DKBxLTEF.js +240 -0
  229. package/dist/widget/index-DQEVT3dx.js +511 -0
  230. package/dist/widget/index-DU2HcCis.js +200 -0
  231. package/dist/widget/index-DutZGWNW.js +321 -0
  232. package/dist/widget/index-O0glArmc.js +182 -0
  233. package/dist/widget/index-O8FmRjKe.js +63719 -0
  234. package/dist/widget/index-RtKXrB6I.js +576 -0
  235. package/dist/widget/index-TIYtS0gE.js +88 -0
  236. package/dist/widget/index-dQNJvWHs.js +66 -0
  237. package/dist/widget/index-wmEwdsq7.js +909 -0
  238. package/dist/widget/index.d.ts +3 -0
  239. package/dist/widget/index.d.ts.map +1 -0
  240. package/dist/widget/index.js +2 -0
  241. package/dist/widget/info-DMPChDjV.js +8 -0
  242. package/dist/widget/info-circle-DAvS_7nY.js +17 -0
  243. package/dist/widget/lightbulb-DnZ9mNEs.js +8 -0
  244. package/dist/widget/lit-html-BRjl1r6K.js +243 -0
  245. package/dist/widget/mail-DpaVSOP8.js +13 -0
  246. package/dist/widget/mobile-CRvdyu7I.js +14 -0
  247. package/dist/widget/more-C5VqW9PR.js +16 -0
  248. package/dist/widget/network-placeholder-CZ0vApma.js +19 -0
  249. package/dist/widget/nftPlaceholder-7jjIK2bT.js +13 -0
  250. package/dist/widget/off-4mHjJLLX.js +9 -0
  251. package/dist/widget/onramp-Bc0ozVsw.js +929 -0
  252. package/dist/widget/play-store-Uocul8nC.js +37 -0
  253. package/dist/widget/plus-DrYF7siO.js +18 -0
  254. package/dist/widget/prepareSend-BQJmzM5B.js +54987 -0
  255. package/dist/widget/qr-code-DcnGMUB3.js +11 -0
  256. package/dist/widget/receive-fvIVd7R_.js +184 -0
  257. package/dist/widget/recycle-horizontal-DrDwXC4D.js +14 -0
  258. package/dist/widget/ref-CXNmEjML.js +41 -0
  259. package/dist/widget/refresh-OK9lIPLS.js +13 -0
  260. package/dist/widget/reown-logo-C-Qn7mS3.js +17 -0
  261. package/dist/widget/search-DZqv1oKg.js +13 -0
  262. package/dist/widget/send-CJlmI-xe.js +1039 -0
  263. package/dist/widget/send-otoEC8uU.js +20 -0
  264. package/dist/widget/socials-BJciurWF.js +599 -0
  265. package/dist/widget/solana-Bv5Hs_0T.js +18 -0
  266. package/dist/widget/swapHorizontal-BzOPGV37.js +13 -0
  267. package/dist/widget/swapHorizontalBold-axyHnSmj.js +13 -0
  268. package/dist/widget/swapHorizontalMedium-C6YOPfPz.js +21 -0
  269. package/dist/widget/swapHorizontalRoundedBold-yVcLbWNT.js +13 -0
  270. package/dist/widget/swapVertical-BDjxt9pE.js +13 -0
  271. package/dist/widget/swaps-DEWNj4kd.js +1637 -0
  272. package/dist/widget/telegram-BQJD7dlP.js +21 -0
  273. package/dist/widget/three-dots-DW9jmSMG.js +10 -0
  274. package/dist/widget/transactions-uCseGQQt.js +38 -0
  275. package/dist/widget/twitch-XugxDfOE.js +23 -0
  276. package/dist/widget/twitterIcon-DQVObQUL.js +11 -0
  277. package/dist/widget/types.d.ts +51 -0
  278. package/dist/widget/types.d.ts.map +1 -0
  279. package/dist/widget/types.js +1 -0
  280. package/dist/widget/verify-DpMYHxLf.js +13 -0
  281. package/dist/widget/verify-filled-KpEL6ZJ_.js +13 -0
  282. package/dist/widget/w3m-modal-C8e-6Kba.js +1047 -0
  283. package/dist/widget/wallet-D8ssEB0o.js +13 -0
  284. package/dist/widget/wallet-placeholder-HtAy21Wc.js +19 -0
  285. package/dist/widget/walletconnect-Bp_4XfrY.js +37 -0
  286. package/dist/widget/warning-circle-FgYS7P7n.js +17 -0
  287. package/dist/widget/widget/index.js +7 -0
  288. package/dist/widget/widget.d.ts +47 -0
  289. package/dist/widget/widget.d.ts.map +1 -0
  290. package/dist/widget/widget.js +932 -0
  291. package/dist/widget/x-DlZBoP9k.js +17 -0
  292. package/dist/widget/x-mark-Ba9pt-_h.js +8 -0
  293. package/package.json +102 -8
  294. package/src/abi.ts +38 -0
  295. package/src/apiClient.ts +32 -0
  296. package/src/buffer.ts +10 -0
  297. package/src/cctp.ts +579 -0
  298. package/src/chainSwitch.ts +55 -0
  299. package/src/chains.ts +124 -0
  300. package/src/constants.ts +26 -0
  301. package/src/encoders.ts +20 -0
  302. package/src/error.ts +15 -0
  303. package/src/explorer.ts +37 -0
  304. package/src/gasless.ts +545 -0
  305. package/src/index.ts +48 -0
  306. package/src/indexerClient.ts +36 -0
  307. package/src/intents.ts +537 -0
  308. package/src/metaTxnMonitor.ts +163 -0
  309. package/src/metaTxns.ts +21 -0
  310. package/src/paymasterSend.ts +503 -0
  311. package/src/preconditions.ts +52 -0
  312. package/src/prepareSend.ts +1849 -0
  313. package/src/prices.ts +186 -0
  314. package/src/queryParams.ts +80 -0
  315. package/src/relaySdk.ts +481 -0
  316. package/src/relayer.ts +255 -0
  317. package/src/sendUserOp.ts +570 -0
  318. package/src/sequenceWallet.ts +579 -0
  319. package/src/theme.ts +2 -0
  320. package/src/toSimpleSmartAccount.ts +567 -0
  321. package/src/tokenBalances.ts +760 -0
  322. package/src/tokens.ts +471 -0
  323. package/src/trails.ts +1591 -0
  324. package/src/types.d.ts +11 -0
  325. package/src/umd.tsx +49 -0
  326. package/src/utils.ts +16 -0
  327. package/src/vite-env.d.ts +4 -0
  328. package/src/widget/assets/MetaMask-icon-fox-with-margins.svg +31 -0
  329. package/src/widget/assets/MetaMask-icon-fox.svg +26 -0
  330. package/src/widget/assets/MetaMask-logo-black.svg +3 -0
  331. package/src/widget/assets/MetaMask-logo-white.svg +16 -0
  332. package/src/widget/assets/Privy_Brandmark_Black.svg +9 -0
  333. package/src/widget/assets/Privy_Brandmark_White.svg +9 -0
  334. package/src/widget/assets/Trails-logo-black.svg +11 -0
  335. package/src/widget/assets/Trails-logo-white.svg +11 -0
  336. package/src/widget/components/ChainImage.tsx +28 -0
  337. package/src/widget/components/ConnectWallet.tsx +206 -0
  338. package/src/widget/components/DebugScreensDropdown.tsx +88 -0
  339. package/src/widget/components/FeeOptions.tsx +199 -0
  340. package/src/widget/components/Footer.tsx +51 -0
  341. package/src/widget/components/GreenCheckAnimation.tsx +119 -0
  342. package/src/widget/components/Modal.tsx +97 -0
  343. package/src/widget/components/Receipt.tsx +237 -0
  344. package/src/widget/components/SendForm.tsx +695 -0
  345. package/src/widget/components/TokenImage.tsx +37 -0
  346. package/src/widget/components/TokenList.tsx +287 -0
  347. package/src/widget/components/TransferPending.tsx +204 -0
  348. package/src/widget/components/TransferPendingVertical.tsx +412 -0
  349. package/src/widget/components/WalletConfirmation.tsx +172 -0
  350. package/src/widget/config.ts +5 -0
  351. package/src/widget/hooks/useAmountUsd.ts +59 -0
  352. package/src/widget/hooks/useSendForm.ts +715 -0
  353. package/src/widget/hooks/useTokenList.ts +397 -0
  354. package/src/widget/index.css +2 -0
  355. package/src/widget/index.tsx +8 -0
  356. package/src/widget/types/svg.d.ts +8 -0
  357. package/src/widget/types.ts +59 -0
  358. package/src/widget/widget.tsx +1438 -0
  359. package/index.js +0 -1
@@ -0,0 +1,715 @@
1
+ import type { TokenPrice } from "@0xsequence/trails-api"
2
+ import type { MetaTxnReceipt } from "@0xsequence/trails-relayer"
3
+ import type React from "react"
4
+ import { useCallback, useEffect, useMemo, useState } from "react"
5
+ import {
6
+ type Account,
7
+ formatUnits,
8
+ getAddress,
9
+ isAddress,
10
+ parseUnits,
11
+ type TransactionReceipt,
12
+ type WalletClient,
13
+ } from "viem"
14
+ import { mainnet } from "viem/chains"
15
+ import { useEnsAddress } from "wagmi"
16
+ import { useAPIClient } from "../../apiClient.js"
17
+ import { getChainInfo, useSupportedChains } from "../../chains.js"
18
+ import { getFullErrorMessage } from "../../error.js"
19
+ import { prepareSend, type TransactionState } from "../../prepareSend.js"
20
+ import { useTokenPrices } from "../../prices.js"
21
+ import { useQueryParams } from "../../queryParams.js"
22
+ import { getRelayer, type RelayerEnv } from "../../relayer.js"
23
+ import type { Theme } from "../../theme.js"
24
+ import {
25
+ formatBalance,
26
+ formatUsdValue,
27
+ formatValue,
28
+ } from "../../tokenBalances.js"
29
+ import type { SupportedToken } from "../../tokens.js"
30
+ import {
31
+ useSupportedTokens,
32
+ useTokenAddress,
33
+ useTokenInfo,
34
+ } from "../../tokens.js"
35
+ import { DEFAULT_USE_V3_RELAYERS } from "../../constants.js"
36
+
37
+ export interface Token {
38
+ id: number
39
+ name: string
40
+ symbol: string
41
+ balance: string
42
+ imageUrl: string
43
+ chainId: number
44
+ contractAddress: string
45
+ tokenPriceUsd?: number
46
+ balanceUsdFormatted?: string
47
+ contractInfo?: {
48
+ decimals: number
49
+ symbol: string
50
+ name: string
51
+ }
52
+ }
53
+
54
+ export type TokenInfo = {
55
+ symbol: string
56
+ name: string
57
+ imageUrl: string
58
+ decimals: number
59
+ }
60
+
61
+ type ChainInfo = {
62
+ id: number
63
+ name: string
64
+ imageUrl?: string
65
+ }
66
+
67
+ type PaymasterUrl = {
68
+ chainId: number
69
+ url: string
70
+ }
71
+
72
+ // Add FEE_TOKENS constant after SUPPORTED_TOKENS
73
+ const FEE_TOKENS: TokenInfo[] = [
74
+ {
75
+ symbol: "ETH",
76
+ name: "Ethereum",
77
+ imageUrl: `https://assets.sequence.info/images/tokens/large/1/0x0000000000000000000000000000000000000000.webp`,
78
+ decimals: 18,
79
+ },
80
+ {
81
+ symbol: "USDC",
82
+ name: "USD Coin",
83
+ imageUrl: `https://assets.sequence.info/images/tokens/large/1/0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48.webp`,
84
+ decimals: 6,
85
+ },
86
+ ]
87
+
88
+ export type OnCompleteProps = {
89
+ originChainId: number
90
+ destinationChainId: number
91
+ originUserTxReceipt: TransactionReceipt | null
92
+ originMetaTxnReceipt: MetaTxnReceipt | null
93
+ destinationMetaTxnReceipt: MetaTxnReceipt | null
94
+ }
95
+
96
+ export type UseSendProps = {
97
+ account: Account
98
+ sequenceProjectAccessKey: string
99
+ apiUrl?: string
100
+ env?: RelayerEnv
101
+ toAmount?: string
102
+ toRecipient?: string
103
+ toChainId?: number
104
+ toToken?: string
105
+ toCalldata?: string
106
+ walletClient: WalletClient
107
+ theme: Theme
108
+ onTransactionStateChange: (transactionStates: TransactionState[]) => void
109
+ useSourceTokenForButtonText: boolean
110
+ onError: (error: Error | string | null) => void
111
+ onWaitingForWalletConfirm: (
112
+ intentAddress: string,
113
+ details: {
114
+ amount: string
115
+ amountUsd: string
116
+ tokenSymbol: string
117
+ tokenName: string
118
+ chainId: number
119
+ imageUrl: string
120
+ },
121
+ ) => void
122
+ paymasterUrls?: PaymasterUrl[]
123
+ gasless?: boolean
124
+ onSend: (amount: string, recipient: string) => void
125
+ onConfirm: () => void
126
+ onComplete: (result: OnCompleteProps) => void
127
+ selectedToken: Token
128
+ setWalletConfirmRetryHandler: (handler: () => Promise<void>) => void
129
+ }
130
+
131
+ export type UseSendReturn = {
132
+ amount: string
133
+ amountUsdFormatted: string
134
+ balanceUsdFormatted: string
135
+ chainInfo: ChainInfo | null
136
+ error: string | null
137
+ toChainId: number | undefined
138
+ balanceFormatted: string
139
+ handleRecipientInputChange: (e: React.ChangeEvent<HTMLInputElement>) => void
140
+ handleSubmit: (e: React.FormEvent) => Promise<void>
141
+ isChainDropdownOpen: boolean
142
+ isSubmitting: boolean
143
+ isTokenDropdownOpen: boolean
144
+ recipient: string
145
+ recipientInput: string
146
+ selectedDestinationChain: ChainInfo | null
147
+ selectedDestToken: TokenInfo
148
+ setAmount: (amount: string) => void
149
+ setRecipient: (recipient: string) => void
150
+ setRecipientInput: (recipientInput: string) => void
151
+ setSelectedDestinationChain: (chain: ChainInfo) => void
152
+ setSelectedDestToken: (token: TokenInfo) => void
153
+ setSelectedFeeToken: (token: TokenInfo) => void
154
+ FEE_TOKENS: TokenInfo[]
155
+ supportedTokens: SupportedToken[]
156
+ supportedChains: ChainInfo[]
157
+ ensAddress: string | null
158
+ isWaitingForWalletConfirm: boolean
159
+ buttonText: string
160
+ isValidRecipient: boolean
161
+ useSourceTokenForButtonText: boolean
162
+ destTokenPrices: TokenPrice[] | null
163
+ selectedToken: Token
164
+ selectedFeeToken: TokenInfo | null
165
+ setIsChainDropdownOpen: (isOpen: boolean) => void
166
+ setIsTokenDropdownOpen: (isOpen: boolean) => void
167
+ toAmountFormatted: string
168
+ destinationTokenAddress: string | null
169
+ isValidCustomToken: boolean
170
+ }
171
+
172
+ export function useSendForm({
173
+ account,
174
+ sequenceProjectAccessKey,
175
+ apiUrl,
176
+ env,
177
+ toAmount, // Custom specified amount
178
+ toRecipient, // Custom specified recipient
179
+ toChainId, // Custom specified destination chain id
180
+ toToken, // Custom specified destination token address or symbol
181
+ toCalldata, // Custom specified destination calldata
182
+ walletClient,
183
+ onTransactionStateChange,
184
+ useSourceTokenForButtonText,
185
+ onError,
186
+ onWaitingForWalletConfirm,
187
+ paymasterUrls,
188
+ gasless,
189
+ selectedToken,
190
+ onSend,
191
+ onConfirm,
192
+ onComplete,
193
+ setWalletConfirmRetryHandler,
194
+ }: UseSendProps): UseSendReturn {
195
+ const [amount, setAmount] = useState(toAmount ?? "")
196
+ const [recipientInput, setRecipientInput] = useState(toRecipient ?? "")
197
+ const [recipient, setRecipient] = useState(toRecipient ?? "")
198
+ const [error, setError] = useState<string | null>(null)
199
+ const { supportedChains } = useSupportedChains()
200
+ const { data: ensAddress } = useEnsAddress({
201
+ name: recipientInput?.endsWith(".eth") ? recipientInput : undefined,
202
+ chainId: mainnet.id,
203
+ query: {
204
+ enabled: !!recipientInput && recipientInput.endsWith(".eth"),
205
+ },
206
+ })
207
+
208
+ useEffect(() => {
209
+ if (ensAddress) {
210
+ setRecipient(ensAddress)
211
+ } else {
212
+ setRecipient(recipientInput)
213
+ }
214
+ }, [ensAddress, recipientInput])
215
+
216
+ useEffect(() => {
217
+ if (onError) {
218
+ onError(error)
219
+ }
220
+ }, [error, onError])
221
+
222
+ const handleRecipientInputChange = (
223
+ e: React.ChangeEvent<HTMLInputElement>,
224
+ ) => {
225
+ setRecipientInput(e.target.value.trim())
226
+ }
227
+
228
+ const [selectedDestinationChain, setSelectedDestinationChain] =
229
+ useState<ChainInfo>(() => {
230
+ const chain = supportedChains.find((chain) => chain.id === toChainId)
231
+ if (chain) {
232
+ return chain
233
+ }
234
+ return supportedChains[0]!
235
+ })
236
+
237
+ const { supportedTokens } = useSupportedTokens({
238
+ chainId: selectedDestinationChain?.id,
239
+ })
240
+
241
+ const isCustomToken = useMemo(() => toToken?.startsWith("0x"), [toToken])
242
+
243
+ const {
244
+ tokenInfo: customTokenInfo,
245
+ isLoading: isLoadingCustomToken,
246
+ error: errorCustomToken,
247
+ } = useTokenInfo({
248
+ address: isCustomToken ? toToken! : "",
249
+ chainId: toChainId,
250
+ })
251
+
252
+ const isValidCustomToken = useMemo(() => {
253
+ if (!isCustomToken) {
254
+ return true
255
+ }
256
+
257
+ return Boolean(
258
+ isCustomToken &&
259
+ !errorCustomToken &&
260
+ !isLoadingCustomToken &&
261
+ !!customTokenInfo,
262
+ )
263
+ }, [isCustomToken, errorCustomToken, isLoadingCustomToken, customTokenInfo])
264
+
265
+ useEffect(() => {
266
+ if (isCustomToken && customTokenInfo && !isLoadingCustomToken) {
267
+ setSelectedDestToken(customTokenInfo as TokenInfo)
268
+ }
269
+ }, [customTokenInfo, isCustomToken, isLoadingCustomToken])
270
+
271
+ useEffect(() => {
272
+ if (isCustomToken && errorCustomToken && !isLoadingCustomToken) {
273
+ console.error("[trails-sdk] errorCustomToken", errorCustomToken)
274
+ setError(
275
+ `Invalid custom toToken address. Error: ${errorCustomToken.message}`,
276
+ )
277
+ }
278
+ }, [errorCustomToken, isCustomToken, isLoadingCustomToken])
279
+
280
+ const defaultDestToken = useMemo(() => {
281
+ if (selectedDestinationChain) {
282
+ return supportedTokens.find(
283
+ (token) => token.chainId === selectedDestinationChain.id,
284
+ )
285
+ }
286
+ return supportedTokens?.[0] as TokenInfo
287
+ }, [supportedTokens, selectedDestinationChain])
288
+
289
+ const [isChainDropdownOpen, setIsChainDropdownOpen] = useState(false)
290
+ const [isTokenDropdownOpen, setIsTokenDropdownOpen] = useState(false)
291
+ const [selectedDestToken, setSelectedDestToken] = useState<TokenInfo>(() => {
292
+ let token = defaultDestToken
293
+ if (toToken && !isCustomToken) {
294
+ const isToTokenAddress = isAddress(toToken)
295
+ token = supportedTokens.find(
296
+ (token) =>
297
+ (isToTokenAddress // Match by specified destination token address or symbol
298
+ ? token.contractAddress === toToken
299
+ : token.symbol === toToken) &&
300
+ (toChainId // Match by specified destination chain id
301
+ ? token.chainId === toChainId
302
+ : selectedDestinationChain.id), // Select by selected destination chain id
303
+ )
304
+ }
305
+
306
+ return token as TokenInfo
307
+ })
308
+
309
+ useEffect(() => {
310
+ if (!selectedDestToken && defaultDestToken) {
311
+ setSelectedDestToken(defaultDestToken as TokenInfo)
312
+ }
313
+ }, [selectedDestToken, defaultDestToken])
314
+
315
+ const apiClient = useAPIClient({
316
+ apiUrl,
317
+ projectAccessKey: sequenceProjectAccessKey,
318
+ })
319
+
320
+ const destTokenAddress = useTokenAddress({
321
+ chainId: selectedDestinationChain?.id,
322
+ tokenSymbol: selectedDestToken?.symbol,
323
+ })
324
+
325
+ const { tokenPrices: destTokenPrices } = useTokenPrices(
326
+ selectedDestToken && destTokenAddress
327
+ ? [
328
+ {
329
+ tokenId: selectedDestToken.symbol,
330
+ contractAddress: destTokenAddress,
331
+ chainId: selectedDestinationChain.id,
332
+ },
333
+ ]
334
+ : [],
335
+ apiClient,
336
+ )
337
+
338
+ // Update selectedChain when toChainId prop changes
339
+ useEffect(() => {
340
+ if (toChainId) {
341
+ const newChain = supportedChains.find((chain) => chain.id === toChainId)
342
+ if (newChain) {
343
+ setSelectedDestinationChain(newChain)
344
+ }
345
+ }
346
+ }, [toChainId, supportedChains])
347
+
348
+ // Update selectedDestToken when toToken prop changes
349
+ useEffect(() => {
350
+ if (toToken && !isCustomToken) {
351
+ const isToTokenAddress = isAddress(toToken)
352
+ const newToken = supportedTokens.find(
353
+ (token) =>
354
+ (isToTokenAddress // Match by specified destination token address or symbol
355
+ ? token.contractAddress === toToken
356
+ : token.symbol === toToken) &&
357
+ (toChainId // Match by specified destination chain id
358
+ ? token.chainId === toChainId
359
+ : token.chainId === selectedDestinationChain.id),
360
+ )
361
+ if (newToken) {
362
+ setSelectedDestToken(newToken as TokenInfo)
363
+ }
364
+ }
365
+ }, [
366
+ toToken,
367
+ supportedTokens,
368
+ toChainId,
369
+ selectedDestinationChain.id,
370
+ isCustomToken,
371
+ ])
372
+
373
+ // Update amount when toAmount prop changes
374
+ useEffect(() => {
375
+ setAmount(toAmount ?? "")
376
+ }, [toAmount])
377
+
378
+ const toAmountFormatted = useMemo(() => {
379
+ return formatValue(toAmount || 0)
380
+ }, [toAmount])
381
+
382
+ // Update recipient when toRecipient prop changes
383
+ useEffect(() => {
384
+ setRecipientInput(toRecipient ?? "")
385
+ setRecipient(toRecipient ?? "")
386
+ }, [toRecipient])
387
+
388
+ const chainInfo = getChainInfo(selectedToken.chainId)
389
+ const [isSubmitting, setIsSubmitting] = useState(false)
390
+ const [isWaitingForWalletConfirm, setIsWaitingForWalletConfirm] =
391
+ useState(false)
392
+
393
+ const balanceFormatted = formatBalance(
394
+ selectedToken.balance,
395
+ selectedToken.contractInfo?.decimals,
396
+ )
397
+ const balanceUsdFormatted = selectedToken.balanceUsdFormatted ?? ""
398
+ const relayerConfig = useMemo(
399
+ () => ({ env, useV3Relayers: DEFAULT_USE_V3_RELAYERS }),
400
+ [env],
401
+ )
402
+
403
+ const isValidRecipient = Boolean(recipient && isAddress(recipient))
404
+
405
+ // Calculate USD value
406
+ const amountUsdFormatted = useMemo(() => {
407
+ const amountUsd = Number(amount) * (destTokenPrices?.[0]?.price?.value ?? 0)
408
+ return formatUsdValue(amountUsd)
409
+ }, [amount, destTokenPrices])
410
+
411
+ const [selectedFeeToken, setSelectedFeeToken] = useState<TokenInfo | null>(
412
+ null,
413
+ )
414
+
415
+ const { hasParam } = useQueryParams()
416
+ const isDryMode = hasParam("dryMode", "true")
417
+
418
+ const destinationTokenAddressFromTokenSymbol = useTokenAddress({
419
+ chainId: selectedDestinationChain?.id,
420
+ tokenSymbol: selectedDestToken?.symbol,
421
+ })
422
+
423
+ const destinationTokenAddress = useMemo(() => {
424
+ if (isCustomToken) {
425
+ return toToken ?? null
426
+ }
427
+ return destinationTokenAddressFromTokenSymbol ?? null
428
+ }, [isCustomToken, toToken, destinationTokenAddressFromTokenSymbol])
429
+
430
+ const processSend = useCallback(async () => {
431
+ try {
432
+ if (!destinationTokenAddress) {
433
+ return
434
+ }
435
+
436
+ setError(null)
437
+ setIsSubmitting(true)
438
+ const decimals = selectedDestToken?.decimals
439
+ const parsedAmount = parseUnits(amount, decimals).toString()
440
+
441
+ const originRelayer = getRelayer(relayerConfig, selectedToken.chainId)
442
+ const destinationRelayer = getRelayer(
443
+ relayerConfig,
444
+ selectedDestinationChain.id,
445
+ )
446
+
447
+ const sourceTokenDecimals =
448
+ typeof selectedToken.contractInfo?.decimals === "number"
449
+ ? selectedToken.contractInfo.decimals
450
+ : null
451
+ const destinationTokenDecimals =
452
+ typeof selectedDestToken.decimals === "number"
453
+ ? selectedDestToken.decimals
454
+ : null
455
+
456
+ if (sourceTokenDecimals === null || destinationTokenDecimals === null) {
457
+ setError("Invalid token decimals")
458
+ setIsSubmitting(false)
459
+ return
460
+ }
461
+
462
+ const sourceTokenPriceUsd = selectedToken.tokenPriceUsd ?? null
463
+ const destinationTokenPriceUsd =
464
+ destTokenPrices?.[0]?.price?.value ?? null
465
+
466
+ const options = {
467
+ account,
468
+ originTokenAddress: selectedToken.contractAddress,
469
+ originChainId: selectedToken.chainId,
470
+ originTokenAmount: selectedToken.balance,
471
+ destinationChainId: selectedDestinationChain.id,
472
+ recipient,
473
+ destinationTokenAddress,
474
+ destinationTokenAmount: parsedAmount,
475
+ destinationTokenSymbol: selectedDestToken.symbol,
476
+ sequenceProjectAccessKey,
477
+ fee: "0",
478
+ client: walletClient,
479
+ apiClient,
480
+ originRelayer,
481
+ destinationRelayer,
482
+ destinationCalldata: toCalldata,
483
+ dryMode: isDryMode,
484
+ onTransactionStateChange: (transactionStates: TransactionState[]) => {
485
+ onTransactionStateChange(transactionStates)
486
+ },
487
+ sourceTokenPriceUsd,
488
+ destinationTokenPriceUsd,
489
+ sourceTokenDecimals,
490
+ destinationTokenDecimals,
491
+ paymasterUrl:
492
+ paymasterUrls?.find(
493
+ (p) => p.chainId.toString() === selectedToken.chainId.toString(),
494
+ )?.url ?? undefined,
495
+ gasless,
496
+ relayerConfig,
497
+ }
498
+
499
+ console.log("[trails-sdk] options", options)
500
+
501
+ const { intentAddress, originSendAmount, send } =
502
+ await prepareSend(options)
503
+ console.log("[trails-sdk] Intent address:", intentAddress?.toString())
504
+
505
+ function onOriginSend() {
506
+ console.log("[trails-sdk] onOriginSend called")
507
+ onConfirm()
508
+ setIsWaitingForWalletConfirm(false)
509
+ onSend(amount, recipient)
510
+ }
511
+
512
+ const originSendAmountFormatted = Number(
513
+ formatUnits(
514
+ BigInt(originSendAmount),
515
+ selectedToken.contractInfo?.decimals ?? 18,
516
+ ),
517
+ )
518
+
519
+ const originSendAmountUsdFormatted =
520
+ originSendAmountFormatted * (sourceTokenPriceUsd ?? 0)
521
+
522
+ setIsWaitingForWalletConfirm(true)
523
+ onWaitingForWalletConfirm(intentAddress?.toString() ?? "", {
524
+ amount: formatValue(originSendAmountFormatted),
525
+ amountUsd: formatUsdValue(originSendAmountUsdFormatted),
526
+ tokenSymbol: selectedToken.symbol,
527
+ tokenName: selectedToken.name,
528
+ chainId: selectedToken.chainId,
529
+ imageUrl: selectedToken.imageUrl,
530
+ })
531
+
532
+ async function handleSend() {
533
+ console.log("[trails-sdk] handleRetry called, about to call send()")
534
+ // Wait for full send to complete
535
+ const {
536
+ originUserTxReceipt,
537
+ originMetaTxnReceipt,
538
+ destinationMetaTxnReceipt,
539
+ } = await send(onOriginSend)
540
+ console.log("[trails-sdk] send() completed, receipts:", {
541
+ originUserTxReceipt,
542
+ originMetaTxnReceipt,
543
+ destinationMetaTxnReceipt,
544
+ })
545
+
546
+ // Move to receipt screen
547
+ onComplete({
548
+ originChainId: selectedToken.chainId,
549
+ destinationChainId: selectedDestinationChain.id,
550
+ originUserTxReceipt,
551
+ originMetaTxnReceipt,
552
+ destinationMetaTxnReceipt,
553
+ })
554
+ }
555
+
556
+ async function walletConfirmRetryHandler() {
557
+ console.log("[trails-sdk] walletConfirmRetryHandler called")
558
+ try {
559
+ console.log("[trails-sdk] About to call handleRetry")
560
+ await handleSend()
561
+ console.log("[trails-sdk] handleRetry completed successfully")
562
+ } catch (error) {
563
+ console.error(
564
+ "[trails-sdk] Error in prepareSend walletConfirmRetryHandler:",
565
+ error,
566
+ )
567
+ const errorMessage = getFullErrorMessage(error)
568
+ setError(errorMessage)
569
+ if (onError) {
570
+ onError(errorMessage)
571
+ }
572
+ }
573
+ }
574
+
575
+ setWalletConfirmRetryHandler(
576
+ () => walletConfirmRetryHandler as unknown as Promise<void>,
577
+ )
578
+
579
+ await handleSend()
580
+ } catch (error) {
581
+ console.error("[trails-sdk] Error in prepareSend:", error)
582
+ const errorMessage = getFullErrorMessage(error)
583
+ setError(errorMessage)
584
+ if (onError) {
585
+ onError(errorMessage)
586
+ }
587
+ }
588
+
589
+ setIsSubmitting(false)
590
+ setIsWaitingForWalletConfirm(false)
591
+ }, [
592
+ amount,
593
+ selectedToken,
594
+ onSend,
595
+ onConfirm,
596
+ onComplete,
597
+ walletClient,
598
+ apiClient,
599
+ relayerConfig,
600
+ isDryMode,
601
+ selectedDestToken,
602
+ selectedDestinationChain,
603
+ toCalldata,
604
+ paymasterUrls,
605
+ gasless,
606
+ sequenceProjectAccessKey,
607
+ account,
608
+ destTokenPrices,
609
+ setWalletConfirmRetryHandler,
610
+ onWaitingForWalletConfirm,
611
+ recipient,
612
+ onTransactionStateChange,
613
+ destinationTokenAddress,
614
+ onError,
615
+ ])
616
+
617
+ const handleSubmit = async (e: React.FormEvent) => {
618
+ e.preventDefault()
619
+ processSend().catch((error) => {
620
+ console.error("[trails-sdk] Error in processSend:", error)
621
+ setError(
622
+ error instanceof Error ? error.message : "An unexpected error occurred",
623
+ )
624
+ })
625
+ }
626
+
627
+ // Get button text based on recipient and calldata
628
+ const buttonText = useMemo(() => {
629
+ if (isWaitingForWalletConfirm) return "Waiting for wallet..."
630
+ if (isSubmitting) return "Processing..."
631
+ if (!amount) return "Enter amount"
632
+ if (!isValidRecipient) return "Enter recipient"
633
+
634
+ const amountFormatted = formatValue(amount)
635
+ const destTokenSymbol = selectedDestToken?.symbol ?? "Token"
636
+
637
+ try {
638
+ const checksummedRecipient = getAddress(recipient)
639
+ const checksummedAccount = getAddress(account.address)
640
+
641
+ if (checksummedRecipient === checksummedAccount) {
642
+ return `Receive ${amountFormatted} ${destTokenSymbol}`
643
+ }
644
+ if (toCalldata) {
645
+ if (useSourceTokenForButtonText) {
646
+ const destPrice = destTokenPrices?.[0]?.price?.value ?? 0
647
+ const sourcePrice = selectedToken.tokenPriceUsd ?? 0
648
+ if (destPrice > 0 && sourcePrice > 0) {
649
+ const destAmountUsd = Number(amount) * destPrice
650
+ const sourceAmount = destAmountUsd / sourcePrice
651
+ const formattedSourceAmount = formatValue(sourceAmount)
652
+ return `Spend ~${formattedSourceAmount} ${selectedToken.symbol}`
653
+ }
654
+ }
655
+ return `Spend ${amountFormatted} ${destTokenSymbol}`
656
+ }
657
+ return `Pay ${amountFormatted} ${destTokenSymbol}`
658
+ } catch {
659
+ return `Send ${amountFormatted} ${destTokenSymbol}`
660
+ }
661
+ }, [
662
+ amount,
663
+ isValidRecipient,
664
+ recipient,
665
+ account.address,
666
+ selectedDestToken?.symbol,
667
+ toCalldata,
668
+ isWaitingForWalletConfirm,
669
+ isSubmitting,
670
+ useSourceTokenForButtonText,
671
+ destTokenPrices,
672
+ selectedToken,
673
+ ])
674
+
675
+ return {
676
+ amount,
677
+ amountUsdFormatted,
678
+ balanceUsdFormatted,
679
+ chainInfo,
680
+ toChainId,
681
+ error,
682
+ balanceFormatted,
683
+ handleRecipientInputChange,
684
+ handleSubmit,
685
+ isChainDropdownOpen,
686
+ isSubmitting,
687
+ isTokenDropdownOpen,
688
+ recipient,
689
+ recipientInput,
690
+ selectedDestinationChain,
691
+ selectedDestToken,
692
+ setAmount,
693
+ setRecipient,
694
+ setRecipientInput,
695
+ setSelectedDestinationChain,
696
+ setSelectedDestToken,
697
+ setSelectedFeeToken,
698
+ FEE_TOKENS,
699
+ supportedTokens,
700
+ supportedChains,
701
+ ensAddress: ensAddress ?? null,
702
+ isWaitingForWalletConfirm,
703
+ buttonText,
704
+ isValidRecipient,
705
+ useSourceTokenForButtonText,
706
+ destTokenPrices: destTokenPrices ?? null,
707
+ selectedToken,
708
+ selectedFeeToken,
709
+ setIsChainDropdownOpen,
710
+ setIsTokenDropdownOpen,
711
+ toAmountFormatted,
712
+ destinationTokenAddress,
713
+ isValidCustomToken,
714
+ }
715
+ }