mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2025-01-31 15:06:04 +00:00
wip
This commit is contained in:
parent
7b5c36e5a7
commit
aa6cac897e
5 changed files with 54 additions and 98 deletions
|
@ -4,6 +4,7 @@ import 'dart:io';
|
||||||
import 'dart:isolate';
|
import 'dart:isolate';
|
||||||
|
|
||||||
import 'package:bitcoin_base/bitcoin_base.dart';
|
import 'package:bitcoin_base/bitcoin_base.dart';
|
||||||
|
import 'package:cw_bitcoin/litecoin_wallet_addresses.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:cw_core/encryption_file_utils.dart';
|
import 'package:cw_core/encryption_file_utils.dart';
|
||||||
import 'package:blockchain_utils/blockchain_utils.dart';
|
import 'package:blockchain_utils/blockchain_utils.dart';
|
||||||
|
@ -795,7 +796,10 @@ abstract class ElectrumWalletBase
|
||||||
throw BitcoinTransactionWrongBalanceException();
|
throw BitcoinTransactionWrongBalanceException();
|
||||||
}
|
}
|
||||||
|
|
||||||
final changeAddress = await walletAddresses.getChangeAddress();
|
final changeAddress = await walletAddresses.getChangeAddress(
|
||||||
|
outputs: outputs,
|
||||||
|
utxoDetails: utxoDetails,
|
||||||
|
);
|
||||||
final address = addressTypeFromStr(changeAddress, network);
|
final address = addressTypeFromStr(changeAddress, network);
|
||||||
outputs.add(BitcoinOutput(
|
outputs.add(BitcoinOutput(
|
||||||
address: address,
|
address: address,
|
||||||
|
@ -2061,7 +2065,8 @@ abstract class ElectrumWalletBase
|
||||||
_isTryingToConnect = true;
|
_isTryingToConnect = true;
|
||||||
|
|
||||||
Timer(Duration(seconds: 10), () {
|
Timer(Duration(seconds: 10), () {
|
||||||
if (this.syncStatus is NotConnectedSyncStatus || this.syncStatus is LostConnectionSyncStatus) {
|
if (this.syncStatus is NotConnectedSyncStatus ||
|
||||||
|
this.syncStatus is LostConnectionSyncStatus) {
|
||||||
this.electrumClient.connectToUri(
|
this.electrumClient.connectToUri(
|
||||||
node!.uri,
|
node!.uri,
|
||||||
useSSL: node!.useSSL ?? false,
|
useSSL: node!.useSSL ?? false,
|
||||||
|
@ -2387,6 +2392,8 @@ class PublicKeyWithDerivationPath {
|
||||||
}
|
}
|
||||||
|
|
||||||
BitcoinBaseAddress addressTypeFromStr(String address, BasedUtxoNetwork network) {
|
BitcoinBaseAddress addressTypeFromStr(String address, BasedUtxoNetwork network) {
|
||||||
|
// print("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
|
||||||
|
// print(network);
|
||||||
if (network is BitcoinCashNetwork) {
|
if (network is BitcoinCashNetwork) {
|
||||||
if (!address.startsWith("bitcoincash:") &&
|
if (!address.startsWith("bitcoincash:") &&
|
||||||
(address.startsWith("q") || address.startsWith("p"))) {
|
(address.startsWith("q") || address.startsWith("p"))) {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
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/electrum_wallet.dart';
|
||||||
import 'package:cw_core/wallet_addresses.dart';
|
import 'package:cw_core/wallet_addresses.dart';
|
||||||
import 'package:cw_core/wallet_info.dart';
|
import 'package:cw_core/wallet_info.dart';
|
||||||
import 'package:cw_core/wallet_type.dart';
|
import 'package:cw_core/wallet_type.dart';
|
||||||
|
@ -239,7 +240,7 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
Future<String> getChangeAddress() async {
|
Future<String> getChangeAddress({List<BitcoinOutput>? outputs, UtxoDetails? utxoDetails}) async {
|
||||||
updateChangeAddresses();
|
updateChangeAddresses();
|
||||||
|
|
||||||
if (changeAddresses.isEmpty) {
|
if (changeAddresses.isEmpty) {
|
||||||
|
|
|
@ -2,6 +2,7 @@ import 'package:bech32/bech32.dart';
|
||||||
import 'package:bitcoin_base/bitcoin_base.dart';
|
import 'package:bitcoin_base/bitcoin_base.dart';
|
||||||
import 'package:blockchain_utils/bech32/bech32_base.dart';
|
import 'package:blockchain_utils/bech32/bech32_base.dart';
|
||||||
import 'package:blockchain_utils/blockchain_utils.dart';
|
import 'package:blockchain_utils/blockchain_utils.dart';
|
||||||
|
import 'package:cw_bitcoin/electrum_wallet.dart';
|
||||||
import 'package:cw_bitcoin/utils.dart';
|
import 'package:cw_bitcoin/utils.dart';
|
||||||
import 'package:cw_bitcoin/electrum_wallet_addresses.dart';
|
import 'package:cw_bitcoin/electrum_wallet_addresses.dart';
|
||||||
import 'package:cw_core/wallet_info.dart';
|
import 'package:cw_core/wallet_info.dart';
|
||||||
|
@ -15,79 +16,6 @@ import 'package:mobx/mobx.dart';
|
||||||
|
|
||||||
part 'litecoin_wallet_addresses.g.dart';
|
part 'litecoin_wallet_addresses.g.dart';
|
||||||
|
|
||||||
// class Keychain {
|
|
||||||
// // ECPrivate scan;
|
|
||||||
// // ECPrivate? spend;
|
|
||||||
// ECPrivate scan;
|
|
||||||
// ECPrivate? spend;
|
|
||||||
// ECPublic? spendPubKey;
|
|
||||||
|
|
||||||
// Keychain({required this.scan, this.spend, this.spendPubKey}) {
|
|
||||||
// if (this.spend != null) {
|
|
||||||
// spendPubKey = this.spend!.getPublic();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// static const HashTagAddress = 'A';
|
|
||||||
|
|
||||||
// ECPrivate mi(int index) {
|
|
||||||
// final input = BytesBuilder();
|
|
||||||
|
|
||||||
// // Write HashTagAddress to the input
|
|
||||||
// input.addByte(HashTagAddress.codeUnitAt(0));
|
|
||||||
|
|
||||||
// // Write index to the input in little endian
|
|
||||||
// final indexBytes = Uint8List(4);
|
|
||||||
// final byteData = ByteData.view(indexBytes.buffer);
|
|
||||||
// byteData.setUint32(0, index, Endian.little);
|
|
||||||
// input.add(indexBytes);
|
|
||||||
|
|
||||||
// // Write scan to the input
|
|
||||||
// input.add(scan.prive.raw);
|
|
||||||
|
|
||||||
// // Hash the input using Blake3 with a length of 32 bytes
|
|
||||||
// final hash = rHash.hashString(HashType.blake3(length: 32), input.toString());
|
|
||||||
|
|
||||||
// // Return the hash digest
|
|
||||||
// var res = Uint8List.fromList(hash);
|
|
||||||
// return ECPrivate.fromBytes(res);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Keychain address(int index) {
|
|
||||||
|
|
||||||
// final miPub = this.mi(index).getPublic();
|
|
||||||
// final Bi = spendPubKey!.pubkeyAdd(miPub);
|
|
||||||
// // final Ai = Bi.pubkeyMult(ECPublic.fromBytes(scan.toBytes()));
|
|
||||||
// final Ai = Bi.tweakMul(scan.toBigInt());
|
|
||||||
|
|
||||||
// // final miPubKey = ECCurve_secp256k1().G * BigInt.parse(hex.encode(mi), radix: 16);
|
|
||||||
// // final Bi = spendPubKey + miPubKey;
|
|
||||||
// // return Uint8List.fromList(Ai.getEncoded(compressed: true) + Bi.getEncoded(compressed: true));
|
|
||||||
// final AiPriv = ECPrivate.fromBytes(Ai.toBytes());
|
|
||||||
// final BiPriv = ECPrivate.fromBytes(Bi.toBytes());
|
|
||||||
|
|
||||||
// return Keychain(scan: AiPriv, spend: BiPriv);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// String addressString(int index) {
|
|
||||||
// final address = this.address(index);
|
|
||||||
// List<int> bytes = [];
|
|
||||||
// bytes.addAll(address.scan.toBytes());
|
|
||||||
// bytes.addAll(address.spend!.toBytes());
|
|
||||||
// return encodeMwebAddress(bytes);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Uint8List spendKey(int index) {
|
|
||||||
// // final mi = this.mi(index);
|
|
||||||
// // final spendKey = spend + ECCurve_secp256k1().G * BigInt.parse(hex.encode(mi), radix: 16);
|
|
||||||
// // return spendKey.getEncoded(compressed: true);
|
|
||||||
// // }
|
|
||||||
|
|
||||||
// String encodeMwebAddress(List<int> scriptPubKey) {
|
|
||||||
// return bech32.encode(Bech32("ltcmweb", scriptPubKey));
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
String encodeMwebAddress(List<int> scriptPubKey) {
|
String encodeMwebAddress(List<int> scriptPubKey) {
|
||||||
return bech32.encode(Bech32("ltcmweb1", scriptPubKey), 250);
|
return bech32.encode(Bech32("ltcmweb1", scriptPubKey), 250);
|
||||||
}
|
}
|
||||||
|
@ -126,32 +54,28 @@ abstract class LitecoinWalletAddressesBase extends ElectrumWalletAddresses with
|
||||||
|
|
||||||
Future<void> topUpMweb(int index) async {
|
Future<void> topUpMweb(int index) async {
|
||||||
final stub = await CwMweb.stub();
|
final stub = await CwMweb.stub();
|
||||||
while (oldMwebAddrs.length - index < 1000) {
|
while (mwebAddrs.length - index < 1000) {
|
||||||
final length = oldMwebAddrs.length;
|
final length = mwebAddrs.length;
|
||||||
final resp = await stub.addresses(AddressRequest(
|
final resp = await stub.addresses(AddressRequest(
|
||||||
fromIndex: length,
|
fromIndex: length,
|
||||||
toIndex: index + 1000,
|
toIndex: index + 1000,
|
||||||
scanSecret: scanSecret,
|
scanSecret: scanSecret,
|
||||||
spendPubkey: spendPubkey,
|
spendPubkey: spendPubkey,
|
||||||
));
|
));
|
||||||
if (oldMwebAddrs.length == length) {
|
if (mwebAddrs.length == length) {
|
||||||
oldMwebAddrs.addAll(resp.address);
|
mwebAddrs.addAll(resp.address);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keychain k = Keychain(scan: ECPrivate.fromBytes(scanSecret), spendPubKey: ECPublic.fromBytes(spendPubkey),);
|
// for (int i = 0; i < 10; i++) {
|
||||||
|
// final address = await CwMweb.address(
|
||||||
for (int i = 0; i < 10; i++) {
|
// hex.encode(scanSecret),
|
||||||
// final address = k.addressString(i + 1000);
|
// hex.encode(spendPubkey),
|
||||||
final addressHex =
|
// index + 1000,
|
||||||
await CwMweb.address(hex.encode(scanSecret), hex.encode(spendPubkey), index);
|
// );
|
||||||
// print(addressHex);
|
// mwebAddrs.add(address!);
|
||||||
// print(hex.decode(addressHex!).length);
|
// }
|
||||||
// return;
|
// print("old function: ${oldMwebAddrs.first} new function!: ${mwebAddrs.first}");
|
||||||
final address = encodeMwebAddress(hex.decode(addressHex!));
|
|
||||||
mwebAddrs.add(address);
|
|
||||||
}
|
|
||||||
print("old function: ${oldMwebAddrs.first} new function!: ${mwebAddrs.first}");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -185,11 +109,38 @@ abstract class LitecoinWalletAddressesBase extends ElectrumWalletAddresses with
|
||||||
|
|
||||||
@action
|
@action
|
||||||
@override
|
@override
|
||||||
Future<String> getChangeAddress() async {
|
Future<String> getChangeAddress({List<BitcoinOutput>? outputs, UtxoDetails? utxoDetails}) async {
|
||||||
|
// use regular change address on peg in, otherwise use mweb for change address:
|
||||||
|
|
||||||
|
if (outputs != null && utxoDetails != null) {
|
||||||
|
// check if this is a PEGIN:
|
||||||
|
bool outputsToMweb = false;
|
||||||
|
bool comesFromMweb = false;
|
||||||
|
|
||||||
|
for (var i = 0; i < outputs.length; i++) {
|
||||||
|
// TODO: probably not the best way to tell if this is an mweb address
|
||||||
|
// (but it doesn't contain the "mweb" text at this stage)
|
||||||
|
if (outputs[i].address.toAddress(network).length > 110) {
|
||||||
|
outputsToMweb = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
utxoDetails.availableInputs.forEach((element) {
|
||||||
|
if (element.address.contains("mweb")) {
|
||||||
|
comesFromMweb = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
bool isPegIn = !comesFromMweb && outputsToMweb;
|
||||||
|
if (isPegIn && mwebEnabled) {
|
||||||
|
return super.getChangeAddress();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (mwebEnabled) {
|
if (mwebEnabled) {
|
||||||
await topUpMweb(0);
|
await topUpMweb(0);
|
||||||
return mwebAddrs[0];
|
return mwebAddrs[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
return super.getChangeAddress();
|
return super.getChangeAddress();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,6 @@ dependencies:
|
||||||
bech32:
|
bech32:
|
||||||
git:
|
git:
|
||||||
url: https://github.com/cake-tech/bech32.git
|
url: https://github.com/cake-tech/bech32.git
|
||||||
r_crypto: ^0.5.0
|
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|
|
@ -30,8 +30,6 @@ class CwMwebPlugin: FlutterPlugin, MethodCallHandler {
|
||||||
if (call.method == "start") {
|
if (call.method == "start") {
|
||||||
server?.stop()
|
server?.stop()
|
||||||
val dataDir = call.argument("dataDir") ?: ""
|
val dataDir = call.argument("dataDir") ?: ""
|
||||||
// server = server ?: Mwebd.newServer("", dataDir, "")
|
|
||||||
// port = port ?: server?.start(0)
|
|
||||||
server = server ?: Mwebd.newServer("", dataDir, "")
|
server = server ?: Mwebd.newServer("", dataDir, "")
|
||||||
port = server?.start(0)
|
port = server?.start(0)
|
||||||
result.success(port)
|
result.success(port)
|
||||||
|
@ -44,7 +42,7 @@ class CwMwebPlugin: FlutterPlugin, MethodCallHandler {
|
||||||
val scanSecret: String = call.argument<String>("scanSecret") ?: ""
|
val scanSecret: String = call.argument<String>("scanSecret") ?: ""
|
||||||
val spendPub: String = call.argument<String>("spendPub") ?: ""
|
val spendPub: String = call.argument<String>("spendPub") ?: ""
|
||||||
val index: Int = call.argument<Int>("index") ?: 0
|
val index: Int = call.argument<Int>("index") ?: 0
|
||||||
val res = Mwebd.addressIndex(scanSecret, spendPub)
|
val res = Mwebd.addressIndex(scanSecret, spendPub, index.toString())
|
||||||
result.success(res)
|
result.success(res)
|
||||||
} else {
|
} else {
|
||||||
result.notImplemented()
|
result.notImplemented()
|
||||||
|
|
Loading…
Reference in a new issue