+×+
Skip to content

Styx Protocol · Waitlist

One address, and one link that deletes it.

Your email is used for one thing only: telling you when your access opens. Every email has an unsubscribe link.

Double opt-in, plus one daily maintenance pass. Five steps, and each one is a file you can open.

  • 01

    The record is written before the email leaves.

    Your address is stored first, then the confirmation email is sent. A failed send is counted rather than swallowed, and the signup survives it, so submitting again gets you a fresh link instead of a duplicate row. Those resends are capped at five per address, and at one every ten minutes.

    app/api/waitlist/route.ts · MAX_RESENDS = 5

  • 02

    Clicking the link confirms it.

    The link lands on the confirmation page, and clicking it twice is harmless. Only the newest link works: every resend and the reminder rotate the token, so a link that has been replaced lands on the expired page instead, which tells you to ask for a new one.

    app/api/waitlist/confirm/route.ts · /waitlist/confirmed · /waitlist/invalid

  • 03

    One reminder, and only one.

    If you never click, a daily job sends a single reminder once the signup has been pending for 24 hours, and never to a signup older than seven days. The record is stamped when it goes out, which is what makes a second one impossible.

    app/api/waitlist/remind/route.ts · cron 0 10 * * *

  • 04

    Unsubscribe deletes the record.

    Every email carries an unsubscribe link. It deletes the address, its token index and the mailing entry, then lands on the removed page. No ghost record is left behind and there is no suppression list, so the same address can sign up again later. The aggregate daily counters are not decremented.

    app/api/waitlist/unsubscribe/route.ts · /waitlist/removed

  • 05

    An address that never confirms is erased.

    The same daily job hard-deletes pending signups after 30 days. Not archived, not moved to a colder store. Deleted.

    app/api/waitlist/remind/route.ts · PURGE_DAYS = 30

One address, plus the little context a signup needs. The panel below is the whole record, with the field names the type declares and the values the code accepts. There is no analytics identifier in it, no browser fingerprint and no referrer chain.

WaitlistRecord · lib/waitlist/store.ts

Twelve fields, and one of them is only a hash.

emailyour address, lowercased
statuspending · confirmed
tokenHashsha256(token)
interestmobile · extension · sdk
localeen · fr
sourcewaitlist-page · ?src=
countryISO 3166-1 alpha-2
timestampscreatedAt · lastSentAt · confirmedAt
remindedAtthe stamp that caps the reminder at one
resendCounthow many extra emails have gone out
iphashed hourly, never in the record

The token is stored as a hash. Only the SHA-256 of your confirmation token is kept, so a dump of the store cannot be replayed into working confirm or unsubscribe links. The raw token exists in one place, the email we sent you.

The country is coarse, and the IP is not kept. The two-letter code comes from the edge header Vercel attaches to the request. Your IP is hashed with a server secret to enforce a cap of twenty signups an hour, and that hash expires with the hour. It never enters the record.

The locale is not decoration. It decides which language your confirmation email is written in, English or French. That is the only reason the form posts it at all.

The privacy page covers the rest of the site.

Proof system

Hash-based STARK

Poseidon and Merkle trees only. No elliptic curve anywhere in the proof.

Key encapsulation

X25519 + ML-KEM-768

Hybrid stealth addresses. The lattice half follows FIPS 203.

Status

Devnet

Deployed and running there. There is no mainnet deployment.

Audits

None yet

Said on every page, and until it changes.

Transaction signatures are Ed25519 and stay Ed25519: Solana verifies nothing else, so no protocol on this chain can offer a fully post-quantum transaction today. The post-quantum work sits where it can, in the proofs and in the stealth addresses.

Picking an interest tags the record, it does not reserve a build. Extension beta downloads are paused, and a full unshield cannot finish on a phone today: the installed build carries a prover older than the deployed verifier.

Both are on the roadmap, and neither is on a date.

Read this before you sign up

Styx is devnet software and has not been audited. There is no mainnet deployment. The shielded pool does not yet hide the link between a deposit and the withdrawal that follows it: the withdrawal republishes the deposit commitment, so anyone reading the chain can pair the two. The spend circuit that closes it is in development. Joining this list is joining a project mid-repair, not a finished product.