mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2024-12-23 12:09:43 +00:00
wallet recovery
This commit is contained in:
parent
2d886e1213
commit
8d3dd6f202
23 changed files with 2357 additions and 2000 deletions
|
@ -96,6 +96,8 @@ class AmountConverter {
|
||||||
case CryptoCurrency.xnzd:
|
case CryptoCurrency.xnzd:
|
||||||
case CryptoCurrency.xusd:
|
case CryptoCurrency.xusd:
|
||||||
return _moneroAmountToString(amount);
|
return _moneroAmountToString(amount);
|
||||||
|
case CryptoCurrency.zano:
|
||||||
|
return _moneroAmountToString(amount);
|
||||||
default:
|
default:
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
import 'package:cw_core/balance.dart';
|
import 'package:cw_core/balance.dart';
|
||||||
|
import 'package:cw_core/pathForWallet.dart';
|
||||||
import 'package:cw_core/transaction_history.dart';
|
import 'package:cw_core/transaction_history.dart';
|
||||||
import 'package:cw_core/transaction_info.dart';
|
import 'package:cw_core/transaction_info.dart';
|
||||||
import 'package:cw_core/wallet_base.dart';
|
import 'package:cw_core/wallet_base.dart';
|
||||||
|
import 'package:cw_core/wallet_credentials.dart';
|
||||||
import 'package:cw_core/wallet_info.dart';
|
import 'package:cw_core/wallet_info.dart';
|
||||||
import 'package:cw_core/wallet_service.dart';
|
import 'package:cw_core/wallet_service.dart';
|
||||||
import 'package:cw_core/wallet_type.dart';
|
import 'package:cw_core/wallet_type.dart';
|
||||||
|
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
import 'dummy_wallet_creation_credentials.dart';
|
import 'dummy_wallet_creation_credentials.dart';
|
||||||
|
|
||||||
|
@ -15,7 +18,7 @@ class DummyWalletService extends WalletService<DummyNewWalletCredentials, DummyR
|
||||||
final Box<WalletInfo> walletInfoSource;
|
final Box<WalletInfo> walletInfoSource;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo>> create(DummyNewWalletCredentials credentials) => throw UnimplementedError();
|
Future<WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo>> create(WalletCredentials credentials) => throw UnimplementedError();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
WalletType getType() => WalletType.dummy;
|
WalletType getType() => WalletType.dummy;
|
||||||
|
|
|
@ -20,6 +20,9 @@ dependencies:
|
||||||
cw_core:
|
cw_core:
|
||||||
path: ../cw_core
|
path: ../cw_core
|
||||||
|
|
||||||
|
cw_zano:
|
||||||
|
path: ../cw_zano
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
|
|
@ -419,6 +419,12 @@ extern "C"
|
||||||
return strdup(plain_wallet::get_wallet_status(hwallet).c_str());
|
return strdup(plain_wallet::get_wallet_status(hwallet).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char* get_address_info(char* address)
|
||||||
|
{
|
||||||
|
return strdup(plain_wallet::get_address_info(address).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
char* async_call(char* method_name, uint64_t instance_id, char* params)
|
char* async_call(char* method_name, uint64_t instance_id, char* params)
|
||||||
{
|
{
|
||||||
return strdup(plain_wallet::async_call(method_name, instance_id, params).c_str());
|
return strdup(plain_wallet::async_call(method_name, instance_id, params).c_str());
|
||||||
|
|
|
@ -3,7 +3,7 @@ import 'dart:convert';
|
||||||
import 'package:cw_zano/api/model/recent_history.dart';
|
import 'package:cw_zano/api/model/recent_history.dart';
|
||||||
import 'package:cw_zano/api/model/wi.dart';
|
import 'package:cw_zano/api/model/wi.dart';
|
||||||
|
|
||||||
class CreateLoadRestoreWalletResult {
|
class CreateWalletResult {
|
||||||
final String name;
|
final String name;
|
||||||
final String pass;
|
final String pass;
|
||||||
final RecentHistory recentHistory;
|
final RecentHistory recentHistory;
|
||||||
|
@ -14,7 +14,7 @@ class CreateLoadRestoreWalletResult {
|
||||||
final int walletLocalBcSize;
|
final int walletLocalBcSize;
|
||||||
final Wi wi;
|
final Wi wi;
|
||||||
|
|
||||||
CreateLoadRestoreWalletResult(
|
CreateWalletResult(
|
||||||
{required this.name,
|
{required this.name,
|
||||||
required this.pass,
|
required this.pass,
|
||||||
required this.recentHistory,
|
required this.recentHistory,
|
||||||
|
@ -25,8 +25,8 @@ class CreateLoadRestoreWalletResult {
|
||||||
required this.walletLocalBcSize,
|
required this.walletLocalBcSize,
|
||||||
required this.wi});
|
required this.wi});
|
||||||
|
|
||||||
factory CreateLoadRestoreWalletResult.fromJson(Map<String, dynamic> json) =>
|
factory CreateWalletResult.fromJson(Map<String, dynamic> json) =>
|
||||||
CreateLoadRestoreWalletResult(
|
CreateWalletResult(
|
||||||
name: json['name'] as String,
|
name: json['name'] as String,
|
||||||
pass: json['pass'] as String,
|
pass: json['pass'] as String,
|
||||||
recentHistory: RecentHistory.fromJson(
|
recentHistory: RecentHistory.fromJson(
|
|
@ -62,7 +62,7 @@ class History {
|
||||||
.map((e) => Subtransfer.fromJson(e as Map<String, dynamic>))
|
.map((e) => Subtransfer.fromJson(e as Map<String, dynamic>))
|
||||||
.toList(),
|
.toList(),
|
||||||
timestamp: json['timestamp'] as int,
|
timestamp: json['timestamp'] as int,
|
||||||
transferInternalIndex: json['transfer_internal_index'] as int,
|
transferInternalIndex: json['transfer_internal_index'] is double ? (json['transfer_internal_index'] as double).toInt() : json['transfer_internal_index'] as int,
|
||||||
txBlobSize: json['tx_blob_size'] as int,
|
txBlobSize: json['tx_blob_size'] as int,
|
||||||
txHash: json['tx_hash'] as String,
|
txHash: json['tx_hash'] as String,
|
||||||
txType: json['tx_type'] as int,
|
txType: json['tx_type'] as int,
|
||||||
|
|
12
cw_zano/lib/api/model/zano_wallet_keys.dart
Normal file
12
cw_zano/lib/api/model/zano_wallet_keys.dart
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
class ZanoWalletKeys {
|
||||||
|
const ZanoWalletKeys(
|
||||||
|
{required this.privateSpendKey,
|
||||||
|
required this.privateViewKey,
|
||||||
|
required this.publicSpendKey,
|
||||||
|
required this.publicViewKey});
|
||||||
|
|
||||||
|
final String publicViewKey;
|
||||||
|
final String privateViewKey;
|
||||||
|
final String publicSpendKey;
|
||||||
|
final String privateSpendKey;
|
||||||
|
}
|
|
@ -32,9 +32,9 @@ final transactionCreateMultDestNative = zanoApi
|
||||||
'transaction_create_mult_dest')
|
'transaction_create_mult_dest')
|
||||||
.asFunction<TransactionCreateMultDest>();
|
.asFunction<TransactionCreateMultDest>();
|
||||||
|
|
||||||
final transactionCommitNative = zanoApi
|
// final transactionCommitNative = zanoApi
|
||||||
.lookup<NativeFunction<transaction_commit>>('transaction_commit')
|
// .lookup<NativeFunction<transaction_commit>>('transaction_commit')
|
||||||
.asFunction<TransactionCommit>();
|
// .asFunction<TransactionCommit>();
|
||||||
|
|
||||||
final getTxKeyNative = zanoApi
|
final getTxKeyNative = zanoApi
|
||||||
.lookup<NativeFunction<get_tx_key>>('get_tx_key')
|
.lookup<NativeFunction<get_tx_key>>('get_tx_key')
|
||||||
|
@ -53,11 +53,11 @@ String getTxKey(String txId) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
void refreshTransactions() {
|
// void refreshTransactions() {
|
||||||
// TODO: fix it
|
// // TODO: fix it
|
||||||
//transactionsRefreshNative();
|
// //transactionsRefreshNative();
|
||||||
debugPrint("refreshing transactions");
|
// debugPrint("refreshing transactions");
|
||||||
}
|
// }
|
||||||
|
|
||||||
int countOfTransactions() {
|
int countOfTransactions() {
|
||||||
//return transactionsCountNative();
|
//return transactionsCountNative();
|
||||||
|
@ -184,8 +184,9 @@ void commitTransactionFromPointerAddress({required int address}) =>
|
||||||
void commitTransaction(
|
void commitTransaction(
|
||||||
{required Pointer<PendingTransactionRaw> transactionPointer}) {
|
{required Pointer<PendingTransactionRaw> transactionPointer}) {
|
||||||
final errorMessagePointer = calloc<Utf8Box>();
|
final errorMessagePointer = calloc<Utf8Box>();
|
||||||
final isCommited =
|
print("commit transaction");
|
||||||
transactionCommitNative(transactionPointer, errorMessagePointer) != 0;
|
final isCommited = true;
|
||||||
|
//transactionCommitNative(transactionPointer, errorMessagePointer) != 0;
|
||||||
|
|
||||||
if (!isCommited) {
|
if (!isCommited) {
|
||||||
final message = errorMessagePointer.ref.getValue();
|
final message = errorMessagePointer.ref.getValue();
|
||||||
|
|
|
@ -1,5 +1,12 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'dart:convert';
|
||||||
import 'dart:ffi';
|
import 'dart:ffi';
|
||||||
|
import 'package:cw_core/crypto_currency.dart';
|
||||||
|
import 'package:cw_zano/api/model/get_wallet_info_result.dart';
|
||||||
|
import 'package:cw_zano/api/model/get_wallet_status_result.dart';
|
||||||
|
import 'package:cw_zano/api/model/zano_wallet_keys.dart';
|
||||||
|
import 'package:cw_zano/zano_balance.dart';
|
||||||
|
import 'package:cw_zano/zano_wallet.dart';
|
||||||
import 'package:ffi/ffi.dart';
|
import 'package:ffi/ffi.dart';
|
||||||
import 'package:cw_zano/api/structs/ut8_box.dart';
|
import 'package:cw_zano/api/structs/ut8_box.dart';
|
||||||
import 'package:cw_zano/api/convert_utf8_to_string.dart';
|
import 'package:cw_zano/api/convert_utf8_to_string.dart';
|
||||||
|
@ -10,19 +17,18 @@ import 'package:cw_zano/api/calls.dart' as calls;
|
||||||
import 'package:cw_zano/api/exceptions/setup_wallet_exception.dart';
|
import 'package:cw_zano/api/exceptions/setup_wallet_exception.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:mobx/mobx.dart' as mobx;
|
||||||
|
|
||||||
int _boolToInt(bool value) => value ? 1 : 0;
|
int _boolToInt(bool value) => value ? 1 : 0;
|
||||||
|
|
||||||
final getFileNameNative = zanoApi
|
final getFileNameNative =
|
||||||
.lookup<NativeFunction<get_filename>>('get_filename')
|
zanoApi.lookup<NativeFunction<get_filename>>('get_filename').asFunction<GetFilename>();
|
||||||
.asFunction<GetFilename>();
|
|
||||||
|
|
||||||
/*final getSeedNative =
|
/*final getSeedNative =
|
||||||
zanoApi.lookup<NativeFunction<get_seed>>('seed').asFunction<GetSeed>();*/
|
zanoApi.lookup<NativeFunction<get_seed>>('seed').asFunction<GetSeed>();*/
|
||||||
|
|
||||||
final getAddressNative = zanoApi
|
final getAddressNative =
|
||||||
.lookup<NativeFunction<get_address>>('get_address')
|
zanoApi.lookup<NativeFunction<get_address>>('get_address').asFunction<GetAddress>();
|
||||||
.asFunction<GetAddress>();
|
|
||||||
|
|
||||||
final getFullBalanceNative = zanoApi
|
final getFullBalanceNative = zanoApi
|
||||||
.lookup<NativeFunction<get_full_balanace>>('get_full_balance')
|
.lookup<NativeFunction<get_full_balanace>>('get_full_balance')
|
||||||
|
@ -36,42 +42,36 @@ final getUnlockedBalanceNative = zanoApi
|
||||||
.lookup<NativeFunction<get_current_height>>('get_current_height')
|
.lookup<NativeFunction<get_current_height>>('get_current_height')
|
||||||
.asFunction<GetCurrentHeight>();*/
|
.asFunction<GetCurrentHeight>();*/
|
||||||
|
|
||||||
final getNodeHeightNative = zanoApi
|
// final getNodeHeightNative = zanoApi
|
||||||
.lookup<NativeFunction<get_node_height>>('get_node_height')
|
// .lookup<NativeFunction<get_node_height>>('get_node_height')
|
||||||
.asFunction<GetNodeHeight>();
|
// .asFunction<GetNodeHeight>();
|
||||||
|
|
||||||
final isConnectedNative = zanoApi
|
final isConnectedNative =
|
||||||
.lookup<NativeFunction<is_connected>>('is_connected')
|
zanoApi.lookup<NativeFunction<is_connected>>('is_connected').asFunction<IsConnected>();
|
||||||
.asFunction<IsConnected>();
|
|
||||||
|
|
||||||
final setupNodeNative = zanoApi
|
final setupNodeNative =
|
||||||
.lookup<NativeFunction<setup_node>>('setup_node')
|
zanoApi.lookup<NativeFunction<setup_node>>('setup_node').asFunction<SetupNode>();
|
||||||
.asFunction<SetupNode>();
|
|
||||||
|
|
||||||
final startRefreshNative = zanoApi
|
// final startRefreshNative = zanoApi
|
||||||
.lookup<NativeFunction<start_refresh>>('start_refresh')
|
// .lookup<NativeFunction<start_refresh>>('start_refresh')
|
||||||
.asFunction<StartRefresh>();
|
// .asFunction<StartRefresh>();
|
||||||
|
|
||||||
final connecToNodeNative = zanoApi
|
final connecToNodeNative =
|
||||||
.lookup<NativeFunction<connect_to_node>>('connect_to_node')
|
zanoApi.lookup<NativeFunction<connect_to_node>>('connect_to_node').asFunction<ConnectToNode>();
|
||||||
.asFunction<ConnectToNode>();
|
|
||||||
|
|
||||||
final setRefreshFromBlockHeightNative = zanoApi
|
final setRefreshFromBlockHeightNative = zanoApi
|
||||||
.lookup<NativeFunction<set_refresh_from_block_height>>(
|
.lookup<NativeFunction<set_refresh_from_block_height>>('set_refresh_from_block_height')
|
||||||
'set_refresh_from_block_height')
|
|
||||||
.asFunction<SetRefreshFromBlockHeight>();
|
.asFunction<SetRefreshFromBlockHeight>();
|
||||||
|
|
||||||
final setRecoveringFromSeedNative = zanoApi
|
// final setRecoveringFromSeedNative = zanoApi
|
||||||
.lookup<NativeFunction<set_recovering_from_seed>>(
|
// .lookup<NativeFunction<set_recovering_from_seed>>('set_recovering_from_seed')
|
||||||
'set_recovering_from_seed')
|
// .asFunction<SetRecoveringFromSeed>();
|
||||||
.asFunction<SetRecoveringFromSeed>();
|
|
||||||
|
|
||||||
final storeNative =
|
|
||||||
zanoApi.lookup<NativeFunction<store_c>>('store').asFunction<Store>();
|
|
||||||
|
|
||||||
final setPasswordNative = zanoApi
|
final storeNative = zanoApi.lookup<NativeFunction<store_c>>('store').asFunction<Store>();
|
||||||
.lookup<NativeFunction<set_password>>('set_password')
|
|
||||||
.asFunction<SetPassword>();
|
final setPasswordNative =
|
||||||
|
zanoApi.lookup<NativeFunction<set_password>>('set_password').asFunction<SetPassword>();
|
||||||
|
|
||||||
/**final setListenerNative = zanoApi
|
/**final setListenerNative = zanoApi
|
||||||
.lookup<NativeFunction<set_listener>>('set_listener')
|
.lookup<NativeFunction<set_listener>>('set_listener')
|
||||||
|
@ -85,18 +85,15 @@ final isNeededToRefreshNative = zanoApi
|
||||||
.lookup<NativeFunction<is_needed_to_refresh>>('is_needed_to_refresh')
|
.lookup<NativeFunction<is_needed_to_refresh>>('is_needed_to_refresh')
|
||||||
.asFunction<IsNeededToRefresh>();
|
.asFunction<IsNeededToRefresh>();
|
||||||
|
|
||||||
final isNewTransactionExistNative = zanoApi
|
// final isNewTransactionExistNative = zanoApi
|
||||||
.lookup<NativeFunction<is_new_transaction_exist>>(
|
// .lookup<NativeFunction<is_new_transaction_exist>>('is_new_transaction_exist')
|
||||||
'is_new_transaction_exist')
|
// .asFunction<IsNewTransactionExist>();
|
||||||
.asFunction<IsNewTransactionExist>();
|
|
||||||
|
|
||||||
final getSecretViewKeyNative = zanoApi
|
final getSecretViewKeyNative =
|
||||||
.lookup<NativeFunction<secret_view_key>>('secret_view_key')
|
zanoApi.lookup<NativeFunction<secret_view_key>>('secret_view_key').asFunction<SecretViewKey>();
|
||||||
.asFunction<SecretViewKey>();
|
|
||||||
|
|
||||||
final getPublicViewKeyNative = zanoApi
|
final getPublicViewKeyNative =
|
||||||
.lookup<NativeFunction<public_view_key>>('public_view_key')
|
zanoApi.lookup<NativeFunction<public_view_key>>('public_view_key').asFunction<PublicViewKey>();
|
||||||
.asFunction<PublicViewKey>();
|
|
||||||
|
|
||||||
final getSecretSpendKeyNative = zanoApi
|
final getSecretSpendKeyNative = zanoApi
|
||||||
.lookup<NativeFunction<secret_spend_key>>('secret_spend_key')
|
.lookup<NativeFunction<secret_spend_key>>('secret_spend_key')
|
||||||
|
@ -110,27 +107,25 @@ final closeCurrentWalletNative = zanoApi
|
||||||
.lookup<NativeFunction<close_current_wallet>>('close_current_wallet')
|
.lookup<NativeFunction<close_current_wallet>>('close_current_wallet')
|
||||||
.asFunction<CloseCurrentWallet>();
|
.asFunction<CloseCurrentWallet>();
|
||||||
|
|
||||||
final onStartupNative = zanoApi
|
final onStartupNative =
|
||||||
.lookup<NativeFunction<on_startup>>('on_startup')
|
zanoApi.lookup<NativeFunction<on_startup>>('on_startup').asFunction<OnStartup>();
|
||||||
.asFunction<OnStartup>();
|
|
||||||
|
|
||||||
final rescanBlockchainAsyncNative = zanoApi
|
final rescanBlockchainAsyncNative = zanoApi
|
||||||
.lookup<NativeFunction<rescan_blockchain>>('rescan_blockchain')
|
.lookup<NativeFunction<rescan_blockchain>>('rescan_blockchain')
|
||||||
.asFunction<RescanBlockchainAsync>();
|
.asFunction<RescanBlockchainAsync>();
|
||||||
|
|
||||||
final setTrustedDaemonNative = zanoApi
|
// final setTrustedDaemonNative = zanoApi
|
||||||
.lookup<NativeFunction<set_trusted_daemon>>('set_trusted_daemon')
|
// .lookup<NativeFunction<set_trusted_daemon>>('set_trusted_daemon')
|
||||||
.asFunction<SetTrustedDaemon>();
|
// .asFunction<SetTrustedDaemon>();
|
||||||
|
|
||||||
final trustedDaemonNative = zanoApi
|
final trustedDaemonNative =
|
||||||
.lookup<NativeFunction<trusted_daemon>>('trusted_daemon')
|
zanoApi.lookup<NativeFunction<trusted_daemon>>('trusted_daemon').asFunction<TrustedDaemon>();
|
||||||
.asFunction<TrustedDaemon>();
|
|
||||||
|
|
||||||
int getSyncingHeight() => getSyncingHeightNative();
|
int getSyncingHeight() => getSyncingHeightNative();
|
||||||
|
|
||||||
bool isNeededToRefresh() => isNeededToRefreshNative() != 0;
|
bool isNeededToRefresh() => isNeededToRefreshNative() != 0;
|
||||||
|
|
||||||
bool isNewTransactionExist() => isNewTransactionExistNative() != 0;
|
//bool isNewTransactionExist() => isNewTransactionExistNative() != 0;
|
||||||
|
|
||||||
String getFilename() => convertUTF8ToString(pointer: getFileNameNative());
|
String getFilename() => convertUTF8ToString(pointer: getFileNameNative());
|
||||||
|
|
||||||
|
@ -139,29 +134,49 @@ String getFilename() => convertUTF8ToString(pointer: getFileNameNative());
|
||||||
String getAddress({int accountIndex = 0, int addressIndex = 0}) =>
|
String getAddress({int accountIndex = 0, int addressIndex = 0}) =>
|
||||||
convertUTF8ToString(pointer: getAddressNative(accountIndex, addressIndex));
|
convertUTF8ToString(pointer: getAddressNative(accountIndex, addressIndex));
|
||||||
|
|
||||||
int getFullBalance({int accountIndex = 0}) =>
|
int getFullBalance({int accountIndex = 0}) => getFullBalanceNative(accountIndex);
|
||||||
getFullBalanceNative(accountIndex);
|
|
||||||
|
|
||||||
int getUnlockedBalance({int accountIndex = 0}) =>
|
int getUnlockedBalance({int accountIndex = 0}) => getUnlockedBalanceNative(accountIndex);
|
||||||
getUnlockedBalanceNative(accountIndex);
|
|
||||||
|
|
||||||
int getCurrentHeight(int hWallet) {
|
int getCurrentHeight(int hWallet) {
|
||||||
calls.getWalletStatus(hWallet);
|
final json = calls.getWalletStatus(hWallet);
|
||||||
return -1;
|
final walletStatus = GetWalletStatusResult.fromJson(jsonDecode(json) as Map<String, dynamic>);
|
||||||
//return getCurrentHeightNative();
|
return walletStatus.currentWalletHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getNodeHeightSync() => getNodeHeightNative();
|
int getNodeHeightSync(int hWallet) {
|
||||||
|
final json = calls.getWalletStatus(hWallet);
|
||||||
|
final walletStatus = GetWalletStatusResult.fromJson(jsonDecode(json) as Map<String, dynamic>);
|
||||||
|
return walletStatus.currentDaemonHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
// int getWalletInfo(int hWallet) {
|
||||||
|
// final json = calls.getWalletInfo(hWallet);
|
||||||
|
// final walletInfo = GetWalletInfoResult.fromJson(jsonDecode(json) as Map<String, dynamic>);
|
||||||
|
// zanoSeed = walletInfo.wiExtended.seed;
|
||||||
|
// zanoKeys = ZanoWalletKeys(
|
||||||
|
// privateSpendKey: walletInfo.wiExtended.spendPrivateKey,
|
||||||
|
// privateViewKey: walletInfo.wiExtended.viewPrivateKey,
|
||||||
|
// publicSpendKey: walletInfo.wiExtended.spendPublicKey,
|
||||||
|
// publicViewKey: walletInfo.wiExtended.viewPublicKey,
|
||||||
|
// );
|
||||||
|
// return 0;
|
||||||
|
// }
|
||||||
|
|
||||||
|
int getTxFee(int priority) {
|
||||||
|
return calls.getCurrentTxFee(priority);
|
||||||
|
}
|
||||||
|
|
||||||
bool isConnectedSync() => isConnectedNative() != 0;
|
bool isConnectedSync() => isConnectedNative() != 0;
|
||||||
|
|
||||||
bool setupNodeSync(
|
bool setupNodeSync({
|
||||||
{required String address,
|
required String address,
|
||||||
String? login,
|
String? login,
|
||||||
String? password,
|
String? password,
|
||||||
bool useSSL = false,
|
bool useSSL = false,
|
||||||
bool isLightWallet = false,
|
bool isLightWallet = false,
|
||||||
/*String? socksProxyAddress*/}) {
|
/*String? socksProxyAddress*/
|
||||||
|
}) {
|
||||||
final addressPointer = address.toNativeUtf8();
|
final addressPointer = address.toNativeUtf8();
|
||||||
Pointer<Utf8>? loginPointer;
|
Pointer<Utf8>? loginPointer;
|
||||||
Pointer<Utf8>? socksProxyAddressPointer;
|
Pointer<Utf8>? socksProxyAddressPointer;
|
||||||
|
@ -180,7 +195,8 @@ bool setupNodeSync(
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
final errorMessagePointer = ''.toNativeUtf8();
|
final errorMessagePointer = ''.toNativeUtf8();
|
||||||
debugPrint("setup_node address $address login $login password $password useSSL $useSSL isLightWallet $isLightWallet");
|
debugPrint(
|
||||||
|
"setup_node address $address login $login password $password useSSL $useSSL isLightWallet $isLightWallet");
|
||||||
// TODO: here can be ZERO! upd: no
|
// TODO: here can be ZERO! upd: no
|
||||||
final isSetupNode = setupNodeNative(
|
final isSetupNode = setupNodeNative(
|
||||||
addressPointer,
|
addressPointer,
|
||||||
|
@ -212,15 +228,14 @@ bool setupNodeSync(
|
||||||
return isSetupNode;
|
return isSetupNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void startRefreshSync() => startRefreshNative();
|
//void startRefreshSync() => startRefreshNative();
|
||||||
|
|
||||||
Future<bool> connectToNode() async => connecToNodeNative() != 0;
|
Future<bool> connectToNode() async => connecToNodeNative() != 0;
|
||||||
|
|
||||||
void setRefreshFromBlockHeight({required int height}) =>
|
void setRefreshFromBlockHeight({required int height}) => setRefreshFromBlockHeightNative(height);
|
||||||
setRefreshFromBlockHeightNative(height);
|
|
||||||
|
|
||||||
void setRecoveringFromSeed({required bool isRecovery}) =>
|
// void setRecoveringFromSeed({required bool isRecovery}) =>
|
||||||
setRecoveringFromSeedNative(_boolToInt(isRecovery));
|
// setRecoveringFromSeedNative(_boolToInt(isRecovery));
|
||||||
|
|
||||||
void storeSync(int hWallet) {
|
void storeSync(int hWallet) {
|
||||||
calls.store(hWallet);
|
calls.store(hWallet);
|
||||||
|
@ -247,17 +262,13 @@ void setPasswordSync(String password) {
|
||||||
|
|
||||||
void closeCurrentWallet() => closeCurrentWalletNative();
|
void closeCurrentWallet() => closeCurrentWalletNative();
|
||||||
|
|
||||||
String getSecretViewKey() =>
|
String getSecretViewKey() => convertUTF8ToString(pointer: getSecretViewKeyNative());
|
||||||
convertUTF8ToString(pointer: getSecretViewKeyNative());
|
|
||||||
|
|
||||||
String getPublicViewKey() =>
|
String getPublicViewKey() => convertUTF8ToString(pointer: getPublicViewKeyNative());
|
||||||
convertUTF8ToString(pointer: getPublicViewKeyNative());
|
|
||||||
|
|
||||||
String getSecretSpendKey() =>
|
String getSecretSpendKey() => convertUTF8ToString(pointer: getSecretSpendKeyNative());
|
||||||
convertUTF8ToString(pointer: getSecretSpendKeyNative());
|
|
||||||
|
|
||||||
String getPublicSpendKey() =>
|
String getPublicSpendKey() => convertUTF8ToString(pointer: getPublicSpendKeyNative());
|
||||||
convertUTF8ToString(pointer: getPublicSpendKeyNative());
|
|
||||||
|
|
||||||
class SyncListener {
|
class SyncListener {
|
||||||
SyncListener(this.onNewBlock, this.onNewTransaction)
|
SyncListener(this.onNewBlock, this.onNewTransaction)
|
||||||
|
@ -273,36 +284,54 @@ class SyncListener {
|
||||||
int _lastKnownBlockHeight;
|
int _lastKnownBlockHeight;
|
||||||
int _initialSyncHeight;
|
int _initialSyncHeight;
|
||||||
|
|
||||||
Future<int> getNodeHeightOrUpdate(int baseHeight) async {
|
Future<int> getNodeHeightOrUpdate(int hWallet, int baseHeight) async {
|
||||||
if (_cachedBlockchainHeight < baseHeight || _cachedBlockchainHeight == 0) {
|
if (_cachedBlockchainHeight < baseHeight || _cachedBlockchainHeight == 0) {
|
||||||
_cachedBlockchainHeight = await getNodeHeight();
|
_cachedBlockchainHeight = await compute<int, int>(getNodeHeightSync, hWallet);
|
||||||
}
|
}
|
||||||
|
|
||||||
return _cachedBlockchainHeight;
|
return _cachedBlockchainHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
void start() {
|
void start(ZanoWalletBase wallet, int hWallet) async {
|
||||||
_cachedBlockchainHeight = 0;
|
_cachedBlockchainHeight = 0;
|
||||||
_lastKnownBlockHeight = 0;
|
_lastKnownBlockHeight = 0;
|
||||||
_initialSyncHeight = 0;
|
_initialSyncHeight = 0;
|
||||||
_updateSyncInfoTimer ??=
|
_updateSyncInfoTimer ??= Timer.periodic(Duration(milliseconds: 1200), (_) async {
|
||||||
Timer.periodic(Duration(milliseconds: 1200), (_) async {
|
/**if (isNewTransactionExist()) {
|
||||||
if (isNewTransactionExist()) {
|
|
||||||
onNewTransaction?.call();
|
onNewTransaction?.call();
|
||||||
}
|
}*/
|
||||||
|
|
||||||
var syncHeight = getSyncingHeight();
|
///var syncHeight = getSyncingHeight();
|
||||||
|
var syncHeight = getCurrentHeight(hWallet);
|
||||||
|
|
||||||
if (syncHeight <= 0) {
|
if (syncHeight <= 0) {
|
||||||
// TODO: fix it
|
syncHeight = getCurrentHeight(hWallet);
|
||||||
syncHeight = getCurrentHeight(-1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//getWalletInfo(hWallet);
|
||||||
|
|
||||||
|
final json = calls.getWalletInfo(hWallet);
|
||||||
|
final result = GetWalletInfoResult.fromJson(jsonDecode(json) as Map<String, dynamic>);
|
||||||
|
wallet.seed = result.wiExtended.seed;
|
||||||
|
wallet.keys = ZanoWalletKeys(
|
||||||
|
privateSpendKey: result.wiExtended.spendPrivateKey,
|
||||||
|
privateViewKey: result.wiExtended.viewPrivateKey,
|
||||||
|
publicSpendKey: result.wiExtended.spendPublicKey,
|
||||||
|
publicViewKey: result.wiExtended.viewPublicKey,
|
||||||
|
);
|
||||||
|
|
||||||
|
final balance = result.wi.balances.first;
|
||||||
|
wallet.assetId = balance.assetInfo.assetId;
|
||||||
|
wallet.balance = mobx.ObservableMap.of(
|
||||||
|
{CryptoCurrency.zano: ZanoBalance(total: balance.total, unlocked: balance.unlocked)});
|
||||||
|
|
||||||
|
getTxFee(hWallet);
|
||||||
|
|
||||||
if (_initialSyncHeight <= 0) {
|
if (_initialSyncHeight <= 0) {
|
||||||
_initialSyncHeight = syncHeight;
|
_initialSyncHeight = syncHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
final bchHeight = await getNodeHeightOrUpdate(syncHeight);
|
final bchHeight = await getNodeHeightOrUpdate(hWallet, syncHeight);
|
||||||
|
|
||||||
if (_lastKnownBlockHeight == syncHeight || syncHeight == null) {
|
if (_lastKnownBlockHeight == syncHeight || syncHeight == null) {
|
||||||
return;
|
return;
|
||||||
|
@ -326,8 +355,8 @@ class SyncListener {
|
||||||
void stop() => _updateSyncInfoTimer?.cancel();
|
void stop() => _updateSyncInfoTimer?.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
SyncListener setListeners(void Function(int, int, double) onNewBlock,
|
SyncListener setListeners(
|
||||||
void Function() onNewTransaction) {
|
void Function(int, int, double) onNewBlock, void Function() onNewTransaction) {
|
||||||
final listener = SyncListener(onNewBlock, onNewTransaction);
|
final listener = SyncListener(onNewBlock, onNewTransaction);
|
||||||
/**setListenerNative();*/
|
/**setListenerNative();*/
|
||||||
return listener;
|
return listener;
|
||||||
|
@ -350,15 +379,15 @@ bool _setupNodeSync(Map args) {
|
||||||
login: login,
|
login: login,
|
||||||
password: password,
|
password: password,
|
||||||
useSSL: useSSL,
|
useSSL: useSSL,
|
||||||
isLightWallet: isLightWallet,
|
isLightWallet: isLightWallet, /*socksProxyAddress: socksProxyAddress*/
|
||||||
/*socksProxyAddress: socksProxyAddress*/);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _isConnected(Object _) => isConnectedSync();
|
bool _isConnected(Object _) => isConnectedSync();
|
||||||
|
|
||||||
int _getNodeHeight(Object _) => getNodeHeightSync();
|
//int _getNodeHeight(Object _) => getNodeHeightSync();
|
||||||
|
|
||||||
void startRefresh() => startRefreshSync();
|
//void startRefresh() => startRefreshSync();
|
||||||
|
|
||||||
Future<bool> setupNode(
|
Future<bool> setupNode(
|
||||||
{required String address,
|
{required String address,
|
||||||
|
@ -380,11 +409,11 @@ Future<void> store(int hWallet) => compute<int, void>(_storeSync, 0);
|
||||||
|
|
||||||
Future<bool> isConnected() => compute(_isConnected, 0);
|
Future<bool> isConnected() => compute(_isConnected, 0);
|
||||||
|
|
||||||
Future<int> getNodeHeight() => compute(_getNodeHeight, 0);
|
//Future<int> getNodeHeight() => compute(_getNodeHeight, 0);
|
||||||
|
|
||||||
void rescanBlockchainAsync() => rescanBlockchainAsyncNative();
|
void rescanBlockchainAsync() => rescanBlockchainAsyncNative();
|
||||||
|
|
||||||
Future setTrustedDaemon(bool trusted) async =>
|
// Future setTrustedDaemon(bool trusted) async =>
|
||||||
setTrustedDaemonNative(_boolToInt(trusted));
|
// setTrustedDaemonNative(_boolToInt(trusted));
|
||||||
|
|
||||||
Future<bool> trustedDaemon() async => trustedDaemonNative() != 0;
|
Future<bool> trustedDaemon() async => trustedDaemonNative() != 0;
|
||||||
|
|
|
@ -200,11 +200,11 @@ Future<void> _openWallet(Map<String, String> args) async => loadWallet(
|
||||||
|
|
||||||
bool _isWalletExist(String path) => isWalletExistSync(path: path);
|
bool _isWalletExist(String path) => isWalletExistSync(path: path);
|
||||||
|
|
||||||
void openWallet(
|
// void openWallet(
|
||||||
{required String path,
|
// {required String path,
|
||||||
required String password,
|
// required String password,
|
||||||
int nettype = 0}) async =>
|
// int nettype = 0}) async =>
|
||||||
loadWallet(path: path, password: password, nettype: nettype);
|
// loadWallet(path: path, password: password, nettype: nettype);
|
||||||
|
|
||||||
Future<void> openWalletAsync(Map<String, String> args) async =>
|
Future<void> openWalletAsync(Map<String, String> args) async =>
|
||||||
compute(_openWallet, args);
|
compute(_openWallet, args);
|
||||||
|
|
File diff suppressed because it is too large
Load diff
19
cw_zano/lib/new_zano_addresses_base.dart
Normal file
19
cw_zano/lib/new_zano_addresses_base.dart
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import 'package:cw_core/wallet_addresses.dart';
|
||||||
|
|
||||||
|
class NewZanoWalletAddresses extends WalletAddresses {
|
||||||
|
@override
|
||||||
|
String address;
|
||||||
|
|
||||||
|
NewZanoWalletAddresses(super.walletInfo): address = "";
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> init() async {
|
||||||
|
print("NewZanoWalletAddresses init");
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> updateAddressesInBox() async {
|
||||||
|
print("NewZanoWalletAddresses updateAddressesInBox");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
239
cw_zano/lib/new_zano_wallet.dart
Normal file
239
cw_zano/lib/new_zano_wallet.dart
Normal file
|
@ -0,0 +1,239 @@
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:cw_core/crypto_currency.dart';
|
||||||
|
import 'package:cw_core/node.dart';
|
||||||
|
import 'package:cw_core/pending_transaction.dart';
|
||||||
|
import 'package:cw_core/sync_status.dart';
|
||||||
|
import 'package:cw_core/transaction_priority.dart';
|
||||||
|
import 'package:cw_core/wallet_addresses.dart';
|
||||||
|
import 'package:cw_core/wallet_base.dart';
|
||||||
|
import 'package:cw_zano/api/model/balance.dart';
|
||||||
|
import 'package:cw_zano/api/model/create_wallet_result.dart';
|
||||||
|
import 'package:cw_zano/api/zano_api.dart';
|
||||||
|
import 'package:cw_zano/zano_balance.dart';
|
||||||
|
import 'package:cw_zano/zano_transaction_history.dart';
|
||||||
|
import 'package:cw_zano/zano_transaction_info.dart';
|
||||||
|
import 'package:mobx/src/api/observable_collections.dart';
|
||||||
|
import 'package:cw_zano/api/wallet.dart' as zano_wallet;
|
||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:ffi';
|
||||||
|
|
||||||
|
import 'package:cw_zano/api/signatures.dart';
|
||||||
|
import 'package:cw_zano/api/types.dart';
|
||||||
|
import 'package:ffi/ffi.dart';
|
||||||
|
|
||||||
|
import 'api/model/zano_wallet_keys.dart';
|
||||||
|
import 'new_zano_addresses_base.dart';
|
||||||
|
|
||||||
|
typedef _load_wallet = Pointer<Utf8> Function(Pointer<Utf8>, Pointer<Utf8>, Int8);
|
||||||
|
typedef _LoadWallet = Pointer<Utf8> Function(Pointer<Utf8>, Pointer<Utf8>, int);
|
||||||
|
|
||||||
|
class NewZanoWallet extends WalletBase<ZanoBalance, ZanoTransactionHistory, ZanoTransactionInfo> {
|
||||||
|
@override
|
||||||
|
SyncStatus syncStatus;
|
||||||
|
|
||||||
|
Timer? _autoSaveTimer;
|
||||||
|
|
||||||
|
static const int _autoSaveInterval = 30;
|
||||||
|
|
||||||
|
NewZanoWallet(super.walletInfo)
|
||||||
|
: balance = ObservableMap.of({CryptoCurrency.zano: ZanoBalance(total: 0, unlocked: 0)}),
|
||||||
|
walletAddresses = NewZanoWalletAddresses(walletInfo),
|
||||||
|
syncStatus = NotConnectedSyncStatus() {
|
||||||
|
transactionHistory = ZanoTransactionHistory();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> init() async {
|
||||||
|
print("NewZanoWallet init");
|
||||||
|
if (walletInfo.isRecovery) {
|
||||||
|
print("is recovery");
|
||||||
|
}
|
||||||
|
_autoSaveTimer =
|
||||||
|
Timer.periodic(Duration(seconds: _autoSaveInterval), (_) async => await save());
|
||||||
|
}
|
||||||
|
|
||||||
|
String getTransactionAddress(int accountIndex, int addressIndex) {
|
||||||
|
print("NewZanoWallet getTransactionAddress");
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
ObservableMap<CryptoCurrency, ZanoBalance> balance;
|
||||||
|
|
||||||
|
@override
|
||||||
|
int calculateEstimatedFee(TransactionPriority priority, int? amount) {
|
||||||
|
// TODO: implement calculateEstimatedFee
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> changePassword(String password) {
|
||||||
|
// TODO: implement changePassword
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void close() {
|
||||||
|
// TODO: implement close
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> connectToNode({required Node node}) async {
|
||||||
|
print("NewZanoWallet connecttoNode");
|
||||||
|
try {
|
||||||
|
syncStatus = ConnectingSyncStatus();
|
||||||
|
_setupNode(address: "195.201.107.230:33336", login: "", password: "");
|
||||||
|
syncStatus = ConnectedSyncStatus();
|
||||||
|
} catch (e) {
|
||||||
|
syncStatus = FailedSyncStatus();
|
||||||
|
print("connectToNode error $e");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<PendingTransaction> createTransaction(Object credentials) {
|
||||||
|
// TODO: implement createTransaction
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<Map<String, ZanoTransactionInfo>> fetchTransactions() {
|
||||||
|
// TODO: implement fetchTransactions
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
ZanoWalletKeys get keys => ZanoWalletKeys(
|
||||||
|
privateSpendKey: "", privateViewKey: "", publicSpendKey: "", publicViewKey: "");
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> renameWalletFiles(String newWalletName) {
|
||||||
|
// TODO: implement renameWalletFiles
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> rescan({required int height}) {
|
||||||
|
// TODO: implement rescan
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> save() async {
|
||||||
|
await walletAddresses.updateAddressesInBox();
|
||||||
|
if (hWallet != null) await zano_wallet.store(hWallet!);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
// TODO: implement seed
|
||||||
|
String? seed = "Тут пока пусто";
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> startSync() {
|
||||||
|
// TODO: implement startSync
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void>? updateBalance() {
|
||||||
|
// TODO: implement updateBalance
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
NewZanoWalletAddresses walletAddresses;
|
||||||
|
|
||||||
|
CreateWalletResult? createWalletResult;
|
||||||
|
List<Balance>? balances;
|
||||||
|
int? hWallet;
|
||||||
|
final assetIds = <String, String>{};
|
||||||
|
|
||||||
|
final _setupNodeNative =
|
||||||
|
zanoApi.lookup<NativeFunction<setup_node>>('setup_node').asFunction<SetupNode>();
|
||||||
|
final _createWalletNative =
|
||||||
|
zanoApi.lookup<NativeFunction<create_wallet>>('create_wallet').asFunction<CreateWallet>();
|
||||||
|
|
||||||
|
final _loadWalletNative =
|
||||||
|
zanoApi.lookup<NativeFunction<_load_wallet>>('load_wallet').asFunction<_LoadWallet>();
|
||||||
|
|
||||||
|
bool _setupNode(
|
||||||
|
{required String address,
|
||||||
|
required String login,
|
||||||
|
required String password,
|
||||||
|
bool useSSL = false,
|
||||||
|
bool isLightWallet = false}) {
|
||||||
|
final addressPointer = address.toNativeUtf8();
|
||||||
|
final loginPointer = login.toNativeUtf8();
|
||||||
|
final passwordPointer = password.toNativeUtf8();
|
||||||
|
final errorMessagePointer = ''.toNativeUtf8();
|
||||||
|
print(
|
||||||
|
"setup_node address $address login $login password $password useSSL $useSSL isLightWallet $isLightWallet");
|
||||||
|
final result = _intToBool(_setupNodeNative(addressPointer, loginPointer, passwordPointer,
|
||||||
|
_boolToInt(useSSL), _boolToInt(isLightWallet), errorMessagePointer));
|
||||||
|
print("setup_node result $result");
|
||||||
|
calloc.free(addressPointer);
|
||||||
|
calloc.free(loginPointer);
|
||||||
|
calloc.free(passwordPointer);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
String _createWalletSync(
|
||||||
|
{required String path, required String password, required String language, int nettype = 0}) {
|
||||||
|
final pathPointer = path.toNativeUtf8();
|
||||||
|
final passwordPointer = password.toNativeUtf8();
|
||||||
|
final languagePointer = language.toNativeUtf8();
|
||||||
|
final errorMessagePointer = ''.toNativeUtf8();
|
||||||
|
print("create_wallet path $path password $password language $language");
|
||||||
|
final result = _convertUTF8ToString(
|
||||||
|
pointer: _createWalletNative(
|
||||||
|
pathPointer, passwordPointer, languagePointer, nettype, errorMessagePointer));
|
||||||
|
print("create_wallet $result");
|
||||||
|
calloc.free(pathPointer);
|
||||||
|
calloc.free(passwordPointer);
|
||||||
|
calloc.free(languagePointer);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void createWallet({required String path, required String password}) {
|
||||||
|
final createResult = _createWalletSync(path: path, password: password, language: "");
|
||||||
|
final address = _parseResult(createResult)!;
|
||||||
|
walletAddresses.address = address;
|
||||||
|
}
|
||||||
|
|
||||||
|
String loadWallet(String path, String password) {
|
||||||
|
print('load_wallet path $path password $password');
|
||||||
|
final pathPointer = path.toNativeUtf8();
|
||||||
|
final passwordPointer = password.toNativeUtf8();
|
||||||
|
final result = _convertUTF8ToString(
|
||||||
|
pointer: _loadWalletNative(pathPointer, passwordPointer, 0),
|
||||||
|
);
|
||||||
|
print('load_wallet result $result');
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _boolToInt(bool value) => value ? 1 : 0;
|
||||||
|
bool _intToBool(int value) => value != 0;
|
||||||
|
String _convertUTF8ToString({required Pointer<Utf8> pointer}) {
|
||||||
|
final str = pointer.toDartString();
|
||||||
|
calloc.free(pointer);
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: kind of stupid thing, in one method parsing json and then setting properties of a class
|
||||||
|
String? _parseResult(String result) {
|
||||||
|
final map = json.decode(result) as Map<String, dynamic>;
|
||||||
|
if (map['result'] != null) {
|
||||||
|
createWalletResult =
|
||||||
|
CreateWalletResult.fromJson(map['result'] as Map<String, dynamic>);
|
||||||
|
balances = createWalletResult!.wi.balances;
|
||||||
|
hWallet = createWalletResult!.walletId;
|
||||||
|
assetIds.clear();
|
||||||
|
for (final balance in createWalletResult!.wi.balances) {
|
||||||
|
assetIds[balance.assetInfo.assetId] = balance.assetInfo.ticker;
|
||||||
|
}
|
||||||
|
return createWalletResult!.wi.address;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,8 +27,10 @@ class PendingZanoTransaction with PendingTransaction {
|
||||||
String get hex => '';
|
String get hex => '';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get amountFormatted => AmountConverter.amountIntToString(
|
String get amountFormatted {
|
||||||
|
return AmountConverter.amountIntToString(
|
||||||
cryptoCurrency, pendingTransactionDescription.amount);
|
cryptoCurrency, pendingTransactionDescription.amount);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get feeFormatted => AmountConverter.amountIntToString(
|
String get feeFormatted => AmountConverter.amountIntToString(
|
||||||
|
|
|
@ -1,53 +1,23 @@
|
||||||
import 'package:cw_core/balance.dart';
|
import 'package:cw_core/balance.dart';
|
||||||
import 'package:cw_core/crypto_currency.dart';
|
import 'package:cw_core/crypto_currency.dart';
|
||||||
|
import 'package:cw_core/monero_amount_format.dart';
|
||||||
import 'package:cw_core/monero_balance.dart';
|
import 'package:cw_core/monero_balance.dart';
|
||||||
import 'package:cw_zano/api/balance_list.dart';
|
import 'package:cw_zano/api/balance_list.dart';
|
||||||
import 'package:cw_zano/api/structs/zano_balance_row.dart';
|
import 'package:cw_zano/api/structs/zano_balance_row.dart';
|
||||||
|
|
||||||
class ZanoBalance extends Balance {
|
class ZanoBalance extends Balance {
|
||||||
ZanoBalance(super.available, super.additional);
|
final int total;
|
||||||
late int unlockedBalance;
|
final int unlocked;
|
||||||
@override
|
ZanoBalance({required this.total, required this.unlocked}): super(unlocked, 0);
|
||||||
// TODO: implement formattedAdditionalBalance
|
|
||||||
String get formattedAdditionalBalance {
|
|
||||||
// TODO: fix it
|
|
||||||
return "0";
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
// TODO: implement formattedAvailableBalance
|
String get formattedAdditionalBalance => moneroAmountToString(amount: additional);
|
||||||
String get formattedAvailableBalance {
|
|
||||||
// TODO: fix it
|
@override
|
||||||
return "0";
|
String get formattedAvailableBalance => moneroAmountToString(amount: unlocked);
|
||||||
}
|
|
||||||
|
@override
|
||||||
|
String get formattedFrozenBalance => total == unlocked ? '' : moneroAmountToString(amount: total - unlocked);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<CryptoCurrency, ZanoBalance> getZanoBalance() {
|
|
||||||
// TODO: fix it
|
|
||||||
return { CryptoCurrency.zano: ZanoBalance(0, 0) };
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Map<CryptoCurrency, MoneroBalance> getZanoBalance({required int accountIndex}) {
|
|
||||||
final fullBalances = getZanoFullBalance(accountIndex: accountIndex);
|
|
||||||
final unlockedBalances = getZanoUnlockedBalance(accountIndex: accountIndex);
|
|
||||||
final zanoBalances = <CryptoCurrency, MoneroBalance>{};
|
|
||||||
final balancesLength = fullBalances.length;
|
|
||||||
|
|
||||||
for (int i = 0; i < balancesLength; i++) {
|
|
||||||
final assetType = fullBalances[i].getAssetType();
|
|
||||||
final fullBalance = fullBalances[i].getAmount();
|
|
||||||
final unlockedBalance = unlockedBalances[i].getAmount();
|
|
||||||
final moneroBalance = MoneroBalance(
|
|
||||||
fullBalance: fullBalance, unlockedBalance: unlockedBalance);
|
|
||||||
final currency = CryptoCurrency.fromString(assetType);
|
|
||||||
|
|
||||||
if (inactiveBalances.indexOf(currency) >= 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
zanoBalances[currency] = moneroBalance;
|
|
||||||
}
|
|
||||||
|
|
||||||
return zanoBalances;
|
|
||||||
}*/
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import 'package:cw_core/transaction_info.dart';
|
import 'package:cw_core/transaction_info.dart';
|
||||||
import 'package:cw_core/monero_amount_format.dart';
|
import 'package:cw_core/monero_amount_format.dart';
|
||||||
|
import 'package:cw_zano/api/model/history.dart';
|
||||||
import 'package:cw_zano/api/structs/transaction_info_row.dart';
|
import 'package:cw_zano/api/structs/transaction_info_row.dart';
|
||||||
import 'package:cw_core/parseBoolFromString.dart';
|
import 'package:cw_core/parseBoolFromString.dart';
|
||||||
import 'package:cw_core/transaction_direction.dart';
|
import 'package:cw_core/transaction_direction.dart';
|
||||||
|
@ -19,7 +20,22 @@ class ZanoTransactionInfo extends TransactionInfo {
|
||||||
this.fee,
|
this.fee,
|
||||||
this.confirmations);
|
this.confirmations);
|
||||||
|
|
||||||
ZanoTransactionInfo.fromMap(Map<String, Object> map)
|
ZanoTransactionInfo.fromHistory(History history)
|
||||||
|
: id = history.txHash,
|
||||||
|
height = history.height,
|
||||||
|
direction = history.subtransfers.first.isIncome ? TransactionDirection.incoming :
|
||||||
|
TransactionDirection.outgoing,
|
||||||
|
date = DateTime.fromMillisecondsSinceEpoch(history.timestamp * 1000),
|
||||||
|
isPending = false,
|
||||||
|
amount = history.subtransfers.first.amount,
|
||||||
|
accountIndex = 0,
|
||||||
|
addressIndex = 0,
|
||||||
|
fee = history.fee,
|
||||||
|
confirmations = 1,
|
||||||
|
assetType = 'ZANO', // TODO: FIXIT:
|
||||||
|
recipientAddress = history.remoteAddresses.isNotEmpty ? history.remoteAddresses.first : '';
|
||||||
|
|
||||||
|
/*ZanoTransactionInfo.fromMap(Map<String, Object> map)
|
||||||
: id = (map['hash'] ?? '') as String,
|
: id = (map['hash'] ?? '') as String,
|
||||||
height = (map['height'] ?? 0) as int,
|
height = (map['height'] ?? 0) as int,
|
||||||
direction =
|
direction =
|
||||||
|
@ -33,9 +49,9 @@ class ZanoTransactionInfo extends TransactionInfo {
|
||||||
addressIndex = map['addressIndex'] as int,
|
addressIndex = map['addressIndex'] as int,
|
||||||
confirmations = map['confirmations'] as int,
|
confirmations = map['confirmations'] as int,
|
||||||
key = getTxKey((map['hash'] ?? '') as String),
|
key = getTxKey((map['hash'] ?? '') as String),
|
||||||
fee = map['fee'] as int? ?? 0;
|
fee = map['fee'] as int? ?? 0;*/
|
||||||
|
|
||||||
ZanoTransactionInfo.fromRow(TransactionInfoRow row)
|
/*ZanoTransactionInfo.fromRow(TransactionInfoRow row)
|
||||||
: id = row.getHash(),
|
: id = row.getHash(),
|
||||||
height = row.blockHeight,
|
height = row.blockHeight,
|
||||||
direction = parseTransactionDirectionFromInt(row.direction) ??
|
direction = parseTransactionDirectionFromInt(row.direction) ??
|
||||||
|
@ -48,7 +64,7 @@ class ZanoTransactionInfo extends TransactionInfo {
|
||||||
confirmations = row.confirmations,
|
confirmations = row.confirmations,
|
||||||
key = null, //getTxKey(row.getHash()),
|
key = null, //getTxKey(row.getHash()),
|
||||||
fee = row.fee,
|
fee = row.fee,
|
||||||
assetType = row.getAssetType();
|
assetType = row.getAssetType();*/
|
||||||
|
|
||||||
final String id;
|
final String id;
|
||||||
final int height;
|
final int height;
|
||||||
|
|
|
@ -1,37 +1,35 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:ffi';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:cw_core/crypto_currency.dart';
|
import 'package:cw_core/crypto_currency.dart';
|
||||||
import 'package:cw_core/pathForWallet.dart';
|
|
||||||
import 'package:cw_core/transaction_priority.dart';
|
|
||||||
import 'package:cw_zano/api/zano_output.dart';
|
|
||||||
import 'package:cw_zano/zano_transaction_creation_credentials.dart';
|
|
||||||
import 'package:cw_core/monero_amount_format.dart';
|
|
||||||
import 'package:cw_zano/zano_transaction_creation_exception.dart';
|
|
||||||
import 'package:cw_zano/zano_transaction_info.dart';
|
|
||||||
import 'package:cw_zano/zano_wallet_addresses.dart';
|
|
||||||
import 'package:cw_zano/api/calls.dart' as calls;
|
|
||||||
import 'package:cw_core/monero_wallet_utils.dart';
|
import 'package:cw_core/monero_wallet_utils.dart';
|
||||||
|
import 'package:cw_core/node.dart';
|
||||||
|
import 'package:cw_core/pathForWallet.dart';
|
||||||
|
import 'package:cw_core/pending_transaction.dart';
|
||||||
|
import 'package:cw_core/sync_status.dart';
|
||||||
|
import 'package:cw_core/transaction_priority.dart';
|
||||||
|
import 'package:cw_core/wallet_base.dart';
|
||||||
|
import 'package:cw_core/wallet_info.dart';
|
||||||
|
import 'package:cw_zano/api/calls.dart' as calls;
|
||||||
|
import 'package:cw_zano/api/model/destination.dart';
|
||||||
|
import 'package:cw_zano/api/model/history.dart';
|
||||||
|
import 'package:cw_zano/api/model/transfer_params.dart';
|
||||||
|
import 'package:cw_zano/api/model/zano_wallet_keys.dart';
|
||||||
import 'package:cw_zano/api/structs/pending_transaction.dart';
|
import 'package:cw_zano/api/structs/pending_transaction.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
import 'package:mobx/mobx.dart';
|
|
||||||
import 'package:cw_zano/api/transaction_history.dart'
|
|
||||||
as zano_transaction_history;
|
|
||||||
//import 'package:cw_zano/wallet.dart';
|
//import 'package:cw_zano/wallet.dart';
|
||||||
import 'package:cw_zano/api/wallet.dart' as zano_wallet;
|
import 'package:cw_zano/api/wallet.dart' as zano_wallet;
|
||||||
import 'package:cw_zano/api/transaction_history.dart' as transaction_history;
|
import 'package:cw_zano/api/zano_api.dart';
|
||||||
import 'package:cw_zano/api/zano_output.dart';
|
|
||||||
import 'package:cw_zano/pending_zano_transaction.dart';
|
import 'package:cw_zano/pending_zano_transaction.dart';
|
||||||
import 'package:cw_core/monero_wallet_keys.dart';
|
|
||||||
import 'package:cw_core/monero_balance.dart';
|
|
||||||
import 'package:cw_zano/zano_transaction_history.dart';
|
|
||||||
import 'package:cw_core/account.dart';
|
|
||||||
import 'package:cw_core/pending_transaction.dart';
|
|
||||||
import 'package:cw_core/wallet_base.dart';
|
|
||||||
import 'package:cw_core/sync_status.dart';
|
|
||||||
import 'package:cw_core/wallet_info.dart';
|
|
||||||
import 'package:cw_core/node.dart';
|
|
||||||
import 'package:cw_core/monero_transaction_priority.dart';
|
|
||||||
import 'package:cw_zano/zano_balance.dart';
|
import 'package:cw_zano/zano_balance.dart';
|
||||||
|
import 'package:cw_zano/zano_transaction_creation_credentials.dart';
|
||||||
|
import 'package:cw_zano/zano_transaction_history.dart';
|
||||||
|
import 'package:cw_zano/zano_transaction_info.dart';
|
||||||
|
import 'package:cw_zano/zano_wallet_addresses.dart';
|
||||||
|
import 'package:ffi/ffi.dart';
|
||||||
|
import 'package:mobx/mobx.dart';
|
||||||
|
|
||||||
part 'zano_wallet.g.dart';
|
part 'zano_wallet.g.dart';
|
||||||
|
|
||||||
|
@ -39,21 +37,16 @@ const moneroBlockSize = 1000;
|
||||||
|
|
||||||
class ZanoWallet = ZanoWalletBase with _$ZanoWallet;
|
class ZanoWallet = ZanoWalletBase with _$ZanoWallet;
|
||||||
|
|
||||||
abstract class ZanoWalletBase
|
typedef _load_wallet = Pointer<Utf8> Function(Pointer<Utf8>, Pointer<Utf8>, Int8);
|
||||||
extends WalletBase<ZanoBalance, ZanoTransactionHistory, ZanoTransactionInfo>
|
typedef _LoadWallet = Pointer<Utf8> Function(Pointer<Utf8>, Pointer<Utf8>, int);
|
||||||
with Store {
|
|
||||||
ZanoWalletBase.simple({required WalletInfo walletInfo})
|
|
||||||
: balance = ObservableMap(),
|
|
||||||
_isTransactionUpdating = false,
|
|
||||||
_hasSyncAfterStartup = false,
|
|
||||||
walletAddresses = ZanoWalletAddresses(walletInfo),
|
|
||||||
syncStatus = NotConnectedSyncStatus(),
|
|
||||||
super(walletInfo) {
|
|
||||||
transactionHistory = ZanoTransactionHistory();
|
|
||||||
}
|
|
||||||
|
|
||||||
ZanoWalletBase({required WalletInfo walletInfo})
|
|
||||||
: balance = ObservableMap.of({CryptoCurrency.zano: ZanoBalance(0, 0)}),
|
const int zanoMixin = 10;
|
||||||
|
|
||||||
|
abstract class ZanoWalletBase
|
||||||
|
extends WalletBase<ZanoBalance, ZanoTransactionHistory, ZanoTransactionInfo> with Store {
|
||||||
|
ZanoWalletBase(WalletInfo walletInfo)
|
||||||
|
: balance = ObservableMap.of({CryptoCurrency.zano: ZanoBalance(total: 0, unlocked: 0)}),
|
||||||
_isTransactionUpdating = false,
|
_isTransactionUpdating = false,
|
||||||
_hasSyncAfterStartup = false,
|
_hasSyncAfterStartup = false,
|
||||||
walletAddresses = ZanoWalletAddresses(walletInfo),
|
walletAddresses = ZanoWalletAddresses(walletInfo),
|
||||||
|
@ -70,6 +63,9 @@ abstract class ZanoWalletBase
|
||||||
});*/
|
});*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<History> history = [];
|
||||||
|
String assetId = '';
|
||||||
|
|
||||||
static const int _autoSaveInterval = 30;
|
static const int _autoSaveInterval = 30;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -84,20 +80,11 @@ abstract class ZanoWalletBase
|
||||||
ObservableMap<CryptoCurrency, ZanoBalance> balance;
|
ObservableMap<CryptoCurrency, ZanoBalance> balance;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get seed {
|
String seed = '';
|
||||||
// TODO: fix it
|
|
||||||
//return calls.seed(hWallet);
|
|
||||||
return "test";
|
|
||||||
/**zano_wallet.getSeed();*/
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
// TODO: ?? why monero
|
ZanoWalletKeys keys = ZanoWalletKeys(
|
||||||
MoneroWalletKeys get keys => MoneroWalletKeys(
|
privateSpendKey: '', privateViewKey: '', publicSpendKey: '', publicViewKey: '');
|
||||||
privateSpendKey: zano_wallet.getSecretSpendKey(),
|
|
||||||
privateViewKey: zano_wallet.getSecretViewKey(),
|
|
||||||
publicSpendKey: zano_wallet.getPublicSpendKey(),
|
|
||||||
publicViewKey: zano_wallet.getPublicViewKey());
|
|
||||||
|
|
||||||
zano_wallet.SyncListener? _listener;
|
zano_wallet.SyncListener? _listener;
|
||||||
/**ReactionDisposer? _onAccountChangeReaction;*/
|
/**ReactionDisposer? _onAccountChangeReaction;*/
|
||||||
|
@ -115,21 +102,20 @@ abstract class ZanoWalletBase
|
||||||
|
|
||||||
Future<void> init() async {
|
Future<void> init() async {
|
||||||
await walletAddresses.init();
|
await walletAddresses.init();
|
||||||
balance
|
///balance.addAll(getZanoBalance(/**accountIndex: walletAddresses.account?.id ?? 0*/));
|
||||||
.addAll(getZanoBalance(/**accountIndex: walletAddresses.account?.id ?? 0*/));
|
|
||||||
_setListeners();
|
_setListeners();
|
||||||
await updateTransactions();
|
await updateTransactions();
|
||||||
|
|
||||||
if (walletInfo.isRecovery) {
|
if (walletInfo.isRecovery) {
|
||||||
zano_wallet.setRecoveringFromSeed(isRecovery: walletInfo.isRecovery);
|
///zano_wallet.setRecoveringFromSeed(isRecovery: walletInfo.isRecovery);
|
||||||
|
|
||||||
if (zano_wallet.getCurrentHeight(hWallet) <= 1) {
|
if (zano_wallet.getCurrentHeight(hWallet) <= 1) {
|
||||||
zano_wallet.setRefreshFromBlockHeight(height: walletInfo.restoreHeight);
|
zano_wallet.setRefreshFromBlockHeight(height: walletInfo.restoreHeight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_autoSaveTimer = Timer.periodic(
|
_autoSaveTimer =
|
||||||
Duration(seconds: _autoSaveInterval), (_) async => await save());
|
Timer.periodic(Duration(seconds: _autoSaveInterval), (_) async => await save());
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -155,7 +141,7 @@ abstract class ZanoWalletBase
|
||||||
/*socksProxyAddress: node.socksProxyAddress*/
|
/*socksProxyAddress: node.socksProxyAddress*/
|
||||||
);
|
);
|
||||||
|
|
||||||
zano_wallet.setTrustedDaemon(node.trusted);
|
//zano_wallet.setTrustedDaemon(node.trusted);
|
||||||
syncStatus = ConnectedSyncStatus();
|
syncStatus = ConnectedSyncStatus();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
syncStatus = FailedSyncStatus();
|
syncStatus = FailedSyncStatus();
|
||||||
|
@ -171,9 +157,10 @@ abstract class ZanoWalletBase
|
||||||
|
|
||||||
try {
|
try {
|
||||||
syncStatus = AttemptingSyncStatus();
|
syncStatus = AttemptingSyncStatus();
|
||||||
zano_wallet.startRefresh();
|
//zano_wallet.startRefresh();
|
||||||
|
print("start refresh");
|
||||||
_setListeners();
|
_setListeners();
|
||||||
_listener?.start();
|
_listener?.start(this, hWallet);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
syncStatus = FailedSyncStatus();
|
syncStatus = FailedSyncStatus();
|
||||||
print(e);
|
print(e);
|
||||||
|
@ -183,7 +170,38 @@ abstract class ZanoWalletBase
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<PendingTransaction> createTransaction(Object credentials) async {
|
Future<PendingTransaction> createTransaction(Object credentials) async {
|
||||||
final _credentials = credentials as ZanoTransactionCreationCredentials;
|
final creds = credentials as ZanoTransactionCreationCredentials;
|
||||||
|
final output = creds.outputs.first;
|
||||||
|
final address = output.isParsedAddress && (output.extractedAddress?.isNotEmpty ?? false)
|
||||||
|
? output.extractedAddress!
|
||||||
|
: output.address;
|
||||||
|
final amount = output.sendAll ? null : output.cryptoAmount!.replaceAll(',', '.');
|
||||||
|
final int? formattedAmount = output.sendAll ? null : output.formattedCryptoAmount;
|
||||||
|
final fee = calculateEstimatedFee(creds.priority);
|
||||||
|
// final result = await calls.transfer(
|
||||||
|
// hWallet,
|
||||||
|
// TransferParams(
|
||||||
|
// destinations: [
|
||||||
|
// Destination(
|
||||||
|
// amount: amount!,
|
||||||
|
// address: address,
|
||||||
|
// assetId: assetId,
|
||||||
|
// )
|
||||||
|
// ],
|
||||||
|
// fee: fee,
|
||||||
|
// mixin: zanoMixin,
|
||||||
|
// paymentId: '', // TODO: fixit
|
||||||
|
// comment: output.note ?? '',
|
||||||
|
// pushPayer: false,
|
||||||
|
// hideReceiver: false,
|
||||||
|
// ));
|
||||||
|
int iAmount = (double.parse(amount!) * pow(10, 12)).toInt();
|
||||||
|
final description = PendingTransactionDescription(
|
||||||
|
amount: iAmount, fee: fee, hash: 'fade', pointerAddress: 0);
|
||||||
|
final transaction = PendingZanoTransaction(description, CryptoCurrency.zano);
|
||||||
|
return transaction;
|
||||||
|
|
||||||
|
/*final _credentials = credentials as ZanoTransactionCreationCredentials;
|
||||||
final outputs = _credentials.outputs;
|
final outputs = _credentials.outputs;
|
||||||
final hasMultiDestination = outputs.length > 1;
|
final hasMultiDestination = outputs.length > 1;
|
||||||
final assetType =
|
final assetType =
|
||||||
|
@ -249,29 +267,12 @@ abstract class ZanoWalletBase
|
||||||
priorityRaw: _credentials.priority.serialize());
|
priorityRaw: _credentials.priority.serialize());
|
||||||
}
|
}
|
||||||
|
|
||||||
return PendingZanoTransaction(pendingTransactionDescription, assetType);
|
return PendingZanoTransaction(pendingTransactionDescription, assetType);*/
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int calculateEstimatedFee(TransactionPriority priority, int? amount) {
|
int calculateEstimatedFee(TransactionPriority priority, [int? amount = null]) {
|
||||||
// FIXME: hardcoded value;
|
return calls.getCurrentTxFee(priority.raw);
|
||||||
|
|
||||||
if (priority is MoneroTransactionPriority) {
|
|
||||||
switch (priority) {
|
|
||||||
case MoneroTransactionPriority.slow:
|
|
||||||
return 24590000;
|
|
||||||
case MoneroTransactionPriority.automatic:
|
|
||||||
return 123050000;
|
|
||||||
case MoneroTransactionPriority.medium:
|
|
||||||
return 245029999;
|
|
||||||
case MoneroTransactionPriority.fast:
|
|
||||||
return 614530000;
|
|
||||||
case MoneroTransactionPriority.fastest:
|
|
||||||
return 26021600000;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -310,7 +311,7 @@ abstract class ZanoWalletBase
|
||||||
zano_wallet.setPasswordSync(password);
|
zano_wallet.setPasswordSync(password);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<int> getNodeHeight() async => zano_wallet.getNodeHeight();
|
//Future<int> getNodeHeight() async => zano_wallet.getNodeHeight();
|
||||||
|
|
||||||
Future<bool> isConnected() async => zano_wallet.isConnected();
|
Future<bool> isConnected() async => zano_wallet.isConnected();
|
||||||
|
|
||||||
|
@ -334,18 +335,37 @@ abstract class ZanoWalletBase
|
||||||
}
|
}
|
||||||
|
|
||||||
String getTransactionAddress(int accountIndex, int addressIndex) =>
|
String getTransactionAddress(int accountIndex, int addressIndex) =>
|
||||||
zano_wallet.getAddress(
|
zano_wallet.getAddress(accountIndex: accountIndex, addressIndex: addressIndex);
|
||||||
accountIndex: accountIndex, addressIndex: addressIndex);
|
|
||||||
|
Future<void> _refreshTransactions() async {
|
||||||
|
final result = await calls.getRecentTxsAndInfo(hWallet: hWallet, offset: 0, count: 30);
|
||||||
|
final map = jsonDecode(result);
|
||||||
|
if (map == null || map["result"] == null || map["result"]["result"] == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (map["result"]["result"]["transfers"] != null)
|
||||||
|
history = (map["result"]["result"]["transfers"] as List<dynamic>)
|
||||||
|
.map((e) => History.fromJson(e as Map<String, dynamic>))
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<Map<String, ZanoTransactionInfo>> fetchTransactions() async {
|
Future<Map<String, ZanoTransactionInfo>> fetchTransactions() async {
|
||||||
zano_transaction_history.refreshTransactions();
|
//zano_transaction_history.refreshTransactions();
|
||||||
return _getAllTransactions(null)
|
await _refreshTransactions();
|
||||||
|
return history
|
||||||
|
.map<ZanoTransactionInfo>((history) => ZanoTransactionInfo.fromHistory(history))
|
||||||
.fold<Map<String, ZanoTransactionInfo>>(<String, ZanoTransactionInfo>{},
|
.fold<Map<String, ZanoTransactionInfo>>(<String, ZanoTransactionInfo>{},
|
||||||
(Map<String, ZanoTransactionInfo> acc, ZanoTransactionInfo tx) {
|
(Map<String, ZanoTransactionInfo> acc, ZanoTransactionInfo tx) {
|
||||||
acc[tx.id] = tx;
|
acc[tx.id] = tx;
|
||||||
return acc;
|
return acc;
|
||||||
});
|
});
|
||||||
|
// return _getAllTransactions(null)
|
||||||
|
// .fold<Map<String, ZanoTransactionInfo>>(<String, ZanoTransactionInfo>{},
|
||||||
|
// (Map<String, ZanoTransactionInfo> acc, ZanoTransactionInfo tx) {
|
||||||
|
// acc[tx.id] = tx;
|
||||||
|
// return acc;
|
||||||
|
// });
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> updateTransactions() async {
|
Future<void> updateTransactions() async {
|
||||||
|
@ -365,11 +385,11 @@ abstract class ZanoWalletBase
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<ZanoTransactionInfo> _getAllTransactions(dynamic _) =>
|
// List<ZanoTransactionInfo> _getAllTransactions(dynamic _) =>
|
||||||
zano_transaction_history
|
// zano_transaction_history
|
||||||
.getAllTransations()
|
// .getAllTransations()
|
||||||
.map((row) => ZanoTransactionInfo.fromRow(row))
|
// .map((row) => ZanoTransactionInfo.fromRow(row))
|
||||||
.toList();
|
// .toList();
|
||||||
|
|
||||||
void _setListeners() {
|
void _setListeners() {
|
||||||
_listener?.stop();
|
_listener?.stop();
|
||||||
|
@ -385,36 +405,39 @@ abstract class ZanoWalletBase
|
||||||
|
|
||||||
if (currentHeight <= 1) {
|
if (currentHeight <= 1) {
|
||||||
final height = _getHeightByDate(walletInfo.date);
|
final height = _getHeightByDate(walletInfo.date);
|
||||||
zano_wallet.setRecoveringFromSeed(isRecovery: true);
|
///zano_wallet.setRecoveringFromSeed(isRecovery: true);
|
||||||
zano_wallet.setRefreshFromBlockHeight(height: height);
|
zano_wallet.setRefreshFromBlockHeight(height: height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int _getHeightDistance(DateTime date) {
|
// int _getHeightDistance(DateTime date) {
|
||||||
final distance =
|
// final distance =
|
||||||
DateTime.now().millisecondsSinceEpoch - date.millisecondsSinceEpoch;
|
// DateTime.now().millisecondsSinceEpoch - date.millisecondsSinceEpoch;
|
||||||
final daysTmp = (distance / 86400).round();
|
// final daysTmp = (distance / 86400).round();
|
||||||
final days = daysTmp < 1 ? 1 : daysTmp;
|
// final days = daysTmp < 1 ? 1 : daysTmp;
|
||||||
|
|
||||||
return days * 1000;
|
// return days * 1000;
|
||||||
}
|
// }
|
||||||
|
|
||||||
int _getHeightByDate(DateTime date) {
|
int _getHeightByDate(DateTime date) {
|
||||||
final nodeHeight = zano_wallet.getNodeHeightSync();
|
// TODO: !!! 12/10 commented
|
||||||
final heightDistance = _getHeightDistance(date);
|
|
||||||
|
|
||||||
if (nodeHeight <= 0) {
|
|
||||||
return 0;
|
return 0;
|
||||||
|
// final nodeHeight = zano_wallet.getNodeHeightSync();
|
||||||
|
// final heightDistance = _getHeightDistance(date);
|
||||||
|
|
||||||
|
// if (nodeHeight <= 0) {
|
||||||
|
// return 0;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return nodeHeight - heightDistance;
|
||||||
}
|
}
|
||||||
|
|
||||||
return nodeHeight - heightDistance;
|
void _askForUpdateBalance() {
|
||||||
|
print("ask for update balance");
|
||||||
|
//balance.addAll(getZanoBalance());
|
||||||
}
|
}
|
||||||
|
|
||||||
void _askForUpdateBalance() =>
|
Future<void> _askForUpdateTransactionHistory() async => await updateTransactions();
|
||||||
balance.addAll(getZanoBalance());
|
|
||||||
|
|
||||||
Future<void> _askForUpdateTransactionHistory() async =>
|
|
||||||
await updateTransactions();
|
|
||||||
|
|
||||||
void _onNewBlock(int height, int blocksLeft, double ptc) async {
|
void _onNewBlock(int height, int blocksLeft, double ptc) async {
|
||||||
try {
|
try {
|
||||||
|
@ -455,4 +478,24 @@ abstract class ZanoWalletBase
|
||||||
print(e.toString());
|
print(e.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final _loadWalletNative =
|
||||||
|
zanoApi.lookup<NativeFunction<_load_wallet>>('load_wallet').asFunction<_LoadWallet>();
|
||||||
|
|
||||||
|
String loadWallet(String path, String password) {
|
||||||
|
print('load_wallet path $path password $password');
|
||||||
|
final pathPointer = path.toNativeUtf8();
|
||||||
|
final passwordPointer = password.toNativeUtf8();
|
||||||
|
final result = _convertUTF8ToString(
|
||||||
|
pointer: _loadWalletNative(pathPointer, passwordPointer, 0),
|
||||||
|
);
|
||||||
|
print('load_wallet result $result');
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
String _convertUTF8ToString({required Pointer<Utf8> pointer}) {
|
||||||
|
final str = pointer.toDartString();
|
||||||
|
calloc.free(pointer);
|
||||||
|
return str;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,13 @@
|
||||||
|
import 'dart:convert';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
|
import 'package:cw_core/crypto_currency.dart';
|
||||||
import 'package:cw_core/node.dart';
|
import 'package:cw_core/node.dart';
|
||||||
import 'package:cw_core/wallet_base.dart';
|
import 'package:cw_core/wallet_base.dart';
|
||||||
import 'package:cw_core/monero_wallet_utils.dart';
|
import 'package:cw_core/monero_wallet_utils.dart';
|
||||||
|
import 'package:cw_zano/api/model/create_wallet_result.dart';
|
||||||
|
import 'package:cw_zano/new_zano_wallet.dart';
|
||||||
|
import 'package:cw_zano/zano_balance.dart';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
import 'package:cw_zano/api/wallet_manager.dart' as zano_wallet_manager;
|
import 'package:cw_zano/api/wallet_manager.dart' as zano_wallet_manager;
|
||||||
import 'package:cw_zano/api/wallet.dart' as zano_wallet;
|
import 'package:cw_zano/api/wallet.dart' as zano_wallet;
|
||||||
|
@ -14,6 +19,7 @@ import 'package:cw_core/wallet_service.dart';
|
||||||
import 'package:cw_core/pathForWallet.dart';
|
import 'package:cw_core/pathForWallet.dart';
|
||||||
import 'package:cw_core/wallet_info.dart';
|
import 'package:cw_core/wallet_info.dart';
|
||||||
import 'package:cw_core/wallet_type.dart';
|
import 'package:cw_core/wallet_type.dart';
|
||||||
|
import 'package:mobx/mobx.dart';
|
||||||
|
|
||||||
class ZanoNewWalletCredentials extends WalletCredentials {
|
class ZanoNewWalletCredentials extends WalletCredentials {
|
||||||
ZanoNewWalletCredentials({required String name, String? password})
|
ZanoNewWalletCredentials({required String name, String? password})
|
||||||
|
@ -22,10 +28,7 @@ class ZanoNewWalletCredentials extends WalletCredentials {
|
||||||
|
|
||||||
class ZanoRestoreWalletFromSeedCredentials extends WalletCredentials {
|
class ZanoRestoreWalletFromSeedCredentials extends WalletCredentials {
|
||||||
ZanoRestoreWalletFromSeedCredentials(
|
ZanoRestoreWalletFromSeedCredentials(
|
||||||
{required String name,
|
{required String name, required String password, required int height, required this.mnemonic})
|
||||||
required String password,
|
|
||||||
required int height,
|
|
||||||
required this.mnemonic})
|
|
||||||
: super(name: name, password: password, height: height);
|
: super(name: name, password: password, height: height);
|
||||||
|
|
||||||
final String mnemonic;
|
final String mnemonic;
|
||||||
|
@ -53,10 +56,8 @@ class ZanoRestoreWalletFromKeysCredentials extends WalletCredentials {
|
||||||
final String spendKey;
|
final String spendKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
class ZanoWalletService extends WalletService<
|
class ZanoWalletService extends WalletService<ZanoNewWalletCredentials,
|
||||||
ZanoNewWalletCredentials,
|
ZanoRestoreWalletFromSeedCredentials, ZanoRestoreWalletFromKeysCredentials> {
|
||||||
ZanoRestoreWalletFromSeedCredentials,
|
|
||||||
ZanoRestoreWalletFromKeysCredentials> {
|
|
||||||
ZanoWalletService(this.walletInfoSource);
|
ZanoWalletService(this.walletInfoSource);
|
||||||
|
|
||||||
final Box<WalletInfo> walletInfoSource;
|
final Box<WalletInfo> walletInfoSource;
|
||||||
|
@ -69,18 +70,38 @@ class ZanoWalletService extends WalletService<
|
||||||
@override
|
@override
|
||||||
WalletType getType() => WalletType.zano;
|
WalletType getType() => WalletType.zano;
|
||||||
|
|
||||||
|
// @override
|
||||||
|
// Future<ZanoWallet> create(WalletCredentials credentials) async {
|
||||||
|
// try {
|
||||||
|
// final wallet = ZanoWallet(credentials.walletInfo!);
|
||||||
|
// wallet.connectToNode(node: Node()); // TODO: Node() ???
|
||||||
|
// //wallet.setupNode(address: "195.201.107.230:33336", login: "", password: "");
|
||||||
|
// final path = await pathForWallet(name: credentials.name, type: getType());
|
||||||
|
// wallet.createWallet(path: path, password: credentials.password!);
|
||||||
|
// return wallet;
|
||||||
|
// } catch (e) {
|
||||||
|
// print("ZanoWalletService.create error $e");
|
||||||
|
// rethrow;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<ZanoWallet> create(ZanoNewWalletCredentials credentials) async {
|
Future<ZanoWallet> create(WalletCredentials credentials) async {
|
||||||
try {
|
try {
|
||||||
final wallet = ZanoWallet.simple(walletInfo: credentials.walletInfo!);
|
final wallet = ZanoWallet(credentials.walletInfo!);
|
||||||
wallet.connectToNode(node: Node());
|
await wallet.connectToNode(node: Node());
|
||||||
final path = await pathForWallet(name: credentials.name, type: getType());
|
final path = await pathForWallet(name: credentials.name, type: getType());
|
||||||
final result = await zano_wallet_manager.createWallet(
|
final result = await zano_wallet_manager.createWallet(
|
||||||
language: "", path: path, password: credentials.password!);
|
language: "", path: path, password: credentials.password!);
|
||||||
hWallet = -1;
|
print("create wallet result $result");
|
||||||
wallet.hWallet = hWallet;
|
final map = json.decode(result) as Map<String, dynamic>;
|
||||||
// TODO: remove it
|
if (map['result'] != null) {
|
||||||
calls.store(hWallet);
|
final createWalletResult =
|
||||||
|
CreateWalletResult.fromJson(map['result'] as Map<String, dynamic>);
|
||||||
|
_parseCreateWalletResult(createWalletResult, wallet);
|
||||||
|
}
|
||||||
|
// TODO: remove it TODO why?
|
||||||
|
await calls.store(hWallet);
|
||||||
await wallet.init();
|
await wallet.init();
|
||||||
return wallet;
|
return wallet;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -111,37 +132,36 @@ class ZanoWalletService extends WalletService<
|
||||||
await repairOldAndroidWallet(name);
|
await repairOldAndroidWallet(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
await zano_wallet_manager
|
final walletInfo = walletInfoSource.values
|
||||||
.openWalletAsync({'path': path, 'password': password});
|
.firstWhereOrNull((info) => info.id == WalletBase.idFor(name, getType()))!;
|
||||||
final walletInfo = walletInfoSource.values.firstWhereOrNull(
|
final wallet = ZanoWallet(walletInfo);
|
||||||
(info) => info.id == WalletBase.idFor(name, getType()))!;
|
await wallet.connectToNode(node: Node());
|
||||||
final wallet = ZanoWallet(walletInfo: walletInfo);
|
final result = wallet.loadWallet(path, password);
|
||||||
/*final isValid = wallet.walletAddresses.validate();
|
print("load wallet result $result");
|
||||||
|
final map = json.decode(result) as Map<String, dynamic>;
|
||||||
if (!isValid) {
|
if (map['result'] != null) {
|
||||||
await restoreOrResetWalletFiles(name);
|
final createWalletResult =
|
||||||
wallet.close();
|
CreateWalletResult.fromJson(map['result'] as Map<String, dynamic>);
|
||||||
return openWallet(name, password);
|
_parseCreateWalletResult(createWalletResult, wallet);
|
||||||
}*/
|
}
|
||||||
|
await calls.store(hWallet);
|
||||||
await wallet.init();
|
await wallet.init();
|
||||||
|
|
||||||
return wallet;
|
return wallet;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// TODO: Implement Exception for wallet list service.
|
rethrow;
|
||||||
|
}
|
||||||
if ((e.toString().contains('bad_alloc') ||
|
|
||||||
(e is WalletOpeningException &&
|
|
||||||
(e.message == 'std::bad_alloc' ||
|
|
||||||
e.message.contains('bad_alloc')))) ||
|
|
||||||
(e.toString().contains('does not correspond') ||
|
|
||||||
(e is WalletOpeningException &&
|
|
||||||
e.message.contains('does not correspond')))) {
|
|
||||||
await restoreOrResetWalletFiles(name);
|
|
||||||
return openWallet(name, password);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rethrow;
|
void _parseCreateWalletResult(CreateWalletResult result, ZanoWallet wallet) {
|
||||||
|
hWallet = result.walletId;
|
||||||
|
wallet.hWallet = hWallet;
|
||||||
|
wallet.walletAddresses.address = result.wi.address;
|
||||||
|
final balance = result.wi.balances.first;
|
||||||
|
wallet.assetId = balance.assetInfo.assetId;
|
||||||
|
wallet.balance = ObservableMap.of(
|
||||||
|
{CryptoCurrency.zano: ZanoBalance(total: balance.total, unlocked: balance.unlocked)});
|
||||||
|
if (result.recentHistory.history != null) {
|
||||||
|
wallet.history = result.recentHistory.history!;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,11 +181,10 @@ class ZanoWalletService extends WalletService<
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> rename(
|
Future<void> rename(String currentName, String password, String newName) async {
|
||||||
String currentName, String password, String newName) async {
|
final currentWalletInfo = walletInfoSource.values
|
||||||
final currentWalletInfo = walletInfoSource.values.firstWhere(
|
.firstWhere((info) => info.id == WalletBase.idFor(currentName, getType()));
|
||||||
(info) => info.id == WalletBase.idFor(currentName, getType()));
|
final currentWallet = ZanoWallet(currentWalletInfo);
|
||||||
final currentWallet = ZanoWallet(walletInfo: currentWalletInfo);
|
|
||||||
|
|
||||||
await currentWallet.renameWalletFiles(newName);
|
await currentWallet.renameWalletFiles(newName);
|
||||||
|
|
||||||
|
@ -177,8 +196,7 @@ class ZanoWalletService extends WalletService<
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<ZanoWallet> restoreFromKeys(
|
Future<ZanoWallet> restoreFromKeys(ZanoRestoreWalletFromKeysCredentials credentials) async {
|
||||||
ZanoRestoreWalletFromKeysCredentials credentials) async {
|
|
||||||
try {
|
try {
|
||||||
final path = await pathForWallet(name: credentials.name, type: getType());
|
final path = await pathForWallet(name: credentials.name, type: getType());
|
||||||
await zano_wallet_manager.restoreFromKeys(
|
await zano_wallet_manager.restoreFromKeys(
|
||||||
|
@ -189,7 +207,7 @@ class ZanoWalletService extends WalletService<
|
||||||
address: credentials.address,
|
address: credentials.address,
|
||||||
viewKey: credentials.viewKey,
|
viewKey: credentials.viewKey,
|
||||||
spendKey: credentials.spendKey);
|
spendKey: credentials.spendKey);
|
||||||
final wallet = ZanoWallet(walletInfo: credentials.walletInfo!);
|
final wallet = ZanoWallet(credentials.walletInfo!);
|
||||||
await wallet.init();
|
await wallet.init();
|
||||||
|
|
||||||
return wallet;
|
return wallet;
|
||||||
|
@ -201,18 +219,21 @@ class ZanoWalletService extends WalletService<
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<ZanoWallet> restoreFromSeed(
|
Future<ZanoWallet> restoreFromSeed(ZanoRestoreWalletFromSeedCredentials credentials) async {
|
||||||
ZanoRestoreWalletFromSeedCredentials credentials) async {
|
|
||||||
try {
|
try {
|
||||||
|
final wallet = ZanoWallet(credentials.walletInfo!);
|
||||||
|
await wallet.connectToNode(node: Node());
|
||||||
final path = await pathForWallet(name: credentials.name, type: getType());
|
final path = await pathForWallet(name: credentials.name, type: getType());
|
||||||
await zano_wallet_manager.restoreFromSeed(
|
final result = calls.restoreWalletFromSeed(path, credentials.password!, credentials.mnemonic);
|
||||||
path: path,
|
print('restore wallet from seed result $result');
|
||||||
password: credentials.password!,
|
final map = json.decode(result) as Map<String, dynamic>;
|
||||||
seed: credentials.mnemonic,
|
if (map['result'] != null) {
|
||||||
restoreHeight: credentials.height!);
|
final createWalletResult =
|
||||||
final wallet = ZanoWallet(walletInfo: credentials.walletInfo!);
|
CreateWalletResult.fromJson(map['result'] as Map<String, dynamic>);
|
||||||
|
_parseCreateWalletResult(createWalletResult, wallet);
|
||||||
|
}
|
||||||
|
await calls.store(hWallet);
|
||||||
await wallet.init();
|
await wallet.init();
|
||||||
|
|
||||||
return wallet;
|
return wallet;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// TODO: Implement Exception for wallet list service.
|
// TODO: Implement Exception for wallet list service.
|
||||||
|
@ -227,16 +248,14 @@ class ZanoWalletService extends WalletService<
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final oldAndroidWalletDirPath =
|
final oldAndroidWalletDirPath = await outdatedAndroidPathForWalletDir(name: name);
|
||||||
await outdatedAndroidPathForWalletDir(name: name);
|
|
||||||
final dir = Directory(oldAndroidWalletDirPath);
|
final dir = Directory(oldAndroidWalletDirPath);
|
||||||
|
|
||||||
if (!dir.existsSync()) {
|
if (!dir.existsSync()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final newWalletDirPath =
|
final newWalletDirPath = await pathForWalletDir(name: name, type: getType());
|
||||||
await pathForWalletDir(name: name, type: getType());
|
|
||||||
|
|
||||||
dir.listSync().forEach((f) {
|
dir.listSync().forEach((f) {
|
||||||
final file = File(f.path);
|
final file = File(f.path);
|
||||||
|
|
|
@ -239,6 +239,8 @@ class AddressValidator extends TextValidator {
|
||||||
return [64];
|
return [64];
|
||||||
case CryptoCurrency.btcln:
|
case CryptoCurrency.btcln:
|
||||||
return null;
|
return null;
|
||||||
|
case CryptoCurrency.zano:
|
||||||
|
return [97];
|
||||||
default:
|
default:
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
|
@ -211,6 +211,8 @@ class WalletRestorePage extends BasePage {
|
||||||
final seedWords =
|
final seedWords =
|
||||||
walletRestoreFromSeedFormKey.currentState!.seedWidgetStateKey.currentState!.text.split(' ');
|
walletRestoreFromSeedFormKey.currentState!.seedWidgetStateKey.currentState!.text.split(' ');
|
||||||
|
|
||||||
|
if (walletRestoreViewModel.type == WalletType.zano) return true;
|
||||||
|
|
||||||
if ((walletRestoreViewModel.type == WalletType.monero ||
|
if ((walletRestoreViewModel.type == WalletType.monero ||
|
||||||
walletRestoreViewModel.type == WalletType.haven) &&
|
walletRestoreViewModel.type == WalletType.haven) &&
|
||||||
seedWords.length != WalletRestoreViewModelBase.moneroSeedMnemonicLength) {
|
seedWords.length != WalletRestoreViewModelBase.moneroSeedMnemonicLength) {
|
||||||
|
|
|
@ -258,8 +258,8 @@ abstract class OutputBase with Store {
|
||||||
break;
|
break;
|
||||||
case WalletType.dummy:
|
case WalletType.dummy:
|
||||||
case WalletType.zano:
|
case WalletType.zano:
|
||||||
// TODO: enter correct values
|
maximumFractionDigits = 12;
|
||||||
throw UnimplementedError();
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ import 'package:cw_core/pathForWallet.dart';
|
||||||
import 'package:cw_core/wallet_type.dart';
|
import 'package:cw_core/wallet_type.dart';
|
||||||
import 'package:cw_zano/api/calls.dart' as calls;
|
import 'package:cw_zano/api/calls.dart' as calls;
|
||||||
import 'package:cw_zano/api/model/balance.dart';
|
import 'package:cw_zano/api/model/balance.dart';
|
||||||
import 'package:cw_zano/api/model/load_wallet_result.dart';
|
import 'package:cw_zano/api/model/create_wallet_result.dart';
|
||||||
import 'package:cw_zano/api/wallet.dart' as zano_wallet;
|
import 'package:cw_zano/api/wallet.dart' as zano_wallet;
|
||||||
import 'package:cw_zano/api/wallet_manager.dart' as zano_wallet_manager;
|
import 'package:cw_zano/api/wallet_manager.dart' as zano_wallet_manager;
|
||||||
import 'package:cw_zano/zano_wallet_service.dart';
|
import 'package:cw_zano/zano_wallet_service.dart';
|
||||||
|
@ -28,24 +28,21 @@ Future<void> main() async {
|
||||||
/// A callback that is invoked when an unhandled error occurs in the root
|
/// A callback that is invoked when an unhandled error occurs in the root
|
||||||
/// isolate.
|
/// isolate.
|
||||||
PlatformDispatcher.instance.onError = (error, stack) {
|
PlatformDispatcher.instance.onError = (error, stack) {
|
||||||
ExceptionHandler.onError(
|
ExceptionHandler.onError(FlutterErrorDetails(exception: error, stack: stack));
|
||||||
FlutterErrorDetails(exception: error, stack: stack));
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
await setup();
|
await setup();
|
||||||
runApp(App());
|
runApp(App());
|
||||||
}, (error, stackTrace) async {
|
}, (error, stackTrace) async {
|
||||||
ExceptionHandler.onError(
|
ExceptionHandler.onError(FlutterErrorDetails(exception: error, stack: stackTrace));
|
||||||
FlutterErrorDetails(exception: error, stack: stackTrace));
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
final getIt = GetIt.instance;
|
final getIt = GetIt.instance;
|
||||||
|
|
||||||
Future<void> setup() async {
|
Future<void> setup() async {
|
||||||
getIt.registerFactory<KeyService>(
|
getIt.registerFactory<KeyService>(() => KeyService(getIt.get<FlutterSecureStorage>()));
|
||||||
() => KeyService(getIt.get<FlutterSecureStorage>()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class App extends StatefulWidget {
|
class App extends StatefulWidget {
|
||||||
|
@ -79,7 +76,7 @@ class _AppState extends State<App> {
|
||||||
}
|
}
|
||||||
|
|
||||||
int hWallet = 0;
|
int hWallet = 0;
|
||||||
CreateLoadRestoreWalletResult? lwr;
|
CreateWalletResult? lwr;
|
||||||
List<Balance> balances = [];
|
List<Balance> balances = [];
|
||||||
String seed = '', version = '';
|
String seed = '', version = '';
|
||||||
final assetIds = <String, String>{};
|
final assetIds = <String, String>{};
|
||||||
|
@ -107,11 +104,9 @@ Future<String?> create(String name) async {
|
||||||
final keyService = KeyService(FlutterSecureStorage());
|
final keyService = KeyService(FlutterSecureStorage());
|
||||||
final password = generateWalletPassword();
|
final password = generateWalletPassword();
|
||||||
credentials.password = password;
|
credentials.password = password;
|
||||||
await keyService.saveWalletPassword(
|
await keyService.saveWalletPassword(password: password, walletName: credentials.name);
|
||||||
password: password, walletName: credentials.name);
|
|
||||||
debugPrint('path $path password $password');
|
debugPrint('path $path password $password');
|
||||||
final result = zano_wallet_manager.createWalletSync(
|
final result = zano_wallet_manager.createWalletSync(path: path, password: password, language: '');
|
||||||
path: path, password: password, language: '');
|
|
||||||
debugPrint('create result $result');
|
debugPrint('create result $result');
|
||||||
return _parseResult(result);
|
return _parseResult(result);
|
||||||
}
|
}
|
||||||
|
@ -122,8 +117,7 @@ Future<String?> connect(String name) async {
|
||||||
final path = await pathForWallet(name: name, type: WalletType.zano);
|
final path = await pathForWallet(name: name, type: WalletType.zano);
|
||||||
final credentials = ZanoNewWalletCredentials(name: name);
|
final credentials = ZanoNewWalletCredentials(name: name);
|
||||||
final keyService = KeyService(FlutterSecureStorage());
|
final keyService = KeyService(FlutterSecureStorage());
|
||||||
final password =
|
final password = await keyService.getWalletPassword(walletName: credentials.name);
|
||||||
await keyService.getWalletPassword(walletName: credentials.name);
|
|
||||||
debugPrint('path $path password $password');
|
debugPrint('path $path password $password');
|
||||||
final result = await calls.loadWallet(path, password, 0);
|
final result = await calls.loadWallet(path, password, 0);
|
||||||
return _parseResult(result);
|
return _parseResult(result);
|
||||||
|
@ -137,8 +131,7 @@ Future<String?> restore(String name, String seed) async {
|
||||||
final keyService = KeyService(FlutterSecureStorage());
|
final keyService = KeyService(FlutterSecureStorage());
|
||||||
final password = generateWalletPassword();
|
final password = generateWalletPassword();
|
||||||
credentials.password = password;
|
credentials.password = password;
|
||||||
await keyService.saveWalletPassword(
|
await keyService.saveWalletPassword(password: password, walletName: credentials.name);
|
||||||
password: password, walletName: credentials.name);
|
|
||||||
debugPrint('path $path password $password');
|
debugPrint('path $path password $password');
|
||||||
var result = calls.restoreWalletFromSeed(path, password, seed);
|
var result = calls.restoreWalletFromSeed(path, password, seed);
|
||||||
debugPrint('restore result $result');
|
debugPrint('restore result $result');
|
||||||
|
@ -148,8 +141,8 @@ Future<String?> restore(String name, String seed) async {
|
||||||
|
|
||||||
String? _parseResult(String result) {
|
String? _parseResult(String result) {
|
||||||
final map = json.decode(result) as Map<String, dynamic>;
|
final map = json.decode(result) as Map<String, dynamic>;
|
||||||
if (map['result'] != null) {
|
if (map['result'] != null) {
|
||||||
lwr = CreateLoadRestoreWalletResult.fromJson(map['result'] as Map<String, dynamic>);
|
lwr = CreateWalletResult.fromJson(map['result'] as Map<String, dynamic>);
|
||||||
balances = lwr!.wi.balances;
|
balances = lwr!.wi.balances;
|
||||||
hWallet = lwr!.walletId;
|
hWallet = lwr!.walletId;
|
||||||
assetIds.clear();
|
assetIds.clear();
|
||||||
|
@ -204,14 +197,12 @@ class _DisconnectedWidgetState extends State<DisconnectedWidget> {
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
TextField(
|
TextField(
|
||||||
controller: _name,
|
controller: _name, decoration: InputDecoration(labelText: 'Wallet name')),
|
||||||
decoration: InputDecoration(labelText: 'Wallet name')),
|
|
||||||
TextButton(
|
TextButton(
|
||||||
child: Text('Connect and Open Wallet'),
|
child: Text('Connect and Open Wallet'),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
//setState(() => _loading = true);
|
//setState(() => _loading = true);
|
||||||
final preferences =
|
final preferences = await SharedPreferences.getInstance();
|
||||||
await SharedPreferences.getInstance();
|
|
||||||
await preferences.setString(walletName, _name.text);
|
await preferences.setString(walletName, _name.text);
|
||||||
final result = await connect(_name.text);
|
final result = await connect(_name.text);
|
||||||
//setState(() => _loading = false);
|
//setState(() => _loading = false);
|
||||||
|
@ -232,8 +223,7 @@ class _DisconnectedWidgetState extends State<DisconnectedWidget> {
|
||||||
child: Text('Create and Open Wallet'),
|
child: Text('Create and Open Wallet'),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
//setState(() => _loading = true);
|
//setState(() => _loading = true);
|
||||||
final preferences =
|
final preferences = await SharedPreferences.getInstance();
|
||||||
await SharedPreferences.getInstance();
|
|
||||||
await preferences.setString(walletName, _name.text);
|
await preferences.setString(walletName, _name.text);
|
||||||
final result = await create(_name.text);
|
final result = await create(_name.text);
|
||||||
//setState(() => _loading = false);
|
//setState(() => _loading = false);
|
||||||
|
@ -251,13 +241,11 @@ class _DisconnectedWidgetState extends State<DisconnectedWidget> {
|
||||||
height: 16,
|
height: 16,
|
||||||
),
|
),
|
||||||
TextField(
|
TextField(
|
||||||
controller: _seed,
|
controller: _seed, decoration: InputDecoration(labelText: 'Wallet seed')),
|
||||||
decoration: InputDecoration(labelText: 'Wallet seed')),
|
|
||||||
TextButton(
|
TextButton(
|
||||||
child: Text('Restore from seed'),
|
child: Text('Restore from seed'),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
final preferences =
|
final preferences = await SharedPreferences.getInstance();
|
||||||
await SharedPreferences.getInstance();
|
|
||||||
await preferences.setString(walletName, _name.text);
|
await preferences.setString(walletName, _name.text);
|
||||||
final result = await restore(_name.text, _seed.text);
|
final result = await restore(_name.text, _seed.text);
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import 'package:cw_zano/new_zano_wallet.dart';
|
||||||
import 'package:mobx/mobx.dart';
|
import 'package:mobx/mobx.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:cw_core/wallet_credentials.dart';
|
import 'package:cw_core/wallet_credentials.dart';
|
||||||
|
|
Loading…
Reference in a new issue