other fixes from monero.dart and monero_c

This commit is contained in:
Czarek Nakamoto 2024-04-20 19:19:13 +02:00 committed by cyan
parent dcf6140444
commit 5b42130e85
9 changed files with 154 additions and 151 deletions

View file

@ -1,6 +1,6 @@
# TODO(mrcyjanek): Cleanup, this is borrowed from unnamed_monero_wallet repo. # TODO(mrcyjanek): Cleanup, this is borrowed from unnamed_monero_wallet repo.
MONERO_C_TAG=v0.18.3.3-RC27 MONERO_C_TAG=v0.18.3.3-RC31
LIBCPP_SHARED_SO_TAG=latest-RC1 LIBCPP_SHARED_SO_TAG=latest-RC1
LIBCPP_SHARED_SO_NDKVERSION=r17c LIBCPP_SHARED_SO_NDKVERSION=r17c

View file

@ -245,8 +245,8 @@ packages:
dependency: transitive dependency: transitive
description: description:
path: "." path: "."
ref: ada81417cb53d8b0e34022df1dd3d9dc1fe62ab5 ref: e2149153ecbaa6cc4d7d3970d8fa8ce1099b63af
resolved-ref: ada81417cb53d8b0e34022df1dd3d9dc1fe62ab5 resolved-ref: e2149153ecbaa6cc4d7d3970d8fa8ce1099b63af
url: "https://git.mrcyjanek.net/mrcyjanek/monero.dart" url: "https://git.mrcyjanek.net/mrcyjanek/monero.dart"
source: git source: git
version: "0.0.0" version: "0.0.0"

View file

@ -1,9 +1,14 @@
import 'dart:ffi';
import 'dart:isolate';
import 'package:cw_monero/api/account_list.dart'; import 'package:cw_monero/api/account_list.dart';
import 'package:cw_monero/api/exceptions/creation_transaction_exception.dart'; import 'package:cw_monero/api/exceptions/creation_transaction_exception.dart';
import 'package:cw_monero/api/monero_output.dart'; import 'package:cw_monero/api/monero_output.dart';
import 'package:cw_monero/api/structs/pending_transaction.dart'; import 'package:cw_monero/api/structs/pending_transaction.dart';
import 'package:ffi/ffi.dart';
import 'package:monero/monero.dart' as monero; import 'package:monero/monero.dart' as monero;
import 'package:monero/src/generated_bindings_monero.g.dart' as monero_gen;
String getTxKey(String txId) { String getTxKey(String txId) {
@ -30,31 +35,48 @@ Transaction getTransaction(String txId) {
return Transaction(txInfo: monero.TransactionHistory_transactionById(txhistory!, txid: txId)); return Transaction(txInfo: monero.TransactionHistory_transactionById(txhistory!, txid: txId));
} }
PendingTransactionDescription createTransactionSync( Future<PendingTransactionDescription> createTransactionSync(
{required String address, {required String address,
required String paymentId, required String paymentId,
required int priorityRaw, required int priorityRaw,
String? amount, String? amount,
int accountIndex = 0, int accountIndex = 0,
List<String> preferredInputs = const []}) { List<String> preferredInputs = const []}) async {
final amt = amount == null ? 0 : monero.Wallet_amountFromString(amount); final amt = amount == null ? 0 : monero.Wallet_amountFromString(amount);
final pendingTx = monero.Wallet_createTransaction(
wptr!, final address_ = address.toNativeUtf8();
dst_addr: address, final paymentId_ = paymentId.toNativeUtf8();
payment_id: paymentId, final preferredInputs_ = preferredInputs.join(monero.defaultSeparatorStr).toNativeUtf8();
amount: amt,
mixin_count: 1, final waddr = wptr!.address;
pendingTransactionPriority: priorityRaw, final addraddr = address_.address;
subaddr_account: accountIndex, final paymentIdAddr = paymentId_.address;
preferredInputs: preferredInputs, final preferredInputsAddr = preferredInputs_.address;
); final spaddr = monero.defaultSeparator.address;
final pendingTx = Pointer<Void>.fromAddress(await Isolate.run(() {
final tx = monero_gen.MoneroC(DynamicLibrary.open(monero.libPath)).MONERO_Wallet_createTransaction(
Pointer.fromAddress(waddr),
Pointer.fromAddress(addraddr).cast(),
Pointer.fromAddress(paymentIdAddr).cast(),
amt,
1,
priorityRaw,
accountIndex,
Pointer.fromAddress(preferredInputsAddr).cast(),
Pointer.fromAddress(spaddr),
);
return tx.address;
}));
calloc.free(address_);
calloc.free(paymentId_);
calloc.free(preferredInputs_);
final String? error = (() { final String? error = (() {
final status = monero.Wallet_status(wptr!); final status = monero.PendingTransaction_status(pendingTx);
if (status == 0) { if (status == 0) {
return null; return null;
} }
return monero.Wallet_errorString(wptr!); return monero.PendingTransaction_errorString(pendingTx);
})(); })();
if (error != null) { if (error != null) {
@ -83,68 +105,27 @@ PendingTransactionDescription createTransactionMultDestSync(
required int priorityRaw, required int priorityRaw,
int accountIndex = 0, int accountIndex = 0,
List<String> preferredInputs = const []}) { List<String> preferredInputs = const []}) {
// final int size = outputs.length;
// final List<Pointer<Utf8>> addressesPointers =
// outputs.map((output) => output.address.toNativeUtf8()).toList();
// final Pointer<Pointer<Utf8>> addressesPointerPointer = calloc(size);
// final List<Pointer<Utf8>> amountsPointers =
// outputs.map((output) => output.amount.toNativeUtf8()).toList();
// final Pointer<Pointer<Utf8>> amountsPointerPointer = calloc(size);
// for (int i = 0; i < size; i++) { final txptr = monero.Wallet_createTransactionMultDest(
// addressesPointerPointer[i] = addressesPointers[i]; wptr!,
// amountsPointerPointer[i] = amountsPointers[i]; dstAddr: outputs.map((e) => e.address).toList(),
// } isSweepAll: false,
amounts: outputs.map((e) => monero.Wallet_amountFromString(e.amount)).toList(),
// final int preferredInputsSize = preferredInputs.length; mixinCount: 0,
// final List<Pointer<Utf8>> preferredInputsPointers = pendingTransactionPriority: priorityRaw,
// preferredInputs.map((output) => output.toNativeUtf8()).toList(); subaddr_account: accountIndex,
// final Pointer<Pointer<Utf8>> preferredInputsPointerPointer = calloc(preferredInputsSize); );
if (monero.PendingTransaction_status(txptr) != 0) {
// for (int i = 0; i < preferredInputsSize; i++) { throw CreationTransactionException(message: monero.PendingTransaction_errorString(txptr));
// preferredInputsPointerPointer[i] = preferredInputsPointers[i]; }
// } return PendingTransactionDescription(
amount: monero.PendingTransaction_amount(txptr),
// final paymentIdPointer = paymentId.toNativeUtf8(); fee: monero.PendingTransaction_fee(txptr),
// final errorMessagePointer = calloc<Utf8Box>(); hash: monero.PendingTransaction_txid(txptr, ''),
// final pendingTransactionRawPointer = calloc<PendingTransactionRaw>(); hex: monero.PendingTransaction_txid(txptr, ''),
// final created = transactionCreateMultDestNative( txKey: monero.PendingTransaction_txid(txptr, ''),
// addressesPointerPointer, pointerAddress: txptr.address,
// paymentIdPointer, );
// amountsPointerPointer,
// size,
// priorityRaw,
// accountIndex,
// preferredInputsPointerPointer,
// preferredInputsSize,
// errorMessagePointer,
// pendingTransactionRawPointer) !=
// 0;
// calloc.free(addressesPointerPointer);
// calloc.free(amountsPointerPointer);
// calloc.free(preferredInputsPointerPointer);
// addressesPointers.forEach((element) => calloc.free(element));
// amountsPointers.forEach((element) => calloc.free(element));
// preferredInputsPointers.forEach((element) => calloc.free(element));
// calloc.free(paymentIdPointer);
// if (!created) {
// final message = errorMessagePointer.ref.getValue();
// calloc.free(errorMessagePointer);
// throw CreationTransactionException(message: message);
// }
// return PendingTransactionDescription(
// amount: pendingTransactionRawPointer.ref.amount,
// fee: pendingTransactionRawPointer.ref.fee,
// hash: pendingTransactionRawPointer.ref.getHash(),
// hex: pendingTransactionRawPointer.ref.getHex(),
// txKey: pendingTransactionRawPointer.ref.getKey(),
// pointerAddress: pendingTransactionRawPointer.address);
throw CreationTransactionException(message: "Unimplemented in monero_c");
} }
void commitTransactionFromPointerAddress({required int address}) => void commitTransactionFromPointerAddress({required int address}) =>
@ -168,7 +149,7 @@ void commitTransaction({required monero.PendingTransaction transactionPointer})
} }
} }
PendingTransactionDescription _createTransactionSync(Map args) { Future<PendingTransactionDescription> _createTransactionSync(Map args) async {
final address = args['address'] as String; final address = args['address'] as String;
final paymentId = args['paymentId'] as String; final paymentId = args['paymentId'] as String;
final amount = args['amount'] as String?; final amount = args['amount'] as String?;
@ -244,6 +225,7 @@ class Transaction {
final int confirmations; final int confirmations;
late final bool isPending = confirmations < 10; late final bool isPending = confirmations < 10;
final int blockheight; final int blockheight;
final int addressIndex = 0;
final int accountIndex; final int accountIndex;
final String paymentId; final String paymentId;
final int amount; final int amount;
@ -251,6 +233,7 @@ class Transaction {
late DateTime timeStamp; late DateTime timeStamp;
late final bool isConfirmed = !isPending; late final bool isConfirmed = !isPending;
final String hash; final String hash;
final String key;
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
return { return {
@ -263,6 +246,7 @@ class Transaction {
"isPending": isPending, "isPending": isPending,
"blockheight": blockheight, "blockheight": blockheight,
"accountIndex": accountIndex, "accountIndex": accountIndex,
"addressIndex": addressIndex,
"paymentId": paymentId, "paymentId": paymentId,
"amount": amount, "amount": amount,
"isSpend": isSpend, "isSpend": isSpend,
@ -291,5 +275,6 @@ class Transaction {
blockheight = monero.TransactionInfo_blockHeight(txInfo), blockheight = monero.TransactionInfo_blockHeight(txInfo),
confirmations = monero.TransactionInfo_confirmations(txInfo), confirmations = monero.TransactionInfo_confirmations(txInfo),
fee = monero.TransactionInfo_fee(txInfo), fee = monero.TransactionInfo_fee(txInfo),
description = monero.TransactionInfo_description(txInfo); description = monero.TransactionInfo_description(txInfo),
key = monero.Wallet_getTxKey(wptr!, txid: monero.TransactionInfo_hash(txInfo));
} }

View file

@ -4,10 +4,12 @@ import 'package:cw_monero/api/account_list.dart';
import 'package:cw_monero/api/exceptions/setup_wallet_exception.dart'; import 'package:cw_monero/api/exceptions/setup_wallet_exception.dart';
import 'package:monero/monero.dart' as monero; import 'package:monero/monero.dart' as monero;
int _boolToInt(bool value) => value ? 1 : 0; int getSyncingHeight() {
// final height = monero.MONERO_cw_WalletListener_height(getWlptr());
int getSyncingHeight() => monero.MONERO_cw_WalletListener_height(getWlptr()); final h2 = monero.Wallet_blockChainHeight(wptr!);
// print("height: $height / $h2");
return h2;
}
bool isNeededToRefresh() { bool isNeededToRefresh() {
final ret = monero.MONERO_cw_WalletListener_isNeedToRefresh(getWlptr()); final ret = monero.MONERO_cw_WalletListener_isNeedToRefresh(getWlptr());
monero.MONERO_cw_WalletListener_resetNeedToRefresh(getWlptr()); monero.MONERO_cw_WalletListener_resetNeedToRefresh(getWlptr());
@ -22,7 +24,14 @@ bool isNewTransactionExist() {
String getFilename() => monero.Wallet_filename(wptr!); String getFilename() => monero.Wallet_filename(wptr!);
// TODO(mrcyjanek): Cake polyseed support // TODO(mrcyjanek): Cake polyseed support
String getSeed() => monero.Wallet_seed(wptr!, seedOffset: ''); String getSeed() {
final legacy = monero.Wallet_seed(wptr!, seedOffset: '');
final polyseed = monero.Wallet_getPolyseed(wptr!, passphrase: '');
if (polyseed == "") {
return legacy;
}
return polyseed;
}
String getAddress({int accountIndex = 0, int addressIndex = 1}) => monero.Wallet_address(wptr!, accountIndex: accountIndex, addressIndex: addressIndex); String getAddress({int accountIndex = 0, int addressIndex = 1}) => monero.Wallet_address(wptr!, accountIndex: accountIndex, addressIndex: addressIndex);
@ -62,8 +71,6 @@ bool setupNodeSync(
daemonPassword: password ?? '' daemonPassword: password ?? ''
); );
// monero.Wallet_init3(wptr!, argv0: '', defaultLogBaseName: 'moneroc', console: true); // monero.Wallet_init3(wptr!, argv0: '', defaultLogBaseName: 'moneroc', console: true);
monero.Wallet_startRefresh(wptr!);
monero.Wallet_refreshAsync(wptr!);
final status = monero.Wallet_status(wptr!); final status = monero.Wallet_status(wptr!);
@ -76,7 +83,10 @@ bool setupNodeSync(
return status == 0; return status == 0;
} }
void startRefreshSync() {} void startRefreshSync() {
monero.Wallet_refreshAsync(wptr!);
monero.Wallet_startRefresh(wptr!);
}
Future<bool> connectToNode() async { Future<bool> connectToNode() async {
return true; return true;

View file

@ -7,7 +7,6 @@ import 'package:cw_monero/api/exceptions/wallet_opening_exception.dart';
import 'package:cw_monero/api/exceptions/wallet_restore_from_keys_exception.dart'; import 'package:cw_monero/api/exceptions/wallet_restore_from_keys_exception.dart';
import 'package:cw_monero/api/exceptions/wallet_restore_from_seed_exception.dart'; import 'package:cw_monero/api/exceptions/wallet_restore_from_seed_exception.dart';
import 'package:cw_monero/api/wallet.dart'; import 'package:cw_monero/api/wallet.dart';
import 'package:ffi/ffi.dart';
import 'package:monero/monero.dart' as monero; import 'package:monero/monero.dart' as monero;
monero.WalletManager? _wmPtr; monero.WalletManager? _wmPtr;
@ -77,13 +76,7 @@ void restoreWalletFromKeysSync(
required String spendKey, required String spendKey,
int nettype = 0, int nettype = 0,
int restoreHeight = 0}) { int restoreHeight = 0}) {
final pathPointer = path.toNativeUtf8();
final passwordPointer = password.toNativeUtf8();
final languagePointer = language.toNativeUtf8();
final addressPointer = address.toNativeUtf8();
final viewKeyPointer = viewKey.toNativeUtf8();
final spendKeyPointer = spendKey.toNativeUtf8();
final errorMessagePointer = ''.toNativeUtf8();
wptr = monero.WalletManager_createWalletFromKeys( wptr = monero.WalletManager_createWalletFromKeys(
wmPtr, wmPtr,
path: path, path: path,
@ -109,28 +102,35 @@ void restoreWalletFromSpendKeySync(
required String spendKey, required String spendKey,
int nettype = 0, int nettype = 0,
int restoreHeight = 0}) { int restoreHeight = 0}) {
final pathPointer = path.toNativeUtf8();
final passwordPointer = password.toNativeUtf8();
final seedPointer = seed.toNativeUtf8();
final languagePointer = language.toNativeUtf8();
final spendKeyPointer = spendKey.toNativeUtf8();
final errorMessagePointer = ''.toNativeUtf8();
wptr = monero.WalletManager_createWalletFromKeys( // wptr = monero.WalletManager_createWalletFromKeys(
// wmPtr,
// path: path,
// password: password,
// restoreHeight: restoreHeight,
// addressString: '',
// spendKeyString: spendKey,
// viewKeyString: '',
// nettype: 0,
// );
wptr = monero.WalletManager_createWalletFromPolyseed(
wmPtr, wmPtr,
path: path, path: path,
password: password, password: password,
mnemonic: seed,
seedOffset: '',
newWallet: false,
restoreHeight: restoreHeight, restoreHeight: restoreHeight,
addressString: '', kdfRounds: 1,
spendKeyString: spendKey,
viewKeyString: '',
nettype: 0,
); );
final status = monero.Wallet_status(wptr!); final status = monero.Wallet_status(wptr!);
if (status == 0) { if (status != 0) {
throw WalletRestoreFromKeysException(message: monero.Wallet_errorString(wptr!)); final err = monero.Wallet_errorString(wptr!);
print("err: $err");
throw WalletRestoreFromKeysException(message: err);
} }
storeSync(); storeSync();

View file

@ -552,16 +552,23 @@ abstract class MoneroWalletBase
List<MoneroTransactionInfo> _getAllTransactionsOfAccount(int? accountIndex) => transaction_history List<MoneroTransactionInfo> _getAllTransactionsOfAccount(int? accountIndex) => transaction_history
.getAllTransactions() .getAllTransactions()
.map((row) => MoneroTransactionInfo( .map((row) => MoneroTransactionInfo(
row.hash, row.hash,
row.blockheight, row.blockheight,
row.isSpend ? TransactionDirection.outgoing : TransactionDirection.incoming, row.isSpend ? TransactionDirection.outgoing : TransactionDirection.incoming,
row.timeStamp, row.timeStamp,
row.isPending, row.isPending,
row.amount, row.amount,
row.accountIndex, row.accountIndex,
0, 0,
row.fee, row.fee,
row.confirmations)) row.confirmations,
)..additionalInfo = <String, dynamic>{
'key': row.key,
'accountIndex': row.accountIndex,
'addressIndex': row.addressIndex
},
)
.where((element) => element.accountIndex == (accountIndex ?? 0)) .where((element) => element.accountIndex == (accountIndex ?? 0))
.toList(); .toList();

View file

@ -414,8 +414,8 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
path: "." path: "."
ref: ada81417cb53d8b0e34022df1dd3d9dc1fe62ab5 ref: e2149153ecbaa6cc4d7d3970d8fa8ce1099b63af
resolved-ref: ada81417cb53d8b0e34022df1dd3d9dc1fe62ab5 resolved-ref: e2149153ecbaa6cc4d7d3970d8fa8ce1099b63af
url: "https://git.mrcyjanek.net/mrcyjanek/monero.dart" url: "https://git.mrcyjanek.net/mrcyjanek/monero.dart"
source: git source: git
version: "0.0.0" version: "0.0.0"

View file

@ -6,7 +6,7 @@ author: Cake Wallet
homepage: https://cakewallet.com homepage: https://cakewallet.com
environment: environment:
sdk: ">=2.17.5 <3.0.0" sdk: ">=2.19.0 <3.0.0"
flutter: ">=1.20.0" flutter: ">=1.20.0"
dependencies: dependencies:
@ -25,7 +25,7 @@ dependencies:
monero: monero:
git: git:
url: https://git.mrcyjanek.net/mrcyjanek/monero.dart url: https://git.mrcyjanek.net/mrcyjanek/monero.dart
ref: ada81417cb53d8b0e34022df1dd3d9dc1fe62ab5 ref: e2149153ecbaa6cc4d7d3970d8fa8ce1099b63af
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:

View file

@ -1,46 +1,47 @@
import 'dart:async'; import 'dart:async';
import 'package:cake_wallet/anonpay/anonpay_invoice_info.dart'; import 'package:cake_wallet/anonpay/anonpay_invoice_info.dart';
import 'package:cake_wallet/core/auth_service.dart';
import 'package:cake_wallet/entities/language_service.dart';
import 'package:cake_wallet/buy/order.dart'; import 'package:cake_wallet/buy/order.dart';
import 'package:cake_wallet/core/auth_service.dart';
import 'package:cake_wallet/di.dart';
import 'package:cake_wallet/entities/contact.dart';
import 'package:cake_wallet/entities/default_settings_migration.dart';
import 'package:cake_wallet/entities/get_encryption_key.dart';
import 'package:cake_wallet/entities/language_service.dart';
import 'package:cake_wallet/entities/template.dart';
import 'package:cake_wallet/entities/transaction_description.dart';
import 'package:cake_wallet/exchange/exchange_template.dart';
import 'package:cake_wallet/exchange/trade.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/locales/locale.dart'; import 'package:cake_wallet/locales/locale.dart';
import 'package:cake_wallet/monero/monero.dart';
import 'package:cake_wallet/reactions/bootstrap.dart';
import 'package:cake_wallet/router.dart' as Router;
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/root/root.dart';
import 'package:cake_wallet/store/app_store.dart';
import 'package:cake_wallet/store/authentication_store.dart';
import 'package:cake_wallet/store/yat/yat_store.dart'; import 'package:cake_wallet/store/yat/yat_store.dart';
import 'package:cake_wallet/themes/theme_base.dart';
import 'package:cake_wallet/utils/device_info.dart'; import 'package:cake_wallet/utils/device_info.dart';
import 'package:cake_wallet/utils/exception_handler.dart'; import 'package:cake_wallet/utils/exception_handler.dart';
import 'package:cw_core/address_info.dart';
import 'package:cake_wallet/utils/responsive_layout_util.dart'; import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:cw_core/address_info.dart';
import 'package:cw_core/cake_hive.dart';
import 'package:cw_core/hive_type_ids.dart'; import 'package:cw_core/hive_type_ids.dart';
import 'package:cw_core/node.dart';
import 'package:cw_core/unspent_coins_info.dart';
import 'package:cw_core/wallet_info.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:hive/hive.dart'; import 'package:hive/hive.dart';
import 'package:cake_wallet/di.dart';
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:cake_wallet/themes/theme_base.dart';
import 'package:cake_wallet/router.dart' as Router;
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/reactions/bootstrap.dart';
import 'package:cake_wallet/store/app_store.dart';
import 'package:cake_wallet/store/authentication_store.dart';
import 'package:cake_wallet/entities/transaction_description.dart';
import 'package:cake_wallet/entities/get_encryption_key.dart';
import 'package:cake_wallet/entities/contact.dart';
import 'package:cw_core/node.dart';
import 'package:cw_core/wallet_info.dart';
import 'package:cake_wallet/entities/default_settings_migration.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:cake_wallet/entities/template.dart';
import 'package:cake_wallet/exchange/trade.dart';
import 'package:cake_wallet/exchange/exchange_template.dart';
import 'package:cake_wallet/src/screens/root/root.dart';
import 'package:uni_links/uni_links.dart'; import 'package:uni_links/uni_links.dart';
import 'package:cw_core/unspent_coins_info.dart';
import 'package:cake_wallet/monero/monero.dart';
import 'package:cw_core/cake_hive.dart';
final navigatorKey = GlobalKey<NavigatorState>(); final navigatorKey = GlobalKey<NavigatorState>();
final rootKey = GlobalKey<RootState>(); final rootKey = GlobalKey<RootState>();