Skip to content

Commands

Every subcommand returns a structured envelope under --json. For the walkthrough, see Quickstart.

FlagDefaultDescription
--jsonoffstructured envelope to stdout
--quietoffbody to stdout only (no envelope chrome)
--project <name>resolvedoverrides project resolution
--gateway <url>https://api.pactnetwork.iogateway URL
--rpc <url>https://api.mainnet-beta.solana.comSolana RPC
--cluster <c>mainnetcluster (mainnet only in v1)

Every --json invocation returns:

{
"status": "ok",
"body": { /* command-specific */ },
"meta": { /* optional, present on covered calls */ }
}

status values: see Status taxonomy. body shape is per-command. meta is present on covered calls and carries slug, call_id, latency_ms, outcome, premium_lamports, premium_usdc, tx_signature, settlement_eta_sec when the gateway returns them.

Default when the first positional arg is a URL. Looks up the slug in the discovery cache, takes a premium, proxies through the gateway.

Terminal window
pact --json https://api.helius.xyz/v0/addresses/<addr>/balances
FlagDefaultDescription
--method <m>GETHTTP method
--header <h>repeatable HTTP header
-d, --data <body>request body
--rawoffskip slug rewriting (no coverage)
--timeout <sec>30timeout in seconds

Success envelope:

{
"status": "ok",
"body": { /* upstream response */ },
"meta": {
"slug": "helius-rpc",
"call_id": "...",
"latency_ms": 312,
"outcome": "ok",
"premium_usdc": 0.0001,
"tx_signature": null,
"settlement_eta_sec": 600
}
}

Common failures: no_provider (hostname unknown), endpoint_paused, needs_funding, discovery_unreachable.

pact pay <tool> [args...] — refund-backed 402 wrapper

Section titled “pact pay <tool> [args...] — refund-backed 402 wrapper”

Drop-in for solana-foundation/pay (pay.sh): same argv, exit codes, and x402 + MPP wire format, plus Pact’s chargeback layer. On a 402, pact pay parses the challenge, signs a pact-allowance authorization, and re-runs the wrapped tool with the retry header attached.

Terminal window
pact pay curl https://api.example.com/v1/quote/AAPL
pact pay curl -X POST -d '{...}' https://api.example.com/v1/orders

Wraps curl only as of v0.3.0.

pact pay and pact approve sign with pay.sh’s active account (resolution: PACT_PRIVATE_KEY → pay’s active account → throw). Same wallet pays the merchant and holds the allowance — fund pay once. On every payment attempt, stderr gets:

[pact] wallet: pay/default (4Zx9…k2Vp)

On success, the wrapped tool’s stdout/stderr/exit pass through. With --json: success is x402_payment_made or mpp_payment_made (exit 0) and .body.tool_exit_code carries the wrapped tool’s exit.

Failures get dedicated non-zero exits so shell chains break on typo or rejected challenge:

StatusExitWhen
unsupported_tool50tool isn’t in SUPPORTED_TOOLS (currently only curl) — fires even with the mainnet gate closed so chains stop on typos
tool_missing51tool is supported but not installed on $PATH
payment_failed31a 402 challenge was parsed but the retry was rejected — see body.scheme and body.reason
client_error0unknown 402 envelope, no supported network, MPP session-challenge, or mainnet gate closed

If no wallet resolves, coverage is skipped with [pact] coverage skipped: no wallet — set up pay or PACT_PRIVATE_KEY; the wrapped tool’s exit code is unchanged.

Reports ATA balance, allowance granted to SettlementAuthority, and an eligible flag mirroring what the program sees at debit time.

Terminal window
pact balance --json
{
"status": "ok",
"body": {
"wallet": "<base58>",
"ata": "<base58>",
"ata_balance_usdc": 12.5,
"allowance_usdc": 5,
"eligible": true
}
}

When eligible is false, body.reason is one of: no_allowance, insufficient_balance, insufficient_allowance.

pact approve <usdc> — grant settlement allowance

Section titled “pact approve <usdc> — grant settlement allowance”

SPL Token Approve delegating up to <usdc> from your ATA to SettlementAuthority. Funds stay in your ATA; the protocol debits up to the allowance at settlement.

Signs with pay.sh’s active account (default) or PACT_PRIVATE_KEY. Silent no-op if pay’s account has no SOL — fund pay first.

Terminal window
pact approve 5
{
"status": "ok",
"body": {
"tx_signature": "<base58>",
"confirmation_pending": false,
"allowance_usdc": 5
}
}

If the amount exceeds the per-deposit cap or session total in ~/.config/pact/<project>/policy.yaml, returns auto_deposit_capped (exit 11) without sending.

SPL Token Revoke on the agent’s ATA — SettlementAuthority can’t debit until you approve again. Signs with the same wallet as approve.

Terminal window
pact revoke

pact agents show [pubkey] — inspect calls and balances

Section titled “pact agents show [pubkey] — inspect calls and balances”

Reads ${gateway}/v1/agents/<pubkey> — recent calls, refunds, aggregate stats. Defaults to the project wallet’s pubkey.

Terminal window
pact agents show --json
pact agents show <other-agent-pubkey> --json

The body is the gateway response verbatim. See Protocol Reference → Endpoints for the response schema.

pact agents watch [pubkey] — stream live events

Section titled “pact agents watch [pubkey] — stream live events”

Streams SSE from ${gateway}/v1/agents/<pubkey>/events as JSON lines. Runs until killed.

Terminal window
pact agents watch
# {"type":"call","slug":"helius-rpc","outcome":"ok","premium_usdc":0.0001,...}
# {"type":"settlement","tx_signature":"...","settled_calls":12,...}

pact calls show <call_id> — inspect a single covered call

Section titled “pact calls show <call_id> — inspect a single covered call”

Reads ${gateway}/v1/calls/<call_id> — outcome, latency, premium, refund (if any), and the on-chain settlement signature once batched.

<call_id> is the UUIDv4 from the X-Pact-Call-Id response header (also meta.call_id on pact <url> --json).

Terminal window
pact calls show 11111111-2222-4333-8444-555555555555 --json

The ID is validated as RFC 4122 UUIDv4 before any network round-trip. A typo or a pasted wallet pubkey returns immediately:

{
"status": "client_error",
"body": {
"error": "invalid_call_id",
"message": "Call IDs are UUIDv4 (e.g. 11111111-2222-4333-8444-555555555555). Pass a wallet pubkey to `pact agents show` instead.",
"call_id": "<what-you-passed>"
}
}

Writes .claude/skills/pact/SKILL.md and appends a snippet to CLAUDE.md (or AGENTS.md if present) unless the marker is already there. Idempotent.

Terminal window
pact init
{
"status": "ok",
"body": {
"skill_installed": "/path/to/.claude/skills/pact/SKILL.md",
"claude_md_updated": "/path/to/CLAUDE.md"
}
}

See Quickstart → Agent integration for skill behavior in Claude Code / Codex.

Exit codes map 1:1 from status — useful for shell pipelines that branch without parsing JSON.

StatusExitMeaning
ok0call succeeded
client_error0bad request — your fault
server_error0upstream failed — refund queued
needs_funding10ATA balance / allowance insufficient
auto_deposit_capped11hit the per-deposit or session-total cap
endpoint_paused12provider disabled at gateway
no_provider20hostname not in discovery cache (terminal in private beta)
discovery_unreachable21gateway unreachable
signature_rejected30clock skew — sync NTP
payment_failed31pact pay parsed a 402 but the retry was rejected
x402_payment_made0pact pay --json succeeded via x402 retry
mpp_payment_made0pact pay --json succeeded via MPP retry
needs_project_name40project name could not be resolved
unsupported_tool50pact pay <tool> where <tool> is not in SUPPORTED_TOOLS
tool_missing51pact pay <tool> where <tool> is supported but not on $PATH
cli_internal_error99unexpected CLI error
VarEffect
PACT_MAINNET_ENABLED=1required closed-beta gate; without it every on-chain command short-circuits to client_error
PACT_PRIVATE_KEYbypass the disk wallet (base58 64-byte secret)
PACT_GATEWAY_URLoverride gateway URL
PACT_RPC_URLoverride Solana RPC URL
PACT_CLUSTERonly mainnet is accepted in v1
PACT_PROJECToverride project name resolution
PACT_AUTO_DEPOSIT_DISABLED=1block pact approve entirely

Per-project state under ~/.config/pact/<project>/:

  • wallet.json — keypair, mode 0600. Gateway flow only.
  • policy.yaml — auto-approve caps (per_deposit_max_usdc, session_total_max_usdc); also gates pact approve.
  • endpoints-cache.json — last fetched discovery entries.

pact pay / pact approve read pay.sh’s account from ~/.config/pay/accounts.yml via pay account export <name> -.