Skip to content

feat(cli): receipt --event decoding, wallet password, per-line balance - #94

Open
erikzrekz wants to merge 2 commits into
mainfrom
eriks-claude/open-issues
Open

erikzrekz wants to merge 2 commits into
mainfrom
eriks-claude/open-issues

Conversation

@erikzrekz

@erikzrekz erikzrekz commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

Addresses all three open issues.

#11 — receipt --event <sig>

  • New src/lib/events.ts: parseEventSignature and decodeLogs.
    • Signatures are cast-style, with an optional event prefix.
    • Parsing reuses findMatchingClose from signature.ts, so trailing content and malformed signatures fail with a clear error.
  • A log is decoded when topics[0] equals the event's selector and its topic count matches the number of indexed params. That count also separates ERC-20 Transfer from ERC-721 Transfer, which share a selector.
  • When the selector matches but the topic count doesn't (usually a missing indexed), or the data doesn't decode, the log stays raw and a warning goes to stderr. Logs that match no signature pass through raw and are never dropped.
  • A log doesn't record which params were indexed. A signature that marks the same number of params as indexed, but different ones, therefore decodes to wrong values without a warning. This caveat is in the help text and the docs.
  • --json prints an array: {address, logIndex, eventName, args} for decoded logs and {address, logIndex, topics, data} for raw ones. Args follow signature order; unnamed params are keyed by position; bigints are decimal strings.
  • The human output starts with Status:. On a reverted transaction the command writes an error to stderr and exits 1, so a revert never reads as "no matching events".
  • Signatures are parsed before the RPC call, so a bad one fails fast.

#7 — greppable balance

wallet balance without --json now prints one line per asset, each written as amount plus asset:

Address: 0x…
SBC:     0.030002 SBC
RUSD:    0.129961 RUSD
Total:   0.159963 USD

If the SBC read fails, that line shows only the first line of the error. --json is unchanged. The changeset marks this as Breaking for scripts that parse human output. The now-unused formatUsdShort is removed.

#1 — password for the auto-created wallet

Following the discussion on the issue, creating a keystore still never prompts, so agents don't block. The gap was the recovery path: the notice and README pointed to wallet new --force, which replaces the key and strands any funds on the old address. This PR adds:

  • wallet password: re-encrypts the keystore under a new password and keeps the same key and address.
    • RADIUS_NEW_PASSWORD, at least 8 characters, makes it non-interactive. An empty value is rejected.
    • --remove is the only way to strip the password.
    • A passwordless keystore decrypts with '' even when RADIUS_PASSWORD is exported. A decrypt failure names the source of the wrong password.
  • The auto-create notice now points to wallet password and to RADIUS_PASSWORD.
  • saveKeystore writes a uniquely named temp file (opened 'wx' at 0o600), fsyncs it, then renames it into place. If the keystore path is a symlink, it writes to the link's target and keeps the link.

Docs, changeset, skills

  • CLI README and docs/pages/reference/radius-cli.mdx updated.
  • Changeset: radius-cli minor.
  • Skills audit: the skills only use wallet balance --json and receipt <tx>, and neither changed. The new commands aren't on npm yet, so the skills don't name them and the plugin version isn't bumped.

Validation

  • pnpm build, pnpm typecheck, pnpm test (cli: 85 tests, covering event decoding, balance formatting, keystore password changes, symlinks and temp-file cleanup)
  • docs: format:check, lint, typecheck:docs, docs:validate, test:skills, docs:markdown-audit, build, docs:agent-check, docs:sitemap-check
  • Ran the built CLI against a local mock RPC (the testnet RPC isn't reachable from the sandbox) to check receipt --event output, the missing-indexed warning and the exit code on a revert.
  • Ran every wallet password path end to end on a throwaway RADIUS_HOME: empty env value, exported RADIUS_PASSWORD, wrong current password, --remove. Nothing was spent from a funded wallet.

Closes #11
Closes #7
Closes #1

🤖 Generated with Claude Code

https://claude.ai/code/session_0168UCoE4YkJyyaAW9RdKdLo

- receipt --event <sig> (repeatable) decodes logs against cast-style event
  signatures; unmatched logs pass through raw, selector matches with the
  wrong topic count warn on stderr (closes #11)
- wallet balance prints SBC:, RUSD: and Total: on separate lines (closes #7)
- wallet password re-encrypts the keystore under a new password, keeping
  the key; the auto-create notice points to it instead of wallet new
  --force, and keystores are written via temp file + rename. Creation stays
  non-interactive (closes #1)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0168UCoE4YkJyyaAW9RdKdLo
@github-actions

github-actions Bot commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

🦋 Changeset detected

Latest commit: fd04a56

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
radius-cli Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions

github-actions Bot commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

@erikzrekz
erikzrekz marked this pull request as ready for review October 27, 2026 19:58

@azf20 azf20 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review notes inline — the main ones are receipt --event hiding reverts and the RADIUS_NEW_PASSWORD empty-value path.

Comment thread packages/cli/src/commands/receipt.ts
Comment thread packages/cli/src/commands/wallet.ts Outdated
Comment thread packages/cli/src/commands/wallet.ts Outdated
Comment thread packages/cli/src/lib/keystore.ts Outdated
Comment thread packages/cli/src/lib/keystore.ts Outdated
Comment thread packages/cli/src/lib/erc20.ts Outdated
Comment thread packages/cli/src/lib/erc20.ts
Comment thread packages/cli/src/lib/events.ts
Comment thread packages/cli/src/lib/events.ts
Comment thread packages/cli/src/lib/events.ts Outdated
…e writes

- receipt --event prints Status and exits 1 on a reverted transaction
- wallet password: RADIUS_NEW_PASSWORD needs 8+ characters, --remove is the
  only way to strip the password, a passwordless keystore decrypts with ''
  even when RADIUS_PASSWORD is exported, decrypt failures name the source
- saveKeystore: unique tmp name opened 'wx' at 0o600, fsync before rename,
  writes through a symlinked path to its target, tmp cleaned up on failure
- wallet balance: amount plus asset per line, SBC error kept to one line
- events: reuse findMatchingClose (rejects trailing content), errDetail
  helper, RawLogEntry = RawLog, document the indexed-position caveat

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0168UCoE4YkJyyaAW9RdKdLo

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

3 participants