Skip to content

contracts: x402r extensions (payment-operator + condition plugins)#3

Open
A1igator wants to merge 1 commit into
aliabdoli/svm-base-portfrom
aliabdoli/svm-x402r-extensions
Open

contracts: x402r extensions (payment-operator + condition plugins)#3
A1igator wants to merge 1 commit into
aliabdoli/svm-base-portfrom
aliabdoli/svm-x402r-extensions

Conversation

@A1igator
Copy link
Copy Markdown
Contributor

Summary

Stacks on top of #2 (base commerce-payments port). Adds the x402r-specific layer on top of the escrow primitive — the second half of the two-PR split of #1.

Program Role
payment-operator Factory + slot dispatch. create_operator allocates a per-merchant OperatorState PDA at [b"operator", authority] (PDA address IS the merchant's operator pubkey). Wraps escrow authorize / capture / void / charge / refund with pre-action conditions + post-action hooks, CPI'ing into escrow as the per-merchant PDA via invoke_signed. update_operator rotates the slot config under the existing authority.
static-address-condition Generic ICondition reference impl: outer signer must equal a configured target address.
receiver-condition Stateless ICondition: outer signer must equal payment_info.receiver.
payer-condition Stateless ICondition: outer signer must equal payment_info.payer.

Also adds:

  • fuzz_slot_dispatch: Trident scaffold for fuzzing slot fan-out (input shape only; full banks-client harness is a follow-up).
  • Re-adds the slot-dispatch test cases removed from the base PR.

Workspace plumbing (Anchor.toml, Cargo workspace, codama/generate.ts, migrations/pin-program-ids.ts, fuzz/Cargo.toml) is updated to include the new programs.

reclaim stays on the escrow and is called by the payer directly — it intentionally bypasses the operator program so the payer's deadline-based escape hatch cannot be defeasibly delegated.

Review order

This PR will look smaller and cleaner after #2 merges; until then GitHub will show the union diff. Reviewing as aliabdoli/svm-x402r-extensions...aliabdoli/svm-base-port isolates this PR's changes from the base.

Licensing

Same BUSL-1.1 terms as the base PR.

Status

Pilot, unaudited. Mainnet usage is at users' own risk.

🤖 Generated with Claude Code

Stacks on top of the base commerce-payments port. Adds the x402r-specific
layer:

- payment-operator: factory + slot dispatch. create_operator allocates a
  per-merchant OperatorState PDA at ["operator", authority] whose address
  IS the merchant's operator pubkey. Wraps escrow authorize/capture/void/
  charge/refund with pre-action conditions + post-action hooks, CPI'ing
  into escrow as the per-merchant PDA via invoke_signed. update_operator
  rotates the slot config under the existing authority.
- static-address-condition: generic ICondition reference impl. Outer
  signer must equal a configured target.
- receiver-condition: stateless ICondition. Outer signer == payment_info.
  receiver.
- payer-condition: stateless ICondition. Outer signer == payment_info.
  payer.
- fuzz_slot_dispatch: Trident scaffold for fuzzing the slot fan-out.
- Re-adds the slot-dispatch test cases removed from the base PR.

Workspace plumbing (Anchor.toml, Cargo workspace, codama generator,
pin-program-ids, fuzz Cargo) is updated to include the new programs.

reclaim stays on the escrow and is called by the payer directly: it
intentionally bypasses the operator program so the payer's deadline-
based escape hatch cannot be defeasibly delegated.

Status: pilot, unaudited. Mainnet usage is at users' own risk.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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