MINARA

x402 paywall pre-authorization

x402 paywall pre-authorization (PR-X)

These vars bound the "session-level pre-authorization" feature that lets an operator authorize x402 paywall payments ONCE for a given scope, then auto-pay (no per-call confirmation) until expiry / budget exhaustion / explicit revoke. The grant call itself ALWAYS goes through the unified confirm gate. After it lands a session row, in-window x402 payments matching the session's scope skip the per-call user prompt and execute directly via transfer_token. Every auto-spend writes audit metadata (session id + remaining budget) so the user can trace each charge. Wired into: - src/minara/x402-preauth-store.ts (SQLite store + cap math) - src/minara/x402-preauth-config.ts (env loader + cap helpers) - src/tools/_shared/confirm.ts (shouldAutoExecuteX402) - src/tools/trade.ts (transfer_token consults the auto-execute path; unmatched payments stay on the unified confirm gate) - src/tools/x402-preauth.ts (LLM-callable grant / list / revoke) - src/gateway/repl-commands.ts (/x402 preauth CLI surface)

X402_PREAUTH_DEFAULT_TTL_HOURS

default session expiry when the user / LLM doesn't specify one.

  • What it controls: the TTL applied when x402_preauth_grant is called without ttl_hours.
  • Consumed by: src/minara/x402-preauth-config.ts.
  • When to set: shorten to keep grants short-lived (e.g. 4 = 4h); raise to give long-running batch jobs more room.
  • When unset: 24 hours.
  • Format: positive integer (hours).
  • Setting home: Not a user-facing setting

X402_PREAUTH_MAX_TTL_HOURS

hard upper bound for non-forever session TTL.

  • What it controls: a grant request with ttl_hours > this value is rejected with field: "ttlMs". The cap helper enforces it uniformly across the LLM tool, the REPL command, and direct store access.
  • When to set: shorten to enforce shorter operator trust windows; raise only when long-lived sessions are a deployment requirement.
  • When unset: 168 (7 days).
  • Format: positive integer (hours).
  • Setting home: Not a user-facing setting

X402_PREAUTH_ALLOW_FOREVER

whether ttl_hours: "forever" (no time-based expiry) grants are allowed.

  • What it controls: when 0, the LLM tool + REPL + store reject forever-grant requests with field: "forever". The forever-budget cap is still read for documentation but never reachable. Set to 0 for environments that want hard-bounded expirations on every grant (audit / compliance).
  • When unset: 1 (forever grants permitted, gated by user-explicit double-confirm in the REPL + the LLM never proposes forever automatically).
  • Format: 1/true/yes/on (allow) or 0/false/no/off.
  • Setting home: Not a user-facing setting

X402_PREAUTH_MAX_PER_CALL_USDC

hard upper bound for a single auto-paid x402 payment (USDC).

  • What it controls: (a) the LLM tool + REPL reject grants with per_call_cap_usdc > this value; (b) shouldAutoExecuteX402 short-circuits with amount_over_cap for any single payment above this amount, falling back to the regular two-step confirm. This is the single most important safety bound — it caps how much a single bad paywall can drain even if the user granted a higher cap inside an existing session.
  • When to set: shorten on shared infrastructure to limit per-call blast radius. Raise only when paywalls legitimately cost more.
  • When unset: 0.5 (USDC).
  • Format: positive number (USDC).
  • Setting home: Not a user-facing setting

X402_PREAUTH_MAX_BUDGET_USDC

hard upper bound for a non-forever session's total budget (USDC).

  • What it controls: a grant request with total_budget_usdc > this AND a non-null ttl_hours is rejected. Forever-grant budgets use a separate (typically stricter) cap below.
  • When unset: 5 (USDC).
  • Format: positive number (USDC).
  • Setting home: Not a user-facing setting

X402_PREAUTH_MAX_FOREVER_BUDGET_USDC

hard upper bound for a forever-session total budget (USDC).

  • What it controls: same shape as MAX_BUDGET_USDC but applies only when ttl_hours: "forever". Independent because removing the time bound demands tighter $ control. The forever budget can be ABOVE or BELOW the time-bounded one — operators choose; the default sits higher because forever grants are usually small per-call that accumulate over months ("$0.01/call x 2000 calls").
  • When unset: 20 (USDC).
  • Format: positive number (USDC).
  • Setting home: Not a user-facing setting

X402_PREAUTH_DISABLE

global kill switch.

  • What it controls: when 1, every preauth code path short-circuits. transfer_token ignores x402_context, the LLM tools return disabled errors, the REPL prints "x402 preauth disabled by env" and refuses to grant. All x402 payments fall back to the regular two-step confirm flow.
  • When to set: incident response (suspected runaway paywall), compliance audit windows where every payment must be logged with explicit user confirm, or operators who never want this feature at all.
  • When unset: 0 (preauth machinery active).
  • Format: 1/true/yes/on to disable; anything else (default) keeps it on.
  • Setting home: Not a user-facing setting

OpenClaw workspace integration

The agent reads + writes a workspace dir at ~/.minara/workspace/ (override via --workspace) containing markdown files modelled on OpenClaw's AGENTS.default schema: SOUL.md (identity), AGENTS.md (rules), IDENTITY.md, USER.md, MEMORY.md (curated long-term), HEARTBEAT.md (between-session memo), BOOTSTRAP.md (first-run only), and memory/YYYY-MM-DD-*.md (daily logs). Templates ship under src/workspace/templates/. minara setup seeds them on first run. The seed is idempotent and never overwrites a file the user has already edited.

WORKSPACE_HEARTBEAT_ENABLED

per-turn HEARTBEAT.md state writer.

  • What it controls: when on, after every turn the agent writes <workspace>/HEARTBEAT.md with last_seen, session_id, surface, turn_count, last_user_query, plus heuristic open_loops extracted from the reply. The writer preserves any user-edited ## Schedule section verbatim across writes.
  • When to disable: read-only workspace mounts, CI runs, privacy- sensitive contexts where you don't want a session memo on disk.
  • When unset: ON.
  • Format: 0/false/no/off to disable; anything else (default) keeps it on.
  • Setting home: Settings → Preferences (schema key)

WORKSPACE_DAILY_LOG_ENABLED

append per-session daily logs.

  • What it controls: when on, each cadence flushes every unjournaled chat_turns row after a durable SQLite watermark into <workspace>/memory/YYYY-MM-DD-<session>.md. Rows retain their real session id, surface, and runtime source; correlation ids are never used as session ids. Per-session files avoid multi-process append races.
  • When to enable: long-running deployments where you want the agent to accumulate working memory you can later promote to MEMORY.md.
  • When unset: OFF (the workspace stays small until explicitly opted in).
  • Format: 1/true/yes/on to enable.
  • Setting home: Settings → Preferences (schema key)

WORKSPACE_DAILY_LOG_INTERVAL

turns between daily-log appends.

  • What it controls: cadence for flushing the chat_turns backlog above. Every due flush writes all rows after the watermark, so increasing the interval delays persistence but does not sample or drop intervening turns.
  • When unset: 5 turns.
  • Format: positive integer.
  • Setting home: Not a user-facing setting

WORKSPACE_DREAM_ENABLED

periodic MEMORY.md consolidation.

  • What it controls: when on, a setInterval task wakes every WORKSPACE_DREAM_INTERVAL_HOURS, reads recent daily logs from memory/, and asks the active LLM to extract durable facts / preferences / decisions. The result lands as a ## Dreamed YYYY-MM-DD section appended to MEMORY.md (append-only — user edits are never overwritten). Automation-origin journal turns remain auditable on disk but are removed before the LLM prompt, so Autopilot, strategy, workflow, or unknown perps runs cannot become user preferences.
  • When to enable: long-running deployments where the operator wants long-term memory to evolve from short-term logs without manual curation. Costs LLM calls — keep off in cost-sensitive contexts.
  • When unset: OFF.
  • Format: 1/true/yes/on to enable.
  • Setting home: Settings → Preferences (schema key)

WORKSPACE_DREAM_INTERVAL_HOURS

dream consolidation cadence.

  • What it controls: hours between dreaming runs. The scheduler skips a tick when the previous run is still in flight, so a slow LLM call can't pile up. Has no effect when WORKSPACE_DREAM_ENABLED is off.
  • When unset: 24 (one consolidation pass per day).
  • Format: positive number (hours, can be fractional).
  • Setting home: Not a user-facing setting

WORKSPACE_DREAM_TOTAL_INPUT_BYTES

global byte budget for the dream prompt input (across all daily logs combined).

  • What it controls: caps the total bytes shipped to the LLM in one dream pass. Daily logs are kept as a contiguous newest-first suffix under the budget, so the model always sees a chronologically continuous slice with the most recent activity included. Defends against a long window of dense logs blowing past the model's context window. Per-file content is still tail-truncated to 64 KB (the per-file cap), and the most recent log is always kept even if alone exceeds this budget. Has no effect when WORKSPACE_DREAM_ENABLED is off.
  • When unset: 262144 (256 KB).
  • Format: positive integer (bytes).
  • Setting home: Not a user-facing setting

WORKSPACE_DREAM_LOCK_TTL_MS

TTL for the dream lockfile.

  • What it controls: how long a <workspace>/.dreaming.lock file is honored before it's considered stale and reclaimable by another process. Should reflect the longest reasonable duration for a single dream pass (LLM call + IO), NOT the interval between passes. The lock prevents the REPL and HTTP gateway from both consolidating the same logs into MEMORY.md when their tick windows overlap. NFS workspaces are not supported (the underlying O_EXCL semantics are not guaranteed atomic across all NFS clients) — keep dreaming on a single host. Has no effect when WORKSPACE_DREAM_ENABLED is off.
  • When unset: 1800000 (30 minutes).
  • Format: positive integer (milliseconds).
  • Setting home: Not a user-facing setting

REPORT_BUNDLE_CHART_PNGS

fall back to PNG-bundled charts in deep-research HTML / PDF reports instead of interactive ECharts.

  • What it controls: when set, the gateway's deep-research branch passes ["html", "pdf", "charts"] to renderDeepResearchReport so bundleChartPngs runs and the HTML embeds each chart://<id> as a static <img src="charts/<id>.png"> tag (rendered server-side via headless playwright). When unset, the default since v7, the gateway passes ["html", "pdf"] only and every chart:// link expands to the canonical ECharts embed pattern (<div class="echart-host"> + inline <script> hydrated from the echarts CDN). Default produces interactive charts with zoom + tooltip + saveAsImage PNG download.
  • Which skill / tool consumes it: the deep-research pipeline (src/gateway/api.ts handleChatStream deep-research branch).
  • When to set it: operators who export reports for offline distribution (where the echarts CDN is unreachable) or who cannot tolerate the ~120 KB CDN script being fetched on open. Trade-off: PNG-bundled charts are static — no zoom, no tooltip, no PNG download button. Headless playwright must be installed (already a project dep) so chart materialisation can run.
  • When unset: interactive ECharts (CDN-hydrated). Open the HTML in a browser with network access to see charts; offline charts degrade to a small "chart unavailable" placeholder per the embed script's try/catch.
  • Format: 1 / true (enable) — any other value, or unset, disables.
  • Setting home: Settings → Preferences (schema key)

WALLET DEPOSIT WATCH

Real-time deposit-detection SSE endpoint (POST /v1/wallet/deposits/watch). Powers the green-flip in the Portfolio DepositModal for perps USDC/Arbitrum addresses. Two chain transports; the agent picks at boot: 1. Alchemy (preferred) — set ALCHEMY_API_KEY. Uses alchemy_getAssetTransfers (purpose-built incoming-transfer query) + alchemy_pendingTransactions WS subscription for real mempool sighting. Free tier: 300M CU / month. 2. Public RPC fallback — when no ALCHEMY_API_KEY. Polls eth_getLogs every 5s for the USDC Transfer event filtered to the deposit address. No mempool visibility (the pending event is not emitted in this mode). What it controls: WALLET_DEPOSIT_WATCH_ENABLED — master switch for the SSE endpoint. Default ON in dev so the feature works out of the box; set to false / 0 to disable cleanly. When off, the web-ui's DepositStatus pill shows "Live updates unavailable" and the user can still copy the address normally. Which skill / tool consumes it: apps/agent/src/wallet-watch/* and the api.ts handleWalletDepositsWatch handler.

WALLET_DEPOSIT_WATCH_ENABLED

WALLET_DEPOSIT_WATCH_ENABLED=true

  • Setting home: Settings → Preferences (schema key)

ALCHEMY_API_KEY

Alchemy API key for Arbitrum. One key works across all Alchemy chains. Optional — without it the watcher falls back to the public Arbitrum RPC (no mempool detection). ALCHEMY_API_KEY=abc123...

  • Setting home: Settings → API Keys

ALCHEMY_NETWORK

Alchemy network enum string. arb-mainnet is the only one we care about today (perps wallet deposits = USDC on Arbitrum). Override only if you point ALCHEMY_API_KEY at a testnet for end-to-end QA. ALCHEMY_NETWORK=arb-mainnet

  • Setting home: Not a user-facing setting

ARBITRUM_RPC_URL

Public Arbitrum RPC URL — used when ALCHEMY_API_KEY is unset.

SOLANA_RPC_URL

Public Solana RPC URL — used by the spot deposit watcher for the Solana chain. Non-EVM, so Alchemy isn't auto-wired; this URL is tried first, then the foundation-grade public list (api.mainnet- beta.solana.com, solana-rpc.publicnode.com, …) in order. The transport polls getSignaturesForAddress on the user's USDC token accounts every 5 seconds and flips to credited on the confirmed commitment.

DEPOSIT_WATCH_TIMEOUT_MS

How long a watch session lingers before auto-close (ms). Default 20 minutes — long enough for slow chain confirmation but caps resource use on a forgotten-open modal. DEPOSIT_WATCH_TIMEOUT_MS=1200000

  • Setting home: Not a user-facing setting

On this page