WIP send/receive address derivation for the target payment code + my private key context

This commit is contained in:
julian 2023-01-09 11:05:13 -06:00
parent 5a77efe5f8
commit ae7dbeb988

View file

@ -11,12 +11,12 @@ import 'package:pointycastle/digests/sha256.dart';
import 'package:stackwallet/hive/db.dart';
import 'package:stackwallet/models/paymint/utxo_model.dart';
import 'package:stackwallet/services/coins/dogecoin/dogecoin_wallet.dart';
import 'package:stackwallet/utilities/address_utils.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/format.dart';
import 'package:stackwallet/utilities/logger.dart';
import 'package:tuple/tuple.dart';
import '../../utilities/logger.dart';
class SWException with Exception {
SWException(this.message);
@ -30,6 +30,10 @@ class InsufficientBalanceException extends SWException {
InsufficientBalanceException(super.message);
}
class PaynymSendException extends SWException {
PaynymSendException(super.message);
}
extension PayNym on DogecoinWallet {
// fetch or generate this wallet's bip47 payment code
Future<PaymentCode> getPaymentCode() async {
@ -68,8 +72,89 @@ extension PayNym on DogecoinWallet {
// return Format.uint8listToString(bytes);
}
// Future<Map<String, dynamic>> prepareNotificationTransaction(
// String targetPaymentCode) async {}
void preparePaymentCodeSend(PaymentCode pCode) async {
final notifTx = await hasSentNotificationTx(pCode);
if (notifTx == null) {
throw PaynymSendException("No notification transaction sent to $pCode");
} else if (!notifTx.confirmedStatus) {
throw PaynymSendException(
"Notification transaction sent to $pCode has not confirmed yet");
} else {
final node = getBip32Root((await mnemonic).join(" "), network)
.derivePath("m/47'/0'/0'");
final sendToAddress = await nextUnusedSendAddressFrom(
pCode,
node.derive(0).privateKey!,
);
// todo: Actual transaction build
}
}
/// get the next unused address to send to given the receiver's payment code
/// and your own private key
Future<String> nextUnusedSendAddressFrom(
PaymentCode pCode,
Uint8List privateKey,
) async {
// https://en.bitcoin.it/wiki/BIP_0047#Path_levels
const maxCount = 2147483647;
final paymentAddress = PaymentAddress.initWithPrivateKey(
privateKey,
pCode,
0, // initial index to check
);
for (paymentAddress.index = 0;
paymentAddress.index <= maxCount;
paymentAddress.index++) {
final address = paymentAddress.getSendAddress();
final transactionIds = await electrumXClient.getHistory(
scripthash: AddressUtils.convertToScriptHash(
address,
network,
),
);
if (transactionIds.isEmpty) {
return address;
}
}
throw PaynymSendException("Exhausted unused send addresses!");
}
/// get your receiving addresses given the sender's payment code and your own
/// private key
List<String> deriveReceivingAddressesFor(
PaymentCode pCode,
Uint8List privateKey,
int count,
) {
// https://en.bitcoin.it/wiki/BIP_0047#Path_levels
const maxCount = 2147483647;
assert(count <= maxCount);
final paymentAddress = PaymentAddress.initWithPrivateKey(
privateKey,
pCode,
0, // initial index
);
final List<String> result = [];
for (paymentAddress.index = 0;
paymentAddress.index < count;
paymentAddress.index++) {
final address = paymentAddress.getReceiveAddress();
result.add(address);
}
return result;
}
Future<Map<String, dynamic>> buildNotificationTx({
required int selectedTxFeeRate,
@ -284,13 +369,6 @@ extension PayNym on DogecoinWallet {
blindedPaymentCode,
]);
final bobP2PKH = P2PKH(
data: PaymentData(
pubkey: targetPaymentCode.notificationPublicKey(),
),
).data;
final notificationScript = bscript.compile([bobP2PKH.output]);
// build a notification tx
final txb = TransactionBuilder(network: network);
txb.setVersion(1);