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}