Skip to content

Releases: DarkWalletRH/dark-sdk

Dark SDK 0.4.3: Robustness and hardening

Choose a tag to compare

@DarkWalletRH DarkWalletRH released this 07 Oct 16:47

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, history and 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, senderHint and aeBalance are 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.
  • balancePublic also 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 keyCheckRpcUrl documentation states which RPC source sees each recipient-key lookup.

Dark SDK 0.4.2: Recipient key cross-check

Choose a tag to compare

@DarkWalletRH DarkWalletRH released this 07 Oct 07:03

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-checks registry.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 an api is configured. A disagreement throws RPC_DISAGREEMENT with nothing encrypted or sent; an unreachable second source fails closed (STALE_STATE). The new options keyCheckRpcUrl and keyCheckClient override the choice; null disables the check for single-RPC development setups.
  • newDisclosureId() redraws a mainnet id that would start with t_, 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

Choose a tag to compare

@DarkWalletRH DarkWalletRH released this 07 Oct 07:03

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

Choose a tag to compare

@DarkWalletRH DarkWalletRH released this 07 Oct 07:03

Mainnet support.

Changes

  • deployments[4663] now carries the Robinhood Chain mainnet deployment: vault 0xeD7a0c6899a6AC94Aea7A5b2F8f24a948042DA9C, key registry, the three verifiers, timelock, guardian and deploy block 75151289. isDeployed(4663) returns true.
  • 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

Choose a tag to compare

@DarkWalletRH DarkWalletRH released this 07 Oct 07:03

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, withdraw and disclose_range circuits, proved on Node (NodeDarkProver) or in the browser (WebDarkProver).
  • Live client. LiveDarkClient reads 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

  • balancePublic is derived from the account's ciphertext: an account is public exactly when its available balance carries no randomness and nothing is pending.
  • exportRevokeTokens() and importRevokeTokens() 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.