1use near_primitives::views::StatusResponse;
2
3use crate::network::{Info, RootAccountSubaccountCreator, Sandbox, Testnet};
4use crate::network::{NetworkClient, NetworkInfo};
5use crate::operations::{CallTransaction, Function};
6use crate::result::{ExecutionFinalResult, Result};
7use crate::rpc::client::Client;
8use crate::rpc::patch::{ImportContractTransaction, PatchTransaction};
9use crate::rpc::query::{
10 GasPrice, Query, QueryChunk, ViewAccessKey, ViewAccessKeyList, ViewAccount, ViewBlock,
11 ViewCode, ViewFunction, ViewState,
12};
13use crate::types::{AccountId, InMemorySigner, NearToken, PublicKey};
14use crate::worker::Worker;
15use crate::{Account, Network};
16
17#[cfg(feature = "experimental")]
18use {
19 near_chain_configs::{GenesisConfig, ProtocolConfigView},
20 near_jsonrpc_client::methods::tx::RpcTransactionResponse,
21 near_jsonrpc_primitives::types::{
22 changes::{RpcStateChangesInBlockByTypeResponse, RpcStateChangesInBlockResponse},
23 receipts::ReceiptReference,
24 transactions::TransactionInfo,
25 },
26 near_primitives::{
27 types::{BlockReference, MaybeBlockId},
28 views::{
29 validator_stake_view::ValidatorStakeView, ReceiptView, StateChangesRequestView,
30 TxExecutionStatus,
31 },
32 },
33};
34
35impl<T: ?Sized> Clone for Worker<T> {
36 fn clone(&self) -> Self {
37 Self {
38 workspace: self.workspace.clone(),
39 tx_callbacks: self.tx_callbacks.clone(),
40 }
41 }
42}
43
44impl<T> NetworkInfo for Worker<T>
45where
46 T: NetworkInfo,
47{
48 fn info(&self) -> &Info {
49 self.workspace.info()
50 }
51}
52
53impl<T> Worker<T>
54where
55 T: NetworkClient + ?Sized,
56{
57 pub(crate) fn client(&self) -> &Client {
58 self.workspace.client()
59 }
60
61 pub fn view(&self, contract_id: &AccountId, function: &str) -> Query<'_, ViewFunction> {
65 self.view_by_function(contract_id, Function::new(function))
66 }
67
68 pub(crate) fn view_by_function(
69 &self,
70 contract_id: &AccountId,
71 function: Function,
72 ) -> Query<'_, ViewFunction> {
73 Query::new(
74 self.client(),
75 ViewFunction {
76 account_id: contract_id.clone(),
77 function,
78 },
79 )
80 }
81
82 pub fn view_code(&self, contract_id: &AccountId) -> Query<'_, ViewCode> {
84 Query::new(
85 self.client(),
86 ViewCode {
87 account_id: contract_id.clone(),
88 },
89 )
90 }
91
92 pub fn view_state(&self, contract_id: &AccountId) -> Query<'_, ViewState> {
96 Query::view_state(self.client(), contract_id)
97 }
98
99 pub fn view_block(&self) -> Query<'_, ViewBlock> {
105 Query::new(self.client(), ViewBlock)
106 }
107
108 pub fn view_chunk(&self) -> QueryChunk<'_> {
118 QueryChunk::new(self.client())
119 }
120
121 pub fn view_access_key(&self, id: &AccountId, pk: &PublicKey) -> Query<'_, ViewAccessKey> {
126 Query::new(
127 self.client(),
128 ViewAccessKey {
129 account_id: id.clone(),
130 public_key: pk.clone(),
131 },
132 )
133 }
134
135 pub fn view_access_keys(&self, id: &AccountId) -> Query<'_, ViewAccessKeyList> {
140 Query::new(
141 self.client(),
142 ViewAccessKeyList {
143 account_id: id.clone(),
144 },
145 )
146 }
147
148 pub fn view_account(&self, account_id: &AccountId) -> Query<'_, ViewAccount> {
150 Query::new(
151 self.client(),
152 ViewAccount {
153 account_id: account_id.clone(),
154 },
155 )
156 }
157
158 pub fn gas_price(&self) -> Query<'_, GasPrice> {
159 Query::new(self.client(), GasPrice)
160 }
161}
162
163impl<T> Worker<T>
164where
165 T: NetworkClient + Send + Sync + ?Sized,
166{
167 pub async fn transfer_near(
170 &self,
171 signer: &InMemorySigner,
172 receiver_id: &AccountId,
173 amount_yocto: NearToken,
174 ) -> Result<ExecutionFinalResult> {
175 self.client()
176 .transfer_near(signer, receiver_id, amount_yocto)
177 .await
178 .map(ExecutionFinalResult::from_view)
179 }
180
181 pub async fn delete_account(
184 &self,
185 account_id: &AccountId,
186 signer: &InMemorySigner,
187 beneficiary_id: &AccountId,
188 ) -> Result<ExecutionFinalResult> {
189 self.client()
190 .delete_account(signer, account_id, beneficiary_id)
191 .await
192 .map(ExecutionFinalResult::from_view)
193 }
194
195 pub async fn status(&self) -> Result<StatusResponse> {
197 self.client().status().await
198 }
199}
200
201#[cfg(feature = "experimental")]
202impl<T> Worker<T>
203where
204 T: NetworkClient + Send + Sync + ?Sized,
205{
206 pub async fn changes_in_block(
208 &self,
209 block_reference: BlockReference,
210 ) -> Result<RpcStateChangesInBlockByTypeResponse> {
211 self.client().changes_in_block(block_reference).await
212 }
213
214 pub async fn changes(
216 &self,
217 block_reference: BlockReference,
218 state_changes_request: StateChangesRequestView,
219 ) -> Result<RpcStateChangesInBlockResponse> {
220 self.client()
221 .changes(block_reference, state_changes_request)
222 .await
223 }
224
225 pub async fn genesis_config(&self) -> Result<GenesisConfig> {
227 self.client().genesis_config().await
228 }
229
230 pub async fn protocol_config(
232 &self,
233 block_reference: BlockReference,
234 ) -> Result<ProtocolConfigView> {
235 self.client().protocol_config(block_reference).await
236 }
237
238 pub async fn receipt(&self, receipt_reference: ReceiptReference) -> Result<ReceiptView> {
240 self.client().receipt(receipt_reference).await
241 }
242
243 pub async fn tx_status(
245 &self,
246 transaction_info: TransactionInfo,
247 wait_until: TxExecutionStatus,
248 ) -> Result<RpcTransactionResponse> {
249 self.client().tx_status(transaction_info, wait_until).await
250 }
251
252 pub async fn validators_ordered(
254 &self,
255 block_id: MaybeBlockId,
256 ) -> Result<Vec<ValidatorStakeView>> {
257 self.client().validators_ordered(block_id).await
258 }
259}
260
261impl<T> Worker<T>
262where
263 T: Network + 'static,
264{
265 pub fn call(
271 &self,
272 signer: &InMemorySigner,
273 contract_id: &AccountId,
274 function: &str,
275 ) -> CallTransaction {
276 CallTransaction::new(
277 self.clone().coerce(),
278 contract_id.to_owned(),
279 signer.clone(),
280 function,
281 )
282 }
283}
284
285impl Worker<Testnet> {
286 pub fn root_account_id(&self) -> AccountId {
288 self.workspace
289 .root_account_id()
290 .expect("no source of error expected for testnet")
291 }
292}
293
294impl Worker<Sandbox> {
295 pub fn root_account(&self) -> Result<Account> {
306 let signer = self.workspace.root_signer()?;
307 Ok(Account::new(signer, self.clone().coerce()))
308 }
309
310 pub fn import_contract<'a>(
314 &self,
315 id: &'a AccountId,
316 worker: &Worker<impl Network + 'static>,
317 ) -> ImportContractTransaction<'a> {
318 ImportContractTransaction::new(id, worker.clone().coerce(), self.clone())
319 }
320
321 pub fn patch(&self, account_id: &AccountId) -> PatchTransaction {
326 PatchTransaction::new(self, account_id.clone())
327 }
328
329 pub async fn patch_state(
333 &self,
334 contract_id: &AccountId,
335 key: &[u8],
336 value: &[u8],
337 ) -> Result<()> {
338 self.workspace.patch_state(contract_id, key, value).await
339 }
340
341 pub async fn fast_forward(&self, delta_height: u64) -> Result<()> {
351 self.workspace.fast_forward(delta_height).await
352 }
353
354 pub fn rpc_port(&self) -> Option<u16> {
356 self.workspace.server.rpc_port()
357 }
358
359 pub fn rpc_addr(&self) -> String {
361 self.workspace.server.rpc_addr()
362 }
363}