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
@@ -7,20 +7,28 @@ import type {
7
7
  TokenBalance,
8
8
  } from "@0xsequence/indexer"
9
9
  import { ContractVerificationStatus } from "@0xsequence/indexer"
10
- import type { Page, Price, SequenceAPIClient } from "@0xsequence/api"
10
+ import type { Page } from "@0xsequence/indexer"
11
+ import type { TokenPrice as TrailsTokenPrice } from "@0xsequence/trails-api"
11
12
  import { QueryClient, useQuery } from "@tanstack/react-query"
12
13
  import type { Address } from "ox"
13
14
  import { useEffect, useState } from "react"
14
15
  import { formatUnits, parseUnits, zeroAddress } from "viem"
15
- import { useAPIClient } from "./apiClient.js"
16
16
  import { useIndexerGatewayClient } from "./indexerClient.js"
17
17
  import { getTokenPrices, useTokenPrices } from "./prices.js"
18
18
  import { logger } from "./logger.js"
19
19
  import { getChainInfo } from "./chains.js"
20
20
  import { getTokenImageUrl } from "./tokens.js"
21
+ import type { TrailsClient } from "./trailsClient.js"
22
+ import { useTrailsClient } from "./trailsClient.js"
23
+ import { getFullErrorMessage } from "./error.js"
21
24
 
22
25
  export type { NativeTokenBalance, TokenBalance }
23
26
 
27
+ export type Price = {
28
+ value: number
29
+ currency: string
30
+ }
31
+
24
32
  const REFRESH_INTERVAL = 10000 // 10 seconds
25
33
 
26
34
  // Initialize query client for token balances
@@ -163,7 +171,7 @@ export interface GetTokenBalancesWithPrice {
163
171
  export function useTokenBalances(
164
172
  address: Address.Address,
165
173
  indexerGatewayClient?: SequenceIndexerGateway,
166
- sequenceApiClient?: SequenceAPIClient,
174
+ sequenceApiClient?: TrailsClient,
167
175
  ): {
168
176
  tokenBalancesData: GetTokenBalancesSummaryReturn | undefined
169
177
  isLoadingBalances: boolean
@@ -174,11 +182,11 @@ export function useTokenBalances(
174
182
  } {
175
183
  // Always call hooks unconditionally to fix React rules violation
176
184
  const hookIndexerClient = useIndexerGatewayClient()
177
- const hookApiClient = useAPIClient()
185
+ const hookTrailsClient = useTrailsClient()
178
186
 
179
187
  // Use passed parameters if available, otherwise use hook results
180
188
  const indexerClient = indexerGatewayClient ?? hookIndexerClient
181
- const apiClient = sequenceApiClient ?? hookApiClient
189
+ const apiClient = sequenceApiClient ?? hookTrailsClient
182
190
 
183
191
  // Fetch token balances with improved query key structure
184
192
  const {
@@ -186,7 +194,7 @@ export function useTokenBalances(
186
194
  isLoading: isLoadingBalances,
187
195
  error: balanceError,
188
196
  } = useQuery<GetTokenBalancesWithPrice>({
189
- queryKey: ["tokenBalances", "summary", address],
197
+ queryKey: ["getTokenBalancesWithPrices", "summary", address],
190
198
  queryFn: async (): Promise<GetTokenBalancesWithPrice> => {
191
199
  if (!address) {
192
200
  logger.console.warn("[trails-sdk] No account address or indexer client")
@@ -212,6 +220,33 @@ export function useTokenBalances(
212
220
  ).flatMap((b) => b.results),
213
221
  }
214
222
  } catch (error) {
223
+ const errorMessage = getFullErrorMessage(error)
224
+
225
+ // Check if this is a CORS error or network error
226
+ const isCorsError =
227
+ errorMessage.includes("Cross-Origin") ||
228
+ errorMessage.includes("CORS") ||
229
+ errorMessage.includes("Same Origin Policy")
230
+ const isNetworkError =
231
+ errorMessage.includes("fetch failed") ||
232
+ errorMessage.includes("network")
233
+
234
+ if (isCorsError || isNetworkError) {
235
+ logger.console.warn(
236
+ "[trails-sdk] Network or CORS error fetching token balances in hook, returning empty result:",
237
+ {
238
+ error: errorMessage,
239
+ address,
240
+ },
241
+ )
242
+ // Return empty balances instead of throwing to prevent error boundary
243
+ return {
244
+ page: defaultPage,
245
+ balances: [],
246
+ nativeBalances: [],
247
+ }
248
+ }
249
+
215
250
  logger.console.error(
216
251
  "[trails-sdk] Failed to fetch token balances:",
217
252
  error,
@@ -240,16 +275,16 @@ export function useTokenBalances(
240
275
  (tokenBalancesData?.balances ?? [])
241
276
  .map((b: any) => {
242
277
  return {
243
- tokenId: b.contractInfo?.symbol,
244
- contractAddress: b.contractAddress,
245
- chainId: b.contractInfo?.chainId!,
278
+ tokenSymbol: b.contractInfo?.symbol,
279
+ tokenAddress: b.contractAddress,
280
+ chainId: b.contractInfo?.chainId,
246
281
  }
247
282
  })
248
283
  .concat(
249
284
  (tokenBalancesData?.nativeBalances ?? []).map((b) => {
250
285
  return {
251
- tokenId: b.symbol,
252
- contractAddress: zeroAddress,
286
+ tokenSymbol: b.symbol,
287
+ tokenAddress: zeroAddress,
253
288
  chainId: b.chainId,
254
289
  }
255
290
  }),
@@ -314,23 +349,25 @@ export function useTokenBalances(
314
349
  // First pass: add prices to all tokens
315
350
  const tokensWithPrices = balances.map((token) => {
316
351
  const isNative = isNativeToken(token)
317
- const priceData = tokenPrices.find(
318
- (p: { token: { contractAddress: string; chainId: number } }) =>
319
- p.token.contractAddress ===
352
+ const priceData: TrailsTokenPrice | undefined = tokenPrices.find(
353
+ (p) =>
354
+ p.token.tokenAddress ===
320
355
  (isNative ? zeroAddress : token.contractAddress) &&
321
356
  p.token.chainId ===
322
357
  (isNative ? token.chainId : token.contractInfo?.chainId),
323
358
  )
324
359
 
325
- if (priceData?.price) {
326
- const tokenWithPrice = { ...token, price: priceData.price }
327
- tokenWithPrice.balanceUsd = getTokenBalanceUsd(
328
- token,
329
- priceData.price,
330
- )
360
+ if (priceData?.priceUsd !== undefined) {
361
+ // Create a Price object compatible with the indexer API
362
+ const price: Price = {
363
+ value: priceData.priceUsd,
364
+ currency: "USD",
365
+ }
366
+ const tokenWithPrice = { ...token, price }
367
+ tokenWithPrice.balanceUsd = getTokenBalanceUsd(token, price)
331
368
  tokenWithPrice.balanceUsdFormatted = getTokenBalanceUsdFormatted(
332
369
  token,
333
- priceData.price,
370
+ price,
334
371
  )
335
372
  return tokenWithPrice
336
373
  }
@@ -519,6 +556,24 @@ export function formatUsdAmountDisplay(value: number | string = 0): string {
519
556
  const MAX_DISPLAY_VALUE = 100_000_000_000_000
520
557
  const cappedValue = Math.min(absValue, MAX_DISPLAY_VALUE)
521
558
 
559
+ // For very small amounts (less than $0.01), show 3 decimal places or <$0.01
560
+ if (cappedValue > 0 && cappedValue < 0.01) {
561
+ const displayValue = Intl.NumberFormat("en-US", {
562
+ style: "currency",
563
+ currency: "USD",
564
+ maximumFractionDigits: 3,
565
+ minimumFractionDigits: 3,
566
+ }).format(isNegative ? -cappedValue : cappedValue)
567
+
568
+ // If still rounds to $0.000, show <$0.01
569
+ if (displayValue === "$0.000") {
570
+ return `<$0.01`
571
+ }
572
+
573
+ return displayValue
574
+ }
575
+
576
+ // For amounts >= $0.01, use standard 2 decimal places
522
577
  const displayValue = Intl.NumberFormat("en-US", {
523
578
  style: "currency",
524
579
  currency: "USD",
@@ -526,10 +581,6 @@ export function formatUsdAmountDisplay(value: number | string = 0): string {
526
581
  minimumFractionDigits: 2,
527
582
  }).format(isNegative ? -cappedValue : cappedValue)
528
583
 
529
- if (displayValue === "$0.00" && absValue > 0 && absValue < 0.01) {
530
- return `<$0.01`
531
- }
532
-
533
584
  return displayValue
534
585
  }
535
586
 
@@ -580,6 +631,32 @@ export async function fetchGetTokenBalancesSummary({
580
631
 
581
632
  return summaryFromGateway as unknown as GetTokenBalancesSummaryReturn
582
633
  } catch (error) {
634
+ const errorMessage = getFullErrorMessage(error)
635
+
636
+ // Check if this is a CORS error or network error
637
+ const isCorsError =
638
+ errorMessage.includes("Cross-Origin") ||
639
+ errorMessage.includes("CORS") ||
640
+ errorMessage.includes("Same Origin Policy")
641
+ const isNetworkError =
642
+ errorMessage.includes("fetch failed") || errorMessage.includes("network")
643
+
644
+ if (isCorsError || isNetworkError) {
645
+ logger.console.warn(
646
+ "[trails-sdk] Network or CORS error fetching token balances, returning empty result:",
647
+ {
648
+ error: errorMessage,
649
+ account,
650
+ },
651
+ )
652
+ // Return empty balances instead of throwing to prevent error boundary
653
+ return {
654
+ balances: [],
655
+ nativeBalances: [],
656
+ page: defaultPage,
657
+ }
658
+ }
659
+
583
660
  logger.console.error(
584
661
  "[trails-sdk] Failed to fetch token balances summary:",
585
662
  error,
@@ -593,7 +670,7 @@ export async function getTokenBalances({
593
670
  indexerGatewayClient,
594
671
  }: GetTokenBalancesParams): Promise<GetTokenBalancesSummaryReturn> {
595
672
  return tokenBalancesQueryClient.fetchQuery({
596
- queryKey: ["tokenBalances", "summary", account],
673
+ queryKey: ["fetchGetTokenBalancesSummary", "summary", account],
597
674
  queryFn: () =>
598
675
  fetchGetTokenBalancesSummary({ account, indexerGatewayClient }),
599
676
  staleTime: REFRESH_INTERVAL, // 10 seconds - faster updates for balance changes
@@ -603,17 +680,23 @@ export async function getTokenBalances({
603
680
 
604
681
  // Cache invalidation utility function
605
682
  export function invalidateTokenBalancesCache(account?: string) {
683
+ // Invalidate all token balance queries that match the pattern
684
+ // This will match all queries starting with ["tokenBalances", ...]
685
+ // We invalidate all instead of filtering by account because queries have
686
+ // different structures: ["tokenBalances", "summary", address],
687
+ // ["tokenBalances", "sorted", address, ...], etc.
606
688
  if (account) {
607
- // Invalidate specific account's token balances
608
- tokenBalancesQueryClient.invalidateQueries({
609
- queryKey: ["tokenBalances", account],
610
- })
689
+ logger.console.log(
690
+ "[trails-sdk] Invalidating token balances cache for account:",
691
+ account,
692
+ )
611
693
  } else {
612
- // Invalidate all token balance queries
613
- tokenBalancesQueryClient.invalidateQueries({
614
- queryKey: ["tokenBalances"],
615
- })
694
+ logger.console.log("[trails-sdk] Invalidating all token balances cache")
616
695
  }
696
+
697
+ tokenBalancesQueryClient.invalidateQueries({
698
+ queryKey: ["getTokenBalancesWithPrices"],
699
+ })
617
700
  }
618
701
 
619
702
  export type GetTokenBalancesFlatArrayParams = {
@@ -684,7 +767,7 @@ export async function getTokenBalancesFlatArray({
684
767
  export type GetTokenBalancesWithPricesParams = {
685
768
  account: string
686
769
  indexerGatewayClient: SequenceIndexerGateway
687
- apiClient: SequenceAPIClient
770
+ trailsClient: TrailsClient
688
771
  }
689
772
 
690
773
  export type GetTokenBalancesWithPriceReturn = {
@@ -694,32 +777,43 @@ export type GetTokenBalancesWithPriceReturn = {
694
777
  export async function getTokenBalancesWithPrices({
695
778
  account,
696
779
  indexerGatewayClient,
697
- apiClient,
780
+ trailsClient,
698
781
  }: GetTokenBalancesWithPricesParams): Promise<GetTokenBalancesWithPriceReturn> {
699
782
  const tokens = await getTokenBalancesFlatArray({
700
783
  account,
701
784
  indexerGatewayClient,
702
785
  })
703
- const tokenPrices = await getTokenPrices(apiClient, tokens)
786
+ const tokenPrices = await getTokenPrices(
787
+ trailsClient,
788
+ tokens.map((t) => ({
789
+ chainId: t.chainId,
790
+ tokenAddress: t.contractAddress || zeroAddress,
791
+ tokenSymbol: t.contractInfo?.symbol || "",
792
+ })),
793
+ )
704
794
  const balancesWithPrices = tokens.map((b) => {
705
- const price = tokenPrices.find((p) => {
795
+ const priceData: TrailsTokenPrice | undefined = tokenPrices.find((p) => {
706
796
  const isSameChain = p.token.chainId === b.chainId
707
- let isSameToken = p.token.contractAddress === b.contractAddress
797
+ let isSameToken = p.token.tokenAddress === b.contractAddress
708
798
  if (!b.contractAddress) {
709
799
  isSameToken =
710
- p.token.contractAddress === zeroAddress || !p.token.contractAddress
800
+ p.token.tokenAddress === zeroAddress || !p.token.tokenAddress
711
801
  }
712
802
  return isSameChain && isSameToken
713
803
  })
714
804
 
805
+ // Convert TrailsTokenPrice to Price format for compatibility
806
+ const price: Price | undefined =
807
+ priceData?.priceUsd !== undefined
808
+ ? { value: priceData.priceUsd, currency: "USD" }
809
+ : undefined
810
+
715
811
  return {
716
812
  ...b,
717
- price: price?.price,
718
- balanceUsd: price?.price
719
- ? getTokenBalanceUsd(b, price?.price)
720
- : undefined,
721
- balanceUsdFormatted: price?.price
722
- ? getTokenBalanceUsdFormatted(b, price?.price)
813
+ price,
814
+ balanceUsd: price ? getTokenBalanceUsd(b, price) : undefined,
815
+ balanceUsdFormatted: price
816
+ ? getTokenBalanceUsdFormatted(b, price)
723
817
  : undefined,
724
818
  }
725
819
  })
@@ -734,7 +828,7 @@ export type UseAccountTokenBalanceParams = {
734
828
  token?: string | null
735
829
  chainId?: number | null
736
830
  indexerGatewayClient?: SequenceIndexerGateway | null
737
- apiClient?: SequenceAPIClient | null
831
+ trailsClient?: TrailsClient | null
738
832
  }
739
833
 
740
834
  export function useAccountTokenBalance({
@@ -742,15 +836,15 @@ export function useAccountTokenBalance({
742
836
  token,
743
837
  chainId,
744
838
  indexerGatewayClient,
745
- apiClient,
839
+ trailsClient,
746
840
  }: UseAccountTokenBalanceParams) {
747
841
  const { data: tokenBalance, isLoading: isLoadingTokenBalance } = useQuery({
748
- queryKey: ["tokenBalances", "balances", account],
842
+ queryKey: ["getTokenBalancesWithPrices", "balances", account],
749
843
  queryFn: async () => {
750
844
  if (
751
845
  !account ||
752
846
  !indexerGatewayClient ||
753
- !apiClient ||
847
+ !trailsClient ||
754
848
  !token ||
755
849
  !chainId
756
850
  ) {
@@ -759,7 +853,7 @@ export function useAccountTokenBalance({
759
853
  const { balances } = await getTokenBalancesWithPrices({
760
854
  account,
761
855
  indexerGatewayClient,
762
- apiClient,
856
+ trailsClient,
763
857
  })
764
858
  const tokenBalance = balances.find(
765
859
  (b) =>
@@ -784,7 +878,7 @@ export type HasSufficientBalanceParams = {
784
878
  amount: string
785
879
  chainId: number
786
880
  indexerGatewayClient: SequenceIndexerGateway
787
- apiClient: SequenceAPIClient
881
+ trailsClient: TrailsClient
788
882
  }
789
883
 
790
884
  export async function getHasSufficientBalanceToken({
@@ -793,12 +887,12 @@ export async function getHasSufficientBalanceToken({
793
887
  amount,
794
888
  chainId,
795
889
  indexerGatewayClient,
796
- apiClient,
890
+ trailsClient,
797
891
  }: HasSufficientBalanceParams): Promise<boolean> {
798
892
  const { balances } = await getTokenBalancesWithPrices({
799
893
  account,
800
894
  indexerGatewayClient,
801
- apiClient,
895
+ trailsClient,
802
896
  })
803
897
  const tokenBalance: TokenBalanceExtended | null | undefined = balances.find(
804
898
  (b) =>
@@ -829,13 +923,20 @@ export function useHasSufficientBalanceToken(
829
923
  isLoadingHasSufficientBalanceToken: boolean
830
924
  } {
831
925
  const indexerGatewayClient = useIndexerGatewayClient()
832
- const apiClient = useAPIClient()
926
+ const trailsClient = useTrailsClient()
833
927
 
834
928
  const {
835
929
  data: hasSufficientBalanceToken,
836
930
  isLoading: isLoadingHasSufficientBalanceToken,
837
931
  } = useQuery({
838
- queryKey: ["tokenBalances", "sufficient", account, token, amount, chainId],
932
+ queryKey: [
933
+ "getHasSufficientBalanceToken",
934
+ "sufficient",
935
+ account,
936
+ token,
937
+ amount,
938
+ chainId,
939
+ ],
839
940
  queryFn: () =>
840
941
  account
841
942
  ? getHasSufficientBalanceToken({
@@ -844,7 +945,7 @@ export function useHasSufficientBalanceToken(
844
945
  amount: amount,
845
946
  chainId: chainId,
846
947
  indexerGatewayClient: indexerGatewayClient,
847
- apiClient: apiClient,
948
+ trailsClient: trailsClient,
848
949
  })
849
950
  : null,
850
951
  enabled: !!account && !!token && !!amount && !!chainId,
@@ -869,19 +970,19 @@ export type GetHasSufficientBalanceUsdParams = {
869
970
  account: string
870
971
  targetAmountUsd: number | string
871
972
  indexerGatewayClient: SequenceIndexerGateway
872
- apiClient: SequenceAPIClient
973
+ trailsClient: TrailsClient
873
974
  }
874
975
 
875
976
  export async function getHasSufficientBalanceUsd({
876
977
  account,
877
978
  targetAmountUsd,
878
979
  indexerGatewayClient,
879
- apiClient,
980
+ trailsClient,
880
981
  }: GetHasSufficientBalanceUsdParams): Promise<boolean> {
881
982
  const totalBalanceUsd = await getAccountTotalBalanceUsd({
882
983
  account,
883
984
  indexerGatewayClient,
884
- apiClient,
985
+ trailsClient,
885
986
  })
886
987
  return totalBalanceUsd >= Number(targetAmountUsd)
887
988
  }
@@ -895,21 +996,26 @@ export function useHasSufficientBalanceUsd(
895
996
  hasSufficientBalanceUsdError: Error | null
896
997
  } {
897
998
  const indexerGatewayClient = useIndexerGatewayClient()
898
- const apiClient = useAPIClient()
999
+ const trailsClient = useTrailsClient()
899
1000
 
900
1001
  const {
901
1002
  data: hasSufficientBalanceUsd,
902
1003
  isLoading: isLoadingHasSufficientBalanceUsd,
903
1004
  error: hasSufficientBalanceUsdError,
904
1005
  } = useQuery({
905
- queryKey: ["tokenBalances", "sufficientUsd", account, targetAmountUsd],
1006
+ queryKey: [
1007
+ "getHasSufficientBalanceUsd",
1008
+ "sufficientUsd",
1009
+ account,
1010
+ targetAmountUsd,
1011
+ ],
906
1012
  queryFn: () =>
907
1013
  account && targetAmountUsd
908
1014
  ? getHasSufficientBalanceUsd({
909
1015
  account: account,
910
1016
  targetAmountUsd: targetAmountUsd,
911
1017
  indexerGatewayClient: indexerGatewayClient,
912
- apiClient: apiClient,
1018
+ trailsClient: trailsClient,
913
1019
  })
914
1020
  : false,
915
1021
  enabled: !!account && !!targetAmountUsd,
@@ -935,18 +1041,18 @@ export function useHasSufficientBalanceUsd(
935
1041
  export type GetAccountTotalBalanceUsdParams = {
936
1042
  account: string
937
1043
  indexerGatewayClient: SequenceIndexerGateway
938
- apiClient: SequenceAPIClient
1044
+ trailsClient: TrailsClient
939
1045
  }
940
1046
 
941
1047
  export async function getAccountTotalBalanceUsd({
942
1048
  account,
943
1049
  indexerGatewayClient,
944
- apiClient,
1050
+ trailsClient,
945
1051
  }: GetAccountTotalBalanceUsdParams): Promise<number> {
946
1052
  const { balances } = await getTokenBalancesWithPrices({
947
1053
  account,
948
1054
  indexerGatewayClient,
949
- apiClient,
1055
+ trailsClient,
950
1056
  })
951
1057
 
952
1058
  return balances.reduce((acc, b) => acc + (b.balanceUsd ?? 0), 0)
@@ -958,17 +1064,17 @@ export function useAccountTotalBalanceUsd(account: string): {
958
1064
  totalBalanceUsdFormatted: string
959
1065
  } {
960
1066
  const indexerGatewayClient = useIndexerGatewayClient()
961
- const apiClient = useAPIClient()
1067
+ const trailsClient = useTrailsClient()
962
1068
 
963
1069
  const { data: totalBalanceUsd, isLoading: isLoadingTotalBalanceUsd } =
964
1070
  useQuery({
965
- queryKey: ["tokenBalances", "totalUsd", account],
1071
+ queryKey: ["getAccountTotalBalanceUsd", "totalUsd", account],
966
1072
  queryFn: () =>
967
1073
  account
968
1074
  ? getAccountTotalBalanceUsd({
969
1075
  account: account,
970
1076
  indexerGatewayClient: indexerGatewayClient,
971
- apiClient: apiClient,
1077
+ trailsClient: trailsClient,
972
1078
  })
973
1079
  : null,
974
1080
  enabled: !!account,