Developer Guide
Running the ZNS Server
Mock mode (development):
cd zns && cargo run -p zns-api
Mock mode with escrow:
cd zns && ZNS_ESCROW_SEED=deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef cargo run -p zns-api
Testnet mode:
cd zns && ZNS_CHAIN=testnet ZNS_ESCROW_SEED=<your-seed-hex> cargo run --release -p zns-api
API is on http://localhost:3000. Debug endpoints (/debug/*) are mock mode only.
zns-wallet CLI Tool
cargo run -p zns-wallet -- generate # New wallet
cargo run -p zns-wallet -- balance <t-addr> # Check balance
cargo run -p zns-wallet -- registrar # Show registrar address
cargo run -p zns-wallet -- generate-identity # Generate Ed25519 keypair
cargo run -p zns-wallet -- build-register <sk> <name> <addr> # Signed REGISTER memo
cargo run -p zns-wallet -- sign <secret-key> <message> # Sign for API requests
cargo run -p zns-wallet -- build-buy <pub> <name> <addr> <price> # BUY memo for escrow
cargo run -p zns-wallet -- derive-escrow <seed-hex> # Show escrow address
Quick Registration Test (Mock Mode)
# 1. Generate identity
cargo run -p zns-wallet -- generate-identity # save pubkey + secret key
# 2. Build REGISTER memo
cargo run -p zns-wallet -- build-register <secret-key> <name> <address>
# 3. Submit via debug endpoint
curl -X POST localhost:3000/debug/submit_memo \
-H 'Content-Type: application/json' \
-d '{"memo":"ZNS:v1:REGISTER:myname:u1addr:<pubkey>:<sig>","sender_address":"shielded","value_zat":1000000}'
curl -X POST localhost:3000/debug/mine_blocks \
-H 'Content-Type: application/json' -d '{"count":1}'
# 4. Verify
curl localhost:3000/v1/resolve/myname
Signed API Usage
Message Formats
UPDATE: UPDATE:{name}:{new_address}:{nonce}
TRANSFER: TRANSFER:{name}:{new_owner_pubkey}:{nonce}
LIST: LIST:{name}:{price_zat}:{seller_address}:{nonce}
DELIST: DELIST:{name}:{nonce}
CONFIRM_SALE: CONFIRM_SALE:{name}:{buyer_pubkey}:{buyer_address}:{nonce}
Examples
# Update address
cargo run -p zns-wallet -- sign $SK "UPDATE:myname:u1newaddr:1"
curl -X POST localhost:3000/v1/names/myname/update \
-H 'Content-Type: application/json' \
-d '{"new_address":"u1newaddr","pubkey":"<pk>","nonce":1,"signature":"<sig>"}'
# Transfer ownership
cargo run -p zns-wallet -- sign $SK "TRANSFER:myname:<new-pubkey>:2"
curl -X POST localhost:3000/v1/names/myname/transfer \
-H 'Content-Type: application/json' \
-d '{"new_owner_pubkey":"<new-pk>","pubkey":"<pk>","nonce":2,"signature":"<sig>"}'
# List for sale
cargo run -p zns-wallet -- sign $SK "LIST:myname:100000:u1payoutaddr:1"
curl -X POST localhost:3000/v1/names/myname/list \
-H 'Content-Type: application/json' \
-d '{"price_zat":100000,"seller_address":"u1payoutaddr","pubkey":"<pk>","nonce":1,"signature":"<sig>"}'
Escrow Marketplace Test (Mock Mode)
# Start server with escrow
ZNS_ESCROW_SEED=deadbeef...deadbeef cargo run -p zns-api
# Register a name (see Quick Registration Test above), then:
# List for sale
curl -X POST localhost:3000/v1/names/myname/list ...
# Buy via escrow
curl -X POST localhost:3000/debug/inject_escrow_tx \
-H 'Content-Type: application/json' \
-d '{"memo":"ZNS:v1:BUY:myname:<buyer-pub>:u1buyeraddr:50000","value_zat":50000}'
curl -X POST localhost:3000/debug/mine_blocks -d '{"count":1}'
# Verify
curl localhost:3000/v1/resolve/myname # buyer's address
curl localhost:3000/v1/escrow/payouts # pending payout
curl localhost:3000/v1/marketplace/listing/myname # no listing
Common Pitfalls
- Name must not include
.zec-- the TLD is implied. Registeralice, notalice.zec. - REGISTER value must meet the fee for the name length. Underpayment burns the fee.
- Must shield before sending -- transparent wallets can't attach memos.
- BUY goes to escrow, not registrar -- BUY to registrar is silently ignored.