New:Microsoft Teams Notifications Are Now Available in Socket.Learn more
Get Started

@zkcoins/sdk

Package Overview
Dependencies
Maintainers
1
Versions
4
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@zkcoins/sdk

Pure-TypeScript wallet SDK for zkCoins — BIP-39/32 derivation, Schnorr signing, typed REST client, high-level account adapter.

Source
npmnpm
Version
0.1.0
Version published
Weekly downloads
13
333.33%
Maintainers
1
Weekly downloads
 
Created
Source

@zkcoins/sdk

Pure-TypeScript wallet SDK for zkCoins. One package covers BIP-39 / BIP-32 derivation, BIP-340 Schnorr signing, the typed REST client for /api/*, and a high-level account adapter that wallet integrators (Cake Wallet, Layerz Wallet, the in-tree web app) consume as a drop-in InterfaceAccountBasedWallet-style API.

Status: v0.1.0 implementation complete, awaiting first npm publish. Tracked on the develop branch — see CONTRIBUTING.md for the bootstrap workflow.

Why pure TypeScript

Earlier iterations of the wallet primitives were compiled to WASM from zk-coins/app/rust/client/. That works in the browser but creates friction for every other consumer — React Native (Layerz Wallet) struggles to bundle WASM cleanly, and Cake Wallet (Dart) cannot consume a WASM blob at all. The functions involved are all standard BIP-39 / BIP-32 / secp256k1 Schnorr / SHA-256 — every audited pure-JS library can do them. @zkcoins/sdk is the pure-JS replacement, so the same library runs identically in Node 22+, the browser, and React Native.

Each cryptographic primitive is exercised by an internal verify-roundtrip test: the SDK produces a Schnorr signature, then re-verifies it under the derived x-only pubkey via the same @noble/curves library. This proves the signing → verifying loop is consistent within JS.

A separate cross-test against the Rust reference in zk-coins/app/rust/client/ (proving the JS output is byte-equivalent to the in-tree Rust implementation for 100 randomized inputs per primitive) is planned as a v0.1.1 follow-up — see issue #6 once tracked.

Install

npm install @zkcoins/sdk

Quick start

import { ZkCoinsAccount, generateMnemonic } from '@zkcoins/sdk';

// 1. Create or restore an account. The SDK does not ship endpoint
//    constants — pass the URL of the node you want to talk to.
const mnemonic = await generateMnemonic();
const account = await ZkCoinsAccount.fromMnemonic(mnemonic, /* accountIndex */ 0, {
  apiUrl: 'https://dev-api.zkcoins.app',
});

// 2. Read authoritative state from the server.
const { balance, username } = await account.getBalance();
console.warn('balance:', balance, 'sats; username:', username);

// 3. Send.
const result = await account.pay(/* recipient */ recipientHex, /* amountSats */ 5_000);
console.warn('proof id:', result.proofId);

Choosing a node

@zkcoins/sdk is a protocol SDK, not a service SDK — it has no built-in knowledge of any particular operator. The apiUrl you pass to ZkCoinsAccount.fromMnemonic or new ZkCoinsClient({ apiUrl }) is the only thing that determines which node the wallet talks to.

DFX operates two public stages today:

URLBitcoin networkNotes
https://api.zkcoins.appMainnetProduction. No faucet — mint requires real on-chain funding.
https://dev-api.zkcoins.appMutinynetDEV. Open mint faucet, signet-grade reorgs, no real value.

Self-hosters point apiUrl at their own node (zk-coins/node docker image, see zk-coins/node README). Wallet integrators typically expose a chooser in their own config; the SDK stays opinion-free on which node is "the right one".

API surface (preview)

The ZkCoinsAccount class is the recommended entry point. It composes the lower-level building blocks (derivation, signing, REST client) into a wallet-friendly shape:

class ZkCoinsAccount {
  static fromMnemonic(
    mnemonic: string,
    accountIndex: number,
    opts: { apiUrl: string; passphrase?: string },
  ): Promise<ZkCoinsAccount>;

  readonly address: string;

  getBalance(): Promise<{ balance: number; username?: string }>;
  pay(recipient: string, amountSats: number): Promise<{ txid?: string; proofId: number }>;
  getTransactions(opts?: HistoryOpts): Promise<TxItem[]>; // throws until /api/history lands
  claimUsername(username: string): Promise<void>;
  resolveUsername(username: string): Promise<{ address: string }>;
}

Lower-level building blocks are also exported for advanced use (custom signing flows, key-derivation helpers, raw REST client):

import {
  // BIP-39 / BIP-32
  generateMnemonic,
  validateMnemonic,
  mnemonicFromEntropy,
  generateAccountKeys,
  generateAccountKeysFromMnemonic,
  derivePublicKeys,
  deriveSigningKey,

  // BIP-340 Schnorr + commitment building
  signSchnorr,
  createCommitment,

  // Typed REST client
  ZkCoinsClient,

  // Zod schemas + typed errors
  InfoResponseSchema,
  BalanceResponseSchema,
  SendResponseSchema,
  ApiError,
  NotImplementedError,
} from '@zkcoins/sdk';

Compatibility

  • Node 22+ (no native dependencies; runs in Bun, Deno, AWS Lambda, etc.).
  • All evergreen browsers (uses Web Crypto API + standard fetch).
  • React Native (tested with Expo SDK 51+ on iOS and Android).

Wallet integrator notes

  • Thin-client invariant. Before every signed request, the server is the source of truth. ZkCoinsAccount.pay() enforces this by calling getBalance() first internally — but if you build your own flow on top of the lower-level ZkCoinsClient, replicate that pattern.
  • No local state. The SDK does not persist anything to disk. Mnemonic storage, address book, transaction cache — all handled by the integrating wallet.
  • History endpoint pending. getTransactions() will throw NotImplementedError until zk-coins/node #153 ships. Wallets that need a transaction list today should poll getBalance() and persist sends locally as a fallback.

License

MIT.

See also

Keywords

zkcoins

FAQs

Package last updated on 31 May 2026

Related posts