0xtrails 0.13.0 → 0.13.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (307) hide show
  1. package/dist/{ccip-Cg9-lJ6K.js → ccip-CT_An6eM.js} +39 -39
  2. package/dist/chains.d.ts +4 -3
  3. package/dist/chains.d.ts.map +1 -1
  4. package/dist/constants.d.ts +1 -0
  5. package/dist/constants.d.ts.map +1 -1
  6. package/dist/customTokens.d.ts.map +1 -1
  7. package/dist/error.d.ts +1 -0
  8. package/dist/error.d.ts.map +1 -1
  9. package/dist/gasless.d.ts +1 -2
  10. package/dist/gasless.d.ts.map +1 -1
  11. package/dist/{index-DEojZg7b.js → index-RfqL5Foz.js} +56672 -43550
  12. package/dist/index.d.ts +5 -2
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +385 -333
  15. package/dist/intents.d.ts +8 -2
  16. package/dist/intents.d.ts.map +1 -1
  17. package/dist/keyMachineClient.d.ts +9 -0
  18. package/dist/keyMachineClient.d.ts.map +1 -0
  19. package/dist/keymachine/index.d.ts +14 -0
  20. package/dist/keymachine/index.d.ts.map +1 -0
  21. package/dist/keymachine/key-machine.gen.d.ts +461 -0
  22. package/dist/keymachine/key-machine.gen.d.ts.map +1 -0
  23. package/dist/onramp/MeshConnectFlow.d.ts +18 -0
  24. package/dist/onramp/MeshConnectFlow.d.ts.map +1 -0
  25. package/dist/onramp/MeshConnectIframe.d.ts +13 -0
  26. package/dist/onramp/MeshConnectIframe.d.ts.map +1 -0
  27. package/dist/onramp/SendFromExchangeButton.d.ts +16 -0
  28. package/dist/onramp/SendFromExchangeButton.d.ts.map +1 -0
  29. package/dist/onramp/TrailsOnRampProvider.d.ts +31 -0
  30. package/dist/onramp/TrailsOnRampProvider.d.ts.map +1 -0
  31. package/dist/onramp/index.d.ts +13 -0
  32. package/dist/onramp/index.d.ts.map +1 -0
  33. package/dist/onramp/meshconnect.d.ts +30 -0
  34. package/dist/onramp/meshconnect.d.ts.map +1 -0
  35. package/dist/onramp/trailsOnramp.d.ts +24 -0
  36. package/dist/onramp/trailsOnramp.d.ts.map +1 -0
  37. package/dist/onramp-client/index.d.ts +3 -3
  38. package/dist/onramp-client/index.d.ts.map +1 -1
  39. package/dist/paymasterSend.d.ts.map +1 -1
  40. package/dist/prepareSend.d.ts.map +1 -1
  41. package/dist/query/balance.fetchers.d.ts +31 -2
  42. package/dist/query/balance.fetchers.d.ts.map +1 -1
  43. package/dist/query/balance.hooks.d.ts +21 -2
  44. package/dist/query/balance.hooks.d.ts.map +1 -1
  45. package/dist/query/balance.queries.d.ts +18 -1
  46. package/dist/query/balance.queries.d.ts.map +1 -1
  47. package/dist/query/chains.queries.d.ts.map +1 -1
  48. package/dist/query/meld.fetchers.d.ts +1 -1
  49. package/dist/query/meld.fetchers.d.ts.map +1 -1
  50. package/dist/query/meld.hooks.d.ts +3 -3
  51. package/dist/query/meld.hooks.d.ts.map +1 -1
  52. package/dist/query/meld.queries.d.ts +1 -1
  53. package/dist/query/meld.queries.d.ts.map +1 -1
  54. package/dist/query/price.fetchers.d.ts +15 -0
  55. package/dist/query/price.fetchers.d.ts.map +1 -0
  56. package/dist/query/price.hooks.d.ts +352 -0
  57. package/dist/query/price.hooks.d.ts.map +1 -0
  58. package/dist/query/price.queries.d.ts +34 -0
  59. package/dist/query/price.queries.d.ts.map +1 -0
  60. package/dist/query/tokenList.queries.d.ts +54 -0
  61. package/dist/query/tokenList.queries.d.ts.map +1 -0
  62. package/dist/recover.d.ts +6 -4
  63. package/dist/recover.d.ts.map +1 -1
  64. package/dist/tokens.d.ts +13 -0
  65. package/dist/tokens.d.ts.map +1 -1
  66. package/dist/transactionIntent/deposits/depositOrchestrator.d.ts +2 -2
  67. package/dist/transactionIntent/deposits/depositOrchestrator.d.ts.map +1 -1
  68. package/dist/transactionIntent/deposits/gaslessDeposit.d.ts +2 -2
  69. package/dist/transactionIntent/deposits/gaslessDeposit.d.ts.map +1 -1
  70. package/dist/transactionIntent/deposits/standardDeposit.d.ts +1 -1
  71. package/dist/transactionIntent/deposits/standardDeposit.d.ts.map +1 -1
  72. package/dist/transactionIntent/handlers/intentHandler.d.ts.map +1 -1
  73. package/dist/transactionIntent/helpers/transactionStateHelpers.d.ts.map +1 -1
  74. package/dist/transactionIntent/quote/normalizeQuote.d.ts.map +1 -1
  75. package/dist/transactionIntent/types.d.ts +1 -1
  76. package/dist/transactionIntent/types.d.ts.map +1 -1
  77. package/dist/transactions.d.ts +4 -0
  78. package/dist/transactions.d.ts.map +1 -1
  79. package/dist/umd/trails.min.js +291 -202
  80. package/dist/utils/format.d.ts +7 -0
  81. package/dist/utils/format.d.ts.map +1 -1
  82. package/dist/walletUtils.d.ts +2 -1
  83. package/dist/walletUtils.d.ts.map +1 -1
  84. package/dist/wallets.d.ts +13 -54
  85. package/dist/wallets.d.ts.map +1 -1
  86. package/dist/widget/components/AccountIntentTransactionHistory.d.ts.map +1 -1
  87. package/dist/widget/components/ClassicSwap.d.ts.map +1 -1
  88. package/dist/widget/components/ConnectWallet.d.ts.map +1 -1
  89. package/dist/widget/components/ConnectedWallets.d.ts.map +1 -1
  90. package/dist/widget/components/DirectTransfer.d.ts +1 -1
  91. package/dist/widget/components/DirectTransfer.d.ts.map +1 -1
  92. package/dist/widget/components/EarnPools.d.ts.map +1 -1
  93. package/dist/widget/components/ExecutionStatusBadge.d.ts.map +1 -1
  94. package/dist/widget/components/Fund.d.ts.map +1 -1
  95. package/dist/widget/components/FundMethods.d.ts.map +1 -1
  96. package/dist/widget/components/HighPriceImpactBlock.d.ts +7 -0
  97. package/dist/widget/components/HighPriceImpactBlock.d.ts.map +1 -0
  98. package/dist/widget/components/MeldHistory.d.ts.map +1 -1
  99. package/dist/widget/components/MeshExchangeSelection.d.ts +11 -0
  100. package/dist/widget/components/MeshExchangeSelection.d.ts.map +1 -0
  101. package/dist/widget/components/OnrampHistoryRow.d.ts +1 -1
  102. package/dist/widget/components/OnrampHistoryRow.d.ts.map +1 -1
  103. package/dist/widget/components/OnrampProviderConfirmation.d.ts.map +1 -1
  104. package/dist/widget/components/Pay.d.ts.map +1 -1
  105. package/dist/widget/components/PoolDeposit.d.ts.map +1 -1
  106. package/dist/widget/components/PoolWithdraw.d.ts.map +1 -1
  107. package/dist/widget/components/QRCodeWalletSelect.d.ts +1 -1
  108. package/dist/widget/components/QRCodeWalletSelect.d.ts.map +1 -1
  109. package/dist/widget/components/QuoteDetails.d.ts.map +1 -1
  110. package/dist/widget/components/Receipt.d.ts.map +1 -1
  111. package/dist/widget/components/Recipients.d.ts.map +1 -1
  112. package/dist/widget/components/RefundWarning.d.ts.map +1 -1
  113. package/dist/widget/components/TokenSelector.d.ts.map +1 -1
  114. package/dist/widget/components/TransactionDetails.d.ts.map +1 -1
  115. package/dist/widget/components/TransactionHistoryItem.d.ts +2 -0
  116. package/dist/widget/components/TransactionHistoryItem.d.ts.map +1 -1
  117. package/dist/widget/components/TransferPendingVertical.d.ts +1 -0
  118. package/dist/widget/components/TransferPendingVertical.d.ts.map +1 -1
  119. package/dist/widget/components/WaasFeeOptions.d.ts.map +1 -1
  120. package/dist/widget/components/WalletConnect.d.ts.map +1 -1
  121. package/dist/widget/components/WalletImage.d.ts.map +1 -1
  122. package/dist/widget/components/WalletList.d.ts.map +1 -1
  123. package/dist/widget/components/Withdraw.d.ts.map +1 -1
  124. package/dist/widget/css/compiled.css +1 -1
  125. package/dist/widget/hooks/useAddressWalletIcon.d.ts.map +1 -1
  126. package/dist/widget/hooks/useCombinedHistory.d.ts +6 -5
  127. package/dist/widget/hooks/useCombinedHistory.d.ts.map +1 -1
  128. package/dist/widget/hooks/useCustomTokenSearch.d.ts +6 -1
  129. package/dist/widget/hooks/useCustomTokenSearch.d.ts.map +1 -1
  130. package/dist/widget/hooks/useDefaultDestinationToken.d.ts.map +1 -1
  131. package/dist/widget/hooks/useDefaultOriginToken.d.ts.map +1 -1
  132. package/dist/widget/hooks/useFiatOnRampCurrencies.d.ts +1 -1
  133. package/dist/widget/hooks/useFiatOnRampCurrencies.d.ts.map +1 -1
  134. package/dist/widget/hooks/useGetIntent.d.ts +3 -2
  135. package/dist/widget/hooks/useGetIntent.d.ts.map +1 -1
  136. package/dist/widget/hooks/useIntentReceiptBalances.d.ts +1 -1
  137. package/dist/widget/hooks/useIntentReceiptBalances.d.ts.map +1 -1
  138. package/dist/widget/hooks/useIntentTransactionHistory.d.ts +3 -2
  139. package/dist/widget/hooks/useIntentTransactionHistory.d.ts.map +1 -1
  140. package/dist/widget/hooks/useMeldTransactionHistory.d.ts +1 -1
  141. package/dist/widget/hooks/useMeldTransactionHistory.d.ts.map +1 -1
  142. package/dist/widget/hooks/useMeldTransactionStatus.d.ts +1 -1
  143. package/dist/widget/hooks/useMeldTransactionStatus.d.ts.map +1 -1
  144. package/dist/widget/hooks/useOnRampQuote.d.ts +1 -1
  145. package/dist/widget/hooks/useOnRampQuote.d.ts.map +1 -1
  146. package/dist/widget/hooks/useOnRampTransactionStatus.d.ts +1 -1
  147. package/dist/widget/hooks/useOnRampTransactionStatus.d.ts.map +1 -1
  148. package/dist/widget/hooks/useQuote.d.ts +2 -2
  149. package/dist/widget/hooks/useQuote.d.ts.map +1 -1
  150. package/dist/widget/hooks/useSelectedFundMethod.d.ts +7 -0
  151. package/dist/widget/hooks/useSelectedFundMethod.d.ts.map +1 -1
  152. package/dist/widget/hooks/useSendForm.d.ts +0 -1
  153. package/dist/widget/hooks/useSendForm.d.ts.map +1 -1
  154. package/dist/widget/hooks/useTokenList.d.ts +7 -1
  155. package/dist/widget/hooks/useTokenList.d.ts.map +1 -1
  156. package/dist/widget/hooks/useViewManager.d.ts +1 -1
  157. package/dist/widget/hooks/useViewManager.d.ts.map +1 -1
  158. package/dist/widget/index.js +1 -1
  159. package/dist/widget/providers/TrailsProvider.d.ts +2 -0
  160. package/dist/widget/providers/TrailsProvider.d.ts.map +1 -1
  161. package/dist/widget/utils/createWagmiConfig.d.ts +2 -2
  162. package/dist/widget/utils/createWagmiConfig.d.ts.map +1 -1
  163. package/dist/widget/utils/fundMethodSwitchState.d.ts +1 -0
  164. package/dist/widget/utils/fundMethodSwitchState.d.ts.map +1 -1
  165. package/dist/widget/utils/historyFilters.d.ts +13 -0
  166. package/dist/widget/utils/historyFilters.d.ts.map +1 -0
  167. package/dist/widget/utils/meldProviderUtils.d.ts +1 -1
  168. package/dist/widget/utils/meldProviderUtils.d.ts.map +1 -1
  169. package/dist/widget/utils/meshSupportedTokens.d.ts +4 -0
  170. package/dist/widget/utils/meshSupportedTokens.d.ts.map +1 -0
  171. package/dist/widget/utils/onrampConfig.d.ts +11 -0
  172. package/dist/widget/utils/onrampConfig.d.ts.map +1 -0
  173. package/dist/widget/utils/statusLabel.d.ts +2 -0
  174. package/dist/widget/utils/statusLabel.d.ts.map +1 -0
  175. package/dist/widget/utils/trailsOnrampConfig.d.ts +18 -0
  176. package/dist/widget/utils/trailsOnrampConfig.d.ts.map +1 -0
  177. package/dist/widget/widget.d.ts +24 -8
  178. package/dist/widget/widget.d.ts.map +1 -1
  179. package/package.json +9 -7
  180. package/src/chains.ts +26 -9
  181. package/src/constants.ts +2 -0
  182. package/src/customTokens.ts +22 -7
  183. package/src/error.ts +7 -0
  184. package/src/gasless.ts +5 -2
  185. package/src/index.ts +8 -5
  186. package/src/intents.ts +56 -60
  187. package/src/keyMachineClient.ts +29 -0
  188. package/src/keymachine/index.ts +175 -0
  189. package/src/keymachine/key-machine.gen.ts +993 -0
  190. package/src/onramp/MeshConnectFlow.tsx +86 -0
  191. package/src/onramp/MeshConnectIframe.tsx +661 -0
  192. package/src/onramp/SendFromExchangeButton.tsx +81 -0
  193. package/src/onramp/TrailsOnRampProvider.tsx +59 -0
  194. package/src/onramp/index.ts +31 -0
  195. package/src/onramp/meshconnect.ts +277 -0
  196. package/src/onramp/trailsOnramp.tsx +130 -0
  197. package/src/onramp-client/index.ts +4 -6
  198. package/src/paymasterSend.ts +0 -5
  199. package/src/prepareSend.ts +45 -44
  200. package/src/query/balance.fetchers.ts +172 -17
  201. package/src/query/balance.hooks.ts +69 -6
  202. package/src/query/balance.queries.ts +63 -0
  203. package/src/query/chains.queries.ts +1 -6
  204. package/src/query/meld.fetchers.ts +1 -1
  205. package/src/query/meld.hooks.ts +1 -1
  206. package/src/query/meld.queries.ts +1 -1
  207. package/src/query/price.fetchers.ts +53 -0
  208. package/src/query/price.hooks.ts +46 -0
  209. package/src/query/price.queries.ts +364 -0
  210. package/src/query/tokenList.queries.ts +118 -0
  211. package/src/recover.ts +89 -26
  212. package/src/tokens.ts +108 -26
  213. package/src/transactionIntent/deposits/depositOrchestrator.ts +11 -11
  214. package/src/transactionIntent/deposits/gaslessDeposit.ts +38 -39
  215. package/src/transactionIntent/deposits/standardDeposit.ts +5 -30
  216. package/src/transactionIntent/handlers/intentHandler.ts +29 -12
  217. package/src/transactionIntent/helpers/transactionStateHelpers.ts +5 -2
  218. package/src/transactionIntent/quote/normalizeQuote.ts +11 -5
  219. package/src/transactionIntent/types.ts +1 -1
  220. package/src/transactions.ts +5 -1
  221. package/src/utils/format.ts +85 -1
  222. package/src/walletUtils.ts +2 -1
  223. package/src/wallets.ts +184 -380
  224. package/src/widget/compiled.css +1 -1
  225. package/src/widget/components/AccountIntentTransactionHistory.tsx +134 -109
  226. package/src/widget/components/ClassicSwap.tsx +26 -24
  227. package/src/widget/components/ConnectWallet.tsx +4 -2
  228. package/src/widget/components/ConnectedWallets.tsx +2 -5
  229. package/src/widget/components/DirectTransfer.tsx +5 -2
  230. package/src/widget/components/EarnPools.tsx +1 -2
  231. package/src/widget/components/ExecutionStatusBadge.tsx +10 -4
  232. package/src/widget/components/Fund.tsx +169 -110
  233. package/src/widget/components/FundMethods.tsx +5 -9
  234. package/src/widget/components/HighPriceImpactBlock.tsx +44 -0
  235. package/src/widget/components/MeldHistory.tsx +4 -28
  236. package/src/widget/components/MeshExchangeSelection.tsx +218 -0
  237. package/src/widget/components/OnrampHistoryRow.tsx +3 -27
  238. package/src/widget/components/OnrampProviderConfirmation.tsx +0 -25
  239. package/src/widget/components/Pay.tsx +20 -36
  240. package/src/widget/components/PoolDeposit.tsx +14 -24
  241. package/src/widget/components/PoolWithdraw.tsx +1 -63
  242. package/src/widget/components/QRCodeWalletSelect.tsx +5 -2
  243. package/src/widget/components/QuoteDetails.tsx +113 -106
  244. package/src/widget/components/Receipt.tsx +0 -11
  245. package/src/widget/components/Recipients.tsx +2 -1
  246. package/src/widget/components/RefundWarning.tsx +5 -10
  247. package/src/widget/components/ThemeProvider.tsx +4 -4
  248. package/src/widget/components/TokenSelector.tsx +85 -16
  249. package/src/widget/components/TransactionDetails.tsx +46 -0
  250. package/src/widget/components/TransactionHistoryItem.tsx +14 -23
  251. package/src/widget/components/TransferPendingVertical.tsx +17 -11
  252. package/src/widget/components/WaasFeeOptions.tsx +4 -42
  253. package/src/widget/components/WalletConnect.tsx +2 -5
  254. package/src/widget/components/WalletImage.tsx +6 -18
  255. package/src/widget/components/WalletList.tsx +1 -1
  256. package/src/widget/components/Withdraw.tsx +22 -23
  257. package/src/widget/hooks/useAddressWalletIcon.ts +2 -1
  258. package/src/widget/hooks/useAmountUsd.ts +1 -1
  259. package/src/widget/hooks/useCombinedHistory.ts +37 -93
  260. package/src/widget/hooks/useCustomTokenSearch.tsx +63 -33
  261. package/src/widget/hooks/useDefaultDestinationToken.tsx +2 -5
  262. package/src/widget/hooks/useDefaultOriginToken.tsx +2 -5
  263. package/src/widget/hooks/useFiatOnRampCurrencies.ts +1 -1
  264. package/src/widget/hooks/useGetIntent.ts +5 -4
  265. package/src/widget/hooks/useIntentReceiptBalances.ts +3 -3
  266. package/src/widget/hooks/useIntentTransactionHistory.ts +24 -47
  267. package/src/widget/hooks/useMeldTransactionHistory.ts +4 -2
  268. package/src/widget/hooks/useMeldTransactionStatus.ts +13 -11
  269. package/src/widget/hooks/useOnRampQuote.ts +3 -3
  270. package/src/widget/hooks/useOnRampTransactionStatus.ts +8 -6
  271. package/src/widget/hooks/useQuote.ts +56 -48
  272. package/src/widget/hooks/useSelectedFundMethod.tsx +14 -1
  273. package/src/widget/hooks/useSendForm.ts +52 -31
  274. package/src/widget/hooks/useTokenList.ts +209 -140
  275. package/src/widget/hooks/useTrailsSendTransaction.ts +1 -1
  276. package/src/widget/hooks/useViewManager.tsx +1 -0
  277. package/src/widget/providers/TrailsProvider.tsx +5 -0
  278. package/src/widget/styles.ts +1 -1
  279. package/src/widget/utils/createWagmiConfig.ts +7 -2
  280. package/src/widget/utils/fundMethodSwitchState.ts +2 -0
  281. package/src/widget/utils/historyFilters.ts +157 -0
  282. package/src/widget/utils/meldProviderUtils.ts +8 -2
  283. package/src/widget/utils/meshSupportedTokens.ts +28 -0
  284. package/src/widget/utils/onrampConfig.ts +15 -0
  285. package/src/widget/utils/statusLabel.ts +3 -0
  286. package/src/widget/utils/trailsOnrampConfig.ts +39 -0
  287. package/src/widget/widget.tsx +235 -185
  288. package/dist/onramp-client/trails-onramp.gen.d.ts +0 -570
  289. package/dist/onramp-client/trails-onramp.gen.d.ts.map +0 -1
  290. package/dist/prices.d.ts +0 -34
  291. package/dist/prices.d.ts.map +0 -1
  292. package/dist/useGasEstimation.d.ts +0 -34
  293. package/dist/useGasEstimation.d.ts.map +0 -1
  294. package/dist/widget/hooks/useCustomTokenFetch.d.ts +0 -19
  295. package/dist/widget/hooks/useCustomTokenFetch.d.ts.map +0 -1
  296. package/dist/widget/hooks/useTokenWithFreshBalance.d.ts +0 -18
  297. package/dist/widget/hooks/useTokenWithFreshBalance.d.ts.map +0 -1
  298. package/src/onramp-client/trails-onramp.gen.ts +0 -1320
  299. package/src/prices.ts +0 -528
  300. package/src/useGasEstimation.ts +0 -147
  301. package/src/widget/assets/Binance_Icon_Logo.svg +0 -14
  302. package/src/widget/assets/Bitfinex_Icon_Logo.svg +0 -5
  303. package/src/widget/assets/Coinbase_Icon_Logo.svg +0 -1
  304. package/src/widget/assets/WalletConnect-logo-blue-bg.svg +0 -11
  305. package/src/widget/assets/sequence-logo.svg +0 -15
  306. package/src/widget/hooks/useCustomTokenFetch.tsx +0 -74
  307. package/src/widget/hooks/useTokenWithFreshBalance.ts +0 -246
@@ -0,0 +1,661 @@
1
+ import * as meshSDK from "@meshconnect/web-link-sdk"
2
+ import type React from "react"
3
+ import { useCallback, useEffect, useMemo, useRef, useState } from "react"
4
+ import { logger } from "../logger.js"
5
+ import { SimpleHeader } from "../meld/components/SimpleHeader.js"
6
+ import { getActiveMeshMode, useTrailsOnRamp } from "./TrailsOnRampProvider.js"
7
+ import { createMeshLinkToken } from "./meshconnect.js"
8
+
9
+ const MESH_SESSION_DURATION_S = 20 * 60
10
+ const MESH_RENDER_TIMEOUT_MS = 8000
11
+
12
+ type MeshPopupState = "idle" | "closed" | "error"
13
+
14
+ function getMeshErrorMessage(err: unknown): string {
15
+ if (err && typeof err === "object") {
16
+ const cause = (err as { cause?: unknown }).cause
17
+ if (typeof cause === "string" && cause.trim().length > 0) {
18
+ return cause
19
+ }
20
+
21
+ const message = (err as { message?: unknown }).message
22
+ if (typeof message === "string" && message.trim().length > 0) {
23
+ return message
24
+ }
25
+ }
26
+
27
+ return err instanceof Error ? err.message : String(err)
28
+ }
29
+
30
+ function formatCountdown(seconds: number): string {
31
+ const mins = Math.floor(seconds / 60)
32
+ const secs = seconds % 60
33
+ return `${mins}:${secs.toString().padStart(2, "0")}`
34
+ }
35
+
36
+ function getPendingTransitionPayload(payload: any): any {
37
+ if (!payload || typeof payload !== "object") {
38
+ return null
39
+ }
40
+
41
+ return {
42
+ ...payload,
43
+ status:
44
+ typeof payload.status === "string" && payload.status.length > 0
45
+ ? payload.status
46
+ : "pending",
47
+ }
48
+ }
49
+
50
+ export interface MeshConnectProps {
51
+ onBack: () => void
52
+ toTokenSymbol?: string
53
+ onComplete?: (transferData: any) => void
54
+ toTokenAmount?: string
55
+ toChainId?: number
56
+ toRecipientAddress?: string
57
+ integrationId?: string
58
+ exchangeName?: string
59
+ }
60
+
61
+ export const MeshConnectIframe: React.FC<MeshConnectProps> = ({
62
+ onBack,
63
+ toTokenSymbol,
64
+ toTokenAmount,
65
+ toChainId,
66
+ toRecipientAddress,
67
+ onComplete,
68
+ integrationId,
69
+ exchangeName,
70
+ }) => {
71
+ const onRampContext = useTrailsOnRamp()
72
+ // Get environment from config, defaulting to sandbox if mesh.sandbox is true
73
+ const environment = getActiveMeshMode(onRampContext?.config)
74
+ const hostname = onRampContext?.config.hostname
75
+ const apiKey = onRampContext?.config.apiKey
76
+ const jwt = onRampContext?.config.jwt
77
+ const meshConfig = onRampContext?.config.mesh
78
+ const requestConfig = useMemo(
79
+ () => ({
80
+ hostname,
81
+ apiKey,
82
+ jwt,
83
+ mesh: meshConfig,
84
+ }),
85
+ [hostname, apiKey, jwt, meshConfig],
86
+ )
87
+
88
+ // Log environment configuration immediately
89
+ console.log("[onramp] MeshConnect environment configuration (console.log):", {
90
+ meshSandbox: onRampContext?.config.mesh?.sandbox,
91
+ environment,
92
+ config: onRampContext?.config,
93
+ defaultEnvironment: "production",
94
+ hasContext: !!onRampContext,
95
+ })
96
+ logger.console.log("[onramp] MeshConnect environment configuration:", {
97
+ meshSandbox: onRampContext?.config.mesh?.sandbox,
98
+ environment,
99
+ config: onRampContext?.config,
100
+ defaultEnvironment: "production",
101
+ hasContext: !!onRampContext,
102
+ })
103
+
104
+ // Log environment configuration on context changes
105
+ useEffect(() => {
106
+ logger.console.log(
107
+ "[onramp] MeshConnect environment configuration (useEffect):",
108
+ {
109
+ meshSandbox: onRampContext?.config.mesh?.sandbox,
110
+ environment,
111
+ config: onRampContext?.config,
112
+ defaultEnvironment: "production",
113
+ hasContext: !!onRampContext,
114
+ },
115
+ )
116
+ }, [environment, onRampContext])
117
+
118
+ const [linkToken, setLinkToken] = useState<string | null>(null)
119
+ const [meshClientId, setMeshClientId] = useState<string | null>(null)
120
+ const [loading, setLoading] = useState(true)
121
+ const [error, setError] = useState<string | null>(null)
122
+ const [payload, setPayload] = useState<any>(null)
123
+ const [transferFinishedData, setTransferFinishedData] = useState<any>(null)
124
+ const [meshLink, setMeshLink] = useState<any>(null)
125
+ const [popupState, setPopupState] = useState<MeshPopupState>("idle")
126
+ const [popupMessage, setPopupMessage] = useState<string | null>(null)
127
+ const [sessionTimeRemaining, setSessionTimeRemaining] = useState(
128
+ MESH_SESSION_DURATION_S,
129
+ )
130
+ const [refreshKey, setRefreshKey] = useState(0)
131
+ const meshRenderWatchdogRef = useRef<number | null>(null)
132
+ const hasPendingTransitionRef = useRef(false)
133
+ const initiatedTransferRef = useRef<any>(null)
134
+
135
+ const clearMeshRenderWatchdog = useCallback(() => {
136
+ if (
137
+ meshRenderWatchdogRef.current !== null &&
138
+ typeof window !== "undefined"
139
+ ) {
140
+ window.clearTimeout(meshRenderWatchdogRef.current)
141
+ meshRenderWatchdogRef.current = null
142
+ }
143
+ }, [])
144
+
145
+ const failMeshRender = useCallback(
146
+ async (message: string) => {
147
+ clearMeshRenderWatchdog()
148
+
149
+ try {
150
+ await meshLink?.closeLink?.()
151
+ } catch (closeError) {
152
+ logger.console.warn(
153
+ "[onramp] Failed to close Mesh popup after render failure:",
154
+ closeError,
155
+ )
156
+ }
157
+
158
+ setPopupState("error")
159
+ setPopupMessage(message)
160
+ },
161
+ [clearMeshRenderWatchdog, meshLink],
162
+ )
163
+
164
+ useEffect(() => {
165
+ if (transferFinishedData) {
166
+ return
167
+ }
168
+
169
+ const interval = setInterval(() => {
170
+ setSessionTimeRemaining((prev) => (prev > 0 ? prev - 1 : 0))
171
+ }, 1000)
172
+
173
+ return () => clearInterval(interval)
174
+ }, [transferFinishedData])
175
+
176
+ // Generate link token on component mount
177
+ useEffect(() => {
178
+ logger.console.log("[onramp] generateLinkToken useEffect triggered:", {
179
+ environment,
180
+ toRecipientAddress: !!toRecipientAddress,
181
+ toTokenSymbol: !!toTokenSymbol,
182
+ toChainId: !!toChainId,
183
+ toTokenAmount: !!toTokenAmount,
184
+ integrationId: !!integrationId,
185
+ })
186
+
187
+ const generateLinkToken = async () => {
188
+ try {
189
+ setLoading(true)
190
+ setError(null)
191
+
192
+ logger.console.log("[onramp] Starting link token generation:", {
193
+ environment,
194
+ toRecipientAddress,
195
+ toTokenSymbol,
196
+ toChainId,
197
+ toTokenAmount,
198
+ integrationId,
199
+ })
200
+
201
+ if (
202
+ !toRecipientAddress ||
203
+ !toTokenSymbol ||
204
+ !toChainId ||
205
+ !toTokenAmount
206
+ ) {
207
+ logger.console.error("[onramp] Missing required parameters", {
208
+ toRecipientAddress,
209
+ toTokenSymbol,
210
+ toChainId,
211
+ toTokenAmount,
212
+ })
213
+ throw new Error("Missing required parameters")
214
+ }
215
+
216
+ logger.console.log("[onramp] Generating link token with environment:", {
217
+ environment,
218
+ toChainId,
219
+ toTokenSymbol,
220
+ toTokenAmount,
221
+ integrationId,
222
+ isSandbox: environment === "sandbox",
223
+ })
224
+
225
+ // Generate a new link token via trails-api so Mesh secrets stay server-side
226
+ const response = await createMeshLinkToken(
227
+ {
228
+ address: toRecipientAddress,
229
+ symbol: toTokenSymbol,
230
+ amount: toTokenAmount.toString(),
231
+ destinationChainId: toChainId,
232
+ transactionId: `txid_${refreshKey}_${Date.now()}`,
233
+ integrationId, // Use the provided integration ID (ie Coinbase, Binance, etc)
234
+ },
235
+ requestConfig,
236
+ )
237
+
238
+ logger.console.log(
239
+ "[onramp] Generated Mesh Connect link token response:",
240
+ response,
241
+ )
242
+ logger.console.log("[onramp] Mesh link token generated successfully")
243
+
244
+ // Validate link token format
245
+ if (!response.linkToken || typeof response.linkToken !== "string") {
246
+ throw new Error("Invalid link token received")
247
+ }
248
+ if (!response.clientId || typeof response.clientId !== "string") {
249
+ throw new Error("Invalid Mesh client ID received")
250
+ }
251
+
252
+ setLinkToken(response.linkToken)
253
+ setMeshClientId(response.clientId)
254
+ setSessionTimeRemaining(MESH_SESSION_DURATION_S)
255
+ } catch (err) {
256
+ logger.console.error(
257
+ "[onramp] Failed to generate Mesh Connect link token:",
258
+ err,
259
+ )
260
+ setError(getMeshErrorMessage(err) || "Failed to generate link token")
261
+ } finally {
262
+ setLoading(false)
263
+ }
264
+ }
265
+
266
+ generateLinkToken().catch((err) => {
267
+ logger.console.error("[onramp] Error in generateLinkToken:", err)
268
+ })
269
+ }, [
270
+ toRecipientAddress,
271
+ toTokenSymbol,
272
+ toChainId,
273
+ toTokenAmount,
274
+ integrationId,
275
+ environment,
276
+ requestConfig,
277
+ refreshKey,
278
+ ])
279
+
280
+ const handleIntegrationConnected = useCallback((authData: any) => {
281
+ logger.console.log("[onramp] MESH CONNECTED:", authData)
282
+ setPayload(authData)
283
+
284
+ // Once connected, we can initiate a transfer
285
+ if (authData.accessToken) {
286
+ logger.console.log("[onramp] Ready to transfer - access token available")
287
+ }
288
+ }, [])
289
+
290
+ const transitionToPending = useCallback(
291
+ (transferData: any, eventType: string) => {
292
+ const pendingPayload = getPendingTransitionPayload(transferData)
293
+ if (!pendingPayload) {
294
+ return
295
+ }
296
+
297
+ if (hasPendingTransitionRef.current) {
298
+ logger.console.log(
299
+ `[onramp] Ignoring duplicate Mesh transfer event after pending transition: ${eventType}`,
300
+ pendingPayload,
301
+ )
302
+ return
303
+ }
304
+
305
+ hasPendingTransitionRef.current = true
306
+ clearMeshRenderWatchdog()
307
+ setTransferFinishedData(pendingPayload)
308
+ },
309
+ [clearMeshRenderWatchdog],
310
+ )
311
+
312
+ const handleTransferFinished = useCallback(
313
+ (transferData: any) => {
314
+ logger.console.log("[onramp] MESH TRANSFER FINISHED:", transferData)
315
+ transitionToPending(transferData, "onTransferFinished")
316
+ },
317
+ [transitionToPending],
318
+ )
319
+
320
+ const handleExit = useCallback(
321
+ (error?: string) => {
322
+ logger.console.log("[onramp] MESH EXIT:", error)
323
+
324
+ if (error) {
325
+ clearMeshRenderWatchdog()
326
+ logger.console.error("[onramp] MESH ERROR:", error)
327
+ setPopupState("error")
328
+ setPopupMessage(error)
329
+ return
330
+ }
331
+
332
+ if (!hasPendingTransitionRef.current && initiatedTransferRef.current) {
333
+ logger.console.log(
334
+ "[onramp] Treating Mesh exit after initiated transfer as pending",
335
+ initiatedTransferRef.current,
336
+ )
337
+ transitionToPending(
338
+ initiatedTransferRef.current,
339
+ "onExitAfterTransferInitiated",
340
+ )
341
+ return
342
+ }
343
+
344
+ clearMeshRenderWatchdog()
345
+ setPopupState("closed")
346
+ setPopupMessage("Mesh window was closed before funding completed.")
347
+ },
348
+ [clearMeshRenderWatchdog, transitionToPending],
349
+ )
350
+
351
+ // Create Mesh Connect link instance when component mounts
352
+ useEffect(() => {
353
+ const createMeshLink = async () => {
354
+ try {
355
+ if (!meshClientId) {
356
+ return
357
+ }
358
+
359
+ logger.console.log("[onramp] Creating Mesh Connect link...")
360
+ const link = meshSDK.createLink({
361
+ clientId: meshClientId,
362
+ language: "en",
363
+ onIntegrationConnected: handleIntegrationConnected,
364
+ onExit: handleExit,
365
+ onTransferFinished: handleTransferFinished,
366
+ onEvent: (ev: any) => {
367
+ logger.console.log("[onramp] MESH Event:", ev)
368
+ if (ev.type === "pageLoaded") {
369
+ clearMeshRenderWatchdog()
370
+ }
371
+ if (
372
+ ev.type === "integrationConnectionError" ||
373
+ ev.type === "transferPreviewError" ||
374
+ ev.type === "transferExecutionError" ||
375
+ ev.type === "transferConfigureError" ||
376
+ ev.type === "connectionUnavailable"
377
+ ) {
378
+ clearMeshRenderWatchdog()
379
+ setPopupState("error")
380
+ setPopupMessage(
381
+ ev.payload?.errorMessage || "Mesh Connect failed to load.",
382
+ )
383
+ }
384
+ if (ev.type === "transferInitiated" && ev.payload) {
385
+ clearMeshRenderWatchdog()
386
+ logger.console.log(
387
+ "[onramp] MESH TRANSFER INITIATED:",
388
+ ev.payload,
389
+ )
390
+ initiatedTransferRef.current = ev.payload
391
+ }
392
+ if (ev.type === "transferExecuted" && ev.payload) {
393
+ transitionToPending(ev.payload, ev.type)
394
+ }
395
+ if (ev.type === "transferCompleted" && ev.payload) {
396
+ transitionToPending(ev.payload, ev.type)
397
+ }
398
+ },
399
+ })
400
+
401
+ logger.console.log("[onramp] Mesh Connect link created successfully")
402
+ setMeshLink(link)
403
+ } catch (err) {
404
+ logger.console.error(
405
+ "[onramp] Failed to create Mesh Connect link:",
406
+ err,
407
+ )
408
+ setError(`Failed to load Mesh Connect SDK: ${getMeshErrorMessage(err)}`)
409
+ }
410
+ }
411
+
412
+ createMeshLink()
413
+ }, [
414
+ clearMeshRenderWatchdog,
415
+ handleIntegrationConnected,
416
+ handleTransferFinished,
417
+ handleExit,
418
+ meshClientId,
419
+ transitionToPending,
420
+ ])
421
+
422
+ const openMeshConnect = useCallback(() => {
423
+ logger.console.log("[onramp] openMeshConnect called:", {
424
+ meshLink: !!meshLink,
425
+ linkToken: !!linkToken,
426
+ })
427
+
428
+ if (!meshLink || !linkToken) {
429
+ logger.console.log("[onramp] Missing requirements for opening")
430
+ return
431
+ }
432
+
433
+ setPopupState("idle")
434
+ setPopupMessage(null)
435
+
436
+ setTimeout(() => {
437
+ logger.console.log("[onramp] Opening Mesh Connect with token:", linkToken)
438
+ try {
439
+ meshLink.openLink(linkToken)
440
+ clearMeshRenderWatchdog()
441
+ meshRenderWatchdogRef.current = window.setTimeout(() => {
442
+ void failMeshRender(
443
+ "Mesh Connect did not finish loading. Please try again.",
444
+ )
445
+ }, MESH_RENDER_TIMEOUT_MS)
446
+ logger.console.log("[onramp] Opened in popup successfully")
447
+ } catch (popupError) {
448
+ clearMeshRenderWatchdog()
449
+ logger.console.error("[onramp] Failed to open popup link:", popupError)
450
+ setPopupState("error")
451
+ setPopupMessage("Failed to open Mesh Connect popup")
452
+ }
453
+ }, 200)
454
+ }, [clearMeshRenderWatchdog, failMeshRender, linkToken, meshLink])
455
+
456
+ const handleRetry = useCallback(() => {
457
+ hasPendingTransitionRef.current = false
458
+ initiatedTransferRef.current = null
459
+ setLinkToken(null)
460
+ setMeshClientId(null)
461
+ setTransferFinishedData(null)
462
+ setPopupState("idle")
463
+ setPopupMessage(null)
464
+ setRefreshKey((prev) => prev + 1)
465
+ }, [])
466
+
467
+ // Console log payload changes
468
+ useEffect(() => {
469
+ if (payload) {
470
+ logger.console.log("[onramp] Payload updated:", payload)
471
+ }
472
+ }, [payload])
473
+
474
+ // Navigate to pending screen when transfer is finished
475
+ useEffect(() => {
476
+ if (transferFinishedData) {
477
+ logger.console.log(
478
+ "[onramp] Transfer finished data updated:",
479
+ transferFinishedData,
480
+ )
481
+ logger.console.log("[onramp] onComplete callback check:", {
482
+ hasOnComplete: !!onComplete,
483
+ onCompleteType: typeof onComplete,
484
+ })
485
+
486
+ // Navigate to pending screen
487
+ if (onComplete) {
488
+ try {
489
+ logger.console.log("[onramp] Calling onComplete with transfer data")
490
+ onComplete(transferFinishedData)
491
+ logger.console.log("[onramp] onComplete called successfully")
492
+ } catch (error) {
493
+ logger.console.error("[onramp] Error calling onComplete:", error)
494
+ }
495
+ } else {
496
+ logger.console.warn(
497
+ "[onramp] onComplete callback is not defined - cannot redirect",
498
+ )
499
+ }
500
+ }
501
+ }, [transferFinishedData, onComplete])
502
+
503
+ // Auto-click the openMeshConnect button when ready
504
+ useEffect(() => {
505
+ return () => {
506
+ clearMeshRenderWatchdog()
507
+ }
508
+ }, [clearMeshRenderWatchdog])
509
+
510
+ useEffect(() => {
511
+ return () => {
512
+ const closeLink = meshLink?.closeLink
513
+ if (!closeLink) {
514
+ return
515
+ }
516
+
517
+ void Promise.resolve(closeLink()).catch((closeError: unknown) => {
518
+ logger.console.warn(
519
+ "[onramp] Failed to close Mesh popup on unmount:",
520
+ closeError,
521
+ )
522
+ })
523
+ }
524
+ }, [meshLink])
525
+
526
+ useEffect(() => {
527
+ if (meshLink && linkToken && !payload && popupState === "idle") {
528
+ logger.console.log("[onramp] Auto-clicking openMeshConnect button")
529
+ openMeshConnect()
530
+ }
531
+ }, [meshLink, linkToken, payload, openMeshConnect, popupState])
532
+
533
+ if (loading) {
534
+ return (
535
+ <div className="flex flex-col h-full">
536
+ <SimpleHeader onBack={onBack} title="Mesh Connect" />
537
+
538
+ <div className="flex-1 flex items-center justify-center">
539
+ <div className="text-center">
540
+ <div className="mt-4 w-8 h-8 border-solid border-2 border-blue-500 border-t-transparent rounded-full animate-spin mx-auto mb-4"></div>
541
+ <p className="text-gray-600 dark:text-gray-400">
542
+ Generating secure connection...
543
+ </p>
544
+ </div>
545
+ </div>
546
+ </div>
547
+ )
548
+ }
549
+
550
+ if (error) {
551
+ return (
552
+ <div className="flex flex-col h-full">
553
+ <SimpleHeader onBack={onBack} title="Mesh Connect" />
554
+
555
+ <div className="flex-1 flex items-center justify-center">
556
+ <div className="text-center p-4 border border-solid border-red-200 rounded-lg bg-red-50 dark:bg-red-900/20 dark:border-red-800">
557
+ <p className="text-red-600 dark:text-red-200 mb-4">{error}</p>
558
+ <button
559
+ type="button"
560
+ onClick={() => {
561
+ if (typeof window !== "undefined") {
562
+ window.location.reload()
563
+ }
564
+ }}
565
+ className="px-4 py-2 bg-red-600 text-white rounded-lg hover:bg-red-700 transition-colors"
566
+ >
567
+ Try Again
568
+ </button>
569
+ </div>
570
+ </div>
571
+ </div>
572
+ )
573
+ }
574
+
575
+ return (
576
+ <div className="flex flex-col h-full">
577
+ <SimpleHeader
578
+ onBack={onBack}
579
+ title={`Fund with ${exchangeName || "Mesh Connect"}`}
580
+ />
581
+
582
+ {transferFinishedData && (
583
+ <div className="mb-4 p-3 bg-blue-50 dark:bg-blue-900/20 border border-solid border-blue-200 dark:border-blue-800 rounded-lg">
584
+ <p className="text-sm text-blue-600 dark:text-blue-200">
585
+ ✓ Transfer completed: {transferFinishedData.amount}{" "}
586
+ {transferFinishedData.symbol}
587
+ </p>
588
+ <p className="text-xs text-blue-500 dark:text-blue-300 mt-1">
589
+ Redirecting to pending screen...
590
+ </p>
591
+ </div>
592
+ )}
593
+
594
+ <div className="mb-4 flex items-center justify-center py-2">
595
+ <div className="w-full max-w-md rounded-lg border border-solid border-gray-200 p-8 text-center dark:border-gray-700">
596
+ <div className="space-y-6">
597
+ <div className="space-y-3">
598
+ <h3 className="text-lg font-semibold">
599
+ Fund your account with {exchangeName || "Mesh Connect"}
600
+ </h3>
601
+ <p className="text-gray-600 dark:text-gray-400">
602
+ Connect to{" "}
603
+ {exchangeName?.toLowerCase() || "bank account or exchange"} to
604
+ fund your wallet securely.
605
+ </p>
606
+ </div>
607
+ {popupState !== "idle" && popupMessage && (
608
+ <div className="rounded-lg border border-solid border-yellow-200 bg-yellow-50 px-4 py-3 text-left dark:border-yellow-800 dark:bg-yellow-900/20">
609
+ <p className="text-sm font-medium text-yellow-900 dark:text-yellow-100">
610
+ {popupState === "closed"
611
+ ? "Funding window closed"
612
+ : "Mesh Connect error"}
613
+ </p>
614
+ <p className="mt-2 text-sm text-yellow-700 dark:text-yellow-300">
615
+ {popupMessage}
616
+ </p>
617
+ </div>
618
+ )}
619
+ <div className="rounded-lg border border-solid border-gray-200 bg-gray-50 px-4 py-3 dark:border-gray-700 dark:bg-gray-800/70">
620
+ <p className="text-sm font-medium text-gray-900 dark:text-gray-100">
621
+ Funding session expires in{" "}
622
+ {formatCountdown(sessionTimeRemaining)}
623
+ </p>
624
+ <p className="mt-2 text-xs text-gray-500 dark:text-gray-400">
625
+ Retry before expiry to keep the current funding session.
626
+ </p>
627
+ </div>
628
+ {popupState !== "idle" && (
629
+ <button
630
+ type="button"
631
+ onClick={handleRetry}
632
+ disabled={loading}
633
+ className="w-full px-6 py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed"
634
+ >
635
+ {loading
636
+ ? "Preparing..."
637
+ : sessionTimeRemaining <= 0
638
+ ? "Refresh Session"
639
+ : "Retry"}
640
+ </button>
641
+ )}
642
+ </div>
643
+ </div>
644
+ </div>
645
+
646
+ {/* Sandbox Environment Banner */}
647
+ {environment === "sandbox" && (
648
+ <div className="mt-4 p-3 bg-yellow-50 dark:bg-yellow-900/20 border border-solid border-yellow-200 dark:border-yellow-800">
649
+ <div className="text-center">
650
+ <p className="text-sm font-medium text-yellow-800 dark:text-yellow-200">
651
+ Sandbox environment
652
+ </p>
653
+ <p className="text-xs text-yellow-600 dark:text-yellow-300">
654
+ No real funds are used
655
+ </p>
656
+ </div>
657
+ </div>
658
+ )}
659
+ </div>
660
+ )
661
+ }