mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2025-01-23 19:05:51 +00:00
detect paynym notification transactions
This commit is contained in:
parent
6498e1926c
commit
6253652c21
3 changed files with 71 additions and 20 deletions
|
@ -28,7 +28,7 @@ extension PayNym on DogecoinWallet {
|
|||
return root;
|
||||
}
|
||||
|
||||
// fetch or generate this wallet's bip47 payment code
|
||||
/// fetch or generate this wallet's bip47 payment code
|
||||
Future<PaymentCode> getPaymentCode() async {
|
||||
final address = await db
|
||||
.getAddresses(walletId)
|
||||
|
@ -75,7 +75,7 @@ extension PayNym on DogecoinWallet {
|
|||
}
|
||||
|
||||
void preparePaymentCodeSend(PaymentCode pCode) async {
|
||||
if (!hasConnected(pCode.notificationAddress())) {
|
||||
if (!(await hasConnected(pCode.notificationAddress()))) {
|
||||
throw PaynymSendException("No notification transaction sent to $pCode");
|
||||
} else {
|
||||
final root = await getRootNode(mnemonic: await mnemonic);
|
||||
|
@ -433,12 +433,56 @@ extension PayNym on DogecoinWallet {
|
|||
}
|
||||
}
|
||||
|
||||
bool hasConnected(String paymentCodeString) {
|
||||
return db
|
||||
// TODO optimize
|
||||
Future<bool> hasConnected(String paymentCodeString) async {
|
||||
final myCode = await getPaymentCode();
|
||||
final myNotificationAddress = myCode.notificationAddress();
|
||||
|
||||
final txns = await db
|
||||
.getTransactions(walletId)
|
||||
.filter()
|
||||
.address((q) => q.valueEqualTo(paymentCodeString))
|
||||
.countSync() >
|
||||
0;
|
||||
.subTypeEqualTo(TransactionSubType.bip47Notification)
|
||||
.findAll();
|
||||
|
||||
for (final tx in txns) {
|
||||
if (tx.address.value?.value == myNotificationAddress) {
|
||||
return true;
|
||||
}
|
||||
|
||||
final blindedCode =
|
||||
tx.outputs.elementAt(1).scriptPubKeyAsm!.split(" ")[1];
|
||||
|
||||
final designatedInput = tx.inputs.first;
|
||||
|
||||
final txPoint = designatedInput.txid.fromHex.toList();
|
||||
final txPointIndex = designatedInput.vout;
|
||||
|
||||
final rev = Uint8List(txPoint.length + 4);
|
||||
Util.copyBytes(Uint8List.fromList(txPoint), 0, rev, 0, txPoint.length);
|
||||
final buffer = rev.buffer.asByteData();
|
||||
buffer.setUint32(txPoint.length, txPointIndex, Endian.little);
|
||||
|
||||
final pubKey = designatedInput.scriptSigAsm!.split(" ")[1].fromHex;
|
||||
|
||||
final root = await getRootNode(mnemonic: await mnemonic);
|
||||
final myPrivateKey =
|
||||
root.derivePath(kPaynymDerivePath).derive(0).privateKey!;
|
||||
|
||||
final S = SecretPoint(myPrivateKey, pubKey);
|
||||
|
||||
final mask = PaymentCode.getMask(S.ecdhSecret(), rev);
|
||||
|
||||
final unBlindedPayload = PaymentCode.blind(blindedCode.fromHex, mask);
|
||||
|
||||
final unBlindedPaymentCode =
|
||||
PaymentCode.initFromPayload(unBlindedPayload);
|
||||
|
||||
if (paymentCodeString == unBlindedPaymentCode.toString()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// otherwise return no
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1162,10 +1162,8 @@ class DogecoinWallet extends CoinServiceAPI
|
|||
.not()
|
||||
.typeEqualTo(isar_models.AddressType.nonWallet)
|
||||
.and()
|
||||
.group((q) => q
|
||||
.subTypeEqualTo(isar_models.AddressSubType.receiving)
|
||||
.or()
|
||||
.subTypeEqualTo(isar_models.AddressSubType.change))
|
||||
.not()
|
||||
.subTypeEqualTo(isar_models.AddressSubType.nonWallet)
|
||||
.findAll();
|
||||
return allAddresses;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import 'package:bip47/src/util.dart';
|
||||
import 'package:decimal/decimal.dart';
|
||||
import 'package:stackwallet/models/isar/models/isar_models.dart';
|
||||
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||
|
@ -148,10 +149,6 @@ mixin ElectrumXParsing {
|
|||
amount = amountReceivedInWallet;
|
||||
}
|
||||
|
||||
bool isNotificationTx = coin.hasPaynymSupport &&
|
||||
type == TransactionType.incoming &&
|
||||
transactionAddress.subType == AddressSubType.paynymNotification;
|
||||
|
||||
List<Output> outs = [];
|
||||
List<Input> ins = [];
|
||||
|
||||
|
@ -188,15 +185,27 @@ mixin ElectrumXParsing {
|
|||
outs.add(output);
|
||||
}
|
||||
|
||||
TransactionSubType txSubType = TransactionSubType.none;
|
||||
if (coin.hasPaynymSupport && outs.length > 1) {
|
||||
List<String>? scriptChunks = outs[1].scriptPubKeyAsm?.split(" ");
|
||||
if (scriptChunks?.length == 2 && scriptChunks?[0] == "OP_RETURN") {
|
||||
final blindedPaymentCode = scriptChunks![1];
|
||||
final bytes = blindedPaymentCode.fromHex;
|
||||
|
||||
// https://en.bitcoin.it/wiki/BIP_0047#Sending
|
||||
if (bytes.length == 80 && bytes.first == 1) {
|
||||
txSubType = TransactionSubType.bip47Notification;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final tx = Transaction(
|
||||
walletId: walletId,
|
||||
txid: txData["txid"] as String,
|
||||
timestamp: txData["blocktime"] as int? ??
|
||||
(DateTime.now().millisecondsSinceEpoch ~/ 1000),
|
||||
type: type,
|
||||
subType: isNotificationTx
|
||||
? TransactionSubType.bip47Notification
|
||||
: TransactionSubType.none,
|
||||
subType: txSubType,
|
||||
amount: amount,
|
||||
fee: fee,
|
||||
height: txData["height"] as int?,
|
||||
|
|
Loading…
Reference in a new issue