Skip to content

README.md

English governs the contract statements on this page. Contract names, addresses and numbers are shown as they are on the chain.

KAY9 — The On-Chain Watchdog

KAY9 is built for the person about to buy a token and wondering whether they should. It answers that question with technical risk analysis of tokens on Robinhood Chain, BNB Chain and Solana: a free basic scan that runs in the visitor's own browser, and deep and forensic audits produced by three independent auditors whose two-of-three quorum signs the result on-chain. Nobody pays for an audit. Access to the deeper tiers is a lock in KAY9AccessVault — you deposit KAY9, you keep it, and you take all of it back at the end of the period — so no score is ever something anybody bought. Token creators may request an audit of their own token and get the identical engine; wallets, DEXs and launchpads read the same results straight from KAY9Registry. The website at https://kay9.io is a window, not the source of truth: if it disappears, every contract, balance, lock, auction record, access period and committed audit result survives and any developer can build another interface against the same addresses.

The watchdog runs before the token exists, and that ordering is deliberate. KAY9 discovers tokens as they launch, scans them for free without being asked, and commits the results to KAY9ScanRegistry in Merkle batches — no lock, no wallet, nobody's permission. Measured on Robinhood Chain in September 2026, that chain produces 20,000 to 50,000 token launches a day against roughly 600 that reach a real pool, so the hard part is ranking rather than finding: what people can actually buy is scanned first. $KAY9 has not launched, everything above works without it, and the conditions that must hold before it does are written down in docs/LAUNCH_READINESS.md as fourteen gates with the evidence that settles each. When it does launch it is a fixed-supply token with a fair launch and permanent liquidity.

Layout

apps/web                 Next.js website (kay9.io)
packages/contracts       Foundry: KAY9Token, KAY9TeamVesting, KAY9Genesis, KAY9LiquidityLock,
                         KAY9AuditorRegistry, KAY9Pricing, KAY9AccessVault, KAY9Registry,
                         KAY9AuditHub, KAY9ScanRegistry, scripts, tests
packages/chain           Shared TypeScript: chain definitions, addresses, ABIs, identity/pricing helpers
services/watchdog        Analysis engine, chain adapters (EVM, Solana), and token discovery
services/audit-worker    Auditor job: detect requests, analyse, sign, attest; TWAP keeper; optional
                         convenience scan endpoint
docs/                    Protocol documentation

Documents

FileContent
DESIGN.mdBrand and design system
ARCHITECTURE.mdTrust model, lifecycle, network facts, admin surface
docs/ACCESS_MODEL.mdHow the tiers are unlocked: the lock, the period, the quota, what the owner cannot do
docs/AUDITOR_NETWORK.mdThe three auditors, the two-of-three quorum, where the code runs, what it does not claim
docs/TOKENOMICS.mdSupply, allocation, vesting, liquidity, and what KAY9 is used for
docs/FAIR_LAUNCH.mdCCA launch mechanics, parameters, failure paths
docs/AUDIT_PROTOCOL.mdRequest, access, quota, attestation, quorum, dispute, result format, flags, scoring
docs/WATCHDOG.mdOff-chain engine, adapters, what each tier can compute, the automatic scan loop, what it costs to run
docs/TOKEN_DISCOVERY.mdHow tokens are found: the sources, the measurements, why ranking is the problem
docs/SCORE_CALIBRATION.mdThe engine pointed at real tokens: what it got wrong and what changed
docs/KAY9_INTEGRATION_STANDARD.mdHow a wallet, DEX or explorer reads KAY9 risk data without asking KAY9
docs/LAUNCH_READINESS.mdThe fourteen gates on launching $KAY9, and the evidence each needs
docs/CONTRACTS.mdEvery contract, permissions, what can change
docs/CONTRACT_INTERFACES.mdBinding ABI spec
docs/SECURITY.mdThreat model, invariants, test matrix, static analysis
docs/DEPLOYMENT.mdTestnet rehearsal, mainnet procedure, launch report template
docs/RESEARCH.mdVerified network and Uniswap facts with the commands used
docs/ROADMAP.mdPhased plan relative to TGE, and what is deliberately not planned
docs/STATUS.mdWhat is built, what is being rewritten, what is not finished

Quick start

Prerequisites: Node ≥ 22, npm ≥ 10, Foundry (curl -L https://foundry.paradigm.xyz | bash && foundryup), Python 3 with slither-analyzer for static analysis.

# contracts
cd packages/contracts
forge build
forge test
ROBINHOOD_RPC_URL=https://rpc.mainnet.chain.robinhood.com forge test --match-path 'test/fork/*'   # fork tests

# workspace (chain package, services, web)
npm install
npm run build
npm test

# website
cp .env.example .env            # fill NEXT_PUBLIC_* values
npm run dev:web                 # http://localhost:3000

# an auditor, locally
cp .env.example services/audit-worker/.env
npm run dev:worker

Network

MainnetTestnet
Chain ID466346630
RPChttps://rpc.mainnet.chain.robinhood.comhttps://rpc.testnet.chain.robinhood.com
Explorerhttps://robinhoodchain.blockscout.comhttps://explorer.testnet.chain.robinhood.com
GasETHETH (faucet: https://faucet.testnet.chain.robinhood.com)

Contract addresses are recorded in packages/chain/deployments/<chainId>.json after deployment and rendered on kay9.io/contracts and kay9.io/transparency.

Hosting

The website is a static export: next build writes a folder of HTML, CSS, JS and images and there is no server to run. That matches the project's premise, since the site only reads the chain from the browser, and it means the whole bundle can be mirrored anywhere, including pinned to IPFS, if kay9.io ever goes away.

It is deployed to Azure Static Web Apps (free tier, commercial use permitted) from .github/workflows/deploy.yml on every push to main. Pull requests get their own preview environment, torn down when the pull request closes. DNS lives in the Azure DNS zone kay9.io.

PieceWhere
Static Web Appkay9-web in resource group Kay9SEA
Default hostnamemango-field-0e854c400.5.azurestaticapps.net
DNS zonekay9.io in resource group kay9sea
Apex recordAzure DNS alias A record at @, target resource kay9-web
www recordCNAME www to mango-field-0e854c400.5.azurestaticapps.net
Custom domainskay9.io (TXT-token validated) and www.kay9.io (CNAME validated), both registered on the Static Web App
Deploy credentialrepository secret AZURE_STATIC_WEB_APPS_API_TOKEN
Build outputapps/web/out

The apex is an alias record rather than a plain A, because the Static Web App sits behind Traffic Manager on an address that is not stable; an alias tracks the resource instead of pinning an IP. The custom domain must also be registered on the Static Web App itself, not only in DNS — DNS alone gets the request to Azure, and Azure then answers 404 until it knows which app the hostname belongs to.

www.kay9.io is a plain CNAME rather than an alias, because only the apex needs one. After binding a hostname, Azure issues its managed certificate in the background and serves the platform wildcard in the meantime, so a certificate whose subject is not the hostname means the issue is still in flight rather than broken. Check with openssl s_client -servername www.kay9.io -connect www.kay9.io:443 and read the subject.

# Verify the wiring end to end
az staticwebapp hostname show -n kay9-web -g Kay9SEA --hostname kay9.io --query status       # expect: Ready
az staticwebapp hostname show -n kay9-web -g Kay9SEA --hostname www.kay9.io --query status   # expect: Ready
az network dns record-set a show -g kay9sea -z kay9.io -n '@' --query targetResource.id      # expect: .../staticSites/kay9-web
curl -sI https://kay9.io | head -1                                                           # expect: HTTP/2 200
curl -sI https://www.kay9.io | head -1                                                       # expect: HTTP/2 200

Until 2026-09-07 the apex A record still pointed at 76.76.21.21, a Vercel anycast address left over from the previous host, and the domain had never been attached to the Static Web App at all. The site was reachable only because the old Vercel deployment was still answering; deleting that project took kay9.io down even though Azure had been building and serving the correct site the whole time. If the domain ever 404s with a Microsoft Azure Web App - Error 404 page, the custom domain registration is missing; a Vercel DEPLOYMENT_NOT_FOUND page means the apex record has been pointed back at the old IP.

Two things make the export work and are easy to break:

  • apps/web has a prebuild script that builds the @kay9/chain workspace package, whose dist is generated rather than committed. Without it a fresh clone cannot resolve the site's imports.
  • postbuild generates out/staticwebapp.config.json, which gives every exported page an explicit rewrite. Next writes flat files (en/token.html), while Static Web Apps expects directory-style paths, so without those rewrites /en/token answers with a redirect. The config is derived from the export, so adding a page needs no change. It also maps /<locale>/audit/<id> and /<locale>/registry/<chain>/<asset> onto single pages per locale that read the path in the browser, because both carry unbounded values and cannot be prerendered, and it redirects / and the old unprefixed paths to English.

Azure rejects that file above 20 KB, and thirteen locales put it at 19.3 KB, so the generator prints the size and fails the build if it goes over. If you add a page and the build stops there, the fix is to fold routes into a wildcard rather than to raise a limit you do not control.

  • postbuild also runs prune-font-css.mjs, which removes the stylesheet links a locale cannot use. Every font family has to be declared in one place — next/font only accepts a call at module scope — so without this every page links the @font-face rules of all ten families, most of the weight being the unicode-range blocks of the three CJK faces.

Run the site exactly as deployed, rewrites included, with npm run start -w apps/web, which serves out through Azure's own emulator. Do not rebuild while it is running; Next serves content-hashed assets tied to the build it started with.

Search engines are blocked until NEXT_PUBLIC_ALLOW_INDEXING is exactly true, and only on the production deployment. Set it when the product — the live feed, token and report pages — is genuinely ready for a search visitor to land on, not on a fixed date relative to the token launch; see docs/ROADMAP.md §2 for why those two are deliberately not tied together.

Production launch

Mainnet deployment is never automatic. The owner supplies the production wallets (owner Safe, team beneficiary, creator-fee recipient, auditor keys), confirms the jurisdiction they operate from and obtains professional review before launch, reviews the final launch report produced by the deployment scripts (docs/DEPLOYMENT.md), and signs the deployment and launch transactions. No private keys are stored in this repository; see .env.example.

License

MIT for KAY9 contracts and code. Uniswap Liquidity Launcher, Continuous Clearing Auction and v4 contracts are Uniswap Labs' and are used as deployed on Robinhood Chain.