diff --git a/workspaces/src/network/sandbox.rs b/workspaces/src/network/sandbox.rs index 22e0b058..705d33b8 100644 --- a/workspaces/src/network/sandbox.rs +++ b/workspaces/src/network/sandbox.rs @@ -98,9 +98,9 @@ impl TopLevelAccountCreator for Sandbox { .create_account(&root_signer, &id, sk.public_key(), DEFAULT_DEPOSIT) .await?; - let signer = InMemorySigner::from_secret_key(id.clone(), sk); + let signer = InMemorySigner::from_secret_key(id, sk); Ok(Execution { - result: Account::new(id, signer, worker), + result: Account::new(signer, worker), details: ExecutionFinalResult::from_view(outcome), }) } @@ -124,9 +124,9 @@ impl TopLevelAccountCreator for Sandbox { ) .await?; - let signer = InMemorySigner::from_secret_key(id.clone(), sk); + let signer = InMemorySigner::from_secret_key(id, sk); Ok(Execution { - result: Contract::new(id, signer, worker), + result: Contract::new(signer, worker), details: ExecutionFinalResult::from_view(outcome), }) } diff --git a/workspaces/src/network/testnet.rs b/workspaces/src/network/testnet.rs index 5411e77d..e86c94e0 100644 --- a/workspaces/src/network/testnet.rs +++ b/workspaces/src/network/testnet.rs @@ -83,10 +83,10 @@ impl TopLevelAccountCreator for Testnet { ) -> Result> { let url = Url::parse(HELPER_URL).unwrap(); tool::url_create_account(url, id.clone(), sk.public_key()).await?; - let signer = InMemorySigner::from_secret_key(id.clone(), sk); + let signer = InMemorySigner::from_secret_key(id, sk); Ok(Execution { - result: Account::new(id, signer, worker), + result: Account::new(signer, worker), details: ExecutionFinalResult { // We technically have not burnt any gas ourselves since someone else paid to // create the account for us in testnet when we used the Helper contract. diff --git a/workspaces/src/operations.rs b/workspaces/src/operations.rs index 5d887426..1083f3c7 100644 --- a/workspaces/src/operations.rs +++ b/workspaces/src/operations.rs @@ -6,6 +6,7 @@ use crate::rpc::client::{ send_batch_tx_and_retry, send_batch_tx_async_and_retry, Client, DEFAULT_CALL_DEPOSIT, DEFAULT_CALL_FN_GAS, }; +use crate::rpc::query::{Query, ViewFunction}; use crate::rpc::BoxFuture; use crate::types::{ AccessKey, AccountId, Balance, Gas, InMemorySigner, KeyType, PublicKey, SecretKey, @@ -256,7 +257,7 @@ impl<'a> Transaction<'a> { /// Similiar to a [`Transaction`], but more specific to making a call into a contract. /// Note, only one call can be made per `CallTransaction`. pub struct CallTransaction<'a> { - worker: &'a Worker, + client: &'a Client, signer: InMemorySigner, contract_id: AccountId, function: Function, @@ -264,13 +265,13 @@ pub struct CallTransaction<'a> { impl<'a> CallTransaction<'a> { pub(crate) fn new( - worker: &'a Worker, + client: &'a Client, contract_id: AccountId, signer: InMemorySigner, function: &str, ) -> Self { Self { - worker, + client, signer, contract_id, function: Function::new(function), @@ -322,8 +323,7 @@ impl<'a> CallTransaction<'a> { /// object and return us the execution details, along with any errors if the transaction /// failed in any process along the way. pub async fn transact(self) -> Result { - self.worker - .client() + self.client .call( &self.signer, &self.contract_id, @@ -346,7 +346,7 @@ impl<'a> CallTransaction<'a> { /// [`status`]: TransactionStatus::status pub async fn transact_async(self) -> Result> { send_batch_tx_async_and_retry( - self.worker.client(), + self.client, &self.signer, &self.contract_id, vec![FunctionCallAction { @@ -362,9 +362,14 @@ impl<'a> CallTransaction<'a> { /// Instead of transacting the transaction, call into the specified view function. pub async fn view(self) -> Result { - self.worker - .view_by_function(&self.contract_id, self.function) - .await + Query::new( + self.client, + ViewFunction { + account_id: self.contract_id.clone(), + function: self.function, + }, + ) + .await } } @@ -426,8 +431,8 @@ impl<'a, 'b> CreateAccountTransaction<'a, 'b> { .create_account(&self.signer, &id, sk.public_key(), self.initial_balance) .await?; - let signer = InMemorySigner::from_secret_key(id.clone(), sk); - let account = Account::new(id, signer, self.worker.clone()); + let signer = InMemorySigner::from_secret_key(id, sk); + let account = Account::new(signer, self.worker.clone()); Ok(Execution { result: account, diff --git a/workspaces/src/rpc/patch.rs b/workspaces/src/rpc/patch.rs index 4f2e0a36..c9893669 100644 --- a/workspaces/src/rpc/patch.rs +++ b/workspaces/src/rpc/patch.rs @@ -154,6 +154,6 @@ impl<'a, 'b> ImportContractTransaction<'a> { .await .map_err(|err| SandboxErrorCode::PatchStateFailure.custom(err))?; - Ok(Contract::new(account_id, signer, self.into_network)) + Ok(Contract::new(signer, self.into_network)) } } diff --git a/workspaces/src/types/account.rs b/workspaces/src/types/account.rs index 6aa9729b..87802d29 100644 --- a/workspaces/src/types/account.rs +++ b/workspaces/src/types/account.rs @@ -18,14 +18,15 @@ use crate::result::{Execution, ExecutionFinalResult, Result}; /// network, such as creating transactions and calling into contract functions. #[derive(Clone)] pub struct Account { - pub(crate) id: AccountId, - pub(crate) signer: InMemorySigner, + signer: InMemorySigner, worker: Worker, } impl fmt::Debug for Account { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_struct("Account").field("id", &self.id).finish() + f.debug_struct("Account") + .field("id", &self.signer.account_id) + .finish() } } @@ -36,8 +37,7 @@ impl Account { worker: &Worker, ) -> Result { let signer = InMemorySigner::from_file(path.as_ref())?; - let id = signer.account_id.clone(); - Ok(Self::new(id, signer, worker.clone().coerce())) + Ok(Self::new(signer, worker.clone().coerce())) } /// Create an [`Account`] object from an [`AccountId`] and [`SecretKey`]. @@ -47,22 +47,23 @@ impl Account { worker: &Worker, ) -> Self { Self { - id: id.clone(), signer: InMemorySigner::from_secret_key(id, sk), worker: worker.clone().coerce(), } } - pub(crate) fn new(id: AccountId, signer: InMemorySigner, worker: Worker) -> Self { - Self { id, signer, worker } + pub(crate) fn new(signer: InMemorySigner, worker: Worker) -> Self { + Self { signer, worker } } /// Grab the current account identifier pub fn id(&self) -> &AccountId { - &self.id + &self.signer.account_id } - pub(crate) fn signer(&self) -> &InMemorySigner { + /// Grab the signer of the account. This signer is used to sign all transactions + /// sent to the network. + pub fn signer(&self) -> &InMemorySigner { &self.signer } @@ -70,13 +71,9 @@ impl Account { /// a [`CallTransaction`] object that we will make use to populate the /// rest of the call details. Note that the current [`Account`]'s secret /// key is used as the signer of the transaction. - pub fn call<'a, 'b>( - &'a self, - contract_id: &AccountId, - function: &'b str, - ) -> CallTransaction<'a> { + pub fn call(&self, contract_id: &AccountId, function: &str) -> CallTransaction<'_> { CallTransaction::new( - &self.worker, + self.worker.client(), contract_id.to_owned(), self.signer.clone(), function, @@ -105,13 +102,13 @@ impl Account { /// transaction. The beneficiary will receive the funds of the account deleted pub async fn delete_account(self, beneficiary_id: &AccountId) -> Result { self.worker - .delete_account(&self.id, &self.signer, beneficiary_id) + .delete_account(self.id(), &self.signer, beneficiary_id) .await } /// Views the current account's details such as balance and storage usage. pub fn view_account(&self) -> Query<'_, ViewAccount> { - self.worker.view_account(&self.id) + self.worker.view_account(self.id()) } /// Views the current accounts's access key, given the [`PublicKey`] associated to it. @@ -133,7 +130,7 @@ impl Account { Query::new( self.worker.client(), ViewAccessKeyList { - account_id: self.id.clone(), + account_id: self.id().clone(), }, ) } @@ -163,11 +160,7 @@ impl Account { .await?; Ok(Execution { - result: Contract::new( - self.id().clone(), - self.signer().clone(), - self.worker.clone(), - ), + result: Contract::new(self.signer().clone(), self.worker.clone()), details: ExecutionFinalResult::from_view(outcome), }) } @@ -190,10 +183,10 @@ impl Account { let savepath = save_dir.as_ref().to_path_buf(); std::fs::create_dir_all(save_dir).map_err(|e| ErrorKind::Io.custom(e))?; - let mut savepath = savepath.join(self.id.to_string()); + let mut savepath = savepath.join(self.id().to_string()); savepath.set_extension("json"); - crate::rpc::tool::write_cred_to_file(&savepath, &self.id, &self.secret_key().0); + crate::rpc::tool::write_cred_to_file(&savepath, self.id(), &self.secret_key().0); Ok(()) } @@ -221,7 +214,7 @@ pub struct Contract { impl fmt::Debug for Contract { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_struct("Contract") - .field("id", &self.account.id) + .field("id", self.account.id()) .finish() } } @@ -236,9 +229,9 @@ impl Contract { Self::account(Account::from_secret_key(id, sk, worker)) } - pub(crate) fn new(id: AccountId, signer: InMemorySigner, worker: Worker) -> Self { + pub(crate) fn new(signer: InMemorySigner, worker: Worker) -> Self { Self { - account: Account::new(id, signer, worker), + account: Account::new(signer, worker), } } @@ -248,7 +241,7 @@ impl Contract { /// Grab the current contract's account identifier pub fn id(&self) -> &AccountId { - &self.account.id + self.account.id() } /// Treat this [`Contract`] object as an [`Account`] type. This does nothing @@ -265,7 +258,9 @@ impl Contract { &mut self.account } - pub(crate) fn signer(&self) -> &InMemorySigner { + /// Grab the signer of the account. This signer is used to sign all transactions + /// sent to the network. + pub fn signer(&self) -> &InMemorySigner { self.account.signer() } diff --git a/workspaces/src/worker/impls.rs b/workspaces/src/worker/impls.rs index f9fe3745..83a50c51 100644 --- a/workspaces/src/worker/impls.rs +++ b/workspaces/src/worker/impls.rs @@ -1,16 +1,16 @@ use crate::network::{AllowDevAccountCreation, NetworkClient, NetworkInfo}; use crate::network::{Info, Sandbox}; -use crate::operations::Function; +use crate::operations::{CallTransaction, Function}; use crate::result::{ExecutionFinalResult, Result}; -use crate::rpc::client::{Client, DEFAULT_CALL_DEPOSIT, DEFAULT_CALL_FN_GAS}; +use crate::rpc::client::Client; use crate::rpc::patch::ImportContractTransaction; use crate::rpc::query::{ GasPrice, Query, QueryChunk, ViewAccessKey, ViewAccessKeyList, ViewAccount, ViewBlock, ViewCode, ViewFunction, ViewState, }; -use crate::types::{AccountId, Gas, InMemorySigner, PublicKey}; +use crate::types::{AccountId, InMemorySigner, PublicKey}; use crate::worker::Worker; -use crate::{Account, Contract, Network}; +use crate::{Account, Network}; use near_primitives::types::Balance; @@ -41,31 +41,28 @@ where self.workspace.client() } - /// Call into a contract's change function. - pub async fn call( + /// Call into a contract's change function. Returns a [`CallTransaction`] object + /// that we will make use to populate the rest of the call details. The [`signer`] + /// will be used to sign the transaction. + /// + /// [`signer`]: crate::types::InMemorySigner + pub fn call( &self, - contract: &Contract, + signer: &InMemorySigner, + contract_id: &AccountId, function: &str, - args: Vec, - gas: Option, - deposit: Option, - ) -> Result { - let outcome = self - .client() - .call( - contract.signer(), - contract.id(), - function.into(), - args, - gas.unwrap_or(DEFAULT_CALL_FN_GAS), - deposit.unwrap_or(DEFAULT_CALL_DEPOSIT), - ) - .await?; - - Ok(ExecutionFinalResult::from_view(outcome)) - } - - /// Call into a contract's view function. + ) -> CallTransaction<'_> { + CallTransaction::new( + self.client(), + contract_id.to_owned(), + signer.clone(), + function, + ) + } + + /// Call into a contract's view function. Returns a [`Query`] which allows us + /// to specify further details like the arguments of the view call, or at what + /// point in the chain we want to view. pub fn view(&self, contract_id: &AccountId, function: &str) -> Query<'_, ViewFunction> { self.view_by_function(contract_id, Function::new(function)) } @@ -197,9 +194,8 @@ where impl Worker { pub fn root_account(&self) -> Result { - let account_id = self.info().root_id.clone(); let signer = self.workspace.root_signer()?; - Ok(Account::new(account_id, signer, self.clone().coerce())) + Ok(Account::new(signer, self.clone().coerce())) } /// Import a contract from the the given network, and return us a [`ImportContractTransaction`]