apex-sdk-core

Core traits and functionality for the Apex SDK blockchain development framework.
Overview
apex-sdk-core provides the foundational traits, interfaces, and core functionality that power the Apex SDK. It defines the common abstractions that allow seamless interaction with different blockchain ecosystems through a unified API.
Features
- Blockchain Adapter Traits: Define standard interfaces for blockchain interaction
- Async-First Design: Built with
async/await support from the ground up
- Error Handling: Comprehensive error types with
anyhow and thiserror integration
- Type Safety: Leverages Rust's type system for safe blockchain operations
- Cross-Chain Abstractions: Common patterns for multi-chain applications
Installation
Add this to your Cargo.toml:
[dependencies]
apex-sdk-core = "0.1"
tokio = { version = "1.0", features = ["full"] }
Core Traits
BlockchainAdapter
The main trait for blockchain interaction:
use apex_sdk_core::{BlockchainAdapter, Result};
use apex_sdk_types::{Account, BlockNumber, TransactionHash};
#[async_trait::async_trait]
pub trait BlockchainAdapter: Send + Sync {
async fn get_latest_block(&self) -> Result<BlockNumber>;
async fn get_balance(&self, account: &Account) -> Result<u128>;
async fn submit_transaction(&self, tx: Transaction) -> Result<TransactionHash>;
async fn wait_for_confirmation(&self, hash: &TransactionHash) -> Result<Receipt>;
}
TransactionBuilder
For building blockchain transactions:
use apex_sdk_core::TransactionBuilder;
#[async_trait::async_trait]
pub trait TransactionBuilder<T> {
type Transaction;
type Error;
async fn build(self) -> std::result::Result<Self::Transaction, Self::Error>;
async fn estimate_cost(&self) -> std::result::Result<u128, Self::Error>;
async fn sign<S: Signer>(&self, signer: &S) -> std::result::Result<Self::Transaction, Self::Error>;
}
Signer
For transaction signing:
use apex_sdk_core::Signer;
#[async_trait::async_trait]
pub trait Signer: Send + Sync {
type Signature;
type Error;
async fn sign(&self, message: &[u8]) -> std::result::Result<Self::Signature, Self::Error>;
fn public_key(&self) -> &PublicKey;
fn address(&self) -> Address;
}
Usage Examples
Implementing a Custom Adapter
use apex_sdk_core::{BlockchainAdapter, Result};
use apex_sdk_types::*;
use async_trait::async_trait;
pub struct CustomAdapter {
client: CustomClient,
}
#[async_trait]
impl BlockchainAdapter for CustomAdapter {
async fn get_latest_block(&self) -> Result<BlockNumber> {
let block = self.client.latest_block().await?;
Ok(BlockNumber::new(block.number))
}
async fn get_balance(&self, account: &Account) -> Result<u128> {
let balance = self.client.get_balance(account.address()).await?;
Ok(balance)
}
async fn submit_transaction(&self, tx: Transaction) -> Result<TransactionHash> {
let hash = self.client.send_transaction(tx).await?;
Ok(TransactionHash::new(hash))
}
async fn wait_for_confirmation(&self, hash: &TransactionHash) -> Result<Receipt> {
let receipt = self.client.wait_for_receipt(hash).await?;
Ok(receipt.into())
}
}
Using the Error Types
use apex_sdk_core::{Error, Result};
fn example_function() -> Result<String> {
let data = fetch_data()
.map_err(|e| Error::NetworkError(e.to_string()))?;
Ok(process_data(data))
}
use thiserror::Error;
#[derive(Error, Debug)]
pub enum CustomError {
#[error("Invalid configuration: {0}")]
InvalidConfig(String),
#[error("Connection failed: {0}")]
ConnectionFailed(String),
#[error(transparent)]
CoreError(#[from] apex_sdk_core::Error),
}
Architecture
The core crate provides several key abstractions:
apex-sdk-core
├── traits/ # Core traits and interfaces
│ ├── adapter.rs # BlockchainAdapter trait
│ ├── signer.rs # Signer trait
│ └── builder.rs # TransactionBuilder trait
├── error.rs # Error types and Result alias
├── config.rs # Configuration utilities
└── utils.rs # Common utilities
Error Handling
Comprehensive error handling with context:
use apex_sdk_core::{Error, Result};
match some_operation().await {
Err(Error::NetworkError(msg)) => {
log::error!("Network error: {}", msg);
}
Err(Error::InvalidTransaction(reason)) => {
log::warn!("Invalid transaction: {}", reason);
}
Err(Error::InsufficientFunds) => {
}
Ok(result) => {
}
}
Configuration
Built-in configuration support:
use apex_sdk_core::Config;
#[derive(Debug, Clone)]
pub struct AdapterConfig {
pub endpoint: String,
pub timeout: Duration,
pub retry_attempts: u32,
}
impl Config for AdapterConfig {
fn validate(&self) -> Result<()> {
if self.endpoint.is_empty() {
return Err(Error::InvalidConfig("endpoint cannot be empty".to_string()));
}
Ok(())
}
}
Integration with Other Crates
This core crate is used by:
Example integration:
use apex_sdk_core::{BlockchainAdapter, Result};
pub struct EvmAdapter {
}
#[async_trait]
impl BlockchainAdapter for EvmAdapter {
}
use apex_sdk_core::{BlockchainAdapter, Result};
pub struct SubstrateAdapter {
}
#[async_trait]
impl BlockchainAdapter for SubstrateAdapter {
}
Development
Building
cargo build
Testing
cargo test
Documentation
cargo doc --open
Linting
cargo clippy -- -D warnings
Examples
See the examples directory for complete usage examples:
License
Licensed under the Apache License, Version 2.0. See LICENSE for details.
Contributing
Contributions are welcome! Please read CONTRIBUTING.md for guidelines.