@magicscodes/cli
v0.1.0
Published
Local-first CLI for the magics protocol on Base. Mint seals, summon agents, sign casts.
Maintainers
Readme
magics-cli
The local CLI for the magics protocol. Mint seals, summon agents, sign casts — all from your shell, with the root signer never leaving your wallet.
What it is
magics is the local-first companion to the magics web app. The app is fine for casual use; the CLI is for when you want to:
- script the lifecycle of a seal,
- pre-build cast transactions in CI,
- keep ephemeral signing keys outside the browser,
- read on-chain state without opening DevTools.
The CLI never holds your root-signer private key. For anything that needs the root signer — minting a seal, depositing into the router — magics prints the calldata so you can submit it from your hardware wallet, your favourite Foundry alias, or whatever else you trust. The only keys the CLI handles directly are the ephemeral session keys an agent signs with — and those live encrypted under ~/.magics/keys/.
Install
npm install -g @magicscodes/cli
# or, for a one-off:
npx @magicscodes/cli --helpFrom source:
git clone https://github.com/magics-codes/magics-cli.git
cd magics-cli
npm install && npm run build
npm link # gives you a global `magics` commandFirst run
magics initWalks through:
- Pick a network (
basemainnet orbase-sepolia). - Confirm or paste an RPC URL — we ping it before saving.
- Writes
~/.magics/config.jsonwith mode 0600.
Then mint an ephemeral signer:
magics keystore new daily-yield
# Passphrase for "daily-yield": ········
# ✓ minted "daily-yield" — 0x82c1…7a2bThe address printed at the end is what you'll plug into --signer when minting a seal.
The verbs
magics init one-time setup
magics whoami current config + RPC latency + block height
magics keystore manage ephemeral signers
new <name> generate a fresh key, encrypted
import <name> import an existing 0x-key
list list local keystores
rm <name> irreversible delete
magics seals
list [--owner <addr>] list seals owned by your wallet
mint build a mint-seal transaction
revoke <id> build a revoke transaction
revoke-all build the kill-switch transaction
magics summon <name> build a summon transaction
magics agents
list list your agents
pause / resume / halt build status-change transactions
magics cast <agentId> sign and pack a Cast intent
magics inspect
seal <id> full state of a seal
agent <id> full state of an agent
router active address book
balance <agentId> <token>
magics config read / set values in config.json
magics about long-form version bannerRun any verb with --help for flags and examples.
Daily flow
The shortest path from cold install to a passive-yield agent compounding once a day:
# 1. Setup.
magics init # walk through prompts
magics keystore new yield-cycle # ephemeral signer
magics config set owner 0xYourRootSigner
# 2. Mint a seal valid for 30d, capped at 50 USDC per 24h.
magics seals mint \
--signer 0x82c1…7a2b \
--target $(magics config get rpc | xargs -I{} magics inspect router | head -1) \
--expiry 2592000 \
--daily-cap 50000000
# (paste the printed cast send into your wallet — root signer mints the seal)
# 3. Summon an agent under that seal.
magics summon yield-cycle \
--strategy 0xPassiveYieldStrategyAddress \
--seal 0xSealIdFromStepTwo
# (paste the printed cast send — root signer summons)
# 4. Deposit working capital from your root signer.
# (Not a CLI verb — this is a router.deposit call; see docs/sdk/cli.md.)
# 5. Cast.
magics cast 0xAgentId --op compound --amount 0 # 0 = all idle
# Passphrase for signer "yield-cycle": ········
# ✓ signed
#
# Broadcast:
# to: 0xRouter…
# data: 0x…The cast tx can be submitted by anyone — the signature proves authorisation, the seal proves scope. In practice you'll pipe it to cast send or to a watcher running on your VPS.
What ends up on disk
~/.magics/
├── config.json # 0600, JSON, owned by you
├── deployments/
│ └── 8453.json # mirrored from the contracts repo
└── keys/
├── yield-cycle.json # encrypted, 0600
└── alpha-bot.jsonThat's it. No daemon, no socket, no telemetry. Delete the directory to start over.
Configuration
~/.magics/config.json:
{
"version": 1,
"network": "base",
"rpc": "https://mainnet.base.org",
"owner": "0xYourRootSigner",
"defaultSigner": "yield-cycle",
"overrides": {
"MagicsRouter": "0x…"
}
}Env vars override the file per-invocation:
| Variable | Effect |
| :----------------- | :---------------------------------------------------- |
| MAGICS_RPC_URL | Override the RPC for this command only |
| MAGICS_NETWORK | base | base-sepolia |
| MAGICS_HOME | Use a different config dir (handy for tests) |
| MAGICS_NO_PROMPT | Fail rather than open an interactive prompt |
| MAGICS_DEBUG | Print stack traces on uncaught errors |
| NO_COLOR | Disable colour output |
Exit codes
| Code | Meaning | | :--: | :-------------------------------------------- | | 0 | success | | 1 | generic error | | 2 | bad usage (missing flag, malformed argument) | | 10 | missing or unreadable config | | 20 | RPC unreachable / network failure | | 30 | passphrase wrong / signer not configured | | 40 | on-chain revert (custom error returned) | | 50 | user cancelled at a prompt |
Scripts wrapping magics can branch on these without parsing stderr.
Layout
cli/
├── bin/magics # shebang shim -> dist/index.js
├── src/
│ ├── index.ts # wires commander, top-level error handler
│ ├── version.ts
│ ├── types.ts
│ ├── commands/
│ │ ├── init.ts
│ │ ├── whoami.ts
│ │ ├── keystore.ts
│ │ ├── seals.ts
│ │ ├── summon.ts
│ │ ├── agents.ts
│ │ ├── cast.ts
│ │ ├── inspect.ts
│ │ └── config.ts
│ └── lib/
│ ├── client.ts # viem public/wallet client factory
│ ├── config.ts # ~/.magics/config.json
│ ├── keystore.ts # scrypt + AES-256-GCM encrypted keystore
│ ├── addresses.ts # per-chain address book
│ ├── abi.ts # ABI fragments
│ ├── signing.ts # EIP-712 Cast intent signing
│ ├── format.ts # terminal formatting helpers
│ ├── prompt.ts # interactive prompts (suppressible)
│ └── errors.ts # typed error surface + exit codes
├── package.json
├── tsconfig.json
└── README.mdLicense
MIT. See LICENSE.
