Icon LinkCustom Transactions

There may be scenarios where you need to build out transactions that involve multiple program types and assets; this can be done by instantiating a ScriptTransactionRequest. This class allows you to a append multiple program types and assets to a single transaction.

Consider the following script that transfers multiple assets to a contract:

script;
 
use std::token::force_transfer_to_contract;
 
fn main(contract_address: b256, asset_a: AssetId, amount_asset_a: u64, asset_b: AssetId, amount_asset_b: u64) -> bool {
let wrapped_contract = ContractId::from(contract_address);
 
force_transfer_to_contract(wrapped_contract, asset_a,  amount_asset_a);
force_transfer_to_contract(wrapped_contract, asset_b,  amount_asset_b);
true
}

This script can be executed by creating a ScriptTransactionRequest, appending the resource and contract inputs/outputs and then sending the transaction, as follows:

import type { BN, CoinQuantityLike, ScriptTransactionRequest } from 'fuels';
 
// 1. Create a script transaction using the script binary
const request = new ScriptTransactionRequest({
	...defaultTxParams,
	gasLimit: 3_000_000,
	script: scriptBin,
});
 
// 2. Instantiate the script main arguments
const scriptArguments = [contract.id.toB256(), assetIdA, new BN(1000), assetIdB, new BN(500)];
 
// 3. Get the resources for inputs and outpoints
const fee = request.calculateFee();
const quantities: CoinQuantityLike[] = [[1000, assetIdA], [500, assetIdB], fee];
const resources = await wallet.getResourcesToSpend(quantities);
 
// 4. Populate the script data and inputs/outputs
request
	.setData(abiContents, scriptArguments)
	.addContractInputAndOutput(contract.id)
	.addResourceInputsAndOutputs(resources);
 
// 5. Send the transaction
const tx = await wallet.sendTransaction(request);
await tx.waitForResult();