feat(x402): add the signer groundwork for an x402 command group - #1001
Open
gummy789j wants to merge 1 commit into
Open
feat(x402): add the signer groundwork for an x402 command group#1001gummy789j wants to merge 1 commit into
gummy789j wants to merge 1 commit into
Conversation
x402-cli signs its payments through @bankofai/agent-wallet. Migrating its commands into wallet-cli means re-pointing that signer at a wallet-cli account; this is the seam that makes the rest of that migration mechanical. No x402 SDK is a dependency yet, and no command is wired. - domain/x402/network-id — convert between wallet-cli network ids and the CAIP-2 ids x402 uses. TRON differs only in base (tron:728126428 is tron:0x2b6653dc); eip155 identifiers are identical on both sides. - application/contracts/x402-payer — PayerSigner and PayerPolicy. The contract carries two closures rather than the domain Signer, because an x402 scheme calls the wallet from deep inside a payment flow, where nothing can run a Ledger's precheck / prompt / abort ceremony. - application/services/x402/payer-signer — resolve the active account, refusing a watch-only one before any keystore decrypt, and apply that ceremony once per signature. The TRON allowance path signs an approve transaction before the payment, so each signature needs its own round. - adapters/outbound/x402/signer-bridge — reshape the payer for the x402 SDK, declared structurally so no x402 package is imported. It is the one place every typed-data payload passes through, so it carries all three guards: the payload's payer must be the selected account, a GasFree maxFee must stay within the caller's ceiling, and the returned signature must be for the struct that was requested. The first two refuse before any signature is requested, so a rejected payment never reaches a device prompt. - domain/typed-data — resolvePrimaryType, so those guards work from the payload's real signing root instead of an optional field. Without it, a payload that omitted primaryType skipped all three checks. - three error codes: payer_mismatch, fee_cap_exceeded and signed_payload_mismatch, with their rows in machine-interface.md.
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.
x402-cli signs its payments through @bankofai/agent-wallet. Migrating its commands into wallet-cli means re-pointing that signer at a wallet-cli account; this is the seam that makes the rest of that migration mechanical. No x402 SDK is a dependency yet, and no command is wired.
domain/x402/network-id — convert between wallet-cli network ids and the CAIP-2 ids x402 uses. TRON differs only in base (tron:728126428 is tron:0x2b6653dc); eip155 identifiers are identical on both sides.
application/contracts/x402-payer — PayerSigner and PayerPolicy. The contract carries two closures rather than the domain Signer, because an x402 scheme calls the wallet from deep inside a payment flow, where nothing can run a Ledger's precheck / prompt / abort ceremony.
application/services/x402/payer-signer — resolve the active account, refusing a watch-only one before any keystore decrypt, and apply that ceremony once per signature. The TRON allowance path signs an approve transaction before the payment, so each signature needs its own round.
adapters/outbound/x402/signer-bridge — reshape the payer for the x402 SDK, declared structurally so no x402 package is imported. It is the one place every typed-data payload passes through, so it carries all three guards: the payload's payer must be the selected account, a GasFree maxFee must stay within the caller's ceiling, and the returned signature must be for the struct that was requested. The first two refuse before any signature is requested, so a rejected payment never reaches a device prompt.
domain/typed-data — resolvePrimaryType, so those guards work from the payload's real signing root instead of an optional field. Without it, a payload that omitted primaryType skipped all three checks.
three error codes: payer_mismatch, fee_cap_exceeded and signed_payload_mismatch, with their rows in machine-interface.md.