0xtrails 0.1.13 → 0.2.1

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 (256) hide show
  1. package/dist/aave.d.ts.map +1 -1
  2. package/dist/analytics.d.ts +12 -2
  3. package/dist/analytics.d.ts.map +1 -1
  4. package/dist/apiClient.d.ts +1 -1
  5. package/dist/apiClient.d.ts.map +1 -1
  6. package/dist/{ccip-D3gTQONK.js → ccip-BbfANth7.js} +12 -12
  7. package/dist/cctp.d.ts.map +1 -1
  8. package/dist/cctpqueue.d.ts +3 -3
  9. package/dist/cctpqueue.d.ts.map +1 -1
  10. package/dist/chains.d.ts.map +1 -1
  11. package/dist/config.d.ts +18 -5
  12. package/dist/config.d.ts.map +1 -1
  13. package/dist/constants.d.ts +6 -5
  14. package/dist/constants.d.ts.map +1 -1
  15. package/dist/contractUtils.d.ts +2 -0
  16. package/dist/contractUtils.d.ts.map +1 -1
  17. package/dist/customChains.d.ts +24 -0
  18. package/dist/customChains.d.ts.map +1 -0
  19. package/dist/gasless.d.ts +19 -7
  20. package/dist/gasless.d.ts.map +1 -1
  21. package/dist/{index-CnUM7lKf.js → index-WpIVoh3X.js} +36741 -31761
  22. package/dist/index.d.ts +5 -3
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +405 -394
  25. package/dist/indexerClient.d.ts +10 -0
  26. package/dist/indexerClient.d.ts.map +1 -1
  27. package/dist/intentEntrypoint.d.ts +122 -0
  28. package/dist/intentEntrypoint.d.ts.map +1 -0
  29. package/dist/intents.d.ts +5 -3
  30. package/dist/intents.d.ts.map +1 -1
  31. package/dist/metaTxnMonitor.d.ts.map +1 -1
  32. package/dist/morpho.d.ts.map +1 -1
  33. package/dist/pools.d.ts +3 -1
  34. package/dist/pools.d.ts.map +1 -1
  35. package/dist/prepareSend.d.ts +18 -9
  36. package/dist/prepareSend.d.ts.map +1 -1
  37. package/dist/prices.d.ts +1 -1
  38. package/dist/prices.d.ts.map +1 -1
  39. package/dist/relaySdk.d.ts.map +1 -1
  40. package/dist/relayer.d.ts.map +1 -1
  41. package/dist/toast.d.ts +9 -0
  42. package/dist/toast.d.ts.map +1 -0
  43. package/dist/tokenBalances.d.ts +6 -2
  44. package/dist/tokenBalances.d.ts.map +1 -1
  45. package/dist/tokens.d.ts.map +1 -1
  46. package/dist/trails.d.ts +6 -5
  47. package/dist/trails.d.ts.map +1 -1
  48. package/dist/trailsClient.d.ts +12 -0
  49. package/dist/trailsClient.d.ts.map +1 -0
  50. package/dist/trailsRouter.d.ts +22 -0
  51. package/dist/trailsRouter.d.ts.map +1 -0
  52. package/dist/transactions.d.ts +8 -1
  53. package/dist/transactions.d.ts.map +1 -1
  54. package/dist/wallets.d.ts.map +1 -1
  55. package/dist/widget/components/AccountActionsDropdown.d.ts.map +1 -1
  56. package/dist/widget/components/AccountIntentTransactionHistory.d.ts.map +1 -1
  57. package/dist/widget/components/AccountSettings.d.ts +7 -0
  58. package/dist/widget/components/AccountSettings.d.ts.map +1 -0
  59. package/dist/widget/components/ChainList.d.ts +0 -1
  60. package/dist/widget/components/ChainList.d.ts.map +1 -1
  61. package/dist/widget/components/ClassicSwap.d.ts +46 -0
  62. package/dist/widget/components/ClassicSwap.d.ts.map +1 -0
  63. package/dist/widget/components/ConfigDisplay.d.ts.map +1 -1
  64. package/dist/widget/components/ConnectWallet.d.ts.map +1 -1
  65. package/dist/widget/components/ConnectedWallets.d.ts +9 -0
  66. package/dist/widget/components/ConnectedWallets.d.ts.map +1 -0
  67. package/dist/widget/components/DebugMenu.d.ts.map +1 -1
  68. package/dist/widget/components/DebugScreensList.d.ts.map +1 -1
  69. package/dist/widget/components/DebugToast.d.ts +3 -0
  70. package/dist/widget/components/DebugToast.d.ts.map +1 -0
  71. package/dist/widget/components/Earn.d.ts.map +1 -1
  72. package/dist/widget/components/EarnPools.d.ts.map +1 -1
  73. package/dist/widget/components/FeeOption.d.ts +22 -0
  74. package/dist/widget/components/FeeOption.d.ts.map +1 -0
  75. package/dist/widget/components/FeeOptions.d.ts +13 -17
  76. package/dist/widget/components/FeeOptions.d.ts.map +1 -1
  77. package/dist/widget/components/Fund.d.ts +44 -0
  78. package/dist/widget/components/Fund.d.ts.map +1 -0
  79. package/dist/widget/components/FundMethods.d.ts +1 -1
  80. package/dist/widget/components/FundMethods.d.ts.map +1 -1
  81. package/dist/widget/components/FundSendForm.d.ts.map +1 -1
  82. package/dist/widget/components/Identicon.d.ts +9 -0
  83. package/dist/widget/components/Identicon.d.ts.map +1 -0
  84. package/dist/widget/components/MeshConnectExchanges.d.ts +5 -2
  85. package/dist/widget/components/MeshConnectExchanges.d.ts.map +1 -1
  86. package/dist/widget/components/MeshConnectFlow.d.ts +2 -0
  87. package/dist/widget/components/MeshConnectFlow.d.ts.map +1 -1
  88. package/dist/widget/components/NativeGasOption.d.ts +12 -0
  89. package/dist/widget/components/NativeGasOption.d.ts.map +1 -0
  90. package/dist/widget/components/Pay.d.ts +46 -0
  91. package/dist/widget/components/Pay.d.ts.map +1 -0
  92. package/dist/widget/components/PaySendForm.d.ts.map +1 -1
  93. package/dist/widget/components/QuoteDetails.d.ts.map +1 -1
  94. package/dist/widget/components/Receive.d.ts.map +1 -1
  95. package/dist/widget/components/RecentTokens.d.ts.map +1 -1
  96. package/dist/widget/components/Recipients.d.ts +9 -0
  97. package/dist/widget/components/Recipients.d.ts.map +1 -0
  98. package/dist/widget/components/RefundWarning.d.ts +9 -0
  99. package/dist/widget/components/RefundWarning.d.ts.map +1 -0
  100. package/dist/widget/components/SimpleSwap.d.ts.map +1 -1
  101. package/dist/widget/components/Swap.d.ts.map +1 -1
  102. package/dist/widget/components/SwapSettings.d.ts +1 -5
  103. package/dist/widget/components/SwapSettings.d.ts.map +1 -1
  104. package/dist/widget/components/ThemeProvider.d.ts.map +1 -1
  105. package/dist/widget/components/ThemeSyncer.d.ts +6 -0
  106. package/dist/widget/components/ThemeSyncer.d.ts.map +1 -0
  107. package/dist/widget/components/Toast.d.ts +24 -0
  108. package/dist/widget/components/Toast.d.ts.map +1 -0
  109. package/dist/widget/components/TokenList.d.ts.map +1 -1
  110. package/dist/widget/components/TokenSelector.d.ts.map +1 -1
  111. package/dist/widget/components/TransactionDetails.d.ts.map +1 -1
  112. package/dist/widget/components/TruncatedAddress.d.ts +2 -0
  113. package/dist/widget/components/TruncatedAddress.d.ts.map +1 -1
  114. package/dist/widget/components/UserPreferences.d.ts +7 -0
  115. package/dist/widget/components/UserPreferences.d.ts.map +1 -0
  116. package/dist/widget/hooks/useBack.d.ts +2 -0
  117. package/dist/widget/hooks/useBack.d.ts.map +1 -1
  118. package/dist/widget/hooks/useBalanceVisible.d.ts +1 -0
  119. package/dist/widget/hooks/useBalanceVisible.d.ts.map +1 -1
  120. package/dist/widget/hooks/useCheckout.d.ts.map +1 -1
  121. package/dist/widget/hooks/useCurrentScreen.d.ts +1 -1
  122. package/dist/widget/hooks/useCurrentScreen.d.ts.map +1 -1
  123. package/dist/widget/hooks/useDebugScreens.d.ts +1 -1
  124. package/dist/widget/hooks/useDebugScreens.d.ts.map +1 -1
  125. package/dist/widget/hooks/useDefaultTokenSelection.d.ts +54 -0
  126. package/dist/widget/hooks/useDefaultTokenSelection.d.ts.map +1 -0
  127. package/dist/widget/hooks/useIntentTransactionHistory.d.ts.map +1 -1
  128. package/dist/widget/hooks/usePayMessage.d.ts +34 -0
  129. package/dist/widget/hooks/usePayMessage.d.ts.map +1 -0
  130. package/dist/widget/hooks/useRecipients.d.ts +17 -0
  131. package/dist/widget/hooks/useRecipients.d.ts.map +1 -0
  132. package/dist/widget/hooks/useSelectedFeeToken.d.ts +32 -0
  133. package/dist/widget/hooks/useSelectedFeeToken.d.ts.map +1 -0
  134. package/dist/widget/hooks/useSelectedMeshExchange.d.ts +14 -0
  135. package/dist/widget/hooks/useSelectedMeshExchange.d.ts.map +1 -0
  136. package/dist/widget/hooks/useSelectedRecipient.d.ts +12 -0
  137. package/dist/widget/hooks/useSelectedRecipient.d.ts.map +1 -0
  138. package/dist/widget/hooks/useSendForm.d.ts +10 -13
  139. package/dist/widget/hooks/useSendForm.d.ts.map +1 -1
  140. package/dist/widget/hooks/useSwapAmount.d.ts +13 -0
  141. package/dist/widget/hooks/useSwapAmount.d.ts.map +1 -0
  142. package/dist/widget/hooks/useSwapSettings.d.ts +16 -0
  143. package/dist/widget/hooks/useSwapSettings.d.ts.map +1 -0
  144. package/dist/widget/hooks/useTargetAmount.d.ts +5 -0
  145. package/dist/widget/hooks/useTargetAmount.d.ts.map +1 -0
  146. package/dist/widget/hooks/useTheme.d.ts +14 -0
  147. package/dist/widget/hooks/useTheme.d.ts.map +1 -0
  148. package/dist/widget/hooks/useTokenList.d.ts.map +1 -1
  149. package/dist/widget/index.js +2 -2
  150. package/dist/widget/widget.d.ts +9 -0
  151. package/dist/widget/widget.d.ts.map +1 -1
  152. package/package.json +38 -36
  153. package/src/aave.ts +6 -1
  154. package/src/analytics.ts +109 -53
  155. package/src/apiClient.ts +1 -1
  156. package/src/cctp.ts +6 -2
  157. package/src/cctpqueue.ts +7 -7
  158. package/src/chains.ts +18 -0
  159. package/src/config.ts +63 -17
  160. package/src/constants.ts +20 -16
  161. package/src/contractUtils.ts +33 -2
  162. package/src/customChains.ts +24 -0
  163. package/src/gasless.ts +162 -109
  164. package/src/index.ts +11 -1
  165. package/src/indexerClient.ts +73 -1
  166. package/src/intentEntrypoint.ts +218 -0
  167. package/src/intents.ts +85 -54
  168. package/src/metaTxnMonitor.ts +1 -0
  169. package/src/morpho.ts +13 -2
  170. package/src/pools.ts +68 -86
  171. package/src/prepareSend.ts +1719 -967
  172. package/src/prices.ts +51 -7
  173. package/src/relaySdk.ts +6 -4
  174. package/src/relayer.ts +6 -3
  175. package/src/toast.ts +110 -0
  176. package/src/tokenBalances.ts +112 -20
  177. package/src/tokens.ts +70 -7
  178. package/src/trails.ts +81 -80
  179. package/src/trailsClient.ts +48 -0
  180. package/src/{proxyCaller.ts → trailsRouter.ts} +25 -20
  181. package/src/transactions.ts +30 -88
  182. package/src/umd.tsx +1 -1
  183. package/src/wallets.ts +2 -1
  184. package/src/widget/assets/sequence-logo.svg +15 -0
  185. package/src/widget/compiled.css +2 -2
  186. package/src/widget/components/AccountActionsDropdown.tsx +18 -159
  187. package/src/widget/components/AccountIntentTransactionHistory.tsx +346 -63
  188. package/src/widget/components/AccountSettings.tsx +102 -0
  189. package/src/widget/components/ChainFilterDropdown.tsx +1 -1
  190. package/src/widget/components/ChainList.tsx +10 -20
  191. package/src/widget/components/ClassicSwap.tsx +921 -0
  192. package/src/widget/components/ConfigDisplay.tsx +41 -5
  193. package/src/widget/components/ConnectWallet.tsx +168 -11
  194. package/src/widget/components/ConnectedWallets.tsx +342 -0
  195. package/src/widget/components/DebugMenu.tsx +2 -0
  196. package/src/widget/components/DebugScreensList.tsx +3 -0
  197. package/src/widget/components/DebugToast.tsx +63 -0
  198. package/src/widget/components/Earn.tsx +112 -143
  199. package/src/widget/components/EarnPools.tsx +2 -4
  200. package/src/widget/components/EarnPoolsFilters.tsx +6 -6
  201. package/src/widget/components/FeeOption.tsx +78 -0
  202. package/src/widget/components/FeeOptions.tsx +192 -127
  203. package/src/widget/components/Fund.tsx +1236 -0
  204. package/src/widget/components/FundMethods.tsx +4 -4
  205. package/src/widget/components/FundSendForm.tsx +1 -34
  206. package/src/widget/components/Identicon.tsx +158 -0
  207. package/src/widget/components/MeshConnectExchanges.tsx +32 -3
  208. package/src/widget/components/MeshConnectFlow.tsx +23 -4
  209. package/src/widget/components/NativeGasOption.tsx +99 -0
  210. package/src/widget/components/Pay.tsx +1092 -0
  211. package/src/widget/components/PaySendForm.tsx +1 -38
  212. package/src/widget/components/QuoteDetails.tsx +1 -30
  213. package/src/widget/components/Receipt.tsx +1 -1
  214. package/src/widget/components/Receive.tsx +4 -2
  215. package/src/widget/components/RecentTokens.tsx +2 -1
  216. package/src/widget/components/Recipients.tsx +448 -0
  217. package/src/widget/components/RefundWarning.tsx +61 -0
  218. package/src/widget/components/ScreenHeader.tsx +1 -1
  219. package/src/widget/components/SimpleSwap.tsx +74 -58
  220. package/src/widget/components/Swap.tsx +35 -853
  221. package/src/widget/components/SwapSettings.tsx +5 -11
  222. package/src/widget/components/ThemeProvider.tsx +32 -0
  223. package/src/widget/components/ThemeSyncer.tsx +47 -0
  224. package/src/widget/components/Toast.tsx +315 -0
  225. package/src/widget/components/TokenList.tsx +2 -34
  226. package/src/widget/components/TokenSelector.tsx +14 -3
  227. package/src/widget/components/TransactionDetails.tsx +153 -13
  228. package/src/widget/components/TransferPendingVertical.tsx +1 -1
  229. package/src/widget/components/TruncatedAddress.tsx +5 -1
  230. package/src/widget/components/UserPreferences.tsx +155 -0
  231. package/src/widget/components/WalletList.tsx +1 -1
  232. package/src/widget/hooks/useBack.tsx +4 -0
  233. package/src/widget/hooks/useBalanceVisible.tsx +40 -2
  234. package/src/widget/hooks/useCheckout.ts +13 -0
  235. package/src/widget/hooks/useCurrentScreen.tsx +4 -0
  236. package/src/widget/hooks/useDebugScreens.ts +12 -2
  237. package/src/widget/hooks/useDefaultTokenSelection.tsx +471 -0
  238. package/src/widget/hooks/useIntentTransactionHistory.ts +212 -0
  239. package/src/widget/hooks/usePayMessage.tsx +370 -0
  240. package/src/widget/hooks/useRecipients.ts +168 -0
  241. package/src/widget/hooks/useSelectedFeeToken.tsx +299 -0
  242. package/src/widget/hooks/useSelectedMeshExchange.tsx +46 -0
  243. package/src/widget/hooks/useSelectedRecipient.tsx +48 -0
  244. package/src/widget/hooks/useSendForm.ts +257 -49
  245. package/src/widget/hooks/useSwapAmount.tsx +50 -0
  246. package/src/widget/hooks/useSwapSettings.tsx +100 -0
  247. package/src/widget/hooks/useTargetAmount.ts +23 -0
  248. package/src/widget/hooks/useTheme.tsx +80 -0
  249. package/src/widget/hooks/useTokenList.ts +20 -11
  250. package/src/widget/index.css +45 -21
  251. package/src/widget/widget.tsx +294 -136
  252. package/dist/address.d.ts +0 -2
  253. package/dist/address.d.ts.map +0 -1
  254. package/dist/proxyCaller.d.ts +0 -21
  255. package/dist/proxyCaller.d.ts.map +0 -1
  256. package/src/address.ts +0 -6
@@ -0,0 +1,218 @@
1
+ import type { Account, WalletClient, Hex, Address, PublicClient } from "viem"
2
+ import { intentEntrypoints } from "./constants.js"
3
+ import type { TrailsAPIClient } from "@0xsequence/trails-api"
4
+
5
+ // Intent Entrypoint ABI (partial - only the functions we need)
6
+ // TODO: Uncomment and use when implementing calldata injection
7
+ /* const INTENT_ENTRYPOINT_ABI = [
8
+ {
9
+ name: "depositToIntent",
10
+ type: "function",
11
+ stateMutability: "nonpayable",
12
+ inputs: [
13
+ { name: "user", type: "address" },
14
+ { name: "token", type: "address" },
15
+ { name: "amount", type: "uint256" },
16
+ { name: "intentAddress", type: "address" },
17
+ { name: "deadline", type: "uint256" },
18
+ { name: "sigV", type: "uint8" },
19
+ { name: "sigR", type: "bytes32" },
20
+ { name: "sigS", type: "bytes32" },
21
+ ],
22
+ outputs: [],
23
+ },
24
+ {
25
+ name: "depositToIntentWithPermit",
26
+ type: "function",
27
+ stateMutability: "nonpayable",
28
+ inputs: [
29
+ { name: "user", type: "address" },
30
+ { name: "token", type: "address" },
31
+ { name: "amount", type: "uint256" },
32
+ { name: "permitAmount", type: "uint256" },
33
+ { name: "intentAddress", type: "address" },
34
+ { name: "deadline", type: "uint256" },
35
+ { name: "permitV", type: "uint8" },
36
+ { name: "permitR", type: "bytes32" },
37
+ { name: "permitS", type: "bytes32" },
38
+ { name: "sigV", type: "uint8" },
39
+ { name: "sigR", type: "bytes32" },
40
+ { name: "sigS", type: "bytes32" },
41
+ ],
42
+ outputs: [],
43
+ },
44
+ ] as const */
45
+
46
+ // Note: EIP-712 typed data signing has been replaced with raw message signing
47
+ // The backend generates the EIP-712 hash and the client signs it as a raw message
48
+ // This simplifies the flow and avoids wallet compatibility issues
49
+
50
+ export type IntentEntrypointDepositParams = {
51
+ userAddress: Address
52
+ tokenAddress: Address
53
+ amount: bigint | string
54
+ intentAddress: Address
55
+ chainId: number
56
+ deadline?: number // Unix timestamp, defaults to 1 hour from now
57
+ usePermit?: boolean
58
+ permitDeadline?: number
59
+ }
60
+
61
+ export type IntentEntrypointDepositResult = {
62
+ depositWalletAddress: Address
63
+ metaTxn: {
64
+ id: string
65
+ chainId: string
66
+ contract: string
67
+ input: string
68
+ walletAddress: string
69
+ }
70
+ feeQuote: string
71
+ entrypointAddress: Address
72
+ }
73
+
74
+ export type IntentEntrypointFeeOptionsParams = {
75
+ userAddress: Address
76
+ tokenAddress: Address
77
+ amount: string
78
+ intentAddress: Address
79
+ chainID: number
80
+ }
81
+
82
+ export type FeeOption = {
83
+ tokenAddress: string
84
+ tokenSymbol: string
85
+ tokenDecimals: number
86
+ amount: string
87
+ amountUSD: number
88
+ feeCollector: string
89
+ }
90
+
91
+ export type GasEstimate = {
92
+ totalGas: number
93
+ gasPrice: string
94
+ nativeCost: string
95
+ nativeCostUSD: number
96
+ }
97
+
98
+ export type IntentEntrypointFeeOptionsResult = {
99
+ gasEstimate: GasEstimate
100
+ feeOptions: FeeOption[]
101
+ expiresAt: number
102
+ feeCollector: string
103
+ }
104
+
105
+ export type GaslessDepositOptions = {
106
+ trailsClient: TrailsAPIClient
107
+ walletClient: WalletClient
108
+ publicClient: PublicClient
109
+ account: Account
110
+ tokenAddress: Address
111
+ amount: bigint | string
112
+ intentAddress: Address
113
+ chainId: number
114
+ deadline?: number
115
+ usePermit?: boolean
116
+ onStatusUpdate?: (status: DepositStatus) => void
117
+ }
118
+
119
+ export enum DepositStatus {
120
+ PREPARING = "preparing",
121
+ SIGNING = "signing",
122
+ SUBMITTING = "submitting",
123
+ PENDING = "pending",
124
+ CONFIRMED = "confirmed",
125
+ FAILED = "failed",
126
+ }
127
+
128
+ /**
129
+ * Inject signatures into the meta transaction calldata
130
+ * This updates the placeholder signature values in the Intent Entrypoint call
131
+ *
132
+ * TODO: Implement this function to properly update nested calldata
133
+ * This would require:
134
+ * 1. Decode the guest module execdata
135
+ * 2. Find the Intent Entrypoint call
136
+ * 3. Replace its calldata with properly signed version
137
+ * 4. Re-encode the guest module execdata
138
+ *
139
+ * For reference, the signed calldata can be generated using:
140
+ * ```typescript
141
+ * const { v, r, s } = splitSignature(signatures.intent)
142
+ * const depositCalldata = encodeFunctionData({
143
+ * abi: INTENT_ENTRYPOINT_ABI,
144
+ * functionName: "depositToIntent",
145
+ * args: [userAddress, tokenAddress, amount, intentAddress, deadline, v, r, s],
146
+ * })
147
+ * ```
148
+ */
149
+
150
+ /**
151
+ * Split a signature into v, r, s components
152
+ * TODO: Use this when implementing calldata injection
153
+ */
154
+ export function splitSignature(signature: Hex): {
155
+ v: number
156
+ r: Hex
157
+ s: Hex
158
+ } {
159
+ // Remove 0x prefix if present
160
+ const sig = signature.startsWith("0x") ? signature.slice(2) : signature
161
+
162
+ if (sig.length !== 130) {
163
+ throw new Error(`Invalid signature length: ${sig.length}`)
164
+ }
165
+
166
+ const r = `0x${sig.slice(0, 64)}` as Hex
167
+ const s = `0x${sig.slice(64, 128)}` as Hex
168
+ const v = parseInt(sig.slice(128, 130), 16)
169
+
170
+ return { v, r, s }
171
+ }
172
+
173
+ /**
174
+ * Get the Intent Entrypoint address for a given chain
175
+ */
176
+ export function getIntentEntrypointAddress(chainId: number): Address | null {
177
+ return (intentEntrypoints[chainId] as Address) || null
178
+ }
179
+
180
+ /**
181
+ * Check if Intent Entrypoint is deployed on a chain
182
+ */
183
+ export function isIntentEntrypointSupported(chainId: number): boolean {
184
+ return chainId in intentEntrypoints
185
+ }
186
+
187
+ /**
188
+ * Get fee options for intent entrypoint deposits
189
+ */
190
+ export async function getIntentEntrypointFeeOptions({
191
+ trailsClient,
192
+ userAddress,
193
+ tokenAddress,
194
+ amount,
195
+ intentAddress,
196
+ chainId,
197
+ }: {
198
+ trailsClient: TrailsAPIClient
199
+ userAddress: Address
200
+ tokenAddress: Address
201
+ amount: bigint | string
202
+ intentAddress: Address
203
+ chainId: number
204
+ }): Promise<IntentEntrypointFeeOptionsResult> {
205
+ const params: IntentEntrypointFeeOptionsParams = {
206
+ userAddress,
207
+ tokenAddress,
208
+ amount: amount.toString(),
209
+ intentAddress,
210
+ chainID: chainId,
211
+ }
212
+
213
+ const response = await trailsClient.getIntentEntrypointDepositFeeOptions({
214
+ params,
215
+ })
216
+
217
+ return response.result
218
+ }
package/src/intents.ts CHANGED
@@ -5,8 +5,9 @@ import type {
5
5
  GetIntentCallsPayloadsReturn,
6
6
  IntentCallsPayload,
7
7
  IntentPrecondition,
8
- SequenceAPIClient,
9
8
  } from "@0xsequence/trails-api"
9
+ import type { TrailsAPIClient } from "@0xsequence/trails-api"
10
+ import type { TrailsClient } from "./trailsClient.js"
10
11
  import { logger } from "./logger.js"
11
12
  import { bigintReplacer } from "./utils.js"
12
13
 
@@ -35,9 +36,7 @@ import {
35
36
  import {
36
37
  ATTESATION_SIGNER_ADDRESS,
37
38
  SEQUENCE_V3_CONTRACT_ADDRESSES,
38
- TRAILS_CCTP_SAPIENT_SIGNER_ADDRESS,
39
- TRAILS_LIFI_SAPIENT_SIGNER_ADDRESS,
40
- TRAILS_RELAY_SAPIENT_SIGNER_ADDRESS,
39
+ SEQUENCE_V3_CONTRACT_ADDRESSES_OVERRIDES,
41
40
  } from "./constants.js"
42
41
  import { findPreconditionAddresses } from "./preconditions.js"
43
42
  import { getChainInfo } from "./chains.js"
@@ -129,58 +128,85 @@ export type SendOriginCallTxArgs = {
129
128
  chain: Chain
130
129
  }
131
130
 
132
- export async function getIntentCallsPayloads(
133
- apiClient: SequenceAPIClient,
134
- args: GetIntentCallsPayloadsArgs,
135
- additionalTrackingProps: Record<string, string> = {},
136
- ): Promise<GetIntentCallsPayloadsReturn> {
131
+ export async function getLocalClientIfEnabled(
132
+ apiClient: TrailsAPIClient,
133
+ ): Promise<TrailsAPIClient> {
137
134
  const localApiIntent = getQueryParam("localapiintent") === "true"
138
135
  if (localApiIntent) {
139
136
  // for testing local api changes
140
- const { getAPIClient } = await import("./apiClient.js")
141
- apiClient = getAPIClient({
142
- apiUrl: "http://localhost:4422",
137
+ const { getTrailsClient } = await import("./trailsClient.js")
138
+ apiClient = getTrailsClient({
139
+ hostname: "http://localhost:4422",
143
140
  })
144
141
  }
142
+ return apiClient
143
+ }
144
+
145
+ export async function getIntentCallsPayloads(
146
+ apiClient: TrailsAPIClient,
147
+ args: GetIntentCallsPayloadsArgs,
148
+ additionalTrackingProps: Record<string, string> = {},
149
+ ): Promise<GetIntentCallsPayloadsReturn> {
150
+ apiClient = await getLocalClientIfEnabled(apiClient)
145
151
 
146
152
  // Track intent quote request
147
153
  trackIntentQuoteRequested({
148
- originChainId: args.originChainId || 0,
149
- destinationChainId: args.destinationChainId || 0,
150
- originTokenAddress: args.originTokenAddress,
151
- destinationTokenAddress: args.destinationTokenAddress,
152
- userAddress: args.userAddress,
154
+ originChainId: args.params.originChainId || 0,
155
+ destinationChainId: args.params.destinationChainId || 0,
156
+ originTokenAddress: args.params.originTokenAddress,
157
+ destinationTokenAddress: args.params.destinationTokenAddress,
158
+ userAddress: args.params.userAddress,
153
159
  ...additionalTrackingProps,
154
160
  })
155
161
 
156
162
  try {
157
163
  logger.console.log("[trails-sdk] getIntentCallsPayloads args:", args)
158
- const result = await apiClient.getIntentCallsPayloads(args)
164
+ const result = await apiClient.getIntentCallsPayloads({
165
+ params: args.params,
166
+ })
159
167
 
160
168
  if (!result) {
161
169
  logger.console.error("[trails-sdk] No result from getIntentCallsPayloads")
162
170
  throw new Error("No result from getIntentCallsPayloads")
163
171
  }
164
172
 
173
+ // Extract precondition amounts
174
+ const originChainId = args.params.originChainId || 0
175
+ const destinationChainId = args.params.destinationChainId || 0
176
+ const originPrecondition = result.payloads.preconditions?.find(
177
+ (p: IntentPrecondition) => Number(p.chainId) === Number(originChainId),
178
+ )
179
+ const destinationPrecondition = result.payloads.preconditions?.find(
180
+ (p: IntentPrecondition) =>
181
+ Number(p.chainId) === Number(destinationChainId),
182
+ )
183
+
165
184
  // Track successful intent quote received
166
185
  trackIntentQuoteReceived({
167
- quoteId: result.originIntentAddress || "unknown",
168
- totalFeeUSD: result.trailsFee?.totalFeeUSD,
169
- trailsFixedFeeUSD: result.trailsFee?.trailsFixedFeeUSD,
170
- crossChainFeeTotalUSD: result.trailsFee?.crossChainFee?.totalFeeUSD,
171
- takerFeeUSD: result.trailsFee?.crossChainFee?.providerFeeUSD,
172
- providerFeeUSD: result.trailsFee?.crossChainFee?.providerFeeUSD,
173
- trailsSwapFeeUSD: result.trailsFee?.crossChainFee?.trailsSwapFeeUSD,
186
+ quoteId: result.payloads.originIntentAddress || "unknown",
187
+ totalFeeUSD: result.payloads.trailsFee?.totalFeeUSD,
188
+ crossChainFeeTotalUSD:
189
+ result.payloads.trailsFee?.crossChainFee?.totalFeeUSD,
190
+ providerFeeUSD: result.payloads.trailsFee?.crossChainFee?.providerFeeUSD,
191
+ trailsSwapFeeUSD:
192
+ result.payloads.trailsFee?.crossChainFee?.trailsSwapFeeUSD,
174
193
  gasFeesPerChainUSD:
175
- result.trailsFee?.executeQuote?.chainQuotes?.map((quote: any) =>
176
- parseFloat(quote.totalFeeUSD || "0"),
194
+ result.payloads.trailsFee?.executeQuote?.chainQuotes?.map(
195
+ (quote: any) => parseFloat(quote.totalFeeUSD || "0"),
177
196
  ) || [],
178
- originTokenTotalAmount: result.trailsFee?.originTokenTotalAmount,
179
- destinationTokenAmount: result.trailsFee?.totalFeeAmount, // Using available property
180
- provider: result.trailsFee?.quoteProvider,
181
- feeToken: result.trailsFee?.feeToken,
182
- userAddress: args.userAddress,
183
- intentAddress: result.originIntentAddress,
197
+ originTokenTotalAmount: result.payloads.trailsFee?.originTokenTotalAmount,
198
+ totalFeeAmount: result.payloads.trailsFee?.totalFeeAmount, // Using available property
199
+ provider: result.payloads.trailsFee?.quoteProvider,
200
+ feeToken: result.payloads.trailsFee?.feeToken,
201
+ userAddress: args.params.userAddress,
202
+ intentAddress: result.payloads.originIntentAddress,
203
+ originPreconditionAmount: originPrecondition?.data?.min?.toString(),
204
+ destinationPreconditionAmount:
205
+ destinationPrecondition?.data?.min?.toString(),
206
+ fromAmount: result.payloads.quote?.fromAmount,
207
+ fromAmountMin: result.payloads.quote?.fromAmountMin,
208
+ toAmount: result.payloads.quote?.toAmount,
209
+ toAmountMin: result.payloads.quote?.toAmountMin,
184
210
  ...additionalTrackingProps,
185
211
  })
186
212
 
@@ -190,11 +216,11 @@ export async function getIntentCallsPayloads(
190
216
  // Track intent quote error
191
217
  trackIntentQuoteError({
192
218
  error: getFullErrorMessage(error),
193
- userAddress: args.userAddress,
194
- originChainId: args.originChainId || 0,
195
- destinationChainId: args.destinationChainId || 0,
196
- originTokenAddress: args.originTokenAddress,
197
- destinationTokenAddress: args.destinationTokenAddress,
219
+ userAddress: args.params.userAddress,
220
+ originChainId: args.params.originChainId || 0,
221
+ destinationChainId: args.params.destinationChainId || 0,
222
+ originTokenAddress: args.params.originTokenAddress,
223
+ destinationTokenAddress: args.params.destinationTokenAddress,
198
224
  ...additionalTrackingProps,
199
225
  })
200
226
  throw error
@@ -277,13 +303,15 @@ export function calculateOriginAndDestinationIntentAddresses(
277
303
  }
278
304
 
279
305
  export async function commitIntentConfig(
280
- apiClient: SequenceAPIClient,
306
+ apiClient: TrailsClient,
281
307
  mainSignerAddress: string,
282
308
  calls: Array<IntentCallsPayload>,
283
309
  preconditions: Array<IntentPrecondition>,
284
310
  additionalTrackingProps: Record<string, string> = {},
285
311
  requestParams?: IntentRequestParams,
286
312
  ): Promise<CommitIntentConfigReturn> {
313
+ apiClient = await getLocalClientIfEnabled(apiClient)
314
+
287
315
  logger.console.log("[trails-sdk] commitIntentConfig inputs:", {
288
316
  mainSignerAddress,
289
317
  calls: JSON.stringify(calls, bigintReplacer, 2),
@@ -336,12 +364,21 @@ export async function commitIntentConfig(
336
364
  isAddressEqual(Address.from(receivedAddress), originIntentAddress),
337
365
  })
338
366
 
367
+ const addressOverrides = SEQUENCE_V3_CONTRACT_ADDRESSES_OVERRIDES
368
+
339
369
  const args: CommitIntentConfigArgs = {
340
- originIntentAddress: originIntentAddress.toString(),
341
- destinationIntentAddress: destinationIntentAddress.toString(),
342
- mainSigner: mainSignerAddress,
343
- calls: calls,
344
- preconditions: preconditions,
370
+ params: {
371
+ originIntentAddress: originIntentAddress.toString(),
372
+ destinationIntentAddress: destinationIntentAddress.toString(),
373
+ mainSigner: mainSignerAddress,
374
+ calls: calls,
375
+ preconditions: preconditions,
376
+ addressOverrides: addressOverrides,
377
+ requestParams: {
378
+ version: "1.0",
379
+ ...requestParams,
380
+ } as any,
381
+ },
345
382
  }
346
383
 
347
384
  // Add request parameters if provided
@@ -370,13 +407,6 @@ export async function commitIntentConfig(
370
407
  // This will need to be updated when the API client is regenerated
371
408
  }
372
409
 
373
- const addressOverrides = {
374
- trailsLiFiSapientSignerAddress: TRAILS_LIFI_SAPIENT_SIGNER_ADDRESS,
375
- trailsRelaySapientSignerAddress: TRAILS_RELAY_SAPIENT_SIGNER_ADDRESS,
376
- trailsCCTPV2SapientSignerAddress: TRAILS_CCTP_SAPIENT_SIGNER_ADDRESS,
377
- ...args.addressOverrides,
378
- }
379
-
380
410
  try {
381
411
  // Track successful intent commit
382
412
  trackIntentCommitStarted({
@@ -391,8 +421,6 @@ export async function commitIntentConfig(
391
421
 
392
422
  const result = await apiClient.commitIntentConfig({
393
423
  ...args,
394
- addressOverrides,
395
- // requestParams: requestParams, // TODO
396
424
  })
397
425
 
398
426
  // Track successful intent commit
@@ -458,13 +486,16 @@ export async function sendOriginTransaction(
458
486
  transport: http(),
459
487
  })
460
488
 
461
- const gasLimit = await publicClient.estimateGas({
489
+ const estimatedGasLimit = await publicClient.estimateGas({
462
490
  account: account,
463
491
  to: originParams.to as `0x${string}`,
464
492
  data: originParams.data as `0x${string}`,
465
493
  value: BigInt(originParams.value),
466
494
  })
467
495
 
496
+ const gsaBuffer = BigInt(50_000)
497
+ const gasLimit = estimatedGasLimit + gsaBuffer
498
+
468
499
  logger.console.log("[trails-sdk] estimated gasLimit:", gasLimit)
469
500
 
470
501
  logger.console.log(
@@ -92,6 +92,7 @@ export const useMetaTxnsMonitor = (
92
92
  }
93
93
  return newStatusEntry
94
94
  },
95
+ refetchIntervalInBackground: true,
95
96
  refetchInterval: (
96
97
  query: Query<
97
98
  Relayer.OperationStatus,
package/src/morpho.ts CHANGED
@@ -295,11 +295,22 @@ function transformVaultToPool(vaultData: any): Pool | null {
295
295
  // Use the actual APY from the API
296
296
  const apy = state?.apy || state?.netApy || 0
297
297
 
298
+ const decimals = asset?.decimals
299
+ if (!decimals) {
300
+ // logger.console.warn("Decimals not found", {
301
+ // asset,
302
+ // state,
303
+ // vaultData,
304
+ // chainId,
305
+ // })
306
+ return null
307
+ }
308
+
298
309
  // Calculate TVL from totalAssetsUsd if available, otherwise from totalAssets
299
310
  const tvl = state?.totalAssetsUsd
300
311
  ? Number(state.totalAssetsUsd)
301
312
  : state?.totalAssets
302
- ? Number(state.totalAssets) / 10 ** (asset?.decimals || 18)
313
+ ? Number(state.totalAssets) / 10 ** decimals
303
314
  : 0
304
315
 
305
316
  // Filter out vaults with TVL < 1M OR APY > 20%
@@ -324,7 +335,7 @@ function transformVaultToPool(vaultData: any): Pool | null {
324
335
  symbol: vaultData.symbol || asset?.symbol || "UNKNOWN",
325
336
  name: vaultData.name || asset?.name || "Unknown Token",
326
337
  address: asset?.address || vaultData.address,
327
- decimals: asset?.decimals || 18,
338
+ decimals,
328
339
  logoUrl: asset?.logoURI || undefined,
329
340
  },
330
341
  depositAddress: vaultData.address,
package/src/pools.ts CHANGED
@@ -1,19 +1,9 @@
1
- import { useMemo, useEffect } from "react"
1
+ import { useMemo } from "react"
2
+ import { useQuery } from "@tanstack/react-query"
2
3
  import { useAavePools } from "./aave.js"
3
4
  import { useMorphoVaults } from "./morpho.js"
4
5
  import { logger } from "./logger.js"
5
6
 
6
- // Cache configuration
7
- const CACHE_DURATION = 5 * 60 * 1000 // 5 minutes in milliseconds
8
-
9
- // Global cache for pools data
10
- let poolsCache: {
11
- data: Pool[]
12
- timestamp: number
13
- aaveData: Pool[] | null
14
- morphoData: Pool[] | null
15
- } | null = null
16
-
17
7
  // Pool data interface (shared across all protocols)
18
8
  export interface Pool {
19
9
  id: string
@@ -36,7 +26,7 @@ export interface Pool {
36
26
  wrappedTokenGatewayAddress?: string
37
27
  }
38
28
 
39
- export function usePools() {
29
+ export function usePools({ enabled = true }: { enabled?: boolean } = {}) {
40
30
  // Fetch pools from Aave
41
31
  const {
42
32
  data: aavePools,
@@ -51,31 +41,18 @@ export function usePools() {
51
41
  error: morphoError,
52
42
  } = useMorphoVaults()
53
43
 
54
- // Check if cache is valid
55
- const isCacheValid = useMemo(() => {
56
- if (!poolsCache) return false
57
-
58
- const now = Date.now()
59
- const isExpired = now - poolsCache.timestamp > CACHE_DURATION
60
-
61
- // Check if underlying data has changed
62
- const aaveDataChanged =
63
- JSON.stringify(poolsCache.aaveData) !== JSON.stringify(aavePools)
64
- const morphoDataChanged =
65
- JSON.stringify(poolsCache.morphoData) !== JSON.stringify(morphoPools)
66
-
67
- return !isExpired && !aaveDataChanged && !morphoDataChanged
68
- }, [aavePools, morphoPools])
44
+ // Combine pools data with memoization
45
+ const combinedPools = useMemo(() => {
46
+ // Don't process if not enabled
47
+ if (!enabled) {
48
+ return []
49
+ }
69
50
 
70
- // Combine and transform all pools with caching
71
- const allPools: Pool[] = useMemo(() => {
72
- // Return cached data if valid
73
- if (isCacheValid && poolsCache) {
74
- logger.console.log("[trails-sdk] Using cached pools data")
75
- return poolsCache.data
51
+ if (!aavePools && !morphoPools) {
52
+ return []
76
53
  }
77
54
 
78
- logger.console.log("[trails-sdk] Generating new pools data")
55
+ logger.console.log("[trails-sdk] Combining pools data from sources")
79
56
  const pools: Pool[] = []
80
57
 
81
58
  // Add Aave pools
@@ -88,68 +65,73 @@ export function usePools() {
88
65
  pools.push(...morphoPools)
89
66
  }
90
67
 
91
- // Update cache
92
- poolsCache = {
93
- data: pools,
94
- timestamp: Date.now(),
95
- aaveData: aavePools,
96
- morphoData: morphoPools,
68
+ // Sort by APY descending
69
+ const sortedPools = pools.sort((a: Pool, b: Pool) => b.apy - a.apy)
70
+
71
+ logger.console.log(
72
+ "[trails-sdk] Combined and sorted",
73
+ sortedPools.length,
74
+ "pools",
75
+ )
76
+ return sortedPools
77
+ }, [aavePools, morphoPools, enabled])
78
+
79
+ // Use React Query for caching the combined pools data
80
+ const { data: cachedPools } = useQuery({
81
+ queryKey: ["pools", "combined", combinedPools.length, enabled],
82
+ queryFn: async () => {
83
+ return combinedPools
84
+ },
85
+ enabled: enabled && combinedPools.length > 0,
86
+ staleTime: 5 * 60 * 1000, // 5 minutes
87
+ gcTime: 10 * 60 * 1000, // 10 minutes
88
+ refetchOnWindowFocus: false,
89
+ refetchIntervalInBackground: true,
90
+ refetchOnReconnect: true,
91
+ retry: 2,
92
+ initialData: combinedPools.length > 0 ? combinedPools : undefined,
93
+ })
94
+
95
+ // Determine loading state
96
+ const loading = useMemo(() => {
97
+ // If not enabled, never show loading
98
+ if (!enabled) {
99
+ return false
97
100
  }
98
101
 
99
- return pools
100
- }, [aavePools, morphoPools, isCacheValid])
101
-
102
- // Determine overall loading and error states
103
- const loading = useMemo(() => {
104
- // Don't show loading if we have valid cached data
105
- if (isCacheValid && poolsCache) {
102
+ // If we have cached data, never show loading (this is the key fix!)
103
+ if (cachedPools && cachedPools.length > 0) {
104
+ logger.console.log("[trails-sdk] Using cached pools, not showing loading")
106
105
  return false
107
106
  }
108
- return aaveLoading || morphoLoading
109
- }, [aaveLoading, morphoLoading, isCacheValid])
110
107
 
108
+ // Show loading if sources are still loading
109
+ const shouldShowLoading = aaveLoading || morphoLoading
110
+
111
+ if (shouldShowLoading) {
112
+ logger.console.log("[trails-sdk] Showing loading - sources still loading")
113
+ }
114
+
115
+ return shouldShowLoading
116
+ }, [aaveLoading, morphoLoading, cachedPools, enabled])
117
+
118
+ // Determine error state
111
119
  const error = useMemo(() => {
112
- // Don't show error if we have valid cached data
113
- if (isCacheValid && poolsCache) {
120
+ // If not enabled, don't show errors
121
+ if (!enabled) {
114
122
  return null
115
123
  }
116
- return aaveError || morphoError
117
- }, [aaveError, morphoError, isCacheValid])
118
-
119
- // Sort by APY descending with caching
120
- const sortedPools = useMemo(() => {
121
- return allPools.sort((a: Pool, b: Pool) => b.apy - a.apy)
122
- }, [allPools])
123
-
124
- // Clear cache when there are errors
125
- useEffect(() => {
126
- if (aaveError || morphoError) {
127
- logger.console.log("[trails-sdk] Clearing cache due to errors")
128
- poolsCache = null
124
+
125
+ // If we have cached data, don't show errors
126
+ if (cachedPools && cachedPools.length > 0) {
127
+ return null
129
128
  }
130
- }, [aaveError, morphoError])
131
-
132
- // logger.console.log("[trails-sdk] === COMBINED POOLS DEBUG ===")
133
- // logger.console.log("[trails-sdk] Cache valid:", isCacheValid)
134
- // logger.console.log("[trails-sdk] Aave pools count:", aavePools?.length || 0)
135
- // logger.console.log("[trails-sdk] Morpho pools count:", morphoPools?.length || 0)
136
- // logger.console.log("[trails-sdk] Total pools count:", sortedPools.length)
137
- // logger.console.log(
138
- // "[trails-sdk] Loading states - Aave:",
139
- // aaveLoading,
140
- // "Morpho:",
141
- // morphoLoading,
142
- // )
143
- // logger.console.log(
144
- // "[trails-sdk] Error states - Aave:",
145
- // aaveError,
146
- // "Morpho:",
147
- // morphoError,
148
- // )
149
- // logger.console.log("[trails-sdk] ==============================")
129
+
130
+ return aaveError || morphoError
131
+ }, [aaveError, morphoError, cachedPools, enabled])
150
132
 
151
133
  return {
152
- data: sortedPools,
134
+ data: cachedPools || [],
153
135
  loading,
154
136
  error,
155
137
  }