Skip to content

Injected-provider wallet signing: spec for nom-webwallet + InjectedZenonSigner (flagged) - #2

Merged
0x3639 merged 4 commits into
mainfrom
injected-provider
Aug 29, 2026
Merged

0x3639 merged 4 commits into
mainfrom
injected-provider

Conversation

@0x3639

@0x3639 0x3639 commented Aug 29, 2026

Copy link
Copy Markdown
Owner

Summary

Groundwork for signing with a browser-extension wallet instead of the in-page keystore — MetaMask-style injected provider, no WalletConnect.

  • docs/proposals/zenon-injected-provider.md — a provider spec written for nom-webwallet's "Phase 2": content script + inpage window.zenon, EIP-6963-style discovery (zenon:announceProvider / zenon:requestProvider), methods zenon_requestAccounts / zenon_accounts / zenon_chainId / zenon_sendBlock({template}) with zwap's ZenonTemplate JSON as the wire schema, events, EIP-1193-style error codes, and security requirements (origin permissions, decoded confirmations, no key exposure). Intended to be filed as an issue/PR against https://github.com/digitalSloth/nom-webwallet.
  • src/zenon/injected-signer.tsdetectInjectedProvider() and InjectedZenonSigner implementing the existing ZenonSigner interface: verifies chain id before requesting accounts, validates every value the extension returns, serialized sends, provider error codes passed through.
  • Wiring behind VITE_INJECTED_WALLET=1 — when a provider is detected the account panel offers Connect wallet; once connected, the trade runtime signs through the extension and the keystore-only actions (createWallet / importWallet / revealMnemonic / clearWallet) are refused by a structural guard, not just hidden. With the flag unset, behaviour is unchanged.

Stacked on #1 (zenon-dex). Tests: 589 passed / 1 skipped; typecheck + build green.

Test plan

  • npm ci && npm run typecheck && npm test && npm run build
  • With VITE_INJECTED_WALLET=1 and no extension installed: app behaves exactly as before
  • Once an extension implements the proposal: Connect wallet → address shown → post/take an order → blocks signed by the extension

🤖 Generated with Claude Code

https://claude.ai/code/session_01C4rUSnTuZarM7aNR4F6hAv

0x3639 and others added 4 commits August 28, 2026 21:21
Adds the page half of the proposed Zenon injected-provider protocol:
EIP-6963-style discovery (announce event, `window.zenon` fallback, null on
timeout) and a `ZenonSigner` that sends blocks through the extension
instead of a local key pair. Sends are serialized per instance exactly as
`KeystoreSigner` serializes them - the extension builds each block on the
frontier the previous one produced.

The extension is a foreign process, so everything it returns is validated:
accounts against `isZenonAddress`, published hashes against `isHex32`, and
its thrown values re-shaped into `InjectedProviderError` keeping the
wallet's own code (4001 rejected, 4100 unauthorized, 4901 chain mismatch).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C4rUSnTuZarM7aNR4F6hAv
A spec to file against nom-webwallet Phase 2: content script plus inpage
provider, EIP-6963-style announcement, and one write method
(`zenon_sendBlock`) that takes zwap's `ZenonTemplate` union verbatim as its
wire schema. The wallet fills address/height/previousHash and the fee mode;
the page supplies only the semantics of the block.

The parts that matter most for HTLC settlement are the encoding rules -
amounts as decimal strings, hex bare and lowercase, `hashType` 1 and
`keyMaxSize` 32 rejected if anything else - and the requirement that the
confirmation decode the embedded-contract call rather than show raw data.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C4rUSnTuZarM7aNR4F6hAv
…WALLET

With the flag on, startup runs `detectInjectedProvider(window)` and the
account panel gains a "Connect wallet" outline action badged with the
extension's name. Connecting swaps the page's signer: the trade runtime,
`ZwapState.address`, balances, receive and send all move to the extension's
address, and the seed reveal and local-wallet erase are hidden because the
profile's keystore is no longer the wallet in use.

`ZwapState` grows `walletSource` so the panel can tell the two apart, and
the injected snapshot reports no plasma bot and no PoW warning - the
extension owns the fee decision and shows it in its own confirmation. With
the flag off, or with nothing detected, every path is byte-for-byte the one
that was there before.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C4rUSnTuZarM7aNR4F6hAv
…igns

Hiding the reveal and the erase in the panel was a UI courtesy, not a rule:
`window.zwap` is a public surface, so an agent script could still call
`createWallet`, `importWallet`, `revealMnemonic` or `clearWallet` during an
extension session and read or destroy a seed that is not the wallet in use.

`guardKeystoreActions` wraps those four behind a pure guard that reads the
wallet source per call, so connecting an extension mid-session closes the
door immediately and nothing reaches the keystore before the refusal.
`resetProfile` stays unguarded on purpose - it is not a keystore action but
the whole-profile escape hatch, and it erases the trade journal and Nostr
identity the extension session is itself using.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C4rUSnTuZarM7aNR4F6hAv
@coderabbitai

coderabbitai Bot commented Aug 29, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 2de8b2a8-7148-4446-a6dd-39205fc104be

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

Base automatically changed from zenon-dex to main August 29, 2026 10:59
@0x3639
0x3639 merged commit aee4db5 into main Aug 29, 2026
2 checks passed
@0x3639
0x3639 deleted the injected-provider branch August 29, 2026 10:59
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.

1 participant