@oneswap/trader-sdk
v0.2.3
Published
OneSwap Trader SDK: trade your own custodial OneSwap wallet programmatically via a trader API key
Maintainers
Readme
@oneswap/trader-sdk
Trade your own OneSwap wallet programmatically from a bot, script, or backend service. The SDK is for an existing OneSwap account holder; it does not onboard other users or withdraw funds.
Install
npm install @oneswap/trader-sdkGet a key
A OneSwap administrator enables access and issues a trader key for an approved account and wallet. A trader cannot enable Trader SDK access, create a key, change its wallet binding, or enable three-token fees. Contact OneSwap to request issuance, revocation, or replacement.
A trader key moves real funds. Keep it in a server-side secret manager. Never put it in a browser, mobile app, repository, log, or analytics event. Ask OneSwap to revoke an exposed key immediately. The trader key is not a self-custody key and never touches that key.
Create a client
import { TraderSDK } from '@oneswap/trader-sdk'
const trader = new TraderSDK({
apiKey: process.env.ONESWAP_TRADER_KEY!,
environment: 'mainnet',
})The administrator-issued key is bound to one wallet, so no method takes a walletId.
For a self-custody wallet, swaps require an active OneSwap user mandate.
Pools, tokens, and balances
const pools = await trader.pools()
const tokens = await trader.tokens()
const balances = await trader.balances()
const pool = pools.find((candidate) => candidate.id === 'rt-...')
if (!pool) throw new Error('Pool is unavailable to this trader')xToY: true spends the pool's assetX and receives assetY; false reverses the
direction.
Quote and swap
const quote = await trader.quote({
poolId: pool.id,
amountIn: 0.5,
xToY: true,
feeMode: 'prepaid',
})
if (!quote.sufficientFunds) throw new Error('Insufficient spendable balance')
const result = await trader.swap({
poolId: pool.id,
amountIn: 0.5,
xToY: true,
minAmountOut: quote.amountOut * 0.99,
feeMode: quote.feeMode,
idempotencyKey: 'order-1042',
})Quote immediately before swapping. Pass a unique idempotencyKey for each intended swap and
reuse it only when retrying that exact order.
Some pools enforce commercial rules on every entry point. pool.minTradeUsd and
quote.minTradeUsd expose the minimum input value in USDCx; quotes below it fail with a
validation error. pool.flatNetworkFeeUsd and quote.flatNetworkFeeUsd expose an exact
per-swap network fee in USDCx value. When three-token mode is selected, the backend converts
that value into the configured fee token at its live USDCx price and returns the exact amount
as quote.tokenFee.amount with pricingMode: 'flat-usd'.
Optional three-token fees
An administrator must enable the trader and configure a distinct fee instrument for the selected synchronous atomic pool. Use the same explicit mode for the quote and swap:
const tokenFeeQuote = await trader.quote({
poolId: pool.id,
amountIn: 0.5,
xToY: true,
feeMode: 'token',
})
if (tokenFeeQuote.sufficientFunds) {
await trader.swap({
poolId: pool.id,
amountIn: 0.5,
xToY: true,
minAmountOut: tokenFeeQuote.amountOut * 0.99,
feeMode: 'token',
idempotencyKey: 'order-1043',
})
}Unless a pool has a flat network fee, the final quote calculates tokenFee.amount from the
live Canton traffic cost, including the extra fee-token allocation. It subtracts OneSwap's
measured reward recovery, applies the best global, pool, account, or wallet network-fee
promotion, and converts CC → USDCx → the configured fee token at live prices. A pool flat fee
is the commercial base amount, so global traffic markup and dynamic recovery do not change
it. Existing promotional network discounts still apply, followed by live conversion into the
configured fee token.
The quote also returns authoritative fee-token funding checks. A 100% promotion returns
amount: 0 with promotionalWaiver: true, and settlement omits the fee allocation. Traders
without that promotion pay the converted amount in the final quote. When a fee is charged,
the input, output, and fee-token allocations settle atomically.
Do not switch fee modes between quote and swap. Build minAmountOut from a quote with the
same pool, direction, amount, and fee mode as the submitted swap.
History and intent status
const history = await trader.history({ limit: 50 })
if (result.status === 'reserved' && result.intentId) {
const status = await trader.intent(result.intentId)
console.log(status.status)
}Synchronous pools settle inline. For an asynchronous pool, poll the returned intent to a terminal state. Three-token settlement is supported only on synchronous atomic pools.
Errors
Failures are subclasses of TraderError. Inspect the error's status and data fields and
handle authentication, permission, validation, conflict, rate-limit, transport, timeout, and
server failures explicitly. A self-custody wallet with a revoked or expired mandate fails with
ConflictError; restore the mandate in OneSwap before retrying.
License
MIT
