fuels_accounts/
impersonated_account.rs

1use std::fmt::Debug;
2
3use async_trait::async_trait;
4use fuel_crypto::{Message, Signature};
5use fuels_core::{
6    traits::Signer,
7    types::{
8        bech32::Bech32Address, coin_type_id::CoinTypeId, errors::Result, input::Input,
9        transaction_builders::TransactionBuilder, AssetId,
10    },
11};
12
13use crate::{accounts_utils::try_provider_error, provider::Provider, Account, ViewOnlyAccount};
14
15/// A `ImpersonatedAccount` simulates ownership of assets held by an account with a given address.
16/// `ImpersonatedAccount` will only succeed in unlocking assets if the the network is setup with
17/// utxo_validation set to false.
18#[derive(Debug, Clone)]
19pub struct ImpersonatedAccount {
20    address: Bech32Address,
21    provider: Option<Provider>,
22}
23
24impl ImpersonatedAccount {
25    pub fn new(address: Bech32Address, provider: Option<Provider>) -> Self {
26        Self { address, provider }
27    }
28
29    pub fn address(&self) -> &Bech32Address {
30        &self.address
31    }
32}
33
34#[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)]
35impl ViewOnlyAccount for ImpersonatedAccount {
36    fn address(&self) -> &Bech32Address {
37        self.address()
38    }
39
40    fn try_provider(&self) -> Result<&Provider> {
41        self.provider.as_ref().ok_or_else(try_provider_error)
42    }
43
44    async fn get_asset_inputs_for_amount(
45        &self,
46        asset_id: AssetId,
47        amount: u64,
48        excluded_coins: Option<Vec<CoinTypeId>>,
49    ) -> Result<Vec<Input>> {
50        Ok(self
51            .get_spendable_resources(asset_id, amount, excluded_coins)
52            .await?
53            .into_iter()
54            .map(Input::resource_signed)
55            .collect::<Vec<Input>>())
56    }
57}
58
59impl Account for ImpersonatedAccount {
60    fn add_witnesses<Tb: TransactionBuilder>(&self, tb: &mut Tb) -> Result<()> {
61        tb.add_signer(self.clone())?;
62
63        Ok(())
64    }
65}
66
67#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
68#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
69impl Signer for ImpersonatedAccount {
70    async fn sign(&self, _message: Message) -> Result<Signature> {
71        Ok(Signature::default())
72    }
73
74    fn address(&self) -> &Bech32Address {
75        &self.address
76    }
77}