JavaScript SDK
A zero-dependency Node/browser SDK combining a REST client with deterministic, offline, independently verifiable modules.
The JavaScript SDK (sdk/) is two things in one package: a REST client for the PolicyVault API, and a set of portable, deterministic, zero-dependency modules you can run yourself to independently verify what a PolicyVault deployment tells you — instead of trusting it. It requires Node.js ≥ 18 or any modern browser / WinterCG runtime.
What it is not
This SDK never asks for, accepts, stores, transmits, or signs with a seed phrase or private key — there is no code path that would accept one. It cannot authorize a spend; financial authority lives in the Kaspa covenant, and a signature comes from your own signer (KasWare, an offline/CLI signer, or anything implementing the Universal Signer Interface). A PolicyVault server, its database, and its operator are coordination infrastructure, not authority — the point of the deterministic modules below is that you can catch a lying or compromised server.
Quickstart
const { createClient, parseSompi, sompiToKas } = require("policyvault-sdk");
const client = createClient({
baseUrl: "http://127.0.0.1:8080", // "/api/v1" is appended for you
token: process.env.POLICYVAULT_TOKEN // omit entirely for a self-hosted server
});
const caps = await client.capabilities();
const { vaults } = await client.listVaults();
const { simulation } = await client.simulate({
vaultId,
action: "agentSpend",
params: {
payAmountSompi: "1500000000", // integer sompi, as a STRING
agentPk: agentXOnlyHex,
recipient: recipientXOnlyHex
},
signerAddress: agentAddress
});
if (!simulation.ok) {
console.error("would refuse:", simulation.refusalReason.code, simulation.refusalReason.message);
} else {
const built = await client.createRequest({ vaultId, action: "agentSpend", params, signerAddress });
}
A built request is not a broadcast — the pipeline is intent → build → sign → finalize → submit → reconcile, and each stage is a separate call.
Local verification — the part that matters
The deterministic modules are the same code the server runs (re-exported, not reimplemented). Run them yourself and compare:
| You want to know | Use |
|---|---|
| Is this the state the covenant is actually bound to? | state normalization + state-id computation |
| Is the successor they propose what the covenant will accept? | the vault-transitions module — derive it yourself |
| Is this agent/recipient really in the committed set? | Merkle proof verifiers — recompute the root, never adopt one |
| Is this fee real? | fee/mass computation |
| Is this transaction the intent I asked for? | intent.verifyIntentManifest |
const { intent } = require("policyvault-sdk");
const verdict = intent.verifyIntentManifest({ manifest, requestedIntent, decodedTransaction });
if (!verdict.ok) throw new Error(`intent refused: ${verdict.failures.map((f) => f.code).join(", ")}`);
verdict.statement; // "THIS TRANSACTION DOES EXACTLY WHAT WAS REQUESTED AND NOTHING ELSE."
Verify with your own requested intent, held locally — checking a manifest against a server-supplied description of "what you asked for" proves nothing.
Amounts: integer sompi, always
Every consensus and accounting value is integer sompi — BigInt in JavaScript, a decimal string on the wire, never a floating-point number. Use the SDK's canonical parsers (parseSompi, kasToSompi, sompiToKas); they fail closed on NaN, Infinity, negatives, unsafe integers, overflow, and malformed decimals.
Errors
PolicyVaultApiError carries the server's error envelope verbatim (status, code, serverMessage, body) — the client never maps one refusal onto another. PolicyVaultNetworkError means no answer arrived; you cannot assume the call didn't execute, so replay its idempotency key to find out safely rather than blindly retrying.
Status
DESIGNED + IMPLEMENTED + UNIT-TESTED + INTEGRATION-TESTED (exercised against a real spawned PolicyVault HTTP server). Not independently published to npm — sdk/ is consumed in-repo today; publication of any PolicyVault package is a separate, deliberate decision.
See also: Local intent verification, REST API.