0xtrails 0.4.1 → 0.4.3
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/aave.d.ts.map +1 -1
- package/dist/{ccip-Bc-mZIIK.js → ccip-C9CA3tIi.js} +5 -5
- package/dist/{index-BWGjgMLm.js → index-CNB57v0n.js} +15676 -15527
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +501 -474
- package/dist/intents.d.ts +1 -1
- package/dist/intents.d.ts.map +1 -1
- package/dist/morpho.d.ts.map +1 -1
- package/dist/mutations.d.ts +2 -2
- package/dist/mutations.d.ts.map +1 -1
- package/dist/prepareSend.d.ts.map +1 -1
- package/dist/trails.d.ts +9 -10
- package/dist/trails.d.ts.map +1 -1
- package/dist/transactionIntent/deposits/depositOrchestrator.d.ts +3 -2
- package/dist/transactionIntent/deposits/depositOrchestrator.d.ts.map +1 -1
- package/dist/transactionIntent/deposits/gaslessDeposit.d.ts +1 -1
- package/dist/transactionIntent/deposits/gaslessDeposit.d.ts.map +1 -1
- package/dist/transactionIntent/deposits/standardDeposit.d.ts +3 -2
- package/dist/transactionIntent/deposits/standardDeposit.d.ts.map +1 -1
- package/dist/transactionIntent/handlers/crossChain.d.ts +1 -1
- package/dist/transactionIntent/handlers/crossChain.d.ts.map +1 -1
- package/dist/transactionIntent/handlers/sameChainSameToken.d.ts +3 -2
- package/dist/transactionIntent/handlers/sameChainSameToken.d.ts.map +1 -1
- package/dist/transactionIntent/quote/quoteHelpers.d.ts.map +1 -1
- package/dist/transactionIntent/types.d.ts +1 -1
- package/dist/transactionIntent/types.d.ts.map +1 -1
- package/dist/widget/components/FeeOptions.d.ts +2 -1
- package/dist/widget/components/FeeOptions.d.ts.map +1 -1
- package/dist/widget/components/PoolDeposit.d.ts.map +1 -1
- package/dist/widget/hooks/useQuote.d.ts +31 -1
- package/dist/widget/hooks/useQuote.d.ts.map +1 -1
- package/dist/widget/hooks/useSendForm.d.ts +1 -1
- package/dist/widget/hooks/useSendForm.d.ts.map +1 -1
- package/dist/widget/index.js +1 -1
- package/package.json +7 -7
- package/src/aave.ts +1 -0
- package/src/index.ts +1 -1
- package/src/intents.ts +2 -2
- package/src/morpho.ts +3 -2
- package/src/mutations.ts +53 -5
- package/src/prepareSend.ts +16 -1
- package/src/trails.ts +57 -65
- package/src/transactionIntent/deposits/depositOrchestrator.ts +4 -1
- package/src/transactionIntent/deposits/gaslessDeposit.ts +89 -44
- package/src/transactionIntent/deposits/standardDeposit.ts +198 -39
- package/src/transactionIntent/handlers/crossChain.ts +84 -9
- package/src/transactionIntent/handlers/sameChainSameToken.ts +54 -12
- package/src/transactionIntent/quote/quoteHelpers.ts +4 -11
- package/src/transactionIntent/types.ts +1 -1
- package/src/widget/components/FeeOptions.tsx +2 -1
- package/src/widget/components/PoolDeposit.tsx +68 -4
- package/src/widget/hooks/useDebugScreens.ts +11 -11
- package/src/widget/hooks/useQuote.ts +37 -2
- package/src/widget/hooks/useSendForm.ts +2 -2
|
@@ -5,7 +5,7 @@ import type {
|
|
|
5
5
|
WalletClient,
|
|
6
6
|
TransactionReceipt,
|
|
7
7
|
} from "viem"
|
|
8
|
-
import { parseUnits } from "viem"
|
|
8
|
+
import { parseUnits, encodeFunctionData } from "viem"
|
|
9
9
|
import type { TransactionState } from "../../transactions.js"
|
|
10
10
|
import type { CheckoutOnHandlers } from "../../widget/hooks/useCheckout.js"
|
|
11
11
|
import { logger } from "../../logger.js"
|
|
@@ -15,12 +15,15 @@ import {
|
|
|
15
15
|
buildSameChainSameTokenTransactionParams,
|
|
16
16
|
sendOriginTransaction,
|
|
17
17
|
} from "../../intents.js"
|
|
18
|
+
import { getIsCustomCalldata } from "../../contractUtils.js"
|
|
18
19
|
import { estimateGasLimit } from "../../estimate.js"
|
|
19
20
|
import { attemptSwitchChain } from "../../chainSwitch.js"
|
|
20
21
|
import { requestWithTimeout } from "../../utils.js"
|
|
21
22
|
import { updatePersistentToast } from "../../toast.js"
|
|
22
23
|
import { getChainInfo } from "../../chains.js"
|
|
23
24
|
import { trackTransactionConfirmed } from "../../analytics.js"
|
|
25
|
+
import { zeroAddress } from "viem"
|
|
26
|
+
import { getIsUserRejectionError } from "../../error.js"
|
|
24
27
|
|
|
25
28
|
export async function attemptStandardDeposit({
|
|
26
29
|
originTokenAddress,
|
|
@@ -47,6 +50,7 @@ export async function attemptStandardDeposit({
|
|
|
47
50
|
checkoutOnHandlers,
|
|
48
51
|
isSameChainSameToken,
|
|
49
52
|
recipient,
|
|
53
|
+
destinationCalldata,
|
|
50
54
|
}: {
|
|
51
55
|
originTokenAddress: string
|
|
52
56
|
firstPreconditionMin: string
|
|
@@ -69,10 +73,12 @@ export async function attemptStandardDeposit({
|
|
|
69
73
|
originTokenSymbol: string
|
|
70
74
|
destinationTokenSymbol: string
|
|
71
75
|
depositAmountUsd: number
|
|
72
|
-
checkoutOnHandlers?: CheckoutOnHandlers
|
|
76
|
+
checkoutOnHandlers?: Partial<CheckoutOnHandlers>
|
|
73
77
|
isSameChainSameToken?: boolean
|
|
74
78
|
recipient?: string
|
|
79
|
+
destinationCalldata?: string
|
|
75
80
|
}): Promise<TransactionReceipt | null> {
|
|
81
|
+
console.log("IN ATTEMPT STANDARD DEPOSIT!")
|
|
76
82
|
let depositUserTxnReceipt: TransactionReceipt | null = null
|
|
77
83
|
const usingLIfi = false
|
|
78
84
|
let needsNativeFee = false
|
|
@@ -100,9 +106,10 @@ export async function attemptStandardDeposit({
|
|
|
100
106
|
// For cross-chain deposits, send to intent address for backend processing
|
|
101
107
|
const originCallParamsBase = isSameChainSameToken
|
|
102
108
|
? buildSameChainSameTokenTransactionParams({
|
|
103
|
-
hasCustomCalldata:
|
|
109
|
+
hasCustomCalldata: getIsCustomCalldata(destinationCalldata),
|
|
104
110
|
recipient: recipient || originIntentAddress,
|
|
105
111
|
effectiveOriginTokenAddress: originTokenAddress,
|
|
112
|
+
destinationCalldata,
|
|
106
113
|
swapAmount: firstPreconditionMin,
|
|
107
114
|
effectiveOriginChainId: originChainId,
|
|
108
115
|
effectiveOriginChain: chain,
|
|
@@ -116,6 +123,134 @@ export async function attemptStandardDeposit({
|
|
|
116
123
|
chain,
|
|
117
124
|
})
|
|
118
125
|
|
|
126
|
+
const hasCustomCalldata = isSameChainSameToken
|
|
127
|
+
? getIsCustomCalldata(destinationCalldata)
|
|
128
|
+
: false
|
|
129
|
+
|
|
130
|
+
if (
|
|
131
|
+
isSameChainSameToken &&
|
|
132
|
+
originTokenAddress !== zeroAddress &&
|
|
133
|
+
hasCustomCalldata &&
|
|
134
|
+
!dryMode &&
|
|
135
|
+
recipient
|
|
136
|
+
) {
|
|
137
|
+
// ERC20 custom calldata requires approval to the recipient contract
|
|
138
|
+
const erc20Abi = [
|
|
139
|
+
{
|
|
140
|
+
name: "allowance",
|
|
141
|
+
type: "function",
|
|
142
|
+
stateMutability: "view",
|
|
143
|
+
inputs: [
|
|
144
|
+
{ name: "owner", type: "address" },
|
|
145
|
+
{ name: "spender", type: "address" },
|
|
146
|
+
],
|
|
147
|
+
outputs: [{ type: "uint256" }],
|
|
148
|
+
} as const,
|
|
149
|
+
{
|
|
150
|
+
name: "approve",
|
|
151
|
+
type: "function",
|
|
152
|
+
stateMutability: "nonpayable",
|
|
153
|
+
inputs: [
|
|
154
|
+
{ name: "spender", type: "address" },
|
|
155
|
+
{ name: "amount", type: "uint256" },
|
|
156
|
+
],
|
|
157
|
+
outputs: [{ type: "bool" }],
|
|
158
|
+
} as const,
|
|
159
|
+
] as const
|
|
160
|
+
|
|
161
|
+
const currentAllowance = (await publicClient.readContract({
|
|
162
|
+
address: originTokenAddress as `0x${string}`,
|
|
163
|
+
abi: erc20Abi,
|
|
164
|
+
functionName: "allowance",
|
|
165
|
+
args: [account.address, recipient as `0x${string}`],
|
|
166
|
+
})) as bigint
|
|
167
|
+
|
|
168
|
+
const requiredAmount = BigInt(firstPreconditionMin)
|
|
169
|
+
|
|
170
|
+
if (currentAllowance < requiredAmount) {
|
|
171
|
+
logger.console.log(
|
|
172
|
+
"[trails-sdk] Insufficient allowance, sending approve transaction...",
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
const approveData = encodeFunctionData({
|
|
176
|
+
abi: erc20Abi,
|
|
177
|
+
functionName: "approve",
|
|
178
|
+
args: [recipient as `0x${string}`, requiredAmount],
|
|
179
|
+
}) as `0x${string}`
|
|
180
|
+
|
|
181
|
+
let approveHash: `0x${string}`
|
|
182
|
+
let approveReceipt: TransactionReceipt
|
|
183
|
+
try {
|
|
184
|
+
approveHash = await sendOriginTransaction(
|
|
185
|
+
account,
|
|
186
|
+
walletClient,
|
|
187
|
+
{
|
|
188
|
+
to: originTokenAddress as `0x${string}`,
|
|
189
|
+
data: approveData,
|
|
190
|
+
value: 0n,
|
|
191
|
+
chain,
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
transactionType: "token_approve",
|
|
195
|
+
depositTokenAmountUsd: depositAmountUsd?.toString(),
|
|
196
|
+
},
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
approveReceipt = await publicClient.waitForTransactionReceipt({
|
|
200
|
+
hash: approveHash,
|
|
201
|
+
})
|
|
202
|
+
} catch (error) {
|
|
203
|
+
// Check if this is a user rejection error
|
|
204
|
+
if (getIsUserRejectionError(error)) {
|
|
205
|
+
if (checkoutOnHandlers?.triggerCheckoutSignatureRejected) {
|
|
206
|
+
checkoutOnHandlers.triggerCheckoutSignatureRejected(error)
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
throw error
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
logger.console.log(
|
|
213
|
+
"[trails-sdk] Approve transaction confirmed:",
|
|
214
|
+
approveReceipt,
|
|
215
|
+
)
|
|
216
|
+
|
|
217
|
+
// Poll to ensure allowance is updated on-chain before proceeding
|
|
218
|
+
let updatedAllowance = currentAllowance
|
|
219
|
+
const maxPollAttempts = 15 // 30 seconds at 2s intervals
|
|
220
|
+
let pollAttempts = 0
|
|
221
|
+
|
|
222
|
+
while (
|
|
223
|
+
updatedAllowance < requiredAmount &&
|
|
224
|
+
pollAttempts < maxPollAttempts
|
|
225
|
+
) {
|
|
226
|
+
await new Promise((resolve) => setTimeout(resolve, 2000)) // Wait 2 seconds
|
|
227
|
+
updatedAllowance = (await publicClient.readContract({
|
|
228
|
+
address: originTokenAddress as `0x${string}`,
|
|
229
|
+
abi: erc20Abi,
|
|
230
|
+
functionName: "allowance",
|
|
231
|
+
args: [account.address, recipient as `0x${string}`],
|
|
232
|
+
})) as bigint
|
|
233
|
+
pollAttempts++
|
|
234
|
+
logger.console.log(
|
|
235
|
+
`[trails-sdk] Polling allowance (attempt ${pollAttempts}): ${updatedAllowance.toString()}`,
|
|
236
|
+
)
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
if (updatedAllowance < requiredAmount) {
|
|
240
|
+
throw new Error(
|
|
241
|
+
"Allowance not updated after approve transaction - RPC may be delayed or transaction failed",
|
|
242
|
+
)
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
logger.console.log(
|
|
246
|
+
"[trails-sdk] Allowance confirmed updated:",
|
|
247
|
+
updatedAllowance.toString(),
|
|
248
|
+
)
|
|
249
|
+
} else {
|
|
250
|
+
logger.console.log("[trails-sdk] Sufficient allowance, skipping approve")
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
119
254
|
// Estimate gas limit for consistency with actual transaction
|
|
120
255
|
const gasLimit = await estimateGasLimit(
|
|
121
256
|
publicClient,
|
|
@@ -276,31 +411,44 @@ export async function attemptStandardDeposit({
|
|
|
276
411
|
checkoutOnHandlers.triggerCheckoutSignatureRequest()
|
|
277
412
|
}
|
|
278
413
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
414
|
+
try {
|
|
415
|
+
const txHashNativeFee = await sendOriginTransaction(
|
|
416
|
+
account,
|
|
417
|
+
walletClient,
|
|
418
|
+
{
|
|
419
|
+
to: originIntentAddress,
|
|
420
|
+
data: "0x00",
|
|
421
|
+
value: nativeFee,
|
|
422
|
+
chainId: originChainId,
|
|
423
|
+
chain,
|
|
424
|
+
} as any,
|
|
425
|
+
{
|
|
426
|
+
depositTokenAmountUsd: depositAmountUsd?.toString(),
|
|
427
|
+
},
|
|
428
|
+
) // TODO: Add proper type
|
|
429
|
+
logger.console.log(
|
|
430
|
+
"[trails-sdk] origin tx native fee",
|
|
431
|
+
txHashNativeFee,
|
|
432
|
+
)
|
|
294
433
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
434
|
+
// Trigger signature confirmed callback after successful signing
|
|
435
|
+
if (checkoutOnHandlers?.triggerCheckoutSignatureConfirmed) {
|
|
436
|
+
checkoutOnHandlers.triggerCheckoutSignatureConfirmed()
|
|
437
|
+
}
|
|
438
|
+
// Wait for transaction receipt
|
|
439
|
+
const feeReceipt = await publicClient.waitForTransactionReceipt({
|
|
440
|
+
hash: txHashNativeFee,
|
|
441
|
+
})
|
|
442
|
+
logger.console.log("[trails-sdk] nativeFeeReceipt", feeReceipt)
|
|
443
|
+
} catch (error) {
|
|
444
|
+
// Check if this is a user rejection error
|
|
445
|
+
if (getIsUserRejectionError(error)) {
|
|
446
|
+
if (checkoutOnHandlers?.triggerCheckoutSignatureRejected) {
|
|
447
|
+
checkoutOnHandlers.triggerCheckoutSignatureRejected(error)
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
throw error
|
|
298
451
|
}
|
|
299
|
-
// Wait for transaction receipt
|
|
300
|
-
const feeReceipt = await publicClient.waitForTransactionReceipt({
|
|
301
|
-
hash: txHashNativeFee,
|
|
302
|
-
})
|
|
303
|
-
logger.console.log("[trails-sdk] nativeFeeReceipt", feeReceipt)
|
|
304
452
|
}
|
|
305
453
|
|
|
306
454
|
// Show persistent toast for checkout flow
|
|
@@ -315,19 +463,30 @@ export async function attemptStandardDeposit({
|
|
|
315
463
|
checkoutOnHandlers.triggerCheckoutSignatureRequest()
|
|
316
464
|
}
|
|
317
465
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
466
|
+
let txHash: `0x${string}`
|
|
467
|
+
try {
|
|
468
|
+
txHash = await sendOriginTransaction(
|
|
469
|
+
account,
|
|
470
|
+
walletClient,
|
|
471
|
+
originCallParams as any,
|
|
472
|
+
{
|
|
473
|
+
depositTokenAmountUsd: depositAmountUsd?.toString(),
|
|
474
|
+
},
|
|
475
|
+
) // TODO: Add proper type
|
|
476
|
+
logger.console.log("[trails-sdk] origin tx", txHash)
|
|
477
|
+
|
|
478
|
+
// Trigger signature confirmed callback after successful signing
|
|
479
|
+
if (checkoutOnHandlers?.triggerCheckoutSignatureConfirmed) {
|
|
480
|
+
checkoutOnHandlers.triggerCheckoutSignatureConfirmed()
|
|
481
|
+
}
|
|
482
|
+
} catch (error) {
|
|
483
|
+
// Check if this is a user rejection error
|
|
484
|
+
if (getIsUserRejectionError(error)) {
|
|
485
|
+
if (checkoutOnHandlers?.triggerCheckoutSignatureRejected) {
|
|
486
|
+
checkoutOnHandlers.triggerCheckoutSignatureRejected(error)
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
throw error
|
|
331
490
|
}
|
|
332
491
|
|
|
333
492
|
if (onOriginSend) {
|
|
@@ -43,7 +43,7 @@ import {
|
|
|
43
43
|
} from "../../sequenceWallet.js"
|
|
44
44
|
import { getIntentArgs } from "../quote/quoteHelpers.js"
|
|
45
45
|
import {
|
|
46
|
-
|
|
46
|
+
quoteIntent,
|
|
47
47
|
commitIntent,
|
|
48
48
|
buildCrossChainDepositParams,
|
|
49
49
|
} from "../../intents.js"
|
|
@@ -177,7 +177,7 @@ export async function handleCrossChain({
|
|
|
177
177
|
quoteProvider?: string | null
|
|
178
178
|
fundMethod?: string
|
|
179
179
|
mode?: "pay" | "fund" | "earn" | "swap" | "receive"
|
|
180
|
-
checkoutOnHandlers?: CheckoutOnHandlers
|
|
180
|
+
checkoutOnHandlers?: Partial<CheckoutOnHandlers>
|
|
181
181
|
selectedFeeToken?: SelectedFeeToken
|
|
182
182
|
walletId?: string
|
|
183
183
|
abortSignal?: AbortSignal
|
|
@@ -324,6 +324,10 @@ export async function handleCrossChain({
|
|
|
324
324
|
)
|
|
325
325
|
|
|
326
326
|
onTransactionStateChange(transactionStates)
|
|
327
|
+
// Also trigger checkout status update if handler is provided
|
|
328
|
+
if (checkoutOnHandlers?.triggerCheckoutStatusUpdate) {
|
|
329
|
+
checkoutOnHandlers.triggerCheckoutStatusUpdate(transactionStates)
|
|
330
|
+
}
|
|
327
331
|
|
|
328
332
|
const attestation = await waitForAttestation()
|
|
329
333
|
|
|
@@ -407,6 +411,10 @@ export async function handleCrossChain({
|
|
|
407
411
|
}
|
|
408
412
|
|
|
409
413
|
onTransactionStateChange(transactionStates)
|
|
414
|
+
// Also trigger checkout status update if handler is provided
|
|
415
|
+
if (checkoutOnHandlers?.triggerCheckoutStatusUpdate) {
|
|
416
|
+
checkoutOnHandlers.triggerCheckoutStatusUpdate(transactionStates)
|
|
417
|
+
}
|
|
410
418
|
|
|
411
419
|
return {
|
|
412
420
|
depositUserTxnReceipt: receipt,
|
|
@@ -438,13 +446,17 @@ export async function handleCrossChain({
|
|
|
438
446
|
|
|
439
447
|
logger.console.log("[trails-sdk] Creating intent with args:", intentArgs)
|
|
440
448
|
|
|
441
|
-
const { intent, gasFeeOptions } = await
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
449
|
+
const { intent, gasFeeOptions } = await quoteIntent(
|
|
450
|
+
trailsClient,
|
|
451
|
+
intentArgs,
|
|
452
|
+
{
|
|
453
|
+
originTokenSymbol,
|
|
454
|
+
destinationTokenSymbol,
|
|
455
|
+
feeTokenSymbol: originTokenSymbol,
|
|
456
|
+
},
|
|
457
|
+
)
|
|
458
|
+
logger.console.log("[trails-sdk] Quote intent:", intent)
|
|
459
|
+
logger.console.log("[trails-sdk] Quote intent gasFeeOptions:", gasFeeOptions)
|
|
448
460
|
|
|
449
461
|
if (!intent.preconditions?.length || !intent.calls?.length) {
|
|
450
462
|
throw new Error("Invalid intent")
|
|
@@ -747,6 +759,7 @@ export async function handleCrossChain({
|
|
|
747
759
|
selectedFeeToken: effectiveSelectedFeeToken,
|
|
748
760
|
selectedFeeTokenType: typeof effectiveSelectedFeeToken,
|
|
749
761
|
selectedFeeTokenValue: JSON.stringify(effectiveSelectedFeeToken),
|
|
762
|
+
checkoutOnHandlers,
|
|
750
763
|
},
|
|
751
764
|
)
|
|
752
765
|
|
|
@@ -774,11 +787,13 @@ export async function handleCrossChain({
|
|
|
774
787
|
destinationTokenSymbol,
|
|
775
788
|
depositAmountUsd,
|
|
776
789
|
feeOptions: gasFeeOptions,
|
|
790
|
+
checkoutOnHandlers,
|
|
777
791
|
trailsClient,
|
|
778
792
|
selectedFeeToken: effectiveSelectedFeeToken,
|
|
779
793
|
walletId,
|
|
780
794
|
abortSignal,
|
|
781
795
|
intentId: intent.intentId,
|
|
796
|
+
executeIntentFn,
|
|
782
797
|
})
|
|
783
798
|
|
|
784
799
|
// In gasless mode, depositUserTxnReceipt will be null because the transaction
|
|
@@ -881,6 +896,10 @@ export async function handleCrossChain({
|
|
|
881
896
|
}
|
|
882
897
|
|
|
883
898
|
onTransactionStateChange(transactionStates)
|
|
899
|
+
// Also trigger checkout status update if handler is provided
|
|
900
|
+
if (checkoutOnHandlers?.triggerCheckoutStatusUpdate) {
|
|
901
|
+
checkoutOnHandlers.triggerCheckoutStatusUpdate(transactionStates)
|
|
902
|
+
}
|
|
884
903
|
|
|
885
904
|
setTimeout(() => {
|
|
886
905
|
const destinationChain = getChainInfo(destinationChainId)
|
|
@@ -948,6 +967,12 @@ export async function handleCrossChain({
|
|
|
948
967
|
transactionStates[0]?.label,
|
|
949
968
|
)
|
|
950
969
|
onTransactionStateChange(transactionStates)
|
|
970
|
+
// Also trigger checkout status update if handler is provided
|
|
971
|
+
if (checkoutOnHandlers?.triggerCheckoutStatusUpdate) {
|
|
972
|
+
checkoutOnHandlers.triggerCheckoutStatusUpdate(
|
|
973
|
+
transactionStates,
|
|
974
|
+
)
|
|
975
|
+
}
|
|
951
976
|
|
|
952
977
|
if (onOriginSend) {
|
|
953
978
|
onOriginSend()
|
|
@@ -1014,6 +1039,12 @@ export async function handleCrossChain({
|
|
|
1014
1039
|
transactionStates[2]?.label,
|
|
1015
1040
|
)
|
|
1016
1041
|
onTransactionStateChange(transactionStates)
|
|
1042
|
+
// Also trigger checkout status update if handler is provided
|
|
1043
|
+
if (checkoutOnHandlers?.triggerCheckoutStatusUpdate) {
|
|
1044
|
+
checkoutOnHandlers.triggerCheckoutStatusUpdate(
|
|
1045
|
+
transactionStates,
|
|
1046
|
+
)
|
|
1047
|
+
}
|
|
1017
1048
|
|
|
1018
1049
|
return destinationDepositTxReceipt
|
|
1019
1050
|
}
|
|
@@ -1087,6 +1118,12 @@ export async function handleCrossChain({
|
|
|
1087
1118
|
transactionStates[0]?.label,
|
|
1088
1119
|
)
|
|
1089
1120
|
onTransactionStateChange(transactionStates)
|
|
1121
|
+
// Also trigger checkout status update if handler is provided
|
|
1122
|
+
if (checkoutOnHandlers?.triggerCheckoutStatusUpdate) {
|
|
1123
|
+
checkoutOnHandlers.triggerCheckoutStatusUpdate(
|
|
1124
|
+
transactionStates,
|
|
1125
|
+
)
|
|
1126
|
+
}
|
|
1090
1127
|
|
|
1091
1128
|
// Decode events for the deposit transaction
|
|
1092
1129
|
try {
|
|
@@ -1142,6 +1179,12 @@ export async function handleCrossChain({
|
|
|
1142
1179
|
}
|
|
1143
1180
|
|
|
1144
1181
|
onTransactionStateChange(transactionStates)
|
|
1182
|
+
// Also trigger checkout status update if handler is provided
|
|
1183
|
+
if (checkoutOnHandlers?.triggerCheckoutStatusUpdate) {
|
|
1184
|
+
checkoutOnHandlers.triggerCheckoutStatusUpdate(
|
|
1185
|
+
transactionStates,
|
|
1186
|
+
)
|
|
1187
|
+
}
|
|
1145
1188
|
} catch (error) {
|
|
1146
1189
|
logger.console.error(
|
|
1147
1190
|
"Error decoding deposit tx events",
|
|
@@ -1187,6 +1230,12 @@ export async function handleCrossChain({
|
|
|
1187
1230
|
transactionStates[1]?.label,
|
|
1188
1231
|
)
|
|
1189
1232
|
onTransactionStateChange(transactionStates)
|
|
1233
|
+
// Also trigger checkout status update if handler is provided
|
|
1234
|
+
if (checkoutOnHandlers?.triggerCheckoutStatusUpdate) {
|
|
1235
|
+
checkoutOnHandlers.triggerCheckoutStatusUpdate(
|
|
1236
|
+
transactionStates,
|
|
1237
|
+
)
|
|
1238
|
+
}
|
|
1190
1239
|
}
|
|
1191
1240
|
|
|
1192
1241
|
// Decode events for the origin transaction
|
|
@@ -1236,6 +1285,12 @@ export async function handleCrossChain({
|
|
|
1236
1285
|
}
|
|
1237
1286
|
|
|
1238
1287
|
onTransactionStateChange(transactionStates)
|
|
1288
|
+
// Also trigger checkout status update if handler is provided
|
|
1289
|
+
if (checkoutOnHandlers?.triggerCheckoutStatusUpdate) {
|
|
1290
|
+
checkoutOnHandlers.triggerCheckoutStatusUpdate(
|
|
1291
|
+
transactionStates,
|
|
1292
|
+
)
|
|
1293
|
+
}
|
|
1239
1294
|
} catch (error) {
|
|
1240
1295
|
logger.console.error(
|
|
1241
1296
|
"Error decoding origin tx events",
|
|
@@ -1276,6 +1331,12 @@ export async function handleCrossChain({
|
|
|
1276
1331
|
transactionStates[2]?.label,
|
|
1277
1332
|
)
|
|
1278
1333
|
onTransactionStateChange(transactionStates)
|
|
1334
|
+
// Also trigger checkout status update if handler is provided
|
|
1335
|
+
if (checkoutOnHandlers?.triggerCheckoutStatusUpdate) {
|
|
1336
|
+
checkoutOnHandlers.triggerCheckoutStatusUpdate(
|
|
1337
|
+
transactionStates,
|
|
1338
|
+
)
|
|
1339
|
+
}
|
|
1279
1340
|
}
|
|
1280
1341
|
|
|
1281
1342
|
// Decode events for the destination transaction
|
|
@@ -1334,6 +1395,12 @@ export async function handleCrossChain({
|
|
|
1334
1395
|
}
|
|
1335
1396
|
|
|
1336
1397
|
onTransactionStateChange(transactionStates)
|
|
1398
|
+
// Also trigger checkout status update if handler is provided
|
|
1399
|
+
if (checkoutOnHandlers?.triggerCheckoutStatusUpdate) {
|
|
1400
|
+
checkoutOnHandlers.triggerCheckoutStatusUpdate(
|
|
1401
|
+
transactionStates,
|
|
1402
|
+
)
|
|
1403
|
+
}
|
|
1337
1404
|
} catch (error) {
|
|
1338
1405
|
logger.console.error(
|
|
1339
1406
|
"Error decoding destination tx events",
|
|
@@ -1626,6 +1693,10 @@ export async function handleCrossChain({
|
|
|
1626
1693
|
) {
|
|
1627
1694
|
transactionStates[1].state = "aborted"
|
|
1628
1695
|
onTransactionStateChange(transactionStates)
|
|
1696
|
+
// Also trigger checkout status update if handler is provided
|
|
1697
|
+
if (checkoutOnHandlers?.triggerCheckoutStatusUpdate) {
|
|
1698
|
+
checkoutOnHandlers.triggerCheckoutStatusUpdate(transactionStates)
|
|
1699
|
+
}
|
|
1629
1700
|
}
|
|
1630
1701
|
if (
|
|
1631
1702
|
transactionStates[2] &&
|
|
@@ -1634,6 +1705,10 @@ export async function handleCrossChain({
|
|
|
1634
1705
|
) {
|
|
1635
1706
|
transactionStates[2].state = "aborted"
|
|
1636
1707
|
onTransactionStateChange(transactionStates)
|
|
1708
|
+
// Also trigger checkout status update if handler is provided
|
|
1709
|
+
if (checkoutOnHandlers?.triggerCheckoutStatusUpdate) {
|
|
1710
|
+
checkoutOnHandlers.triggerCheckoutStatusUpdate(transactionStates)
|
|
1711
|
+
}
|
|
1637
1712
|
}
|
|
1638
1713
|
|
|
1639
1714
|
// Track payment error if transactions didn't complete successfully
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Account, Chain, WalletClient, TransactionReceipt } from "viem"
|
|
2
|
-
import { createPublicClient, http, formatUnits } from "viem"
|
|
2
|
+
import { createPublicClient, http, formatUnits, ethAddress } from "viem"
|
|
3
3
|
import type { TrailsApi } from "@0xsequence/trails-api"
|
|
4
4
|
import type { MetaTxnReceipt, PrepareSendReturn, SendReturn } from "../types.js"
|
|
5
5
|
import type { TransactionState } from "../../transactions.js"
|
|
@@ -21,7 +21,7 @@ import { getTestnetChainInfo } from "../../chains.js"
|
|
|
21
21
|
import { getIsCustomCalldata } from "../../contractUtils.js"
|
|
22
22
|
import {
|
|
23
23
|
buildSameChainSameTokenTransactionParams,
|
|
24
|
-
|
|
24
|
+
quoteIntent,
|
|
25
25
|
commitIntent,
|
|
26
26
|
} from "../../intents.js"
|
|
27
27
|
import { estimateGasLimit } from "../../estimate.js"
|
|
@@ -36,6 +36,7 @@ import { getChainInfo } from "../../chains.js"
|
|
|
36
36
|
import { getTransactionStateFromReceipt } from "../execution/transactionState.js"
|
|
37
37
|
import { calcAmountUsdPrice } from "../../prices.js"
|
|
38
38
|
import { pollIntentReceipt } from "../../intentReceiptPoller.js"
|
|
39
|
+
import { zeroAddress } from "viem"
|
|
39
40
|
|
|
40
41
|
/**
|
|
41
42
|
* @description
|
|
@@ -87,6 +88,7 @@ export async function handleSameChainSameToken({
|
|
|
87
88
|
destinationTokenPriceUsd,
|
|
88
89
|
originNativeTokenPriceUsd,
|
|
89
90
|
slippageTolerance,
|
|
91
|
+
quoteProvider,
|
|
90
92
|
checkoutOnHandlers,
|
|
91
93
|
mode,
|
|
92
94
|
fundMethod,
|
|
@@ -117,7 +119,8 @@ export async function handleSameChainSameToken({
|
|
|
117
119
|
destinationTokenPriceUsd?: number | null
|
|
118
120
|
originNativeTokenPriceUsd?: number | null
|
|
119
121
|
slippageTolerance: string
|
|
120
|
-
|
|
122
|
+
quoteProvider?: string | null
|
|
123
|
+
checkoutOnHandlers?: Partial<CheckoutOnHandlers>
|
|
121
124
|
mode?: "pay" | "fund" | "earn" | "swap" | "receive"
|
|
122
125
|
fundMethod?: string
|
|
123
126
|
paymasterUrl?: string
|
|
@@ -174,7 +177,7 @@ export async function handleSameChainSameToken({
|
|
|
174
177
|
destinationSalt,
|
|
175
178
|
slippageTolerance,
|
|
176
179
|
TradeType.EXACT_INPUT,
|
|
177
|
-
"",
|
|
180
|
+
quoteProvider || "",
|
|
178
181
|
)
|
|
179
182
|
|
|
180
183
|
logger.console.log(
|
|
@@ -182,14 +185,18 @@ export async function handleSameChainSameToken({
|
|
|
182
185
|
intentArgs,
|
|
183
186
|
)
|
|
184
187
|
|
|
185
|
-
const { intent, gasFeeOptions } = await
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
188
|
+
const { intent, gasFeeOptions } = await quoteIntent(
|
|
189
|
+
trailsClient,
|
|
190
|
+
intentArgs,
|
|
191
|
+
{
|
|
192
|
+
originTokenSymbol,
|
|
193
|
+
destinationTokenSymbol,
|
|
194
|
+
feeTokenSymbol: originTokenSymbol,
|
|
195
|
+
},
|
|
196
|
+
)
|
|
190
197
|
|
|
191
|
-
logger.console.log("[trails-sdk]
|
|
192
|
-
logger.console.log("[trails-sdk]
|
|
198
|
+
logger.console.log("[trails-sdk] Quote intent:", intent)
|
|
199
|
+
logger.console.log("[trails-sdk] Quote intent gasFeeOptions:", gasFeeOptions)
|
|
193
200
|
|
|
194
201
|
if (!intent.preconditions?.length || !intent.calls?.length) {
|
|
195
202
|
throw new Error("Invalid intent")
|
|
@@ -280,9 +287,21 @@ export async function handleSameChainSameToken({
|
|
|
280
287
|
// Use runtime selectedFeeToken if provided, otherwise fall back to the one from prepareSend
|
|
281
288
|
const effectiveSelectedFeeToken =
|
|
282
289
|
runtimeSelectedFeeToken ?? selectedFeeToken
|
|
290
|
+
// Check if gasless flow is enabled:
|
|
291
|
+
// - selectedFeeToken must exist and not be null/undefined
|
|
292
|
+
// - tokenAddress must not be native token (zeroAddress or ethAddress)
|
|
293
|
+
// - walletId must not be sequence-waas
|
|
283
294
|
const effectiveGasless =
|
|
284
295
|
effectiveSelectedFeeToken !== null &&
|
|
285
296
|
effectiveSelectedFeeToken !== undefined &&
|
|
297
|
+
effectiveSelectedFeeToken.tokenAddress !== undefined &&
|
|
298
|
+
effectiveSelectedFeeToken.tokenAddress !== null &&
|
|
299
|
+
effectiveSelectedFeeToken.tokenAddress !== zeroAddress &&
|
|
300
|
+
effectiveSelectedFeeToken.tokenAddress.toLowerCase() !==
|
|
301
|
+
zeroAddress.toLowerCase() &&
|
|
302
|
+
effectiveSelectedFeeToken.tokenAddress !== ethAddress &&
|
|
303
|
+
effectiveSelectedFeeToken.tokenAddress.toLowerCase() !==
|
|
304
|
+
ethAddress.toLowerCase() &&
|
|
286
305
|
walletId !== "sequence-waas"
|
|
287
306
|
logger.console.log(
|
|
288
307
|
"[trails-sdk] [FEE-SELECT] [GASLESS-FLOW] send() called for same-chain:",
|
|
@@ -379,7 +398,7 @@ export async function handleSameChainSameToken({
|
|
|
379
398
|
explorerUrl: "",
|
|
380
399
|
chainId: effectiveOriginChainId,
|
|
381
400
|
state: "pending",
|
|
382
|
-
label:
|
|
401
|
+
label: "Deposit",
|
|
383
402
|
}
|
|
384
403
|
|
|
385
404
|
const executeState: TransactionState = {
|
|
@@ -399,6 +418,12 @@ export async function handleSameChainSameToken({
|
|
|
399
418
|
|
|
400
419
|
try {
|
|
401
420
|
onTransactionStateChange(localTransactionStates)
|
|
421
|
+
// Also trigger checkout status update if handler is provided
|
|
422
|
+
if (checkoutOnHandlers?.triggerCheckoutStatusUpdate) {
|
|
423
|
+
checkoutOnHandlers.triggerCheckoutStatusUpdate(
|
|
424
|
+
localTransactionStates,
|
|
425
|
+
)
|
|
426
|
+
}
|
|
402
427
|
} catch (error) {
|
|
403
428
|
logger.console.error(
|
|
404
429
|
"[trails-sdk] Error calling onTransactionStateChange:",
|
|
@@ -447,6 +472,7 @@ export async function handleSameChainSameToken({
|
|
|
447
472
|
executeIntentFn,
|
|
448
473
|
depositRecipientOverride: recipient,
|
|
449
474
|
isSameChainSameToken: true,
|
|
475
|
+
destinationCalldata,
|
|
450
476
|
})
|
|
451
477
|
|
|
452
478
|
// attemptUserDepositTx handles both gasless and non-gasless flows
|
|
@@ -494,6 +520,12 @@ export async function handleSameChainSameToken({
|
|
|
494
520
|
localTransactionStates[0]?.label,
|
|
495
521
|
)
|
|
496
522
|
onTransactionStateChange(localTransactionStates)
|
|
523
|
+
// Also trigger checkout status update if handler is provided
|
|
524
|
+
if (checkoutOnHandlers?.triggerCheckoutStatusUpdate) {
|
|
525
|
+
checkoutOnHandlers.triggerCheckoutStatusUpdate(
|
|
526
|
+
localTransactionStates,
|
|
527
|
+
)
|
|
528
|
+
}
|
|
497
529
|
} catch (error) {
|
|
498
530
|
logger.console.error(
|
|
499
531
|
"[trails-sdk] Error fetching deposit transaction receipt:",
|
|
@@ -531,6 +563,12 @@ export async function handleSameChainSameToken({
|
|
|
531
563
|
localTransactionStates[1]?.label,
|
|
532
564
|
)
|
|
533
565
|
onTransactionStateChange(localTransactionStates)
|
|
566
|
+
// Also trigger checkout status update if handler is provided
|
|
567
|
+
if (checkoutOnHandlers?.triggerCheckoutStatusUpdate) {
|
|
568
|
+
checkoutOnHandlers.triggerCheckoutStatusUpdate(
|
|
569
|
+
localTransactionStates,
|
|
570
|
+
)
|
|
571
|
+
}
|
|
534
572
|
} catch (error) {
|
|
535
573
|
logger.console.error(
|
|
536
574
|
"[trails-sdk] Error fetching origin transaction receipt:",
|
|
@@ -560,6 +598,10 @@ export async function handleSameChainSameToken({
|
|
|
560
598
|
),
|
|
561
599
|
]
|
|
562
600
|
onTransactionStateChange(updatedStates)
|
|
601
|
+
// Also trigger checkout status update if handler is provided
|
|
602
|
+
if (checkoutOnHandlers?.triggerCheckoutStatusUpdate) {
|
|
603
|
+
checkoutOnHandlers.triggerCheckoutStatusUpdate(updatedStates)
|
|
604
|
+
}
|
|
563
605
|
} catch (error) {
|
|
564
606
|
logger.console.error(
|
|
565
607
|
"[trails-sdk] Error calling onTransactionStateChange:",
|