CLI / TUI — kryard
The kryard CLI is a single static binary that speaks both of Kryard's auth tiers: X-Stamp API-key access to the /public/v1/* surface (the same surface @kryard/sdk exposes), and human device login access to the /dashboard/v1/* surface (organizations, wallet reads, the operator console). It also ships an interactive TUI + scriptable --json subcommands, with secrets kept in the OS keychain (never argv, never a file).
The CLI is a sister surface to the SDK: each X-Stamp flow the SDK does, kryard --json does too — and additionally surfaces the dashboard tier, which the SDK does not. The two are byte-identical on the crypto paths; the xstamp header is RFC-6979 P-256, byte-identical to @kryard/sdk/viem, and the EVM signing path is byte-identical to the deployed KryardDelegate and viem.
Proven live on Sepolia
relay submit has broadcast a real managed-relay transaction on Sepolia (0x2a056e76…), and the EIP-7702 authorization produced by the CLI has been accepted on-chain. The sponsor (4337) command is built and tested against the 4337 paymaster shape.
Install
curl -fsSL https://kryard.com/install.sh | shKRYARD_VERSION=0.1.0 curl -fsSL https://kryard.com/install.sh | shcd cli && go build -o kryard ./cmd/kryardThe installer downloads a static binary from https://kryard.com/dl, verifies its SHA-256 against checksums.txt, and installs to /usr/local/bin (falling back to $HOME/.local/bin when that path is not writable). macOS/Linux × amd64/arm64; no Homebrew tap is wired yet.
| Variable | Default | Purpose |
|---|---|---|
KRYARD_VERSION | contents of /dl/latest | pin a specific release, e.g. 0.1.0 |
KRYARD_INSTALL_DIR | /usr/local/bin (else $HOME/.local/bin) | where to install |
KRYARD_BASE | https://kryard.com/dl | download base URL |
Confirm the install:
kryard version
# 0.1.0Two tiers, two logins
| Tier | Surface | How you log in | What you can do |
|---|---|---|---|
| API key (X-Stamp) | /public/v1/* | kryard login --api-key | everything the SDK does — query orgs/wallets/activities, sign, relay submit, sponsor, read balances |
| Device login (human) | /dashboard/v1/* | kryard login (no --api-key) | everything above PLUS multi-org org ls, session-authed dashboard reads, logout (/session) |
Because the API-key tier is identical to what the SDK exposes, the X-Stamp flow is the same one documented in /relay/quickstart and /signing/: you (or someone) registers an API key in the console and the CLI signs each request with its private half — the only difference is the CLI pulls the private key from the OS keychain rather than process.env.
The device-login tier is unique to the CLI: open the printed URL, sign in with email/passkey in the browser, approve, paste the phrase the page prints. The CLI stores the refresh token in the keychain, caches the short-lived access JWT, and rotates on expiry. Logout revokes.
Quickstart (API-key tier)
kryard login --api-key --generate # mint a P-256 key; prints the PUBLIC half
# → register that public key in the Kryard console (API Keys), then:
kryard org use <organization-id>
kryard whoami
kryard wallets ls
kryard activities ls
kryard relay balance
kryard tui # interactive dashboardImport an existing API key instead of generating (the private key is read from stdin, never argv — secrets never show up in ps or shell history):
kryard login --api-key # paste the private key hex when promptedCI / non-interactive (no keychain): set KRYARD_API_PUBLIC_KEY + KRYARD_API_PRIVATE_KEY and use --json for every command — the config + keychain seam is bypassed entirely.
Quickstart (device tier)
kryard login # browser-based phrase flow
kryard org ls # multi-org users only see this here
kryard org use <id>
kryard logout # revoke the sessionorg ls (your organizations across the operator account) lives on the device tier, not the API-key tier, because API keys are scoped to one org — a single API key cannot list the orgs a human user belongs to.
Relay & sponsorship write lanes
The CLI signs your own EOA for the managed-relay + 4337 lanes; the relayer key itself stays Kryard-custodied. Import your EOA key once (read from stdin, never argv; only the address is ever printed):
kryard eoa import # paste the EOA private key hex → prints the address
kryard eoa address # show the stored EOA addressSponsor an EIP-7702 transaction through the managed relay — for the sponsorExecute shape, attach the 7702 authorization:
kryard relay submit --key <relayer-addr-or-id> --chain 11155111 --to 0x… \
[--value <wei>] [--data 0x…]
# 7702 sponsored execution (signs the authorization with the stored EOA key):
kryard relay submit --key <relayer> --chain 11155111 --to 0x… \
--authorize <delegate-contract> --auth-nonce <eoa-account-nonce>
kryard relay status <transaction-id>Request ERC-4337 gas sponsorship for a v0.7 UserOperation (the UserOp is read from a file or stdin as JSON):
kryard sponsor --chain 11155111 --user-op ./userop.json \
[--valid-after <unix-sec>] [--valid-until <unix-sec>]Values the CLI cannot source offline
The 7702 authorization nonce is the EOA's own account nonce (--auth-nonce) — the CLI does not fetch account state to avoid a stale-nonce race; pass it explicitly. Gas limit is the one other override (--gas-limit); the relay pipeline sources everything else (relayer nonce, fees, gas estimation) server-side.
Scripting — --json
Every command accepts --json and prints machine-readable output (skipping the human formatting). This is what the X-Stamp tier emits anyway — the activity envelope is JSON — so the scriptable mode is the same shape the SDK returns.
kryard --json wallets ls | jq '.[] | {id, address, organizationId}'Global flags
--json, --org <id> (override the saved default), and --profile <name> (select a named config profile) apply to every command. The defaults are stored in ~/.config/kryard/config.toml.
Security model
- Secrets in the OS keychain, never argv, never a config file.
loginandeoa importread the private key from stdin so it never appears inpsor shell history. Only the address of a stored EOA key is printed at any point. - Crypto is byte-pinned to the canonical SDK/viem — the X-Stamp header, the KryardDelegate EIP-712 digest, and the EIP-7702 authorization hash all match
@kryard/sdk/viembyte-for-byte. Drift is a failing test, not a production incident. - No wallet keys leave the client. The CLI signs the user's own EOA for the 7702 authorization + 4337 sponsor lanes; Kryard's signer only holds the relayer key. This is the same division as the SDK — see
/relay/quickstart.
Next steps
- CLI command reference — every subcommand, every flag.
- Relay quickstart — the same flow via the SDK, side-by-side.
- Signing API — the
/public/v1/*surface the CLI speaks.