Getting started
Two paths, same library: install the package and call the product API, or install the binary and type commands. Most teams do both — the CLI is the fastest way to see what a call will do before you automate it.
Install
The package is published to GitHub Packages, a registry scoped to Swarm-AI-Labs. Point the scope at it and install by version:
# .npmrc
@swarm-ai-labs:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}bun add @swarm-ai-labs/turnkey-extensions
# or: npm i @swarm-ai-labs/turnkey-extensionsGITHUB_TOKEN needs the read:packages scope. In GitHub Actions the built-in secrets.GITHUB_TOKEN already has it — no PAT required.
The package is ESM-only and unbundled: dist/ mirrors src/ one file per module, so your bundler tree-shakes at module granularity. Chain SDKs are optional peer dependencies — importing /hyperliquid never pulls in TON, Sui or NEAR.
Import the subpath, not the root barrel
import { … } from "@swarm-ai-labs/turnkey-extensions" re-exports every chain, so one symbol drags the rest into your graph. The product API lives at /runtime; everything else has its own subpath.
Who signs
Every write needs an identity: one primitive (signRawPayload) from which the viem account, the EIP-712 signer and the address book are all derived. Pick the backend that matches where your code runs.
import { turnkeyApiKeyIdentity } from "@swarm-ai-labs/turnkey-extensions/runtime";
const identity = turnkeyApiKeyIdentity({
apiPublicKey: process.env.TURNKEY_API_PUBLIC_KEY!,
apiPrivateKey: process.env.TURNKEY_API_PRIVATE_KEY!,
organizationId: process.env.TURNKEY_ORG_ID!,
});import {
otpLogin,
turnkeySessionIdentity,
} from "@swarm-ai-labs/turnkey-extensions/runtime";
const session = await otpLogin({
initiator,
email: "you@example.com",
promptCode: async () => askTheUserForTheCode(),
});
const identity = turnkeySessionIdentity(session);import { turnkeyKitIdentity } from "@swarm-ai-labs/turnkey-extensions/runtime";
// `client` is the @turnkey/react-wallet-kit client.
const identity = turnkeyKitIdentity(client, organizationId);import { turnkeyBinaryIdentity } from "@swarm-ai-labs/turnkey-extensions/runtime/node";
const identity = turnkeyBinaryIdentity({ keyName: "default" });Your first calls
import { createSwarm } from "@swarm-ai-labs/turnkey-extensions/runtime";
const swarm = createSwarm({
identity,
policy: { capUsd: 500, limits: { maxLeverage: 5 } },
});
// Reads: no key is touched.
const holdings = await swarm.portfolio.holdings({ view: { hideZero: true } });
console.log(holdings.totalUsd);
// Writes: plan first. This signs nothing.
const preview = await swarm.perps.open({
coin: "ETH",
side: "buy",
notionalUsd: 250,
});
console.log(preview.plan.steps, preview.data.plan.liquidationPx);
// The same call, for real.
const placed = await swarm.perps.open({
coin: "ETH",
side: "buy",
notionalUsd: 250,
mode: "live",
});mode defaults to "plan" on every operation that can move money. A preview and a receipt come back in the same shape, so one renderer handles both. Read the execution contract before the first "live".
Configure endpoints
Every RPC and API endpoint is read through getConfig(), with mainnet defaults baked in — the package works zero-config. Override once at startup:
import { configure } from "@swarm-ai-labs/turnkey-extensions/config";
configure({
rpc: {
sol: process.env.SOL_RPC_URL,
evm: { 1: process.env.ETH_RPC_URL },
},
// Empty ⇒ same-origin proxy paths (`/api/…`); set them to call upstreams directly.
apiBases: { inventory: "/api/inventory", indexer: "" },
prices: { indexerType: "custom" }, // "public" opts out to CoinGecko only
});Or use the CLI
npm i -g @swarm-ai-labs/turnkey-extensions
swarm login --email you@example.com # email OTP into a Turnkey sub-org
swarm holdings # the whole wallet, valued
swarm positions # every venue, one table
swarm market hyperliquid buy --coin ETH --notional 250 # preview onlyWrites are dry runs until --confirm, and --confirm is refused without a SWARM_BUDGET_USD cap:
SWARM_BUDGET_USD=500 swarm market hyperliquid buy --coin ETH --notional 250 --confirmThe full command list, the safety model and the flags are in the CLI reference.
Where to go next
- SDK reference — every product function, grouped by namespace.
- CLI reference — every command and the guard rails around it.
- Capabilities reference — the complete export surface, per subpath, for what the product API does not wrap.
- Architecture — why the layers are cut where they are.