mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2025-01-05 10:29:23 +00:00
fix: fee and addresses
This commit is contained in:
parent
7964b2a056
commit
884a822cea
14 changed files with 460 additions and 335 deletions
|
@ -1,25 +1,25 @@
|
||||||
import 'package:cw_core/transaction_priority.dart';
|
import 'package:cw_core/transaction_priority.dart';
|
||||||
|
|
||||||
|
class BitcoinTransactionPriority extends TransactionPriority {
|
||||||
|
const BitcoinTransactionPriority({required super.title, required super.raw});
|
||||||
|
|
||||||
// Unimportant: the lowest possible, confirms when it confirms no matter how long it takes
|
// Unimportant: the lowest possible, confirms when it confirms no matter how long it takes
|
||||||
|
static const BitcoinTransactionPriority unimportant =
|
||||||
|
BitcoinTransactionPriority(title: 'Unimportant', raw: 0);
|
||||||
// Normal: low fee, confirms in a reasonable time, normal because in most cases more than this is not needed, gets you in the next 2-3 blocks (about 1 hour)
|
// Normal: low fee, confirms in a reasonable time, normal because in most cases more than this is not needed, gets you in the next 2-3 blocks (about 1 hour)
|
||||||
|
static const BitcoinTransactionPriority normal =
|
||||||
|
BitcoinTransactionPriority(title: 'Normal', raw: 1);
|
||||||
// Elevated: medium fee, confirms soon, elevated because it's higher than normal, gets you in the next 1-2 blocks (about 30 mins)
|
// Elevated: medium fee, confirms soon, elevated because it's higher than normal, gets you in the next 1-2 blocks (about 30 mins)
|
||||||
|
static const BitcoinTransactionPriority elevated =
|
||||||
|
BitcoinTransactionPriority(title: 'Elevated', raw: 2);
|
||||||
// Priority: high fee, expected in the next block (about 10 mins).
|
// Priority: high fee, expected in the next block (about 10 mins).
|
||||||
|
static const BitcoinTransactionPriority priority =
|
||||||
|
BitcoinTransactionPriority(title: 'Priority', raw: 3);
|
||||||
|
// Custom: any fee, user defined
|
||||||
|
static const BitcoinTransactionPriority custom =
|
||||||
|
BitcoinTransactionPriority(title: 'Custom', raw: 4);
|
||||||
|
|
||||||
class BitcoinMempoolAPITransactionPriority extends TransactionPriority {
|
static BitcoinTransactionPriority deserialize({required int raw}) {
|
||||||
const BitcoinMempoolAPITransactionPriority({required super.title, required super.raw});
|
|
||||||
|
|
||||||
static const BitcoinMempoolAPITransactionPriority unimportant =
|
|
||||||
BitcoinMempoolAPITransactionPriority(title: 'Unimportant', raw: 0);
|
|
||||||
static const BitcoinMempoolAPITransactionPriority normal =
|
|
||||||
BitcoinMempoolAPITransactionPriority(title: 'Normal', raw: 1);
|
|
||||||
static const BitcoinMempoolAPITransactionPriority elevated =
|
|
||||||
BitcoinMempoolAPITransactionPriority(title: 'Elevated', raw: 2);
|
|
||||||
static const BitcoinMempoolAPITransactionPriority priority =
|
|
||||||
BitcoinMempoolAPITransactionPriority(title: 'Priority', raw: 3);
|
|
||||||
static const BitcoinMempoolAPITransactionPriority custom =
|
|
||||||
BitcoinMempoolAPITransactionPriority(title: 'Custom', raw: 4);
|
|
||||||
|
|
||||||
static BitcoinMempoolAPITransactionPriority deserialize({required int raw}) {
|
|
||||||
switch (raw) {
|
switch (raw) {
|
||||||
case 0:
|
case 0:
|
||||||
return unimportant;
|
return unimportant;
|
||||||
|
@ -41,19 +41,19 @@ class BitcoinMempoolAPITransactionPriority extends TransactionPriority {
|
||||||
var label = '';
|
var label = '';
|
||||||
|
|
||||||
switch (this) {
|
switch (this) {
|
||||||
case BitcoinMempoolAPITransactionPriority.unimportant:
|
case BitcoinTransactionPriority.unimportant:
|
||||||
label = 'Unimportant ~24hrs+'; // '${S.current.transaction_priority_slow} ~24hrs';
|
label = 'Unimportant ~24hrs+'; // '${S.current.transaction_priority_slow} ~24hrs';
|
||||||
break;
|
break;
|
||||||
case BitcoinMempoolAPITransactionPriority.normal:
|
case BitcoinTransactionPriority.normal:
|
||||||
label = 'Normal ~1hr+'; // S.current.transaction_priority_medium;
|
label = 'Normal ~1hr+'; // S.current.transaction_priority_medium;
|
||||||
break;
|
break;
|
||||||
case BitcoinMempoolAPITransactionPriority.elevated:
|
case BitcoinTransactionPriority.elevated:
|
||||||
label = 'Elevated';
|
label = 'Elevated';
|
||||||
break; // S.current.transaction_priority_fast;
|
break; // S.current.transaction_priority_fast;
|
||||||
case BitcoinMempoolAPITransactionPriority.priority:
|
case BitcoinTransactionPriority.priority:
|
||||||
label = 'Priority';
|
label = 'Priority';
|
||||||
break; // S.current.transaction_priority_fast;
|
break; // S.current.transaction_priority_fast;
|
||||||
case BitcoinMempoolAPITransactionPriority.custom:
|
case BitcoinTransactionPriority.custom:
|
||||||
label = 'Custom';
|
label = 'Custom';
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -69,92 +69,22 @@ class BitcoinMempoolAPITransactionPriority extends TransactionPriority {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class BitcoinElectrumTransactionPriority extends TransactionPriority {
|
class ElectrumTransactionPriority extends TransactionPriority {
|
||||||
const BitcoinElectrumTransactionPriority({required String title, required int raw})
|
const ElectrumTransactionPriority({required String title, required int raw})
|
||||||
: super(title: title, raw: raw);
|
: super(title: title, raw: raw);
|
||||||
|
|
||||||
static const List<BitcoinElectrumTransactionPriority> all = [
|
static const List<ElectrumTransactionPriority> all = [fast, medium, slow, custom];
|
||||||
unimportant,
|
|
||||||
normal,
|
|
||||||
elevated,
|
|
||||||
priority,
|
|
||||||
custom,
|
|
||||||
];
|
|
||||||
|
|
||||||
static const BitcoinElectrumTransactionPriority unimportant =
|
static const ElectrumTransactionPriority slow =
|
||||||
BitcoinElectrumTransactionPriority(title: 'Unimportant', raw: 0);
|
ElectrumTransactionPriority(title: 'Slow', raw: 0);
|
||||||
static const BitcoinElectrumTransactionPriority normal =
|
static const ElectrumTransactionPriority medium =
|
||||||
BitcoinElectrumTransactionPriority(title: 'Normal', raw: 1);
|
ElectrumTransactionPriority(title: 'Medium', raw: 1);
|
||||||
static const BitcoinElectrumTransactionPriority elevated =
|
static const ElectrumTransactionPriority fast =
|
||||||
BitcoinElectrumTransactionPriority(title: 'Elevated', raw: 2);
|
ElectrumTransactionPriority(title: 'Fast', raw: 2);
|
||||||
static const BitcoinElectrumTransactionPriority priority =
|
static const ElectrumTransactionPriority custom =
|
||||||
BitcoinElectrumTransactionPriority(title: 'Priority', raw: 3);
|
ElectrumTransactionPriority(title: 'Custom', raw: 3);
|
||||||
static const BitcoinElectrumTransactionPriority custom =
|
|
||||||
BitcoinElectrumTransactionPriority(title: 'Custom', raw: 4);
|
|
||||||
|
|
||||||
static BitcoinElectrumTransactionPriority deserialize({required int raw}) {
|
static ElectrumTransactionPriority deserialize({required int raw}) {
|
||||||
switch (raw) {
|
|
||||||
case 0:
|
|
||||||
return unimportant;
|
|
||||||
case 1:
|
|
||||||
return normal;
|
|
||||||
case 2:
|
|
||||||
return elevated;
|
|
||||||
case 3:
|
|
||||||
return priority;
|
|
||||||
case 4:
|
|
||||||
return custom;
|
|
||||||
default:
|
|
||||||
throw Exception('Unexpected token: $raw for TransactionPriority deserialize');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() {
|
|
||||||
var label = '';
|
|
||||||
|
|
||||||
switch (this) {
|
|
||||||
case BitcoinElectrumTransactionPriority.unimportant:
|
|
||||||
label = 'Unimportant'; // '${S.current.transaction_priority_slow} ~24hrs';
|
|
||||||
break;
|
|
||||||
case BitcoinElectrumTransactionPriority.normal:
|
|
||||||
label = 'Slow ~24hrs+'; // '${S.current.transaction_priority_slow} ~24hrs';
|
|
||||||
break;
|
|
||||||
case BitcoinElectrumTransactionPriority.elevated:
|
|
||||||
label = 'Medium'; // S.current.transaction_priority_medium;
|
|
||||||
break; // S.current.transaction_priority_fast;
|
|
||||||
case BitcoinElectrumTransactionPriority.priority:
|
|
||||||
label = 'Fast';
|
|
||||||
break; // S.current.transaction_priority_fast;
|
|
||||||
case BitcoinElectrumTransactionPriority.custom:
|
|
||||||
label = 'Custom';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return label;
|
|
||||||
}
|
|
||||||
|
|
||||||
String labelWithRate(int rate, int? customRate) {
|
|
||||||
final rateValue = this == custom ? customRate ??= 0 : rate;
|
|
||||||
return '${toString()} ($rateValue ${units}/byte)';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class LitecoinTransactionPriority extends BitcoinElectrumTransactionPriority {
|
|
||||||
const LitecoinTransactionPriority({required super.title, required super.raw});
|
|
||||||
|
|
||||||
static const all = [slow, medium, fast];
|
|
||||||
|
|
||||||
static const LitecoinTransactionPriority slow =
|
|
||||||
LitecoinTransactionPriority(title: 'Slow', raw: 0);
|
|
||||||
static const LitecoinTransactionPriority medium =
|
|
||||||
LitecoinTransactionPriority(title: 'Medium', raw: 1);
|
|
||||||
static const LitecoinTransactionPriority fast =
|
|
||||||
LitecoinTransactionPriority(title: 'Fast', raw: 2);
|
|
||||||
|
|
||||||
static LitecoinTransactionPriority deserialize({required int raw}) {
|
|
||||||
switch (raw) {
|
switch (raw) {
|
||||||
case 0:
|
case 0:
|
||||||
return slow;
|
return slow;
|
||||||
|
@ -162,68 +92,87 @@ class LitecoinTransactionPriority extends BitcoinElectrumTransactionPriority {
|
||||||
return medium;
|
return medium;
|
||||||
case 2:
|
case 2:
|
||||||
return fast;
|
return fast;
|
||||||
|
case 3:
|
||||||
|
return custom;
|
||||||
default:
|
default:
|
||||||
throw Exception('Unexpected token: $raw for LitecoinTransactionPriority deserialize');
|
throw Exception('Unexpected token: $raw for ElectrumTransactionPriority deserialize');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String get units => 'sat';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
var label = '';
|
||||||
|
|
||||||
|
switch (this) {
|
||||||
|
case ElectrumTransactionPriority.slow:
|
||||||
|
label = 'Slow ~24hrs+'; // '${S.current.transaction_priority_slow} ~24hrs';
|
||||||
|
break;
|
||||||
|
case ElectrumTransactionPriority.medium:
|
||||||
|
label = 'Medium'; // S.current.transaction_priority_medium;
|
||||||
|
break;
|
||||||
|
case ElectrumTransactionPriority.fast:
|
||||||
|
label = 'Fast';
|
||||||
|
break; // S.current.transaction_priority_fast;
|
||||||
|
case ElectrumTransactionPriority.custom:
|
||||||
|
label = 'Custom';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
|
String labelWithRate(int rate, int? customRate) {
|
||||||
|
final rateValue = this == custom ? customRate ??= 0 : rate;
|
||||||
|
return '${toString()} ($rateValue ${units}/byte)';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class LitecoinTransactionPriority extends ElectrumTransactionPriority {
|
||||||
|
const LitecoinTransactionPriority({required super.title, required super.raw});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get units => 'lit';
|
String get units => 'lit';
|
||||||
}
|
}
|
||||||
|
|
||||||
class BitcoinCashTransactionPriority extends BitcoinElectrumTransactionPriority {
|
class BitcoinCashTransactionPriority extends ElectrumTransactionPriority {
|
||||||
const BitcoinCashTransactionPriority({required super.title, required super.raw});
|
const BitcoinCashTransactionPriority({required super.title, required super.raw});
|
||||||
|
|
||||||
static const all = [slow, medium, fast];
|
|
||||||
|
|
||||||
static const BitcoinCashTransactionPriority slow =
|
|
||||||
BitcoinCashTransactionPriority(title: 'Slow', raw: 0);
|
|
||||||
static const BitcoinCashTransactionPriority medium =
|
|
||||||
BitcoinCashTransactionPriority(title: 'Medium', raw: 1);
|
|
||||||
static const BitcoinCashTransactionPriority fast =
|
|
||||||
BitcoinCashTransactionPriority(title: 'Fast', raw: 2);
|
|
||||||
|
|
||||||
static BitcoinCashTransactionPriority deserialize({required int raw}) {
|
|
||||||
switch (raw) {
|
|
||||||
case 0:
|
|
||||||
return slow;
|
|
||||||
case 1:
|
|
||||||
return medium;
|
|
||||||
case 2:
|
|
||||||
return fast;
|
|
||||||
default:
|
|
||||||
throw Exception('Unexpected token: $raw for LitecoinTransactionPriority deserialize');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get units => 'satoshi';
|
String get units => 'satoshi';
|
||||||
}
|
}
|
||||||
|
|
||||||
class BitcoinMempoolAPITransactionPriorities implements TransactionPriorities {
|
class BitcoinTransactionPriorities implements TransactionPriorities {
|
||||||
const BitcoinMempoolAPITransactionPriorities({
|
const BitcoinTransactionPriorities({
|
||||||
required this.unimportant,
|
required this.unimportant,
|
||||||
required this.normal,
|
required this.normal,
|
||||||
required this.elevated,
|
required this.elevated,
|
||||||
required this.priority,
|
required this.priority,
|
||||||
|
required this.custom,
|
||||||
});
|
});
|
||||||
|
|
||||||
final int unimportant;
|
final int unimportant;
|
||||||
final int normal;
|
final int normal;
|
||||||
final int elevated;
|
final int elevated;
|
||||||
final int priority;
|
final int priority;
|
||||||
|
final int custom;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int operator [](TransactionPriority type) {
|
int operator [](TransactionPriority type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case BitcoinMempoolAPITransactionPriority.unimportant:
|
case BitcoinTransactionPriority.unimportant:
|
||||||
return unimportant;
|
return unimportant;
|
||||||
case BitcoinMempoolAPITransactionPriority.normal:
|
case BitcoinTransactionPriority.normal:
|
||||||
return normal;
|
return normal;
|
||||||
case BitcoinMempoolAPITransactionPriority.elevated:
|
case BitcoinTransactionPriority.elevated:
|
||||||
return elevated;
|
return elevated;
|
||||||
case BitcoinMempoolAPITransactionPriority.priority:
|
case BitcoinTransactionPriority.priority:
|
||||||
return priority;
|
return priority;
|
||||||
|
case BitcoinTransactionPriority.custom:
|
||||||
|
return custom;
|
||||||
default:
|
default:
|
||||||
throw Exception('Unexpected token: $type for TransactionPriorities operator[]');
|
throw Exception('Unexpected token: $type for TransactionPriorities operator[]');
|
||||||
}
|
}
|
||||||
|
@ -233,7 +182,7 @@ class BitcoinMempoolAPITransactionPriorities implements TransactionPriorities {
|
||||||
String labelWithRate(TransactionPriority priorityType, [int? rate]) {
|
String labelWithRate(TransactionPriority priorityType, [int? rate]) {
|
||||||
late int rateValue;
|
late int rateValue;
|
||||||
|
|
||||||
if (priorityType == BitcoinMempoolAPITransactionPriority.custom) {
|
if (priorityType == BitcoinTransactionPriority.custom) {
|
||||||
if (rate == null) {
|
if (rate == null) {
|
||||||
throw Exception('Rate must be provided for custom transaction priority');
|
throw Exception('Rate must be provided for custom transaction priority');
|
||||||
}
|
}
|
||||||
|
@ -244,32 +193,53 @@ class BitcoinMempoolAPITransactionPriorities implements TransactionPriorities {
|
||||||
|
|
||||||
return '${priorityType.toString()} (${rateValue} ${priorityType.units}/byte)';
|
return '${priorityType.toString()} (${rateValue} ${priorityType.units}/byte)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, int> toJson() {
|
||||||
|
return {
|
||||||
|
'unimportant': unimportant,
|
||||||
|
'normal': normal,
|
||||||
|
'elevated': elevated,
|
||||||
|
'priority': priority,
|
||||||
|
'custom': custom,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static BitcoinTransactionPriorities fromJson(Map<String, dynamic> json) {
|
||||||
|
return BitcoinTransactionPriorities(
|
||||||
|
unimportant: json['unimportant'] as int,
|
||||||
|
normal: json['normal'] as int,
|
||||||
|
elevated: json['elevated'] as int,
|
||||||
|
priority: json['priority'] as int,
|
||||||
|
custom: json['custom'] as int,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class BitcoinElectrumTransactionPriorities implements TransactionPriorities {
|
class ElectrumTransactionPriorities implements TransactionPriorities {
|
||||||
const BitcoinElectrumTransactionPriorities({
|
const ElectrumTransactionPriorities({
|
||||||
required this.unimportant,
|
|
||||||
required this.slow,
|
required this.slow,
|
||||||
required this.medium,
|
required this.medium,
|
||||||
required this.fast,
|
required this.fast,
|
||||||
|
required this.custom,
|
||||||
});
|
});
|
||||||
|
|
||||||
final int unimportant;
|
|
||||||
final int slow;
|
final int slow;
|
||||||
final int medium;
|
final int medium;
|
||||||
final int fast;
|
final int fast;
|
||||||
|
final int custom;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int operator [](TransactionPriority type) {
|
int operator [](TransactionPriority type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case BitcoinElectrumTransactionPriority.unimportant:
|
case ElectrumTransactionPriority.slow:
|
||||||
return unimportant;
|
|
||||||
case BitcoinElectrumTransactionPriority.normal:
|
|
||||||
return slow;
|
return slow;
|
||||||
case BitcoinElectrumTransactionPriority.elevated:
|
case ElectrumTransactionPriority.medium:
|
||||||
return medium;
|
return medium;
|
||||||
case BitcoinElectrumTransactionPriority.priority:
|
case ElectrumTransactionPriority.fast:
|
||||||
return fast;
|
return fast;
|
||||||
|
case ElectrumTransactionPriority.custom:
|
||||||
|
return custom;
|
||||||
default:
|
default:
|
||||||
throw Exception('Unexpected token: $type for TransactionPriorities operator[]');
|
throw Exception('Unexpected token: $type for TransactionPriorities operator[]');
|
||||||
}
|
}
|
||||||
|
@ -280,25 +250,46 @@ class BitcoinElectrumTransactionPriorities implements TransactionPriorities {
|
||||||
return '${priorityType.toString()} (${this[priorityType]} ${priorityType.units}/byte)';
|
return '${priorityType.toString()} (${this[priorityType]} ${priorityType.units}/byte)';
|
||||||
}
|
}
|
||||||
|
|
||||||
factory BitcoinElectrumTransactionPriorities.fromList(List<int> list) {
|
factory ElectrumTransactionPriorities.fromList(List<int> list) {
|
||||||
if (list.length != 3) {
|
if (list.length != 3) {
|
||||||
throw Exception(
|
throw Exception(
|
||||||
'Unexpected list length: ${list.length} for BitcoinElectrumTransactionPriorities.fromList');
|
'Unexpected list length: ${list.length} for BitcoinElectrumTransactionPriorities.fromList');
|
||||||
}
|
}
|
||||||
|
|
||||||
int unimportantFee = list[0];
|
return ElectrumTransactionPriorities(
|
||||||
|
|
||||||
// Electrum servers only provides 3 levels: slow, medium, fast
|
|
||||||
// so make "unimportant" always lower than slow (but not 0)
|
|
||||||
if (unimportantFee > 1) {
|
|
||||||
unimportantFee--;
|
|
||||||
}
|
|
||||||
|
|
||||||
return BitcoinElectrumTransactionPriorities(
|
|
||||||
unimportant: unimportantFee,
|
|
||||||
slow: list[0],
|
slow: list[0],
|
||||||
medium: list[1],
|
medium: list[1],
|
||||||
fast: list[2],
|
fast: list[2],
|
||||||
|
custom: 0,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, int> toJson() {
|
||||||
|
return {
|
||||||
|
'slow': slow,
|
||||||
|
'medium': medium,
|
||||||
|
'fast': fast,
|
||||||
|
'custom': custom,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static ElectrumTransactionPriorities fromJson(Map<String, dynamic> json) {
|
||||||
|
return ElectrumTransactionPriorities(
|
||||||
|
slow: json['slow'] as int,
|
||||||
|
medium: json['medium'] as int,
|
||||||
|
fast: json['fast'] as int,
|
||||||
|
custom: json['custom'] as int,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TransactionPriorities deserializeTransactionPriorities(Map<String, dynamic> json) {
|
||||||
|
if (json.containsKey('unimportant')) {
|
||||||
|
return BitcoinTransactionPriorities.fromJson(json);
|
||||||
|
} else if (json.containsKey('slow')) {
|
||||||
|
return ElectrumTransactionPriorities.fromJson(json);
|
||||||
|
} else {
|
||||||
|
throw Exception('Unexpected token: $json for deserializeTransactionPriorities');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -276,6 +276,24 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<bool> getNodeIsElectrs() async {
|
||||||
|
final version = await sendWorker(ElectrumWorkerGetVersionRequest()) as List<String>;
|
||||||
|
|
||||||
|
if (version.isNotEmpty) {
|
||||||
|
final server = version[0];
|
||||||
|
|
||||||
|
if (server.toLowerCase().contains('electrs')) {
|
||||||
|
node!.isElectrs = true;
|
||||||
|
node!.save();
|
||||||
|
return node!.isElectrs!;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
node!.isElectrs = false;
|
||||||
|
node!.save();
|
||||||
|
return node!.isElectrs!;
|
||||||
|
}
|
||||||
|
|
||||||
Future<bool> getNodeSupportsSilentPayments() async {
|
Future<bool> getNodeSupportsSilentPayments() async {
|
||||||
return true;
|
return true;
|
||||||
// As of today (august 2024), only ElectrumRS supports silent payments
|
// As of today (august 2024), only ElectrumRS supports silent payments
|
||||||
|
@ -757,51 +775,6 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
|
||||||
// );
|
// );
|
||||||
// }
|
// }
|
||||||
|
|
||||||
@override
|
|
||||||
@action
|
|
||||||
Future<void> updateFeeRates() async {
|
|
||||||
// Bitcoin only: use the mempool.space backend API for accurate fee rates
|
|
||||||
if (mempoolAPIEnabled) {
|
|
||||||
try {
|
|
||||||
final recommendedFees = await apiProvider!.getRecommendedFeeRate();
|
|
||||||
|
|
||||||
final unimportantFee = recommendedFees.economyFee!.satoshis;
|
|
||||||
final normalFee = recommendedFees.low.satoshis;
|
|
||||||
int elevatedFee = recommendedFees.medium.satoshis;
|
|
||||||
int priorityFee = recommendedFees.high.satoshis;
|
|
||||||
|
|
||||||
// Bitcoin only: adjust fee rates to avoid equal fee values
|
|
||||||
// elevated should be higher than normal
|
|
||||||
if (normalFee == elevatedFee) {
|
|
||||||
elevatedFee++;
|
|
||||||
}
|
|
||||||
// priority should be higher than elevated
|
|
||||||
while (priorityFee <= elevatedFee) {
|
|
||||||
priorityFee++;
|
|
||||||
}
|
|
||||||
// this guarantees that, even if all fees are low and equal,
|
|
||||||
// higher priority fees can be taken when fees start surging
|
|
||||||
|
|
||||||
feeRates = BitcoinMempoolAPITransactionPriorities(
|
|
||||||
unimportant: unimportantFee,
|
|
||||||
normal: normalFee,
|
|
||||||
elevated: elevatedFee,
|
|
||||||
priority: priorityFee,
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
} catch (e, stacktrace) {
|
|
||||||
callError(FlutterErrorDetails(
|
|
||||||
exception: e,
|
|
||||||
stack: stacktrace,
|
|
||||||
library: this.runtimeType.toString(),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Bitcoin only: Ideally this should be avoided, electrum is terrible at fee rates
|
|
||||||
await super.updateFeeRates();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@action
|
@action
|
||||||
Future<void> onHeadersResponse(ElectrumHeaderResponse response) async {
|
Future<void> onHeadersResponse(ElectrumHeaderResponse response) async {
|
||||||
|
|
|
@ -16,7 +16,6 @@ import 'package:cw_bitcoin/bitcoin_transaction_credentials.dart';
|
||||||
import 'package:cw_bitcoin/bitcoin_transaction_priority.dart';
|
import 'package:cw_bitcoin/bitcoin_transaction_priority.dart';
|
||||||
import 'package:cw_bitcoin/bitcoin_unspent.dart';
|
import 'package:cw_bitcoin/bitcoin_unspent.dart';
|
||||||
import 'package:cw_bitcoin/bitcoin_wallet_keys.dart';
|
import 'package:cw_bitcoin/bitcoin_wallet_keys.dart';
|
||||||
import 'package:cw_bitcoin/electrum.dart';
|
|
||||||
import 'package:cw_bitcoin/electrum_balance.dart';
|
import 'package:cw_bitcoin/electrum_balance.dart';
|
||||||
import 'package:cw_bitcoin/electrum_transaction_history.dart';
|
import 'package:cw_bitcoin/electrum_transaction_history.dart';
|
||||||
import 'package:cw_bitcoin/electrum_transaction_info.dart';
|
import 'package:cw_bitcoin/electrum_transaction_info.dart';
|
||||||
|
@ -84,7 +83,6 @@ abstract class ElectrumWalletBase
|
||||||
},
|
},
|
||||||
syncStatus = NotConnectedSyncStatus(),
|
syncStatus = NotConnectedSyncStatus(),
|
||||||
_password = password,
|
_password = password,
|
||||||
_isTransactionUpdating = false,
|
|
||||||
isEnabledAutoGenerateSubaddress = true,
|
isEnabledAutoGenerateSubaddress = true,
|
||||||
// TODO: inital unspent coins
|
// TODO: inital unspent coins
|
||||||
unspentCoins = BitcoinUnspentCoins(),
|
unspentCoins = BitcoinUnspentCoins(),
|
||||||
|
@ -115,6 +113,7 @@ abstract class ElectrumWalletBase
|
||||||
sharedPrefs.complete(SharedPreferences.getInstance());
|
sharedPrefs.complete(SharedPreferences.getInstance());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sends a request to the worker and returns a future that completes when the worker responds
|
||||||
Future<dynamic> sendWorker(ElectrumWorkerRequest request) {
|
Future<dynamic> sendWorker(ElectrumWorkerRequest request) {
|
||||||
final messageId = ++_messageId;
|
final messageId = ++_messageId;
|
||||||
|
|
||||||
|
@ -144,28 +143,14 @@ abstract class ElectrumWalletBase
|
||||||
} else {
|
} else {
|
||||||
messageJson = message as Map<String, dynamic>;
|
messageJson = message as Map<String, dynamic>;
|
||||||
}
|
}
|
||||||
|
|
||||||
final workerMethod = messageJson['method'] as String;
|
final workerMethod = messageJson['method'] as String;
|
||||||
|
final workerError = messageJson['error'] as String?;
|
||||||
|
|
||||||
// if (workerResponse.error != null) {
|
if (workerError != null) {
|
||||||
// print('Worker error: ${workerResponse.error}');
|
print('Worker error: $workerError');
|
||||||
|
return;
|
||||||
// switch (workerResponse.method) {
|
}
|
||||||
// // case 'connectionStatus':
|
|
||||||
// // final status = ConnectionStatus.values.firstWhere(
|
|
||||||
// // (e) => e.toString() == workerResponse.error,
|
|
||||||
// // );
|
|
||||||
// // _onConnectionStatusChange(status);
|
|
||||||
// // break;
|
|
||||||
// // case 'fetchBalances':
|
|
||||||
// // // Update the balance state
|
|
||||||
// // // this.balance[currency] = balance!;
|
|
||||||
// // break;
|
|
||||||
// case 'blockchain.headers.subscribe':
|
|
||||||
// _chainTipListenerOn = false;
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
final responseId = messageJson['id'] as int?;
|
final responseId = messageJson['id'] as int?;
|
||||||
if (responseId != null && _responseCompleters.containsKey(responseId)) {
|
if (responseId != null && _responseCompleters.containsKey(responseId)) {
|
||||||
|
@ -194,16 +179,13 @@ abstract class ElectrumWalletBase
|
||||||
final response = ElectrumWorkerListUnspentResponse.fromJson(messageJson);
|
final response = ElectrumWorkerListUnspentResponse.fromJson(messageJson);
|
||||||
onUnspentResponse(response.result);
|
onUnspentResponse(response.result);
|
||||||
break;
|
break;
|
||||||
|
case ElectrumRequestMethods.estimateFeeMethod:
|
||||||
|
final response = ElectrumWorkerGetFeesResponse.fromJson(messageJson);
|
||||||
|
onFeesResponse(response.result);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't forget to clean up in the close method
|
|
||||||
// @override
|
|
||||||
// Future<void> close({required bool shouldCleanup}) async {
|
|
||||||
// await _workerSubscription?.cancel();
|
|
||||||
// await super.close(shouldCleanup: shouldCleanup);
|
|
||||||
// }
|
|
||||||
|
|
||||||
static Bip32Slip10Secp256k1 getAccountHDWallet(CryptoCurrency? currency, BasedUtxoNetwork network,
|
static Bip32Slip10Secp256k1 getAccountHDWallet(CryptoCurrency? currency, BasedUtxoNetwork network,
|
||||||
List<int>? seedBytes, String? xpub, DerivationInfo? derivationInfo) {
|
List<int>? seedBytes, String? xpub, DerivationInfo? derivationInfo) {
|
||||||
if (seedBytes == null && xpub == null) {
|
if (seedBytes == null && xpub == null) {
|
||||||
|
@ -317,13 +299,30 @@ abstract class ElectrumWalletBase
|
||||||
|
|
||||||
@observable
|
@observable
|
||||||
TransactionPriorities? feeRates;
|
TransactionPriorities? feeRates;
|
||||||
int feeRate(TransactionPriority priority) => feeRates![priority];
|
|
||||||
|
int feeRate(TransactionPriority priority) {
|
||||||
|
if (priority is ElectrumTransactionPriority && feeRates is BitcoinTransactionPriorities) {
|
||||||
|
final rates = feeRates as BitcoinTransactionPriorities;
|
||||||
|
|
||||||
|
switch (priority) {
|
||||||
|
case ElectrumTransactionPriority.slow:
|
||||||
|
return rates.normal;
|
||||||
|
case ElectrumTransactionPriority.medium:
|
||||||
|
return rates.elevated;
|
||||||
|
case ElectrumTransactionPriority.fast:
|
||||||
|
return rates.priority;
|
||||||
|
case ElectrumTransactionPriority.custom:
|
||||||
|
return rates.custom;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return feeRates![priority];
|
||||||
|
}
|
||||||
|
|
||||||
@observable
|
@observable
|
||||||
List<String> scripthashesListening;
|
List<String> scripthashesListening;
|
||||||
|
|
||||||
bool _chainTipListenerOn = false;
|
bool _chainTipListenerOn = false;
|
||||||
bool _isTransactionUpdating;
|
|
||||||
bool _isInitialSync = true;
|
bool _isInitialSync = true;
|
||||||
|
|
||||||
void Function(FlutterErrorDetails)? _onError;
|
void Function(FlutterErrorDetails)? _onError;
|
||||||
|
@ -361,13 +360,12 @@ abstract class ElectrumWalletBase
|
||||||
// INFO: FOURTH: Finish with unspents
|
// INFO: FOURTH: Finish with unspents
|
||||||
await updateAllUnspents();
|
await updateAllUnspents();
|
||||||
|
|
||||||
|
await updateFeeRates();
|
||||||
|
|
||||||
|
_updateFeeRateTimer ??=
|
||||||
|
Timer.periodic(const Duration(seconds: 5), (timer) async => await updateFeeRates());
|
||||||
|
|
||||||
_isInitialSync = false;
|
_isInitialSync = false;
|
||||||
|
|
||||||
// await updateFeeRates();
|
|
||||||
|
|
||||||
// _updateFeeRateTimer ??=
|
|
||||||
// Timer.periodic(const Duration(seconds: 5), (timer) async => await updateFeeRates());
|
|
||||||
|
|
||||||
syncStatus = SyncedSyncStatus();
|
syncStatus = SyncedSyncStatus();
|
||||||
|
|
||||||
await save();
|
await save();
|
||||||
|
@ -385,44 +383,18 @@ abstract class ElectrumWalletBase
|
||||||
|
|
||||||
@action
|
@action
|
||||||
Future<void> updateFeeRates() async {
|
Future<void> updateFeeRates() async {
|
||||||
try {
|
workerSendPort!.send(
|
||||||
// feeRates = BitcoinElectrumTransactionPriorities.fromList(
|
ElectrumWorkerGetFeesRequest(mempoolAPIEnabled: mempoolAPIEnabled).toJson(),
|
||||||
// await electrumClient2!.getFeeRates(),
|
);
|
||||||
// );
|
}
|
||||||
} catch (e, stacktrace) {
|
|
||||||
// _onError?.call(FlutterErrorDetails(
|
@action
|
||||||
// exception: e,
|
Future<void> onFeesResponse(TransactionPriorities result) async {
|
||||||
// stack: stacktrace,
|
feeRates = result;
|
||||||
// library: this.runtimeType.toString(),
|
|
||||||
// ));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Node? node;
|
Node? node;
|
||||||
|
|
||||||
Future<bool> getNodeIsElectrs() async {
|
|
||||||
return true;
|
|
||||||
if (node == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// final version = await electrumClient.version();
|
|
||||||
|
|
||||||
if (version.isNotEmpty) {
|
|
||||||
final server = version[0];
|
|
||||||
|
|
||||||
if (server.toLowerCase().contains('electrs')) {
|
|
||||||
node!.isElectrs = true;
|
|
||||||
node!.save();
|
|
||||||
return node!.isElectrs!;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
node!.isElectrs = false;
|
|
||||||
node!.save();
|
|
||||||
return node!.isElectrs!;
|
|
||||||
}
|
|
||||||
|
|
||||||
@action
|
@action
|
||||||
@override
|
@override
|
||||||
Future<void> connectToNode({required Node node}) async {
|
Future<void> connectToNode({required Node node}) async {
|
||||||
|
@ -520,11 +492,14 @@ abstract class ElectrumWalletBase
|
||||||
spendsSilentPayment = true;
|
spendsSilentPayment = true;
|
||||||
isSilentPayment = true;
|
isSilentPayment = true;
|
||||||
} else if (!isHardwareWallet) {
|
} else if (!isHardwareWallet) {
|
||||||
privkey = ECPrivate.fromBip32(
|
final addressRecord = (utx.bitcoinAddressRecord as BitcoinAddressRecord);
|
||||||
bip32: walletAddresses.bip32,
|
final path = addressRecord.derivationInfo.derivationPath
|
||||||
account: BitcoinAddressUtils.getAccountFromChange(utx.bitcoinAddressRecord.isChange),
|
.addElem(Bip32KeyIndex(
|
||||||
index: utx.bitcoinAddressRecord.index,
|
BitcoinAddressUtils.getAccountFromChange(addressRecord.isChange),
|
||||||
);
|
))
|
||||||
|
.addElem(Bip32KeyIndex(addressRecord.index));
|
||||||
|
|
||||||
|
privkey = ECPrivate.fromBip32(bip32: bip32.derive(path));
|
||||||
}
|
}
|
||||||
|
|
||||||
vinOutpoints.add(Outpoint(txid: utx.hash, index: utx.vout));
|
vinOutpoints.add(Outpoint(txid: utx.hash, index: utx.vout));
|
||||||
|
@ -1110,7 +1085,7 @@ abstract class ElectrumWalletBase
|
||||||
@override
|
@override
|
||||||
int calculateEstimatedFee(TransactionPriority? priority, int? amount,
|
int calculateEstimatedFee(TransactionPriority? priority, int? amount,
|
||||||
{int? outputsCount, int? size}) {
|
{int? outputsCount, int? size}) {
|
||||||
if (priority is BitcoinMempoolAPITransactionPriority) {
|
if (priority is BitcoinTransactionPriority) {
|
||||||
return calculateEstimatedFeeWithFeeRate(
|
return calculateEstimatedFeeWithFeeRate(
|
||||||
feeRate(priority),
|
feeRate(priority),
|
||||||
amount,
|
amount,
|
||||||
|
@ -1478,11 +1453,13 @@ abstract class ElectrumWalletBase
|
||||||
walletAddresses.allAddresses.firstWhere((element) => element.address == address);
|
walletAddresses.allAddresses.firstWhere((element) => element.address == address);
|
||||||
|
|
||||||
final btcAddress = RegexUtils.addressTypeFromStr(addressRecord.address, network);
|
final btcAddress = RegexUtils.addressTypeFromStr(addressRecord.address, network);
|
||||||
final privkey = ECPrivate.fromBip32(
|
final path = addressRecord.derivationInfo.derivationPath
|
||||||
bip32: walletAddresses.bip32,
|
.addElem(Bip32KeyIndex(
|
||||||
account: addressRecord.isChange ? 1 : 0,
|
BitcoinAddressUtils.getAccountFromChange(addressRecord.isChange),
|
||||||
index: addressRecord.index,
|
))
|
||||||
);
|
.addElem(Bip32KeyIndex(addressRecord.index));
|
||||||
|
|
||||||
|
final privkey = ECPrivate.fromBip32(bip32: bip32.derive(path));
|
||||||
|
|
||||||
privateKeys.add(privkey);
|
privateKeys.add(privkey);
|
||||||
|
|
||||||
|
@ -1694,10 +1671,7 @@ abstract class ElectrumWalletBase
|
||||||
|
|
||||||
unspentCoins.forInfo(unspentCoinsInfo.values).forEach((unspentCoinInfo) {
|
unspentCoins.forInfo(unspentCoinsInfo.values).forEach((unspentCoinInfo) {
|
||||||
if (unspentCoinInfo.isFrozen) {
|
if (unspentCoinInfo.isFrozen) {
|
||||||
// TODO: verify this works well
|
|
||||||
totalFrozen += unspentCoinInfo.value;
|
totalFrozen += unspentCoinInfo.value;
|
||||||
totalConfirmed -= unspentCoinInfo.value;
|
|
||||||
totalUnconfirmed -= unspentCoinInfo.value;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1835,7 +1809,6 @@ abstract class ElectrumWalletBase
|
||||||
if (syncStatus is ConnectingSyncStatus || isDisconnectedStatus) {
|
if (syncStatus is ConnectingSyncStatus || isDisconnectedStatus) {
|
||||||
// Needs to re-subscribe to all scripthashes when reconnected
|
// Needs to re-subscribe to all scripthashes when reconnected
|
||||||
scripthashesListening = [];
|
scripthashesListening = [];
|
||||||
_isTransactionUpdating = false;
|
|
||||||
_chainTipListenerOn = false;
|
_chainTipListenerOn = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -605,6 +605,10 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
|
||||||
@action
|
@action
|
||||||
Future<void> generateInitialAddresses({required BitcoinAddressType type}) async {
|
Future<void> generateInitialAddresses({required BitcoinAddressType type}) async {
|
||||||
for (final derivationType in hdWallets.keys) {
|
for (final derivationType in hdWallets.keys) {
|
||||||
|
if (derivationType == CWBitcoinDerivationType.old && type == SegwitAddresType.p2wpkh) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
final derivationInfo = BitcoinAddressUtils.getDerivationFromType(
|
final derivationInfo = BitcoinAddressUtils.getDerivationFromType(
|
||||||
type,
|
type,
|
||||||
isElectrum: derivationType == CWBitcoinDerivationType.electrum,
|
isElectrum: derivationType == CWBitcoinDerivationType.electrum,
|
||||||
|
|
|
@ -5,6 +5,7 @@ import 'dart:isolate';
|
||||||
import 'package:bitcoin_base/bitcoin_base.dart';
|
import 'package:bitcoin_base/bitcoin_base.dart';
|
||||||
import 'package:blockchain_utils/blockchain_utils.dart';
|
import 'package:blockchain_utils/blockchain_utils.dart';
|
||||||
import 'package:cw_bitcoin/bitcoin_address_record.dart';
|
import 'package:cw_bitcoin/bitcoin_address_record.dart';
|
||||||
|
import 'package:cw_bitcoin/bitcoin_transaction_priority.dart';
|
||||||
import 'package:cw_bitcoin/bitcoin_unspent.dart';
|
import 'package:cw_bitcoin/bitcoin_unspent.dart';
|
||||||
import 'package:cw_core/get_height_by_date.dart';
|
import 'package:cw_core/get_height_by_date.dart';
|
||||||
import 'package:cw_bitcoin/electrum_balance.dart';
|
import 'package:cw_bitcoin/electrum_balance.dart';
|
||||||
|
@ -21,6 +22,7 @@ import 'package:sp_scanner/sp_scanner.dart';
|
||||||
class ElectrumWorker {
|
class ElectrumWorker {
|
||||||
final SendPort sendPort;
|
final SendPort sendPort;
|
||||||
ElectrumApiProvider? _electrumClient;
|
ElectrumApiProvider? _electrumClient;
|
||||||
|
BasedUtxoNetwork? _network;
|
||||||
|
|
||||||
ElectrumWorker._(this.sendPort, {ElectrumApiProvider? electrumClient})
|
ElectrumWorker._(this.sendPort, {ElectrumApiProvider? electrumClient})
|
||||||
: _electrumClient = electrumClient;
|
: _electrumClient = electrumClient;
|
||||||
|
@ -100,6 +102,16 @@ class ElectrumWorker {
|
||||||
ElectrumWorkerTweaksSubscribeRequest.fromJson(messageJson),
|
ElectrumWorkerTweaksSubscribeRequest.fromJson(messageJson),
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
case ElectrumRequestMethods.estimateFeeMethod:
|
||||||
|
await _handleGetFeeRates(
|
||||||
|
ElectrumWorkerGetFeesRequest.fromJson(messageJson),
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case ElectrumRequestMethods.versionMethod:
|
||||||
|
await _handleGetVersion(
|
||||||
|
ElectrumWorkerGetVersionRequest.fromJson(messageJson),
|
||||||
|
);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
print(s);
|
print(s);
|
||||||
|
@ -108,6 +120,8 @@ class ElectrumWorker {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _handleConnect(ElectrumWorkerConnectionRequest request) async {
|
Future<void> _handleConnect(ElectrumWorkerConnectionRequest request) async {
|
||||||
|
_network = request.network;
|
||||||
|
|
||||||
_electrumClient = await ElectrumApiProvider.connect(
|
_electrumClient = await ElectrumApiProvider.connect(
|
||||||
ElectrumTCPService.connect(
|
ElectrumTCPService.connect(
|
||||||
request.uri,
|
request.uri,
|
||||||
|
@ -415,6 +429,56 @@ class ElectrumWorker {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> _handleGetFeeRates(ElectrumWorkerGetFeesRequest request) async {
|
||||||
|
if (request.mempoolAPIEnabled) {
|
||||||
|
try {
|
||||||
|
final recommendedFees = await ApiProvider.fromMempool(
|
||||||
|
_network!,
|
||||||
|
baseUrl: "http://mempool.cakewallet.com:8999/api",
|
||||||
|
).getRecommendedFeeRate();
|
||||||
|
|
||||||
|
final unimportantFee = recommendedFees.economyFee!.satoshis;
|
||||||
|
final normalFee = recommendedFees.low.satoshis;
|
||||||
|
int elevatedFee = recommendedFees.medium.satoshis;
|
||||||
|
int priorityFee = recommendedFees.high.satoshis;
|
||||||
|
|
||||||
|
// Bitcoin only: adjust fee rates to avoid equal fee values
|
||||||
|
// elevated fee should be higher than normal fee
|
||||||
|
if (normalFee == elevatedFee) {
|
||||||
|
elevatedFee++;
|
||||||
|
}
|
||||||
|
// priority fee should be higher than elevated fee
|
||||||
|
while (priorityFee <= elevatedFee) {
|
||||||
|
priorityFee++;
|
||||||
|
}
|
||||||
|
// this guarantees that, even if all fees are low and equal,
|
||||||
|
// higher priority fee txs can be consumed when chain fees start surging
|
||||||
|
|
||||||
|
_sendResponse(
|
||||||
|
ElectrumWorkerGetFeesResponse(
|
||||||
|
result: BitcoinTransactionPriorities(
|
||||||
|
unimportant: unimportantFee,
|
||||||
|
normal: normalFee,
|
||||||
|
elevated: elevatedFee,
|
||||||
|
priority: priorityFee,
|
||||||
|
custom: unimportantFee,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
_sendError(ElectrumWorkerGetFeesError(error: e.toString()));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_sendResponse(
|
||||||
|
ElectrumWorkerGetFeesResponse(
|
||||||
|
result: ElectrumTransactionPriorities.fromList(
|
||||||
|
await _electrumClient!.getFeeRates(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> _handleScanSilentPayments(ElectrumWorkerTweaksSubscribeRequest request) async {
|
Future<void> _handleScanSilentPayments(ElectrumWorkerTweaksSubscribeRequest request) async {
|
||||||
final scanData = request.scanData;
|
final scanData = request.scanData;
|
||||||
int syncHeight = scanData.height;
|
int syncHeight = scanData.height;
|
||||||
|
@ -446,7 +510,6 @@ class ElectrumWorker {
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
|
|
||||||
print([syncHeight, initialCount]);
|
|
||||||
final listener = await _electrumClient!.subscribe(
|
final listener = await _electrumClient!.subscribe(
|
||||||
ElectrumTweaksSubscribe(height: syncHeight, count: initialCount),
|
ElectrumTweaksSubscribe(height: syncHeight, count: initialCount),
|
||||||
);
|
);
|
||||||
|
@ -578,12 +641,17 @@ class ElectrumWorker {
|
||||||
}
|
}
|
||||||
|
|
||||||
listener?.call(listenFn);
|
listener?.call(listenFn);
|
||||||
|
}
|
||||||
|
|
||||||
// if (tweaksSubscription == null) {
|
Future<void> _handleGetVersion(ElectrumWorkerGetVersionRequest request) async {
|
||||||
// return scanData.sendPort.send(
|
_sendResponse(ElectrumWorkerGetVersionResponse(
|
||||||
// SyncResponse(syncHeight, UnsupportedSyncStatus()),
|
result: (await _electrumClient!.request(
|
||||||
// );
|
ElectrumVersion(
|
||||||
// }
|
clientName: "",
|
||||||
|
protocolVersion: ["1.4"],
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
id: request.id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
60
cw_bitcoin/lib/electrum_worker/methods/get_fees.dart
Normal file
60
cw_bitcoin/lib/electrum_worker/methods/get_fees.dart
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
part of 'methods.dart';
|
||||||
|
|
||||||
|
class ElectrumWorkerGetFeesRequest implements ElectrumWorkerRequest {
|
||||||
|
ElectrumWorkerGetFeesRequest({
|
||||||
|
required this.mempoolAPIEnabled,
|
||||||
|
this.id,
|
||||||
|
});
|
||||||
|
|
||||||
|
final bool mempoolAPIEnabled;
|
||||||
|
final int? id;
|
||||||
|
|
||||||
|
@override
|
||||||
|
final String method = ElectrumRequestMethods.estimateFee.method;
|
||||||
|
|
||||||
|
@override
|
||||||
|
factory ElectrumWorkerGetFeesRequest.fromJson(Map<String, dynamic> json) {
|
||||||
|
return ElectrumWorkerGetFeesRequest(
|
||||||
|
mempoolAPIEnabled: json['mempoolAPIEnabled'] as bool,
|
||||||
|
id: json['id'] as int?,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return {'method': method, 'mempoolAPIEnabled': mempoolAPIEnabled};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ElectrumWorkerGetFeesError extends ElectrumWorkerErrorResponse {
|
||||||
|
ElectrumWorkerGetFeesError({
|
||||||
|
required super.error,
|
||||||
|
super.id,
|
||||||
|
}) : super();
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get method => ElectrumRequestMethods.estimateFee.method;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ElectrumWorkerGetFeesResponse
|
||||||
|
extends ElectrumWorkerResponse<TransactionPriorities, Map<String, int>> {
|
||||||
|
ElectrumWorkerGetFeesResponse({
|
||||||
|
required super.result,
|
||||||
|
super.error,
|
||||||
|
super.id,
|
||||||
|
}) : super(method: ElectrumRequestMethods.estimateFee.method);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, int> resultJson(result) {
|
||||||
|
return result.toJson();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
factory ElectrumWorkerGetFeesResponse.fromJson(Map<String, dynamic> json) {
|
||||||
|
return ElectrumWorkerGetFeesResponse(
|
||||||
|
result: deserializeTransactionPriorities(json['result'] as Map<String, dynamic>),
|
||||||
|
error: json['error'] as String?,
|
||||||
|
id: json['id'] as int?,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,6 +6,8 @@ import 'package:cw_bitcoin/electrum_worker/electrum_worker_params.dart';
|
||||||
import 'package:cw_bitcoin/electrum_transaction_info.dart';
|
import 'package:cw_bitcoin/electrum_transaction_info.dart';
|
||||||
import 'package:cw_core/wallet_type.dart';
|
import 'package:cw_core/wallet_type.dart';
|
||||||
import 'package:cw_core/sync_status.dart';
|
import 'package:cw_core/sync_status.dart';
|
||||||
|
import 'package:cw_core/transaction_priority.dart';
|
||||||
|
import 'package:cw_bitcoin/bitcoin_transaction_priority.dart';
|
||||||
|
|
||||||
part 'connection.dart';
|
part 'connection.dart';
|
||||||
part 'headers_subscribe.dart';
|
part 'headers_subscribe.dart';
|
||||||
|
@ -16,3 +18,5 @@ part 'get_tx_expanded.dart';
|
||||||
part 'broadcast.dart';
|
part 'broadcast.dart';
|
||||||
part 'list_unspent.dart';
|
part 'list_unspent.dart';
|
||||||
part 'tweaks_subscribe.dart';
|
part 'tweaks_subscribe.dart';
|
||||||
|
part 'get_fees.dart';
|
||||||
|
part 'version.dart';
|
||||||
|
|
52
cw_bitcoin/lib/electrum_worker/methods/version.dart
Normal file
52
cw_bitcoin/lib/electrum_worker/methods/version.dart
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
part of 'methods.dart';
|
||||||
|
|
||||||
|
class ElectrumWorkerGetVersionRequest implements ElectrumWorkerRequest {
|
||||||
|
ElectrumWorkerGetVersionRequest({this.id});
|
||||||
|
|
||||||
|
final int? id;
|
||||||
|
|
||||||
|
@override
|
||||||
|
final String method = ElectrumRequestMethods.version.method;
|
||||||
|
|
||||||
|
@override
|
||||||
|
factory ElectrumWorkerGetVersionRequest.fromJson(Map<String, dynamic> json) {
|
||||||
|
return ElectrumWorkerGetVersionRequest(id: json['id'] as int?);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return {'method': method};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ElectrumWorkerGetVersionError extends ElectrumWorkerErrorResponse {
|
||||||
|
ElectrumWorkerGetVersionError({
|
||||||
|
required super.error,
|
||||||
|
super.id,
|
||||||
|
}) : super();
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get method => ElectrumRequestMethods.version.method;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ElectrumWorkerGetVersionResponse extends ElectrumWorkerResponse<List<String>, List<String>> {
|
||||||
|
ElectrumWorkerGetVersionResponse({
|
||||||
|
required super.result,
|
||||||
|
super.error,
|
||||||
|
super.id,
|
||||||
|
}) : super(method: ElectrumRequestMethods.version.method);
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<String> resultJson(result) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
factory ElectrumWorkerGetVersionResponse.fromJson(Map<String, dynamic> json) {
|
||||||
|
return ElectrumWorkerGetVersionResponse(
|
||||||
|
result: json['result'] as List<String>,
|
||||||
|
error: json['error'] as String?,
|
||||||
|
id: json['id'] as int?,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -877,13 +877,13 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int feeRate(TransactionPriority priority) {
|
int feeRate(TransactionPriority priority) {
|
||||||
if (priority is LitecoinTransactionPriority) {
|
if (priority is ElectrumTransactionPriority) {
|
||||||
switch (priority) {
|
switch (priority) {
|
||||||
case LitecoinTransactionPriority.slow:
|
case ElectrumTransactionPriority.slow:
|
||||||
return 1;
|
return 1;
|
||||||
case LitecoinTransactionPriority.medium:
|
case ElectrumTransactionPriority.medium:
|
||||||
return 2;
|
return 2;
|
||||||
case LitecoinTransactionPriority.fast:
|
case ElectrumTransactionPriority.fast:
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1036,11 +1036,12 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
|
||||||
witnesses: tx2.inputs.asMap().entries.map((e) {
|
witnesses: tx2.inputs.asMap().entries.map((e) {
|
||||||
final utxo = unspentCoins
|
final utxo = unspentCoins
|
||||||
.firstWhere((utxo) => utxo.hash == e.value.txId && utxo.vout == e.value.txIndex);
|
.firstWhere((utxo) => utxo.hash == e.value.txId && utxo.vout == e.value.txIndex);
|
||||||
final key = ECPrivate.fromBip32(
|
final addressRecord = (utxo.bitcoinAddressRecord as BitcoinAddressRecord);
|
||||||
bip32: walletAddresses.bip32,
|
final path = addressRecord.derivationInfo.derivationPath
|
||||||
account: BitcoinAddressUtils.getAccountFromChange(utxo.bitcoinAddressRecord.isChange),
|
.addElem(
|
||||||
index: utxo.bitcoinAddressRecord.index,
|
Bip32KeyIndex(BitcoinAddressUtils.getAccountFromChange(addressRecord.isChange)))
|
||||||
);
|
.addElem(Bip32KeyIndex(addressRecord.index));
|
||||||
|
final key = ECPrivate.fromBip32(bip32: bip32.derive(path));
|
||||||
final digest = tx2.getTransactionSegwitDigit(
|
final digest = tx2.getTransactionSegwitDigit(
|
||||||
txInIndex: e.key,
|
txInIndex: e.key,
|
||||||
script: key.getPublic().toP2pkhAddress().toScriptPubKey(),
|
script: key.getPublic().toP2pkhAddress().toScriptPubKey(),
|
||||||
|
|
|
@ -209,13 +209,13 @@ abstract class BitcoinCashWalletBase extends ElectrumWallet with Store {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int feeRate(TransactionPriority priority) {
|
int feeRate(TransactionPriority priority) {
|
||||||
if (priority is BitcoinCashTransactionPriority) {
|
if (priority is ElectrumTransactionPriority) {
|
||||||
switch (priority) {
|
switch (priority) {
|
||||||
case BitcoinCashTransactionPriority.slow:
|
case ElectrumTransactionPriority.slow:
|
||||||
return 1;
|
return 1;
|
||||||
case BitcoinCashTransactionPriority.medium:
|
case ElectrumTransactionPriority.medium:
|
||||||
return 5;
|
return 5;
|
||||||
case BitcoinCashTransactionPriority.fast:
|
case ElectrumTransactionPriority.fast:
|
||||||
return 10;
|
return 10;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,4 +13,8 @@ abstract class TransactionPriorities {
|
||||||
const TransactionPriorities();
|
const TransactionPriorities();
|
||||||
int operator [](TransactionPriority type);
|
int operator [](TransactionPriority type);
|
||||||
String labelWithRate(TransactionPriority type);
|
String labelWithRate(TransactionPriority type);
|
||||||
|
Map<String, int> toJson();
|
||||||
|
factory TransactionPriorities.fromJson(Map<String, int> json) {
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ class CWBitcoin extends Bitcoin {
|
||||||
name: name, hwAccountData: accountData, walletInfo: walletInfo);
|
name: name, hwAccountData: accountData, walletInfo: walletInfo);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
TransactionPriority getMediumTransactionPriority() => BitcoinElectrumTransactionPriority.elevated;
|
TransactionPriority getMediumTransactionPriority() => ElectrumTransactionPriority.medium;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<String> getWordList() => wordlist;
|
List<String> getWordList() => wordlist;
|
||||||
|
@ -70,18 +70,18 @@ class CWBitcoin extends Bitcoin {
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<TransactionPriority> getTransactionPriorities() => BitcoinElectrumTransactionPriority.all;
|
List<TransactionPriority> getTransactionPriorities() => ElectrumTransactionPriority.all;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<TransactionPriority> getLitecoinTransactionPriorities() => LitecoinTransactionPriority.all;
|
List<TransactionPriority> getLitecoinTransactionPriorities() => ElectrumTransactionPriority.all;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
TransactionPriority deserializeBitcoinTransactionPriority(int raw) =>
|
TransactionPriority deserializeBitcoinTransactionPriority(int raw) =>
|
||||||
BitcoinElectrumTransactionPriority.deserialize(raw: raw);
|
ElectrumTransactionPriority.deserialize(raw: raw);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
TransactionPriority deserializeLitecoinTransactionPriority(int raw) =>
|
TransactionPriority deserializeLitecoinTransactionPriority(int raw) =>
|
||||||
LitecoinTransactionPriority.deserialize(raw: raw);
|
ElectrumTransactionPriority.deserialize(raw: raw);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int getFeeRate(Object wallet, TransactionPriority priority) {
|
int getFeeRate(Object wallet, TransactionPriority priority) {
|
||||||
|
@ -111,7 +111,7 @@ class CWBitcoin extends Bitcoin {
|
||||||
UnspentCoinType coinTypeToSpendFrom = UnspentCoinType.any,
|
UnspentCoinType coinTypeToSpendFrom = UnspentCoinType.any,
|
||||||
}) {
|
}) {
|
||||||
final bitcoinFeeRate =
|
final bitcoinFeeRate =
|
||||||
priority == BitcoinElectrumTransactionPriority.custom && feeRate != null ? feeRate : null;
|
priority == ElectrumTransactionPriority.custom && feeRate != null ? feeRate : null;
|
||||||
return BitcoinTransactionCredentials(
|
return BitcoinTransactionCredentials(
|
||||||
outputs
|
outputs
|
||||||
.map((out) => OutputInfo(
|
.map((out) => OutputInfo(
|
||||||
|
@ -125,7 +125,7 @@ class CWBitcoin extends Bitcoin {
|
||||||
formattedCryptoAmount: out.formattedCryptoAmount,
|
formattedCryptoAmount: out.formattedCryptoAmount,
|
||||||
memo: out.memo))
|
memo: out.memo))
|
||||||
.toList(),
|
.toList(),
|
||||||
priority: priority as BitcoinElectrumTransactionPriority,
|
priority: priority as ElectrumTransactionPriority,
|
||||||
feeRate: bitcoinFeeRate,
|
feeRate: bitcoinFeeRate,
|
||||||
coinTypeToSpendFrom: coinTypeToSpendFrom,
|
coinTypeToSpendFrom: coinTypeToSpendFrom,
|
||||||
);
|
);
|
||||||
|
@ -165,12 +165,7 @@ class CWBitcoin extends Bitcoin {
|
||||||
final p2shAddr = sk.getPublic().toP2pkhInP2sh();
|
final p2shAddr = sk.getPublic().toP2pkhInP2sh();
|
||||||
final estimatedTx = await electrumWallet.estimateSendAllTx(
|
final estimatedTx = await electrumWallet.estimateSendAllTx(
|
||||||
[BitcoinOutput(address: p2shAddr, value: BigInt.zero)],
|
[BitcoinOutput(address: p2shAddr, value: BigInt.zero)],
|
||||||
getFeeRate(
|
getFeeRate(wallet, priority),
|
||||||
wallet,
|
|
||||||
wallet.type == WalletType.litecoin
|
|
||||||
? priority as LitecoinTransactionPriority
|
|
||||||
: priority as BitcoinElectrumTransactionPriority,
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return estimatedTx.amount;
|
return estimatedTx.amount;
|
||||||
|
@ -200,7 +195,7 @@ class CWBitcoin extends Bitcoin {
|
||||||
@override
|
@override
|
||||||
String bitcoinTransactionPriorityWithLabel(TransactionPriority priority, int rate,
|
String bitcoinTransactionPriorityWithLabel(TransactionPriority priority, int rate,
|
||||||
{int? customRate}) =>
|
{int? customRate}) =>
|
||||||
(priority as BitcoinElectrumTransactionPriority).labelWithRate(rate, customRate);
|
(priority as ElectrumTransactionPriority).labelWithRate(rate, customRate);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<BitcoinUnspent> getUnspents(Object wallet,
|
List<BitcoinUnspent> getUnspents(Object wallet,
|
||||||
|
@ -256,22 +251,19 @@ class CWBitcoin extends Bitcoin {
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
TransactionPriority getBitcoinTransactionPriorityMedium() =>
|
TransactionPriority getBitcoinTransactionPriorityMedium() => ElectrumTransactionPriority.fast;
|
||||||
BitcoinElectrumTransactionPriority.elevated;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
TransactionPriority getBitcoinTransactionPriorityCustom() =>
|
TransactionPriority getBitcoinTransactionPriorityCustom() => ElectrumTransactionPriority.custom;
|
||||||
BitcoinElectrumTransactionPriority.custom;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
TransactionPriority getLitecoinTransactionPriorityMedium() => LitecoinTransactionPriority.medium;
|
TransactionPriority getLitecoinTransactionPriorityMedium() => ElectrumTransactionPriority.medium;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
TransactionPriority getBitcoinTransactionPrioritySlow() =>
|
TransactionPriority getBitcoinTransactionPrioritySlow() => ElectrumTransactionPriority.medium;
|
||||||
BitcoinElectrumTransactionPriority.normal;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
TransactionPriority getLitecoinTransactionPrioritySlow() => LitecoinTransactionPriority.slow;
|
TransactionPriority getLitecoinTransactionPrioritySlow() => ElectrumTransactionPriority.slow;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> setAddressType(Object wallet, dynamic option) async {
|
Future<void> setAddressType(Object wallet, dynamic option) async {
|
||||||
|
@ -436,7 +428,7 @@ class CWBitcoin extends Bitcoin {
|
||||||
{int? size}) {
|
{int? size}) {
|
||||||
final bitcoinWallet = wallet as ElectrumWallet;
|
final bitcoinWallet = wallet as ElectrumWallet;
|
||||||
return bitcoinWallet.feeAmountForPriority(
|
return bitcoinWallet.feeAmountForPriority(
|
||||||
priority as BitcoinElectrumTransactionPriority, inputsCount, outputsCount);
|
priority as ElectrumTransactionPriority, inputsCount, outputsCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -460,8 +452,13 @@ class CWBitcoin extends Bitcoin {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int getMaxCustomFeeRate(Object wallet) {
|
int getMaxCustomFeeRate(Object wallet) {
|
||||||
final bitcoinWallet = wallet as ElectrumWallet;
|
final electrumWallet = wallet as ElectrumWallet;
|
||||||
return (bitcoinWallet.feeRate(BitcoinElectrumTransactionPriority.priority) * 10).round();
|
final feeRates = electrumWallet.feeRates;
|
||||||
|
final maxFee = electrumWallet.feeRates is ElectrumTransactionPriorities
|
||||||
|
? ElectrumTransactionPriority.fast
|
||||||
|
: BitcoinTransactionPriority.priority;
|
||||||
|
|
||||||
|
return (electrumWallet.feeRate(maxFee) * 10).round();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
|
@ -48,15 +48,14 @@ class CWBitcoinCash extends BitcoinCash {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
TransactionPriority deserializeBitcoinCashTransactionPriority(int raw) =>
|
TransactionPriority deserializeBitcoinCashTransactionPriority(int raw) =>
|
||||||
BitcoinCashTransactionPriority.deserialize(raw: raw);
|
ElectrumTransactionPriority.deserialize(raw: raw);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
TransactionPriority getDefaultTransactionPriority() => BitcoinCashTransactionPriority.medium;
|
TransactionPriority getDefaultTransactionPriority() => ElectrumTransactionPriority.medium;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<TransactionPriority> getTransactionPriorities() => BitcoinCashTransactionPriority.all;
|
List<TransactionPriority> getTransactionPriorities() => ElectrumTransactionPriority.all;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
TransactionPriority getBitcoinCashTransactionPrioritySlow() =>
|
TransactionPriority getBitcoinCashTransactionPrioritySlow() => ElectrumTransactionPriority.slow;
|
||||||
BitcoinCashTransactionPriority.slow;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -602,8 +602,7 @@ abstract class SettingsStoreBase with Store {
|
||||||
static const defaultActionsMode = 11;
|
static const defaultActionsMode = 11;
|
||||||
static const defaultPinCodeTimeOutDuration = PinCodeRequiredDuration.tenMinutes;
|
static const defaultPinCodeTimeOutDuration = PinCodeRequiredDuration.tenMinutes;
|
||||||
static const defaultAutoGenerateSubaddressStatus = AutoGenerateSubaddressStatus.initialized;
|
static const defaultAutoGenerateSubaddressStatus = AutoGenerateSubaddressStatus.initialized;
|
||||||
// static final walletPasswordDirectInput = Platform.isLinux;
|
static final walletPasswordDirectInput = Platform.isLinux;
|
||||||
static final walletPasswordDirectInput = false;
|
|
||||||
static const defaultSeedPhraseLength = SeedPhraseLength.twelveWords;
|
static const defaultSeedPhraseLength = SeedPhraseLength.twelveWords;
|
||||||
static const defaultMoneroSeedType = MoneroSeedType.defaultSeedType;
|
static const defaultMoneroSeedType = MoneroSeedType.defaultSeedType;
|
||||||
static const defaultBitcoinSeedType = BitcoinSeedType.defaultDerivationType;
|
static const defaultBitcoinSeedType = BitcoinSeedType.defaultDerivationType;
|
||||||
|
|
Loading…
Reference in a new issue