UDA endpoints
stridge.uda is the public, unauthenticated surface of the SDK. Both methods on this client go through the SDK's httpClient — they send no X-Gateway-Key header and work without a projectKey on the createApiClient call.
| Method | HTTP | Auth | Returns |
|---|---|---|---|
uda.supportedAssets | GET /uda/supported-assets | none | SupportedAssetsResponse |
uda.quote | GET /uda/quote | none | QuoteResponse |
Calling these two endpoints does not require projectKey. You can instantiate createApiClient({ env: "prod" }) with no key at all and they'll work. Browser builds of the SDK can call them safely without leaking a secret. Every other endpoint in the SDK is project-scoped — see Gateway endpoints and Balance endpoint.
If a project key is in scope, prefer gateway.assets() over uda.supportedAssets() for catalogues — it returns only the chains and tokens the merchant has enabled, not the entire platform-wide list.
uda.supportedAssets
Lists every chain with uda_support=true on the Stridge platform, along with each chain's native currency and configured token contracts. Use as the source-of-truth catalogue for chain pickers and token pickers when no project context exists yet.
Signature
uda.supportedAssets(
options?: { signal?: AbortSignal },
): Promise<SupportedAssetsResponse>Example
import { createApiClient } from "@stridge/sdk"
const stridge = createApiClient({ env: "prod" }) // no projectKey needed
const { assets } = await stridge.uda.supportedAssets()
const evmChains = assets.filter((c) => c.chain_type === "EVM")
const tronChains = assets.filter((c) => c.chain_type === "TVM")
console.log(`${evmChains.length} EVM chain(s), ${tronChains.length} Tron chain(s)`)Returns
SupportedAssetsResponse — { assets: SupportedAssetDto[] }. Each SupportedAssetDto carries:
| Field | Type | Notes |
|---|---|---|
network_id | string | Stable Stridge network id (e.g. "60", "8453"). Use for destination.network_id on gateway.start. |
network_name | string | Human-readable name (e.g. "ethereum"). |
network_symbol | string | Short ticker (e.g. "ethereum", "base"). |
chain_type | "EVM" | "TVM" | string | Chain family — drives address-shape validation. Widenable union so unknown future families still typecheck. |
eip155_id | number | EIP-155 id; only meaningful when chain_type === "EVM". |
native_currency | NativeCurrencyDto | Symbol, name, decimals, logo, optional min_deposit_usd, optional price_impact. |
assets | AssetDto[] | Token contracts on the chain. Each carries symbol, name, address, decimals, logo, optional min_deposit_usd, optional price_impact. |
The assets field is named the same at both nesting levels — the outer assets is a list of chains, each chain's inner assets is a list of tokens on that chain. Same key, two meanings.
uda.quote
Returns a cross-chain or cross-asset quote: destination amount, exchange rate, fee breakdown, selected route, and an absolute expires_at. The Kit's wallet flow drives its confirm step off this response; hosts can call it directly to render a static preview ahead of a wallet connect.
Signature
uda.quote(
input: QuoteInput,
options?: { signal?: AbortSignal },
): Promise<QuoteResponse>
interface QuoteInput {
fromNetworkId: number // EIP-155 chain id of the source
fromAsset: string // token contract; zero address for native currency
toNetworkId: number // EIP-155 chain id of the destination
toAsset: string // token contract; zero address for native currency
amount: string // smallest-unit, decimal-string-encoded
fromAddress: string // required — source EOA, used for routing + gas
toAddress: string // required — destination recipient, used for routing
}Both fromAddress and toAddress are required. Omitting either field can yield inaccurate quotes from one of the upstream providers — the backend uses both for routing and gas estimation. Drivers should always populate fromAddress from the connected wallet and toAddress from the configured destination (the address field on gateway.start.destination).
Example
const quote = await stridge.uda.quote({
fromNetworkId: 56, // BSC
fromAsset: "0x55d398326f99059fF775485246999027B3197955", // USDT BEP-20
toNetworkId: 42161, // Arbitrum One
toAsset: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831", // USDC native Arbitrum
amount: "100000000000000000000", // 100 USDT in smallest units (18 decimals on BSC)
fromAddress: walletAddress,
toAddress: payoutAddress,
})
console.log(quote.to.amount) // smallest-unit, decimal string
console.log(quote.exchange_rate) // "0.99988"
console.log(quote.fees.total_fee) // smallest-unit fee on the from-asset
console.log(quote.route.provider) // "lifi"
console.log(quote.expires_at) // ISO-8601 absolute deadlineReturns
QuoteResponse carries from, to, fees, route, exchange_rate, and expires_at. The from / to sides share the QuoteSideDto shape (network_id, asset_address, amount); fees break down into optional gas_fee and protocol_fee plus a total_fee; the route announces a provider, scenario, and optional estimated_time_seconds. See Models & types for the full DTO surface.
Errors
Quote failures come back wrapped in BackendError with the parsed gateway envelope on error.cause. The error shape narrows to QuoteErrorResponse, which adds a typed error field with these known codes:
| Code | What happened | Retry helps? |
|---|---|---|
upstream_unavailable | A downstream provider (price feed, bridge, RPC) is unreachable. | Yes — transient. |
route_unavailable | No provider can fulfil this (from → to) hop right now. | Usually no — liquidity gap; nudge user to a different asset. |
unsupported_asset | Source or destination asset isn't in the configured catalogue. | No. |
amount_too_low | Requested amount is below the gateway's minimum for the picked route. | No. |
amount_too_high | Requested amount exceeds the gateway's per-quote ceiling. | No. |
quote_expired | Caller passed a stale quote id; ask for a fresh one. | Re-quote. |
internal_error | Catch-all server failure. | Maybe — surface as generic "something went wrong". |
The code-union is open ((string & {}) tail), so new gateway codes still type-check — fall back to a generic message on anything unrecognized. Use the isQuoteErrorResponse type guard to narrow:
import { BackendError, isQuoteErrorResponse } from "@stridge/sdk"
try {
const quote = await stridge.uda.quote(input)
// …
} catch (err) {
if (err instanceof BackendError && isQuoteErrorResponse(err.cause)) {
switch (err.cause.error) {
case "amount_too_low":
// surface a "minimum is $X" hint
break
case "route_unavailable":
// suggest a different pair
break
default:
// generic fallback
}
}
throw err
}See Errors & retries for the full BackendError shape and retry guidance.
Related
- Gateway endpoints — the authenticated UDA lifecycle (
start,poll) and project-scoped catalogue. - API client — why
uda.*flows through the unauthenticatedhttpClientandgateway.*flows throughprojectHttpClient. - Models & types —
QuoteResponse,QuoteErrorResponse,SupportedAssetDto,AssetDto,NativeCurrencyDto. - Universal Deposit Addresses — the settlement model behind the gateway.