The pod Rust SDK provides a robust interface for interacting with the pod network through its This SDK enables developers to communicate with pod nodes, manage transactions, and handle network responses in a type-safe manner. The SDK includes comprehensive error handling, serialization management, and strongly-typed responses for pod-specific features.
Getting Started
Installation
To begin using the pod Rust SDK, add the following dependency to your project's Cargo.toml:
[dependencies]
pod-client = "0.1.0"
Building the pod provider
Helper function for building pod provider can be seen bellow:
use alloy::providers::{Provider, WsConnect};
use alloy_network::EthereumWallet;
use pod_sdk::PrivateKeySigner;
use eyre::Result;
async fn build_pod_provider(ws_url: Url, private_key_hex: &str) -> Result<impl Provider> {
// Create a signer from the private key
let wallet = EthereumWallet::from_hex(private_key_hex)
.expect("Invalid private key format for PRIVATE_KEY");
// Initialize WebSocket
let ws = WsConnect::new(ws_url);
// Build the PodProvider
let pod_provider = provider::PodProviderBuilder::new()
.wallet(wallet)
.on_ws(ws)
.await?;
Ok(pod_provider)
}
Basic Usage
Here's a simple example demonstrating how to initialize the client and perform basic operations:
use pod_sdk::provider;
use alloy_primitives::B256;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let ws_url = Url::parse("ws://127.0.0.1:8545")?;
let ws = WsConnect::new(ws_url);
let pod_client = provider::PodProviderBuilder::new()
.on_ws(ws)
.await?;
// Get transaction by hash
let tx_hash = B256::from_str("0x...")?;
// Get transaction without attestations
let tx = pod_client.get_transaction_by_hash(&tx_hash).await?;
Ok(())
}
Core Components
PodClient
The PodClient serves as the primary interface for interacting with the Pod network. It manages RPC communication and provides methods for executing common operations. PodClient is built on top of the Alloy client, making most of its methods Alloy-compatible.
Initialization
Create a new PodClient instance by using PodProviderBuilder and passing your url:
let ws_url = Url::parse("ws://127.0.0.1:8545")?;
let ws = WsConnect::new(ws_url);
let pod_client = provider::PodProviderBuilder::new().on_ws(ws).await?;
The same procedure can be repeated for http endpoint:
let rpc_url = "http://127.0.0.1:8545".parse()?;
let pod_client = provider::ProviderBuilder::new().on_http(rpc_url).await?;
API Methods
The SDK provides several key methods for interacting with the pod network:
Sending Transactions
In order to submit a fund transfer transaction to the network, please follow the script bellow:
#[tokio::main]
async fn main() -> Result<()> {
let ws_url = Url::parse("ws://127.0.0.1:8545")?;
let ws = WsConnect::new(ws_url);
let private_key_bytes =
<[u8; 32]>::from_hex("abc...")?; /// Your Private key
let field_bytes = FieldBytes::from_slice(&private_key_bytes);
let signing_key = SigningKey::from_bytes(field_bytes)?;
let signer = PrivateKeySigner::from(signing_key);
let wallet = EthereumWallet::new(signer);
let pod_provider = provider::PodProviderBuilder::new()
.wallet(wallet)
.on_ws(ws)
.await?;
let tx = TxLegacy {
chain_id: Some(1293),
nonce: 0,
gas_price: 20_000_000_000,
gas_limit: 21_000,
to: TxKind::Call(Address::from_str("0x742d35Cc6634C0532925a3b844Bc454e4438f44e").unwrap()),
value: U256::from(1000000000000000000u64),
input: Bytes::default(),
};
let pending_tx = pod_provider.send_transaction(tx.into()).await?;
let receipt = pending_tx.get_receipt().await?;
println!("receipt: {:?}", receipt);
}
Retrieving Transactions
As shown in the introductory section, the transaction can be retreived by hash as:
use pod_sdk::provider;
use alloy_primitives::B256;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let ws_url = Url::parse("ws://127.0.0.1:8545")?;
let ws = WsConnect::new(ws_url);
let pod_client = provider::PodProviderBuilder::new()
.on_ws(ws)
.await?;
// Get transaction by hash
let tx_hash = B256::from_str("0x...")?;
// Get transaction without attestations
let tx = pod_client.get_transaction_by_hash(&tx_hash).await?;
Ok(())
}
This method returns the transaction details along with pod-specific certificate information.
Retrieving Transaction Receipts
To obtain the transaction receipt with Pod-specific metadata and verify whether the signatures have passed the quorum threshold. For a pending transaction the receipt can be obtained as:
let pending_tx = pod_provider.send_transaction(tx.into()).await?;
let receipt = pending_tx.get_receipt().await?; /// Wait for the transaction to be finalized
If you need to obtain the transaction by the transaction hash, you can do it as follows:
// Replace with your transaction hash
let tx_hash: B256 = "0xabc...".parse()?;
// Fetch the transaction receipt
let receipt = pod_provider.get_transaction_receipt(tx_hash).await?;
// Handle the result
match receipt {
Some(receipt) => println!("Transaction Receipt: {:?}", receipt),
None => println!("Transaction not mined yet or invalid hash."),
}
The difference between pod SDK and Alloy SDK
In general, the Alloy SDK could be used to interact with the Pod network. However, this is not recommended, as the Pod SDK extends the Alloy SDK and provides essential functionalities like `wait_past_perfect_time`, which integrate Pod-specific features.
Additionally, using the Alloy SDK directly may lead to unexpected behavior when waiting for transaction confirmations or fetching blocks. Therefore, the Pod SDK is recommended, especially for more secure applications.
Error Handling
The error handling is identical to the Alloy error handling framework:
Best practices
For optimal client usage:
Always check for and handle the None case when querying transactions or receipts. the specific error types provided by the SDK for precise error handling.
Implement appropriate retry logic and timeouts for handling transient failures.
Maintain a single client instance when possible to improve resource utilization.
Check attestations when required by your application's security requirements.
Security Considerations
When developing applications using the pod Rust SDK:
Never expose private keys or sensitive credentials in your application code.
Verify transaction receipts and attestations before considering transactions final.
Implement appropriate timeouts and circuit breakers for network operations.
Monitor and log suspicious activity or unexpected errors.