Skip to main content

sui_cluster_test/
wallet_client.rs

1// Copyright (c) Mysten Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4use crate::cluster::new_wallet_context_from_cluster;
5
6use super::Cluster;
7use shared_crypto::intent::Intent;
8use sui_keys::keystore::AccountKeystore;
9use sui_rpc_api::Client as GrpcClient;
10use sui_sdk::wallet_context::WalletContext;
11use sui_types::base_types::SuiAddress;
12use sui_types::crypto::{KeypairTraits, Signature};
13use sui_types::transaction::TransactionData;
14use tracing::{Instrument, info_span};
15
16/// Wraps a `WalletContext` for the test user. The wallet context already caches
17/// a gRPC client (`WalletContext::grpc_client`) that talks to the fullnode over
18/// the public gRPC services (`LedgerService`, `StateService`,
19/// `TransactionExecutionService`), so we do not build a separate JSON-RPC client.
20pub struct WalletClient {
21    wallet_context: WalletContext,
22    address: SuiAddress,
23}
24
25#[allow(clippy::borrowed_box)]
26impl WalletClient {
27    pub async fn new_from_cluster(cluster: &(dyn Cluster + Sync + Send)) -> Self {
28        let key = cluster.user_key();
29        let address: SuiAddress = key.public().into();
30        let wallet_context = new_wallet_context_from_cluster(cluster, key)
31            .await
32            .instrument(info_span!("init_wallet_context_for_test_user"));
33
34        Self {
35            wallet_context: wallet_context.into_inner(),
36            address,
37        }
38    }
39
40    pub fn get_wallet(&self) -> &WalletContext {
41        &self.wallet_context
42    }
43
44    pub fn get_wallet_mut(&mut self) -> &mut WalletContext {
45        &mut self.wallet_context
46    }
47
48    pub fn get_wallet_address(&self) -> SuiAddress {
49        self.address
50    }
51
52    /// Returns a fresh (owned, cheaply cloned) gRPC client backed by the wallet's
53    /// cached connection. All network reads and execution in the suite go through
54    /// this client rather than the retired full JSON-RPC contract.
55    pub fn grpc_client(&self) -> GrpcClient {
56        self.wallet_context
57            .grpc_client()
58            .expect("wallet context should expose a gRPC client")
59    }
60
61    pub async fn sign(&self, txn_data: &TransactionData, desc: &str) -> Signature {
62        self.get_wallet()
63            .config
64            .keystore
65            .sign_secure(&self.address, txn_data, Intent::sui_transaction())
66            .await
67            .unwrap_or_else(|e| panic!("Failed to sign transaction for {}. {}", desc, e))
68    }
69}