Docs/Reference
SDK
Build on Opaque from JavaScript.
@opaque/sdk is the library the app is built on. It runs in Node and in the browser, and it does everything except hold your keys for you.
Accounts
import { accountFromSeed, encodeAddress } from "@opaque/sdk";
const account = accountFromSeed(seed); // seed: 32 bytes, e.g. sha256 of a wallet signature
const address = encodeAddress(account); // 64-byte shielded address, base58, to give out
Syncing
import { Wallet, status, sync } from "@opaque/sdk";
const wallet = new Wallet(account);
await sync(wallet, SERVER); // replays every leaf, nullifier, reveal and claim
const { assets } = await status(SERVER); // each listed mint and its pool index
wallet.balance(aapl.index); // raw units
wallet.unspent(aapl.index); // notes with their leaf indices
Assets are identified inside the pool by their index, not their mint.
Transacting
import { transact, newNote, relay, transactInstructions } from "@opaque/sdk";
const tx = await transact(
{
account, tree: wallet.tree, auditorKey, asset: aapl.index,
inputs: wallet.unspent(aapl.index).slice(0, 2),
outputs: [{ note: newNote(BigInt(aapl.index), amount, recipient.owner), viewKey: recipient.viewKey }],
},
prove, // a Prover: Node's from "@opaque/sdk/node", or a Web Worker
);
await relay(SERVER, tx); // or build and send the two transactions yourself:
const { stage, transact: execute } = await transactInstructions(connection, payer, tx, { mint, tokenProgram });
transact balances the notes, pads missing inputs and outputs, encrypts the memos, and returns the proof and the instruction data. Deposits set extAmount positive and are sent by the depositor; withdrawals set it negative with a recipient.
Cross
import { draftOrder, commitHash, relayCommit, proveReveal, relayReveal, crossBatches } from "@opaque/sdk";
const { open, quotePrice } = await crossBatches(SERVER, market.id);
const batch = BigInt(open.id);
const draft = draftOrder(account, market, batch, 1, qty, limit, fundingNote);
await relayCommit(SERVER, market.id, batch, commitHash(account, draft));
// ...after the batch closes at `price`:
await relayReveal(SERVER, await proveReveal(account, draft, price, wallet.tree, auditorKey, prove));
Payouts arrive as notes with one-time secrets; sync finds them from the public reveal and claim streams.
Proofs
import { proveHoldings, holdingsSignals, holdsAtLeastInstruction, disclose, readDisclosure, ANY_INDEX } from "@opaque/sdk";
const statement = await proveHoldings({ asset: aapl.index, threshold, maxIndex: ANY_INDEX }, wallet.unspent(aapl.index), wallet.tree, prove);
holdingsSignals(statement); // the verifier's public inputs, for snarkjs
holdsAtLeastInstruction(connection, statement.proof, statement.nullifiers, statement.root, aapl.index, threshold, ANY_INDEX); // for the chain
disclose(notes, reader.viewKey); // encrypt notes to one reader; readDisclosure opens them
Audit
import { publicShare, combine, partial, openAudit } from "@opaque/sdk";
Key holders use these through the auditor CLI; see Auditor CLI.