0xtrails 0.12.2 → 0.13.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.
- package/dist/abis/trailsHydrate.d.ts.map +1 -1
- package/dist/analytics.d.ts +41 -0
- package/dist/analytics.d.ts.map +1 -1
- package/dist/{ccip-62W6LwH2.js → ccip-Cg9-lJ6K.js} +16 -16
- package/dist/chainSwitch.d.ts.map +1 -1
- package/dist/chains.d.ts +9 -3
- package/dist/chains.d.ts.map +1 -1
- package/dist/error.d.ts +1 -0
- package/dist/error.d.ts.map +1 -1
- package/dist/{index-C0QTNYIA.js → index-DEojZg7b.js} +50431 -50424
- package/dist/index.d.ts +1 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +377 -421
- package/dist/intentReceiptPoller.d.ts.map +1 -1
- package/dist/intents.d.ts +1 -3
- package/dist/intents.d.ts.map +1 -1
- package/dist/mutations.d.ts +1 -4
- package/dist/mutations.d.ts.map +1 -1
- package/dist/prepareSend.d.ts.map +1 -1
- package/dist/query/balance.hooks.d.ts.map +1 -1
- package/dist/query/chains.hooks.d.ts.map +1 -1
- package/dist/query/chains.queries.d.ts +4 -1
- package/dist/query/chains.queries.d.ts.map +1 -1
- package/dist/queryParams.d.ts.map +1 -1
- package/dist/recover.d.ts.map +1 -1
- package/dist/tokens.d.ts.map +1 -1
- package/dist/transactionIntent/deposits/depositOrchestrator.d.ts.map +1 -1
- package/dist/transactionIntent/deposits/gaslessDeposit.d.ts.map +1 -1
- package/dist/transactionIntent/deposits/standardDeposit.d.ts +1 -7
- 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 +10 -1
- package/dist/transactionIntent/helpers/transactionStateHelpers.d.ts.map +1 -1
- package/dist/transactionIntent/types.d.ts +3 -6
- package/dist/transactionIntent/types.d.ts.map +1 -1
- package/dist/transactionIntent/utils/resilientDepositTracker.d.ts +3 -3
- package/dist/transactionIntent/utils/resilientDepositTracker.d.ts.map +1 -1
- package/dist/transactions.d.ts +2 -0
- package/dist/transactions.d.ts.map +1 -1
- package/dist/umd/trails.min.js +200 -200
- package/dist/walletUtils.d.ts +4 -0
- package/dist/walletUtils.d.ts.map +1 -1
- package/dist/wallets.d.ts +2 -1
- package/dist/wallets.d.ts.map +1 -1
- package/dist/widget/components/AccountActionsDropdown.d.ts.map +1 -1
- package/dist/widget/components/AccountIntentTransactionHistoryButton.d.ts.map +1 -1
- package/dist/widget/components/AccountSettings.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 +5 -1
- package/dist/widget/components/ConnectedWallets.d.ts.map +1 -1
- package/dist/widget/components/DepositTracker.d.ts +1 -1
- package/dist/widget/components/DepositTracker.d.ts.map +1 -1
- package/dist/widget/components/DirectTransfer.d.ts +0 -8
- package/dist/widget/components/DirectTransfer.d.ts.map +1 -1
- package/dist/widget/components/Fund.d.ts +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/FundWalletSelection.d.ts +0 -8
- package/dist/widget/components/FundWalletSelection.d.ts.map +1 -1
- package/dist/widget/components/FundingMethodSelectorButton.d.ts +1 -1
- package/dist/widget/components/FundingMethodSelectorButton.d.ts.map +1 -1
- package/dist/widget/components/MeldStepsFlow.d.ts.map +1 -1
- package/dist/widget/components/OnrampErrorScreen.d.ts.map +1 -1
- package/dist/widget/components/OnrampPaymentMethods.d.ts.map +1 -1
- package/dist/widget/components/OnrampProviderConfirmation.d.ts +0 -6
- package/dist/widget/components/OnrampProviderConfirmation.d.ts.map +1 -1
- package/dist/widget/components/Pay.d.ts.map +1 -1
- package/dist/widget/components/QrCode.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/ReceiptRecoverableFunds.d.ts +25 -0
- package/dist/widget/components/ReceiptRecoverableFunds.d.ts.map +1 -0
- package/dist/widget/components/RecipientSelectorButton.d.ts +3 -1
- package/dist/widget/components/RecipientSelectorButton.d.ts.map +1 -1
- package/dist/widget/components/Recipients.d.ts.map +1 -1
- package/dist/widget/components/Swap.d.ts +2 -16
- package/dist/widget/components/Swap.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.map +1 -1
- package/dist/widget/components/TransferPendingVertical.d.ts.map +1 -1
- package/dist/widget/components/TruncatedTransactionHash.d.ts.map +1 -1
- package/dist/widget/components/WalletConfirmation.d.ts.map +1 -1
- package/dist/widget/components/WalletConnect.d.ts.map +1 -1
- package/dist/widget/components/WidgetProviders.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/useClickTracking.d.ts.map +1 -1
- package/dist/widget/hooks/useDebugScreens.d.ts +1 -10
- package/dist/widget/hooks/useDebugScreens.d.ts.map +1 -1
- package/dist/widget/hooks/useDepositMonitor.d.ts +2 -4
- package/dist/widget/hooks/useDepositMonitor.d.ts.map +1 -1
- package/dist/widget/hooks/useExternalFundingReceiptSync.d.ts +11 -0
- package/dist/widget/hooks/useExternalFundingReceiptSync.d.ts.map +1 -0
- package/dist/widget/hooks/useIntentReceiptBalances.d.ts +16 -0
- package/dist/widget/hooks/useIntentReceiptBalances.d.ts.map +1 -0
- package/dist/widget/hooks/useQuote.d.ts +0 -4
- package/dist/widget/hooks/useQuote.d.ts.map +1 -1
- package/dist/widget/hooks/useScreenTracking.d.ts +2 -0
- package/dist/widget/hooks/useScreenTracking.d.ts.map +1 -0
- package/dist/widget/hooks/useSelectedFundMethod.d.ts +0 -2
- package/dist/widget/hooks/useSelectedFundMethod.d.ts.map +1 -1
- package/dist/widget/hooks/useSendForm.d.ts +0 -4
- package/dist/widget/hooks/useSendForm.d.ts.map +1 -1
- package/dist/widget/hooks/useTokenList.d.ts.map +1 -1
- package/dist/widget/hooks/useTrailsSendTransaction.d.ts.map +1 -1
- package/dist/widget/hooks/useViewManager.d.ts +89 -0
- package/dist/widget/hooks/useViewManager.d.ts.map +1 -0
- package/dist/widget/hooks/useWalletConnectUri.d.ts.map +1 -1
- package/dist/widget/hooks/useWalletConnectionContext.d.ts +1 -1
- package/dist/widget/hooks/useWalletConnectionContext.d.ts.map +1 -1
- package/dist/widget/index.d.ts +1 -1
- package/dist/widget/index.d.ts.map +1 -1
- package/dist/widget/index.js +7 -6
- package/dist/widget/providers/TrailsProvider.d.ts.map +1 -1
- package/dist/widget/types/commonProps.d.ts +1 -6
- package/dist/widget/types/commonProps.d.ts.map +1 -1
- package/dist/widget/utils/forexRateStore.d.ts.map +1 -1
- package/dist/widget/utils/fundMethodSwitchState.d.ts +10 -0
- package/dist/widget/utils/fundMethodSwitchState.d.ts.map +1 -0
- package/dist/widget/utils/localeStore.d.ts.map +1 -1
- package/dist/widget/utils/viewManagerGuards.d.ts +5 -0
- package/dist/widget/utils/viewManagerGuards.d.ts.map +1 -0
- package/dist/widget/widget.d.ts +23 -2
- package/dist/widget/widget.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/abis/trailsHydrate.ts +2 -1
- package/src/analytics.ts +60 -0
- package/src/chainSwitch.ts +11 -8
- package/src/chains.ts +82 -37
- package/src/constants.ts +2 -2
- package/src/error.ts +8 -0
- package/src/index.ts +1 -12
- package/src/intentReceiptPoller.ts +27 -0
- package/src/intents.ts +36 -87
- package/src/mutations.ts +11 -102
- package/src/onramp-client/index.ts +3 -3
- package/src/prepareSend.ts +6 -2
- package/src/query/balance.hooks.ts +31 -10
- package/src/query/chains.hooks.ts +7 -1
- package/src/query/chains.queries.ts +8 -5
- package/src/queryParams.ts +8 -6
- package/src/recover.ts +9 -9
- package/src/tokens.ts +4 -2
- package/src/transactionIntent/deposits/depositOrchestrator.ts +0 -2
- package/src/transactionIntent/deposits/gaslessDeposit.ts +8 -0
- package/src/transactionIntent/deposits/standardDeposit.ts +25 -35
- package/src/transactionIntent/handlers/intentHandler.ts +234 -138
- package/src/transactionIntent/helpers/transactionStateHelpers.ts +108 -1
- package/src/transactionIntent/types.ts +14 -8
- package/src/transactionIntent/utils/resilientDepositTracker.ts +72 -183
- package/src/transactions.ts +16 -0
- package/src/walletUtils.ts +188 -1
- package/src/wallets.ts +50 -15
- package/src/widget/compiled.css +1 -1
- package/src/widget/components/AccountActionsDropdown.tsx +4 -6
- package/src/widget/components/AccountIntentTransactionHistoryButton.tsx +4 -6
- package/src/widget/components/AccountSettings.tsx +36 -22
- package/src/widget/components/ClassicSwap.tsx +67 -9
- package/src/widget/components/ConnectWallet.tsx +5 -7
- package/src/widget/components/ConnectedWallets.tsx +143 -82
- package/src/widget/components/DepositTracker.tsx +4 -5
- package/src/widget/components/DirectTransfer.tsx +85 -84
- package/src/widget/components/Earn.tsx +3 -3
- package/src/widget/components/Fund.tsx +90 -17
- package/src/widget/components/FundMethods.tsx +77 -43
- package/src/widget/components/FundWalletSelection.tsx +13 -397
- package/src/widget/components/FundingMethodSelectorButton.tsx +11 -10
- package/src/widget/components/MeldStepsFlow.tsx +64 -30
- package/src/widget/components/OnrampErrorScreen.tsx +2 -18
- package/src/widget/components/OnrampPaymentMethods.tsx +4 -6
- package/src/widget/components/OnrampProviderConfirmation.tsx +91 -110
- package/src/widget/components/OriginTransferInformation.tsx +2 -2
- package/src/widget/components/Pay.tsx +27 -7
- package/src/widget/components/PaymentMethods.tsx +10 -10
- package/src/widget/components/PoolDeposit.tsx +2 -2
- package/src/widget/components/QrCode.tsx +13 -11
- package/src/widget/components/QuoteDetails.tsx +16 -6
- package/src/widget/components/Receipt.tsx +66 -6
- package/src/widget/components/ReceiptRecoverableFunds.tsx +135 -0
- package/src/widget/components/RecipientSelectorButton.tsx +6 -17
- package/src/widget/components/Recipients.tsx +38 -29
- package/src/widget/components/Swap.tsx +2 -25
- package/src/widget/components/TokenList.tsx +2 -2
- package/src/widget/components/TokenSelector.tsx +11 -11
- package/src/widget/components/TokenSelectorButton.tsx +3 -3
- package/src/widget/components/TrailsHookModal.tsx +1 -1
- package/src/widget/components/TransactionDetails.tsx +43 -37
- package/src/widget/components/TransactionHistoryItem.tsx +1 -42
- package/src/widget/components/TransferPendingVertical.tsx +11 -4
- package/src/widget/components/TruncatedTransactionHash.tsx +5 -0
- package/src/widget/components/WalletConfirmation.tsx +5 -8
- package/src/widget/components/WalletConnect.tsx +6 -2
- package/src/widget/components/WidgetProviders.tsx +34 -43
- package/src/widget/components/Withdraw.tsx +25 -11
- package/src/widget/hooks/useClickTracking.ts +5 -0
- package/src/widget/hooks/useDebugScreens.ts +40 -86
- package/src/widget/hooks/useDepositMonitor.ts +14 -149
- package/src/widget/hooks/useExternalFundingReceiptSync.ts +79 -0
- package/src/widget/hooks/useIntentReceiptBalances.ts +141 -0
- package/src/widget/hooks/useQuote.ts +7 -16
- package/src/widget/hooks/useScreenTracking.ts +14 -0
- package/src/widget/hooks/useSelectedFundMethod.tsx +0 -5
- package/src/widget/hooks/useSendForm.ts +5 -14
- package/src/widget/hooks/useTokenList.ts +3 -16
- package/src/widget/hooks/useTrailsSendTransaction.ts +1 -5
- package/src/widget/hooks/useViewManager.tsx +505 -0
- package/src/widget/hooks/useWalletConnectUri.tsx +77 -18
- package/src/widget/hooks/useWalletConnectionContext.tsx +1 -1
- package/src/widget/index.tsx +1 -0
- package/src/widget/providers/TrailsProvider.tsx +0 -41
- package/src/widget/styles.ts +1 -1
- package/src/widget/types/commonProps.ts +0 -8
- package/src/widget/utils/forexRateStore.ts +0 -2
- package/src/widget/utils/fundMethodSwitchState.ts +25 -0
- package/src/widget/utils/localeStore.ts +0 -1
- package/src/widget/utils/viewManagerGuards.ts +49 -0
- package/src/widget/widget.tsx +405 -316
- package/dist/intentStorage.d.ts +0 -24
- package/dist/intentStorage.d.ts.map +0 -1
- package/dist/mode.d.ts +0 -2
- package/dist/mode.d.ts.map +0 -1
- package/dist/widget/hooks/useBack.d.ts +0 -22
- package/dist/widget/hooks/useBack.d.ts.map +0 -1
- package/dist/widget/hooks/useCurrentScreen.d.ts +0 -13
- package/dist/widget/hooks/useCurrentScreen.d.ts.map +0 -1
- package/dist/widget/hooks/useInitialRedirect.d.ts +0 -7
- package/dist/widget/hooks/useInitialRedirect.d.ts.map +0 -1
- package/dist/widget/hooks/useMode.d.ts +0 -20
- package/dist/widget/hooks/useMode.d.ts.map +0 -1
- package/dist/widget/hooks/usePreviousScreen.d.ts +0 -12
- package/dist/widget/hooks/usePreviousScreen.d.ts.map +0 -1
- package/dist/widget/workers/intentExecutionWorker.d.ts +0 -73
- package/dist/widget/workers/intentExecutionWorker.d.ts.map +0 -1
- package/src/intentStorage.ts +0 -106
- package/src/mode.ts +0 -1
- package/src/widget/hooks/useBack.tsx +0 -210
- package/src/widget/hooks/useCurrentScreen.tsx +0 -73
- package/src/widget/hooks/useInitialRedirect.tsx +0 -70
- package/src/widget/hooks/useMode.tsx +0 -51
- package/src/widget/hooks/usePreviousScreen.ts +0 -36
- package/src/widget/workers/intentExecutionWorker.ts +0 -502
package/src/widget/widget.tsx
CHANGED
|
@@ -51,6 +51,7 @@ interface OnrampTransferResult {
|
|
|
51
51
|
txHash?: string
|
|
52
52
|
transferId?: string
|
|
53
53
|
}
|
|
54
|
+
|
|
54
55
|
import {
|
|
55
56
|
createStorage,
|
|
56
57
|
useAccount,
|
|
@@ -61,7 +62,7 @@ import {
|
|
|
61
62
|
useDisconnect,
|
|
62
63
|
useSwitchAccount,
|
|
63
64
|
} from "wagmi"
|
|
64
|
-
import { getSessionId
|
|
65
|
+
import { getSessionId } from "../analytics.js"
|
|
65
66
|
import { getChainInfo } from "../chains.js"
|
|
66
67
|
// Config is now managed exclusively by TrailsProvider
|
|
67
68
|
import { cssObjectToString } from "../cssUtils.js"
|
|
@@ -73,14 +74,11 @@ import {
|
|
|
73
74
|
getIsUserRejectionError,
|
|
74
75
|
getPrettifiedErrorMessage,
|
|
75
76
|
} from "../error.js"
|
|
76
|
-
import { removeStoredIntent } from "../intentStorage.js"
|
|
77
77
|
import { logger } from "../logger.js"
|
|
78
|
-
import
|
|
78
|
+
import { abortControllerRegistry } from "../abortController.js"
|
|
79
79
|
import type { Pool } from "../pools.js"
|
|
80
80
|
import { usePools } from "../pools.js"
|
|
81
|
-
|
|
82
|
-
// biome-ignore lint/style/useImportType: Keep current import shape for now per requested temporary ignores.
|
|
83
|
-
import { type PrepareSendQuote } from "../prepareSend.js"
|
|
81
|
+
import type { PrepareSendQuote } from "../prepareSend.js"
|
|
84
82
|
import { isValidInteger, isValidNumeric } from "../utils/validation.js"
|
|
85
83
|
import type { Theme } from "../theme.js"
|
|
86
84
|
import type { Token } from "../tokens.js"
|
|
@@ -135,14 +133,13 @@ import WalletConnectScreen from "./components/WalletConnect.js"
|
|
|
135
133
|
import WalletConnectionPending from "./components/WalletConnectionPending.js"
|
|
136
134
|
import { FundWalletSelection } from "./components/FundWalletSelection.js"
|
|
137
135
|
import { WalletList } from "./components/WalletList.js"
|
|
138
|
-
import { useBack } from "./hooks/useBack.js"
|
|
139
136
|
import { useCheckout } from "./hooks/useCheckout.js"
|
|
140
|
-
import { useCurrentScreen, type Screen } from "./hooks/useCurrentScreen.js"
|
|
141
137
|
import { useDebugScreens } from "./hooks/useDebugScreens.js"
|
|
138
|
+
import { useExternalFundingReceiptSync } from "./hooks/useExternalFundingReceiptSync.js"
|
|
139
|
+
import { useScreenTracking } from "./hooks/useScreenTracking.js"
|
|
142
140
|
import { useEarnPool } from "./hooks/useEarnPool.js"
|
|
143
|
-
|
|
141
|
+
|
|
144
142
|
import { useIsSequenceWallet } from "./hooks/useIsSequenceWallet.js"
|
|
145
|
-
import { useMode } from "./hooks/useMode.js"
|
|
146
143
|
import { useOriginSelectedToken as useSelectedToken } from "./hooks/useOriginSelectedToken.js"
|
|
147
144
|
import { PriceImpactWarningProvider } from "./hooks/usePriceImpactWarning.js"
|
|
148
145
|
import { useRecentTokens } from "./hooks/useRecentTokens.js"
|
|
@@ -151,9 +148,11 @@ import { useSelectedFundMethod } from "./hooks/useSelectedFundMethod.js"
|
|
|
151
148
|
import { useSelectedRecipient } from "./hooks/useSelectedRecipient.js"
|
|
152
149
|
import type { OnCompleteProps } from "./hooks/useSendForm.js"
|
|
153
150
|
import { useTargetAmount } from "./hooks/useTargetAmount.js"
|
|
151
|
+
import { useSwapState } from "./hooks/useSwapState.js"
|
|
154
152
|
import { useWidgetAnalytics } from "./analytics/useWidgetAnalytics.js"
|
|
155
153
|
import { useWalletConnectionContext } from "./hooks/useWalletConnectionContext.js"
|
|
156
154
|
import { useWidgetProps } from "./hooks/useWidgetProps.js"
|
|
155
|
+
import { clearFundStateForMethodSwitch } from "./utils/fundMethodSwitchState.js"
|
|
157
156
|
import { useOnRampProviderWidget } from "./hooks/useOnRampProviderWidget.js"
|
|
158
157
|
import { WidgetProviders } from "./components/WidgetProviders.js"
|
|
159
158
|
import {
|
|
@@ -161,7 +160,14 @@ import {
|
|
|
161
160
|
type TrailsProviderProps,
|
|
162
161
|
} from "./providers/TrailsProvider.js"
|
|
163
162
|
import { useTrailsModal } from "./providers/TrailsModalProvider.js"
|
|
164
|
-
import {
|
|
163
|
+
import {
|
|
164
|
+
useViewManager,
|
|
165
|
+
useNavigationEffect,
|
|
166
|
+
useScreenGuard,
|
|
167
|
+
getInitialScreen,
|
|
168
|
+
type Screen,
|
|
169
|
+
type Mode,
|
|
170
|
+
} from "./hooks/useViewManager.js"
|
|
165
171
|
import PaymentMethods from "./components/PaymentMethods.js"
|
|
166
172
|
import type { OnrampQuote } from "./hooks/useOnRampQuote.js"
|
|
167
173
|
import {
|
|
@@ -169,14 +175,15 @@ import {
|
|
|
169
175
|
isNativeToken,
|
|
170
176
|
normalizeAddress,
|
|
171
177
|
} from "../utils/address.js"
|
|
178
|
+
import { isWalletConnectConnector } from "../walletUtils.js"
|
|
172
179
|
import type { SendOptions, SwapReturn } from "./hooks/useQuote.js"
|
|
173
180
|
import { hasFailedOrAbortedTransaction } from "./utils/transactionFailure.js"
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
181
|
+
import {
|
|
182
|
+
shouldClearTransferFlowOnNavigate,
|
|
183
|
+
shouldRedirectToConnect,
|
|
184
|
+
} from "./utils/viewManagerGuards.js"
|
|
185
|
+
import type { FundMethod } from "../transactionIntent/types.js"
|
|
186
|
+
import { isExternalFundingMethod } from "../transactionIntent/types.js"
|
|
180
187
|
|
|
181
188
|
// Validate toToken - must be "ETH", "USDC", or a valid hex address
|
|
182
189
|
const isValidToToToken = (toToken: string | null | undefined) => {
|
|
@@ -191,6 +198,21 @@ const isValidToToToken = (toToken: string | null | undefined) => {
|
|
|
191
198
|
return isAddress(token)
|
|
192
199
|
}
|
|
193
200
|
|
|
201
|
+
export type FundMethodListOption =
|
|
202
|
+
| "connected-wallet"
|
|
203
|
+
| "crypto-transfer"
|
|
204
|
+
| "cc-onramp"
|
|
205
|
+
| "exchange-onramp"
|
|
206
|
+
|
|
207
|
+
export const WidgetFundMethod = {
|
|
208
|
+
Wallet: "wallet",
|
|
209
|
+
CryptoTransfer: "crypto-transfer",
|
|
210
|
+
Onramp: "onramp",
|
|
211
|
+
OnrampExchange: "onramp-exchange",
|
|
212
|
+
} as const
|
|
213
|
+
export type WidgetFundMethod =
|
|
214
|
+
(typeof WidgetFundMethod)[keyof typeof WidgetFundMethod]
|
|
215
|
+
|
|
194
216
|
export type TrailsWidgetProps = {
|
|
195
217
|
apiKey: string
|
|
196
218
|
sequenceIndexerUrl?: string
|
|
@@ -218,6 +240,17 @@ export type TrailsWidgetProps = {
|
|
|
218
240
|
renderInline?: boolean
|
|
219
241
|
theme?: Theme
|
|
220
242
|
mode?: Mode
|
|
243
|
+
/**
|
|
244
|
+
* Pre-select funding method used by the widget.
|
|
245
|
+
*
|
|
246
|
+
* This applies across modes (fund/pay/swap/earn) wherever funding method is used.
|
|
247
|
+
* In fund mode it also controls the initial destination flow:
|
|
248
|
+
* - "wallet" -> Funding with wallet flow
|
|
249
|
+
* - "crypto-transfer" --> Funding with QR Code or deposit to address flow
|
|
250
|
+
* - "onramp" --> Funding with onramp flow
|
|
251
|
+
* - "onramp-exchange" --> Funding with exchange flow
|
|
252
|
+
*/
|
|
253
|
+
fundMethod?: WidgetFundMethod
|
|
221
254
|
walletOptions?: string[]
|
|
222
255
|
onOriginConfirmation?: (data: {
|
|
223
256
|
txHash: string
|
|
@@ -302,6 +335,10 @@ export type TrailsWidgetProps = {
|
|
|
302
335
|
* Default: false.
|
|
303
336
|
*/
|
|
304
337
|
hideUnlistedFundMethods?: boolean
|
|
338
|
+
/** ISO 4217 currency code to pre-select in onramp mode (e.g. "EUR", "GBP") */
|
|
339
|
+
fiatCurrency?: string
|
|
340
|
+
/** Fiat amount to pre-populate in onramp mode */
|
|
341
|
+
fiatAmount?: string
|
|
305
342
|
}
|
|
306
343
|
toast?: boolean
|
|
307
344
|
appName?: string
|
|
@@ -619,6 +656,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
619
656
|
decoupleWagmi,
|
|
620
657
|
hideDisconnect,
|
|
621
658
|
defaultInputMode,
|
|
659
|
+
fundMethod: configuredFundMethod,
|
|
622
660
|
} = useWidgetProps()
|
|
623
661
|
const { address, chainId, connector } = useAccount()
|
|
624
662
|
const connectors = useConnectors()
|
|
@@ -688,11 +726,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
688
726
|
},
|
|
689
727
|
})
|
|
690
728
|
|
|
691
|
-
// Handle fromAccount preselection
|
|
692
|
-
// We use a ref to ensure this only runs once on mount.
|
|
693
|
-
// Without this guard, the effect re-fires on every render cycle
|
|
694
|
-
// and overrides the user's wallet selection (e.g. switching back
|
|
695
|
-
// from MetaMask to Privy embedded wallet).
|
|
729
|
+
// Handle fromAccount preselection
|
|
696
730
|
const hasInitializedFromAccount = useRef(false)
|
|
697
731
|
useEffect(() => {
|
|
698
732
|
if (hasInitializedFromAccount.current) return
|
|
@@ -737,11 +771,31 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
737
771
|
isModalOpen,
|
|
738
772
|
)
|
|
739
773
|
}, [isModalOpen])
|
|
740
|
-
const {
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
774
|
+
const {
|
|
775
|
+
mode: currentMode,
|
|
776
|
+
configuredMode,
|
|
777
|
+
resetMode,
|
|
778
|
+
screen,
|
|
779
|
+
navigate,
|
|
780
|
+
goBack,
|
|
781
|
+
goHome,
|
|
782
|
+
canGoBack,
|
|
783
|
+
backScreen,
|
|
784
|
+
state,
|
|
785
|
+
} = useViewManager()
|
|
786
|
+
const { setSellAmount, setBuyAmount } = useSwapState()
|
|
787
|
+
|
|
788
|
+
// Abort in-flight requests when navigating away from transfer screens.
|
|
789
|
+
useNavigationEffect(({ from, to }) => {
|
|
790
|
+
if (shouldClearTransferFlowOnNavigate(from, to)) {
|
|
791
|
+
abortControllerRegistry.abortAll()
|
|
792
|
+
setPrepareSendQuote(null)
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
if (to === "fund-methods") {
|
|
796
|
+
fundMethodSelectionStartRef.current = selectedFundMethod
|
|
797
|
+
}
|
|
798
|
+
})
|
|
745
799
|
const {
|
|
746
800
|
connectionContext,
|
|
747
801
|
clearConnectionContext,
|
|
@@ -753,12 +807,34 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
753
807
|
// Wrapper function that clears errors when going back
|
|
754
808
|
const handleBack = () => {
|
|
755
809
|
setError(null)
|
|
756
|
-
goBack
|
|
810
|
+
if (canGoBack) goBack()
|
|
811
|
+
else goHome()
|
|
757
812
|
}
|
|
758
813
|
const [previousAddress, setPreviousAddress] = useState<string | undefined>(
|
|
759
814
|
address,
|
|
760
815
|
)
|
|
761
816
|
const { selectedFundMethod, setSelectedFundMethod } = useSelectedFundMethod()
|
|
817
|
+
const fundMethodSelectionStartRef = useRef(selectedFundMethod)
|
|
818
|
+
const clearStateForFundMethodSwitch = useCallback(
|
|
819
|
+
(nextMethod: typeof selectedFundMethod) => {
|
|
820
|
+
const previousMethod = fundMethodSelectionStartRef.current
|
|
821
|
+
const didSwitchMethods = clearFundStateForMethodSwitch(
|
|
822
|
+
previousMethod,
|
|
823
|
+
nextMethod,
|
|
824
|
+
{
|
|
825
|
+
clearSelectedToken,
|
|
826
|
+
setSellAmount,
|
|
827
|
+
setBuyAmount,
|
|
828
|
+
setPrepareSendQuote,
|
|
829
|
+
},
|
|
830
|
+
)
|
|
831
|
+
|
|
832
|
+
if (didSwitchMethods) {
|
|
833
|
+
fundMethodSelectionStartRef.current = nextMethod
|
|
834
|
+
}
|
|
835
|
+
},
|
|
836
|
+
[clearSelectedToken, setSellAmount, setBuyAmount],
|
|
837
|
+
)
|
|
762
838
|
const { selectedPool, setSelectedPool } = useEarnPool()
|
|
763
839
|
const [selectedWalletId, setSelectedWalletId] = useState<string | null>(
|
|
764
840
|
() => {
|
|
@@ -788,9 +864,6 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
788
864
|
useState<PrepareSendQuote | null>(null)
|
|
789
865
|
const [onrampProviderQuote, setOnrampProviderQuote] =
|
|
790
866
|
useState<OnrampQuote | null>(null)
|
|
791
|
-
const [prepareSendFn, setPrepareSendFn] = useState<
|
|
792
|
-
((options?: SendOptions) => Promise<SwapReturn | null>) | null
|
|
793
|
-
>(null)
|
|
794
867
|
|
|
795
868
|
// Store widget creation parameters for retry functionality
|
|
796
869
|
const [widgetCreationParams, setWidgetCreationParams] = useState<{
|
|
@@ -831,73 +904,94 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
831
904
|
>(null)
|
|
832
905
|
const { connectAsync } = useConnect()
|
|
833
906
|
|
|
834
|
-
const
|
|
835
|
-
if (mode === "swap") {
|
|
836
|
-
return "swap"
|
|
837
|
-
} else if (mode === "earn") {
|
|
838
|
-
return "earn"
|
|
839
|
-
} else if (mode === "fund") {
|
|
840
|
-
return "fund-methods"
|
|
841
|
-
} else if (mode === "withdraw") {
|
|
842
|
-
return "withdraw"
|
|
843
|
-
} else if (mode === "pay") {
|
|
844
|
-
return "send-form"
|
|
845
|
-
} else {
|
|
846
|
-
return "send-form"
|
|
847
|
-
}
|
|
848
|
-
}, [])
|
|
849
|
-
|
|
850
|
-
const prevConfiguredModeRef = useRef(configuredMode)
|
|
907
|
+
const hasAppliedFundMethodNavigation = useRef<string | null>(null)
|
|
851
908
|
useEffect(() => {
|
|
852
|
-
|
|
853
|
-
if (
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
}, [
|
|
857
|
-
|
|
858
|
-
const goHome = useCallback(() => {
|
|
859
|
-
const initialScreen = getInitialScreenForMode(currentMode)
|
|
860
|
-
setCurrentScreen(initialScreen)
|
|
861
|
-
}, [currentMode, setCurrentScreen, getInitialScreenForMode])
|
|
909
|
+
const isWidgetActive = renderInline || isModalOpen
|
|
910
|
+
if (!isWidgetActive) {
|
|
911
|
+
hasAppliedFundMethodNavigation.current = null
|
|
912
|
+
}
|
|
913
|
+
}, [renderInline, isModalOpen])
|
|
862
914
|
|
|
863
915
|
useEffect(() => {
|
|
864
|
-
|
|
865
|
-
|
|
916
|
+
const isWidgetActive = renderInline || isModalOpen
|
|
917
|
+
if (!isWidgetActive) return
|
|
918
|
+
|
|
919
|
+
let mappedFundMethod: FundMethod | null = null
|
|
920
|
+
if (configuredFundMethod === WidgetFundMethod.Wallet) {
|
|
921
|
+
mappedFundMethod = "wallet"
|
|
922
|
+
} else if (configuredFundMethod === WidgetFundMethod.CryptoTransfer) {
|
|
923
|
+
mappedFundMethod = "direct-transfer"
|
|
924
|
+
} else if (
|
|
925
|
+
configuredFundMethod === WidgetFundMethod.Onramp &&
|
|
926
|
+
currentMode !== "pay" &&
|
|
927
|
+
currentMode !== "earn"
|
|
928
|
+
) {
|
|
929
|
+
mappedFundMethod = "onramp-meld"
|
|
930
|
+
} else if (
|
|
931
|
+
configuredFundMethod === WidgetFundMethod.OnrampExchange &&
|
|
932
|
+
currentMode !== "pay"
|
|
933
|
+
) {
|
|
934
|
+
mappedFundMethod = "onramp-mesh"
|
|
866
935
|
}
|
|
867
|
-
}, [currentScreen, goHome])
|
|
868
936
|
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
937
|
+
if (!mappedFundMethod) return
|
|
938
|
+
if (selectedFundMethod === mappedFundMethod) return
|
|
939
|
+
setSelectedFundMethod(mappedFundMethod)
|
|
940
|
+
}, [
|
|
941
|
+
configuredFundMethod,
|
|
942
|
+
selectedFundMethod,
|
|
943
|
+
setSelectedFundMethod,
|
|
944
|
+
renderInline,
|
|
945
|
+
isModalOpen,
|
|
872
946
|
currentMode,
|
|
873
|
-
|
|
874
|
-
)
|
|
947
|
+
])
|
|
875
948
|
|
|
876
|
-
// Keep screen and wallet-connection state in sync without bouncing between screens
|
|
877
949
|
useEffect(() => {
|
|
878
|
-
const
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
if (!isConnected && !connectionExemptScreens.includes(currentScreen)) {
|
|
886
|
-
setCurrentScreen("connect")
|
|
950
|
+
const isWidgetActive = renderInline || isModalOpen
|
|
951
|
+
if (!isWidgetActive) return
|
|
952
|
+
if (!isConnected) return
|
|
953
|
+
if (currentMode !== "fund") return
|
|
954
|
+
|
|
955
|
+
if (!configuredFundMethod) {
|
|
887
956
|
return
|
|
888
957
|
}
|
|
889
958
|
|
|
890
|
-
|
|
891
|
-
|
|
959
|
+
const navKey = `${configuredFundMethod}:${currentMode}:${isWidgetActive}`
|
|
960
|
+
if (hasAppliedFundMethodNavigation.current === navKey) return
|
|
961
|
+
hasAppliedFundMethodNavigation.current = navKey
|
|
962
|
+
|
|
963
|
+
if (configuredFundMethod === WidgetFundMethod.Onramp) {
|
|
964
|
+
setSelectedFundMethod("onramp-meld")
|
|
965
|
+
navigate("fund-form")
|
|
966
|
+
} else if (configuredFundMethod === WidgetFundMethod.Wallet) {
|
|
967
|
+
setSelectedFundMethod("wallet")
|
|
968
|
+
navigate("tokens")
|
|
969
|
+
} else if (configuredFundMethod === WidgetFundMethod.CryptoTransfer) {
|
|
970
|
+
setSelectedFundMethod("direct-transfer")
|
|
971
|
+
navigate("fund-form")
|
|
972
|
+
} else if (configuredFundMethod === WidgetFundMethod.OnrampExchange) {
|
|
973
|
+
setSelectedFundMethod("onramp-mesh")
|
|
974
|
+
navigate("fund-form")
|
|
892
975
|
}
|
|
893
976
|
}, [
|
|
894
|
-
isConnected,
|
|
895
|
-
currentScreen,
|
|
896
977
|
currentMode,
|
|
897
|
-
|
|
898
|
-
|
|
978
|
+
isConnected,
|
|
979
|
+
configuredFundMethod,
|
|
980
|
+
renderInline,
|
|
981
|
+
isModalOpen,
|
|
982
|
+
navigate,
|
|
983
|
+
setSelectedFundMethod,
|
|
899
984
|
])
|
|
900
985
|
|
|
986
|
+
useEffect(() => {
|
|
987
|
+
if (!isConnected || screen !== "connect") return
|
|
988
|
+
if (currentMode === "fund" && configuredFundMethod) return
|
|
989
|
+
goHome()
|
|
990
|
+
}, [isConnected, screen, currentMode, configuredFundMethod, goHome])
|
|
991
|
+
|
|
992
|
+
// Global wallet connection check — redirect to connect screen when disconnected
|
|
993
|
+
useScreenGuard(shouldRedirectToConnect(isConnected, screen), "connect")
|
|
994
|
+
|
|
901
995
|
const modeToButtonText: Record<string, string> = {
|
|
902
996
|
fund: "Fund",
|
|
903
997
|
swap: "Swap",
|
|
@@ -1149,18 +1243,11 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
1149
1243
|
)
|
|
1150
1244
|
|
|
1151
1245
|
// Auto-navigate from pending → receipt when first transaction is aborted or failed
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
if (firstTx && hasFailedOrAbortedTransaction(firstTx)) {
|
|
1158
|
-
logger.console.log(
|
|
1159
|
-
`[trails-sdk] First transaction state is ${firstTx.state}, navigating to receipt`,
|
|
1160
|
-
)
|
|
1161
|
-
setCurrentScreen("receipt")
|
|
1162
|
-
}
|
|
1163
|
-
}, [transactionStates, currentScreen, setCurrentScreen])
|
|
1246
|
+
const firstTx = transactionStates?.[0]
|
|
1247
|
+
useScreenGuard(
|
|
1248
|
+
screen === "pending" && !!firstTx && hasFailedOrAbortedTransaction(firstTx),
|
|
1249
|
+
"receipt",
|
|
1250
|
+
)
|
|
1164
1251
|
|
|
1165
1252
|
const { checkoutOnHandlers } = useCheckout({
|
|
1166
1253
|
onCheckoutStart,
|
|
@@ -1177,10 +1264,29 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
1177
1264
|
})
|
|
1178
1265
|
|
|
1179
1266
|
const { clearSelectedFeeOption } = useSelectedFeeOption()
|
|
1267
|
+
useExternalFundingReceiptSync({
|
|
1268
|
+
enabled:
|
|
1269
|
+
isExternalFundingMethod(selectedFundMethod) &&
|
|
1270
|
+
!!prepareSendQuote?.intentId &&
|
|
1271
|
+
(screen === "direct-transfer-screen" ||
|
|
1272
|
+
screen === "onramp-confirmation" ||
|
|
1273
|
+
screen === "pending"),
|
|
1274
|
+
intentId: prepareSendQuote?.intentId ?? undefined,
|
|
1275
|
+
fallbackTransactionStates: prepareSendQuote?.transactionStates,
|
|
1276
|
+
setTransactionStates,
|
|
1277
|
+
onStatusUpdate: checkoutOnHandlers?.triggerCheckoutStatusUpdate,
|
|
1278
|
+
onFundingObserved: () => {
|
|
1279
|
+
if (
|
|
1280
|
+
screen === "direct-transfer-screen" ||
|
|
1281
|
+
screen === "onramp-confirmation"
|
|
1282
|
+
) {
|
|
1283
|
+
navigate("pending")
|
|
1284
|
+
}
|
|
1285
|
+
},
|
|
1286
|
+
})
|
|
1180
1287
|
|
|
1181
1288
|
// Use the debug screens hook
|
|
1182
1289
|
const { handleDebugScreenSelect } = useDebugScreens({
|
|
1183
|
-
setCurrentScreen,
|
|
1184
1290
|
setSelectedToken,
|
|
1185
1291
|
setTransactionStates,
|
|
1186
1292
|
setPrepareSendQuote,
|
|
@@ -1188,30 +1294,20 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
1188
1294
|
setSelectedWalletId,
|
|
1189
1295
|
setShowWalletConnectionRetry,
|
|
1190
1296
|
setError,
|
|
1191
|
-
setIsConnecting,
|
|
1192
|
-
setOnrampProps,
|
|
1193
1297
|
isConnected,
|
|
1194
1298
|
})
|
|
1195
1299
|
|
|
1196
1300
|
// Auto-detect mode changes and switch screens accordingly
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
}
|
|
1206
|
-
}
|
|
1207
|
-
}, [currentMode, currentScreen, selectedPool, setCurrentScreen])
|
|
1301
|
+
const poolTargetScreen: Screen =
|
|
1302
|
+
currentMode === "fund" ? "fund-form" : "send-form"
|
|
1303
|
+
useScreenGuard(
|
|
1304
|
+
!!selectedPool &&
|
|
1305
|
+
(screen === "send-form" || screen === "fund-form") &&
|
|
1306
|
+
screen !== poolTargetScreen,
|
|
1307
|
+
poolTargetScreen,
|
|
1308
|
+
)
|
|
1208
1309
|
|
|
1209
|
-
|
|
1210
|
-
trackWidgetScreen({
|
|
1211
|
-
screen: currentScreen,
|
|
1212
|
-
userAddress: address || undefined,
|
|
1213
|
-
})
|
|
1214
|
-
}, [currentScreen, address])
|
|
1310
|
+
useScreenTracking(address || undefined)
|
|
1215
1311
|
|
|
1216
1312
|
useEffect(() => {
|
|
1217
1313
|
const status = hostTransactionState.status
|
|
@@ -1225,27 +1321,27 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
1225
1321
|
|
|
1226
1322
|
switch (status) {
|
|
1227
1323
|
case "awaiting-origin":
|
|
1228
|
-
|
|
1324
|
+
navigate("select-origin-token")
|
|
1229
1325
|
break
|
|
1230
1326
|
case "awaiting-amount":
|
|
1231
|
-
|
|
1327
|
+
navigate("select-origin-amount")
|
|
1232
1328
|
break
|
|
1233
1329
|
case "confirmation":
|
|
1234
|
-
|
|
1330
|
+
navigate("wallet-confirmation")
|
|
1235
1331
|
break
|
|
1236
1332
|
case "pending":
|
|
1237
|
-
|
|
1333
|
+
navigate("pending")
|
|
1238
1334
|
break
|
|
1239
1335
|
case "success":
|
|
1240
1336
|
case "error":
|
|
1241
1337
|
if (hostTransactionStates.length > 0) {
|
|
1242
|
-
|
|
1338
|
+
navigate("receipt")
|
|
1243
1339
|
} else {
|
|
1244
|
-
|
|
1340
|
+
navigate("pending")
|
|
1245
1341
|
}
|
|
1246
1342
|
break
|
|
1247
1343
|
default:
|
|
1248
|
-
|
|
1344
|
+
navigate("pending")
|
|
1249
1345
|
break
|
|
1250
1346
|
}
|
|
1251
1347
|
}, [
|
|
@@ -1253,7 +1349,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
1253
1349
|
hostTransactionStates.length,
|
|
1254
1350
|
isModalOpen,
|
|
1255
1351
|
openTrailsModal,
|
|
1256
|
-
|
|
1352
|
+
navigate,
|
|
1257
1353
|
])
|
|
1258
1354
|
|
|
1259
1355
|
useEffect(() => {
|
|
@@ -1305,14 +1401,14 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
1305
1401
|
"earn",
|
|
1306
1402
|
]
|
|
1307
1403
|
|
|
1308
|
-
if (screensToReset.includes(
|
|
1404
|
+
if (screensToReset.includes(screen)) {
|
|
1309
1405
|
logger.console.log(
|
|
1310
1406
|
"[trails-sdk] Resetting to tokens screen due to account change",
|
|
1311
|
-
|
|
1407
|
+
screen,
|
|
1312
1408
|
)
|
|
1313
|
-
if (
|
|
1314
|
-
const initialScreen =
|
|
1315
|
-
|
|
1409
|
+
if (!state.stack.some((e) => e.screen === "select-funding-wallet")) {
|
|
1410
|
+
const initialScreen = getInitialScreen(currentMode)
|
|
1411
|
+
navigate(initialScreen)
|
|
1316
1412
|
clearSelectedToken()
|
|
1317
1413
|
}
|
|
1318
1414
|
setError(null)
|
|
@@ -1326,12 +1422,11 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
1326
1422
|
}, [
|
|
1327
1423
|
address,
|
|
1328
1424
|
previousAddress,
|
|
1329
|
-
|
|
1425
|
+
screen,
|
|
1330
1426
|
currentMode,
|
|
1331
1427
|
clearSelectedToken,
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
previousScreen,
|
|
1428
|
+
navigate,
|
|
1429
|
+
state.stack,
|
|
1335
1430
|
])
|
|
1336
1431
|
|
|
1337
1432
|
// Update generated calldata when amount changes in earn mode
|
|
@@ -1466,9 +1561,9 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
1466
1561
|
// Navigate back to the origin screen (recipients)
|
|
1467
1562
|
const originScreen = connectionContext.originScreen
|
|
1468
1563
|
if (originScreen) {
|
|
1469
|
-
|
|
1564
|
+
navigate(originScreen)
|
|
1470
1565
|
} else {
|
|
1471
|
-
|
|
1566
|
+
navigate("recipients")
|
|
1472
1567
|
}
|
|
1473
1568
|
} else if (isFundMethodSelection) {
|
|
1474
1569
|
logger.console.log(
|
|
@@ -1478,9 +1573,9 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
1478
1573
|
clearConnectionContext()
|
|
1479
1574
|
|
|
1480
1575
|
if (currentMode === "fund") {
|
|
1481
|
-
|
|
1576
|
+
navigate("tokens", { backTarget: "fund-methods" })
|
|
1482
1577
|
} else {
|
|
1483
|
-
|
|
1578
|
+
goHome()
|
|
1484
1579
|
}
|
|
1485
1580
|
} else {
|
|
1486
1581
|
// Normal connection - switch active wallet and navigate home
|
|
@@ -1491,20 +1586,8 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
1491
1586
|
// Clear the connection context
|
|
1492
1587
|
clearConnectionContext()
|
|
1493
1588
|
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
// First connection - go to initial screen for the mode
|
|
1497
|
-
logger.console.log(
|
|
1498
|
-
"[trails-sdk] First wallet connection, going home",
|
|
1499
|
-
)
|
|
1500
|
-
goHome()
|
|
1501
|
-
} else {
|
|
1502
|
-
// Subsequent connection - go to home which will route to the appropriate screen
|
|
1503
|
-
logger.console.log(
|
|
1504
|
-
"[trails-sdk] Subsequent wallet connection, going to home",
|
|
1505
|
-
)
|
|
1506
|
-
goHome()
|
|
1507
|
-
}
|
|
1589
|
+
logger.console.log("[trails-sdk] Wallet connected, going home")
|
|
1590
|
+
goHome()
|
|
1508
1591
|
}
|
|
1509
1592
|
} else if (walletConnector === getWalletConnectConnector()) {
|
|
1510
1593
|
// Store the current connector as previous before switching to WalletConnect
|
|
@@ -1512,7 +1595,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
1512
1595
|
setPreviousConnector(connector)
|
|
1513
1596
|
}
|
|
1514
1597
|
// Route to dedicated WalletConnect screen where we show our own QR
|
|
1515
|
-
|
|
1598
|
+
navigate("wallet-connect")
|
|
1516
1599
|
setIsConnecting(false)
|
|
1517
1600
|
return
|
|
1518
1601
|
}
|
|
@@ -1560,7 +1643,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
1560
1643
|
logger.console.error("[trails-sdk] Failed to disconnect:", error)
|
|
1561
1644
|
}
|
|
1562
1645
|
|
|
1563
|
-
|
|
1646
|
+
navigate("connect")
|
|
1564
1647
|
}
|
|
1565
1648
|
|
|
1566
1649
|
const handleContinue = async () => {
|
|
@@ -1600,9 +1683,9 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
1600
1683
|
// Navigate back to the origin screen (recipients)
|
|
1601
1684
|
const originScreen = connectionContext.originScreen
|
|
1602
1685
|
if (originScreen) {
|
|
1603
|
-
|
|
1686
|
+
navigate(originScreen)
|
|
1604
1687
|
} else {
|
|
1605
|
-
|
|
1688
|
+
navigate("recipients")
|
|
1606
1689
|
}
|
|
1607
1690
|
} else if (isFundMethodSelection) {
|
|
1608
1691
|
logger.console.log(
|
|
@@ -1612,22 +1695,22 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
1612
1695
|
clearConnectionContext()
|
|
1613
1696
|
|
|
1614
1697
|
if (currentMode === "fund") {
|
|
1615
|
-
|
|
1698
|
+
navigate("tokens", { backTarget: "fund-methods" })
|
|
1616
1699
|
} else {
|
|
1617
|
-
|
|
1700
|
+
goHome()
|
|
1618
1701
|
}
|
|
1619
1702
|
} else {
|
|
1620
1703
|
// Normal flow - navigate based on mode
|
|
1621
1704
|
if (currentMode === "swap") {
|
|
1622
|
-
|
|
1705
|
+
navigate("swap")
|
|
1623
1706
|
} else if (currentMode === "earn") {
|
|
1624
|
-
|
|
1707
|
+
navigate("earn")
|
|
1625
1708
|
} else if (currentMode === "fund") {
|
|
1626
|
-
|
|
1709
|
+
navigate("fund-methods")
|
|
1627
1710
|
} else if (currentMode === "pay") {
|
|
1628
|
-
|
|
1711
|
+
navigate("send-form")
|
|
1629
1712
|
} else {
|
|
1630
|
-
|
|
1713
|
+
navigate("account-settings")
|
|
1631
1714
|
}
|
|
1632
1715
|
}
|
|
1633
1716
|
}
|
|
@@ -1671,18 +1754,18 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
1671
1754
|
if (currentMode === "earn") {
|
|
1672
1755
|
if (toAddress && toChainId) {
|
|
1673
1756
|
// Skip earn-pools and go directly to send-form when toAddress and toChainId are specified
|
|
1674
|
-
|
|
1757
|
+
navigate("send-form")
|
|
1675
1758
|
} else if (selectedPool) {
|
|
1676
1759
|
// If a pool is already selected (auto-selected or manually), go to send-form
|
|
1677
|
-
|
|
1760
|
+
navigate("send-form")
|
|
1678
1761
|
} else {
|
|
1679
1762
|
// Go to earn-pools for pool selection when no specific destination is set
|
|
1680
|
-
|
|
1763
|
+
navigate("earn-pools")
|
|
1681
1764
|
}
|
|
1682
1765
|
} else if (currentMode === "swap") {
|
|
1683
|
-
|
|
1766
|
+
navigate("swap")
|
|
1684
1767
|
} else {
|
|
1685
|
-
|
|
1768
|
+
navigate(currentMode === "fund" ? "fund-form" : "send-form")
|
|
1686
1769
|
}
|
|
1687
1770
|
|
|
1688
1771
|
handleTrackToken(token)
|
|
@@ -1772,16 +1855,11 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
1772
1855
|
|
|
1773
1856
|
const handleSendAnother = () => {
|
|
1774
1857
|
invalidateTokenBalancesCache()
|
|
1775
|
-
const initialScreen = getInitialScreenForMode(currentMode)
|
|
1776
|
-
setCurrentScreen(initialScreen)
|
|
1777
1858
|
resetState()
|
|
1778
1859
|
}
|
|
1779
1860
|
|
|
1780
1861
|
const resetState = useCallback(() => {
|
|
1781
|
-
resetMode()
|
|
1782
1862
|
setSelectedFundMethod("wallet")
|
|
1783
|
-
// Reset to appropriate screen based on mode
|
|
1784
|
-
setCurrentScreen("home")
|
|
1785
1863
|
setSelectedPool(null)
|
|
1786
1864
|
setSelectedWalletId(null)
|
|
1787
1865
|
setIsConnecting(false)
|
|
@@ -1794,13 +1872,12 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
1794
1872
|
setTransactionStates([])
|
|
1795
1873
|
setPrepareSendQuote(null)
|
|
1796
1874
|
setTotalCompletionSeconds(null)
|
|
1797
|
-
clearHistory()
|
|
1798
1875
|
// Clear selected fee option, but localStorage preference is preserved
|
|
1799
1876
|
// Auto-selection will use the preference when fee options render next time
|
|
1800
1877
|
clearSelectedFeeOption()
|
|
1801
1878
|
resetHostTransactionState()
|
|
1879
|
+
goHome()
|
|
1802
1880
|
}, [
|
|
1803
|
-
resetMode,
|
|
1804
1881
|
setSelectedFundMethod,
|
|
1805
1882
|
setDestinationTxHash,
|
|
1806
1883
|
setDestinationChainId,
|
|
@@ -1808,19 +1885,11 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
1808
1885
|
setOriginTxHash,
|
|
1809
1886
|
setOriginChainId,
|
|
1810
1887
|
setSelectedPool,
|
|
1811
|
-
|
|
1812
|
-
clearHistory,
|
|
1888
|
+
goHome,
|
|
1813
1889
|
clearSelectedFeeOption,
|
|
1814
1890
|
resetHostTransactionState,
|
|
1815
1891
|
])
|
|
1816
1892
|
|
|
1817
|
-
// Update the currentScreen state when the widget receives an updated 'mode' prop passed in by the consuming app.
|
|
1818
|
-
// This allows the widget to change modes without remounting the component.
|
|
1819
|
-
useEffect(() => {
|
|
1820
|
-
const initialScreen = getInitialScreenForMode(configuredMode)
|
|
1821
|
-
setCurrentScreen(initialScreen)
|
|
1822
|
-
}, [configuredMode, getInitialScreenForMode, setCurrentScreen])
|
|
1823
|
-
|
|
1824
1893
|
// When pendingSelection exists (from useTrailsSendTransaction),
|
|
1825
1894
|
// open the modal and navigate to select-origin-token screen
|
|
1826
1895
|
useEffect(() => {
|
|
@@ -1830,60 +1899,81 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
1830
1899
|
openTrailsModal()
|
|
1831
1900
|
}
|
|
1832
1901
|
// Navigate to select-origin-token screen
|
|
1833
|
-
if (
|
|
1834
|
-
|
|
1902
|
+
if (screen !== "select-origin-token") {
|
|
1903
|
+
navigate("select-origin-token")
|
|
1835
1904
|
}
|
|
1836
1905
|
}
|
|
1837
|
-
}, [
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1906
|
+
}, [pendingSelection, isModalOpen, screen, navigate, openTrailsModal])
|
|
1907
|
+
|
|
1908
|
+
const onOpenRef = useRef(onOpen)
|
|
1909
|
+
onOpenRef.current = onOpen
|
|
1910
|
+
const onCloseRef = useRef(onClose)
|
|
1911
|
+
onCloseRef.current = onClose
|
|
1912
|
+
const pendingSelectionRef = useRef(pendingSelection)
|
|
1913
|
+
pendingSelectionRef.current = pendingSelection
|
|
1914
|
+
const prepareSendQuoteRef = useRef(prepareSendQuote)
|
|
1915
|
+
prepareSendQuoteRef.current = prepareSendQuote
|
|
1916
|
+
const screenRef = useRef(screen)
|
|
1917
|
+
screenRef.current = screen
|
|
1918
|
+
|
|
1919
|
+
const initialActiveConnectorRef = useRef<any>(null)
|
|
1920
|
+
const initialActiveAddressRef = useRef<string | null>(null)
|
|
1844
1921
|
|
|
1845
1922
|
const handleOpenModal = useCallback(() => {
|
|
1923
|
+
if (!decoupleWagmi) {
|
|
1924
|
+
initialActiveConnectorRef.current = connector ?? null
|
|
1925
|
+
initialActiveAddressRef.current = address ?? null
|
|
1926
|
+
}
|
|
1846
1927
|
openTrailsModal()
|
|
1847
|
-
|
|
1848
|
-
}, [openTrailsModal,
|
|
1849
|
-
|
|
1850
|
-
const screensWithCommittedIntent: Screen[] = [
|
|
1851
|
-
"wallet-confirmation",
|
|
1852
|
-
"onramp-confirmation",
|
|
1853
|
-
]
|
|
1928
|
+
onOpenRef.current?.()
|
|
1929
|
+
}, [openTrailsModal, decoupleWagmi, connector, address])
|
|
1854
1930
|
|
|
1855
1931
|
const handleCloseModal = useCallback(() => {
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
screensWithCommittedIntent.includes(currentScreen)
|
|
1859
|
-
) {
|
|
1860
|
-
removeStoredIntent(prepareSendQuote.intentId)
|
|
1861
|
-
}
|
|
1862
|
-
if (pendingSelection) {
|
|
1932
|
+
const pending = pendingSelectionRef.current
|
|
1933
|
+
if (pending) {
|
|
1863
1934
|
logger.console.log(
|
|
1864
1935
|
"[trails-sdk] handleCloseModal called, rejecting pending selection",
|
|
1865
1936
|
)
|
|
1866
|
-
|
|
1937
|
+
pending.reject(new Error("Modal closed by user"))
|
|
1867
1938
|
setPendingSelection(undefined)
|
|
1868
1939
|
} else {
|
|
1869
1940
|
logger.console.log(
|
|
1870
1941
|
"[trails-sdk] handleCloseModal called, no pending selection",
|
|
1871
1942
|
)
|
|
1872
1943
|
}
|
|
1944
|
+
|
|
1945
|
+
if (!decoupleWagmi && initialActiveConnectorRef.current) {
|
|
1946
|
+
const originalStillConnected = connections.some(
|
|
1947
|
+
(c) => c.connector.id === initialActiveConnectorRef.current?.id,
|
|
1948
|
+
)
|
|
1949
|
+
if (
|
|
1950
|
+
originalStillConnected &&
|
|
1951
|
+
initialActiveConnectorRef.current.id !== connector?.id
|
|
1952
|
+
) {
|
|
1953
|
+
logger.console.log(
|
|
1954
|
+
"[trails-sdk] Restoring host app active wallet:",
|
|
1955
|
+
initialActiveAddressRef.current,
|
|
1956
|
+
)
|
|
1957
|
+
switchAccount({ connector: initialActiveConnectorRef.current })
|
|
1958
|
+
}
|
|
1959
|
+
}
|
|
1960
|
+
initialActiveConnectorRef.current = null
|
|
1961
|
+
initialActiveAddressRef.current = null
|
|
1962
|
+
|
|
1873
1963
|
logger.console.log("[trails-sdk] handleCloseModal called, closing modal")
|
|
1874
1964
|
closeTrailsModal()
|
|
1875
1965
|
resetState()
|
|
1876
1966
|
resetHostTransactionState()
|
|
1877
|
-
|
|
1967
|
+
onCloseRef.current?.()
|
|
1878
1968
|
}, [
|
|
1879
1969
|
closeTrailsModal,
|
|
1880
1970
|
resetState,
|
|
1881
1971
|
resetHostTransactionState,
|
|
1882
|
-
onClose,
|
|
1883
|
-
pendingSelection,
|
|
1884
1972
|
setPendingSelection,
|
|
1885
|
-
|
|
1886
|
-
|
|
1973
|
+
decoupleWagmi,
|
|
1974
|
+
connections,
|
|
1975
|
+
connector,
|
|
1976
|
+
switchAccount,
|
|
1887
1977
|
])
|
|
1888
1978
|
|
|
1889
1979
|
// Register handleCloseModal with TrailsModalProvider so ScreenHeader can use it
|
|
@@ -1906,7 +1996,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
1906
1996
|
)
|
|
1907
1997
|
|
|
1908
1998
|
function handleWalletConfirmComplete() {
|
|
1909
|
-
|
|
1999
|
+
navigate("pending")
|
|
1910
2000
|
}
|
|
1911
2001
|
|
|
1912
2002
|
function handleElapsedTime(totalCompletionSeconds: number = 0) {
|
|
@@ -1943,11 +2033,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
1943
2033
|
setDestinationChainId(lastTransactionState?.chainId)
|
|
1944
2034
|
}
|
|
1945
2035
|
|
|
1946
|
-
|
|
1947
|
-
if (prepareSendQuote?.intentId) {
|
|
1948
|
-
removeStoredIntent(prepareSendQuote.intentId)
|
|
1949
|
-
}
|
|
1950
|
-
setCurrentScreen("receipt")
|
|
2036
|
+
navigate("receipt")
|
|
1951
2037
|
}
|
|
1952
2038
|
|
|
1953
2039
|
async function handleOnrampComplete(transferData: OnrampTransferResult) {
|
|
@@ -1958,7 +2044,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
1958
2044
|
logger.console.log("[trails-sdk] handleOnrampComplete state:", {
|
|
1959
2045
|
hasOnrampContinueSend: !!onrampContinueSend,
|
|
1960
2046
|
hasPrepareSendQuote: !!prepareSendQuote,
|
|
1961
|
-
|
|
2047
|
+
screen,
|
|
1962
2048
|
onrampContinueSendInProgress,
|
|
1963
2049
|
})
|
|
1964
2050
|
|
|
@@ -1978,7 +2064,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
1978
2064
|
|
|
1979
2065
|
// Navigate away from onramp screen immediately
|
|
1980
2066
|
logger.console.log("[trails-sdk] Navigating away from onramp screen")
|
|
1981
|
-
|
|
2067
|
+
navigate("pending")
|
|
1982
2068
|
|
|
1983
2069
|
// Continue with the send flow after onramp completes
|
|
1984
2070
|
if (onrampContinueSend) {
|
|
@@ -2036,7 +2122,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
2036
2122
|
|
|
2037
2123
|
// Navigate to pending screen immediately
|
|
2038
2124
|
logger.console.log("[trails-sdk] Navigating to pending screen")
|
|
2039
|
-
|
|
2125
|
+
navigate("pending")
|
|
2040
2126
|
|
|
2041
2127
|
// Continue with the send flow after deposit is confirmed
|
|
2042
2128
|
if (onrampContinueSend) {
|
|
@@ -2082,7 +2168,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
2082
2168
|
setPreviousConnector(connector)
|
|
2083
2169
|
}
|
|
2084
2170
|
setSelectedWalletId(null)
|
|
2085
|
-
|
|
2171
|
+
navigate("wallet-connect")
|
|
2086
2172
|
}
|
|
2087
2173
|
|
|
2088
2174
|
const handleReconnectPreviousWallet = async () => {
|
|
@@ -2108,11 +2194,11 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
2108
2194
|
error,
|
|
2109
2195
|
)
|
|
2110
2196
|
// If reconnection fails, go back to fund methods
|
|
2111
|
-
|
|
2197
|
+
navigate("fund-methods")
|
|
2112
2198
|
}
|
|
2113
2199
|
} else {
|
|
2114
2200
|
// If no previous connector, go back to fund methods
|
|
2115
|
-
|
|
2201
|
+
navigate("fund-methods")
|
|
2116
2202
|
}
|
|
2117
2203
|
}
|
|
2118
2204
|
|
|
@@ -2164,7 +2250,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
2164
2250
|
onRampMethod && onRampMethod === "onramp-meld"
|
|
2165
2251
|
? "onramp-meld"
|
|
2166
2252
|
: "onramp-mesh"
|
|
2167
|
-
|
|
2253
|
+
navigate(targetScreen)
|
|
2168
2254
|
|
|
2169
2255
|
if (
|
|
2170
2256
|
targetScreen === "onramp-meld" &&
|
|
@@ -2240,10 +2326,6 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
2240
2326
|
setPrepareSendQuote(quote ?? null)
|
|
2241
2327
|
// Navigate to QR wallet selection when using QR code funding method
|
|
2242
2328
|
if (selectedFundMethod === "direct-transfer") {
|
|
2243
|
-
if (sendFn) {
|
|
2244
|
-
setPrepareSendFn(() => sendFn)
|
|
2245
|
-
}
|
|
2246
|
-
|
|
2247
2329
|
if (!sendFn) {
|
|
2248
2330
|
handleSendError(
|
|
2249
2331
|
"Unable to continue: direct-transfer send function is missing.",
|
|
@@ -2252,17 +2334,18 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
2252
2334
|
}
|
|
2253
2335
|
|
|
2254
2336
|
setError(null)
|
|
2337
|
+
|
|
2255
2338
|
void (async () => {
|
|
2256
2339
|
try {
|
|
2257
|
-
await sendFn(
|
|
2258
|
-
|
|
2340
|
+
await sendFn()
|
|
2341
|
+
navigate("direct-transfer-screen", { backTarget: screen })
|
|
2259
2342
|
} catch (error) {
|
|
2260
2343
|
handleSendError(error as Error | string | null)
|
|
2261
2344
|
}
|
|
2262
2345
|
})()
|
|
2263
2346
|
return
|
|
2264
2347
|
}
|
|
2265
|
-
|
|
2348
|
+
navigate("wallet-confirmation")
|
|
2266
2349
|
}
|
|
2267
2350
|
|
|
2268
2351
|
const handleWaitingOnrampConfirm = (
|
|
@@ -2279,7 +2362,6 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
2279
2362
|
paymentMethodType?: string
|
|
2280
2363
|
},
|
|
2281
2364
|
sessionId?: string,
|
|
2282
|
-
sendFn?: ((options?: SendOptions) => Promise<SwapReturn | null>) | null,
|
|
2283
2365
|
popupWindowRef?: Window | null,
|
|
2284
2366
|
) => {
|
|
2285
2367
|
logger.console.log(
|
|
@@ -2288,9 +2370,6 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
2288
2370
|
)
|
|
2289
2371
|
setPrepareSendQuote(quote ?? null)
|
|
2290
2372
|
setOnrampProviderQuote(onrampProviderQuote ?? null)
|
|
2291
|
-
if (sendFn) {
|
|
2292
|
-
setPrepareSendFn(() => sendFn)
|
|
2293
|
-
}
|
|
2294
2373
|
setOnrampPopupWindowRef(popupWindowRef ?? null)
|
|
2295
2374
|
if (params) {
|
|
2296
2375
|
setWidgetCreationParams(params)
|
|
@@ -2304,7 +2383,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
2304
2383
|
)
|
|
2305
2384
|
setExternalSessionId(null)
|
|
2306
2385
|
}
|
|
2307
|
-
|
|
2386
|
+
navigate("onramp-confirmation")
|
|
2308
2387
|
}
|
|
2309
2388
|
|
|
2310
2389
|
async function handleWalletConfirmRetry() {
|
|
@@ -2327,7 +2406,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
2327
2406
|
const { targetAmountUsd, targetAmountUsdFormatted } = useTargetAmount()
|
|
2328
2407
|
|
|
2329
2408
|
const renderScreenContent = () => {
|
|
2330
|
-
switch (
|
|
2409
|
+
switch (screen) {
|
|
2331
2410
|
case "connect": {
|
|
2332
2411
|
const showDisconnect = !decoupleWagmi && !hideDisconnect
|
|
2333
2412
|
return (
|
|
@@ -2354,20 +2433,20 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
2354
2433
|
// Check if we need to show WalletConnect QR
|
|
2355
2434
|
// Don't show QR if we have an EIP-6963 connector or injected connector
|
|
2356
2435
|
const shouldShowQR =
|
|
2357
|
-
!isEIP6963Connector &&
|
|
2358
|
-
walletConnector === getWalletConnectConnector()
|
|
2436
|
+
!isEIP6963Connector && isWalletConnectConnector(walletConnector)
|
|
2359
2437
|
|
|
2360
2438
|
if (shouldShowQR) {
|
|
2361
2439
|
saveLastClickedWallet(walletId)
|
|
2362
|
-
|
|
2440
|
+
navigate("wallet-connect")
|
|
2363
2441
|
} else {
|
|
2364
2442
|
saveLastClickedWallet(walletId)
|
|
2365
2443
|
// Preserve the existing back route from the navigation stack
|
|
2366
|
-
const backRoute =
|
|
2367
|
-
|
|
2368
|
-
"wallet-
|
|
2369
|
-
|
|
2370
|
-
|
|
2444
|
+
const backRoute = backScreen
|
|
2445
|
+
const safeBackRoute =
|
|
2446
|
+
backRoute === "wallet-confirmation" ? undefined : backRoute
|
|
2447
|
+
navigate("wallet-connection-pending", {
|
|
2448
|
+
backTarget: safeBackRoute || undefined,
|
|
2449
|
+
})
|
|
2371
2450
|
// Auto-trigger connection - pass the actual connector
|
|
2372
2451
|
setTimeout(() => {
|
|
2373
2452
|
handleConnectWallet(walletId, walletConnector)
|
|
@@ -2391,44 +2470,52 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
2391
2470
|
: "Choose a funding method"
|
|
2392
2471
|
}
|
|
2393
2472
|
onBack={() => {
|
|
2394
|
-
|
|
2395
|
-
if (previous) {
|
|
2473
|
+
if (currentMode !== configuredMode) {
|
|
2396
2474
|
resetMode()
|
|
2397
|
-
|
|
2398
|
-
}
|
|
2399
|
-
|
|
2475
|
+
return
|
|
2476
|
+
}
|
|
2477
|
+
|
|
2478
|
+
if (canGoBack) {
|
|
2479
|
+
goBack()
|
|
2480
|
+
return
|
|
2400
2481
|
}
|
|
2482
|
+
|
|
2483
|
+
goHome()
|
|
2401
2484
|
}}
|
|
2402
2485
|
onramp={onrampFactory}
|
|
2403
2486
|
onSelectWalletConnect={handleSelectWalletConnect}
|
|
2404
2487
|
onSelectConnectedAccount={() => {
|
|
2488
|
+
clearStateForFundMethodSwitch("wallet")
|
|
2405
2489
|
setSelectedFundMethod("wallet")
|
|
2406
2490
|
if (currentMode === "fund") {
|
|
2407
|
-
|
|
2491
|
+
navigate("select-origin-token", { backTarget: "fund-methods" })
|
|
2408
2492
|
} else {
|
|
2409
|
-
|
|
2493
|
+
goHome()
|
|
2410
2494
|
}
|
|
2411
2495
|
}}
|
|
2412
2496
|
onSelectTransferCrypto={() => {
|
|
2497
|
+
clearStateForFundMethodSwitch("direct-transfer")
|
|
2413
2498
|
setSelectedFundMethod("direct-transfer")
|
|
2414
2499
|
if (currentMode === "fund") {
|
|
2415
|
-
|
|
2500
|
+
navigate("fund-form", { backTarget: "fund-methods" })
|
|
2416
2501
|
} else {
|
|
2417
|
-
|
|
2502
|
+
goHome()
|
|
2418
2503
|
}
|
|
2419
2504
|
}}
|
|
2420
2505
|
onSelectOnrampMeld={() => {
|
|
2506
|
+
clearStateForFundMethodSwitch("onramp-meld")
|
|
2421
2507
|
if (currentMode === "fund") {
|
|
2422
|
-
|
|
2508
|
+
navigate("fund-form")
|
|
2423
2509
|
} else {
|
|
2424
|
-
|
|
2510
|
+
goHome()
|
|
2425
2511
|
}
|
|
2426
2512
|
}}
|
|
2427
2513
|
onSelectOnrampExchange={() => {
|
|
2514
|
+
clearStateForFundMethodSwitch("onramp-mesh")
|
|
2428
2515
|
if (currentMode === "fund") {
|
|
2429
|
-
|
|
2516
|
+
navigate("fund-form")
|
|
2430
2517
|
} else {
|
|
2431
|
-
|
|
2518
|
+
goHome()
|
|
2432
2519
|
}
|
|
2433
2520
|
}}
|
|
2434
2521
|
/>
|
|
@@ -2439,33 +2526,31 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
2439
2526
|
onBack={() => goHome()}
|
|
2440
2527
|
onSelectWalletConnect={handleSelectWalletConnect}
|
|
2441
2528
|
onSelectConnectedAccount={() => {
|
|
2529
|
+
clearStateForFundMethodSwitch("wallet")
|
|
2442
2530
|
setSelectedFundMethod("wallet")
|
|
2443
|
-
|
|
2531
|
+
goHome()
|
|
2444
2532
|
}}
|
|
2445
2533
|
onSelectQrCode={() => {
|
|
2446
|
-
|
|
2534
|
+
navigate("qrcode-options", { backTarget: "payment-methods" })
|
|
2447
2535
|
}}
|
|
2448
2536
|
/>
|
|
2449
2537
|
)
|
|
2450
2538
|
case "select-funding-wallet":
|
|
2451
2539
|
return <FundWalletSelection />
|
|
2452
2540
|
case "onramp-payment-methods":
|
|
2453
|
-
return (
|
|
2454
|
-
<OnrampPaymentMethods
|
|
2455
|
-
onBack={() => setCurrentScreen("fund-methods")}
|
|
2456
|
-
/>
|
|
2457
|
-
)
|
|
2541
|
+
return <OnrampPaymentMethods onBack={() => navigate("fund-methods")} />
|
|
2458
2542
|
case "qrcode-options":
|
|
2459
2543
|
return (
|
|
2460
2544
|
<QRCodeOptions
|
|
2461
2545
|
onBack={handleBack}
|
|
2462
2546
|
onSelectWalletConnect={handleSelectWalletConnect}
|
|
2463
2547
|
onSelectQRCode={() => {
|
|
2548
|
+
clearStateForFundMethodSwitch("direct-transfer")
|
|
2464
2549
|
setSelectedFundMethod("direct-transfer")
|
|
2465
2550
|
if (currentMode === "fund") {
|
|
2466
|
-
|
|
2551
|
+
navigate("fund-form")
|
|
2467
2552
|
} else {
|
|
2468
|
-
|
|
2553
|
+
goHome()
|
|
2469
2554
|
}
|
|
2470
2555
|
}}
|
|
2471
2556
|
/>
|
|
@@ -2482,14 +2567,14 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
2482
2567
|
onRecentTokenSelect={handleRecentTokenSelect}
|
|
2483
2568
|
fundMethod={selectedFundMethod}
|
|
2484
2569
|
renderInline={renderInline}
|
|
2485
|
-
onNavigateToFundMethods={() =>
|
|
2570
|
+
onNavigateToFundMethods={() => navigate("fund-methods")}
|
|
2486
2571
|
/>
|
|
2487
2572
|
)
|
|
2488
2573
|
case "select-origin-token":
|
|
2489
2574
|
return (
|
|
2490
2575
|
<TokenList
|
|
2491
2576
|
onContinue={handleTokenSelect}
|
|
2492
|
-
onBack={
|
|
2577
|
+
onBack={handleBack}
|
|
2493
2578
|
targetAmountUsd={null}
|
|
2494
2579
|
targetAmountUsdFormatted={null}
|
|
2495
2580
|
onError={handleTokenListError}
|
|
@@ -2503,7 +2588,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
2503
2588
|
return (
|
|
2504
2589
|
<OriginSelectionAmount
|
|
2505
2590
|
token={selectedToken}
|
|
2506
|
-
onBack={() =>
|
|
2591
|
+
onBack={() => navigate("select-origin-token")}
|
|
2507
2592
|
onCancel={handleCloseModal}
|
|
2508
2593
|
onSubmit={handleOriginAmountSubmit}
|
|
2509
2594
|
/>
|
|
@@ -2515,7 +2600,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
2515
2600
|
selectedToken={selectedToken}
|
|
2516
2601
|
onSend={handleOnSend}
|
|
2517
2602
|
onWaitingForWalletConfirm={handleWaitingForWalletConfirm}
|
|
2518
|
-
onConfirm={() =>
|
|
2603
|
+
onConfirm={() => navigate("pending")}
|
|
2519
2604
|
onComplete={handleTransferComplete}
|
|
2520
2605
|
account={walletClient?.account}
|
|
2521
2606
|
toRecipient={
|
|
@@ -2587,9 +2672,9 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
2587
2672
|
onSend={handleOnSend}
|
|
2588
2673
|
onWaitingForWalletConfirm={handleWaitingForWalletConfirm}
|
|
2589
2674
|
onrampPropsCallback={setOnrampProps}
|
|
2590
|
-
screenNavigationCallback={
|
|
2675
|
+
screenNavigationCallback={navigate}
|
|
2591
2676
|
onWaitingForOnrampConfirm={handleWaitingOnrampConfirm}
|
|
2592
|
-
onConfirm={() =>
|
|
2677
|
+
onConfirm={() => navigate("pending")}
|
|
2593
2678
|
onComplete={handleTransferComplete}
|
|
2594
2679
|
account={walletClient?.account}
|
|
2595
2680
|
toAmount={toAmount || undefined}
|
|
@@ -2622,18 +2707,17 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
2622
2707
|
onBack={handleBack}
|
|
2623
2708
|
onRetry={() => {
|
|
2624
2709
|
// Go back to fund screen to regenerate widget session
|
|
2625
|
-
|
|
2710
|
+
navigate("fund-form")
|
|
2626
2711
|
}}
|
|
2627
2712
|
onIntentExecuted={() => {
|
|
2628
2713
|
// Navigate to pending screen when intent is executed
|
|
2629
|
-
|
|
2714
|
+
navigate("pending")
|
|
2630
2715
|
}}
|
|
2631
2716
|
quote={prepareSendQuote}
|
|
2632
2717
|
onRampQuote={onrampProviderQuote}
|
|
2633
2718
|
widgetCreationParams={widgetCreationParams}
|
|
2634
2719
|
onCreateWidgetSession={createWidgetSession}
|
|
2635
2720
|
externalSessionId={externalSessionId}
|
|
2636
|
-
sendFn={prepareSendFn}
|
|
2637
2721
|
popupWindowRef={onrampPopupWindowRef}
|
|
2638
2722
|
/>
|
|
2639
2723
|
)
|
|
@@ -2675,7 +2759,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
2675
2759
|
onBack={handleBack}
|
|
2676
2760
|
onSelect={(walletId) => {
|
|
2677
2761
|
setQrCodeWalletId(walletId)
|
|
2678
|
-
|
|
2762
|
+
navigate("direct-transfer-screen")
|
|
2679
2763
|
}}
|
|
2680
2764
|
selectedWalletId={qrCodeWalletId}
|
|
2681
2765
|
/>
|
|
@@ -2685,27 +2769,18 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
2685
2769
|
<DirectTransfer
|
|
2686
2770
|
onBack={() => {
|
|
2687
2771
|
if (currentMode === "fund") {
|
|
2688
|
-
|
|
2772
|
+
navigate("fund-form")
|
|
2689
2773
|
} else {
|
|
2690
|
-
|
|
2774
|
+
goHome()
|
|
2691
2775
|
}
|
|
2692
2776
|
}}
|
|
2693
|
-
onChangeWallet={() =>
|
|
2777
|
+
onChangeWallet={() => navigate("qr-code-wallet-select")}
|
|
2694
2778
|
quote={prepareSendQuote}
|
|
2695
2779
|
selectedWalletId={qrCodeWalletId}
|
|
2696
2780
|
walletOptions={qrCodeWallets}
|
|
2697
|
-
|
|
2698
|
-
onIntentExecuted={() => setCurrentScreen("pending")}
|
|
2781
|
+
onIntentExecuted={() => navigate("pending")}
|
|
2699
2782
|
/>
|
|
2700
2783
|
)
|
|
2701
|
-
// case "onramp-meld":
|
|
2702
|
-
// return (
|
|
2703
|
-
// <OnrampDeposit
|
|
2704
|
-
// onBack={handleBack}
|
|
2705
|
-
// quote={prepareSendQuote}
|
|
2706
|
-
// onDepositComplete={handleOnrampDepositComplete}
|
|
2707
|
-
// />
|
|
2708
|
-
// )
|
|
2709
2784
|
case "pending":
|
|
2710
2785
|
return (
|
|
2711
2786
|
<TransferPending
|
|
@@ -2716,7 +2791,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
2716
2791
|
timestamp={hostTransactionTimestamp ?? undefined}
|
|
2717
2792
|
onContinue={() => {
|
|
2718
2793
|
logger.console.log("[trails-sdk] onContinue called")
|
|
2719
|
-
|
|
2794
|
+
navigate("receipt")
|
|
2720
2795
|
}}
|
|
2721
2796
|
/>
|
|
2722
2797
|
)
|
|
@@ -2789,7 +2864,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
2789
2864
|
<div className="flex flex-col h-full">
|
|
2790
2865
|
{onrampFactory({
|
|
2791
2866
|
setCurrentScreen: (screen) => {
|
|
2792
|
-
|
|
2867
|
+
navigate(screen)
|
|
2793
2868
|
},
|
|
2794
2869
|
onComplete: handleOnrampComplete,
|
|
2795
2870
|
onError: (error) => {
|
|
@@ -2835,7 +2910,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
2835
2910
|
</div>
|
|
2836
2911
|
)
|
|
2837
2912
|
}
|
|
2838
|
-
case "meld
|
|
2913
|
+
case "onramp-meld":
|
|
2839
2914
|
return <MeldStepsFlow onBack={handleBack} />
|
|
2840
2915
|
case "wallet-connect":
|
|
2841
2916
|
return (
|
|
@@ -2857,14 +2932,17 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
2857
2932
|
)
|
|
2858
2933
|
|
|
2859
2934
|
if (
|
|
2860
|
-
|
|
2861
|
-
|
|
2935
|
+
isWalletConnectConnector(
|
|
2936
|
+
allWallets.find((w) => w.id === walletId)?.connector as
|
|
2937
|
+
| Connector
|
|
2938
|
+
| undefined,
|
|
2939
|
+
)
|
|
2862
2940
|
) {
|
|
2863
2941
|
saveLastClickedWallet(walletId)
|
|
2864
2942
|
logger.console.log(
|
|
2865
2943
|
"[trails-sdk] WalletConnect selected, going to wallet-connect screen",
|
|
2866
2944
|
)
|
|
2867
|
-
|
|
2945
|
+
navigate("wallet-connect")
|
|
2868
2946
|
} else {
|
|
2869
2947
|
saveLastClickedWallet(walletId)
|
|
2870
2948
|
logger.console.log(
|
|
@@ -2873,11 +2951,12 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
2873
2951
|
// Don't reset the redirect flag - user has already been through initial flow
|
|
2874
2952
|
setTimeout(() => {
|
|
2875
2953
|
// Preserve the existing back route from the navigation stack
|
|
2876
|
-
const backRoute =
|
|
2877
|
-
|
|
2878
|
-
"wallet-
|
|
2879
|
-
|
|
2880
|
-
|
|
2954
|
+
const backRoute = backScreen
|
|
2955
|
+
const safeBackRoute =
|
|
2956
|
+
backRoute === "wallet-confirmation" ? undefined : backRoute
|
|
2957
|
+
navigate("wallet-connection-pending", {
|
|
2958
|
+
backTarget: safeBackRoute || undefined,
|
|
2959
|
+
})
|
|
2881
2960
|
}, 100)
|
|
2882
2961
|
// Auto-trigger connection
|
|
2883
2962
|
setTimeout(() => {
|
|
@@ -2896,13 +2975,13 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
2896
2975
|
case "earn":
|
|
2897
2976
|
return (
|
|
2898
2977
|
<Earn
|
|
2899
|
-
onContinue={() =>
|
|
2978
|
+
onContinue={() => navigate("send-form")}
|
|
2900
2979
|
account={walletClient?.account}
|
|
2901
2980
|
walletClient={walletClient ?? undefined}
|
|
2902
2981
|
onTransactionStateChange={handleTransactionStateChange}
|
|
2903
2982
|
onError={handleSendError}
|
|
2904
2983
|
onWaitingForWalletConfirm={handleWaitingForWalletConfirm}
|
|
2905
|
-
onConfirm={() =>
|
|
2984
|
+
onConfirm={() => navigate("pending")}
|
|
2906
2985
|
onComplete={handleTransferComplete}
|
|
2907
2986
|
onSend={handleOnSend}
|
|
2908
2987
|
paymasterUrls={paymasterUrls}
|
|
@@ -2925,7 +3004,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
2925
3004
|
onPoolSelect={(pool) => {
|
|
2926
3005
|
logger.console.log("Selected pool:", pool)
|
|
2927
3006
|
setSelectedPool(pool)
|
|
2928
|
-
|
|
3007
|
+
navigate("send-form")
|
|
2929
3008
|
}}
|
|
2930
3009
|
/>
|
|
2931
3010
|
)
|
|
@@ -2935,7 +3014,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
2935
3014
|
onSend={handleOnSend}
|
|
2936
3015
|
onWaitingForWalletConfirm={handleWaitingForWalletConfirm}
|
|
2937
3016
|
onWaitingForOnrampConfirm={handleWaitingOnrampConfirm}
|
|
2938
|
-
onConfirm={() =>
|
|
3017
|
+
onConfirm={() => navigate("pending")}
|
|
2939
3018
|
onComplete={handleTransferComplete}
|
|
2940
3019
|
selectedToken={selectedToken}
|
|
2941
3020
|
account={walletClient?.account}
|
|
@@ -2967,7 +3046,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
2967
3046
|
<Withdraw
|
|
2968
3047
|
onSend={handleOnSend}
|
|
2969
3048
|
onWaitingForWalletConfirm={handleWaitingForWalletConfirm}
|
|
2970
|
-
onConfirm={() =>
|
|
3049
|
+
onConfirm={() => navigate("pending")}
|
|
2971
3050
|
onComplete={handleTransferComplete}
|
|
2972
3051
|
selectedToken={selectedToken}
|
|
2973
3052
|
account={walletClient?.account}
|
|
@@ -3027,7 +3106,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
3027
3106
|
case "user-preferences":
|
|
3028
3107
|
return <UserPreferences onBack={handleBack} />
|
|
3029
3108
|
case "chain-list":
|
|
3030
|
-
return <ChainList onBack={() =>
|
|
3109
|
+
return <ChainList onBack={() => navigate("tokens")} />
|
|
3031
3110
|
case "recipients":
|
|
3032
3111
|
return <Recipients onBack={handleBack} />
|
|
3033
3112
|
case "disconnect":
|
|
@@ -3037,13 +3116,10 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
3037
3116
|
disconnectHandler={handleWalletDisconnect}
|
|
3038
3117
|
/>
|
|
3039
3118
|
)
|
|
3040
|
-
case "home": {
|
|
3041
|
-
// Navigation handled by useEffect above, otherwise it would cause a loop
|
|
3042
|
-
return null
|
|
3043
|
-
}
|
|
3044
|
-
default:
|
|
3045
|
-
return null
|
|
3046
3119
|
}
|
|
3120
|
+
|
|
3121
|
+
const unhandledScreen: never = screen
|
|
3122
|
+
throw new Error(`[trails-sdk] Unhandled screen state: ${unhandledScreen}`)
|
|
3047
3123
|
}
|
|
3048
3124
|
|
|
3049
3125
|
const renderScreen = () => {
|
|
@@ -3072,7 +3148,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
3072
3148
|
>
|
|
3073
3149
|
<AnimatePresence mode="wait">
|
|
3074
3150
|
<motion.div
|
|
3075
|
-
key={
|
|
3151
|
+
key={screen}
|
|
3076
3152
|
initial={{ opacity: 0, x: 20 }}
|
|
3077
3153
|
animate={{ opacity: 1, x: 0 }}
|
|
3078
3154
|
exit={{ opacity: 0, x: -20 }}
|
|
@@ -3164,11 +3240,24 @@ export const TrailsWidget = forwardRef<TrailsWidgetRef, TrailsWidgetProps>(
|
|
|
3164
3240
|
|
|
3165
3241
|
// Memoize connectors separately to ensure stable references
|
|
3166
3242
|
const connectors = React.useMemo(() => {
|
|
3167
|
-
if (Array.isArray(props.wagmiConnectors)) {
|
|
3243
|
+
if (!Array.isArray(props.wagmiConnectors)) {
|
|
3244
|
+
return getConnectorsInternal(props.apiKey, props.trailsApiUrl)
|
|
3245
|
+
}
|
|
3246
|
+
|
|
3247
|
+
if (
|
|
3248
|
+
props.wagmiConnectors.some((connector) =>
|
|
3249
|
+
isWalletConnectConnector(connector),
|
|
3250
|
+
)
|
|
3251
|
+
) {
|
|
3168
3252
|
return props.wagmiConnectors
|
|
3169
3253
|
}
|
|
3170
|
-
|
|
3171
|
-
|
|
3254
|
+
|
|
3255
|
+
logger.console.warn(
|
|
3256
|
+
"[trails-sdk] wagmiConnectors is missing WalletConnect connector; appending internal WalletConnect connector to avoid broken QR flow",
|
|
3257
|
+
)
|
|
3258
|
+
// TODO: Remove this append fallback in a future major release. The correct long-term behavior may be to hide WalletConnect options when consumers intentionally omit the connector.
|
|
3259
|
+
return [...props.wagmiConnectors, getWalletConnectConnector()]
|
|
3260
|
+
}, [props.apiKey, props.trailsApiUrl, props.wagmiConnectors])
|
|
3172
3261
|
|
|
3173
3262
|
// Create stable wagmi config using useMemo with minimal dependencies
|
|
3174
3263
|
const wagmiConfig = React.useMemo(() => {
|