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
|
@@ -22,7 +22,11 @@ import {
|
|
|
22
22
|
IntentStatus,
|
|
23
23
|
} from "@0xtrails/api"
|
|
24
24
|
import type { PrepareSendReturn, SendReturn, FundMethod } from "../types.js"
|
|
25
|
-
import {
|
|
25
|
+
import {
|
|
26
|
+
isExternalFundingMethod,
|
|
27
|
+
TradeType,
|
|
28
|
+
toApiFundMethod,
|
|
29
|
+
} from "../types.js"
|
|
26
30
|
import type { QueryClient } from "@tanstack/react-query"
|
|
27
31
|
import type { TransactionState } from "../../transactions.js"
|
|
28
32
|
import type { CheckoutOnHandlers } from "../../widget/hooks/useCheckout.js"
|
|
@@ -35,6 +39,7 @@ import {
|
|
|
35
39
|
quoteIntent,
|
|
36
40
|
commitIntent,
|
|
37
41
|
sendOriginTransaction,
|
|
42
|
+
executeIntent as executeIntentRequest,
|
|
38
43
|
} from "../../intents.js"
|
|
39
44
|
import {
|
|
40
45
|
decodeTokenSweeperEvents,
|
|
@@ -65,12 +70,15 @@ import { isNativeToken } from "../../utils/address.js"
|
|
|
65
70
|
import { ensureErc20Approval } from "../utils/erc20Approval.js"
|
|
66
71
|
import { HOUR_MS } from "../../utils/time.js"
|
|
67
72
|
import { attemptSwitchChain } from "../../chainSwitch.js"
|
|
73
|
+
import { getDoGasless } from "../deposits/gaslessDeposit.js"
|
|
68
74
|
import {
|
|
75
|
+
applyIntentReceiptToTransactionStates,
|
|
69
76
|
getNormalizedTransactionStates,
|
|
70
|
-
updateTransactionStateWithDecodedEvents,
|
|
71
77
|
insertRefundTransactionState,
|
|
78
|
+
updateTransactionStateWithDecodedEvents,
|
|
72
79
|
} from "../helpers/transactionStateHelpers.js"
|
|
73
80
|
import { isSameChain, isSameToken } from "../validators.js"
|
|
81
|
+
import { isSyntheticTransactionHash } from "../../transactions.js"
|
|
74
82
|
|
|
75
83
|
/**
|
|
76
84
|
* Parameters for the unified intent handler.
|
|
@@ -293,6 +301,16 @@ async function executePassthrough(
|
|
|
293
301
|
// Wait for transaction receipt
|
|
294
302
|
const receipt = await effectivePublicClient.waitForTransactionReceipt({
|
|
295
303
|
hash: finalDepositTransactionHash,
|
|
304
|
+
onReplaced: (replacement) => {
|
|
305
|
+
logger.console.log(
|
|
306
|
+
"[trails-sdk] Passthrough deposit transaction replaced",
|
|
307
|
+
{
|
|
308
|
+
reason: replacement.reason,
|
|
309
|
+
replacedHash: replacement.replacedTransaction.hash,
|
|
310
|
+
replacementHash: replacement.transaction.hash,
|
|
311
|
+
},
|
|
312
|
+
)
|
|
313
|
+
},
|
|
296
314
|
})
|
|
297
315
|
logger.console.log("[trails-sdk] Passthrough receipt:", receipt)
|
|
298
316
|
|
|
@@ -391,8 +409,6 @@ async function executeIntent(
|
|
|
391
409
|
selectedFeeOption?: FeeOption | null
|
|
392
410
|
depositTransactionHash?: string
|
|
393
411
|
skipCommit?: boolean
|
|
394
|
-
commitOnly?: boolean
|
|
395
|
-
skipIntentMonitoring?: boolean
|
|
396
412
|
},
|
|
397
413
|
): Promise<SendReturn> {
|
|
398
414
|
const {
|
|
@@ -427,7 +443,6 @@ async function executeIntent(
|
|
|
427
443
|
onOriginSend,
|
|
428
444
|
selectedFeeOption: runtimeSelectedFeeOption,
|
|
429
445
|
depositTransactionHash,
|
|
430
|
-
commitOnly,
|
|
431
446
|
} = options
|
|
432
447
|
|
|
433
448
|
const effectiveSelectedFeeOption = runtimeSelectedFeeOption
|
|
@@ -466,23 +481,81 @@ async function executeIntent(
|
|
|
466
481
|
let depositUserTxnReceipt: TransactionReceipt | null = null
|
|
467
482
|
let originIntentTransaction: IntentTransaction | null = null
|
|
468
483
|
let destinationIntentTransaction: IntentTransaction | null = null
|
|
484
|
+
let hasExecutedIntentEarly = false
|
|
469
485
|
|
|
470
486
|
// Create destination public client for cross-chain polling
|
|
471
487
|
const destinationPublicClient = getChainRpcClient(params.destinationChainId)
|
|
472
488
|
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
489
|
+
const shouldUseGaslessFlow =
|
|
490
|
+
fundMethod === "wallet" &&
|
|
491
|
+
(getDoGasless(
|
|
492
|
+
effectiveOriginTokenAddress,
|
|
493
|
+
gasFeeOptions,
|
|
494
|
+
effectiveSelectedFeeOption,
|
|
495
|
+
walletId,
|
|
496
|
+
) ||
|
|
497
|
+
Boolean(paymasterUrl))
|
|
498
|
+
|
|
499
|
+
// Signal executeIntent immediately after commit for all funding flows.
|
|
500
|
+
if (intent.intentId && !shouldUseGaslessFlow) {
|
|
501
|
+
try {
|
|
502
|
+
if (executeIntentFn) {
|
|
503
|
+
await executeIntentFn({
|
|
504
|
+
intentId: intent.intentId,
|
|
505
|
+
})
|
|
506
|
+
} else {
|
|
507
|
+
await executeIntentRequest(trailsClient, intent.intentId, undefined)
|
|
508
|
+
}
|
|
509
|
+
hasExecutedIntentEarly = true
|
|
510
|
+
logger.console.log(
|
|
511
|
+
"[trails-sdk] executeIntent called immediately after commit",
|
|
512
|
+
{
|
|
513
|
+
intentId: intent.intentId,
|
|
514
|
+
fundMethod,
|
|
515
|
+
depositTransactionHash,
|
|
516
|
+
},
|
|
517
|
+
)
|
|
518
|
+
} catch (executeError: unknown) {
|
|
519
|
+
if (getIsAlreadyExecutingError(executeError)) {
|
|
520
|
+
hasExecutedIntentEarly = true
|
|
521
|
+
logger.console.log(
|
|
522
|
+
"[trails-sdk] Intent already executing after early executeIntent call",
|
|
523
|
+
)
|
|
524
|
+
} else {
|
|
525
|
+
throw executeError
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
} else if (intent.intentId && shouldUseGaslessFlow) {
|
|
529
|
+
logger.console.log(
|
|
530
|
+
"[trails-sdk] Skipping early executeIntent for gasless flow, waiting for deposit signature",
|
|
531
|
+
{
|
|
532
|
+
intentId: intent.intentId,
|
|
533
|
+
fundMethod,
|
|
534
|
+
hasPaymasterUrl: Boolean(paymasterUrl),
|
|
535
|
+
hasSelectedFeeOption: effectiveSelectedFeeOption !== undefined,
|
|
536
|
+
},
|
|
537
|
+
)
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
// External funding flows without a client-provided deposit hash should return
|
|
541
|
+
// immediately after commit/early execute. Their UI will monitor balance at the
|
|
542
|
+
// origin intent address and continue independently of this send() call.
|
|
543
|
+
const publishTransactionStates = (states: TransactionState[]) => {
|
|
544
|
+
onTransactionStateChange(states)
|
|
545
|
+
if (checkoutOnHandlers?.triggerCheckoutStatusUpdate) {
|
|
546
|
+
checkoutOnHandlers.triggerCheckoutStatusUpdate(states)
|
|
479
547
|
}
|
|
480
548
|
}
|
|
481
549
|
|
|
482
|
-
|
|
483
|
-
|
|
550
|
+
if (isExternalFundingMethod(fundMethod) && !depositTransactionHash) {
|
|
551
|
+
publishTransactionStates(localTransactionStates)
|
|
552
|
+
|
|
484
553
|
logger.console.log(
|
|
485
|
-
"[trails-sdk]
|
|
554
|
+
"[trails-sdk] External funding flow: intent committed, returning early",
|
|
555
|
+
{
|
|
556
|
+
fundMethod,
|
|
557
|
+
intentId: intent.intentId,
|
|
558
|
+
},
|
|
486
559
|
)
|
|
487
560
|
return {
|
|
488
561
|
depositUserTxnReceipt: null,
|
|
@@ -513,10 +586,7 @@ async function executeIntent(
|
|
|
513
586
|
})
|
|
514
587
|
|
|
515
588
|
// Set up transaction state tracking
|
|
516
|
-
|
|
517
|
-
if (checkoutOnHandlers?.triggerCheckoutStatusUpdate) {
|
|
518
|
-
checkoutOnHandlers.triggerCheckoutStatusUpdate(localTransactionStates)
|
|
519
|
-
}
|
|
589
|
+
publishTransactionStates(localTransactionStates)
|
|
520
590
|
|
|
521
591
|
if (!intent.intentProtocolVersion) {
|
|
522
592
|
logger.console.log(
|
|
@@ -540,8 +610,32 @@ async function executeIntent(
|
|
|
540
610
|
// Execute deposit transaction
|
|
541
611
|
if (depositTransactionHash && fundMethod !== "wallet") {
|
|
542
612
|
// External deposit with provided hash (onramp-meld, direct-transfer, etc.)
|
|
543
|
-
|
|
544
|
-
|
|
613
|
+
let resolvedDepositTransactionHash = depositTransactionHash as `0x${string}`
|
|
614
|
+
depositUserTxnReceipt =
|
|
615
|
+
await effectivePublicClient.waitForTransactionReceipt({
|
|
616
|
+
hash: depositTransactionHash as `0x${string}`,
|
|
617
|
+
onReplaced: (replacement) => {
|
|
618
|
+
resolvedDepositTransactionHash = replacement.transaction.hash
|
|
619
|
+
logger.console.log(
|
|
620
|
+
"[trails-sdk] External deposit transaction replaced",
|
|
621
|
+
{
|
|
622
|
+
reason: replacement.reason,
|
|
623
|
+
replacedHash: replacement.replacedTransaction.hash,
|
|
624
|
+
replacementHash: replacement.transaction.hash,
|
|
625
|
+
},
|
|
626
|
+
)
|
|
627
|
+
},
|
|
628
|
+
})
|
|
629
|
+
|
|
630
|
+
if (depositUserTxnReceipt?.transactionHash) {
|
|
631
|
+
resolvedDepositTransactionHash =
|
|
632
|
+
depositUserTxnReceipt.transactionHash as `0x${string}`
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
logger.console.log("[trails-sdk] External deposit receipt resolved", {
|
|
636
|
+
providedHash: depositTransactionHash,
|
|
637
|
+
resolvedHash: resolvedDepositTransactionHash,
|
|
638
|
+
status: depositUserTxnReceipt.status,
|
|
545
639
|
})
|
|
546
640
|
|
|
547
641
|
// Update transaction state with receipt
|
|
@@ -551,14 +645,11 @@ async function executeIntent(
|
|
|
551
645
|
effectiveOriginChainId,
|
|
552
646
|
localTransactionStates[0]?.label,
|
|
553
647
|
)
|
|
554
|
-
|
|
555
|
-
if (checkoutOnHandlers?.triggerCheckoutStatusUpdate) {
|
|
556
|
-
checkoutOnHandlers.triggerCheckoutStatusUpdate(localTransactionStates)
|
|
557
|
-
}
|
|
648
|
+
publishTransactionStates(localTransactionStates)
|
|
558
649
|
}
|
|
559
650
|
|
|
560
651
|
if (depositUserTxnReceipt.status === "success" && intent.intentId) {
|
|
561
|
-
//
|
|
652
|
+
// Always signal external deposit success so UI can navigate to pending.
|
|
562
653
|
if (onOriginSend) {
|
|
563
654
|
logger.console.log(
|
|
564
655
|
"[trails-sdk] Calling onOriginSend for external deposit",
|
|
@@ -566,23 +657,28 @@ async function executeIntent(
|
|
|
566
657
|
onOriginSend()
|
|
567
658
|
}
|
|
568
659
|
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
660
|
+
if (hasExecutedIntentEarly) {
|
|
661
|
+
// Intent execution was already triggered immediately after commit.
|
|
662
|
+
// Skip the duplicate executeIntent call, but continue into receipt polling.
|
|
663
|
+
} else {
|
|
664
|
+
// Try to execute the intent if early execution didn't run.
|
|
665
|
+
try {
|
|
666
|
+
if (executeIntentFn) {
|
|
667
|
+
await executeIntentFn({
|
|
668
|
+
intentId: intent.intentId,
|
|
669
|
+
})
|
|
670
|
+
} else {
|
|
671
|
+
await executeIntentRequest(trailsClient, intent.intentId, undefined)
|
|
672
|
+
}
|
|
673
|
+
} catch (executeError: unknown) {
|
|
674
|
+
// If intent is already executing, that's fine - it means the system picked it up
|
|
675
|
+
if (getIsAlreadyExecutingError(executeError)) {
|
|
676
|
+
logger.console.log(
|
|
677
|
+
"[trails-sdk] Intent already executing, continuing...",
|
|
678
|
+
)
|
|
679
|
+
} else {
|
|
680
|
+
throw executeError
|
|
681
|
+
}
|
|
586
682
|
}
|
|
587
683
|
}
|
|
588
684
|
}
|
|
@@ -651,38 +747,12 @@ async function executeIntent(
|
|
|
651
747
|
)
|
|
652
748
|
}
|
|
653
749
|
|
|
654
|
-
|
|
655
|
-
if (checkoutOnHandlers?.triggerCheckoutStatusUpdate) {
|
|
656
|
-
checkoutOnHandlers.triggerCheckoutStatusUpdate(localTransactionStates)
|
|
657
|
-
}
|
|
658
|
-
|
|
659
|
-
// Call executeIntent
|
|
660
|
-
if (depositUserTxnReceipt.status === "success" && intent.intentId) {
|
|
661
|
-
try {
|
|
662
|
-
const executeIntentFnToUse =
|
|
663
|
-
executeIntentFn || trailsClient.executeIntent.bind(trailsClient)
|
|
664
|
-
await executeIntentFnToUse({
|
|
665
|
-
intentId: intent.intentId,
|
|
666
|
-
depositTransactionHash: depositUserTxnReceipt.transactionHash,
|
|
667
|
-
})
|
|
668
|
-
} catch (executeError: unknown) {
|
|
669
|
-
// If intent is already executing (e.g. from early executeIntent call), that's fine
|
|
670
|
-
if (getIsAlreadyExecutingError(executeError)) {
|
|
671
|
-
logger.console.log(
|
|
672
|
-
"[trails-sdk] Intent already executing after deposit, continuing...",
|
|
673
|
-
)
|
|
674
|
-
} else {
|
|
675
|
-
logger.console.error(
|
|
676
|
-
"[trails-sdk] Error calling executeIntent:",
|
|
677
|
-
executeError,
|
|
678
|
-
)
|
|
679
|
-
}
|
|
680
|
-
}
|
|
681
|
-
}
|
|
750
|
+
publishTransactionStates(localTransactionStates)
|
|
682
751
|
}
|
|
683
752
|
}
|
|
684
753
|
// Start polling for intent completion to update transaction states
|
|
685
754
|
let finalReceipt: Awaited<ReturnType<typeof pollIntentReceipt>> = null
|
|
755
|
+
let pollStartMs = 0
|
|
686
756
|
if (intent.intentId) {
|
|
687
757
|
// Determine max wait time based on route provider.
|
|
688
758
|
// OFT routes (LayerZero OFT) can take 5-10+ minutes to complete.
|
|
@@ -695,18 +765,43 @@ async function executeIntent(
|
|
|
695
765
|
routeProviders: intent.quote?.routeProviders,
|
|
696
766
|
})
|
|
697
767
|
try {
|
|
768
|
+
pollStartMs = Date.now()
|
|
698
769
|
finalReceipt = await pollIntentReceipt({
|
|
699
770
|
intentId: intent.intentId,
|
|
700
771
|
trailsClient,
|
|
701
772
|
abortSignal,
|
|
702
773
|
callbacks: {
|
|
703
|
-
onDepositTransactionFound: async (txHash) => {
|
|
774
|
+
onDepositTransactionFound: async (txHash, receipt) => {
|
|
704
775
|
logger.console.log(
|
|
705
776
|
"[trails-sdk] Deposit transaction found:",
|
|
706
777
|
txHash,
|
|
707
778
|
)
|
|
708
779
|
|
|
709
780
|
if (localTransactionStates[0]) {
|
|
781
|
+
if (isSyntheticTransactionHash(txHash)) {
|
|
782
|
+
logger.console.log(
|
|
783
|
+
"[trails-sdk] Deposit transaction hash is synthetic, marking deposit from status",
|
|
784
|
+
{
|
|
785
|
+
txHash,
|
|
786
|
+
status: receipt.depositTransaction?.status,
|
|
787
|
+
},
|
|
788
|
+
)
|
|
789
|
+
|
|
790
|
+
if (receipt.depositTransaction?.status === "SUCCEEDED") {
|
|
791
|
+
localTransactionStates[0] = {
|
|
792
|
+
...localTransactionStates[0],
|
|
793
|
+
state: "confirmed",
|
|
794
|
+
transactionHash: "",
|
|
795
|
+
explorerUrl: "",
|
|
796
|
+
txnMinedAt:
|
|
797
|
+
receipt.depositTransaction?.txnMinedAt || undefined,
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
publishTransactionStates(localTransactionStates)
|
|
801
|
+
}
|
|
802
|
+
return
|
|
803
|
+
}
|
|
804
|
+
|
|
710
805
|
try {
|
|
711
806
|
const depositTxReceipt =
|
|
712
807
|
await effectivePublicClient.getTransactionReceipt({
|
|
@@ -725,12 +820,7 @@ async function executeIntent(
|
|
|
725
820
|
localTransactionStates[0].decodedGuestModuleEvents =
|
|
726
821
|
decodeGuestModuleEvents(depositTxReceipt)
|
|
727
822
|
|
|
728
|
-
|
|
729
|
-
if (checkoutOnHandlers?.triggerCheckoutStatusUpdate) {
|
|
730
|
-
checkoutOnHandlers.triggerCheckoutStatusUpdate(
|
|
731
|
-
localTransactionStates,
|
|
732
|
-
)
|
|
733
|
-
}
|
|
823
|
+
publishTransactionStates(localTransactionStates)
|
|
734
824
|
} catch (error) {
|
|
735
825
|
logger.console.error(
|
|
736
826
|
"[trails-sdk] Error fetching deposit receipt:",
|
|
@@ -739,7 +829,7 @@ async function executeIntent(
|
|
|
739
829
|
}
|
|
740
830
|
}
|
|
741
831
|
},
|
|
742
|
-
onOriginTransactionFound: async (txHash) => {
|
|
832
|
+
onOriginTransactionFound: async (txHash, receipt) => {
|
|
743
833
|
logger.console.log("[trails-sdk] Origin transaction found:", txHash)
|
|
744
834
|
|
|
745
835
|
originIntentTransaction = { txnHash: txHash } as IntentTransaction
|
|
@@ -770,12 +860,27 @@ async function executeIntent(
|
|
|
770
860
|
].decodedGuestModuleEvents =
|
|
771
861
|
decodeGuestModuleEvents(originTxReceipt)
|
|
772
862
|
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
863
|
+
// Some external funding flows do not surface a distinct
|
|
864
|
+
// depositTransaction in the receipt. In those cases the origin
|
|
865
|
+
// transaction implicitly covers the deposit step as well.
|
|
866
|
+
if (
|
|
867
|
+
!receipt.depositTransaction?.txnHash &&
|
|
868
|
+
!receipt.depositTransaction?.status &&
|
|
869
|
+
localTransactionStates.length > 1 &&
|
|
870
|
+
localTransactionStates[0]
|
|
871
|
+
) {
|
|
872
|
+
localTransactionStates[0] = getTransactionStateFromReceipt(
|
|
873
|
+
originTxReceipt,
|
|
874
|
+
effectiveOriginChainId,
|
|
875
|
+
localTransactionStates[0]?.label,
|
|
777
876
|
)
|
|
877
|
+
localTransactionStates[0].decodedTokenSweeperEvents =
|
|
878
|
+
decodeTokenSweeperEvents(originTxReceipt)
|
|
879
|
+
localTransactionStates[0].decodedGuestModuleEvents =
|
|
880
|
+
decodeGuestModuleEvents(originTxReceipt)
|
|
778
881
|
}
|
|
882
|
+
|
|
883
|
+
publishTransactionStates(localTransactionStates)
|
|
779
884
|
}
|
|
780
885
|
} catch (error) {
|
|
781
886
|
logger.console.error(
|
|
@@ -820,12 +925,7 @@ async function executeIntent(
|
|
|
820
925
|
].decodedGuestModuleEvents =
|
|
821
926
|
decodeGuestModuleEvents(destinationTxReceipt)
|
|
822
927
|
|
|
823
|
-
|
|
824
|
-
if (checkoutOnHandlers?.triggerCheckoutStatusUpdate) {
|
|
825
|
-
checkoutOnHandlers.triggerCheckoutStatusUpdate(
|
|
826
|
-
localTransactionStates,
|
|
827
|
-
)
|
|
828
|
-
}
|
|
928
|
+
publishTransactionStates(localTransactionStates)
|
|
829
929
|
}
|
|
830
930
|
} catch (error) {
|
|
831
931
|
logger.console.error(
|
|
@@ -844,6 +944,15 @@ async function executeIntent(
|
|
|
844
944
|
hasRefund: !!receipt.refundTransaction,
|
|
845
945
|
})
|
|
846
946
|
|
|
947
|
+
const reconciledStates = applyIntentReceiptToTransactionStates({
|
|
948
|
+
currentStates: localTransactionStates,
|
|
949
|
+
receipt,
|
|
950
|
+
})
|
|
951
|
+
if (reconciledStates.changed) {
|
|
952
|
+
localTransactionStates = reconciledStates.transactionStates
|
|
953
|
+
publishTransactionStates(localTransactionStates)
|
|
954
|
+
}
|
|
955
|
+
|
|
847
956
|
// Handle terminal status - mark pending steps as aborted/failed
|
|
848
957
|
if (
|
|
849
958
|
done &&
|
|
@@ -863,12 +972,7 @@ async function executeIntent(
|
|
|
863
972
|
}
|
|
864
973
|
}
|
|
865
974
|
|
|
866
|
-
|
|
867
|
-
if (checkoutOnHandlers?.triggerCheckoutStatusUpdate) {
|
|
868
|
-
checkoutOnHandlers.triggerCheckoutStatusUpdate(
|
|
869
|
-
localTransactionStates,
|
|
870
|
-
)
|
|
871
|
-
}
|
|
975
|
+
publishTransactionStates(localTransactionStates)
|
|
872
976
|
}
|
|
873
977
|
|
|
874
978
|
// Handle deposit tx revert - mark all txs as failed
|
|
@@ -883,12 +987,7 @@ async function executeIntent(
|
|
|
883
987
|
}
|
|
884
988
|
}
|
|
885
989
|
|
|
886
|
-
|
|
887
|
-
if (checkoutOnHandlers?.triggerCheckoutStatusUpdate) {
|
|
888
|
-
checkoutOnHandlers.triggerCheckoutStatusUpdate(
|
|
889
|
-
localTransactionStates,
|
|
890
|
-
)
|
|
891
|
-
}
|
|
990
|
+
publishTransactionStates(localTransactionStates)
|
|
892
991
|
}
|
|
893
992
|
|
|
894
993
|
// Insert refund transaction state if refund exists
|
|
@@ -911,12 +1010,7 @@ async function executeIntent(
|
|
|
911
1010
|
if (statesChanged) {
|
|
912
1011
|
localTransactionStates.length = 0
|
|
913
1012
|
localTransactionStates.push(...updatedStates)
|
|
914
|
-
|
|
915
|
-
if (checkoutOnHandlers?.triggerCheckoutStatusUpdate) {
|
|
916
|
-
checkoutOnHandlers.triggerCheckoutStatusUpdate(
|
|
917
|
-
localTransactionStates,
|
|
918
|
-
)
|
|
919
|
-
}
|
|
1013
|
+
publishTransactionStates(localTransactionStates)
|
|
920
1014
|
}
|
|
921
1015
|
}
|
|
922
1016
|
},
|
|
@@ -931,22 +1025,43 @@ async function executeIntent(
|
|
|
931
1025
|
IntentStatus.REFUNDED,
|
|
932
1026
|
IntentStatus.ABORTED,
|
|
933
1027
|
]
|
|
1028
|
+
const summary = (
|
|
1029
|
+
finalReceipt as unknown as { summary?: { finishedAt?: string | null } }
|
|
1030
|
+
)?.summary
|
|
1031
|
+
const hasFinishedMarker = Boolean(
|
|
1032
|
+
summary?.finishedAt ||
|
|
1033
|
+
finalReceipt?.destinationTransaction?.txnMinedAt ||
|
|
1034
|
+
finalReceipt?.destinationTransaction?.txnHash,
|
|
1035
|
+
)
|
|
1036
|
+
const destinationSucceeded =
|
|
1037
|
+
finalReceipt?.destinationTransaction?.status === "SUCCEEDED"
|
|
1038
|
+
const completeViaDestinationFallback =
|
|
1039
|
+
!!finalReceipt && destinationSucceeded && hasFinishedMarker
|
|
934
1040
|
const isComplete =
|
|
935
|
-
finalReceipt &&
|
|
1041
|
+
!!finalReceipt &&
|
|
1042
|
+
(terminalStatuses.includes(finalReceipt.status) ||
|
|
1043
|
+
completeViaDestinationFallback)
|
|
936
1044
|
|
|
937
1045
|
if (!isComplete) {
|
|
938
|
-
|
|
1046
|
+
const elapsedMs = pollStartMs > 0 ? Date.now() - pollStartMs : 0
|
|
1047
|
+
const timedOut = elapsedMs >= maxWaitTime
|
|
1048
|
+
const reason = timedOut
|
|
1049
|
+
? `Intent execution timed out after ${Math.round(maxWaitTime / 60000)} minutes.`
|
|
1050
|
+
: "Unable to confirm final intent status from receipt polling."
|
|
1051
|
+
|
|
939
1052
|
logger.console.warn(
|
|
940
|
-
"[trails-sdk] Intent polling
|
|
1053
|
+
"[trails-sdk] Intent polling ended without terminal status",
|
|
941
1054
|
{
|
|
942
1055
|
intentId: intent.intentId,
|
|
943
1056
|
status: finalReceipt?.status,
|
|
944
1057
|
maxWaitTime,
|
|
1058
|
+
elapsedMs,
|
|
1059
|
+
timedOut,
|
|
945
1060
|
},
|
|
946
1061
|
)
|
|
947
1062
|
|
|
948
1063
|
trackPaymentError({
|
|
949
|
-
error:
|
|
1064
|
+
error: `${reason} Please check transaction history or query GetIntentReceipt.`,
|
|
950
1065
|
userAddress: account.address,
|
|
951
1066
|
mode,
|
|
952
1067
|
fundMethod,
|
|
@@ -957,12 +1072,12 @@ async function executeIntent(
|
|
|
957
1072
|
|
|
958
1073
|
if (checkoutOnHandlers?.triggerCheckoutError) {
|
|
959
1074
|
checkoutOnHandlers.triggerCheckoutError(
|
|
960
|
-
"
|
|
1075
|
+
"Unable to confirm final transaction status",
|
|
961
1076
|
)
|
|
962
1077
|
}
|
|
963
1078
|
|
|
964
1079
|
throw new Error(
|
|
965
|
-
|
|
1080
|
+
`${reason} Please check transaction history or query GetIntentReceipt with this intent ID.`,
|
|
966
1081
|
)
|
|
967
1082
|
}
|
|
968
1083
|
} catch (error) {
|
|
@@ -1375,7 +1490,7 @@ export async function handleIntent(
|
|
|
1375
1490
|
quote,
|
|
1376
1491
|
feeOptions: gasFeeOptions,
|
|
1377
1492
|
send: async (options) => {
|
|
1378
|
-
const { skipCommit
|
|
1493
|
+
const { skipCommit } = options
|
|
1379
1494
|
|
|
1380
1495
|
try {
|
|
1381
1496
|
// Recalculate passthrough decision at send time based on fee option.
|
|
@@ -1426,19 +1541,12 @@ export async function handleIntent(
|
|
|
1426
1541
|
|
|
1427
1542
|
const commitIntentFnToUse =
|
|
1428
1543
|
commitIntentFn ||
|
|
1429
|
-
((intent: Intent
|
|
1430
|
-
commitIntent(
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
destinationTokenSymbol,
|
|
1436
|
-
},
|
|
1437
|
-
{
|
|
1438
|
-
skipIntentMonitoring: options?.skipIntentMonitoring,
|
|
1439
|
-
},
|
|
1440
|
-
))
|
|
1441
|
-
await commitIntentFnToUse(intent, { skipIntentMonitoring })
|
|
1544
|
+
((intent: Intent) =>
|
|
1545
|
+
commitIntent(trailsClient, intent, {
|
|
1546
|
+
originTokenSymbol,
|
|
1547
|
+
destinationTokenSymbol,
|
|
1548
|
+
}))
|
|
1549
|
+
await commitIntentFnToUse(intent)
|
|
1442
1550
|
|
|
1443
1551
|
logger.console.log("[trails-sdk] Intent committed successfully")
|
|
1444
1552
|
} catch (error) {
|
|
@@ -1447,18 +1555,6 @@ export async function handleIntent(
|
|
|
1447
1555
|
}
|
|
1448
1556
|
}
|
|
1449
1557
|
|
|
1450
|
-
if (commitOnly) {
|
|
1451
|
-
// Handle commit-only case
|
|
1452
|
-
if (!sendUsePassthrough) {
|
|
1453
|
-
await commitIntentIfNeeded()
|
|
1454
|
-
}
|
|
1455
|
-
return {
|
|
1456
|
-
depositUserTxnReceipt: null,
|
|
1457
|
-
originIntentTransaction: null,
|
|
1458
|
-
destinationIntentTransaction: null,
|
|
1459
|
-
}
|
|
1460
|
-
}
|
|
1461
|
-
|
|
1462
1558
|
if (sendUsePassthrough && sendDepositTransaction) {
|
|
1463
1559
|
return executePassthrough(
|
|
1464
1560
|
params,
|