diff --git a/docs/src/custom-transactions/transaction-builders.md b/docs/src/custom-transactions/transaction-builders.md index 629f96b16..03cfbbe82 100644 --- a/docs/src/custom-transactions/transaction-builders.md +++ b/docs/src/custom-transactions/transaction-builders.md @@ -60,7 +60,7 @@ As we have used coins that require a signature, we have to add the signer to the > **Note** The signature is not created until the transaction is finalized with `build(&provider)` -We need to do one more thing before we stop thinking about transaction inputs. Executing the transaction also incurs a fee that is paid with the base asset. Our base asset inputs need to be large enough so that the total amount covers the transaction fee and any other operations we are doing. The `Account` trait lets us use `adjust_for_fee()` for adjusting the transaction inputs if needed to cover the fee. The second argument to `adjust_for_fee()` is the total amount of the base asset that we expect our transaction to spend regardless of fees. In our case, this is the **ask_amount** we are transferring to the predicate. +We need to do one more thing before we stop thinking about transaction inputs. Executing the transaction also incurs a fee that is paid with the base asset. Our base asset inputs need to be large enough so that the total amount covers the transaction fee and any other operations we are doing. The `ViewOnlyAccount` trait lets us use `adjust_for_fee()` for adjusting the transaction inputs if needed to cover the fee. The second argument to `adjust_for_fee()` is the total amount of the base asset that we expect our transaction to spend regardless of fees. In our case, this is the **ask_amount** we are transferring to the predicate. ```rust,ignore {{#include ../../../examples/cookbook/src/lib.rs:custom_tx_adjust}} diff --git a/examples/cookbook/src/lib.rs b/examples/cookbook/src/lib.rs index 88c8a0bae..7814432c4 100644 --- a/examples/cookbook/src/lib.rs +++ b/examples/cookbook/src/lib.rs @@ -3,7 +3,7 @@ mod tests { use std::{str::FromStr, time::Duration}; use fuels::{ - accounts::{predicate::Predicate, wallet::WalletUnlocked, Account, ViewOnlyAccount}, + accounts::{predicate::Predicate, wallet::WalletUnlocked, ViewOnlyAccount}, prelude::Result, test_helpers::{setup_single_asset_coins, setup_test_provider}, types::{ diff --git a/packages/fuels-accounts/src/account.rs b/packages/fuels-accounts/src/account.rs index 7801e4973..dbc46dab9 100644 --- a/packages/fuels-accounts/src/account.rs +++ b/packages/fuels-accounts/src/account.rs @@ -92,20 +92,6 @@ pub trait ViewOnlyAccount: std::fmt::Debug + Send + Sync + Clone { self.try_provider()?.get_spendable_resources(filter).await } -} - -#[cfg_attr(not(target_arch = "wasm32"), async_trait)] -pub trait Account: ViewOnlyAccount { - /// Returns a vector consisting of `Input::Coin`s and `Input::Message`s for the given - /// asset ID and amount. The `witness_index` is the position of the witness (signature) - /// in the transaction's list of witnesses. In the validation process, the node will - /// use the witness at this index to validate the coins returned by this method. - async fn get_asset_inputs_for_amount( - &self, - asset_id: AssetId, - amount: u64, - excluded_coins: Option>, - ) -> Result>; /// Returns a vector containing the output coin and change output given an asset and amount fn get_asset_outputs_for_amount( @@ -122,6 +108,15 @@ pub trait Account: ViewOnlyAccount { ] } + /// Returns a vector consisting of `Input::Coin`s and `Input::Message`s for the given + /// asset ID and amount. + async fn get_asset_inputs_for_amount( + &self, + asset_id: AssetId, + amount: u64, + excluded_coins: Option>, + ) -> Result>; + /// Add base asset inputs to the transaction to cover the estimated fee. /// Requires contract inputs to be at the start of the transactions inputs vec /// so that their indexes are retained @@ -155,7 +150,10 @@ pub trait Account: ViewOnlyAccount { Ok(()) } +} +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] +pub trait Account: ViewOnlyAccount { // Add signatures to the builder if the underlying account is a wallet fn add_witnesses(&self, _tb: &mut Tb) -> Result<()> { Ok(()) diff --git a/packages/fuels-accounts/src/impersonated_account.rs b/packages/fuels-accounts/src/impersonated_account.rs index 77e4f1994..10f3759df 100644 --- a/packages/fuels-accounts/src/impersonated_account.rs +++ b/packages/fuels-accounts/src/impersonated_account.rs @@ -29,6 +29,7 @@ impl ImpersonatedAccount { } } +#[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)] impl ViewOnlyAccount for ImpersonatedAccount { fn address(&self) -> &Bech32Address { self.address() @@ -37,12 +38,7 @@ impl ViewOnlyAccount for ImpersonatedAccount { fn try_provider(&self) -> Result<&Provider> { self.provider.as_ref().ok_or_else(try_provider_error) } -} -#[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)] -impl Account for ImpersonatedAccount { - /// Returns a vector consisting of `Input::Coin`s and `Input::Message`s for the given - /// asset ID and amount. async fn get_asset_inputs_for_amount( &self, asset_id: AssetId, @@ -56,7 +52,9 @@ impl Account for ImpersonatedAccount { .map(Input::resource_signed) .collect::>()) } +} +impl Account for ImpersonatedAccount { fn add_witnesses(&self, tb: &mut Tb) -> Result<()> { tb.add_signer(self.clone())?; diff --git a/packages/fuels-accounts/src/predicate.rs b/packages/fuels-accounts/src/predicate.rs index c623d053a..6fc1262ef 100644 --- a/packages/fuels-accounts/src/predicate.rs +++ b/packages/fuels-accounts/src/predicate.rs @@ -101,6 +101,7 @@ impl Predicate { } #[cfg(feature = "std")] +#[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)] impl ViewOnlyAccount for Predicate { fn address(&self) -> &Bech32Address { self.address() @@ -109,11 +110,7 @@ impl ViewOnlyAccount for Predicate { fn try_provider(&self) -> Result<&Provider> { self.provider.as_ref().ok_or_else(try_provider_error) } -} -#[cfg(feature = "std")] -#[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)] -impl Account for Predicate { async fn get_asset_inputs_for_amount( &self, asset_id: AssetId, @@ -130,3 +127,6 @@ impl Account for Predicate { .collect::>()) } } + +#[cfg(feature = "std")] +impl Account for Predicate {} diff --git a/packages/fuels-accounts/src/wallet.rs b/packages/fuels-accounts/src/wallet.rs index fe124f58e..45fec01d2 100644 --- a/packages/fuels-accounts/src/wallet.rs +++ b/packages/fuels-accounts/src/wallet.rs @@ -78,6 +78,7 @@ impl Wallet { } } +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] impl ViewOnlyAccount for Wallet { fn address(&self) -> &Bech32Address { self.address() @@ -86,6 +87,20 @@ impl ViewOnlyAccount for Wallet { fn try_provider(&self) -> Result<&Provider> { self.provider.as_ref().ok_or_else(try_provider_error) } + + async fn get_asset_inputs_for_amount( + &self, + asset_id: AssetId, + amount: u64, + excluded_coins: Option>, + ) -> Result> { + Ok(self + .get_spendable_resources(asset_id, amount, excluded_coins) + .await? + .into_iter() + .map(Input::resource_signed) + .collect::>()) + } } impl WalletUnlocked { @@ -190,6 +205,7 @@ impl WalletUnlocked { } } +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] impl ViewOnlyAccount for WalletUnlocked { fn address(&self) -> &Bech32Address { self.wallet.address() @@ -198,28 +214,20 @@ impl ViewOnlyAccount for WalletUnlocked { fn try_provider(&self) -> Result<&Provider> { self.provider.as_ref().ok_or_else(try_provider_error) } -} -#[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)] -impl Account for WalletUnlocked { - /// Returns a vector consisting of `Input::Coin`s and `Input::Message`s for the given - /// asset ID and amount. The `witness_index` is the position of the witness (signature) - /// in the transaction's list of witnesses. In the validation process, the node will - /// use the witness at this index to validate the coins returned by this method. async fn get_asset_inputs_for_amount( &self, asset_id: AssetId, amount: u64, excluded_coins: Option>, ) -> Result> { - Ok(self - .get_spendable_resources(asset_id, amount, excluded_coins) - .await? - .into_iter() - .map(Input::resource_signed) - .collect::>()) + self.wallet + .get_asset_inputs_for_amount(asset_id, amount, excluded_coins) + .await } +} +impl Account for WalletUnlocked { fn add_witnesses(&self, tb: &mut Tb) -> Result<()> { tb.add_signer(self.clone())?;