Arkognito is a client SDK plus three small open-source services. All shared state lives on Arkiv:
relayer discovery, issuer keys and the spent-token list are Arkiv entities, so there is no database,
no central operator and nothing that only one company can run.
Experimental, testnet only (Arkiv Tiramisu). The protocol is version 0.x and has not had an
outside audit.
On this page
System overview
Keys
- The wallet signs one EIP-712 message per app (
"arkognito key v1", app, chain id), twice to check
it is deterministic.
- HKDF derives a root key, which never leaves the key worker.
- Each record gets a fresh random 15-byte id; its one-time key and owner
S derive from the root
and the id. No counters: nothing is reused after expiry, devices never collide.
- Each record carries an encrypted tag naming its id. Only the root opens it.
- One-time keys sign only envelopes and ownership proofs.
One-time owners
Write path
- Check.
check() flags identifying attributes; the rarity check compares against the app’s
records; strict turns warnings into refusals.
- Seal. The SDK takes a fresh key and tag, optionally encrypts the payload, and builds the
envelope: signed by
S, padded to a size bucket, lifetime rounded to
a bucket.
- Wait and submit. A random 0–20 s delay, one write in flight per user (across tabs), a
rate-limit token if required, optionally through OHTTP.
- Relayer validates the request (padding, buckets, lowercase attribute names, signature) and
redeems the token against the shared spent list.
- Batch. When
k records are queued or the max wait expires, and at least 5 blocks after the
last batch, the relayer shuffles the batch and sends one executeBatch: creates, spent markers
(shuffled separately), and an ownership transfer of each record to its S.
- Verify. The client reads the whole batch back and checks the signature and owner. A
mismatch marks the relayer bad and retries elsewhere.
Read path
- List the app pinned to one block: keys, owners, attributes, no payloads. Every user downloads
the same list.
- Open tags locally. Tags that open are yours; each names a key whose address must equal the
record’s owner.
- Fetch whole batches that hold your records, plus two random cover batches, and verify.
The RPC provider never sees a query that names your record or address.
Finding your records
Rate-limit tokens
- Issuance at session start: blinded messages, a wallet signature, a per-wallet (or per
attestation code) daily quota.
- Redemption per write: the relayer verifies the unblinded token against the day’s key from
Arkiv and writes an
arkognito.spent marker in the same transaction.
- Key consistency: one key per app per day; two on Arkiv and everyone refuses the issuer.
- Timing: tokens fetched at session start, oldest first, at least 60 s old when spent.
- Double spend: checked at redemption and before writing; a monitor reports any id recorded twice.
Blind tokens
Oblivious HTTP
- The client encrypts each relayer request to the relayer’s gateway key (HPKE, RFC 9458 §4) and sends
it to an OHTTP relay run by someone else.
- Gateway keys come from heartbeats on Arkiv. For a URL several heartbeats claim, the client accepts
only the key whose decrypted answer names that heartbeat’s creator.
- The relay forwards only to https relayers on public hosts that answer
/v1/info with the heartbeat
creator’s address and key, and follows no redirects.
Hide your IP
Discovery
- Each relayer keeps an
arkognito.relayer heartbeat entity (150 blocks, renewed every 2 minutes)
with its URL, batch size, token requirement and OHTTP key. A dead relayer drops out on its own.
- A relayer’s address is the heartbeat’s
$creator; nothing else in the heartbeat is trusted alone.
- On restart a relayer patches its heartbeat with its current settings.
Failure handling
Deployment
One container image serves every role (ROLE=relayer or ROLE=ohttp-relay). The reference stack
is two relayers (one also runs the issuer, with a volume for its quota file) and an OHTTP relay,
behind HTTPS. It runs with Docker Compose, on Railway or Fly, or as plain Node processes.
Self-hosting
Delivery boundary
Built and tested on Tiramisu: the SDK (browser and Node), relayer, token issuer, OHTTP relay,
Docker Compose stack, unit, browser and on-chain test suites, and the linkage experiment.
Not yet: an outside security audit; mainnet; public hosted relayers; smart-contract wallets;
updating or deleting records from one-time owners (they hold no gas); sharing encrypted records with
other people; an index service for very large apps.