Command-line tool for SphereNet governance and network administration.
cargo install spherenet-admin
spherenet-admin --helpOr download a prebuilt binary for Linux (x86_64) or macOS (Apple Silicon) from the Releases page. Each archive ships the spherenet-admin binary plus a .sha256 checksum — extract it and put it on your PATH:
tar -xzf spherenet-admin-<version>-<target>.tar.gz
sudo mv spherenet-admin-<version>-<target>/spherenet-admin /usr/local/bin/Or build from source:
git clone https://github.com/Sphere-Foundation/spherenet-admin
cd spherenet-admin
cargo build --release # binary at target/release/spherenet-adminGlobal flags (all commands): --url <URL> (defaults to testnet https://api.test.sphere.net) and --output text|json. In both modes stdout carries only the result and diagnostics go to stderr, so … --output json | jq always sees clean JSON.
Every governance/program/transfer command runs single-sig (--authority <keypair>, executes immediately) or multisig (--multisig <create-key> --multisig-authority <member>, creates a Squads proposal). A multisig is always referenced by its create-key (a pubkey), which the CLI resolves + validates to the vault that holds funds and signs.
Everything a validator, deployer, or user runs on their own — no governance authority required.
Onboarding is two-step: you request, an authority approves async. The requester co-signs to prove control of the key.
# Validator: request a validator-whitelist entry (the vote account co-signs)
spherenet-admin vw request ./vote-account.json --start-epoch 100 --end-epoch 200 --authority ./payer.json
# Deployer: request program-deploy access (the deploy authority co-signs)
spherenet-admin pw request ./deploy-authority.json --authority ./payer.jsonThe --authority here is just the fee-payer; the requesting key (vote account / deploy authority) is the co-signer that proves control. Once an admin approves, you're active.
# minimal — every other role defaults to the identity keypair
spherenet-admin vote create --vote-account ./vote.json --identity ./identity.jsonvote show <VOTE_ACCOUNT>·vote withdraw --vote-account <PK> --destination <PK> (--all) --withdraw-authority ./w.json
Produces a V4 vote account with a BLS voter key in one command — the default path creates with the legacy VoteInit and appends the BLS key inline via authorize_checked (needs the bls_pubkey_management_in_vote_account feature active). Pass --vote-init-v2 to set the BLS key at creation instead (VoteInitV2, requires SIMD-0464).
Optional overrides: --authorized-voter <KEYPAIR> (signs the BLS append and is what the BLS key is derived from — defaults to the identity), --authorized-withdrawer <PK> (defaults to the voter → identity; keep it a distinct cold key), --from / --payer (default to the identity), --commission <0-100> (default 100).
spherenet-admin stake create --stake-account ./stake.json --amount 10000 \
--stake-authority <PK> --withdraw-authority <PK> --from ./funder.json --payer ./payer.json
spherenet-admin stake delegate --stake-account <PK> --vote-account <PK> --stake-authority ./staker.json --payer ./payer.jsonstake show <PK>·stake deactivate …·stake withdraw … (--amount <SPHR> | --all)stake deactivate --stake-account <PK> --force --payer ./payer.json— permissionlessly deactivate stake still delegated to a validator that was removed from the whitelist (no stake authority needed)
Delegation is gated on the validator whitelist and fails fast if the vote account isn't approved.
The upgrade authority must be pw-approved first (see Join the network).
spherenet-admin program deploy --program-so ./p.so --program-keypair ./p-keypair.json \
--upgrade-authority ./auth.json --payer ~/.config/solana/id.json [--max-data-len 500000]program upgrade --program-id <ID> --program-so ./p.so …(single-sig or multisig)program extend --program-id <ID> --bytes <N>— grow capacity (permissionless; payer covers the added rent)program set-upgrade-authority --program-id <ID> [--new-authority <PK> | --new-multisig <CK> | --final]program write-buffer --program-so ./p.so (--buffer-authority <PK> | --buffer-multisig <CK>) --payer <KEYPAIR> [--buffer-keypair <KEYPAIR | kms://>]— stage a buffer for a feature-gated upgrade (verifies the on-chain bytes against the.so; the authority target is multisig-guarded)program show-buffer <BUFFER>— a buffer's authority, program-byte length and SHA-256 (read-only;--output jsoncompares directly withwrite-buffer's output)program set-buffer-authority --buffer <BUFFER> [--new-authority <PK> | --new-multisig <CK> | --lock]— the current authority (--authority, or a multisig) hands the buffer over;--locksets it to1111…1(irreversible; what a feature-gated upgrade of a genesis program needs)program close-buffer --buffer <BUFFER> [--recipient <PK> | --recipient-multisig <CK>]— the current authority closes the buffer and reclaims its rent (defaults to the authority); a locked buffer can't be closed. Re-create at the same address withwrite-buffer --buffer-keypair(the address key)
spherenet-admin multisig create --members <PK>,<PK>,<PK> --threshold 2 --create-key ./ck.json --payer ./payer.json --memo "Treasury"
spherenet-admin multisig show --multisig <CREATE_KEY>
spherenet-admin multisig approve --multisig <CREATE_KEY> --transaction-index <N> --member ./member.json
spherenet-admin multisig execute --multisig <CREATE_KEY> --transaction-index <N> --member ./member.jsonspherenet-admin transfer --amount 1.5 --to <PK> --from ./keypair.json # or --to-multisig <CREATE_KEY>
spherenet-admin transfer --all --to <PK> --from ./keypair.json # drain the source (single-sig: balance - fee; multisig vault: full balance)
spherenet-admin airdrop --pubkey <PK> --amount 5.0 # testnet faucet
spherenet-admin balance <PK>
spherenet-admin epoch
spherenet-admin server --port 8080 # read-only JSON HTTP API (GET /mp /vw /pw /epoch /balance/{pk} …)Governance-authority actions. Three whitelists/policies govern the network:
- Validator Whitelist (
vw) — which validators may join consensus. - Program Whitelist (
pw) — which authorities may deploy/upgrade programs. - Monetary Policy (
mp) — inflation rate, per-signature fee, fee burn, and per-epoch VAT.
Each is a single config account with a transferable authority; vw/pw entries move through a request → approve/reject lifecycle.
spherenet-admin vw approve <VOTE_ACCOUNT> --start-epoch 100 --end-epoch 200 --authority ./authority.json
spherenet-admin vw reject <VOTE_ACCOUNT> --authority ./authority.jsonvw show— authority + entries (eachPendingorApproved)vw remove <VOTE_ACCOUNT>·vw update-start-epoch <VA> --epoch <N>·vw update-end-epoch <VA> --epoch <N>vw propose-authority [--new-authority <PK> | --new-multisig <CK>]·vw accept-authority·vw cancel-authority
spherenet-admin pw approve <DEPLOYER_PUBKEY> --authority ./authority.json
spherenet-admin pw reject <DEPLOYER_PUBKEY> --authority ./authority.jsonpw show·pw remove <DEPLOYER>pw propose-authority [--new-authority | --new-multisig]·pw accept-authority·pw cancel-authority
spherenet-admin mp update-inflation-rate <BIPS> --authority ./authority.json # 0–2000 = 0–20%mp showmp update-lamports-per-signature <LAMPORTS>·mp update-burn-percent <PERCENT>·mp update-vat-lamports-per-epoch <LAMPORTS>mp propose-authority [--new-authority | --new-multisig]·mp accept-authority·mp cancel-authority
The mp config account is created at genesis, not by this CLI.
Anywhere a command takes a keypair path — authorities, payers, funders,
multisig members, co-signers — a kms:// URI can be passed instead to sign
with an Ed25519 key held in Google Cloud KMS, so the private key never
touches disk:
spherenet-admin vw approve <VOTE_ACCOUNT> \
--authority "kms://projects/<p>/locations/<l>/keyRings/<r>/cryptoKeys/<k>/cryptoKeyVersions/<v>?pubkey=<BASE58_ADDRESS>"The URI names the exact crypto-key version (the key must use algorithm
EC_SIGN_ED25519) and the Solana address the key is expected to have; every
signature returned by KMS is verified against that address before use. To get
the address from a key's public-key PEM:
gcloud kms keys versions get-public-key <V> --key <K> --keyring <R> \
--location <L> --project <P> --output-file pubkey.pem
spherenet-admin kms address pubkey.pemAuthentication uses Application Default Credentials: run
gcloud auth application-default login, or point
GOOGLE_APPLICATION_CREDENTIALS at a service-account key. Note that gcloud
keeps two separate credential stores: gcloud auth login covers the
gcloud CLI itself, while gcloud auth application-default login covers
client libraries — including this CLI's KMS signing. Refreshing one does not
refresh the other, so when your session expires (e.g. an org session-length
policy), re-run both:
gcloud auth login && gcloud auth application-default loginAn expired ADC session surfaces here as Cannot access KMS key …: cannot create the authentication headers. The caller needs
cloudkms.cryptoKeyVersions.useToSign on the key (e.g. role
roles/cloudkms.signerVerifier). Before building a transaction, the CLI
preflights the key (access, algorithm, and that its address matches the URI's
pubkey) — but the sign permission itself can only be proven by signing, so
a caller with only roles/cloudkms.publicKeyViewer passes preflight and
fails at signing time.
One exception stays local-file only:
vote create --identity/--authorized-voter— the validator host derives its BLS voting key from the authorized-voter keypair file (and needs the identity key to run); a KMS key here would strand the vote account.
program deploy and program upgrade are fully supported: deploy uses the
same buffer handoff as upgrade (the payer writes the ~900-byte chunks, then
the buffer is transferred to the upgrade authority), so the upgrade authority
signs exactly once per deploy or upgrade regardless of program size. The
payer may also be kms://, at a documented cost of one KMS round-trip per
chunk (roughly 2 minutes of extra signing per 500KB). Every send retries a
few times with a fresh blockhash before giving up, and the one-off sends
(buffer creation, authority transfer, the deploy itself) also detect a
transaction that landed but lost its confirmation, rather than aborting a
fully written buffer.
Testnet RPC: https://api.test.sphere.net
| program | address |
|---|---|
| Stake | Stake11111111111111111111111111111111111111 |
| Vote | Vote111111111111111111111111111111111111111 |
| Validator Whitelist | VwL1111111111111111111111111111111111111111 |
| Program Whitelist | PwL1111111111111111111111111111111111111111 |
| Monetary Policy | MpM1111111111111111111111111111111111111111 |
| Squads v4 | Sqds111111111111111111111111111111111111111 |
| ZK Loader | ZkLoader11111111111111111111111111111111111 |
| SPL Token | TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA |
| Token-2022 | TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb |
| Associated Token Account | ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL |