0xtrails 0.4.3 → 0.6.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/analytics.d.ts +8 -3
- package/dist/analytics.d.ts.map +1 -1
- package/dist/{ccip-C9CA3tIi.js → ccip-Dw5AN7oU.js} +27 -27
- package/dist/cctp.d.ts +0 -149
- package/dist/cctp.d.ts.map +1 -1
- package/dist/chains.d.ts +31 -4
- package/dist/chains.d.ts.map +1 -1
- package/dist/config.d.ts +28 -52
- package/dist/config.d.ts.map +1 -1
- package/dist/constants.d.ts +1 -7
- package/dist/constants.d.ts.map +1 -1
- package/dist/contractUtils.d.ts.map +1 -1
- package/dist/estimate.d.ts.map +1 -1
- package/dist/fees.d.ts.map +1 -1
- package/dist/gasless.d.ts +12 -0
- package/dist/gasless.d.ts.map +1 -1
- package/dist/{index-CNB57v0n.js → index-BtVUTbEZ.js} +32255 -40547
- package/dist/index.d.ts +13 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +320 -944
- package/dist/indexerClient.d.ts +9 -6
- package/dist/indexerClient.d.ts.map +1 -1
- package/dist/intents.d.ts +0 -18
- package/dist/intents.d.ts.map +1 -1
- package/dist/mutations.d.ts.map +1 -1
- package/dist/paymasterSend.d.ts.map +1 -1
- package/dist/prepareSend.d.ts +1 -1
- package/dist/prepareSend.d.ts.map +1 -1
- package/dist/sendUserOp.d.ts +0 -18
- package/dist/sendUserOp.d.ts.map +1 -1
- package/dist/sequenceWallet.d.ts +1 -1
- package/dist/sequenceWallet.d.ts.map +1 -1
- package/dist/tokenBalances.d.ts.map +1 -1
- package/dist/tokens.d.ts +10 -8
- package/dist/tokens.d.ts.map +1 -1
- package/dist/trailsClient.d.ts +3 -3
- package/dist/trailsClient.d.ts.map +1 -1
- package/dist/transactionIntent/deposits/depositOrchestrator.d.ts +4 -5
- package/dist/transactionIntent/deposits/depositOrchestrator.d.ts.map +1 -1
- package/dist/transactionIntent/deposits/gaslessDeposit.d.ts +4 -5
- package/dist/transactionIntent/deposits/gaslessDeposit.d.ts.map +1 -1
- package/dist/transactionIntent/deposits/standardDeposit.d.ts +2 -2
- package/dist/transactionIntent/deposits/standardDeposit.d.ts.map +1 -1
- package/dist/transactionIntent/execution/transactionState.d.ts +2 -2
- package/dist/transactionIntent/execution/transactionState.d.ts.map +1 -1
- package/dist/transactionIntent/handlers/crossChain.d.ts +6 -4
- package/dist/transactionIntent/handlers/crossChain.d.ts.map +1 -1
- package/dist/transactionIntent/handlers/index.d.ts +0 -1
- package/dist/transactionIntent/handlers/index.d.ts.map +1 -1
- package/dist/transactionIntent/handlers/sameChainSameToken.d.ts +4 -34
- package/dist/transactionIntent/handlers/sameChainSameToken.d.ts.map +1 -1
- package/dist/transactionIntent/quote/normalizeQuote.d.ts.map +1 -1
- package/dist/transactionIntent/quote/quoteHelpers.d.ts +2 -1
- package/dist/transactionIntent/quote/quoteHelpers.d.ts.map +1 -1
- package/dist/transactionIntent/types.d.ts +7 -19
- package/dist/transactionIntent/types.d.ts.map +1 -1
- package/dist/transactionIntent/utils/index.d.ts +0 -1
- package/dist/transactionIntent/utils/index.d.ts.map +1 -1
- package/dist/transactions.d.ts +6 -18
- package/dist/transactions.d.ts.map +1 -1
- package/dist/utils.d.ts +8 -2
- package/dist/utils.d.ts.map +1 -1
- package/dist/walletUtils.d.ts +21 -0
- package/dist/walletUtils.d.ts.map +1 -0
- package/dist/wallets.d.ts +33 -240
- package/dist/wallets.d.ts.map +1 -1
- package/dist/widget/components/AccountIntentTransactionHistory.d.ts.map +1 -1
- package/dist/widget/components/ClassicSwap.d.ts.map +1 -1
- package/dist/widget/components/ConfigDisplay.d.ts.map +1 -1
- package/dist/widget/components/FeeOption.d.ts +8 -13
- package/dist/widget/components/FeeOption.d.ts.map +1 -1
- package/dist/widget/components/FeeOptions.d.ts +11 -5
- package/dist/widget/components/FeeOptions.d.ts.map +1 -1
- package/dist/widget/components/NativeGasOption.d.ts.map +1 -1
- package/dist/widget/components/Pay.d.ts.map +1 -1
- package/dist/widget/components/PoolDeposit.d.ts.map +1 -1
- package/dist/widget/components/QRCodeDeposit.d.ts +5 -0
- package/dist/widget/components/QRCodeDeposit.d.ts.map +1 -1
- package/dist/widget/components/QRCodeWalletSelect.d.ts +13 -0
- package/dist/widget/components/QRCodeWalletSelect.d.ts.map +1 -0
- 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/ScreenHeader.d.ts +1 -1
- package/dist/widget/components/ScreenHeader.d.ts.map +1 -1
- package/dist/widget/components/SlippageToleranceSettings.d.ts +1 -0
- package/dist/widget/components/SlippageToleranceSettings.d.ts.map +1 -1
- package/dist/widget/components/Toast.d.ts.map +1 -1
- package/dist/widget/components/TokenImage.d.ts.map +1 -1
- package/dist/widget/components/WalletConnect.d.ts.map +1 -1
- package/dist/widget/css/compiled.css +1 -1
- package/dist/widget/hooks/useCheckout.d.ts +15 -1
- package/dist/widget/hooks/useCheckout.d.ts.map +1 -1
- package/dist/widget/hooks/useCurrentScreen.d.ts +1 -1
- package/dist/widget/hooks/useCurrentScreen.d.ts.map +1 -1
- package/dist/widget/hooks/useDebugScreens.d.ts +1 -1
- package/dist/widget/hooks/useDebugScreens.d.ts.map +1 -1
- package/dist/widget/hooks/useIntentTransactionHistory.d.ts.map +1 -1
- package/dist/widget/hooks/useIsConnectedWalletSmartContract.d.ts +7 -0
- package/dist/widget/hooks/useIsConnectedWalletSmartContract.d.ts.map +1 -0
- package/dist/widget/hooks/useIsSequenceWallet.d.ts +6 -0
- package/dist/widget/hooks/useIsSequenceWallet.d.ts.map +1 -0
- package/dist/widget/hooks/useQuote.d.ts +6 -11
- package/dist/widget/hooks/useQuote.d.ts.map +1 -1
- package/dist/widget/hooks/useRecentTokens.d.ts.map +1 -1
- package/dist/widget/hooks/useSelectedFeeOption.d.ts +30 -0
- package/dist/widget/hooks/useSelectedFeeOption.d.ts.map +1 -0
- package/dist/widget/hooks/useSendForm.d.ts +6 -15
- package/dist/widget/hooks/useSendForm.d.ts.map +1 -1
- package/dist/widget/hooks/useTokenList.d.ts.map +1 -1
- package/dist/widget/index.d.ts +1 -0
- package/dist/widget/index.d.ts.map +1 -1
- package/dist/widget/index.js +4 -2
- package/dist/widget/providers/TrailsProvider.d.ts +29 -0
- package/dist/widget/providers/TrailsProvider.d.ts.map +1 -0
- package/dist/widget/widget.d.ts +14 -3
- package/dist/widget/widget.d.ts.map +1 -1
- package/package.json +9 -8
- package/src/analytics.ts +53 -21
- package/src/cctp.ts +0 -1016
- package/src/chains.ts +155 -68
- package/src/config.ts +51 -207
- package/src/constants.ts +1 -13
- package/src/contractUtils.ts +6 -6
- package/src/estimate.ts +3 -6
- package/src/fees.ts +5 -10
- package/src/gasless.ts +45 -0
- package/src/index.ts +18 -40
- package/src/indexerClient.ts +39 -48
- package/src/intents.ts +51 -226
- package/src/mutations.ts +3 -2
- package/src/paymasterSend.ts +2 -5
- package/src/prepareSend.ts +21 -14
- package/src/sendUserOp.ts +3 -64
- package/src/sequenceWallet.ts +1 -2
- package/src/tokenBalances.ts +2 -1
- package/src/tokens.ts +62 -133
- package/src/trailsClient.ts +17 -12
- package/src/transactionIntent/deposits/depositOrchestrator.ts +14 -15
- package/src/transactionIntent/deposits/gaslessDeposit.ts +70 -100
- package/src/transactionIntent/deposits/standardDeposit.ts +22 -28
- package/src/transactionIntent/execution/transactionState.ts +2 -2
- package/src/transactionIntent/handlers/crossChain.ts +179 -381
- package/src/transactionIntent/handlers/index.ts +0 -1
- package/src/transactionIntent/handlers/sameChainSameToken.ts +228 -94
- package/src/transactionIntent/quote/normalizeQuote.ts +4 -6
- package/src/transactionIntent/quote/quoteHelpers.ts +35 -3
- package/src/transactionIntent/types.ts +7 -27
- package/src/transactionIntent/utils/index.ts +0 -1
- package/src/transactions.ts +19 -118
- package/src/umd.tsx +1 -3
- package/src/utils.ts +28 -8
- package/src/walletUtils.ts +42 -0
- package/src/wallets.ts +365 -208
- package/src/widget/compiled.css +1 -1
- package/src/widget/components/AccountIntentTransactionHistory.tsx +78 -4
- package/src/widget/components/AccountSettings.tsx +17 -17
- package/src/widget/components/ChainList.tsx +3 -3
- package/src/widget/components/ClassicSwap.tsx +19 -10
- package/src/widget/components/ConfigDisplay.tsx +19 -59
- package/src/widget/components/FeeOption.tsx +63 -20
- package/src/widget/components/FeeOptions.tsx +54 -123
- package/src/widget/components/NativeGasOption.tsx +3 -1
- package/src/widget/components/Pay.tsx +18 -11
- package/src/widget/components/PoolDeposit.tsx +23 -10
- package/src/widget/components/QRCodeDeposit.tsx +50 -30
- package/src/widget/components/QRCodeWalletSelect.tsx +77 -0
- package/src/widget/components/QrCode.tsx +188 -233
- package/src/widget/components/QuoteDetails.tsx +48 -2
- package/src/widget/components/Receipt.tsx +5 -2
- package/src/widget/components/ScreenHeader.tsx +10 -8
- package/src/widget/components/SlippageToleranceSettings.tsx +63 -14
- package/src/widget/components/Toast.tsx +10 -0
- package/src/widget/components/TokenImage.tsx +56 -13
- package/src/widget/components/WalletConnect.tsx +37 -99
- package/src/widget/hooks/useCheckout.ts +71 -0
- package/src/widget/hooks/useCurrentScreen.tsx +1 -0
- package/src/widget/hooks/useDebugScreens.ts +5 -0
- package/src/widget/hooks/useIntentTransactionHistory.ts +790 -412
- package/src/widget/hooks/useIsConnectedWalletSmartContract.ts +43 -0
- package/src/widget/hooks/useIsSequenceWallet.ts +17 -0
- package/src/widget/hooks/useQuote.ts +27 -34
- package/src/widget/hooks/useRecentTokens.ts +2 -1
- package/src/widget/hooks/useSelectedFeeOption.tsx +257 -0
- package/src/widget/hooks/useSendForm.ts +175 -46
- package/src/widget/hooks/useTokenList.ts +15 -2
- package/src/widget/index.tsx +8 -0
- package/src/widget/providers/TrailsProvider.tsx +123 -0
- package/src/widget/widget.tsx +165 -143
- package/dist/cctpqueue.d.ts +0 -18
- package/dist/cctpqueue.d.ts.map +0 -1
- package/dist/preconditions.d.ts +0 -12
- package/dist/preconditions.d.ts.map +0 -1
- package/dist/trails.d.ts +0 -110
- package/dist/trails.d.ts.map +0 -1
- package/dist/transactionIntent/handlers/sameChainDifferentToken.d.ts +0 -62
- package/dist/transactionIntent/handlers/sameChainDifferentToken.d.ts.map +0 -1
- package/dist/transactionIntent/utils/lifiHelpers.d.ts +0 -10
- package/dist/transactionIntent/utils/lifiHelpers.d.ts.map +0 -1
- package/dist/widget/hooks/useSelectedFeeToken.d.ts +0 -33
- package/dist/widget/hooks/useSelectedFeeToken.d.ts.map +0 -1
- package/src/cctpqueue.ts +0 -66
- package/src/preconditions.ts +0 -47
- package/src/trails.ts +0 -1303
- package/src/transactionIntent/handlers/sameChainDifferentToken.ts +0 -323
- package/src/transactionIntent/utils/lifiHelpers.ts +0 -68
- package/src/widget/hooks/useSelectedFeeToken.tsx +0 -288
|
@@ -5,11 +5,11 @@ import type {
|
|
|
5
5
|
WalletClient,
|
|
6
6
|
TransactionReceipt,
|
|
7
7
|
} from "viem"
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import type { TrailsApi } from "@0xsequence/trails-api"
|
|
11
|
-
import type {
|
|
12
|
-
import type {
|
|
8
|
+
import { JsonEncode } from "@0xsequence/trails-api"
|
|
9
|
+
import { getPublicRpcClient } from "../../chains.js"
|
|
10
|
+
import type { FeeOption, TrailsApi } from "@0xsequence/trails-api"
|
|
11
|
+
import type { IntentTransaction } from "@0xsequence/trails-api"
|
|
12
|
+
import type { PrepareSendReturn, SendReturn } from "../types.js"
|
|
13
13
|
import type { TransactionState } from "../../transactions.js"
|
|
14
14
|
import type { CheckoutOnHandlers } from "../../widget/hooks/useCheckout.js"
|
|
15
15
|
import type {
|
|
@@ -18,42 +18,26 @@ import type {
|
|
|
18
18
|
DepositSignature,
|
|
19
19
|
ExecuteIntentResponse,
|
|
20
20
|
} from "@0xsequence/trails-api"
|
|
21
|
-
import { TradeType
|
|
21
|
+
import { TradeType } from "../types.js"
|
|
22
22
|
import { logger } from "../../logger.js"
|
|
23
23
|
import {
|
|
24
24
|
isTestnetDebugMode,
|
|
25
25
|
getTestnetOriginTokenAddress,
|
|
26
26
|
} from "../utils/testnetHelpers.js"
|
|
27
|
-
import { shouldUseCctp, validateCctpDestinationToken } from "../validators.js"
|
|
28
|
-
import { getQueryParam } from "../../queryParams.js"
|
|
29
|
-
import { getIsCustomCalldata } from "../../contractUtils.js"
|
|
30
27
|
import { getNormalizedQuoteObject } from "../quote/normalizeQuote.js"
|
|
31
|
-
import {
|
|
32
|
-
cctpTransfer,
|
|
33
|
-
cctpTransferWithCustomCall,
|
|
34
|
-
getCCTPRelayerCallData,
|
|
35
|
-
getMintUSDCData,
|
|
36
|
-
getMessageTransmitter,
|
|
37
|
-
} from "../../cctp.js"
|
|
38
28
|
import { getChainInfo, getTestnetChainInfo } from "../../chains.js"
|
|
39
29
|
import { getTransactionStateFromReceipt } from "../execution/transactionState.js"
|
|
40
|
-
import {
|
|
41
|
-
simpleCreateSequenceWallet,
|
|
42
|
-
sequenceSendTransaction,
|
|
43
|
-
} from "../../sequenceWallet.js"
|
|
44
30
|
import { getIntentArgs } from "../quote/quoteHelpers.js"
|
|
45
31
|
import {
|
|
46
32
|
quoteIntent,
|
|
47
33
|
commitIntent,
|
|
48
34
|
buildCrossChainDepositParams,
|
|
49
35
|
} from "../../intents.js"
|
|
50
|
-
import { findFirstPreconditionForChainId } from "../../preconditions.js"
|
|
51
36
|
import {
|
|
52
37
|
decodeTrailsTokenSweeperEvents,
|
|
53
38
|
decodeGuestModuleEvents,
|
|
54
39
|
} from "../../decoders.js"
|
|
55
40
|
import { updatePersistentToast } from "../../toast.js"
|
|
56
|
-
import { queueCCTPTransfer } from "../../cctpqueue.js"
|
|
57
41
|
import { formatRawAmount } from "../../tokenBalances.js"
|
|
58
42
|
import { calcAmountUsdPrice } from "../../prices.js"
|
|
59
43
|
import { checkAccountBalance } from "../utils/balanceChecker.js"
|
|
@@ -63,16 +47,15 @@ import {
|
|
|
63
47
|
getPriceImpactFromIntent,
|
|
64
48
|
getPriceImpactUsdFromIntent,
|
|
65
49
|
} from "../quote/feeExtractors.js"
|
|
66
|
-
import { getNeedsLifiNativeFee } from "../utils/lifiHelpers.js"
|
|
67
50
|
import { attemptUserDepositTx } from "../deposits/depositOrchestrator.js"
|
|
68
51
|
import {
|
|
69
52
|
getAccountTransactionHistory,
|
|
70
53
|
getTxTimeDiff,
|
|
71
54
|
} from "../../transactions.js"
|
|
72
55
|
import { trackPaymentCompleted, trackPaymentError } from "../../analytics.js"
|
|
73
|
-
import { POLLING_INTERVALS } from "../constants.js"
|
|
74
56
|
import { pollIntentReceipt } from "../../intentReceiptPoller.js"
|
|
75
57
|
import type { IntentReceipt } from "@0xsequence/trails-api"
|
|
58
|
+
import { POLLING_INTERVALS } from "../constants.js"
|
|
76
59
|
|
|
77
60
|
/**
|
|
78
61
|
* @description
|
|
@@ -140,11 +123,13 @@ export async function handleCrossChain({
|
|
|
140
123
|
fundMethod,
|
|
141
124
|
mode,
|
|
142
125
|
checkoutOnHandlers,
|
|
143
|
-
|
|
126
|
+
selectedFeeOption,
|
|
144
127
|
walletId,
|
|
145
128
|
abortSignal,
|
|
146
129
|
commitIntentFn,
|
|
147
130
|
executeIntentFn,
|
|
131
|
+
sequenceProjectAccessKey,
|
|
132
|
+
sequenceIndexerUrl,
|
|
148
133
|
}: {
|
|
149
134
|
mainSignerAddress: string
|
|
150
135
|
originChainId: number
|
|
@@ -178,7 +163,7 @@ export async function handleCrossChain({
|
|
|
178
163
|
fundMethod?: string
|
|
179
164
|
mode?: "pay" | "fund" | "earn" | "swap" | "receive"
|
|
180
165
|
checkoutOnHandlers?: Partial<CheckoutOnHandlers>
|
|
181
|
-
|
|
166
|
+
selectedFeeOption?: FeeOption | null
|
|
182
167
|
walletId?: string
|
|
183
168
|
abortSignal?: AbortSignal
|
|
184
169
|
commitIntentFn?: (intent: Intent) => Promise<CommitIntentResponse>
|
|
@@ -187,248 +172,12 @@ export async function handleCrossChain({
|
|
|
187
172
|
depositTransactionHash?: string
|
|
188
173
|
depositSignature?: DepositSignature
|
|
189
174
|
}) => Promise<ExecuteIntentResponse>
|
|
175
|
+
sequenceProjectAccessKey?: string
|
|
176
|
+
sequenceIndexerUrl?: string
|
|
190
177
|
}): Promise<PrepareSendReturn> {
|
|
191
|
-
const
|
|
192
|
-
const useCctp = shouldUseCctp(
|
|
193
|
-
originTokenAddress,
|
|
194
|
-
destinationTokenAddress,
|
|
195
|
-
originChainId,
|
|
196
|
-
destinationChainId,
|
|
197
|
-
)
|
|
198
|
-
|
|
199
|
-
const cctpFlag = getQueryParam("cctp") === "true"
|
|
200
|
-
const hasCustomCalldata = getIsCustomCalldata(destinationCalldata)
|
|
201
|
-
|
|
202
|
-
// Validate CCTP destination token requirement for explicit CCTP usage
|
|
203
|
-
if (useCctp && cctpFlag) {
|
|
204
|
-
validateCctpDestinationToken(
|
|
205
|
-
destinationTokenAddress,
|
|
206
|
-
destinationChainId,
|
|
207
|
-
"cctp",
|
|
208
|
-
)
|
|
209
|
-
logger.console.log("[trails-sdk] using cctp")
|
|
210
|
-
|
|
211
|
-
const quote = await getNormalizedQuoteObject({
|
|
212
|
-
destinationAddress: recipient,
|
|
213
|
-
destinationCalldata,
|
|
214
|
-
originAmount: swapAmount,
|
|
215
|
-
originTokenPriceUsd: sourceTokenPriceUsd?.toString() || null,
|
|
216
|
-
destinationAmount: swapAmount,
|
|
217
|
-
destinationTokenPriceUsd: destinationTokenPriceUsd?.toString() || null,
|
|
218
|
-
originTokenAddress: originTokenAddress,
|
|
219
|
-
destinationTokenAddress: destinationTokenAddress,
|
|
220
|
-
originChainId,
|
|
221
|
-
destinationChainId,
|
|
222
|
-
transactionStates,
|
|
223
|
-
originNativeTokenPriceUsd,
|
|
224
|
-
slippageTolerance,
|
|
225
|
-
quoteProvider: "cctp",
|
|
226
|
-
})
|
|
227
|
-
|
|
228
|
-
// Call onCheckoutQuote callback if provided
|
|
229
|
-
if (checkoutOnHandlers?.triggerCheckoutQuote) {
|
|
230
|
-
checkoutOnHandlers.triggerCheckoutQuote(quote)
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
return {
|
|
234
|
-
quote,
|
|
235
|
-
send: async ({
|
|
236
|
-
onOriginSend,
|
|
237
|
-
selectedFeeToken: runtimeSelectedFeeToken,
|
|
238
|
-
}: {
|
|
239
|
-
onOriginSend?: () => void
|
|
240
|
-
selectedFeeToken?: SelectedFeeToken
|
|
241
|
-
}): Promise<SendReturn> => {
|
|
242
|
-
// Use runtime selectedFeeToken if provided, otherwise fall back to the one from prepareSend
|
|
243
|
-
const effectiveSelectedFeeToken =
|
|
244
|
-
runtimeSelectedFeeToken ?? selectedFeeToken
|
|
245
|
-
logger.console.log(
|
|
246
|
-
"[trails-sdk] [FEE-SELECT] [GASLESS-FLOW] send() called (LEGACY PATH):",
|
|
247
|
-
{
|
|
248
|
-
runtimeSelectedFeeToken,
|
|
249
|
-
prepareTimeSelectedFeeToken: selectedFeeToken,
|
|
250
|
-
effectiveSelectedFeeToken,
|
|
251
|
-
},
|
|
252
|
-
)
|
|
253
|
-
const originChain = testnet ? getTestnetChainInfo(chain)! : chain
|
|
254
|
-
const destinationChain = testnet
|
|
255
|
-
? getTestnetChainInfo(destinationChainId)!
|
|
256
|
-
: getChainInfo(destinationChainId)
|
|
257
|
-
|
|
258
|
-
if (!originChain || !destinationChain) {
|
|
259
|
-
logger.console.error("[trails-sdk] Invalid chain", {
|
|
260
|
-
originChain,
|
|
261
|
-
destinationChain,
|
|
262
|
-
originChainId,
|
|
263
|
-
destinationChainId,
|
|
264
|
-
chain,
|
|
265
|
-
testnet,
|
|
266
|
-
})
|
|
267
|
-
throw new Error("Invalid chain")
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
logger.console.log("[trails-sdk] originChain", originChain)
|
|
271
|
-
logger.console.log("[trails-sdk] destinationChain", destinationChain)
|
|
272
|
-
|
|
273
|
-
const originPublicClient = createPublicClient({
|
|
274
|
-
chain: originChain,
|
|
275
|
-
transport: http(),
|
|
276
|
-
})
|
|
277
|
-
|
|
278
|
-
let txHash: `0x${string}`
|
|
279
|
-
let waitForAttestation: () => Promise<Attestation>
|
|
280
|
-
|
|
281
|
-
if (hasCustomCalldata) {
|
|
282
|
-
const result = await cctpTransferWithCustomCall({
|
|
283
|
-
walletClient,
|
|
284
|
-
originChain,
|
|
285
|
-
destinationChain,
|
|
286
|
-
amount: BigInt(swapAmount),
|
|
287
|
-
})
|
|
288
|
-
|
|
289
|
-
txHash = result.txHash
|
|
290
|
-
waitForAttestation = result.waitForAttestation
|
|
291
|
-
} else {
|
|
292
|
-
const result = await cctpTransfer({
|
|
293
|
-
walletClient,
|
|
294
|
-
originChain,
|
|
295
|
-
destinationChain,
|
|
296
|
-
amount: BigInt(swapAmount),
|
|
297
|
-
})
|
|
298
|
-
|
|
299
|
-
txHash = result.txHash
|
|
300
|
-
waitForAttestation = result.waitForAttestation
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
if (onOriginSend) {
|
|
304
|
-
onOriginSend()
|
|
305
|
-
}
|
|
178
|
+
const salt = Date.now().toString()
|
|
306
179
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
const receipt = await originPublicClient.waitForTransactionReceipt({
|
|
310
|
-
hash: txHash,
|
|
311
|
-
})
|
|
312
|
-
|
|
313
|
-
logger.console.log("[trails-sdk] tx receipt", receipt)
|
|
314
|
-
|
|
315
|
-
transactionStates[0] = getTransactionStateFromReceipt(
|
|
316
|
-
receipt,
|
|
317
|
-
originChain.id,
|
|
318
|
-
transactionStates[0]?.label,
|
|
319
|
-
)
|
|
320
|
-
transactionStates[1] = getTransactionStateFromReceipt(
|
|
321
|
-
receipt,
|
|
322
|
-
originChain.id,
|
|
323
|
-
transactionStates[1]?.label,
|
|
324
|
-
)
|
|
325
|
-
|
|
326
|
-
onTransactionStateChange(transactionStates)
|
|
327
|
-
// Also trigger checkout status update if handler is provided
|
|
328
|
-
if (checkoutOnHandlers?.triggerCheckoutStatusUpdate) {
|
|
329
|
-
checkoutOnHandlers.triggerCheckoutStatusUpdate(transactionStates)
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
const attestation = await waitForAttestation()
|
|
333
|
-
|
|
334
|
-
if (!attestation) {
|
|
335
|
-
throw new Error("Failed to retrieve attestation")
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
const tokenMessenger = getMessageTransmitter(destinationChain.id)!
|
|
339
|
-
|
|
340
|
-
logger.console.log("[trails-sdk] tokenMessenger", tokenMessenger)
|
|
341
|
-
const calls: {
|
|
342
|
-
to: `0x${string}`
|
|
343
|
-
data: `0x${string}`
|
|
344
|
-
value: bigint
|
|
345
|
-
}[] = []
|
|
346
|
-
|
|
347
|
-
if (hasCustomCalldata) {
|
|
348
|
-
calls.push(
|
|
349
|
-
await getCCTPRelayerCallData({
|
|
350
|
-
attestation,
|
|
351
|
-
targetContract: recipient,
|
|
352
|
-
calldata: destinationCalldata as `0x${string}`,
|
|
353
|
-
gasLimit: 300000n,
|
|
354
|
-
destinationChain,
|
|
355
|
-
}),
|
|
356
|
-
)
|
|
357
|
-
} else {
|
|
358
|
-
calls.push(
|
|
359
|
-
await getMintUSDCData({
|
|
360
|
-
tokenMessenger,
|
|
361
|
-
attestation,
|
|
362
|
-
}),
|
|
363
|
-
)
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
logger.console.log("[trails-sdk] calls", calls)
|
|
367
|
-
const delegatorPrivateKey = generatePrivateKey()
|
|
368
|
-
const delegatorAccount = privateKeyToAccount(delegatorPrivateKey)
|
|
369
|
-
const delegatorClient = createWalletClient({
|
|
370
|
-
account: delegatorAccount,
|
|
371
|
-
chain: destinationChain,
|
|
372
|
-
transport: http(),
|
|
373
|
-
})
|
|
374
|
-
const destinationPublicClient = createPublicClient({
|
|
375
|
-
chain: destinationChain,
|
|
376
|
-
transport: http(),
|
|
377
|
-
})
|
|
378
|
-
logger.console.log("[trails-sdk] delegatorClient", delegatorClient)
|
|
379
|
-
|
|
380
|
-
const sequenceWalletAddress = await simpleCreateSequenceWallet(
|
|
381
|
-
delegatorAccount as any,
|
|
382
|
-
)
|
|
383
|
-
logger.console.log(
|
|
384
|
-
"[trails-sdk] sequenceWalletAddress",
|
|
385
|
-
sequenceWalletAddress,
|
|
386
|
-
)
|
|
387
|
-
const sequenceTxHash = await sequenceSendTransaction(
|
|
388
|
-
sequenceWalletAddress,
|
|
389
|
-
delegatorClient,
|
|
390
|
-
destinationPublicClient,
|
|
391
|
-
calls,
|
|
392
|
-
destinationChain,
|
|
393
|
-
)
|
|
394
|
-
|
|
395
|
-
const destinationReceipt =
|
|
396
|
-
await destinationPublicClient.waitForTransactionReceipt({
|
|
397
|
-
hash: sequenceTxHash as `0x${string}`,
|
|
398
|
-
})
|
|
399
|
-
|
|
400
|
-
logger.console.log(
|
|
401
|
-
"[trails-sdk] destinationReceipt",
|
|
402
|
-
destinationReceipt,
|
|
403
|
-
)
|
|
404
|
-
|
|
405
|
-
if (transactionStates[2]) {
|
|
406
|
-
transactionStates[2] = getTransactionStateFromReceipt(
|
|
407
|
-
destinationReceipt,
|
|
408
|
-
destinationChain.id,
|
|
409
|
-
transactionStates[2]?.label,
|
|
410
|
-
)
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
onTransactionStateChange(transactionStates)
|
|
414
|
-
// Also trigger checkout status update if handler is provided
|
|
415
|
-
if (checkoutOnHandlers?.triggerCheckoutStatusUpdate) {
|
|
416
|
-
checkoutOnHandlers.triggerCheckoutStatusUpdate(transactionStates)
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
return {
|
|
420
|
-
depositUserTxnReceipt: receipt,
|
|
421
|
-
originMetaTxnReceipt: null,
|
|
422
|
-
destinationMetaTxnReceipt: null,
|
|
423
|
-
totalCompletionSeconds: 0,
|
|
424
|
-
}
|
|
425
|
-
},
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
const destinationSalt = Date.now().toString()
|
|
430
|
-
|
|
431
|
-
const intentArgs = getIntentArgs(
|
|
180
|
+
const intentArgs = await getIntentArgs(
|
|
432
181
|
mainSignerAddress,
|
|
433
182
|
originChainId,
|
|
434
183
|
originTokenAddress,
|
|
@@ -438,13 +187,18 @@ export async function handleCrossChain({
|
|
|
438
187
|
tradeType === TradeType.EXACT_OUTPUT ? swapAmount : "0", // destinationTokenAmount
|
|
439
188
|
recipient,
|
|
440
189
|
destinationCalldata,
|
|
441
|
-
|
|
190
|
+
salt,
|
|
442
191
|
slippageTolerance,
|
|
443
192
|
tradeType,
|
|
444
193
|
quoteProvider,
|
|
194
|
+
undefined, // connector - not available in this context
|
|
195
|
+
walletId, // walletId - use this to check for Sequence wallets
|
|
445
196
|
)
|
|
446
197
|
|
|
447
|
-
logger.console.log(
|
|
198
|
+
logger.console.log(
|
|
199
|
+
"[trails-sdk] Creating intent for cross-chain with args:",
|
|
200
|
+
intentArgs,
|
|
201
|
+
)
|
|
448
202
|
|
|
449
203
|
const { intent, gasFeeOptions } = await quoteIntent(
|
|
450
204
|
trailsClient,
|
|
@@ -458,7 +212,7 @@ export async function handleCrossChain({
|
|
|
458
212
|
logger.console.log("[trails-sdk] Quote intent:", intent)
|
|
459
213
|
logger.console.log("[trails-sdk] Quote intent gasFeeOptions:", gasFeeOptions)
|
|
460
214
|
|
|
461
|
-
if (!intent.
|
|
215
|
+
if (!intent.originPrecondition || !intent.originCalls) {
|
|
462
216
|
throw new Error("Invalid intent")
|
|
463
217
|
}
|
|
464
218
|
|
|
@@ -468,17 +222,8 @@ export async function handleCrossChain({
|
|
|
468
222
|
originIntentAddress.toString(),
|
|
469
223
|
)
|
|
470
224
|
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
originChainId,
|
|
474
|
-
)
|
|
475
|
-
|
|
476
|
-
if (!firstPrecondition) {
|
|
477
|
-
throw new Error("No precondition found for origin chain")
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
const firstPreconditionMin = firstPrecondition?.minAmount?.toString()
|
|
481
|
-
const depositAmount = firstPreconditionMin
|
|
225
|
+
// Use depositTransaction amount - this is the actual amount to deposit
|
|
226
|
+
const depositAmount = intent.depositTransaction.amount?.toString()
|
|
482
227
|
|
|
483
228
|
const quoteToAmount = intent.quote.toAmount
|
|
484
229
|
const quoteToAmountMin = intent.quote.toAmountMin
|
|
@@ -543,7 +288,7 @@ export async function handleCrossChain({
|
|
|
543
288
|
const originCallParamsForEstimate = buildCrossChainDepositParams({
|
|
544
289
|
originTokenAddress,
|
|
545
290
|
originIntentAddress,
|
|
546
|
-
depositAmount
|
|
291
|
+
depositAmount,
|
|
547
292
|
fee,
|
|
548
293
|
originChainId,
|
|
549
294
|
chain,
|
|
@@ -614,8 +359,8 @@ export async function handleCrossChain({
|
|
|
614
359
|
// Gasless fee options are now returned in QuoteIntentResponse.gasFeeOptions
|
|
615
360
|
// and properly propagated from getIntent()
|
|
616
361
|
const effectiveGasless =
|
|
617
|
-
|
|
618
|
-
|
|
362
|
+
selectedFeeOption !== null &&
|
|
363
|
+
selectedFeeOption !== undefined &&
|
|
619
364
|
walletId !== "sequence-waas"
|
|
620
365
|
if (effectiveGasless) {
|
|
621
366
|
logger.console.log(
|
|
@@ -637,21 +382,19 @@ export async function handleCrossChain({
|
|
|
637
382
|
feeOptions: gasFeeOptions,
|
|
638
383
|
send: async ({
|
|
639
384
|
onOriginSend,
|
|
640
|
-
|
|
385
|
+
selectedFeeOption: runtimeSelectedFeeOption,
|
|
641
386
|
}: {
|
|
642
387
|
onOriginSend?: () => void
|
|
643
|
-
|
|
388
|
+
selectedFeeOption?: FeeOption | null
|
|
644
389
|
}): Promise<SendReturn> => {
|
|
645
390
|
try {
|
|
646
|
-
// Use runtime
|
|
647
|
-
const
|
|
648
|
-
runtimeSelectedFeeToken ?? selectedFeeToken
|
|
391
|
+
// Use runtime selectedFeeOption (passed at execution time, always up-to-date)
|
|
392
|
+
const effectiveSelectedFeeOption = runtimeSelectedFeeOption
|
|
649
393
|
logger.console.log(
|
|
650
394
|
"[trails-sdk] [FEE-SELECT] [GASLESS-FLOW] send() called with:",
|
|
651
395
|
{
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
effectiveSelectedFeeToken,
|
|
396
|
+
runtimeSelectedFeeOption,
|
|
397
|
+
effectiveSelectedFeeOption,
|
|
655
398
|
},
|
|
656
399
|
)
|
|
657
400
|
const commitIntentFnToUse =
|
|
@@ -677,20 +420,7 @@ export async function handleCrossChain({
|
|
|
677
420
|
}
|
|
678
421
|
|
|
679
422
|
logger.console.log("[trails-sdk] sending origin transaction")
|
|
680
|
-
const
|
|
681
|
-
let needsNativeFee = false
|
|
682
|
-
|
|
683
|
-
if (usingLIfi) {
|
|
684
|
-
needsNativeFee = getNeedsLifiNativeFee({
|
|
685
|
-
originTokenAddress,
|
|
686
|
-
destinationTokenAmount: swapAmount,
|
|
687
|
-
destinationTokenDecimals,
|
|
688
|
-
sourceTokenDecimals,
|
|
689
|
-
sourceTokenPriceUsd: sourceTokenPriceUsd ?? null,
|
|
690
|
-
destinationTokenPriceUsd: destinationTokenPriceUsd ?? null,
|
|
691
|
-
depositAmount,
|
|
692
|
-
})
|
|
693
|
-
}
|
|
423
|
+
const needsNativeFee = false
|
|
694
424
|
|
|
695
425
|
logger.console.log("[trails-sdk] needsNativeFee", needsNativeFee)
|
|
696
426
|
logger.console.log(
|
|
@@ -711,8 +441,8 @@ export async function handleCrossChain({
|
|
|
711
441
|
)
|
|
712
442
|
|
|
713
443
|
let depositUserTxnReceipt: TransactionReceipt | null = null
|
|
714
|
-
let
|
|
715
|
-
let
|
|
444
|
+
let originIntentTransaction: IntentTransaction | null = null
|
|
445
|
+
let destinationIntentTransaction: IntentTransaction | null = null
|
|
716
446
|
|
|
717
447
|
const testnet = isTestnetDebugMode()
|
|
718
448
|
const effectiveOriginChain = testnet
|
|
@@ -724,10 +454,11 @@ export async function handleCrossChain({
|
|
|
724
454
|
|
|
725
455
|
logger.console.log("[trails-sdk] testnet", testnet)
|
|
726
456
|
|
|
727
|
-
const
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
}
|
|
457
|
+
const destinationChainInfo = getChainInfo(destinationChainId)
|
|
458
|
+
if (!destinationChainInfo) {
|
|
459
|
+
throw new Error(`Chain ${destinationChainId} not found`)
|
|
460
|
+
}
|
|
461
|
+
const destinationPublicClient = getPublicRpcClient(destinationChainInfo)
|
|
731
462
|
|
|
732
463
|
const depositPromise = async () => {
|
|
733
464
|
logger.console.log(
|
|
@@ -751,14 +482,14 @@ export async function handleCrossChain({
|
|
|
751
482
|
paymasterUrl,
|
|
752
483
|
chain: effectiveOriginChain.id,
|
|
753
484
|
account: account.address,
|
|
754
|
-
|
|
485
|
+
depositAmount,
|
|
755
486
|
originIntentAddress,
|
|
756
487
|
fee,
|
|
757
488
|
dryMode,
|
|
758
489
|
feeOptions: gasFeeOptions,
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
490
|
+
selectedFeeOption: effectiveSelectedFeeOption,
|
|
491
|
+
selectedFeeOptionType: typeof effectiveSelectedFeeOption,
|
|
492
|
+
selectedFeeOptionValue: JsonEncode(effectiveSelectedFeeOption),
|
|
762
493
|
checkoutOnHandlers,
|
|
763
494
|
},
|
|
764
495
|
)
|
|
@@ -768,7 +499,7 @@ export async function handleCrossChain({
|
|
|
768
499
|
paymasterUrl,
|
|
769
500
|
chain: effectiveOriginChain,
|
|
770
501
|
account,
|
|
771
|
-
|
|
502
|
+
depositAmount,
|
|
772
503
|
originIntentAddress,
|
|
773
504
|
onOriginSend,
|
|
774
505
|
publicClient,
|
|
@@ -789,7 +520,7 @@ export async function handleCrossChain({
|
|
|
789
520
|
feeOptions: gasFeeOptions,
|
|
790
521
|
checkoutOnHandlers,
|
|
791
522
|
trailsClient,
|
|
792
|
-
|
|
523
|
+
selectedFeeOption: effectiveSelectedFeeOption,
|
|
793
524
|
walletId,
|
|
794
525
|
abortSignal,
|
|
795
526
|
intentId: intent.intentId,
|
|
@@ -930,10 +661,15 @@ export async function handleCrossChain({
|
|
|
930
661
|
}
|
|
931
662
|
|
|
932
663
|
try {
|
|
664
|
+
if (!sequenceIndexerUrl) {
|
|
665
|
+
throw new Error("sequenceIndexerUrl is required")
|
|
666
|
+
}
|
|
933
667
|
const response = await getAccountTransactionHistory({
|
|
934
668
|
chainId: originChainId,
|
|
935
669
|
accountAddress: originIntentAddress,
|
|
936
670
|
abortSignal,
|
|
671
|
+
apiKey: sequenceProjectAccessKey!,
|
|
672
|
+
indexerUrl: sequenceIndexerUrl,
|
|
937
673
|
})
|
|
938
674
|
logger.console.log(
|
|
939
675
|
"[trails-sdk] getAccountTransactionHistory response",
|
|
@@ -974,6 +710,52 @@ export async function handleCrossChain({
|
|
|
974
710
|
)
|
|
975
711
|
}
|
|
976
712
|
|
|
713
|
+
// Call executeIntent after detecting deposit transaction (for QR code mode)
|
|
714
|
+
// This triggers the backend to start executing the intent
|
|
715
|
+
// Must be called BEFORE waitIntentReceipt polling starts
|
|
716
|
+
if (
|
|
717
|
+
originDepositTxReceipt.status === "success" &&
|
|
718
|
+
intent.intentId &&
|
|
719
|
+
(fundMethod === "qr-code" || fundMethod === "exchange") &&
|
|
720
|
+
!executeIntentCalled
|
|
721
|
+
) {
|
|
722
|
+
logger.console.log(
|
|
723
|
+
"[trails-sdk] Calling executeIntent with detected deposit transaction hash (QR code mode)",
|
|
724
|
+
{
|
|
725
|
+
intentId: intent.intentId,
|
|
726
|
+
txHash: originDepositTxReceipt.transactionHash,
|
|
727
|
+
fundMethod,
|
|
728
|
+
},
|
|
729
|
+
)
|
|
730
|
+
try {
|
|
731
|
+
const executeIntentFnToUse =
|
|
732
|
+
executeIntentFn ||
|
|
733
|
+
trailsClient.executeIntent.bind(trailsClient)
|
|
734
|
+
await executeIntentFnToUse({
|
|
735
|
+
intentId: intent.intentId,
|
|
736
|
+
depositTransactionHash:
|
|
737
|
+
originDepositTxReceipt.transactionHash,
|
|
738
|
+
})
|
|
739
|
+
executeIntentCalled = true
|
|
740
|
+
logger.console.log(
|
|
741
|
+
"[trails-sdk] executeIntent completed successfully (QR code mode)",
|
|
742
|
+
)
|
|
743
|
+
|
|
744
|
+
// Now that executeIntent has been called, start unified polling if not already started
|
|
745
|
+
if (!unifiedPollerPromise) {
|
|
746
|
+
logger.console.log(
|
|
747
|
+
"[trails-sdk] Starting unified polling after executeIntent (QR code mode)",
|
|
748
|
+
)
|
|
749
|
+
startUnifiedPolling()
|
|
750
|
+
}
|
|
751
|
+
} catch (error) {
|
|
752
|
+
logger.console.error(
|
|
753
|
+
"[trails-sdk] Error calling executeIntent (QR code mode):",
|
|
754
|
+
error,
|
|
755
|
+
)
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
|
|
977
759
|
if (onOriginSend) {
|
|
978
760
|
onOriginSend()
|
|
979
761
|
}
|
|
@@ -1000,11 +782,16 @@ export async function handleCrossChain({
|
|
|
1000
782
|
}
|
|
1001
783
|
|
|
1002
784
|
try {
|
|
785
|
+
if (!sequenceIndexerUrl) {
|
|
786
|
+
throw new Error("sequenceIndexerUrl is required")
|
|
787
|
+
}
|
|
1003
788
|
const response = await getAccountTransactionHistory({
|
|
1004
789
|
chainId: destinationChainId,
|
|
1005
790
|
accountAddress:
|
|
1006
791
|
intent.destinationIntentAddress as `0x${string}`,
|
|
1007
792
|
abortSignal,
|
|
793
|
+
apiKey: sequenceProjectAccessKey!,
|
|
794
|
+
indexerUrl: sequenceIndexerUrl,
|
|
1008
795
|
})
|
|
1009
796
|
logger.console.log(
|
|
1010
797
|
"[trails-sdk] getAccountTransactionHistory response",
|
|
@@ -1070,6 +857,7 @@ export async function handleCrossChain({
|
|
|
1070
857
|
// Unified polling via shared poller instead of separate loops
|
|
1071
858
|
let unifiedPollerAbortController: AbortController | null = null
|
|
1072
859
|
let unifiedPollerPromise: Promise<IntentReceipt | null> | null = null
|
|
860
|
+
let executeIntentCalled = false // Track if executeIntent has been called (for QR code mode)
|
|
1073
861
|
|
|
1074
862
|
// Helper function to start unified polling for both origin and destination transactions
|
|
1075
863
|
const startUnifiedPolling = () => {
|
|
@@ -1208,7 +996,9 @@ export async function handleCrossChain({
|
|
|
1208
996
|
)
|
|
1209
997
|
|
|
1210
998
|
// Store the transaction hash
|
|
1211
|
-
|
|
999
|
+
originIntentTransaction = {
|
|
1000
|
+
txnHash: txHash,
|
|
1001
|
+
} as IntentTransaction
|
|
1212
1002
|
|
|
1213
1003
|
const originTxnReceipt =
|
|
1214
1004
|
await publicClient.getTransactionReceipt({
|
|
@@ -1307,9 +1097,9 @@ export async function handleCrossChain({
|
|
|
1307
1097
|
)
|
|
1308
1098
|
|
|
1309
1099
|
// Store the transaction hash
|
|
1310
|
-
|
|
1100
|
+
destinationIntentTransaction = {
|
|
1311
1101
|
txnHash: txHash,
|
|
1312
|
-
} as
|
|
1102
|
+
} as IntentTransaction
|
|
1313
1103
|
|
|
1314
1104
|
const destinationTxnReceipt =
|
|
1315
1105
|
await destinationPublicClient.getTransactionReceipt({
|
|
@@ -1424,15 +1214,17 @@ export async function handleCrossChain({
|
|
|
1424
1214
|
|
|
1425
1215
|
// First phase: Send meta transactions and queue CCTP
|
|
1426
1216
|
const originSendMetaTxnPromise = async () => {
|
|
1217
|
+
const originMeta = intent.originMetaTxn
|
|
1218
|
+
const originPre = intent.originPrecondition
|
|
1427
1219
|
logger.console.log("[trails-sdk] Starting originSendMetaTxnPromise", {
|
|
1428
|
-
hasMetaTxn: !!
|
|
1429
|
-
hasPrecondition: !!
|
|
1430
|
-
metaTxnId:
|
|
1431
|
-
chainId:
|
|
1220
|
+
hasMetaTxn: !!originMeta,
|
|
1221
|
+
hasPrecondition: !!originPre,
|
|
1222
|
+
metaTxnId: originMeta?.id,
|
|
1223
|
+
chainId: originMeta?.chainId,
|
|
1432
1224
|
})
|
|
1433
1225
|
|
|
1434
|
-
if (
|
|
1435
|
-
const metaTxnId =
|
|
1226
|
+
if (originMeta && originPre) {
|
|
1227
|
+
const metaTxnId = originMeta.id
|
|
1436
1228
|
const feeQuote = undefined
|
|
1437
1229
|
logger.console.log("[trails-sdk] Processing origin meta txn", {
|
|
1438
1230
|
metaTxnId,
|
|
@@ -1444,9 +1236,9 @@ export async function handleCrossChain({
|
|
|
1444
1236
|
"[trails-sdk] NOTE: Client-side meta transaction submission deprecated",
|
|
1445
1237
|
{
|
|
1446
1238
|
metaTxnId,
|
|
1447
|
-
chainId:
|
|
1448
|
-
walletAddress:
|
|
1449
|
-
contract:
|
|
1239
|
+
chainId: originMeta.chainId,
|
|
1240
|
+
walletAddress: originMeta.walletAddress,
|
|
1241
|
+
contract: originMeta.contract,
|
|
1450
1242
|
message:
|
|
1451
1243
|
"Transaction submission now handled by backend via executeIntent. Monitoring via WaitIntentReceipt API.",
|
|
1452
1244
|
},
|
|
@@ -1464,21 +1256,23 @@ export async function handleCrossChain({
|
|
|
1464
1256
|
logger.console.warn(
|
|
1465
1257
|
"[trails-sdk] Skipping origin sendMetaTxn - missing metaTxn or precondition",
|
|
1466
1258
|
{
|
|
1467
|
-
hasMetaTxn: !!intent.
|
|
1468
|
-
hasPrecondition: !!intent.
|
|
1259
|
+
hasMetaTxn: !!intent.originMetaTxn,
|
|
1260
|
+
hasPrecondition: !!intent.originPrecondition,
|
|
1469
1261
|
},
|
|
1470
1262
|
)
|
|
1471
1263
|
}
|
|
1472
1264
|
}
|
|
1473
1265
|
|
|
1474
1266
|
const destinationSendMetaTxnPromise = async () => {
|
|
1267
|
+
const destinationPre = intent.destinationPrecondition
|
|
1268
|
+
const destinationMeta = intent.destinationMetaTxn
|
|
1475
1269
|
logger.console.log(
|
|
1476
1270
|
"[trails-sdk] Starting destinationSendMetaTxnPromise",
|
|
1477
1271
|
{
|
|
1478
1272
|
quoteProvider: intent.quote.quoteProvider,
|
|
1479
1273
|
hasQuoteProviderRequestId: !!intent.quote.quoteProviderRequestId,
|
|
1480
|
-
hasPrecondition1: !!
|
|
1481
|
-
hasMetaTxn1: !!
|
|
1274
|
+
hasPrecondition1: !!destinationPre,
|
|
1275
|
+
hasMetaTxn1: !!destinationMeta,
|
|
1482
1276
|
},
|
|
1483
1277
|
)
|
|
1484
1278
|
|
|
@@ -1489,41 +1283,6 @@ export async function handleCrossChain({
|
|
|
1489
1283
|
)
|
|
1490
1284
|
}
|
|
1491
1285
|
|
|
1492
|
-
let queueCctpPromise: (() => Promise<void>) | null = null
|
|
1493
|
-
|
|
1494
|
-
const isCctp = intent.quote.quoteProvider === "cctp"
|
|
1495
|
-
if (isCctp) {
|
|
1496
|
-
queueCctpPromise = async () => {
|
|
1497
|
-
while (true) {
|
|
1498
|
-
// Check if we should abort
|
|
1499
|
-
if (abortSignal?.aborted) {
|
|
1500
|
-
logger.console.log(
|
|
1501
|
-
"[trails-sdk] Aborting CCTP queue due to abort signal",
|
|
1502
|
-
)
|
|
1503
|
-
return
|
|
1504
|
-
}
|
|
1505
|
-
|
|
1506
|
-
const originMetaTxnHash = (
|
|
1507
|
-
originMetaTxnReceipt as MetaTxnReceipt | null
|
|
1508
|
-
)?.txnHash
|
|
1509
|
-
if (originMetaTxnHash) {
|
|
1510
|
-
await queueCCTPTransfer({
|
|
1511
|
-
trailsClient,
|
|
1512
|
-
sourceTxHash: originMetaTxnHash,
|
|
1513
|
-
sourceChainId: originChainId,
|
|
1514
|
-
destinationChainId: destinationChainId,
|
|
1515
|
-
})
|
|
1516
|
-
break
|
|
1517
|
-
}
|
|
1518
|
-
await new Promise((resolve) =>
|
|
1519
|
-
setTimeout(resolve, POLLING_INTERVALS.CCTP_QUEUE),
|
|
1520
|
-
)
|
|
1521
|
-
}
|
|
1522
|
-
}
|
|
1523
|
-
} else {
|
|
1524
|
-
queueCctpPromise = () => Promise.resolve()
|
|
1525
|
-
}
|
|
1526
|
-
|
|
1527
1286
|
// Only start polling for external deposits if needed:
|
|
1528
1287
|
// - QR code or exchange funding (external deposits)
|
|
1529
1288
|
// - Gasless flow (relayer-executed deposits)
|
|
@@ -1565,12 +1324,43 @@ export async function handleCrossChain({
|
|
|
1565
1324
|
"[trails-sdk] Starting Phase 2: Waiting for receipts and executing deposit",
|
|
1566
1325
|
)
|
|
1567
1326
|
|
|
1327
|
+
// Helper function to wait for unifiedPollerPromise to be created (for QR code mode)
|
|
1328
|
+
const waitForUnifiedPollerToStart = async () => {
|
|
1329
|
+
if (fundMethod !== "qr-code" && fundMethod !== "exchange") {
|
|
1330
|
+
return // No need to wait for non-QR code modes
|
|
1331
|
+
}
|
|
1332
|
+
|
|
1333
|
+
const maxWaitTime = 5 * 60 * 1000 // 5 minutes max wait
|
|
1334
|
+
const startTime = Date.now()
|
|
1335
|
+
// Wait for unifiedPollerPromise to be created (after executeIntent is called)
|
|
1336
|
+
while (!unifiedPollerPromise) {
|
|
1337
|
+
if (Date.now() - startTime > maxWaitTime) {
|
|
1338
|
+
logger.console.error(
|
|
1339
|
+
"[trails-sdk] Timeout waiting for unified poller to start (QR code mode)",
|
|
1340
|
+
)
|
|
1341
|
+
throw new Error(
|
|
1342
|
+
"Timeout waiting for deposit detection and executeIntent in QR code mode",
|
|
1343
|
+
)
|
|
1344
|
+
}
|
|
1345
|
+
await new Promise((resolve) => setTimeout(resolve, 100))
|
|
1346
|
+
// Check abort signal
|
|
1347
|
+
if (abortSignal?.aborted) {
|
|
1348
|
+
logger.console.log(
|
|
1349
|
+
"[trails-sdk] Aborting wait for unified poller due to abort signal",
|
|
1350
|
+
)
|
|
1351
|
+
return
|
|
1352
|
+
}
|
|
1353
|
+
}
|
|
1354
|
+
}
|
|
1355
|
+
|
|
1568
1356
|
const waitForOriginMetaTxnReceiptPromise = async () => {
|
|
1569
1357
|
logger.console.log(
|
|
1570
1358
|
"[trails-sdk] Waiting for origin meta transaction receipt via unified poller",
|
|
1571
1359
|
)
|
|
1572
1360
|
// The unified poller handles origin transaction discovery and decoding via callbacks
|
|
1573
|
-
//
|
|
1361
|
+
// For QR code mode, wait for unifiedPollerPromise to be created first (after executeIntent is called)
|
|
1362
|
+
await waitForUnifiedPollerToStart()
|
|
1363
|
+
|
|
1574
1364
|
if (unifiedPollerPromise) {
|
|
1575
1365
|
try {
|
|
1576
1366
|
await unifiedPollerPromise
|
|
@@ -1588,7 +1378,9 @@ export async function handleCrossChain({
|
|
|
1588
1378
|
"[trails-sdk] Waiting for destination meta transaction receipt via unified poller",
|
|
1589
1379
|
)
|
|
1590
1380
|
// The unified poller handles destination transaction discovery and decoding via callbacks
|
|
1591
|
-
//
|
|
1381
|
+
// For QR code mode, wait for unifiedPollerPromise to be created first (after executeIntent is called)
|
|
1382
|
+
await waitForUnifiedPollerToStart()
|
|
1383
|
+
|
|
1592
1384
|
if (unifiedPollerPromise) {
|
|
1593
1385
|
try {
|
|
1594
1386
|
await unifiedPollerPromise
|
|
@@ -1614,10 +1406,17 @@ export async function handleCrossChain({
|
|
|
1614
1406
|
|
|
1615
1407
|
// Start unified polling after deposit transaction is submitted and executeIntent is called
|
|
1616
1408
|
// This ensures the backend has received the executeIntent call before we start polling waitIntentReceipt
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1409
|
+
// For QR code mode, unified polling will be started after executeIntent is called in checkForDepositTx
|
|
1410
|
+
if (fundMethod !== "qr-code" && fundMethod !== "exchange") {
|
|
1411
|
+
logger.console.log(
|
|
1412
|
+
"[trails-sdk] Starting unified polling after executeIntent has been called",
|
|
1413
|
+
)
|
|
1414
|
+
startUnifiedPolling()
|
|
1415
|
+
} else {
|
|
1416
|
+
logger.console.log(
|
|
1417
|
+
"[trails-sdk] Delaying unified polling for QR code mode - will start after executeIntent is called",
|
|
1418
|
+
)
|
|
1419
|
+
}
|
|
1621
1420
|
|
|
1622
1421
|
// Now wait for all the receipts and CCTP processing
|
|
1623
1422
|
logger.console.log(
|
|
@@ -1626,7 +1425,6 @@ export async function handleCrossChain({
|
|
|
1626
1425
|
await Promise.all([
|
|
1627
1426
|
waitForOriginMetaTxnReceiptPromise(),
|
|
1628
1427
|
waitForDestinationMetaTxnReceiptPromise(),
|
|
1629
|
-
queueCctpPromise(),
|
|
1630
1428
|
])
|
|
1631
1429
|
logger.console.log("[trails-sdk] Phase 2 completed successfully")
|
|
1632
1430
|
|
|
@@ -1639,10 +1437,10 @@ export async function handleCrossChain({
|
|
|
1639
1437
|
const hasRequiredReceipts =
|
|
1640
1438
|
(depositUserTxnReceipt || effectiveGasless) &&
|
|
1641
1439
|
(isDestinationCrossChain
|
|
1642
|
-
?
|
|
1440
|
+
? destinationIntentTransaction
|
|
1643
1441
|
: isSameChain
|
|
1644
|
-
?
|
|
1645
|
-
:
|
|
1442
|
+
? originIntentTransaction
|
|
1443
|
+
: destinationIntentTransaction)
|
|
1646
1444
|
|
|
1647
1445
|
if (hasRequiredReceipts) {
|
|
1648
1446
|
// Check if any transaction failed or was refunded
|
|
@@ -1663,7 +1461,7 @@ export async function handleCrossChain({
|
|
|
1663
1461
|
? (depositUserTxnReceipt as TransactionReceipt).transactionHash
|
|
1664
1462
|
: undefined,
|
|
1665
1463
|
destinationTxHash: (
|
|
1666
|
-
|
|
1464
|
+
destinationIntentTransaction as unknown as IntentTransaction
|
|
1667
1465
|
)?.txnHash,
|
|
1668
1466
|
originChainId,
|
|
1669
1467
|
destinationChainId,
|
|
@@ -1737,8 +1535,8 @@ export async function handleCrossChain({
|
|
|
1737
1535
|
|
|
1738
1536
|
return {
|
|
1739
1537
|
depositUserTxnReceipt,
|
|
1740
|
-
|
|
1741
|
-
|
|
1538
|
+
originIntentTransaction,
|
|
1539
|
+
destinationIntentTransaction,
|
|
1742
1540
|
totalCompletionSeconds: await getTxTimeDiff(
|
|
1743
1541
|
transactionStates[0],
|
|
1744
1542
|
transactionStates[2],
|