| Crates.io | ozon-cli |
| lib.rs | ozon-cli |
| version | 0.1.27 |
| created_at | 2025-10-14 12:15:48.990704+00 |
| updated_at | 2025-10-26 20:24:20.910728+00 |
| description | Ozon CLI helps to manage and register operators and AVSs with the Ozon protocol. |
| homepage | https://github.com/wildchain/ozon_contract |
| repository | https://github.com/wildchain/ozon_contract |
| max_upload_size | |
| id | 1882170 |
| size | 260,483 |
Command-line interface for interacting with the Ozon restaking protocol on Solana. Manage operators and AVS (Actively Validated Services) registrations directly from your terminal.
cargo install ozon-cli
git clone https://github.com/wildchain/ozon_contract.git
cd ozon_contract/ozon-cli
cargo install --path .
ozon-cli --version
ozon-cli --help
Before using ozon-cli, ensure you have:
# Create a new wallet (if you don't have one)
solana-keygen new --outfile ~/.config/solana/id.json
# Set cluster to devnet for testing
solana config set --url devnet
# Check your wallet address
solana address
# Get devnet SOL for testing (devnet only)
solana airdrop 2
ozon-cli <COMMAND> [OPTIONS]
--cluster <CLUSTER>: Specify Solana cluster (devnet, testnet, mainnet) [default: devnet]--wallet <PATH>: Path to wallet keypair file [default: ~/.config/solana/id.json]--help: Display help information--version: Display version informationRegister a new operator with the Ozon protocol by staking a bond amount.
Syntax:
ozon-cli initialize-operator \
--bond-amount <LAMPORTS> \
--metadata <STRING> \
[--cluster <CLUSTER>] \
[--wallet <PATH>]
Parameters:
--bond-amount: Amount of SOL to bond in lamports (minimum: 2 SOL = 2,000,000,000 lamports)--metadata: Metadata describing your operator (e.g., "My Operator Node")--cluster: Network cluster (devnet, testnet, mainnet) [default: devnet]--wallet: Path to wallet file [default: ~/.config/solana/id.json]Example:
# Register operator with 5 SOL bond on devnet
ozon-cli initialize-operator \
--bond-amount 5000000000 \
--metadata "Acme Validator Services" \
--cluster devnet
# Register on mainnet with custom wallet
ozon-cli initialize-operator \
--bond-amount 10000000000 \
--metadata "Production Operator" \
--cluster mainnet \
--wallet /path/to/mainnet-wallet.json
Output:
π Debug info:
Program ID: 6UqcKJ3U7zfr5JkhzjDZQsunbJeFBxgCKYbuMw8Scv6B
Operator key: 8xYz...AbCd
Operator account PDA: 9pQw...XyZa
Vault PDA: 7mNb...LmNo
Bond amount: 5000000000
Metadata: Acme Validator Services
β
Operator initialized with tx 3kL9...8fH2
Remove your operator registration and reclaim your bonded SOL.
Syntax:
ozon-cli de-register-operator \
[--cluster <CLUSTER>] \
[--wallet <PATH>]
Parameters:
--cluster: Network cluster [default: devnet]--wallet: Path to wallet file [default: ~/.config/solana/id.json]Example:
# De-register operator on devnet
ozon-cli de-register-operator --cluster devnet
# De-register on mainnet with custom wallet
ozon-cli de-register-operator \
--cluster mainnet \
--wallet /path/to/mainnet-wallet.json
Output:
π Debug info:
Program ID: 6UqcKJ3U7zfr5JkhzjDZQsunbJeFBxgCKYbuMw8Scv6B
Operator key: 8xYz...AbCd
Operator account PDA: 9pQw...XyZa
Vault PDA: 7mNb...LmNo
β
Operator de-registered with tx 2jK8...9gI1
Register a new Actively Validated Service (AVS) with the protocol.
Syntax:
ozon-cli register-avs \
--metadata <STRING> \
--registration-fee <LAMPORTS> \
[--cluster <CLUSTER>] \
[--wallet <PATH>]
Parameters:
--metadata: Name/metadata for your AVS--registration-fee: Registration fee in lamports (minimum: 3 SOL = 3,000,000,000 lamports)--cluster: Network cluster [default: devnet]--wallet: Path to wallet file [default: ~/.config/solana/id.json]Example:
# Register AVS on devnet
ozon-cli register-avs \
--metadata "Oracle Price Feeds" \
--registration-fee 3000000000 \
--cluster devnet
# Register on mainnet
ozon-cli register-avs \
--metadata "Cross-Chain Bridge Service" \
--registration-fee 5000000000 \
--cluster mainnet \
--wallet /path/to/mainnet-wallet.json
Output:
π Debug info:
Program ID: 6UqcKJ3U7zfr5JkhzjDZQsunbJeFBxgCKYbuMw8Scv6B
AVS owner: 8xYz...AbCd
AVS account PDA: 4sWx...KlMn
Treasury PDA: 6tRy...PqRs
Registration fee: 3000000000
Avs Name: Oracle Price Feeds
β
Avs registered with tx 5nM7...3pQ9
Update the metadata/name of your registered AVS.
Syntax:
ozon-cli update-avs-metadata \
--metadata <STRING> \
[--cluster <CLUSTER>] \
[--wallet <PATH>]
Parameters:
--metadata: New name/metadata for your AVS--cluster: Network cluster [default: devnet]--wallet: Path to wallet file [default: ~/.config/solana/id.json]Example:
# Update AVS metadata
ozon-cli update-avs-metadata \
--metadata "Oracle Price Feeds v2.0" \
--cluster devnet
# Update on mainnet
ozon-cli update-avs-metadata \
--metadata "Enhanced Oracle Service" \
--cluster mainnet \
--wallet /path/to/mainnet-wallet.json
Output:
π Debug info:
Program ID: 6UqcKJ3U7zfr5JkhzjDZQsunbJeFBxgCKYbuMw8Scv6B
AVS owner: 8xYz...AbCd
AVS account PDA: 4sWx...KlMn
New Avs Name: Oracle Price Feeds v2.0
β
AVS metadata updated with tx 7oL6...4rH8
Remove your AVS registration from the protocol.
Syntax:
ozon-cli de-register-avs \
[--cluster <CLUSTER>] \
[--wallet <PATH>]
Parameters:
--cluster: Network cluster [default: devnet]--wallet: Path to wallet file [default: ~/.config/solana/id.json]Example:
# De-register AVS on devnet
ozon-cli de-register-avs --cluster devnet
# De-register on mainnet(comming soon)
ozon-cli de-register-avs \
--cluster mainnet \
--wallet /path/to/mainnet-wallet.json
Output:
π Debug info:
Program ID: 6UqcKJ3U7zfr5JkhzjDZQsunbJeFBxgCKYbuMw8Scv6B
AVS owner: 8xYz...AbCd
AVS account PDA: 4sWx...KlMn
β
AVS de-registered with tx 9kP4...2sG7
Allow an operator to opt into an Actively Validated Service to start providing services.
Syntax:
ozon-cli opt-in-avs \
--avs-owner <PUBKEY> \
[--cluster <CLUSTER>] \
[--wallet <PATH>] \
[--interactive]
Parameters:
--avs-owner: The public key of the AVS owner you want to opt into--cluster: Network cluster [default: devnet]--wallet: Path to wallet file [default: ~/.config/solana/id.json]--interactive: Launch the Ozon AVS Selection dashboard in your browser [optional]Example:
# Opt into an AVS using the AVS owner's public key
ozon-cli opt-in-avs \
--avs-owner 8xYzAbCdEfGh1234567890qwertyuiopasdfghjklzxc \
--cluster devnet
# Use interactive mode to browse and select AVS from the dashboard
ozon-cli opt-in-avs --interactive
# Opt in on mainnet with custom wallet
ozon-cli opt-in-avs \
--avs-owner 8xYzAbCdEfGh1234567890qwertyuiopasdfghjklzxc \
--cluster mainnet \
--wallet /path/to/mainnet-wallet.json
Output:
π Debug info:
Operator: CLuH...btHN
AVS Owner: 8xYz...zxc
AVS Account: 4sWx...KlMn
Registration PDA: 9pQw...XyZa
β
Opted into AVS with tx 7mN8...5kL2
Run a local operator daemon that polls for active tasks and submits results automatically.
Syntax:
ozon-cli run-operator \
[--cluster <CLUSTER>] \
[--wallet <PATH>] \
[--poll-interval-seconds <SECONDS>]
Parameters:
--poll-interval-seconds: Poll interval in seconds [default: 10]Example:
ozon-cli run-operator \
--cluster devnet \
--wallet ./operator1.json \
--poll-interval-seconds 10
Create a new task under your AVS.
Syntax:
ozon-cli create-task \
--task-id <U64> \
--submission-deadline-slots <U64> \
--verification-threshold-bps <U64> \
[--cluster <CLUSTER>] \
[--wallet <PATH>]
Example:
ozon-cli create-task \
--task-id 3 \
--submission-deadline-slots 1200 \
--verification-threshold-bps 200 \
--cluster devnet \
--wallet ~/.config/solana/avs-owner.json
Submit a task result manually (the daemon usually handles this automatically).
Syntax:
ozon-cli submit-task-result \
--task-pubkey <PUBKEY> \
--submitted-price <I64_SCALED_1e8> \
--confidence <U64> \
--publish-time <I64_UNIX_S> \
[--cluster <CLUSTER>] \
[--wallet <PATH>]
Verify an operator's submission and slash if incorrect.
Syntax:
ozon-cli verify-task \
--task-pubkey <PUBKEY> \
--operator-owner <PUBKEY> \
--actual-price <I64_SCALED_1e8> \
[--cluster <CLUSTER>] \
[--wallet <PATH>]
Notes:
--actual-price must be an integer i64 scaled to 8 decimals (e.g., 67321.12 β 6732112000000000).Close a task after the submission window has passed.
Syntax:
ozon-cli close-task \
--task-pubkey <PUBKEY> \
[--cluster <CLUSTER>] \
[--wallet <PATH>]
Derive the task account PDA for a given task_id and avs_owner.
Syntax:
ozon-cli get-task-pda \
--task-id <U64> \
--avs-owner <PUBKEY>
Interactive Mode: When using --interactive, the command will open the Ozon AVS Selection dashboard in your default browser, where you can:
Browse available AVS services View AVS metadata and requirements Select an AVS to opt into Complete the opt-in process through a user-friendly interface
# 1. Check your balance
solana balance
# 2. Request airdrop if on devnet
solana airdrop 10
# 3. Register as operator
ozon-cli initialize-operator \
--bond-amount 2000000000 \
--metadata "My Operator Node" \
--cluster devnet
# 4. Browse available AVS services interactively
ozon-cli opt-in-avs --interactive
# 5. Or opt into a specific AVS directly
ozon-cli opt-in-avs \
--avs-owner 8xYzAbCdEfGh1234567890qwertyuiopasdfghjklzxc \
--cluster devnet
# 6. Verify transaction on explorer
# Visit: https://explorer.solana.com/tx/<SIGNATURE>?cluster=devnet
# 1. Ensure you have enough SOL
solana balance
# 2. Register your AVS
ozon-cli register-avs \
--metadata "My Validation Service" \
--registration-fee 3000000000 \
--cluster devnet
# 3. Update name later if needed
ozon-cli update-avs-metadata \
--metadata "My Validation Service v2" \
--cluster devnet
# 5. Share your AVS owner pubkey with operators
solana address
There are two methods to find and opt into an AVS:
The easiest way to discover and opt into AVS services is through the interactive web dashboard:
# Launch the Ozon AVS Selection dashboard in your browser
ozon-cli opt-in-avs --interactive
What you'll see:
If you already know which AVS you want to join, you can opt in directly using the AVS owner's public key:
Ways to obtain the AVS owner pubkey:
Ask the AVS provider directly
Check the AVS registry on Solana Explorer
Use the AVS provider's documentation
Example:
# Once you have the AVS owner pubkey, opt in directly
ozon-cli opt-in-avs \
--avs-owner 8xYzAbCdEfGh1234567890qwertyuiopasdfghjklzxc \
--cluster devnet
You can run multiple operators and have them opt into different AVS services using separate wallets.
# Create and fund separate wallets for each operator
solana-keygen new --outfile ~/operator1-wallet.json
solana-keygen new --outfile ~/operator2-wallet.json
# Fund each wallet (on devnet)
solana airdrop 10 ~/operator1-wallet.json --url devnet
solana airdrop 10 ~/operator2-wallet.json --url devnet
# Register first operator
ozon-cli initialize-operator \
--bond-amount 5000000000 \
--metadata "Operator Node 1 - Oracle Services" \
--cluster devnet \
--wallet ~/operator1-wallet.json
# Register second operator
ozon-cli initialize-operator \
--bond-amount 5000000000 \
--metadata "Operator Node 2 - Bridge Services" \
--cluster devnet \
--wallet ~/operator2-wallet.json
# Operator 1 opts into Oracle AVS
ozon-cli opt-in-avs \
--avs-owner 8xYzAbCdEfGh1234567890qwertyuiopasdfghjklzxc \
--cluster devnet \
--wallet ~/operator1-wallet.json
# Operator 2 opts into Bridge AVS
ozon-cli opt-in-avs \
--avs-owner 9aWxBcDeFgHi2345678901zxcvbnmasdfghjklqwert \
--cluster devnet \
--wallet ~/operator2-wallet.json
# One operator can also opt into multiple AVS
ozon-cli opt-in-avs \
--avs-owner <ANOTHER_AVS_OWNER_PUBKEY> \
--cluster devnet \
--wallet ~/operator1-wallet.json
Best practices:
oracle-operator.json, bridge-operator.jsonExample directory structure:
~/solana-wallets/
βββ devnet/
β βββ operator-1-oracle.json
β βββ operator-2-bridge.json
β βββ operator-3-backup.json
βββ mainnet/
βββ production-operator-1.json
βββ production-operator-2.json
| Command | Purpose | Minimum Requirement |
|---|---|---|
initialize-operator |
Register as an operator | 2 SOL bond |
de-register-operator |
Unregister operator | Must be registered |
register-avs |
Register an AVS | 3 SOL registration fee |
update-avs-metadata |
Update AVS information | Must own AVS |
de-register-avs |
Unregister AVS | Must own AVS |
opt-in-avs |
Operator joins an AVS | Must be registered operator |
initialize-reward-treasury |
Setup reward system | Protocol authority only |
run-operator |
Run operator daemon to auto-submit tasks | Registered operator |
create-task |
Create a new task | AVS owner |
submit-task-result |
Manually submit result | Operator opted into AVS |
verify-task |
Verify submission and slash if wrong | AVS owner |
close-task |
Close an expired task | AVS owner |
get-task-pda |
Derive task PDA | None |
βββββββββββ
β Start β
ββββββ¬βββββ
β
βΌ
βββββββββββββββββββββββ
β Initialize Operator β βββ Bond 2+ SOL
ββββββββββββ¬βββββββββββ
β
βΌ
ββββββββββββββββ
βActive Operatorβ
ββββββββ¬ββββββββ
β
βΌ
βββββββββββββββ
βOpt Into AVS β βββ Join one or more services
ββββββββ¬βββββββ
β
βΌ
ββββββββββββββββββ
βProviding Servicesβ
ββββββββββ¬βββββββββ
β
βΌ
ββββββββββββββββββββββββ
β De-register Operator β βββ Reclaim bond
ββββββββββββ¬ββββββββββββ
β
βΌ
βββββββ
β End β
βββββββ
βββββββββββ
β Start β
ββββββ¬βββββ
β
βΌ
βββββββββββββββββββββββ
βInitialize Treasury β βββ Protocol setup (once)
ββββββββββββ¬βββββββββββ
β
βΌ
βββββββββββββββ
βRegister AVS β βββ Pay 3+ SOL fee
ββββββββ¬βββββββ
β
βΌ
ββββββββββββ
βActive AVSβ
ββββββ¬ββββββ
β
βΌ
ββββββββββββββββ
βUpdate Metadataβ βββ Optional updates
ββββββββ¬ββββββββ
β
βΌ
βββββββββββββββββ
βAccept Operatorsβ βββ Operators opt in
βββββββββ¬βββββββββ
β
βΌ
ββββββββββββββββ
βDe-register AVSβ βββ Close service
ββββββββ¬ββββββββ
β
βΌ
βββββββ
β End β
βββββββ
Use case: You run one operator node that provides multiple services.
# 1. Initialize your operator once
ozon-cli initialize-operator \
--bond-amount 5000000000 \
--metadata "Multi-Service Operator Node" \
--cluster devnet
# 2. Opt into multiple AVS services
ozon-cli opt-in-avs --avs-owner <ORACLE_AVS_OWNER>
ozon-cli opt-in-avs --avs-owner <BRIDGE_AVS_OWNER>
ozon-cli opt-in-avs --avs-owner <DATA_AVS_OWNER>
Use case: You run separate operators for different service types.
# Oracle-specialized operator
ozon-cli initialize-operator \
--bond-amount 10000000000 \
--metadata "Oracle Specialist Node" \
--wallet ~/oracle-operator.json
ozon-cli opt-in-avs \
--avs-owner <ORACLE_AVS_OWNER> \
--wallet ~/oracle-operator.json
# Bridge-specialized operator
ozon-cli initialize-operator \
--bond-amount 10000000000 \
--metadata "Bridge Specialist Node" \
--wallet ~/bridge-operator.json
ozon-cli opt-in-avs \
--avs-owner <BRIDGE_AVS_OWNER> \
--wallet ~/bridge-operator.json
Use case: Test your setup on devnet before going live on mainnet.
# Test on devnet first
ozon-cli initialize-operator \
--bond-amount 2000000000 \
--metadata "Test Operator" \
--cluster devnet \
--wallet ~/test-wallet.json
# Once confident, deploy to mainnet
ozon-cli initialize-operator \
--bond-amount 20000000000 \
--metadata "Production Operator" \
--cluster mainnet \
--wallet ~/prod-wallet.json
# Development/Testing on devnet
ozon-cli initialize-operator \
--bond-amount 2000000000 \
--metadata "Test Operator" \
--cluster devnet
# Production on mainnet
ozon-cli initialize-operator \
--bond-amount 10000000000 \
--metadata "Production Operator" \
--cluster mainnet \
--wallet /secure/mainnet-wallet.json
# Ensure cargo bin is in your PATH
export PATH="$HOME/.cargo/bin:$PATH"
# Add to your shell profile (~/.bashrc, ~/.zshrc)
echo 'export PATH="$HOME/.cargo/bin:$PATH"' >> ~/.zshrc
# Check your balance
solana balance
# On devnet, request airdrop
solana airdrop 5
# On mainnet, ensure you have enough SOL
Supported clusters are:
devnet (default)
testnet
mainnet or mainnet-beta (coming soon)
Ensure you're using the correct wallet that owns the operator/AVS you're trying to modify.
After each command, you'll receive a transaction signature. Verify it on Solana Explorer:
Devnet:
https://explorer.solana.com/tx/<SIGNATURE>?cluster=devnet
Mainnet:
https://explorer.solana.com/tx/<SIGNATURE>
Syntax:
ozon-cli run-nodes-client --cluster <CLUSTER> --operator-owner <PUBKEY> --debug
6UqcKJ3U7zfr5JkhzjDZQsunbJeFBxgCKYbuMw8Scv6Bwe will share this once we make our repo public]This project is licensed under the Apache-2.0 License - see the LICENSE file for details.
Built with:
Made with β€οΈ by the Ozon Team