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