mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2024-11-16 17:27:37 +00:00
Merge branch 'flutter-upgrade' of https://github.com/cake-tech/cake_wallet into CW-182-allow-trusted-nodes
Conflicts: cw_core/lib/node.dart lib/view_model/node_list/node_create_or_edit_view_model.dart
This commit is contained in:
commit
469f23c09b
507 changed files with 6832 additions and 5981 deletions
|
@ -1,51 +1,73 @@
|
|||
include: package:lints/recommended.yaml
|
||||
|
||||
analyzer:
|
||||
strong-mode:
|
||||
implicit-casts: false
|
||||
implicit-dynamic: false
|
||||
exclude: [build/**, lib/generated/*.dart, lib/**.g.dart, cw_monero/ios/External/**, cw_shared_external/**, shared_external/**]
|
||||
exclude: [
|
||||
build/**,
|
||||
lib/**.g.dart,
|
||||
cw_core/lib/**.g.dart,
|
||||
cw_haven/lib/**.g.dart,
|
||||
cw_monero/lib/**.g.dart,
|
||||
lib/generated/*.dart,
|
||||
cw_monero/ios/External/**,
|
||||
cw_shared_external/**,
|
||||
shared_external/**]
|
||||
language:
|
||||
strict-casts: true
|
||||
strict-raw-types: true
|
||||
|
||||
linter:
|
||||
rules:
|
||||
- always_declare_return_types
|
||||
- annotate_overrides
|
||||
- avoid_empty_else
|
||||
- avoid_init_to_null
|
||||
- avoid_return_types_on_setters
|
||||
- await_only_futures
|
||||
- camel_case_types
|
||||
- cancel_subscriptions
|
||||
- close_sinks
|
||||
- comment_references
|
||||
- constant_identifier_names
|
||||
- control_flow_in_finally
|
||||
- empty_catches
|
||||
- empty_constructor_bodies
|
||||
- empty_statements
|
||||
- hash_and_equals
|
||||
- invariant_booleans
|
||||
- iterable_contains_unrelated_type
|
||||
- library_names
|
||||
- library_prefixes
|
||||
- list_remove_unrelated_type
|
||||
- literal_only_boolean_expressions
|
||||
- non_constant_identifier_names
|
||||
- one_member_abstracts
|
||||
- only_throw_errors
|
||||
- overridden_fields
|
||||
- package_api_docs
|
||||
- package_names
|
||||
- package_prefixed_library_names
|
||||
- parameter_assignments
|
||||
- prefer_final_fields
|
||||
- prefer_final_locals
|
||||
- prefer_is_not_empty
|
||||
- slash_for_doc_comments
|
||||
- sort_constructors_first
|
||||
- sort_unnamed_constructors_first
|
||||
- test_types_in_equals
|
||||
- throw_in_finally
|
||||
- type_init_formals
|
||||
- unawaited_futures
|
||||
- unnecessary_getters_setters
|
||||
- unrelated_type_equality_checks
|
||||
- valid_regexps
|
||||
|
||||
|
||||
# analyzer:
|
||||
# strong-mode:
|
||||
# implicit-casts: false
|
||||
# implicit-dynamic: false
|
||||
# exclude: [build/**, lib/generated/*.dart, lib/**.g.dart, cw_monero/ios/External/**, cw_shared_external/**, shared_external/**]
|
||||
|
||||
# linter:
|
||||
# rules:
|
||||
# - always_declare_return_types
|
||||
# - annotate_overrides
|
||||
# - avoid_empty_else
|
||||
# - avoid_init_to_null
|
||||
# - avoid_return_types_on_setters
|
||||
# - await_only_futures
|
||||
# - camel_case_types
|
||||
# - cancel_subscriptions
|
||||
# - close_sinks
|
||||
# - comment_references
|
||||
# - constant_identifier_names
|
||||
# - control_flow_in_finally
|
||||
# - empty_catches
|
||||
# - empty_constructor_bodies
|
||||
# - empty_statements
|
||||
# - hash_and_equals
|
||||
# - invariant_booleans
|
||||
# - iterable_contains_unrelated_type
|
||||
# - library_names
|
||||
# - library_prefixes
|
||||
# - list_remove_unrelated_type
|
||||
# - literal_only_boolean_expressions
|
||||
# - non_constant_identifier_names
|
||||
# - one_member_abstracts
|
||||
# - only_throw_errors
|
||||
# - overridden_fields
|
||||
# - package_api_docs
|
||||
# - package_names
|
||||
# - package_prefixed_library_names
|
||||
# - parameter_assignments
|
||||
# - prefer_final_fields
|
||||
# - prefer_final_locals
|
||||
# - prefer_is_not_empty
|
||||
# - slash_for_doc_comments
|
||||
# - sort_constructors_first
|
||||
# - sort_unnamed_constructors_first
|
||||
# - test_types_in_equals
|
||||
# - throw_in_finally
|
||||
# - type_init_formals
|
||||
# - unawaited_futures
|
||||
# - unnecessary_getters_setters
|
||||
# - unrelated_type_equality_checks
|
||||
# - valid_regexps
|
|
@ -37,7 +37,7 @@ if (appPropertiesFile.exists()) {
|
|||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion 29
|
||||
compileSdkVersion 33
|
||||
|
||||
lintOptions {
|
||||
disable 'InvalidPackage'
|
||||
|
@ -80,6 +80,8 @@ android {
|
|||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
|
||||
ndkVersion "25.1.8937393"
|
||||
}
|
||||
|
||||
flutter {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
buildscript {
|
||||
ext.kotlin_version = '1.5.10'
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
|
@ -7,6 +8,7 @@ buildscript {
|
|||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:4.1.3'
|
||||
classpath 'com.google.gms:google-services:4.3.8'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ String addressFromOutput(Uint8List script, bitcoin.NetworkType networkType) {
|
|||
data: PaymentData(output: script),
|
||||
network: networkType)
|
||||
.data
|
||||
.address;
|
||||
.address!;
|
||||
} catch (_) {}
|
||||
|
||||
try {
|
||||
|
@ -16,8 +16,8 @@ String addressFromOutput(Uint8List script, bitcoin.NetworkType networkType) {
|
|||
data: PaymentData(output: script),
|
||||
network: networkType)
|
||||
.data
|
||||
.address;
|
||||
.address!;
|
||||
} catch(_) {}
|
||||
|
||||
return null;
|
||||
return '';
|
||||
}
|
|
@ -2,7 +2,7 @@ import 'dart:convert';
|
|||
|
||||
class BitcoinAddressRecord {
|
||||
BitcoinAddressRecord(this.address,
|
||||
{this.index, this.isHidden = false, bool isUsed = false})
|
||||
{required this.index, this.isHidden = false, bool isUsed = false})
|
||||
: _isUsed = isUsed;
|
||||
|
||||
factory BitcoinAddressRecord.fromJSON(String jsonSource) {
|
||||
|
@ -11,8 +11,8 @@ class BitcoinAddressRecord {
|
|||
return BitcoinAddressRecord(
|
||||
decoded['address'] as String,
|
||||
index: decoded['index'] as int,
|
||||
isHidden: decoded['isHidden'] as bool ?? false,
|
||||
isUsed: decoded['isUsed'] as bool ?? false);
|
||||
isHidden: decoded['isHidden'] as bool? ?? false,
|
||||
isUsed: decoded['isUsed'] as bool? ?? false);
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -7,10 +7,10 @@ final bitcoinAmountFormat = NumberFormat()
|
|||
..maximumFractionDigits = bitcoinAmountLength
|
||||
..minimumFractionDigits = 1;
|
||||
|
||||
String bitcoinAmountToString({int amount}) => bitcoinAmountFormat.format(
|
||||
String bitcoinAmountToString({required int amount}) => bitcoinAmountFormat.format(
|
||||
cryptoAmountToDouble(amount: amount, divider: bitcoinAmountDivider));
|
||||
|
||||
double bitcoinAmountToDouble({int amount}) =>
|
||||
double bitcoinAmountToDouble({required int amount}) =>
|
||||
cryptoAmountToDouble(amount: amount, divider: bitcoinAmountDivider);
|
||||
|
||||
int stringDoubleToBitcoinAmount(String amount) {
|
||||
|
|
|
@ -106,15 +106,18 @@ Future<String> generateMnemonic(
|
|||
return result;
|
||||
}
|
||||
|
||||
Uint8List mnemonicToSeedBytes(String mnemonic, {String prefix = segwit}) {
|
||||
Future<Uint8List> mnemonicToSeedBytes(String mnemonic, {String prefix = segwit}) async {
|
||||
final pbkdf2 = cryptography.Pbkdf2(
|
||||
macAlgorithm: cryptography.Hmac(cryptography.sha512),
|
||||
macAlgorithm: cryptography.Hmac.sha512(),
|
||||
iterations: 2048,
|
||||
bits: 512);
|
||||
final text = normalizeText(mnemonic);
|
||||
|
||||
return pbkdf2.deriveBitsSync(text.codeUnits,
|
||||
nonce: cryptography.Nonce('electrum'.codeUnits));
|
||||
// pbkdf2.deriveKey(secretKey: secretKey, nonce: nonce)
|
||||
final key = await pbkdf2.deriveKey(
|
||||
secretKey: cryptography.SecretKey(text.codeUnits),
|
||||
nonce: 'electrum'.codeUnits);
|
||||
final bytes = await key.extractBytes();
|
||||
return Uint8List.fromList(bytes);
|
||||
}
|
||||
|
||||
bool matchesAnyPrefix(String mnemonic) =>
|
||||
|
|
|
@ -2,9 +2,9 @@ import 'package:cw_bitcoin/bitcoin_transaction_priority.dart';
|
|||
import 'package:cw_core/output_info.dart';
|
||||
|
||||
class BitcoinTransactionCredentials {
|
||||
BitcoinTransactionCredentials(this.outputs, {this.priority, this.feeRate});
|
||||
BitcoinTransactionCredentials(this.outputs, {required this.priority, this.feeRate});
|
||||
|
||||
final List<OutputInfo> outputs;
|
||||
final BitcoinTransactionPriority priority;
|
||||
final int feeRate;
|
||||
final BitcoinTransactionPriority? priority;
|
||||
final int? feeRate;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ import 'package:cw_core/transaction_priority.dart';
|
|||
//import 'package:cake_wallet/generated/i18n.dart';
|
||||
|
||||
class BitcoinTransactionPriority extends TransactionPriority {
|
||||
const BitcoinTransactionPriority({String title, int raw})
|
||||
const BitcoinTransactionPriority({required String title, required int raw})
|
||||
: super(title: title, raw: raw);
|
||||
|
||||
static const List<BitcoinTransactionPriority> all = [fast, medium, slow];
|
||||
|
@ -13,7 +13,7 @@ class BitcoinTransactionPriority extends TransactionPriority {
|
|||
static const BitcoinTransactionPriority fast =
|
||||
BitcoinTransactionPriority(title: 'Fast', raw: 2);
|
||||
|
||||
static BitcoinTransactionPriority deserialize({int raw}) {
|
||||
static BitcoinTransactionPriority deserialize({required int raw}) {
|
||||
switch (raw) {
|
||||
case 0:
|
||||
return slow;
|
||||
|
@ -22,7 +22,7 @@ class BitcoinTransactionPriority extends TransactionPriority {
|
|||
case 2:
|
||||
return fast;
|
||||
default:
|
||||
return null;
|
||||
throw Exception('Unexpected token: $raw for BitcoinTransactionPriority deserialize');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -53,7 +53,7 @@ class BitcoinTransactionPriority extends TransactionPriority {
|
|||
}
|
||||
|
||||
class LitecoinTransactionPriority extends BitcoinTransactionPriority {
|
||||
const LitecoinTransactionPriority({String title, int raw})
|
||||
const LitecoinTransactionPriority({required String title, required int raw})
|
||||
: super(title: title, raw: raw);
|
||||
|
||||
static const List<LitecoinTransactionPriority> all = [fast, medium, slow];
|
||||
|
@ -64,7 +64,7 @@ class LitecoinTransactionPriority extends BitcoinTransactionPriority {
|
|||
static const LitecoinTransactionPriority fast =
|
||||
LitecoinTransactionPriority(title: 'Fast', raw: 2);
|
||||
|
||||
static LitecoinTransactionPriority deserialize({int raw}) {
|
||||
static LitecoinTransactionPriority deserialize({required int raw}) {
|
||||
switch (raw) {
|
||||
case 0:
|
||||
return slow;
|
||||
|
@ -73,7 +73,7 @@ class LitecoinTransactionPriority extends BitcoinTransactionPriority {
|
|||
case 2:
|
||||
return fast;
|
||||
default:
|
||||
return null;
|
||||
throw Exception('Unexpected token: $raw for LitecoinTransactionPriority deserialize');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import 'package:cw_bitcoin/bitcoin_mnemonic.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cw_core/unspent_coins_info.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
|
@ -17,12 +18,13 @@ class BitcoinWallet = BitcoinWalletBase with _$BitcoinWallet;
|
|||
|
||||
abstract class BitcoinWalletBase extends ElectrumWallet with Store {
|
||||
BitcoinWalletBase(
|
||||
{@required String mnemonic,
|
||||
@required String password,
|
||||
@required WalletInfo walletInfo,
|
||||
@required Box<UnspentCoinsInfo> unspentCoinsInfo,
|
||||
List<BitcoinAddressRecord> initialAddresses,
|
||||
ElectrumBalance initialBalance,
|
||||
{required String mnemonic,
|
||||
required String password,
|
||||
required WalletInfo walletInfo,
|
||||
required Box<UnspentCoinsInfo> unspentCoinsInfo,
|
||||
required Uint8List seedBytes,
|
||||
List<BitcoinAddressRecord>? initialAddresses,
|
||||
ElectrumBalance? initialBalance,
|
||||
int initialRegularAddressIndex = 0,
|
||||
int initialChangeAddressIndex = 0})
|
||||
: super(
|
||||
|
@ -32,7 +34,9 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
|
|||
unspentCoinsInfo: unspentCoinsInfo,
|
||||
networkType: bitcoin.bitcoin,
|
||||
initialAddresses: initialAddresses,
|
||||
initialBalance: initialBalance) {
|
||||
initialBalance: initialBalance,
|
||||
seedBytes: seedBytes,
|
||||
currency: CryptoCurrency.btc) {
|
||||
walletAddresses = BitcoinWalletAddresses(
|
||||
walletInfo,
|
||||
electrumClient: electrumClient,
|
||||
|
@ -40,20 +44,40 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
|
|||
initialRegularAddressIndex: initialRegularAddressIndex,
|
||||
initialChangeAddressIndex: initialChangeAddressIndex,
|
||||
mainHd: hd,
|
||||
sideHd: bitcoin.HDWallet.fromSeed(
|
||||
mnemonicToSeedBytes(mnemonic), network: networkType)
|
||||
sideHd: bitcoin.HDWallet.fromSeed(seedBytes, network: networkType)
|
||||
.derivePath("m/0'/1"),
|
||||
networkType: networkType);
|
||||
}
|
||||
|
||||
static Future<BitcoinWallet> open({
|
||||
@required String name,
|
||||
@required WalletInfo walletInfo,
|
||||
@required Box<UnspentCoinsInfo> unspentCoinsInfo,
|
||||
@required String password,
|
||||
static Future<BitcoinWallet> create({
|
||||
required String mnemonic,
|
||||
required String password,
|
||||
required WalletInfo walletInfo,
|
||||
required Box<UnspentCoinsInfo> unspentCoinsInfo,
|
||||
List<BitcoinAddressRecord>? initialAddresses,
|
||||
ElectrumBalance? initialBalance,
|
||||
int initialRegularAddressIndex = 0,
|
||||
int initialChangeAddressIndex = 0
|
||||
}) async {
|
||||
final snp = ElectrumWallletSnapshot(name, walletInfo.type, password);
|
||||
await snp.load();
|
||||
return BitcoinWallet(
|
||||
mnemonic: mnemonic,
|
||||
password: password,
|
||||
walletInfo: walletInfo,
|
||||
unspentCoinsInfo: unspentCoinsInfo,
|
||||
initialAddresses: initialAddresses,
|
||||
initialBalance: initialBalance,
|
||||
seedBytes: await mnemonicToSeedBytes(mnemonic),
|
||||
initialRegularAddressIndex: initialRegularAddressIndex,
|
||||
initialChangeAddressIndex: initialChangeAddressIndex);
|
||||
}
|
||||
|
||||
static Future<BitcoinWallet> open({
|
||||
required String name,
|
||||
required WalletInfo walletInfo,
|
||||
required Box<UnspentCoinsInfo> unspentCoinsInfo,
|
||||
required String password,
|
||||
}) async {
|
||||
final snp = await ElectrumWallletSnapshot.load(name, walletInfo.type, password);
|
||||
return BitcoinWallet(
|
||||
mnemonic: snp.mnemonic,
|
||||
password: password,
|
||||
|
@ -61,6 +85,7 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
|
|||
unspentCoinsInfo: unspentCoinsInfo,
|
||||
initialAddresses: snp.addresses,
|
||||
initialBalance: snp.balance,
|
||||
seedBytes: await mnemonicToSeedBytes(snp.mnemonic),
|
||||
initialRegularAddressIndex: snp.regularAddressIndex,
|
||||
initialChangeAddressIndex: snp.changeAddressIndex);
|
||||
}
|
||||
|
|
|
@ -16,13 +16,13 @@ abstract class BitcoinWalletAddressesBase extends ElectrumWalletAddresses
|
|||
with Store {
|
||||
BitcoinWalletAddressesBase(
|
||||
WalletInfo walletInfo,
|
||||
{@required List<BitcoinAddressRecord> initialAddresses,
|
||||
{required bitcoin.HDWallet mainHd,
|
||||
required bitcoin.HDWallet sideHd,
|
||||
required bitcoin.NetworkType networkType,
|
||||
required ElectrumClient electrumClient,
|
||||
List<BitcoinAddressRecord>? initialAddresses,
|
||||
int initialRegularAddressIndex = 0,
|
||||
int initialChangeAddressIndex = 0,
|
||||
ElectrumClient electrumClient,
|
||||
@required bitcoin.HDWallet mainHd,
|
||||
@required bitcoin.HDWallet sideHd,
|
||||
@required bitcoin.NetworkType networkType})
|
||||
int initialChangeAddressIndex = 0})
|
||||
: super(
|
||||
walletInfo,
|
||||
initialAddresses: initialAddresses,
|
||||
|
@ -34,6 +34,6 @@ abstract class BitcoinWalletAddressesBase extends ElectrumWalletAddresses
|
|||
networkType: networkType);
|
||||
|
||||
@override
|
||||
String getAddress({@required int index, @required bitcoin.HDWallet hd}) =>
|
||||
String getAddress({required int index, required bitcoin.HDWallet hd}) =>
|
||||
generateP2WPKHAddress(hd: hd, index: index, networkType: networkType);
|
||||
}
|
|
@ -2,13 +2,13 @@ import 'package:cw_core/wallet_credentials.dart';
|
|||
import 'package:cw_core/wallet_info.dart';
|
||||
|
||||
class BitcoinNewWalletCredentials extends WalletCredentials {
|
||||
BitcoinNewWalletCredentials({String name, WalletInfo walletInfo})
|
||||
BitcoinNewWalletCredentials({required String name, WalletInfo? walletInfo})
|
||||
: super(name: name, walletInfo: walletInfo);
|
||||
}
|
||||
|
||||
class BitcoinRestoreWalletFromSeedCredentials extends WalletCredentials {
|
||||
BitcoinRestoreWalletFromSeedCredentials(
|
||||
{String name, String password, this.mnemonic, WalletInfo walletInfo})
|
||||
{required String name, required String password, required this.mnemonic, WalletInfo? walletInfo})
|
||||
: super(name: name, password: password, walletInfo: walletInfo);
|
||||
|
||||
final String mnemonic;
|
||||
|
@ -16,7 +16,7 @@ class BitcoinRestoreWalletFromSeedCredentials extends WalletCredentials {
|
|||
|
||||
class BitcoinRestoreWalletFromWIFCredentials extends WalletCredentials {
|
||||
BitcoinRestoreWalletFromWIFCredentials(
|
||||
{String name, String password, this.wif, WalletInfo walletInfo})
|
||||
{required String name, required String password, required this.wif, WalletInfo? walletInfo})
|
||||
: super(name: name, password: password, walletInfo: walletInfo);
|
||||
|
||||
final String wif;
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
import 'package:flutter/foundation.dart';
|
||||
|
||||
class BitcoinWalletKeys {
|
||||
const BitcoinWalletKeys({@required this.wif, @required this.privateKey, @required this.publicKey});
|
||||
const BitcoinWalletKeys({required this.wif, required this.privateKey, required this.publicKey});
|
||||
|
||||
final String wif;
|
||||
final String privateKey;
|
||||
|
|
|
@ -10,6 +10,7 @@ import 'package:cw_core/pathForWallet.dart';
|
|||
import 'package:cw_core/wallet_info.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
|
||||
class BitcoinWalletService extends WalletService<
|
||||
BitcoinNewWalletCredentials,
|
||||
|
@ -25,10 +26,10 @@ class BitcoinWalletService extends WalletService<
|
|||
|
||||
@override
|
||||
Future<BitcoinWallet> create(BitcoinNewWalletCredentials credentials) async {
|
||||
final wallet = BitcoinWallet(
|
||||
final wallet = await BitcoinWalletBase.create(
|
||||
mnemonic: await generateMnemonic(),
|
||||
password: credentials.password,
|
||||
walletInfo: credentials.walletInfo,
|
||||
password: credentials.password!,
|
||||
walletInfo: credentials.walletInfo!,
|
||||
unspentCoinsInfo: unspentCoinsInfoSource);
|
||||
await wallet.save();
|
||||
await wallet.init();
|
||||
|
@ -41,9 +42,8 @@ class BitcoinWalletService extends WalletService<
|
|||
|
||||
@override
|
||||
Future<BitcoinWallet> openWallet(String name, String password) async {
|
||||
final walletInfo = walletInfoSource.values.firstWhere(
|
||||
(info) => info.id == WalletBase.idFor(name, getType()),
|
||||
orElse: () => null);
|
||||
final walletInfo = walletInfoSource.values.firstWhereOrNull(
|
||||
(info) => info.id == WalletBase.idFor(name, getType()))!;
|
||||
final wallet = await BitcoinWalletBase.open(
|
||||
password: password, name: name, walletInfo: walletInfo,
|
||||
unspentCoinsInfo: unspentCoinsInfoSource);
|
||||
|
@ -68,10 +68,10 @@ class BitcoinWalletService extends WalletService<
|
|||
throw BitcoinMnemonicIsIncorrectException();
|
||||
}
|
||||
|
||||
final wallet = BitcoinWallet(
|
||||
password: credentials.password,
|
||||
final wallet = await BitcoinWalletBase.create(
|
||||
password: credentials.password!,
|
||||
mnemonic: credentials.mnemonic,
|
||||
walletInfo: credentials.walletInfo,
|
||||
walletInfo: credentials.walletInfo!,
|
||||
unspentCoinsInfo: unspentCoinsInfoSource);
|
||||
await wallet.save();
|
||||
await wallet.init();
|
||||
|
|
|
@ -7,6 +7,7 @@ import 'package:cw_bitcoin/bitcoin_amount_format.dart';
|
|||
import 'package:cw_bitcoin/script_hash.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:rxdart/rxdart.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
|
||||
String jsonrpcparams(List<Object> params) {
|
||||
final _params = params?.map((val) => '"${val.toString()}"')?.join(',');
|
||||
|
@ -14,14 +15,20 @@ String jsonrpcparams(List<Object> params) {
|
|||
}
|
||||
|
||||
String jsonrpc(
|
||||
{String method, List<Object> params, int id, double version = 2.0}) =>
|
||||
{required String method,
|
||||
required List<Object> params,
|
||||
required int id,
|
||||
double version = 2.0}) =>
|
||||
'{"jsonrpc": "$version", "method": "$method", "id": "$id", "params": ${json.encode(params)}}\n';
|
||||
|
||||
class SocketTask {
|
||||
SocketTask({this.completer, this.isSubscription, this.subject});
|
||||
SocketTask({
|
||||
required this.isSubscription,
|
||||
this.completer,
|
||||
this.subject});
|
||||
|
||||
final Completer completer;
|
||||
final BehaviorSubject subject;
|
||||
final Completer<dynamic>? completer;
|
||||
final BehaviorSubject<dynamic>? subject;
|
||||
final bool isSubscription;
|
||||
}
|
||||
|
||||
|
@ -36,18 +43,18 @@ class ElectrumClient {
|
|||
static const aliveTimerDuration = Duration(seconds: 2);
|
||||
|
||||
bool get isConnected => _isConnected;
|
||||
Socket socket;
|
||||
void Function(bool) onConnectionStatusChange;
|
||||
Socket? socket;
|
||||
void Function(bool)? onConnectionStatusChange;
|
||||
int _id;
|
||||
final Map<String, SocketTask> _tasks;
|
||||
bool _isConnected;
|
||||
Timer _aliveTimer;
|
||||
Timer? _aliveTimer;
|
||||
String unterminatedString;
|
||||
|
||||
Future<void> connectToUri(Uri uri) async =>
|
||||
await connect(host: uri.host, port: uri.port);
|
||||
|
||||
Future<void> connect({@required String host, @required int port}) async {
|
||||
Future<void> connect({required String host, required int port}) async {
|
||||
try {
|
||||
await socket?.close();
|
||||
} catch (_) {}
|
||||
|
@ -56,10 +63,11 @@ class ElectrumClient {
|
|||
timeout: connectionTimeout, onBadCertificate: (_) => true);
|
||||
_setIsConnected(true);
|
||||
|
||||
socket.listen((Uint8List event) {
|
||||
socket!.listen((Uint8List event) {
|
||||
try {
|
||||
final msg = utf8.decode(event.toList());
|
||||
final response =
|
||||
json.decode(utf8.decode(event.toList())) as Map<String, Object>;
|
||||
json.decode(msg) as Map<String, dynamic>;
|
||||
_handleResponse(response);
|
||||
} on FormatException catch (e) {
|
||||
final msg = e.message.toLowerCase();
|
||||
|
@ -75,12 +83,12 @@ class ElectrumClient {
|
|||
|
||||
if (isJSONStringCorrect(unterminatedString)) {
|
||||
final response =
|
||||
json.decode(unterminatedString) as Map<String, Object>;
|
||||
json.decode(unterminatedString) as Map<String, dynamic>;
|
||||
_handleResponse(response);
|
||||
unterminatedString = '';
|
||||
}
|
||||
} on TypeError catch (e) {
|
||||
if (!e.toString().contains('Map<String, Object>')) {
|
||||
if (!e.toString().contains('Map<String, Object>') || !e.toString().contains('Map<String, dynamic>')) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -89,9 +97,10 @@ class ElectrumClient {
|
|||
|
||||
if (isJSONStringCorrect(unterminatedString)) {
|
||||
final response =
|
||||
json.decode(unterminatedString) as Map<String, Object>;
|
||||
json.decode(unterminatedString) as Map<String, dynamic>;
|
||||
_handleResponse(response);
|
||||
unterminatedString = null;
|
||||
// unterminatedString = null;
|
||||
unterminatedString = '';
|
||||
}
|
||||
} catch (e) {
|
||||
print(e.toString());
|
||||
|
@ -128,14 +137,14 @@ class ElectrumClient {
|
|||
return [];
|
||||
});
|
||||
|
||||
Future<Map<String, Object>> getBalance(String scriptHash) =>
|
||||
Future<Map<String, dynamic>> getBalance(String scriptHash) =>
|
||||
call(method: 'blockchain.scripthash.get_balance', params: [scriptHash])
|
||||
.then((dynamic result) {
|
||||
if (result is Map<String, Object>) {
|
||||
if (result is Map<String, dynamic>) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return <String, Object>{};
|
||||
return <String, dynamic>{};
|
||||
});
|
||||
|
||||
Future<List<Map<String, dynamic>>> getHistory(String scriptHash) =>
|
||||
|
@ -143,11 +152,11 @@ class ElectrumClient {
|
|||
.then((dynamic result) {
|
||||
if (result is List) {
|
||||
return result.map((dynamic val) {
|
||||
if (val is Map<String, Object>) {
|
||||
if (val is Map<String, dynamic>) {
|
||||
return val;
|
||||
}
|
||||
|
||||
return <String, Object>{};
|
||||
return <String, dynamic>{};
|
||||
}).toList();
|
||||
}
|
||||
|
||||
|
@ -162,12 +171,12 @@ class ElectrumClient {
|
|||
.then((dynamic result) {
|
||||
if (result is List) {
|
||||
return result.map((dynamic val) {
|
||||
if (val is Map<String, Object>) {
|
||||
if (val is Map<String, dynamic>) {
|
||||
val['address'] = address;
|
||||
return val;
|
||||
}
|
||||
|
||||
return <String, Object>{};
|
||||
return <String, dynamic>{};
|
||||
}).toList();
|
||||
}
|
||||
|
||||
|
@ -179,11 +188,11 @@ class ElectrumClient {
|
|||
.then((dynamic result) {
|
||||
if (result is List) {
|
||||
return result.map((dynamic val) {
|
||||
if (val is Map<String, Object>) {
|
||||
if (val is Map<String, dynamic>) {
|
||||
return val;
|
||||
}
|
||||
|
||||
return <String, Object>{};
|
||||
return <String, dynamic>{};
|
||||
}).toList();
|
||||
}
|
||||
|
||||
|
@ -195,30 +204,30 @@ class ElectrumClient {
|
|||
.then((dynamic result) {
|
||||
if (result is List) {
|
||||
return result.map((dynamic val) {
|
||||
if (val is Map<String, Object>) {
|
||||
if (val is Map<String, dynamic>) {
|
||||
return val;
|
||||
}
|
||||
|
||||
return <String, Object>{};
|
||||
return <String, dynamic>{};
|
||||
}).toList();
|
||||
}
|
||||
|
||||
return [];
|
||||
});
|
||||
|
||||
Future<Map<String, Object>> getTransactionRaw(
|
||||
{@required String hash}) async =>
|
||||
Future<Map<String, dynamic>> getTransactionRaw(
|
||||
{required String hash}) async =>
|
||||
call(method: 'blockchain.transaction.get', params: [hash, true])
|
||||
.then((dynamic result) {
|
||||
if (result is Map<String, Object>) {
|
||||
if (result is Map<String, dynamic>) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return <String, Object>{};
|
||||
return <String, dynamic>{};
|
||||
});
|
||||
|
||||
Future<String> getTransactionHex(
|
||||
{@required String hash}) async =>
|
||||
{required String hash}) async =>
|
||||
call(method: 'blockchain.transaction.get', params: [hash, false])
|
||||
.then((dynamic result) {
|
||||
if (result is String) {
|
||||
|
@ -229,7 +238,7 @@ class ElectrumClient {
|
|||
});
|
||||
|
||||
Future<String> broadcastTransaction(
|
||||
{@required String transactionRaw}) async =>
|
||||
{required String transactionRaw}) async =>
|
||||
call(method: 'blockchain.transaction.broadcast', params: [transactionRaw])
|
||||
.then((dynamic result) {
|
||||
if (result is String) {
|
||||
|
@ -240,16 +249,16 @@ class ElectrumClient {
|
|||
});
|
||||
|
||||
Future<Map<String, dynamic>> getMerkle(
|
||||
{@required String hash, @required int height}) async =>
|
||||
{required String hash, required int height}) async =>
|
||||
await call(
|
||||
method: 'blockchain.transaction.get_merkle',
|
||||
params: [hash, height]) as Map<String, dynamic>;
|
||||
|
||||
Future<Map<String, dynamic>> getHeader({@required int height}) async =>
|
||||
Future<Map<String, dynamic>> getHeader({required int height}) async =>
|
||||
await call(method: 'blockchain.block.get_header', params: [height])
|
||||
as Map<String, dynamic>;
|
||||
|
||||
Future<double> estimatefee({@required int p}) =>
|
||||
Future<double> estimatefee({required int p}) =>
|
||||
call(method: 'blockchain.estimatefee', params: [p])
|
||||
.then((dynamic result) {
|
||||
if (result is double) {
|
||||
|
@ -266,13 +275,26 @@ class ElectrumClient {
|
|||
Future<List<List<int>>> feeHistogram() =>
|
||||
call(method: 'mempool.get_fee_histogram').then((dynamic result) {
|
||||
if (result is List) {
|
||||
return result.map((dynamic e) {
|
||||
if (e is List) {
|
||||
return e.map((dynamic ee) => ee is int ? ee : null).toList();
|
||||
}
|
||||
// return result.map((dynamic e) {
|
||||
// if (e is List) {
|
||||
// return e.map((dynamic ee) => ee is int ? ee : null).toList();
|
||||
// }
|
||||
|
||||
return null;
|
||||
}).toList();
|
||||
// return null;
|
||||
// }).toList();
|
||||
final histogram = <List<int>>[];
|
||||
for (final e in result) {
|
||||
if (e is List) {
|
||||
final eee = <int>[];
|
||||
for (final ee in e) {
|
||||
if (ee is int) {
|
||||
eee.add(ee);
|
||||
}
|
||||
}
|
||||
histogram.add(eee);
|
||||
}
|
||||
}
|
||||
return histogram;
|
||||
}
|
||||
|
||||
return [];
|
||||
|
@ -299,7 +321,7 @@ class ElectrumClient {
|
|||
}
|
||||
}
|
||||
|
||||
BehaviorSubject<Object> scripthashUpdate(String scripthash) {
|
||||
BehaviorSubject<Object>? scripthashUpdate(String scripthash) {
|
||||
_id += 1;
|
||||
return subscribe<Object>(
|
||||
id: 'blockchain.scripthash.subscribe:$scripthash',
|
||||
|
@ -307,14 +329,14 @@ class ElectrumClient {
|
|||
params: [scripthash]);
|
||||
}
|
||||
|
||||
BehaviorSubject<T> subscribe<T>(
|
||||
{@required String id,
|
||||
@required String method,
|
||||
BehaviorSubject<T>? subscribe<T>(
|
||||
{required String id,
|
||||
required String method,
|
||||
List<Object> params = const []}) {
|
||||
try {
|
||||
final subscription = BehaviorSubject<T>();
|
||||
_regisrySubscription(id, subscription);
|
||||
socket.write(jsonrpc(method: method, id: _id, params: params));
|
||||
socket!.write(jsonrpc(method: method, id: _id, params: params));
|
||||
|
||||
return subscription;
|
||||
} catch(e) {
|
||||
|
@ -323,18 +345,18 @@ class ElectrumClient {
|
|||
}
|
||||
}
|
||||
|
||||
Future<dynamic> call({String method, List<Object> params = const []}) async {
|
||||
Future<dynamic> call({required String method, List<Object> params = const []}) async {
|
||||
final completer = Completer<dynamic>();
|
||||
_id += 1;
|
||||
final id = _id;
|
||||
_registryTask(id, completer);
|
||||
socket.write(jsonrpc(method: method, id: id, params: params));
|
||||
socket!.write(jsonrpc(method: method, id: id, params: params));
|
||||
|
||||
return completer.future;
|
||||
}
|
||||
|
||||
Future<dynamic> callWithTimeout(
|
||||
{String method,
|
||||
{required String method,
|
||||
List<Object> params = const [],
|
||||
int timeout = 2000}) async {
|
||||
try {
|
||||
|
@ -342,7 +364,7 @@ class ElectrumClient {
|
|||
_id += 1;
|
||||
final id = _id;
|
||||
_registryTask(id, completer);
|
||||
socket.write(jsonrpc(method: method, id: id, params: params));
|
||||
socket!.write(jsonrpc(method: method, id: id, params: params));
|
||||
Timer(Duration(milliseconds: timeout), () {
|
||||
if (!completer.isCompleted) {
|
||||
completer.completeError(RequestFailedTimeoutException(method, id));
|
||||
|
@ -356,35 +378,35 @@ class ElectrumClient {
|
|||
}
|
||||
|
||||
Future<void> close() async {
|
||||
_aliveTimer.cancel();
|
||||
await socket.close();
|
||||
_aliveTimer?.cancel();
|
||||
await socket?.close();
|
||||
onConnectionStatusChange = null;
|
||||
}
|
||||
|
||||
void _registryTask(int id, Completer completer) => _tasks[id.toString()] =
|
||||
void _registryTask(int id, Completer<dynamic> completer) => _tasks[id.toString()] =
|
||||
SocketTask(completer: completer, isSubscription: false);
|
||||
|
||||
void _regisrySubscription(String id, BehaviorSubject subject) =>
|
||||
void _regisrySubscription(String id, BehaviorSubject<dynamic> subject) =>
|
||||
_tasks[id] = SocketTask(subject: subject, isSubscription: true);
|
||||
|
||||
void _finish(String id, Object data) {
|
||||
void _finish(String id, Object? data) {
|
||||
if (_tasks[id] == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(_tasks[id]?.completer?.isCompleted ?? false)) {
|
||||
_tasks[id]?.completer?.complete(data);
|
||||
_tasks[id]?.completer!.complete(data);
|
||||
}
|
||||
|
||||
if (!(_tasks[id]?.isSubscription ?? false)) {
|
||||
_tasks[id] = null;
|
||||
_tasks.remove(id);
|
||||
} else {
|
||||
_tasks[id].subject.add(data);
|
||||
_tasks[id]?.subject?.add(data);
|
||||
}
|
||||
}
|
||||
|
||||
void _methodHandler(
|
||||
{@required String method, @required Map<String, Object> request}) {
|
||||
{required String method, required Map<String, dynamic> request}) {
|
||||
switch (method) {
|
||||
case 'blockchain.scripthash.subscribe':
|
||||
final params = request['params'] as List<dynamic>;
|
||||
|
@ -406,7 +428,7 @@ class ElectrumClient {
|
|||
_isConnected = isConnected;
|
||||
}
|
||||
|
||||
void _handleResponse(Map<String, Object> response) {
|
||||
void _handleResponse(Map<String, dynamic> response) {
|
||||
final method = response['method'];
|
||||
final id = response['id'] as String;
|
||||
final result = response['result'];
|
||||
|
|
|
@ -4,10 +4,10 @@ import 'package:cw_bitcoin/bitcoin_amount_format.dart';
|
|||
import 'package:cw_core/balance.dart';
|
||||
|
||||
class ElectrumBalance extends Balance {
|
||||
const ElectrumBalance({@required this.confirmed, @required this.unconfirmed})
|
||||
const ElectrumBalance({required this.confirmed, required this.unconfirmed})
|
||||
: super(confirmed, unconfirmed);
|
||||
|
||||
factory ElectrumBalance.fromJSON(String jsonSource) {
|
||||
static ElectrumBalance? fromJSON(String? jsonSource) {
|
||||
if (jsonSource == null) {
|
||||
return null;
|
||||
}
|
||||
|
@ -15,8 +15,8 @@ class ElectrumBalance extends Balance {
|
|||
final decoded = json.decode(jsonSource) as Map;
|
||||
|
||||
return ElectrumBalance(
|
||||
confirmed: decoded['confirmed'] as int ?? 0,
|
||||
unconfirmed: decoded['unconfirmed'] as int ?? 0);
|
||||
confirmed: decoded['confirmed'] as int? ?? 0,
|
||||
unconfirmed: decoded['unconfirmed'] as int? ?? 0);
|
||||
}
|
||||
|
||||
final int confirmed;
|
||||
|
|
|
@ -17,7 +17,7 @@ class ElectrumTransactionHistory = ElectrumTransactionHistoryBase
|
|||
abstract class ElectrumTransactionHistoryBase
|
||||
extends TransactionHistoryBase<ElectrumTransactionInfo> with Store {
|
||||
ElectrumTransactionHistoryBase(
|
||||
{@required this.walletInfo, @required String password})
|
||||
{required this.walletInfo, required String password})
|
||||
: _password = password,
|
||||
_height = 0 {
|
||||
transactions = ObservableMap<String, ElectrumTransactionInfo>();
|
||||
|
@ -56,18 +56,18 @@ abstract class ElectrumTransactionHistoryBase
|
|||
await save();
|
||||
}
|
||||
|
||||
Future<Map<String, Object>> _read() async {
|
||||
Future<Map<String, dynamic>> _read() async {
|
||||
final dirPath =
|
||||
await pathForWalletDir(name: walletInfo.name, type: walletInfo.type);
|
||||
final path = '$dirPath/$_transactionsHistoryFileName';
|
||||
final content = await read(path: path, password: _password);
|
||||
return json.decode(content) as Map<String, Object>;
|
||||
return json.decode(content) as Map<String, dynamic>;
|
||||
}
|
||||
|
||||
Future<void> _load() async {
|
||||
try {
|
||||
final content = await _read();
|
||||
final txs = content['transactions'] as Map<String, Object> ?? {};
|
||||
final txs = content['transactions'] as Map<String, dynamic> ?? {};
|
||||
|
||||
txs.entries.forEach((entry) {
|
||||
final val = entry.value;
|
||||
|
@ -93,11 +93,11 @@ abstract class ElectrumTransactionHistoryBase
|
|||
transactions[transaction.id] = transaction;
|
||||
} else {
|
||||
final originalTx = transactions[transaction.id];
|
||||
originalTx.confirmations = transaction.confirmations;
|
||||
originalTx.amount = transaction.amount;
|
||||
originalTx.height = transaction.height;
|
||||
originalTx.date ??= transaction.date;
|
||||
originalTx.isPending = transaction.isPending;
|
||||
originalTx?.confirmations = transaction.confirmations;
|
||||
originalTx?.amount = transaction.amount;
|
||||
originalTx?.height = transaction.height;
|
||||
originalTx?.date ??= transaction.date;
|
||||
originalTx?.isPending = transaction.isPending;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,23 +10,26 @@ import 'package:cw_core/format_amount.dart';
|
|||
import 'package:cw_core/wallet_type.dart';
|
||||
|
||||
class ElectrumTransactionBundle {
|
||||
ElectrumTransactionBundle(this.originalTransaction, {this.ins, this.time, this.confirmations});
|
||||
ElectrumTransactionBundle(this.originalTransaction,
|
||||
{required this.ins,
|
||||
required this.confirmations,
|
||||
this.time});
|
||||
final bitcoin.Transaction originalTransaction;
|
||||
final List<bitcoin.Transaction> ins;
|
||||
final int time;
|
||||
final int? time;
|
||||
final int confirmations;
|
||||
}
|
||||
|
||||
class ElectrumTransactionInfo extends TransactionInfo {
|
||||
ElectrumTransactionInfo(this.type,
|
||||
{@required String id,
|
||||
@required int height,
|
||||
@required int amount,
|
||||
@required int fee,
|
||||
@required TransactionDirection direction,
|
||||
@required bool isPending,
|
||||
@required DateTime date,
|
||||
@required int confirmations}) {
|
||||
{required String id,
|
||||
required int height,
|
||||
required int amount,
|
||||
int? fee,
|
||||
required TransactionDirection direction,
|
||||
required bool isPending,
|
||||
required DateTime date,
|
||||
required int confirmations}) {
|
||||
this.id = id;
|
||||
this.height = height;
|
||||
this.amount = amount;
|
||||
|
@ -39,15 +42,15 @@ class ElectrumTransactionInfo extends TransactionInfo {
|
|||
|
||||
factory ElectrumTransactionInfo.fromElectrumVerbose(
|
||||
Map<String, Object> obj, WalletType type,
|
||||
{@required List<BitcoinAddressRecord> addresses, @required int height}) {
|
||||
{required List<BitcoinAddressRecord> addresses, required int height}) {
|
||||
final addressesSet = addresses.map((addr) => addr.address).toSet();
|
||||
final id = obj['txid'] as String;
|
||||
final vins = obj['vin'] as List<Object> ?? [];
|
||||
final vout = (obj['vout'] as List<Object> ?? []);
|
||||
final vins = obj['vin'] as List<Object>? ?? [];
|
||||
final vout = (obj['vout'] as List<Object>? ?? []);
|
||||
final date = obj['time'] is int
|
||||
? DateTime.fromMillisecondsSinceEpoch((obj['time'] as int) * 1000)
|
||||
: DateTime.now();
|
||||
final confirmations = obj['confirmations'] as int ?? 0;
|
||||
final confirmations = obj['confirmations'] as int? ?? 0;
|
||||
var direction = TransactionDirection.incoming;
|
||||
var inputsAmount = 0;
|
||||
var amount = 0;
|
||||
|
@ -57,21 +60,21 @@ class ElectrumTransactionInfo extends TransactionInfo {
|
|||
final vout = vin['vout'] as int;
|
||||
final out = vin['tx']['vout'][vout] as Map;
|
||||
final outAddresses =
|
||||
(out['scriptPubKey']['addresses'] as List<Object>)?.toSet();
|
||||
(out['scriptPubKey']['addresses'] as List<Object>?)?.toSet();
|
||||
inputsAmount +=
|
||||
stringDoubleToBitcoinAmount((out['value'] as double ?? 0).toString());
|
||||
stringDoubleToBitcoinAmount((out['value'] as double? ?? 0).toString());
|
||||
|
||||
if (outAddresses?.intersection(addressesSet)?.isNotEmpty ?? false) {
|
||||
if (outAddresses?.intersection(addressesSet).isNotEmpty ?? false) {
|
||||
direction = TransactionDirection.outgoing;
|
||||
}
|
||||
}
|
||||
|
||||
for (dynamic out in vout) {
|
||||
final outAddresses =
|
||||
out['scriptPubKey']['addresses'] as List<Object> ?? [];
|
||||
out['scriptPubKey']['addresses'] as List<Object>? ?? [];
|
||||
final ntrs = outAddresses.toSet().intersection(addressesSet);
|
||||
final value = stringDoubleToBitcoinAmount(
|
||||
(out['value'] as double ?? 0.0).toString());
|
||||
(out['value'] as double? ?? 0.0).toString());
|
||||
totalOutAmount += value;
|
||||
|
||||
if ((direction == TransactionDirection.incoming && ntrs.isNotEmpty) ||
|
||||
|
@ -97,10 +100,10 @@ class ElectrumTransactionInfo extends TransactionInfo {
|
|||
ElectrumTransactionBundle bundle,
|
||||
WalletType type,
|
||||
bitcoin.NetworkType networkType,
|
||||
{@required Set<String> addresses,
|
||||
int height}) {
|
||||
{required Set<String> addresses,
|
||||
required int height}) {
|
||||
final date = bundle.time != null
|
||||
? DateTime.fromMillisecondsSinceEpoch(bundle.time * 1000)
|
||||
? DateTime.fromMillisecondsSinceEpoch(bundle.time! * 1000)
|
||||
: DateTime.now();
|
||||
var direction = TransactionDirection.incoming;
|
||||
var amount = 0;
|
||||
|
@ -111,21 +114,21 @@ class ElectrumTransactionInfo extends TransactionInfo {
|
|||
final input = bundle.originalTransaction.ins[i];
|
||||
final inputTransaction = bundle.ins[i];
|
||||
final vout = input.index;
|
||||
final outTransaction = inputTransaction.outs[vout];
|
||||
final address = addressFromOutput(outTransaction.script, networkType);
|
||||
inputAmount += outTransaction.value;
|
||||
final outTransaction = inputTransaction.outs[vout!];
|
||||
final address = addressFromOutput(outTransaction.script!, networkType);
|
||||
inputAmount += outTransaction.value!;
|
||||
if (addresses.contains(address)) {
|
||||
direction = TransactionDirection.outgoing;
|
||||
}
|
||||
}
|
||||
|
||||
for (final out in bundle.originalTransaction.outs) {
|
||||
totalOutAmount += out.value;
|
||||
final address = addressFromOutput(out.script, networkType);
|
||||
totalOutAmount += out.value!;
|
||||
final address = addressFromOutput(out.script!, networkType);
|
||||
final addressExists = addresses.contains(address);
|
||||
if ((direction == TransactionDirection.incoming && addressExists) ||
|
||||
(direction == TransactionDirection.outgoing && !addressExists)) {
|
||||
amount += out.value;
|
||||
amount += out.value!;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -142,7 +145,7 @@ class ElectrumTransactionInfo extends TransactionInfo {
|
|||
}
|
||||
|
||||
factory ElectrumTransactionInfo.fromHexAndHeader(WalletType type, String hex,
|
||||
{List<String> addresses, int height, int timestamp, int confirmations}) {
|
||||
{List<String>? addresses, required int height, int? timestamp, required int confirmations}) {
|
||||
final tx = bitcoin.Transaction.fromHex(hex);
|
||||
var exist = false;
|
||||
var amount = 0;
|
||||
|
@ -155,7 +158,7 @@ class ElectrumTransactionInfo extends TransactionInfo {
|
|||
exist = addresses.contains(p2pkh.data.address);
|
||||
|
||||
if (exist) {
|
||||
amount += out.value;
|
||||
amount += out.value!;
|
||||
}
|
||||
} catch (_) {}
|
||||
});
|
||||
|
@ -191,15 +194,15 @@ class ElectrumTransactionInfo extends TransactionInfo {
|
|||
|
||||
final WalletType type;
|
||||
|
||||
String _fiatAmount;
|
||||
String? _fiatAmount;
|
||||
|
||||
@override
|
||||
String amountFormatted() =>
|
||||
'${formatAmount(bitcoinAmountToString(amount: amount))} ${walletTypeToCryptoCurrency(type).title}';
|
||||
|
||||
@override
|
||||
String feeFormatted() => fee != null
|
||||
? '${formatAmount(bitcoinAmountToString(amount: fee))} ${walletTypeToCryptoCurrency(type).title}'
|
||||
String? feeFormatted() => fee != null
|
||||
? '${formatAmount(bitcoinAmountToString(amount: fee!))} ${walletTypeToCryptoCurrency(type).title}'
|
||||
: '';
|
||||
|
||||
@override
|
||||
|
@ -225,7 +228,9 @@ class ElectrumTransactionInfo extends TransactionInfo {
|
|||
m['id'] = id;
|
||||
m['height'] = height;
|
||||
m['amount'] = amount;
|
||||
m['direction'] = direction.index;
|
||||
// FIX-ME: Hardcoded value
|
||||
// m['direction'] = direction.index;
|
||||
m['direction'] = 0;
|
||||
m['date'] = date.millisecondsSinceEpoch;
|
||||
m['isPending'] = isPending;
|
||||
m['confirmations'] = confirmations;
|
||||
|
|
|
@ -34,6 +34,7 @@ import 'package:cw_core/wallet_info.dart';
|
|||
import 'package:cw_bitcoin/electrum.dart';
|
||||
import 'package:hex/hex.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
|
||||
part 'electrum_wallet.g.dart';
|
||||
|
||||
|
@ -42,31 +43,34 @@ class ElectrumWallet = ElectrumWalletBase with _$ElectrumWallet;
|
|||
abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
||||
ElectrumTransactionHistory, ElectrumTransactionInfo> with Store {
|
||||
ElectrumWalletBase(
|
||||
{@required String password,
|
||||
@required WalletInfo walletInfo,
|
||||
@required Box<UnspentCoinsInfo> unspentCoinsInfo,
|
||||
@required List<BitcoinAddressRecord> initialAddresses,
|
||||
@required this.networkType,
|
||||
@required this.mnemonic,
|
||||
ElectrumClient electrumClient,
|
||||
ElectrumBalance initialBalance})
|
||||
: hd = bitcoin.HDWallet.fromSeed(mnemonicToSeedBytes(mnemonic),
|
||||
network: networkType)
|
||||
{required String password,
|
||||
required WalletInfo walletInfo,
|
||||
required Box<UnspentCoinsInfo> unspentCoinsInfo,
|
||||
required this.networkType,
|
||||
required this.mnemonic,
|
||||
required Uint8List seedBytes,
|
||||
List<BitcoinAddressRecord>? initialAddresses,
|
||||
ElectrumClient? electrumClient,
|
||||
ElectrumBalance? initialBalance,
|
||||
CryptoCurrency? currency})
|
||||
: hd = bitcoin.HDWallet.fromSeed(seedBytes, network: networkType)
|
||||
.derivePath("m/0'/0"),
|
||||
syncStatus = NotConnectedSyncStatus(),
|
||||
_password = password,
|
||||
_feeRates = <int>[],
|
||||
_isTransactionUpdating = false,
|
||||
unspentCoins = [],
|
||||
_scripthashesUpdateSubject = {},
|
||||
balance = ObservableMap<CryptoCurrency, ElectrumBalance>.of(
|
||||
currency != null
|
||||
? {currency: initialBalance ?? const ElectrumBalance(confirmed: 0, unconfirmed: 0)}
|
||||
: {}),
|
||||
this.unspentCoinsInfo = unspentCoinsInfo,
|
||||
super(walletInfo) {
|
||||
balance = ObservableMap<CryptoCurrency, ElectrumBalance>.of({
|
||||
currency: initialBalance ?? const ElectrumBalance(confirmed: 0, unconfirmed: 0)});
|
||||
this.electrumClient = electrumClient ?? ElectrumClient();
|
||||
this.walletInfo = walletInfo;
|
||||
this.unspentCoinsInfo = unspentCoinsInfo;
|
||||
transactionHistory =
|
||||
ElectrumTransactionHistory(walletInfo: walletInfo, password: password);
|
||||
unspentCoins = [];
|
||||
_scripthashesUpdateSubject = {};
|
||||
}
|
||||
|
||||
static int estimatedTransactionSize(int inputsCount, int outputsCounts) =>
|
||||
|
@ -75,15 +79,15 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
|||
final bitcoin.HDWallet hd;
|
||||
final String mnemonic;
|
||||
|
||||
ElectrumClient electrumClient;
|
||||
late ElectrumClient electrumClient;
|
||||
Box<UnspentCoinsInfo> unspentCoinsInfo;
|
||||
|
||||
@override
|
||||
ElectrumWalletAddresses walletAddresses;
|
||||
late ElectrumWalletAddresses walletAddresses;
|
||||
|
||||
@override
|
||||
@observable
|
||||
ObservableMap<CryptoCurrency, ElectrumBalance> balance;
|
||||
late ObservableMap<CryptoCurrency, ElectrumBalance> balance;
|
||||
|
||||
@override
|
||||
@observable
|
||||
|
@ -98,7 +102,7 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
|||
.map((addr) => scriptHash(addr.address, networkType: networkType))
|
||||
.toList();
|
||||
|
||||
String get xpub => hd.base58;
|
||||
String get xpub => hd.base58!;
|
||||
|
||||
@override
|
||||
String get seed => mnemonic;
|
||||
|
@ -107,12 +111,12 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
|||
|
||||
@override
|
||||
BitcoinWalletKeys get keys => BitcoinWalletKeys(
|
||||
wif: hd.wif, privateKey: hd.privKey, publicKey: hd.pubKey);
|
||||
wif: hd.wif!, privateKey: hd.privKey!, publicKey: hd.pubKey!);
|
||||
|
||||
String _password;
|
||||
List<BitcoinUnspent> unspentCoins;
|
||||
List<int> _feeRates;
|
||||
Map<String, BehaviorSubject<Object>> _scripthashesUpdateSubject;
|
||||
Map<String, BehaviorSubject<Object>?> _scripthashesUpdateSubject;
|
||||
bool _isTransactionUpdating;
|
||||
|
||||
Future<void> init() async {
|
||||
|
@ -137,7 +141,8 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
|||
(timer) async => _feeRates = await electrumClient.feeRates());
|
||||
|
||||
syncStatus = SyncedSyncStatus();
|
||||
} catch (e) {
|
||||
} catch (e, stacktrace) {
|
||||
print(stacktrace);
|
||||
print(e.toString());
|
||||
syncStatus = FailedSyncStatus();
|
||||
}
|
||||
|
@ -145,7 +150,7 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
|||
|
||||
@action
|
||||
@override
|
||||
Future<void> connectToNode({@required Node node}) async {
|
||||
Future<void> connectToNode({required Node node}) async {
|
||||
try {
|
||||
syncStatus = ConnectingSyncStatus();
|
||||
await electrumClient.connectToUri(node.uri);
|
||||
|
@ -187,7 +192,7 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
|||
}
|
||||
|
||||
final allAmountFee = feeAmountForPriority(
|
||||
transactionCredentials.priority, inputs.length, outputs.length);
|
||||
transactionCredentials.priority!, inputs.length, outputs.length);
|
||||
final allAmount = allInputsAmount - allAmountFee;
|
||||
|
||||
var credentialsAmount = 0;
|
||||
|
@ -196,12 +201,12 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
|||
|
||||
if (hasMultiDestination) {
|
||||
if (outputs.any((item) => item.sendAll
|
||||
|| item.formattedCryptoAmount <= 0)) {
|
||||
|| item.formattedCryptoAmount! <= 0)) {
|
||||
throw BitcoinTransactionWrongBalanceException(currency);
|
||||
}
|
||||
|
||||
credentialsAmount = outputs.fold(0, (acc, value) =>
|
||||
acc + value.formattedCryptoAmount);
|
||||
acc + value.formattedCryptoAmount!);
|
||||
|
||||
if (allAmount - credentialsAmount < minAmount) {
|
||||
throw BitcoinTransactionWrongBalanceException(currency);
|
||||
|
@ -210,7 +215,7 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
|||
amount = credentialsAmount;
|
||||
|
||||
if (transactionCredentials.feeRate != null) {
|
||||
fee = calculateEstimatedFeeWithFeeRate(transactionCredentials.feeRate, amount,
|
||||
fee = calculateEstimatedFeeWithFeeRate(transactionCredentials.feeRate!, amount,
|
||||
outputsCount: outputs.length + 1);
|
||||
} else {
|
||||
fee = calculateEstimatedFee(transactionCredentials.priority, amount,
|
||||
|
@ -219,7 +224,7 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
|||
} else {
|
||||
final output = outputs.first;
|
||||
credentialsAmount = !output.sendAll
|
||||
? output.formattedCryptoAmount
|
||||
? output.formattedCryptoAmount!
|
||||
: 0;
|
||||
|
||||
if (credentialsAmount > allAmount) {
|
||||
|
@ -233,7 +238,7 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
|||
if (output.sendAll || amount == allAmount) {
|
||||
fee = allAmountFee;
|
||||
} else if (transactionCredentials.feeRate != null) {
|
||||
fee = calculateEstimatedFeeWithFeeRate(transactionCredentials.feeRate, amount);
|
||||
fee = calculateEstimatedFeeWithFeeRate(transactionCredentials.feeRate!, amount);
|
||||
} else {
|
||||
fee = calculateEstimatedFee(transactionCredentials.priority, amount);
|
||||
}
|
||||
|
@ -245,7 +250,7 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
|||
|
||||
final totalAmount = amount + fee;
|
||||
|
||||
if (totalAmount > balance[currency].confirmed || totalAmount > allInputsAmount) {
|
||||
if (totalAmount > balance[currency]!.confirmed || totalAmount > allInputsAmount) {
|
||||
throw BitcoinTransactionWrongBalanceException(currency);
|
||||
}
|
||||
|
||||
|
@ -298,11 +303,11 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
|||
? item.formattedCryptoAmount
|
||||
: amount;
|
||||
final outputAddress = item.isParsedAddress
|
||||
? item.extractedAddress
|
||||
? item.extractedAddress!
|
||||
: item.address;
|
||||
txb.addOutput(
|
||||
addressToOutputScript(outputAddress, networkType),
|
||||
outputAmount);
|
||||
outputAmount!);
|
||||
});
|
||||
|
||||
final estimatedSize =
|
||||
|
@ -310,9 +315,9 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
|||
var feeAmount = 0;
|
||||
|
||||
if (transactionCredentials.feeRate != null) {
|
||||
feeAmount = transactionCredentials.feeRate * estimatedSize;
|
||||
feeAmount = transactionCredentials.feeRate! * estimatedSize;
|
||||
} else {
|
||||
feeAmount = feeRate(transactionCredentials.priority) * estimatedSize;
|
||||
feeAmount = feeRate(transactionCredentials.priority!) * estimatedSize;
|
||||
}
|
||||
|
||||
final changeValue = totalInputAmount - amount - feeAmount;
|
||||
|
@ -369,8 +374,8 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
|||
feeRate * estimatedTransactionSize(inputsCount, outputsCount);
|
||||
|
||||
@override
|
||||
int calculateEstimatedFee(TransactionPriority priority, int amount,
|
||||
{int outputsCount}) {
|
||||
int calculateEstimatedFee(TransactionPriority? priority, int? amount,
|
||||
{int? outputsCount}) {
|
||||
if (priority is BitcoinTransactionPriority) {
|
||||
return calculateEstimatedFeeWithFeeRate(
|
||||
feeRate(priority),
|
||||
|
@ -381,8 +386,8 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int calculateEstimatedFeeWithFeeRate(int feeRate, int amount,
|
||||
{int outputsCount}) {
|
||||
int calculateEstimatedFeeWithFeeRate(int feeRate, int? amount,
|
||||
{int? outputsCount}) {
|
||||
int inputsCount = 0;
|
||||
|
||||
if (amount != null) {
|
||||
|
@ -429,16 +434,16 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
|||
await transactionHistory.changePassword(password);
|
||||
}
|
||||
|
||||
bitcoin.ECPair keyPairFor({@required int index}) =>
|
||||
bitcoin.ECPair keyPairFor({required int index}) =>
|
||||
generateKeyPair(hd: hd, index: index, network: networkType);
|
||||
|
||||
@override
|
||||
Future<void> rescan({int height}) async => throw UnimplementedError();
|
||||
Future<void> rescan({required int height}) async => throw UnimplementedError();
|
||||
|
||||
@override
|
||||
Future<void> close() async {
|
||||
try {
|
||||
await electrumClient?.close();
|
||||
await electrumClient.close();
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
|
@ -450,7 +455,13 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
|||
.addresses.map((address) => electrumClient
|
||||
.getListUnspentWithAddress(address.address, networkType)
|
||||
.then((unspent) => unspent
|
||||
.map((unspent) => BitcoinUnspent.fromJSON(address, unspent)))));
|
||||
.map((unspent) {
|
||||
try {
|
||||
return BitcoinUnspent.fromJSON(address, unspent);
|
||||
} catch(_) {
|
||||
return null;
|
||||
}
|
||||
}).whereNotNull())));
|
||||
unspentCoins = unspent.expand((e) => e).toList();
|
||||
|
||||
if (unspentCoinsInfo.isEmpty) {
|
||||
|
@ -498,10 +509,9 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
|||
|
||||
if (currentWalletUnspentCoins.isNotEmpty) {
|
||||
currentWalletUnspentCoins.forEach((element) {
|
||||
final existUnspentCoins = unspentCoins
|
||||
?.where((coin) => element.hash.contains(coin?.hash));
|
||||
final existUnspentCoins = unspentCoins.where((coin) => element.hash.contains(coin.hash));
|
||||
|
||||
if (existUnspentCoins?.isEmpty ?? true) {
|
||||
if (existUnspentCoins.isEmpty) {
|
||||
keys.add(element.key);
|
||||
}
|
||||
});
|
||||
|
@ -516,7 +526,7 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
|||
}
|
||||
|
||||
Future<ElectrumTransactionBundle> getTransactionExpanded(
|
||||
{@required String hash, @required int height}) async {
|
||||
{required String hash, required int height}) async {
|
||||
final verboseTransaction = await electrumClient.getTransactionRaw(hash: hash);
|
||||
final transactionHex = verboseTransaction['hex'] as String;
|
||||
final original = bitcoin.Transaction.fromHex(transactionHex);
|
||||
|
@ -525,7 +535,7 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
|||
final confirmations = verboseTransaction['confirmations'] as int ?? 0;
|
||||
|
||||
for (final vin in original.ins) {
|
||||
final id = HEX.encode(vin.hash.reversed.toList());
|
||||
final id = HEX.encode(vin.hash!.reversed.toList());
|
||||
final txHex = await electrumClient.getTransactionHex(hash: id);
|
||||
final tx = bitcoin.Transaction.fromHex(txHex);
|
||||
ins.add(tx);
|
||||
|
@ -538,8 +548,9 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
|||
confirmations: confirmations);
|
||||
}
|
||||
|
||||
Future<ElectrumTransactionInfo> fetchTransactionInfo(
|
||||
{@required String hash, @required int height}) async {
|
||||
Future<ElectrumTransactionInfo?> fetchTransactionInfo(
|
||||
{required String hash, required int height}) async {
|
||||
try {
|
||||
final tx = await getTransactionExpanded(hash: hash, height: height);
|
||||
final addresses = walletAddresses.addresses.map((addr) => addr.address).toSet();
|
||||
return ElectrumTransactionInfo.fromElectrumBundle(
|
||||
|
@ -548,6 +559,9 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
|||
networkType,
|
||||
addresses: addresses,
|
||||
height: height);
|
||||
} catch(_) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -567,19 +581,27 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
|||
history.entries.forEach((historyItem) {
|
||||
if (historyItem.value.isNotEmpty) {
|
||||
final address = addressHashes[historyItem.key];
|
||||
address.setAsUsed();
|
||||
address?.setAsUsed();
|
||||
normalizedHistories.addAll(historyItem.value);
|
||||
}
|
||||
});
|
||||
});
|
||||
final historiesWithDetails = await Future.wait(
|
||||
normalizedHistories
|
||||
.map((transaction) => fetchTransactionInfo(
|
||||
hash: transaction['tx_hash'] as String,
|
||||
height: transaction['height'] as int)));
|
||||
|
||||
.map((transaction) {
|
||||
try {
|
||||
return fetchTransactionInfo(
|
||||
hash: transaction['tx_hash'] as String,
|
||||
height: transaction['height'] as int);
|
||||
} catch(_) {
|
||||
return Future.value(null);
|
||||
}
|
||||
}));
|
||||
return historiesWithDetails.fold<Map<String, ElectrumTransactionInfo>>(
|
||||
<String, ElectrumTransactionInfo>{}, (acc, tx) {
|
||||
if (tx == null) {
|
||||
return acc;
|
||||
}
|
||||
acc[tx.id] = acc[tx.id]?.updated(tx) ?? tx;
|
||||
return acc;
|
||||
});
|
||||
|
@ -597,7 +619,8 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
|||
walletAddresses.updateReceiveAddresses();
|
||||
await transactionHistory.save();
|
||||
_isTransactionUpdating = false;
|
||||
} catch (e) {
|
||||
} catch (e, stacktrace) {
|
||||
print(stacktrace);
|
||||
print(e);
|
||||
_isTransactionUpdating = false;
|
||||
}
|
||||
|
@ -637,8 +660,8 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
|||
for (var i = 0; i < balances.length; i++) {
|
||||
final addressRecord = addresses[i];
|
||||
final balance = balances[i];
|
||||
final confirmed = balance['confirmed'] as int ?? 0;
|
||||
final unconfirmed = balance['unconfirmed'] as int ?? 0;
|
||||
final confirmed = balance['confirmed'] as int? ?? 0;
|
||||
final unconfirmed = balance['unconfirmed'] as int? ?? 0;
|
||||
totalConfirmed += confirmed;
|
||||
totalUnconfirmed += unconfirmed;
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@ import 'package:cw_bitcoin/electrum.dart';
|
|||
import 'package:cw_bitcoin/script_hash.dart';
|
||||
import 'package:cw_core/wallet_addresses.dart';
|
||||
import 'package:cw_core/wallet_info.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
|
||||
part 'electrum_wallet_addresses.g.dart';
|
||||
|
@ -14,13 +13,13 @@ class ElectrumWalletAddresses = ElectrumWalletAddressesBase
|
|||
|
||||
abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
|
||||
ElectrumWalletAddressesBase(WalletInfo walletInfo,
|
||||
{@required List<BitcoinAddressRecord> initialAddresses,
|
||||
{required this.mainHd,
|
||||
required this.sideHd,
|
||||
required this.electrumClient,
|
||||
required this.networkType,
|
||||
List<BitcoinAddressRecord>? initialAddresses,
|
||||
int initialRegularAddressIndex = 0,
|
||||
int initialChangeAddressIndex = 0,
|
||||
this.mainHd,
|
||||
this.sideHd,
|
||||
this.electrumClient,
|
||||
this.networkType})
|
||||
int initialChangeAddressIndex = 0})
|
||||
: addresses = ObservableList<BitcoinAddressRecord>.of(
|
||||
(initialAddresses ?? []).toSet()),
|
||||
receiveAddresses = ObservableList<BitcoinAddressRecord>.of(
|
||||
|
@ -31,10 +30,9 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
|
|||
(initialAddresses ?? [])
|
||||
.where((addressRecord) => addressRecord.isHidden && !addressRecord.isUsed)
|
||||
.toSet()),
|
||||
super(walletInfo) {
|
||||
currentReceiveAddressIndex = initialRegularAddressIndex;
|
||||
currentChangeAddressIndex = initialChangeAddressIndex;
|
||||
}
|
||||
currentReceiveAddressIndex = initialRegularAddressIndex,
|
||||
currentChangeAddressIndex = initialChangeAddressIndex,
|
||||
super(walletInfo);
|
||||
|
||||
static const defaultReceiveAddressesCount = 22;
|
||||
static const defaultChangeAddressesCount = 17;
|
||||
|
@ -124,17 +122,18 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
|
|||
}
|
||||
|
||||
Future<BitcoinAddressRecord> generateNewAddress(
|
||||
{bool isHidden = false, bitcoin.HDWallet hd}) async {
|
||||
{bitcoin.HDWallet? hd, bool isHidden = false}) async {
|
||||
currentReceiveAddressIndex += 1;
|
||||
// FIX-ME: Check logic for whichi HD should be used here ???
|
||||
final address = BitcoinAddressRecord(
|
||||
getAddress(index: currentReceiveAddressIndex, hd: hd),
|
||||
getAddress(index: currentReceiveAddressIndex, hd: hd ?? sideHd),
|
||||
index: currentReceiveAddressIndex,
|
||||
isHidden: isHidden);
|
||||
addresses.add(address);
|
||||
return address;
|
||||
}
|
||||
|
||||
String getAddress({@required int index, @required bitcoin.HDWallet hd}) => '';
|
||||
String getAddress({required int index, required bitcoin.HDWallet hd}) => '';
|
||||
|
||||
@override
|
||||
Future<void> updateAddressesInBox() async {
|
||||
|
@ -239,7 +238,7 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
|
|||
}
|
||||
|
||||
Future<List<BitcoinAddressRecord>> _createNewAddresses(int count,
|
||||
{int startIndex = 0, bitcoin.HDWallet hd, bool isHidden = false}) async {
|
||||
{required bitcoin.HDWallet hd, int startIndex = 0, bool isHidden = false}) async {
|
||||
final list = <BitcoinAddressRecord>[];
|
||||
|
||||
for (var i = startIndex; i < count + startIndex; i++) {
|
||||
|
|
|
@ -6,7 +6,15 @@ import 'package:cw_core/pathForWallet.dart';
|
|||
import 'package:cw_core/wallet_type.dart';
|
||||
|
||||
class ElectrumWallletSnapshot {
|
||||
ElectrumWallletSnapshot(this.name, this.type, this.password);
|
||||
ElectrumWallletSnapshot({
|
||||
required this.name,
|
||||
required this.type,
|
||||
required this.password,
|
||||
required this.mnemonic,
|
||||
required this.addresses,
|
||||
required this.balance,
|
||||
required this.regularAddressIndex,
|
||||
required this.changeAddressIndex});
|
||||
|
||||
final String name;
|
||||
final String password;
|
||||
|
@ -18,28 +26,34 @@ class ElectrumWallletSnapshot {
|
|||
int regularAddressIndex;
|
||||
int changeAddressIndex;
|
||||
|
||||
Future<void> load() async {
|
||||
try {
|
||||
final path = await pathForWallet(name: name, type: type);
|
||||
final jsonSource = await read(path: path, password: password);
|
||||
final data = json.decode(jsonSource) as Map;
|
||||
final addressesTmp = data['addresses'] as List ?? <Object>[];
|
||||
mnemonic = data['mnemonic'] as String;
|
||||
addresses = addressesTmp
|
||||
.whereType<String>()
|
||||
.map((addr) => BitcoinAddressRecord.fromJSON(addr))
|
||||
.toList();
|
||||
balance = ElectrumBalance.fromJSON(data['balance'] as String) ??
|
||||
ElectrumBalance(confirmed: 0, unconfirmed: 0);
|
||||
regularAddressIndex = 0;
|
||||
changeAddressIndex = 0;
|
||||
static Future<ElectrumWallletSnapshot> load(String name, WalletType type, String password) async {
|
||||
final path = await pathForWallet(name: name, type: type);
|
||||
final jsonSource = await read(path: path, password: password);
|
||||
final data = json.decode(jsonSource) as Map;
|
||||
final addressesTmp = data['addresses'] as List? ?? <Object>[];
|
||||
final mnemonic = data['mnemonic'] as String;
|
||||
final addresses = addressesTmp
|
||||
.whereType<String>()
|
||||
.map((addr) => BitcoinAddressRecord.fromJSON(addr))
|
||||
.toList();
|
||||
final balance = ElectrumBalance.fromJSON(data['balance'] as String) ??
|
||||
ElectrumBalance(confirmed: 0, unconfirmed: 0);
|
||||
var regularAddressIndex = 0;
|
||||
var changeAddressIndex = 0;
|
||||
|
||||
try {
|
||||
regularAddressIndex = int.parse(data['account_index'] as String);
|
||||
changeAddressIndex = int.parse(data['change_address_index'] as String);
|
||||
} catch (_) {}
|
||||
} catch (e) {
|
||||
print(e);
|
||||
}
|
||||
try {
|
||||
regularAddressIndex = int.parse(data['account_index'] as String? ?? '0');
|
||||
changeAddressIndex = int.parse(data['change_address_index'] as String? ?? '0');
|
||||
} catch (_) {}
|
||||
|
||||
return ElectrumWallletSnapshot(
|
||||
name: name,
|
||||
type: type,
|
||||
password: password,
|
||||
mnemonic: mnemonic,
|
||||
addresses: addresses,
|
||||
balance: balance,
|
||||
regularAddressIndex: regularAddressIndex,
|
||||
changeAddressIndex: changeAddressIndex);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
import 'dart:io';
|
||||
import 'package:cw_core/key.dart';
|
||||
import 'package:encrypt/encrypt.dart' as encrypt;
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
Future<void> write(
|
||||
{@required String path,
|
||||
@required String password,
|
||||
@required String data}) async {
|
||||
{required String path,
|
||||
required String password,
|
||||
required String data}) async {
|
||||
final keys = extractKeys(password);
|
||||
final key = encrypt.Key.fromBase64(keys.first);
|
||||
final iv = encrypt.IV.fromBase64(keys.last);
|
||||
|
@ -16,9 +15,9 @@ Future<void> write(
|
|||
}
|
||||
|
||||
Future<void> writeData(
|
||||
{@required String path,
|
||||
@required String password,
|
||||
@required String data}) async {
|
||||
{required String path,
|
||||
required String password,
|
||||
required String data}) async {
|
||||
final keys = extractKeys(password);
|
||||
final key = encrypt.Key.fromBase64(keys.first);
|
||||
final iv = encrypt.IV.fromBase64(keys.last);
|
||||
|
@ -27,7 +26,7 @@ Future<void> writeData(
|
|||
f.writeAsStringSync(encrypted);
|
||||
}
|
||||
|
||||
Future<String> read({@required String path, @required String password}) async {
|
||||
Future<String> read({required String path, required String password}) async {
|
||||
final file = File(path);
|
||||
|
||||
if (!file.existsSync()) {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import 'package:cw_bitcoin/bitcoin_mnemonic.dart';
|
||||
import 'package:cw_bitcoin/bitcoin_transaction_priority.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cw_core/unspent_coins_info.dart';
|
||||
import 'package:cw_bitcoin/litecoin_wallet_addresses.dart';
|
||||
import 'package:cw_core/transaction_priority.dart';
|
||||
|
@ -20,12 +21,13 @@ class LitecoinWallet = LitecoinWalletBase with _$LitecoinWallet;
|
|||
|
||||
abstract class LitecoinWalletBase extends ElectrumWallet with Store {
|
||||
LitecoinWalletBase(
|
||||
{@required String mnemonic,
|
||||
@required String password,
|
||||
@required WalletInfo walletInfo,
|
||||
@required Box<UnspentCoinsInfo> unspentCoinsInfo,
|
||||
List<BitcoinAddressRecord> initialAddresses,
|
||||
ElectrumBalance initialBalance,
|
||||
{required String mnemonic,
|
||||
required String password,
|
||||
required WalletInfo walletInfo,
|
||||
required Box<UnspentCoinsInfo> unspentCoinsInfo,
|
||||
required Uint8List seedBytes,
|
||||
List<BitcoinAddressRecord>? initialAddresses,
|
||||
ElectrumBalance? initialBalance,
|
||||
int initialRegularAddressIndex = 0,
|
||||
int initialChangeAddressIndex = 0})
|
||||
: super(
|
||||
|
@ -35,7 +37,9 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
|
|||
unspentCoinsInfo: unspentCoinsInfo,
|
||||
networkType: litecoinNetwork,
|
||||
initialAddresses: initialAddresses,
|
||||
initialBalance: initialBalance) {
|
||||
initialBalance: initialBalance,
|
||||
seedBytes: seedBytes,
|
||||
currency: CryptoCurrency.ltc) {
|
||||
walletAddresses = LitecoinWalletAddresses(
|
||||
walletInfo,
|
||||
electrumClient: electrumClient,
|
||||
|
@ -44,19 +48,40 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
|
|||
initialChangeAddressIndex: initialChangeAddressIndex,
|
||||
mainHd: hd,
|
||||
sideHd: bitcoin.HDWallet
|
||||
.fromSeed(mnemonicToSeedBytes(mnemonic), network: networkType)
|
||||
.fromSeed(seedBytes, network: networkType)
|
||||
.derivePath("m/0'/1"),
|
||||
networkType: networkType,);
|
||||
}
|
||||
|
||||
static Future<LitecoinWallet> open({
|
||||
@required String name,
|
||||
@required WalletInfo walletInfo,
|
||||
@required Box<UnspentCoinsInfo> unspentCoinsInfo,
|
||||
@required String password,
|
||||
static Future<LitecoinWallet> create({
|
||||
required String mnemonic,
|
||||
required String password,
|
||||
required WalletInfo walletInfo,
|
||||
required Box<UnspentCoinsInfo> unspentCoinsInfo,
|
||||
List<BitcoinAddressRecord>? initialAddresses,
|
||||
ElectrumBalance? initialBalance,
|
||||
int initialRegularAddressIndex = 0,
|
||||
int initialChangeAddressIndex = 0
|
||||
}) async {
|
||||
final snp = ElectrumWallletSnapshot(name, walletInfo.type, password);
|
||||
await snp.load();
|
||||
return LitecoinWallet(
|
||||
mnemonic: mnemonic,
|
||||
password: password,
|
||||
walletInfo: walletInfo,
|
||||
unspentCoinsInfo: unspentCoinsInfo,
|
||||
initialAddresses: initialAddresses,
|
||||
initialBalance: initialBalance,
|
||||
seedBytes: await mnemonicToSeedBytes(mnemonic),
|
||||
initialRegularAddressIndex: initialRegularAddressIndex,
|
||||
initialChangeAddressIndex: initialChangeAddressIndex);
|
||||
}
|
||||
|
||||
static Future<LitecoinWallet> open({
|
||||
required String name,
|
||||
required WalletInfo walletInfo,
|
||||
required Box<UnspentCoinsInfo> unspentCoinsInfo,
|
||||
required String password,
|
||||
}) async {
|
||||
final snp = await ElectrumWallletSnapshot.load (name, walletInfo.type, password);
|
||||
return LitecoinWallet(
|
||||
mnemonic: snp.mnemonic,
|
||||
password: password,
|
||||
|
@ -64,6 +89,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
|
|||
unspentCoinsInfo: unspentCoinsInfo,
|
||||
initialAddresses: snp.addresses,
|
||||
initialBalance: snp.balance,
|
||||
seedBytes: await mnemonicToSeedBytes(snp.mnemonic),
|
||||
initialRegularAddressIndex: snp.regularAddressIndex,
|
||||
initialChangeAddressIndex: snp.changeAddressIndex);
|
||||
}
|
||||
|
|
|
@ -16,13 +16,13 @@ abstract class LitecoinWalletAddressesBase extends ElectrumWalletAddresses
|
|||
with Store {
|
||||
LitecoinWalletAddressesBase(
|
||||
WalletInfo walletInfo,
|
||||
{@required List<BitcoinAddressRecord> initialAddresses,
|
||||
{required bitcoin.HDWallet mainHd,
|
||||
required bitcoin.HDWallet sideHd,
|
||||
required bitcoin.NetworkType networkType,
|
||||
required ElectrumClient electrumClient,
|
||||
List<BitcoinAddressRecord>? initialAddresses,
|
||||
int initialRegularAddressIndex = 0,
|
||||
int initialChangeAddressIndex = 0,
|
||||
ElectrumClient electrumClient,
|
||||
@required bitcoin.HDWallet mainHd,
|
||||
@required bitcoin.HDWallet sideHd,
|
||||
@required bitcoin.NetworkType networkType})
|
||||
int initialChangeAddressIndex = 0})
|
||||
: super(
|
||||
walletInfo,
|
||||
initialAddresses: initialAddresses,
|
||||
|
@ -34,6 +34,6 @@ abstract class LitecoinWalletAddressesBase extends ElectrumWalletAddresses
|
|||
networkType: networkType);
|
||||
|
||||
@override
|
||||
String getAddress({@required int index, @required bitcoin.HDWallet hd}) =>
|
||||
String getAddress({required int index, required bitcoin.HDWallet hd}) =>
|
||||
generateP2WPKHAddress(hd: hd, index: index, networkType: networkType);
|
||||
}
|
|
@ -10,6 +10,7 @@ import 'package:cw_core/pathForWallet.dart';
|
|||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:cw_core/wallet_info.dart';
|
||||
import 'package:cw_core/wallet_base.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
|
||||
class LitecoinWalletService extends WalletService<
|
||||
BitcoinNewWalletCredentials,
|
||||
|
@ -25,10 +26,10 @@ class LitecoinWalletService extends WalletService<
|
|||
|
||||
@override
|
||||
Future<LitecoinWallet> create(BitcoinNewWalletCredentials credentials) async {
|
||||
final wallet = LitecoinWallet(
|
||||
final wallet = await LitecoinWalletBase.create(
|
||||
mnemonic: await generateMnemonic(),
|
||||
password: credentials.password,
|
||||
walletInfo: credentials.walletInfo,
|
||||
password: credentials.password!,
|
||||
walletInfo: credentials.walletInfo!,
|
||||
unspentCoinsInfo: unspentCoinsInfoSource);
|
||||
await wallet.save();
|
||||
await wallet.init();
|
||||
|
@ -42,9 +43,8 @@ class LitecoinWalletService extends WalletService<
|
|||
|
||||
@override
|
||||
Future<LitecoinWallet> openWallet(String name, String password) async {
|
||||
final walletInfo = walletInfoSource.values.firstWhere(
|
||||
(info) => info.id == WalletBase.idFor(name, getType()),
|
||||
orElse: () => null);
|
||||
final walletInfo = walletInfoSource.values.firstWhereOrNull(
|
||||
(info) => info.id == WalletBase.idFor(name, getType()))!;
|
||||
final wallet = await LitecoinWalletBase.open(
|
||||
password: password, name: name, walletInfo: walletInfo,
|
||||
unspentCoinsInfo: unspentCoinsInfoSource);
|
||||
|
@ -69,10 +69,10 @@ class LitecoinWalletService extends WalletService<
|
|||
throw BitcoinMnemonicIsIncorrectException();
|
||||
}
|
||||
|
||||
final wallet = LitecoinWallet(
|
||||
password: credentials.password,
|
||||
final wallet = await LitecoinWalletBase.create(
|
||||
password: credentials.password!,
|
||||
mnemonic: credentials.mnemonic,
|
||||
walletInfo: credentials.walletInfo,
|
||||
walletInfo: credentials.walletInfo!,
|
||||
unspentCoinsInfo: unspentCoinsInfoSource);
|
||||
await wallet.save();
|
||||
await wallet.init();
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import 'package:cw_bitcoin/bitcoin_commit_transaction_exception.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:bitcoin_flutter/bitcoin_flutter.dart' as bitcoin;
|
||||
import 'package:cw_core/pending_transaction.dart';
|
||||
import 'package:cw_bitcoin/electrum.dart';
|
||||
|
@ -10,9 +9,9 @@ import 'package:cw_core/wallet_type.dart';
|
|||
|
||||
class PendingBitcoinTransaction with PendingTransaction {
|
||||
PendingBitcoinTransaction(this._tx, this.type,
|
||||
{@required this.electrumClient,
|
||||
@required this.amount,
|
||||
@required this.fee})
|
||||
{required this.electrumClient,
|
||||
required this.amount,
|
||||
required this.fee})
|
||||
: _listeners = <void Function(ElectrumTransactionInfo transaction)>[];
|
||||
|
||||
final WalletType type;
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import 'package:flutter/foundation.dart';
|
||||
import 'package:bitcoin_flutter/bitcoin_flutter.dart' as bitcoin;
|
||||
import 'package:crypto/crypto.dart';
|
||||
|
||||
String scriptHash(String address, {@required bitcoin.NetworkType networkType}) {
|
||||
String scriptHash(String address, {required bitcoin.NetworkType networkType}) {
|
||||
final outputScript =
|
||||
bitcoin.Address.addressToOutputScript(address, networkType);
|
||||
final parts = sha256.convert(outputScript).toString().split('');
|
||||
|
|
|
@ -5,51 +5,51 @@ import 'package:bitcoin_flutter/src/payments/index.dart' show PaymentData;
|
|||
import 'package:hex/hex.dart';
|
||||
|
||||
bitcoin.PaymentData generatePaymentData(
|
||||
{@required bitcoin.HDWallet hd, @required int index}) =>
|
||||
{required bitcoin.HDWallet hd, required int index}) =>
|
||||
PaymentData(
|
||||
pubkey: Uint8List.fromList(HEX.decode(hd.derive(index).pubKey)));
|
||||
pubkey: Uint8List.fromList(HEX.decode(hd.derive(index).pubKey!)));
|
||||
|
||||
bitcoin.ECPair generateKeyPair(
|
||||
{@required bitcoin.HDWallet hd,
|
||||
@required int index,
|
||||
bitcoin.NetworkType network}) =>
|
||||
bitcoin.ECPair.fromWIF(hd.derive(index).wif, network: network);
|
||||
{required bitcoin.HDWallet hd,
|
||||
required int index,
|
||||
required bitcoin.NetworkType network}) =>
|
||||
bitcoin.ECPair.fromWIF(hd.derive(index).wif!, network: network);
|
||||
|
||||
String generateP2WPKHAddress(
|
||||
{@required bitcoin.HDWallet hd,
|
||||
@required int index,
|
||||
bitcoin.NetworkType networkType}) =>
|
||||
{required bitcoin.HDWallet hd,
|
||||
required int index,
|
||||
required bitcoin.NetworkType networkType}) =>
|
||||
bitcoin
|
||||
.P2WPKH(
|
||||
data: PaymentData(
|
||||
pubkey:
|
||||
Uint8List.fromList(HEX.decode(hd.derive(index).pubKey))),
|
||||
Uint8List.fromList(HEX.decode(hd.derive(index).pubKey!))),
|
||||
network: networkType)
|
||||
.data
|
||||
.address;
|
||||
.address!;
|
||||
|
||||
String generateP2WPKHAddressByPath(
|
||||
{@required bitcoin.HDWallet hd,
|
||||
@required String path,
|
||||
bitcoin.NetworkType networkType}) =>
|
||||
{required bitcoin.HDWallet hd,
|
||||
required String path,
|
||||
required bitcoin.NetworkType networkType}) =>
|
||||
bitcoin
|
||||
.P2WPKH(
|
||||
data: PaymentData(
|
||||
pubkey:
|
||||
Uint8List.fromList(HEX.decode(hd.derivePath(path).pubKey))),
|
||||
Uint8List.fromList(HEX.decode(hd.derivePath(path).pubKey!))),
|
||||
network: networkType)
|
||||
.data
|
||||
.address;
|
||||
.address!;
|
||||
|
||||
String generateP2PKHAddress(
|
||||
{@required bitcoin.HDWallet hd,
|
||||
@required int index,
|
||||
bitcoin.NetworkType networkType}) =>
|
||||
{required bitcoin.HDWallet hd,
|
||||
required int index,
|
||||
required bitcoin.NetworkType networkType}) =>
|
||||
bitcoin
|
||||
.P2PKH(
|
||||
data: PaymentData(
|
||||
pubkey:
|
||||
Uint8List.fromList(HEX.decode(hd.derive(index).pubKey))),
|
||||
Uint8List.fromList(HEX.decode(hd.derive(index).pubKey!))),
|
||||
network: networkType)
|
||||
.data
|
||||
.address;
|
||||
.address!;
|
||||
|
|
|
@ -7,64 +7,64 @@ packages:
|
|||
name: _fe_analyzer_shared
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "14.0.0"
|
||||
version: "47.0.0"
|
||||
analyzer:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: analyzer
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.41.2"
|
||||
version: "4.7.0"
|
||||
args:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: args
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.6.0"
|
||||
version: "2.3.1"
|
||||
asn1lib:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: asn1lib
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.6.5"
|
||||
version: "1.1.1"
|
||||
async:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: async
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.5.0"
|
||||
version: "2.9.0"
|
||||
bech32:
|
||||
dependency: transitive
|
||||
description:
|
||||
path: "."
|
||||
ref: cake
|
||||
resolved-ref: "02fef082f20af13de00b4e64efb93a2c1e5e1cf2"
|
||||
ref: "cake-0.2.1"
|
||||
resolved-ref: cafd1c270641e95017d57d69f55cca9831d4db56
|
||||
url: "https://github.com/cake-tech/bech32.git"
|
||||
source: git
|
||||
version: "0.2.0"
|
||||
version: "0.2.1"
|
||||
bip32:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: bip32
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.7"
|
||||
version: "2.0.0"
|
||||
bip39:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: bip39
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.3"
|
||||
version: "1.0.6"
|
||||
bitcoin_flutter:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
path: "."
|
||||
ref: cake
|
||||
resolved-ref: cbabfd87b6ce3cae6051a3e86ddb56e7a934e188
|
||||
ref: cake-update-v2
|
||||
resolved-ref: "8f86453761c0c26e368392d0ff2c6f12f3b7397b"
|
||||
url: "https://github.com/cake-tech/bitcoin_flutter.git"
|
||||
source: git
|
||||
version: "2.0.2"
|
||||
|
@ -81,133 +81,119 @@ packages:
|
|||
name: bs58check
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
version: "1.0.2"
|
||||
build:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.6.2"
|
||||
version: "2.3.1"
|
||||
build_config:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_config
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.4.6"
|
||||
version: "1.1.0"
|
||||
build_daemon:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_daemon
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.10"
|
||||
version: "3.1.0"
|
||||
build_resolvers:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: build_resolvers
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.5.3"
|
||||
version: "2.0.10"
|
||||
build_runner:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: build_runner
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.11.5"
|
||||
version: "2.2.1"
|
||||
build_runner_core:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_runner_core
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "6.1.10"
|
||||
version: "7.2.4"
|
||||
built_collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: built_collection
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.3.2"
|
||||
version: "5.1.1"
|
||||
built_value:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: built_value
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "7.1.0"
|
||||
version: "8.4.1"
|
||||
characters:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: characters
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
charcode:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: charcode
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
version: "1.2.1"
|
||||
checked_yaml:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: checked_yaml
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.4"
|
||||
cli_util:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: cli_util
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.3.5"
|
||||
version: "2.0.1"
|
||||
clock:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: clock
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
version: "1.1.1"
|
||||
code_builder:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: code_builder
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.7.0"
|
||||
version: "4.3.0"
|
||||
collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: collection
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.15.0"
|
||||
version: "1.16.0"
|
||||
convert:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: convert
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.1"
|
||||
version: "3.0.2"
|
||||
crypto:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: crypto
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.5"
|
||||
version: "3.0.2"
|
||||
cryptography:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: cryptography
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.4.1"
|
||||
version: "2.0.5"
|
||||
cw_core:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -221,35 +207,28 @@ packages:
|
|||
name: dart_style
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.3.12"
|
||||
dartx:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: dartx
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.5.0"
|
||||
version: "2.2.4"
|
||||
encrypt:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: encrypt
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.0.3"
|
||||
version: "5.0.1"
|
||||
fake_async:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: fake_async
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
version: "1.3.1"
|
||||
ffi:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: ffi
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.2"
|
||||
version: "2.0.1"
|
||||
file:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -263,7 +242,7 @@ packages:
|
|||
name: fixnum
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.10.11"
|
||||
version: "1.0.1"
|
||||
flutter:
|
||||
dependency: "direct main"
|
||||
description: flutter
|
||||
|
@ -275,12 +254,19 @@ packages:
|
|||
name: flutter_mobx
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0+2"
|
||||
version: "2.0.6+4"
|
||||
flutter_test:
|
||||
dependency: "direct dev"
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
frontend_server_client:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: frontend_server_client
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.3"
|
||||
glob:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -294,49 +280,49 @@ packages:
|
|||
name: graphs
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.0"
|
||||
version: "2.1.0"
|
||||
hex:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: hex
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.2"
|
||||
version: "0.2.0"
|
||||
hive:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: hive
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.4.4+1"
|
||||
version: "2.2.3"
|
||||
hive_generator:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: hive_generator
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.8.2"
|
||||
version: "1.1.3"
|
||||
http:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: http
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.12.2"
|
||||
version: "0.13.5"
|
||||
http_multi_server:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http_multi_server
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.2.0"
|
||||
version: "3.2.1"
|
||||
http_parser:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http_parser
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.1.4"
|
||||
version: "4.0.1"
|
||||
intl:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -350,7 +336,7 @@ packages:
|
|||
name: io
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.3.5"
|
||||
version: "1.0.3"
|
||||
js:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -364,7 +350,7 @@ packages:
|
|||
name: json_annotation
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.0.1"
|
||||
version: "4.7.0"
|
||||
logging:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -378,14 +364,21 @@ packages:
|
|||
name: matcher
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.12.10"
|
||||
version: "0.12.12"
|
||||
material_color_utilities:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: material_color_utilities
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.5"
|
||||
meta:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: meta
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.3.0"
|
||||
version: "1.8.0"
|
||||
mime:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -399,63 +392,77 @@ packages:
|
|||
name: mobx
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.1+4"
|
||||
version: "2.1.0"
|
||||
mobx_codegen:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: mobx_codegen
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.2"
|
||||
version: "2.0.7+3"
|
||||
package_config:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: package_config
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.9.3"
|
||||
version: "2.1.0"
|
||||
path:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.8.0"
|
||||
version: "1.8.2"
|
||||
path_provider:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: path_provider
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.6.28"
|
||||
version: "2.0.11"
|
||||
path_provider_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_android
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.20"
|
||||
path_provider_ios:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_ios
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.11"
|
||||
path_provider_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_linux
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.0.1+2"
|
||||
version: "2.1.7"
|
||||
path_provider_macos:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_macos
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.0.4+8"
|
||||
version: "2.0.6"
|
||||
path_provider_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.4"
|
||||
version: "2.0.5"
|
||||
path_provider_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_windows
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.0.5"
|
||||
version: "2.1.3"
|
||||
pedantic:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -476,14 +483,14 @@ packages:
|
|||
name: plugin_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.3"
|
||||
version: "2.1.3"
|
||||
pointycastle:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pointycastle
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.2"
|
||||
version: "3.6.2"
|
||||
pool:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -511,35 +518,28 @@ packages:
|
|||
name: pubspec_parse
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.8"
|
||||
quiver:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: quiver
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.5"
|
||||
version: "1.2.1"
|
||||
rxdart:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: rxdart
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.26.0"
|
||||
version: "0.27.5"
|
||||
shelf:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.7.9"
|
||||
version: "1.4.0"
|
||||
shelf_web_socket:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf_web_socket
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.4+1"
|
||||
version: "1.0.2"
|
||||
sky_engine:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
|
@ -551,14 +551,21 @@ packages:
|
|||
name: source_gen
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.9.10+3"
|
||||
version: "1.2.5"
|
||||
source_helper:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_helper
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.3.3"
|
||||
source_span:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_span
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.8.0"
|
||||
version: "1.9.0"
|
||||
stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -586,35 +593,28 @@ packages:
|
|||
name: string_scanner
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
version: "1.1.1"
|
||||
term_glyph:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: term_glyph
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
version: "1.2.1"
|
||||
test_api:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_api
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.19"
|
||||
time:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: time
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.4.1"
|
||||
version: "0.4.12"
|
||||
timing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: timing
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.1+3"
|
||||
version: "1.0.0"
|
||||
typed_data:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -635,7 +635,7 @@ packages:
|
|||
name: vector_math
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
version: "2.1.2"
|
||||
watcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -649,21 +649,21 @@ packages:
|
|||
name: web_socket_channel
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
version: "2.2.0"
|
||||
win32:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: win32
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.5"
|
||||
version: "3.0.0"
|
||||
xdg_directories:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: xdg_directories
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.2"
|
||||
version: "0.2.0+2"
|
||||
yaml:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -672,5 +672,5 @@ packages:
|
|||
source: hosted
|
||||
version: "3.1.0"
|
||||
sdks:
|
||||
dart: ">=2.12.0 <3.0.0"
|
||||
flutter: ">=1.20.0"
|
||||
dart: ">=2.17.5 <3.0.0"
|
||||
flutter: ">=3.0.0"
|
||||
|
|
|
@ -6,35 +6,35 @@ author: Cake Wallet
|
|||
homepage: https://cakewallet.com
|
||||
|
||||
environment:
|
||||
sdk: ">=2.7.0 <3.0.0"
|
||||
flutter: ">=1.17.0"
|
||||
sdk: ">=2.17.5 <3.0.0"
|
||||
flutter: ">=1.20.0"
|
||||
|
||||
dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
path_provider: ^1.4.0
|
||||
http: ^0.12.0+2
|
||||
mobx: ^1.2.1+2
|
||||
flutter_mobx: ^1.1.0+2
|
||||
path_provider: ^2.0.11
|
||||
http: ^0.13.4
|
||||
mobx: ^2.0.7+4
|
||||
flutter_mobx: ^2.0.6+1
|
||||
intl: ^0.17.0
|
||||
cw_core:
|
||||
path: ../cw_core
|
||||
bitcoin_flutter:
|
||||
git:
|
||||
url: https://github.com/cake-tech/bitcoin_flutter.git
|
||||
ref: cake
|
||||
rxdart: ^0.26.0
|
||||
ref: cake-update-v2
|
||||
rxdart: ^0.27.5
|
||||
unorm_dart: ^0.2.0
|
||||
cryptography: ^1.4.0
|
||||
encrypt: ^4.0.0
|
||||
cryptography: ^2.0.5
|
||||
encrypt: ^5.0.1
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
build_runner: ^1.10.3
|
||||
build_resolvers: ^1.3.10
|
||||
mobx_codegen: ^1.1.0+1
|
||||
hive_generator: ^0.8.1
|
||||
build_runner: ^2.1.11
|
||||
build_resolvers: ^2.0.9
|
||||
mobx_codegen: ^2.0.7
|
||||
hive_generator: ^1.1.3
|
||||
|
||||
# For information on the generic Dart part of this file, see the
|
||||
# following page: https://dart.dev/tools/pub/pubspec
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
class Account {
|
||||
Account({this.id, this.label});
|
||||
Account({required this.id, required this.label});
|
||||
|
||||
Account.fromMap(Map map)
|
||||
Account.fromMap(Map<String, Object> map)
|
||||
: this.id = map['id'] == null ? 0 : int.parse(map['id'] as String),
|
||||
this.label = (map['label'] ?? '') as String;
|
||||
|
||||
|
|
|
@ -8,9 +8,9 @@ abstract class AccountList<T> {
|
|||
|
||||
List<T> getAll();
|
||||
|
||||
Future addAccount({String label});
|
||||
Future<void> addAccount({required String label});
|
||||
|
||||
Future setLabelAccount({int accountIndex, String label});
|
||||
Future<void> setLabelAccount({required int accountIndex, required String label});
|
||||
|
||||
void refresh();
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
double cryptoAmountToDouble({num amount, num divider}) => amount / divider;
|
||||
double cryptoAmountToDouble({required num amount, required num divider}) => amount / divider;
|
|
@ -5,12 +5,17 @@ part 'crypto_currency.g.dart';
|
|||
|
||||
@HiveType(typeId: 0)
|
||||
class CryptoCurrency extends EnumerableItem<int> with Serializable<int> {
|
||||
const CryptoCurrency({final String title, this.tag, this.name, this.iconPath, final int raw})
|
||||
const CryptoCurrency({
|
||||
String title = '',
|
||||
int raw = -1,
|
||||
this.name,
|
||||
this.iconPath,
|
||||
this.tag,})
|
||||
: super(title: title, raw: raw);
|
||||
|
||||
final String tag;
|
||||
final String name;
|
||||
final String iconPath;
|
||||
final String? tag;
|
||||
final String? name;
|
||||
final String? iconPath;
|
||||
|
||||
static const all = [
|
||||
CryptoCurrency.xmr,
|
||||
|
@ -97,10 +102,7 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> {
|
|||
static const zen = CryptoCurrency(title: 'ZEN', iconPath: 'assets/images/zen_icon.png', raw: 44);
|
||||
static const xvg = CryptoCurrency(title: 'XVG', name: 'Verge', iconPath: 'assets/images/xvg_icon.png', raw: 45);
|
||||
|
||||
|
||||
|
||||
|
||||
static CryptoCurrency deserialize({int raw}) {
|
||||
static CryptoCurrency deserialize({required int raw}) {
|
||||
switch (raw) {
|
||||
case 0:
|
||||
return CryptoCurrency.xmr;
|
||||
|
@ -195,7 +197,7 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> {
|
|||
case 45:
|
||||
return CryptoCurrency.xvg;
|
||||
default:
|
||||
return null;
|
||||
throw Exception('Unexpected token: $raw for CryptoCurrency deserialize');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -294,7 +296,7 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> {
|
|||
case 'xvg':
|
||||
return CryptoCurrency.xvg;
|
||||
default:
|
||||
return null;
|
||||
throw Exception('Unexpected token: $raw for CryptoCurrency fromString');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,6 @@ CryptoCurrency currencyForWalletType(WalletType type) {
|
|||
case WalletType.haven:
|
||||
return CryptoCurrency.xhv;
|
||||
default:
|
||||
return null;
|
||||
throw Exception('Unexpected wallet type: ${type.toString()} for CryptoCurrency currencyForWalletType');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import 'package:flutter/foundation.dart';
|
||||
|
||||
abstract class EnumerableItem<T> {
|
||||
const EnumerableItem({@required this.title, @required this.raw});
|
||||
const EnumerableItem({required this.title, required this.raw});
|
||||
|
||||
final T raw;
|
||||
final String title;
|
||||
|
@ -11,6 +11,6 @@ abstract class EnumerableItem<T> {
|
|||
}
|
||||
|
||||
mixin Serializable<T> on EnumerableItem<T> {
|
||||
static Serializable deserialize<T>({T raw}) => null;
|
||||
static Serializable deserialize<T>({required T raw}) => throw Exception('Unimplemented');
|
||||
T serialize() => raw;
|
||||
}
|
||||
|
|
|
@ -85,7 +85,7 @@ final dates = {
|
|||
"2020-11": 2220000
|
||||
};
|
||||
|
||||
int getMoneroHeigthByDate({DateTime date}) {
|
||||
int getMoneroHeigthByDate({required DateTime date}) {
|
||||
final raw = '${date.year}' + '-' + '${date.month}';
|
||||
final lastHeight = dates.values.last;
|
||||
int startHeight;
|
||||
|
@ -105,7 +105,7 @@ int getMoneroHeigthByDate({DateTime date}) {
|
|||
final daysHeight = (differenceInDays * heightPerDay).round();
|
||||
height = endHeight + daysHeight;
|
||||
} else {
|
||||
startHeight = dates[raw];
|
||||
startHeight = dates[raw]!;
|
||||
final index = dates.values.toList().indexOf(startHeight);
|
||||
endHeight = dates.values.toList()[index + 1];
|
||||
final heightPerDay = ((endHeight - startHeight) / 31).round();
|
||||
|
|
|
@ -16,14 +16,14 @@ List<String> extractKeys(String key) {
|
|||
return [_key, iv];
|
||||
}
|
||||
|
||||
Future<String> encode({encrypt.Key key, encrypt.IV iv, String data}) async {
|
||||
Future<String> encode({required encrypt.Key key, required encrypt.IV iv, required String data}) async {
|
||||
final encrypter = encrypt.Encrypter(encrypt.Salsa20(key));
|
||||
final encrypted = encrypter.encrypt(data, iv: iv);
|
||||
|
||||
return encrypted.base64;
|
||||
}
|
||||
|
||||
Future<String> decode({String password, String data}) async {
|
||||
Future<String> decode({required String password, required String data}) async {
|
||||
final keys = extractKeys(password);
|
||||
final key = encrypt.Key.fromBase64(keys.first);
|
||||
final iv = encrypt.IV.fromBase64(keys.last);
|
||||
|
|
|
@ -7,12 +7,12 @@ final moneroAmountFormat = NumberFormat()
|
|||
..maximumFractionDigits = moneroAmountLength
|
||||
..minimumFractionDigits = 1;
|
||||
|
||||
String moneroAmountToString({int amount}) => moneroAmountFormat
|
||||
String moneroAmountToString({required int amount}) => moneroAmountFormat
|
||||
.format(cryptoAmountToDouble(amount: amount, divider: moneroAmountDivider))
|
||||
.replaceAll(',', '');
|
||||
|
||||
double moneroAmountToDouble({int amount}) =>
|
||||
double moneroAmountToDouble({required int amount}) =>
|
||||
cryptoAmountToDouble(amount: amount, divider: moneroAmountDivider);
|
||||
|
||||
int moneroParseAmount({String amount}) =>
|
||||
int moneroParseAmount({required String amount}) =>
|
||||
(double.parse(amount) * moneroAmountDivider).toInt();
|
||||
|
|
|
@ -1,17 +1,16 @@
|
|||
import 'package:cw_core/balance.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:cw_core/monero_amount_format.dart';
|
||||
|
||||
class MoneroBalance extends Balance {
|
||||
MoneroBalance({@required this.fullBalance, @required this.unlockedBalance})
|
||||
MoneroBalance({required this.fullBalance, required this.unlockedBalance})
|
||||
: formattedFullBalance = moneroAmountToString(amount: fullBalance),
|
||||
formattedUnlockedBalance =
|
||||
moneroAmountToString(amount: unlockedBalance),
|
||||
super(unlockedBalance, fullBalance);
|
||||
|
||||
MoneroBalance.fromString(
|
||||
{@required this.formattedFullBalance,
|
||||
@required this.formattedUnlockedBalance})
|
||||
{required this.formattedFullBalance,
|
||||
required this.formattedUnlockedBalance})
|
||||
: fullBalance = moneroParseAmount(amount: formattedFullBalance),
|
||||
unlockedBalance = moneroParseAmount(amount: formattedUnlockedBalance),
|
||||
super(moneroParseAmount(amount: formattedUnlockedBalance),
|
||||
|
|
|
@ -4,7 +4,7 @@ import 'package:cw_core/wallet_type.dart';
|
|||
import 'package:cw_core/enumerable_item.dart';
|
||||
|
||||
class MoneroTransactionPriority extends TransactionPriority {
|
||||
const MoneroTransactionPriority({String title, int raw})
|
||||
const MoneroTransactionPriority({required String title, required int raw})
|
||||
: super(title: title, raw: raw);
|
||||
|
||||
static const all = [
|
||||
|
@ -37,7 +37,7 @@ class MoneroTransactionPriority extends TransactionPriority {
|
|||
}
|
||||
}
|
||||
|
||||
static MoneroTransactionPriority deserialize({int raw}) {
|
||||
static MoneroTransactionPriority deserialize({required int raw}) {
|
||||
switch (raw) {
|
||||
case 0:
|
||||
return slow;
|
||||
|
@ -50,7 +50,7 @@ class MoneroTransactionPriority extends TransactionPriority {
|
|||
case 4:
|
||||
return fastest;
|
||||
default:
|
||||
return null;
|
||||
throw Exception('Unexpected token: $raw for MoneroTransactionPriority deserialize');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
class MoneroWalletKeys {
|
||||
const MoneroWalletKeys(
|
||||
{this.privateSpendKey,
|
||||
this.privateViewKey,
|
||||
this.publicSpendKey,
|
||||
this.publicViewKey});
|
||||
{required this.privateSpendKey,
|
||||
required this.privateViewKey,
|
||||
required this.publicSpendKey,
|
||||
required this.publicViewKey});
|
||||
|
||||
final String publicViewKey;
|
||||
final String privateViewKey;
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:cw_core/keyable.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'dart:convert';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:hive/hive.dart';
|
||||
|
@ -11,46 +9,49 @@ import 'package:http/io_client.dart' as ioc;
|
|||
part 'node.g.dart';
|
||||
|
||||
Uri createUriFromElectrumAddress(String address) =>
|
||||
Uri.tryParse('tcp://$address');
|
||||
Uri.tryParse('tcp://$address')!;
|
||||
|
||||
@HiveType(typeId: Node.typeId)
|
||||
class Node extends HiveObject with Keyable {
|
||||
Node(
|
||||
{@required String uri,
|
||||
@required WalletType type,
|
||||
this.login,
|
||||
{this.login,
|
||||
this.password,
|
||||
this.useSSL,
|
||||
this.trusted}) {
|
||||
uriRaw = uri;
|
||||
this.type = type;
|
||||
this.trusted = false,
|
||||
String? uri,
|
||||
WalletType? type,}) {
|
||||
if (uri != null) {
|
||||
uriRaw = uri;
|
||||
}
|
||||
if (type != null) {
|
||||
this.type = type;
|
||||
}
|
||||
}
|
||||
|
||||
Node.fromMap(Map map)
|
||||
: uriRaw = map['uri'] as String ?? '',
|
||||
login = map['login'] as String,
|
||||
password = map['password'] as String,
|
||||
typeRaw = map['typeRaw'] as int,
|
||||
useSSL = map['useSSL'] as bool,
|
||||
trusted = map['trusted'] as bool ?? false;
|
||||
Node.fromMap(Map<String, Object?> map)
|
||||
: uriRaw = map['uri'] as String? ?? '',
|
||||
login = map['login'] as String?,
|
||||
password = map['password'] as String?,
|
||||
useSSL = map['useSSL'] as bool?,
|
||||
trusted = map['trusted'] as bool? ?? false;
|
||||
|
||||
static const typeId = 1;
|
||||
static const boxName = 'Nodes';
|
||||
|
||||
@HiveField(0)
|
||||
String uriRaw;
|
||||
late String uriRaw;
|
||||
|
||||
@HiveField(1)
|
||||
String login;
|
||||
String? login;
|
||||
|
||||
@HiveField(2)
|
||||
String password;
|
||||
String? password;
|
||||
|
||||
@HiveField(3)
|
||||
int typeRaw;
|
||||
late int typeRaw;
|
||||
|
||||
@HiveField(4)
|
||||
bool useSSL;
|
||||
bool? useSSL;
|
||||
|
||||
@HiveField(5)
|
||||
bool trusted;
|
||||
|
@ -68,7 +69,7 @@ class Node extends HiveObject with Keyable {
|
|||
case WalletType.haven:
|
||||
return Uri.http(uriRaw, '');
|
||||
default:
|
||||
return null;
|
||||
throw Exception('Unexpected type ${type.toString()} for Node uri');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -104,33 +105,32 @@ class Node extends HiveObject with Keyable {
|
|||
}
|
||||
|
||||
Future<bool> requestMoneroNode() async {
|
||||
|
||||
final path = '/json_rpc';
|
||||
final rpcUri = isSSL ? Uri.https(uri.authority, path) : Uri.http(uri.authority, path);
|
||||
final realm = 'monero-rpc';
|
||||
final body = {
|
||||
'jsonrpc': '2.0',
|
||||
'id': '0',
|
||||
'jsonrpc': '2.0',
|
||||
'id': '0',
|
||||
'method': 'get_info'
|
||||
};
|
||||
|
||||
try {
|
||||
final authenticatingClient = HttpClient();
|
||||
|
||||
|
||||
authenticatingClient.addCredentials(
|
||||
rpcUri,
|
||||
realm,
|
||||
realm,
|
||||
HttpClientDigestCredentials(login ?? '', password ?? ''),
|
||||
);
|
||||
|
||||
|
||||
final http.Client client = ioc.IOClient(authenticatingClient);
|
||||
|
||||
|
||||
final response = await client.post(
|
||||
rpcUri,
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: json.encode(body),
|
||||
);
|
||||
|
||||
|
||||
client.close();
|
||||
|
||||
final resBody = json.decode(response.body) as Map<String, dynamic>;
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
class OutputInfo {
|
||||
const OutputInfo(
|
||||
{this.fiatAmount,
|
||||
this.cryptoAmount,
|
||||
this.address,
|
||||
this.note,
|
||||
this.sendAll,
|
||||
this.extractedAddress,
|
||||
this.isParsedAddress,
|
||||
this.formattedCryptoAmount});
|
||||
{required this.address,
|
||||
required this.sendAll,
|
||||
required this.isParsedAddress,
|
||||
this.cryptoAmount,
|
||||
this.formattedCryptoAmount,
|
||||
this.fiatAmount,
|
||||
this.note,
|
||||
this.extractedAddress,});
|
||||
|
||||
final String fiatAmount;
|
||||
final String cryptoAmount;
|
||||
final String? fiatAmount;
|
||||
final String? cryptoAmount;
|
||||
final String address;
|
||||
final String note;
|
||||
final String extractedAddress;
|
||||
final String? note;
|
||||
final String? extractedAddress;
|
||||
final bool sendAll;
|
||||
final bool isParsedAddress;
|
||||
final int formattedCryptoAmount;
|
||||
final int? formattedCryptoAmount;
|
||||
}
|
|
@ -3,7 +3,7 @@ import 'package:cw_core/wallet_type.dart';
|
|||
import 'package:flutter/foundation.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
|
||||
Future<String> pathForWalletDir({@required String name, @required WalletType type}) async {
|
||||
Future<String> pathForWalletDir({required String name, required WalletType type}) async {
|
||||
final root = await getApplicationDocumentsDirectory();
|
||||
final prefix = walletTypeToString(type).toLowerCase();
|
||||
final walletsDir = Directory('${root.path}/wallets');
|
||||
|
@ -16,11 +16,11 @@ Future<String> pathForWalletDir({@required String name, @required WalletType ty
|
|||
return walletDire.path;
|
||||
}
|
||||
|
||||
Future<String> pathForWallet({@required String name, @required WalletType type}) async =>
|
||||
Future<String> pathForWallet({required String name, required WalletType type}) async =>
|
||||
await pathForWalletDir(name: name, type: type)
|
||||
.then((path) => path + '/$name');
|
||||
|
||||
Future<String> outdatedAndroidPathForWalletDir({String name}) async {
|
||||
Future<String> outdatedAndroidPathForWalletDir({required String name}) async {
|
||||
final directory = await getApplicationDocumentsDirectory();
|
||||
final pathDir = directory.path + '/$name';
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ const utils = const MethodChannel('com.cake_wallet/native_utils');
|
|||
|
||||
Future<Uint8List> secRandom(int count) async {
|
||||
try {
|
||||
return await utils.invokeMethod<Uint8List>('sec_random', {'count': count});
|
||||
return await utils.invokeMethod<Uint8List>('sec_random', {'count': count}) ?? Uint8List.fromList([]);
|
||||
} on PlatformException catch (_) {
|
||||
return Uint8List.fromList([]);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
class Subaddress {
|
||||
Subaddress({this.id, this.address, this.label});
|
||||
Subaddress({required this.id, required this.address, required this.label});
|
||||
|
||||
Subaddress.fromMap(Map map)
|
||||
Subaddress.fromMap(Map<String, Object?> map)
|
||||
: this.id = map['id'] == null ? 0 : int.parse(map['id'] as String),
|
||||
this.address = (map['address'] ?? '') as String,
|
||||
this.label = (map['label'] ?? '') as String;
|
||||
|
|
|
@ -2,16 +2,22 @@ enum TransactionDirection { incoming, outgoing }
|
|||
|
||||
TransactionDirection parseTransactionDirectionFromInt(int raw) {
|
||||
switch (raw) {
|
||||
case 0: return TransactionDirection.incoming;
|
||||
case 1: return TransactionDirection.outgoing;
|
||||
default: return null;
|
||||
case 0:
|
||||
return TransactionDirection.incoming;
|
||||
case 1:
|
||||
return TransactionDirection.outgoing;
|
||||
default:
|
||||
throw Exception('Unexpected token: raw for TransactionDirection parseTransactionDirectionFromInt');
|
||||
}
|
||||
}
|
||||
|
||||
TransactionDirection parseTransactionDirectionFromNumber(String raw) {
|
||||
switch (raw) {
|
||||
case "0": return TransactionDirection.incoming;
|
||||
case "1": return TransactionDirection.outgoing;
|
||||
default: return null;
|
||||
case "0":
|
||||
return TransactionDirection.incoming;
|
||||
case "1":
|
||||
return TransactionDirection.outgoing;
|
||||
default:
|
||||
throw Exception('Unexpected token: raw for TransactionDirection parseTransactionDirectionFromNumber');
|
||||
}
|
||||
}
|
|
@ -1,10 +1,9 @@
|
|||
import 'package:flutter/foundation.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:cw_core/transaction_info.dart';
|
||||
|
||||
abstract class TransactionHistoryBase<TransactionType extends TransactionInfo> {
|
||||
TransactionHistoryBase();
|
||||
// : _isUpdating = false;
|
||||
TransactionHistoryBase()
|
||||
: transactions = ObservableMap<String, TransactionType>();
|
||||
|
||||
@observable
|
||||
ObservableMap<String, TransactionType> transactions;
|
||||
|
|
|
@ -2,21 +2,21 @@ import 'package:cw_core/transaction_direction.dart';
|
|||
import 'package:cw_core/keyable.dart';
|
||||
|
||||
abstract class TransactionInfo extends Object with Keyable {
|
||||
String id;
|
||||
int amount;
|
||||
int fee;
|
||||
TransactionDirection direction;
|
||||
bool isPending;
|
||||
DateTime date;
|
||||
int height;
|
||||
int confirmations;
|
||||
late String id;
|
||||
late int amount;
|
||||
int? fee;
|
||||
late TransactionDirection direction;
|
||||
late bool isPending;
|
||||
late DateTime date;
|
||||
late int height;
|
||||
late int confirmations;
|
||||
String amountFormatted();
|
||||
String fiatAmount();
|
||||
String feeFormatted();
|
||||
String? feeFormatted();
|
||||
void changeFiatAmount(String amount);
|
||||
|
||||
@override
|
||||
dynamic get keyIndex => id;
|
||||
|
||||
Map<String, dynamic> additionalInfo;
|
||||
late Map<String, dynamic> additionalInfo;
|
||||
}
|
|
@ -2,5 +2,5 @@ import 'package:cw_core/enumerable_item.dart';
|
|||
|
||||
abstract class TransactionPriority extends EnumerableItem<int>
|
||||
with Serializable<int> {
|
||||
const TransactionPriority({String title, int raw}) : super(title: title, raw: raw);
|
||||
const TransactionPriority({required String title, required int raw}) : super(title: title, raw: raw);
|
||||
}
|
||||
|
|
|
@ -5,11 +5,11 @@ part 'unspent_coins_info.g.dart';
|
|||
@HiveType(typeId: UnspentCoinsInfo.typeId)
|
||||
class UnspentCoinsInfo extends HiveObject {
|
||||
UnspentCoinsInfo({
|
||||
this.walletId,
|
||||
this.hash,
|
||||
this.isFrozen,
|
||||
this.isSending,
|
||||
this.note});
|
||||
required this.walletId,
|
||||
required this.hash,
|
||||
required this.isFrozen,
|
||||
required this.isSending,
|
||||
required this.note});
|
||||
|
||||
static const typeId = 9;
|
||||
static const boxName = 'Unspent';
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
import 'package:cw_core/wallet_info.dart';
|
||||
|
||||
abstract class WalletAddresses {
|
||||
WalletAddresses(this.walletInfo) {
|
||||
addressesMap = {};
|
||||
}
|
||||
WalletAddresses(this.walletInfo)
|
||||
: addressesMap = {};
|
||||
|
||||
final WalletInfo walletInfo;
|
||||
|
||||
|
@ -19,10 +18,6 @@ abstract class WalletAddresses {
|
|||
|
||||
Future<void> saveAddressesInBox() async {
|
||||
try {
|
||||
if (walletInfo == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
walletInfo.address = address;
|
||||
walletInfo.addresses = addressesMap;
|
||||
|
||||
|
|
|
@ -5,9 +5,9 @@ import 'package:cw_core/wallet_info.dart';
|
|||
abstract class WalletAddressesWithAccount<T> extends WalletAddresses {
|
||||
WalletAddressesWithAccount(WalletInfo walletInfo) : super(walletInfo);
|
||||
|
||||
T get account;
|
||||
// T get account;
|
||||
|
||||
set account(T account);
|
||||
// set account(T account);
|
||||
|
||||
AccountList<T> get accountList;
|
||||
}
|
|
@ -1,12 +1,12 @@
|
|||
import 'package:mobx/mobx.dart';
|
||||
import 'package:cw_core/balance.dart';
|
||||
import 'package:cw_core/transaction_info.dart';
|
||||
import 'package:cw_core/transaction_history.dart';
|
||||
import 'package:cw_core/transaction_priority.dart';
|
||||
import 'package:cw_core/wallet_addresses.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:cw_core/wallet_info.dart';
|
||||
import 'package:cw_core/pending_transaction.dart';
|
||||
import 'package:cw_core/transaction_history.dart';
|
||||
import 'package:cw_core/currency_for_wallet_type.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cw_core/sync_status.dart';
|
||||
|
@ -48,15 +48,15 @@ abstract class WalletBase<
|
|||
|
||||
WalletAddresses get walletAddresses;
|
||||
|
||||
HistoryType transactionHistory;
|
||||
late HistoryType transactionHistory;
|
||||
|
||||
Future<void> connectToNode({@required Node node});
|
||||
Future<void> connectToNode({required Node node});
|
||||
|
||||
Future<void> startSync();
|
||||
|
||||
Future<PendingTransaction> createTransaction(Object credentials);
|
||||
|
||||
int calculateEstimatedFee(TransactionPriority priority, int amount);
|
||||
int calculateEstimatedFee(TransactionPriority priority, int? amount);
|
||||
|
||||
// void fetchTransactionsAsync(
|
||||
// void Function(TransactionType transaction) onTransactionLoaded,
|
||||
|
@ -66,7 +66,7 @@ abstract class WalletBase<
|
|||
|
||||
Future<void> save();
|
||||
|
||||
Future<void> rescan({int height});
|
||||
Future<void> rescan({required int height});
|
||||
|
||||
void close();
|
||||
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
import 'package:cw_core/wallet_info.dart';
|
||||
|
||||
abstract class WalletCredentials {
|
||||
WalletCredentials({this.name, this.password, this.height, this.walletInfo});
|
||||
WalletCredentials({
|
||||
required this.name,
|
||||
this.height,
|
||||
this.walletInfo,
|
||||
this.password});
|
||||
|
||||
final String name;
|
||||
final int height;
|
||||
String password;
|
||||
WalletInfo walletInfo;
|
||||
final int? height;
|
||||
String? password;
|
||||
WalletInfo? walletInfo;
|
||||
}
|
||||
|
|
|
@ -13,20 +13,20 @@ class WalletInfo extends HiveObject {
|
|||
: _yatLastUsedAddressController = StreamController<String>.broadcast();
|
||||
|
||||
factory WalletInfo.external(
|
||||
{@required String id,
|
||||
@required String name,
|
||||
@required WalletType type,
|
||||
@required bool isRecovery,
|
||||
@required int restoreHeight,
|
||||
@required DateTime date,
|
||||
@required String dirPath,
|
||||
@required String path,
|
||||
@required String address,
|
||||
{required String id,
|
||||
required String name,
|
||||
required WalletType type,
|
||||
required bool isRecovery,
|
||||
required int restoreHeight,
|
||||
required DateTime date,
|
||||
required String dirPath,
|
||||
required String path,
|
||||
required String address,
|
||||
bool? showIntroCakePayCard,
|
||||
String yatEid ='',
|
||||
String yatLastUsedAddressRaw = '',
|
||||
bool showIntroCakePayCard}) {
|
||||
String yatLastUsedAddressRaw = ''}) {
|
||||
return WalletInfo(id, name, type, isRecovery, restoreHeight,
|
||||
date.millisecondsSinceEpoch ?? 0, dirPath, path, address,
|
||||
date.millisecondsSinceEpoch, dirPath, path, address,
|
||||
yatEid, yatLastUsedAddressRaw, showIntroCakePayCard);
|
||||
}
|
||||
|
||||
|
@ -61,7 +61,7 @@ class WalletInfo extends HiveObject {
|
|||
String address;
|
||||
|
||||
@HiveField(10)
|
||||
Map<String, String> addresses;
|
||||
Map<String, String>? addresses;
|
||||
|
||||
@HiveField(11)
|
||||
String yatEid;
|
||||
|
@ -70,7 +70,7 @@ class WalletInfo extends HiveObject {
|
|||
String yatLastUsedAddressRaw;
|
||||
|
||||
@HiveField(13)
|
||||
bool showIntroCakePayCard;
|
||||
bool? showIntroCakePayCard;
|
||||
|
||||
String get yatLastUsedAddress => yatLastUsedAddressRaw;
|
||||
|
||||
|
@ -85,7 +85,7 @@ class WalletInfo extends HiveObject {
|
|||
if(showIntroCakePayCard == null) {
|
||||
return type != WalletType.haven;
|
||||
}
|
||||
return showIntroCakePayCard;
|
||||
return showIntroCakePayCard!;
|
||||
}
|
||||
|
||||
DateTime get date => DateTime.fromMillisecondsSinceEpoch(timestamp);
|
||||
|
|
|
@ -55,7 +55,7 @@ WalletType deserializeFromInt(int raw) {
|
|||
case 3:
|
||||
return WalletType.haven;
|
||||
default:
|
||||
return null;
|
||||
throw Exception('Unexpected token: $raw for WalletType deserializeFromInt');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -100,6 +100,6 @@ CryptoCurrency walletTypeToCryptoCurrency(WalletType type) {
|
|||
case WalletType.haven:
|
||||
return CryptoCurrency.xhv;
|
||||
default:
|
||||
return null;
|
||||
throw Exception('Unexpected wallet type: ${type.toString()} for CryptoCurrency walletTypeToCryptoCurrency');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,35 +7,35 @@ packages:
|
|||
name: _fe_analyzer_shared
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "14.0.0"
|
||||
version: "47.0.0"
|
||||
analyzer:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: analyzer
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.41.2"
|
||||
version: "4.7.0"
|
||||
args:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: args
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.6.0"
|
||||
version: "2.3.1"
|
||||
asn1lib:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: asn1lib
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.8.1"
|
||||
version: "1.1.1"
|
||||
async:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: async
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.5.0"
|
||||
version: "2.9.0"
|
||||
boolean_selector:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -49,42 +49,42 @@ packages:
|
|||
name: build
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.6.2"
|
||||
version: "2.3.1"
|
||||
build_config:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_config
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.4.6"
|
||||
version: "1.1.0"
|
||||
build_daemon:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_daemon
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.10"
|
||||
version: "3.1.0"
|
||||
build_resolvers:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: build_resolvers
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.5.3"
|
||||
version: "2.0.10"
|
||||
build_runner:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: build_runner
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.11.5"
|
||||
version: "2.2.1"
|
||||
build_runner_core:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_runner_core
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "6.1.10"
|
||||
version: "7.2.4"
|
||||
built_collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -105,98 +105,77 @@ packages:
|
|||
name: characters
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
charcode:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: charcode
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
version: "1.2.1"
|
||||
checked_yaml:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: checked_yaml
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.4"
|
||||
cli_util:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: cli_util
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.3.5"
|
||||
version: "2.0.1"
|
||||
clock:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: clock
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
version: "1.1.1"
|
||||
code_builder:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: code_builder
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.7.0"
|
||||
version: "4.3.0"
|
||||
collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: collection
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.15.0"
|
||||
version: "1.16.0"
|
||||
convert:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: convert
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.1"
|
||||
version: "3.0.2"
|
||||
crypto:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: crypto
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.5"
|
||||
version: "3.0.2"
|
||||
dart_style:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: dart_style
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.3.12"
|
||||
dartx:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: dartx
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.5.0"
|
||||
version: "2.2.4"
|
||||
encrypt:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: encrypt
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.1.0"
|
||||
version: "5.0.1"
|
||||
fake_async:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: fake_async
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
version: "1.3.1"
|
||||
ffi:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: ffi
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.2"
|
||||
version: "2.0.1"
|
||||
file:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -222,12 +201,19 @@ packages:
|
|||
name: flutter_mobx
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0+2"
|
||||
version: "2.0.6+4"
|
||||
flutter_test:
|
||||
dependency: "direct dev"
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
frontend_server_client:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: frontend_server_client
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.3"
|
||||
glob:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -241,42 +227,42 @@ packages:
|
|||
name: graphs
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.0"
|
||||
version: "2.1.0"
|
||||
hive:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: hive
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.4.4+1"
|
||||
version: "2.2.3"
|
||||
hive_generator:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: hive_generator
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.8.2"
|
||||
version: "1.1.3"
|
||||
http:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: http
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.12.2"
|
||||
version: "0.13.5"
|
||||
http_multi_server:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http_multi_server
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.2.0"
|
||||
version: "3.2.1"
|
||||
http_parser:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http_parser
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.1.4"
|
||||
version: "4.0.1"
|
||||
intl:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -290,7 +276,7 @@ packages:
|
|||
name: io
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.3.5"
|
||||
version: "1.0.3"
|
||||
js:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -304,7 +290,7 @@ packages:
|
|||
name: json_annotation
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.0.1"
|
||||
version: "4.6.0"
|
||||
logging:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -318,14 +304,21 @@ packages:
|
|||
name: matcher
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.12.10"
|
||||
version: "0.12.12"
|
||||
material_color_utilities:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: material_color_utilities
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.5"
|
||||
meta:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: meta
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.3.0"
|
||||
version: "1.8.0"
|
||||
mime:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -339,63 +332,77 @@ packages:
|
|||
name: mobx
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.1+4"
|
||||
version: "2.1.0"
|
||||
mobx_codegen:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: mobx_codegen
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.2"
|
||||
version: "2.0.7+3"
|
||||
package_config:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: package_config
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.9.3"
|
||||
version: "2.1.0"
|
||||
path:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.8.0"
|
||||
version: "1.8.2"
|
||||
path_provider:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: path_provider
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.6.28"
|
||||
version: "2.0.11"
|
||||
path_provider_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_android
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.20"
|
||||
path_provider_ios:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_ios
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.11"
|
||||
path_provider_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_linux
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.0.1+2"
|
||||
version: "2.1.7"
|
||||
path_provider_macos:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_macos
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.0.4+8"
|
||||
version: "2.0.6"
|
||||
path_provider_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.4"
|
||||
version: "2.0.4"
|
||||
path_provider_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_windows
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.0.5"
|
||||
version: "2.1.3"
|
||||
pedantic:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -416,14 +423,14 @@ packages:
|
|||
name: plugin_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.3"
|
||||
version: "2.1.3"
|
||||
pointycastle:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pointycastle
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.1"
|
||||
version: "3.6.2"
|
||||
pool:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -451,21 +458,21 @@ packages:
|
|||
name: pubspec_parse
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.8"
|
||||
version: "1.2.1"
|
||||
shelf:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.7.9"
|
||||
version: "1.3.2"
|
||||
shelf_web_socket:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf_web_socket
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.4+1"
|
||||
version: "1.0.2"
|
||||
sky_engine:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
|
@ -477,14 +484,21 @@ packages:
|
|||
name: source_gen
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.9.10+3"
|
||||
version: "1.2.3"
|
||||
source_helper:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_helper
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.3.3"
|
||||
source_span:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_span
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.8.0"
|
||||
version: "1.9.0"
|
||||
stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -512,35 +526,28 @@ packages:
|
|||
name: string_scanner
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
version: "1.1.1"
|
||||
term_glyph:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: term_glyph
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
version: "1.2.1"
|
||||
test_api:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_api
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.19"
|
||||
time:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: time
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.4.1"
|
||||
version: "0.4.12"
|
||||
timing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: timing
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.1+3"
|
||||
version: "1.0.0"
|
||||
typed_data:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -554,7 +561,7 @@ packages:
|
|||
name: vector_math
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
version: "2.1.2"
|
||||
watcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -568,21 +575,21 @@ packages:
|
|||
name: web_socket_channel
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
version: "2.2.0"
|
||||
win32:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: win32
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.5"
|
||||
version: "3.0.0"
|
||||
xdg_directories:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: xdg_directories
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.2"
|
||||
version: "0.2.0+2"
|
||||
yaml:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -591,5 +598,5 @@ packages:
|
|||
source: hosted
|
||||
version: "3.1.0"
|
||||
sdks:
|
||||
dart: ">=2.12.0 <3.0.0"
|
||||
flutter: ">=1.20.0"
|
||||
dart: ">=2.17.5 <3.0.0"
|
||||
flutter: ">=3.0.0"
|
||||
|
|
|
@ -6,26 +6,26 @@ author: Cake Wallet
|
|||
homepage: https://cakewallet.com
|
||||
|
||||
environment:
|
||||
sdk: ">=2.7.0 <3.0.0"
|
||||
flutter: ">=1.17.0"
|
||||
sdk: ">=2.17.5 <3.0.0"
|
||||
flutter: ">=1.20.0"
|
||||
|
||||
dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
http: ^0.12.0+2
|
||||
path_provider: ^1.3.0
|
||||
mobx: ^1.2.1+2
|
||||
flutter_mobx: ^1.1.0+2
|
||||
http: ^0.13.4
|
||||
path_provider: ^2.0.11
|
||||
mobx: ^2.0.7+4
|
||||
flutter_mobx: ^2.0.6+1
|
||||
intl: ^0.17.0
|
||||
encrypt: ^4.0.0
|
||||
encrypt: ^5.0.1
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
build_runner: ^1.10.3
|
||||
build_resolvers: ^1.3.10
|
||||
mobx_codegen: ^1.1.0+1
|
||||
hive_generator: ^0.8.1
|
||||
build_runner: ^2.1.11
|
||||
build_resolvers: ^2.0.9
|
||||
mobx_codegen: ^2.0.7
|
||||
hive_generator: ^1.1.3
|
||||
|
||||
# For information on the generic Dart part of this file, see the
|
||||
# following page: https://dart.dev/tools/pub/pubspec
|
||||
|
|
|
@ -50,16 +50,16 @@ List<AccountRow> getAllAccount() {
|
|||
.toList();
|
||||
}
|
||||
|
||||
void addAccountSync({String label}) {
|
||||
final labelPointer = Utf8.toUtf8(label);
|
||||
void addAccountSync({required String label}) {
|
||||
final labelPointer = label.toNativeUtf8();
|
||||
accountAddNewNative(labelPointer);
|
||||
free(labelPointer);
|
||||
calloc.free(labelPointer);
|
||||
}
|
||||
|
||||
void setLabelForAccountSync({int accountIndex, String label}) {
|
||||
final labelPointer = Utf8.toUtf8(label);
|
||||
void setLabelForAccountSync({required int accountIndex, required String label}) {
|
||||
final labelPointer = label.toNativeUtf8();
|
||||
accountSetLabelNative(accountIndex, labelPointer);
|
||||
free(labelPointer);
|
||||
calloc.free(labelPointer);
|
||||
}
|
||||
|
||||
void _addAccount(String label) => addAccountSync(label: label);
|
||||
|
@ -71,12 +71,12 @@ void _setLabelForAccount(Map<String, dynamic> args) {
|
|||
setLabelForAccountSync(label: label, accountIndex: accountIndex);
|
||||
}
|
||||
|
||||
Future<void> addAccount({String label}) async {
|
||||
Future<void> addAccount({required String label}) async {
|
||||
await compute(_addAccount, label);
|
||||
await store();
|
||||
}
|
||||
|
||||
Future<void> setLabelForAccount({int accountIndex, String label}) async {
|
||||
Future<void> setLabelForAccount({required int accountIndex, required String label}) async {
|
||||
await compute(
|
||||
_setLabelForAccount, {'accountIndex': accountIndex, 'label': label});
|
||||
await store();
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import 'dart:ffi';
|
||||
import 'package:ffi/ffi.dart';
|
||||
|
||||
String convertUTF8ToString({Pointer<Utf8> pointer}) {
|
||||
final str = Utf8.fromUtf8(pointer);
|
||||
free(pointer);
|
||||
String convertUTF8ToString({required Pointer<Utf8> pointer}) {
|
||||
final str = pointer.toDartString();
|
||||
calloc.free(pointer);
|
||||
return str;
|
||||
}
|
|
@ -8,7 +8,7 @@ class CwHaven {
|
|||
const MethodChannel('cw_haven');
|
||||
|
||||
static Future<String> get platformVersion async {
|
||||
final String version = await _channel.invokeMethod('getPlatformVersion');
|
||||
final String version = await _channel.invokeMethod<String>('getPlatformVersion') ?? '';
|
||||
return version;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
class ConnectionToNodeException implements Exception {
|
||||
ConnectionToNodeException({this.message});
|
||||
ConnectionToNodeException({required this.message});
|
||||
|
||||
final String message;
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
class CreationTransactionException implements Exception {
|
||||
CreationTransactionException({this.message});
|
||||
CreationTransactionException({required this.message});
|
||||
|
||||
final String message;
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
class SetupWalletException implements Exception {
|
||||
SetupWalletException({this.message});
|
||||
SetupWalletException({required this.message});
|
||||
|
||||
final String message;
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
class WalletCreationException implements Exception {
|
||||
WalletCreationException({this.message});
|
||||
WalletCreationException({required this.message});
|
||||
|
||||
final String message;
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
class WalletOpeningException implements Exception {
|
||||
WalletOpeningException({this.message});
|
||||
WalletOpeningException({required this.message});
|
||||
|
||||
final String message;
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
class WalletRestoreFromKeysException implements Exception {
|
||||
WalletRestoreFromKeysException({this.message});
|
||||
WalletRestoreFromKeysException({required this.message});
|
||||
|
||||
final String message;
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
class WalletRestoreFromSeedException implements Exception {
|
||||
WalletRestoreFromSeedException({this.message});
|
||||
WalletRestoreFromSeedException({required this.message});
|
||||
|
||||
final String message;
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
import 'package:flutter/foundation.dart';
|
||||
|
||||
class MoneroOutput {
|
||||
MoneroOutput({@required this.address, @required this.amount});
|
||||
MoneroOutput({required this.address, required this.amount});
|
||||
|
||||
final String address;
|
||||
final String amount;
|
||||
|
|
|
@ -39,7 +39,7 @@ typedef get_node_height = Int64 Function();
|
|||
typedef is_connected = Int8 Function();
|
||||
|
||||
typedef setup_node = Int8 Function(
|
||||
Pointer<Utf8>, Pointer<Utf8>, Pointer<Utf8>, Int8, Int8, Pointer<Utf8>);
|
||||
Pointer<Utf8>, Pointer<Utf8>?, Pointer<Utf8>?, Int8, Int8, Pointer<Utf8>);
|
||||
|
||||
typedef start_refresh = Void Function();
|
||||
|
||||
|
@ -86,7 +86,7 @@ typedef account_set_label = Void Function(
|
|||
|
||||
typedef transactions_refresh = Void Function();
|
||||
|
||||
typedef get_tx_key = Pointer<Utf8> Function(Pointer<Utf8> txId);
|
||||
typedef get_tx_key = Pointer<Utf8>? Function(Pointer<Utf8> txId);
|
||||
|
||||
typedef transactions_count = Int64 Function();
|
||||
|
||||
|
|
|
@ -3,9 +3,10 @@ import 'package:ffi/ffi.dart';
|
|||
|
||||
class AccountRow extends Struct {
|
||||
@Int64()
|
||||
int id;
|
||||
Pointer<Utf8> label;
|
||||
external int id;
|
||||
|
||||
external Pointer<Utf8> label;
|
||||
|
||||
String getLabel() => Utf8.fromUtf8(label);
|
||||
String getLabel() => label.toDartString();
|
||||
int getId() => id;
|
||||
}
|
||||
|
|
|
@ -3,9 +3,10 @@ import 'package:ffi/ffi.dart';
|
|||
|
||||
class HavenBalanceRow extends Struct {
|
||||
@Int64()
|
||||
int amount;
|
||||
Pointer<Utf8> assetType;
|
||||
external int amount;
|
||||
|
||||
external Pointer<Utf8> assetType;
|
||||
|
||||
int getAmount() => amount;
|
||||
String getAssetType() => Utf8.fromUtf8(assetType);
|
||||
String getAssetType() => assetType.toDartString();
|
||||
}
|
||||
|
|
|
@ -3,9 +3,10 @@ import 'package:ffi/ffi.dart';
|
|||
|
||||
class HavenRate extends Struct {
|
||||
@Int64()
|
||||
int rate;
|
||||
Pointer<Utf8> assetType;
|
||||
external int rate;
|
||||
|
||||
external Pointer<Utf8> assetType;
|
||||
|
||||
int getRate() => rate;
|
||||
String getAssetType() => Utf8.fromUtf8(assetType);
|
||||
String getAssetType() => assetType.toDartString();
|
||||
}
|
||||
|
|
|
@ -3,18 +3,22 @@ import 'package:ffi/ffi.dart';
|
|||
|
||||
class PendingTransactionRaw extends Struct {
|
||||
@Int64()
|
||||
int amount;
|
||||
external int amount;
|
||||
|
||||
@Int64()
|
||||
int fee;
|
||||
external int fee;
|
||||
|
||||
Pointer<Utf8> hash;
|
||||
external Pointer<Utf8> hash;
|
||||
|
||||
String getHash() => Utf8.fromUtf8(hash);
|
||||
String getHash() => hash.toDartString();
|
||||
}
|
||||
|
||||
class PendingTransactionDescription {
|
||||
PendingTransactionDescription({this.amount, this.fee, this.hash, this.pointerAddress});
|
||||
PendingTransactionDescription({
|
||||
required this.amount,
|
||||
required this.fee,
|
||||
required this.hash,
|
||||
required this.pointerAddress});
|
||||
|
||||
final int amount;
|
||||
final int fee;
|
||||
|
|
|
@ -3,11 +3,13 @@ import 'package:ffi/ffi.dart';
|
|||
|
||||
class SubaddressRow extends Struct {
|
||||
@Int64()
|
||||
int id;
|
||||
Pointer<Utf8> address;
|
||||
Pointer<Utf8> label;
|
||||
external int id;
|
||||
|
||||
external Pointer<Utf8> address;
|
||||
|
||||
external Pointer<Utf8> label;
|
||||
|
||||
String getLabel() => Utf8.fromUtf8(label);
|
||||
String getAddress() => Utf8.fromUtf8(address);
|
||||
String getLabel() => label.toDartString();
|
||||
String getAddress() => address.toDartString();
|
||||
int getId() => id;
|
||||
}
|
|
@ -3,42 +3,42 @@ import 'package:ffi/ffi.dart';
|
|||
|
||||
class TransactionInfoRow extends Struct {
|
||||
@Uint64()
|
||||
int amount;
|
||||
external int amount;
|
||||
|
||||
@Uint64()
|
||||
int fee;
|
||||
external int fee;
|
||||
|
||||
@Uint64()
|
||||
int blockHeight;
|
||||
external int blockHeight;
|
||||
|
||||
@Uint64()
|
||||
int confirmations;
|
||||
external int confirmations;
|
||||
|
||||
@Uint32()
|
||||
int subaddrAccount;
|
||||
external int subaddrAccount;
|
||||
|
||||
@Int8()
|
||||
int direction;
|
||||
external int direction;
|
||||
|
||||
@Int8()
|
||||
int isPending;
|
||||
external int isPending;
|
||||
|
||||
@Uint32()
|
||||
int subaddrIndex;
|
||||
external int subaddrIndex;
|
||||
|
||||
Pointer<Utf8> hash;
|
||||
external Pointer<Utf8> hash;
|
||||
|
||||
Pointer<Utf8> paymentId;
|
||||
external Pointer<Utf8> paymentId;
|
||||
|
||||
Pointer<Utf8> assetType;
|
||||
external Pointer<Utf8> assetType;
|
||||
|
||||
@Int64()
|
||||
int datetime;
|
||||
external int datetime;
|
||||
|
||||
int getDatetime() => datetime;
|
||||
int getAmount() => amount >= 0 ? amount : amount * -1;
|
||||
bool getIsPending() => isPending != 0;
|
||||
String getHash() => Utf8.fromUtf8(hash);
|
||||
String getPaymentId() => Utf8.fromUtf8(paymentId);
|
||||
String getAssetType() => Utf8.fromUtf8(assetType);
|
||||
String getHash() => hash.toDartString();
|
||||
String getPaymentId() => paymentId.toDartString();
|
||||
String getAssetType() => assetType.toDartString();
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ import 'dart:ffi';
|
|||
import 'package:ffi/ffi.dart';
|
||||
|
||||
class Utf8Box extends Struct {
|
||||
Pointer<Utf8> value;
|
||||
external Pointer<Utf8> value;
|
||||
|
||||
String getValue() => Utf8.fromUtf8(value);
|
||||
String getValue() => value.toDartString();
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ final subaddrressSetLabelNative = havenApi
|
|||
|
||||
bool isUpdating = false;
|
||||
|
||||
void refreshSubaddresses({@required int accountIndex}) {
|
||||
void refreshSubaddresses({required int accountIndex}) {
|
||||
try {
|
||||
isUpdating = true;
|
||||
subaddressRefreshNative(accountIndex);
|
||||
|
@ -50,18 +50,18 @@ List<SubaddressRow> getAllSubaddresses() {
|
|||
.toList();
|
||||
}
|
||||
|
||||
void addSubaddressSync({int accountIndex, String label}) {
|
||||
final labelPointer = Utf8.toUtf8(label);
|
||||
void addSubaddressSync({required int accountIndex, required String label}) {
|
||||
final labelPointer = label.toNativeUtf8();
|
||||
subaddrressAddNewNative(accountIndex, labelPointer);
|
||||
free(labelPointer);
|
||||
calloc.free(labelPointer);
|
||||
}
|
||||
|
||||
void setLabelForSubaddressSync(
|
||||
{int accountIndex, int addressIndex, String label}) {
|
||||
final labelPointer = Utf8.toUtf8(label);
|
||||
{required int accountIndex, required int addressIndex, required String label}) {
|
||||
final labelPointer = label.toNativeUtf8();
|
||||
|
||||
subaddrressSetLabelNative(accountIndex, addressIndex, labelPointer);
|
||||
free(labelPointer);
|
||||
calloc.free(labelPointer);
|
||||
}
|
||||
|
||||
void _addSubaddress(Map<String, dynamic> args) {
|
||||
|
@ -80,14 +80,14 @@ void _setLabelForSubaddress(Map<String, dynamic> args) {
|
|||
accountIndex: accountIndex, addressIndex: addressIndex, label: label);
|
||||
}
|
||||
|
||||
Future addSubaddress({int accountIndex, String label}) async {
|
||||
Future addSubaddress({required int accountIndex, required String label}) async {
|
||||
await compute<Map<String, Object>, void>(
|
||||
_addSubaddress, {'accountIndex': accountIndex, 'label': label});
|
||||
await store();
|
||||
}
|
||||
|
||||
Future setLabelForSubaddress(
|
||||
{int accountIndex, int addressIndex, String label}) async {
|
||||
{required int accountIndex, required int addressIndex, required String label}) async {
|
||||
await compute<Map<String, Object>, void>(_setLabelForSubaddress, {
|
||||
'accountIndex': accountIndex,
|
||||
'addressIndex': addressIndex,
|
||||
|
|
|
@ -40,16 +40,16 @@ final getTxKeyNative = havenApi
|
|||
.asFunction<GetTxKey>();
|
||||
|
||||
String getTxKey(String txId) {
|
||||
final txIdPointer = Utf8.toUtf8(txId);
|
||||
final txIdPointer = txId.toNativeUtf8();
|
||||
final keyPointer = getTxKeyNative(txIdPointer);
|
||||
|
||||
free(txIdPointer);
|
||||
calloc.free(txIdPointer);
|
||||
|
||||
if (keyPointer != null) {
|
||||
return convertUTF8ToString(pointer: keyPointer);
|
||||
}
|
||||
|
||||
return null;
|
||||
return '';
|
||||
}
|
||||
|
||||
void refreshTransactions() => transactionsRefreshNative();
|
||||
|
@ -67,18 +67,18 @@ List<TransactionInfoRow> getAllTransations() {
|
|||
}
|
||||
|
||||
PendingTransactionDescription createTransactionSync(
|
||||
{String address,
|
||||
String assetType,
|
||||
String paymentId,
|
||||
String amount,
|
||||
int priorityRaw,
|
||||
{required String address,
|
||||
required String assetType,
|
||||
required String paymentId,
|
||||
required int priorityRaw,
|
||||
String? amount,
|
||||
int accountIndex = 0}) {
|
||||
final addressPointer = Utf8.toUtf8(address);
|
||||
final assetTypePointer = Utf8.toUtf8(assetType);
|
||||
final paymentIdPointer = Utf8.toUtf8(paymentId);
|
||||
final amountPointer = amount != null ? Utf8.toUtf8(amount) : nullptr;
|
||||
final errorMessagePointer = allocate<Utf8Box>();
|
||||
final pendingTransactionRawPointer = allocate<PendingTransactionRaw>();
|
||||
final addressPointer = address.toNativeUtf8();
|
||||
final assetTypePointer = assetType.toNativeUtf8();
|
||||
final paymentIdPointer = paymentId.toNativeUtf8();
|
||||
final amountPointer = amount != null ? amount.toNativeUtf8() : nullptr;
|
||||
final errorMessagePointer = calloc<Utf8Box>();
|
||||
final pendingTransactionRawPointer = calloc<PendingTransactionRaw>();
|
||||
final created = transactionCreateNative(
|
||||
addressPointer,
|
||||
assetTypePointer,
|
||||
|
@ -90,17 +90,17 @@ PendingTransactionDescription createTransactionSync(
|
|||
pendingTransactionRawPointer) !=
|
||||
0;
|
||||
|
||||
free(addressPointer);
|
||||
free(assetTypePointer);
|
||||
free(paymentIdPointer);
|
||||
calloc.free(addressPointer);
|
||||
calloc.free(assetTypePointer);
|
||||
calloc.free(paymentIdPointer);
|
||||
|
||||
if (amountPointer != nullptr) {
|
||||
free(amountPointer);
|
||||
calloc.free(amountPointer);
|
||||
}
|
||||
|
||||
if (!created) {
|
||||
final message = errorMessagePointer.ref.getValue();
|
||||
free(errorMessagePointer);
|
||||
calloc.free(errorMessagePointer);
|
||||
throw CreationTransactionException(message: message);
|
||||
}
|
||||
|
||||
|
@ -112,28 +112,28 @@ PendingTransactionDescription createTransactionSync(
|
|||
}
|
||||
|
||||
PendingTransactionDescription createTransactionMultDestSync(
|
||||
{List<MoneroOutput> outputs,
|
||||
String assetType,
|
||||
String paymentId,
|
||||
int priorityRaw,
|
||||
{required List<MoneroOutput> outputs,
|
||||
required String assetType,
|
||||
required String paymentId,
|
||||
required int priorityRaw,
|
||||
int accountIndex = 0}) {
|
||||
final int size = outputs.length;
|
||||
final List<Pointer<Utf8>> addressesPointers = outputs.map((output) =>
|
||||
Utf8.toUtf8(output.address)).toList();
|
||||
final Pointer<Pointer<Utf8>> addressesPointerPointer = allocate(count: size);
|
||||
output.address.toNativeUtf8()).toList();
|
||||
final Pointer<Pointer<Utf8>> addressesPointerPointer = calloc(size);
|
||||
final List<Pointer<Utf8>> amountsPointers = outputs.map((output) =>
|
||||
Utf8.toUtf8(output.amount)).toList();
|
||||
final Pointer<Pointer<Utf8>> amountsPointerPointer = allocate(count: size);
|
||||
output.amount.toNativeUtf8()).toList();
|
||||
final Pointer<Pointer<Utf8>> amountsPointerPointer = calloc( size);
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
addressesPointerPointer[i] = addressesPointers[i];
|
||||
amountsPointerPointer[i] = amountsPointers[i];
|
||||
}
|
||||
|
||||
final assetTypePointer = Utf8.toUtf8(assetType);
|
||||
final paymentIdPointer = Utf8.toUtf8(paymentId);
|
||||
final errorMessagePointer = allocate<Utf8Box>();
|
||||
final pendingTransactionRawPointer = allocate<PendingTransactionRaw>();
|
||||
final assetTypePointer = assetType.toNativeUtf8();
|
||||
final paymentIdPointer = paymentId.toNativeUtf8();
|
||||
final errorMessagePointer = calloc<Utf8Box>();
|
||||
final pendingTransactionRawPointer = calloc<PendingTransactionRaw>();
|
||||
final created = transactionCreateMultDestNative(
|
||||
addressesPointerPointer,
|
||||
assetTypePointer,
|
||||
|
@ -146,18 +146,18 @@ PendingTransactionDescription createTransactionMultDestSync(
|
|||
pendingTransactionRawPointer) !=
|
||||
0;
|
||||
|
||||
free(addressesPointerPointer);
|
||||
free(assetTypePointer);
|
||||
free(amountsPointerPointer);
|
||||
calloc.free(addressesPointerPointer);
|
||||
calloc.free(assetTypePointer);
|
||||
calloc.free(amountsPointerPointer);
|
||||
|
||||
addressesPointers.forEach((element) => free(element));
|
||||
amountsPointers.forEach((element) => free(element));
|
||||
addressesPointers.forEach((element) => calloc.free(element));
|
||||
amountsPointers.forEach((element) => calloc.free(element));
|
||||
|
||||
free(paymentIdPointer);
|
||||
calloc.free(paymentIdPointer);
|
||||
|
||||
if (!created) {
|
||||
final message = errorMessagePointer.ref.getValue();
|
||||
free(errorMessagePointer);
|
||||
calloc.free(errorMessagePointer);
|
||||
throw CreationTransactionException(message: message);
|
||||
}
|
||||
|
||||
|
@ -168,17 +168,17 @@ PendingTransactionDescription createTransactionMultDestSync(
|
|||
pointerAddress: pendingTransactionRawPointer.address);
|
||||
}
|
||||
|
||||
void commitTransactionFromPointerAddress({int address}) => commitTransaction(
|
||||
void commitTransactionFromPointerAddress({required int address}) => commitTransaction(
|
||||
transactionPointer: Pointer<PendingTransactionRaw>.fromAddress(address));
|
||||
|
||||
void commitTransaction({Pointer<PendingTransactionRaw> transactionPointer}) {
|
||||
final errorMessagePointer = allocate<Utf8Box>();
|
||||
void commitTransaction({required Pointer<PendingTransactionRaw> transactionPointer}) {
|
||||
final errorMessagePointer = calloc<Utf8Box>();
|
||||
final isCommited =
|
||||
transactionCommitNative(transactionPointer, errorMessagePointer) != 0;
|
||||
|
||||
if (!isCommited) {
|
||||
final message = errorMessagePointer.ref.getValue();
|
||||
free(errorMessagePointer);
|
||||
calloc.free(errorMessagePointer);
|
||||
throw CreationTransactionException(message: message);
|
||||
}
|
||||
}
|
||||
|
@ -216,11 +216,11 @@ PendingTransactionDescription _createTransactionMultDestSync(Map args) {
|
|||
}
|
||||
|
||||
Future<PendingTransactionDescription> createTransaction(
|
||||
{String address,
|
||||
String assetType,
|
||||
{required String address,
|
||||
required String assetType,
|
||||
required int priorityRaw,
|
||||
String? amount,
|
||||
String paymentId = '',
|
||||
String amount,
|
||||
int priorityRaw,
|
||||
int accountIndex = 0}) =>
|
||||
compute(_createTransactionSync, {
|
||||
'address': address,
|
||||
|
@ -232,10 +232,10 @@ Future<PendingTransactionDescription> createTransaction(
|
|||
});
|
||||
|
||||
Future<PendingTransactionDescription> createTransactionMultDest(
|
||||
{List<MoneroOutput> outputs,
|
||||
String assetType,
|
||||
{required List<MoneroOutput> outputs,
|
||||
required int priorityRaw,
|
||||
String? assetType,
|
||||
String paymentId = '',
|
||||
int priorityRaw,
|
||||
int accountIndex = 0}) =>
|
||||
compute(_createTransactionMultDestSync, {
|
||||
'outputs': outputs,
|
||||
|
|
|
@ -39,7 +39,7 @@ typedef GetNodeHeight = int Function();
|
|||
typedef IsConnected = int Function();
|
||||
|
||||
typedef SetupNode = int Function(
|
||||
Pointer<Utf8>, Pointer<Utf8>, Pointer<Utf8>, int, int, Pointer<Utf8>);
|
||||
Pointer<Utf8>, Pointer<Utf8>?, Pointer<Utf8>?, int, int, Pointer<Utf8>);
|
||||
|
||||
typedef StartRefresh = void Function();
|
||||
|
||||
|
@ -84,7 +84,7 @@ typedef AccountSetLabel = void Function(int accountIndex, Pointer<Utf8> label);
|
|||
|
||||
typedef TransactionsRefresh = void Function();
|
||||
|
||||
typedef GetTxKey = Pointer<Utf8> Function(Pointer<Utf8> txId);
|
||||
typedef GetTxKey = Pointer<Utf8>? Function(Pointer<Utf8> txId);
|
||||
|
||||
typedef TransactionsCount = int Function();
|
||||
|
||||
|
|
|
@ -150,24 +150,24 @@ int getNodeHeightSync() => getNodeHeightNative();
|
|||
bool isConnectedSync() => isConnectedNative() != 0;
|
||||
|
||||
bool setupNodeSync(
|
||||
{String address,
|
||||
String login,
|
||||
String password,
|
||||
{required String address,
|
||||
String? login,
|
||||
String? password,
|
||||
bool useSSL = false,
|
||||
bool isLightWallet = false}) {
|
||||
final addressPointer = Utf8.toUtf8(address);
|
||||
Pointer<Utf8> loginPointer;
|
||||
Pointer<Utf8> passwordPointer;
|
||||
final addressPointer = address.toNativeUtf8();
|
||||
Pointer<Utf8>? loginPointer;
|
||||
Pointer<Utf8>? passwordPointer;
|
||||
|
||||
if (login != null) {
|
||||
loginPointer = Utf8.toUtf8(login);
|
||||
loginPointer = login.toNativeUtf8();
|
||||
}
|
||||
|
||||
if (password != null) {
|
||||
passwordPointer = Utf8.toUtf8(password);
|
||||
passwordPointer = password.toNativeUtf8();
|
||||
}
|
||||
|
||||
final errorMessagePointer = allocate<Utf8>();
|
||||
final errorMessagePointer = ''.toNativeUtf8();
|
||||
final isSetupNode = setupNodeNative(
|
||||
addressPointer,
|
||||
loginPointer,
|
||||
|
@ -177,9 +177,15 @@ bool setupNodeSync(
|
|||
errorMessagePointer) !=
|
||||
0;
|
||||
|
||||
free(addressPointer);
|
||||
free(loginPointer);
|
||||
free(passwordPointer);
|
||||
calloc.free(addressPointer);
|
||||
|
||||
if (loginPointer != null) {
|
||||
calloc.free(loginPointer);
|
||||
}
|
||||
|
||||
if (passwordPointer != null) {
|
||||
calloc.free(passwordPointer);
|
||||
}
|
||||
|
||||
if (!isSetupNode) {
|
||||
throw SetupWalletException(
|
||||
|
@ -193,31 +199,31 @@ void startRefreshSync() => startRefreshNative();
|
|||
|
||||
Future<bool> connectToNode() async => connecToNodeNative() != 0;
|
||||
|
||||
void setRefreshFromBlockHeight({int height}) =>
|
||||
void setRefreshFromBlockHeight({required int height}) =>
|
||||
setRefreshFromBlockHeightNative(height);
|
||||
|
||||
void setRecoveringFromSeed({bool isRecovery}) =>
|
||||
void setRecoveringFromSeed({required bool isRecovery}) =>
|
||||
setRecoveringFromSeedNative(_boolToInt(isRecovery));
|
||||
|
||||
void storeSync() {
|
||||
final pathPointer = Utf8.toUtf8('');
|
||||
final pathPointer = ''.toNativeUtf8();
|
||||
storeNative(pathPointer);
|
||||
free(pathPointer);
|
||||
calloc.free(pathPointer);
|
||||
}
|
||||
|
||||
void setPasswordSync(String password) {
|
||||
final passwordPointer = Utf8.toUtf8(password);
|
||||
final errorMessagePointer = allocate<Utf8Box>();
|
||||
final passwordPointer = password.toNativeUtf8();
|
||||
final errorMessagePointer = calloc<Utf8Box>();
|
||||
final changed = setPasswordNative(passwordPointer, errorMessagePointer) != 0;
|
||||
free(passwordPointer);
|
||||
calloc.free(passwordPointer);
|
||||
|
||||
if (!changed) {
|
||||
final message = errorMessagePointer.ref.getValue();
|
||||
free(errorMessagePointer);
|
||||
calloc.free(errorMessagePointer);
|
||||
throw Exception(message);
|
||||
}
|
||||
|
||||
free(errorMessagePointer);
|
||||
calloc.free(errorMessagePointer);
|
||||
}
|
||||
|
||||
void closeCurrentWallet() => closeCurrentWalletNative();
|
||||
|
@ -235,16 +241,15 @@ String getPublicSpendKey() =>
|
|||
convertUTF8ToString(pointer: getPublicSpendKeyNative());
|
||||
|
||||
class SyncListener {
|
||||
SyncListener(this.onNewBlock, this.onNewTransaction) {
|
||||
_cachedBlockchainHeight = 0;
|
||||
_lastKnownBlockHeight = 0;
|
||||
_initialSyncHeight = 0;
|
||||
}
|
||||
SyncListener(this.onNewBlock, this.onNewTransaction)
|
||||
: _cachedBlockchainHeight = 0,
|
||||
_lastKnownBlockHeight = 0,
|
||||
_initialSyncHeight = 0;
|
||||
|
||||
void Function(int, int, double) onNewBlock;
|
||||
void Function() onNewTransaction;
|
||||
|
||||
Timer _updateSyncInfoTimer;
|
||||
Timer? _updateSyncInfoTimer;
|
||||
int _cachedBlockchainHeight;
|
||||
int _lastKnownBlockHeight;
|
||||
int _initialSyncHeight;
|
||||
|
@ -333,13 +338,13 @@ int _getNodeHeight(Object _) => getNodeHeightSync();
|
|||
|
||||
void startRefresh() => startRefreshSync();
|
||||
|
||||
Future setupNode(
|
||||
{String address,
|
||||
String login,
|
||||
String password,
|
||||
Future<void> setupNode(
|
||||
{required String address,
|
||||
String? login,
|
||||
String? password,
|
||||
bool useSSL = false,
|
||||
bool isLightWallet = false}) =>
|
||||
compute<Map<String, Object>, void>(_setupNodeSync, {
|
||||
compute<Map<String, Object?>, void>(_setupNodeSync, {
|
||||
'address': address,
|
||||
'login': login,
|
||||
'password': password,
|
||||
|
@ -347,7 +352,7 @@ Future setupNode(
|
|||
'isLightWallet': isLightWallet
|
||||
});
|
||||
|
||||
Future store() => compute<int, void>(_storeSync, 0);
|
||||
Future<void> store() => compute<int, void>(_storeSync, 0);
|
||||
|
||||
Future<bool> isConnected() => compute(_isConnected, 0);
|
||||
|
||||
|
|
|
@ -38,18 +38,18 @@ final errorStringNative = havenApi
|
|||
.asFunction<ErrorString>();
|
||||
|
||||
void createWalletSync(
|
||||
{String path, String password, String language, int nettype = 0}) {
|
||||
final pathPointer = Utf8.toUtf8(path);
|
||||
final passwordPointer = Utf8.toUtf8(password);
|
||||
final languagePointer = Utf8.toUtf8(language);
|
||||
final errorMessagePointer = allocate<Utf8>();
|
||||
{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();
|
||||
final isWalletCreated = createWalletNative(pathPointer, passwordPointer,
|
||||
languagePointer, nettype, errorMessagePointer) !=
|
||||
0;
|
||||
|
||||
free(pathPointer);
|
||||
free(passwordPointer);
|
||||
free(languagePointer);
|
||||
calloc.free(pathPointer);
|
||||
calloc.free(passwordPointer);
|
||||
calloc.free(languagePointer);
|
||||
|
||||
if (!isWalletCreated) {
|
||||
throw WalletCreationException(
|
||||
|
@ -59,25 +59,25 @@ void createWalletSync(
|
|||
// setupNodeSync(address: "node.moneroworld.com:18089");
|
||||
}
|
||||
|
||||
bool isWalletExistSync({String path}) {
|
||||
final pathPointer = Utf8.toUtf8(path);
|
||||
bool isWalletExistSync({required String path}) {
|
||||
final pathPointer = path.toNativeUtf8();
|
||||
final isExist = isWalletExistNative(pathPointer) != 0;
|
||||
|
||||
free(pathPointer);
|
||||
calloc.free(pathPointer);
|
||||
|
||||
return isExist;
|
||||
}
|
||||
|
||||
void restoreWalletFromSeedSync(
|
||||
{String path,
|
||||
String password,
|
||||
String seed,
|
||||
{required String path,
|
||||
required String password,
|
||||
required String seed,
|
||||
int nettype = 0,
|
||||
int restoreHeight = 0}) {
|
||||
final pathPointer = Utf8.toUtf8(path);
|
||||
final passwordPointer = Utf8.toUtf8(password);
|
||||
final seedPointer = Utf8.toUtf8(seed);
|
||||
final errorMessagePointer = allocate<Utf8>();
|
||||
final pathPointer = path.toNativeUtf8();
|
||||
final passwordPointer = password.toNativeUtf8();
|
||||
final seedPointer = seed.toNativeUtf8();
|
||||
final errorMessagePointer = ''.toNativeUtf8();
|
||||
final isWalletRestored = restoreWalletFromSeedNative(
|
||||
pathPointer,
|
||||
passwordPointer,
|
||||
|
@ -87,9 +87,9 @@ void restoreWalletFromSeedSync(
|
|||
errorMessagePointer) !=
|
||||
0;
|
||||
|
||||
free(pathPointer);
|
||||
free(passwordPointer);
|
||||
free(seedPointer);
|
||||
calloc.free(pathPointer);
|
||||
calloc.free(passwordPointer);
|
||||
calloc.free(seedPointer);
|
||||
|
||||
if (!isWalletRestored) {
|
||||
throw WalletRestoreFromSeedException(
|
||||
|
@ -98,21 +98,21 @@ void restoreWalletFromSeedSync(
|
|||
}
|
||||
|
||||
void restoreWalletFromKeysSync(
|
||||
{String path,
|
||||
String password,
|
||||
String language,
|
||||
String address,
|
||||
String viewKey,
|
||||
String spendKey,
|
||||
{required String path,
|
||||
required String password,
|
||||
required String language,
|
||||
required String address,
|
||||
required String viewKey,
|
||||
required String spendKey,
|
||||
int nettype = 0,
|
||||
int restoreHeight = 0}) {
|
||||
final pathPointer = Utf8.toUtf8(path);
|
||||
final passwordPointer = Utf8.toUtf8(password);
|
||||
final languagePointer = Utf8.toUtf8(language);
|
||||
final addressPointer = Utf8.toUtf8(address);
|
||||
final viewKeyPointer = Utf8.toUtf8(viewKey);
|
||||
final spendKeyPointer = Utf8.toUtf8(spendKey);
|
||||
final errorMessagePointer = allocate<Utf8>();
|
||||
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();
|
||||
final isWalletRestored = restoreWalletFromKeysNative(
|
||||
pathPointer,
|
||||
passwordPointer,
|
||||
|
@ -125,12 +125,12 @@ void restoreWalletFromKeysSync(
|
|||
errorMessagePointer) !=
|
||||
0;
|
||||
|
||||
free(pathPointer);
|
||||
free(passwordPointer);
|
||||
free(languagePointer);
|
||||
free(addressPointer);
|
||||
free(viewKeyPointer);
|
||||
free(spendKeyPointer);
|
||||
calloc.free(pathPointer);
|
||||
calloc.free(passwordPointer);
|
||||
calloc.free(languagePointer);
|
||||
calloc.free(addressPointer);
|
||||
calloc.free(viewKeyPointer);
|
||||
calloc.free(spendKeyPointer);
|
||||
|
||||
if (!isWalletRestored) {
|
||||
throw WalletRestoreFromKeysException(
|
||||
|
@ -138,12 +138,12 @@ void restoreWalletFromKeysSync(
|
|||
}
|
||||
}
|
||||
|
||||
void loadWallet({String path, String password, int nettype = 0}) {
|
||||
final pathPointer = Utf8.toUtf8(path);
|
||||
final passwordPointer = Utf8.toUtf8(password);
|
||||
void loadWallet({required String path, required String password, int nettype = 0}) {
|
||||
final pathPointer = path.toNativeUtf8();
|
||||
final passwordPointer = password.toNativeUtf8();
|
||||
final loaded = loadWalletNative(pathPointer, passwordPointer, nettype) != 0;
|
||||
free(pathPointer);
|
||||
free(passwordPointer);
|
||||
calloc.free(pathPointer);
|
||||
calloc.free(passwordPointer);
|
||||
|
||||
if (!loaded) {
|
||||
throw WalletOpeningException(
|
||||
|
@ -189,20 +189,20 @@ void _restoreFromKeys(Map<String, dynamic> args) {
|
|||
}
|
||||
|
||||
Future<void> _openWallet(Map<String, String> args) async =>
|
||||
loadWallet(path: args['path'], password: args['password']);
|
||||
loadWallet(path: args['path'] as String, password: args['password'] as String);
|
||||
|
||||
bool _isWalletExist(String path) => isWalletExistSync(path: path);
|
||||
|
||||
void openWallet({String path, String password, int nettype = 0}) async =>
|
||||
void openWallet({required String path, required String password, int nettype = 0}) async =>
|
||||
loadWallet(path: path, password: password, nettype: nettype);
|
||||
|
||||
Future<void> openWalletAsync(Map<String, String> args) async =>
|
||||
compute(_openWallet, args);
|
||||
|
||||
Future<void> createWallet(
|
||||
{String path,
|
||||
String password,
|
||||
String language,
|
||||
{required String path,
|
||||
required String password,
|
||||
required String language,
|
||||
int nettype = 0}) async =>
|
||||
compute(_createWallet, {
|
||||
'path': path,
|
||||
|
@ -211,10 +211,10 @@ Future<void> createWallet(
|
|||
'nettype': nettype
|
||||
});
|
||||
|
||||
Future restoreFromSeed(
|
||||
{String path,
|
||||
String password,
|
||||
String seed,
|
||||
Future<void> restoreFromSeed(
|
||||
{required String path,
|
||||
required String password,
|
||||
required String seed,
|
||||
int nettype = 0,
|
||||
int restoreHeight = 0}) async =>
|
||||
compute<Map<String, Object>, void>(_restoreFromSeed, {
|
||||
|
@ -225,13 +225,13 @@ Future restoreFromSeed(
|
|||
'restoreHeight': restoreHeight
|
||||
});
|
||||
|
||||
Future restoreFromKeys(
|
||||
{String path,
|
||||
String password,
|
||||
String language,
|
||||
String address,
|
||||
String viewKey,
|
||||
String spendKey,
|
||||
Future<void> restoreFromKeys(
|
||||
{required String path,
|
||||
required String password,
|
||||
required String language,
|
||||
required String address,
|
||||
required String viewKey,
|
||||
required String spendKey,
|
||||
int nettype = 0,
|
||||
int restoreHeight = 0}) async =>
|
||||
compute<Map<String, Object>, void>(_restoreFromKeys, {
|
||||
|
@ -245,4 +245,4 @@ Future restoreFromKeys(
|
|||
'restoreHeight': restoreHeight
|
||||
});
|
||||
|
||||
Future<bool> isWalletExist({String path}) => compute(_isWalletExist, path);
|
||||
Future<bool> isWalletExist({required String path}) => compute(_isWalletExist, path);
|
||||
|
|
|
@ -53,13 +53,13 @@ abstract class HavenAccountListBase extends AccountList<Account> with Store {
|
|||
.toList();
|
||||
|
||||
@override
|
||||
Future addAccount({String label}) async {
|
||||
Future<void> addAccount({required String label}) async {
|
||||
await account_list.addAccount(label: label);
|
||||
update();
|
||||
}
|
||||
|
||||
@override
|
||||
Future setLabelAccount({int accountIndex, String label}) async {
|
||||
Future<void> setLabelAccount({required int accountIndex, required String label}) async {
|
||||
await account_list.setLabelForAccount(
|
||||
accountIndex: accountIndex, label: label);
|
||||
update();
|
||||
|
|
|
@ -9,7 +9,7 @@ const inactiveBalances = [
|
|||
CryptoCurrency.xnok,
|
||||
CryptoCurrency.xnzd];
|
||||
|
||||
Map<CryptoCurrency, MoneroBalance> getHavenBalance({int accountIndex}) {
|
||||
Map<CryptoCurrency, MoneroBalance> getHavenBalance({required int accountIndex}) {
|
||||
final fullBalances = getHavenFullBalance(accountIndex: accountIndex);
|
||||
final unlockedBalances = getHavenUnlockedBalance(accountIndex: accountIndex);
|
||||
final havenBalances = <CryptoCurrency, MoneroBalance>{};
|
||||
|
|
|
@ -10,11 +10,10 @@ class HavenSubaddressList = HavenSubaddressListBase
|
|||
with _$HavenSubaddressList;
|
||||
|
||||
abstract class HavenSubaddressListBase with Store {
|
||||
HavenSubaddressListBase() {
|
||||
_isRefreshing = false;
|
||||
_isUpdating = false;
|
||||
HavenSubaddressListBase()
|
||||
: _isRefreshing = false,
|
||||
_isUpdating = false,
|
||||
subaddresses = ObservableList<Subaddress>();
|
||||
}
|
||||
|
||||
@observable
|
||||
ObservableList<Subaddress> subaddresses;
|
||||
|
@ -22,7 +21,7 @@ abstract class HavenSubaddressListBase with Store {
|
|||
bool _isRefreshing;
|
||||
bool _isUpdating;
|
||||
|
||||
void update({int accountIndex}) {
|
||||
void update({required int accountIndex}) {
|
||||
if (_isUpdating) {
|
||||
return;
|
||||
}
|
||||
|
@ -56,20 +55,20 @@ abstract class HavenSubaddressListBase with Store {
|
|||
.toList();
|
||||
}
|
||||
|
||||
Future addSubaddress({int accountIndex, String label}) async {
|
||||
Future<void> addSubaddress({required int accountIndex, required String label}) async {
|
||||
await subaddress_list.addSubaddress(
|
||||
accountIndex: accountIndex, label: label);
|
||||
update(accountIndex: accountIndex);
|
||||
}
|
||||
|
||||
Future setLabelSubaddress(
|
||||
{int accountIndex, int addressIndex, String label}) async {
|
||||
Future<void> setLabelSubaddress(
|
||||
{required int accountIndex, required int addressIndex, required String label}) async {
|
||||
await subaddress_list.setLabelForSubaddress(
|
||||
accountIndex: accountIndex, addressIndex: addressIndex, label: label);
|
||||
update(accountIndex: accountIndex);
|
||||
}
|
||||
|
||||
void refresh({int accountIndex}) {
|
||||
void refresh({required int accountIndex}) {
|
||||
if (_isRefreshing) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,10 @@ import 'package:cw_core/monero_transaction_priority.dart';
|
|||
import 'package:cw_core/output_info.dart';
|
||||
|
||||
class HavenTransactionCreationCredentials {
|
||||
HavenTransactionCreationCredentials({this.outputs, this.priority, this.assetType});
|
||||
HavenTransactionCreationCredentials({
|
||||
required this.outputs,
|
||||
required this.priority,
|
||||
required this.assetType});
|
||||
|
||||
final List<OutputInfo> outputs;
|
||||
final MoneroTransactionPriority priority;
|
||||
|
|
|
@ -10,20 +10,20 @@ class HavenTransactionInfo extends TransactionInfo {
|
|||
HavenTransactionInfo(this.id, this.height, this.direction, this.date,
|
||||
this.isPending, this.amount, this.accountIndex, this.addressIndex, this.fee);
|
||||
|
||||
HavenTransactionInfo.fromMap(Map map)
|
||||
HavenTransactionInfo.fromMap(Map<String, Object> map)
|
||||
: id = (map['hash'] ?? '') as String,
|
||||
height = (map['height'] ?? 0) as int,
|
||||
direction =
|
||||
parseTransactionDirectionFromNumber(map['direction'] as String) ??
|
||||
TransactionDirection.incoming,
|
||||
date = DateTime.fromMillisecondsSinceEpoch(
|
||||
(int.parse(map['timestamp'] as String) ?? 0) * 1000),
|
||||
int.parse(map['timestamp'] as String? ?? '0') * 1000),
|
||||
isPending = parseBoolFromString(map['isPending'] as String),
|
||||
amount = map['amount'] as int,
|
||||
accountIndex = int.parse(map['accountIndex'] as String),
|
||||
addressIndex = map['addressIndex'] as int,
|
||||
key = getTxKey((map['hash'] ?? '') as String),
|
||||
fee = map['fee'] as int ?? 0;
|
||||
fee = map['fee'] as int? ?? 0;
|
||||
|
||||
HavenTransactionInfo.fromRow(TransactionInfoRow row)
|
||||
: id = row.getHash(),
|
||||
|
@ -48,11 +48,10 @@ class HavenTransactionInfo extends TransactionInfo {
|
|||
final int amount;
|
||||
final int fee;
|
||||
final int addressIndex;
|
||||
String recipientAddress;
|
||||
String key;
|
||||
String assetType;
|
||||
|
||||
String _fiatAmount;
|
||||
late String recipientAddress;
|
||||
late String assetType;
|
||||
String? _fiatAmount;
|
||||
String? key;
|
||||
|
||||
@override
|
||||
String amountFormatted() =>
|
||||
|
|
|
@ -37,15 +37,19 @@ class HavenWallet = HavenWalletBase with _$HavenWallet;
|
|||
|
||||
abstract class HavenWalletBase extends WalletBase<MoneroBalance,
|
||||
HavenTransactionHistory, HavenTransactionInfo> with Store {
|
||||
HavenWalletBase({WalletInfo walletInfo})
|
||||
: super(walletInfo) {
|
||||
HavenWalletBase({required WalletInfo walletInfo})
|
||||
: balance = ObservableMap.of(getHavenBalance(accountIndex: 0)),
|
||||
_isTransactionUpdating = false,
|
||||
_hasSyncAfterStartup = false,
|
||||
walletAddresses = HavenWalletAddresses(walletInfo),
|
||||
syncStatus = NotConnectedSyncStatus(),
|
||||
super(walletInfo) {
|
||||
transactionHistory = HavenTransactionHistory();
|
||||
balance = ObservableMap.of(getHavenBalance(accountIndex: 0));
|
||||
_isTransactionUpdating = false;
|
||||
_hasSyncAfterStartup = false;
|
||||
walletAddresses = HavenWalletAddresses(walletInfo);
|
||||
_onAccountChangeReaction = reaction((_) => walletAddresses.account,
|
||||
(Account account) {
|
||||
(Account? account) {
|
||||
if (account == null) {
|
||||
return;
|
||||
}
|
||||
balance.addAll(getHavenBalance(accountIndex: account.id));
|
||||
walletAddresses.updateSubaddressList(accountIndex: account.id);
|
||||
});
|
||||
|
@ -74,15 +78,15 @@ abstract class HavenWalletBase extends WalletBase<MoneroBalance,
|
|||
publicSpendKey: haven_wallet.getPublicSpendKey(),
|
||||
publicViewKey: haven_wallet.getPublicViewKey());
|
||||
|
||||
haven_wallet.SyncListener _listener;
|
||||
ReactionDisposer _onAccountChangeReaction;
|
||||
haven_wallet.SyncListener? _listener;
|
||||
ReactionDisposer? _onAccountChangeReaction;
|
||||
bool _isTransactionUpdating;
|
||||
bool _hasSyncAfterStartup;
|
||||
Timer _autoSaveTimer;
|
||||
Timer? _autoSaveTimer;
|
||||
|
||||
Future<void> init() async {
|
||||
await walletAddresses.init();
|
||||
balance.addAll(getHavenBalance(accountIndex: walletAddresses.account.id ?? 0));
|
||||
balance.addAll(getHavenBalance(accountIndex: walletAddresses.account?.id ?? 0));
|
||||
_setListeners();
|
||||
await updateTransactions();
|
||||
|
||||
|
@ -103,19 +107,19 @@ abstract class HavenWalletBase extends WalletBase<MoneroBalance,
|
|||
@override
|
||||
void close() {
|
||||
_listener?.stop();
|
||||
_onAccountChangeReaction?.reaction?.dispose();
|
||||
_onAccountChangeReaction?.reaction.dispose();
|
||||
_autoSaveTimer?.cancel();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> connectToNode({@required Node node}) async {
|
||||
Future<void> connectToNode({required Node node}) async {
|
||||
try {
|
||||
syncStatus = ConnectingSyncStatus();
|
||||
await haven_wallet.setupNode(
|
||||
address: node.uriRaw,
|
||||
login: node.login,
|
||||
password: node.password,
|
||||
useSSL: node.useSSL,
|
||||
useSSL: node.useSSL ?? false,
|
||||
isLightWallet: false); // FIXME: hardcoded value
|
||||
syncStatus = ConnectedSyncStatus();
|
||||
} catch (e) {
|
||||
|
@ -148,8 +152,8 @@ abstract class HavenWalletBase extends WalletBase<MoneroBalance,
|
|||
final outputs = _credentials.outputs;
|
||||
final hasMultiDestination = outputs.length > 1;
|
||||
final assetType = CryptoCurrency.fromString(_credentials.assetType.toLowerCase());
|
||||
final balances = getHavenBalance(accountIndex: walletAddresses.account.id);
|
||||
final unlockedBalance = balances[assetType].unlockedBalance;
|
||||
final balances = getHavenBalance(accountIndex: walletAddresses.account!.id);
|
||||
final unlockedBalance = balances[assetType]!.unlockedBalance;
|
||||
|
||||
PendingTransactionDescription pendingTransactionDescription;
|
||||
|
||||
|
@ -159,12 +163,12 @@ abstract class HavenWalletBase extends WalletBase<MoneroBalance,
|
|||
|
||||
if (hasMultiDestination) {
|
||||
if (outputs.any((item) => item.sendAll
|
||||
|| item.formattedCryptoAmount <= 0)) {
|
||||
|| (item.formattedCryptoAmount ?? 0) <= 0)) {
|
||||
throw HavenTransactionCreationException('Wrong balance. Not enough XMR on your balance.');
|
||||
}
|
||||
|
||||
final int totalAmount = outputs.fold(0, (acc, value) =>
|
||||
acc + value.formattedCryptoAmount);
|
||||
acc + (value.formattedCryptoAmount ?? 0));
|
||||
|
||||
if (unlockedBalance < totalAmount) {
|
||||
throw HavenTransactionCreationException('Wrong balance. Not enough XMR on your balance.');
|
||||
|
@ -173,21 +177,21 @@ abstract class HavenWalletBase extends WalletBase<MoneroBalance,
|
|||
final moneroOutputs = outputs.map((output) =>
|
||||
MoneroOutput(
|
||||
address: output.address,
|
||||
amount: output.cryptoAmount.replaceAll(',', '.')))
|
||||
amount: output.cryptoAmount!.replaceAll(',', '.')))
|
||||
.toList();
|
||||
|
||||
pendingTransactionDescription =
|
||||
await transaction_history.createTransactionMultDest(
|
||||
outputs: moneroOutputs,
|
||||
priorityRaw: _credentials.priority.serialize(),
|
||||
accountIndex: walletAddresses.account.id);
|
||||
accountIndex: walletAddresses.account!.id);
|
||||
} else {
|
||||
final output = outputs.first;
|
||||
final address = output.address;
|
||||
final amount = output.sendAll
|
||||
? null
|
||||
: output.cryptoAmount.replaceAll(',', '.');
|
||||
final formattedAmount = output.sendAll
|
||||
: output.cryptoAmount!.replaceAll(',', '.');
|
||||
final int? formattedAmount = output.sendAll
|
||||
? null
|
||||
: output.formattedCryptoAmount;
|
||||
|
||||
|
@ -205,14 +209,14 @@ abstract class HavenWalletBase extends WalletBase<MoneroBalance,
|
|||
assetType: _credentials.assetType,
|
||||
amount: amount,
|
||||
priorityRaw: _credentials.priority.serialize(),
|
||||
accountIndex: walletAddresses.account.id);
|
||||
accountIndex: walletAddresses.account!.id);
|
||||
}
|
||||
|
||||
return PendingHavenTransaction(pendingTransactionDescription, assetType);
|
||||
}
|
||||
|
||||
@override
|
||||
int calculateEstimatedFee(TransactionPriority priority, int amount) {
|
||||
int calculateEstimatedFee(TransactionPriority priority, int? amount) {
|
||||
// FIXME: hardcoded value;
|
||||
|
||||
if (priority is MoneroTransactionPriority) {
|
||||
|
@ -255,7 +259,7 @@ abstract class HavenWalletBase extends WalletBase<MoneroBalance,
|
|||
}
|
||||
|
||||
@override
|
||||
Future<void> rescan({int height}) async {
|
||||
Future<void> rescan({required int height}) async {
|
||||
walletInfo.restoreHeight = height;
|
||||
walletInfo.isRecovery = true;
|
||||
haven_wallet.setRefreshFromBlockHeight(height: height);
|
||||
|
@ -346,7 +350,7 @@ abstract class HavenWalletBase extends WalletBase<MoneroBalance,
|
|||
}
|
||||
|
||||
void _askForUpdateBalance() =>
|
||||
balance.addAll(getHavenBalance(accountIndex: walletAddresses.account.id));
|
||||
balance.addAll(getHavenBalance(accountIndex: walletAddresses.account!.id));
|
||||
|
||||
Future<void> _askForUpdateTransactionHistory() async =>
|
||||
await updateTransactions();
|
||||
|
|
|
@ -12,21 +12,22 @@ class HavenWalletAddresses = HavenWalletAddressesBase
|
|||
with _$HavenWalletAddresses;
|
||||
|
||||
abstract class HavenWalletAddressesBase extends WalletAddressesWithAccount<Account> with Store {
|
||||
HavenWalletAddressesBase(WalletInfo walletInfo) : super(walletInfo) {
|
||||
accountList = HavenAccountList();
|
||||
subaddressList = HavenSubaddressList();
|
||||
}
|
||||
HavenWalletAddressesBase(WalletInfo walletInfo)
|
||||
: accountList = HavenAccountList(),
|
||||
subaddressList = HavenSubaddressList(),
|
||||
address = '',
|
||||
super(walletInfo);
|
||||
|
||||
@override
|
||||
@observable
|
||||
String address;
|
||||
|
||||
@override
|
||||
// @override
|
||||
@observable
|
||||
Account account;
|
||||
Account? account;
|
||||
|
||||
@observable
|
||||
Subaddress subaddress;
|
||||
Subaddress? subaddress;
|
||||
|
||||
HavenSubaddressList subaddressList;
|
||||
|
||||
|
@ -36,7 +37,7 @@ abstract class HavenWalletAddressesBase extends WalletAddressesWithAccount<Accou
|
|||
Future<void> init() async {
|
||||
accountList.update();
|
||||
account = accountList.accounts.first;
|
||||
updateSubaddressList(accountIndex: account.id ?? 0);
|
||||
updateSubaddressList(accountIndex: account?.id ?? 0);
|
||||
await updateAddressesInBox();
|
||||
}
|
||||
|
||||
|
@ -62,14 +63,14 @@ abstract class HavenWalletAddressesBase extends WalletAddressesWithAccount<Accou
|
|||
|
||||
bool validate() {
|
||||
accountList.update();
|
||||
final accountListLength = accountList.accounts?.length ?? 0;
|
||||
final accountListLength = accountList.accounts.length ?? 0;
|
||||
|
||||
if (accountListLength <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
subaddressList.update(accountIndex: accountList.accounts.first.id);
|
||||
final subaddressListLength = subaddressList.subaddresses?.length ?? 0;
|
||||
final subaddressListLength = subaddressList.subaddresses.length ?? 0;
|
||||
|
||||
if (subaddressListLength <= 0) {
|
||||
return false;
|
||||
|
@ -78,9 +79,9 @@ abstract class HavenWalletAddressesBase extends WalletAddressesWithAccount<Accou
|
|||
return true;
|
||||
}
|
||||
|
||||
void updateSubaddressList({int accountIndex}) {
|
||||
void updateSubaddressList({required int accountIndex}) {
|
||||
subaddressList.update(accountIndex: accountIndex);
|
||||
subaddress = subaddressList.subaddresses.first;
|
||||
address = subaddress.address;
|
||||
address = subaddress!.address;
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
import 'dart:io';
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:cw_core/wallet_base.dart';
|
||||
import 'package:cw_core/monero_wallet_utils.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
|
@ -13,7 +14,7 @@ import 'package:cw_core/wallet_info.dart';
|
|||
import 'package:cw_core/wallet_type.dart';
|
||||
|
||||
class HavenNewWalletCredentials extends WalletCredentials {
|
||||
HavenNewWalletCredentials({String name, String password, this.language})
|
||||
HavenNewWalletCredentials({required String name, required this.language, String? password})
|
||||
: super(name: name, password: password);
|
||||
|
||||
final String language;
|
||||
|
@ -21,7 +22,10 @@ class HavenNewWalletCredentials extends WalletCredentials {
|
|||
|
||||
class HavenRestoreWalletFromSeedCredentials extends WalletCredentials {
|
||||
HavenRestoreWalletFromSeedCredentials(
|
||||
{String name, String password, int height, this.mnemonic})
|
||||
{required String name,
|
||||
required String password,
|
||||
required int height,
|
||||
required this.mnemonic})
|
||||
: super(name: name, password: password, height: height);
|
||||
|
||||
final String mnemonic;
|
||||
|
@ -34,13 +38,13 @@ class HavenWalletLoadingException implements Exception {
|
|||
|
||||
class HavenRestoreWalletFromKeysCredentials extends WalletCredentials {
|
||||
HavenRestoreWalletFromKeysCredentials(
|
||||
{String name,
|
||||
String password,
|
||||
this.language,
|
||||
this.address,
|
||||
this.viewKey,
|
||||
this.spendKey,
|
||||
int height})
|
||||
{required String name,
|
||||
required String password,
|
||||
required this.language,
|
||||
required this.address,
|
||||
required this.viewKey,
|
||||
required this.spendKey,
|
||||
required int height})
|
||||
: super(name: name, password: password, height: height);
|
||||
|
||||
final String language;
|
||||
|
@ -69,9 +73,9 @@ class HavenWalletService extends WalletService<
|
|||
final path = await pathForWallet(name: credentials.name, type: getType());
|
||||
await haven_wallet_manager.createWallet(
|
||||
path: path,
|
||||
password: credentials.password,
|
||||
password: credentials.password!,
|
||||
language: credentials.language);
|
||||
final wallet = HavenWallet(walletInfo: credentials.walletInfo);
|
||||
final wallet = HavenWallet(walletInfo: credentials.walletInfo!);
|
||||
await wallet.init();
|
||||
return wallet;
|
||||
} catch (e) {
|
||||
|
@ -104,9 +108,8 @@ class HavenWalletService extends WalletService<
|
|||
|
||||
await haven_wallet_manager
|
||||
.openWalletAsync({'path': path, 'password': password});
|
||||
final walletInfo = walletInfoSource.values.firstWhere(
|
||||
(info) => info.id == WalletBase.idFor(name, getType()),
|
||||
orElse: () => null);
|
||||
final walletInfo = walletInfoSource.values.firstWhereOrNull(
|
||||
(info) => info.id == WalletBase.idFor(name, getType()))!;
|
||||
final wallet = HavenWallet(walletInfo: walletInfo);
|
||||
final isValid = wallet.walletAddresses.validate();
|
||||
|
||||
|
@ -155,13 +158,13 @@ class HavenWalletService extends WalletService<
|
|||
final path = await pathForWallet(name: credentials.name, type: getType());
|
||||
await haven_wallet_manager.restoreFromKeys(
|
||||
path: path,
|
||||
password: credentials.password,
|
||||
password: credentials.password!,
|
||||
language: credentials.language,
|
||||
restoreHeight: credentials.height,
|
||||
restoreHeight: credentials.height!,
|
||||
address: credentials.address,
|
||||
viewKey: credentials.viewKey,
|
||||
spendKey: credentials.spendKey);
|
||||
final wallet = HavenWallet(walletInfo: credentials.walletInfo);
|
||||
final wallet = HavenWallet(walletInfo: credentials.walletInfo!);
|
||||
await wallet.init();
|
||||
|
||||
return wallet;
|
||||
|
@ -179,10 +182,10 @@ class HavenWalletService extends WalletService<
|
|||
final path = await pathForWallet(name: credentials.name, type: getType());
|
||||
await haven_wallet_manager.restoreFromSeed(
|
||||
path: path,
|
||||
password: credentials.password,
|
||||
password: credentials.password!,
|
||||
seed: credentials.mnemonic,
|
||||
restoreHeight: credentials.height);
|
||||
final wallet = HavenWallet(walletInfo: credentials.walletInfo);
|
||||
restoreHeight: credentials.height!);
|
||||
final wallet = HavenWallet(walletInfo: credentials.walletInfo!);
|
||||
await wallet.init();
|
||||
|
||||
return wallet;
|
||||
|
|
|
@ -2,7 +2,7 @@ import 'package:cw_haven/api/structs/pending_transaction.dart';
|
|||
import 'package:cw_haven/api/transaction_history.dart'
|
||||
as haven_transaction_history;
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cake_wallet/core/amount_converter.dart';
|
||||
// import 'package:cake_wallet/core/amount_converter.dart';
|
||||
import 'package:cw_core/pending_transaction.dart';
|
||||
|
||||
class DoubleSpendException implements Exception {
|
||||
|
@ -25,13 +25,17 @@ class PendingHavenTransaction with PendingTransaction {
|
|||
@override
|
||||
String get hex => '';
|
||||
|
||||
// FIX-ME: AmountConverter
|
||||
@override
|
||||
String get amountFormatted => AmountConverter.amountIntToString(
|
||||
cryptoCurrency, pendingTransactionDescription.amount);
|
||||
String get amountFormatted => '';
|
||||
// AmountConverter.amountIntToString(
|
||||
// cryptoCurrency, pendingTransactionDescription.amount);
|
||||
|
||||
// FIX-ME: AmountConverter
|
||||
@override
|
||||
String get feeFormatted => AmountConverter.amountIntToString(
|
||||
cryptoCurrency, pendingTransactionDescription.fee);
|
||||
String get feeFormatted => '';
|
||||
// AmountConverter.amountIntToString(
|
||||
// cryptoCurrency, pendingTransactionDescription.fee);
|
||||
|
||||
@override
|
||||
Future<void> commit() async {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//import 'package:cake_wallet/store/dashboard/fiat_conversion_store.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cw_core/monero_amount_format.dart';
|
||||
import 'package:cw_haven/balance_list.dart';
|
||||
import 'package:cw_haven/api/balance_list.dart';
|
||||
|
||||
//Future<void> updateHavenRate(FiatConversionStore fiatConversionStore) async {
|
||||
// final rate = getRate();
|
||||
|
|
|
@ -7,35 +7,35 @@ packages:
|
|||
name: _fe_analyzer_shared
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "14.0.0"
|
||||
version: "47.0.0"
|
||||
analyzer:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: analyzer
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.41.2"
|
||||
version: "4.7.0"
|
||||
args:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: args
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.6.0"
|
||||
version: "2.3.1"
|
||||
asn1lib:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: asn1lib
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.8.1"
|
||||
version: "1.1.1"
|
||||
async:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: async
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.5.0"
|
||||
version: "2.9.0"
|
||||
boolean_selector:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -49,42 +49,42 @@ packages:
|
|||
name: build
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.6.2"
|
||||
version: "2.3.1"
|
||||
build_config:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_config
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.4.6"
|
||||
version: "1.1.0"
|
||||
build_daemon:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_daemon
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.10"
|
||||
version: "3.1.0"
|
||||
build_resolvers:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: build_resolvers
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.5.3"
|
||||
version: "2.0.10"
|
||||
build_runner:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: build_runner
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.11.5"
|
||||
version: "2.2.1"
|
||||
build_runner_core:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_runner_core
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "6.1.10"
|
||||
version: "7.2.4"
|
||||
built_collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -105,63 +105,49 @@ packages:
|
|||
name: characters
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
charcode:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: charcode
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
version: "1.2.1"
|
||||
checked_yaml:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: checked_yaml
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.4"
|
||||
cli_util:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: cli_util
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.3.5"
|
||||
version: "2.0.1"
|
||||
clock:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: clock
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
version: "1.1.1"
|
||||
code_builder:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: code_builder
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.7.0"
|
||||
version: "4.3.0"
|
||||
collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: collection
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.15.0"
|
||||
version: "1.16.0"
|
||||
convert:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: convert
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.1"
|
||||
version: "3.0.2"
|
||||
crypto:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: crypto
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.5"
|
||||
version: "3.0.2"
|
||||
cw_core:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -175,35 +161,28 @@ packages:
|
|||
name: dart_style
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.3.12"
|
||||
dartx:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: dartx
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.5.0"
|
||||
version: "2.2.4"
|
||||
encrypt:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: encrypt
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.1.0"
|
||||
version: "5.0.1"
|
||||
fake_async:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: fake_async
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
version: "1.3.1"
|
||||
ffi:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: ffi
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.3"
|
||||
version: "1.2.1"
|
||||
file:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -229,12 +208,19 @@ packages:
|
|||
name: flutter_mobx
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0+2"
|
||||
version: "2.0.6+4"
|
||||
flutter_test:
|
||||
dependency: "direct dev"
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
frontend_server_client:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: frontend_server_client
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.3"
|
||||
glob:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -248,42 +234,42 @@ packages:
|
|||
name: graphs
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.0"
|
||||
version: "2.1.0"
|
||||
hive:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: hive
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.4.4+1"
|
||||
version: "2.2.3"
|
||||
hive_generator:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: hive_generator
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.8.2"
|
||||
version: "1.1.3"
|
||||
http:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: http
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.12.2"
|
||||
version: "0.13.5"
|
||||
http_multi_server:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http_multi_server
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.2.0"
|
||||
version: "3.2.1"
|
||||
http_parser:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http_parser
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.1.4"
|
||||
version: "4.0.1"
|
||||
intl:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -297,7 +283,7 @@ packages:
|
|||
name: io
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.3.5"
|
||||
version: "1.0.3"
|
||||
js:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -311,7 +297,7 @@ packages:
|
|||
name: json_annotation
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.0.1"
|
||||
version: "4.6.0"
|
||||
logging:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -325,14 +311,21 @@ packages:
|
|||
name: matcher
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.12.10"
|
||||
version: "0.12.12"
|
||||
material_color_utilities:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: material_color_utilities
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.5"
|
||||
meta:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: meta
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.3.0"
|
||||
version: "1.8.0"
|
||||
mime:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -346,63 +339,77 @@ packages:
|
|||
name: mobx
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.1+4"
|
||||
version: "2.1.0"
|
||||
mobx_codegen:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: mobx_codegen
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.2"
|
||||
version: "2.0.7+3"
|
||||
package_config:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: package_config
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.9.3"
|
||||
version: "2.1.0"
|
||||
path:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.8.0"
|
||||
version: "1.8.2"
|
||||
path_provider:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: path_provider
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.6.28"
|
||||
version: "2.0.11"
|
||||
path_provider_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_android
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.20"
|
||||
path_provider_ios:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_ios
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.11"
|
||||
path_provider_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_linux
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.0.1+2"
|
||||
version: "2.1.7"
|
||||
path_provider_macos:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_macos
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.0.4+8"
|
||||
version: "2.0.6"
|
||||
path_provider_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.4"
|
||||
version: "2.0.4"
|
||||
path_provider_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_windows
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.0.4+3"
|
||||
version: "2.0.7"
|
||||
pedantic:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -423,14 +430,14 @@ packages:
|
|||
name: plugin_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.3"
|
||||
version: "2.1.3"
|
||||
pointycastle:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pointycastle
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.1"
|
||||
version: "3.6.2"
|
||||
pool:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -458,21 +465,21 @@ packages:
|
|||
name: pubspec_parse
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.8"
|
||||
version: "1.2.1"
|
||||
shelf:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.7.9"
|
||||
version: "1.3.2"
|
||||
shelf_web_socket:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf_web_socket
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.4+1"
|
||||
version: "1.0.2"
|
||||
sky_engine:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
|
@ -484,14 +491,21 @@ packages:
|
|||
name: source_gen
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.9.10+3"
|
||||
version: "1.2.3"
|
||||
source_helper:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_helper
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.3.3"
|
||||
source_span:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_span
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.8.0"
|
||||
version: "1.9.0"
|
||||
stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -519,35 +533,28 @@ packages:
|
|||
name: string_scanner
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
version: "1.1.1"
|
||||
term_glyph:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: term_glyph
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
version: "1.2.1"
|
||||
test_api:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_api
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.19"
|
||||
time:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: time
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.4.1"
|
||||
version: "0.4.12"
|
||||
timing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: timing
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.1+3"
|
||||
version: "1.0.0"
|
||||
typed_data:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -561,7 +568,7 @@ packages:
|
|||
name: vector_math
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
version: "2.1.2"
|
||||
watcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -575,21 +582,21 @@ packages:
|
|||
name: web_socket_channel
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
version: "2.2.0"
|
||||
win32:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: win32
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.7.4+1"
|
||||
version: "2.6.1"
|
||||
xdg_directories:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: xdg_directories
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.2"
|
||||
version: "0.2.0+2"
|
||||
yaml:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -598,5 +605,5 @@ packages:
|
|||
source: hosted
|
||||
version: "3.1.0"
|
||||
sdks:
|
||||
dart: ">=2.12.0 <3.0.0"
|
||||
flutter: ">=1.20.0"
|
||||
dart: ">=2.17.5 <3.0.0"
|
||||
flutter: ">=2.8.1"
|
||||
|
|
|
@ -6,17 +6,17 @@ author: Cake Wallet
|
|||
homepage: https://cakewallet.com
|
||||
|
||||
environment:
|
||||
sdk: ">=2.7.0 <3.0.0"
|
||||
sdk: ">=2.17.5 <3.0.0"
|
||||
flutter: ">=1.20.0"
|
||||
|
||||
dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
ffi: ^0.1.3
|
||||
path_provider: ^1.4.0
|
||||
http: ^0.12.0+2
|
||||
mobx: ^1.2.1+2
|
||||
flutter_mobx: ^1.1.0+2
|
||||
ffi: ^1.1.2
|
||||
http: ^0.13.4
|
||||
path_provider: ^2.0.11
|
||||
mobx: ^2.0.7+4
|
||||
flutter_mobx: ^2.0.6+1
|
||||
intl: ^0.17.0
|
||||
cw_core:
|
||||
path: ../cw_core
|
||||
|
@ -24,10 +24,10 @@ dependencies:
|
|||
dev_dependencies:
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
build_runner: ^1.10.3
|
||||
build_resolvers: ^1.3.10
|
||||
mobx_codegen: ^1.1.0+1
|
||||
hive_generator: ^0.8.1
|
||||
build_runner: ^2.1.11
|
||||
mobx_codegen: ^2.0.7
|
||||
build_resolvers: ^2.0.9
|
||||
hive_generator: ^1.1.3
|
||||
|
||||
# For information on the generic Dart part of this file, see the
|
||||
# following page: https://dart.dev/tools/pub/pubspec
|
||||
|
|
|
@ -50,16 +50,16 @@ List<AccountRow> getAllAccount() {
|
|||
.toList();
|
||||
}
|
||||
|
||||
void addAccountSync({String label}) {
|
||||
final labelPointer = Utf8.toUtf8(label);
|
||||
void addAccountSync({required String label}) {
|
||||
final labelPointer = label.toNativeUtf8();
|
||||
accountAddNewNative(labelPointer);
|
||||
free(labelPointer);
|
||||
calloc.free(labelPointer);
|
||||
}
|
||||
|
||||
void setLabelForAccountSync({int accountIndex, String label}) {
|
||||
final labelPointer = Utf8.toUtf8(label);
|
||||
void setLabelForAccountSync({required int accountIndex, required String label}) {
|
||||
final labelPointer = label.toNativeUtf8();
|
||||
accountSetLabelNative(accountIndex, labelPointer);
|
||||
free(labelPointer);
|
||||
calloc.free(labelPointer);
|
||||
}
|
||||
|
||||
void _addAccount(String label) => addAccountSync(label: label);
|
||||
|
@ -71,12 +71,12 @@ void _setLabelForAccount(Map<String, dynamic> args) {
|
|||
setLabelForAccountSync(label: label, accountIndex: accountIndex);
|
||||
}
|
||||
|
||||
Future<void> addAccount({String label}) async {
|
||||
Future<void> addAccount({required String label}) async {
|
||||
await compute(_addAccount, label);
|
||||
await store();
|
||||
}
|
||||
|
||||
Future<void> setLabelForAccount({int accountIndex, String label}) async {
|
||||
Future<void> setLabelForAccount({required int accountIndex, required String label}) async {
|
||||
await compute(
|
||||
_setLabelForAccount, {'accountIndex': accountIndex, 'label': label});
|
||||
await store();
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import 'dart:ffi';
|
||||
import 'package:ffi/ffi.dart';
|
||||
|
||||
String convertUTF8ToString({Pointer<Utf8> pointer}) {
|
||||
final str = Utf8.fromUtf8(pointer);
|
||||
free(pointer);
|
||||
String convertUTF8ToString({required Pointer<Utf8> pointer}) {
|
||||
final str = pointer.toDartString();
|
||||
calloc.free(pointer);
|
||||
return str;
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
class ConnectionToNodeException implements Exception {
|
||||
ConnectionToNodeException({this.message});
|
||||
ConnectionToNodeException({required this.message});
|
||||
|
||||
final String message;
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
class CreationTransactionException implements Exception {
|
||||
CreationTransactionException({this.message});
|
||||
CreationTransactionException({required this.message});
|
||||
|
||||
final String message;
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue