x402_kit/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.
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 // fn select<A: Address<Network = Self::Network>>(
37 // &self,
38 // pr: &PaymentRequirements,
39 // ) -> Option<PaymentSelection<A>>
40 // where
41 // Self: Sized,
42 // {
43 // if pr.scheme == Self::SCHEME_NAME && pr.network == self.network().network_name() {
44 // Some(PaymentSelection {
45 // max_amount_required: pr.max_amount_required,
46 // resource: pr.resource.clone(),
47 // description: pr.description.clone(),
48 // mime_type: pr.mime_type.clone(),
49 // pay_to: pr.pay_to.parse().ok()?,
50 // max_timeout_seconds: pr.max_timeout_seconds,
51 // asset: pr.asset.parse().ok()?,
52 // output_schema: pr.output_schema.clone(),
53 // extra: pr.extra.clone(),
54 // })
55 // } else {
56 // None
57 // }
58 // }
59}
60
61/// Represents an asset on a given address.
62#[derive(Debug, Clone, Copy, PartialEq, Eq)]
63pub struct Asset<A: Address> {
64 pub address: A,
65 pub decimals: u8,
66 pub name: &'static str,
67 pub symbol: &'static str,
68}
69
70/// Payment configuration for a given scheme and transport.
71#[derive(Builder)]
72pub struct Payment<S, A>
73where
74 S: Scheme,
75 A: Address<Network = S::Network>,
76{
77 /// The payment scheme.
78 pub scheme: S,
79 /// The address to use for payments.
80 #[builder(into)]
81 pub pay_to: A,
82 /// The asset for the payment
83 #[builder(into)]
84 pub asset: Asset<A>,
85 /// The amount of the asset to pay, in smallest units.
86 #[builder(into)]
87 pub amount: AmountValue,
88 /// Maximum timeout in seconds for the payment to be completed.
89 pub max_timeout_seconds: u64,
90 /// Optional extra data for the payment.
91 pub extra: Option<AnyJson>,
92}
93
94/// Payment configuration for a given scheme and transport.
95#[derive(Builder)]
96pub struct PaymentSelection<A: Address> {
97 /// The address to use for payments.
98 #[builder(into)]
99 pub pay_to: A,
100 /// The asset for the payment
101 #[builder(into)]
102 pub asset: A,
103 /// The amount of the asset to pay, in smallest units.
104 #[builder(into)]
105 pub amount: AmountValue,
106 /// Maximum timeout in seconds for the payment to be completed.
107 pub max_timeout_seconds: u64,
108 /// Optional extra data for the payment.
109 pub extra: Option<AnyJson>,
110 /// Resource definition.
111 pub resource: Resource,
112 /// Extensions
113 #[builder(default)]
114 pub extensions: Record<Extension>,
115}
116
117/// Signer for a given payment scheme.
118pub trait SchemeSigner<A: Address<Network = <Self::Scheme as Scheme>::Network>> {
119 type Scheme: Scheme;
120 type Error: std::error::Error;
121
122 fn sign(
123 &self,
124 payment: &PaymentSelection<A>,
125 ) -> impl Future<Output = Result<<Self::Scheme as Scheme>::Payload, Self::Error>>;
126}
127
128/// Resource definition.
129#[derive(Builder, Debug, Clone, PartialEq, Eq)]
130pub struct Resource {
131 /// Optional resource URL.
132 pub url: Url,
133 /// Optional description of the resource.
134 #[builder(into)]
135 pub description: String,
136 /// Optional MIME type of the resource.
137 #[builder(into)]
138 pub mime_type: String,
139 /// Optional output schema for the payment payload.
140 pub output_schema: Option<OutputSchema>,
141}