buildSafeTransaction function

SafeTransaction buildSafeTransaction({
  1. required List<SafeUtxoOutput> utxos,
  2. required List<SafeTransactionRecipient> rs,
  3. required List<SafeGhostKey?> gs,
  4. required String extra,
  5. String? reference,
})

Implementation

SafeTransaction buildSafeTransaction({
  required List<SafeUtxoOutput> utxos,
  required List<SafeTransactionRecipient> rs,
  required List<SafeGhostKey?> gs,
  required String extra,
  String? reference,
}) {
  if (utxos.isEmpty) {
    throw Exception('utxo list is empty');
  }
  if (utf8.encode(extra).length > 512) {
    throw Exception('extra data is too long. ${utf8.encode(extra).length}');
  }
  var asset = '';
  final inputs = <Input>[];
  for (final utxo in utxos) {
    if (asset.isEmpty) {
      asset = utxo.asset;
    } else if (asset != utxo.asset) {
      throw Exception('utxo list contains different asset');
    }
    inputs.add(Input(hash: utxo.transactionHash, index: utxo.outputIndex));
  }

  if (rs.length != gs.length) {
    throw Exception('recipient and ghost key count not match');
  }

  final outputs = <Output>[];
  for (var i = 0; i < rs.length; i++) {
    final recipient = rs[i];
    switch (recipient) {
      case WithdrawalTransactionRecipient():
        outputs.add(Output(
            type: OutputType.withdrawalSubmit,
            amount: recipient.amount,
            withdrawal: WithdrawalData(
              address: recipient.destination,
              tag: recipient.tag ?? '',
            )));
      case UserTransactionRecipient():
        assert(gs[i] != null, 'ghost key is null for recipient $i');
        outputs.add(Output(
          type: OutputType.script,
          amount: recipient.amount,
          keys: gs[i]!.keys,
          mask: gs[i]!.mask,
          script: encodeScript(recipient.threshold),
        ));
    }
  }

  return SafeTransaction(
    asset: asset,
    extra: extra,
    inputs: inputs,
    outputs: outputs,
    reference: reference != null ? [reference] : const [],
  );
}