x402_kit/networks/
svm.rs

1use std::{
2    fmt::{Debug, Display},
3    str::FromStr,
4};
5
6use serde::{Deserialize, Serialize};
7use solana_pubkey::{ParsePubkeyError, Pubkey};
8
9use crate::concepts::{Address, NetworkFamily};
10
11pub struct SvmNetwork(pub &'static str);
12
13impl NetworkFamily for SvmNetwork {
14    fn network_name(&self) -> &str {
15        self.0
16    }
17}
18
19#[derive(Clone, Copy, PartialEq, Eq, Hash)]
20pub struct SvmAddress(pub Pubkey);
21
22impl From<Pubkey> for SvmAddress {
23    fn from(pk: Pubkey) -> Self {
24        SvmAddress(pk)
25    }
26}
27
28impl FromStr for SvmAddress {
29    type Err = ParsePubkeyError;
30
31    fn from_str(s: &str) -> Result<Self, Self::Err> {
32        let pk = Pubkey::from_str(s)?;
33        Ok(SvmAddress(pk))
34    }
35}
36
37impl Display for SvmAddress {
38    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
39        write!(f, "{}", self.0)
40    }
41}
42
43impl Debug for SvmAddress {
44    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
45        write!(f, "SvmAddress({})", self.0)
46    }
47}
48
49impl Serialize for SvmAddress {
50    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
51    where
52        S: serde::Serializer,
53    {
54        serializer.serialize_str(&self.to_string())
55    }
56}
57
58impl<'de> Deserialize<'de> for SvmAddress {
59    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
60    where
61        D: serde::Deserializer<'de>,
62    {
63        let s = String::deserialize(deserializer)?;
64        let pk = Pubkey::from_str(&s).map_err(serde::de::Error::custom)?;
65        Ok(SvmAddress(pk))
66    }
67}
68
69#[derive(Clone, Copy, PartialEq, Eq, Hash)]
70pub struct SvmSignature(pub solana_signature::Signature);
71
72impl FromStr for SvmSignature {
73    type Err = solana_signature::ParseSignatureError;
74
75    fn from_str(s: &str) -> Result<Self, Self::Err> {
76        let sig = solana_signature::Signature::from_str(s)?;
77        Ok(SvmSignature(sig))
78    }
79}
80
81impl Debug for SvmSignature {
82    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
83        write!(f, "SvmSignature({})", self.0)
84    }
85}
86
87impl Display for SvmSignature {
88    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
89        write!(f, "{}", self.0)
90    }
91}
92
93impl Serialize for SvmSignature {
94    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
95    where
96        S: serde::Serializer,
97    {
98        serializer.serialize_str(&self.to_string())
99    }
100}
101
102impl<'de> Deserialize<'de> for SvmSignature {
103    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
104    where
105        D: serde::Deserializer<'de>,
106    {
107        let s = String::deserialize(deserializer)?;
108        let sig = solana_signature::Signature::from_str(&s).map_err(serde::de::Error::custom)?;
109        Ok(SvmSignature(sig))
110    }
111}
112
113impl Address for SvmAddress {
114    type Network = SvmNetwork;
115}
116
117pub type SvmAsset = crate::concepts::Asset<SvmAddress>;
118
119pub trait ExplicitSvmNetwork {
120    const NETWORK: SvmNetwork;
121}
122
123pub trait ExplicitSvmAsset {
124    type Network: ExplicitSvmNetwork;
125    const ASSET: SvmAsset;
126}
127
128pub mod networks {
129    use super::*;
130
131    pub struct Solana;
132    impl ExplicitSvmNetwork for Solana {
133        const NETWORK: SvmNetwork = SvmNetwork("solana");
134    }
135
136    pub struct SolanaDevnet;
137    impl ExplicitSvmNetwork for SolanaDevnet {
138        const NETWORK: SvmNetwork = SvmNetwork("solana-devnet");
139    }
140
141    pub struct SolanaTestnet;
142    impl ExplicitSvmNetwork for SolanaTestnet {
143        const NETWORK: SvmNetwork = SvmNetwork("solana-testnet");
144    }
145}
146
147pub mod assets {
148    use solana_pubkey::pubkey;
149
150    use super::*;
151
152    macro_rules! create_usdc {
153        ($addr:expr) => {
154            SvmAsset {
155                address: SvmAddress($addr),
156                decimals: 6,
157                name: "USD Coin",
158                symbol: "USDC",
159            }
160        };
161    }
162
163    pub struct UsdcSolana;
164    impl ExplicitSvmAsset for UsdcSolana {
165        type Network = networks::Solana;
166        const ASSET: SvmAsset =
167            create_usdc!(pubkey!("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"));
168    }
169
170    pub struct UsdcSolanaDevnet;
171    impl ExplicitSvmAsset for UsdcSolanaDevnet {
172        type Network = networks::SolanaDevnet;
173        const ASSET: SvmAsset =
174            create_usdc!(pubkey!("4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU"));
175    }
176}