Developers

Gateway endpoints

stridge.gateway is the authenticated surface that powers every Universal Deposit Address (UDA) lifecycle call and the gateway-internal pricing endpoints. Five methods, all going through projectHttpClient — each call sends the configured projectKey as X-Gateway-Key.

MethodHTTPIdempotentReturns
gateway.startPOST /gateway/startYes, on (owner, destination)GatewayStartResponse
gateway.pollGET /gateway/{owner}Yes (pure read)GatewayPollResponse
gateway.assetsGET /gateway/assetsYes (pure read)SupportedAssetsResponse
gateway.rateBySymbolGET /gateway/rates/{asset_symbol}Yes (pure read)RateResponse
gateway.rateByErc20GET /gateway/rates/erc20/{chain}/{contract_address}Yes (pure read)RateResponse

Every method accepts an optional final options argument that takes an AbortSignal (and, where it makes sense, server-side filters). All return types are unwrapped — the SDK strips the { data, success, message } envelope for you.

For the raw wire contract behind each call, see Gateway HTTP API.

gateway.start

Provisions a new UDA for the owner, or returns the existing one if the same (owner, destination) was already provisioned. Idempotent — safe to call on every wallet connect.

Signature

gateway.start(
  payload: StartGatewayRequest,
  options?: { signal?: AbortSignal },
): Promise<GatewayStartResponse>

Request shape

interface StartGatewayRequest {
  owner: string                         // wallet address; lowercased server-side for 0x...
  destination: {
    network_id: string                  // Stridge network id, e.g. "9001"
    to_address: string                  // payout address on the destination network
    asset_symbol?: string               // e.g. "USDC" (omit when unambiguous)
    asset_address?: string              // disambiguator when symbol alone collides
  }
  metadata?: Record<string, unknown>    // free-form, ≤ ~4 KB, echoed on poll + webhooks
}

Example

const uda = await stridge.gateway.start({
  owner: walletAddress,
  destination: {
    network_id: "9001",           // Arbitrum One
    to_address: walletAddress,
    asset_symbol: "USDC",
  },
  metadata: { app_user_id: "user_42", checkout_session: "cs_abc" },
})

console.log(uda.uda_id, uda.status) // "uda_01...", "active"

const arbitrumDeposit = uda.deposit_addresses.find(
  (addr) => addr.network_name === "arbitrum-one",
)

Returns

GatewayStartResponse carries the UDA id, the merchant-facing destination tuple, the lifecycle status ("active" / "retired"), and the per-chain deposit_addresses[] array — one entry per source chain the gateway will route through, each with its accepted_assets[] (native + tokens). See Models & types for the full DTO surface.

Status codes

  • 200 — UDA already existed for (owner, destination); the same record is returned.
  • 201 — UDA newly provisioned.
  • 4xx / 5xx — throws BackendError with the parsed gateway message.

gateway.poll

Returns every UDA registered against the owner plus their settlement history. The canonical readback after a wallet has been seen.

Signature

gateway.poll(
  owner: string,
  options?: PollOptions,
): Promise<GatewayPollResponse>

interface PollOptions {
  // Destination filter — echoed in the response.filter, NOT applied server-side.
  network_id?: string
  to_address?: string
  asset_symbol?: string
  asset_address?: string

  // Settlement scoping
  txId?: string                         // scope settlements[] to entries with from.tx_id === txId
  limit?: number                        // server default 50, cap 200
  offset?: number                       // zero-based

  // Conditional request
  ifNoneMatch?: string                  // sent as If-None-Match; 304 throws BackendError(304)

  signal?: AbortSignal
}

Example — poll once

const { owner, udas } = await stridge.gateway.poll(walletAddress)

for (const uda of udas) {
  if (uda.destination.network_id !== "9001") continue
  if (uda.destination.asset_symbol !== "USDC") continue

  const newest = uda.settlements[0]
  console.log(uda.status, newest?.status, newest?.from.tx_id)
}

Example — poll until terminal

async function pollUntilTerminal(owner: string, sourceTxHash: string) {
  const controller = new AbortController()
  for (;;) {
    const { udas } = await stridge.gateway.poll(owner, { signal: controller.signal })

    const settlement = udas
      .flatMap((u) => u.settlements.map((s) => ({ uda: u, settlement: s })))
      .find(({ settlement }) => settlement.from.tx_id?.toLowerCase() === sourceTxHash.toLowerCase())

    if (settlement?.uda.is_terminal) return settlement
    await new Promise((r) => setTimeout(r, 2_000))
  }
}
Note

The gateway returns the full UDA list and full settlement history for the owner. The destination-filter fields (network_id, to_address, asset_symbol, asset_address) are echoed back inside response.filter for traceability, but server-side narrowing of udas[] is not applied today. Match by destination.* and settlements[i].from.tx_id client-side, as in the example above.

Polling cadence

Recommended cadence is one call every 2 seconds while a payment may be in flight. Stop polling a given UDA once is_terminal === true (terminal states are completed and failed). The endpoint honors If-None-Match — pass an ETag from a previous response and the gateway returns 304 Not Modified, which surfaces as a BackendError with statusCode === 304 so you can treat it as a "nothing changed" branch in your loop.

Returns

GatewayPollResponse with owner, filter (echoed back), udas[], and an optional pagination envelope. Every UDA carries its own derived status, is_terminal flag, destination, and settlements[]. See Models & types for the full breakdown — including the eight-state GatewayUdaDto.Status enum (idlefrom_detectedfrom_confirmedroutingto_pendingto_fundedcompleted / failed).

gateway.assets

Returns the merchant-scoped supported-asset catalogue — only the chains and tokens the workspace has enabled in its Gateway Kit configuration. Same wire shape as the public uda.supportedAssets catalogue (chain family, native currency, token contracts) but filtered to what's routable for this project.

Signature

gateway.assets(
  options?: { signal?: AbortSignal },
): Promise<SupportedAssetsResponse>

Example

const { assets } = await stridge.gateway.assets()

for (const chain of assets) {
  console.log(chain.network_name, chain.assets.map((a) => a.symbol).join(", "))
}
// → "arbitrum-one USDC, USDT"
// → "ethereum   USDC, USDT, DAI"
Tip

Prefer gateway.assets() over the public uda.supportedAssets() whenever you have a project key in scope. The UI then surfaces only chains and tokens this project can actually settle, instead of the full platform-wide catalogue.

Returns

SupportedAssetsResponse{ assets: SupportedAssetDto[] }. Each SupportedAssetDto carries network_id, network_name, network_symbol, eip155_id, chain_type ("EVM", "TVM", or a forward-compat string), native_currency, and the configured assets[] (token contracts).

gateway.rateBySymbol

Per-unit USD price for a token symbol. Lightweight read against the gateway's pricing layer.

Signature

gateway.rateBySymbol(
  assetSymbol: string,
  options?: { signal?: AbortSignal },
): Promise<RateResponse>

Example

const { unit_price } = await stridge.gateway.rateBySymbol("USDC")
console.log(`1 USDC ≈ $${unit_price}`) // "1 USDC ≈ $0.9998"

Returns

RateResponse{ amount, unit_price, total }, all decimal-string-encoded. amount and total echo the input scaling (today the endpoint treats amount as 1 per call); unit_price is the per-unit USD price.

gateway.rateByErc20

Per-unit USD price for an ERC-20, keyed off (chain, contract_address). Use when the same symbol resolves to different contracts on different chains and you need the contract-precise rate.

Signature

gateway.rateByErc20(
  chain: string,
  contractAddress: string,
  options?: { signal?: AbortSignal },
): Promise<RateResponse>

The chain parameter is the gateway's internal network_id (e.g. "9001"), not the EIP-155 id. Get the value from gateway.assets()[i].network_id or Supported networks.

Example

const { unit_price } = await stridge.gateway.rateByErc20(
  "9001",
  "0xaf88d065e77c8cC2239327C5EDb3A432268e5831", // USDC on Arbitrum
)

Returns

RateResponse — same shape as rateBySymbol.

Cancellation

Every method accepts options.signal. Aborting it cancels the in-flight fetch; the SDK wraps the abort error in a BackendError. Use this for long-lived polling loops or per-request timeouts.

const controller = new AbortController()
const timer = setTimeout(() => controller.abort(), 10_000)

try {
  const { udas } = await stridge.gateway.poll(walletAddress, { signal: controller.signal })
  // …
} finally {
  clearTimeout(timer)
}
  • API client — how projectKey flows into the authenticated projectHttpClient.
  • UDA endpoints — public, unauthenticated catalogue and quote calls.
  • Errors & retriesBackendError shape, retry policy for polling loops.
  • Gateway HTTP API — the raw wire contract behind every method.
  • Models & types — every request and response DTO referenced above.
Was this page helpful?