Skip to main content

scematica_protocol/
types.rs

1use serde::{Deserialize, Serialize};
2
3pub const X402_VERSION: u32 = 2;
4
5/// Returned by the resource server as the body of a 402 Payment Required response.
6#[derive(Debug, Clone, Serialize, Deserialize)]
7pub struct PaymentRequired {
8    pub x402_version: u32,
9    pub resource: ResourceInfo,
10    pub accepts: Vec<PaymentRequirements>,
11}
12
13#[derive(Debug, Clone, Serialize, Deserialize)]
14pub struct ResourceInfo {
15    pub url: String,
16    pub method: String,
17    pub description: String,
18}
19
20/// One accepted payment option served in the 402 response.
21#[derive(Debug, Clone, Serialize, Deserialize)]
22pub struct PaymentRequirements {
23    /// "exact" (only supported scheme for now)
24    pub scheme: String,
25    /// "solana-mainnet" | "solana-devnet"
26    pub network: String,
27    /// SPL token mint address (use WSOL mint for native SOL payments)
28    pub asset: String,
29    /// Required transfer amount in raw atomic units (lamports for SOL, micro-USDC for USDC)
30    pub amount: u64,
31    /// Recipient wallet address
32    pub pay_to: String,
33    /// Seconds after which the payment authorization expires
34    pub max_timeout_seconds: u64,
35    /// Optional scheme-specific extras (decimals, memo requirements, etc.)
36    #[serde(default)]
37    pub extra: serde_json::Value,
38}
39
40/// Sent by the client in the `X-Payment` header (base64-encoded JSON).
41#[derive(Debug, Clone, Serialize, Deserialize)]
42pub struct PaymentPayload {
43    pub x402_version: u32,
44    /// Must match `PaymentRequirements.scheme`
45    pub scheme: String,
46    /// Must match `PaymentRequirements.network`
47    pub network: String,
48    /// Scheme-specific payload
49    pub payload: SvmExactPayload,
50}
51
52/// Payload for the Solana exact scheme.
53/// The client creates a partially-signed SPL Token TransferChecked transaction,
54/// serialises it with bincode, and base64-encodes it here.
55/// The fee payer slot is left empty — the facilitator fills it at settlement.
56#[derive(Debug, Clone, Serialize, Deserialize)]
57pub struct SvmExactPayload {
58    /// bincode + base64 encoded `solana_sdk::transaction::Transaction`
59    pub transaction: String,
60}
61
62/// Returned by the facilitator `POST /verify` endpoint and the inline verifier.
63#[derive(Debug, Clone, Serialize, Deserialize)]
64pub struct VerifyResponse {
65    pub is_valid: bool,
66    #[serde(skip_serializing_if = "Option::is_none")]
67    pub invalid_reason: Option<String>,
68    #[serde(skip_serializing_if = "Option::is_none")]
69    pub payer: Option<String>,
70}
71
72/// Returned by the facilitator `POST /settle` endpoint
73/// and attached to the `X-Payment-Response` header as base64-encoded JSON.
74#[derive(Debug, Clone, Serialize, Deserialize)]
75pub struct SettlementResponse {
76    pub success: bool,
77    #[serde(skip_serializing_if = "Option::is_none")]
78    pub transaction: Option<String>,
79    #[serde(skip_serializing_if = "Option::is_none")]
80    pub error: Option<String>,
81    #[serde(skip_serializing_if = "Option::is_none")]
82    pub payer: Option<String>,
83    pub network: String,
84}