Skip to main content

Setup

import { OneSwap } from '@oneswap/sdk'
const client = new OneSwap({ apiKey: 'os_live_...' })
const devnetClient = new OneSwap({
  apiKey: 'os_live_...',
  environment: 'devnet',
})
OptionTypeDefaultDescription
apiKeystringrequiredYour OneSwap SDK API key (os_live_...).
environment'mainnet' | 'devnet''mainnet'Logical target environment. devnet defaults to https://devnet.api.oneswap.cc.
baseUrlstringenvironment defaultOverride the API origin directly.
walletTokenstring | (() => string | Promise<string | undefined> | undefined)noneOptional end-user wallet token, or a lazy getter, for wallet-authenticated SDK calls.
timeoutnumber30000Request timeout in ms
Create apiKey values through the wallet-authenticated OneSwap developer portal. Authenticate your wallet on POST /api/sdk/wallet-login, then create or rotate keys on POST /api/sdk/keys. SDK developer auth and SDK swap flows do not use site-access tokens or access codes. Portal entry points:
  • Mainnet SDK keys: https://oneswap.cc/developer/keys
  • Devnet SDK keys: https://devnet.oneswap.cc/developer/keys
In SDK params and responses, use Amulet when you mean CC (Amulet).

Pools

MethodDescription
client.pools.list()All pools with effective reserves, fee, and LP supply
client.pools.get(poolId)Pool detail with swapAddress and lpAddress
client.pools.getStats(poolId, { days? })apr, apy, volume24h, fees24h, lpFees24h, tvl, swapCount24h, and APR metadata computed from fee events and effective reserves. Default lookback is 7 days.
client.pools.getTicker(poolId)USD-denominated price, priceChange24h, and volume24h for a pool. Live price and volume are derived from effective reserves and fee events (via the canonical CC/USDCx pool); priceChange24h comes from hourly USD snapshots and is null until ~24h of history exists.

Tokens

MethodDescription
client.tokens.list()Available tokens with name and admin

Quotes

MethodDescription
client.quotes.get({ from, to, amount, receiverParty?, poolId?, fromAdmin?, toAdmin? })Price quote. amount is the exact deposit amount you want the user to send. The response includes networkFeeAmount, poolFeeAmount, inputAmountAfterPoolFee, and totalInputAmount. outputAmount is based on inputAmountAfterPoolFee, while totalInputAmount currently echoes the exact deposit amount to send. trafficFeeInInput remains as a compatibility alias for networkFeeAmount. When token symbols are reused across issuers, pass poolId or both admin fields to disambiguate the pool pair.
Quotes also return inputTokenAdmin and outputTokenAdmin so you can keep working with the exact instrument identity that was priced. The quote response also includes a top-level settlementSafety field — null when the swap is clear to proceed, or { code, reason, message } when a swap of this size/timing would be blocked at settlement. Inspect it before calling swaps.create; see Settlement safety.

Fee discounts

If a fee discount applies — from the SDK API key, the wallet party, or the pool (see Fee discounts) — the charged amount fields already reflect it, and the applied policy is returned in networkFeePolicy / platformFeePolicy (otherwise null). The same quote without and with a pool discount (50% off network, 30% off platform):
{
  "outputAmount": "0.0000277700",
  "fee": 0.003,
  "networkFeeAmount": "7.2871950000",
  "platformFeeAmount": "0.0132846037",
  "networkFeePolicy": null,
  "platformFeePolicy": null
}
{
  "outputAmount": "0.0000334890",            // +20.6% more output
  "fee": 0.003,                              // nominal rate — unchanged
  "networkFeeAmount": "3.6435975000",        // 50% off
  "platformFeeAmount": "0.0112121113",
  "networkFeePolicy": {
    "targetType": "pool",
    "chargeBps": 5000,
    "estimatedNetworkFeeAmount": "7.2871950000",
    "chargedNetworkFeeAmount": "3.6435975000"
  },
  "platformFeePolicy": {
    "targetType": "pool",
    "chargeBps": 7000,
    "fullPlatformFeeRate": "0.0007500000",
    "chargedPlatformFeeRate": "0.0005250000",
    "discountBps": 3000
  }
}
The top-level fee rate stays nominal regardless of the discount — read the charged amount fields or discountBps. A wallet discount only resolves in a quote when you pass receiverParty.

Swaps

MethodDescription
client.swaps.create(params)Create a wallet-authenticated swap intent. Can throw SettlementSafetyError (HTTP 400) when the pre-payout safety guard blocks the swap — no intent is created.
client.swaps.getStatus(intentId)Poll swap status for the authenticated wallet party
client.swaps.cancel(intentId)Cancel a pending swap intent for the authenticated wallet party

Settlement safety

quotes.get returns a top-level settlementSafety field. It is null when the swap is clear, or { code, reason, message } when a swap of this size/timing would be blocked at settlement before any payout. code is one of output_reserve_share_exceeded, output_velocity_exceeded, reserve_price_deviation_exceeded, reference_price_deviation_exceeded, incomplete_completed_accounting, invalid_output_reserve, invalid_execution_price, or settlement_safety_guard_unavailable. Check it before calling swaps.create. If you skip the check and the guard would block, swaps.create returns HTTP 400 and the SDK throws SettlementSafetyError (which carries the same code/reason/message); no intent is created and no deposit happens.

Wallet auth

MethodDescription
client.walletAuth.requestChallenge(partyId)Create a signable OneSwap wallet-auth challenge
client.walletAuth.verifyChallenge(params)Verify the signed challenge and return a wallet token

swaps.create params

ParamRequiredDescription
fromTokenyesInput token
toTokenyesOutput token
amountyesSwap amount to price into the pool. The returned intent tells you the larger total deposit amount after adding the estimated network fee.
slippageToleranceno0.0010.05 (0.1%–5%), default 0.05. Validated client-side; non-finite or out-of-range values throw ValidationError before any request is sent.
walletAddressnoOptional sender party ID for UI clarity. If present, it must match the authenticated wallet token.
poolIdnoPreferred disambiguator when the token pair can map to more than one pool.
fromAdminnoExact admin for the input token when token symbols are reused.
toAdminnoExact admin for the output token when token symbols are reused.
idempotencyKeynoClient-supplied key forwarded to the backend for safe retries after a lost response. (Server-side dedup on this key is not yet implemented; rely on the active-intent guard for now.)
outputAddressnoDeprecated. Ignored by the SDK client because the current execution flow always pays back to the depositor party.

SwapIntent object

Properties: intentId, poolId, depositAddress, swapAddress, depositReference, inputToken, inputTokenAdmin, outputToken, outputTokenAdmin, expectedAmount, quotedSwapAmount, totalInputAmount, poolFeeAmount, lpFeeAmount, platformFeeAmount, inputAmountAfterPoolFee, networkFeeAmount, trafficFeeInInput, expectedOutput, minOutput, slippageTolerance, outputAddress, expiresAt, instructions. Notes:
  • depositAddress is the pool swap party, not the user’s own party.
  • expectedAmount is the final deposit amount to send. totalInputAmount returns the same value explicitly.
  • quotedSwapAmount is the original deposit amount you entered. In the current flow it matches expectedAmount.
  • poolFeeAmount is the 0.3% swap fee deducted before the remaining amount is priced into the pool.
  • networkFeeAmount is the estimated network fee deducted internally from the deposit. trafficFeeInInput remains as a compatibility alias.
  • inputAmountAfterPoolFee is the amount that actually trades into the pool after both deductions.
  • depositReference is recommended when your wallet flow supports Canton reason/reference metadata. Sender attribution does not depend on it for standard 1-step transfers.
  • client.swaps.create(...) requires both a valid API key and a wallet-authenticated end-user token.
  • The deposit must be sent from the same signed-in wallet party used to create the swap intent.
  • A different wallet or Canton party will not complete the swap intent.
  • Current backend swap intents give you a 24-hour deposit window. Use expiresAt from the response instead of hard-coding the timeout.
  • outputAddress in the response is the resolved destination party. In the current flow it matches the depositor party.
Method / EventDescription
swap.cancel()Cancel a pending swap intent
swap.wait(opts?)Await terminal state
'matched'A matching intent/deposit pair has been claimed
'deposit_received'The input deposit has been attributed to the swap
'forwarded'The swap has moved past deposit handling and into settlement
'processing'Deposit detected, swap executing
'sending_output'OneSwap is sending output back to the depositor party
'completed'Swap done
'slippage_failed'Refunded because price moved
'price_impact_exceeded'Refunded because price impact exceeded the server cap
'insufficient_amount'Refunded because the deposit was too small to cover the required network cost
'insufficient_liquidity'Refunded because pool liquidity is insufficient
'output_failed'Output transfer failed and the input refund succeeded
'no_output_holdings'No output inventory was available on the swap party
'failed'Swap reached a generic terminal failure state
'refund_failed'Refund path failed and manual intervention is required
'expired'Timed out
'cancelled'Intent was cancelled before execution started

Track

MethodDescription
client.track(partyId)Swap intents only for the wallet-authenticated Canton party under your API key. The partyId must match the authenticated wallet token.
Liquidity intents, LP positions, add/remove liquidity flows, developer earnings, collections, and account analytics stay outside the public SDK API.