Skip to main content

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. Register alice, not alice.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.