This directory contains everything needed to build and deploy the PhantomOperator on-chain program to Solana.
solana/
├── programs/
│ └── phantom_operator/
│ ├── Cargo.toml Rust project manifest
│ └── src/
│ └── lib.rs BPF/SBF program source code
├── deploy/ (created by build.sh) compiled .so artifacts
├── scripts/
│ ├── check-solana.sh Verify toolchain prerequisites
│ ├── build.sh Compile the program into a .so binary
│ └── deploy.sh Deploy (or upgrade) the program on-chain
└── README.md ← you are here
curl https://sh.rustup.rs -sSf | sh
source "$HOME/.cargo/env"sh -c "$(curl -sSfL https://release.solana.com/stable/install)"Add the Solana bin directory to your PATH (the installer prints the exact
command — typically export PATH="$HOME/.local/share/solana/install/active_release/bin:$PATH").
Verify the installation:
solana --version
cargo-build-sbf --version./solana/scripts/check-solana.shIf you do not already have a Solana keypair, generate one:
solana-keygen new --outfile ~/.config/solana/id.jsonFor a dedicated program keypair (lets you redeploy to the same address):
solana-keygen new --outfile solana/deploy/phantom_operator-keypair.jsonSecurity: Never commit keypair files to source control.
solana/deploy/is excluded by.gitignore.
# Default (release build)
./solana/scripts/build.sh
# Debug build (larger binary, more log output)
./solana/scripts/build.sh --debugThe compiled phantom_operator.so is written to solana/deploy/.
You can also build manually:
cd solana/programs/phantom_operator
cargo build-sbf
# Output: ../../target/deploy/phantom_operator.so-
Configure the Solana CLI to use devnet and your keypair:
solana config set --url devnet --keypair ~/.config/solana/id.json
-
Fund your wallet (devnet only):
solana airdrop 2
-
Deploy:
./solana/scripts/deploy.sh --cluster devnet
Or with explicit flags:
./solana/scripts/deploy.sh \ --cluster devnet \ --keypair ~/.config/solana/id.json \ --so-file solana/deploy/phantom_operator.so -
The script prints the deployed Program ID.
Copy it into your.env:SOLANA_PROGRAM_ID=<printed-program-id>
Deploying to mainnet requires real SOL.
Ensure your wallet is funded before proceeding.
./solana/scripts/deploy.sh --cluster mainnet-betaPass the program keypair used during the initial deploy to preserve the program address:
./solana/scripts/deploy.sh \
--cluster devnet \
--program-id solana/deploy/phantom_operator-keypair.jsonInstall the Solana web3.js client:
npm install @solana/web3.jsSOLANA_PROGRAM_ID=<your-program-id> \
node scripts/solana-invoke.js init-registrySOLANA_PROGRAM_ID=<your-program-id> \
node scripts/solana-invoke.js invoke-skill \
--skill-id 0 \
--amount 1000000Skill IDs:
| ID | Slug | Min price (lamports) |
|---|---|---|
| 0 | threat-scan | 1 000 000 |
| 1 | data-removal | 5 000 000 |
| 2 | full-privacy-sweep | 10 000 000 |
| 3 | opsec-score | 5 000 000 |
| 4 | breach-check | 2 000 000 |
| 5 | metadata-audit | 1 000 000 |
SOLANA_PROGRAM_ID=<your-program-id> \
node scripts/solana-invoke.js read-registryThe on-chain program (lib.rs) exposes two instructions:
Creates a PDA account (seeds = [b"phantom_registry", operator_pubkey]) that
stores:
| Field | Type | Description |
|---|---|---|
is_initialized |
bool | Set to true after init |
owner |
Pubkey | Operator wallet that receives payments |
total_invocations |
u64 | Running count of all invocations |
total_fees_lamports |
u64 | Running sum of all lamports received |
- Validates
skill_id(0–5) andamount_lamports ≥ SKILL_MIN_PRICES[skill_id]. - Transfers
amount_lamportsfrom the caller to the operator wallet. - Increments the registry counters.
- Emits a program log with the skill name, payer, amount, and slot.
cd solana/programs/phantom_operator
cargo testAdd these to your .env (see .env.example for all variables):
# Solana cluster: devnet | testnet | mainnet-beta
SOLANA_CLUSTER=devnet
# Path to the deployer / payer keypair JSON file
SOLANA_KEYPAIR_PATH=~/.config/solana/id.json
# Program ID returned by deploy.sh
SOLANA_PROGRAM_ID=
# (optional) Custom RPC URL for mainnet-beta (Alchemy, QuickNode, etc.)
SOLANA_RPC_URL=https://api.mainnet-beta.solana.com| Symptom | Likely cause | Fix |
|---|---|---|
cargo-build-sbf: command not found |
Solana CLI not in PATH | Re-source your shell or open a new terminal after installing the CLI |
Error: RPC response error -32002 |
Account not found | Run init-registry before invoke-skill |
Error: insufficient funds |
Wallet balance too low | Airdrop on devnet, or fund mainnet wallet |
.so file not found |
Build step skipped | Run ./solana/scripts/build.sh first |
PDA mismatch |
Wrong program ID or owner | Check SOLANA_PROGRAM_ID and --operator flag |