Uruk Docs
Partners

SDK reference

createUrukClient methods for assets, prices, KYC, buy, sell, quote, and swap.

SDK reference

Package: @uruk.finance/partner-sdk

Quick start

import { createUrukClient } from "@uruk.finance/partner-sdk";

const uruk = createUrukClient({
  partnerId: 1, // assigned by Uruk DAO (0 = untagged B2C)
  network: "testnet",
  signTransaction: async (xdr) => yourWallet.signTransaction(xdr),
  publicKey: userAddress,
});

const assets = await uruk.listAssets();
// each asset includes pool.poolId, tokenA/tokenB, quoteAddress (usually USDC)

const sbtc = assets.find((a) => a.symbol === "SBTC");
console.log(sbtc?.address, sbtc?.pool?.poolId, sbtc?.pool?.quoteSymbol);

const { price, decimals, quoteSymbol } = await uruk.getAssetPrice("SBTC");
// spot: quote per 1 asset, 7dp (LiquidityPool.get_price). e.g. 65000_0000000 USDC
const usd = Number(price) / 10 ** decimals;

createUrukClient(config)

OptionTypeDescription
partnerIdnumberYour referral tag (0 = untagged)
network'local' | 'testnet' | 'mainnet'Defaults endpoints
apiUrlstring?Override REST API base
rpcUrlstring?Override Soroban RPC
signTransaction(xdr: string) => Promise<string>Required for swap/claim
publicKeystring?Used as the simulation source

Methods

listAssets()

GET /api/sdk/assets?partnerId= - active markets; curated if you saved a catalog.

Each item includes the token address and the pool used by buy/sell:

{
  symbol: "SBTC",
  address: "C...",          // SEP-41 token contract
  pool: {
    poolId: "SBTC_USDC",    // on-chain pool id (LiquidityPool symbol)
    tokenA: "C...",
    tokenB: "C...",         // usually USDC
    quoteAddress: "C...",
    quoteSymbol: "USDC",
    assetIsTokenA: true,    // direction hint (`sell` => `aToB` when true)
    feeTier: 30             // bps
  }
}

pool is null when the market has no live liquidity pool.

getContracts()

GET /api/sdk/contracts - liquidity pool, synthetic engine, USDC, partner registry, compliance, earnings, DAO, oracle, stability pool.

getKycStatus(address)

Returns { compliant, needsKyc, status }.

startKyc(address, { providerKey?, mode? })

Returns:

  • startUrl / directLink - open in a new tab
  • embedUrl - Uruk KYC page suitable for iframe
  • mode - 'redirect' | 'iframe'
  • guidance - human-readable integration notes

getAssetPrice(asset)

Simulates LiquidityPool.get_price(pool_id, a_to_b):

price = reserve_out * 10_000_000 / reserve_in

The SDK picks a_to_b so the result is quote per 1 asset (usually USDC per sBTC), scaled to 7 decimals (WAD = 10_000_000). This is the pool mid price (no swap fee and no price impact).

asset is a symbol, token contract, or listAssets() item.

const spot = await uruk.getAssetPrice("SBTC");
// spot.price is bigint, 7 decimals
// spot.quoteSymbol === "USDC"

Use quoteBuyAsset / quoteSellAsset when you need the expected output for a specific size (includes pool fee).

buyAsset({ trader, asset, amountIn, minOut?, slippageBps? })

Spend the quote token (usually USDC) to buy the asset. asset can be a symbol (SBTC), token contract, or an item from listAssets(). Resolves poolId / aToB for you, and passes your partnerId through to swap_exact_in. Default slippage is 50 bps if minOut is omitted.

sellAsset({ trader, asset, amountIn, minOut?, slippageBps? })

Sell the asset for the quote token. Same asset lookup as buyAsset.

Buy and sell with KYC

buyAsset / sellAsset block until the trader's KYC is compliant (throwing an error with needsKyc helpers when not):

const kyc = await uruk.getKycStatus(userAddress);
if (!kyc.compliant) {
  const session = await uruk.startKyc(userAddress, { mode: "redirect" });
  // open session.startUrl, or embed session.embedUrl
}

// Spend 100 USDC (7 decimals) to buy sBTC
const expectedOut = await uruk.quoteBuyAsset({
  asset: "SBTC", // symbol, token address, or listAssets() item
  amountIn: 100_0000000n,
});

const buy = await uruk.buyAsset({
  trader: userAddress,
  asset: "SBTC",
  amountIn: 100_0000000n, // quote token in (USDC)
  slippageBps: 50, // 0.5% default; or pass minOut instead
});

// Sell 0.01 sBTC for USDC
const sell = await uruk.sellAsset({
  trader: userAddress,
  asset: "SBTC",
  amountIn: 100000n, // asset amount in
});

Amounts are integer stroops (decimals from listAssets(), typically 7).

MethodamountInYou receive
buyAssetQuote token (usually USDC)The asset
sellAssetThe assetQuote token (usually USDC)

If you already have an asset from listAssets(), pass it through to skip a second lookup:

await uruk.buyAsset({ trader: userAddress, asset: sbtc, amountIn: 10_0000000n });

quoteBuyAsset({ asset, amountIn }) / quoteSellAsset({ asset, amountIn })

On-chain quotes without submitting a transaction. Includes the pool fee.

quoteSwap({ poolId, aToB, amountIn })

Simulates on-chain quote when you already know the pool.

swap({ trader, poolId, aToB, amountIn, minOut })

Low-level swap_exact_in with your partnerId. Use this when you already know the pool (for example a non-USDC pair):

const result = await uruk.swap({
  trader: userAddress,
  poolId: "SBTC_USDC",
  aToB: true, // true = sell token A, receive token B
  amountIn: 10_0000000n,
  minOut: 9_5000000n,
});

Blocks until KYC is compliant (throws with needsKyc helpers). Prefer buyAsset / sellAsset unless you need a custom pair.

claimRevenue(partnerOwner)

Invokes PartnerRegistry.claim_revenue.

Attribution

  • partnerId > 0 tags swap_exact_in so protocol fees are split with your partner share.
  • partnerId = 0 is untagged B2C - Uruk keeps the full protocol fee.

On this page