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,695 @@
1
+ import { ChevronDown, ChevronLeft, Loader2 } from "lucide-react"
2
+ import type React from "react"
3
+ import { useEffect, useRef } from "react"
4
+ import type { Account, WalletClient } from "viem"
5
+ import { isAddress } from "viem"
6
+ import type { TransactionState } from "../../prepareSend.js"
7
+ import type { RelayerEnv } from "../../relayer.js"
8
+ import type { ActiveTheme } from "../../theme.js"
9
+ import type { OnCompleteProps, Token, TokenInfo } from "../hooks/useSendForm.js"
10
+ import { useSendForm } from "../hooks/useSendForm.js"
11
+ import { ChainImage } from "./ChainImage.js"
12
+ import { FeeOptions } from "./FeeOptions.js"
13
+ import { TokenImage } from "./TokenImage.js"
14
+
15
+ interface SendFormProps {
16
+ selectedToken: Token
17
+ onSend: (amount: string, recipient: string) => void
18
+ onBack: () => void
19
+ onConfirm: () => void
20
+ onComplete: (result: OnCompleteProps) => void
21
+ account: Account
22
+ sequenceProjectAccessKey: string
23
+ apiUrl?: string
24
+ env?: RelayerEnv
25
+ toRecipient?: string
26
+ toAmount?: string
27
+ toChainId?: number
28
+ toToken?: string
29
+ toCalldata?: string
30
+ walletClient: WalletClient
31
+ theme?: ActiveTheme
32
+ onTransactionStateChange: (transactionStates: TransactionState[]) => void
33
+ useSourceTokenForButtonText?: boolean
34
+ onError: (error: Error | string | null) => void
35
+ onWaitingForWalletConfirm: (
36
+ intentAddress?: string,
37
+ originTokenInfo?: {
38
+ amount: string
39
+ amountUsd: string
40
+ tokenSymbol: string
41
+ tokenName: string
42
+ chainId: number
43
+ imageUrl: string
44
+ },
45
+ ) => void
46
+ paymasterUrls?: Array<{ chainId: number; url: string }>
47
+ gasless?: boolean
48
+ setWalletConfirmRetryHandler: (handler: () => Promise<void>) => void
49
+ }
50
+
51
+ export const SendForm: React.FC<SendFormProps> = ({
52
+ selectedToken,
53
+ onSend,
54
+ onBack,
55
+ onConfirm,
56
+ onComplete,
57
+ account,
58
+ sequenceProjectAccessKey,
59
+ apiUrl,
60
+ env,
61
+ toAmount,
62
+ toRecipient,
63
+ toChainId,
64
+ toToken,
65
+ toCalldata,
66
+ walletClient,
67
+ theme = "light",
68
+ onTransactionStateChange,
69
+ useSourceTokenForButtonText = false,
70
+ onError,
71
+ onWaitingForWalletConfirm,
72
+ paymasterUrls,
73
+ gasless,
74
+ setWalletConfirmRetryHandler,
75
+ }) => {
76
+ const {
77
+ amount,
78
+ amountUsdFormatted,
79
+ balanceUsdFormatted,
80
+ chainInfo,
81
+ balanceFormatted,
82
+ handleRecipientInputChange,
83
+ handleSubmit,
84
+ isChainDropdownOpen,
85
+ isSubmitting,
86
+ isTokenDropdownOpen,
87
+ recipient,
88
+ recipientInput,
89
+ selectedDestinationChain,
90
+ selectedDestToken,
91
+ setAmount,
92
+ setRecipient,
93
+ setRecipientInput,
94
+ setSelectedDestinationChain,
95
+ setSelectedDestToken,
96
+ buttonText,
97
+ isValidRecipient,
98
+ ensAddress,
99
+ selectedFeeToken,
100
+ setSelectedFeeToken,
101
+ FEE_TOKENS,
102
+ supportedTokens,
103
+ setIsChainDropdownOpen,
104
+ setIsTokenDropdownOpen,
105
+ toAmountFormatted,
106
+ destinationTokenAddress,
107
+ supportedChains,
108
+ isValidCustomToken,
109
+ } = useSendForm({
110
+ account,
111
+ sequenceProjectAccessKey,
112
+ apiUrl,
113
+ env,
114
+ toAmount,
115
+ toRecipient,
116
+ toChainId,
117
+ toToken,
118
+ toCalldata,
119
+ walletClient,
120
+ theme,
121
+ onTransactionStateChange,
122
+ useSourceTokenForButtonText,
123
+ onError,
124
+ onWaitingForWalletConfirm,
125
+ paymasterUrls,
126
+ gasless,
127
+ onConfirm,
128
+ onComplete,
129
+ onSend,
130
+ selectedToken,
131
+ setWalletConfirmRetryHandler,
132
+ })
133
+
134
+ console.log("[trails-sdk] SendForm", {
135
+ amount,
136
+ isValidRecipient,
137
+ isSubmitting,
138
+ destinationTokenAddress,
139
+ isValidCustomToken,
140
+ isChainDropdownOpen,
141
+ selectedDestinationChain,
142
+ supportedChains: supportedChains.length,
143
+ })
144
+
145
+ const chainDropdownRef = useRef<HTMLDivElement>(null)
146
+ const tokenDropdownRef = useRef<HTMLDivElement>(null)
147
+
148
+ useEffect(() => {
149
+ const handleClickOutside = (event: MouseEvent) => {
150
+ console.log(
151
+ "[trails-sdk] click outside handler called, isChainDropdownOpen:",
152
+ isChainDropdownOpen,
153
+ )
154
+ if (
155
+ chainDropdownRef.current &&
156
+ !chainDropdownRef.current.contains(event.target as Node)
157
+ ) {
158
+ console.log("[trails-sdk] closing chain dropdown from outside click")
159
+ setIsChainDropdownOpen(false)
160
+ }
161
+ if (
162
+ tokenDropdownRef.current &&
163
+ !tokenDropdownRef.current.contains(event.target as Node)
164
+ ) {
165
+ setIsTokenDropdownOpen(false)
166
+ }
167
+ }
168
+
169
+ if (isChainDropdownOpen || isTokenDropdownOpen) {
170
+ document.addEventListener("click", handleClickOutside)
171
+ return () => document.removeEventListener("click", handleClickOutside)
172
+ }
173
+ }, [
174
+ setIsChainDropdownOpen,
175
+ setIsTokenDropdownOpen,
176
+ isChainDropdownOpen,
177
+ isTokenDropdownOpen,
178
+ ])
179
+
180
+ if (!selectedDestinationChain) {
181
+ return null
182
+ }
183
+
184
+ if (!selectedToken) {
185
+ return null
186
+ }
187
+
188
+ return (
189
+ <div className="space-y-6">
190
+ <div className="flex items-center relative">
191
+ <button
192
+ type="button"
193
+ onClick={onBack}
194
+ className={`absolute -left-2 p-2 rounded-full transition-colors cursor-pointer ${
195
+ theme === "dark"
196
+ ? "hover:bg-gray-800 text-gray-400"
197
+ : "hover:bg-gray-100 text-gray-600"
198
+ }`}
199
+ >
200
+ <ChevronLeft className="h-6 w-6" />
201
+ </button>
202
+ <h2
203
+ className={`text-lg font-semibold w-full text-center ${theme === "dark" ? "text-white" : "text-gray-900"}`}
204
+ >
205
+ Send Payment
206
+ </h2>
207
+ </div>
208
+
209
+ <div
210
+ className={`flex items-center space-x-4 p-4 rounded-lg ${theme === "dark" ? "bg-gray-800" : "bg-gray-50"}`}
211
+ >
212
+ <div className="flex items-start justify-between w-full">
213
+ {/* Left side - Chain and Token images with token name */}
214
+ <div className="flex items-start space-x-2">
215
+ {/* Token Image and Name */}
216
+ <div className="flex items-center space-x-2">
217
+ <div style={{ width: "32px", height: "32px" }}>
218
+ <TokenImage
219
+ symbol={selectedToken.symbol}
220
+ imageUrl={selectedToken.imageUrl}
221
+ chainId={selectedToken.chainId}
222
+ size={32}
223
+ />
224
+ </div>
225
+ <div className="flex flex-col">
226
+ <span
227
+ className={`text-sm font-medium max-w-[135px] truncate ${theme === "dark" ? "text-white" : "text-gray-900"}`}
228
+ >
229
+ {selectedToken.name}
230
+ </span>
231
+ <span
232
+ className={`text-sm ${theme === "dark" ? "text-gray-400" : "text-gray-500"}`}
233
+ >
234
+ on {chainInfo?.name || "Unknown Chain"}
235
+ </span>
236
+ </div>
237
+ </div>
238
+ </div>
239
+
240
+ {/* Right side - USD value and amount */}
241
+ <div className="text-right">
242
+ <div
243
+ className={`text-sm font-medium ${theme === "dark" ? "text-white" : "text-gray-900"}`}
244
+ >
245
+ <span
246
+ className={`${theme === "dark" ? "text-gray-400" : "text-gray-600"}`}
247
+ >
248
+ Balance:{" "}
249
+ </span>
250
+ {balanceUsdFormatted}
251
+ </div>
252
+ <div
253
+ className={`text-sm ${theme === "dark" ? "text-gray-400" : "text-gray-600"}`}
254
+ >
255
+ {balanceFormatted} {selectedToken.symbol}
256
+ </div>
257
+ </div>
258
+ </div>
259
+ </div>
260
+
261
+ <form onSubmit={handleSubmit} className="space-y-2">
262
+ {/* Chain Selection - More Compact */}
263
+ <div className={!toChainId ? "mb-4" : undefined}>
264
+ <label
265
+ htmlFor="destination-chain"
266
+ className={`block text-sm font-medium mb-1 ${theme === "dark" ? "text-gray-300" : "text-gray-700"}`}
267
+ >
268
+ Destination Chain
269
+ </label>
270
+ {toChainId ? (
271
+ <div className="flex items-center px-2 py-1">
272
+ <ChainImage chainId={selectedDestinationChain.id} size={24} />
273
+ <span
274
+ className={`ml-2 ${theme === "dark" ? "text-white" : "text-gray-900"}`}
275
+ >
276
+ {selectedDestinationChain.name}
277
+ </span>
278
+ </div>
279
+ ) : (
280
+ <div className="relative" ref={chainDropdownRef}>
281
+ <button
282
+ type="button"
283
+ onClick={() => setIsChainDropdownOpen(!isChainDropdownOpen)}
284
+ className={`w-full flex items-center px-4 py-3 border rounded-[24px] hover:border-gray-400 cursor-pointer focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 ${
285
+ theme === "dark"
286
+ ? "bg-gray-800 border-gray-700 text-white"
287
+ : "bg-white border-gray-300 text-gray-900"
288
+ }`}
289
+ >
290
+ <ChainImage chainId={selectedDestinationChain.id} size={24} />
291
+ <span className="ml-2 flex-1 text-left">
292
+ {selectedDestinationChain.name}
293
+ </span>
294
+ <ChevronDown
295
+ className={`h-5 w-5 ${theme === "dark" ? "text-gray-400" : "text-gray-400"} transition-transform ${
296
+ isChainDropdownOpen ? "transform rotate-180" : ""
297
+ }`}
298
+ />
299
+ </button>
300
+
301
+ {isChainDropdownOpen && (
302
+ <div
303
+ className={`absolute z-10 w-full mt-1 border rounded-[24px] shadow-lg max-h-60 overflow-y-auto ${
304
+ theme === "dark"
305
+ ? "bg-gray-800 border-gray-700"
306
+ : "bg-white border-gray-200"
307
+ }`}
308
+ >
309
+ {supportedChains.map((chain) => (
310
+ <button
311
+ key={chain.id}
312
+ type="button"
313
+ onClick={(e) => {
314
+ e.preventDefault()
315
+ e.stopPropagation()
316
+ setSelectedDestinationChain(chain)
317
+ setIsChainDropdownOpen(false)
318
+ }}
319
+ onMouseDown={(e) => {
320
+ e.preventDefault()
321
+ e.stopPropagation()
322
+ }}
323
+ className={`w-full flex items-center px-4 py-3 ${
324
+ theme === "dark"
325
+ ? selectedDestinationChain.id === chain.id
326
+ ? "bg-gray-700 text-white"
327
+ : "text-white hover:bg-gray-700"
328
+ : selectedDestinationChain.id === chain.id
329
+ ? "bg-gray-100 text-gray-900"
330
+ : "text-gray-900 hover:bg-gray-50"
331
+ }`}
332
+ >
333
+ <ChainImage chainId={chain.id} size={24} />
334
+ <span className="ml-2">{chain.name}</span>
335
+ {selectedDestinationChain.id === chain.id && (
336
+ <span
337
+ className={`ml-auto ${theme === "dark" ? "text-white" : "text-gray-900"}`}
338
+ >
339
+
340
+ </span>
341
+ )}
342
+ </button>
343
+ ))}
344
+ </div>
345
+ )}
346
+ </div>
347
+ )}
348
+ </div>
349
+
350
+ {/* Token Selection - More Compact */}
351
+ <div className={!toToken ? "mb-4" : undefined}>
352
+ <label
353
+ htmlFor="token"
354
+ className={`block text-sm font-medium mb-1 ${theme === "dark" ? "text-gray-300" : "text-gray-700"}`}
355
+ >
356
+ Receive Token
357
+ </label>
358
+ {toToken ? (
359
+ <div className="flex items-center px-2 py-1">
360
+ <TokenImage
361
+ symbol={selectedDestToken?.symbol}
362
+ imageUrl={selectedDestToken?.imageUrl}
363
+ size={24}
364
+ />
365
+ <span
366
+ className={`ml-2 ${theme === "dark" ? "text-white" : "text-gray-900"}`}
367
+ >
368
+ {selectedDestToken?.name ?? "Unknown Token"} (
369
+ {selectedDestToken?.symbol ?? "Unknown Symbol"})
370
+ </span>
371
+ </div>
372
+ ) : (
373
+ <div className="relative" ref={tokenDropdownRef}>
374
+ <button
375
+ type="button"
376
+ onClick={() => setIsTokenDropdownOpen(!isTokenDropdownOpen)}
377
+ className={`w-full flex items-center px-4 py-3 border rounded-[24px] hover:border-gray-400 cursor-pointer focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 ${
378
+ theme === "dark"
379
+ ? "bg-gray-800 border-gray-700 text-white"
380
+ : "bg-white border-gray-300 text-gray-900"
381
+ }`}
382
+ >
383
+ <div
384
+ className={`w-5 h-5 rounded-full flex items-center justify-center text-sm ${
385
+ theme === "dark" ? "bg-gray-700" : "bg-gray-100"
386
+ }`}
387
+ >
388
+ <TokenImage
389
+ symbol={selectedDestToken?.symbol}
390
+ imageUrl={selectedDestToken?.imageUrl}
391
+ size={24}
392
+ />
393
+ </div>
394
+ <span className="ml-2 flex-1 text-left">
395
+ {selectedDestToken?.name} ({selectedDestToken?.symbol})
396
+ </span>
397
+ <ChevronDown
398
+ className={`h-5 w-5 ${theme === "dark" ? "text-gray-400" : "text-gray-400"} transition-transform ${
399
+ isTokenDropdownOpen ? "transform rotate-180" : ""
400
+ }`}
401
+ />
402
+ </button>
403
+
404
+ {isTokenDropdownOpen && (
405
+ <div
406
+ className={`absolute z-10 w-full mt-1 border rounded-[24px] shadow-lg max-h-60 overflow-y-auto ${
407
+ theme === "dark"
408
+ ? "bg-gray-800 border-gray-700"
409
+ : "bg-white border-gray-200"
410
+ }`}
411
+ >
412
+ {supportedTokens.map((token) => (
413
+ <button
414
+ key={`${token.contractAddress}-${token.chainId}`}
415
+ type="button"
416
+ onClick={() => {
417
+ setSelectedDestToken(token as TokenInfo)
418
+ setIsTokenDropdownOpen(false)
419
+ }}
420
+ className={`w-full flex items-center px-4 py-3 cursor-pointer ${
421
+ theme === "dark"
422
+ ? selectedDestToken?.symbol === token.symbol
423
+ ? "bg-gray-700 text-white"
424
+ : "text-white hover:bg-gray-700"
425
+ : selectedDestToken?.symbol === token.symbol
426
+ ? "bg-gray-100 text-gray-900"
427
+ : "text-gray-900 hover:bg-gray-50"
428
+ }`}
429
+ >
430
+ <div
431
+ className={`w-5 h-5 rounded-full flex items-center justify-center text-sm ${
432
+ theme === "dark" ? "bg-gray-700" : "bg-gray-100"
433
+ }`}
434
+ >
435
+ <TokenImage
436
+ symbol={token.symbol}
437
+ imageUrl={token.imageUrl}
438
+ size={24}
439
+ />
440
+ </div>
441
+ <span className="ml-2">
442
+ {token.name} ({token.symbol})
443
+ </span>
444
+ {selectedDestToken?.symbol === token.symbol && (
445
+ <span
446
+ className={`ml-auto ${theme === "dark" ? "text-white" : "text-gray-900"}`}
447
+ >
448
+
449
+ </span>
450
+ )}
451
+ </button>
452
+ ))}
453
+ </div>
454
+ )}
455
+ </div>
456
+ )}
457
+ </div>
458
+
459
+ {/* Amount Input - More Compact */}
460
+ <div className={!toAmount ? "mb-2" : undefined}>
461
+ <label
462
+ htmlFor="amount"
463
+ className={`block text-sm font-medium mb-1 ${theme === "dark" ? "text-gray-300" : "text-gray-700"}`}
464
+ >
465
+ Amount to Receive
466
+ </label>
467
+ {toAmount ? (
468
+ <div className="flex items-center justify-between px-2 py-1">
469
+ <span
470
+ className={`${theme === "dark" ? "text-white" : "text-gray-900"}`}
471
+ >
472
+ {toAmountFormatted} {selectedDestToken?.symbol}
473
+ </span>
474
+ <span
475
+ className={`text-sm ${theme === "dark" ? "text-gray-400" : "text-gray-500"}`}
476
+ >
477
+ ≈ {amountUsdFormatted}
478
+ </span>
479
+ </div>
480
+ ) : (
481
+ <>
482
+ <div className="relative rounded-lg">
483
+ <input
484
+ id="amount"
485
+ type="text"
486
+ value={amount}
487
+ onChange={(e) => setAmount(e.target.value)}
488
+ placeholder="0.00"
489
+ className={`block w-full pl-4 pr-12 py-3 border rounded-[24px] focus:ring-2 focus:ring-blue-500 focus:border-blue-500 text-lg ${
490
+ theme === "dark"
491
+ ? "bg-gray-800 border-gray-700 text-white placeholder-gray-500"
492
+ : "bg-white border-gray-300 text-gray-900 placeholder-gray-400"
493
+ }`}
494
+ />
495
+ <div className="absolute inset-y-0 right-0 flex items-center pr-4">
496
+ <span
497
+ className={
498
+ theme === "dark" ? "text-gray-400" : "text-gray-500"
499
+ }
500
+ >
501
+ {selectedDestToken?.symbol}
502
+ </span>
503
+ </div>
504
+ </div>
505
+ <div className="h-6 mt-1">
506
+ {amount && selectedDestToken?.symbol && (
507
+ <div
508
+ className={`text-sm ${theme === "dark" ? "text-gray-400" : "text-gray-500"}`}
509
+ >
510
+ ≈ {amountUsdFormatted}
511
+ </div>
512
+ )}
513
+ </div>
514
+ </>
515
+ )}
516
+ </div>
517
+
518
+ {/* Recipient Input - More Compact */}
519
+ <div className={!toRecipient ? "mb-4" : undefined}>
520
+ <div className="flex justify-between items-center mb-1">
521
+ <div>
522
+ <label
523
+ htmlFor="recipient"
524
+ className={`text-sm font-medium ${theme === "dark" ? "text-gray-300" : "text-gray-700"}`}
525
+ >
526
+ {toCalldata ? "Destination Address" : "Recipient Address"}
527
+ </label>
528
+ {recipient &&
529
+ isAddress(recipient) &&
530
+ recipient.toLowerCase() === account.address.toLowerCase() && (
531
+ <div
532
+ className={`text-xs mt-0.5 ${theme === "dark" ? "text-gray-400" : "text-gray-500"}`}
533
+ >
534
+ Same as sender
535
+ </div>
536
+ )}
537
+ </div>
538
+ <div className="h-7 flex items-center">
539
+ {!toRecipient && recipient !== account.address ? (
540
+ <button
541
+ type="button"
542
+ onClick={(event: React.MouseEvent<HTMLButtonElement>) => {
543
+ event.preventDefault()
544
+ setRecipientInput(account.address)
545
+ setRecipient(account.address)
546
+ }}
547
+ className={`px-2 py-1 text-xs cursor-pointer rounded-[24px] transition-colors bg-blue-500 hover:bg-blue-600 text-white`}
548
+ >
549
+ Use Account
550
+ </button>
551
+ ) : null}
552
+ </div>
553
+ </div>
554
+ {toRecipient ? (
555
+ <div className="px-2 py-1 font-mono text-sm">
556
+ <span
557
+ className={`break-all ${theme === "dark" ? "text-white" : "text-gray-900"}`}
558
+ >
559
+ {recipient}
560
+ </span>
561
+ </div>
562
+ ) : (
563
+ <>
564
+ <input
565
+ id="recipient"
566
+ type="text"
567
+ value={recipientInput}
568
+ onChange={handleRecipientInputChange}
569
+ placeholder="0x... or name.eth"
570
+ className={`block w-full px-4 py-3 border rounded-[24px] focus:ring-2 focus:ring-blue-500 focus:border-blue-500 font-mono text-sm ${
571
+ theme === "dark"
572
+ ? "bg-gray-800 border-gray-700 text-white placeholder-gray-500"
573
+ : "bg-white border-gray-300 text-gray-900 placeholder-gray-400"
574
+ }`}
575
+ />
576
+ {ensAddress && (
577
+ <p
578
+ className={
579
+ theme === "dark"
580
+ ? "text-sm text-gray-400"
581
+ : "text-sm text-gray-500"
582
+ }
583
+ >
584
+ {recipient}
585
+ </p>
586
+ )}
587
+ </>
588
+ )}
589
+ </div>
590
+
591
+ {/* Custom Calldata - More Compact */}
592
+ {toCalldata && (
593
+ <div className="px-2 py-1">
594
+ <p
595
+ className={`text-xs ${theme === "dark" ? "text-gray-300" : "text-gray-600"}`}
596
+ >
597
+ This transaction includes custom calldata for contract interaction
598
+ at the destination address
599
+ </p>
600
+ </div>
601
+ )}
602
+
603
+ {/* Fee Options */}
604
+ <FeeOptions
605
+ options={FEE_TOKENS}
606
+ selectedOption={selectedFeeToken ?? undefined}
607
+ onSelect={setSelectedFeeToken}
608
+ theme={theme}
609
+ />
610
+
611
+ <div className="flex flex-col space-y-3 pt-2">
612
+ <button
613
+ type="submit"
614
+ disabled={
615
+ !amount ||
616
+ !isValidRecipient ||
617
+ isSubmitting ||
618
+ !destinationTokenAddress ||
619
+ !isValidCustomToken
620
+ }
621
+ className={`w-full font-semibold py-3 px-4 rounded-[24px] transition-colors relative ${
622
+ theme === "dark"
623
+ ? "bg-blue-600 disabled:bg-gray-700 text-white disabled:text-gray-400 enabled:hover:bg-blue-700"
624
+ : "bg-blue-500 disabled:bg-gray-300 text-white disabled:text-gray-500 enabled:hover:bg-blue-600"
625
+ } disabled:cursor-not-allowed cursor-pointer`}
626
+ >
627
+ {isSubmitting ? (
628
+ <div className="flex items-center justify-center">
629
+ <Loader2
630
+ className={`w-5 h-5 animate-spin mr-2 ${theme === "dark" ? "text-gray-400" : "text-white"}`}
631
+ />
632
+ <span>{buttonText}</span>
633
+ </div>
634
+ ) : (
635
+ buttonText
636
+ )}
637
+ </button>
638
+ </div>
639
+ </form>
640
+ </div>
641
+ )
642
+ }
643
+
644
+ const styles = `
645
+ select {
646
+ appearance: none;
647
+ border: 1px solid #e5e7eb;
648
+ outline: none;
649
+ font-size: 1rem;
650
+ width: 100%;
651
+ background-color: #fff;
652
+ border-radius: 0.5rem;
653
+ padding: 0.75rem 1rem;
654
+ padding-right: 2rem;
655
+
656
+ cursor: pointer;
657
+ transition: all 0.2s;
658
+ }
659
+
660
+ select:hover {
661
+ border-color: #d1d5db;
662
+ }
663
+
664
+ select:focus {
665
+ border-color: #3b82f6;
666
+ box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.1);
667
+ }
668
+
669
+ select option {
670
+ padding: 0.75rem 1rem;
671
+ min-height: 3rem;
672
+ display: flex;
673
+ align-items: center;
674
+ padding-left: 2.75rem;
675
+ position: relative;
676
+ cursor: pointer;
677
+ }
678
+
679
+ select option:hover {
680
+ background-color: #f3f4f6;
681
+ }
682
+
683
+ select option:checked {
684
+ background-color: #eff6ff;
685
+ color: #1d4ed8;
686
+ }
687
+ `
688
+
689
+ if (typeof document !== "undefined") {
690
+ const styleTag = document.createElement("style")
691
+ styleTag.textContent = styles
692
+ document.head.appendChild(styleTag)
693
+ }
694
+
695
+ export default SendForm