Skip to content
LogoLogo

Arrekta SDKs and documentation site: shared design contract

2026-10-18. Read by the three parallel workstreams: sdk/typescript, sdk/python and docs-site. Any change to this contract must be applied to all three.

1. One source of truth: change once, update everywhere

SourceOwnsConsumers
core/PROTOCOL.mdencodings, consensus rules, error codesSDK codecs; docs "Protocol" section (rendered from the file at build time, never copied)
core/vectors/*.jsonbyte-exact expected outputsboth SDKs' conformance tests (keys, hashing, transactions, pst, base_layer, security)
docs/api/openapi.jsonREST contract of the node (/v1/..., /rpc)generated TypeScript types (openapi-typescript), generated Python models, docs "REST API" reference (generated pages)
sdk/*/examples/*runnable examplesdocs code tabs import these files, and CI runs them against a regtest node
docs/OPERATIONS.md, docs/*.mdoperator docsdocs "Operate" section (rendered from the files)

One command regenerates everything derived: tools/sdkgen/gen.sh. It regenerates TypeScript types, Python models and the docs API pages from openapi.json. A CI check fails if generated files are stale. When the protocol changes: update PROTOCOL.md, regenerate the vectors, and both SDKs' conformance tests fail until they follow.

2. Design references (what we copy, what we improve)

ReferenceCopied ideaArrekta twist
viem (Ethereum)Clients made from a transport; tree-shakable standalone actions (getBlock(client, …)); strict types; bigint amounts; typed errorsPost-quantum accounts; issued assets as first-class types; policy locks; PST
@solana/kitFunctional, composable codecs; RPC and subscriptions as separate modules; async-iterator subscriptions with AbortSignalSubscriptions resume from the last event id (gateway streams)
bitcoinjs-libUTXO transaction builder; PSBT-style multi-party flowPST with a constructor phase, policy-lock satisfaction, issuer controls
web3.py v7Sync and async clients over one core; provider/middleware splitShares the protocol code with the reference implementation
viem.sh / wagmi.sh docs (Vocs)React + Vite docs, code tabs, search, API referenceDocs generated from the spec, vectors and OpenAPI; runnable examples

3. API surface (both languages; TypeScript camelCase, Python snake_case)

Clients
  createClient({ url, network?, fetch? })            → Client (node REST /v1 + /rpc)
  createGatewayClient({ url, apiKey })               → Client for the gateway (/v1 proxied, /gateway/v1, /wallet/v1, /issuer/v1)
  Python: Client(url) and AsyncClient(url) (httpx); same action names as methods and as functions

Actions (standalone functions taking a client; Python also exposes them as client methods)
  getChain, getBlock({ id }), getBlockFilter({ id }), getFilterHeaders({ start, count }),
  getTransaction({ txid }), getRawTransaction({ txid }), decodeTransaction({ hex }),
  sendTransaction({ tx | hex }), sendPackage({ parent, child }),
  getAddress({ address }), getUtxos({ address, asset? }), getAddressHistory({ address }),
  getAssets(), getAsset({ idOrTicker }), getFrozen({ asset }),
  getMempool(), estimateFee(), getDeployments(), getCheckpoints(), submitCheckpoint({ hex }),
  getMiningTemplate({ address }), createAuxBlock({ address }), submitAuxBlock({ hash, auxpow })
  watchEvents({ signal?, lastEventId? }) → async iterator (node SSE /v1/events; gateway /gateway/v1/stream)

Accounts and keys
  generateSeed(); keychainFromSeed(seed, { network, scheme? }) → { key(i, change), lock(i), address(i), signingKeys(n) }
  privateKeyFromSeed(seed32) → { publicKey, sign(msg, context), keyHash }   (ML-DSA-65 default, ML-DSA-87 optional)
  Addresses: encodeAddress(lock, hrp), decodeAddress(addr, hrp) (bech32m arrk/tarrk/rarrk)

Locks and policies
  lockFromPublicKey(pk), multisigLock(m, keys), policyLock(node);
  policy builders key/multi/after/older/sha3/and/or/thresh plus templates htlc/vault/vesting

Transactions
  buildTransaction({ coins, payments, change, feeRate, issuances?, mints?, freezes?, version?, validUntil? })
  signTransaction(tx, spentOutputs, signingKeys, network); txid/wtxid; serialize/deserialize; sighash
  fee bumping: bumpFee (RBF rebuild with a higher fee rate), cpfp (child package)

PST (multi-party)
  createPst, signPst, combinePst, finalizePst, decode/encode, status

Light clients
  verifyFilter(filter, header, prevHeader), matchFilter(prevHash, filter, items), verifyMerkleBranch(...),
  verifyCheckpoint(checkpoint, signerSet, network)

Units and errors
  parseArrk("1.5") → 150000000n; formatArrk(150000000n) → "1.5"; parseUnits/formatUnits(decimals)
  ArrektaError { status, code, title, detail }, from RFC 9457 problem+json; DecodeError; ValidationError(code)

4. Implementation rules

  • TypeScript (sdk/typescript, npm arrekta-sdk): ESM, Node ≥ 20 and browsers, zero Node-only APIs in core paths.
    • Crypto: @noble/post-quantum for ML-DSA (keygen from the 32-byte seed ξ; context "ARRK-TX-v1"), and @noble/hashes for SHA-3, SHA-256 and SHAKE256. @scure/base for bech32m.
    • Build with tsup, test with vitest, generate types with openapi-typescript.
    • Pin exact versions.
  • Python (sdk/python, pip arrekta-sdk, import arrekta_sdk): depends on the reference package arrekta (core/) for all protocol code (encodings, crypto, tx, PST, policy, filters), so it can't drift. Adds httpx sync and async clients, typed models generated from OpenAPI, the ergonomic action API, units and errors. Python ≥ 3.13, ruff, pytest.
  • Conformance: each SDK has a test that loads core/vectors/*.json (by relative path) and reproduces keys, addresses, tx encodings, txids, sighashes, PST, policies and filters byte for byte.
  • Integration tests: start a throwaway regtest node on free ports in a temp directory, using node-rs/target/release/arrekta-node-rs (built) or core/.venv/bin/arrekta-node. Never touch the running Docker devnet (ports 28332/28342/28352, 29333) or the soak test.
  • Licence: MIT OR Apache-2.0 (as the workspace). Dependencies must be permissive; record them in THIRD_PARTY_NOTICES.md.

5. Documentation site (docs-site, Vocs = React + Vite)

  • Sections:
    • Introduction: what Arrekta is, quick start.
    • Concepts: UTXO and multi-asset, locks and policies, PST, merged mining, checkpoints and finality, fees and RBF, light clients, snapshots, post-quantum crypto.
    • Guides: send a payment, issue an asset, multisig with PST, HTLC swap, vault, light client, run a node, merged mining for pools, checkpoint signer, snapshots.
    • SDK: TypeScript and Python, with tabs for the same example in both languages.
    • REST API: generated from OpenAPI.
    • Protocol: core/PROTOCOL.md.
    • Operate: docs/OPERATIONS.md, security policy.
  • Markdown sources outside docs-site are imported at build time (a small Vite or remark step copies or includes them), never duplicated by hand.
  • Production standard:
    • fast static build (vocs build), search, dark mode, mobile layout, accessible colours;
    • a versioned API reference;
    • an edit-on-repo link and a "last updated" date from the source;
    • no external trackers.