prepareTransaction method
Future<Uint8List>
prepareTransaction(
- Transaction tx, {
- required String sender,
- BigInt? gasBudget,
Prepare tx (sender, gas price/payment/budget) and return the built
TransactionData BCS bytes, ready to sign.
Implementation
Future<Uint8List> prepareTransaction(
Transaction tx, {
required String sender,
BigInt? gasBudget,
}) async {
// The adapter lets the builder resolve object references and moveCall
// signatures over gRPC; offline limits avoid a protocol-config fetch.
final buildOptions = BuildOptions(
client: GrpcBuilderAdapter(this),
limits: <String, dynamic>{},
);
// Resolve any Move Registry (`@org/app`) names in moveCall targets/types.
await tx.resolveNames(
resolvePackage: resolvePackage,
resolveType: resolveType,
);
tx.setSenderIfNotSet(sender);
final gasPrice = BigInt.from((await getReferenceGasPrice()).toInt());
tx.setGasPrice(gasPrice);
final gasCoin = await _selectGasCoin(sender);
tx.setGasPayment([gasCoin]);
if (gasBudget != null) {
tx.setGasBudget(gasBudget);
return tx.build(buildOptions);
}
// Estimate budget by simulating. The provisional budget must (a) not exceed
// the gas coin's balance and (b) leave room for amounts the transaction
// splits off the gas coin. Use a modest cap; callers moving large amounts
// from gas should pass an explicit [gasBudget].
final suiBalance = BigInt.from((await getBalance(sender)).balance.toInt());
final provisionalCap = BigInt.from(100000000); // 0.1 SUI
tx.setGasBudget(suiBalance < provisionalCap ? suiBalance : provisionalCap);
final provisional = await tx.build(buildOptions);
final sim = await simulateTransaction(provisional);
final status = sim.transaction.effects.status;
if (!status.success) {
throw StateError('Gas estimation simulation failed: ${status.error}');
}
final gas = sim.transaction.effects.gasUsed;
final computation = BigInt.from(gas.computationCost.toInt());
final storage = BigInt.from(gas.storageCost.toInt());
final rebate = BigInt.from(gas.storageRebate.toInt());
final base = computation + _safeOverhead * gasPrice;
final withStorage = base + storage - rebate;
final budget = withStorage > base ? withStorage : base;
tx.setGasBudget(budget);
return tx.build(buildOptions);
}