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.
- package/dist/aave.d.ts +2 -0
- package/dist/aave.d.ts.map +1 -1
- package/dist/abortController.d.ts +8 -0
- package/dist/abortController.d.ts.map +1 -0
- package/dist/{ccip-CXlshvBY.js → ccip-BMB3uDZt.js} +1 -1
- package/dist/config.d.ts +0 -5
- package/dist/config.d.ts.map +1 -1
- package/dist/constants.d.ts +4 -4
- package/dist/constants.d.ts.map +1 -1
- package/dist/error.d.ts +4 -1
- package/dist/error.d.ts.map +1 -1
- package/dist/fees.d.ts +19 -0
- package/dist/fees.d.ts.map +1 -0
- package/dist/{index-_QuyGrjU.js → index-QXPUrZVv.js} +48719 -50852
- package/dist/index.d.ts +9 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +811 -784
- package/dist/intentReceiptMonitor.d.ts +24 -0
- package/dist/intentReceiptMonitor.d.ts.map +1 -0
- package/dist/intentReceiptPoller.d.ts +69 -0
- package/dist/intentReceiptPoller.d.ts.map +1 -0
- package/dist/intents.d.ts +15 -11
- package/dist/intents.d.ts.map +1 -1
- package/dist/morpho.d.ts +6 -5
- package/dist/morpho.d.ts.map +1 -1
- package/dist/mutations.d.ts +16 -0
- package/dist/mutations.d.ts.map +1 -0
- package/dist/preconditions.d.ts +5 -4
- package/dist/preconditions.d.ts.map +1 -1
- package/dist/prepareSend.d.ts +7 -258
- package/dist/prepareSend.d.ts.map +1 -1
- package/dist/prices.d.ts +9 -6
- package/dist/prices.d.ts.map +1 -1
- package/dist/sequenceWallet.d.ts +3 -16
- package/dist/sequenceWallet.d.ts.map +1 -1
- package/dist/tokenBalances.d.ts +17 -13
- package/dist/tokenBalances.d.ts.map +1 -1
- package/dist/trails.d.ts +24 -40
- package/dist/trails.d.ts.map +1 -1
- package/dist/transactionIntent/constants.d.ts +7 -0
- package/dist/transactionIntent/constants.d.ts.map +1 -0
- package/dist/transactionIntent/deposits/depositOrchestrator.d.ts +44 -0
- package/dist/transactionIntent/deposits/depositOrchestrator.d.ts.map +1 -0
- package/dist/transactionIntent/deposits/gaslessDeposit.d.ts +30 -0
- package/dist/transactionIntent/deposits/gaslessDeposit.d.ts.map +1 -0
- package/dist/transactionIntent/deposits/index.d.ts +4 -0
- package/dist/transactionIntent/deposits/index.d.ts.map +1 -0
- package/dist/transactionIntent/deposits/standardDeposit.d.ts +30 -0
- package/dist/transactionIntent/deposits/standardDeposit.d.ts.map +1 -0
- package/dist/transactionIntent/execution/index.d.ts +2 -0
- package/dist/transactionIntent/execution/index.d.ts.map +1 -0
- package/dist/transactionIntent/execution/transactionState.d.ts +5 -0
- package/dist/transactionIntent/execution/transactionState.d.ts.map +1 -0
- package/dist/transactionIntent/handlers/crossChain.d.ts +82 -0
- package/dist/transactionIntent/handlers/crossChain.d.ts.map +1 -0
- package/dist/transactionIntent/handlers/index.d.ts +4 -0
- package/dist/transactionIntent/handlers/index.d.ts.map +1 -0
- package/dist/transactionIntent/handlers/sameChainDifferentToken.d.ts +62 -0
- package/dist/transactionIntent/handlers/sameChainDifferentToken.d.ts.map +1 -0
- package/dist/transactionIntent/handlers/sameChainSameToken.d.ts +72 -0
- package/dist/transactionIntent/handlers/sameChainSameToken.d.ts.map +1 -0
- package/dist/transactionIntent/index.d.ts +9 -0
- package/dist/transactionIntent/index.d.ts.map +1 -0
- package/dist/transactionIntent/quote/feeExtractors.d.ts +17 -0
- package/dist/transactionIntent/quote/feeExtractors.d.ts.map +1 -0
- package/dist/transactionIntent/quote/index.d.ts +4 -0
- package/dist/transactionIntent/quote/index.d.ts.map +1 -0
- package/dist/transactionIntent/quote/normalizeQuote.d.ts +34 -0
- package/dist/transactionIntent/quote/normalizeQuote.d.ts.map +1 -0
- package/dist/transactionIntent/quote/quoteHelpers.d.ts +5 -0
- package/dist/transactionIntent/quote/quoteHelpers.d.ts.map +1 -0
- package/dist/transactionIntent/types.d.ts +131 -0
- package/dist/transactionIntent/types.d.ts.map +1 -0
- package/dist/transactionIntent/utils/balanceChecker.d.ts +18 -0
- package/dist/transactionIntent/utils/balanceChecker.d.ts.map +1 -0
- package/dist/transactionIntent/utils/index.d.ts +4 -0
- package/dist/transactionIntent/utils/index.d.ts.map +1 -0
- package/dist/transactionIntent/utils/lifiHelpers.d.ts +10 -0
- package/dist/transactionIntent/utils/lifiHelpers.d.ts.map +1 -0
- package/dist/transactionIntent/utils/testnetHelpers.d.ts +3 -0
- package/dist/transactionIntent/utils/testnetHelpers.d.ts.map +1 -0
- package/dist/transactionIntent/validators.d.ts +6 -0
- package/dist/transactionIntent/validators.d.ts.map +1 -0
- package/dist/transactions.d.ts +6 -3
- package/dist/transactions.d.ts.map +1 -1
- package/dist/widget/components/AccountIntentTransactionHistoryButton.d.ts +4 -0
- package/dist/widget/components/AccountIntentTransactionHistoryButton.d.ts.map +1 -0
- package/dist/widget/components/AccountSettings.d.ts.map +1 -1
- package/dist/widget/components/ChainFilterDropdown.d.ts.map +1 -1
- package/dist/widget/components/ClassicSwap.d.ts +2 -3
- package/dist/widget/components/ClassicSwap.d.ts.map +1 -1
- package/dist/widget/components/ConfigDisplay.d.ts.map +1 -1
- package/dist/widget/components/ConnectWallet.d.ts.map +1 -1
- package/dist/widget/components/ConnectedWallets.d.ts.map +1 -1
- package/dist/widget/components/DynamicInputStyles.d.ts +18 -0
- package/dist/widget/components/DynamicInputStyles.d.ts.map +1 -0
- package/dist/widget/components/DynamicSizeInputField.d.ts +13 -0
- package/dist/widget/components/DynamicSizeInputField.d.ts.map +1 -0
- package/dist/widget/components/Earn.d.ts +2 -3
- package/dist/widget/components/Earn.d.ts.map +1 -1
- package/dist/widget/components/ErrorAnimationIcon.d.ts +2 -0
- package/dist/widget/components/ErrorAnimationIcon.d.ts.map +1 -0
- package/dist/widget/components/FeeBreakdown.d.ts +9 -0
- package/dist/widget/components/FeeBreakdown.d.ts.map +1 -0
- package/dist/widget/components/FeeOptions.d.ts +5 -13
- package/dist/widget/components/FeeOptions.d.ts.map +1 -1
- package/dist/widget/components/Fund.d.ts +2 -3
- package/dist/widget/components/Fund.d.ts.map +1 -1
- package/dist/widget/components/FundMethods.d.ts.map +1 -1
- package/dist/widget/components/FundSwap.d.ts +2 -3
- package/dist/widget/components/FundSwap.d.ts.map +1 -1
- package/dist/widget/components/FundingMethodSelectorButton.d.ts.map +1 -1
- package/dist/widget/components/Identicon.d.ts.map +1 -1
- package/dist/widget/components/MeshConnectExchanges.d.ts +0 -3
- package/dist/widget/components/MeshConnectExchanges.d.ts.map +1 -1
- package/dist/widget/components/Modal.d.ts.map +1 -1
- package/dist/widget/components/Pay.d.ts +2 -3
- package/dist/widget/components/Pay.d.ts.map +1 -1
- package/dist/widget/components/PoolDeposit.d.ts +3 -3
- package/dist/widget/components/PoolDeposit.d.ts.map +1 -1
- package/dist/widget/components/PoolWithdraw.d.ts +3 -20
- package/dist/widget/components/PoolWithdraw.d.ts.map +1 -1
- package/dist/widget/components/QuoteDetails.d.ts +2 -0
- package/dist/widget/components/QuoteDetails.d.ts.map +1 -1
- package/dist/widget/components/Receipt.d.ts.map +1 -1
- package/dist/widget/components/RecipientSelectorButton.d.ts.map +1 -1
- package/dist/widget/components/ScreenHeader.d.ts.map +1 -1
- package/dist/widget/components/Swap.d.ts +2 -3
- package/dist/widget/components/Swap.d.ts.map +1 -1
- package/dist/widget/components/ThemeProvider.d.ts.map +1 -1
- package/dist/widget/components/TokenDisplayNonSelectable.d.ts +11 -0
- package/dist/widget/components/TokenDisplayNonSelectable.d.ts.map +1 -0
- package/dist/widget/components/TokenSelector.d.ts.map +1 -1
- package/dist/widget/components/TokenSelectorButton.d.ts.map +1 -1
- package/dist/widget/components/Tooltip.d.ts +9 -0
- package/dist/widget/components/Tooltip.d.ts.map +1 -0
- package/dist/widget/components/TransferPendingVertical.d.ts.map +1 -1
- package/dist/widget/components/WaasFeeOptions.d.ts +1 -0
- package/dist/widget/components/WaasFeeOptions.d.ts.map +1 -1
- package/dist/widget/components/WalletConfirmation.d.ts.map +1 -1
- package/dist/widget/components/WalletConnect.d.ts.map +1 -1
- package/dist/widget/css/compiled.css +2 -2
- package/dist/widget/hooks/useCheckout.d.ts +17 -4
- package/dist/widget/hooks/useCheckout.d.ts.map +1 -1
- package/dist/widget/hooks/useDefaultTokenSelection.d.ts.map +1 -1
- package/dist/widget/hooks/useQuote.d.ts +82 -0
- package/dist/widget/hooks/useQuote.d.ts.map +1 -0
- package/dist/widget/hooks/useSelectedFeeToken.d.ts +1 -0
- package/dist/widget/hooks/useSelectedFeeToken.d.ts.map +1 -1
- package/dist/widget/hooks/useSendForm.d.ts +5 -6
- package/dist/widget/hooks/useSendForm.d.ts.map +1 -1
- package/dist/widget/hooks/useTokenList.d.ts.map +1 -1
- package/dist/widget/hooks/useWalletConnectionContext.d.ts +25 -0
- package/dist/widget/hooks/useWalletConnectionContext.d.ts.map +1 -0
- package/dist/widget/index.js +2 -2
- package/dist/widget/widget.d.ts +17 -7
- package/dist/widget/widget.d.ts.map +1 -1
- package/package.json +19 -21
- package/src/aave.ts +54 -1
- package/src/abortController.ts +35 -0
- package/src/config.ts +57 -58
- package/src/constants.ts +11 -9
- package/src/error.ts +21 -3
- package/src/fees.ts +210 -0
- package/src/index.ts +35 -13
- package/src/intentReceiptMonitor.ts +102 -0
- package/src/intentReceiptPoller.ts +299 -0
- package/src/intents.ts +205 -171
- package/src/morpho.ts +58 -9
- package/src/mutations.ts +129 -0
- package/src/preconditions.ts +16 -21
- package/src/prepareSend.ts +92 -4699
- package/src/prices.ts +26 -22
- package/src/relaySdk.ts +2 -2
- package/src/sequenceWallet.ts +6 -73
- package/src/tokenBalances.ts +175 -69
- package/src/trails.ts +230 -722
- package/src/transactionIntent/constants.ts +11 -0
- package/src/transactionIntent/deposits/depositOrchestrator.ts +210 -0
- package/src/transactionIntent/deposits/gaslessDeposit.ts +588 -0
- package/src/transactionIntent/deposits/index.ts +3 -0
- package/src/transactionIntent/deposits/standardDeposit.ts +379 -0
- package/src/transactionIntent/execution/index.ts +1 -0
- package/src/transactionIntent/execution/transactionState.ts +35 -0
- package/src/transactionIntent/handlers/crossChain.ts +1707 -0
- package/src/transactionIntent/handlers/index.ts +3 -0
- package/src/transactionIntent/handlers/sameChainDifferentToken.ts +323 -0
- package/src/transactionIntent/handlers/sameChainSameToken.ts +712 -0
- package/src/transactionIntent/index.ts +9 -0
- package/src/transactionIntent/quote/feeExtractors.ts +81 -0
- package/src/transactionIntent/quote/index.ts +3 -0
- package/src/transactionIntent/quote/normalizeQuote.ts +367 -0
- package/src/transactionIntent/quote/quoteHelpers.ts +53 -0
- package/src/transactionIntent/types.ts +157 -0
- package/src/transactionIntent/utils/balanceChecker.ts +96 -0
- package/src/transactionIntent/utils/index.ts +3 -0
- package/src/transactionIntent/utils/lifiHelpers.ts +68 -0
- package/src/transactionIntent/utils/testnetHelpers.ts +10 -0
- package/src/transactionIntent/validators.ts +57 -0
- package/src/transactions.ts +98 -71
- package/src/widget/compiled.css +2 -2
- package/src/widget/components/AccountIntentTransactionHistory.tsx +36 -36
- package/src/widget/components/AccountIntentTransactionHistoryButton.tsx +22 -0
- package/src/widget/components/AccountSettings.tsx +70 -41
- package/src/widget/components/ChainFilterDropdown.tsx +24 -3
- package/src/widget/components/ClassicSwap.tsx +44 -107
- package/src/widget/components/ConfigDisplay.tsx +0 -11
- package/src/widget/components/ConnectWallet.tsx +4 -1
- package/src/widget/components/ConnectedWallets.tsx +51 -25
- package/src/widget/components/DynamicInputStyles.tsx +76 -0
- package/src/widget/components/DynamicSizeInputField.tsx +109 -0
- package/src/widget/components/Earn.tsx +34 -45
- package/src/widget/components/ErrorAnimationIcon.tsx +130 -0
- package/src/widget/components/FeeBreakdown.tsx +155 -0
- package/src/widget/components/FeeOption.tsx +2 -2
- package/src/widget/components/FeeOptions.tsx +151 -112
- package/src/widget/components/Fund.tsx +10 -29
- package/src/widget/components/FundMethods.tsx +4 -3
- package/src/widget/components/FundSwap.tsx +2 -3
- package/src/widget/components/FundingMethodSelectorButton.tsx +24 -14
- package/src/widget/components/Identicon.tsx +164 -95
- package/src/widget/components/MeshConnectExchanges.tsx +2 -15
- package/src/widget/components/Modal.tsx +0 -12
- package/src/widget/components/Pay.tsx +72 -75
- package/src/widget/components/PoolDeposit.tsx +221 -242
- package/src/widget/components/PoolWithdraw.tsx +347 -469
- package/src/widget/components/PriceImpactWarning.tsx +1 -1
- package/src/widget/components/QuoteDetails.tsx +906 -484
- package/src/widget/components/Receipt.tsx +16 -2
- package/src/widget/components/RecipientSelectorButton.tsx +7 -5
- package/src/widget/components/Recipients.tsx +1 -1
- package/src/widget/components/ScreenHeader.tsx +60 -36
- package/src/widget/components/Swap.tsx +2 -3
- package/src/widget/components/ThemeProvider.tsx +2 -1
- package/src/widget/components/TokenDisplayNonSelectable.tsx +40 -0
- package/src/widget/components/TokenImage.tsx +1 -1
- package/src/widget/components/TokenSelector.tsx +62 -53
- package/src/widget/components/TokenSelectorButton.tsx +38 -15
- package/src/widget/components/Tooltip.tsx +51 -0
- package/src/widget/components/TransferPendingVertical.tsx +12 -8
- package/src/widget/components/WaasFeeOptions.tsx +139 -4
- package/src/widget/components/WalletConfirmation.tsx +23 -13
- package/src/widget/components/WalletConnect.tsx +93 -29
- package/src/widget/hooks/useAmountUsd.ts +9 -9
- package/src/widget/hooks/useCheckout.ts +97 -9
- package/src/widget/hooks/useDefaultTokenSelection.tsx +27 -21
- package/src/widget/hooks/useQuote.ts +466 -0
- package/src/widget/hooks/useSelectedFeeToken.tsx +32 -37
- package/src/widget/hooks/useSendForm.ts +45 -51
- package/src/widget/hooks/useTokenList.ts +34 -26
- package/src/widget/hooks/useWalletConnectionContext.tsx +128 -0
- package/src/widget/widget.tsx +365 -390
- package/dist/apiClient.d.ts +0 -9
- package/dist/apiClient.d.ts.map +0 -1
- package/dist/intentEntrypoint.d.ts +0 -114
- package/dist/intentEntrypoint.d.ts.map +0 -1
- package/dist/metaTxnMonitor.d.ts +0 -15
- package/dist/metaTxnMonitor.d.ts.map +0 -1
- package/dist/metaTxns.d.ts +0 -11
- package/dist/metaTxns.d.ts.map +0 -1
- package/dist/relayer.d.ts +0 -43
- package/dist/relayer.d.ts.map +0 -1
- package/src/apiClient.ts +0 -35
- package/src/intentEntrypoint.ts +0 -203
- package/src/metaTxnMonitor.ts +0 -171
- package/src/metaTxns.ts +0 -45
- package/src/relayer.ts +0 -289
package/src/tokenBalances.ts
CHANGED
|
@@ -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
|
|
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?:
|
|
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
|
|
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 ??
|
|
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: ["
|
|
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
|
-
|
|
244
|
-
|
|
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
|
-
|
|
252
|
-
|
|
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
|
|
319
|
-
p.token.
|
|
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?.
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
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
|
-
|
|
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: ["
|
|
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
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
689
|
+
logger.console.log(
|
|
690
|
+
"[trails-sdk] Invalidating token balances cache for account:",
|
|
691
|
+
account,
|
|
692
|
+
)
|
|
611
693
|
} else {
|
|
612
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
|
795
|
+
const priceData: TrailsTokenPrice | undefined = tokenPrices.find((p) => {
|
|
706
796
|
const isSameChain = p.token.chainId === b.chainId
|
|
707
|
-
let isSameToken = p.token.
|
|
797
|
+
let isSameToken = p.token.tokenAddress === b.contractAddress
|
|
708
798
|
if (!b.contractAddress) {
|
|
709
799
|
isSameToken =
|
|
710
|
-
p.token.
|
|
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
|
|
718
|
-
balanceUsd: price
|
|
719
|
-
|
|
720
|
-
|
|
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
|
-
|
|
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
|
-
|
|
839
|
+
trailsClient,
|
|
746
840
|
}: UseAccountTokenBalanceParams) {
|
|
747
841
|
const { data: tokenBalance, isLoading: isLoadingTokenBalance } = useQuery({
|
|
748
|
-
queryKey: ["
|
|
842
|
+
queryKey: ["getTokenBalancesWithPrices", "balances", account],
|
|
749
843
|
queryFn: async () => {
|
|
750
844
|
if (
|
|
751
845
|
!account ||
|
|
752
846
|
!indexerGatewayClient ||
|
|
753
|
-
!
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
890
|
+
trailsClient,
|
|
797
891
|
}: HasSufficientBalanceParams): Promise<boolean> {
|
|
798
892
|
const { balances } = await getTokenBalancesWithPrices({
|
|
799
893
|
account,
|
|
800
894
|
indexerGatewayClient,
|
|
801
|
-
|
|
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
|
|
926
|
+
const trailsClient = useTrailsClient()
|
|
833
927
|
|
|
834
928
|
const {
|
|
835
929
|
data: hasSufficientBalanceToken,
|
|
836
930
|
isLoading: isLoadingHasSufficientBalanceToken,
|
|
837
931
|
} = useQuery({
|
|
838
|
-
queryKey: [
|
|
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
|
-
|
|
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
|
-
|
|
973
|
+
trailsClient: TrailsClient
|
|
873
974
|
}
|
|
874
975
|
|
|
875
976
|
export async function getHasSufficientBalanceUsd({
|
|
876
977
|
account,
|
|
877
978
|
targetAmountUsd,
|
|
878
979
|
indexerGatewayClient,
|
|
879
|
-
|
|
980
|
+
trailsClient,
|
|
880
981
|
}: GetHasSufficientBalanceUsdParams): Promise<boolean> {
|
|
881
982
|
const totalBalanceUsd = await getAccountTotalBalanceUsd({
|
|
882
983
|
account,
|
|
883
984
|
indexerGatewayClient,
|
|
884
|
-
|
|
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
|
|
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: [
|
|
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
|
-
|
|
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
|
-
|
|
1044
|
+
trailsClient: TrailsClient
|
|
939
1045
|
}
|
|
940
1046
|
|
|
941
1047
|
export async function getAccountTotalBalanceUsd({
|
|
942
1048
|
account,
|
|
943
1049
|
indexerGatewayClient,
|
|
944
|
-
|
|
1050
|
+
trailsClient,
|
|
945
1051
|
}: GetAccountTotalBalanceUsdParams): Promise<number> {
|
|
946
1052
|
const { balances } = await getTokenBalancesWithPrices({
|
|
947
1053
|
account,
|
|
948
1054
|
indexerGatewayClient,
|
|
949
|
-
|
|
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
|
|
1067
|
+
const trailsClient = useTrailsClient()
|
|
962
1068
|
|
|
963
1069
|
const { data: totalBalanceUsd, isLoading: isLoadingTotalBalanceUsd } =
|
|
964
1070
|
useQuery({
|
|
965
|
-
queryKey: ["
|
|
1071
|
+
queryKey: ["getAccountTotalBalanceUsd", "totalUsd", account],
|
|
966
1072
|
queryFn: () =>
|
|
967
1073
|
account
|
|
968
1074
|
? getAccountTotalBalanceUsd({
|
|
969
1075
|
account: account,
|
|
970
1076
|
indexerGatewayClient: indexerGatewayClient,
|
|
971
|
-
|
|
1077
|
+
trailsClient: trailsClient,
|
|
972
1078
|
})
|
|
973
1079
|
: null,
|
|
974
1080
|
enabled: !!account,
|