Skip to content

Commit

Permalink
feat: Upgrade near-primitives to 0.21.x and refactor the API adding `…
Browse files Browse the repository at this point in the history
…wait_until` flag, drop `check_tx` method (#136)
  • Loading branch information
telezhnaya authored Apr 19, 2024
1 parent c1fdbd1 commit 2b4ad7b
Show file tree
Hide file tree
Showing 14 changed files with 233 additions and 107 deletions.
8 changes: 4 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ thiserror = "1.0.37"
serde_json = "1.0.85"
lazy_static = "1.4.0"

near-crypto = "0.20.0"
near-primitives = "0.20.0"
near-chain-configs = "0.20.0"
near-jsonrpc-primitives = "0.20.0"
near-crypto = "0.21.1"
near-primitives = "0.21.1"
near-chain-configs = "0.21.1"
near-jsonrpc-primitives = "0.21.1"

[dev-dependencies]
tokio = { version = "1.0", features = ["macros", "rt-multi-thread"] }
Expand Down
9 changes: 7 additions & 2 deletions examples/contract_change_method.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use near_jsonrpc_client::{methods, JsonRpcClient};
use near_jsonrpc_primitives::types::query::QueryResponseKind;
use near_jsonrpc_primitives::types::transactions::TransactionInfo;
use near_jsonrpc_primitives::types::transactions::{RpcTransactionError, TransactionInfo};
use near_primitives::transaction::{Action, FunctionCallAction, Transaction};
use near_primitives::types::BlockReference;
use near_primitives::views::TxExecutionStatus;

use serde_json::json;
use tokio::time;
Expand Down Expand Up @@ -71,6 +72,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
tx_hash,
sender_account_id: signer.account_id.clone(),
},
wait_until: TxExecutionStatus::Executed,
})
.await;
let received_at = time::Instant::now();
Expand All @@ -82,7 +84,10 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {

match response {
Err(err) => match err.handler_error() {
Some(methods::tx::RpcTransactionError::UnknownTransaction { .. }) => {
Some(
RpcTransactionError::TimeoutError
| RpcTransactionError::UnknownTransaction { .. },
) => {
time::sleep(time::Duration::from_secs(2)).await;
continue;
}
Expand Down
46 changes: 23 additions & 23 deletions examples/create_account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use near_primitives::transaction::{
Action, AddKeyAction, CreateAccountAction, FunctionCallAction, Transaction, TransferAction,
};
use near_primitives::types::{AccountId, BlockReference};
use near_primitives::views::{FinalExecutionStatus, TxExecutionStatus};

use serde_json::json;
use tokio::time;
Expand Down Expand Up @@ -205,6 +206,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
tx_hash,
sender_account_id: signer.account_id.clone(),
},
wait_until: TxExecutionStatus::Final,
})
.await;
let received_at = time::Instant::now();
Expand All @@ -215,40 +217,38 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
}

match response {
Ok(
ref outcome @ near_primitives::views::FinalExecutionOutcomeView {
status: near_primitives::views::FinalExecutionStatus::SuccessValue(ref s),
..
},
) => {
// outcome.status != SuccessValue(`false`)
if s == b"false" {
println!("(i) Account successfully created after {}s", delta);
} else {
println!("{:#?}", outcome);
println!("(!) Creating the account failed, check above for full logs");
Ok(tx) => {
// it's fine to unwrap because we asked for finalized tx
let outcome = tx.final_execution_outcome.unwrap().into_outcome();
match outcome.status {
FinalExecutionStatus::Failure(err) => {
println!("{:#?}", err);
println!("(!) Creating the account failed, check above for full logs");
break;
}
FinalExecutionStatus::SuccessValue(ref s) => {
// outcome.status != SuccessValue(`false`)
if s == b"false" {
println!("(i) Account successfully created after {}s", delta);
} else {
println!("{:#?}", outcome);
println!("(!) Creating the account failed, check above for full logs");
}
break;
}
_ => {}
}
break;
}
Ok(near_primitives::views::FinalExecutionOutcomeView {
status: near_primitives::views::FinalExecutionStatus::Failure(err),
..
}) => {
println!("{:#?}", err);
println!("(!) Creating the account failed, check above for full logs");
break;
}
Err(err) => match err.handler_error() {
Some(
RpcTransactionError::TimeoutError
| methods::tx::RpcTransactionError::UnknownTransaction { .. },
| RpcTransactionError::UnknownTransaction { .. },
) => {
time::sleep(time::Duration::from_secs(2)).await;
continue;
}
_ => Err(err)?,
},
_ => {}
}
}

Expand Down
8 changes: 6 additions & 2 deletions examples/query_tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,22 +93,26 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
break 'root;
};

let wait_until_str = utils::input("Enter the desired guaranteed execution status (can be one of: NONE, INCLUDED, INCLUDED_FINAL, EXECUTED, FINAL): ")?;
let wait_until = serde_json::from_value(serde_json::json!(wait_until_str))?;

match client
.call(methods::tx::RpcTransactionStatusRequest {
transaction_info: methods::tx::TransactionInfo::TransactionId {
tx_hash,
sender_account_id: account_id,
},
wait_until,
})
.await
{
Ok(block_details) => println!("{:#?}", block_details),
Ok(tx_details) => println!("{:#?}", tx_details),
Err(err) => match err.handler_error() {
Some(err) => {
println!("(i) An error occurred `{:#?}`", err);
continue;
}
_ => println!("(i) A non-handler error ocurred `{:#?}`", err),
_ => println!("(i) A non-handler error occurred `{:#?}`", err),
},
};
break;
Expand Down
111 changes: 111 additions & 0 deletions examples/send_tx.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
use near_jsonrpc_client::{methods, JsonRpcClient};
use near_jsonrpc_primitives::types::query::QueryResponseKind;
use near_jsonrpc_primitives::types::transactions::{RpcTransactionError, TransactionInfo};
use near_primitives::transaction::{Action, FunctionCallAction, Transaction};
use near_primitives::types::BlockReference;
use near_primitives::views::TxExecutionStatus;
use tokio::time;

mod utils;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
env_logger::init();

let client = JsonRpcClient::connect("https://rpc.testnet.near.org");

let signer_account_id = utils::input("Enter the signer Account ID: ")?.parse()?;
let signer_secret_key = utils::input("Enter the signer's private key: ")?.parse()?;
let wait_until_str = utils::input("Enter the desired guaranteed execution status (can be one of: NONE, INCLUDED, INCLUDED_FINAL, EXECUTED, FINAL): ")?;
let wait_until: TxExecutionStatus = serde_json::from_value(serde_json::json!(wait_until_str))?;

let signer = near_crypto::InMemorySigner::from_secret_key(signer_account_id, signer_secret_key);

let access_key_query_response = client
.call(methods::query::RpcQueryRequest {
block_reference: BlockReference::latest(),
request: near_primitives::views::QueryRequest::ViewAccessKey {
account_id: signer.account_id.clone(),
public_key: signer.public_key.clone(),
},
})
.await?;

let current_nonce = match access_key_query_response.kind {
QueryResponseKind::AccessKey(access_key) => access_key.nonce,
_ => Err("failed to extract current nonce")?,
};

let other_account = utils::input("Enter the account to be rated: ")?;
let rating = utils::input("Enter a rating: ")?.parse::<f32>()?;

let transaction = Transaction {
signer_id: signer.account_id.clone(),
public_key: signer.public_key.clone(),
nonce: current_nonce + 1,
receiver_id: "nosedive.testnet".parse()?,
block_hash: access_key_query_response.block_hash,
actions: vec![Action::FunctionCall(Box::new(FunctionCallAction {
method_name: "rate".to_string(),
args: serde_json::json!({
"account_id": other_account,
"rating": rating,
})
.to_string()
.into_bytes(),
gas: 100_000_000_000_000, // 100 TeraGas
deposit: 0,
}))],
};
let tx_hash = transaction.get_hash_and_size().0;

let request = methods::send_tx::RpcSendTransactionRequest {
signed_transaction: transaction.sign(&signer),
wait_until: wait_until.clone(),
};

let sent_at = time::Instant::now();
let response = match client.call(request).await {
Ok(response) => response,
Err(err) => {
match err.handler_error() {
Some(RpcTransactionError::TimeoutError) => {}
_ => Err(err)?,
}
loop {
let response = client
.call(methods::tx::RpcTransactionStatusRequest {
transaction_info: TransactionInfo::TransactionId {
tx_hash,
sender_account_id: signer.account_id.clone(),
},
wait_until: wait_until.clone(),
})
.await;
let received_at = time::Instant::now();
let delta = (received_at - sent_at).as_secs();

if delta > 60 {
Err("time limit exceeded for the transaction to be recognized")?;
}

match response {
Err(err) => match err.handler_error() {
Some(RpcTransactionError::TimeoutError) => {}
_ => Err(err)?,
},
Ok(response) => {
break response;
}
}
}
}
};

let received_at = time::Instant::now();
let delta = (received_at - sent_at).as_secs();
println!("response gotten after: {}s", delta);
println!("response: {:#?}", response);

Ok(())
}
8 changes: 5 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
//! ```no_run
//! use near_jsonrpc_client::{methods, JsonRpcClient};
//! use near_jsonrpc_primitives::types::transactions::TransactionInfo;
//! use near_primitives::views::TxExecutionStatus;
//!
//! # #[tokio::main]
//! # async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
Expand All @@ -48,6 +49,7 @@
//! tx_hash: "9FtHUFBQsZ2MG77K3x3MJ9wjX3UT8zE1TczCrhZEcG8U".parse()?,
//! sender_account_id: "miraclx.near".parse()?,
//! },
//! wait_until: TxExecutionStatus::Executed,
//! };
//!
//! let tx_status = client.call(tx_status_request).await?;
Expand Down Expand Up @@ -439,9 +441,9 @@ mod tests {
assert!(
matches!(
tx_status,
Ok(methods::tx::RpcTransactionStatusResponse { ref transaction, .. })
if transaction.signer_id == "miraclx.near"
&& transaction.hash == "9FtHUFBQsZ2MG77K3x3MJ9wjX3UT8zE1TczCrhZEcG8U".parse()?
Ok(methods::tx::RpcTransactionResponse { ref final_execution_outcome, .. })
if final_execution_outcome.unwrap().into_outcome().transaction.signer_id == "miraclx.near"
&& final_execution_outcome.unwrap().into_outcome().transaction.hash == "9FtHUFBQsZ2MG77K3x3MJ9wjX3UT8zE1TczCrhZEcG8U".parse()?
),
"expected an Ok(RpcTransactionStatusResponse) with matching signer_id + hash, found [{:?}]",
tx_status
Expand Down
2 changes: 1 addition & 1 deletion src/methods/broadcast_tx_async.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ impl From<RpcBroadcastTxAsyncRequest>
fn from(this: RpcBroadcastTxAsyncRequest) -> Self {
Self {
signed_transaction: this.signed_transaction,
wait_until: near_primitives::views::TxExecutionStatus::None,
wait_until: near_primitives::views::TxExecutionStatus::default(),
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/methods/broadcast_tx_commit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ impl From<RpcBroadcastTxCommitRequest>
fn from(this: RpcBroadcastTxCommitRequest) -> Self {
Self {
signed_transaction: this.signed_transaction,
wait_until: near_primitives::views::TxExecutionStatus::None,
wait_until: near_primitives::views::TxExecutionStatus::default(),
}
}
}
Expand Down
3 changes: 0 additions & 3 deletions src/methods/experimental/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@ pub use changes as EXPERIMENTAL_changes;
pub mod changes_in_block;
pub use changes_in_block as EXPERIMENTAL_changes_in_block;

pub mod check_tx;
pub use check_tx as EXPERIMENTAL_check_tx;

pub mod genesis_config;
pub use genesis_config as EXPERIMENTAL_genesis_config;

Expand Down
Loading

0 comments on commit 2b4ad7b

Please sign in to comment.