0xtrails 0.2.1 → 0.2.4

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 (87) hide show
  1. package/dist/aave.d.ts.map +1 -1
  2. package/dist/{ccip-BbfANth7.js → ccip-BlV1Mry3.js} +1 -1
  3. package/dist/chains.d.ts +5 -1
  4. package/dist/chains.d.ts.map +1 -1
  5. package/dist/constants.d.ts +4 -4
  6. package/dist/constants.d.ts.map +1 -1
  7. package/dist/{index-WpIVoh3X.js → index-BNWCIGfQ.js} +49015 -46131
  8. package/dist/index.d.ts +4 -3
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +2 -2
  11. package/dist/intentEntrypoint.d.ts +0 -8
  12. package/dist/intentEntrypoint.d.ts.map +1 -1
  13. package/dist/metaTxnMonitor.d.ts +5 -4
  14. package/dist/metaTxnMonitor.d.ts.map +1 -1
  15. package/dist/metaTxns.d.ts +3 -3
  16. package/dist/metaTxns.d.ts.map +1 -1
  17. package/dist/prepareSend.d.ts +3 -3
  18. package/dist/prepareSend.d.ts.map +1 -1
  19. package/dist/relayer.d.ts +10 -7
  20. package/dist/relayer.d.ts.map +1 -1
  21. package/dist/sequenceWallet.d.ts +3 -2
  22. package/dist/sequenceWallet.d.ts.map +1 -1
  23. package/dist/tokenBalances.d.ts +7 -0
  24. package/dist/tokenBalances.d.ts.map +1 -1
  25. package/dist/tokens.d.ts +2 -1
  26. package/dist/tokens.d.ts.map +1 -1
  27. package/dist/trails.d.ts +2 -2
  28. package/dist/trails.d.ts.map +1 -1
  29. package/dist/widget/components/AccountActionsDropdown.d.ts.map +1 -1
  30. package/dist/widget/components/AccountSettings.d.ts.map +1 -1
  31. package/dist/widget/components/ConnectWallet.d.ts.map +1 -1
  32. package/dist/widget/components/EarnPools.d.ts.map +1 -1
  33. package/dist/widget/components/Fund.d.ts +1 -0
  34. package/dist/widget/components/Fund.d.ts.map +1 -1
  35. package/dist/widget/components/Pay.d.ts +1 -0
  36. package/dist/widget/components/Pay.d.ts.map +1 -1
  37. package/dist/widget/components/Recipients.d.ts.map +1 -1
  38. package/dist/widget/components/RefundWarning.d.ts +1 -0
  39. package/dist/widget/components/RefundWarning.d.ts.map +1 -1
  40. package/dist/widget/hooks/useBack.d.ts +5 -0
  41. package/dist/widget/hooks/useBack.d.ts.map +1 -1
  42. package/dist/widget/hooks/useDefaultTokenSelection.d.ts.map +1 -1
  43. package/dist/widget/hooks/useInitialRedirect.d.ts +7 -0
  44. package/dist/widget/hooks/useInitialRedirect.d.ts.map +1 -0
  45. package/dist/widget/hooks/useSelectedFeeToken.d.ts.map +1 -1
  46. package/dist/widget/hooks/useTokenList.d.ts.map +1 -1
  47. package/dist/widget/index.js +1 -1
  48. package/dist/widget/widget.d.ts.map +1 -1
  49. package/package.json +18 -17
  50. package/src/aave.ts +90 -74
  51. package/src/chains.ts +23 -3
  52. package/src/constants.ts +10 -17
  53. package/src/error.ts +1 -1
  54. package/src/index.ts +8 -3
  55. package/src/intentEntrypoint.ts +0 -15
  56. package/src/metaTxnMonitor.ts +28 -22
  57. package/src/metaTxns.ts +5 -3
  58. package/src/prepareSend.ts +217 -286
  59. package/src/relayer.ts +15 -16
  60. package/src/sequenceWallet.ts +7 -3
  61. package/src/tokenBalances.ts +55 -1
  62. package/src/tokens.ts +10 -0
  63. package/src/trails.ts +2 -2
  64. package/src/widget/compiled.css +1 -1
  65. package/src/widget/components/AccountActionsDropdown.tsx +6 -2
  66. package/src/widget/components/AccountIntentTransactionHistory.tsx +1 -1
  67. package/src/widget/components/AccountSettings.tsx +5 -4
  68. package/src/widget/components/ChainFilterDropdown.tsx +1 -1
  69. package/src/widget/components/ChainList.tsx +1 -1
  70. package/src/widget/components/ConnectWallet.tsx +6 -2
  71. package/src/widget/components/EarnPools.tsx +2 -1
  72. package/src/widget/components/Fund.tsx +50 -27
  73. package/src/widget/components/Pay.tsx +24 -1
  74. package/src/widget/components/Receive.tsx +1 -1
  75. package/src/widget/components/Recipients.tsx +4 -2
  76. package/src/widget/components/RefundWarning.tsx +5 -1
  77. package/src/widget/components/SwapSettings.tsx +9 -9
  78. package/src/widget/components/TokenSelector.tsx +1 -1
  79. package/src/widget/components/WalletList.tsx +3 -3
  80. package/src/widget/hooks/useBack.tsx +111 -9
  81. package/src/widget/hooks/useDefaultTokenSelection.tsx +5 -1
  82. package/src/widget/hooks/useInitialRedirect.tsx +70 -0
  83. package/src/widget/hooks/useSelectedFeeToken.tsx +10 -16
  84. package/src/widget/hooks/useSendForm.ts +10 -10
  85. package/src/widget/hooks/useTokenList.ts +11 -2
  86. package/src/widget/widget.tsx +85 -106
  87. /package/dist/{style.css → 0xtrails.css} +0 -0
@@ -4,7 +4,6 @@ import type {
4
4
  IntentPrecondition,
5
5
  } from "@0xsequence/trails-api"
6
6
  import type { TrailsAPIClient } from "@0xsequence/trails-api"
7
- import type { Relayer } from "@0xsequence/wallet-core"
8
7
  import { useQuery } from "@tanstack/react-query"
9
8
  import type {
10
9
  Account,
@@ -56,26 +55,22 @@ import {
56
55
  getSlippageTolerance,
57
56
  type SequenceEnv,
58
57
  } from "./config.js"
59
- import { intentEntrypoints } from "./constants.js"
58
+ import { TRAILS_INTENT_ENTRYPOINT_ADDRESS } from "./constants.js"
60
59
  import {
61
60
  decodeGuestModuleEvents,
62
61
  decodeTrailsTokenSweeperEvents,
63
62
  } from "./decoders.js"
64
63
  import { getERC20TransferData } from "./encoders.js"
65
- import { InsufficientBalanceError } from "./error.js"
64
+ import { getFullErrorMessage, InsufficientBalanceError } from "./error.js"
66
65
  import { estimateGasCostUsd } from "./estimate.js"
67
66
  import { getExplorerUrl } from "./explorer.js"
68
67
  import {
69
68
  getNeedsIntentEntrypointApproval,
70
- getPermitCalls,
71
69
  getPermitSignature,
72
70
  getUserNonce,
73
71
  signIntent,
74
72
  } from "./gasless.js"
75
- import {
76
- getIntentEntrypointFeeOptions,
77
- isIntentEntrypointSupported,
78
- } from "./intentEntrypoint.js"
73
+ import { getIntentEntrypointFeeOptions } from "./intentEntrypoint.js"
79
74
  import { useIndexerGatewayClient } from "./indexerClient.js"
80
75
  import {
81
76
  commitIntentConfig,
@@ -86,11 +81,6 @@ import type { IntentRequestParams } from "./intents.js"
86
81
  import type { MetaTxn } from "./metaTxnMonitor.js"
87
82
  import { getMetaTxStatus } from "./metaTxnMonitor.js"
88
83
  import { relayerSendMetaTx } from "./metaTxns.js"
89
- import {
90
- getDelegatorSmartAccount,
91
- getPaymasterGaslessTransaction,
92
- sendPaymasterGaslessTransaction,
93
- } from "./paymasterSend.js"
94
84
  import { findFirstPreconditionForChainId } from "./preconditions.js"
95
85
  import { calcAmountUsdPrice, getTokenPrice } from "./prices.js"
96
86
  import { getQueryParam } from "./queryParams.js"
@@ -136,6 +126,12 @@ import { getIsCustomCalldata } from "./contractUtils.js"
136
126
  import type { SequenceAPIClient } from "@0xsequence/api"
137
127
  import { useTrailsClient } from "./trailsClient.js"
138
128
  import { updatePersistentToast } from "./toast.js"
129
+ import {
130
+ getDelegatorSmartAccount,
131
+ getPaymasterGaslessTransaction,
132
+ sendPaymasterGaslessTransaction,
133
+ } from "./paymasterSend.js"
134
+ import type { RpcRelayer } from "@0xsequence/relayer"
139
135
 
140
136
  export enum TradeType {
141
137
  EXACT_INPUT = "EXACT_INPUT",
@@ -160,8 +156,8 @@ export type PrepareSendOptions = {
160
156
  dryMode: boolean
161
157
  apiClient: SequenceAPIClient
162
158
  trailsClient: TrailsAPIClient
163
- originRelayer: Relayer.Standard.Rpc.RpcRelayer
164
- destinationRelayer: Relayer.Standard.Rpc.RpcRelayer
159
+ originRelayer: RpcRelayer.RpcRelayer
160
+ destinationRelayer: RpcRelayer.RpcRelayer
165
161
  destinationCalldata?: string
166
162
  onTransactionStateChange: (transactionStates: TransactionState[]) => void
167
163
  sourceTokenPriceUsd?: number | null
@@ -757,8 +753,8 @@ async function sendHandlerForDifferentChainDifferentToken({
757
753
  destinationTokenDecimals: number
758
754
  gasless: boolean
759
755
  paymasterUrl?: string
760
- originRelayer: Relayer.Standard.Rpc.RpcRelayer
761
- destinationRelayer: Relayer.Standard.Rpc.RpcRelayer
756
+ originRelayer: RpcRelayer.RpcRelayer
757
+ destinationRelayer: RpcRelayer.RpcRelayer
762
758
  walletClient: WalletClient
763
759
  publicClient: PublicClient
764
760
  chain: Chain
@@ -1166,28 +1162,19 @@ async function sendHandlerForDifferentChainDifferentToken({
1166
1162
  "[trails-sdk] [GASLESS-FLOW] [FEE-SELECT] Gasless enabled and fundMethod is wallet, checking intent entrypoint support for chain:",
1167
1163
  originChainId,
1168
1164
  )
1169
- if (isIntentEntrypointSupported(originChainId)) {
1170
- logger.console.log(
1171
- "[trails-sdk] [GASLESS-FLOW] [FEE-SELECT] Chain supported, fetching fee options...",
1172
- )
1173
- intentEntrypointFeeOptions = await getIntentEntrypointFeeOptions({
1174
- trailsClient,
1175
- userAddress: mainSignerAddress as `0x${string}`,
1176
- tokenAddress: originTokenAddress as `0x${string}`,
1177
- amount: depositAmount,
1178
- intentAddress: originIntentAddress as `0x${string}`,
1179
- chainId: originChainId,
1180
- })
1181
- logger.console.log(
1182
- "[trails-sdk] [GASLESS-FLOW] [FEE-SELECT] Intent entrypoint fee options:",
1183
- intentEntrypointFeeOptions,
1184
- )
1185
- } else {
1186
- logger.console.log(
1187
- "[trails-sdk] [GASLESS-FLOW] [FEE-SELECT] Chain not supported for intent entrypoint:",
1188
- originChainId,
1189
- )
1190
- }
1165
+
1166
+ intentEntrypointFeeOptions = await getIntentEntrypointFeeOptions({
1167
+ trailsClient,
1168
+ userAddress: mainSignerAddress as `0x${string}`,
1169
+ tokenAddress: originTokenAddress as `0x${string}`,
1170
+ amount: depositAmount,
1171
+ intentAddress: originIntentAddress as `0x${string}`,
1172
+ chainId: originChainId,
1173
+ })
1174
+ logger.console.log(
1175
+ "[trails-sdk] [GASLESS-FLOW] [FEE-SELECT] Intent entrypoint fee options:",
1176
+ intentEntrypointFeeOptions,
1177
+ )
1191
1178
  } catch (error) {
1192
1179
  logger.console.error(
1193
1180
  "[trails-sdk] [GASLESS-FLOW] [FEE-SELECT] Error getting intent entrypoint fee options:",
@@ -2806,7 +2793,7 @@ async function attemptGaslessDeposit({
2806
2793
  chain: Chain
2807
2794
  account: Account
2808
2795
  trailsClient: TrailsAPIClient
2809
- originRelayer: Relayer.Standard.Rpc.RpcRelayer
2796
+ originRelayer: RpcRelayer.RpcRelayer
2810
2797
  feeOptions: any
2811
2798
  selectedFeeToken?: any
2812
2799
  }): Promise<TransactionReceipt | null> {
@@ -2833,29 +2820,28 @@ async function attemptGaslessDeposit({
2833
2820
  transport: http(),
2834
2821
  })
2835
2822
 
2836
- const intentEntrypoint = intentEntrypoints[chain.id]
2837
2823
  logger.console.log("[trails-sdk] [GASLESS-FLOW] Intent entrypoint check:", {
2838
2824
  chainId: chain.id,
2839
2825
  chainName: chain.name,
2840
- intentEntrypoint,
2841
- hasIntentEntrypoint: !!intentEntrypoint,
2842
- availableChains: Object.keys(intentEntrypoints).map(Number),
2826
+ intentEntrypoint: TRAILS_INTENT_ENTRYPOINT_ADDRESS,
2843
2827
  })
2844
2828
 
2845
- // If intent entrypoint is not available, fall back to old flow
2846
- if (!intentEntrypoint) {
2847
- logger.console.warn(
2848
- `[trails-sdk] ⚠️ No intent entrypoint configured for chain ${chain.id} (${chain.name}). ` +
2849
- `Gasless deposits with fee options are only supported on chains: ${Object.keys(intentEntrypoints).join(", ")}. ` +
2850
- `Falling back to old flow (permit2/paymaster).`,
2851
- )
2829
+ // NEW FLOW: Use Intent Entrypoint API with permit2 support
2830
+ logger.console.log(
2831
+ "[trails-sdk] Using Intent Entrypoint API flow with permit2 support for gasless deposit",
2832
+ )
2852
2833
 
2853
- let calls: Array<{
2854
- to: string
2855
- data: string
2856
- value: string
2857
- }> = []
2834
+ // Switch to correct chain before requesting signatures
2835
+ logger.console.log(
2836
+ "[trails-sdk] [GASLESS-FLOW] Switching to chain before permit/intent signatures",
2837
+ { originChainId },
2838
+ )
2839
+ await attemptSwitchChain({
2840
+ walletClient,
2841
+ desiredChainId: originChainId,
2842
+ })
2858
2843
 
2844
+ try {
2859
2845
  if (paymasterUrl) {
2860
2846
  logger.console.log(
2861
2847
  "[trails-sdk] [GASLESS-FLOW] doing gasless with paymaster",
@@ -2874,7 +2860,11 @@ async function attemptGaslessDeposit({
2874
2860
  publicClient,
2875
2861
  })
2876
2862
 
2877
- calls = await getPaymasterGaslessTransaction({
2863
+ const calls: Array<{
2864
+ to: string
2865
+ data: string
2866
+ value: string
2867
+ }> = await getPaymasterGaslessTransaction({
2878
2868
  walletClient,
2879
2869
  chain,
2880
2870
  tokenAddress: depositTokenAddress as `0x${string}`,
@@ -2903,91 +2893,8 @@ async function attemptGaslessDeposit({
2903
2893
  })
2904
2894
  logger.console.log("[trails-sdk] receipt", receipt)
2905
2895
  return receipt
2906
- } else {
2907
- logger.console.log(
2908
- "[trails-sdk] [GASLESS-FLOW] doing gasless with sequence wallet",
2909
- )
2910
- const delegatorPrivateKey = generatePrivateKey()
2911
- const delegatorAccount = privateKeyToAccount(delegatorPrivateKey)
2912
- const delegatorClient = createWalletClient({
2913
- account: delegatorAccount,
2914
- chain,
2915
- transport: http(),
2916
- })
2917
-
2918
- logger.console.log("[trails-sdk] attempting to switch chain")
2919
- await attemptSwitchChain({
2920
- walletClient,
2921
- desiredChainId: originChainId,
2922
- })
2923
-
2924
- logger.console.log("[trails-sdk] creating sequence wallet")
2925
- const sequenceWalletAddress = await simpleCreateSequenceWallet(
2926
- delegatorAccount as any,
2927
- )
2928
- logger.console.log(
2929
- "[trails-sdk] sequenceWalletAddress",
2930
- sequenceWalletAddress,
2931
- )
2932
-
2933
- const { signature, deadline } = await getPermitSignature({
2934
- publicClient,
2935
- walletClient,
2936
- signer: account.address,
2937
- spender: sequenceWalletAddress,
2938
- tokenAddress: depositTokenAddress as `0x${string}`,
2939
- amount: BigInt(depositTokenAmount),
2940
- chain,
2941
- })
2942
-
2943
- calls = getPermitCalls(
2944
- account.address,
2945
- sequenceWalletAddress,
2946
- BigInt(depositTokenAmount),
2947
- deadline,
2948
- signature,
2949
- depositRecipient as `0x${string}`,
2950
- depositTokenAddress as `0x${string}`,
2951
- )
2952
-
2953
- logger.console.log("[trails-sdk] calls", calls)
2954
-
2955
- const sequenceTxHash = await sequenceSendTransaction(
2956
- sequenceWalletAddress,
2957
- delegatorClient,
2958
- publicClient,
2959
- calls,
2960
- chain,
2961
- )
2962
- logger.console.log("[trails-sdk] sequenceTxHash", sequenceTxHash)
2963
- if (onOriginSend) {
2964
- onOriginSend()
2965
- }
2966
-
2967
- const receipt = await publicClient.waitForTransactionReceipt({
2968
- hash: sequenceTxHash as `0x${string}`,
2969
- })
2970
- logger.console.log("[trails-sdk] receipt", receipt)
2971
- return receipt
2972
2896
  }
2973
- }
2974
-
2975
- // NEW FLOW: Use Intent Entrypoint API with permit2 support
2976
- logger.console.log(
2977
- "[trails-sdk] Using Intent Entrypoint API flow with permit2 support for gasless deposit",
2978
- )
2979
-
2980
- // Switch to correct chain before requesting signatures
2981
- logger.console.log(
2982
- "[trails-sdk] [GASLESS-FLOW] Switching to chain before permit/intent signatures",
2983
- { originChainId },
2984
- )
2985
- await attemptSwitchChain({
2986
- walletClient,
2987
- desiredChainId: originChainId,
2988
- })
2989
2897
 
2990
- try {
2991
2898
  const deadline = Math.floor(Date.now() / 1000) + 3600 // 1 hour from now
2992
2899
  const hasFeeOptions = Boolean(
2993
2900
  feeOptions && feeOptions.feeOptions?.length > 0,
@@ -3037,7 +2944,7 @@ async function attemptGaslessDeposit({
3037
2944
  client: publicClient,
3038
2945
  token: depositTokenAddress as `0x${string}`,
3039
2946
  account: account.address,
3040
- entrypoint: intentEntrypoint as `0x${string}`,
2947
+ entrypoint: TRAILS_INTENT_ENTRYPOINT_ADDRESS,
3041
2948
  amount: requiredAmount, // Check if we have enough allowance for this specific transaction
3042
2949
  })
3043
2950
 
@@ -3078,7 +2985,7 @@ async function attemptGaslessDeposit({
3078
2985
  publicClient,
3079
2986
  walletClient,
3080
2987
  signer: account.address,
3081
- spender: intentEntrypoint as `0x${string}`,
2988
+ spender: TRAILS_INTENT_ENTRYPOINT_ADDRESS,
3082
2989
  tokenAddress: depositTokenAddress as `0x${string}`,
3083
2990
  amount: permitAmount, // Infinite approval
3084
2991
  chain,
@@ -3096,7 +3003,7 @@ async function attemptGaslessDeposit({
3096
3003
  const nonce = await getUserNonce({
3097
3004
  publicClient,
3098
3005
  userAddress: account.address,
3099
- intentEntrypoint: intentEntrypoint as `0x${string}`,
3006
+ intentEntrypoint: TRAILS_INTENT_ENTRYPOINT_ADDRESS,
3100
3007
  })
3101
3008
  logger.console.log("[trails-sdk] User nonce:", nonce.toString())
3102
3009
 
@@ -3128,7 +3035,7 @@ async function attemptGaslessDeposit({
3128
3035
  intentAddress: depositRecipient as `0x${string}`,
3129
3036
  deadline: BigInt(deadline),
3130
3037
  chainId: originChainId,
3131
- contractAddress: intentEntrypoint as `0x${string}`,
3038
+ contractAddress: TRAILS_INTENT_ENTRYPOINT_ADDRESS,
3132
3039
  nonce,
3133
3040
  feeAmount: BigInt(selectedFeeOption?.amount || "0"),
3134
3041
  feeCollector: feeCollectorAddress,
@@ -3593,7 +3500,7 @@ async function attemptUserDepositTx({
3593
3500
  paymasterUrl?: string
3594
3501
  chain: Chain
3595
3502
  account: Account
3596
- originRelayer: Relayer.Standard.Rpc.RpcRelayer
3503
+ originRelayer: RpcRelayer.RpcRelayer
3597
3504
  firstPreconditionMin: string
3598
3505
  originIntentAddress: string
3599
3506
  onOriginSend?: () => void
@@ -3856,7 +3763,7 @@ async function sendMetaTxAndWaitForReceipt({
3856
3763
  feeQuote,
3857
3764
  }: {
3858
3765
  metaTx: MetaTxn
3859
- relayer: Relayer.Standard.Rpc.RpcRelayer
3766
+ relayer: RpcRelayer.RpcRelayer
3860
3767
  precondition: IntentPrecondition | null
3861
3768
  feeQuote?: string
3862
3769
  }): Promise<{
@@ -4209,158 +4116,182 @@ export function useQuote({
4209
4116
  quoteProvider,
4210
4117
  ],
4211
4118
  queryFn: async () => {
4212
- if (
4213
- !walletClient ||
4214
- !apiClient ||
4215
- !trailsClient ||
4216
- !fromTokenAddress ||
4217
- !toTokenAddress ||
4218
- !swapAmount ||
4219
- !toRecipient ||
4220
- !fromChainId ||
4221
- !toChainId ||
4222
- !indexerGatewayClient
4223
- ) {
4224
- return null
4225
- }
4119
+ try {
4120
+ if (
4121
+ !walletClient ||
4122
+ !apiClient ||
4123
+ !trailsClient ||
4124
+ !fromTokenAddress ||
4125
+ !toTokenAddress ||
4126
+ !swapAmount ||
4127
+ !toRecipient ||
4128
+ !fromChainId ||
4129
+ !toChainId ||
4130
+ !indexerGatewayClient
4131
+ ) {
4132
+ return null
4133
+ }
4226
4134
 
4227
- // Get token balance using async method
4228
- const { balances } = await getTokenBalancesWithPrices({
4229
- account: walletClient.account!.address,
4230
- indexerGatewayClient,
4231
- apiClient,
4232
- })
4135
+ // Get token balance using async method
4136
+ const { balances } = await getTokenBalancesWithPrices({
4137
+ account: walletClient.account!.address,
4138
+ indexerGatewayClient,
4139
+ apiClient,
4140
+ })
4233
4141
 
4234
- const originTokenBalance = balances.find(
4235
- (b) =>
4236
- b.chainId === fromChainId &&
4237
- (b.contractAddress?.toLowerCase() ===
4238
- fromTokenAddress.toLowerCase() ||
4239
- (!b.contractAddress && fromTokenAddress === zeroAddress)),
4240
- )
4142
+ const originTokenBalance = balances.find(
4143
+ (b) =>
4144
+ b.chainId === fromChainId &&
4145
+ (b.contractAddress?.toLowerCase() ===
4146
+ fromTokenAddress.toLowerCase() ||
4147
+ (!b.contractAddress && fromTokenAddress === zeroAddress)),
4148
+ )
4241
4149
 
4242
- const originTokenBalanceAmount = originTokenBalance?.balance ?? "0"
4243
- const destinationRelayer = getRelayer(toChainId)
4244
- const originRelayer = getRelayer(fromChainId)
4150
+ const originTokenBalanceAmount = originTokenBalance?.balance ?? "0"
4151
+ const destinationRelayer = getRelayer(toChainId)
4152
+ const originRelayer = getRelayer(fromChainId)
4245
4153
 
4246
- // Note: Disable this check for now to allow fetching a quote even when the origin balance is zero
4247
- // if (originTokenBalanceAmount === "0") {
4248
- // return null
4249
- // }
4154
+ // Note: Disable this check for now to allow fetching a quote even when the origin balance is zero
4155
+ // if (originTokenBalanceAmount === "0") {
4156
+ // return null
4157
+ // }
4250
4158
 
4251
- // logger.console.log("supportedTokens", supportedTokens)
4159
+ // logger.console.log("supportedTokens", supportedTokens)
4252
4160
 
4253
- const originToken = supportedTokens?.find(
4254
- (token) =>
4255
- token.contractAddress?.toLowerCase() ===
4256
- fromTokenAddress?.toLowerCase() && token.chainId === fromChainId,
4257
- )
4258
- const destinationToken = supportedTokens?.find(
4259
- (token) =>
4260
- token.contractAddress?.toLowerCase() ===
4261
- toTokenAddress?.toLowerCase() && token.chainId === toChainId,
4262
- )
4161
+ const originToken = supportedTokens?.find(
4162
+ (token) =>
4163
+ token.contractAddress?.toLowerCase() ===
4164
+ fromTokenAddress?.toLowerCase() && token.chainId === fromChainId,
4165
+ )
4166
+ const destinationToken = supportedTokens?.find(
4167
+ (token) =>
4168
+ token.contractAddress?.toLowerCase() ===
4169
+ toTokenAddress?.toLowerCase() && token.chainId === toChainId,
4170
+ )
4263
4171
 
4264
- const sourceTokenDecimals = originToken?.decimals
4265
- if (!sourceTokenDecimals) {
4266
- throw new Error("Source token decimals not found")
4267
- }
4268
- const destinationTokenDecimals = destinationToken?.decimals
4269
- if (!destinationTokenDecimals) {
4270
- throw new Error("Destination token decimals not found")
4271
- }
4272
- const destinationTokenSymbol = destinationToken?.symbol ?? ""
4273
- const originTokenSymbol = originToken?.symbol ?? ""
4274
-
4275
- const options = {
4276
- account: walletClient.account!,
4277
- originTokenAddress: fromTokenAddress,
4278
- originChainId: fromChainId,
4279
- originTokenBalance: originTokenBalanceAmount,
4280
- destinationChainId: toChainId,
4281
- recipient: toRecipient,
4282
- destinationTokenAddress: toTokenAddress,
4283
- swapAmount: swapAmount.toString(),
4284
- tradeType: tradeType ?? TradeType.EXACT_OUTPUT,
4285
- originTokenSymbol: originTokenSymbol,
4286
- destinationTokenSymbol: destinationTokenSymbol,
4287
- destinationCalldata: toCalldata as string,
4288
- client: walletClient,
4289
- apiClient,
4290
- trailsClient,
4291
- originRelayer,
4292
- destinationRelayer,
4293
- sourceTokenDecimals,
4294
- destinationTokenDecimals,
4295
- fee: "0",
4296
- dryMode: false,
4297
- onTransactionStateChange: onStatusUpdate ?? (() => {}),
4298
- slippageTolerance: slippageTolerance?.toString(),
4299
- quoteProvider: quoteProvider,
4300
- gasless: gasless ?? false,
4301
- paymasterUrl: paymasterUrl,
4302
- }
4172
+ const sourceTokenDecimals = originToken?.decimals
4173
+ if (!sourceTokenDecimals) {
4174
+ logger.console.error(
4175
+ "[trails-sdk] [useQuote] Missing source token decimals:",
4176
+ {
4177
+ originToken,
4178
+ fromTokenAddress,
4179
+ fromChainId,
4180
+ },
4181
+ )
4182
+ throw new Error("Source token decimals not found")
4183
+ }
4184
+ const destinationTokenDecimals = destinationToken?.decimals
4185
+ if (!destinationTokenDecimals) {
4186
+ logger.console.error(
4187
+ "[trails-sdk] Missing destination token decimals:",
4188
+ {
4189
+ destinationToken,
4190
+ toTokenAddress,
4191
+ toChainId,
4192
+ },
4193
+ )
4194
+ throw new Error("Destination token decimals not found")
4195
+ }
4196
+ const destinationTokenSymbol = destinationToken?.symbol ?? ""
4197
+ const originTokenSymbol = originToken?.symbol ?? ""
4198
+
4199
+ const options = {
4200
+ account: walletClient.account!,
4201
+ originTokenAddress: fromTokenAddress,
4202
+ originChainId: fromChainId,
4203
+ originTokenBalance: originTokenBalanceAmount,
4204
+ destinationChainId: toChainId,
4205
+ recipient: toRecipient,
4206
+ destinationTokenAddress: toTokenAddress,
4207
+ swapAmount: swapAmount.toString(),
4208
+ tradeType: tradeType ?? TradeType.EXACT_OUTPUT,
4209
+ originTokenSymbol: originTokenSymbol,
4210
+ destinationTokenSymbol: destinationTokenSymbol,
4211
+ destinationCalldata: toCalldata as string,
4212
+ client: walletClient,
4213
+ apiClient,
4214
+ trailsClient,
4215
+ originRelayer,
4216
+ destinationRelayer,
4217
+ sourceTokenDecimals,
4218
+ destinationTokenDecimals,
4219
+ fee: "0",
4220
+ dryMode: false,
4221
+ onTransactionStateChange: onStatusUpdate ?? (() => {}),
4222
+ slippageTolerance: slippageTolerance?.toString(),
4223
+ quoteProvider: quoteProvider,
4224
+ gasless: gasless ?? false,
4225
+ paymasterUrl: paymasterUrl,
4226
+ }
4303
4227
 
4304
- logger.console.log("[trails-sdk] options", options)
4305
-
4306
- const { quote: prepareSendQuote, send } = await prepareSend(options)
4307
-
4308
- const quote = {
4309
- fromAmount: prepareSendQuote.originAmount,
4310
- toAmount: prepareSendQuote.destinationAmount,
4311
- fromAmountMin: prepareSendQuote.originAmountMin,
4312
- toAmountMin: prepareSendQuote.destinationAmountMin,
4313
- originToken: prepareSendQuote.originToken,
4314
- destinationToken: prepareSendQuote.destinationToken,
4315
- originChain: prepareSendQuote.originChain,
4316
- destinationChain: prepareSendQuote.destinationChain,
4317
- fees: prepareSendQuote.fees,
4318
- priceImpact: prepareSendQuote.priceImpact,
4319
- completionEstimateSeconds: prepareSendQuote.completionEstimateSeconds,
4320
- slippageTolerance: prepareSendQuote.slippageTolerance,
4321
- transactionStates: prepareSendQuote.transactionStates,
4322
- originTokenRate: prepareSendQuote.originTokenRate,
4323
- destinationTokenRate: prepareSendQuote.destinationTokenRate,
4324
- quoteProvider: prepareSendQuote.quoteProvider,
4325
- fromAmountUsdDisplay:
4326
- prepareSendQuote.originAmountUsdDisplay ?? undefined,
4327
- toAmountUsdDisplay:
4328
- prepareSendQuote.destinationAmountUsdDisplay ?? undefined,
4329
- gasCostUsd: prepareSendQuote.gasCostUsd ?? undefined,
4330
- gasCostUsdDisplay: prepareSendQuote.gasCostUsdDisplay ?? undefined,
4331
- }
4228
+ logger.console.log("[trails-sdk] options", options)
4229
+
4230
+ const { quote: prepareSendQuote, send } = await prepareSend(options)
4231
+
4232
+ const quote = {
4233
+ fromAmount: prepareSendQuote.originAmount,
4234
+ toAmount: prepareSendQuote.destinationAmount,
4235
+ fromAmountMin: prepareSendQuote.originAmountMin,
4236
+ toAmountMin: prepareSendQuote.destinationAmountMin,
4237
+ originToken: prepareSendQuote.originToken,
4238
+ destinationToken: prepareSendQuote.destinationToken,
4239
+ originChain: prepareSendQuote.originChain,
4240
+ destinationChain: prepareSendQuote.destinationChain,
4241
+ fees: prepareSendQuote.fees,
4242
+ priceImpact: prepareSendQuote.priceImpact,
4243
+ completionEstimateSeconds: prepareSendQuote.completionEstimateSeconds,
4244
+ slippageTolerance: prepareSendQuote.slippageTolerance,
4245
+ transactionStates: prepareSendQuote.transactionStates,
4246
+ originTokenRate: prepareSendQuote.originTokenRate,
4247
+ destinationTokenRate: prepareSendQuote.destinationTokenRate,
4248
+ quoteProvider: prepareSendQuote.quoteProvider,
4249
+ fromAmountUsdDisplay:
4250
+ prepareSendQuote.originAmountUsdDisplay ?? undefined,
4251
+ toAmountUsdDisplay:
4252
+ prepareSendQuote.destinationAmountUsdDisplay ?? undefined,
4253
+ gasCostUsd: prepareSendQuote.gasCostUsd ?? undefined,
4254
+ gasCostUsdDisplay: prepareSendQuote.gasCostUsdDisplay ?? undefined,
4255
+ }
4332
4256
 
4333
- const swap = async (): Promise<SwapReturn> => {
4334
- const {
4335
- originUserTxReceipt,
4336
- destinationMetaTxnReceipt,
4337
- totalCompletionSeconds,
4338
- } = await send({})
4257
+ const swap = async (): Promise<SwapReturn> => {
4258
+ const {
4259
+ originUserTxReceipt,
4260
+ destinationMetaTxnReceipt,
4261
+ totalCompletionSeconds,
4262
+ } = await send({})
4263
+
4264
+ return {
4265
+ originTransaction: {
4266
+ transactionHash: originUserTxReceipt?.transactionHash,
4267
+ explorerUrl: getExplorerUrl({
4268
+ txHash: originUserTxReceipt?.transactionHash as string,
4269
+ chainId: fromChainId,
4270
+ }),
4271
+ receipt: originUserTxReceipt,
4272
+ },
4273
+ destinationTransaction: {
4274
+ transactionHash: destinationMetaTxnReceipt?.txnHash,
4275
+ explorerUrl: getExplorerUrl({
4276
+ txHash: destinationMetaTxnReceipt?.txnHash as string,
4277
+ chainId: toChainId,
4278
+ }),
4279
+ receipt: destinationMetaTxnReceipt,
4280
+ },
4281
+ totalCompletionSeconds,
4282
+ }
4283
+ }
4339
4284
 
4340
4285
  return {
4341
- originTransaction: {
4342
- transactionHash: originUserTxReceipt?.transactionHash,
4343
- explorerUrl: getExplorerUrl({
4344
- txHash: originUserTxReceipt?.transactionHash as string,
4345
- chainId: fromChainId,
4346
- }),
4347
- receipt: originUserTxReceipt,
4348
- },
4349
- destinationTransaction: {
4350
- transactionHash: destinationMetaTxnReceipt?.txnHash,
4351
- explorerUrl: getExplorerUrl({
4352
- txHash: destinationMetaTxnReceipt?.txnHash as string,
4353
- chainId: toChainId,
4354
- }),
4355
- receipt: destinationMetaTxnReceipt,
4356
- },
4357
- totalCompletionSeconds,
4286
+ quote,
4287
+ swap,
4358
4288
  }
4359
- }
4360
-
4361
- return {
4362
- quote,
4363
- swap,
4289
+ } catch (error) {
4290
+ logger.console.error(
4291
+ "[trails-sdk] [useQuote] Error getting quote:",
4292
+ error,
4293
+ )
4294
+ throw getFullErrorMessage(error)
4364
4295
  }
4365
4296
  },
4366
4297
  // Prevent unnecessary refetching