Experimental only. Not a product. Testnet-10 only. tKAS is worthless testnet coin.
Do not use wallet integrations on this GitHub. DISCLAIMER.md
KNS (Kaspa Name Service) .kas domain inscriptions, tested on Kaspa Testnet-10 (TN10). What, why, how, and a running log.
Experimental. Not advice. Not Kaspa core. Not official KNS. Not mainnet. Keys never in this repo.
Log: UPDATES.md. Older lab repo (19–23 Sep, first 750 names): STP-KAS/kns-kasware-tn10-test.
KNS names are inscriptions. A domain create is a commit–reveal pair on Kaspa L1:
- Envelope:
<xonly_pubkey> OP_CHECKSIG OP_FALSE OP_IF <kns> <0> <payload> OP_ENDIFin a P2SH (docs/kns-spec/PROTOCOL.md). - Payload:
{"op":"create","p":"domain","v":"<label>"}(label without.kas). - Commit locks 1 tKAS in the P2SH. Reveal spends it; output 0 pays the KNS fee to the TN10 sink
kaspatest:qq9h47etjv6x8jgcla0ecnp8mgrkfxm70ch3k60es5a50ypsf4h6sak3g0lru. - Fee by grapheme length: 1–2 → 4200, 3 → 2100, 4 → 525, 5+ → 35 tKAS. Text inscription → 1.
- Uniqueness is the KNS indexer, first valid reveal wins. A losing reveal still pays.
What was tested on TN10 (all scripted, no wallet UI):
| Run | Names | Payer | Scripts |
|---|---|---|---|
| Smoke | stp-smoke-1789839537.kas |
one funded test address | kns-create-dryrun.mjs, kns-smoke-create.mjs |
| Bulk | stp-bulk-0001 … stp-bulk-3000 (target) |
same single address, paced | kns-bulk-create.mjs, kns-bulk-chain-resume.sh |
| Snapshot Phase A | stp-snap-w###-d###, wallets 0–699, up to 100 names each |
many distinct derived addresses | kns-snap-smoke.mjs, kns-snap-phase-a.mjs, kns-snap-pool.mjs, phase-a-*.sh |
| S3 | stp-s3-w#####-d#, wallets 700–20699, 3 or 2 names each (50,000 target) |
one name per child process | kns-snap-s3.mjs, kns-s3-create.mjs, s3-supervisor.mjs |
| R1 | one random name, length 3–10, per wallet 20700–25699 (5,000 target) | includes 3- and 4-char fee tiers | gen-r1-names.mjs, kns-snap-r1.mjs, r1-supervisor.sh |
| Storm / Blueprint / Funded (1–2 Oct) | random 5–10 char creates until funds exhaust | snapshot leftovers, then fresh wallet sets | kns-storm-runner.mjs, kns-storm-start.sh, kns-storm-stop.sh, kns-storm-funds-inventory.mjs |
| Trickle transfers (2–3 Oct) | move existing funded names between the 100 funded wallets | funded-2026-10-02 dust; transfer op only | kns-trickle.mjs, kns-trickle-start.sh, kns-trickle-watchdog.py |
APIs used:
- KNS indexer TN10:
https://api.knsdomains.org/tn10/api/v1(POST /domains/check,GET /{domain}/owner,GET /assets,GET /primary-name/{owner}). OpenAPI 0.1.4 extracted fromhttps://apidoc.knsdomains.org/tn10/: api/openapi-tn10.json. - Balances/UTXOs:
https://api-tn10.kaspa.org/addresses/<addr>/balance. - Signing and submit:
kaspa-wasm32-sdkv2.0.1 (Node) over the public TN10 Resolver wRPC. npmkaspa-wasm@0.13.0ScriptBuilderhit a null-pointer on this box, so it is not used for the envelope.
From the run notes, not a mission statement:
- Conformance. Check that a script built only from kns-spec (
PROTOCOL.md,CONFORMANCE.md) and the KNS docs produces creates the official TN10 indexer accepts: fee output 0, grapheme pricing,domains/checkbefore every create. - Wallet behaviour. The KasWare path (
buildScript→submitCommitReveal) was the intended reference. On the box, KasWare was not injected, so the wallet UI stayed unverified and the scripted path was used (docs/KASWARE-CREATE-TN10.md). - Load and bulk behaviour. Pace thousands of creates from one payer and from many payers, and see where the public node, the indexer and the create code break.
- Snapshot testing. Thousands of distinct holder addresses with names. The snapshot
addresses.csv(and a holders-with-names join) is shared with the KNS team in the kns-spec repo: STP-KAS/kns-spec/snapshot-tn10. - Find bugs before mainnet. Several were found (see Results). Smoke first, then scale: "Do not scale until smoke green" (SMOKE-PLAN.md).
Official @knsdomain posts (post 1, post 2):
We just successfully tested .kas registration on Covenant TN10 today~
KNS Covenant UI/UX Redesign, around 80% completed. A teaser will come out soon!
Airdrop/ Claim mechanism WIP
Kaspire Wallet on TN10/ MN soon
— @knsdomain
KNS is moving .kas registration onto covenants on Testnet-10, with a redesigned UI, a claim/airdrop mechanism, and the Kaspire wallet coming to TN10 and mainnet. Independent testing on TN10 now helps catch problems before mainnet. The runs here use the current inscription path, not the covenant path.
What to copy from this lab, and what to take from DOTK 2.0 instead of copying .k: FOR-KNS.md.
Nothing here is needed to use KNS. It is how this desk ran the tests. Scripts assume the box layout /workspace/artifacts/kns-tn10/ (scripts/, api/, snapshot-wallets/, npm-kaspa/, wasm-sdk/). Adjust paths if you copy them.
- Node 20 (tested v20.19.2),
websocketnpm package (innpm-kaspa/),kaspa-wasm32-sdk-v2.0.1unzipped towasm-sdk/kaspa-wasm32-sdk/. - A TN10 node is optional. The box runs local TN10 kaspad + miners, but they run without
--utxoindex, so creates use the public Resolver wRPC andapi-tn10.kaspa.org. - A TN10 (
kaspatest:) Schnorr address. KNS does not support ECDSA addresses.
Published scripts contain no keys. Secret paths were replaced by env vars:
| Env var | Used by | Holds |
|---|---|---|
BACKUP_PRIVKEY_FILE |
kns-smoke-create.mjs, kns-snap-create.mjs, kns-s3-create.mjs |
path to a file with one TN10 hex key. Required, no default |
KNS_TN10_SNAPSHOT_SECRETS_DIR |
gen-snapshot-wallets.mjs, kns-snap-*.mjs |
dir for the snapshot mnemonic + per-index key JSONL (chmod 700, outside any repo) |
KNS_TN10_TREASURY_KEY |
treasury-fund-desk/s3/r1.mjs |
treasury hex key or mnemonic |
KNS_TN10_TREASURY_MNEMONIC_FILE |
treasury-fund-snapshot.mjs |
path to treasury mnemonic file |
FAUCET_API |
faucet-fund-snapshot.mjs |
faucet API origin (see window.FAUCET_API on the faucet page) |
Never paste keys in chat, logs or commits. .gitignore blocks the usual key and wallet files.
- Faucet: sixpack.wtf/faucet.html. JSON API, 30,000 tKAS drip, cap 30,000 tKAS per IP and per address per 24 h (docs/runs/FAUCET-FINDINGS.md).
faucet-fund-snapshot.mjsclaims for a range of snapshot addresses. faucet-tn10.kaspanet.ioreturned a Cloudflare challenge (HTTP 403) from the box.- Large runs were funded from a treasury address with
treasury-fund-*.mjs(batched outputs, balance re-checks, floor, dry-run flag). - Hold about 1.05× the fee per name. Measured network cost is about 0.035 tKAS per name on top of the KNS fee.
Follow SMOKE-PLAN.md:
curl -sS "https://api-tn10.kaspa.org/addresses/<PAYER>/balance"
curl -sS -X POST https://api.knsdomains.org/tn10/api/v1/domains/check \
-H 'content-type: application/json' \
-d '{"domainNames":["stp-smoke-XXXX.kas"],"address":"<PAYER>"}'
node scripts/kns-create-dryrun.mjs --label stp-smoke-XXXX --payer <PAYER> # dry run, no signing
BACKUP_PRIVKEY_FILE=/path/outside/repo/key.hex \
node scripts/kns-smoke-create.mjs --label stp-smoke-XXXX --broadcast 0 # plan only
# --broadcast 1 submits commit + reveal (TN10 only)
curl -sS https://api.knsdomains.org/tn10/api/v1/stp-smoke-XXXX.kas/ownerEach create writes api/smoke-result-<label>.json (domain, payer, commit/reveal tx ids, inscription id <revealId>i0, fee, time).
node scripts/kns-bulk-create.mjs --from 1 --to 10 --delay-ms 12000 --retries 3 --broadcast 1
scripts/kns-bulk-chain-resume.sh 751 3000 250 12000 # batches of 250, no idle gapsnode scripts/gen-snapshot-wallets.mjs --count 200 --secrets "$KNS_TN10_SNAPSHOT_SECRETS_DIR" # BIP44 m/44'/111111'/0'/0/i
node scripts/kns-snap-smoke.mjs --wallet 0 --domain-from 0 --domain-to 1 --broadcast 0
node scripts/kns-snap-pool.mjs --wallet-from 7 --wallet-to 249 --lanes 10 --domain-from 0 --domain-to 99 --delay-ms 12000 --broadcast 1 --retries 3
node scripts/s3-supervisor.mjs # S3 workers over 500-wallet ranges
node scripts/gen-r1-names.mjs && scripts/r1-supervisor.sh # R1Run notes: Phase A, S3, R1. Stop files (s3-STOP, r1-STOP) stop new work between names, never mid commit/reveal.
node scripts/phase-a-monitor.mjs --window-min 5,scripts/s3-progress.sh,scripts/r1-progress.sh(read-only, no secrets).node scripts/rebuild-inscriptions-digest.mjsrebuilds the digest fromapi/smoke-result-*.json.python3 scripts/export-results-csv.pywrites results/inscriptions.csv (public fields only; refuses files with unexpected fields).
Leftover snapshot-wallet tKAS only (treasury address hard-blocked). Default --owner-mode payer (proven 26 Sep). Broadcast needs ./kns-storm-start.sh GO (KNS_STORM_GO=1). Offline: node scripts/kns-storm-runner.mjs --dry-run N. Notes: docs/runs/STORM-2026-10-01.md, FUNDED-2026-10-02.md.
Moves already-created funded names between the 100 funded wallets (transfer op; no protocol fee). Broadcast needs KNS_TRICKLE_GO=1 via scripts/kns-trickle-start.sh. Notes: docs/runs/TRICKLE-2026-10-02.md.
Counts below come from results/inscriptions.csv, exported from the box's api/smoke-result-*.json at 3 Oct 2026 ~20:20 CEST (unchanged since 2 Oct ~20:16). Each row has a commit tx id and a reveal tx id recorded by the create script. Newest create in the export: eukjsfzxl.kas at 12:52:59 CEST 2 Oct (run=funded-2026-10-02).
| Run | Creates with reveal tx | Notes |
|---|---|---|
| Smoke | 1 | stp-smoke-1789839537.kas, 19 Sep ~19:45 CEST, indexer owner matched |
| Bulk | 1,518 | stp-bulk-0001–1518, no gaps. Target 3,000. Source: CSV run=bulk |
| Snapshot Phase A | 69,856 | across 699 wallets; 698 wallets have all 100. Source: CSV run=snapshot-phase-a; phase-a-status-pool-7-699.json |
| S3 | 50,000 | across 20,000 wallets; target hit. Source: CSV run=s3; s3-status-pool-700-20699.json |
| R1 | 3,211 | 3,211 of 5,000 wallets funded (desk-fund-r1-status.json; r1-done/ 3,211). Source: CSV run=r1 |
| Storm (1 Oct) | 9,509 | Snapshot leftover funds, payer-mode, ramped to 3,600/min, funds_exhausted. Source: CSV run=storm-2026-10-01; storm-2026-10-01/final-summary.json (names_ok_this_run 9509). Notes: docs/runs/STORM-2026-10-01.md |
| Blueprint | 8,258 | Fresh 1,000-wallet set after storm sweep. Source: CSV run=blueprint-2026-10-01; blueprint-2026-10-01/final-summary.json. BLUEPRINT-2026-10-01.md |
| Blueprint2 | 757 | Fresh 100-wallet set; --sweep-smalls 6. Source: CSV run=blueprint2-2026-10-01; blueprint2-2026-10-01/final-summary.json |
| Dust | 58 | Blueprint2 dust consolidated to 6 wallets (2 Oct morning). Source: CSV run=dust-2026-10-02; dust-2026-10-02/final-summary.json |
| Funded (2 Oct) | 11,400 | Fresh 100-wallet set + fan-out; 180/min until exhausted. Source: CSV run=funded-2026-10-02; funded-2026-10-02/final-summary.json. FUNDED-2026-10-02.md |
| Total | 154,568 |
Transfer stress (not creates): overnight trickle 2 Oct 21:58 – 3 Oct 01:06 CEST moved 26,230 domains (11,134 unique) among the funded-2026-10-02 wallets; exit storm_stop_file. Sources: trickle-2026-10-02/summary.json, transfers.jsonl. Notes: docs/runs/TRICKLE-2026-10-02.md.
Indexer / ownership: 23 Sep, stp-bulk-0001–0750 all returned an owner (750/750, older repo). After the 26 Sep stress window, a read-only ownership verify over the 79,764 names created that day (ownership_verify_storm_2026_09_26.py) reported owned_expected 79,764 / missing 0 / owned_other 0 (ownership-verify-summary-2026-09-26.json; /owner was tip-lag blocked so /assets was used). After the 1–2 Oct storm/blueprint runs, read-only /assets verify reported 9,509 + 8,258 + 757 expected / 0 missing / 0 wrong (_ownership_verify_2026-10-01/combined-report.json). Funded/dust journals report owner_eq_payer_all true (no separate indexer pass recorded for those two).
Findings (docs/FINDINGS-DRAFT.md, run notes):
POST /domains/checkneeds bothdomainNamesandaddress. It has no price field; onlyavailableandisReservedDomain.- npm
kaspa-wasm@0.13.0ScriptBuildernull-pointers onaddData/addOpin Node here.kaspa-wasm32-sdkv2.0.1 works. - KasWare extension not installed in the box browser:
tn10.knsdomains.orgsaid "Kasware not found". Wallet UI path unverified. - kns-spec KasWare HTML examples hardcode mainnet fee address and network string; TN10 needs substitution.
- Bulk 51–150 first pass: 51/100 ok. Race failures (no artifact, indexer 404). Fixed with per-attempt logs, artifact-aware completion and up to 3 retries; gaps backfilled. 151–350: 141/200 first pass, 200/200 after backfill. 351–550: 200/200 after backfill.
- The first bulk wrapper printed
ok: 0, fail: 10while all 10 creates succeeded (it parsed the last line of pretty-printed JSON). - Retrying against a lagging public node caused "already spent" reveals and stranded commits.
kns-s3-create.mjsreuses a stranded P2SH commit and builds the reveal from the commit's own change output on the same RPC node. - The TN10 indexer is more lenient than the kns-spec label regex (accepts leading/trailing hyphens). R1 uses the stricter set.
- Faucet caps (30,000 tKAS / IP / 24 h) gate large runs; the box also hit the OOM killer, so workers pause on low memory.
- Testnet-10 only. No mainnet transactions. tKAS is worthless.
- No private keys, seeds, mnemonics, xprv, wallet files, key CSVs,
.envor tokens in this repo. Scripts read keys from env vars at runtime and never print them. - 64-hex strings in this repo are transaction ids (commit/reveal) or inscription ids, labelled as such.
kaspatest:addresses shown are public.- Scripts with
--broadcast 1spend tKAS. Default is plan-only where supported.
- KNS TN10 site: https://tn10.knsdomains.org/
- KNS TN10 indexer: https://api.knsdomains.org/tn10 · API docs: https://apidoc.knsdomains.org/tn10/
- KNS docs: https://kns-2.gitbook.io/kns-docs-1/
- For KNS, inscription lab vs DOTK 2.0: FOR-KNS.md
- Mix sketch this lab was read against: STP-KAS/kns-dotk
- Protocol reference: STP-KAS/kns-spec (copies in docs/kns-spec/)
- Snapshot holder set for the KNS team: kns-spec/snapshot-tn10
- How we recommend testing a snapshot with it: kns-spec/snapshot-tn10/TESTING-SNAPSHOT.md
- Older lab: STP-KAS/kns-kasware-tn10-test
- Front door: STP-KAS/kaspa-dapps · pins: STP-KAS/kaspa-master-file
- TN10 faucet: https://sixpack.wtf/faucet.html
X: https://x.com/StppStp · GitHub: https://github.com/STP-KAS