fix(openclaw): 0.4.2 — verified Pinata install flow + security warnings preamble#23
Merged
Merged
Conversation
…gs preamble A live Pinata Agents install of 0.4.1 surfaced one code bug, two doc lies, and one missing operator preamble. This bundle ships all four fixes as 0.4.2. ## Code: `Plugin loaded:` now reports the actual tool count The README told operators to grep for `[xpr-agents] Plugin loaded: 72 tools (35 read, 37 write)` — a string the code never emitted. The code emitted `Plugin loaded: <network> (<rpc>)`, no count. Rather than backing out the README claim, instrument the registration. `xprAgentsPlugin()` now wraps `api.registerTool` with a counter and logs: [xpr-agents] Plugin loaded: 72 tools, mainnet (https://proton.eosusa.io) The count is computed from real registrations, so it auto-tracks any future tool additions and the README claim stays true. ## Doc lie 1: harness install path was unverified README and PINATA.md hand-waved "register with your harness" because we'd never actually traced what an OpenClaw harness does with the package. Now verified empirically: - Plain `npm install @xpr-agents/openclaw` is NOT sufficient — the harness does not auto-scan workspace `node_modules`. - The supported install is `openclaw plugins install @xpr-agents/openclaw` which downloads from npm, copies to `~/.openclaw/extensions/openclaw/`, and auto-writes both `plugins.entries.openclaw.enabled` and `plugins.installs.openclaw.*` metadata (sha256, integrity, install path, ISO timestamp) to `~/.openclaw/openclaw.json`. Docs now show the verified command, the exact JSON diff the installer writes, and explicitly call out the `npm-install-is-not-enough` trap. ## Doc lie 2: `XPR_ACCOUNT` placement was ambiguous PINATA.md (and implicit in the README's env block) suggested `XPR_ACCOUNT` could go in the plugin's config tree. It can't — the plugin reads `process.env.XPR_ACCOUNT`, which is populated from the gateway env layer (`env.vars` in `openclaw.json`), NOT from `plugins.entries.openclaw.config`. Operators putting it in the config tree end up in silent read-only mode. Docs now show the correct `env.vars.XPR_ACCOUNT` surface with a contrastive note pointing at the wrong location. ## Missing preamble: 19 install-time security warnings OpenClaw's installer scans tarballs and flags risky patterns. It finds 19 in `@xpr-agents/openclaw` — every one intentional and named in the new "Security notes" section: - 16 × env-var-plus-network-send: each skill reads its own service API key (REPLICATE_API_TOKEN, GITHUB_TOKEN, PINATA_JWT, SHELLBOOK_API_KEY, COINGECKO_API_KEY, A2A_SIGNING_KEY) and calls that service. No blockchain key is read from env. - 2 × dynamic-code-execution: that is literally what the `code-sandbox` skill does. - 1 × child_process exec: the proton CLI shell-out. The post- charliebot security feature itself, ironically flagged. The whole point of v0.4.x is that the blockchain key never enters the agent process — it stays in the proton CLI's encrypted keychain and we cross that trust boundary via this exec call. Operators evaluating the package see 19 lines of red text at install time and bail. The new section pre-empts that. ## Pinata-specific restart mechanism The imperative `openclaw gateway restart` doesn't work on Pinata's container — they don't expose systemctl, the command errors with "Gateway service disabled." The actual mechanism is config-driven: patching `openclaw.json` makes the harness emit SIGUSR1 to the gateway process. PINATA.md now documents this with the expected restart event shape. ## Harness-vs-standalone registration gap The standalone `create-xpr-agent` scaffold auto-registers via the runner's `ensureRegistered()`. The harness path loads only the plugin, so the account stays absent from `agentcore::agents` until the operator explicitly calls `xpr_register_agent`. Every `xpr_update_*` / `xpr_set_agent_status` call fails with `Agent not found` until then. Docs now name this explicitly and use `xpr_register_agent` as the canonical "first signed test" — replacing the previous "send 0.0001 XPR" recipe that didn't work anyway (the plugin has no transfer tool; it's domain-scoped to the registry/escrow/feedback/validation/ A2A surface). ## Verification - 80 openclaw tests pass - Smoke-test confirms `Plugin loaded: 72 tools, mainnet (...)` line emitted by `dist/index.js` - All harness-flow specifics verified against a live OpenClaw 2026.3.x install (Pinata Agents container)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A live Pinata Agents install of 0.4.1 surfaced one code bug, two doc lies, and one missing operator preamble. This bundle ships all four fixes as 0.4.2.
Code:
Plugin loaded:now reports the actual tool countThe README told operators to grep for
[xpr-agents] Plugin loaded: 72 tools (35 read, 37 write)— a string the code never emitted (it loggedPlugin loaded: <network> (<rpc>), no count). Rather than backing out the README claim, this PR instruments registration:xprAgentsPlugin()wrapsapi.registerToolwith a counter and logs:The count is computed from real registrations, so the README claim stays true even if tools are added.
Doc lie 1: harness install path was unverified
The docs hand-waved "register with your harness" because we'd never actually traced what an OpenClaw harness does with the package. Now verified empirically on a live Pinata Agents container running OpenClaw 2026.3.x:
npm install @xpr-agents/openclawis NOT sufficient — the harness does not auto-scan workspacenode_modules.openclaw plugins install @xpr-agents/openclaw, which downloads from npm, copies to~/.openclaw/extensions/openclaw/, and auto-writesplugins.entries.openclaw.enabled+plugins.installs.openclaw.*metadata to~/.openclaw/openclaw.json.Docs now show the verified command + the exact JSON diff the installer writes + explicit "
npm installis not enough" callout.Doc lie 2:
XPR_ACCOUNTplacement was ambiguousPINATA.md suggested
XPR_ACCOUNTcould go in the plugin's config tree. It can't — the plugin readsprocess.env.XPR_ACCOUNT, which comes fromenv.varsinopenclaw.json, NOT fromplugins.entries.openclaw.config. Operators who put it in the config tree silently end up in read-only mode.Docs now show the correct
env.vars.XPR_ACCOUNTsurface with a contrastive note pointing at the wrong location.Missing preamble: 19 install-time security warnings
OpenClaw's installer scans tarballs and flags risky patterns. It finds 19 in
@xpr-agents/openclaw— every one intentional, now explained in a new "Security notes" section in the README:child_processexeccode-sandboxskill's entire purpose.Pre-empts the 19-lines-of-red-text-at-install moment that was making operators bail.
Pinata-specific restart mechanism
openclaw gateway restartdoesn't work on Pinata's container — they don't expose systemctl, command errors with "Gateway service disabled." The actual mechanism: patchingopenclaw.jsonmakes the harness emitSIGUSR1to the gateway process. PINATA.md now documents this with the expected restart event shape.Harness-vs-standalone registration gap
Standalone scaffold auto-registers via
ensureRegistered(). Harness path doesn't. Everyxpr_update_*/xpr_set_agent_statusfails withAgent not founduntil the operator explicitly callsxpr_register_agent. Docs now name this and usexpr_register_agentas the canonical first-signed-test (replacing the previous "send 0.0001 XPR" recipe — the plugin has no transfer tool, it's domain-scoped).Verification
Plugin loaded: 72 tools, mainnet (...)line emits fromdist/index.js