TypeScript SDK
A thin client library for proof generation, delegation management, reputation queries, and account derivation. The SDK is optional — every instruction is reachable via Anchor's generated IDL — but it handles WASM loading, circuit artifacts, and PDA math for you.
@writnetwork/sdk@solana/web3.js ^1.90Install
$ npm install @writnetwork/sdk @solana/web3.jsQuick surface
import {
Writ,
generateProof,
deriveWritAccounts,
deriveScope,
ACTION,
} from "@writnetwork/sdk";
const writ = new Writ({
cluster: "devnet",
connection,
});Core APIs
generateProof
Generate a Groth16 proof in the browser (or Node). Returns serialized proof bytes plus the public inputs. The secret trapdoor is derived from a user passphrase via Argon2id.
const { proof, publicInputs } = await generateProof({
secret: "correct horse battery staple", // any string
epoch: await writ.currentEpoch(),
});
const sig = await writ.register({ proof, publicInputs, authority });createDelegation
await writ.createDelegation({
slot: 0,
agent: agentKey,
programs: [METEORA_ID, RAYDIUM_ID],
budgetSol: 25,
durationDays: 14,
actions: ACTION.SWAP | ACTION.PROVIDE_LIQUIDITY,
});verify
Client-side verify that mirrors the on-chain CPI. Useful for UI — previewing whether a proposed action will pass before submitting a transaction.
const status = await writ.verify(agentKey);
if (!status.isValid) showRegistrationPrompt();
if (status.score < 500) warnLowReputation(status);deriveScope / deriveWritAccounts
Helpers to produce the nine account pubkeys needed for a writ_gate::verify CPI.
const accounts = await deriveWritAccounts(connection, agentKey);
// {
// writAccount, scope_0..scope_4, reputationAccount,
// sbtTokenAccount, writGateProgram
// }Full API
| Method | Purpose |
|---|---|
writ.register | Submit proof + mint SBT |
writ.rotateAuthority | Transfer writ to a new wallet |
writ.createDelegation | Add a scope to a slot |
writ.revokeDelegation | Mark a scope as revoked |
writ.listDelegations | Enumerate active + expired scopes |
writ.verify | Simulate writ_gate::verify locally |
writ.reputation | Fetch ReputationAccount |
writ.submitReport | Wrap reputation::submit_report (program-signed) |
writ.openDispute | Stake SOL to challenge a report |
writ.onStatusChange | WebSocket subscription to AgentStatus |
React hook
import { useAgentStatus } from "@writnetwork/sdk/react";
export function TradePanel({ agent }: { agent: PublicKey }) {
const { status, loading, error } = useAgentStatus(agent);
if (loading) return <Spinner />;
if (!status?.isValid) return <RegisterCTA />;
return (
<>
<ReputationBadge score={status.score} />
<BudgetMeter remaining={status.scope.budgetRemaining} />
<SwapForm />
</>
);
}Error handling
SDK methods throw typed errors extending WritError. Use instanceof checks to branch, or the narrowing helpers isWritError.
try {
await writ.register({ /* ... */ });
} catch (e) {
if (e instanceof NullifierCollision) {
toast("Wallet already linked to another writ.");
} else if (e instanceof ProofInvalid) {
toast("Proof generation failed — retry or check passphrase.");
} else {
throw e;
}
}Stability
The SDK is versioned in lockstep with the programs. The major version tracks the on-chain ABI; minor versions add helpers without breaking existing call sites. The 0.x line is devnet-only and may break on any release.