npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@derivexyz/derive-ts

v3.0.29

Published

TypeScript SDK for the Derive v3 exchange API

Readme

@derivexyz/derive-ts

npm version CI license

TypeScript SDK for the Derive v3 exchange API — a typed client for market data, orders, RFQs, transfers, withdrawals, deposits, vaults, session keys, and websocket subscriptions.

For more detailed docs see the Derive v3 API reference.

Install

npm install @derivexyz/derive-ts ethers ws

Quickstart

import { DeriveClient } from '@derivexyz/derive-ts';

const client = new DeriveClient({
  network: 'testnet', // 'mainnet' | 'testnet' | 'local'
  wallet: process.env.PRIVATE_KEY, // account owner key (or an ethers Wallet)
});

// Public data needs no auth:
const ticker = await client.marketData.getTicker('ETH-PERP');
console.log('ETH index price', ticker.I);

// Private calls sign automatically. Open the websocket and log in first:
await client.connect();
const subaccountIds = await client.login();

await client.orders.place({
  subaccountId: subaccountIds[0],
  instrumentName: 'ETH-PERP',
  direction: 'buy',
  amount: '0.1',
  limitPrice: '1000', // rests below market
});

await client.close();

Authentication & session keys

Login and per-request auth use an EIP-191 signature over a millisecond timestamp. Trading/transfer/withdrawal actions are separately EIP-712 signed. Both are handled for you — you only provide a signing key.

For bots and frontends, do not ship the account owner key. Register a scoped session key once (signed by the owner), then run with only that key:

import { DeriveClient, ProtocolScopeCode } from '@derivexyz/derive-ts';
import { Wallet } from 'ethers';

const sessionKey = Wallet.createRandom();
const owner = new DeriveClient({ network: 'testnet', wallet: process.env.PRIVATE_KEY });
await owner.connect();
await owner.login();
await owner.sessionKeys.set({
  publicSessionKey: sessionKey,
  expirySec: Math.floor(Date.now() / 1000) + 7 * 24 * 3600,
  protocolScopes: [ProtocolScopeCode.Trade], // least privilege — never Admin for a bot
  ipWhitelist: ['203.0.113.7'],
});

// Later, in the bot, with only the session key:
const bot = new DeriveClient({
  network: 'testnet',
  sessionKey: sessionKey.privateKey,
  ownerAddress: await (new Wallet(process.env.PRIVATE_KEY!)).getAddress(),
});

Session keys expire at their signed expirySec and cannot be revoked via the API — set a sensible expiry. sessionKeys.edit changes only off-chain attributes (label, IP allowlist).

API surface

DeriveClient exposes namespaced sub-APIs:

| Namespace | What it does | |---|---| | client.marketData | instruments, tickers, currencies (public, no auth) | | client.subaccounts | portfolio, positions, margin, trade history | | client.orders | place / cancel / query orders | | client.rfq | RFQ taker (request → quote → execute) and maker (quote) flows | | client.spotTransfers | transferInternal (own subaccounts), transferExternal (other wallets), updateWhitelistedRecipients | | client.positionTransfers | RFQ-backed transferPositions between subaccounts owned by the same wallet | | client.withdrawals | signed L1 withdrawals | | client.deposits | contractCall.* (self-custody on-chain) and depositAddress.* (CEX-style) | | client.vaults | public reads + vaults.shareholder.* and vaults.curator.* | | client.sessionKeys | create / list / edit session keys | | client.subscriptions | websocket channels (callback or async-iterator) |

Anything not wrapped is reachable, fully typed, via client.send(method, params).

Type-only usage (stubs)

If you only want the endpoint type stubs — the request/response shape of every public RPC method, with no runtime client — import them from the types/endpoints subpath. They're generated from the exchange's canonical API spec, so they stay in lockstep with the live surface; nothing here pulls in ethers, ws, or any runtime.

import type { EndpointMap, ParamsOf, ResultFor } from '@derivexyz/derive-ts/types/endpoints';

type PlaceParams = ParamsOf<'private/order'>;
type Ticker = ResultFor<'public/get_ticker'>;
// or reach into the map structurally:
type PlaceParamsStructural = EndpointMap['private/order']['request']['params'];

Useful for codegen, tooling, or typing a hand-rolled client. EndpointMap is keyed by method string; each entry is { request, response }, where response is the { result } | { error } JSON-RPC union — use ResultFor<M> to pull out the success payload.

Subscriptions

import { channel } from '@derivexyz/derive-ts';

await client.connect();
const book = channel('orderbook.{instrument_name}.{group}.{depth}', {
  instrument_name: 'ETH-PERP',
  group: '1',
  depth: '10',
});

const sub = await client.subscriptions.subscribe(book, (data) => console.log(data));
// ...later
await sub.unsubscribe();

// Or as an async iterator:
for await (const update of client.subscriptions.stream(channel('trades.{instrument_name}', { instrument_name: 'ETH-PERP' }))) {
  console.log(update);
}

Value conventions (read this before signing)

  • Prices, amounts, and fees are passed as decimal strings/numbers (e.g. '1500.5'). On the wire the SDK sends decimal strings; inside signed action data it scales them to 1e18. The protocol runs at 1e12 precision and rejects (does not truncate) values with more than 12 decimal places.
  • Withdrawal amounts are the one exception — they are in the ERC-20's native decimals (e.g. USDC has 6), because they are the L1 payout value.
  • Withdrawals always pay out to the signer. If a session key signs a withdrawal, funds go to the session key's address, not the owner's.
  • Deposits are two distinct flows, chosen explicitly:
    • deposits.depositAddress.register(...) returns a deterministic address; send funds to it from anywhere and the exchange sweeps and credits them.
    • deposits.contractCall.* builds the on-chain approve + ActionManager transaction from an ethers Signer you provide.

Examples

Runnable, heavily commented walkthroughs live in examples/:

DERIVE_NETWORK=testnet PRIVATE_KEY=0x... npx tsx examples/01-deposit.ts

Ordered by the v3 onboarding flow — your first deposit creates your account, then session keys, then the rest: 01-deposit, 02-session-keys, 03-market-data, 04-subscribe, 05-place-order, 06-rfq-taker, 07-rfq-maker, 08-transfers, 09-withdraw, 10-vaults, 11-position-transfers.

Networks & signing params

The EIP-712 domain separator is computed from the network's chain id and the protocol's constant Matching verifying contract; the action typehash is a protocol constant. You normally just pass network: 'mainnet' | 'testnet' | 'local'. To point at a custom deployment, pass a full NetworkConfig.

Security note: auth headers are named X-Derive* on the wire. Keep your private keys in a secret manager; the SDK never logs key material.

License

MIT — see LICENSE.