Create shared accounts governed by multiple signers and approval thresholds, then propose, co-sign, and submit transactions together. On top of standard multisig, Cluster adds asset management, trustlines, DeFi yield (DeFindex vaults), and confidential tokens β balances and transfer amounts hidden on-chain with zero-knowledge proofs, where co-signers can still decrypt and review each amount before they sign.
Cluster is a Turborepo monorepo: a NestJS API, a Next.js web app, and shared TypeScript packages (Stellar helpers, ZK cryptography, generated contract bindings, UI, and shared DTOs).
A Stellar account can be turned into a multisig account by adding signer keys with weights and setting low/medium/high operation thresholds. Cluster is the coordination layer on top of that primitive:
- Connect a wallet and sign in β no passwords. Authentication is a signed challenge (SEP-53
signMessage) exchanged for a session cookie. - Create and manage multisig accounts β add or remove signers, set weights and thresholds, and
disable the master key, all through native Stellar
setOptionsoperations. - Propose β co-sign β submit β any member proposes a transaction; the others review and add their signatures; Cluster combines them and submits to the network once the required threshold weight is met.
- See everything in one place β balances, transaction history and status, trustlines, and the proposals awaiting your signature.
Members never hand over keys: every transaction is signed by each member's own wallet, and Cluster only assembles and submits what the group has approved.
- Wallet authentication β SEP-53 signed-message login (challenge β verify β session cookie), via Stellar Wallets Kit.
- Multisig accounts β real Stellar multisig (weighted signers + low/medium/high thresholds + optional master-key disable).
- Members & thresholds β add/remove co-signers and adjust the signing policy through the same propose-and-approve pipeline.
- Transaction pipeline β a single propose β sign β submit flow for every transaction type: payments, account configuration changes, trustlines, DEX trades, DeFindex vault deposits/withdrawals, and confidential-token operations.
- Assets & activity β token balances, transaction history, and an activity view with pending / done / expired proposals.
- Payments & trustlines β send assets and manage trustlines from the multisig account.
- Invest (DeFindex) β deposit into and withdraw from DeFindex yield vaults.
- Confidential tokens (zero-knowledge) β the highlight below.
Cluster's differentiating feature: private balances for a multisig account on Stellar. Amounts and
balances are hidden on-chain β the network stores only Pedersen commitments (C = vΒ·G + rΒ·H) and
UltraHonk zero-knowledge proofs β while the account's co-signers can still decrypt and see each amount
before signing. Built on the OpenZeppelin confidential-token protocol and deployed on Stellar
testnet.
Testnet only, unaudited. The confidential contracts are unaudited; this feature runs on Stellar testnet and is kept separate from mainnet activity. Do not use for real value.
What it enables
- Confidential operations through the normal multisig pipeline:
register(activate confidential for an account),deposit(public β confidential),merge(fold received funds into spendable),confidential_transfer(hidden amount), andwithdraw(confidential β public). - Co-signers see the amount before signing β each member locally decrypts a pending confidential transfer and reviews the real value before adding their signature.
- Selective disclosure β a holder can prove a single transfer's amount to a chosen verifier, who
checks it on a public page (
/verify) without a wallet or an account. - Auditor view β the designated auditor can decrypt every transfer of the token (
/auditor), entirely client-side.
How it works
- Every state change carries an UltraHonk proof (Aztec Barretenberg /
bb.js) verified on-chain by a Soroban verifier contract. Proofs are generated in the browser under a keccak transcript (required by the on-chain verifier). - The account has one spending secret
sk, sealed individually to each member (X25519 sealed-box). The server is blind: it stores only ciphertexts and public keys β neversk, an amount, or a blinding factor. A member's browser unwraps its copy ofskfor the session (key derived from a wallet message signature) and never persists it. - A confidential operation flows:
build witness β prove in browser β encode {payload, proof} XDR β build a Soroban transaction wrapping the generated contract binding β propose to the multisig pipeline β co-signers decrypt & review the amount β sign β auto-submit at threshold. - The transaction source is always the multisig G-address, so Soroban
require_authis met by the envelope signatures the pipeline already collects. Confidential spends bind the current balance commitment, so the API serializes them (a second concurrent spend proposal returns HTTP 409).
Turborepo monorepo (npm workspaces):
apps/api NestJS API β auth, accounts, members/thresholds, transaction
pipeline, assets, DeFindex, and the server-blind `confidential` module
apps/web Next.js app β dashboard, members, transfer, activity, coins,
trustlines, invest, and confidential surfaces (disclose / verify / auditor)
packages/stellar Stellar SDK helpers β multisig config ops, tx builders, signature
combination, submission, and the Soroban confidential builders
packages/zk ZK cryptography + proving core (browser-safe)
. Grumpkin/Poseidon2, key derivation, X25519 sealed-box, k_store openings,
XDR payload codec, StateEngine, disclosure prove/verify, bb.js proving
/node node-only helpers (circuit/VK loaders, prove ops, JSON store)
/chain chain reader + event fetch + auditor decryption
packages/contracts/* generated TypeScript bindings for the token/verifier/auditor contracts
packages/shared shared enums + zod DTOs (transaction types, confidential ops, β¦)
packages/ui shared React component library
packages/config shared TS / lint / build config
prisma database schema + migrations
- Monorepo / tooling: Turborepo, npm workspaces, TypeScript, tsup, Vitest, Jest
- API: NestJS, Prisma, PostgreSQL, cookie-session auth
- Web: Next.js (App Router), React, TanStack Query, Tailwind
- Stellar:
@stellar/stellar-sdk, Soroban smart contracts, Stellar Wallets Kit (SEP-53) - Zero-knowledge:
@aztec/bb.js(Barretenberg UltraHonk), Noir circuits,@noble/curves,@noble/hashes,@noble/ciphers,@zkpassport/poseidon2
All routes except the public disclosure/verify surface sit behind a session-cookie guard.
| Area | Routes |
|---|---|
| Auth | GET /auth/challenge Β· POST /auth/verify Β· POST /auth/logout Β· GET /auth/me |
| Accounts | GET /accounts/:id Β· members GET/POST/DELETE /accounts/:id/members[/:memberId] Β· PATCH /accounts/:id/thresholds |
| Transactions | POST/GET /accounts/:id/transactions Β· POST /transactions/:id/signatures Β· POST /transactions/:id/submit Β· GET /transactions/pending-for-me Β· GET /transactions/:id |
| Assets | GET /accounts/:id/balances Β· GET /accounts/:id/history |
| DeFindex | POST /defindex/vault/:address/{deposit,withdraw}-xdr Β· GET /defindex/vault/:address/balance |
| Confidential | wrap-keys Β· per-account envelopes / openings / registration (all server-blind) |
| Role | Contract ID | Explorer |
|---|---|---|
| Confidential token | CAPLH4ZW7EDSYRBCQN77Y4K7W5RNA6TO76JQ5CGHHIPY4ALWVQZ2WFAY |
stellar.expert |
| Verifier | CC6NG5LWW6QA4YSW2RP7RR2CE5FF6IHAGJEYY4STG6QP563EWSZU5DG7 |
stellar.expert |
| Auditor | CAEYYDRJPJ73UR3UZWYLSIWW4CHUZILTSENAWOUYXGSR4LPY4HQ23R4L |
stellar.expert |
| Underlying asset (XLM SAC) | CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC |
stellar.expert |
Network passphrase: Test SDF Network ; September 2015. Auditor id: 0.
Prerequisites: Node.js β₯ 18, npm, a PostgreSQL database (e.g. Supabase), and a Stellar wallet
supported by Stellar Wallets Kit. The stellar CLI
is only needed to regenerate contract bindings.
# 1. install
npm install
# 2. configure environment
cp apps/api/.env.example apps/api/.env
cp apps/web/.env.example apps/web/.env
# 3. apply database migrations (needs DATABASE_URL / DIRECT_URL)
npx prisma migrate deploy
# 4. vendor the bb.js browser assets (also runs automatically on predev/prebuild)
npm run vendor:bb -w web
# 5. run
npm run dev # API on :3001, web on :3000
# quality gate
npx turbo run lint typecheck build testThe base app targets Stellar; testnet is an explicit opt-in used by DeFindex vaults and the confidential-token feature, so a missing variable can never silently downgrade network safety.
API (apps/api/.env):
STELLAR_NETWORK=β¦ # mainnet | testnet
STELLAR_RPC_URL / STELLAR_HORIZON_URL # active network
STELLAR_TESTNET_RPC_URL=β¦ # cross-network testnet opt-in
DATABASE_URL=β¦ / DIRECT_URL=β¦
CONFIDENTIAL_{TOKEN,VERIFIER,AUDITOR}_CONTRACT_ID # confidential feature
CONFIDENTIAL_UNDERLYING_SAC=β¦
CONFIDENTIAL_AUDITOR_ID=0
Web (apps/web/.env): NEXT_PUBLIC_ mirrors of the network + confidential contract IDs.
- Non-custodial multisig. Cluster never holds member keys; every transaction is signed by each member's own wallet, and the server only combines approved signatures and submits them.
- Server-blind confidential storage. The confidential API persists only ciphertexts and public keys β never an amount, a blinding factor, or a spending secret. Each member holds their own sealed copy of the account secret, unwrapped only in their browser and never transmitted.
- The auditor secret is a master key (it can decrypt every confidential amount). It is entered on the
/auditorpage at runtime and stays in the browser β do not bake it into a build via aNEXT_PUBLIC_*variable in any shared deployment, since Next.js inlines those into the public client bundle.
The suite runs offline: the network, wallet, and bb.js prover are exercised through test doubles at the
edges (bb.js cannot run under jsdom), while the confidential cryptography β the part that must match the
chain β is verified directly: a real UltraHonk proof is generated and self-verified in Node, the XDR
payload codec is checked byte-for-byte against reference vectors, and the on-chain address_to_field
value is asserted against the deployed contract.
npx turbo run test- OpenZeppelin Stellar contracts (confidential token) β https://github.com/OpenZeppelin/stellar-contracts
- Reference confidential-token demo β https://github.com/brozorec/stellar-confidential-token-demo
- Barretenberg /
bb.js(UltraHonk proving) β https://github.com/AztecProtocol/aztec-packages - Noir (ZK circuits) β https://noir-lang.org
- Stellar / Soroban developer docs β https://developers.stellar.org
- SEP-53 (signed messages) β https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0053.md
- Stellar Wallets Kit β https://github.com/Creit-Tech/Stellar-Wallets-Kit
- DeFindex β https://defindex.io
Confidential-token protocol and circuits by OpenZeppelin; reference SDK/app patterns adapted from
brozorec/stellar-confidential-token-demo; zero-knowledge proving powered by Aztec's Barretenberg.