0xtrails 0.4.1 → 0.4.2

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.
Files changed (55) hide show
  1. package/dist/aave.d.ts.map +1 -1
  2. package/dist/{ccip-Bc-mZIIK.js → ccip-Dl3umoGg.js} +5 -5
  3. package/dist/{index-BWGjgMLm.js → index-sMS_ge1R.js} +13956 -13858
  4. package/dist/index.d.ts +1 -1
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +501 -474
  7. package/dist/intents.d.ts +1 -1
  8. package/dist/intents.d.ts.map +1 -1
  9. package/dist/morpho.d.ts.map +1 -1
  10. package/dist/mutations.d.ts +2 -2
  11. package/dist/mutations.d.ts.map +1 -1
  12. package/dist/prepareSend.d.ts.map +1 -1
  13. package/dist/trails.d.ts +9 -10
  14. package/dist/trails.d.ts.map +1 -1
  15. package/dist/transactionIntent/deposits/depositOrchestrator.d.ts +3 -2
  16. package/dist/transactionIntent/deposits/depositOrchestrator.d.ts.map +1 -1
  17. package/dist/transactionIntent/deposits/gaslessDeposit.d.ts +1 -1
  18. package/dist/transactionIntent/deposits/gaslessDeposit.d.ts.map +1 -1
  19. package/dist/transactionIntent/deposits/standardDeposit.d.ts +3 -2
  20. package/dist/transactionIntent/deposits/standardDeposit.d.ts.map +1 -1
  21. package/dist/transactionIntent/handlers/crossChain.d.ts +1 -1
  22. package/dist/transactionIntent/handlers/crossChain.d.ts.map +1 -1
  23. package/dist/transactionIntent/handlers/sameChainSameToken.d.ts +3 -2
  24. package/dist/transactionIntent/handlers/sameChainSameToken.d.ts.map +1 -1
  25. package/dist/transactionIntent/quote/quoteHelpers.d.ts.map +1 -1
  26. package/dist/transactionIntent/types.d.ts +1 -1
  27. package/dist/transactionIntent/types.d.ts.map +1 -1
  28. package/dist/widget/components/FeeOptions.d.ts +2 -1
  29. package/dist/widget/components/FeeOptions.d.ts.map +1 -1
  30. package/dist/widget/components/PoolDeposit.d.ts.map +1 -1
  31. package/dist/widget/hooks/useQuote.d.ts +31 -1
  32. package/dist/widget/hooks/useQuote.d.ts.map +1 -1
  33. package/dist/widget/hooks/useSendForm.d.ts +1 -1
  34. package/dist/widget/hooks/useSendForm.d.ts.map +1 -1
  35. package/dist/widget/index.js +1 -1
  36. package/package.json +7 -7
  37. package/src/aave.ts +1 -0
  38. package/src/index.ts +1 -1
  39. package/src/intents.ts +2 -2
  40. package/src/morpho.ts +3 -2
  41. package/src/mutations.ts +53 -5
  42. package/src/prepareSend.ts +12 -1
  43. package/src/trails.ts +57 -65
  44. package/src/transactionIntent/deposits/depositOrchestrator.ts +4 -1
  45. package/src/transactionIntent/deposits/gaslessDeposit.ts +1 -1
  46. package/src/transactionIntent/deposits/standardDeposit.ts +124 -3
  47. package/src/transactionIntent/handlers/crossChain.ts +14 -9
  48. package/src/transactionIntent/handlers/sameChainSameToken.ts +32 -12
  49. package/src/transactionIntent/quote/quoteHelpers.ts +4 -11
  50. package/src/transactionIntent/types.ts +1 -1
  51. package/src/widget/components/FeeOptions.tsx +2 -1
  52. package/src/widget/components/PoolDeposit.tsx +68 -4
  53. package/src/widget/hooks/useDebugScreens.ts +11 -11
  54. package/src/widget/hooks/useQuote.ts +37 -2
  55. package/src/widget/hooks/useSendForm.ts +2 -2
@@ -43,7 +43,7 @@ import {
43
43
  } from "../../sequenceWallet.js"
44
44
  import { getIntentArgs } from "../quote/quoteHelpers.js"
45
45
  import {
46
- getIntent,
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
@@ -438,13 +438,17 @@ export async function handleCrossChain({
438
438
 
439
439
  logger.console.log("[trails-sdk] Creating intent with args:", intentArgs)
440
440
 
441
- const { intent, gasFeeOptions } = await getIntent(trailsClient, intentArgs, {
442
- originTokenSymbol,
443
- destinationTokenSymbol,
444
- feeTokenSymbol: originTokenSymbol,
445
- })
446
- logger.console.log("[trails-sdk] Got intent:", intent)
447
- logger.console.log("[trails-sdk] Got gasFeeOptions:", gasFeeOptions)
441
+ const { intent, gasFeeOptions } = await quoteIntent(
442
+ trailsClient,
443
+ intentArgs,
444
+ {
445
+ originTokenSymbol,
446
+ destinationTokenSymbol,
447
+ feeTokenSymbol: originTokenSymbol,
448
+ },
449
+ )
450
+ logger.console.log("[trails-sdk] Quote intent:", intent)
451
+ logger.console.log("[trails-sdk] Quote intent gasFeeOptions:", gasFeeOptions)
448
452
 
449
453
  if (!intent.preconditions?.length || !intent.calls?.length) {
450
454
  throw new Error("Invalid intent")
@@ -779,6 +783,7 @@ export async function handleCrossChain({
779
783
  walletId,
780
784
  abortSignal,
781
785
  intentId: intent.intentId,
786
+ executeIntentFn,
782
787
  })
783
788
 
784
789
  // In gasless mode, depositUserTxnReceipt will be null because the transaction
@@ -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
- getIntent,
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
- checkoutOnHandlers?: CheckoutOnHandlers
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
- "", // quoteProvider - empty for same-chain
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 getIntent(trailsClient, intentArgs, {
186
- originTokenSymbol,
187
- destinationTokenSymbol,
188
- feeTokenSymbol: originTokenSymbol,
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] Got intent:", intent)
192
- logger.console.log("[trails-sdk] Got gasFeeOptions:", gasFeeOptions)
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: effectiveGasless ? "Deposit" : "Execute",
401
+ label: "Deposit",
383
402
  }
384
403
 
385
404
  const executeState: TransactionState = {
@@ -447,6 +466,7 @@ export async function handleSameChainSameToken({
447
466
  executeIntentFn,
448
467
  depositRecipientOverride: recipient,
449
468
  isSameChainSameToken: true,
469
+ destinationCalldata,
450
470
  })
451
471
 
452
472
  // attemptUserDepositTx handles both gasless and non-gasless flows
@@ -1,5 +1,4 @@
1
1
  import type { QuoteIntentRequest } from "@0xsequence/trails-api"
2
- import { QuoteProviderType } from "@0xsequence/trails-api"
3
2
  import { getIsCustomCalldata } from "../../contractUtils.js"
4
3
  import type { TradeType } from "../types.js"
5
4
 
@@ -20,8 +19,9 @@ export function getIntentArgs(
20
19
  ): QuoteIntentRequest {
21
20
  const hasCustomCalldata = getIsCustomCalldata(destinationCalldata)
22
21
 
23
- if (!provider || provider === "auto") {
24
- provider = undefined
22
+ let effectiveProvider = provider
23
+ if (provider === "auto") {
24
+ effectiveProvider = undefined
25
25
  }
26
26
 
27
27
  const intentArgs: QuoteIntentRequest = {
@@ -37,14 +37,7 @@ export function getIntentArgs(
37
37
  destinationCallValue: "0",
38
38
  options: {
39
39
  slippageTolerance: Number(slippageTolerance),
40
- quoteProvider:
41
- provider === "relay"
42
- ? QuoteProviderType.RELAY
43
- : provider === "cctp"
44
- ? QuoteProviderType.CCTPV2
45
- : provider === "lifi"
46
- ? QuoteProviderType.LIFI
47
- : undefined,
40
+ quoteProvider: effectiveProvider || undefined,
48
41
  },
49
42
  tradeType,
50
43
  }
@@ -72,7 +72,7 @@ export type PrepareSendOptions = {
72
72
  quoteProvider?: string | null
73
73
  fundMethod?: string
74
74
  mode?: "pay" | "fund" | "earn" | "swap" | "receive"
75
- checkoutOnHandlers?: CheckoutOnHandlers
75
+ checkoutOnHandlers?: Partial<CheckoutOnHandlers>
76
76
  refundAddress?: string
77
77
  selectedFeeToken?: SelectedFeeToken
78
78
  walletId?: string
@@ -11,6 +11,7 @@ import { getTokenImageUrl } from "../../tokens.js"
11
11
  import { TokenImage } from "./TokenImage.js"
12
12
  import { ethAddress, zeroAddress } from "viem"
13
13
  import type { FeeOption as APIFeeOption } from "../../widget/hooks/useSelectedFeeToken.js"
14
+ import { SelectedFeeToken } from "../../prepareSend.js"
14
15
 
15
16
  const ZERO_ADDRESS = zeroAddress.toLowerCase()
16
17
  const ETH_ADDRESS = ethAddress.toLowerCase()
@@ -67,7 +68,7 @@ const safeFormatUsdDisplay = (option: APIFeeOption): string => {
67
68
 
68
69
  interface FeeOptionsProps {
69
70
  feeOptions: APIFeeOption[]
70
- selectedFeeToken: APIFeeOption | null
71
+ selectedFeeToken: APIFeeOption | SelectedFeeToken | null
71
72
  setSelectedFeeToken: (token: APIFeeOption | null) => void
72
73
  chainId?: number
73
74
  isRefetching?: boolean // When true, the fee quote is stale and being refreshed, so hide the component
@@ -5,10 +5,10 @@ import {
5
5
  Search,
6
6
  Loader2,
7
7
  } from "lucide-react"
8
- import { useEffect, useState, useRef } from "react"
8
+ import { useEffect, useState, useRef, useMemo } from "react"
9
9
  import type React from "react"
10
10
  import type { Account, WalletClient } from "viem"
11
- import { zeroAddress } from "viem"
11
+ import { parseUnits, zeroAddress } from "viem"
12
12
  import type { TransactionState } from "../../transactions.js"
13
13
  import type { OnCompleteProps } from "../hooks/useSendForm.js"
14
14
  import type { CheckoutOnHandlers } from "../hooks/useCheckout.js"
@@ -36,6 +36,9 @@ import type { SupportedToken } from "../../tokens.js"
36
36
  import { logger } from "../../logger.js"
37
37
  import { DynamicSizeInputField } from "./DynamicSizeInputField.js"
38
38
  import { FeeOptions } from "./FeeOptions.js"
39
+ import { generateAaveDepositCalldata } from "../../aave.js"
40
+ import { generateMorphoDepositCalldata } from "../../morpho.js"
41
+ import { TRAILS_ROUTER_PLACEHOLDER_AMOUNT } from "../../trailsRouter.js"
39
42
 
40
43
  interface PoolDepositProps {
41
44
  account?: Account
@@ -106,6 +109,67 @@ export const PoolDeposit: React.FC<PoolDepositProps> = ({
106
109
  allSupportedTokens: false,
107
110
  })
108
111
 
112
+ // Memoized generated calldata
113
+ const generatedDepositCalldata = useMemo(() => {
114
+ if (!selectedPool || !amount || !walletClient || Number(amount) <= 0) {
115
+ logger.console.log(
116
+ "Skipping calldata generation: missing pool/amount/wallet or invalid amount",
117
+ )
118
+ return undefined
119
+ }
120
+
121
+ try {
122
+ const decimals = selectedPool.token.decimals
123
+ if (typeof decimals !== "number" || decimals < 0 || decimals > 18) {
124
+ throw new Error(`Invalid decimals: ${decimals}`)
125
+ }
126
+
127
+ // Check if same-chain same-token for direct amount usage
128
+ const isSameChainSameToken =
129
+ originToken &&
130
+ originToken.chainId === selectedPool.chainId &&
131
+ (originToken.contractAddress ?? zeroAddress).toLowerCase() ===
132
+ selectedPool.token.address.toLowerCase()
133
+
134
+ let amountForCalldata: string
135
+ if (isSameChainSameToken) {
136
+ // Parse real amount with pool decimals for direct deposit
137
+ const parsedAmount = parseUnits(amount, decimals)
138
+ amountForCalldata = parsedAmount.toString()
139
+ logger.console.log(
140
+ `Same-chain same-token deposit: Parsed amount: ${amount} -> ${parsedAmount} wei (decimals: ${decimals})`,
141
+ )
142
+ } else {
143
+ // Use placeholder for wrapping in routed flows
144
+ amountForCalldata = TRAILS_ROUTER_PLACEHOLDER_AMOUNT.toString()
145
+ logger.console.log(
146
+ `Routed deposit (different-token or cross-chain): Using placeholder for ${selectedPool.protocol} pool: ${selectedPool.name}`,
147
+ )
148
+ }
149
+
150
+ logger.console.log(
151
+ `Generating deposit calldata for ${selectedPool.protocol} pool: ${selectedPool.name} (amount: ${amountForCalldata})`,
152
+ )
153
+
154
+ switch (selectedPool.protocol.toLowerCase()) {
155
+ case "aave":
156
+ return generateAaveDepositCalldata(
157
+ walletClient,
158
+ selectedPool,
159
+ amountForCalldata,
160
+ )
161
+ case "morpho":
162
+ return generateMorphoDepositCalldata(walletClient, amountForCalldata)
163
+ default:
164
+ logger.console.warn(`Unsupported protocol: ${selectedPool.protocol}`)
165
+ return undefined
166
+ }
167
+ } catch (error) {
168
+ logger.console.error("Error generating deposit calldata:", error)
169
+ return undefined
170
+ }
171
+ }, [walletClient, selectedPool, amount, originToken])
172
+
109
173
  // Use useSendForm for quote functionality when both token and pool are selected
110
174
  const {
111
175
  balanceFormatted,
@@ -125,7 +189,7 @@ export const PoolDeposit: React.FC<PoolDepositProps> = ({
125
189
  toRecipient: selectedPool?.depositAddress,
126
190
  toChainId: selectedPool?.chainId,
127
191
  toToken: selectedPool?.token.address,
128
- toCalldata: undefined,
192
+ toCalldata: generatedDepositCalldata,
129
193
  walletClient,
130
194
  onTransactionStateChange,
131
195
  onError,
@@ -521,7 +585,7 @@ export const PoolDeposit: React.FC<PoolDepositProps> = ({
521
585
  {/* Fee Options */}
522
586
  <FeeOptions
523
587
  feeOptions={feeOptions || []}
524
- selectedFeeToken={selectedFeeToken}
588
+ selectedFeeToken={selectedFeeToken as any}
525
589
  setSelectedFeeToken={(token) => setSelectedFeeToken(token as any)}
526
590
  chainId={originToken?.chainId}
527
591
  isRefetching={isLoadingQuote}
@@ -182,7 +182,7 @@ export const useDebugScreens = ({
182
182
  "https://polygonscan.com/tx/0x45bb2259631e73f32841a6058b0a4008c75bca296942bec6326d188978d5353d",
183
183
  chainId: 137,
184
184
  state: "pending",
185
- label: "Transfer",
185
+ label: "Deposit",
186
186
  },
187
187
  {
188
188
  transactionHash:
@@ -207,7 +207,7 @@ export const useDebugScreens = ({
207
207
  "https://polygonscan.com/tx/0x45bb2259631e73f32841a6058b0a4008c75bca296942bec6326d188978d5353d",
208
208
  chainId: 137,
209
209
  state: "confirmed",
210
- label: "Transfer",
210
+ label: "Deposit",
211
211
  },
212
212
  {
213
213
  transactionHash:
@@ -232,7 +232,7 @@ export const useDebugScreens = ({
232
232
  "https://polygonscan.com/tx/0x45bb2259631e73f32841a6058b0a4008c75bca296942bec6326d188978d5353d",
233
233
  chainId: 137,
234
234
  state: "confirmed",
235
- label: "Transfer",
235
+ label: "Deposit",
236
236
  },
237
237
  {
238
238
  transactionHash:
@@ -257,7 +257,7 @@ export const useDebugScreens = ({
257
257
  "https://polygonscan.com/tx/0x45bb2259631e73f32841a6058b0a4008c75bca296942bec6326d188978d5353d",
258
258
  chainId: 137,
259
259
  state: "pending",
260
- label: "Transfer",
260
+ label: "Deposit",
261
261
  },
262
262
  {
263
263
  transactionHash:
@@ -291,7 +291,7 @@ export const useDebugScreens = ({
291
291
  "https://polygonscan.com/tx/0x45bb2259631e73f32841a6058b0a4008c75bca296942bec6326d188978d5353d",
292
292
  chainId: 137,
293
293
  state: "confirmed",
294
- label: "Transfer",
294
+ label: "Deposit",
295
295
  },
296
296
  {
297
297
  transactionHash:
@@ -325,7 +325,7 @@ export const useDebugScreens = ({
325
325
  "https://polygonscan.com/tx/0x45bb2259631e73f32841a6058b0a4008c75bca296942bec6326d188978d5353d",
326
326
  chainId: 137,
327
327
  state: "confirmed",
328
- label: "Transfer",
328
+ label: "Deposit",
329
329
  },
330
330
  {
331
331
  transactionHash:
@@ -359,7 +359,7 @@ export const useDebugScreens = ({
359
359
  "https://polygonscan.com/tx/0x45bb2259631e73f32841a6058b0a4008c75bca296942bec6326d188978d5353d",
360
360
  chainId: 137,
361
361
  state: "confirmed",
362
- label: "Transfer",
362
+ label: "Deposit",
363
363
  },
364
364
  {
365
365
  transactionHash:
@@ -393,7 +393,7 @@ export const useDebugScreens = ({
393
393
  "https://polygonscan.com/tx/0x45bb2259631e73f32841a6058b0a4008c75bca296942bec6326d188978d5353d",
394
394
  chainId: 137,
395
395
  state: "confirmed",
396
- label: "Transfer",
396
+ label: "Deposit",
397
397
  },
398
398
  {
399
399
  transactionHash:
@@ -436,7 +436,7 @@ export const useDebugScreens = ({
436
436
  "https://polygonscan.com/tx/0x45bb2259631e73f32841a6058b0a4008c75bca296942bec6326d188978d5353d",
437
437
  chainId: 137,
438
438
  state: "confirmed",
439
- label: "Transfer",
439
+ label: "Deposit",
440
440
  },
441
441
  {
442
442
  transactionHash:
@@ -470,7 +470,7 @@ export const useDebugScreens = ({
470
470
  "https://polygonscan.com/tx/0x45bb2259631e73f32841a6058b0a4008c75bca296942bec6326d188978d5353d",
471
471
  chainId: 137,
472
472
  state: "confirmed",
473
- label: "Transfer",
473
+ label: "Deposit",
474
474
  },
475
475
  {
476
476
  transactionHash:
@@ -502,7 +502,7 @@ export const useDebugScreens = ({
502
502
  "https://polygonscan.com/tx/0x45bb2259631e73f32841a6058b0a4008c75bca296942bec6326d188978d5353d",
503
503
  chainId: 137,
504
504
  state: "confirmed",
505
- label: "Transfer",
505
+ label: "Deposit",
506
506
  },
507
507
  {
508
508
  transactionHash:
@@ -15,7 +15,10 @@ import { TradeType } from "../../prepareSend.js"
15
15
  import { getChainInfo } from "../../chains.js"
16
16
  import type { TrailsClientConfig } from "../../trailsClient.js"
17
17
  import type { IndexerGatewayConfig } from "../../indexerClient.js"
18
- import type { MetaTxnReceipt } from "../../transactionIntent/types.js"
18
+ import type {
19
+ MetaTxnReceipt,
20
+ PrepareSendOptions,
21
+ } from "../../transactionIntent/types.js"
19
22
  import type { Chain } from "../../chains.js"
20
23
  import type { SupportedToken } from "../../tokens.js"
21
24
  import type { TransactionState } from "../../transactions.js"
@@ -23,6 +26,7 @@ import type { PrepareSendFees } from "../../prepareSend.js"
23
26
  import type { SequenceEnv } from "../../config.js"
24
27
  import { getTokenPrice } from "../../prices.js"
25
28
  import { useCommitIntent, useExecuteIntent } from "../../mutations.js"
29
+ import type { CheckoutOnHandlers } from "./useCheckout.js"
26
30
 
27
31
  export type UseQuoteProps = {
28
32
  walletClient?: any // TODO: fix this, has to do with viem/wagmi versions
@@ -37,6 +41,35 @@ export type UseQuoteProps = {
37
41
  slippageTolerance?: string | number | null
38
42
  onStatusUpdate?: ((transactionStates: TransactionState[]) => void) | null
39
43
  quoteProvider?: string | null
44
+ /**
45
+ * Optional checkout event handlers for tracking the states of a Trails transaction.
46
+ *
47
+ * @example
48
+ * ```ts
49
+ * checkoutOnHandlers: {
50
+ * triggerCheckoutStart: () => {
51
+ * console.log('Checkout started')
52
+ * },
53
+ * triggerCheckoutQuote: (quote) => {
54
+ * console.log('Quote received:', quote)
55
+ * },
56
+ * triggerCheckoutComplete: (status, accountAddress) => {
57
+ * console.log('Checkout completed:', status, accountAddress)
58
+ * }
59
+ * }
60
+ * ```
61
+ *
62
+ * Available handlers:
63
+ * - `triggerCheckoutStart`
64
+ * - `triggerCheckoutQuote`
65
+ * - `triggerCheckoutSignatureRequest`
66
+ * - `triggerCheckoutSignatureConfirmed`
67
+ * - `triggerCheckoutSignatureRejected`
68
+ * - `triggerCheckoutComplete`
69
+ * - `triggerCheckoutError`
70
+ * - `triggerCheckoutStatusUpdate`
71
+ */
72
+ checkoutOnHandlers?: Partial<CheckoutOnHandlers>
40
73
  paymasterUrl?: string
41
74
  selectedFeeToken?: {
42
75
  tokenAddress: string
@@ -114,6 +147,7 @@ export function useQuote({
114
147
  toCalldata,
115
148
  slippageTolerance,
116
149
  onStatusUpdate,
150
+ checkoutOnHandlers,
117
151
  quoteProvider,
118
152
  paymasterUrl,
119
153
  selectedFeeToken,
@@ -325,7 +359,7 @@ export function useQuote({
325
359
  const destinationTokenSymbol = destinationToken?.symbol ?? ""
326
360
  const originTokenSymbol = originToken?.symbol ?? ""
327
361
 
328
- const options = {
362
+ const options: PrepareSendOptions = {
329
363
  account: walletClient.account!,
330
364
  originTokenAddress: fromTokenAddress,
331
365
  originChainId: fromChainId,
@@ -353,6 +387,7 @@ export function useQuote({
353
387
  originNativeTokenPriceUsd: originNativeTokenPriceUsd,
354
388
  commitIntentFn: commitIntentMutation.mutateAsync,
355
389
  executeIntentFn: executeIntentMutation.mutateAsync,
390
+ checkoutOnHandlers,
356
391
  }
357
392
 
358
393
  logger.console.log("[trails-sdk] options", options)
@@ -163,7 +163,7 @@ export type UseSendReturn = {
163
163
  destTokenPrices: TokenPrice[] | null
164
164
  sourceTokenPrices: TokenPrice[] | null
165
165
  selectedToken?: Token
166
- selectedFeeToken: SelectedFeeToken | undefined
166
+ selectedFeeToken: SelectedFeeToken | null
167
167
  setIsChainDropdownOpen: (isOpen: boolean) => void
168
168
  setIsTokenDropdownOpen: (isOpen: boolean) => void
169
169
  toAmountFormatted: string
@@ -1336,7 +1336,7 @@ export function useSendForm({
1336
1336
  destTokenPrices: destTokenPrices ?? null,
1337
1337
  sourceTokenPrices: sourceTokenPrices ?? null,
1338
1338
  selectedToken,
1339
- selectedFeeToken: selectedFeeToken ?? undefined,
1339
+ selectedFeeToken: selectedFeeToken ?? null,
1340
1340
  setIsChainDropdownOpen,
1341
1341
  setIsTokenDropdownOpen,
1342
1342
  toAmountFormatted: quotedDestinationAmount,