Skip to content

Repository files navigation

Confide — private block trades for tokenized stocks

Confidential delivery-versus-payment on Solana. Exchange tokenized stock for stablecoin in one atomic transaction. Each side verifies the other's encrypted amount before signing, and everyone else sees nothing that moved — no size, no price, no position. Confide builds the zero-knowledge proofs the chain will not assemble for you, with nobody in the middle.

→ Try it live · Watch, 2:32 · no wallet, no API key, no install

One correction to the video, 2026-09-30. It says "every tokenized stock on Solana". The measurement is 1,992 mints from three issuers' catalogues — exhaustive over that list, not a census of the chain. Everything the video counts is unchanged; only the population's name was wrong. The narration is left as recorded because it is the record of what was said — docs/cwf-2026/THE-POPULATION.md.


Why now

On 17 September 2026 the SEC gave tokenized stock five years of relief — and set the conditions: AMM-executed trading only, every fill's size, time and direction published within ten minutes, a Tier 1 name capped at 0.25% of average daily volume. Block trades have always settled away from that tape, and a desk cannot go where every fill is published. Confide settles off it — and is not a venue, so the exemption neither covers it nor is needed.

What is on chain, and what Token-2022 does not provide

All 1,992 tokenized-equity mints from three issuers' catalogues already run Token-2022 with confidential transfers on and the auditor slot empty — every mint in the list checked, not sampled, and the list is a catalogue rather than a census. The same 1,992 carry permanentDelegate, pausableConfig and a transfer hook. Token-2022's only disclosure model is mint-wide — one auditor key, reading every transfer made while it is set, scoped to nobody. Every holder's transfer amounts, or no one's; there is no setting in between. Why the slot is empty is not measured — an empty slot is also what a zero-initialised mint gets by default (THE-PINCER.md). And a confidential account cannot receive anything until its issuer signs for it.

Which makes the first trade an issuance

Of 518,744 live accounts, two have asked for a confidential balance and none has been approved. So the party who can open the account is one of the two parties to the trade — and the first trade through that gate is not a swap between holders. It is an issuance.


What runs today — a trade that settles without publishing either side

The gate, both ways — the first trade, which is an issuance. The same 20,000-share allocation against $3,500,000, sent twice. ./scripts/issue-e2e.sh

  issuance: REFUSED, the issuer had not signed for the account
    error          {'InstructionError': [0, {'Custom': 24}]}  (expected)
  issuance: the same allocation, after the issuer signed
    error          none                       2 signatures   59,804 compute units

One instruction from the issuer stands between the two. The auditor slot is empty throughout — the issuer is the sender and needs no key to read what they sent. 5fqZLgbj… refused · 29coq95v… settled

Then between two strangers, sharing nothing but public keys. Run it yourself with MODE=dvp ./scripts/swap-e2e.sh; these three are on devnet now.

$ MODE=dvp ./scripts/swap-e2e.sh
  50,000 shares  ↔  $8,750,000        $175/share, agreed off chain
  one transaction   2 signatures   59,804 compute units   1,074 bytes
  alice, stock (delivered)  123,000 units      bob, stock (received)   50,000 units
  bob,   cash  (paid)       250,000 units      alice, cash (received)  8,750,000 units

All four accounts are ordinary associated token accounts — what a wallet creates — and all four still report a public balance of 0. Nobody watching the chain learns the size of the trade or the price it implies.

devnet
stock for stock 2RksP5AM… — 29,417 CU, 1,006 bytes
stock for cash 4gzku3FW… — 29,849 CU
stock for cash, on a mint shaped like PYUSD 5ZrJPGRL… — carries confidentialTransfer and confidentialTransferWithFee in one transaction

The numbers

1,992 tokenized stocks ship confidential balances — every one of them
518,744 live token accounts across Apple, NVIDIA, SpaceX, Anthropic and AMC
2 have asked for a confidential balance — one on NVDAx, one on AAPLx
0 have been approved. Nobody is through the gate.

Counted from mainnet by ./scripts/usage-scan.sh, on six mints — two per issuer — on 2026-09-28. The feature is shipped and gated on every mint in the list; on the six counted, no issuer has approved an account yet — so where we looked, nobody is using it yet. The other mints in the list have not been counted.

Go and do it yourself — devnet, nobody's permission

The whole flow, one command, then re-read from the chain by a separate keyless process:

git clone https://github.com/psyto/confide && cd confide
RPC=<your devnet endpoint> ./scripts/review.sh

It builds, then runs the issuer's gate refusing an allocation on chain, the investor failing to approve themselves, the issuer approving that one account, a half-signed send refused, the allocation settling, two approved holders trading, and the issuer under-delivering into the investor's pre-signing check. Then scripts/observe-run.py, holding no key, looks up each signature and account the run cites and checks the error or success, the signatures, that only Token-2022 ran, and that each settlement touched the accounts that read a public balance of 0. It cannot see amounts, and it cannot confirm the pre-signing refusal, which has no transaction; the receipt marks that row as the run's own word. It is in this repository and by default uses your RPC — set OBSERVE_RPC to read through a different one.

Needs the Solana CLI, Rust, a devnet endpoint (the public one rate-limits) and a keypair with about 2.3 devnet SOL, which it lends to the run's throwaway wallets and sweeps back at the end. Rent in the accounts the run creates stays on chain. What a passing run cost and how long it took, with its receipts: docs/cwf-2026/REVIEW-RUNS.md. A cold build or a struggling endpoint takes longer.

Or stand where one holder stands, on the standing testbed:

There is a standing issuer on devnet whose gate is shut exactly as all 1,992 are, and whose approval key is published in this repository. So you can hold something the chain reports as zero — and, as of 2026-09-22, trade it with somebody else and have the chain show neither size:

git clone https://github.com/psyto/confide
./scripts/testbed-join.sh                    # a position the chain reports as 0

With a counterparty, four commands and four files. Each of you joins both mints, then:

./scripts/swap-offer.sh  you.json --give <mint> 100 --want <mint> 17500  > offer.json
# they: ./scripts/swap-accept.sh them.json offer.json > accept.json
./scripts/swap-settle.sh you.json accept.json                            > settle.json
# they: ./scripts/swap-sign.sh   them.json settle.json

Steps 3 and 4 each decrypt the other side's amount before signing and compare it to what was agreed, out of a proof context the chain has already verified — without the other party's cooperation, and without revealing it to anyone else. The figure they compare against is pinned by steps 1 and 2 on your own machine, so the counterparty cannot supply both the leg and the expectation; a leg that is short, or a file that restates the terms, stops the command unsigned. Nothing moves until the fourth command: a proof is not a transfer, and a transaction carrying one of two signatures cannot execute. docs/TESTBED.md · what changed on 09-30

Needs the Solana CLI, Rust and a little devnet SOL. The key can approve accounts and cannot mint — observed when the testbed was set up, not re-checked by a script — docs/TESTBED.md.


Everything below is the evidence. Nothing above depends on you reading it.

This file was 4,850 words opening on the market, with what Confide is on line 48 and the trade at 102 seconds of reading. Measured 2026-09-20 and folded: the first two minutes are now the product, the trade, the count and one command, and the argument is everything under this line. A reader who stops early leaves with the product rather than with a gap in somebody else's.

Why there is nothing in the middle

Nothing of ours runs inside the trade: two Token-2022 instructions, two signatures, and Solana's atomicity where a clearing house would be. What Confide does is everything around it — the zero-knowledge proofs the chain will not assemble for you, verified on chain and citable by address, and the check that lets each side read the other's amount before it signs.

Delivery versus payment is what a clearing house exists for. Neither side will go first, so finance inserts a central counterparty, membership, margin and a day of lag. A Solana transaction is all-or-nothing, so the transaction is the clearing house — and the confidential version means neither party publishes the size that clearing house would have been told anyway.

The one danger a confidential trade has, and how it is answered

The amounts are encrypted, so a party could sign a transaction whose other leg sends far less than was agreed. It is answerable before signing, by the recipient alone: a confidential transfer encrypts the amount under the recipient's key too, so each side decrypts the other's leg straight out of the already-verified proof context.

$ cargo run -p confide-ct --bin swap-check -- my-keys.json <the validity context> 8750000000000
  ✓ it is addressed to your key
  ✓ it will move 8750000000000 base units to you
      decrypted from the verified context, by you, without anyone's cooperation
  ✓ and 8750000000000 is what you agreed
      compared here, not left to your eye

The third argument is the agreed amount and the comparison is the exit code. Leave it off and this prints a figure and compares nothing — which is what it did until 2026-09-30, and why the sentence that used to sit here told the reader to compare it themselves. The four scripts above pass it for you, from terms each side pinned on its own machine before any proof existed: what changed, how it is checked.

No trust, no third party, no floor proof, and nothing revealed to anybody else.

It is not an equities story

A stock-for-cash trade needs cash that can move confidentially. USDC, USDT and USDS cannot — legacy SPL, no extensions at all. PYUSD and USDG can, and land on the identical configuration as every tokenized stock: gate closed, auditor slot empty, and one key as confidential authority, permanent delegate and freeze authority on both.

PayPal's dollar ships the same unusable privacy feature behind the same door. Four issuers, two asset classes, one configuration — also the default, so it says what ships, not why. docs/cwf-2026/COMPOSITION.md

And what it cost to build, because that is the interesting part

The cash leg's mint carries a transfer fee config — PYUSD's is 0 bps and Token-2022 still refuses the plain confidential transfer. So that leg needs TransferWithFee: five proofs instead of three, and a BatchedRangeProofU256 that cannot be verified from instruction data at all (1,269 bytes against a 1,232-byte limit). It is written into an spl-record account in 800-byte chunks and cited by offset through the ZK program's fourth instruction layout — five bytes of instruction data, a discriminant and a u32.

Three things that only appeared by running it: a blockhash does not live long enough for fourteen transactions; the U256 verification does not fit the 200,000-unit compute default; and the script was sending its own rejection to /dev/null. All three are in docs/cwf-2026/THE-SWAP.md.

Why anybody wants it

Everything above is what runs. This is the market it runs into, measured rather than asserted.

The US market for this opened on 17 September 2026, when the SEC exempted tokenized-stock venues for five years. The count below was re-run three days later.

1,992 tokenized stocks from three issuers' catalogues have confidential transfers switched on. On the six whose accounts were counted, no confidential account has been approved. Every mint in the list checked rather than sampled — ./scripts/slot-scan.sh, re-run 2026-09-20:

checked  1992 tokenized-equity mints in web/mints.json
  Backed     EMPTY   828      Swiss-issued, own ISIN (xStocks)
  Backpack   EMPTY   1156     US CUSIP, a security entitlement by the issuer's own description
  PreStocks  EMPTY   8        pre-IPO companies with no public market

The list comes from each issuer's own asset API (scripts/refresh-mints.sh), so the scan is exhaustive over what these three publish and is not an issuer census of Solana. The table is written to web/slots.json and prose is checked against it — a hand-typed copy of it sat here saying 732 and 1137 and no third issuer, for weeks, without failing anything.

One issuer would be a quirk. Three of them, on every mint any of them has shipped, at the same dead end, is the shape of the problem. Four of them mint by mint, with no key and no account: ./scripts/onchain-check.sh, and docs/ONCHAIN.md for every reading behind it.

And the second half of that sentence is measured, not assumed. Configuration says the door is locked; it does not say whether anyone walked through. So count the accounts:

$ ./scripts/usage-scan.sh
  AAPLx      Backed       74045 accounts     7 over 400 bytes   1 configured   0 approved
  NVDAx      Backed      218084 accounts    30 over 400 bytes   1 configured   0 approved
  SPACEX     PreStocks    17747 accounts     6 over 400 bytes   0 configured   0 approved
  ANTHROPIC  PreStocks    78825 accounts    37 over 400 bytes   0 configured   0 approved
  AMC.US     Backpack     14624 accounts     4 over 400 bytes   0 configured   0 approved
  SPCX.US    Backpack    115419 accounts    29 over 400 bytes   0 configured   0 approved

  518744 token accounts across 6 mints, 2 configured for confidential transfers, 0 approved by an issuer

Not "few". Zero. A holder can configure a confidential account, but only the issuer's approval makes it usable, and on the six mints counted no issuer has approved one. Where we looked, nobody is using it yet.

The feature is shipped, configured, and inert. Token-2022 offers exactly one disclosure model — a single mint-wide auditor key that can decrypt the amount of every confidential transfer made while it is set, and cannot be scoped to one holder or one reader. Fill it and one party reads every holder's transfers. Leave it null and no holder can demonstrate anything to anyone. It is null on every mint in the list — why is not measured, since null is also the default — and with no confidential account approved, a fund holding NVDAx has nowhere to hold it except in the clear.

Confide is what makes that slot usable, and the trade above is the first thing it makes possible. The underlying capability is broader — disclosure scoped by recipient, by granularity and by schedule — and the last section demonstrates the other two, because a primitive with a second working use is a different claim from a trick with one. It is the last section rather than this one deliberately: one wedge, made excellent.

day      LANE A · a public wallet       LANE B · Confide
         what anyone can see            what anyone can see   the auditor
────────────────────────────────────────────────────────────────────────────
  3        42,000 NVDAx · +42,000        —                   42,000 NVDAx
 11        96,000 NVDAx · +54,000        —                   96,000 NVDAx
 ...
 58       173,000 NVDAx · +7,000         —                  173,000 NVDAx

Lane A leaked the position continuously, from day 3, mid-accumulation.
Nobody attacked anything. The chain simply published it.
 1 Oct · the LP asks

auditor reads the position    173,000 NVDAx   44 days before the public can
is the fund above its floor?  YES   floor $100M — and that is all this reveals
(the portfolio is $106M across NVDAx/TSLAx/SPYx — the LP is not told that)

14 Nov · the obligation comes due

agents 1, 2, 3 publish their shares  · the fund is not asked, and cannot object
reconstructed  ✓   commitment matches slot 340112045  ✓

LANE B is now public: 173,000 NVDAx, held by Fund A as of 30 Sep.

And that predicate is not only checkable off-chain. The same proof bytes out of the same sealed package go to Solana's live ZK ElGamal Proof Program:

$ ./scripts/devnet-verify.sh
err   : None
units : 111000
logs  :
    Program ZkE1Gama1Proof11111111111111111111111111111 invoke [1]
    VerifyBatchedRangeProofU64
    Program ZkE1Gama1Proof11111111111111111111111111111 success

Who uses this first

The issuer. Backed's and Backpack's mints have confidential transfers on, the approval gate shut and the auditor key null — why is not measured, and nobody has asked them. Confide is a disclosure model they could use, and nothing reaches a live mint without them. The issuer is the customer here, not the obstacle — Kraken included, having acquired Backed in December 2025.

The fund holding the position. A GP with NVDAx owes its LPs a quarterly report and broadcasts the position continuously instead. Stopping that is what it pays for.

The lender. The position securing a loan against tokenized stock is public today. Both halves a lender needs now run on devnet — the check, and the seizure.

Reversed 2026-09-16, and the paragraph above is kept rather than edited. The order in this section was wrong. The issuer is a gate on eligibility, not the first buyer: a business whose revenue is issuing and selling has no reason to act on a disclosure model, and none of them has been asked. The lender is first, and the evidence is no longer an argument.

Kamino's lending program names the confidential-transfer extensions on its allow-lists and requires them to be inert — constraints.rs:187, :194, :201, :131. The ordinary deposit path applies them to the depositor's own account (lending_checks.rs:186), so collateral carrying confidential value cannot get in, and what cannot get in cannot be borrowed against or liquidated. 1,992 of 1,992 tokenized-equity mints clear every other condition.

And Kamino already lends against these. 19 live reserves at LTVs from 30 % to 73 %. At the reserves' own prices that is $24.1 m of tokenized stock deposited and $85.5 m of borrowing their caps already authorise — of which $0 is reachable while a position stays confidential. SpaceX has a reserve too: SPCX.US, Active, 40 % LTV, 15,000 cap. Every position in all of them is public, and that is the only way in.

./scripts/capacity.sh computes those two figures from Kamino's own caps, LTVs and prices. Nobody has to agree to anything for the number to exist.

./scripts/kamino-verdict.sh · ./scripts/kamino-reserves.sh · ./scripts/packet.sh SPCX.US · docs/KAMINO.md · the reasoning is in docs/27-DAYS.md.

Jupiter Lend was named here as the lender example. It was never checked from chain in this repository, and the Kamino numbers above were — so it is not repeated as a claim.

Corrected again, 2026-09-20, and this one moves the product rather than the buyer. The section above is about a loan, and a loan needs a third party to hold the collateral — which is what ran into the issuer's gate, and into ImmutableOwner on the associated token account every wallet creates. A trade needs no third party, because a Solana transaction is all-or-nothing, so the swap above runs today where the loan could not.

So the first user is neither the issuer nor the lender. It is a desk moving size — every purchase settles on chain, so a position is assembled in public and the price moves against it the whole way, and selling on a book publishes the size a second time. Then securities lending, where lending your book is how you publish your book.

The lender paragraph is kept because the collateral half still runs and the $0 is still the measurement it always was. It simply waits on a venue, and the swap waits on nobody.

Traction is zero, and the sentence has no second half. No issuer approval, no pilot, no customer interview, no design partner, nobody outside this repository has used any of it. What exists is a mechanism that runs and a finding you can check in one RPC call. Everything below is the second kind of evidence, and none of it is the first.

Run it

The live page reads the mints from mainnet in your browser, pulls real wallets out of recent NVDAx transactions with the balance each published as it settled, shows the Confide account on devnet reading zero, and — on a button press — has Solana's ZK program verify the lender's proof while you watch. Source in web/.

Nothing required — no key, no account, no funding:

./scripts/kamino-verdict.sh  # can Kamino take confidential collateral — read out of its own source
./scripts/kamino-admissible.sh # the same question against all 1,992, not one
./scripts/kamino-reserves.sh  # which tokenized stocks Kamino already lends against, on what terms
./scripts/packet.sh --all     # an admission packet for every mint that has a Kamino reserve
./scripts/capacity.sh         # what is on the table in dollars, and how much a confidential holder reaches
./scripts/slot-scan.sh        # every mint in web/mints.json — 1,992, not a census of Solana
./scripts/onchain-check.sh    # four of them in detail
./scripts/bind-account.sh     # bind a disclosure to a live account, re-read to confirm
./scripts/swap-pin-check.sh   # does the pre-signing check compare what YOU agreed? no chain needed
./scripts/devnet-verify.sh    # the NAV-floor proof, checked by Solana's ZK program
./scripts/committee.sh        # the release committee as five actual processes
./scripts/demo.sh             # the two lanes, then the proof going to Solana
./scripts/deshield-proofs.sh  # the two withdraw proofs, checked by Solana's ZK program
                              #   (the instruction they feed is disabled — docs/SEIZURE.md)
./scripts/seizure-status.sh   # read the seizure back off devnet — no keys, no wallet
./scripts/seizure-proofs.sh   # the three proofs a seizure needs, checked by Solana's ZK program
./scripts/healthcheck.sh      # every live claim above; exits with the number that died
cargo test               # 72 tests
cd programs/confide-seizure && cargo test    # 44 more, over the seizure program

healthcheck.sh covers the mainnet finding on NVDAx, the devnet program, account, mirror mint and its account gate, the anchored disclosure, the keys quoted in docs/ONCHAIN.md, and the four published links. It is not a proof that every sentence here is true — the 1,992-mint premise is slot-scan.sh, and prose it does not know about can still rot. It is the set of claims worth failing loudly.

Needs the account's keys — account-keys.json, written by provision-account.sh. Reading a confidential balance and proving over it are things only the holder can do; that is the point.

./scripts/read-balance.sh <account> account-keys.json
./scripts/prove-collateral.sh <account> 100000 account-keys.json
./scripts/refresh-proofs.sh <account> 100000    # rewrite the page's proofs for a new account
./scripts/refresh-loans.sh                     # which devnet loans the page reads, and their layout

Being the borrower, from a position you already hold.

./scripts/borrow.sh <your-keypair> <your-account> <your-keys.json> \
                    <lender-elgamal-pubkey> <lender-token-account> <oracle-pubkey> \
                    [q_min] [principal_cents] [ratio_bps]

It creates no mint and configures no account: the issuer gate on autoApproveNewAccounts: false is per account and was paid when yours was opened. It prints what the handover costs you before it signs anything, builds the proofs while you still own the account, hands it over, originates, and ends with the exact lender-check line to send the other party.

It refuses an associated token account, up front, before you pay for ten proof transactions. An ATA carries ImmutableOwner and SetAuthority on one fails — so a position sitting where a wallet put it cannot be pledged this way, which is most of them. That is the gate again, and docs/cwf-2026/THE-PINCER.md says how far it reaches.

Being the lender. Until 2026-09-19 both sides of a loan were the same person — seizure-e2e.sh generates the borrower and the lender — so nothing established what the other side could confirm on their own. Now:

MODE=open ./scripts/seizure-e2e.sh             # originate and stop, leaving a loan open
./scripts/lender-check.sh <loan> <my-account> [q_min] [principal_cents] [ratio_bps]

lender-check calls the program's own predicates — floor_is_proved and context_is_armed, imported from confide-seizure and pointed at data fetched from RPC — rather than a second implementation that could disagree with the chain. It answers whether the collateral is out of the borrower's hands, whether the seizure proofs are armed under an authority they cannot close, and whether the route points at your account. It says nothing about whether the asset is worth lending against; that is docs/packets/.

It also says what it cannot establish: the floor proof contexts are not recorded in the loan, so a lender relies on the program having checked them at origination rather than re-deriving the floor themselves. The first version of the tool hid that by checking the transfer proofs and calling them the floor, which failed on a healthy loan — which is how the gap was found.

refresh-loans.sh writes web/loans.json — which accounts the page should open, not what they say. The page fetches each loan off devnet and decodes the flags in the visitor's browser, so a re-run or a devnet reset shows through instead of leaving the page asserting an outcome the chain no longer has. The record layout is copied into that file so a browser can decode without the program; docs-consistency.sh checks the copy against programs/confide-seizure/src/lib.rs.

Needs a devnet-funded keypair:

./scripts/provision-account.sh    # stand up a confidential account we hold the key to
./scripts/set-auditor.sh <mint>   # fill the auditor slot — one UpdateMint
./scripts/anchor-receipt.sh       # seal this account's position and anchor its commitment

anchor-receipt.sh needs account-keys.json as well, because what it seals is read out of the account rather than invented for the occasion.

anchor-receipt.sh writes through 6a1Kd8…AHytv and reads it back to check the stored bytes against the artifact. 147 bytes land on-chain: a hash and two dates. Deploying a program costs devnet rent proportional to its size, and the faucet refuses — see docs/DURABILITY.md for the figures and for which keypair pays.

Data the repo pins rather than fetching at runtime is refreshable: ./scripts/refresh-mints.sh (the 1,992 mints) and ./scripts/refresh-actions.sh (the corporate-action schedule). Both assert on what they must contain rather than writing whatever came back.

The invariants are written as claims you can run, not prose: crates/confide-embargo/tests/invariants.rs.

I1 unopenable before T — if fewer than k agents collude. Shares carry no clock; the assumption is stamped on the artifact (ReleaseTrustModel), not implied
I2 unstoppable at T by the holder as a party to the protocol — it is not a parameter of any function on the opening path, and in scripts/committee.sh it is a process that exited in September. A holder that captures n − k + 1 agents stops it anyway, and nothing here prevents that
I3 bound to the position of record — a post-hoc revision is refused. The commitment is over the account's own on-chain ciphertext, so the figure released at T has to open it. The only one that depends on no one's behaviour: it is a comparison, not a promise
I4 the auditor reads throughout; only public disclosure is delayed
I5 opening is irreversible — revocation is not clawback

What it does not do

Stated because a reader should find the limits here rather than discover them:

  • The committee is the trust. k = 3, n = 5 tolerates 2 early colluders and 2 withholders, and those are the same agents — choosing k trades I1 against I2 and cannot minimise both. There is no stake to slash and no cryptographic clock. A public-randomness timelock (TimeLockPuzzle in ReleaseTrustModel) is the one change that would make both unconditional; it is named, not built.

  • Lending. Seizure runs — that row is above, and docs/SEIZURE.md is how. What is still missing is everything around it: origination, interest, a liquidation engine, and an oracle anyone should trust. Confide takes collateral on a default someone else defines. The escrow is also frozen while the loan lives — the proofs bind to a ciphertext that must not move, so a borrower cannot top up or partially withdraw without unwinding and re-originating.

  • One mint, ours. The accounts here are on a mint this repo provisioned with NVDAx's confidential-transfer configuration — the auditor slot and autoApproveNewAccounts: false. It is not an NVDAx replica: the live mint also carries a permanent delegate, a transfer hook, a default-account-state, a scaled-UI-amount config, a pausable config and metadata, and none of those are here. Doing it on NVDAx needs Backed's approval, which is why they are the first customer rather than an obstacle — see Who uses this first.

    Wrapping xStocks into a mint of our own would dodge the approval and is the wrong trade twice over. A wrapped token is not the one lenders take as collateral, so the clearest use case dies on contact. And holding the backing would make us the single trusted party this layer exists to remove.

  • Custody, in the one sense that counts. Confide holds nobody's keys and never sees a balance, but the seizure escrow is a token account a program owns, and while a loan is open the borrower cannot move what is in it. The same custody every lending protocol takes, named here rather than left inside a word used elsewhere to mean something else.

  • Matching, and not only because it is hard. Settlement is done; finding the party who wants the other side is not, and it is the same two-sided problem as finding a lender. It also has a second reason under the engineering one, added 2026-09-21: bringing multiple buyers and sellers together by established, non-discretionary methods is the exchange definition at Rule 3b-16, and doing it for others is broker registration at §15(a). Not doing it is what keeps this a settlement primitive rather than a venue. And the obvious version would put back the one thing the finding removed — a party who sees both sides. See docs/SEC-EXEMPTION.md.

  • Anything settled against a pool, permanently. A pool's reserves are public and a trade moves them by exactly the traded amount, so the size is recoverable by subtracting two consecutive public states. Confidential composition works where the counterparty is a party, not a pool. This one never clears, and it is in the list beside the solvable ones on purpose.

  • A confidential flash loan. A program cannot read a confidential balance, so repayment would have to be proved inline — and the proof does not fit in the transaction. Blocked by transaction size, not by cryptography, and the distinction is the honest way to say it.

  • Not built, deliberately: no ATS, no order matching, no MEV protection, no mainnet deployment, and no claim to discharge any regulatory filing.

Why this and not MEV protection — and why not a pool, ever

Jupiter already ships Ultra / MEV Protect / JupiterZ RFQ, and they are good. They protect the transaction in flight. Confide is about the settled balance — the permanent public record of what you hold, which no relay touches. Different axis. See DESIGN.md §2.

And the sharper contrast, because it is a limit rather than a comparison. Confidentiality and pooled liquidity are mutually exclusive: a pool's reserves are public state and a trade moves them by exactly the traded amount, so the size is recoverable by subtracting two consecutive public states. An order book publishes fills; a lending reserve publishes its totals. Confidential composition works where the counterparty is a party, not a pool — which is why this is a bilateral settlement primitive and not a venue, and why it will never be one.

As of 2026-09-17 that limit is also written into US regulation. The SEC granted two five-year exemptions for tokenized NMS stock, and they cover trading executed by an AMM only — a venue relying on them must publish every fill's price, size, time and direction within ten minutes, and a Tier 1 name is capped at 0.25 % of average daily volume. So the sanctioned venue publishes the size by rule, and size cannot go there anyway. The paragraph above was this repository's own structural finding; it is now a condition of the only US venue that may legally operate. A bilateral trade between two holders is outside that relief and does not need it — it was never an exchange. Outside an exemption is not outside regulation, and docs/SEC-EXEMPTION.md says exactly what this does and does not claim.

In TradFi a manager with discretion over $100M+ of Section 13(f) securities files Form 13F 45 days after quarter end. That lag is legislated, for exactly the harm that real-time position disclosure causes. On Solana, tokenized equities did ~$5.8B of spot DEX volume in Q2 2026 (Crypto Briefing, Q2 2026) and the lag is zero.

What this is not. xStocks are not Section 13(f) securities and holding them creates no Form 13F obligation — they are issued by Backed Finance AG under Swiss law with their own Swiss ISIN (NVDAx = CH1436219195; NVDA itself = US67066G1040), and the SEC's joint statement of 28 January 2026 separates issuer-sponsored tokenization conveying true ownership from third-party products conveying a custodial entitlement. The obligation Confide serves today is contractual — the quarterly report a GP owes its LPs. 13F is the design this borrows and the requirement that arrives with instruments like the tokenized-form trading the SEC approved for Nasdaq on 2026-03-18. DESIGN.md §3a says all of this in full rather than leaving it implied.

The other half — disclosure by schedule

Everything above is one wedge: settlement. This section is the rest of the capability, and it is here rather than in the pitch on purpose — docs/cwf-2026/GTM.md makes that a decision. It appears at all for one reason: the same primitive has a second use that runs, which is a different claim from a trick with one. The three parts below are unchanged from where they used to sit higher up the page.


What a usable auditor slot is worth

Split by whether it runs, not by which repository it came from — a reader of this gets the whole stack, and the reuse declaration below is for eligibility, not for discounting what works.

Demonstrated here. Every line of this runs; the on-chain ones reach Solana.

Hold a position on-chain that reads as zero. A live devnet account: spl-token balance says 0, the confidential balance holds 173,000. Both public, both true. ./scripts/bind-account.sh — explorer
Bind a disclosure to that account, not to a string — its own ElGamal key and its own ciphertext, re-read from chain to confirm. ./scripts/bind-account.sh
Fill the auditor slot. The mirror gates new accounts exactly as NVDAx does — autoApproveNewAccounts: false — so the issuer has to sign for the confidential account before it can hold anything, and the demo does that rather than describing it. One field then separates the two mints: the key it holds cannot be scoped, and it is null on every live mint. ./scripts/set-auditor.sh — devnet
Let only chosen parties read it. The auditor reads throughout; the market never does. cargo test — I4
Prove "this account holds at least X" — over the account's own on-chain ciphertext. The counterparty learns one bit: not the value, not the composition, not any holding. Two proofs, because one does not exist: equality binds a commitment we can open to the account's ciphertext, then the range proof runs on the surplus. ./scripts/prove-collateral.sh — both accepted by Solana's live ZK ElGamal Proof Program
Bind a disclosure to a date and make it unrevisable. The commitment is over the account's own on-chain ciphertext, so the 45 days are not merely a promise: a figure restated afterwards does not open it. ./scripts/anchor-receipt.sh — 147 bytes on devnet
Open on schedule without the holder. Five separate processes; the holder exited in September. What they publish is checked against the commitment sealed that day before it is read out. ./scripts/committee.sh
Take that collateral on default. A transfer the borrower authorises at origination and cannot later refuse: the proofs are parked on chain under an authority they cannot close, and fired by a program that owns the escrow. No key is reconstructed, no committee is asked, and neither account ever shows what moved. The floor is proved on chain against the escrow's own ciphertext; the price is the loan's to establish, not the chain's — SEIZURE.md §4. ./scripts/seizure-e2e.sh — on devnet; ./scripts/seizure-status.sh reads it back
Survive a stock split. A number sealed in September is quoted in September's units. Eleven actions are queued on the live schedule: eight restate exactly, three have no whole ratio and are reported, not guessed. cargo test -p confide-equity

The same primitive, pointed elsewhere. Not built here, and not claimed as working.

  • Borrowing against stock without publishing the collateral. Kamino takes SPYx, QQQx, NVDAx and sixteen more as collateral today — verified from its own reserves, ./scripts/kamino-reserves.sh — and every position securing those loans is public. Both halves a lender needs now run on devnet: the check, and the seizure (above). What is missing is the lending itself: origination, interest, and a liquidation engine. Confide takes collateral on a default someone else defines, and is not a lending protocol.
  • Liquidation as a predicate. Is this account underwater is the same claim with the threshold moved, and the program evaluates it — from a floor it records rather than verifies and a price one named oracle asserts. Both are the loan's to get right; the chain only enforces the consequence.
  • An issuer filling the slot on the live mints. ./scripts/set-auditor.sh fills it on a mint we control — one UpdateMint, readable on devnet. On NVDAx it is Backed's call, which is the point: see What it does not do.
  • Standing grants per counterparty, revocable. The policy layer expresses it; there is no product surface on top of it here.

Details and the full mint readings: docs/ONCHAIN.md.

On devnet outliving the judging window: the finding above is on mainnet and does not reset; the account, the program and the mirrored mint are on devnet and can. ./scripts/healthcheck.sh checks every live claim, and docs/DURABILITY.md has the recovery steps and the recorded evidence. The collateral proofs are self-contained and would keep verifying after a reset wiped the account they are about — so the page compares the live ciphertext before treating a pass as meaningful, rather than showing a green that means nothing.

Two things it has to get right, and does

A split between sealing and opening. A number sealed in September is quoted in September's units, and the commitment must not move — that is the point. So restatement happens at read time, deterministically, from the issuer's published schedule. The live xStocks calendar has eleven actions queued: eight restate exactly, three have no whole-number ratio and are reported rather than guessed (fixtures, scripts/refresh-actions.sh). confide-open prints both numbers and refuses rather than rounding.

A covenant, before the position is disclosable. An LPA asks "is the fund at or above X" as well as "what do you hold". confide-equity proves that as a predicate — the LP learns one bit and no position — and the proof goes to the live ZK program.

The premise under all of it, that every auditor slot is still empty, is checked by ./scripts/slot-scan.sh against mainnet. The unit test guarding it covers the four mints this repo pins and would stay green if an issuer filled a key elsewhere; its own doc comment says so, and this sentence used to claim the opposite.

Built on

Stocklana's rules: original work. Open-source components are fine if you say so. So, said plainly:

Component Origin License Role
aperture-core psyto/aperture, pre-existing Apache-2.0 Token-2022 confidential balances, disclosure package, policy, auditor
aperture-receipts psyto/aperture, pre-existing Apache-2.0 content-blind on-chain receipt, native Solana program
Confide this repository Apache-2.0 the embargo mechanism (I1–I3), the k-of-n sharing, the equity layer, the seizure program, the demo

Where the reuse actually lands, measured 2026-09-29 rather than summarised. aperture-core is consumed by the five crates on the disclosure side — confide-onchain, confide-embargo, confide-equity, confide-committee, confide-demo — at 20 use sites. confide-ct, the crate that builds and submits the two confidential-transfer legs of the trade this page opens with, has no aperture dependency and zero use sites. So the wedge is this repository's own work end to end, and a reader can check that with cargo tree rather than take the row above on trust.

(The row above lists this repository's contribution as the embargo, the k-of-n sharing, the equity layer, the seizure program and the demo. It was written before the swap became the thing the page leads with, and confide-ct belongs on it. Left as-is here deliberately: the same table exists in STATUS.md and DESIGN.md, it is the text the founder pastes into both competition forms, and one of those fields is already flagged by docs-consistency.sh as having drifted from what was pasted. Changing three copies of a disclosure surface days before a deadline is a founder call.)

Which window, because the two events do not share one. For Stocklana, Confide is new work start to finish — the first commit is inside its window. For Crypto World's Fair the window opened 2026-09-14 06:00 PT, when 48 commits already existed, so what that contest judges is cwf-2026-baseline..HEAD and nothing before it. The boundary is a tag, recorded with the commands that establish it, in docs/WORK-WINDOW.md. Saying "in-window" without saying which window is how a true sentence becomes a false declaration.

The secret sharing is Confide's own — crates/confide-embargo/src/shamir.rs, GF(256), no dependency.

About

Private block trades for tokenized stocks: confidential delivery-versus-payment on Solana. Stock for stablecoin in one atomic transaction, neither side publishing what moved. All 1,992 such mints ship it, auditor slot empty; of 518,744 live accounts 2 have asked for one and none is approved — so the first trade is an issuance.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages