On-Chain Reference
Instructions

Instructions

The sandbox_ghi program exposes six public instructions. Below is the full spec for each — required accounts, arguments, on-chain checks, and what gets emitted.


stake_nft

Locks an Agent NFT in the staking contract. Creates a StakeAccount PDA and transfers custody of the NFT to the program.

Accounts

AccountTypeWritableSignerDescription
ownerSignerNFT owner
nft_mintMintAgent NFT mint
owner_nft_ataTokenAccountOwner's NFT token account
vault_nft_ataTokenAccountProgram vault for NFT custody
stake_accountStakeAccount (PDA)Created by this instruction
mining_poolMiningPool (PDA)total_staked incremented
token_programProgramSPL Token
system_programProgram

Arguments

None. Tier is read from the NFT's on-chain metadata (Metaplex attribute field).

On-Chain Checks

  • NFT must be a verified Sandbox GHI collection member
  • Owner must hold the NFT (balance = 1)
  • No existing StakeAccount for this mint + owner pair

Emits

emit!(StakeEvent {
    owner: ctx.accounts.owner.key(),
    nft_mint: ctx.accounts.nft_mint.key(),
    tier,
    timestamp: Clock::get()?.unix_timestamp,
});

unstake_nft

Returns the NFT to the owner and auto-claims all pending $GHI rewards. Closes the StakeAccount.

Accounts

AccountTypeWritableSignerDescription
ownerSignerMust match stake_account.owner
nft_mintMint
owner_nft_ataTokenAccountReceives NFT back
vault_nft_ataTokenAccountReleases NFT from custody
stake_accountStakeAccount (PDA)Closed — rent returned to owner
mining_poolMiningPool (PDA)total_staked decremented
ghi_vaultTokenAccount (PDA)Source of reward tokens
owner_ghi_ataTokenAccountCreated if needed; receives rewards
ghi_mintMint$GHI SPL mint
token_programProgram
system_programProgram
associated_token_programProgram

Flow

1. calculate_rewards(stake_account, mining_pool, now)
2. transfer NFT: vault_nft_ata → owner_nft_ata
3. mint_to / transfer: ghi_vault → owner_ghi_ata (reward amount)
4. close stake_account (rent → owner)
5. pool.total_staked -= 1

If rewards are zero (staked for less than 1 second), the token transfer is skipped. No error is thrown.


claim_rewards

Claims pending $GHI without unstaking. Updates last_claimed timestamp.

Accounts

AccountTypeWritableSignerDescription
ownerSigner
stake_accountStakeAccount (PDA)last_claimed updated
mining_poolMiningPool (PDA)Read-only (epoch data)
ghi_vaultTokenAccount (PDA)
owner_ghi_ataTokenAccount
ghi_mintMint
token_programProgram
associated_token_programProgram

On-Chain Checks

  • stake_account.owner == owner.key()
  • Pending rewards > 0 (otherwise: ErrorCode::NothingToClaim)

deploy_agent

Creates an AgentAccount and funds it with $GHI for task execution. The NFT must be staked to deploy an agent.

Accounts

AccountTypeWritableSignerDescription
ownerSigner
nft_mintMint
stake_accountStakeAccount (PDA)Must exist (NFT must be staked)
agent_accountAgentAccount (PDA)Created here
owner_ghi_ataTokenAccountSource of $GHI budget
agent_ghi_ataTokenAccountAgent's own ATA (created here)
ghi_mintMint
token_programProgram
system_programProgram
associated_token_programProgram

Arguments

ArgTypeDescription
task_typeTaskTypeMonitor / Trader / Optimizer / Custom
ghi_budgetu64$GHI to allocate (raw units, min: 1_000_000 = 1 $GHI)

On-Chain Checks

  • NFT must be staked (stake_account must exist)
  • No existing agent_account for this mint + owner pair
  • Legendary holders bypass the minimum budget requirement

submit_task_result

Called by the off-chain agent executor (program authority) to record task completion and award reputation. This instruction is not callable by users.

Accounts

AccountTypeWritableSignerDescription
authoritySignerMust match mining_pool.authority
agent_accountAgentAccount (PDA)Reputation updated
agent_ghi_ataTokenAccountBudget debited
task_recipientTokenAccountReceives $GHI for completed task

Arguments

ArgTypeDescription
task_weightu81–10 (set by protocol per task type)
completion_bonusu8100 = on-time, 50 = late, 0 = failed
ghi_costu64$GHI deducted from agent budget

close_agent

Stops the agent, returns remaining $GHI budget to owner, and closes the AgentAccount.

Accounts

AccountTypeWritableSignerDescription
ownerSigner
agent_accountAgentAccount (PDA)Closed; rent → owner
agent_ghi_ataTokenAccountRemaining budget returned
owner_ghi_ataTokenAccount
token_programProgram

On-Chain Checks

  • agent_account.owner == owner.key()