detect and handle ct and ringct transactions accordingly

and hopefully catch staking outputs as well
This commit is contained in:
sneurlax 2022-12-08 13:51:49 -06:00
parent 0f7a5cb5e6
commit 028e77baf4
2 changed files with 91 additions and 28 deletions

View file

@ -380,19 +380,45 @@ class Output {
factory Output.fromJson(Map<String, dynamic> json) {
// TODO determine if any of this code is needed.
final address = json["scriptPubKey"]["addresses"] == null
? json['scriptPubKey']['type'] as String
: json["scriptPubKey"]["addresses"][0] as String;
return Output(
scriptpubkey: json['scriptPubKey']['hex'] as String?,
scriptpubkeyAsm: json['scriptPubKey']['asm'] as String?,
scriptpubkeyType: json['scriptPubKey']['type'] as String?,
scriptpubkeyAddress: address,
value: (Decimal.parse(json["value"].toString()) *
Decimal.fromInt(Constants.satsPerCoin(Coin
.firo))) // dirty hack but we need 8 decimal places here to keep consistent data structure
.toBigInt()
.toInt(),
);
// Particl has different tx types that need to be detected and handled here
if (json.containsKey('scriptPubKey') as bool) {
// output is transparent
final address = json["scriptPubKey"]["addresses"] == null
? json['scriptPubKey']['type'] as String
: json["scriptPubKey"]["addresses"][0] as String;
return Output(
scriptpubkey: json['scriptPubKey']['hex'] as String?,
scriptpubkeyAsm: json['scriptPubKey']['asm'] as String?,
scriptpubkeyType: json['scriptPubKey']['type'] as String?,
scriptpubkeyAddress: address,
value: (Decimal.parse(json["value"].toString()) *
Decimal.fromInt(Constants.satsPerCoin(Coin
.firo))) // dirty hack but we need 8 decimal places here to keep consistent data structure
.toBigInt()
.toInt(),
);
} /* else if (json.containsKey('ct_fee') as bool) {
// or type: data
// output is blinded (CT)
} else if (json.containsKey('rangeproof') as bool) {
// or valueCommitment or type: anon
// output is private (RingCT)
} */
else {
// TODO detect staking
// TODO handle CT, RingCT, and staking accordingly
// print("transaction not supported: ${json}");
return Output(
// Return output object with null values; allows wallet history to be built
scriptpubkey: null,
scriptpubkeyAsm: null,
scriptpubkeyType: null,
scriptpubkeyAddress: "",
value: (Decimal.parse(0.toString()) *
Decimal.fromInt(Constants.satsPerCoin(Coin
.firo))) // dirty hack but we need 8 decimal places here to keep consistent data structure
.toBigInt()
.toInt());
}
}
}

View file

@ -2297,9 +2297,24 @@ class ParticlWallet extends CoinServiceAPI {
Logging.instance.log("sendersArray: $sendersArray", level: LogLevel.Info);
for (final output in txObject["vout"] as List) {
final address = output["scriptPubKey"]["address"] as String?;
if (address != null) {
recipientsArray.add(address);
// Particl has different tx types that need to be detected and handled here
if (output.containsKey('scriptPubKey') as bool) {
// Logging.instance.log("output is transparent", level: LogLevel.Info);
final address = output["scriptPubKey"]["address"] as String?;
if (address != null) {
recipientsArray.add(address);
}
} else if (output.containsKey('ct_fee') as bool) {
// or type: data
Logging.instance.log("output is blinded (CT)", level: LogLevel.Info);
} else if (output.containsKey('rangeproof') as bool) {
// or valueCommitment or type: anon
Logging.instance
.log("output is private (RingCT)", level: LogLevel.Info);
} else {
// TODO detect staking
Logging.instance.log("output type not detected; output: ${output}",
level: LogLevel.Info);
}
}
@ -2336,19 +2351,41 @@ class ParticlWallet extends CoinServiceAPI {
totalInput = inputAmtSentFromWallet;
int totalOutput = 0;
Logging.instance.log("txObject: ${txObject}", level: LogLevel.Info);
for (final output in txObject["vout"] as List) {
final String address = output["scriptPubKey"]!["address"] as String;
final value = output["value"]!;
final _value = (Decimal.parse(value.toString()) *
Decimal.fromInt(Constants.satsPerCoin(coin)))
.toBigInt()
.toInt();
totalOutput += _value;
if (changeAddresses.contains(address)) {
inputAmtSentFromWallet -= _value;
// Particl has different tx types that need to be detected and handled here
if (output.containsKey('scriptPubKey') as bool) {
// Logging.instance.log("output is transparent", level: LogLevel.Info);
final String address = output["scriptPubKey"]!["address"] as String;
final value = output["value"]!;
final _value = (Decimal.parse(value.toString()) *
Decimal.fromInt(Constants.satsPerCoin(coin)))
.toBigInt()
.toInt();
totalOutput += _value;
if (changeAddresses.contains(address)) {
inputAmtSentFromWallet -= _value;
} else {
// change address from 'sent from' to the 'sent to' address
txObject["address"] = address;
}
} else if (output.containsKey('ct_fee') as bool) {
// or type: data
// TODO handle CT tx
Logging.instance.log(
"output is blinded (CT); cannot parse output values",
level: LogLevel.Info);
} else if (output.containsKey('rangeproof') as bool) {
// or valueCommitment or type: anon
// TODO handle RingCT tx
Logging.instance.log(
"output is private (RingCT); cannot parse output values",
level: LogLevel.Info);
} else {
// change address from 'sent from' to the 'sent to' address
txObject["address"] = address;
// TODO detect staking
Logging.instance.log("output type not detected; output: ${output}",
level: LogLevel.Info);
}
}
// calculate transaction fee