On this page

Welcome to Cloakra

Cloakra is a shielded capital-allocation desk for organizations on Starknet mainnet. It settles grants, bug bounties, and contributor payouts through the STRK20 privacy pool, so who receives and how much stays private, while the pool's public legs stay public and verifiable.

On a transparent chain every organizational payout is also a disclosure. Paying a security researcher links their wallet to the vulnerability they reported. Splitting a grant among contributors publishes the salary table. Funding a round broadcasts the whole allocation strategy. Cloakra removes the recipient side of that disclosure without pretending the public side disappears.

Where everything lives

The stack, in one paragraph

A static Next.js frontend talking to the canonical STRK20 pool through WalletAccountV6 in starknet.js. There are no Cloakra contracts, no backend, and no server-held keys: the pool's own batch call settles many transfers atomically, and every operation is signed by your own wallet. Cloakra never touches a viewing key - that is a protocol rule, not a policy choice.

How it works

Three stages. Only the middle one is private, and the documentation is explicit about that throughout.

  1. 1. Shield. You deposit STRK into the pool. This leg is public: the depositing address and the amount are visible onchain, forever.
  2. 2. Allocate privately. Splits, bounties and grants settle inside the pool as encrypted notes. Recipients, amounts, and the link back to your organization are unreadable.
  3. 3. Unshield. Recipients withdraw to a public address on their own schedule. That leg is public too. What is broken is the link between your deposit and their withdrawal.

Set up a wallet

STRK20 operations require a privacy-enabled wallet. Today that means Ready. Cloakra detects any Starknet wallet that registers through the browser (Argent X, Braavos, OKX and others will appear in the picker), but only wallets exposing wallet-API 0.10 or later can perform private operations. Capability is detected with a version query - the app never reads your balances to feature-detect.

Registration is not automatic. The documentation says wallets register on first use; in practice a dapp-initiated deposit is rejected with NOT_REGISTERED until you run “Enable private tokens” inside Ready. That one-time flow itself deposits 6 STRK, which the pool fee consumes entirely - so budget for it before your first shield.

StealthSplit

Pay a whole team from one shielded balance in a single atomic transaction: all transfers land or none do. Add recipients by hand or paste a CSV payroll - one address, amount per line, with comma, semicolon or tab separators. Every pasted row passes exactly the same validation as a typed one, and a malformed row is reported with its line number rather than silently skipped.

Inside the pool no recipient can read another recipient's allocation. Advise recipients not to unshield their exact row amount immediately, though: matching withdrawals let an outside observer partition the split.

GhostBounty

A single private payout to a security researcher. The payout transaction names no recipient, no amount, and nothing linking them to your programme. The module includes an onboarding checklist for the researcher, because they must have a privacy-enabled wallet with private tokens enabled before a payout can reach them.

StealthGrant

A whole grant round disbursed in one atomic transaction. Each grantee sees only their own award; the recipient list and per-grant amounts never appear onchain. Only your total deposit into the pool is public.

Treasury

Shield STRK into the pool and unshield back out, read your shielded balance (consent-gated - your wallet asks first), and review your public footprint: every pool leg the chain can see about your account, reconstructed from the pool's Deposit and Withdrawal events. The instructive part is what is absent from that list - the private transfers and splits between the legs.

Shielding is two wallet prompts, by design: an ERC-20 approval, then the private deposit. The second prompt is part of the same flow, not a duplicate. Freshly shielded notes also mature for about ten blocks before they can be spent.

What's private, what isn't

Private (inside the pool)Public (onchain)
Who receives a split, bounty, or grantYour deposits into the pool (address + amount)
Per-recipient amountsAny withdrawal to a public wallet (address + amount)
The link between payer and payeeThat an address interacted with the pool, and when

One consequence deserves emphasis: because both legs are public, timing and amount correlation can re-link them. Unshielding an amount that echoes a recent deposit, or moving funds minutes after shielding, undoes much of what the pool provides. Patience is part of the privacy.

Privacy warnings

Before any private operation opens your wallet, Cloakra checks your own public footprint for the mechanical mistakes and warns you:

Matching is deliberately approximate, within about one per cent. Real observers match approximately, so nudging an amount by dust does not help and the warning will not pretend otherwise - waiting does. Warnings never block a payment; they turn an accident into a choice.

This is a bounded check over your own public legs from roughly the last day - not a complete privacy analysis. It cannot see the recipient side, longer history, or patterns across accounts.

Safe to unshield?

The payer check above looks at your own deposits. A recipient unshielding a payout faces the mirror-image risk: the chain shows some organization's deposit going in and, later, your withdrawal coming out - and if the two amounts rhyme, an observer pairs them without needing anything private. So before an unshield opens the wallet, Cloakra also reads the pool's recent public activity by every account and checks:

The Unshield panel and the dashboard both show the pool's current STRK crowd - withdrawals and deposits by anyone over the window - so the figure is visible before you type an amount, not only when it triggers a warning. Other tokens the pool carries are ignored: an ETH deposit is not a crowd for a STRK withdrawal. Recency drives severity: an echo of a deposit from the last hour is high; from earlier in the day, medium.

This is still a bounded check. It sees roughly the last day of public pool activity, one account's history, and amount shapes an observer would try first. It cannot see longer history, patterns across many accounts, or what anyone does off this chain. The practical advice is unchanged: wait, and do not withdraw your exact row.

Signed payout receipts

A shielded payout is private, which makes it awkward to prove. After a run settles, Cloakra can turn it into receipts with a single off-chain wallet signature (SNIP-12 typed data - free, no gas). The signature commits to the operation, the settlement transaction hash, the pool, the recipient count, and a salted Merkle root over every (recipient, amount) pair.

Each recipient receives a file carrying only their leaf and proof, so a receipt discloses nothing about anyone else in the run. The salts stop anyone brute-forcing the root against guessed address and amount pairs.

A receipt is an attestation, not proof of transfer. The pool keeps transaction contents private by design, so no scheme can verify the shielded movement itself. What verification proves is that the paying organization signed this statement, and that the transaction it references really settled and touched the pool. A receipt is exactly as trustworthy as its signer.

Verifying a receipt

Anyone can check a receipt at /verify - no wallet, no account, no trust in Cloakra. Four checks run:

The displayed amount is derived from the signed value rather than the file's human-readable field, so a receipt cannot be edited to show a different number under a passing check.

Auditing a run

A recipient holds one receipt. An auditor holds a folder of them and one question: did this organization pay what it claims? Drop every receipt from a run onto /verify - files, a JSON list, or one receipt per line - and the page becomes the auditor's desk:

Verdicts are deliberately narrow. Verified means every supplied receipt passes and the run is fully covered. Partial coverage means every supplied receipt passes but some are missing - the total covers only those present, and a missing receipt is a gap in the audit, not evidence of anything. Inconclusive means the chain could not be reached for a check; nothing is presumed. Does not verify means at least one row failed a check the receipt scheme can actually make.

An audit inherits the receipt scheme's limit: it establishes what the org attested, and that the attested settlement really happened in the pool. The shielded transfers inside that settlement stay private by design. An auditor who needs more than the org's signed word needs a viewing key, which no dapp - Cloakra included - is allowed to hold.

Fees & registration

The pool charges a flat fee per private operation. Cloakra reads it live from the contract with get_fee_amount and never hardcodes it - the fee moved from 4 to 6 STRK during the sprint, which is precisely why. On a shield the fee is deducted from the deposit: shielding 26 STRK leaves a 20 STRK shielded balance.

The fee is re-read at signing time, and a submit is aborted if it changed between quote and signature rather than letting the transaction revert after you have already approved it.

Mainnet transactions

Cloakra's submission records seven mainnet transactions, all accepted on L1 with successful execution and confirmed to have emitted STRK20 pool events. The landing page re-verifies them against Starknet in your own browser on every visit - a fabricated hash renders a red NOT FOUND, so the claim is falsifiable through the interface itself.

The repository ships scripts/verify-tx.mjs and scripts/preflight.mjs if you would rather check them from a terminal than trust a web page.

Architecture

Known limits

Cloakra is unaudited hackathon software built for the STRK20 Private Sprint. It holds no keys and cannot move your funds, but it has not been through a security review. Use amounts you can afford to experiment with.