0xtrails 0.5.0 → 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-DhEkQ6QC.js → ccip-Dw5AN7oU.js} +1 -1
- package/dist/cctp.d.ts +0 -149
- package/dist/cctp.d.ts.map +1 -1
- package/dist/chains.d.ts +28 -3
- package/dist/chains.d.ts.map +1 -1
- package/dist/config.d.ts +11 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/constants.d.ts +1 -1
- 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-MhD2DA7_.js → index-BtVUTbEZ.js} +30984 -38945
- package/dist/index.d.ts +7 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +108 -107
- package/dist/indexerClient.d.ts +2 -2
- package/dist/intents.d.ts +0 -17
- 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/tokenBalances.d.ts.map +1 -1
- package/dist/tokens.d.ts +10 -8
- package/dist/tokens.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 +4 -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 +6 -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 +2 -20
- 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/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/Toast.d.ts.map +1 -1
- package/dist/widget/components/TokenImage.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 +5 -8
- 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.js +1 -1
- package/dist/widget/providers/TrailsProvider.d.ts +23 -12
- package/dist/widget/providers/TrailsProvider.d.ts.map +1 -1
- package/dist/widget/widget.d.ts +11 -0
- package/dist/widget/widget.d.ts.map +1 -1
- package/package.json +8 -8
- package/src/analytics.ts +53 -21
- package/src/cctp.ts +0 -1016
- package/src/chains.ts +93 -39
- package/src/config.ts +24 -6
- package/src/constants.ts +1 -4
- 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 +7 -6
- package/src/indexerClient.ts +2 -2
- package/src/intents.ts +52 -206
- package/src/mutations.ts +3 -2
- package/src/paymasterSend.ts +2 -5
- package/src/prepareSend.ts +9 -12
- package/src/sendUserOp.ts +3 -64
- package/src/tokenBalances.ts +2 -1
- package/src/tokens.ts +62 -133
- package/src/trailsClient.ts +1 -1
- 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 +165 -385
- 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 +6 -27
- package/src/transactionIntent/utils/index.ts +0 -1
- package/src/transactions.ts +6 -203
- package/src/umd.tsx +1 -3
- package/src/utils.ts +28 -8
- package/src/walletUtils.ts +42 -0
- package/src/wallets.ts +361 -203
- package/src/widget/compiled.css +1 -1
- package/src/widget/components/AccountIntentTransactionHistory.tsx +73 -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 +1 -1
- 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/Toast.tsx +10 -0
- package/src/widget/components/TokenImage.tsx +56 -13
- 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 +788 -418
- package/src/widget/hooks/useIsConnectedWalletSmartContract.ts +43 -0
- package/src/widget/hooks/useIsSequenceWallet.ts +17 -0
- package/src/widget/hooks/useQuote.ts +16 -17
- package/src/widget/hooks/useRecentTokens.ts +2 -1
- package/src/widget/hooks/useSelectedFeeOption.tsx +257 -0
- package/src/widget/hooks/useSendForm.ts +172 -47
- package/src/widget/hooks/useTokenList.ts +15 -2
- package/src/widget/providers/TrailsProvider.tsx +53 -25
- package/src/widget/widget.tsx +119 -48
- 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/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 -69
- package/src/preconditions.ts +0 -47
- 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,7 +123,7 @@ 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,
|
|
@@ -180,7 +163,7 @@ export async function handleCrossChain({
|
|
|
180
163
|
fundMethod?: string
|
|
181
164
|
mode?: "pay" | "fund" | "earn" | "swap" | "receive"
|
|
182
165
|
checkoutOnHandlers?: Partial<CheckoutOnHandlers>
|
|
183
|
-
|
|
166
|
+
selectedFeeOption?: FeeOption | null
|
|
184
167
|
walletId?: string
|
|
185
168
|
abortSignal?: AbortSignal
|
|
186
169
|
commitIntentFn?: (intent: Intent) => Promise<CommitIntentResponse>
|
|
@@ -192,251 +175,9 @@ export async function handleCrossChain({
|
|
|
192
175
|
sequenceProjectAccessKey?: string
|
|
193
176
|
sequenceIndexerUrl?: string
|
|
194
177
|
}): Promise<PrepareSendReturn> {
|
|
195
|
-
const
|
|
196
|
-
const useCctp = shouldUseCctp(
|
|
197
|
-
originTokenAddress,
|
|
198
|
-
destinationTokenAddress,
|
|
199
|
-
originChainId,
|
|
200
|
-
destinationChainId,
|
|
201
|
-
)
|
|
202
|
-
|
|
203
|
-
const cctpFlag = getQueryParam("cctp") === "true"
|
|
204
|
-
const hasCustomCalldata = getIsCustomCalldata(destinationCalldata)
|
|
205
|
-
|
|
206
|
-
// Validate CCTP destination token requirement for explicit CCTP usage
|
|
207
|
-
if (useCctp && cctpFlag) {
|
|
208
|
-
validateCctpDestinationToken(
|
|
209
|
-
destinationTokenAddress,
|
|
210
|
-
destinationChainId,
|
|
211
|
-
"cctp",
|
|
212
|
-
)
|
|
213
|
-
logger.console.log("[trails-sdk] using cctp")
|
|
214
|
-
|
|
215
|
-
const quote = await getNormalizedQuoteObject({
|
|
216
|
-
destinationAddress: recipient,
|
|
217
|
-
destinationCalldata,
|
|
218
|
-
originAmount: swapAmount,
|
|
219
|
-
originTokenPriceUsd: sourceTokenPriceUsd?.toString() || null,
|
|
220
|
-
destinationAmount: swapAmount,
|
|
221
|
-
destinationTokenPriceUsd: destinationTokenPriceUsd?.toString() || null,
|
|
222
|
-
originTokenAddress: originTokenAddress,
|
|
223
|
-
destinationTokenAddress: destinationTokenAddress,
|
|
224
|
-
originChainId,
|
|
225
|
-
destinationChainId,
|
|
226
|
-
transactionStates,
|
|
227
|
-
originNativeTokenPriceUsd,
|
|
228
|
-
slippageTolerance,
|
|
229
|
-
quoteProvider: "cctp",
|
|
230
|
-
})
|
|
231
|
-
|
|
232
|
-
// Call onCheckoutQuote callback if provided
|
|
233
|
-
if (checkoutOnHandlers?.triggerCheckoutQuote) {
|
|
234
|
-
checkoutOnHandlers.triggerCheckoutQuote(quote)
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
return {
|
|
238
|
-
quote,
|
|
239
|
-
send: async ({
|
|
240
|
-
onOriginSend,
|
|
241
|
-
selectedFeeToken: runtimeSelectedFeeToken,
|
|
242
|
-
}: {
|
|
243
|
-
onOriginSend?: () => void
|
|
244
|
-
selectedFeeToken?: SelectedFeeToken
|
|
245
|
-
}): Promise<SendReturn> => {
|
|
246
|
-
// Use runtime selectedFeeToken if provided, otherwise fall back to the one from prepareSend
|
|
247
|
-
const effectiveSelectedFeeToken =
|
|
248
|
-
runtimeSelectedFeeToken ?? selectedFeeToken
|
|
249
|
-
logger.console.log(
|
|
250
|
-
"[trails-sdk] [FEE-SELECT] [GASLESS-FLOW] send() called (LEGACY PATH):",
|
|
251
|
-
{
|
|
252
|
-
runtimeSelectedFeeToken,
|
|
253
|
-
prepareTimeSelectedFeeToken: selectedFeeToken,
|
|
254
|
-
effectiveSelectedFeeToken,
|
|
255
|
-
},
|
|
256
|
-
)
|
|
257
|
-
const originChain = testnet ? getTestnetChainInfo(chain)! : chain
|
|
258
|
-
const destinationChain = testnet
|
|
259
|
-
? getTestnetChainInfo(destinationChainId)!
|
|
260
|
-
: getChainInfo(destinationChainId)
|
|
261
|
-
|
|
262
|
-
if (!originChain || !destinationChain) {
|
|
263
|
-
logger.console.error("[trails-sdk] Invalid chain", {
|
|
264
|
-
originChain,
|
|
265
|
-
destinationChain,
|
|
266
|
-
originChainId,
|
|
267
|
-
destinationChainId,
|
|
268
|
-
chain,
|
|
269
|
-
testnet,
|
|
270
|
-
})
|
|
271
|
-
throw new Error("Invalid chain")
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
logger.console.log("[trails-sdk] originChain", originChain)
|
|
275
|
-
logger.console.log("[trails-sdk] destinationChain", destinationChain)
|
|
276
|
-
|
|
277
|
-
const originPublicClient = createPublicClient({
|
|
278
|
-
chain: originChain,
|
|
279
|
-
transport: http(),
|
|
280
|
-
})
|
|
281
|
-
|
|
282
|
-
let txHash: `0x${string}`
|
|
283
|
-
let waitForAttestation: () => Promise<Attestation>
|
|
284
|
-
|
|
285
|
-
if (hasCustomCalldata) {
|
|
286
|
-
const result = await cctpTransferWithCustomCall({
|
|
287
|
-
walletClient,
|
|
288
|
-
originChain,
|
|
289
|
-
destinationChain,
|
|
290
|
-
amount: BigInt(swapAmount),
|
|
291
|
-
})
|
|
292
|
-
|
|
293
|
-
txHash = result.txHash
|
|
294
|
-
waitForAttestation = result.waitForAttestation
|
|
295
|
-
} else {
|
|
296
|
-
const result = await cctpTransfer({
|
|
297
|
-
walletClient,
|
|
298
|
-
originChain,
|
|
299
|
-
destinationChain,
|
|
300
|
-
amount: BigInt(swapAmount),
|
|
301
|
-
})
|
|
302
|
-
|
|
303
|
-
txHash = result.txHash
|
|
304
|
-
waitForAttestation = result.waitForAttestation
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
if (onOriginSend) {
|
|
308
|
-
onOriginSend()
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
logger.console.log("[trails-sdk] waiting for tx", txHash)
|
|
312
|
-
|
|
313
|
-
const receipt = await originPublicClient.waitForTransactionReceipt({
|
|
314
|
-
hash: txHash,
|
|
315
|
-
})
|
|
316
|
-
|
|
317
|
-
logger.console.log("[trails-sdk] tx receipt", receipt)
|
|
318
|
-
|
|
319
|
-
transactionStates[0] = getTransactionStateFromReceipt(
|
|
320
|
-
receipt,
|
|
321
|
-
originChain.id,
|
|
322
|
-
transactionStates[0]?.label,
|
|
323
|
-
)
|
|
324
|
-
transactionStates[1] = getTransactionStateFromReceipt(
|
|
325
|
-
receipt,
|
|
326
|
-
originChain.id,
|
|
327
|
-
transactionStates[1]?.label,
|
|
328
|
-
)
|
|
329
|
-
|
|
330
|
-
onTransactionStateChange(transactionStates)
|
|
331
|
-
// Also trigger checkout status update if handler is provided
|
|
332
|
-
if (checkoutOnHandlers?.triggerCheckoutStatusUpdate) {
|
|
333
|
-
checkoutOnHandlers.triggerCheckoutStatusUpdate(transactionStates)
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
const attestation = await waitForAttestation()
|
|
337
|
-
|
|
338
|
-
if (!attestation) {
|
|
339
|
-
throw new Error("Failed to retrieve attestation")
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
const tokenMessenger = getMessageTransmitter(destinationChain.id)!
|
|
343
|
-
|
|
344
|
-
logger.console.log("[trails-sdk] tokenMessenger", tokenMessenger)
|
|
345
|
-
const calls: {
|
|
346
|
-
to: `0x${string}`
|
|
347
|
-
data: `0x${string}`
|
|
348
|
-
value: bigint
|
|
349
|
-
}[] = []
|
|
350
|
-
|
|
351
|
-
if (hasCustomCalldata) {
|
|
352
|
-
calls.push(
|
|
353
|
-
await getCCTPRelayerCallData({
|
|
354
|
-
attestation,
|
|
355
|
-
targetContract: recipient,
|
|
356
|
-
calldata: destinationCalldata as `0x${string}`,
|
|
357
|
-
gasLimit: 300000n,
|
|
358
|
-
destinationChain,
|
|
359
|
-
}),
|
|
360
|
-
)
|
|
361
|
-
} else {
|
|
362
|
-
calls.push(
|
|
363
|
-
await getMintUSDCData({
|
|
364
|
-
tokenMessenger,
|
|
365
|
-
attestation,
|
|
366
|
-
}),
|
|
367
|
-
)
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
logger.console.log("[trails-sdk] calls", calls)
|
|
371
|
-
const delegatorPrivateKey = generatePrivateKey()
|
|
372
|
-
const delegatorAccount = privateKeyToAccount(delegatorPrivateKey)
|
|
373
|
-
const delegatorClient = createWalletClient({
|
|
374
|
-
account: delegatorAccount,
|
|
375
|
-
chain: destinationChain,
|
|
376
|
-
transport: http(),
|
|
377
|
-
})
|
|
378
|
-
const destinationPublicClient = createPublicClient({
|
|
379
|
-
chain: destinationChain,
|
|
380
|
-
transport: http(),
|
|
381
|
-
})
|
|
382
|
-
logger.console.log("[trails-sdk] delegatorClient", delegatorClient)
|
|
383
|
-
|
|
384
|
-
const sequenceWalletAddress = await simpleCreateSequenceWallet(
|
|
385
|
-
delegatorAccount as any,
|
|
386
|
-
)
|
|
387
|
-
logger.console.log(
|
|
388
|
-
"[trails-sdk] sequenceWalletAddress",
|
|
389
|
-
sequenceWalletAddress,
|
|
390
|
-
)
|
|
391
|
-
if (!sequenceProjectAccessKey) {
|
|
392
|
-
throw new Error("Trails api key is required")
|
|
393
|
-
}
|
|
394
|
-
const sequenceTxHash = await sequenceSendTransaction(
|
|
395
|
-
sequenceWalletAddress,
|
|
396
|
-
delegatorClient,
|
|
397
|
-
destinationPublicClient,
|
|
398
|
-
calls,
|
|
399
|
-
destinationChain,
|
|
400
|
-
sequenceProjectAccessKey,
|
|
401
|
-
)
|
|
402
|
-
|
|
403
|
-
const destinationReceipt =
|
|
404
|
-
await destinationPublicClient.waitForTransactionReceipt({
|
|
405
|
-
hash: sequenceTxHash as `0x${string}`,
|
|
406
|
-
})
|
|
407
|
-
|
|
408
|
-
logger.console.log(
|
|
409
|
-
"[trails-sdk] destinationReceipt",
|
|
410
|
-
destinationReceipt,
|
|
411
|
-
)
|
|
412
|
-
|
|
413
|
-
if (transactionStates[2]) {
|
|
414
|
-
transactionStates[2] = getTransactionStateFromReceipt(
|
|
415
|
-
destinationReceipt,
|
|
416
|
-
destinationChain.id,
|
|
417
|
-
transactionStates[2]?.label,
|
|
418
|
-
)
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
onTransactionStateChange(transactionStates)
|
|
422
|
-
// Also trigger checkout status update if handler is provided
|
|
423
|
-
if (checkoutOnHandlers?.triggerCheckoutStatusUpdate) {
|
|
424
|
-
checkoutOnHandlers.triggerCheckoutStatusUpdate(transactionStates)
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
return {
|
|
428
|
-
depositUserTxnReceipt: receipt,
|
|
429
|
-
originMetaTxnReceipt: null,
|
|
430
|
-
destinationMetaTxnReceipt: null,
|
|
431
|
-
totalCompletionSeconds: 0,
|
|
432
|
-
}
|
|
433
|
-
},
|
|
434
|
-
}
|
|
435
|
-
}
|
|
178
|
+
const salt = Date.now().toString()
|
|
436
179
|
|
|
437
|
-
const
|
|
438
|
-
|
|
439
|
-
const intentArgs = getIntentArgs(
|
|
180
|
+
const intentArgs = await getIntentArgs(
|
|
440
181
|
mainSignerAddress,
|
|
441
182
|
originChainId,
|
|
442
183
|
originTokenAddress,
|
|
@@ -446,13 +187,18 @@ export async function handleCrossChain({
|
|
|
446
187
|
tradeType === TradeType.EXACT_OUTPUT ? swapAmount : "0", // destinationTokenAmount
|
|
447
188
|
recipient,
|
|
448
189
|
destinationCalldata,
|
|
449
|
-
|
|
190
|
+
salt,
|
|
450
191
|
slippageTolerance,
|
|
451
192
|
tradeType,
|
|
452
193
|
quoteProvider,
|
|
194
|
+
undefined, // connector - not available in this context
|
|
195
|
+
walletId, // walletId - use this to check for Sequence wallets
|
|
453
196
|
)
|
|
454
197
|
|
|
455
|
-
logger.console.log(
|
|
198
|
+
logger.console.log(
|
|
199
|
+
"[trails-sdk] Creating intent for cross-chain with args:",
|
|
200
|
+
intentArgs,
|
|
201
|
+
)
|
|
456
202
|
|
|
457
203
|
const { intent, gasFeeOptions } = await quoteIntent(
|
|
458
204
|
trailsClient,
|
|
@@ -466,7 +212,7 @@ export async function handleCrossChain({
|
|
|
466
212
|
logger.console.log("[trails-sdk] Quote intent:", intent)
|
|
467
213
|
logger.console.log("[trails-sdk] Quote intent gasFeeOptions:", gasFeeOptions)
|
|
468
214
|
|
|
469
|
-
if (!intent.
|
|
215
|
+
if (!intent.originPrecondition || !intent.originCalls) {
|
|
470
216
|
throw new Error("Invalid intent")
|
|
471
217
|
}
|
|
472
218
|
|
|
@@ -476,17 +222,8 @@ export async function handleCrossChain({
|
|
|
476
222
|
originIntentAddress.toString(),
|
|
477
223
|
)
|
|
478
224
|
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
originChainId,
|
|
482
|
-
)
|
|
483
|
-
|
|
484
|
-
if (!firstPrecondition) {
|
|
485
|
-
throw new Error("No precondition found for origin chain")
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
const firstPreconditionMin = firstPrecondition?.minAmount?.toString()
|
|
489
|
-
const depositAmount = firstPreconditionMin
|
|
225
|
+
// Use depositTransaction amount - this is the actual amount to deposit
|
|
226
|
+
const depositAmount = intent.depositTransaction.amount?.toString()
|
|
490
227
|
|
|
491
228
|
const quoteToAmount = intent.quote.toAmount
|
|
492
229
|
const quoteToAmountMin = intent.quote.toAmountMin
|
|
@@ -551,7 +288,7 @@ export async function handleCrossChain({
|
|
|
551
288
|
const originCallParamsForEstimate = buildCrossChainDepositParams({
|
|
552
289
|
originTokenAddress,
|
|
553
290
|
originIntentAddress,
|
|
554
|
-
depositAmount
|
|
291
|
+
depositAmount,
|
|
555
292
|
fee,
|
|
556
293
|
originChainId,
|
|
557
294
|
chain,
|
|
@@ -622,8 +359,8 @@ export async function handleCrossChain({
|
|
|
622
359
|
// Gasless fee options are now returned in QuoteIntentResponse.gasFeeOptions
|
|
623
360
|
// and properly propagated from getIntent()
|
|
624
361
|
const effectiveGasless =
|
|
625
|
-
|
|
626
|
-
|
|
362
|
+
selectedFeeOption !== null &&
|
|
363
|
+
selectedFeeOption !== undefined &&
|
|
627
364
|
walletId !== "sequence-waas"
|
|
628
365
|
if (effectiveGasless) {
|
|
629
366
|
logger.console.log(
|
|
@@ -645,21 +382,19 @@ export async function handleCrossChain({
|
|
|
645
382
|
feeOptions: gasFeeOptions,
|
|
646
383
|
send: async ({
|
|
647
384
|
onOriginSend,
|
|
648
|
-
|
|
385
|
+
selectedFeeOption: runtimeSelectedFeeOption,
|
|
649
386
|
}: {
|
|
650
387
|
onOriginSend?: () => void
|
|
651
|
-
|
|
388
|
+
selectedFeeOption?: FeeOption | null
|
|
652
389
|
}): Promise<SendReturn> => {
|
|
653
390
|
try {
|
|
654
|
-
// Use runtime
|
|
655
|
-
const
|
|
656
|
-
runtimeSelectedFeeToken ?? selectedFeeToken
|
|
391
|
+
// Use runtime selectedFeeOption (passed at execution time, always up-to-date)
|
|
392
|
+
const effectiveSelectedFeeOption = runtimeSelectedFeeOption
|
|
657
393
|
logger.console.log(
|
|
658
394
|
"[trails-sdk] [FEE-SELECT] [GASLESS-FLOW] send() called with:",
|
|
659
395
|
{
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
effectiveSelectedFeeToken,
|
|
396
|
+
runtimeSelectedFeeOption,
|
|
397
|
+
effectiveSelectedFeeOption,
|
|
663
398
|
},
|
|
664
399
|
)
|
|
665
400
|
const commitIntentFnToUse =
|
|
@@ -685,20 +420,7 @@ export async function handleCrossChain({
|
|
|
685
420
|
}
|
|
686
421
|
|
|
687
422
|
logger.console.log("[trails-sdk] sending origin transaction")
|
|
688
|
-
const
|
|
689
|
-
let needsNativeFee = false
|
|
690
|
-
|
|
691
|
-
if (usingLIfi) {
|
|
692
|
-
needsNativeFee = getNeedsLifiNativeFee({
|
|
693
|
-
originTokenAddress,
|
|
694
|
-
destinationTokenAmount: swapAmount,
|
|
695
|
-
destinationTokenDecimals,
|
|
696
|
-
sourceTokenDecimals,
|
|
697
|
-
sourceTokenPriceUsd: sourceTokenPriceUsd ?? null,
|
|
698
|
-
destinationTokenPriceUsd: destinationTokenPriceUsd ?? null,
|
|
699
|
-
depositAmount,
|
|
700
|
-
})
|
|
701
|
-
}
|
|
423
|
+
const needsNativeFee = false
|
|
702
424
|
|
|
703
425
|
logger.console.log("[trails-sdk] needsNativeFee", needsNativeFee)
|
|
704
426
|
logger.console.log(
|
|
@@ -719,8 +441,8 @@ export async function handleCrossChain({
|
|
|
719
441
|
)
|
|
720
442
|
|
|
721
443
|
let depositUserTxnReceipt: TransactionReceipt | null = null
|
|
722
|
-
let
|
|
723
|
-
let
|
|
444
|
+
let originIntentTransaction: IntentTransaction | null = null
|
|
445
|
+
let destinationIntentTransaction: IntentTransaction | null = null
|
|
724
446
|
|
|
725
447
|
const testnet = isTestnetDebugMode()
|
|
726
448
|
const effectiveOriginChain = testnet
|
|
@@ -732,10 +454,11 @@ export async function handleCrossChain({
|
|
|
732
454
|
|
|
733
455
|
logger.console.log("[trails-sdk] testnet", testnet)
|
|
734
456
|
|
|
735
|
-
const
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
}
|
|
457
|
+
const destinationChainInfo = getChainInfo(destinationChainId)
|
|
458
|
+
if (!destinationChainInfo) {
|
|
459
|
+
throw new Error(`Chain ${destinationChainId} not found`)
|
|
460
|
+
}
|
|
461
|
+
const destinationPublicClient = getPublicRpcClient(destinationChainInfo)
|
|
739
462
|
|
|
740
463
|
const depositPromise = async () => {
|
|
741
464
|
logger.console.log(
|
|
@@ -759,14 +482,14 @@ export async function handleCrossChain({
|
|
|
759
482
|
paymasterUrl,
|
|
760
483
|
chain: effectiveOriginChain.id,
|
|
761
484
|
account: account.address,
|
|
762
|
-
|
|
485
|
+
depositAmount,
|
|
763
486
|
originIntentAddress,
|
|
764
487
|
fee,
|
|
765
488
|
dryMode,
|
|
766
489
|
feeOptions: gasFeeOptions,
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
490
|
+
selectedFeeOption: effectiveSelectedFeeOption,
|
|
491
|
+
selectedFeeOptionType: typeof effectiveSelectedFeeOption,
|
|
492
|
+
selectedFeeOptionValue: JsonEncode(effectiveSelectedFeeOption),
|
|
770
493
|
checkoutOnHandlers,
|
|
771
494
|
},
|
|
772
495
|
)
|
|
@@ -776,7 +499,7 @@ export async function handleCrossChain({
|
|
|
776
499
|
paymasterUrl,
|
|
777
500
|
chain: effectiveOriginChain,
|
|
778
501
|
account,
|
|
779
|
-
|
|
502
|
+
depositAmount,
|
|
780
503
|
originIntentAddress,
|
|
781
504
|
onOriginSend,
|
|
782
505
|
publicClient,
|
|
@@ -797,7 +520,7 @@ export async function handleCrossChain({
|
|
|
797
520
|
feeOptions: gasFeeOptions,
|
|
798
521
|
checkoutOnHandlers,
|
|
799
522
|
trailsClient,
|
|
800
|
-
|
|
523
|
+
selectedFeeOption: effectiveSelectedFeeOption,
|
|
801
524
|
walletId,
|
|
802
525
|
abortSignal,
|
|
803
526
|
intentId: intent.intentId,
|
|
@@ -987,6 +710,52 @@ export async function handleCrossChain({
|
|
|
987
710
|
)
|
|
988
711
|
}
|
|
989
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
|
+
|
|
990
759
|
if (onOriginSend) {
|
|
991
760
|
onOriginSend()
|
|
992
761
|
}
|
|
@@ -1088,6 +857,7 @@ export async function handleCrossChain({
|
|
|
1088
857
|
// Unified polling via shared poller instead of separate loops
|
|
1089
858
|
let unifiedPollerAbortController: AbortController | null = null
|
|
1090
859
|
let unifiedPollerPromise: Promise<IntentReceipt | null> | null = null
|
|
860
|
+
let executeIntentCalled = false // Track if executeIntent has been called (for QR code mode)
|
|
1091
861
|
|
|
1092
862
|
// Helper function to start unified polling for both origin and destination transactions
|
|
1093
863
|
const startUnifiedPolling = () => {
|
|
@@ -1226,7 +996,9 @@ export async function handleCrossChain({
|
|
|
1226
996
|
)
|
|
1227
997
|
|
|
1228
998
|
// Store the transaction hash
|
|
1229
|
-
|
|
999
|
+
originIntentTransaction = {
|
|
1000
|
+
txnHash: txHash,
|
|
1001
|
+
} as IntentTransaction
|
|
1230
1002
|
|
|
1231
1003
|
const originTxnReceipt =
|
|
1232
1004
|
await publicClient.getTransactionReceipt({
|
|
@@ -1325,9 +1097,9 @@ export async function handleCrossChain({
|
|
|
1325
1097
|
)
|
|
1326
1098
|
|
|
1327
1099
|
// Store the transaction hash
|
|
1328
|
-
|
|
1100
|
+
destinationIntentTransaction = {
|
|
1329
1101
|
txnHash: txHash,
|
|
1330
|
-
} as
|
|
1102
|
+
} as IntentTransaction
|
|
1331
1103
|
|
|
1332
1104
|
const destinationTxnReceipt =
|
|
1333
1105
|
await destinationPublicClient.getTransactionReceipt({
|
|
@@ -1442,15 +1214,17 @@ export async function handleCrossChain({
|
|
|
1442
1214
|
|
|
1443
1215
|
// First phase: Send meta transactions and queue CCTP
|
|
1444
1216
|
const originSendMetaTxnPromise = async () => {
|
|
1217
|
+
const originMeta = intent.originMetaTxn
|
|
1218
|
+
const originPre = intent.originPrecondition
|
|
1445
1219
|
logger.console.log("[trails-sdk] Starting originSendMetaTxnPromise", {
|
|
1446
|
-
hasMetaTxn: !!
|
|
1447
|
-
hasPrecondition: !!
|
|
1448
|
-
metaTxnId:
|
|
1449
|
-
chainId:
|
|
1220
|
+
hasMetaTxn: !!originMeta,
|
|
1221
|
+
hasPrecondition: !!originPre,
|
|
1222
|
+
metaTxnId: originMeta?.id,
|
|
1223
|
+
chainId: originMeta?.chainId,
|
|
1450
1224
|
})
|
|
1451
1225
|
|
|
1452
|
-
if (
|
|
1453
|
-
const metaTxnId =
|
|
1226
|
+
if (originMeta && originPre) {
|
|
1227
|
+
const metaTxnId = originMeta.id
|
|
1454
1228
|
const feeQuote = undefined
|
|
1455
1229
|
logger.console.log("[trails-sdk] Processing origin meta txn", {
|
|
1456
1230
|
metaTxnId,
|
|
@@ -1462,9 +1236,9 @@ export async function handleCrossChain({
|
|
|
1462
1236
|
"[trails-sdk] NOTE: Client-side meta transaction submission deprecated",
|
|
1463
1237
|
{
|
|
1464
1238
|
metaTxnId,
|
|
1465
|
-
chainId:
|
|
1466
|
-
walletAddress:
|
|
1467
|
-
contract:
|
|
1239
|
+
chainId: originMeta.chainId,
|
|
1240
|
+
walletAddress: originMeta.walletAddress,
|
|
1241
|
+
contract: originMeta.contract,
|
|
1468
1242
|
message:
|
|
1469
1243
|
"Transaction submission now handled by backend via executeIntent. Monitoring via WaitIntentReceipt API.",
|
|
1470
1244
|
},
|
|
@@ -1482,21 +1256,23 @@ export async function handleCrossChain({
|
|
|
1482
1256
|
logger.console.warn(
|
|
1483
1257
|
"[trails-sdk] Skipping origin sendMetaTxn - missing metaTxn or precondition",
|
|
1484
1258
|
{
|
|
1485
|
-
hasMetaTxn: !!intent.
|
|
1486
|
-
hasPrecondition: !!intent.
|
|
1259
|
+
hasMetaTxn: !!intent.originMetaTxn,
|
|
1260
|
+
hasPrecondition: !!intent.originPrecondition,
|
|
1487
1261
|
},
|
|
1488
1262
|
)
|
|
1489
1263
|
}
|
|
1490
1264
|
}
|
|
1491
1265
|
|
|
1492
1266
|
const destinationSendMetaTxnPromise = async () => {
|
|
1267
|
+
const destinationPre = intent.destinationPrecondition
|
|
1268
|
+
const destinationMeta = intent.destinationMetaTxn
|
|
1493
1269
|
logger.console.log(
|
|
1494
1270
|
"[trails-sdk] Starting destinationSendMetaTxnPromise",
|
|
1495
1271
|
{
|
|
1496
1272
|
quoteProvider: intent.quote.quoteProvider,
|
|
1497
1273
|
hasQuoteProviderRequestId: !!intent.quote.quoteProviderRequestId,
|
|
1498
|
-
hasPrecondition1: !!
|
|
1499
|
-
hasMetaTxn1: !!
|
|
1274
|
+
hasPrecondition1: !!destinationPre,
|
|
1275
|
+
hasMetaTxn1: !!destinationMeta,
|
|
1500
1276
|
},
|
|
1501
1277
|
)
|
|
1502
1278
|
|
|
@@ -1507,41 +1283,6 @@ export async function handleCrossChain({
|
|
|
1507
1283
|
)
|
|
1508
1284
|
}
|
|
1509
1285
|
|
|
1510
|
-
let queueCctpPromise: (() => Promise<void>) | null = null
|
|
1511
|
-
|
|
1512
|
-
const isCctp = intent.quote.quoteProvider === "cctp"
|
|
1513
|
-
if (isCctp) {
|
|
1514
|
-
queueCctpPromise = async () => {
|
|
1515
|
-
while (true) {
|
|
1516
|
-
// Check if we should abort
|
|
1517
|
-
if (abortSignal?.aborted) {
|
|
1518
|
-
logger.console.log(
|
|
1519
|
-
"[trails-sdk] Aborting CCTP queue due to abort signal",
|
|
1520
|
-
)
|
|
1521
|
-
return
|
|
1522
|
-
}
|
|
1523
|
-
|
|
1524
|
-
const originMetaTxnHash = (
|
|
1525
|
-
originMetaTxnReceipt as MetaTxnReceipt | null
|
|
1526
|
-
)?.txnHash
|
|
1527
|
-
if (originMetaTxnHash) {
|
|
1528
|
-
await queueCCTPTransfer({
|
|
1529
|
-
trailsClient,
|
|
1530
|
-
sourceTxHash: originMetaTxnHash,
|
|
1531
|
-
sourceChainId: originChainId,
|
|
1532
|
-
destinationChainId: destinationChainId,
|
|
1533
|
-
})
|
|
1534
|
-
break
|
|
1535
|
-
}
|
|
1536
|
-
await new Promise((resolve) =>
|
|
1537
|
-
setTimeout(resolve, POLLING_INTERVALS.CCTP_QUEUE),
|
|
1538
|
-
)
|
|
1539
|
-
}
|
|
1540
|
-
}
|
|
1541
|
-
} else {
|
|
1542
|
-
queueCctpPromise = () => Promise.resolve()
|
|
1543
|
-
}
|
|
1544
|
-
|
|
1545
1286
|
// Only start polling for external deposits if needed:
|
|
1546
1287
|
// - QR code or exchange funding (external deposits)
|
|
1547
1288
|
// - Gasless flow (relayer-executed deposits)
|
|
@@ -1583,12 +1324,43 @@ export async function handleCrossChain({
|
|
|
1583
1324
|
"[trails-sdk] Starting Phase 2: Waiting for receipts and executing deposit",
|
|
1584
1325
|
)
|
|
1585
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
|
+
|
|
1586
1356
|
const waitForOriginMetaTxnReceiptPromise = async () => {
|
|
1587
1357
|
logger.console.log(
|
|
1588
1358
|
"[trails-sdk] Waiting for origin meta transaction receipt via unified poller",
|
|
1589
1359
|
)
|
|
1590
1360
|
// The unified poller handles origin transaction discovery and decoding via callbacks
|
|
1591
|
-
//
|
|
1361
|
+
// For QR code mode, wait for unifiedPollerPromise to be created first (after executeIntent is called)
|
|
1362
|
+
await waitForUnifiedPollerToStart()
|
|
1363
|
+
|
|
1592
1364
|
if (unifiedPollerPromise) {
|
|
1593
1365
|
try {
|
|
1594
1366
|
await unifiedPollerPromise
|
|
@@ -1606,7 +1378,9 @@ export async function handleCrossChain({
|
|
|
1606
1378
|
"[trails-sdk] Waiting for destination meta transaction receipt via unified poller",
|
|
1607
1379
|
)
|
|
1608
1380
|
// The unified poller handles destination transaction discovery and decoding via callbacks
|
|
1609
|
-
//
|
|
1381
|
+
// For QR code mode, wait for unifiedPollerPromise to be created first (after executeIntent is called)
|
|
1382
|
+
await waitForUnifiedPollerToStart()
|
|
1383
|
+
|
|
1610
1384
|
if (unifiedPollerPromise) {
|
|
1611
1385
|
try {
|
|
1612
1386
|
await unifiedPollerPromise
|
|
@@ -1632,10 +1406,17 @@ export async function handleCrossChain({
|
|
|
1632
1406
|
|
|
1633
1407
|
// Start unified polling after deposit transaction is submitted and executeIntent is called
|
|
1634
1408
|
// This ensures the backend has received the executeIntent call before we start polling waitIntentReceipt
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
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
|
+
}
|
|
1639
1420
|
|
|
1640
1421
|
// Now wait for all the receipts and CCTP processing
|
|
1641
1422
|
logger.console.log(
|
|
@@ -1644,7 +1425,6 @@ export async function handleCrossChain({
|
|
|
1644
1425
|
await Promise.all([
|
|
1645
1426
|
waitForOriginMetaTxnReceiptPromise(),
|
|
1646
1427
|
waitForDestinationMetaTxnReceiptPromise(),
|
|
1647
|
-
queueCctpPromise(),
|
|
1648
1428
|
])
|
|
1649
1429
|
logger.console.log("[trails-sdk] Phase 2 completed successfully")
|
|
1650
1430
|
|
|
@@ -1657,10 +1437,10 @@ export async function handleCrossChain({
|
|
|
1657
1437
|
const hasRequiredReceipts =
|
|
1658
1438
|
(depositUserTxnReceipt || effectiveGasless) &&
|
|
1659
1439
|
(isDestinationCrossChain
|
|
1660
|
-
?
|
|
1440
|
+
? destinationIntentTransaction
|
|
1661
1441
|
: isSameChain
|
|
1662
|
-
?
|
|
1663
|
-
:
|
|
1442
|
+
? originIntentTransaction
|
|
1443
|
+
: destinationIntentTransaction)
|
|
1664
1444
|
|
|
1665
1445
|
if (hasRequiredReceipts) {
|
|
1666
1446
|
// Check if any transaction failed or was refunded
|
|
@@ -1681,7 +1461,7 @@ export async function handleCrossChain({
|
|
|
1681
1461
|
? (depositUserTxnReceipt as TransactionReceipt).transactionHash
|
|
1682
1462
|
: undefined,
|
|
1683
1463
|
destinationTxHash: (
|
|
1684
|
-
|
|
1464
|
+
destinationIntentTransaction as unknown as IntentTransaction
|
|
1685
1465
|
)?.txnHash,
|
|
1686
1466
|
originChainId,
|
|
1687
1467
|
destinationChainId,
|
|
@@ -1755,8 +1535,8 @@ export async function handleCrossChain({
|
|
|
1755
1535
|
|
|
1756
1536
|
return {
|
|
1757
1537
|
depositUserTxnReceipt,
|
|
1758
|
-
|
|
1759
|
-
|
|
1538
|
+
originIntentTransaction,
|
|
1539
|
+
destinationIntentTransaction,
|
|
1760
1540
|
totalCompletionSeconds: await getTxTimeDiff(
|
|
1761
1541
|
transactionStates[0],
|
|
1762
1542
|
transactionStates[2],
|