Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add send_and_confirm_transaction method and refactor transaction sending logic #87

Merged
merged 4 commits into from
Nov 26, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ Our SDK is designed to provide a seamless developer experience when building on
- [`get_compute_units`](https://github.com/helius-labs/helius-rust-sdk/blob/a79a751e1a064125010bdb359068a366d635d005/src/optimized_transaction.rs#L29-L75) - Simulates a transaction to get the total compute units consumed
- [`poll_transaction_confirmation`](https://github.com/helius-labs/helius-rust-sdk/blob/a79a751e1a064125010bdb359068a366d635d005/src/optimized_transaction.rs#L77-L112) - Polls a transaction to check whether it has been confirmed in 5 second intervals with a 15 second timeout
- [`send_smart_transaction`](https://github.com/helius-labs/helius-rust-sdk/blob/705d66fb7d4004fc32c2a5f0d6ca4a1f2a7b175d/src/optimized_transaction.rs#L314-L374) - Builds and sends an optimized transaction, and handles its confirmation status
- [`send_and_confirm_transaction`] - Sends a transaction and handles its confirmation status with retry logic
- [`send_smart_transaction_with_seeds`]() - Sends a smart transaction using seed bytes

### Jito Smart Transactions and Helper Methods
Expand Down
65 changes: 47 additions & 18 deletions src/optimized_transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@ use crate::Helius;

use bincode::{serialize, ErrorKind};
use reqwest::StatusCode;
use solana_client::rpc_config::{RpcSendTransactionConfig, RpcSimulateTransactionConfig};
use solana_client::rpc_response::{Response, RpcSimulateTransactionResult};
use solana_client::{
rpc_client::SerializableTransaction,
rpc_config::{RpcSendTransactionConfig, RpcSimulateTransactionConfig},
rpc_response::{Response, RpcSimulateTransactionResult},
};
use solana_sdk::signature::{keypair_from_seed, Keypair};
use solana_sdk::{
address_lookup_table::AddressLookupTableAccount,
Expand Down Expand Up @@ -336,29 +339,55 @@ impl Helius {
pub async fn send_smart_transaction(&self, config: SmartTransactionConfig<'_>) -> Result<Signature> {
let (transaction, last_valid_block_height) = self.create_smart_transaction(&config.create_config).await?;

// Common logic for sending transactions
let send_transaction_config = config.send_options.clone();

let send_result = |transaction: &Transaction| {
self.connection()
.send_transaction_with_config(transaction, send_transaction_config)
};
let send_versioned_result = |transaction: &VersionedTransaction| {
self.connection()
.send_transaction_with_config(transaction, send_transaction_config)
};
match transaction {
SmartTransaction::Legacy(tx) => {
self.send_and_confirm_transaction(
&tx,
config.send_options,
last_valid_block_height,
Some(config.timeout.into()),
)
.await
}
SmartTransaction::Versioned(tx) => {
self.send_and_confirm_transaction(
&tx,
config.send_options,
last_valid_block_height,
Some(config.timeout.into()),
)
.await
}
}
}

/// Sends a transaction and handles its confirmation status
///
/// # Arguments
/// * `transaction` - The transaction to be sent, which implements `SerializableTransaction`
/// * `send_transaction_config` - Configuration options for sending the transaction
/// * `last_valid_block_height` - The last block height at which the transaction is valid
/// * `timeout` - Optional duration for polling transaction confirmation, defaults to 60 seconds
///
/// # Returns
/// The transaction signature, if successful
pub async fn send_and_confirm_transaction(
&self,
transaction: &impl SerializableTransaction,
send_transaction_config: RpcSendTransactionConfig,
last_valid_block_height: u64,
timeout: Option<Duration>,
) -> Result<Signature> {
0xIchigo marked this conversation as resolved.
Show resolved Hide resolved
// Retry logic with a timeout
let timeout: Duration = config.timeout.into();
let timeout: Duration = timeout.unwrap_or(Duration::from_secs(60));
let start_time: Instant = Instant::now();

while Instant::now().duration_since(start_time) < timeout
|| self.connection().get_block_height()? <= last_valid_block_height
{
let result = match &transaction {
SmartTransaction::Legacy(tx) => send_result(tx),
SmartTransaction::Versioned(tx) => send_versioned_result(tx),
};
let result = self
.connection()
.send_transaction_with_config(transaction, send_transaction_config);

match result {
Ok(signature) => {
Expand Down