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}