Skip to content

Recognize account API mode in the Hermes integration - #37

Closed
KillerQueen-Z wants to merge 2 commits into
BlockRunAI:mainfrom
KillerQueen-Z:docs/account-api-key
Closed

Recognize account API mode in the Hermes integration#37
KillerQueen-Z wants to merge 2 commits into
BlockRunAI:mainfrom
KillerQueen-Z:docs/account-api-key

Conversation

@KillerQueen-Z

Copy link
Copy Markdown
Contributor

Hermes already passes its environment into the supervised ClawRouter process, so this change makes account mode explicit and reviewable: detect shared account credentials without reading or creating a wallet, make doctor accept account-or-wallet configuration, and document registration, key/credits setup, account billing and wallet-only trading boundaries. Wallet guidance is Solana-first.

Validation: package builds; Python compile passes; 18 focused account/doctor/supervisor tests pass. Full suite: 84 pass, 3 skip, and one external catalog-parity test fails because the unrelated sibling ClawRouter checkout in this workspace has an older top-models.json than this repo's catalog (not changed here). Account propagation is asserted through the existing child environment construction. Requires ClawRouter #338 release before released support.

@VickyXAI

VickyXAI commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Thanks for this — and sorry for the timing. This is closing as superseded, not rejected: the feature you're adding shipped last week in #39 ("Release 0.4.0: pay with a BlockRun API key, not only an x402 wallet", 5e373bc). This branch is based on 237cb36, which predates it, so the duplication isn't visible from here.

What's already on main

src/clawrouter_hermes/api_key.py is a deliberate port of ClawRouter/src/api-key.ts, so the plugin and the proxy resolve the same credential the same way:

  • resolve() — env BLOCKRUN_API_KEY~/.blockrun/.api-key → legacy ~/.openclaw/blockrun/api-key, plus is_valid(), mask(), save(), clear(), verify(), summary()
  • login / logout / account CLI subcommands and /clawrouter account|logout
  • auth-aware doctor, setup, and 401/402 hints
  • proxy_supervisor.desired_auth_mode(), which stops a wallet proxy on :8402 from serving an API-key user and billing the wrong account
  • tests/test_api_key.py

Landing account.py on top would leave two resolvers for one credential with different semantics — raise vs. warn-and-skip, different search paths, different validity rules — and the _doctor hunk conflicts with the API-key rows already there.

Worth knowing for next time

A few of these are real bugs independent of the duplication, and two of them are the same mistakes as in your ClawRouter #338, so they're worth carrying forward:

  1. doctor aborts instead of diagnosing. resolve_api_key() raises ValueError on a malformed key and the call at the top of _doctor is unguarded, so a stale or mistyped BLOCKRUN_API_KEY produces a traceback and zero rows — no Node check, no proxy check, no wallet check — even when the user's x402 wallet is perfectly fine. Diagnosing broken configuration is the one thing that command exists to do; it should print a failed row, not exit.

  2. Presence test instead of value test. if "BLOCKRUN_API_KEY" in os.environ is true for export BLOCKRUN_API_KEY= and for a CI secret that failed to interpolate. key becomes "", the ~/.blockrun/.api-key branch is never reached, and the user is told their valid stored key is invalid and that wallet fallback was refused. api_key.resolve() uses os.environ.get(...).strip() and falls through when empty. (Same shape as the !== undefined env guard in #338 — FOO="" is a common CI idiom for "unset".)

  3. Missing the legacy path ~/.openclaw/blockrun/api-key, so doctor can report "not configured" and point at a nonexistent mnemonic while the proxy it spawned is genuinely running in API-key mode.

  4. read_text() unguardedis_file() passing doesn't mean readable. A .api-key written under sudo, a wrong-owner 0600 file, or a stale network mount raises PermissionError out of _doctor. api_key._read_optional() catches OSError for exactly this.

  5. Validity rule too weak. startswith("brk_") accepts brk_ alone; ^brk_[A-Za-z0-9_-]{8,}$ exists so doctor doesn't report ✓ for a credential the gateway answers with an opaque 401.

  6. tests/test_account.py:8 is vacuous. It asserts ~/.openclaw/blockrun/mnemonic doesn't exist under isolated_home, where HOME is a fresh tmp_path — nothing exists there regardless of what the code does, so it can't fail. To prove "detects account credentials without creating a wallet", assert the resolver ran and that the wallet-creating path was not called.

Also: pyproject.toml here still pins 0.3.20 (main is 0.4.0), and the README section gates the feature on unreleased ClawRouter #338 while main already assumes the released rail and documents hermes-clawrouter login.

If you'd like to keep contributing here, #338 is the live one — the ClawRouter side is being rebased now, and the two design points under discussion are keeping the logUsage write on the accountPassthrough branch (dropping it would re-hide Surf/Exa/pm calls from /stats, which 934bea4 just fixed) and making sure resolveApiKey()'s deliberate throw isn't swallowed by a .catch(() => undefined) upstream. Your instinct there — never silently fall back to spending USDC when the user meant to bill their account — is the right one.

@VickyXAI

VickyXAI commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Closing as superseded by #39 (0.4.0, 5e373bc), which shipped the API-key rail with a shared resolver, login/logout/account commands, and the auth-mode proxy guard. Details and the standalone bugs are in the review above — nothing here is wasted if you carry those forward to ClawRouter #338.

@VickyXAI VickyXAI closed this Sep 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants