import 'dart:ffi'; import 'package:cw_monero/convert_utf8_to_string.dart'; import 'package:cw_monero/structs/ut8_box.dart'; import 'package:ffi/ffi.dart'; import 'package:flutter/foundation.dart'; import 'package:cw_monero/signatures.dart'; import 'package:cw_monero/types.dart'; import 'package:cw_monero/monero_api.dart'; import 'package:cw_monero/structs/transaction_info_row.dart'; import 'package:cw_monero/structs/pending_transaction.dart'; import 'package:cw_monero/exceptions/creation_transaction_exception.dart'; final transactionsRefreshNative = moneroApi .lookup>('transactions_refresh') .asFunction(); final transactionsCountNative = moneroApi .lookup>('transactions_count') .asFunction(); final transactionsGetAllNative = moneroApi .lookup>('transactions_get_all') .asFunction(); final transactionCreateNative = moneroApi .lookup>('transaction_create') .asFunction(); final transactionCreateMultDestNative = moneroApi .lookup>('transaction_create_mult_dest') .asFunction(); final transactionCommitNative = moneroApi .lookup>('transaction_commit') .asFunction(); final getTxKeyNative = moneroApi .lookup>('get_tx_key') .asFunction(); String getTxKey(String txId) { final txIdPointer = Utf8.toUtf8(txId); final keyPointer = getTxKeyNative(txIdPointer); free(txIdPointer); if (keyPointer != null) { return convertUTF8ToString(pointer: keyPointer); } return null; } void refreshTransactions() => transactionsRefreshNative(); int countOfTransactions() => transactionsCountNative(); List getAllTransations() { final size = transactionsCountNative(); final transactionsPointer = transactionsGetAllNative(); final transactionsAddresses = transactionsPointer.asTypedList(size); return transactionsAddresses .map((addr) => Pointer.fromAddress(addr).ref) .toList(); } PendingTransactionDescription createTransactionSync( {String address, String paymentId, String amount, int priorityRaw, int accountIndex = 0}) { final addressPointer = Utf8.toUtf8(address); final paymentIdPointer = Utf8.toUtf8(paymentId); final amountPointer = amount != null ? Utf8.toUtf8(amount) : nullptr; final errorMessagePointer = allocate(); final pendingTransactionRawPointer = allocate(); final created = transactionCreateNative( addressPointer, paymentIdPointer, amountPointer, priorityRaw, accountIndex, errorMessagePointer, pendingTransactionRawPointer) != 0; free(addressPointer); free(paymentIdPointer); if (amountPointer != nullptr) { free(amountPointer); } if (!created) { final message = errorMessagePointer.ref.getValue(); free(errorMessagePointer); throw CreationTransactionException(message: message); } return PendingTransactionDescription( amount: pendingTransactionRawPointer.ref.amount, fee: pendingTransactionRawPointer.ref.fee, hash: pendingTransactionRawPointer.ref.getHash(), pointerAddress: pendingTransactionRawPointer.address); } PendingTransactionDescription createTransactionMultDestSync( {List addresses, String paymentId, List amounts, int size, int priorityRaw, int accountIndex = 0}) { final List> addressesPointers = addresses.map(Utf8.toUtf8).toList(); final Pointer> addressesPointerPointer = allocate(count: size); final List> amountsPointers = amounts.map(Utf8.toUtf8).toList(); final Pointer> amountsPointerPointer = allocate(count: size); for (int i = 0; i < size; i++) { addressesPointerPointer[ i ] = addressesPointers[ i ]; amountsPointerPointer[ i ] = amountsPointers[ i ]; } final paymentIdPointer = Utf8.toUtf8(paymentId); final errorMessagePointer = allocate(); final pendingTransactionRawPointer = allocate(); final created = transactionCreateMultDestNative( addressesPointerPointer, paymentIdPointer, amountsPointerPointer, size, priorityRaw, accountIndex, errorMessagePointer, pendingTransactionRawPointer) != 0; free(addressesPointerPointer); free(amountsPointerPointer); addressesPointers.forEach((element) => free(element)); amountsPointers.forEach((element) => free(element)); free(paymentIdPointer); if (!created) { final message = errorMessagePointer.ref.getValue(); free(errorMessagePointer); throw CreationTransactionException(message: message); } return PendingTransactionDescription( amount: pendingTransactionRawPointer.ref.amount, fee: pendingTransactionRawPointer.ref.fee, hash: pendingTransactionRawPointer.ref.getHash(), pointerAddress: pendingTransactionRawPointer.address); } void commitTransactionFromPointerAddress({int address}) => commitTransaction( transactionPointer: Pointer.fromAddress(address)); void commitTransaction({Pointer transactionPointer}) { final errorMessagePointer = allocate(); final isCommited = transactionCommitNative(transactionPointer, errorMessagePointer) != 0; if (!isCommited) { final message = errorMessagePointer.ref.getValue(); free(errorMessagePointer); throw CreationTransactionException(message: message); } } PendingTransactionDescription _createTransactionSync(Map args) { final address = args['address'] as String; final paymentId = args['paymentId'] as String; final amount = args['amount'] as String; final priorityRaw = args['priorityRaw'] as int; final accountIndex = args['accountIndex'] as int; return createTransactionSync( address: address, paymentId: paymentId, amount: amount, priorityRaw: priorityRaw, accountIndex: accountIndex); } PendingTransactionDescription _createTransactionMultDestSync(Map args) { final addresses = args['addresses'] as List; final paymentId = args['paymentId'] as String; final amounts = args['amounts'] as List; final size = args['size'] as int; final priorityRaw = args['priorityRaw'] as int; final accountIndex = args['accountIndex'] as int; return createTransactionMultDestSync( addresses: addresses, paymentId: paymentId, amounts: amounts, size: size, priorityRaw: priorityRaw, accountIndex: accountIndex); } Future createTransaction( {String address, String paymentId, String amount, int priorityRaw, int accountIndex = 0}) => compute(_createTransactionSync, { 'address': address, 'paymentId': paymentId, 'amount': amount, 'priorityRaw': priorityRaw, 'accountIndex': accountIndex }); Future createTransactionMultDest( {List addresses, String paymentId, List amounts, int size, int priorityRaw, int accountIndex = 0}) => compute(_createTransactionMultDestSync, { 'addresses': addresses, 'paymentId': paymentId, 'amounts': amounts, 'size': size, 'priorityRaw': priorityRaw, 'accountIndex': accountIndex });