Learn how to create, submit, and manage blockchain transactions using the Ember SDK.
Creating Transactions
Create an unsigned transaction:
Copy use ember_sdk::{SubmitTransactionParams, TransactionType};
async fn create_transaction(client: &EmberClient) -> Result<(), EmberError> {
// First create a transaction plan (e.g., swap, transfer, etc.)
let swap_plan = client.create_swap(swap_params).await?;
// The transaction plan contains the unsigned transaction
let unsigned_tx = swap_plan.transaction_plan;
println!("Created unsigned transaction: {:?}", unsigned_tx);
Ok(())
}
Submitting Transactions
Submit a signed transaction:
Copy async fn submit_transaction(
client: &EmberClient,
signed_tx: String
) -> Result<(), EmberError> {
let params = SubmitTransactionParams {
chain_id: 1,
signed_transaction: signed_tx,
transaction_type: TransactionType::Swap,
};
let response = client.submit_transaction(params).await?;
println!("Transaction hash: {}", response.transaction_hash);
println!("Status: {:?}", response.status);
println!("Estimated confirmation time: {} seconds",
response.estimated_confirmation_time);
Ok(())
}
Transaction Status Monitoring
Monitor transaction status using WebSockets:
Copy use ember_sdk::{EmberWebSocket, StreamTransactionsParams};
async fn monitor_transaction(
ws: &EmberWebSocket,
tx_hash: String
) -> Result<(), EmberError> {
let params = StreamTransactionsParams {
transaction_hashes: vec![tx_hash],
};
ws.on_transaction_update(|update| {
println!("Transaction {} status: {:?}", update.transaction_hash, update.status);
match update.status {
TransactionStatus::Pending => {
println!("Waiting for confirmation...");
},
TransactionStatus::Confirmed => {
println!("Transaction confirmed!");
println!("Block number: {}", update.details.block_number);
println!("Gas used: {}", update.details.gas_used);
},
TransactionStatus::Failed => {
println!("Transaction failed!");
println!("Error: {:?}", update.details.error);
},
}
}).await;
Ok(())
}
Gas Management
Handle gas estimation and pricing:
Copy async fn handle_gas(client: &EmberClient) -> Result<(), EmberError> {
// Get transaction plan
let plan = client.create_swap(swap_params).await?;
// Check gas estimates
println!("Estimated gas: {}", plan.fee_breakdown.gas_fee);
println!("Service fee: {}", plan.fee_breakdown.service_fee);
println!("Total fee: {}", plan.fee_breakdown.total);
// Check if gas cost is acceptable
if plan.fee_breakdown.total > max_acceptable_fee {
println!("Gas cost too high, waiting for better rates");
return Ok(());
}
Ok(())
}
Error Recovery
Handle common transaction errors:
Copy async fn handle_transaction_errors(
client: &EmberClient,
params: SubmitTransactionParams
) -> Result<(), EmberError> {
match client.submit_transaction(params).await {
Ok(response) => {
println!("Transaction submitted: {}", response.transaction_hash);
},
Err(EmberError::NetworkError(details)) => {
if details.retryable {
println!("Network error, retrying in {} ms",
details.suggested_wait_time.unwrap_or(1000));
// Implement retry logic
}
},
Err(EmberError::ValidationError(errors)) => {
for error in errors {
println!("Validation error: {} - {}", error.field, error.message);
}
},
Err(e) => println!("Other error: {:?}", e),
}
Ok(())
}
Transaction History
Track transaction history:
Copy use std::collections::HashMap;
struct TransactionTracker {
pending_transactions: HashMap<String, TransactionDetails>,
}
impl TransactionTracker {
async fn track_transaction(
&mut self,
tx_hash: String,
details: TransactionDetails
) {
self.pending_transactions.insert(tx_hash.clone(), details);
// Set up monitoring
let ws = setup_websocket().await?;
let params = StreamTransactionsParams {
transaction_hashes: vec![tx_hash.clone()],
};
ws.on_transaction_update(move |update| {
if update.status == TransactionStatus::Confirmed {
self.pending_transactions.remove(&tx_hash);
println!("Transaction {} confirmed", tx_hash);
}
}).await;
}
}
Best Practices
Always estimate gas costs before submitting transactions
Implement proper error handling and recovery
Monitor transaction status for confirmation
Keep track of pending transactions
Consider implementing automatic retry logic
Set reasonable gas price limits
Handle nonce management for multiple transactions
Clean up transaction tracking resources