Repository navigation
Releases: DarkWalletRH/dark-sdk
Release list
Dark SDK 0.4.3: Robustness and hardening
Robustness and hardening. Upgrading is recommended; no API changes.
Changes
- One incoming transfer that will not open no longer blocks the wallet. A transfer whose hint cannot be opened (malformed, or above the bound for its block) used to make
getBalances,applyPending,historyand Dark Exit throw. The pending total is now recovered by a bounded search over the whole pending ciphertext, and that one transfer shows no amount in the history. - The solved witness and the prover input, which contain the account's secret, live only in an owner-only temporary directory (0700, files 0600) for the whole time they exist.
- The AEAD nonces of
hint,senderHintandaeBalanceare hedged like the encryption randomness: derived from the key, the context and fresh randomness, so a broken random number generator cannot repeat a nonce. The wire format is unchanged. balancePublicalso takes the pending ciphertext into account.- A verifier revert caused by a proof built on state that has since moved is reported as stale state (sync and retry); a bad proof or a vault/verifier mismatch is reported as a failure.
- The
keyCheckRpcUrldocumentation states which RPC source sees each recipient-key lookup.
Dark SDK 0.4.2: Recipient key cross-check
Security release. Upgrading is recommended for every integration that sends private transfers.
Changes
- A transfer encrypts to a recipient key only when two independent RPC sources agree on it. The recipient's registry key decides who can read a transfer's amount and note, so one RPC's answer is no longer enough:
LiveDarkClient.transfer()cross-checksregistry.keyOf(to)against a second source before it builds the ciphertext and the hint. The second source is the chain's public RPC when the client reads through anything else, or Dark's relay when anapiis configured. A disagreement throwsRPC_DISAGREEMENTwith nothing encrypted or sent; an unreachable second source fails closed (STALE_STATE). The new optionskeyCheckRpcUrlandkeyCheckClientoverride the choice;nulldisables the check for single-RPC development setups. newDisclosureId()redraws a mainnet id that would start witht_, so a mainnet link can never be routed to the testnet API.
Compatibility
New error code RPC_DISAGREEMENT. No other API changes; upgrading from 0.4.1 requires no code changes unless a client is built with an injected publicClient and no RPC URL, in which case there is no second source and the check is skipped — pass keyCheckRpcUrl to enable it.
Dark SDK 0.4.1: Standalone tests and CI
Maintenance release. No runtime, API or package-metadata changes.
Changes
- The test suite runs standalone, outside the monorepo it is developed in: the checks that need the Noir workspace skip when
circuits/is absent. - A GitHub Actions workflow runs
npm ci, the build and the tests on Node 22 for every push.
Upgrading from 0.4.0 requires no code changes.
Dark SDK 0.4.0: Mainnet support
Mainnet support.
Changes
deployments[4663]now carries the Robinhood Chain mainnet deployment: vault0xeD7a0c6899a6AC94Aea7A5b2F8f24a948042DA9C, key registry, the three verifiers, timelock, guardian and deploy block75151289.isDeployed(4663)returnstrue.- The deployment record is read back from chain, not transcribed: every address was cross-checked against the vault's own getters and the pinned verifier codehashes.
No API changes. Upgrading from 0.3.2 requires no code changes.
Dark SDK 0.3.2
The first public release of the Dark SDK: the TypeScript client for confidential USDG balances on Robinhood Chain.
Highlights
- Confidential balances. Deterministic privacy-key derivation from an account's secp256k1 key, twisted ElGamal encryption over the Grumpkin curve, and bounded discrete-log decryption.
- Zero-knowledge proofs. Witnesses and public inputs for the
register,transfer,withdrawanddisclose_rangecircuits, proved on Node (NodeDarkProver) or in the browser (WebDarkProver). - Live client.
LiveDarkClientreads and writes the vault through viem, walks every action through explicit states, re-derives public inputs before trusting a proof, and simulates before sending. - Selective disclosure. Create, seal and verify signed statements about a private balance that anyone can check against the chain.
Changes since the previous internal version
balancePublicis derived from the account's ciphertext: an account is public exactly when its available balance carries no randomness and nothing is pending.exportRevokeTokens()andimportRevokeTokens()persist disclosure revoke tokens across restarts. Import is all-or-nothing, and its errors never echo a token.- Chain reads are pinned to a single block and retried at that block when an RPC replica lags.
- Explorer links use hosts that serve TLS.
Security
This release includes hardening from internal security review:
- Disclosure claims are bound to their kind; a claim that mixes an exact value with range bounds is rejected.
- The balance-search bound is clamped to the protocol's hard ceiling.
- Proving witnesses written to disk are created owner-only (
0600) and overwritten before deletion.
Earlier internal versions are not published and should not be used.
Compatibility
Node 22+, ESM only. Optional peers: viem ^2, @aztec/bb.js 5.0.0-nightly.20260522, @noir-lang/noir_js 1.0.0-beta.22, react ≥ 18.