1use apex_sdk_types::{Address, TransactionStatus};
34use async_trait::async_trait;
35use serde::{Deserialize, Serialize};
36use thiserror::Error;
37
38#[cfg(any(test, feature = "mocks"))]
40pub mod mocks;
41
42pub mod pipeline;
44
45pub mod metrics;
47
48pub mod golden_vectors;
50
51pub use golden_vectors::{
52 load_default_golden_vectors, verify_golden_vector, ChainType, GoldenVector, GoldenVectorSet,
53};
54pub use metrics::{MetricType, MetricsCollector};
55pub use pipeline::{TransactionPipeline, TransactionResult};
56
57#[derive(Error, Debug)]
59pub enum SdkError {
60 #[error("Provider error: {0}")]
61 ProviderError(String),
62 #[error("Signer error: {0}")]
63 SignerError(String),
64 #[error("Transaction error: {0}")]
65 TransactionError(String),
66 #[error("Network error: {0}")]
67 NetworkError(String),
68 #[error("Configuration error: {0}")]
69 ConfigError(String),
70 #[error("Not implemented: {0}")]
71 NotImplemented(String),
72}
73
74#[async_trait]
76pub trait ChainAdapter: Send + Sync {
77 async fn get_transaction_status(&self, tx_hash: &str) -> Result<TransactionStatus, String>;
79
80 fn validate_address(&self, address: &Address) -> bool;
82
83 fn chain_name(&self) -> &str;
85}
86
87#[async_trait]
89pub trait TransactionBuilder {
90 fn from(&mut self, address: Address) -> &mut Self;
92
93 fn to(&mut self, address: Address) -> &mut Self;
95
96 fn amount(&mut self, amount: u128) -> &mut Self;
98
99 fn build(&self) -> Result<Vec<u8>, String>;
101}
102
103#[async_trait]
105pub trait Provider: Send + Sync {
106 async fn get_block_number(&self) -> Result<u64, SdkError>;
108
109 async fn get_balance(&self, address: &Address) -> Result<u128, SdkError>;
111
112 async fn get_transaction_count(&self, address: &Address) -> Result<u64, SdkError>;
114
115 async fn estimate_fee(&self, tx: &[u8]) -> Result<u128, SdkError>;
117
118 async fn get_block(&self, block_number: u64) -> Result<BlockInfo, SdkError>;
120
121 async fn health_check(&self) -> Result<(), SdkError>;
123}
124
125#[derive(Debug, Clone, Serialize, Deserialize)]
127pub struct BlockInfo {
128 pub number: u64,
129 pub hash: String,
130 pub parent_hash: String,
131 pub timestamp: u64,
132 pub transactions: Vec<String>,
133
134 #[serde(default)]
136 pub state_root: Option<String>,
137 #[serde(default)]
138 pub extrinsics_root: Option<String>,
139 #[serde(default)]
140 pub extrinsic_count: u32,
141 #[serde(default)]
142 pub event_count: Option<u32>,
143 #[serde(default)]
144 pub is_finalized: bool,
145}
146
147#[derive(Debug, Clone, Serialize, Deserialize)]
149pub struct DetailedBlockInfo {
150 pub basic: BlockInfo,
152 pub extrinsics: Vec<ExtrinsicInfo>,
154 pub events: Vec<BlockEvent>,
156}
157
158#[derive(Debug, Clone, Serialize, Deserialize)]
160pub struct ExtrinsicInfo {
161 pub index: u32,
163 pub hash: String,
165 pub signed: bool,
167 pub signer: Option<String>,
169 pub pallet: String,
171 pub call: String,
173 pub success: bool,
175}
176
177#[derive(Debug, Clone, Serialize, Deserialize)]
179pub struct BlockEvent {
180 pub index: u32,
182 pub extrinsic_index: Option<u32>,
184 pub pallet: String,
186 pub event: String,
188}
189
190#[async_trait]
192pub trait Signer: Send + Sync {
193 async fn sign_transaction(&self, tx: &[u8]) -> Result<Vec<u8>, SdkError>;
195
196 fn address(&self) -> Address;
197}
198
199#[async_trait]
201pub trait FeeEstimator: Send + Sync {
202 async fn estimate_fee(&self, tx: &[u8]) -> Result<u128, SdkError>;
204}
205
206#[async_trait]
208pub trait NonceManager: Send + Sync {
209 async fn get_next_nonce(&self, address: &Address) -> Result<u64, SdkError>;
210}
211
212#[async_trait]
214pub trait Broadcaster: Send + Sync {
215 async fn broadcast(&self, signed_tx: &[u8]) -> Result<String, SdkError>;
217}
218
219#[async_trait]
221pub trait ReceiptWatcher: Send + Sync {
222 async fn wait_for_receipt(&self, tx_hash: &str) -> Result<TransactionStatus, SdkError>;
224
225 async fn wait_for_receipt_with_strategy(
227 &self,
228 tx_hash: &str,
229 strategy: &ConfirmationStrategy,
230 ) -> Result<TransactionStatus, SdkError>;
231
232 async fn get_receipt_status(
234 &self,
235 tx_hash: &str,
236 ) -> Result<Option<TransactionStatus>, SdkError>;
237}
238
239#[derive(Debug, Clone, Serialize, Deserialize)]
241pub enum ConfirmationStrategy {
242 BlockConfirmations {
244 confirmations: u32,
246 timeout_secs: u64,
248 },
249 Finalized {
251 timeout_secs: u64,
253 },
254 Immediate,
256}
257
258impl Default for ConfirmationStrategy {
259 fn default() -> Self {
260 Self::BlockConfirmations {
261 confirmations: 2,
262 timeout_secs: 300, }
264 }
265}
266
267#[derive(Debug, Clone, Serialize, Deserialize)]
269pub struct RetryConfig {
270 pub max_attempts: u32,
272 pub initial_delay_ms: u64,
274 pub max_delay_ms: u64,
276 pub backoff_multiplier: f64,
278}
279
280impl Default for RetryConfig {
281 fn default() -> Self {
282 Self {
283 max_attempts: 5,
284 initial_delay_ms: 250,
285 max_delay_ms: 2000,
286 backoff_multiplier: 2.0,
287 }
288 }
289}
290
291#[derive(Debug, Clone, Serialize, Deserialize)]
293pub struct TimeoutConfig {
294 pub rpc_timeout_secs: u64,
296 pub operation_timeout_secs: u64,
298}
299
300impl Default for TimeoutConfig {
301 fn default() -> Self {
302 Self {
303 rpc_timeout_secs: 10,
304 operation_timeout_secs: 60,
305 }
306 }
307}
308
309#[derive(Debug, Serialize, Deserialize)]
311pub struct SdkLog {
312 pub level: LogLevel,
313 pub message: String,
314 pub timestamp: u64,
315 pub operation: String,
316 pub chain: Option<String>,
317 pub transaction_hash: Option<String>,
318 pub context: Option<serde_json::Value>,
319}
320
321#[derive(Debug, Clone, Serialize, Deserialize)]
323pub enum LogLevel {
324 Trace,
325 Debug,
326 Info,
327 Warn,
328 Error,
329}