feat: WalletStateHook — condition-based wallet-state gating for _preFund#33
Conversation
…w, credentials Follow-ups per CONTRIBUTING.md on PR erc-8183#33: - WalletStateHook.sol: expand NatSpec to match BiddingHook/FundTransferHook style with USE CASE / FLOW / TRUST MODEL sections + Profile A label. - InsumerWalletStateVerifier.sol: add credentials block covering both paths — developers via POST /v1/keys/create (email-based, free tier) and agents via POST /v1/keys/buy (wallet-based, no email, USDC/BTC payment proves identity). - README.md: add WalletStateHook row to the Hook Examples table, Profile A. No code changes — docs only. forge build clean, forge test 21/21 pass.
Adds a minimal ERC-8183 hook that gates the fund stage on a condition-based wallet-state verifier. Complements existing score-based gating (TrustGateHook, erc-8183#9/erc-8183#32) and content-based verification (ReasoningVerifierHook, erc-8183#31) with a third shape: "does this wallet satisfy a named condition set right now?" - contracts/interfaces/IWalletStateVerifier.sol Minimal (bool verified, uint256 validUntil) interface keyed on (wallet, conditionsHash). Hooks stay stateless views. - contracts/hooks/WalletStateHook.sol Inherits BaseERC8183Hook + IERC8183HookMetadata. Immutable verifier + conditionsHash (deploy one hook per distinct condition set, mirrors the minConfidence immutable pattern in ReasoningVerifierHook). Overrides _preFund only — verifier.checkWalletState(caller, conditionsHash) → pass/fail + freshness, reverts otherwise. - contracts/examples/InsumerWalletStateVerifier.sol Reference IWalletStateVerifier implementation. Relayer-push model with optional RIP-7212 P256VERIFY precompile verification of off-chain ECDSA P-256 (ES256) attestation signatures. Works on Base, Arbitrum, Optimism, Polygon, Scroll, ZKsync, Celo — standard ERC-8183 L2 footprint. - test/WalletStateHook.t.sol 21 tests, all passing. Covers constructor guards, _preFund happy path, not-verified revert, expired-attestation revert, validUntil boundary, selector isolation, ERC-165 interface support, verifier relayer auth, and signature-mode flag. Stacked on top of erc-8183#30 (IACPHook → IERC8183Hook rename). Targets main; will rebase cleanly once erc-8183#30 merges.
…w, credentials Follow-ups per CONTRIBUTING.md on PR erc-8183#33: - WalletStateHook.sol: expand NatSpec to match BiddingHook/FundTransferHook style with USE CASE / FLOW / TRUST MODEL sections + Profile A label. - InsumerWalletStateVerifier.sol: add credentials block covering both paths — developers via POST /v1/keys/create (email-based, free tier) and agents via POST /v1/keys/buy (wallet-based, no email, USDC/BTC payment proves identity). - README.md: add WalletStateHook row to the Hook Examples table, Profile A. No code changes — docs only. forge build clean, forge test 21/21 pass.
98c8128 to
f65b913
Compare
|
…MultiHookRouter compat Addresses review on erc-8183#33: - Inline IWalletStateVerifier into WalletStateHook.sol - Remove example verifier (re-hosted in insumer-examples) - Add MULTIHOOKROUTER NatSpec block; requiredSelectors() empty - Tighten FLOW NatSpec to separate off-chain attestation source from on-chain IWalletStateVerifier surface - README row updated to verifier-agnostic phrasing
|
Hi @ariessa, addressed in 420b72b. 1. Outdated. Branch is at current 2. MultiHookRouter support. The hook is router-compatible by construction:
3. Interface inside the hook. Done. 4. Bloat. Removed:
PR now ships three files: 5. Use case. Pre-escrow gating on a deterministic wallet-state condition set. The hook checks "does this wallet satisfy the named conditions right now?" before 6. Problem. Many ERC-8183 jobs need a wallet-policy check before escrow forms — today this happens off-chain in integration code or via custom on-chain logic per project. — Douglas |
|
Thank you for this contribution, and for working through the review feedback with me. I genuinely appreciate the back-and-forth. While reviewing, I noticed that #9 addresses the same problem and takes a more general approach that also covers the case your PR handles. Rather than splitting review effort across two overlapping PRs, it might make more sense to consolidate the work there — either by reviewing the other overlapping PR, suggesting improvements, or contributing follow-up changes once it lands. |
|
Hi @ariessa, thanks for the close read. Quick note on the boundary — #9 and #33 are sibling primitives rather than overlapping ones:
@rnwy mapped this directly in #9 (split-shape note) as the score / condition / content three-way that all sit on — Douglas |
Summary
Adds a minimal ERC-8183 hook that gates the fund stage on a condition-based wallet-state verifier. Complements existing score-based gating (
TrustGateHook, #9/#32) and content-based verification (ReasoningVerifierHook, #31) with a third shape: does this wallet satisfy a named condition set right now?TrustGateHook) — "reputation ≥ N"ReasoningVerifierHook) — "output verified, confidence ≥ N"WalletStateHook, this PR) — "wallet passes condition set X (e.g. USDC ≥ 1000 on Base, KYC attested, NFT held)"What's added
contracts/interfaces/IWalletStateVerifier.sol(bool verified, uint256 validUntil)interface keyed on(wallet, conditionsHash). Hooks remain stateless views.contracts/hooks/WalletStateHook.solBaseERC8183Hook+IERC8183HookMetadata. Immutableverifier+conditionsHash(deploy one hook per distinct set, mirrors theminConfidencepattern in #31). Overrides_preFundonly.contracts/examples/InsumerWalletStateVerifier.solIWalletStateVerifierimplementation. Relayer-push model with optional RIP-7212 P256VERIFY precompile verification of off-chain ECDSA P-256 (ES256) attestation signatures.test/WalletStateHook.t.solDesign intent
Keep the core hook small, generic, and aligned with the current hook stack:
BaseERC8183Hook-native_preFundonlycontracts/examples/Gate stage
_preFund— gates the client wallet before escrow forms. ParallelsTrustGateHook's_preFundstage (score threshold) andReasoningVerifierHook's_preSubmitstage (deliverable hash), so readers see a clean three-way contrast at distinct lifecycle points.Verification model
The example verifier supports two modes:
r,s,messageHash), which are verified via the RIP-7212 precompile before the attestation is stored. Zero trust in the relayer.pubKeyX = pubKeyY = 0, signature verification is skipped and the relayer is trusted. Useful for testnets or deployments where off-chain signature verification is performed by an independent auditor.RIP-7212 is live on Base, Optimism, Arbitrum, Polygon, Scroll, ZKsync, Celo — the standard ERC-8183 L2 footprint.
Verification
forge build✅ (only pre-existing lint notes matching current codebase style)forge test --match-path test/WalletStateHook.t.sol✅ 21/21 passDependency on #30
This branch is stacked on #30 (IACPHook → IERC8183Hook rename) so the new files compile against the post-rename base. Will rebase cleanly once #30 merges.