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.
- package/dist/{ccip-Cg9-lJ6K.js → ccip-CT_An6eM.js} +39 -39
- package/dist/chains.d.ts +4 -3
- package/dist/chains.d.ts.map +1 -1
- package/dist/constants.d.ts +1 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/customTokens.d.ts.map +1 -1
- package/dist/error.d.ts +1 -0
- package/dist/error.d.ts.map +1 -1
- package/dist/gasless.d.ts +1 -2
- package/dist/gasless.d.ts.map +1 -1
- package/dist/{index-DEojZg7b.js → index-RfqL5Foz.js} +56672 -43550
- package/dist/index.d.ts +5 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +385 -333
- package/dist/intents.d.ts +8 -2
- package/dist/intents.d.ts.map +1 -1
- package/dist/keyMachineClient.d.ts +9 -0
- package/dist/keyMachineClient.d.ts.map +1 -0
- package/dist/keymachine/index.d.ts +14 -0
- package/dist/keymachine/index.d.ts.map +1 -0
- package/dist/keymachine/key-machine.gen.d.ts +461 -0
- package/dist/keymachine/key-machine.gen.d.ts.map +1 -0
- package/dist/onramp/MeshConnectFlow.d.ts +18 -0
- package/dist/onramp/MeshConnectFlow.d.ts.map +1 -0
- package/dist/onramp/MeshConnectIframe.d.ts +13 -0
- package/dist/onramp/MeshConnectIframe.d.ts.map +1 -0
- package/dist/onramp/SendFromExchangeButton.d.ts +16 -0
- package/dist/onramp/SendFromExchangeButton.d.ts.map +1 -0
- package/dist/onramp/TrailsOnRampProvider.d.ts +31 -0
- package/dist/onramp/TrailsOnRampProvider.d.ts.map +1 -0
- package/dist/onramp/index.d.ts +13 -0
- package/dist/onramp/index.d.ts.map +1 -0
- package/dist/onramp/meshconnect.d.ts +30 -0
- package/dist/onramp/meshconnect.d.ts.map +1 -0
- package/dist/onramp/trailsOnramp.d.ts +24 -0
- package/dist/onramp/trailsOnramp.d.ts.map +1 -0
- package/dist/onramp-client/index.d.ts +3 -3
- package/dist/onramp-client/index.d.ts.map +1 -1
- package/dist/paymasterSend.d.ts.map +1 -1
- package/dist/prepareSend.d.ts.map +1 -1
- package/dist/query/balance.fetchers.d.ts +31 -2
- package/dist/query/balance.fetchers.d.ts.map +1 -1
- package/dist/query/balance.hooks.d.ts +21 -2
- package/dist/query/balance.hooks.d.ts.map +1 -1
- package/dist/query/balance.queries.d.ts +18 -1
- package/dist/query/balance.queries.d.ts.map +1 -1
- package/dist/query/chains.queries.d.ts.map +1 -1
- package/dist/query/meld.fetchers.d.ts +1 -1
- package/dist/query/meld.fetchers.d.ts.map +1 -1
- package/dist/query/meld.hooks.d.ts +3 -3
- package/dist/query/meld.hooks.d.ts.map +1 -1
- package/dist/query/meld.queries.d.ts +1 -1
- package/dist/query/meld.queries.d.ts.map +1 -1
- package/dist/query/price.fetchers.d.ts +15 -0
- package/dist/query/price.fetchers.d.ts.map +1 -0
- package/dist/query/price.hooks.d.ts +352 -0
- package/dist/query/price.hooks.d.ts.map +1 -0
- package/dist/query/price.queries.d.ts +34 -0
- package/dist/query/price.queries.d.ts.map +1 -0
- package/dist/query/tokenList.queries.d.ts +54 -0
- package/dist/query/tokenList.queries.d.ts.map +1 -0
- package/dist/recover.d.ts +6 -4
- package/dist/recover.d.ts.map +1 -1
- package/dist/tokens.d.ts +13 -0
- package/dist/tokens.d.ts.map +1 -1
- package/dist/transactionIntent/deposits/depositOrchestrator.d.ts +2 -2
- package/dist/transactionIntent/deposits/depositOrchestrator.d.ts.map +1 -1
- package/dist/transactionIntent/deposits/gaslessDeposit.d.ts +2 -2
- package/dist/transactionIntent/deposits/gaslessDeposit.d.ts.map +1 -1
- package/dist/transactionIntent/deposits/standardDeposit.d.ts +1 -1
- package/dist/transactionIntent/deposits/standardDeposit.d.ts.map +1 -1
- package/dist/transactionIntent/handlers/intentHandler.d.ts.map +1 -1
- package/dist/transactionIntent/helpers/transactionStateHelpers.d.ts.map +1 -1
- package/dist/transactionIntent/quote/normalizeQuote.d.ts.map +1 -1
- package/dist/transactionIntent/types.d.ts +1 -1
- package/dist/transactionIntent/types.d.ts.map +1 -1
- package/dist/transactions.d.ts +4 -0
- package/dist/transactions.d.ts.map +1 -1
- package/dist/umd/trails.min.js +291 -202
- package/dist/utils/format.d.ts +7 -0
- package/dist/utils/format.d.ts.map +1 -1
- package/dist/walletUtils.d.ts +2 -1
- package/dist/walletUtils.d.ts.map +1 -1
- package/dist/wallets.d.ts +13 -54
- package/dist/wallets.d.ts.map +1 -1
- package/dist/widget/components/AccountIntentTransactionHistory.d.ts.map +1 -1
- package/dist/widget/components/ClassicSwap.d.ts.map +1 -1
- package/dist/widget/components/ConnectWallet.d.ts.map +1 -1
- package/dist/widget/components/ConnectedWallets.d.ts.map +1 -1
- package/dist/widget/components/DirectTransfer.d.ts +1 -1
- package/dist/widget/components/DirectTransfer.d.ts.map +1 -1
- package/dist/widget/components/EarnPools.d.ts.map +1 -1
- package/dist/widget/components/ExecutionStatusBadge.d.ts.map +1 -1
- package/dist/widget/components/Fund.d.ts.map +1 -1
- package/dist/widget/components/FundMethods.d.ts.map +1 -1
- package/dist/widget/components/HighPriceImpactBlock.d.ts +7 -0
- package/dist/widget/components/HighPriceImpactBlock.d.ts.map +1 -0
- package/dist/widget/components/MeldHistory.d.ts.map +1 -1
- package/dist/widget/components/MeshExchangeSelection.d.ts +11 -0
- package/dist/widget/components/MeshExchangeSelection.d.ts.map +1 -0
- package/dist/widget/components/OnrampHistoryRow.d.ts +1 -1
- package/dist/widget/components/OnrampHistoryRow.d.ts.map +1 -1
- package/dist/widget/components/OnrampProviderConfirmation.d.ts.map +1 -1
- package/dist/widget/components/Pay.d.ts.map +1 -1
- package/dist/widget/components/PoolDeposit.d.ts.map +1 -1
- package/dist/widget/components/PoolWithdraw.d.ts.map +1 -1
- package/dist/widget/components/QRCodeWalletSelect.d.ts +1 -1
- package/dist/widget/components/QRCodeWalletSelect.d.ts.map +1 -1
- package/dist/widget/components/QuoteDetails.d.ts.map +1 -1
- package/dist/widget/components/Receipt.d.ts.map +1 -1
- package/dist/widget/components/Recipients.d.ts.map +1 -1
- package/dist/widget/components/RefundWarning.d.ts.map +1 -1
- package/dist/widget/components/TokenSelector.d.ts.map +1 -1
- package/dist/widget/components/TransactionDetails.d.ts.map +1 -1
- package/dist/widget/components/TransactionHistoryItem.d.ts +2 -0
- package/dist/widget/components/TransactionHistoryItem.d.ts.map +1 -1
- package/dist/widget/components/TransferPendingVertical.d.ts +1 -0
- package/dist/widget/components/TransferPendingVertical.d.ts.map +1 -1
- package/dist/widget/components/WaasFeeOptions.d.ts.map +1 -1
- package/dist/widget/components/WalletConnect.d.ts.map +1 -1
- package/dist/widget/components/WalletImage.d.ts.map +1 -1
- package/dist/widget/components/WalletList.d.ts.map +1 -1
- package/dist/widget/components/Withdraw.d.ts.map +1 -1
- package/dist/widget/css/compiled.css +1 -1
- package/dist/widget/hooks/useAddressWalletIcon.d.ts.map +1 -1
- package/dist/widget/hooks/useCombinedHistory.d.ts +6 -5
- package/dist/widget/hooks/useCombinedHistory.d.ts.map +1 -1
- package/dist/widget/hooks/useCustomTokenSearch.d.ts +6 -1
- package/dist/widget/hooks/useCustomTokenSearch.d.ts.map +1 -1
- package/dist/widget/hooks/useDefaultDestinationToken.d.ts.map +1 -1
- package/dist/widget/hooks/useDefaultOriginToken.d.ts.map +1 -1
- package/dist/widget/hooks/useFiatOnRampCurrencies.d.ts +1 -1
- package/dist/widget/hooks/useFiatOnRampCurrencies.d.ts.map +1 -1
- package/dist/widget/hooks/useGetIntent.d.ts +3 -2
- package/dist/widget/hooks/useGetIntent.d.ts.map +1 -1
- package/dist/widget/hooks/useIntentReceiptBalances.d.ts +1 -1
- package/dist/widget/hooks/useIntentReceiptBalances.d.ts.map +1 -1
- package/dist/widget/hooks/useIntentTransactionHistory.d.ts +3 -2
- package/dist/widget/hooks/useIntentTransactionHistory.d.ts.map +1 -1
- package/dist/widget/hooks/useMeldTransactionHistory.d.ts +1 -1
- package/dist/widget/hooks/useMeldTransactionHistory.d.ts.map +1 -1
- package/dist/widget/hooks/useMeldTransactionStatus.d.ts +1 -1
- package/dist/widget/hooks/useMeldTransactionStatus.d.ts.map +1 -1
- package/dist/widget/hooks/useOnRampQuote.d.ts +1 -1
- package/dist/widget/hooks/useOnRampQuote.d.ts.map +1 -1
- package/dist/widget/hooks/useOnRampTransactionStatus.d.ts +1 -1
- package/dist/widget/hooks/useOnRampTransactionStatus.d.ts.map +1 -1
- package/dist/widget/hooks/useQuote.d.ts +2 -2
- package/dist/widget/hooks/useQuote.d.ts.map +1 -1
- package/dist/widget/hooks/useSelectedFundMethod.d.ts +7 -0
- package/dist/widget/hooks/useSelectedFundMethod.d.ts.map +1 -1
- package/dist/widget/hooks/useSendForm.d.ts +0 -1
- package/dist/widget/hooks/useSendForm.d.ts.map +1 -1
- package/dist/widget/hooks/useTokenList.d.ts +7 -1
- package/dist/widget/hooks/useTokenList.d.ts.map +1 -1
- package/dist/widget/hooks/useViewManager.d.ts +1 -1
- package/dist/widget/hooks/useViewManager.d.ts.map +1 -1
- package/dist/widget/index.js +1 -1
- package/dist/widget/providers/TrailsProvider.d.ts +2 -0
- package/dist/widget/providers/TrailsProvider.d.ts.map +1 -1
- package/dist/widget/utils/createWagmiConfig.d.ts +2 -2
- package/dist/widget/utils/createWagmiConfig.d.ts.map +1 -1
- package/dist/widget/utils/fundMethodSwitchState.d.ts +1 -0
- package/dist/widget/utils/fundMethodSwitchState.d.ts.map +1 -1
- package/dist/widget/utils/historyFilters.d.ts +13 -0
- package/dist/widget/utils/historyFilters.d.ts.map +1 -0
- package/dist/widget/utils/meldProviderUtils.d.ts +1 -1
- package/dist/widget/utils/meldProviderUtils.d.ts.map +1 -1
- package/dist/widget/utils/meshSupportedTokens.d.ts +4 -0
- package/dist/widget/utils/meshSupportedTokens.d.ts.map +1 -0
- package/dist/widget/utils/onrampConfig.d.ts +11 -0
- package/dist/widget/utils/onrampConfig.d.ts.map +1 -0
- package/dist/widget/utils/statusLabel.d.ts +2 -0
- package/dist/widget/utils/statusLabel.d.ts.map +1 -0
- package/dist/widget/utils/trailsOnrampConfig.d.ts +18 -0
- package/dist/widget/utils/trailsOnrampConfig.d.ts.map +1 -0
- package/dist/widget/widget.d.ts +24 -8
- package/dist/widget/widget.d.ts.map +1 -1
- package/package.json +9 -7
- package/src/chains.ts +26 -9
- package/src/constants.ts +2 -0
- package/src/customTokens.ts +22 -7
- package/src/error.ts +7 -0
- package/src/gasless.ts +5 -2
- package/src/index.ts +8 -5
- package/src/intents.ts +56 -60
- package/src/keyMachineClient.ts +29 -0
- package/src/keymachine/index.ts +175 -0
- package/src/keymachine/key-machine.gen.ts +993 -0
- package/src/onramp/MeshConnectFlow.tsx +86 -0
- package/src/onramp/MeshConnectIframe.tsx +661 -0
- package/src/onramp/SendFromExchangeButton.tsx +81 -0
- package/src/onramp/TrailsOnRampProvider.tsx +59 -0
- package/src/onramp/index.ts +31 -0
- package/src/onramp/meshconnect.ts +277 -0
- package/src/onramp/trailsOnramp.tsx +130 -0
- package/src/onramp-client/index.ts +4 -6
- package/src/paymasterSend.ts +0 -5
- package/src/prepareSend.ts +45 -44
- package/src/query/balance.fetchers.ts +172 -17
- package/src/query/balance.hooks.ts +69 -6
- package/src/query/balance.queries.ts +63 -0
- package/src/query/chains.queries.ts +1 -6
- package/src/query/meld.fetchers.ts +1 -1
- package/src/query/meld.hooks.ts +1 -1
- package/src/query/meld.queries.ts +1 -1
- package/src/query/price.fetchers.ts +53 -0
- package/src/query/price.hooks.ts +46 -0
- package/src/query/price.queries.ts +364 -0
- package/src/query/tokenList.queries.ts +118 -0
- package/src/recover.ts +89 -26
- package/src/tokens.ts +108 -26
- package/src/transactionIntent/deposits/depositOrchestrator.ts +11 -11
- package/src/transactionIntent/deposits/gaslessDeposit.ts +38 -39
- package/src/transactionIntent/deposits/standardDeposit.ts +5 -30
- package/src/transactionIntent/handlers/intentHandler.ts +29 -12
- package/src/transactionIntent/helpers/transactionStateHelpers.ts +5 -2
- package/src/transactionIntent/quote/normalizeQuote.ts +11 -5
- package/src/transactionIntent/types.ts +1 -1
- package/src/transactions.ts +5 -1
- package/src/utils/format.ts +85 -1
- package/src/walletUtils.ts +2 -1
- package/src/wallets.ts +184 -380
- package/src/widget/compiled.css +1 -1
- package/src/widget/components/AccountIntentTransactionHistory.tsx +134 -109
- package/src/widget/components/ClassicSwap.tsx +26 -24
- package/src/widget/components/ConnectWallet.tsx +4 -2
- package/src/widget/components/ConnectedWallets.tsx +2 -5
- package/src/widget/components/DirectTransfer.tsx +5 -2
- package/src/widget/components/EarnPools.tsx +1 -2
- package/src/widget/components/ExecutionStatusBadge.tsx +10 -4
- package/src/widget/components/Fund.tsx +169 -110
- package/src/widget/components/FundMethods.tsx +5 -9
- package/src/widget/components/HighPriceImpactBlock.tsx +44 -0
- package/src/widget/components/MeldHistory.tsx +4 -28
- package/src/widget/components/MeshExchangeSelection.tsx +218 -0
- package/src/widget/components/OnrampHistoryRow.tsx +3 -27
- package/src/widget/components/OnrampProviderConfirmation.tsx +0 -25
- package/src/widget/components/Pay.tsx +20 -36
- package/src/widget/components/PoolDeposit.tsx +14 -24
- package/src/widget/components/PoolWithdraw.tsx +1 -63
- package/src/widget/components/QRCodeWalletSelect.tsx +5 -2
- package/src/widget/components/QuoteDetails.tsx +113 -106
- package/src/widget/components/Receipt.tsx +0 -11
- package/src/widget/components/Recipients.tsx +2 -1
- package/src/widget/components/RefundWarning.tsx +5 -10
- package/src/widget/components/ThemeProvider.tsx +4 -4
- package/src/widget/components/TokenSelector.tsx +85 -16
- package/src/widget/components/TransactionDetails.tsx +46 -0
- package/src/widget/components/TransactionHistoryItem.tsx +14 -23
- package/src/widget/components/TransferPendingVertical.tsx +17 -11
- package/src/widget/components/WaasFeeOptions.tsx +4 -42
- package/src/widget/components/WalletConnect.tsx +2 -5
- package/src/widget/components/WalletImage.tsx +6 -18
- package/src/widget/components/WalletList.tsx +1 -1
- package/src/widget/components/Withdraw.tsx +22 -23
- package/src/widget/hooks/useAddressWalletIcon.ts +2 -1
- package/src/widget/hooks/useAmountUsd.ts +1 -1
- package/src/widget/hooks/useCombinedHistory.ts +37 -93
- package/src/widget/hooks/useCustomTokenSearch.tsx +63 -33
- package/src/widget/hooks/useDefaultDestinationToken.tsx +2 -5
- package/src/widget/hooks/useDefaultOriginToken.tsx +2 -5
- package/src/widget/hooks/useFiatOnRampCurrencies.ts +1 -1
- package/src/widget/hooks/useGetIntent.ts +5 -4
- package/src/widget/hooks/useIntentReceiptBalances.ts +3 -3
- package/src/widget/hooks/useIntentTransactionHistory.ts +24 -47
- package/src/widget/hooks/useMeldTransactionHistory.ts +4 -2
- package/src/widget/hooks/useMeldTransactionStatus.ts +13 -11
- package/src/widget/hooks/useOnRampQuote.ts +3 -3
- package/src/widget/hooks/useOnRampTransactionStatus.ts +8 -6
- package/src/widget/hooks/useQuote.ts +56 -48
- package/src/widget/hooks/useSelectedFundMethod.tsx +14 -1
- package/src/widget/hooks/useSendForm.ts +52 -31
- package/src/widget/hooks/useTokenList.ts +209 -140
- package/src/widget/hooks/useTrailsSendTransaction.ts +1 -1
- package/src/widget/hooks/useViewManager.tsx +1 -0
- package/src/widget/providers/TrailsProvider.tsx +5 -0
- package/src/widget/styles.ts +1 -1
- package/src/widget/utils/createWagmiConfig.ts +7 -2
- package/src/widget/utils/fundMethodSwitchState.ts +2 -0
- package/src/widget/utils/historyFilters.ts +157 -0
- package/src/widget/utils/meldProviderUtils.ts +8 -2
- package/src/widget/utils/meshSupportedTokens.ts +28 -0
- package/src/widget/utils/onrampConfig.ts +15 -0
- package/src/widget/utils/statusLabel.ts +3 -0
- package/src/widget/utils/trailsOnrampConfig.ts +39 -0
- package/src/widget/widget.tsx +235 -185
- package/dist/onramp-client/trails-onramp.gen.d.ts +0 -570
- package/dist/onramp-client/trails-onramp.gen.d.ts.map +0 -1
- package/dist/prices.d.ts +0 -34
- package/dist/prices.d.ts.map +0 -1
- package/dist/useGasEstimation.d.ts +0 -34
- package/dist/useGasEstimation.d.ts.map +0 -1
- package/dist/widget/hooks/useCustomTokenFetch.d.ts +0 -19
- package/dist/widget/hooks/useCustomTokenFetch.d.ts.map +0 -1
- package/dist/widget/hooks/useTokenWithFreshBalance.d.ts +0 -18
- package/dist/widget/hooks/useTokenWithFreshBalance.d.ts.map +0 -1
- package/src/onramp-client/trails-onramp.gen.ts +0 -1320
- package/src/prices.ts +0 -528
- package/src/useGasEstimation.ts +0 -147
- package/src/widget/assets/Binance_Icon_Logo.svg +0 -14
- package/src/widget/assets/Bitfinex_Icon_Logo.svg +0 -5
- package/src/widget/assets/Coinbase_Icon_Logo.svg +0 -1
- package/src/widget/assets/WalletConnect-logo-blue-bg.svg +0 -11
- package/src/widget/assets/sequence-logo.svg +0 -15
- package/src/widget/hooks/useCustomTokenFetch.tsx +0 -74
- 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
|
+
}
|