kn:ll documentation
How to commit, cross and read the toll. Sections 01–05 get you to a first fill; the rest is reference for integrators and committee operators.
01Overview
kn:ll is a dark pool on Robinhood Chain for tokenized equities and ETFs. Trading happens in discrete rounds. Within a round, participants commit sealed orders, a public reference mid is posted, sealed orders are revealed to a threshold committee, the committee computes a pro-rata cross at the mid and proves it, fills settle from escrow, and one round later the toll (fill sizes and prices) is published.
No order's side, size or band is ever public. Unfilled orders are never revealed to anyone.
02Vocabulary
| TERM | MEANING |
|---|---|
| round | One fixed-cadence matching cycle (default: every 60 s during reference-market hours). |
| commitment | Hash of (side, size, band, salt) plus escrow; the only on-chain trace of an order before it fills. |
| band | The range of reference mids at which the order is willing to fill. |
| reference mid | Public midpoint for the round from an external price source. |
| cross | Pro-rata matching of eligible buys and sells at the mid. |
| toll | Published record of fills (size, price, round), one round late. |
| committee | Threshold-key holders who compute the cross jointly. |
| nullifier | Per-round pseudonym linking a fill to a commitment only for the filled party. |
03Threat model
| ADVERSARY | CAN | CANNOT |
|---|---|---|
| chain observer | see commitments, escrow amounts, mids, proofs, tolls | read any order; link a toll to a commitment |
| single committee member | see its share of each reveal | decrypt anything alone |
| colluding quorum | read one round's revealed orders | alter fills without failing the proof; read other rounds; hide the collusion (transcript is logged) |
| kn:ll operator | what a chain observer can | anything more — no privileged key or view |
| reference source | influence the mid | see the pool; mids are bounded against a second source (§09) |
Out of scope: your own RPC seeing your address (use a relayer, §20); escrow amount leaking a size upper bound (§12).
04Quickstart
import { knll } from "@knll/sdk";
const c = await knll.commit({
asset: "TSLAx", side: "buy", size: 5000,
band: [247.90, 248.90]
}); // escrows, returns commitment + salt (kept locally)
await knll.reveal(c); // at round close; encrypted to committee
const fills = await knll.fills(c); // your fills, if any, after settlement05Install the SDK
npm install @knll/sdk
The SDK handles commitment hashing, salt storage, threshold encryption of reveals, relayer submission and fill retrieval. It targets Robinhood Chain mainnet by default; set { network: "testnet" } for the test pool.
06Rounds
Rounds have four phases with fixed durations: commit (45 s), reveal (10 s), cross (≤5 s), settle. Commitments received after the commit phase roll to the next round. Rounds run only while the reference market is open; outside hours the pool holds commitments and does not cross.
07Commitments
A commitment is H(asset, side, size, band_lo, band_hi, salt, round). Including the round prevents replay. The salt is 32 random bytes generated and stored by the SDK; losing the salt before reveal means the order cannot fill and escrow is returned at round end.
Commitments are submitted with escrow (§12). An order can be cancelled before the reveal phase by withdrawing escrow; the hash remains on-chain but is never opened.
08Bands
A band is [lo, hi] in reference-price units. The order is eligible only if the round's mid is within the band. Bands replace limit prices: you never state what you will pay, only which public mids you accept. A narrow band protects you from reference moves; a wide band fills more often.
09Reference mid
The mid is posted on-chain by an oracle kn:ll does not operate, at the start of the reveal phase. It is checked against a second independent source; if the two diverge by more than a bound (default 25 bps), the round does not cross and all escrow rests. Historical mids are queryable and included in each toll.
10The cross
Eligible buys and sells are summed. The smaller side fills fully; the larger side fills pro-rata by size. All fills occur at the mid. Remainders rest to the next round automatically unless the commitment was marked fill_or_kill. The committee outputs the fill list and a proof (§17); it never outputs the orders.
11Tolls
One round after settlement, the pool contract publishes the toll: for each fill, size and price, plus round id and mid. No commitment ids. Tolls are the only public record of volume and are complete: total toll for a round equals total escrow movement in that round.
12Escrow
To commit a buy you escrow quote (USDC) ≥ size × band_hi; to commit a sell you escrow the asset ≥ size. Escrow is visible on-chain and is therefore an upper bound on your size. Mitigations: over-escrow, commit from a pooled contract (§29), or split across rounds (§28). Shielded escrow is on the roadmap.
13Minimum round size
A round crosses only if at least k commitments (default 6) are present per asset. Below that, the pool holds and tries again next round. This limits inference from sparse rounds ("one fill, one new commitment").
14Architecture
participant ── commit + escrow ──▶ PoolContract (Robinhood Chain)
── reveal (enc) ────▶ Committee (t-of-n) ── cross + proof ──▶ PoolContract
│ verify proof
oracle ─────── mid ─────────────▶ PoolContract │ settle escrow
└ toll (r+1)
kn:ll runs the coordinator that sequences rounds and relays messages; it holds no key material.
15Threshold encryption
Reveals are encrypted to a committee public key generated by distributed key generation. Decryption requires t of n members (default 5 of 8) and happens only inside the joint cross computation. The committee key rotates on a schedule; old keys are destroyed and cannot open past rounds.
16The committee
Members are independent operators registered on-chain with a bond. Duties: participate in DKG, contribute decryption shares, compute the cross, sign the proof. Missing a round or contributing to a proof that fails verification is slashable. Every member's contribution to every round is logged on-chain, so a colluding quorum leaves a record.
17Cross proof
The committee proves that the output fills are the unique pro-rata cross of the committed orders at the posted mid, without revealing the orders. The proof is verified by the pool contract; settlement is blocked if it fails. Verification cost is constant in the number of orders.
18Pool contract
| FUNCTION | DOES |
|---|---|
commit(hash, asset, escrow) | Records a commitment for the current round. |
withdraw(hash) | Cancels before reveal; returns escrow. |
postMid(asset, mid, sig) | Oracle posts the round mid. |
settle(round, fills, proof) | Committee submits; contract verifies and moves escrow. |
toll(round) | Publishes the previous round's fills. |
19Settlement on Robinhood Chain
Settlement is a single transaction per round per asset moving escrow between filled parties atomically. Filled parties learn their fills via a per-round nullifier only they can compute. Finality follows Robinhood Chain's.
20Relayers
Commitments and reveals can be submitted through a relayer so that the gas-paying address is not yours. The SDK uses the default relayer unless told otherwise. Relayers see your commitment and IP; policy forbids logging them together, and you may run your own.
21Fees
- Commit: gas only.
- Fill: a flat bps fee on filled notional, split between committee bond rewards and the oracle.
- Unfilled: free. Resting costs nothing.
Live values via knll.fees().
22knll.commit()
knll.commit(o: {
asset: string; side: "buy"|"sell"; size: number;
band: [number, number];
fillOrKill?: boolean; // default false: remainder rests
escrowMultiple?: number; // default 1.0; >1 obscures size
relayer?: "default"|"none"|URL;
}): Promise<Commitment> // { hash, salt, round }23knll.reveal()
knll.reveal(c: Commitment): Promise<void>
// encrypts preimage to committee key; submits via relayer during reveal phase.
// The SDK auto-reveals resting orders each round unless withdrawn.24knll.withdraw()
knll.withdraw(c: Commitment): Promise<void> // before reveal phase only25knll.tolls()
knll.tolls({ asset, fromRound, toRound }): Promise<Toll[]>
// public: [{ round, mid, fills: [{size, px}] }]
knll.fills(c): Promise<Fill[]> // private to you: your fills for commitment c26Contract interface
interface IKnllPool {
function commit(bytes32 h, address asset, uint256 escrow) external;
function withdraw(bytes32 h) external;
function currentRound(address asset) external view returns (uint64, Phase);
function toll(address asset, uint64 round) external view returns (Fill[] memory);
}27Errors
| CODE | MEANING |
|---|---|
E_PHASE | Action not allowed in the current phase (e.g. withdraw during reveal). |
E_ESCROW | Escrow below size × band_hi (buy) or size (sell). |
E_SALT_LOST | Salt not found locally; order cannot reveal; escrow returns at round end. |
E_NO_CROSS | Round did not cross (min size or mid divergence); order rests. |
E_BAND | Mid outside band; order rests. |
E_PROOF | Committee proof failed verification; round voided, escrow untouched. |
28Guide: working a block across rounds
- Decide total size and a maximum per-round participation (e.g. 10% of recent toll volume).
- Commit per-round slices with
escrowMultiple≥ 2 so escrow does not reveal slice size. - Let remainders rest; widen the band gradually if fills are slow.
- Use a relayer and a fresh address per slice if you want to break timing correlation.
- Reconcile with
knll.fills()per slice; tolls will show volume but not that it was you.
29Guide: committing from a contract
A treasury or agent contract can commit directly. The contract escrows from its own balance; the salt must be generated off-chain and passed to the reveal step by an authorised keeper. Pooled contracts (many users, one escrow) also hide individual sizes behind the aggregate.
30Guide: running a committee node
- Post the bond and register a key on-chain.
- Run the committee client; it joins the next DKG epoch.
- Stay online: missed rounds are slashed proportionally.
- Never log decrypted material; the client does not persist it, and operators are audited.
31Privacy checklist
- Use a relayer.
- Over-escrow or commit via a pooled contract.
- Split large orders across rounds and addresses.
- Prefer resting to fill-or-kill; FOK on a sparse round leaks more.
- Do not reuse a commitment address across many rounds if timing correlation matters.
32FAQ
Can I set a limit price?
No. You set a band of acceptable mids. Every fill in a round is at the mid.
What if the oracle is wrong?
Mids are checked against a second source; divergent rounds do not cross. Your band also protects you.
Can kn:ll see my order?
No. kn:ll holds no key and has no view beyond the chain.
Is unfilled really never revealed?
Yes. Unfilled orders exist only inside the joint computation and are discarded when it ends.
Why should I trust the committee?
You shouldn't need to: fills are proven, collusion is logged and bounded to one round. See trusting the dark.
33Glossary
band — acceptable mid range. commit — sealed order submission. committee — threshold decryptors. cross — pro-rata match at mid. escrow — locked funds backing a commitment. mid — public reference midpoint. nullifier — private fill link. relayer — submits on your behalf. round — one matching cycle. toll — published fills.