Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ name = "public_api"
required-features = ["btc", "evm", "solana", "tron", "keccak"]

[features]
default = ["btc", "evm", "solana", "tron", "keccak", "net", "key", "asset", "client", "tx"]
default = ["btc", "evm", "solana", "tron", "keccak", "net", "key", "asset", "client", "tx", "x402"]
# Bitcoin address parsing and validation.
btc = ["dep:bitcoin"]
# EVM (Ethereum and compatible chains) address validation. Dependency-free:
Expand All @@ -106,6 +106,7 @@ asset = ["btc", "evm", "solana", "tron"]
client = ["net", "asset", "tx", "serde/derive"]
# Transaction building and signing (`tinywallet::tx`). Needs secp256k1

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

priority medium critique confident

Move x402 below tx so the tx comment stays attached

The new x402 feature is inserted between the comment block that describes tx and the tx line itself, so the tx comment is now visually attached to x402:

# Transaction building and signing (`tinywallet::tx`). Needs secp256k1
# recoverable signing (via `bitcoin`) and Keccak-256 (via `keccak`).
x402 = ["dep:serde", "dep:serde_json", "serde/derive"]
tx = ["btc", "evm", "keccak", "solana", "tron", "key", "dep:ed25519-dalek", "dep:bs58", "dep:sha2", "dep:hex"]

The tx feature loses its explanatory comment and x402 gains a misleading one. The x402 feature should be placed elsewhere (e.g., below the tx line or in its own commented section).

[RULE] Comment why each crate is needed ·

# recoverable signing (via `bitcoin`) and Keccak-256 (via `keccak`).
x402 = ["dep:serde", "dep:serde_json", "serde/derive"]

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

priority medium critique likely

Add an explanatory comment for the x402 feature

The repository rules require commenting why each crate is needed, but the new x402 feature has no comment explaining its purpose or why it pulls in serde, serde_json, and serde/derive:

x402 = ["dep:serde", "dep:serde_json", "serde/derive"]

A descriptive comment should be added, consistent with the other feature definitions in this file.

[RULE] Comment why each crate is needed ·

tx = ["btc", "evm", "keccak", "solana", "tron", "key", "dep:ed25519-dalek", "dep:bs58", "dep:sha2", "dep:hex"]
# Deterministic key derivation from a BIP-39 mnemonic (`tinywallet::key`).
# Needs every chain gate it derives for; `keccak` covers the EVM/Tron address
Expand Down
3 changes: 3 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
//! | `asset` | on | network and token reference data (`tinywallet::asset`) |
//! | `client` | on | chain queries over the seam (`tinywallet::client`) |
//! | `tx` | on | transaction building and signing (`tinywallet::tx`) |
//! | `x402` | on | x402 machine-payment wire types (`tinywallet::x402`) |

mod error;

Expand All @@ -64,6 +65,8 @@ pub mod key;
pub mod rpc;
#[cfg(feature = "tx")]
pub mod tx;
#[cfg(feature = "x402")]
pub mod x402;

pub use chain::Chain;
pub use error::{Error, Result};
44 changes: 44 additions & 0 deletions src/x402/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//! The x402 machine-payment protocol (v2).
//!
//! x402 revives HTTP's long-unused `402 Payment Required`. A server answers a
//! request with a 402 and a `PAYMENT-REQUIRED` header describing what it will
//! accept; the client pays, retries with a `PAYMENT-SIGNATURE` header carrying
//! the proof, and the server settles it through a facilitator and answers with
//! `PAYMENT-RESPONSE`.
//!
//! This module owns the **wire types** — the header payloads and the rules for
//! reading them. Every header payload is standard-base64-encoded JSON, and
//! networks are named in [CAIP-2] form (`solana:…`, `eip155:8453`).
//!
//! ## Amounts are strings, and that is not laziness
//!
//! [`PaymentRequirements::amount`] is a `String` of atomic units, not a number.
//! JSON numbers are IEEE 754 doubles in most parsers, which cannot represent
//! every `u64` exactly — and a token amount that survives a round trip through
//! a JavaScript facilitator only approximately is a payment for the wrong sum.
//! The protocol carries them as decimal strings for that reason, and so does
//! this module.
//!
//! ## The client signs an authorisation; the facilitator broadcasts
//!
//! In both supported schemes the payer never broadcasts. On Solana it hands
//! over a partially-signed transaction that the facilitator co-signs as fee
//! payer; on EVM it signs an EIP-3009 `transferWithAuthorization` the
//! facilitator submits. So a payment proof is a *capability someone else will
//! exercise* — which is why [`EvmAuthorization`] carries `valid_after`,
//! `valid_before` and a `nonce`: without them an authorisation would be
//! replayable indefinitely.
//!
//! [CAIP-2]: https://chainagnostic.org/CAIPs/caip-2

mod types;

pub use types::{
BASE_MAINNET_CAIP2, BASE_SEPOLIA_CAIP2, COMPUTE_BUDGET_PROGRAM, ETHEREUM_MAINNET_CAIP2,
EvmAuthorization, EvmPaymentProof, HEADER_PAYMENT_REQUIRED, HEADER_PAYMENT_REQUIRED_V1,
HEADER_PAYMENT_RESPONSE, HEADER_PAYMENT_SIGNATURE, HEADER_PAYMENT_SIGNATURE_V1, PaymentChain,
PaymentExtra, PaymentPayload, PaymentProof, PaymentRequired, PaymentRequirements, ResourceInfo,
SOLANA_DEVNET_CAIP2, SOLANA_MAINNET_CAIP2, SPL_MEMO_PROGRAM, SPL_TOKEN_PROGRAM,
SettlementResponse, SolanaPaymentProof, USDC_BASE_MAINNET, USDC_BASE_SEPOLIA,
USDC_ETHEREUM_MAINNET, USDC_MINT_DEVNET, USDC_MINT_MAINNET, X402_VERSION,
};
Loading