0xtrails 0.2.5 → 0.3.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.
Files changed (267) hide show
  1. package/dist/aave.d.ts +2 -0
  2. package/dist/aave.d.ts.map +1 -1
  3. package/dist/abortController.d.ts +8 -0
  4. package/dist/abortController.d.ts.map +1 -0
  5. package/dist/{ccip-CXlshvBY.js → ccip-BMB3uDZt.js} +1 -1
  6. package/dist/config.d.ts +0 -5
  7. package/dist/config.d.ts.map +1 -1
  8. package/dist/constants.d.ts +4 -4
  9. package/dist/constants.d.ts.map +1 -1
  10. package/dist/error.d.ts +4 -1
  11. package/dist/error.d.ts.map +1 -1
  12. package/dist/fees.d.ts +19 -0
  13. package/dist/fees.d.ts.map +1 -0
  14. package/dist/{index-_QuyGrjU.js → index-QXPUrZVv.js} +48719 -50852
  15. package/dist/index.d.ts +9 -8
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +811 -784
  18. package/dist/intentReceiptMonitor.d.ts +24 -0
  19. package/dist/intentReceiptMonitor.d.ts.map +1 -0
  20. package/dist/intentReceiptPoller.d.ts +69 -0
  21. package/dist/intentReceiptPoller.d.ts.map +1 -0
  22. package/dist/intents.d.ts +15 -11
  23. package/dist/intents.d.ts.map +1 -1
  24. package/dist/morpho.d.ts +6 -5
  25. package/dist/morpho.d.ts.map +1 -1
  26. package/dist/mutations.d.ts +16 -0
  27. package/dist/mutations.d.ts.map +1 -0
  28. package/dist/preconditions.d.ts +5 -4
  29. package/dist/preconditions.d.ts.map +1 -1
  30. package/dist/prepareSend.d.ts +7 -258
  31. package/dist/prepareSend.d.ts.map +1 -1
  32. package/dist/prices.d.ts +9 -6
  33. package/dist/prices.d.ts.map +1 -1
  34. package/dist/sequenceWallet.d.ts +3 -16
  35. package/dist/sequenceWallet.d.ts.map +1 -1
  36. package/dist/tokenBalances.d.ts +17 -13
  37. package/dist/tokenBalances.d.ts.map +1 -1
  38. package/dist/trails.d.ts +24 -40
  39. package/dist/trails.d.ts.map +1 -1
  40. package/dist/transactionIntent/constants.d.ts +7 -0
  41. package/dist/transactionIntent/constants.d.ts.map +1 -0
  42. package/dist/transactionIntent/deposits/depositOrchestrator.d.ts +44 -0
  43. package/dist/transactionIntent/deposits/depositOrchestrator.d.ts.map +1 -0
  44. package/dist/transactionIntent/deposits/gaslessDeposit.d.ts +30 -0
  45. package/dist/transactionIntent/deposits/gaslessDeposit.d.ts.map +1 -0
  46. package/dist/transactionIntent/deposits/index.d.ts +4 -0
  47. package/dist/transactionIntent/deposits/index.d.ts.map +1 -0
  48. package/dist/transactionIntent/deposits/standardDeposit.d.ts +30 -0
  49. package/dist/transactionIntent/deposits/standardDeposit.d.ts.map +1 -0
  50. package/dist/transactionIntent/execution/index.d.ts +2 -0
  51. package/dist/transactionIntent/execution/index.d.ts.map +1 -0
  52. package/dist/transactionIntent/execution/transactionState.d.ts +5 -0
  53. package/dist/transactionIntent/execution/transactionState.d.ts.map +1 -0
  54. package/dist/transactionIntent/handlers/crossChain.d.ts +82 -0
  55. package/dist/transactionIntent/handlers/crossChain.d.ts.map +1 -0
  56. package/dist/transactionIntent/handlers/index.d.ts +4 -0
  57. package/dist/transactionIntent/handlers/index.d.ts.map +1 -0
  58. package/dist/transactionIntent/handlers/sameChainDifferentToken.d.ts +62 -0
  59. package/dist/transactionIntent/handlers/sameChainDifferentToken.d.ts.map +1 -0
  60. package/dist/transactionIntent/handlers/sameChainSameToken.d.ts +72 -0
  61. package/dist/transactionIntent/handlers/sameChainSameToken.d.ts.map +1 -0
  62. package/dist/transactionIntent/index.d.ts +9 -0
  63. package/dist/transactionIntent/index.d.ts.map +1 -0
  64. package/dist/transactionIntent/quote/feeExtractors.d.ts +17 -0
  65. package/dist/transactionIntent/quote/feeExtractors.d.ts.map +1 -0
  66. package/dist/transactionIntent/quote/index.d.ts +4 -0
  67. package/dist/transactionIntent/quote/index.d.ts.map +1 -0
  68. package/dist/transactionIntent/quote/normalizeQuote.d.ts +34 -0
  69. package/dist/transactionIntent/quote/normalizeQuote.d.ts.map +1 -0
  70. package/dist/transactionIntent/quote/quoteHelpers.d.ts +5 -0
  71. package/dist/transactionIntent/quote/quoteHelpers.d.ts.map +1 -0
  72. package/dist/transactionIntent/types.d.ts +131 -0
  73. package/dist/transactionIntent/types.d.ts.map +1 -0
  74. package/dist/transactionIntent/utils/balanceChecker.d.ts +18 -0
  75. package/dist/transactionIntent/utils/balanceChecker.d.ts.map +1 -0
  76. package/dist/transactionIntent/utils/index.d.ts +4 -0
  77. package/dist/transactionIntent/utils/index.d.ts.map +1 -0
  78. package/dist/transactionIntent/utils/lifiHelpers.d.ts +10 -0
  79. package/dist/transactionIntent/utils/lifiHelpers.d.ts.map +1 -0
  80. package/dist/transactionIntent/utils/testnetHelpers.d.ts +3 -0
  81. package/dist/transactionIntent/utils/testnetHelpers.d.ts.map +1 -0
  82. package/dist/transactionIntent/validators.d.ts +6 -0
  83. package/dist/transactionIntent/validators.d.ts.map +1 -0
  84. package/dist/transactions.d.ts +6 -3
  85. package/dist/transactions.d.ts.map +1 -1
  86. package/dist/widget/components/AccountIntentTransactionHistoryButton.d.ts +4 -0
  87. package/dist/widget/components/AccountIntentTransactionHistoryButton.d.ts.map +1 -0
  88. package/dist/widget/components/AccountSettings.d.ts.map +1 -1
  89. package/dist/widget/components/ChainFilterDropdown.d.ts.map +1 -1
  90. package/dist/widget/components/ClassicSwap.d.ts +2 -3
  91. package/dist/widget/components/ClassicSwap.d.ts.map +1 -1
  92. package/dist/widget/components/ConfigDisplay.d.ts.map +1 -1
  93. package/dist/widget/components/ConnectWallet.d.ts.map +1 -1
  94. package/dist/widget/components/ConnectedWallets.d.ts.map +1 -1
  95. package/dist/widget/components/DynamicInputStyles.d.ts +18 -0
  96. package/dist/widget/components/DynamicInputStyles.d.ts.map +1 -0
  97. package/dist/widget/components/DynamicSizeInputField.d.ts +13 -0
  98. package/dist/widget/components/DynamicSizeInputField.d.ts.map +1 -0
  99. package/dist/widget/components/Earn.d.ts +2 -3
  100. package/dist/widget/components/Earn.d.ts.map +1 -1
  101. package/dist/widget/components/ErrorAnimationIcon.d.ts +2 -0
  102. package/dist/widget/components/ErrorAnimationIcon.d.ts.map +1 -0
  103. package/dist/widget/components/FeeBreakdown.d.ts +9 -0
  104. package/dist/widget/components/FeeBreakdown.d.ts.map +1 -0
  105. package/dist/widget/components/FeeOptions.d.ts +5 -13
  106. package/dist/widget/components/FeeOptions.d.ts.map +1 -1
  107. package/dist/widget/components/Fund.d.ts +2 -3
  108. package/dist/widget/components/Fund.d.ts.map +1 -1
  109. package/dist/widget/components/FundMethods.d.ts.map +1 -1
  110. package/dist/widget/components/FundSwap.d.ts +2 -3
  111. package/dist/widget/components/FundSwap.d.ts.map +1 -1
  112. package/dist/widget/components/FundingMethodSelectorButton.d.ts.map +1 -1
  113. package/dist/widget/components/Identicon.d.ts.map +1 -1
  114. package/dist/widget/components/MeshConnectExchanges.d.ts +0 -3
  115. package/dist/widget/components/MeshConnectExchanges.d.ts.map +1 -1
  116. package/dist/widget/components/Modal.d.ts.map +1 -1
  117. package/dist/widget/components/Pay.d.ts +2 -3
  118. package/dist/widget/components/Pay.d.ts.map +1 -1
  119. package/dist/widget/components/PoolDeposit.d.ts +3 -3
  120. package/dist/widget/components/PoolDeposit.d.ts.map +1 -1
  121. package/dist/widget/components/PoolWithdraw.d.ts +3 -20
  122. package/dist/widget/components/PoolWithdraw.d.ts.map +1 -1
  123. package/dist/widget/components/QuoteDetails.d.ts +2 -0
  124. package/dist/widget/components/QuoteDetails.d.ts.map +1 -1
  125. package/dist/widget/components/Receipt.d.ts.map +1 -1
  126. package/dist/widget/components/RecipientSelectorButton.d.ts.map +1 -1
  127. package/dist/widget/components/ScreenHeader.d.ts.map +1 -1
  128. package/dist/widget/components/Swap.d.ts +2 -3
  129. package/dist/widget/components/Swap.d.ts.map +1 -1
  130. package/dist/widget/components/ThemeProvider.d.ts.map +1 -1
  131. package/dist/widget/components/TokenDisplayNonSelectable.d.ts +11 -0
  132. package/dist/widget/components/TokenDisplayNonSelectable.d.ts.map +1 -0
  133. package/dist/widget/components/TokenSelector.d.ts.map +1 -1
  134. package/dist/widget/components/TokenSelectorButton.d.ts.map +1 -1
  135. package/dist/widget/components/Tooltip.d.ts +9 -0
  136. package/dist/widget/components/Tooltip.d.ts.map +1 -0
  137. package/dist/widget/components/TransferPendingVertical.d.ts.map +1 -1
  138. package/dist/widget/components/WaasFeeOptions.d.ts +1 -0
  139. package/dist/widget/components/WaasFeeOptions.d.ts.map +1 -1
  140. package/dist/widget/components/WalletConfirmation.d.ts.map +1 -1
  141. package/dist/widget/components/WalletConnect.d.ts.map +1 -1
  142. package/dist/widget/css/compiled.css +2 -2
  143. package/dist/widget/hooks/useCheckout.d.ts +17 -4
  144. package/dist/widget/hooks/useCheckout.d.ts.map +1 -1
  145. package/dist/widget/hooks/useDefaultTokenSelection.d.ts.map +1 -1
  146. package/dist/widget/hooks/useQuote.d.ts +82 -0
  147. package/dist/widget/hooks/useQuote.d.ts.map +1 -0
  148. package/dist/widget/hooks/useSelectedFeeToken.d.ts +1 -0
  149. package/dist/widget/hooks/useSelectedFeeToken.d.ts.map +1 -1
  150. package/dist/widget/hooks/useSendForm.d.ts +5 -6
  151. package/dist/widget/hooks/useSendForm.d.ts.map +1 -1
  152. package/dist/widget/hooks/useTokenList.d.ts.map +1 -1
  153. package/dist/widget/hooks/useWalletConnectionContext.d.ts +25 -0
  154. package/dist/widget/hooks/useWalletConnectionContext.d.ts.map +1 -0
  155. package/dist/widget/index.js +2 -2
  156. package/dist/widget/widget.d.ts +17 -7
  157. package/dist/widget/widget.d.ts.map +1 -1
  158. package/package.json +19 -21
  159. package/src/aave.ts +54 -1
  160. package/src/abortController.ts +35 -0
  161. package/src/config.ts +57 -58
  162. package/src/constants.ts +11 -9
  163. package/src/error.ts +21 -3
  164. package/src/fees.ts +210 -0
  165. package/src/index.ts +35 -13
  166. package/src/intentReceiptMonitor.ts +102 -0
  167. package/src/intentReceiptPoller.ts +299 -0
  168. package/src/intents.ts +205 -171
  169. package/src/morpho.ts +58 -9
  170. package/src/mutations.ts +129 -0
  171. package/src/preconditions.ts +16 -21
  172. package/src/prepareSend.ts +92 -4699
  173. package/src/prices.ts +26 -22
  174. package/src/relaySdk.ts +2 -2
  175. package/src/sequenceWallet.ts +6 -73
  176. package/src/tokenBalances.ts +175 -69
  177. package/src/trails.ts +230 -722
  178. package/src/transactionIntent/constants.ts +11 -0
  179. package/src/transactionIntent/deposits/depositOrchestrator.ts +210 -0
  180. package/src/transactionIntent/deposits/gaslessDeposit.ts +588 -0
  181. package/src/transactionIntent/deposits/index.ts +3 -0
  182. package/src/transactionIntent/deposits/standardDeposit.ts +379 -0
  183. package/src/transactionIntent/execution/index.ts +1 -0
  184. package/src/transactionIntent/execution/transactionState.ts +35 -0
  185. package/src/transactionIntent/handlers/crossChain.ts +1707 -0
  186. package/src/transactionIntent/handlers/index.ts +3 -0
  187. package/src/transactionIntent/handlers/sameChainDifferentToken.ts +323 -0
  188. package/src/transactionIntent/handlers/sameChainSameToken.ts +712 -0
  189. package/src/transactionIntent/index.ts +9 -0
  190. package/src/transactionIntent/quote/feeExtractors.ts +81 -0
  191. package/src/transactionIntent/quote/index.ts +3 -0
  192. package/src/transactionIntent/quote/normalizeQuote.ts +367 -0
  193. package/src/transactionIntent/quote/quoteHelpers.ts +53 -0
  194. package/src/transactionIntent/types.ts +157 -0
  195. package/src/transactionIntent/utils/balanceChecker.ts +96 -0
  196. package/src/transactionIntent/utils/index.ts +3 -0
  197. package/src/transactionIntent/utils/lifiHelpers.ts +68 -0
  198. package/src/transactionIntent/utils/testnetHelpers.ts +10 -0
  199. package/src/transactionIntent/validators.ts +57 -0
  200. package/src/transactions.ts +98 -71
  201. package/src/widget/compiled.css +2 -2
  202. package/src/widget/components/AccountIntentTransactionHistory.tsx +36 -36
  203. package/src/widget/components/AccountIntentTransactionHistoryButton.tsx +22 -0
  204. package/src/widget/components/AccountSettings.tsx +70 -41
  205. package/src/widget/components/ChainFilterDropdown.tsx +24 -3
  206. package/src/widget/components/ClassicSwap.tsx +44 -107
  207. package/src/widget/components/ConfigDisplay.tsx +0 -11
  208. package/src/widget/components/ConnectWallet.tsx +4 -1
  209. package/src/widget/components/ConnectedWallets.tsx +51 -25
  210. package/src/widget/components/DynamicInputStyles.tsx +76 -0
  211. package/src/widget/components/DynamicSizeInputField.tsx +109 -0
  212. package/src/widget/components/Earn.tsx +34 -45
  213. package/src/widget/components/ErrorAnimationIcon.tsx +130 -0
  214. package/src/widget/components/FeeBreakdown.tsx +155 -0
  215. package/src/widget/components/FeeOption.tsx +2 -2
  216. package/src/widget/components/FeeOptions.tsx +151 -112
  217. package/src/widget/components/Fund.tsx +10 -29
  218. package/src/widget/components/FundMethods.tsx +4 -3
  219. package/src/widget/components/FundSwap.tsx +2 -3
  220. package/src/widget/components/FundingMethodSelectorButton.tsx +24 -14
  221. package/src/widget/components/Identicon.tsx +164 -95
  222. package/src/widget/components/MeshConnectExchanges.tsx +2 -15
  223. package/src/widget/components/Modal.tsx +0 -12
  224. package/src/widget/components/Pay.tsx +72 -75
  225. package/src/widget/components/PoolDeposit.tsx +221 -242
  226. package/src/widget/components/PoolWithdraw.tsx +347 -469
  227. package/src/widget/components/PriceImpactWarning.tsx +1 -1
  228. package/src/widget/components/QuoteDetails.tsx +906 -484
  229. package/src/widget/components/Receipt.tsx +16 -2
  230. package/src/widget/components/RecipientSelectorButton.tsx +7 -5
  231. package/src/widget/components/Recipients.tsx +1 -1
  232. package/src/widget/components/ScreenHeader.tsx +60 -36
  233. package/src/widget/components/Swap.tsx +2 -3
  234. package/src/widget/components/ThemeProvider.tsx +2 -1
  235. package/src/widget/components/TokenDisplayNonSelectable.tsx +40 -0
  236. package/src/widget/components/TokenImage.tsx +1 -1
  237. package/src/widget/components/TokenSelector.tsx +62 -53
  238. package/src/widget/components/TokenSelectorButton.tsx +38 -15
  239. package/src/widget/components/Tooltip.tsx +51 -0
  240. package/src/widget/components/TransferPendingVertical.tsx +12 -8
  241. package/src/widget/components/WaasFeeOptions.tsx +139 -4
  242. package/src/widget/components/WalletConfirmation.tsx +23 -13
  243. package/src/widget/components/WalletConnect.tsx +93 -29
  244. package/src/widget/hooks/useAmountUsd.ts +9 -9
  245. package/src/widget/hooks/useCheckout.ts +97 -9
  246. package/src/widget/hooks/useDefaultTokenSelection.tsx +27 -21
  247. package/src/widget/hooks/useQuote.ts +466 -0
  248. package/src/widget/hooks/useSelectedFeeToken.tsx +32 -37
  249. package/src/widget/hooks/useSendForm.ts +45 -51
  250. package/src/widget/hooks/useTokenList.ts +34 -26
  251. package/src/widget/hooks/useWalletConnectionContext.tsx +128 -0
  252. package/src/widget/widget.tsx +365 -390
  253. package/dist/apiClient.d.ts +0 -9
  254. package/dist/apiClient.d.ts.map +0 -1
  255. package/dist/intentEntrypoint.d.ts +0 -114
  256. package/dist/intentEntrypoint.d.ts.map +0 -1
  257. package/dist/metaTxnMonitor.d.ts +0 -15
  258. package/dist/metaTxnMonitor.d.ts.map +0 -1
  259. package/dist/metaTxns.d.ts +0 -11
  260. package/dist/metaTxns.d.ts.map +0 -1
  261. package/dist/relayer.d.ts +0 -43
  262. package/dist/relayer.d.ts.map +0 -1
  263. package/src/apiClient.ts +0 -35
  264. package/src/intentEntrypoint.ts +0 -203
  265. package/src/metaTxnMonitor.ts +0 -171
  266. package/src/metaTxns.ts +0 -45
  267. package/src/relayer.ts +0 -289
@@ -0,0 +1,3 @@
1
+ export * from "./sameChainSameToken.js"
2
+ export * from "./sameChainDifferentToken.js"
3
+ export * from "./crossChain.js"
@@ -0,0 +1,323 @@
1
+ import type { Account, PublicClient, WalletClient } from "viem"
2
+ import { zeroAddress, decodeFunctionData, erc20Abi, formatUnits } from "viem"
3
+ import type { TransactionState } from "../../transactions.js"
4
+ import type { PrepareSendReturn, SendReturn, TradeType } from "../types.js"
5
+ import { logger } from "../../logger.js"
6
+ import { getIsCustomCalldata } from "../../contractUtils.js"
7
+ import {
8
+ getRelaySDKQuote,
9
+ executeSimpleRelayTransaction,
10
+ getTxHashFromRelayResult,
11
+ type RelayTradeType,
12
+ } from "../../relaySdk.js"
13
+ import { getNormalizedQuoteObject } from "../quote/normalizeQuote.js"
14
+ import {
15
+ getFeesFromRelaySdkQuote,
16
+ getSlippageToleranceFromRelaySdkQuote,
17
+ getPriceImpactFromRelaySdkQuote,
18
+ getPriceImpactUsdFromRelaySdkQuote,
19
+ } from "../quote/feeExtractors.js"
20
+ import { checkAccountBalance } from "../utils/balanceChecker.js"
21
+ import { attemptSwitchChain } from "../../chainSwitch.js"
22
+ import { getTransactionStateFromReceipt } from "../execution/transactionState.js"
23
+ import { calcAmountUsdPrice } from "../../prices.js"
24
+ import { trackPaymentCompleted, trackPaymentError } from "../../analytics.js"
25
+ import { TradeType as LocalTradeType } from "../types.js"
26
+
27
+ /**
28
+ * @description
29
+ * This handler manages same-chain token swaps (e.g., ETH to WETH on the same chain).
30
+ * It leverages the Relay SDK for quote and transaction execution.
31
+ *
32
+ * Key characteristics:
33
+ * - Uses Relay SDK directly for quote fetching and transaction execution
34
+ * - Single transaction leg (swap on origin chain)
35
+ * - No cross-chain bridging required
36
+ * - Supports various token pair combinations on the same chain
37
+ *
38
+ * Transaction Flow:
39
+ * 1. Fetch quote via getRelaySDKQuote (Relay SDK API)
40
+ * 2. Create intent via createIntent (Intent object created)
41
+ * 3. Execute swap via executeSimpleRelayTransaction (User submits swap transaction)
42
+ * 4. Monitor via waitIntentReceipt API for transaction completion
43
+ * 5. Update transaction state and invoke callbacks
44
+ *
45
+ * Relay SDK Integration:
46
+ * - Direct integration with Relay SDK for quote and transaction submission
47
+ * - Transaction hash extracted via getTxHashFromRelayResult
48
+ * - Receipt polling via Trails API for consistent monitoring
49
+ *
50
+ * Error Handling:
51
+ * - Balance validation before transaction submission
52
+ * - Chain switching if user is on wrong network
53
+ * - Relay SDK error handling with proper error propagation
54
+ * - Checkout error callbacks for UI feedback
55
+ *
56
+ * State Management:
57
+ * - transactionStates[0]: Swap transaction
58
+ * - Updates propagated via onTransactionStateChange callback
59
+ * - Analytics tracking for payment completion or errors
60
+ */
61
+ export async function handleSameChainDifferentToken({
62
+ originTokenAddress,
63
+ originTokenDecimals,
64
+ swapAmount,
65
+ destinationTokenAddress,
66
+ destinationTokenDecimals,
67
+ destinationCalldata,
68
+ recipient,
69
+ originChainId,
70
+ walletClient,
71
+ publicClient,
72
+ account,
73
+ tradeType = LocalTradeType.EXACT_OUTPUT,
74
+ slippageTolerance,
75
+ onTransactionStateChange,
76
+ transactionStates,
77
+ sourceTokenPriceUsd,
78
+ destinationTokenPriceUsd,
79
+ originNativeTokenPriceUsd,
80
+ mode,
81
+ fundMethod,
82
+ originTokenSymbol,
83
+ destinationTokenSymbol,
84
+ }: {
85
+ originTokenAddress: string
86
+ originTokenDecimals: number
87
+ swapAmount: string
88
+ destinationTokenAddress: string
89
+ destinationTokenDecimals: number
90
+ destinationCalldata?: string
91
+ recipient: string
92
+ originChainId: number
93
+ walletClient: WalletClient
94
+ publicClient: PublicClient
95
+ account: Account
96
+ tradeType?: TradeType
97
+ slippageTolerance?: string
98
+ onTransactionStateChange: (transactionStates: TransactionState[]) => void
99
+ transactionStates: TransactionState[]
100
+ sourceTokenPriceUsd?: number | null
101
+ destinationTokenPriceUsd?: number | null
102
+ originNativeTokenPriceUsd?: number | null
103
+ mode?: "pay" | "fund" | "earn" | "swap" | "receive"
104
+ fundMethod?: string
105
+ originTokenSymbol: string
106
+ destinationTokenSymbol: string
107
+ }): Promise<PrepareSendReturn> {
108
+ const destinationTxs: { to: string; value: string; data: string }[] = []
109
+ const hasCustomCalldata = getIsCustomCalldata(destinationCalldata)
110
+ if (hasCustomCalldata && tradeType === LocalTradeType.EXACT_OUTPUT) {
111
+ destinationTxs.push({
112
+ to: recipient,
113
+ value: destinationTokenAddress === zeroAddress ? swapAmount : "0",
114
+ data: destinationCalldata as `0x${string}`,
115
+ })
116
+ } else if (hasCustomCalldata && tradeType === LocalTradeType.EXACT_INPUT) {
117
+ destinationTxs.push({
118
+ to: recipient,
119
+ value: "0",
120
+ data: destinationCalldata as `0x${string}`,
121
+ })
122
+ }
123
+
124
+ const quote = await getRelaySDKQuote({
125
+ wallet: walletClient,
126
+ chainId: originChainId,
127
+ amount: swapAmount,
128
+ currency: originTokenAddress,
129
+ toCurrency: destinationTokenAddress,
130
+ txs: destinationTxs,
131
+ tradeType: tradeType as unknown as RelayTradeType,
132
+ slippageTolerance: slippageTolerance,
133
+ recipient: hasCustomCalldata ? recipient : undefined,
134
+ })
135
+
136
+ logger.console.log("[trails-sdk] relaysdk quote", quote)
137
+ let depositAmount = "0"
138
+ let destinationTokenAmount = "0"
139
+
140
+ if (tradeType === LocalTradeType.EXACT_INPUT) {
141
+ depositAmount = swapAmount
142
+ destinationTokenAmount = quote?.details?.currencyOut?.amount?.toString()
143
+ } else {
144
+ try {
145
+ destinationTokenAmount = swapAmount
146
+ depositAmount = quote.steps?.[0]?.items?.[0]?.data?.value
147
+ if (originTokenAddress !== zeroAddress) {
148
+ const decoded = decodeFunctionData({
149
+ abi: erc20Abi,
150
+ data: quote.steps?.[0]?.items?.[0]?.data?.data,
151
+ })
152
+ if (decoded.functionName === "approve") {
153
+ depositAmount = decoded.args[1].toString()
154
+ }
155
+ if (decoded.functionName === "transfer") {
156
+ depositAmount = decoded.args[1].toString()
157
+ }
158
+ }
159
+ } catch (error) {
160
+ logger.console.error("[trails-sdk] Error decoding function data:", error)
161
+ }
162
+ }
163
+
164
+ const depositOriginAddress =
165
+ quote?.steps?.[quote?.steps?.length - 1]?.items?.[
166
+ quote?.steps?.[quote?.steps?.length - 1]?.items?.length - 1
167
+ ]?.data?.to
168
+
169
+ if (
170
+ quote?.details?.currencyIn?.amountFormatted &&
171
+ quote?.details?.currencyIn?.amountUsd
172
+ ) {
173
+ const quoteProviderSourceTokenPriceUsd =
174
+ Number(quote.details.currencyIn.amountUsd) /
175
+ Number(quote.details.currencyIn.amountFormatted)
176
+ if (quoteProviderSourceTokenPriceUsd) {
177
+ sourceTokenPriceUsd = quoteProviderSourceTokenPriceUsd
178
+ }
179
+ }
180
+
181
+ if (
182
+ quote?.details?.currencyOut?.amountFormatted &&
183
+ quote?.details?.currencyOut?.amountUsd
184
+ ) {
185
+ const quoteProviderDestinationTokenPriceUsd =
186
+ Number(quote.details.currencyOut.amountUsd) /
187
+ Number(quote.details.currencyOut.amountFormatted)
188
+ if (quoteProviderDestinationTokenPriceUsd) {
189
+ destinationTokenPriceUsd = quoteProviderDestinationTokenPriceUsd
190
+ }
191
+ }
192
+
193
+ const normalizedQuote = await getNormalizedQuoteObject({
194
+ originDepositAddress: depositOriginAddress,
195
+ destinationDepositAddress: recipient,
196
+ destinationAddress: recipient,
197
+ destinationCalldata,
198
+ originAmount: depositAmount,
199
+ destinationAmount: destinationTokenAmount,
200
+ originTokenAddress: originTokenAddress,
201
+ destinationTokenAddress: destinationTokenAddress,
202
+ originTokenPriceUsd: sourceTokenPriceUsd?.toString() || null,
203
+ destinationTokenPriceUsd: destinationTokenPriceUsd?.toString() || null,
204
+ fees: getFeesFromRelaySdkQuote(quote),
205
+ slippageTolerance: getSlippageToleranceFromRelaySdkQuote(quote),
206
+ priceImpact: getPriceImpactFromRelaySdkQuote(quote),
207
+ priceImpactUsd: getPriceImpactUsdFromRelaySdkQuote(quote),
208
+ transactionStates,
209
+ originChainId,
210
+ destinationChainId: originChainId,
211
+ originNativeTokenPriceUsd,
212
+ quoteProvider: "relay",
213
+ intent: undefined,
214
+ })
215
+
216
+ return {
217
+ quote: normalizedQuote,
218
+ send: async ({
219
+ onOriginSend,
220
+ }: {
221
+ onOriginSend?: () => void
222
+ }): Promise<SendReturn> => {
223
+ const { hasEnoughBalance, balanceError } = await checkAccountBalance({
224
+ account,
225
+ tokenAddress: originTokenAddress,
226
+ depositAmount,
227
+ publicClient,
228
+ })
229
+
230
+ if (!hasEnoughBalance) {
231
+ throw balanceError
232
+ }
233
+
234
+ await attemptSwitchChain({
235
+ walletClient,
236
+ desiredChainId: originChainId,
237
+ })
238
+
239
+ const result = await executeSimpleRelayTransaction(quote, walletClient)
240
+ logger.console.log("[trails-sdk] relaysdk result", result)
241
+
242
+ const txHash = getTxHashFromRelayResult(result)
243
+
244
+ if (onOriginSend) {
245
+ onOriginSend()
246
+ }
247
+
248
+ const depositUserTxnReceipt =
249
+ await publicClient.waitForTransactionReceipt({
250
+ hash: txHash as `0x${string}`,
251
+ })
252
+
253
+ transactionStates[0] = getTransactionStateFromReceipt(
254
+ depositUserTxnReceipt,
255
+ originChainId,
256
+ transactionStates[0]?.label,
257
+ )
258
+
259
+ try {
260
+ onTransactionStateChange(transactionStates)
261
+ } catch (error) {
262
+ logger.console.error(
263
+ "[trails-sdk] Error calling onTransactionStateChange:",
264
+ error,
265
+ )
266
+ }
267
+
268
+ const depositAmountFormatted = Number(
269
+ formatUnits(BigInt(depositAmount), originTokenDecimals),
270
+ )
271
+
272
+ const depositAmountUsd = calcAmountUsdPrice({
273
+ amount: depositAmountFormatted,
274
+ usdPrice: sourceTokenPriceUsd,
275
+ })
276
+
277
+ const destinationTokenAmountFormatted = Number(
278
+ formatUnits(BigInt(destinationTokenAmount), destinationTokenDecimals),
279
+ )
280
+
281
+ const destinationTokenAmountUsd = calcAmountUsdPrice({
282
+ amount: Number(destinationTokenAmountFormatted),
283
+ usdPrice: destinationTokenPriceUsd,
284
+ })
285
+
286
+ // Track payment completion for same-chain different-token transaction
287
+ if (depositUserTxnReceipt && depositUserTxnReceipt.status === "success") {
288
+ trackPaymentCompleted({
289
+ userAddress: account.address,
290
+ originTxHash: depositUserTxnReceipt.transactionHash,
291
+ originChainId,
292
+ destinationChainId: originChainId, // Same chain
293
+ mode,
294
+ fundMethod,
295
+ originTokenAddress,
296
+ originTokenSymbol,
297
+ destinationTokenAddress,
298
+ destinationTokenSymbol,
299
+ depositTokenAmountUsd: depositAmountUsd?.toString(),
300
+ destinationTokenAmountUsd: destinationTokenAmountUsd?.toString(),
301
+ })
302
+ } else if (depositUserTxnReceipt) {
303
+ trackPaymentError({
304
+ error: "Relay transaction failed",
305
+ userAddress: account.address,
306
+ mode,
307
+ fundMethod,
308
+ originTokenAddress,
309
+ originTokenSymbol,
310
+ destinationTokenAddress,
311
+ destinationTokenSymbol,
312
+ })
313
+ }
314
+
315
+ return {
316
+ depositUserTxnReceipt: depositUserTxnReceipt,
317
+ originMetaTxnReceipt: null,
318
+ destinationMetaTxnReceipt: null,
319
+ totalCompletionSeconds: 0,
320
+ }
321
+ },
322
+ }
323
+ }