The ViewOnlyAccount trait provides a common interface to query balances.
The Account trait, in addition to the above, also provides a common interface to retrieve spendable resources or transfer assets. When performing actions in the SDK that lead to a transaction, you will typically need to provide an account that will be used to allocate resources required by the transaction, including transaction fees.
Both traits are implemented by the following types:
An account implements the following methods for transferring assets:
transfer
force_transfer_to_contract
withdraw_to_base_layer
The following examples are provided for a Wallet account. A Predicate account would work similarly, but you might need to set its predicate data before attempting to spend resources owned by it.
With wallet.transfer you can initiate a transaction to transfer an asset from your account to a target address.
use fuels::prelude::*;// Setup 2 test wallets with 1 coin eachlet num_wallets =Some(2);let coins_per_wallet =Some(1);let coin_amount =Some(1);let wallets =launch_custom_provider_and_get_wallets(WalletsConfig::new(num_wallets, coins_per_wallet, coin_amount),None,None,).await?;// Transfer the base asset with amount 1 from wallet 1 to wallet 2let asset_id =Default::default();let (_tx_id, _receipts) = wallets[0].transfer(wallets[1].address(), 1, asset_id, TxPolicies::default()).await?;let wallet_2_final_coins = wallets[1].get_coins(BASE_ASSET_ID).await?;// Check that wallet 2 now has 2 coinsassert_eq!(wallet_2_final_coins.len(), 2);
You can transfer assets to a contract via wallet.force_transfer_to_contract.
// Check the current balance of the contract with id 'contract_id'let contract_balances = wallet.try_provider()?.get_contract_balances(&contract_id).await?;assert!(contract_balances.is_empty());// Transfer an amount of 300 to the contractlet amount =300;let asset_id = random_asset_id;let (_tx_id, _receipts) = wallet.force_transfer_to_contract(&contract_id, amount, asset_id, TxPolicies::default()).await?;// Check that the contract now has 1 coinlet contract_balances = wallet.try_provider()?.get_contract_balances(&contract_id).await?;assert_eq!(contract_balances.len(), 1);let random_asset_balance = contract_balances.get(&random_asset_id).unwrap();assert_eq!(*random_asset_balance, 300);
For transferring assets to the base layer chain, you can use wallet.withdraw_to_base_layer.
use std::str::FromStr;use fuels::prelude::*;let wallets =launch_custom_provider_and_get_wallets(WalletsConfig::new(Some(1), None, None),None,None,).await?;let wallet = wallets.first().unwrap();let amount =1000;let base_layer_address =Address::from_str("0x4710162c2e3a95a6faff05139150017c9e38e5e280432d546fae345d6ce6d8fe").expect("Invalid address.");let base_layer_address =Bech32Address::from(base_layer_address);// Transfer an amount of 1000 to the specified base layer addresslet (tx_id, msg_id, _receipts) = wallet.withdraw_to_base_layer(&base_layer_address, amount, TxPolicies::default()).await?;let _block_height = wallet.try_provider()?.produce_blocks(1, None).await?;// Retrieve a message proof from the providerlet proof = wallet.try_provider()?.get_message_proof(&tx_id, &msg_id, None, Some(2)).await?.expect("Failed to retrieve message proof.");// Verify the amount and recipientassert_eq!(proof.amount, amount);assert_eq!(proof.recipient, base_layer_address);
The above example creates an Address from a string and converts it to a Bech32Address. Next, it calls wallet.withdraw_to_base_layer by providing the address, the amount to be transferred, and the transaction policies. Lastly, to verify that the transfer succeeded, the relevant message proof is retrieved with provider.get_message_proof, and the amount and the recipient are verified.