Skip to content

Commit

Permalink
send versioned transaction
Browse files Browse the repository at this point in the history
  • Loading branch information
mrmizz committed Dec 21, 2024
1 parent 2c6ca13 commit 9538f6a
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 1 deletion.
42 changes: 41 additions & 1 deletion wasm/solana-client/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use solana_sdk::{
message::Message,
pubkey::Pubkey,
signature::Signature,
transaction::Transaction,
transaction::{Transaction, VersionedTransaction},
};

use crate::{
Expand Down Expand Up @@ -244,6 +244,31 @@ impl WasmClient {
Ok(response.into())
}

pub async fn send_versioned_transaction_with_config(
&self,
transaction: &VersionedTransaction,
config: RpcSendTransactionConfig,
) -> ClientResult<Signature> {
let request =
SendVersionedTransactionRequest::new_with_config(transaction.to_owned(), config).into();
let response = SendVersionedTransactionRequest::from(self.send(request).await?);

let signature: Signature = response.into();

// A mismatching RPC response signature indicates an issue with the RPC node, and
// should not be passed along to confirmation methods. The transaction may or may
// not have been submitted to the cluster, so callers should verify the success of
// the correct transaction signature independently.
if signature != transaction.signatures[0] {
Err(ClientError::new(&format!(
"RPC node returned mismatched signature {:?}, expected {:?}",
signature, transaction.signatures[0]
)))
} else {
Ok(transaction.signatures[0])
}
}

pub async fn send_transaction_with_config(
&self,
transaction: &Transaction,
Expand Down Expand Up @@ -281,6 +306,21 @@ impl WasmClient {
.await
}

pub async fn send_versioned_transaction(
&self,
transaction: &VersionedTransaction,
) -> ClientResult<Signature> {
self.send_versioned_transaction_with_config(
transaction,
RpcSendTransactionConfig {
preflight_commitment: Some(self.commitment()),
encoding: Some(UiTransactionEncoding::Base64),
..Default::default()
},
)
.await
}

pub async fn confirm_transaction_with_commitment(
&self,
signature: &Signature,
Expand Down
4 changes: 4 additions & 0 deletions wasm/solana-client/src/methods/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ mod program_accounts;
mod recent_performance_samples;
mod request_airdrop;
mod send_transaction;
mod send_versioned_transaction;
mod serde_utils;
mod signature_statuses;
mod signatures_for_address;
Expand Down Expand Up @@ -92,6 +93,9 @@ pub use {
},
request_airdrop::{RequestAirdropRequest, RequestAirdropResponse},
send_transaction::{SendTransactionRequest, SendTransactionResponse},
send_versioned_transaction::{
SendVersionedTransactionRequest, SendVersionedTransactionResponse,
},
signature_statuses::{
GetSignatureStatusesRequest, GetSignatureStatusesResponse, SignatureStatusesValue,
},
Expand Down
76 changes: 76 additions & 0 deletions wasm/solana-client/src/methods/send_versioned_transaction.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
use std::str::FromStr;

use solana_extra_wasm::transaction_status::UiTransactionEncoding;
use solana_sdk::{signature::Signature, transaction::VersionedTransaction};

use crate::utils::rpc_config::{serialize_and_encode, RpcSendTransactionConfig};
use crate::{ClientRequest, ClientResponse};

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SendVersionedTransactionRequest {
transaction: VersionedTransaction,
#[serde(skip_serializing_if = "Option::is_none")]
config: Option<RpcSendTransactionConfig>,
}

impl SendVersionedTransactionRequest {
pub fn new(transaction: VersionedTransaction) -> Self {
Self {
transaction,
config: None,
}
}
pub fn new_with_config(
transaction: VersionedTransaction,
config: RpcSendTransactionConfig,
) -> Self {
Self {
transaction,
config: Some(config),
}
}
}

impl From<SendVersionedTransactionRequest> for serde_json::Value {
fn from(value: SendVersionedTransactionRequest) -> Self {
let encoding = match value.config {
Some(ref c) => c.encoding.unwrap_or(UiTransactionEncoding::Base64),
None => UiTransactionEncoding::Base64,
};

let serialized_encoded =
serialize_and_encode::<VersionedTransaction>(&value.transaction, encoding).unwrap();

match value.config {
Some(config) => serde_json::json!([serialized_encoded, config]),
None => serde_json::json!([serialized_encoded]),
}
}
}

impl From<SendVersionedTransactionRequest> for ClientRequest {
fn from(val: SendVersionedTransactionRequest) -> Self {
let mut request = ClientRequest::new("sendTransaction");
let params = val.into();

request.params(params).clone()
}
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SendVersionedTransactionResponse(Signature);

impl From<SendVersionedTransactionResponse> for Signature {
fn from(val: SendVersionedTransactionResponse) -> Self {
val.0
}
}

impl From<ClientResponse> for SendVersionedTransactionResponse {
fn from(response: ClientResponse) -> Self {
let signature = response.result.as_str().expect("invalid response");
let signature = Signature::from_str(signature).expect("invalid signature");

SendVersionedTransactionResponse(signature)
}
}

0 comments on commit 9538f6a

Please sign in to comment.