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,29 +1,30 @@
1
- import { ChevronLeft, Copy } from "lucide-react"
1
+ import { ChevronLeft, Copy, AlertTriangle, Info } from "lucide-react"
2
2
  import type React from "react"
3
3
  import { useState, useMemo } from "react"
4
4
  import { AnimatePresence, motion } from "motion/react"
5
5
  import { zeroAddress } from "viem"
6
- import type { Token, TokenFormatted } from "../hooks/useTokenList.js"
7
6
  import { useTokenList } from "../hooks/useTokenList.js"
8
7
  import { useChainFilter } from "../hooks/useChainFilter.js"
9
8
  import { useBalanceVisible } from "../hooks/useBalanceVisible.js"
10
9
  import { TokenImage } from "./TokenImage.js"
11
- import type { SupportedToken } from "../../tokens.js"
10
+ import type { Token } from "../../tokens.js"
12
11
  import { RecentTokens } from "./RecentTokens.js"
13
12
  import { getChainInfo } from "../../chains.js"
14
13
  import { ChainFilterDropdown } from "./ChainFilterDropdown.js"
15
14
  import { SearchInputField } from "./SearchInputField.js"
16
- import { truncateAddress } from "../../utils.js"
15
+ import { truncateAddress, isValueZero } from "../../utils.js"
17
16
  import { logger } from "../../logger.js"
18
17
  import { useAccount } from "wagmi"
18
+ import { useCustomTokenSearch } from "../hooks/useCustomTokenSearch.js"
19
+ import { Tooltip } from "./Tooltip.js"
19
20
 
20
21
  interface TokenSelectorProps {
21
22
  onTokenSelect: (selectedToken: Token) => void
22
23
  targetAmountUsd?: number | null
23
24
  targetAmountUsdFormatted?: string | null
24
25
  onError: (error: Error | string | null) => void
25
- recentTokens?: SupportedToken[]
26
- onRecentTokenSelect?: (token: SupportedToken) => void
26
+ recentTokens?: Token[]
27
+ onRecentTokenSelect?: (token: Token) => void
27
28
  fundMethod?: string | null
28
29
  onNavigateToFundMethods?: () => void
29
30
  showContinueButton?: boolean
@@ -65,6 +66,7 @@ export const TokenSelector: React.FC<TokenSelectorProps> = ({
65
66
  handleTokenSelect,
66
67
  filteredTokens,
67
68
  isLoadingTokens,
69
+ isSearching,
68
70
  isTokenSelected,
69
71
  filteredTokensFormatted,
70
72
  balanceError,
@@ -81,20 +83,22 @@ export const TokenSelector: React.FC<TokenSelectorProps> = ({
81
83
  setSelectedChainId: setFilterByChainId,
82
84
  } = useChainFilter()
83
85
 
84
- // Apply chain filter to tokens
85
- const chainFilteredTokens = useMemo(() => {
86
- if (filterByChainId === null) {
87
- return filteredTokensFormatted
88
- }
89
- return filteredTokensFormatted.filter(
90
- (token) => token.chainId === filterByChainId,
91
- )
92
- }, [filteredTokensFormatted, filterByChainId])
86
+ // Handle custom token search and integration
87
+ const {
88
+ chainFilteredTokens,
89
+ isLoadingCustomToken,
90
+ customTokenError,
91
+ fetchChainId,
92
+ } = useCustomTokenSearch({
93
+ searchQuery,
94
+ filteredTokensFormatted,
95
+ filterByChainId,
96
+ })
93
97
 
94
98
  // Get unique chains from all tokens (not filtered by chain)
95
99
  const uniqueChains = useMemo(() => {
96
100
  const chainIds = new Set(
97
- filteredTokensFormatted.map((token) => token.chainId),
101
+ filteredTokensFormatted.map((token) => token.chainId || 0),
98
102
  )
99
103
  return Array.from(chainIds)
100
104
  .map((chainId) => {
@@ -115,7 +119,7 @@ export const TokenSelector: React.FC<TokenSelectorProps> = ({
115
119
  (token) =>
116
120
  token.contractAddress.toLowerCase() ===
117
121
  recentToken.contractAddress.toLowerCase() &&
118
- token.chainId === recentToken.chainId,
122
+ (token.chainId || 0) === (recentToken.chainId || 0),
119
123
  )
120
124
 
121
125
  if (!existsInTokenList) return false
@@ -145,7 +149,7 @@ export const TokenSelector: React.FC<TokenSelectorProps> = ({
145
149
  }
146
150
 
147
151
  // Enhanced token select handler that resets chain filter
148
- const handleTokenSelectWithReset = (token: TokenFormatted) => {
152
+ const handleTokenSelectWithReset = (token: Token) => {
149
153
  // Reset chain filter after token selection
150
154
  setFilterByChainId(null)
151
155
  // Call the original handler
@@ -153,13 +157,13 @@ export const TokenSelector: React.FC<TokenSelectorProps> = ({
153
157
  }
154
158
 
155
159
  // Handle recent token selection by finding the actual token from the list
156
- const handleRecentTokenSelect = (recentToken: SupportedToken) => {
160
+ const handleRecentTokenSelect = (recentToken: Token) => {
157
161
  // Find the actual token from the filtered tokens list
158
162
  const actualToken = chainFilteredTokens.find(
159
163
  (token) =>
160
164
  token.contractAddress.toLowerCase() ===
161
165
  recentToken.contractAddress.toLowerCase() &&
162
- token.chainId === recentToken.chainId,
166
+ (token.chainId || 0) === (recentToken.chainId || 0),
163
167
  )
164
168
 
165
169
  if (actualToken) {
@@ -172,13 +176,44 @@ export const TokenSelector: React.FC<TokenSelectorProps> = ({
172
176
  }
173
177
  }
174
178
 
179
+ // Determine the error message to display
180
+ const errorMessage = useMemo(() => {
181
+ // Custom token error with chain info
182
+ if (
183
+ customTokenError &&
184
+ fetchChainId &&
185
+ searchQuery.trim().startsWith("0x")
186
+ ) {
187
+ const chainInfo = getChainInfo(fetchChainId)
188
+ const networkName = chainInfo?.name || `Chain ${fetchChainId}`
189
+ return `Token not found on ${networkName}.`
190
+ }
191
+
192
+ // Search query provided but no results
193
+ if (searchQuery.trim()) {
194
+ return "No tokens found matching your search."
195
+ }
196
+
197
+ // Fund method doesn't require error message
198
+ if (fundMethod === "qr-code" || fundMethod === "exchange") {
199
+ return ""
200
+ }
201
+
202
+ // Address connected but no tokens available
203
+ if (address) {
204
+ return "No available tokens found"
205
+ }
206
+
207
+ return ""
208
+ }, [customTokenError, fetchChainId, searchQuery, fundMethod, address])
209
+
175
210
  return (
176
211
  <div className="space-y-2">
177
212
  {/* Search Field */}
178
213
  <SearchInputField
179
214
  value={searchQuery}
180
215
  onChange={setSearchQuery}
181
- placeholder="Search tokens"
216
+ placeholder="Search tokens, symbol, address"
182
217
  autoFocus={true}
183
218
  className="mb-2"
184
219
  rightAlignedComponent={
@@ -211,48 +246,71 @@ export const TokenSelector: React.FC<TokenSelectorProps> = ({
211
246
  )}
212
247
  </AnimatePresence>
213
248
 
214
- {isLoadingTokens && (
249
+ {/* Show full spinner only for initial load (when no tokens are available yet) */}
250
+ {((isLoadingTokens && chainFilteredTokens.length === 0) ||
251
+ isLoadingCustomToken) && (
215
252
  <div className="text-center py-4">
216
253
  <div className="animate-spin rounded-full h-8 w-8 border-b-2 mx-auto border-solid border-black dark:border-white"></div>
217
254
  <p className="mt-2 text-gray-500 dark:text-gray-400">
218
- Loading your token balances...
255
+ {isLoadingCustomToken
256
+ ? "Fetching token information..."
257
+ : "Loading your token balances..."}
219
258
  </p>
220
259
  </div>
221
260
  )}
222
261
 
223
- {!isLoadingTokens && !balanceError && filteredTokens.length === 0 && (
224
- <div className="text-center py-4 rounded-lg trails-bg-secondary">
225
- <p className="text-gray-500 dark:text-gray-400">
226
- {searchQuery.trim()
227
- ? "No tokens found matching your search."
228
- : fundMethod === "qr-code" || fundMethod === "exchange"
229
- ? ""
230
- : address
231
- ? "No available tokens found"
232
- : ""}
262
+ {/* Subtle search indicator when searching with existing tokens */}
263
+ {isSearching && chainFilteredTokens.length > 0 && (
264
+ <div className="flex items-center justify-center gap-2 py-2">
265
+ <div className="animate-spin rounded-full h-4 w-4 border-b-2 border-solid border-gray-400 dark:border-gray-500"></div>
266
+ <p className="text-xs text-gray-500 dark:text-gray-400">
267
+ Searching...
233
268
  </p>
234
269
  </div>
235
270
  )}
236
271
 
272
+ {!isLoadingTokens &&
273
+ !isLoadingCustomToken &&
274
+ !balanceError &&
275
+ filteredTokens.length === 0 &&
276
+ chainFilteredTokens.length === 0 &&
277
+ errorMessage && (
278
+ <div className="text-center py-4 rounded-lg trails-bg-secondary">
279
+ <p className="text-gray-500 dark:text-gray-400">{errorMessage}</p>
280
+ </div>
281
+ )}
282
+
237
283
  {/* Token List */}
238
284
  {chainFilteredTokens.length > 0 && (
239
285
  <div
240
286
  className={`${compactMode ? "max-h-48" : filteredRecentTokens.length > 0 ? "max-h-[200px]" : "max-h-[250px]"} overflow-y-auto trails-scrollbar space-y-1`}
241
287
  >
242
288
  <AnimatePresence mode="popLayout">
243
- {chainFilteredTokens.map((token: TokenFormatted) => {
289
+ {chainFilteredTokens.map((token: Token) => {
244
290
  const {
245
291
  symbol,
246
292
  imageUrl,
247
293
  chainId,
248
294
  contractAddress,
249
295
  balanceUsdFormatted,
250
- tokenName,
296
+ balanceUsdDisplay,
297
+ name,
251
298
  priceUsd,
252
299
  balanceFormatted,
300
+ balance,
301
+ balanceUsd,
253
302
  isSufficientBalance,
254
303
  } = token
255
304
 
305
+ // Check if balance should be shown (hide if balance is 0 or empty)
306
+ const hasBalance =
307
+ !isValueZero(balance) ||
308
+ !isValueZero(balanceFormatted) ||
309
+ !isValueZero(balanceUsd) ||
310
+ !isValueZero(balanceUsdFormatted)
311
+ // Default isSufficientBalance to true if not set
312
+ const sufficientBalance = isSufficientBalance ?? true
313
+
256
314
  return (
257
315
  <motion.div
258
316
  key={`${chainId}-${contractAddress}`}
@@ -273,22 +331,22 @@ export const TokenSelector: React.FC<TokenSelectorProps> = ({
273
331
  }
274
332
  }}
275
333
  tabIndex={0}
276
- aria-label={`Select ${tokenName} token`}
334
+ aria-label={`Select ${name} token`}
277
335
  title={
278
- !isSufficientBalance &&
336
+ !sufficientBalance &&
279
337
  fundMethod !== "qr-code" &&
280
338
  fundMethod !== "exchange"
281
339
  ? "Insufficient balance for this token"
282
- : `Select ${tokenName} token`
340
+ : `Select ${name} token`
283
341
  }
284
342
  className={`w-full py-2 px-4 flex items-center space-x-3 transition-all duration-200 trails-list-item trails-border-radius-list-button ${
285
343
  isTokenSelected(token) ? "trails-list-item-selected" : ""
286
- } ${!isSufficientBalance && fundMethod !== "qr-code" && fundMethod !== "exchange" ? "opacity-75 cursor-not-allowed" : "cursor-pointer"}`}
344
+ } ${!sufficientBalance && fundMethod !== "qr-code" && fundMethod !== "exchange" ? "opacity-75 cursor-not-allowed" : "cursor-pointer"}`}
287
345
  >
288
346
  <div className="relative flex-shrink-0 mr-2">
289
347
  <div
290
348
  className={`rounded-full flex items-center justify-center bg-gray-100 dark:bg-gray-700 ${
291
- !isSufficientBalance &&
349
+ !sufficientBalance &&
292
350
  fundMethod !== "qr-code" &&
293
351
  fundMethod !== "exchange"
294
352
  ? "opacity-80"
@@ -306,7 +364,7 @@ export const TokenSelector: React.FC<TokenSelectorProps> = ({
306
364
  ) : (
307
365
  <span
308
366
  className={`text-base font-medium text-gray-600 dark:text-gray-300 ${
309
- !isSufficientBalance &&
367
+ !sufficientBalance &&
310
368
  fundMethod !== "qr-code" &&
311
369
  fundMethod !== "exchange"
312
370
  ? "opacity-70"
@@ -322,19 +380,19 @@ export const TokenSelector: React.FC<TokenSelectorProps> = ({
322
380
  <div className="flex-1 min-w-0 text-left">
323
381
  <h3
324
382
  className={`text-sm font-medium truncate text-gray-900 dark:text-white ${
325
- !isSufficientBalance &&
383
+ !sufficientBalance &&
326
384
  fundMethod !== "qr-code" &&
327
385
  fundMethod !== "exchange"
328
386
  ? "opacity-70"
329
387
  : ""
330
388
  }`}
331
389
  >
332
- {tokenName}
390
+ {name}
333
391
  </h3>
334
- <div className="group relative overflow-hidden w-full">
392
+ <div className="group relative w-full">
335
393
  {/* Default state: show symbol */}
336
394
  <div
337
- className={`flex items-center transition-all duration-300 ease-in-out ${
395
+ className={`flex items-center gap-1.5 transition-all duration-300 ease-in-out ${
338
396
  contractAddress &&
339
397
  contractAddress.toLowerCase() !==
340
398
  zeroAddress.toLowerCase()
@@ -351,6 +409,16 @@ export const TokenSelector: React.FC<TokenSelectorProps> = ({
351
409
  <span className="text-xs text-gray-500 dark:text-gray-400 whitespace-nowrap">
352
410
  {symbol}
353
411
  </span>
412
+ {/* Custom token indicator */}
413
+ {token.isCustomToken && (
414
+ <div className="relative group/indicator">
415
+ <AlertTriangle className="w-3 h-3 text-gray-500 dark:text-gray-400" />
416
+ <div className="absolute bottom-full left-1/2 -translate-x-1/2 mb-1 px-2 py-1 text-xs text-white bg-gray-900 dark:bg-gray-700 rounded whitespace-nowrap opacity-0 group-hover/indicator:opacity-100 transition-opacity pointer-events-none z-50">
417
+ Custom token added by user
418
+ <div className="absolute top-full left-1/2 -translate-x-1/2 -mt-px border-4 border-transparent border-t-gray-900 dark:border-t-gray-700"></div>
419
+ </div>
420
+ </div>
421
+ )}
354
422
  </div>
355
423
 
356
424
  {/* Hover state: show address with copy button (only for non-zero addresses) */}
@@ -358,8 +426,8 @@ export const TokenSelector: React.FC<TokenSelectorProps> = ({
358
426
  contractAddress.toLowerCase() !==
359
427
  zeroAddress.toLowerCase() && (
360
428
  <div
361
- className={`absolute top-0 left-0 flex items-center transition-all duration-300 ease-in-out opacity-0 transform translate-x-2 ${
362
- !isSufficientBalance &&
429
+ className={`absolute top-0 left-0 flex items-center gap-1.5 transition-all duration-300 ease-in-out opacity-0 transform translate-x-2 ${
430
+ !sufficientBalance &&
363
431
  fundMethod !== "qr-code" &&
364
432
  fundMethod !== "exchange"
365
433
  ? "group-hover:opacity-70"
@@ -374,7 +442,7 @@ export const TokenSelector: React.FC<TokenSelectorProps> = ({
374
442
  onClick={(e) =>
375
443
  handleCopyAddress(contractAddress, e)
376
444
  }
377
- className={`ml-1 p-0.5 rounded transition-all duration-200 cursor-pointer ${
445
+ className={`p-0.5 rounded transition-all duration-200 cursor-pointer ${
378
446
  copiedAddress === contractAddress
379
447
  ? "bg-green-100 dark:bg-green-900/30"
380
448
  : "hover:bg-gray-200 dark:hover:bg-gray-600"
@@ -405,29 +473,105 @@ export const TokenSelector: React.FC<TokenSelectorProps> = ({
405
473
  <Copy className="w-3 h-3 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300" />
406
474
  )}
407
475
  </button>
476
+ {/* Token info tooltip */}
477
+ <Tooltip
478
+ content={
479
+ <div className="space-y-2 text-left">
480
+ <div>
481
+ <span className="opacity-70">Symbol:</span>{" "}
482
+ <span className="font-medium">
483
+ {token.symbol}
484
+ </span>
485
+ </div>
486
+ <div>
487
+ <span className="opacity-70">Name:</span>{" "}
488
+ <span className="font-medium">
489
+ {token.name}
490
+ </span>
491
+ </div>
492
+ <div>
493
+ <span className="opacity-70">Chain:</span>{" "}
494
+ <span className="font-medium">
495
+ {token.chainName ||
496
+ getChainInfo(token.chainId || 0)
497
+ ?.name ||
498
+ `Chain ${token.chainId || 0}`}
499
+ </span>
500
+ </div>
501
+ <div>
502
+ <span className="opacity-70">
503
+ Decimals:
504
+ </span>{" "}
505
+ <span className="font-medium">
506
+ {token.decimals}
507
+ </span>
508
+ </div>
509
+ <div>
510
+ <span className="opacity-70">Address:</span>{" "}
511
+ <span className="font-mono text-[10px] break-all block mt-0.5">
512
+ {contractAddress}
513
+ </span>
514
+ </div>
515
+ </div>
516
+ }
517
+ side="top"
518
+ align="center"
519
+ sideOffset={8}
520
+ >
521
+ <Info className="w-3 h-3 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 cursor-pointer" />
522
+ </Tooltip>
523
+ {/* Custom token indicator on hover state */}
524
+ {token.isCustomToken && (
525
+ <div className="relative group/indicator">
526
+ <AlertTriangle className="w-3 h-3 text-gray-500 dark:text-gray-400" />
527
+ <div className="absolute bottom-full left-1/2 -translate-x-1/2 mb-1 px-2 py-1 text-xs text-white bg-gray-900 dark:bg-gray-700 rounded whitespace-nowrap opacity-0 group-hover/indicator:opacity-100 transition-opacity pointer-events-none z-50">
528
+ Custom token added by user
529
+ <div className="absolute top-full left-1/2 -translate-x-1/2 -mt-px border-4 border-transparent border-t-gray-900 dark:border-t-gray-700"></div>
530
+ </div>
531
+ </div>
532
+ )}
408
533
  </div>
409
534
  )}
410
535
  </div>
411
536
  </div>
412
537
 
413
- {fundMethod !== "qr-code" && fundMethod !== "exchange" && (
414
- <div className="text-right flex-shrink-0">
415
- {priceUsd > 0 ? (
416
- <>
538
+ {fundMethod !== "qr-code" &&
539
+ fundMethod !== "exchange" &&
540
+ hasBalance && (
541
+ <div className="text-right flex-shrink-0">
542
+ {(priceUsd ?? 0) > 0 ? (
543
+ <>
544
+ <p
545
+ className={`text-sm font-medium text-gray-900 dark:text-white ${
546
+ !sufficientBalance &&
547
+ fundMethod !== "qr-code" &&
548
+ fundMethod !== "exchange"
549
+ ? "opacity-70"
550
+ : ""
551
+ }`}
552
+ >
553
+ {isBalanceVisible
554
+ ? balanceUsdDisplay ||
555
+ balanceUsdFormatted ||
556
+ "$0.00"
557
+ : "••••••"}
558
+ </p>
559
+ <p
560
+ className={`text-xs text-gray-500 dark:text-gray-400 ${
561
+ !sufficientBalance &&
562
+ fundMethod !== "qr-code" &&
563
+ fundMethod !== "exchange"
564
+ ? "opacity-70"
565
+ : ""
566
+ }`}
567
+ >
568
+ {isBalanceVisible ? balanceFormatted : "••••••"}
569
+ </p>
570
+ </>
571
+ ) : (
417
572
  <p
418
573
  className={`text-sm font-medium text-gray-900 dark:text-white ${
419
- !isSufficientBalance &&
420
- fundMethod !== "qr-code" &&
421
- fundMethod !== "exchange"
422
- ? "opacity-70"
423
- : ""
424
- }`}
425
- >
426
- {isBalanceVisible ? balanceUsdFormatted : "••••••"}
427
- </p>
428
- <p
429
- className={`text-xs text-gray-500 dark:text-gray-400 ${
430
- !isSufficientBalance &&
574
+ !sufficientBalance &&
431
575
  fundMethod !== "qr-code" &&
432
576
  fundMethod !== "exchange"
433
577
  ? "opacity-70"
@@ -436,22 +580,9 @@ export const TokenSelector: React.FC<TokenSelectorProps> = ({
436
580
  >
437
581
  {isBalanceVisible ? balanceFormatted : "••••••"}
438
582
  </p>
439
- </>
440
- ) : (
441
- <p
442
- className={`text-sm font-medium text-gray-900 dark:text-white ${
443
- !isSufficientBalance &&
444
- fundMethod !== "qr-code" &&
445
- fundMethod !== "exchange"
446
- ? "opacity-70"
447
- : ""
448
- }`}
449
- >
450
- {isBalanceVisible ? balanceFormatted : "••••••"}
451
- </p>
452
- )}
453
- </div>
454
- )}
583
+ )}
584
+ </div>
585
+ )}
455
586
  </motion.div>
456
587
  )
457
588
  })}
@@ -3,17 +3,28 @@ import * as TooltipPrimitive from "@radix-ui/react-tooltip"
3
3
  import { useTheme } from "./ThemeProvider.js"
4
4
 
5
5
  interface TooltipProps {
6
- message: string
6
+ message?: string
7
+ content?: React.ReactNode
7
8
  children: React.ReactNode
8
9
  className?: string
10
+ side?: "top" | "right" | "bottom" | "left"
11
+ align?: "start" | "center" | "end"
12
+ sideOffset?: number
13
+ alignOffset?: number
9
14
  }
10
15
 
11
16
  export const Tooltip: React.FC<TooltipProps> = ({
12
17
  message,
18
+ content,
13
19
  children,
14
20
  className = "",
21
+ side = "top",
22
+ align = "center",
23
+ sideOffset = 4,
24
+ alignOffset = 0,
15
25
  }) => {
16
26
  const { isDark } = useTheme()
27
+ const tooltipContent = content ?? message
17
28
 
18
29
  return (
19
30
  <TooltipPrimitive.Provider>
@@ -23,7 +34,7 @@ export const Tooltip: React.FC<TooltipProps> = ({
23
34
  </TooltipPrimitive.Trigger>
24
35
  <TooltipPrimitive.Portal>
25
36
  <TooltipPrimitive.Content
26
- className="trails-border-radius-container px-3 py-2 text-xs font-medium shadow-lg z-50 animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2"
37
+ className="trails-border-radius-container px-3 py-2 text-xs font-medium shadow-lg z-[100] animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2"
27
38
  style={{
28
39
  maxWidth: "400px",
29
40
  wordWrap: "break-word",
@@ -32,12 +43,12 @@ export const Tooltip: React.FC<TooltipProps> = ({
32
43
  backgroundColor: isDark ? "#111827" : "#ffffff", // gray-900 or white
33
44
  color: isDark ? "#ffffff" : "#000000", // white or black
34
45
  }}
35
- side="top"
36
- align="center"
37
- sideOffset={4}
38
- alignOffset={0}
46
+ side={side}
47
+ align={align}
48
+ sideOffset={sideOffset}
49
+ alignOffset={alignOffset}
39
50
  >
40
- {message}
51
+ {tooltipContent}
41
52
  <TooltipPrimitive.Arrow
42
53
  style={{ fill: isDark ? "#111827" : "#ffffff" }} // gray-900 or white
43
54
  />
@@ -0,0 +1,118 @@
1
+ import { useState, useEffect, useContext, useMemo } from "react"
2
+ import { createPortal } from "react-dom"
3
+ import { http } from "viem"
4
+ import type { Chain } from "viem"
5
+ import { WagmiContext, WagmiProvider, createConfig, createStorage } from "wagmi"
6
+ import { QueryClient, QueryClientProvider } from "@tanstack/react-query"
7
+ import { logger } from "../../logger.js"
8
+ import { getAllChains, getRpcUrl } from "../../chains.js"
9
+ import { getConnectorsInternal } from "../../wallets.js"
10
+ import { PROD_SEQUENCE_NODE_GATEWAY_URL } from "../../constants.js"
11
+ import { TrailsContext } from "../providers/TrailsProvider.js"
12
+ import { ShadowPortal } from "./ShadowPortal.js"
13
+ import { ThemeProvider } from "./ThemeProvider.js"
14
+ import { WidgetProviders } from "./WidgetProviders.js"
15
+ import { HookModalContent } from "./HookModalContent.js"
16
+
17
+ // QueryClient for when we create our own WagmiProvider
18
+ const hookModalQueryClient = new QueryClient()
19
+
20
+ /**
21
+ * Inner component that renders the portal with shared provider tree.
22
+ * Uses WidgetProviders to ensure all widget-level context providers are available.
23
+ */
24
+ function TrailsHookModalInner() {
25
+ const [mounted, setMounted] = useState(false)
26
+
27
+ useEffect(() => {
28
+ setMounted(true)
29
+ logger.console.log("[trails-sdk] [TrailsHookModalInner] Mounted")
30
+ }, [])
31
+
32
+ if (!mounted) {
33
+ return null
34
+ }
35
+
36
+ return createPortal(
37
+ <ShadowPortal>
38
+ <ThemeProvider>
39
+ <WidgetProviders>
40
+ <HookModalContent />
41
+ </WidgetProviders>
42
+ </ThemeProvider>
43
+ </ShadowPortal>,
44
+ document.body,
45
+ )
46
+ }
47
+
48
+ /**
49
+ * TrailsHookModal is the modal component used by useTrailsSendTransaction.
50
+ * It creates its own WagmiProvider if none exists, ensuring it can work
51
+ * both with and without a parent TrailsWidget.
52
+ *
53
+ * The modal content is wrapped with WidgetProviders to ensure all widget-level
54
+ * context providers are available, making shared components like ScreenHeader work.
55
+ */
56
+ export function TrailsHookModal() {
57
+ const wagmiContext = useContext(WagmiContext)
58
+ const trailsContext = useContext(TrailsContext)
59
+
60
+ logger.console.log("[trails-sdk] [TrailsHookModal] Check:", {
61
+ hasWagmiContext: !!wagmiContext,
62
+ hasTrailsContext: !!trailsContext,
63
+ })
64
+
65
+ // Create wagmi config if no parent WagmiProvider exists
66
+ const wagmiConfig = useMemo(() => {
67
+ if (wagmiContext) {
68
+ logger.console.log(
69
+ "[trails-sdk] [TrailsHookModal] Using parent WagmiProvider",
70
+ )
71
+ return null // Use parent's config
72
+ }
73
+
74
+ logger.console.log(
75
+ "[trails-sdk] [TrailsHookModal] Creating own WagmiProvider",
76
+ )
77
+
78
+ // Create our own config (similar to TrailsWidget)
79
+ const chains = getAllChains() as Chain[]
80
+ const apiKey = trailsContext?.trailsApiKey || ""
81
+ const nodeGatewayUrl =
82
+ trailsContext?.sequenceNodeGatewayUrl || PROD_SEQUENCE_NODE_GATEWAY_URL
83
+
84
+ return createConfig({
85
+ chains: chains as any,
86
+ transports: chains.reduce(
87
+ (acc, chain) => {
88
+ const sequenceRpcUrl = getRpcUrl(chain.id, apiKey, nodeGatewayUrl)
89
+ return {
90
+ ...acc,
91
+ [chain.id]: sequenceRpcUrl ? http(sequenceRpcUrl) : http(),
92
+ }
93
+ },
94
+ {} as Record<number, ReturnType<typeof http>>,
95
+ ),
96
+ connectors: getConnectorsInternal(apiKey),
97
+ storage: createStorage({
98
+ storage: localStorage,
99
+ key: "trails-hook-modal-wagmi",
100
+ }),
101
+ })
102
+ }, [wagmiContext, trailsContext])
103
+
104
+ const content = <TrailsHookModalInner />
105
+
106
+ // Wrap with WagmiProvider if we created our own config
107
+ if (wagmiConfig) {
108
+ return (
109
+ <WagmiProvider config={wagmiConfig}>
110
+ <QueryClientProvider client={hookModalQueryClient}>
111
+ {content}
112
+ </QueryClientProvider>
113
+ </WagmiProvider>
114
+ )
115
+ }
116
+
117
+ return content
118
+ }