mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2025-01-22 10:45:08 +00:00
feat: new rust lib
This commit is contained in:
parent
465c7efa73
commit
a4f8cdfa99
7 changed files with 160 additions and 71 deletions
|
@ -42,6 +42,7 @@ import 'package:hive/hive.dart';
|
|||
import 'package:mobx/mobx.dart';
|
||||
import 'package:rxdart/subjects.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:sp_scanner/sp_scanner.dart';
|
||||
|
||||
part 'electrum_wallet.g.dart';
|
||||
|
||||
|
@ -223,6 +224,10 @@ abstract class ElectrumWalletBase
|
|||
transactionHistoryIds: transactionHistory.transactions.keys.toList(),
|
||||
node: ScanNode(node!.uri, node!.useSSL),
|
||||
labels: walletAddresses.labels,
|
||||
labelIndexes: walletAddresses.silentAddresses
|
||||
.where((addr) => addr.type == SilentPaymentsAddresType.p2sp && addr.index >= 1)
|
||||
.map((addr) => addr.index)
|
||||
.toList(),
|
||||
isSingleScan: doSingleScan ?? false,
|
||||
));
|
||||
|
||||
|
@ -238,6 +243,10 @@ abstract class ElectrumWalletBase
|
|||
|
||||
final existingTxInfo = transactionHistory.transactions[txid];
|
||||
if (existingTxInfo != null) {
|
||||
final addressRecord =
|
||||
walletAddresses.silentAddresses.firstWhere((addr) => addr.address == tx.to);
|
||||
addressRecord.txCount += 1;
|
||||
|
||||
existingTxInfo.amount = tx.amount;
|
||||
existingTxInfo.confirmations = tx.confirmations;
|
||||
existingTxInfo.height = tx.height;
|
||||
|
@ -1616,6 +1625,7 @@ class ScanData {
|
|||
final ElectrumClient electrumClient;
|
||||
final List<String> transactionHistoryIds;
|
||||
final Map<String, String> labels;
|
||||
final List<int> labelIndexes;
|
||||
final bool isSingleScan;
|
||||
|
||||
ScanData({
|
||||
|
@ -1628,6 +1638,7 @@ class ScanData {
|
|||
required this.electrumClient,
|
||||
required this.transactionHistoryIds,
|
||||
required this.labels,
|
||||
required this.labelIndexes,
|
||||
required this.isSingleScan,
|
||||
});
|
||||
|
||||
|
@ -1642,6 +1653,7 @@ class ScanData {
|
|||
transactionHistoryIds: scanData.transactionHistoryIds,
|
||||
electrumClient: scanData.electrumClient,
|
||||
labels: scanData.labels,
|
||||
labelIndexes: scanData.labelIndexes,
|
||||
isSingleScan: scanData.isSingleScan,
|
||||
);
|
||||
}
|
||||
|
@ -1714,8 +1726,9 @@ Future<void> startRefresh(ScanData scanData) async {
|
|||
try {
|
||||
final electrumClient = await getElectrumConnection();
|
||||
|
||||
// TODO: hardcoded values, if timed out decrease amount of blocks per request?
|
||||
final scanningBlockCount =
|
||||
scanData.isSingleScan ? 1 : (scanData.network == BitcoinNetwork.testnet ? 50 : 10);
|
||||
scanData.isSingleScan ? 1 : (scanData.network == BitcoinNetwork.testnet ? 25 : 10);
|
||||
|
||||
Map<String, dynamic>? tweaks;
|
||||
try {
|
||||
|
@ -1752,14 +1765,16 @@ Future<void> startRefresh(ScanData scanData) async {
|
|||
final tweak = details["tweak"].toString();
|
||||
|
||||
try {
|
||||
final spb = SilentPaymentBuilder(receiverTweak: tweak);
|
||||
final addToWallet = spb.scanOutputs(
|
||||
scanData.silentAddress.b_scan,
|
||||
scanData.silentAddress.B_spend,
|
||||
outputPubkeys.values
|
||||
.map((o) => getScriptFromOutput(o[0].toString(), int.parse(o[1].toString())))
|
||||
.toList(),
|
||||
precomputedLabels: scanData.labels,
|
||||
final addToWallet = scanOutputs(
|
||||
outputPubkeys.values.map((o) => o[0].toString()).toList(),
|
||||
tweak,
|
||||
Receiver(
|
||||
scanData.silentAddress.b_scan.toHex(),
|
||||
scanData.silentAddress.B_spend.toHex(),
|
||||
scanData.network == BitcoinNetwork.testnet,
|
||||
scanData.labelIndexes,
|
||||
scanData.labelIndexes.length,
|
||||
),
|
||||
);
|
||||
|
||||
if (addToWallet.isEmpty) {
|
||||
|
@ -1767,64 +1782,72 @@ Future<void> startRefresh(ScanData scanData) async {
|
|||
continue;
|
||||
}
|
||||
|
||||
addToWallet.forEach((key, value) async {
|
||||
final t_k = value.tweak;
|
||||
addToWallet.forEach((label, value) async {
|
||||
(value as Map<String, dynamic>).forEach((output, tweak) async {
|
||||
final t_k = tweak.toString();
|
||||
|
||||
final addressRecord = BitcoinSilentPaymentAddressRecord(
|
||||
value.output.address.toAddress(scanData.network),
|
||||
index: 0,
|
||||
isHidden: false,
|
||||
isUsed: true,
|
||||
network: scanData.network,
|
||||
silentPaymentTweak: t_k,
|
||||
type: SegwitAddresType.p2tr,
|
||||
);
|
||||
final receivingOutputAddress = ECPublic.fromHex(output)
|
||||
.toTaprootAddress(tweak: false)
|
||||
.toAddress(scanData.network);
|
||||
|
||||
int? amount;
|
||||
int? pos;
|
||||
outputPubkeys.entries.firstWhere((k) {
|
||||
final matches = k.value[0] == key;
|
||||
if (matches) {
|
||||
amount = int.parse(k.value[1].toString());
|
||||
pos = int.parse(k.key.toString());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
final receivedAddressRecord = BitcoinSilentPaymentAddressRecord(
|
||||
receivingOutputAddress,
|
||||
index: 0,
|
||||
isHidden: false,
|
||||
isUsed: true,
|
||||
network: scanData.network,
|
||||
silentPaymentTweak: t_k,
|
||||
type: SegwitAddresType.p2tr,
|
||||
);
|
||||
|
||||
int? amount;
|
||||
int? pos;
|
||||
outputPubkeys.entries.firstWhere((k) {
|
||||
final matches = k.value[0] == output;
|
||||
if (matches) {
|
||||
amount = int.parse(k.value[1].toString());
|
||||
pos = int.parse(k.key.toString());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
final json = <String, dynamic>{
|
||||
'address_record': receivedAddressRecord.toJSON(),
|
||||
'tx_hash': txid,
|
||||
'value': amount!,
|
||||
'tx_pos': pos!,
|
||||
'silent_payment_tweak': t_k,
|
||||
};
|
||||
|
||||
final tx = BitcoinUnspent.fromJSON(receivedAddressRecord, json);
|
||||
|
||||
final silentPaymentAddress = SilentPaymentAddress(
|
||||
version: scanData.silentAddress.version,
|
||||
B_scan: scanData.silentAddress.B_scan,
|
||||
B_spend: label == "None"
|
||||
? scanData.silentAddress.B_spend
|
||||
: scanData.silentAddress.B_spend
|
||||
.tweakAdd(BigintUtils.fromBytes(BytesUtils.fromHexString(label))),
|
||||
hrp: scanData.silentAddress.hrp,
|
||||
);
|
||||
|
||||
final txInfo = ElectrumTransactionInfo(
|
||||
WalletType.bitcoin,
|
||||
id: tx.hash,
|
||||
height: syncHeight,
|
||||
amount: amount!,
|
||||
fee: 0,
|
||||
direction: TransactionDirection.incoming,
|
||||
isPending: false,
|
||||
date: DateTime.now(),
|
||||
confirmations: await getUpdatedNodeHeight() - int.parse(blockHeight) + 1,
|
||||
to: silentPaymentAddress.toString(),
|
||||
unspents: [tx],
|
||||
);
|
||||
|
||||
scanData.sendPort.send({txInfo.id: txInfo});
|
||||
});
|
||||
|
||||
final json = <String, dynamic>{
|
||||
'address_record': addressRecord.toJSON(),
|
||||
'tx_hash': txid,
|
||||
'value': amount!,
|
||||
'tx_pos': pos!,
|
||||
'silent_payment_tweak': t_k,
|
||||
};
|
||||
|
||||
final tx = BitcoinUnspent.fromJSON(addressRecord, json);
|
||||
|
||||
final txInfo = ElectrumTransactionInfo(
|
||||
WalletType.bitcoin,
|
||||
id: tx.hash,
|
||||
height: syncHeight,
|
||||
amount: amount!,
|
||||
fee: 0,
|
||||
direction: TransactionDirection.incoming,
|
||||
isPending: false,
|
||||
date: DateTime.now(),
|
||||
confirmations: await getUpdatedNodeHeight() - int.parse(blockHeight) + 1,
|
||||
to: value.label != null
|
||||
? SilentPaymentAddress(
|
||||
version: scanData.silentAddress.version,
|
||||
B_scan: scanData.silentAddress.B_scan.tweakAdd(
|
||||
BigintUtils.fromBytes(BytesUtils.fromHexString(value.tweak))),
|
||||
B_spend: scanData.silentAddress.B_spend,
|
||||
hrp: scanData.silentAddress.hrp,
|
||||
).toString()
|
||||
: scanData.silentAddress.toString(),
|
||||
unspents: [tx],
|
||||
);
|
||||
|
||||
scanData.sendPort.send({txInfo.id: txInfo});
|
||||
});
|
||||
} catch (_) {}
|
||||
}
|
||||
|
|
|
@ -60,7 +60,7 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
|
|||
if (silentAddresses.length == 0)
|
||||
silentAddresses.add(BitcoinSilentPaymentAddressRecord(
|
||||
silentAddress.toString(),
|
||||
index: 1,
|
||||
index: 0,
|
||||
isHidden: false,
|
||||
name: "",
|
||||
silentPaymentTweak: null,
|
||||
|
@ -268,7 +268,7 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
|
|||
if (addressPageType == SilentPaymentsAddresType.p2sp && silentAddress != null) {
|
||||
final currentSilentAddressIndex = silentAddresses
|
||||
.where((addressRecord) => addressRecord.type != SegwitAddresType.p2tr)
|
||||
.length +
|
||||
.length -
|
||||
1;
|
||||
|
||||
this.currentSilentAddressIndex = currentSilentAddressIndex;
|
||||
|
|
|
@ -80,7 +80,7 @@ packages:
|
|||
description:
|
||||
path: "."
|
||||
ref: cake-update-v3
|
||||
resolved-ref: fb4c0a0b6cf24628ddad7d3cdc58e4c918eff714
|
||||
resolved-ref: "3ddad3d1a9b78f49c9ef542962758400315d64a7"
|
||||
url: "https://github.com/cake-tech/bitcoin_base"
|
||||
source: git
|
||||
version: "4.0.0"
|
||||
|
@ -198,6 +198,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.3"
|
||||
cli_util:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: cli_util
|
||||
sha256: c05b7406fdabc7a49a3929d4af76bcaccbbffcbcdcf185b082e1ae07da323d19
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.4.1"
|
||||
clock:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -285,6 +293,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
ffigen:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: ffigen
|
||||
sha256: d3e76c2ad48a4e7f93a29a162006f00eba46ce7c08194a77bb5c5e97d1b5ff0a
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "8.0.2"
|
||||
file:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -607,6 +623,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.3"
|
||||
quiver:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: quiver
|
||||
sha256: b1c1ac5ce6688d77f65f3375a9abb9319b3cb32486bdc7a1e0fdf004d7ba4e47
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.2.1"
|
||||
rxdart:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -668,6 +692,15 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.9.1"
|
||||
sp_scanner:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
path: "."
|
||||
ref: master
|
||||
resolved-ref: de90b20f4250647d0f55f6bd5e7203710d0d5678
|
||||
url: "https://github.com/rafael-xmr/sp_scanner"
|
||||
source: git
|
||||
version: "0.0.1"
|
||||
stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -740,6 +773,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.2.0"
|
||||
uuid:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: uuid
|
||||
sha256: "648e103079f7c64a36dc7d39369cabb358d377078a051d6ae2ad3aa539519313"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.7"
|
||||
vector_math:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -788,6 +829,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.2"
|
||||
yaml_edit:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: yaml_edit
|
||||
sha256: c566f4f804215d84a7a2c377667f546c6033d5b34b4f9e60dfb09d17c4e97826
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.0"
|
||||
sdks:
|
||||
dart: ">=3.0.0 <4.0.0"
|
||||
dart: ">=3.0.6 <4.0.0"
|
||||
flutter: ">=3.10.0"
|
||||
|
|
|
@ -38,6 +38,10 @@ dependencies:
|
|||
git:
|
||||
url: https://github.com/cake-tech/blockchain_utils
|
||||
ref: cake-update-v1
|
||||
sp_scanner:
|
||||
git:
|
||||
url: https://github.com/rafael-xmr/sp_scanner
|
||||
ref: master
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
|
|
@ -297,6 +297,7 @@ class CWBitcoin extends Bitcoin {
|
|||
);
|
||||
}
|
||||
|
||||
@override
|
||||
List<BitcoinSilentPaymentAddressRecord> getSilentPaymentAddresses(Object wallet) {
|
||||
final bitcoinWallet = wallet as ElectrumWallet;
|
||||
return bitcoinWallet.walletAddresses.silentAddresses
|
||||
|
@ -304,6 +305,7 @@ class CWBitcoin extends Bitcoin {
|
|||
.toList();
|
||||
}
|
||||
|
||||
@override
|
||||
List<BitcoinSilentPaymentAddressRecord> getSilentPaymentReceivedAddresses(Object wallet) {
|
||||
final bitcoinWallet = wallet as ElectrumWallet;
|
||||
return bitcoinWallet.walletAddresses.silentAddresses
|
||||
|
@ -311,10 +313,12 @@ class CWBitcoin extends Bitcoin {
|
|||
.toList();
|
||||
}
|
||||
|
||||
@override
|
||||
bool isBitcoinReceivePageOption(ReceivePageOption option) {
|
||||
return option is BitcoinReceivePageOption;
|
||||
}
|
||||
|
||||
@override
|
||||
BitcoinAddressType getOptionToType(ReceivePageOption option) {
|
||||
return (option as BitcoinReceivePageOption).toType();
|
||||
}
|
||||
|
@ -326,6 +330,7 @@ class CWBitcoin extends Bitcoin {
|
|||
return bitcoinWallet.silentPaymentsScanningActive;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> setScanningActive(Object wallet, SettingsStore settingsStore, bool active) async {
|
||||
final bitcoinWallet = wallet as ElectrumWallet;
|
||||
// TODO: always when setting to scanning active, will force switch nodes. Remove when not needed anymore
|
||||
|
@ -338,6 +343,7 @@ class CWBitcoin extends Bitcoin {
|
|||
bitcoinWallet.setSilentPaymentsScanning(active);
|
||||
}
|
||||
|
||||
@override
|
||||
bool isTestnet(Object wallet) {
|
||||
final bitcoinWallet = wallet as ElectrumWallet;
|
||||
return bitcoinWallet.isTestnet ?? false;
|
||||
|
@ -346,6 +352,7 @@ class CWBitcoin extends Bitcoin {
|
|||
@override
|
||||
int getHeightByDate({required DateTime date}) => getBitcoinHeightByDate(date: date);
|
||||
|
||||
@override
|
||||
Future<void> rescan(Object wallet, SettingsStore settingsStore,
|
||||
{required int height, bool? doSingleScan}) async {
|
||||
final bitcoinWallet = wallet as ElectrumWallet;
|
||||
|
@ -359,6 +366,7 @@ class CWBitcoin extends Bitcoin {
|
|||
bitcoinWallet.rescan(height: height, doSingleScan: doSingleScan);
|
||||
}
|
||||
|
||||
@override
|
||||
bool getNodeIsCakeElectrs(Object wallet) {
|
||||
final bitcoinWallet = wallet as ElectrumWallet;
|
||||
final node = bitcoinWallet.node;
|
||||
|
@ -366,6 +374,7 @@ class CWBitcoin extends Bitcoin {
|
|||
return node?.uri.host == '198.58.111.154' && node?.uri.port == 50002;
|
||||
}
|
||||
|
||||
@override
|
||||
void deleteSilentPaymentAddress(Object wallet, String address) {
|
||||
final bitcoinWallet = wallet as ElectrumWallet;
|
||||
bitcoinWallet.walletAddresses.deleteSilentPaymentAddress(address);
|
||||
|
|
|
@ -120,7 +120,7 @@ dev_dependencies:
|
|||
mobx_codegen: ^2.1.1
|
||||
build_resolvers: ^2.0.9
|
||||
hive_generator: ^1.1.3
|
||||
flutter_launcher_icons: ^0.11.0
|
||||
# flutter_launcher_icons: ^0.11.0
|
||||
# check flutter_launcher_icons for usage
|
||||
pedantic: ^1.8.0
|
||||
# replace https://github.com/dart-lang/lints#migrating-from-packagepedantic
|
||||
|
|
|
@ -89,6 +89,7 @@ import 'package:cw_bitcoin/bitcoin_address_record.dart';
|
|||
import 'package:cw_bitcoin/bitcoin_transaction_credentials.dart';
|
||||
import 'package:cw_bitcoin/litecoin_wallet_service.dart';
|
||||
import 'package:cw_core/get_height_by_date.dart';
|
||||
import 'package:cw_core/node.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
""";
|
||||
const bitcoinCwPart = "part 'cw_bitcoin.dart';";
|
||||
|
@ -160,7 +161,7 @@ abstract class Bitcoin {
|
|||
BitcoinAddressType getOptionToType(ReceivePageOption option);
|
||||
bool hasTaprootInput(PendingTransaction pendingTransaction);
|
||||
bool getScanningActive(Object wallet);
|
||||
void setScanningActive(Object wallet, bool active);
|
||||
Future<void> setScanningActive(Object wallet, SettingsStore settingsStore, bool active);
|
||||
bool isTestnet(Object wallet);
|
||||
|
||||
Future<PendingTransaction> replaceByFee(Object wallet, String transactionHash, String fee);
|
||||
|
@ -169,7 +170,10 @@ abstract class Bitcoin {
|
|||
int getFeeAmountForPriority(Object wallet, TransactionPriority priority, int inputsCount, int outputsCount, {int? size});
|
||||
int getFeeAmountWithFeeRate(Object wallet, int feeRate, int inputsCount, int outputsCount, {int? size});
|
||||
int getHeightByDate({required DateTime date});
|
||||
void rescan(Object wallet, {required int height, bool? doSingleScan});
|
||||
Future<void> rescan(Object wallet, SettingsStore settingsStore,
|
||||
{required int height, bool? doSingleScan});
|
||||
bool getNodeIsCakeElectrs(Object wallet);
|
||||
void deleteSilentPaymentAddress(Object wallet, String address);
|
||||
}
|
||||
""";
|
||||
|
||||
|
|
Loading…
Reference in a new issue