Skip to main content

apex_sdk_core/
lib.rs

1//! # Apex SDK Core
2//!
3//! Core traits and functionality for the Apex SDK.
4//!
5//! This crate provides the foundational abstractions used across all blockchain adapters
6//! in the Apex SDK. It defines common traits like `ChainAdapter` and `TransactionBuilder`
7//! that enable unified interaction with different blockchain types.
8//!
9//! ## Features
10//!
11//! - **Chain Adapter Trait**: Common interface for all blockchain types
12//! - **Transaction Builder**: Flexible transaction construction
13//! - **Type-safe abstractions**: Generic over chain implementations
14//!
15//! ## Usage
16//!
17//! This crate is typically used as a dependency by adapter implementations
18//! (e.g., `apex-sdk-substrate`, `apex-sdk-evm`) and is re-exported through
19//! the main `apex-sdk` crate.
20//!
21//! ```rust,no_run
22//! use apex_sdk_core::ChainAdapter;
23//! use apex_sdk_types::{Address, TransactionStatus};
24//!
25//! async fn check_transaction<T: ChainAdapter>(
26//!     adapter: &T,
27//!     tx_hash: &str
28//! ) -> Result<TransactionStatus, String> {
29//!     adapter.get_transaction_status(tx_hash).await
30//! }
31//! ```
32
33use apex_sdk_types::{Address, TransactionStatus};
34use async_trait::async_trait;
35use serde::{Deserialize, Serialize};
36use thiserror::Error;
37
38/// Mock implementations for testing
39#[cfg(any(test, feature = "mocks"))]
40pub mod mocks;
41
42/// Transaction pipeline for unified transaction execution
43pub mod pipeline;
44
45/// Metrics collection and monitoring
46pub mod metrics;
47
48/// Golden vectors for encoding verification
49pub 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/// Unified error taxonomy for the SDK
58#[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/// Trait for blockchain adapters
75#[async_trait]
76pub trait ChainAdapter: Send + Sync {
77    /// Get the transaction status
78    async fn get_transaction_status(&self, tx_hash: &str) -> Result<TransactionStatus, String>;
79
80    /// Validate an address for this chain
81    fn validate_address(&self, address: &Address) -> bool;
82
83    /// Get the chain name
84    fn chain_name(&self) -> &str;
85}
86
87/// Transaction builder trait
88#[async_trait]
89pub trait TransactionBuilder {
90    /// Set the sender address
91    fn from(&mut self, address: Address) -> &mut Self;
92
93    /// Set the recipient address
94    fn to(&mut self, address: Address) -> &mut Self;
95
96    /// Set the amount
97    fn amount(&mut self, amount: u128) -> &mut Self;
98
99    /// Build the transaction
100    fn build(&self) -> Result<Vec<u8>, String>;
101}
102
103/// Provider trait for interacting with the blockchain
104#[async_trait]
105pub trait Provider: Send + Sync {
106    /// Get the current block number
107    async fn get_block_number(&self) -> Result<u64, SdkError>;
108
109    /// Get the balance of an address
110    async fn get_balance(&self, address: &Address) -> Result<u128, SdkError>;
111
112    /// Get the transaction count (nonce) for an address
113    async fn get_transaction_count(&self, address: &Address) -> Result<u64, SdkError>;
114
115    /// Estimate gas/fees for a transaction
116    async fn estimate_fee(&self, tx: &[u8]) -> Result<u128, SdkError>;
117
118    /// Get block information by number
119    async fn get_block(&self, block_number: u64) -> Result<BlockInfo, SdkError>;
120
121    /// Check if the provider is healthy
122    async fn health_check(&self) -> Result<(), SdkError>;
123}
124
125/// Block information
126#[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    // Enhanced fields for comprehensive block data
135    #[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/// Detailed block information with extrinsics and events
148#[derive(Debug, Clone, Serialize, Deserialize)]
149pub struct DetailedBlockInfo {
150    /// Basic block information
151    pub basic: BlockInfo,
152    /// List of extrinsics in the block
153    pub extrinsics: Vec<ExtrinsicInfo>,
154    /// List of events in the block
155    pub events: Vec<BlockEvent>,
156}
157
158/// Information about an extrinsic (transaction) in a block
159#[derive(Debug, Clone, Serialize, Deserialize)]
160pub struct ExtrinsicInfo {
161    /// Index of the extrinsic in the block
162    pub index: u32,
163    /// Hash of the extrinsic
164    pub hash: String,
165    /// Whether the extrinsic is signed
166    pub signed: bool,
167    /// Address of the signer (if signed)
168    pub signer: Option<String>,
169    /// Pallet name
170    pub pallet: String,
171    /// Call name
172    pub call: String,
173    /// Whether the extrinsic succeeded
174    pub success: bool,
175}
176
177/// Information about an event in a block
178#[derive(Debug, Clone, Serialize, Deserialize)]
179pub struct BlockEvent {
180    /// Index of the event
181    pub index: u32,
182    /// Index of the associated extrinsic (if any)
183    pub extrinsic_index: Option<u32>,
184    /// Pallet name
185    pub pallet: String,
186    /// Event name
187    pub event: String,
188}
189
190/// Signer trait for signing transactions
191#[async_trait]
192pub trait Signer: Send + Sync {
193    /// Sign a transaction
194    async fn sign_transaction(&self, tx: &[u8]) -> Result<Vec<u8>, SdkError>;
195
196    fn address(&self) -> Address;
197}
198
199/// Fee estimator trait
200#[async_trait]
201pub trait FeeEstimator: Send + Sync {
202    /// Estimate the fee for a transaction
203    async fn estimate_fee(&self, tx: &[u8]) -> Result<u128, SdkError>;
204}
205
206/// Nonce manager trait
207#[async_trait]
208pub trait NonceManager: Send + Sync {
209    async fn get_next_nonce(&self, address: &Address) -> Result<u64, SdkError>;
210}
211
212/// Broadcaster trait for submitting transactions
213#[async_trait]
214pub trait Broadcaster: Send + Sync {
215    /// Broadcast a signed transaction
216    async fn broadcast(&self, signed_tx: &[u8]) -> Result<String, SdkError>;
217}
218
219/// Receipt watcher trait for tracking transaction status
220#[async_trait]
221pub trait ReceiptWatcher: Send + Sync {
222    /// Wait for a transaction receipt with default confirmation strategy
223    async fn wait_for_receipt(&self, tx_hash: &str) -> Result<TransactionStatus, SdkError>;
224
225    /// Wait for a transaction receipt with custom confirmation strategy
226    async fn wait_for_receipt_with_strategy(
227        &self,
228        tx_hash: &str,
229        strategy: &ConfirmationStrategy,
230    ) -> Result<TransactionStatus, SdkError>;
231
232    /// Get current transaction status without waiting
233    async fn get_receipt_status(
234        &self,
235        tx_hash: &str,
236    ) -> Result<Option<TransactionStatus>, SdkError>;
237}
238
239/// Confirmation strategy for transactions
240#[derive(Debug, Clone, Serialize, Deserialize)]
241pub enum ConfirmationStrategy {
242    /// Wait for a specific number of block confirmations
243    BlockConfirmations {
244        /// Number of confirmations required
245        confirmations: u32,
246        /// Maximum time to wait (in seconds)
247        timeout_secs: u64,
248    },
249    /// Wait for finalization (Substrate chains)
250    Finalized {
251        /// Maximum time to wait (in seconds)
252        timeout_secs: u64,
253    },
254    /// Immediate return after broadcasting
255    Immediate,
256}
257
258impl Default for ConfirmationStrategy {
259    fn default() -> Self {
260        Self::BlockConfirmations {
261            confirmations: 2,
262            timeout_secs: 300, // 5 minutes
263        }
264    }
265}
266
267/// Retry configuration for SDK operations
268#[derive(Debug, Clone, Serialize, Deserialize)]
269pub struct RetryConfig {
270    /// Maximum number of retry attempts
271    pub max_attempts: u32,
272    /// Initial delay in milliseconds
273    pub initial_delay_ms: u64,
274    /// Maximum delay in milliseconds
275    pub max_delay_ms: u64,
276    /// Backoff multiplier
277    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/// Timeout configuration for SDK operations
292#[derive(Debug, Clone, Serialize, Deserialize)]
293pub struct TimeoutConfig {
294    /// RPC call timeout in seconds
295    pub rpc_timeout_secs: u64,
296    /// Overall operation timeout in seconds
297    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/// Structured log entry for SDK operations
310#[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/// Log levels for SDK operations
322#[derive(Debug, Clone, Serialize, Deserialize)]
323pub enum LogLevel {
324    Trace,
325    Debug,
326    Info,
327    Warn,
328    Error,
329}