mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2024-12-23 03:59:23 +00:00
fix: some fixes for stored silent payment data, and fee usage
This commit is contained in:
parent
ea2161010f
commit
c74e335876
4 changed files with 149 additions and 50 deletions
|
@ -8,16 +8,30 @@ class BitcoinUnspent extends Unspent {
|
||||||
: bitcoinAddressRecord = addressRecord,
|
: bitcoinAddressRecord = addressRecord,
|
||||||
super(addressRecord.address, hash, value, vout, null);
|
super(addressRecord.address, hash, value, vout, null);
|
||||||
|
|
||||||
factory BitcoinUnspent.fromJSON(BitcoinAddressRecord address, Map<String, dynamic> json) =>
|
factory BitcoinUnspent.fromJSON(BitcoinAddressRecord? address, Map<String, dynamic> json) =>
|
||||||
BitcoinUnspent(
|
BitcoinUnspent(
|
||||||
address,
|
address ?? BitcoinAddressRecord.fromJSON(json['address_record'] as String),
|
||||||
json['tx_hash'] as String,
|
json['tx_hash'] as String,
|
||||||
json['value'] as int,
|
json['value'] as int,
|
||||||
json['tx_pos'] as int,
|
json['tx_pos'] as int,
|
||||||
silentPaymentTweak: json['silent_payment_tweak'] as String?,
|
silentPaymentTweak: json['silent_payment_tweak'] as String?,
|
||||||
type: json['type'] == null ? null : AddressType.values[json['type'] as int],
|
type: json['type'] == null
|
||||||
|
? null
|
||||||
|
: AddressType.values.firstWhere((e) => e.toString() == json['type']),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final json = <String, dynamic>{
|
||||||
|
'address_record': bitcoinAddressRecord.toJSON(),
|
||||||
|
'tx_hash': hash,
|
||||||
|
'value': value,
|
||||||
|
'tx_pos': vout,
|
||||||
|
'silent_payment_tweak': silentPaymentTweak,
|
||||||
|
'type': type.toString(),
|
||||||
|
};
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
final BitcoinAddressRecord bitcoinAddressRecord;
|
final BitcoinAddressRecord bitcoinAddressRecord;
|
||||||
String? silentPaymentTweak;
|
String? silentPaymentTweak;
|
||||||
AddressType? type;
|
AddressType? type;
|
||||||
|
|
|
@ -3,6 +3,7 @@ import 'package:bitcoin_flutter/src/payments/index.dart' show PaymentData;
|
||||||
import 'package:cw_bitcoin/address_from_output.dart';
|
import 'package:cw_bitcoin/address_from_output.dart';
|
||||||
import 'package:cw_bitcoin/bitcoin_address_record.dart';
|
import 'package:cw_bitcoin/bitcoin_address_record.dart';
|
||||||
import 'package:cw_bitcoin/bitcoin_amount_format.dart';
|
import 'package:cw_bitcoin/bitcoin_amount_format.dart';
|
||||||
|
import 'package:cw_bitcoin/bitcoin_unspent.dart';
|
||||||
import 'package:cw_core/transaction_direction.dart';
|
import 'package:cw_core/transaction_direction.dart';
|
||||||
import 'package:cw_core/transaction_info.dart';
|
import 'package:cw_core/transaction_info.dart';
|
||||||
import 'package:cw_core/format_amount.dart';
|
import 'package:cw_core/format_amount.dart';
|
||||||
|
@ -18,6 +19,8 @@ class ElectrumTransactionBundle {
|
||||||
}
|
}
|
||||||
|
|
||||||
class ElectrumTransactionInfo extends TransactionInfo {
|
class ElectrumTransactionInfo extends TransactionInfo {
|
||||||
|
BitcoinUnspent? unspent;
|
||||||
|
|
||||||
ElectrumTransactionInfo(this.type,
|
ElectrumTransactionInfo(this.type,
|
||||||
{required String id,
|
{required String id,
|
||||||
required int height,
|
required int height,
|
||||||
|
@ -26,7 +29,9 @@ class ElectrumTransactionInfo extends TransactionInfo {
|
||||||
required TransactionDirection direction,
|
required TransactionDirection direction,
|
||||||
required bool isPending,
|
required bool isPending,
|
||||||
required DateTime date,
|
required DateTime date,
|
||||||
required int confirmations}) {
|
required int confirmations,
|
||||||
|
String? to,
|
||||||
|
this.unspent}) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.height = height;
|
this.height = height;
|
||||||
this.amount = amount;
|
this.amount = amount;
|
||||||
|
@ -35,6 +40,7 @@ class ElectrumTransactionInfo extends TransactionInfo {
|
||||||
this.date = date;
|
this.date = date;
|
||||||
this.isPending = isPending;
|
this.isPending = isPending;
|
||||||
this.confirmations = confirmations;
|
this.confirmations = confirmations;
|
||||||
|
this.to = to;
|
||||||
}
|
}
|
||||||
|
|
||||||
factory ElectrumTransactionInfo.fromElectrumVerbose(Map<String, Object> obj, WalletType type,
|
factory ElectrumTransactionInfo.fromElectrumVerbose(Map<String, Object> obj, WalletType type,
|
||||||
|
@ -168,7 +174,8 @@ class ElectrumTransactionInfo extends TransactionInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
factory ElectrumTransactionInfo.fromJson(Map<String, dynamic> data, WalletType type) {
|
factory ElectrumTransactionInfo.fromJson(Map<String, dynamic> data, WalletType type) {
|
||||||
return ElectrumTransactionInfo(type,
|
return ElectrumTransactionInfo(
|
||||||
|
type,
|
||||||
id: data['id'] as String,
|
id: data['id'] as String,
|
||||||
height: data['height'] as int,
|
height: data['height'] as int,
|
||||||
amount: data['amount'] as int,
|
amount: data['amount'] as int,
|
||||||
|
@ -176,7 +183,12 @@ class ElectrumTransactionInfo extends TransactionInfo {
|
||||||
direction: parseTransactionDirectionFromInt(data['direction'] as int),
|
direction: parseTransactionDirectionFromInt(data['direction'] as int),
|
||||||
date: DateTime.fromMillisecondsSinceEpoch(data['date'] as int),
|
date: DateTime.fromMillisecondsSinceEpoch(data['date'] as int),
|
||||||
isPending: data['isPending'] as bool,
|
isPending: data['isPending'] as bool,
|
||||||
confirmations: data['confirmations'] as int);
|
confirmations: data['confirmations'] as int,
|
||||||
|
to: data['to'] as String?,
|
||||||
|
unspent: data['unspent'] != null
|
||||||
|
? BitcoinUnspent.fromJSON(null, data['unspent'] as Map<String, dynamic>)
|
||||||
|
: null,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
final WalletType type;
|
final WalletType type;
|
||||||
|
@ -220,6 +232,8 @@ class ElectrumTransactionInfo extends TransactionInfo {
|
||||||
m['isPending'] = isPending;
|
m['isPending'] = isPending;
|
||||||
m['confirmations'] = confirmations;
|
m['confirmations'] = confirmations;
|
||||||
m['fee'] = fee;
|
m['fee'] = fee;
|
||||||
|
m['to'] = to;
|
||||||
|
m['unspent'] = unspent?.toJson() ?? <String, dynamic>{};
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,8 @@ import 'dart:io';
|
||||||
import 'dart:isolate';
|
import 'dart:isolate';
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
|
import 'package:cw_core/transaction_direction.dart';
|
||||||
|
import 'package:cw_core/wallet_type.dart';
|
||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
import 'package:cw_core/unspent_coins_info.dart';
|
import 'package:cw_core/unspent_coins_info.dart';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
|
@ -165,10 +167,7 @@ abstract class ElectrumWalletBase
|
||||||
startRefresh,
|
startRefresh,
|
||||||
ScanData(
|
ScanData(
|
||||||
sendPort: receivePort.sendPort,
|
sendPort: receivePort.sendPort,
|
||||||
scanPrivkeyCompressed:
|
primarySilentAddress: walletAddresses.primarySilentAddress!,
|
||||||
walletAddresses.primarySilentAddress!.scanPrivkey.toCompressedHex().fromHex,
|
|
||||||
spendPubkeyCompressed:
|
|
||||||
walletAddresses.primarySilentAddress!.spendPubkey.toCompressedHex().fromHex,
|
|
||||||
networkType: networkType,
|
networkType: networkType,
|
||||||
height: height,
|
height: height,
|
||||||
chainTip: currentChainTip,
|
chainTip: currentChainTip,
|
||||||
|
@ -180,13 +179,31 @@ abstract class ElectrumWalletBase
|
||||||
|
|
||||||
await for (var message in receivePort) {
|
await for (var message in receivePort) {
|
||||||
if (message is BitcoinUnspent) {
|
if (message is BitcoinUnspent) {
|
||||||
|
if (!unspentCoins.any((utx) =>
|
||||||
|
utx.hash.contains(message.hash) &&
|
||||||
|
utx.vout == message.vout &&
|
||||||
|
utx.address.contains(message.address))) {
|
||||||
unspentCoins.add(message);
|
unspentCoins.add(message);
|
||||||
await _addCoinInfo(message);
|
|
||||||
balance[currency] = await _fetchBalances();
|
if (unspentCoinsInfo.values.any((element) =>
|
||||||
|
element.walletId.contains(id) &&
|
||||||
|
element.hash.contains(message.hash) &&
|
||||||
|
element.address.contains(message.address))) {
|
||||||
|
_addCoinInfo(message);
|
||||||
|
|
||||||
await walletInfo.save();
|
await walletInfo.save();
|
||||||
await save();
|
await save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
balance[currency] = await _fetchBalances();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message is Map<String, ElectrumTransactionInfo>) {
|
||||||
|
transactionHistory.addMany(message);
|
||||||
|
await transactionHistory.save();
|
||||||
|
}
|
||||||
|
|
||||||
// check if is a SyncStatus type since "is SyncStatus" doesn't work here
|
// check if is a SyncStatus type since "is SyncStatus" doesn't work here
|
||||||
if (message is SyncResponse) {
|
if (message is SyncResponse) {
|
||||||
syncStatus = message.syncStatus;
|
syncStatus = message.syncStatus;
|
||||||
|
@ -268,7 +285,7 @@ abstract class ElectrumWalletBase
|
||||||
throw BitcoinTransactionNoInputsException();
|
throw BitcoinTransactionNoInputsException();
|
||||||
}
|
}
|
||||||
|
|
||||||
final minAmount = networkType == bitcoin.testnet ? 0 : 546;
|
final minAmount = 546;
|
||||||
final transactionCredentials = credentials as BitcoinTransactionCredentials;
|
final transactionCredentials = credentials as BitcoinTransactionCredentials;
|
||||||
final outputs = transactionCredentials.outputs;
|
final outputs = transactionCredentials.outputs;
|
||||||
final hasMultiDestination = outputs.length > 1;
|
final hasMultiDestination = outputs.length > 1;
|
||||||
|
@ -284,7 +301,7 @@ abstract class ElectrumWalletBase
|
||||||
var fee = 0;
|
var fee = 0;
|
||||||
|
|
||||||
if (hasMultiDestination) {
|
if (hasMultiDestination) {
|
||||||
if (outputs.any((item) => item.sendAll || item.formattedCryptoAmount! <= 0)) {
|
if (outputs.any((item) => item.sendAll || item.formattedCryptoAmount! <= 1)) {
|
||||||
throw BitcoinTransactionWrongBalanceException(currency);
|
throw BitcoinTransactionWrongBalanceException(currency);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -324,15 +341,10 @@ abstract class ElectrumWalletBase
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fee == 0 && networkType == bitcoin.bitcoin) {
|
if (fee == 0) {
|
||||||
throw BitcoinTransactionWrongBalanceException(currency);
|
throw BitcoinTransactionWrongBalanceException(currency);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (networkType == bitcoin.testnet) {
|
|
||||||
fee += 50;
|
|
||||||
amount -= 50;
|
|
||||||
}
|
|
||||||
|
|
||||||
final totalAmount = amount + fee;
|
final totalAmount = amount + fee;
|
||||||
|
|
||||||
if ((totalAmount > balance[currency]!.confirmed || totalAmount > allInputsAmount) &&
|
if ((totalAmount > balance[currency]!.confirmed || totalAmount > allInputsAmount) &&
|
||||||
|
@ -656,6 +668,18 @@ abstract class ElectrumWalletBase
|
||||||
Future<String> makePath() async => pathForWallet(name: walletInfo.name, type: walletInfo.type);
|
Future<String> makePath() async => pathForWallet(name: walletInfo.name, type: walletInfo.type);
|
||||||
|
|
||||||
Future<void> updateUnspent() async {
|
Future<void> updateUnspent() async {
|
||||||
|
// Update unspents stored from scanned silent payment transactions
|
||||||
|
transactionHistory.transactions.values.forEach((tx) {
|
||||||
|
if (tx.unspent != null) {
|
||||||
|
if (!unspentCoins.any((utx) =>
|
||||||
|
utx.hash.contains(tx.unspent!.hash) &&
|
||||||
|
utx.vout == tx.unspent!.vout &&
|
||||||
|
utx.address.contains(tx.to!))) {
|
||||||
|
unspentCoins.add(tx.unspent!);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
final unspent = await Future.wait(walletAddresses.addresses.map((address) => electrumClient
|
final unspent = await Future.wait(walletAddresses.addresses.map((address) => electrumClient
|
||||||
.getListUnspentWithAddress(address.address, networkType)
|
.getListUnspentWithAddress(address.address, networkType)
|
||||||
.then((unspent) => unspent.map((unspent) {
|
.then((unspent) => unspent.map((unspent) {
|
||||||
|
@ -763,6 +787,7 @@ abstract class ElectrumWalletBase
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
final historiesWithDetails = await Future.wait(normalizedHistories.map((transaction) {
|
final historiesWithDetails = await Future.wait(normalizedHistories.map((transaction) {
|
||||||
try {
|
try {
|
||||||
return fetchTransactionInfo(
|
return fetchTransactionInfo(
|
||||||
|
@ -776,12 +801,25 @@ abstract class ElectrumWalletBase
|
||||||
return Future.value(null);
|
return Future.value(null);
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
transactionHistory.transactions.values.forEach((tx) {
|
||||||
|
if (tx.direction == TransactionDirection.incoming &&
|
||||||
|
!walletAddresses.addresses.any((addr) => tx.to?.contains(addr.address) ?? false))
|
||||||
|
historiesWithDetails.add(tx);
|
||||||
|
});
|
||||||
|
|
||||||
return historiesWithDetails
|
return historiesWithDetails
|
||||||
.fold<Map<String, ElectrumTransactionInfo>>(<String, ElectrumTransactionInfo>{}, (acc, tx) {
|
.fold<Map<String, ElectrumTransactionInfo>>(<String, ElectrumTransactionInfo>{}, (acc, tx) {
|
||||||
if (tx == null) {
|
if (tx == null) {
|
||||||
return acc;
|
return acc;
|
||||||
}
|
}
|
||||||
acc[tx.id] = acc[tx.id]?.updated(tx) ?? tx;
|
acc[tx.id] = acc[tx.id]?.updated(tx) ?? tx;
|
||||||
|
|
||||||
|
if (tx.to != null && tx.to!.isNotEmpty && acc[tx.id] != null) {
|
||||||
|
final updatedConf = acc[tx.id]!;
|
||||||
|
updatedConf.confirmations = walletInfo.restoreHeight - tx.height;
|
||||||
|
acc[tx.id] = updatedConf;
|
||||||
|
}
|
||||||
return acc;
|
return acc;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -824,6 +862,7 @@ abstract class ElectrumWalletBase
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
await _chainTipUpdateSubject?.close();
|
await _chainTipUpdateSubject?.close();
|
||||||
_chainTipUpdateSubject = electrumClient.chainTipUpdate();
|
_chainTipUpdateSubject = electrumClient.chainTipUpdate();
|
||||||
_chainTipUpdateSubject?.listen((_) async {
|
_chainTipUpdateSubject?.listen((_) async {
|
||||||
|
@ -856,15 +895,18 @@ abstract class ElectrumWalletBase
|
||||||
var totalConfirmed = 0;
|
var totalConfirmed = 0;
|
||||||
var totalUnconfirmed = 0;
|
var totalUnconfirmed = 0;
|
||||||
|
|
||||||
|
// Add values from unspent coins that are not fetched by the address list
|
||||||
|
// i.e. scanned silent payments
|
||||||
unspentCoinsInfo.values.forEach((info) {
|
unspentCoinsInfo.values.forEach((info) {
|
||||||
unspentCoins.forEach((element) {
|
unspentCoins.forEach((element) {
|
||||||
if (element.hash == info.hash &&
|
if (element.hash == info.hash &&
|
||||||
element.bitcoinAddressRecord.address == info.address &&
|
element.bitcoinAddressRecord.address == info.address &&
|
||||||
element.value == info.value) {
|
element.value == info.value) {
|
||||||
if (info.isFrozen) totalFrozen += element.value;
|
if (info.isFrozen) totalFrozen += element.value;
|
||||||
if (element.bitcoinAddressRecord.silentPaymentTweak != null)
|
if (element.bitcoinAddressRecord.silentPaymentTweak != null) {
|
||||||
totalConfirmed += element.value;
|
totalConfirmed += element.value;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -982,8 +1024,7 @@ Future<ElectrumTransactionBundle> getTransactionExpanded(
|
||||||
|
|
||||||
class ScanData {
|
class ScanData {
|
||||||
final SendPort sendPort;
|
final SendPort sendPort;
|
||||||
final Uint8List scanPrivkeyCompressed;
|
final bitcoin.SilentPaymentReceiver primarySilentAddress;
|
||||||
final Uint8List spendPubkeyCompressed;
|
|
||||||
final int height;
|
final int height;
|
||||||
final String node;
|
final String node;
|
||||||
final bitcoin.NetworkType networkType;
|
final bitcoin.NetworkType networkType;
|
||||||
|
@ -994,8 +1035,7 @@ class ScanData {
|
||||||
|
|
||||||
ScanData({
|
ScanData({
|
||||||
required this.sendPort,
|
required this.sendPort,
|
||||||
required this.scanPrivkeyCompressed,
|
required this.primarySilentAddress,
|
||||||
required this.spendPubkeyCompressed,
|
|
||||||
required this.height,
|
required this.height,
|
||||||
required this.node,
|
required this.node,
|
||||||
required this.networkType,
|
required this.networkType,
|
||||||
|
@ -1008,8 +1048,7 @@ class ScanData {
|
||||||
factory ScanData.fromHeight(ScanData scanData, int newHeight) {
|
factory ScanData.fromHeight(ScanData scanData, int newHeight) {
|
||||||
return ScanData(
|
return ScanData(
|
||||||
sendPort: scanData.sendPort,
|
sendPort: scanData.sendPort,
|
||||||
scanPrivkeyCompressed: scanData.scanPrivkeyCompressed,
|
primarySilentAddress: scanData.primarySilentAddress,
|
||||||
spendPubkeyCompressed: scanData.spendPubkeyCompressed,
|
|
||||||
height: newHeight,
|
height: newHeight,
|
||||||
node: scanData.node,
|
node: scanData.node,
|
||||||
networkType: scanData.networkType,
|
networkType: scanData.networkType,
|
||||||
|
@ -1179,10 +1218,10 @@ Future<void> startRefresh(ScanData scanData) async {
|
||||||
// break;
|
// break;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// final p2tr = bitcoin.P2trAddress(program: script.sublist(2).hex);
|
final p2tr = bitcoin.P2trAddress(program: script.sublist(2).hex);
|
||||||
// final address = p2tr.toAddress(scanData.networkType);
|
final address = p2tr.toAddress(scanData.networkType);
|
||||||
|
|
||||||
// print(["Verifying taproot address:", address]);
|
print(["Verifying taproot address:", address]);
|
||||||
|
|
||||||
outpointsByP2TRpubkey[script.sublist(2).hex] =
|
outpointsByP2TRpubkey[script.sublist(2).hex] =
|
||||||
bitcoin.Outpoint(txid: txid, index: i, value: output["value"] as int);
|
bitcoin.Outpoint(txid: txid, index: i, value: output["value"] as int);
|
||||||
|
@ -1198,8 +1237,10 @@ Future<void> startRefresh(ScanData scanData) async {
|
||||||
final curve = bitcoin.getSecp256k1();
|
final curve = bitcoin.getSecp256k1();
|
||||||
|
|
||||||
final result = bitcoin.scanOutputs(
|
final result = bitcoin.scanOutputs(
|
||||||
bitcoin.PrivateKey.fromHex(curve, scanData.scanPrivkeyCompressed.hex),
|
bitcoin.PrivateKey.fromHex(
|
||||||
bitcoin.PublicKey.fromHex(curve, scanData.spendPubkeyCompressed.hex),
|
curve, scanData.primarySilentAddress.scanPrivkey.toCompressedHex()),
|
||||||
|
bitcoin.PublicKey.fromHex(
|
||||||
|
curve, scanData.primarySilentAddress.spendPubkey.toCompressedHex()),
|
||||||
bitcoin.getSumInputPubKeys(pubkeys),
|
bitcoin.getSumInputPubKeys(pubkeys),
|
||||||
outpointHash,
|
outpointHash,
|
||||||
outpointsByP2TRpubkey.keys.map((e) => e.fromHex).toList(),
|
outpointsByP2TRpubkey.keys.map((e) => e.fromHex).toList(),
|
||||||
|
@ -1225,24 +1266,54 @@ Future<void> startRefresh(ScanData scanData) async {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// found utxo for tx
|
final tweak = value[0];
|
||||||
scanData.sendPort.send(BitcoinUnspent(
|
String? label;
|
||||||
|
if (value.length > 1) label = value[1];
|
||||||
|
|
||||||
|
final unspent = BitcoinUnspent(
|
||||||
BitcoinAddressRecord(
|
BitcoinAddressRecord(
|
||||||
bitcoin.P2trAddress(program: key, network: scanData.networkType)
|
bitcoin.P2trAddress(program: key, network: scanData.networkType)
|
||||||
.toAddress(scanData.networkType),
|
.toAddress(scanData.networkType),
|
||||||
index: 0,
|
index: 0,
|
||||||
isHidden: false,
|
isHidden: true,
|
||||||
isUsed: true,
|
isUsed: true,
|
||||||
silentAddressLabel: null,
|
silentAddressLabel: null,
|
||||||
silentPaymentTweak: value,
|
silentPaymentTweak: tweak,
|
||||||
type: bitcoin.AddressType.p2tr,
|
type: bitcoin.AddressType.p2tr,
|
||||||
),
|
),
|
||||||
outpoint.txid,
|
txid,
|
||||||
outpoint.value!,
|
outpoint.value!,
|
||||||
outpoint.index,
|
outpoint.index,
|
||||||
silentPaymentTweak: value,
|
silentPaymentTweak: tweak,
|
||||||
type: bitcoin.AddressType.p2tr,
|
type: bitcoin.AddressType.p2tr,
|
||||||
));
|
);
|
||||||
|
|
||||||
|
// found utxo for tx, send unspent coin to main isolate
|
||||||
|
scanData.sendPort.send(unspent);
|
||||||
|
|
||||||
|
// also send tx data for tx history
|
||||||
|
scanData.sendPort.send({
|
||||||
|
txid: ElectrumTransactionInfo(
|
||||||
|
WalletType.bitcoin,
|
||||||
|
id: txid,
|
||||||
|
height: syncHeight,
|
||||||
|
amount: outpoint.value!,
|
||||||
|
fee: 0,
|
||||||
|
direction: TransactionDirection.incoming,
|
||||||
|
isPending: false,
|
||||||
|
date:
|
||||||
|
DateTime.fromMillisecondsSinceEpoch((blockJson["timestamp"] as int) * 1000),
|
||||||
|
confirmations: currentChainTip - syncHeight,
|
||||||
|
to: bitcoin.SilentPaymentAddress.createLabeledSilentPaymentAddress(
|
||||||
|
scanData.primarySilentAddress.scanPubkey,
|
||||||
|
scanData.primarySilentAddress.spendPubkey,
|
||||||
|
label != null ? label.fromHex : "0".fromHex,
|
||||||
|
hrp: scanData.primarySilentAddress.hrp,
|
||||||
|
version: scanData.primarySilentAddress.version)
|
||||||
|
.toString(),
|
||||||
|
unspent: unspent,
|
||||||
|
)
|
||||||
|
});
|
||||||
});
|
});
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -743,7 +743,7 @@
|
||||||
"unspent_change": "Mudar",
|
"unspent_change": "Mudar",
|
||||||
"Block_remaining": "${status} bloco restante",
|
"Block_remaining": "${status} bloco restante",
|
||||||
"labeled_silent_addresses": "Endereços silenciosos rotulados",
|
"labeled_silent_addresses": "Endereços silenciosos rotulados",
|
||||||
"use_testnet": "Use testNet",
|
"use_testnet": "Use Testnet",
|
||||||
"tor_connection": "Conexão Tor",
|
"tor_connection": "Conexão Tor",
|
||||||
"seed_hex_form": "Semente de carteira (forma hexadecimal)",
|
"seed_hex_form": "Semente de carteira (forma hexadecimal)",
|
||||||
"seedtype": "SeedType",
|
"seedtype": "SeedType",
|
||||||
|
|
Loading…
Reference in a new issue