The old methods of estimating and funding transaction were deprecated in favor of a more robust provider.assembleTx
. This guide will help you migrate your code to use the new method.
getTransactionCost
and fund
const transferAmount = 100;
const request = new ScriptTransactionRequest();
// Add a coin output to transfer 100 base asset to account
request.addCoinOutput(accountB.address, transferAmount, baseAssetId);
const txCost = await accountA.getTransactionCost(request);
request.maxFee = txCost.maxFee;
request.gasLimit = txCost.gasUsed;
await accountA.fund(request, txCost);
const tx = await accountA.sendTransaction(request);
const { isStatusSuccess } = await tx.waitForResult();
const transferAmount = 100;
const request = new ScriptTransactionRequest();
request.addCoinOutput(accountB.address, transferAmount, baseAssetId);
const { assembledRequest } = await provider.assembleTx({
request,
feePayerAccount: accountA,
accountCoinQuantities: [
{
amount: transferAmount,
assetId: baseAssetId,
account: accountA,
changeOutputAccount: accountA,
},
],
});
const tx = await accountA.sendTransaction(assembledRequest);
const { isStatusSuccess } = await tx.waitForResult();
Consider the following Sway script
script;
use std::asset::transfer;
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);
let contract_id = Identity::ContractId(wrapped_contract);
transfer(contract_id, asset_a, amount_asset_a);
transfer(contract_id, asset_b, amount_asset_b);
true
}
This script will transfer 2 assets amount to the same contract address.
const transferAmountA = 400;
const transferAmountB = 600;
const script = new ScriptTransferToContract(account);
const request = await script.functions
.main(
contractId,
{ bits: TestAssetId.A.value },
transferAmountA,
{ bits: TestAssetId.B.value },
transferAmountB
)
.addContracts([contract])
.getTransactionRequest();
const txCost = await account.getTransactionCost(request, {
quantities: [
{
amount: bn(transferAmountA),
assetId: TestAssetId.A.value,
},
{
amount: bn(transferAmountB),
assetId: TestAssetId.B.value,
},
],
});
request.maxFee = txCost.maxFee;
request.gasLimit = txCost.gasUsed;
await account.fund(request, txCost);
const tx = await account.sendTransaction(request);
const { isStatusSuccess } = await tx.waitForResult();
const transferAmountA = 400;
const transferAmountB = 600;
const script = new ScriptTransferToContract(account);
const request = await script.functions
.main(
contractId,
{ bits: TestAssetId.A.value },
transferAmountA,
{ bits: TestAssetId.B.value },
transferAmountB
)
.getTransactionRequest();
const { assembledRequest } = await provider.assembleTx({
request,
feePayerAccount: account,
accountCoinQuantities: [
{
amount: transferAmountA,
assetId: TestAssetId.A.value,
account,
changeOutputAccount: account,
},
{
amount: transferAmountB,
assetId: TestAssetId.B.value,
account,
changeOutputAccount: account,
},
],
});
const tx = await account.sendTransaction(assembledRequest);
const { isStatusSuccess } = await tx.waitForResult();
estimateAndFund
const request = new ScriptTransactionRequest();
// Add a coin output to transfer 100 base asset to accountB
request.addCoinOutput(accountB.address, 100, baseAssetId);
// Estimate and fund the request
await request.estimateAndFund(accountA);
// Send the transaction
const tx = await accountA.sendTransaction(request);
await tx.waitForResult();
const request = new ScriptTransactionRequest();
// Add a coin output to transfer 100 base asset to accountB
request.addCoinOutput(accountB.address, 100, baseAssetId);
const { assembledRequest } = await provider.assembleTx({
request,
feePayerAccount: accountA,
accountCoinQuantities: [
{
amount: 100,
assetId: baseAssetId,
account: accountA,
changeOutputAccount: accountA,
},
],
});
const tx = await accountA.sendTransaction(assembledRequest);
await tx.waitForResult();
More Explicit Control: assembleTx
provides clearer control over which account pays fees and which accounts provide resources.
Better Resource Management: The new method allows you to specify exactly which accounts should provide which quantities of assets.
Controlling Change Output: When informing each account coin quantity you have control over determining who is going to receive a the change for that specific asset ID.
getTransactionCost
and estimateAndFund
are deprecated and are going to be removed on futures updates The new assembleTx
method provides several additional options:
export type AssembleTxParams<T extends TransactionRequest = TransactionRequest> = {
// The transaction request to assemble
request: T;
// Coin quantities required for the transaction, optional if transaction only needs funds for the fee
accountCoinQuantities?: AccountCoinQuantity[];
// Account that will pay for the transaction fees
feePayerAccount: Account;
// Block horizon for gas price estimation (default: 10)
blockHorizon?: number;
// Whether to estimate predicates (default: true)
estimatePredicates?: boolean;
// Resources to be ignored when funding the transaction (optional)
resourcesIdsToIgnore?: ResourcesIdsToIgnore;
// Amount of gas to reserve (optional)
reserveGas?: number;
};
export type AssembleTxResponse<T extends TransactionRequest = TransactionRequest> = {
assembledRequest: T;
gasPrice: BN;
receipts: TransactionResultReceipt[];
rawReceipts: TransactionReceiptJson[];
};
You can read more about the assembleTx
here .