x402_core/
core.rs

1//! Core traits and types used across the X402 Kit.
2
3use std::{fmt::Display, str::FromStr};
4
5use bon::Builder;
6use url::Url;
7
8use crate::types::{AmountValue, AnyJson, Extension, OutputSchema, Record};
9
10/// A series of network families, e.g. EVM, SVM, etc.
11pub trait NetworkFamily {
12    /// The name of the network in the family, should be compatible with X402 V1.
13    fn network_name(&self) -> &str;
14
15    /// The Blockchain network identifier in CAIP-2 format (e.g., "eip155:84532")
16    fn network_id(&self) -> &str;
17}
18
19/// Network-specific address type.
20pub trait Address: FromStr + Display + Copy {
21    /// The network family this address belongs to.
22    type Network: NetworkFamily;
23}
24
25/// A payment scheme applied to a network family.
26pub trait Scheme {
27    /// The network family this scheme applies to.
28    type Network: NetworkFamily;
29    /// The payload type produced by this scheme.
30    type Payload;
31    /// The name of the scheme.
32    const SCHEME_NAME: &'static str;
33    /// Get the concrete network for this scheme.
34    fn network(&self) -> &Self::Network;
35}
36
37/// Represents an asset on a given address.
38#[derive(Debug, Clone, Copy, PartialEq, Eq)]
39pub struct Asset<A: Address> {
40    /// The address of the asset.
41    pub address: A,
42    /// The number of decimals the asset uses.
43    pub decimals: u8,
44    /// The name of the asset.
45    pub name: &'static str,
46    /// The symbol of the asset.
47    pub symbol: &'static str,
48}
49
50/// Payment configuration for a given scheme and transport.
51///
52/// The payment configuration uses a static asset implementation. See [`Asset`].
53#[derive(Builder)]
54pub struct Payment<S, A>
55where
56    S: Scheme,
57    A: Address<Network = S::Network>,
58{
59    /// The payment scheme.
60    pub scheme: S,
61    /// The address to use for payments.
62    #[builder(into)]
63    pub pay_to: A,
64    /// The asset for the payment
65    #[builder(into)]
66    pub asset: Asset<A>,
67    /// The amount of the asset to pay, in smallest units.
68    #[builder(into)]
69    pub amount: AmountValue,
70    /// Maximum timeout in seconds for the payment to be completed.
71    pub max_timeout_seconds: u64,
72    /// Optional extra data for the payment.
73    pub extra: Option<AnyJson>,
74}
75
76/// The selected payment for the signer to sign.
77///
78/// Selected payment only knows about the asset's address, not full asset details.
79#[derive(Builder)]
80pub struct PaymentSelection<A: Address> {
81    /// The address to use for payments.
82    #[builder(into)]
83    pub pay_to: A,
84    /// The asset for the payment
85    #[builder(into)]
86    pub asset: A,
87    /// The amount of the asset to pay, in smallest units.
88    #[builder(into)]
89    pub amount: AmountValue,
90    /// Maximum timeout in seconds for the payment to be completed.
91    pub max_timeout_seconds: u64,
92    /// Optional extra data for the payment.
93    pub extra: Option<AnyJson>,
94    /// Resource definition.
95    pub resource: Resource,
96    /// Extensions
97    #[builder(default)]
98    pub extensions: Record<Extension>,
99}
100
101/// Signer for a given payment scheme.
102pub trait SchemeSigner<A: Address<Network = <Self::Scheme as Scheme>::Network>> {
103    /// The payment scheme this signer supports.
104    type Scheme: Scheme;
105
106    /// The error type for signing failures.
107    type Error: std::error::Error;
108
109    /// Sign the given payment selection, producing a payload.
110    fn sign(
111        &self,
112        payment: &PaymentSelection<A>,
113    ) -> impl Future<Output = Result<<Self::Scheme as Scheme>::Payload, Self::Error>>;
114}
115
116/// Resource definition.
117#[derive(Builder, Debug, Clone, PartialEq, Eq)]
118pub struct Resource {
119    /// Optional resource URL.
120    pub url: Url,
121    /// Optional description of the resource.
122    #[builder(into)]
123    pub description: String,
124    /// Optional MIME type of the resource.
125    #[builder(into)]
126    pub mime_type: String,
127    /// Optional output schema for the payment payload.
128    pub output_schema: Option<OutputSchema>,
129}