0xtrails 0.13.1 → 0.13.2
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/{ccip-DStzFCYT.js → ccip-CT_An6eM.js} +28 -28
- package/dist/chains.d.ts +1 -1
- package/dist/chains.d.ts.map +1 -1
- package/dist/constants.d.ts +1 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/customTokens.d.ts.map +1 -1
- package/dist/{index-HY9_ppit.js → index-RfqL5Foz.js} +56523 -43196
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +383 -332
- package/dist/intents.d.ts +8 -2
- package/dist/intents.d.ts.map +1 -1
- package/dist/keyMachineClient.d.ts +9 -0
- package/dist/keyMachineClient.d.ts.map +1 -0
- package/dist/keymachine/index.d.ts +14 -0
- package/dist/keymachine/index.d.ts.map +1 -0
- package/dist/keymachine/key-machine.gen.d.ts +461 -0
- package/dist/keymachine/key-machine.gen.d.ts.map +1 -0
- package/dist/onramp/MeshConnectFlow.d.ts +18 -0
- package/dist/onramp/MeshConnectFlow.d.ts.map +1 -0
- package/dist/onramp/MeshConnectIframe.d.ts +13 -0
- package/dist/onramp/MeshConnectIframe.d.ts.map +1 -0
- package/dist/onramp/SendFromExchangeButton.d.ts +16 -0
- package/dist/onramp/SendFromExchangeButton.d.ts.map +1 -0
- package/dist/onramp/TrailsOnRampProvider.d.ts +31 -0
- package/dist/onramp/TrailsOnRampProvider.d.ts.map +1 -0
- package/dist/onramp/index.d.ts +13 -0
- package/dist/onramp/index.d.ts.map +1 -0
- package/dist/onramp/meshconnect.d.ts +30 -0
- package/dist/onramp/meshconnect.d.ts.map +1 -0
- package/dist/onramp/trailsOnramp.d.ts +24 -0
- package/dist/onramp/trailsOnramp.d.ts.map +1 -0
- package/dist/onramp-client/index.d.ts +3 -3
- package/dist/onramp-client/index.d.ts.map +1 -1
- package/dist/prepareSend.d.ts.map +1 -1
- package/dist/query/balance.fetchers.d.ts +27 -0
- package/dist/query/balance.fetchers.d.ts.map +1 -1
- package/dist/query/balance.hooks.d.ts +19 -0
- package/dist/query/balance.hooks.d.ts.map +1 -1
- package/dist/query/balance.queries.d.ts +18 -1
- package/dist/query/balance.queries.d.ts.map +1 -1
- package/dist/query/chains.queries.d.ts.map +1 -1
- package/dist/query/meld.fetchers.d.ts +1 -1
- package/dist/query/meld.fetchers.d.ts.map +1 -1
- package/dist/query/meld.hooks.d.ts +3 -3
- package/dist/query/meld.hooks.d.ts.map +1 -1
- package/dist/query/meld.queries.d.ts +1 -1
- package/dist/query/meld.queries.d.ts.map +1 -1
- package/dist/query/tokenList.queries.d.ts +54 -0
- package/dist/query/tokenList.queries.d.ts.map +1 -0
- package/dist/recover.d.ts +3 -1
- package/dist/recover.d.ts.map +1 -1
- package/dist/tokens.d.ts +13 -0
- package/dist/tokens.d.ts.map +1 -1
- package/dist/transactionIntent/deposits/depositOrchestrator.d.ts +2 -2
- package/dist/transactionIntent/deposits/depositOrchestrator.d.ts.map +1 -1
- package/dist/transactionIntent/deposits/gaslessDeposit.d.ts +2 -2
- package/dist/transactionIntent/deposits/gaslessDeposit.d.ts.map +1 -1
- package/dist/transactionIntent/deposits/standardDeposit.d.ts +1 -1
- package/dist/transactionIntent/deposits/standardDeposit.d.ts.map +1 -1
- package/dist/transactionIntent/handlers/intentHandler.d.ts.map +1 -1
- package/dist/transactionIntent/helpers/transactionStateHelpers.d.ts.map +1 -1
- package/dist/transactionIntent/quote/normalizeQuote.d.ts.map +1 -1
- package/dist/transactionIntent/types.d.ts +1 -1
- package/dist/transactionIntent/types.d.ts.map +1 -1
- package/dist/transactions.d.ts +3 -0
- package/dist/transactions.d.ts.map +1 -1
- package/dist/umd/trails.min.js +291 -202
- package/dist/walletUtils.d.ts +2 -1
- package/dist/walletUtils.d.ts.map +1 -1
- package/dist/wallets.d.ts +13 -54
- package/dist/wallets.d.ts.map +1 -1
- package/dist/widget/components/ClassicSwap.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/DirectTransfer.d.ts +1 -1
- package/dist/widget/components/DirectTransfer.d.ts.map +1 -1
- package/dist/widget/components/Fund.d.ts.map +1 -1
- package/dist/widget/components/FundMethods.d.ts.map +1 -1
- package/dist/widget/components/MeshExchangeSelection.d.ts +11 -0
- package/dist/widget/components/MeshExchangeSelection.d.ts.map +1 -0
- package/dist/widget/components/OnrampHistoryRow.d.ts +1 -1
- package/dist/widget/components/OnrampHistoryRow.d.ts.map +1 -1
- package/dist/widget/components/Pay.d.ts.map +1 -1
- package/dist/widget/components/PoolDeposit.d.ts.map +1 -1
- package/dist/widget/components/QRCodeWalletSelect.d.ts +1 -1
- package/dist/widget/components/QRCodeWalletSelect.d.ts.map +1 -1
- package/dist/widget/components/QuoteDetails.d.ts.map +1 -1
- package/dist/widget/components/Recipients.d.ts.map +1 -1
- package/dist/widget/components/RefundWarning.d.ts.map +1 -1
- package/dist/widget/components/TokenSelector.d.ts.map +1 -1
- package/dist/widget/components/TransactionDetails.d.ts.map +1 -1
- package/dist/widget/components/TransferPendingVertical.d.ts +1 -0
- package/dist/widget/components/TransferPendingVertical.d.ts.map +1 -1
- package/dist/widget/components/WalletConnect.d.ts.map +1 -1
- package/dist/widget/components/WalletImage.d.ts.map +1 -1
- package/dist/widget/components/WalletList.d.ts.map +1 -1
- package/dist/widget/components/Withdraw.d.ts.map +1 -1
- package/dist/widget/css/compiled.css +1 -1
- package/dist/widget/hooks/useAddressWalletIcon.d.ts.map +1 -1
- package/dist/widget/hooks/useCustomTokenSearch.d.ts +6 -1
- package/dist/widget/hooks/useCustomTokenSearch.d.ts.map +1 -1
- package/dist/widget/hooks/useDefaultDestinationToken.d.ts.map +1 -1
- package/dist/widget/hooks/useDefaultOriginToken.d.ts.map +1 -1
- package/dist/widget/hooks/useFiatOnRampCurrencies.d.ts +1 -1
- package/dist/widget/hooks/useFiatOnRampCurrencies.d.ts.map +1 -1
- package/dist/widget/hooks/useIntentTransactionHistory.d.ts.map +1 -1
- package/dist/widget/hooks/useQuote.d.ts +1 -1
- package/dist/widget/hooks/useQuote.d.ts.map +1 -1
- package/dist/widget/hooks/useSelectedFundMethod.d.ts +7 -0
- package/dist/widget/hooks/useSelectedFundMethod.d.ts.map +1 -1
- package/dist/widget/hooks/useSendForm.d.ts.map +1 -1
- package/dist/widget/hooks/useTokenList.d.ts +7 -1
- package/dist/widget/hooks/useTokenList.d.ts.map +1 -1
- package/dist/widget/hooks/useViewManager.d.ts +1 -1
- package/dist/widget/hooks/useViewManager.d.ts.map +1 -1
- package/dist/widget/index.js +1 -1
- package/dist/widget/providers/TrailsProvider.d.ts +2 -0
- package/dist/widget/providers/TrailsProvider.d.ts.map +1 -1
- package/dist/widget/utils/createWagmiConfig.d.ts +2 -2
- package/dist/widget/utils/createWagmiConfig.d.ts.map +1 -1
- package/dist/widget/utils/fundMethodSwitchState.d.ts +1 -0
- package/dist/widget/utils/fundMethodSwitchState.d.ts.map +1 -1
- package/dist/widget/utils/meldProviderUtils.d.ts +1 -1
- package/dist/widget/utils/meldProviderUtils.d.ts.map +1 -1
- package/dist/widget/utils/meshSupportedTokens.d.ts +4 -0
- package/dist/widget/utils/meshSupportedTokens.d.ts.map +1 -0
- package/dist/widget/utils/onrampConfig.d.ts +11 -0
- package/dist/widget/utils/onrampConfig.d.ts.map +1 -0
- package/dist/widget/utils/trailsOnrampConfig.d.ts +18 -0
- package/dist/widget/utils/trailsOnrampConfig.d.ts.map +1 -0
- package/dist/widget/widget.d.ts +24 -8
- package/dist/widget/widget.d.ts.map +1 -1
- package/package.json +9 -7
- package/src/chains.ts +9 -4
- package/src/constants.ts +2 -0
- package/src/customTokens.ts +21 -0
- package/src/index.ts +1 -0
- package/src/intents.ts +49 -41
- package/src/keyMachineClient.ts +29 -0
- package/src/keymachine/index.ts +175 -0
- package/src/keymachine/key-machine.gen.ts +993 -0
- package/src/onramp/MeshConnectFlow.tsx +86 -0
- package/src/onramp/MeshConnectIframe.tsx +661 -0
- package/src/onramp/SendFromExchangeButton.tsx +81 -0
- package/src/onramp/TrailsOnRampProvider.tsx +59 -0
- package/src/onramp/index.ts +31 -0
- package/src/onramp/meshconnect.ts +277 -0
- package/src/onramp/trailsOnramp.tsx +130 -0
- package/src/onramp-client/index.ts +4 -6
- package/src/prepareSend.ts +45 -44
- package/src/query/balance.fetchers.ts +134 -4
- package/src/query/balance.hooks.ts +61 -2
- package/src/query/balance.queries.ts +63 -0
- package/src/query/chains.queries.ts +1 -6
- package/src/query/meld.fetchers.ts +1 -1
- package/src/query/meld.hooks.ts +1 -1
- package/src/query/meld.queries.ts +1 -1
- package/src/query/tokenList.queries.ts +118 -0
- package/src/recover.ts +86 -23
- package/src/tokens.ts +108 -26
- package/src/transactionIntent/deposits/depositOrchestrator.ts +11 -11
- package/src/transactionIntent/deposits/gaslessDeposit.ts +38 -38
- package/src/transactionIntent/deposits/standardDeposit.ts +0 -4
- package/src/transactionIntent/handlers/intentHandler.ts +28 -11
- package/src/transactionIntent/helpers/transactionStateHelpers.ts +5 -2
- package/src/transactionIntent/quote/normalizeQuote.ts +11 -5
- package/src/transactionIntent/types.ts +1 -1
- package/src/transactions.ts +3 -0
- package/src/walletUtils.ts +2 -1
- package/src/wallets.ts +184 -380
- package/src/widget/compiled.css +1 -1
- package/src/widget/components/ClassicSwap.tsx +22 -5
- package/src/widget/components/ConnectWallet.tsx +4 -2
- package/src/widget/components/ConnectedWallets.tsx +2 -5
- package/src/widget/components/DirectTransfer.tsx +5 -2
- package/src/widget/components/Fund.tsx +144 -12
- package/src/widget/components/FundMethods.tsx +5 -9
- package/src/widget/components/MeldHistory.tsx +1 -1
- package/src/widget/components/MeshExchangeSelection.tsx +218 -0
- package/src/widget/components/OnrampHistoryRow.tsx +1 -1
- package/src/widget/components/Pay.tsx +20 -36
- package/src/widget/components/PoolDeposit.tsx +13 -22
- package/src/widget/components/QRCodeWalletSelect.tsx +5 -2
- package/src/widget/components/QuoteDetails.tsx +77 -68
- package/src/widget/components/Recipients.tsx +2 -1
- package/src/widget/components/RefundWarning.tsx +5 -10
- package/src/widget/components/TokenSelector.tsx +85 -16
- package/src/widget/components/TransactionDetails.tsx +46 -0
- package/src/widget/components/TransferPendingVertical.tsx +27 -19
- package/src/widget/components/WalletConnect.tsx +2 -5
- package/src/widget/components/WalletImage.tsx +6 -18
- package/src/widget/components/WalletList.tsx +1 -1
- package/src/widget/components/Withdraw.tsx +22 -4
- package/src/widget/hooks/useAddressWalletIcon.ts +2 -1
- package/src/widget/hooks/useCustomTokenSearch.tsx +63 -33
- package/src/widget/hooks/useDefaultDestinationToken.tsx +2 -5
- package/src/widget/hooks/useDefaultOriginToken.tsx +2 -5
- package/src/widget/hooks/useFiatOnRampCurrencies.ts +1 -1
- package/src/widget/hooks/useIntentTransactionHistory.ts +5 -0
- package/src/widget/hooks/useMeldTransactionStatus.ts +1 -1
- package/src/widget/hooks/useQuote.ts +51 -45
- package/src/widget/hooks/useSelectedFundMethod.tsx +14 -1
- package/src/widget/hooks/useSendForm.ts +26 -10
- package/src/widget/hooks/useTokenList.ts +208 -139
- package/src/widget/hooks/useViewManager.tsx +1 -0
- package/src/widget/providers/TrailsProvider.tsx +5 -0
- package/src/widget/styles.ts +1 -1
- package/src/widget/utils/createWagmiConfig.ts +7 -2
- package/src/widget/utils/fundMethodSwitchState.ts +2 -0
- package/src/widget/utils/meldProviderUtils.ts +8 -2
- package/src/widget/utils/meshSupportedTokens.ts +28 -0
- package/src/widget/utils/onrampConfig.ts +15 -0
- package/src/widget/utils/trailsOnrampConfig.ts +39 -0
- package/src/widget/widget.tsx +164 -98
- package/dist/onramp-client/trails-onramp.gen.d.ts +0 -570
- package/dist/onramp-client/trails-onramp.gen.d.ts.map +0 -1
- package/dist/widget/hooks/useCustomTokenFetch.d.ts +0 -19
- package/dist/widget/hooks/useCustomTokenFetch.d.ts.map +0 -1
- package/dist/widget/hooks/useTokenWithFreshBalance.d.ts +0 -18
- package/dist/widget/hooks/useTokenWithFreshBalance.d.ts.map +0 -1
- package/src/onramp-client/trails-onramp.gen.ts +0 -1320
- package/src/widget/assets/Binance_Icon_Logo.svg +0 -14
- package/src/widget/assets/Bitfinex_Icon_Logo.svg +0 -5
- package/src/widget/assets/Coinbase_Icon_Logo.svg +0 -1
- package/src/widget/assets/WalletConnect-logo-blue-bg.svg +0 -11
- package/src/widget/assets/sequence-logo.svg +0 -15
- package/src/widget/hooks/useCustomTokenFetch.tsx +0 -74
- package/src/widget/hooks/useTokenWithFreshBalance.ts +0 -246
package/src/prepareSend.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { trackPaymentError, trackPaymentStarted } from "./analytics.js"
|
|
|
3
3
|
import { getSlippageToleranceValue } from "./widget/components/SlippageToleranceSettings.js"
|
|
4
4
|
import { addressEqual, isNativeToken, isZeroAccount } from "./utils/address.js"
|
|
5
5
|
import { getERC20TransferData } from "./utils.js"
|
|
6
|
-
import {
|
|
6
|
+
import { getTokenPrices } from "./query/price.queries.js"
|
|
7
7
|
import {
|
|
8
8
|
calldataHasPlaceholder,
|
|
9
9
|
replacePlaceholderInCalldata,
|
|
@@ -221,22 +221,28 @@ export async function prepareSend(
|
|
|
221
221
|
)
|
|
222
222
|
}
|
|
223
223
|
|
|
224
|
-
let
|
|
224
|
+
let intentProtocol = IntentProtocolVersion.v1 // Default to v1
|
|
225
225
|
|
|
226
226
|
// Only fetch supported versions when using dev trails API environments for now
|
|
227
|
-
const shouldFetchVersions = getShouldFetchVersions()
|
|
227
|
+
const shouldFetchVersions = getShouldFetchVersions(trailsApiUrl)
|
|
228
228
|
|
|
229
229
|
if (shouldFetchVersions) {
|
|
230
230
|
try {
|
|
231
|
-
const
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
231
|
+
const normalizeIntentProtocolVersion = (
|
|
232
|
+
version?: string,
|
|
233
|
+
): IntentProtocolVersion => {
|
|
234
|
+
if (version === "v1.5" || version === "v1_5") {
|
|
235
|
+
return IntentProtocolVersion.v1_5
|
|
236
|
+
}
|
|
237
|
+
return IntentProtocolVersion.v1
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
const response = await trailsClient.getDefaultIntentProtocol()
|
|
241
|
+
intentProtocol = normalizeIntentProtocolVersion(response.version)
|
|
235
242
|
logger.console.log(
|
|
236
|
-
"[trails-sdk] [intent-protocol] Fetched
|
|
243
|
+
"[trails-sdk] [intent-protocol] Fetched default protocol version from API",
|
|
237
244
|
{
|
|
238
|
-
|
|
239
|
-
selectedVersion: intentProtocolVersion,
|
|
245
|
+
intentProtocol,
|
|
240
246
|
},
|
|
241
247
|
)
|
|
242
248
|
} catch (_error) {
|
|
@@ -254,9 +260,9 @@ export async function prepareSend(
|
|
|
254
260
|
logger.console.log(
|
|
255
261
|
"[trails-sdk] [intent-protocol] === Protocol Version Selected ===",
|
|
256
262
|
{
|
|
257
|
-
|
|
258
|
-
isV1:
|
|
259
|
-
isV1_5:
|
|
263
|
+
intentProtocol,
|
|
264
|
+
isV1: intentProtocol === IntentProtocolVersion.v1,
|
|
265
|
+
isV1_5: intentProtocol === IntentProtocolVersion.v1_5,
|
|
260
266
|
},
|
|
261
267
|
)
|
|
262
268
|
|
|
@@ -264,15 +270,15 @@ export async function prepareSend(
|
|
|
264
270
|
logger.console.log(
|
|
265
271
|
"[trails-sdk] [intent-protocol] Calldata wrapping required for custom calldata",
|
|
266
272
|
{
|
|
267
|
-
|
|
273
|
+
intentProtocol,
|
|
268
274
|
wrapperType:
|
|
269
|
-
|
|
275
|
+
intentProtocol === IntentProtocolVersion.v1
|
|
270
276
|
? "TrailsRouter"
|
|
271
277
|
: "TrailsUtils (Hydrate)",
|
|
272
278
|
},
|
|
273
279
|
)
|
|
274
280
|
|
|
275
|
-
if (
|
|
281
|
+
if (intentProtocol === IntentProtocolVersion.v1) {
|
|
276
282
|
// @deprecated - v1 only
|
|
277
283
|
|
|
278
284
|
logger.console.log(
|
|
@@ -378,36 +384,31 @@ export async function prepareSend(
|
|
|
378
384
|
}
|
|
379
385
|
}
|
|
380
386
|
|
|
381
|
-
// Fallback price fetching if prices are
|
|
382
|
-
if (!sourceTokenPriceUsd) {
|
|
383
|
-
try {
|
|
384
|
-
const price = await getTokenPrice(trailsClient, {
|
|
385
|
-
tokenSymbol: originTokenAddress,
|
|
386
|
-
tokenAddress: originTokenAddress,
|
|
387
|
-
chainId: originChainId,
|
|
388
|
-
})
|
|
389
|
-
sourceTokenPriceUsd = price?.priceUsd ?? 0
|
|
390
|
-
} catch (error) {
|
|
391
|
-
logger.console.error(
|
|
392
|
-
"[trails-sdk] Error getting source token price:",
|
|
393
|
-
error,
|
|
394
|
-
)
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
if (!destinationTokenPriceUsd) {
|
|
387
|
+
// Fallback price fetching if any prices are missing
|
|
388
|
+
if (!sourceTokenPriceUsd || !destinationTokenPriceUsd) {
|
|
399
389
|
try {
|
|
400
|
-
const
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
390
|
+
const prices = await getTokenPrices(trailsClient, [
|
|
391
|
+
{
|
|
392
|
+
tokenSymbol: originTokenSymbol,
|
|
393
|
+
tokenAddress: originTokenAddress,
|
|
394
|
+
chainId: originChainId,
|
|
395
|
+
},
|
|
396
|
+
{
|
|
397
|
+
tokenSymbol: destinationTokenSymbol,
|
|
398
|
+
tokenAddress: destinationTokenAddress,
|
|
399
|
+
chainId: destinationChainId,
|
|
400
|
+
},
|
|
401
|
+
])
|
|
402
|
+
sourceTokenPriceUsd =
|
|
403
|
+
prices.find((p) =>
|
|
404
|
+
addressEqual(p.token.tokenAddress, originTokenAddress),
|
|
405
|
+
)?.priceUsd ?? 0
|
|
406
|
+
destinationTokenPriceUsd =
|
|
407
|
+
prices.find((p) =>
|
|
408
|
+
addressEqual(p.token.tokenAddress, destinationTokenAddress),
|
|
409
|
+
)?.priceUsd ?? 0
|
|
406
410
|
} catch (error) {
|
|
407
|
-
logger.console.error(
|
|
408
|
-
"[trails-sdk] Error getting destination token price:",
|
|
409
|
-
error,
|
|
410
|
-
)
|
|
411
|
+
logger.console.error("[trails-sdk] Error getting token prices:", error)
|
|
411
412
|
}
|
|
412
413
|
}
|
|
413
414
|
|
|
@@ -10,19 +10,22 @@ import type {
|
|
|
10
10
|
} from "@0xsequence/indexer"
|
|
11
11
|
import { ContractVerificationStatus } from "@0xsequence/indexer"
|
|
12
12
|
import type { TokenPrice } from "@0xtrails/api"
|
|
13
|
-
import { parseUnits, zeroAddress } from "viem"
|
|
13
|
+
import { erc20Abi, parseUnits, zeroAddress } from "viem"
|
|
14
14
|
import { getTokenPrices } from "./price.queries.js"
|
|
15
|
-
import { getChainInfo } from "../chains.js"
|
|
15
|
+
import { getChainInfo, getChainRpcClient } from "../chains.js"
|
|
16
16
|
import { getTokenImageUrl, type Token } from "../tokens.js"
|
|
17
17
|
import type { TrailsClient } from "../trailsClient.js"
|
|
18
|
-
|
|
19
18
|
import { logger } from "../logger.js"
|
|
20
|
-
import {
|
|
19
|
+
import {
|
|
20
|
+
addressEqual,
|
|
21
|
+
isNativeToken as isNativeTokenAddress,
|
|
22
|
+
} from "../utils/address.js"
|
|
21
23
|
import {
|
|
22
24
|
formatBalanceFields,
|
|
23
25
|
formatPriceFields,
|
|
24
26
|
formatUsdFields,
|
|
25
27
|
getTokenBalanceUsd,
|
|
28
|
+
rawAmountToNumber,
|
|
26
29
|
type Price,
|
|
27
30
|
} from "../utils/format.js"
|
|
28
31
|
import { isNetworkError } from "./helpers.js"
|
|
@@ -594,6 +597,133 @@ export async function fetchBalancesWithPrices({
|
|
|
594
597
|
}
|
|
595
598
|
}
|
|
596
599
|
|
|
600
|
+
// ============================================================================
|
|
601
|
+
// On-chain Balance Fetcher — bypasses the indexer entirely
|
|
602
|
+
// ============================================================================
|
|
603
|
+
|
|
604
|
+
export type FetchTokenBalanceOnchainParams = {
|
|
605
|
+
token: Token
|
|
606
|
+
accountAddress: string
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
export type FetchTokenBalanceOnchainWithPricesParams = {
|
|
610
|
+
token: Token
|
|
611
|
+
accountAddress: string
|
|
612
|
+
trailsClient: TrailsClient
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
export type FetchTokenBalanceOnchainReturn = {
|
|
616
|
+
token: Token
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
/**
|
|
620
|
+
* Reads the on-chain balance for a single token via RPC.
|
|
621
|
+
* Fast path — only a single RPC call, no price API.
|
|
622
|
+
*
|
|
623
|
+
* Returns a Token with fresh balance fields (balance, balanceFormatted,
|
|
624
|
+
* balanceDisplay, balanceLocaleDisplay).
|
|
625
|
+
*/
|
|
626
|
+
export async function fetchTokenBalanceOnchain({
|
|
627
|
+
token,
|
|
628
|
+
accountAddress,
|
|
629
|
+
}: FetchTokenBalanceOnchainParams): Promise<FetchTokenBalanceOnchainReturn> {
|
|
630
|
+
const chainId = token.chainId
|
|
631
|
+
if (!chainId) {
|
|
632
|
+
throw new Error("Token must have a chainId")
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
const publicClient = getChainRpcClient(chainId)
|
|
636
|
+
const isNative = isNativeTokenAddress(token.contractAddress)
|
|
637
|
+
|
|
638
|
+
let rawBalance: bigint
|
|
639
|
+
if (isNative) {
|
|
640
|
+
rawBalance = await publicClient.getBalance({
|
|
641
|
+
address: accountAddress as `0x${string}`,
|
|
642
|
+
})
|
|
643
|
+
} else {
|
|
644
|
+
rawBalance = (await publicClient.readContract({
|
|
645
|
+
address: token.contractAddress as `0x${string}`,
|
|
646
|
+
abi: erc20Abi,
|
|
647
|
+
functionName: "balanceOf",
|
|
648
|
+
args: [accountAddress as `0x${string}`],
|
|
649
|
+
})) as bigint
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
const balanceFields = formatBalanceFields(
|
|
653
|
+
rawBalance.toString(),
|
|
654
|
+
token.decimals,
|
|
655
|
+
)
|
|
656
|
+
|
|
657
|
+
return {
|
|
658
|
+
token: {
|
|
659
|
+
...token,
|
|
660
|
+
...balanceFields,
|
|
661
|
+
isSufficientBalance: true,
|
|
662
|
+
},
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
/**
|
|
667
|
+
* Reads the on-chain balance via RPC, then enriches it with price and USD
|
|
668
|
+
* data from the Trails price API.
|
|
669
|
+
*
|
|
670
|
+
* Use this variant only when the caller needs balanceUsd / priceUsd fields.
|
|
671
|
+
*/
|
|
672
|
+
export async function fetchTokenBalanceOnchainWithPrices({
|
|
673
|
+
token,
|
|
674
|
+
accountAddress,
|
|
675
|
+
trailsClient,
|
|
676
|
+
}: FetchTokenBalanceOnchainWithPricesParams): Promise<FetchTokenBalanceOnchainReturn> {
|
|
677
|
+
const { token: tokenWithBalance } = await fetchTokenBalanceOnchain({
|
|
678
|
+
token,
|
|
679
|
+
accountAddress,
|
|
680
|
+
})
|
|
681
|
+
|
|
682
|
+
const chainId = token.chainId!
|
|
683
|
+
const isNative = isNativeTokenAddress(token.contractAddress)
|
|
684
|
+
|
|
685
|
+
let priceUsd: number | undefined
|
|
686
|
+
try {
|
|
687
|
+
const tokenPrices = await getTokenPrices(trailsClient, [
|
|
688
|
+
{
|
|
689
|
+
chainId,
|
|
690
|
+
tokenAddress: isNative ? zeroAddress : token.contractAddress,
|
|
691
|
+
tokenSymbol: isNative ? "" : token.symbol,
|
|
692
|
+
},
|
|
693
|
+
])
|
|
694
|
+
if (tokenPrices.length > 0 && tokenPrices[0]?.priceUsd !== undefined) {
|
|
695
|
+
priceUsd = tokenPrices[0].priceUsd
|
|
696
|
+
}
|
|
697
|
+
} catch (err) {
|
|
698
|
+
logger.console.warn(
|
|
699
|
+
"[trails-sdk] Price fetch failed, returning balance without prices:",
|
|
700
|
+
err,
|
|
701
|
+
)
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
const priceFields = priceUsd !== undefined ? formatPriceFields(priceUsd) : {}
|
|
705
|
+
|
|
706
|
+
let usdFields: ReturnType<typeof formatUsdFields> = {}
|
|
707
|
+
if (priceUsd !== undefined && tokenWithBalance.balance) {
|
|
708
|
+
const balanceNum = rawAmountToNumber(
|
|
709
|
+
tokenWithBalance.balance,
|
|
710
|
+
token.decimals,
|
|
711
|
+
)
|
|
712
|
+
const balanceUsdValue = balanceNum * priceUsd
|
|
713
|
+
if (Number.isFinite(balanceUsdValue)) {
|
|
714
|
+
usdFields = formatUsdFields(balanceUsdValue)
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
return {
|
|
719
|
+
token: {
|
|
720
|
+
...tokenWithBalance,
|
|
721
|
+
...priceFields,
|
|
722
|
+
...usdFields,
|
|
723
|
+
},
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
|
|
597
727
|
// ============================================================================
|
|
598
728
|
// Pure Sufficiency Check
|
|
599
729
|
// ============================================================================
|
|
@@ -215,6 +215,67 @@ export type UseAccountTokenBalanceParams = {
|
|
|
215
215
|
trailsClient?: TrailsClient | null
|
|
216
216
|
}
|
|
217
217
|
|
|
218
|
+
/**
|
|
219
|
+
* Fetches a single token's on-chain balance via RPC.
|
|
220
|
+
*
|
|
221
|
+
* Pass `withPrices: true` to additionally fetch USD price data from the
|
|
222
|
+
* Trails price API (uses a separate query key so balance-only consumers
|
|
223
|
+
* are not blocked by the price call).
|
|
224
|
+
*
|
|
225
|
+
* Auto-disables when `accountAddress` or `token` is nullish.
|
|
226
|
+
*/
|
|
227
|
+
export function useAccountTokenBalanceOnchain(
|
|
228
|
+
token: Token | null | undefined,
|
|
229
|
+
accountAddress: string | null | undefined,
|
|
230
|
+
options?: {
|
|
231
|
+
refetchInterval?: number | false
|
|
232
|
+
disabled?: boolean
|
|
233
|
+
withPrices?: boolean
|
|
234
|
+
},
|
|
235
|
+
): {
|
|
236
|
+
token: Token | null | undefined
|
|
237
|
+
isLoadingBalance: boolean
|
|
238
|
+
error: Error | null
|
|
239
|
+
refetch: () => void
|
|
240
|
+
} {
|
|
241
|
+
const trailsClient = useTrailsClient()
|
|
242
|
+
const { isUserActive } = useUserActivityContext()
|
|
243
|
+
|
|
244
|
+
const isDisabled = options?.disabled || !accountAddress || !token
|
|
245
|
+
const effectiveToken = isDisabled ? null : token
|
|
246
|
+
const effectiveAddress = isDisabled ? null : accountAddress
|
|
247
|
+
|
|
248
|
+
const refetchInterval = isUserActive
|
|
249
|
+
? clampRefetchInterval(options?.refetchInterval)
|
|
250
|
+
: false
|
|
251
|
+
|
|
252
|
+
const queryOpts = options?.withPrices
|
|
253
|
+
? balanceQueries.onchainWithPrices(
|
|
254
|
+
effectiveToken,
|
|
255
|
+
effectiveAddress,
|
|
256
|
+
trailsClient,
|
|
257
|
+
)
|
|
258
|
+
: balanceQueries.onchain(effectiveToken, effectiveAddress)
|
|
259
|
+
|
|
260
|
+
const { data, isLoading, error, refetch } = useQuery({
|
|
261
|
+
...queryOpts,
|
|
262
|
+
refetchInterval,
|
|
263
|
+
refetchIntervalInBackground: false,
|
|
264
|
+
refetchOnWindowFocus: true,
|
|
265
|
+
refetchOnReconnect: true,
|
|
266
|
+
refetchOnMount: true,
|
|
267
|
+
})
|
|
268
|
+
|
|
269
|
+
const enrichedToken = data?.token ?? token ?? null
|
|
270
|
+
|
|
271
|
+
return {
|
|
272
|
+
token: isDisabled ? token : enrichedToken,
|
|
273
|
+
isLoadingBalance: isLoading,
|
|
274
|
+
error,
|
|
275
|
+
refetch,
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
218
279
|
export function useAccountTokenBalance({
|
|
219
280
|
account,
|
|
220
281
|
token,
|
|
@@ -285,13 +346,11 @@ export function useHasSufficientBalanceUsd(
|
|
|
285
346
|
export function useAccountTotalBalanceUsd(account: string | null) {
|
|
286
347
|
const indexerGatewayClient = useIndexerGatewayClient()
|
|
287
348
|
const trailsClient = useTrailsClient()
|
|
288
|
-
const { isUserActive } = useUserActivityContext()
|
|
289
349
|
|
|
290
350
|
return useQuery({
|
|
291
351
|
...balanceQueries.totalUsd(account, indexerGatewayClient, trailsClient),
|
|
292
352
|
refetchOnWindowFocus: false,
|
|
293
353
|
refetchOnReconnect: true,
|
|
294
|
-
refetchInterval: isUserActive ? WIDGET_REFRESH_INTERVAL : false,
|
|
295
354
|
refetchIntervalInBackground: false,
|
|
296
355
|
refetchOnMount: true,
|
|
297
356
|
})
|
|
@@ -10,10 +10,14 @@ import { createRetry, retryDelay } from "./helpers.js"
|
|
|
10
10
|
import {
|
|
11
11
|
fetchMultiAccountBalances,
|
|
12
12
|
fetchBalancesWithPrices,
|
|
13
|
+
fetchTokenBalanceOnchain,
|
|
14
|
+
fetchTokenBalanceOnchainWithPrices,
|
|
13
15
|
checkSufficientToken,
|
|
14
16
|
type GetTokenBalancesForMultipleAccountsReturn,
|
|
15
17
|
type GetTokenBalancesWithPriceReturn,
|
|
18
|
+
type FetchTokenBalanceOnchainReturn,
|
|
16
19
|
} from "./balance.fetchers.js"
|
|
20
|
+
import type { Token } from "../tokens.js"
|
|
17
21
|
import { queryClient as defaultQueryClient } from "./client.js"
|
|
18
22
|
import { logger } from "../logger.js"
|
|
19
23
|
|
|
@@ -143,6 +147,65 @@ export const balanceQueries = {
|
|
|
143
147
|
Number(targetAmountUsd),
|
|
144
148
|
})
|
|
145
149
|
},
|
|
150
|
+
|
|
151
|
+
// single-token on-chain balance (RPC only, no price API)
|
|
152
|
+
onchain: (
|
|
153
|
+
token: Token | null | undefined,
|
|
154
|
+
accountAddress: string | null | undefined,
|
|
155
|
+
) => {
|
|
156
|
+
const canFetch = !!token && !!token.chainId && !!accountAddress
|
|
157
|
+
return queryOptions<FetchTokenBalanceOnchainReturn>({
|
|
158
|
+
queryKey: [
|
|
159
|
+
...balanceQueries.all,
|
|
160
|
+
"onchain",
|
|
161
|
+
accountAddress ?? null,
|
|
162
|
+
token?.contractAddress ?? null,
|
|
163
|
+
token?.chainId ?? null,
|
|
164
|
+
] as const,
|
|
165
|
+
queryFn: canFetch
|
|
166
|
+
? () =>
|
|
167
|
+
fetchTokenBalanceOnchain({
|
|
168
|
+
token,
|
|
169
|
+
accountAddress,
|
|
170
|
+
})
|
|
171
|
+
: skipToken,
|
|
172
|
+
staleTime: BALANCE_STALE_MS,
|
|
173
|
+
gcTime: BALANCE_GC_MS,
|
|
174
|
+
retry: createRetry(2),
|
|
175
|
+
retryDelay,
|
|
176
|
+
})
|
|
177
|
+
},
|
|
178
|
+
|
|
179
|
+
// single-token on-chain balance + price/USD enrichment (RPC + price API)
|
|
180
|
+
onchainWithPrices: (
|
|
181
|
+
token: Token | null | undefined,
|
|
182
|
+
accountAddress: string | null | undefined,
|
|
183
|
+
trailsClient: TrailsClient | null | undefined,
|
|
184
|
+
) => {
|
|
185
|
+
const canFetch =
|
|
186
|
+
!!token && !!token.chainId && !!accountAddress && !!trailsClient
|
|
187
|
+
return queryOptions<FetchTokenBalanceOnchainReturn>({
|
|
188
|
+
queryKey: [
|
|
189
|
+
...balanceQueries.all,
|
|
190
|
+
"onchainWithPrices",
|
|
191
|
+
accountAddress ?? null,
|
|
192
|
+
token?.contractAddress ?? null,
|
|
193
|
+
token?.chainId ?? null,
|
|
194
|
+
] as const,
|
|
195
|
+
queryFn: canFetch
|
|
196
|
+
? () =>
|
|
197
|
+
fetchTokenBalanceOnchainWithPrices({
|
|
198
|
+
token,
|
|
199
|
+
accountAddress,
|
|
200
|
+
trailsClient,
|
|
201
|
+
})
|
|
202
|
+
: skipToken,
|
|
203
|
+
staleTime: BALANCE_STALE_MS,
|
|
204
|
+
gcTime: BALANCE_GC_MS,
|
|
205
|
+
retry: createRetry(2),
|
|
206
|
+
retryDelay,
|
|
207
|
+
})
|
|
208
|
+
},
|
|
146
209
|
}
|
|
147
210
|
|
|
148
211
|
// ============================================================================
|
|
@@ -8,12 +8,7 @@ export const chainQueries = {
|
|
|
8
8
|
|
|
9
9
|
supported: (config?: { trailsApiUrl?: string; trailsApiKey?: string }) =>
|
|
10
10
|
queryOptions<Chain[]>({
|
|
11
|
-
queryKey: [
|
|
12
|
-
...chainQueries.all,
|
|
13
|
-
"supported",
|
|
14
|
-
config?.trailsApiUrl || "default",
|
|
15
|
-
config?.trailsApiKey || "",
|
|
16
|
-
] as const,
|
|
11
|
+
queryKey: [...chainQueries.all, "supported"] as const,
|
|
17
12
|
queryFn: () => getSupportedChains(config),
|
|
18
13
|
staleTime: HOUR_MS,
|
|
19
14
|
gcTime: DAY_MS,
|
|
@@ -11,7 +11,7 @@ import type {
|
|
|
11
11
|
MeldCryptoCurrency,
|
|
12
12
|
MeldCountryDefault,
|
|
13
13
|
MeldTransaction,
|
|
14
|
-
} from "
|
|
14
|
+
} from "@0xtrails/api/onramp"
|
|
15
15
|
import { normalizeAddress } from "../utils/address.js"
|
|
16
16
|
|
|
17
17
|
export interface MeldCountryDefaults {
|
package/src/query/meld.hooks.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useQuery } from "@tanstack/react-query"
|
|
2
2
|
import { useOnrampClient } from "../onrampClient.js"
|
|
3
|
-
import type { GetMeldServiceProvidersRequest } from "
|
|
3
|
+
import type { GetMeldServiceProvidersRequest } from "@0xtrails/api/onramp"
|
|
4
4
|
import { meldQueries } from "./meld.queries.js"
|
|
5
5
|
|
|
6
6
|
export function useMeldPaymentMethods(fiatCurrency?: string) {
|
|
@@ -3,7 +3,7 @@ import type { TrailsOnramp } from "../onrampClient.js"
|
|
|
3
3
|
import type {
|
|
4
4
|
GetMeldServiceProvidersRequest,
|
|
5
5
|
MeldServiceProvider,
|
|
6
|
-
} from "
|
|
6
|
+
} from "@0xtrails/api/onramp"
|
|
7
7
|
import { DAY_MS, MINUTE_MS } from "../utils/time.js"
|
|
8
8
|
import { createRetry, retryDelay, STATIC_QUERY_OPTIONS } from "./helpers.js"
|
|
9
9
|
import { queryPersister } from "./persister.js"
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { queryOptions, skipToken } from "@tanstack/react-query"
|
|
2
|
+
import type { TrailsClient } from "../trailsClient.js"
|
|
3
|
+
import { DAY_MS, MINUTE_MS, SECOND_MS } from "../utils/time.js"
|
|
4
|
+
import { createRetry, retryDelay, STATIC_QUERY_OPTIONS } from "./helpers.js"
|
|
5
|
+
|
|
6
|
+
type TokenListResult = {
|
|
7
|
+
tokens: unknown[]
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const EMPTY_RESULT: TokenListResult = { tokens: [] }
|
|
11
|
+
|
|
12
|
+
export const tokenListQueries = {
|
|
13
|
+
all: ["tokenList"] as const,
|
|
14
|
+
|
|
15
|
+
catalog: (
|
|
16
|
+
trailsClient: TrailsClient | null | undefined,
|
|
17
|
+
config: { trailsApiUrl?: string; trailsApiKey?: string },
|
|
18
|
+
params: { chainIds: number[]; includeAllListed?: boolean; limit?: number },
|
|
19
|
+
) => {
|
|
20
|
+
const hasChains = params.chainIds.length > 0
|
|
21
|
+
const canFetch = !!trailsClient && !!config.trailsApiKey && hasChains
|
|
22
|
+
return queryOptions<TokenListResult>({
|
|
23
|
+
queryKey: [
|
|
24
|
+
...tokenListQueries.all,
|
|
25
|
+
"catalog",
|
|
26
|
+
[...params.chainIds].sort((a, b) => a - b).join(","),
|
|
27
|
+
params.includeAllListed ?? true,
|
|
28
|
+
params.limit ?? null,
|
|
29
|
+
] as const,
|
|
30
|
+
queryFn: canFetch
|
|
31
|
+
? async () => {
|
|
32
|
+
return (await trailsClient.getTokenList({
|
|
33
|
+
chainIds: params.chainIds,
|
|
34
|
+
includeAllListed: params.includeAllListed ?? true,
|
|
35
|
+
limit: params.limit,
|
|
36
|
+
})) as TokenListResult
|
|
37
|
+
}
|
|
38
|
+
: skipToken,
|
|
39
|
+
staleTime: DAY_MS,
|
|
40
|
+
gcTime: DAY_MS,
|
|
41
|
+
retry: createRetry(2),
|
|
42
|
+
retryDelay,
|
|
43
|
+
...STATIC_QUERY_OPTIONS,
|
|
44
|
+
})
|
|
45
|
+
},
|
|
46
|
+
|
|
47
|
+
search: (
|
|
48
|
+
trailsClient: TrailsClient | null | undefined,
|
|
49
|
+
config: { trailsApiUrl?: string; trailsApiKey?: string },
|
|
50
|
+
params: { searchQuery: string; chainIds: number[]; limit?: number },
|
|
51
|
+
) => {
|
|
52
|
+
const searchQuery = params.searchQuery.trim()
|
|
53
|
+
const canFetch =
|
|
54
|
+
!!trailsClient &&
|
|
55
|
+
!!config.trailsApiKey &&
|
|
56
|
+
searchQuery.length > 0 &&
|
|
57
|
+
params.chainIds.length > 0
|
|
58
|
+
|
|
59
|
+
return queryOptions<TokenListResult>({
|
|
60
|
+
queryKey: [
|
|
61
|
+
...tokenListQueries.all,
|
|
62
|
+
"search",
|
|
63
|
+
searchQuery,
|
|
64
|
+
[...params.chainIds].sort((a, b) => a - b).join(","),
|
|
65
|
+
params.limit ?? 30,
|
|
66
|
+
] as const,
|
|
67
|
+
queryFn: canFetch
|
|
68
|
+
? async () => {
|
|
69
|
+
return (await trailsClient.getTokenList({
|
|
70
|
+
searchQuery,
|
|
71
|
+
chainIds: params.chainIds,
|
|
72
|
+
includeAllListed: true,
|
|
73
|
+
limit: params.limit ?? 30,
|
|
74
|
+
})) as TokenListResult
|
|
75
|
+
}
|
|
76
|
+
: skipToken,
|
|
77
|
+
staleTime: 30 * SECOND_MS,
|
|
78
|
+
gcTime: 5 * MINUTE_MS,
|
|
79
|
+
retry: createRetry(1),
|
|
80
|
+
retryDelay,
|
|
81
|
+
refetchOnWindowFocus: false,
|
|
82
|
+
refetchOnReconnect: false,
|
|
83
|
+
})
|
|
84
|
+
},
|
|
85
|
+
|
|
86
|
+
byChain: (
|
|
87
|
+
trailsClient: TrailsClient | null | undefined,
|
|
88
|
+
config: { trailsApiUrl?: string; trailsApiKey?: string },
|
|
89
|
+
params: { chainId: number | null; limit?: number },
|
|
90
|
+
) => {
|
|
91
|
+
const canFetch =
|
|
92
|
+
!!trailsClient && !!config.trailsApiKey && params.chainId != null
|
|
93
|
+
return queryOptions<TokenListResult>({
|
|
94
|
+
queryKey: [
|
|
95
|
+
...tokenListQueries.all,
|
|
96
|
+
"byChain",
|
|
97
|
+
params.chainId,
|
|
98
|
+
params.limit ?? 100,
|
|
99
|
+
] as const,
|
|
100
|
+
queryFn: canFetch
|
|
101
|
+
? async () => {
|
|
102
|
+
return (await trailsClient.getTokenList({
|
|
103
|
+
chainIds: [params.chainId as number],
|
|
104
|
+
includeAllListed: true,
|
|
105
|
+
limit: params.limit ?? 100,
|
|
106
|
+
})) as TokenListResult
|
|
107
|
+
}
|
|
108
|
+
: skipToken,
|
|
109
|
+
staleTime: DAY_MS,
|
|
110
|
+
gcTime: DAY_MS,
|
|
111
|
+
retry: createRetry(2),
|
|
112
|
+
retryDelay,
|
|
113
|
+
...STATIC_QUERY_OPTIONS,
|
|
114
|
+
})
|
|
115
|
+
},
|
|
116
|
+
|
|
117
|
+
empty: EMPTY_RESULT,
|
|
118
|
+
}
|