| name | mirage-solana-wallet |
| description | Use when the user wants to operate a Solana wallet from an agent — creating or resolving named wallets, funding them, reading balances, quoting or executing swaps, invoking ANY Anchor program by its IDL (on-chain or local), sending public or private SPL transfers, signing arbitrary transactions or messages — through `mirage` and `mirage ows`, with safe confirmation and post-send verification. |
Mirage Solana Agent Wallet
Use this skill whenever the task is a Solana wallet operation the agent should execute on the user's behalf: wallet creation, address resolution, balance checks, funding, arbitrary Anchor program calls, swaps, SPL transfers (public or private), or raw transaction/message signing. Everything runs through mirage and the bundled mirage ows CLI using an OWS-backed wallet (default: agent-treasury).
Safety
- Treat every wallet, funding, transfer, program-invocation, and signing flow as a sensitive action.
- Before opening a funding link, broadcasting a transfer, invoking a program instruction, or signing a raw transaction, restate the exact wallet, network (cluster/rpc), program/recipient, mint, amount, instruction(s), and any user-provided args or accounts in one short confirmation.
- If the user asks for a swap quote or price, do not run
mirage swap yet. First call the quote endpoint, present the expected input/output and price impact, then ask for explicit confirmation before broadcasting a swap.
- Prefer devnet for first-time runs against an unfamiliar program.
- Prefer
OWS_PASSPHRASE over passing --passphrase on the command line.
- Do not convert UI amounts to base units for
mirage transfer or mirage swap; those CLI commands already accept UI amounts like 0.1. Convert UI amounts only when directly calling the quote API.
Workflow
- Create or resolve the wallet to operate.
- Create a named wallet with
mirage ows wallet create --name <wallet>.
- List wallets with
mirage ows wallet list.
mirage address, mirage balance, mirage fund, mirage transfer, mirage swap, and mirage invoke auto-create the default agent-treasury wallet if it is missing.
- Resolve a wallet's Solana address with
mirage address --wallet <name>; check balance with mirage balance --wallet <name>.
- If the user wants to receive or top up, use
mirage fund (add --wallet <name> when it is not agent-treasury). This opens the Mirage hosted funding flow with the wallet address as rcv.
- If the user wants to invoke an arbitrary Anchor program (build + sign + send any instruction):
- Always attempt the program ID on its own first:
mirage invoke <program-id> (add --cluster devnet or --rpc-url <url> for non-mainnet). Most Anchor programs publish their IDL on-chain, so this is the default path.
- If Mirage errors with
No Anchor IDL is published on-chain for <program-id>. Provide one with --idl <path>., ask the user for a local IDL JSON file (e.g. target/idl/<name>.json in their repo, or downloaded from the program's GitHub) and retry with --idl <path>.
- In a non-interactive environment (scripts, CI, or any agent harness without a TTY), drive the command entirely through flags instead of the interactive picker:
- Inspect first:
mirage invoke <program-id> --cluster <cluster> --show-idl emits a JSON catalog listing every instruction, each arg with its type, and whether every account is auto-resolvable (signer, IDL-declared address, well-known sysvar/program, or PDA with fully declared seeds). Use this to know which instruction(s) to run and which --account/--arg values you still need from the user.
- Run:
mirage invoke <program-id> --cluster <cluster> --ix <name> [--ix <name> ...] --arg <ix>.<name>=<value> ... --account <ix>.<name>=<pubkey> ... --yes. Repeat --ix, --arg, and --account as needed. Add --dry-run to preview the resolved plan without signing when you want to confirm with the user first.
- In interactive use, Mirage fetches the IDL, lets the user pick one or more instructions, auto-derives the signer, well-known sysvars/programs, and IDL-declared PDAs, and only prompts for args or accounts it cannot resolve, then confirms a final summary before signing.
- Add
--wallet <name> when the fee payer is not agent-treasury. Add --yes only when the user has confirmed the full plan.
- If the user wants an SPL transfer (public or private):
mirage transfer --to <recipient> --amount <ui-amount> — defaults to mainnet USDC, private visibility, agent-treasury sender.
- Add
--wallet <name> when the sender is not agent-treasury.
- Add
--mint <mint> for a non-default mint.
- Add
--visibility public to opt out of private routing; --visibility private is the default.
- Use
--cluster or --rpc-url only when the user asks or the environment requires it.
- If the user wants a swap:
- For quote-only requests, call
GET https://payments.magicblock.app/v1/swap/quote directly instead of running mirage swap.
- Convert the requested UI amount to base units for the input mint for
ExactIn quotes, or output mint for ExactOut quotes. Use known decimals when certain (USDC and USDT are 6 decimals); otherwise fetch mint decimals over Solana RPC before calling the quote endpoint.
- Example USDC to USDT quote:
curl -s "https://payments.magicblock.app/v1/swap/quote?inputMint=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v&outputMint=Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB&amount=500000&swapMode=ExactIn".
- Present
inAmount, outAmount, otherAmountThreshold, slippageBps, priceImpactPct, and the route labels if available. Then ask whether to execute the swap.
- Execute only after confirmation with
mirage swap --input-mint <mint> --output-mint <mint> --amount <ui-amount> plus any confirmed flags such as --slippage-bps, --wallet, --visibility, or private delivery fields.
- If the user wants to sign an arbitrary Solana transaction or message (outside the transfer/invoke/swap flows):
mirage ows sign tx --wallet <name> --chain solana --tx <unsigned-tx-hex> for raw transactions.
mirage ows sign message --wallet <name> --chain solana --message "<message>" for message-signing only (not for transactions).
- Report the outcome:
- Include the transaction signature and sender address.
- For
mirage invoke, include the cluster-appropriate explorer URL printed by the CLI.
- Verify status on Solana RPC or check
mirage balance when it is useful.
Common Commands
mirage ows wallet create --name agent-treasury-1
mirage ows wallet list
mirage address --wallet recipient-wallet
mirage balance --wallet agent-treasury
mirage fund
mirage fund --wallet agent-treasury
mirage invoke <program-id> --cluster devnet
mirage invoke <program-id> --idl ./target/idl/<name>.json
mirage invoke <program-id> --cluster devnet --show-idl
mirage invoke <program-id> --cluster devnet \
--ix increment \
--arg increment.amount=1 \
--account increment.counter=<pubkey> \
--dry-run
mirage invoke <program-id> --cluster devnet --ix increment --yes
mirage transfer --to <recipient> --amount 0.1
mirage transfer --wallet sender-wallet --to <recipient> --amount 2.5
mirage transfer --wallet sender-wallet --to <recipient> --amount 2.5 --visibility public
mirage transfer --wallet sender-wallet --to <recipient> --mint <mint> --amount 1
curl -s "https://payments.magicblock.app/v1/swap/quote?inputMint=<mint>&outputMint=<mint>&amount=<base-units>&swapMode=ExactIn"
mirage swap --input-mint <mint> --output-mint <mint> --amount 0.5 --slippage-bps 50
mirage ows sign tx --wallet agent-treasury --chain solana --tx <unsigned-tx-hex>
mirage ows sign message --wallet agent-treasury --chain solana --message "hello"
Notes
mirage fund is a receive/top-up flow, not a send flow.
mirage transfer defaults to mainnet USDC and private visibility; set --visibility public to opt out of private routing.
mirage swap signs and sends; use the quote endpoint directly for quote-only requests before asking the user to confirm execution.
- Do not pass
--yes to mirage swap; it is not supported. After user confirmation, run mirage swap without --yes.
- If the user only supplies a recipient wallet name, resolve it with
mirage address before sending.
- Create a brand-new named wallet explicitly with
mirage ows wallet create --name <wallet> before using it in other commands.
mirage invoke defaults to the on-chain Anchor IDL PDA. Try the bare mirage invoke <program-id> form first; only ask the user for a local IDL when Mirage reports that no on-chain IDL is published.
mirage invoke auto-derives signers, well-known sysvars/programs, and PDAs whose seeds are declared in the IDL; anything else is prompted for (interactively) or requires --account/--arg flags (non-interactively).
- Use
mirage ows sign tx for raw Solana transactions that do not fit mirage transfer or mirage invoke.
- On older Mirage installs,
BlockhashNotFound on private transfers can indicate an outdated global CLI. Re-run with the current build if needed.