diff --git a/near-accounts/examples/multi-thread.rs b/near-accounts/examples/multi-thread.rs new file mode 100644 index 0000000..28d09cb --- /dev/null +++ b/near-accounts/examples/multi-thread.rs @@ -0,0 +1,68 @@ +use near_accounts::Account; +use near_crypto::{InMemorySigner, SecretKey}; +use near_primitives::{types::Gas, views::FinalExecutionOutcomeViewEnum}; +use near_providers::JsonRpcProvider; +use std::sync::Arc; +mod utils; +use near_primitives::types::{AccountId, Balance}; +use serde_json::json; + +#[tokio::main] +async fn main() -> Result<(), Box> { + env_logger::init(); + + // Initialization and user inputs as before + + let signer_account_id: AccountId = "near-api-rs.testnet".parse::()?; + let signer_secret_key = "ed25519:29nYmQCZMsQeYtztXZzm57ayQt2uBHXdn2SAjK4ccMGSQaNUFNJ7Aoteno81eKTex9cGBbk1FuDuqJRsdzx34xDY".parse::()?; + + let provider = Arc::new(JsonRpcProvider::new("https://rpc.testnet.near.org")); + //let provider = JsonRpcProvider::new("https://rpc.testnet.near.org"); + let signer = Arc::new(InMemorySigner::from_secret_key( + signer_account_id.clone(), + signer_secret_key, + )); + let account = Account::new(signer_account_id, signer.clone(), provider.clone()); + + let contract_id: AccountId = "contract.near-api-rs.testnet".parse::()?; + + // This spawns a new asynchronous task to handle account creation + let handle = tokio::spawn(async move { + let method_name = "set_status".to_string(); + let args_json = json!({"message": "working1"}); + + // Amount to transfer to the new account + let gas: Gas = 100_000_000_000_000; // Example amount in yoctoNEAR + let amount: Balance = 10_000_000_000_000_000_000_000; // Example amount in yoctoNEAR + + let result = account + .function_call(&contract_id, method_name, args_json, gas, amount) + .await + .expect("Reason") + .transact() + .await; + + match result { + Ok(res) => match &res.final_execution_outcome { + Some(FinalExecutionOutcomeViewEnum::FinalExecutionOutcome(outcome)) => { + println!("Final Execution outcome: {:#?}", outcome); + } + Some(FinalExecutionOutcomeViewEnum::FinalExecutionOutcomeWithReceipt( + outcome_receipt, + )) => { + println!( + "Final Execution outcome with receipt: {:#?}", + outcome_receipt + ); + } + None => println!("No Final execution outcome."), + }, + Err(err) => println!("Error: {:#?}", err), + } + }); + + // You can do more work here or wait for the handle if needed + handle.await?; + + Ok(()) +} diff --git a/near-accounts/examples/view_function.rs b/near-accounts/examples/view_function.rs index 8855f58..bc1a18a 100644 --- a/near-accounts/examples/view_function.rs +++ b/near-accounts/examples/view_function.rs @@ -5,10 +5,7 @@ mod utils; use near_primitives::types::AccountId; use serde_json::json; -#[tokio::main] -async fn main() -> Result<(), Box> { - env_logger::init(); - +async fn single_thread() -> Result<(), Box> { let contract_id: AccountId = "contract.near-api-rs.testnet".parse::()?; let provider = Arc::new(JsonRpcProvider::new("https://rpc.testnet.near.org")); @@ -22,3 +19,34 @@ async fn main() -> Result<(), Box> { Ok(()) } + +async fn multi_thread() -> Result<(), Box> { + let contract_id: AccountId = "contract.near-api-rs.testnet".parse::()?; + + let provider = Arc::new(JsonRpcProvider::new("https://rpc.testnet.near.org")); + + let args_json = json!({"account_id": "contract.near-api-rs.testnet"}); + let method_name = "get_status".to_string(); + + let handle = tokio::spawn(async move { + let result = view_function(provider, contract_id, method_name, args_json).await; + println!("response: {:#?}", result); + }); + + // You can do more work here or wait for the handle if needed + handle.await?; + Ok(()) +} + +#[tokio::main] +async fn main() -> Result<(), Box> { + env_logger::init(); + + println!("Running single thread view function..."); + single_thread().await?; + + println!("Running multi thread view function..."); + multi_thread().await?; + + Ok(()) +} diff --git a/near-accounts/src/accounts.rs b/near-accounts/src/accounts.rs index 44df053..b677084 100644 --- a/near-accounts/src/accounts.rs +++ b/near-accounts/src/accounts.rs @@ -20,13 +20,16 @@ use serde_json::Value; use std::ops::{Add, Mul, Sub}; use std::sync::Arc; +type ArcProviderSendSync = Arc; +type ArcSignerSendSync = Arc; + ///This struct represent a Transaction Sender used specifically if you want to send transactions manually. /// This gives user more control over how they want to send their transactions to the NEAR network for examples, asyn, sync or advanced. /// It is only used by function_call method from Account for now to enable this flexibility. #[derive(Clone)] pub struct TransactionSender { pub signed_transaction: SignedTransaction, - provider: Arc, + provider: ArcProviderSendSync, } impl TransactionSender { @@ -40,7 +43,7 @@ impl TransactionSender { /// # Returns /// /// A new `Account` instance. - pub fn new(signed_transaction: SignedTransaction, provider: Arc) -> Self { + pub fn new(signed_transaction: SignedTransaction, provider: ArcProviderSendSync) -> Self { Self { signed_transaction, provider, @@ -112,8 +115,8 @@ impl TransactionSender { /// Represents a NEAR account, encapsulating account ID, signer, and provider for blockchain interaction. pub struct Account { pub account_id: AccountId, - pub signer: Arc, // Use your Signer abstraction - pub provider: Arc, // Use your Provider abstraction + pub signer: ArcSignerSendSync, // Use your Signer abstraction + pub provider: ArcProviderSendSync, // Use your Provider abstraction } /// Represents the balance details of a NEAR account. @@ -139,8 +142,8 @@ impl Account { /// A new `Account` instance. pub fn new( account_id: AccountId, - signer: Arc, - provider: Arc, + signer: ArcSignerSendSync, + provider: ArcProviderSendSync, ) -> Self { Self { account_id, @@ -457,7 +460,7 @@ impl Account { /// /// A `Result` containing the result of the function call or an error if the operation fails. pub async fn view_function( - provider: Arc, + provider: ArcProviderSendSync, contract_id: AccountId, method_name: String, args: Value, @@ -494,7 +497,7 @@ pub async fn view_function( /// /// A `Result` containing the contract's state filtered by the specified prefix, or an error if the query fails. pub async fn view_state( - provider: Arc, + provider: ArcProviderSendSync, contract_id: AccountId, prefix: Option, ) -> Result> { @@ -526,7 +529,7 @@ pub async fn view_state( /// /// A `Result` containing a list of access keys for the specified account, or an error if the operation fails. pub async fn get_access_key( - provider: Arc, + provider: ArcProviderSendSync, account_id: AccountId, ) -> Result> { let query_request = QueryRequest::ViewAccessKeyList { account_id }; @@ -552,7 +555,7 @@ pub async fn get_access_key( /// /// A `Result` containing the state of the specified account, or an error if the query fails. pub async fn state( - provider: Arc, + provider: ArcProviderSendSync, account_id: AccountId, ) -> Result> { let query_request = QueryRequest::ViewAccount { account_id }; @@ -578,7 +581,7 @@ pub async fn state( /// /// A `Result` containing the balance details of the account, structured as `AccountBalance`, or an error if the query fails. pub async fn get_account_balance( - provider: Arc, + provider: ArcProviderSendSync, account_id: AccountId, ) -> Result> { // Assuming `experimental_protocol_config` and `state` are async functions you can call on the provider