createTransactions method

Future<List<TransactionWithSigner>> createTransactions()

Create the transactions which will carry out the specified method call. The list of transactions returned by this function will have the same length as method.getTxnCallCount().

Implementation

Future<List<TransactionWithSigner>> createTransactions() async {
  final encodedABIArgs = <Uint8List>[];
  encodedABIArgs.add(method.selector);

  var methodArgs = [];
  var methodAbiTypes = <AbiType>[];

  final transactionArgs = <TransactionWithSigner>[];
  final foreignAccounts = List<Address>.of(this.foreignAccounts);
  final foreignAssets = List<int>.of(this.foreignAssets);
  final foreignApps = List<int>.of(this.foreignApps);
  final appBoxReferences = List<AppBoxReference>.of(this.appBoxReferences);

  for (var i = 0; i < method.arguments.length; i++) {
    final arg = method.arguments[i];
    final methodArg = this.methodArgs[i];
    final parsedType = arg.parsedType;
    if (parsedType == null && methodArg is TransactionWithSigner) {
      if (!_checkTransactionType(methodArg, arg.type)) {
        throw ArgumentError(
            'expected transaction type $parsedType not match with given ');
      }

      transactionArgs.add(methodArg);
    } else if (AbiMethod.RefArgTypes.contains(arg.type)) {
      int index;
      if (arg.type == AbiMethod.RefTypeAccount) {
        final abiAddressT = TypeAddress();
        final accountAddress =
            abiAddressT.decode(abiAddressT.encode(methodArg));
        index = _populateForeignArrayIndex(
            accountAddress, foreignAccounts, sender);
      } else if (arg.type == AbiMethod.RefTypeAsset) {
        final abiUintT = TypeUint(64);
        final assetId = abiUintT.decode(abiUintT.encode(methodArg)) as BigInt;
        index =
            _populateForeignArrayIndex(assetId.toInt(), foreignAssets, null);
      } else if (arg.type == AbiMethod.RefTypeApplication) {
        final abiUintT = TypeUint(64);
        final appId = abiUintT.decode(abiUintT.encode(methodArg)) as BigInt;
        index = _populateForeignArrayIndex(
            appId.toInt(), foreignApps, applicationId);
      } else {
        throw ArgumentError(
            'Cannot add method call in ATC: ForeignArray arg type not matching');
      }

      methodArgs.add(index);
      methodAbiTypes.add(TypeUint(FOREIGN_OBJ_ABI_UINT_SIZE));
    } else if (parsedType != null) {
      methodArgs.add(methodArg);
      methodAbiTypes.add(parsedType);
    } else {
      throw ArgumentError(
          'error: the type of method argument is a transaction-type, but no transaction-with-signer provided');
    }
  }

  if (methodArgs.length > MAX_ABI_ARG_TYPE_LEN) {
    final wrappedABITypeList = <AbiType>[];
    final wrappedValueList = [];

    for (var i = MAX_ABI_ARG_TYPE_LEN - 1; i < methodArgs.length; i++) {
      wrappedABITypeList.add(methodAbiTypes[i]);
      wrappedValueList.add(methodArgs[i]);
    }

    final tupleT = TypeTuple(wrappedABITypeList);
    methodAbiTypes = methodAbiTypes.sublist(0, MAX_ABI_ARG_TYPE_LEN - 1);
    methodAbiTypes.add(tupleT);
    methodArgs = methodArgs.sublist(0, MAX_ABI_ARG_TYPE_LEN - 1);
    methodArgs.add(wrappedValueList);
  }

  for (var i = 0; i < methodArgs.length; i++) {
    encodedABIArgs.add(methodAbiTypes[i].encode(methodArgs[i]));
  }

  final tx = await (ApplicationCreateTransactionBuilder(onCompletion)
        ..firstValid = firstValid
        ..lastValid = lastValid
        ..genesisHash = genesisHash
        ..genesisId = genesisId
        ..suggestedFeePerByte = fee
        ..flatFee = flatFee
        ..note = note
        ..lease = lease
        ..rekeyTo = rekeyTo
        ..sender = sender
        ..arguments = encodedABIArgs
        ..accounts = foreignAccounts
        ..foreignApps = foreignApps
        ..foreignAssets = foreignAssets
        ..appBoxReferences = appBoxReferences
        ..approvalProgram = approvalProgram
        ..clearStateProgram = clearStateProgram
        ..globalStateSchema = globalStateSchema
        ..localStateSchema = localStateSchema)
      .build();

  tx.applicationId = applicationId;
  tx.extraPages = extraPages;

  final methodCall = TransactionWithSigner(transaction: tx, signer: signer);
  transactionArgs.add(methodCall);
  return transactionArgs;
}