mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2024-12-22 19:49:22 +00:00
Rbf fixes issues op return data plus ThorChain (#1648)
* total out amount issue * fix empty inputs and outputs addresses for new tx * fix sum value of utxo not spending * Update configure.dart * Update electrum_wallet.dart * receiving address * review fixes * add op_return data * fix rbf transaction with a memo * add memo check for ThorChain trade * code enhancement [skip ci] * code enhancement [skip ci] * directly use fromElectrumBundle function to update transaction info --------- Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>
This commit is contained in:
parent
8524e238b0
commit
40f85d215b
4 changed files with 65 additions and 24 deletions
|
@ -1,3 +1,5 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:bitcoin_base/bitcoin_base.dart';
|
||||
import 'package:cw_bitcoin/address_from_output.dart';
|
||||
import 'package:cw_bitcoin/bitcoin_address_record.dart';
|
||||
|
@ -7,10 +9,12 @@ import 'package:cw_core/transaction_direction.dart';
|
|||
import 'package:cw_core/transaction_info.dart';
|
||||
import 'package:cw_core/format_amount.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:hex/hex.dart';
|
||||
|
||||
class ElectrumTransactionBundle {
|
||||
ElectrumTransactionBundle(this.originalTransaction,
|
||||
{required this.ins, required this.confirmations, this.time});
|
||||
|
||||
final BtcTransaction originalTransaction;
|
||||
final List<BtcTransaction> ins;
|
||||
final int? time;
|
||||
|
@ -125,7 +129,24 @@ class ElectrumTransactionInfo extends TransactionInfo {
|
|||
for (final out in bundle.originalTransaction.outputs) {
|
||||
totalOutAmount += out.amount.toInt();
|
||||
final addressExists = addresses.contains(addressFromOutputScript(out.scriptPubKey, network));
|
||||
outputAddresses.add(addressFromOutputScript(out.scriptPubKey, network));
|
||||
final address = addressFromOutputScript(out.scriptPubKey, network);
|
||||
|
||||
if (address.isNotEmpty) outputAddresses.add(address);
|
||||
|
||||
// Check if the script contains OP_RETURN
|
||||
final script = out.scriptPubKey.script;
|
||||
if (script.contains('OP_RETURN')) {
|
||||
final index = script.indexOf('OP_RETURN');
|
||||
if (index + 1 <= script.length) {
|
||||
try {
|
||||
final opReturnData = script[index + 1].toString();
|
||||
final decodedString = utf8.decode(HEX.decode(opReturnData));
|
||||
outputAddresses.add('OP_RETURN:$decodedString');
|
||||
} catch (_) {
|
||||
outputAddresses.add('OP_RETURN:');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (addressExists) {
|
||||
receivedAmounts.add(out.amount.toInt());
|
||||
|
|
|
@ -43,6 +43,7 @@ import 'package:hive/hive.dart';
|
|||
import 'package:mobx/mobx.dart';
|
||||
import 'package:rxdart/subjects.dart';
|
||||
import 'package:sp_scanner/sp_scanner.dart';
|
||||
import 'package:hex/hex.dart';
|
||||
|
||||
part 'electrum_wallet.g.dart';
|
||||
|
||||
|
@ -1413,6 +1414,7 @@ abstract class ElectrumWalletBase
|
|||
List<ECPrivate> privateKeys = [];
|
||||
|
||||
var allInputsAmount = 0;
|
||||
String? memo;
|
||||
|
||||
// Add inputs
|
||||
for (var i = 0; i < bundle.originalTransaction.inputs.length; i++) {
|
||||
|
@ -1451,6 +1453,22 @@ abstract class ElectrumWalletBase
|
|||
// Create a list of available outputs
|
||||
final outputs = <BitcoinOutput>[];
|
||||
for (final out in bundle.originalTransaction.outputs) {
|
||||
|
||||
// Check if the script contains OP_RETURN
|
||||
final script = out.scriptPubKey.script;
|
||||
if (script.contains('OP_RETURN') && memo == null) {
|
||||
final index = script.indexOf('OP_RETURN');
|
||||
if (index + 1 <= script.length) {
|
||||
try {
|
||||
final opReturnData = script[index + 1].toString();
|
||||
memo = utf8.decode(HEX.decode(opReturnData));
|
||||
continue;
|
||||
} catch (_) {
|
||||
throw Exception('Cannot decode OP_RETURN data');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final address = addressFromOutputScript(out.scriptPubKey, network);
|
||||
final btcAddress = addressTypeFromStr(address, network);
|
||||
outputs.add(BitcoinOutput(address: btcAddress, value: BigInt.from(out.amount.toInt())));
|
||||
|
@ -1507,6 +1525,8 @@ abstract class ElectrumWalletBase
|
|||
outputs: outputs,
|
||||
fee: BigInt.from(newFee),
|
||||
network: network,
|
||||
memo: memo,
|
||||
outputOrdering: BitcoinOrdering.none,
|
||||
enableRBF: true,
|
||||
);
|
||||
|
||||
|
@ -2036,27 +2056,13 @@ abstract class ElectrumWalletBase
|
|||
tx.inputAddresses!.isEmpty ||
|
||||
tx.outputAddresses == null ||
|
||||
tx.outputAddresses!.isEmpty) {
|
||||
List<String> inputAddresses = [];
|
||||
List<String> outputAddresses = [];
|
||||
|
||||
for (int i = 0; i < bundle.originalTransaction.inputs.length; i++) {
|
||||
final input = bundle.originalTransaction.inputs[i];
|
||||
final inputTransaction = bundle.ins[i];
|
||||
final vout = input.txIndex;
|
||||
final outTransaction = inputTransaction.outputs[vout];
|
||||
final address = addressFromOutputScript(outTransaction.scriptPubKey, network);
|
||||
|
||||
if (address.isNotEmpty) inputAddresses.add(address);
|
||||
}
|
||||
|
||||
for (int i = 0; i < bundle.originalTransaction.outputs.length; i++) {
|
||||
final out = bundle.originalTransaction.outputs[i];
|
||||
final address = addressFromOutputScript(out.scriptPubKey, network);
|
||||
|
||||
if (address.isNotEmpty) outputAddresses.add(address);
|
||||
}
|
||||
tx.inputAddresses = inputAddresses;
|
||||
tx.outputAddresses = outputAddresses;
|
||||
tx = ElectrumTransactionInfo.fromElectrumBundle(
|
||||
bundle,
|
||||
walletInfo.type,
|
||||
network,
|
||||
addresses: addressesSet,
|
||||
height: tx.height,
|
||||
);
|
||||
|
||||
transactionHistory.addOne(tx);
|
||||
}
|
||||
|
|
|
@ -845,6 +845,13 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
|
|||
);
|
||||
}
|
||||
|
||||
if ((trade.memo == null || trade.memo!.isEmpty)) {
|
||||
return CreateTradeResult(
|
||||
result: false,
|
||||
errorMessage: 'Memo is required for Thorchain trade',
|
||||
);
|
||||
}
|
||||
|
||||
final currenciesToCheckPattern = RegExp('0x[0-9a-zA-Z]');
|
||||
|
||||
// Perform checks for payOutAddress
|
||||
|
|
|
@ -392,8 +392,15 @@ abstract class TransactionDetailsViewModelBase with Store {
|
|||
}
|
||||
|
||||
if (transactionInfo.outputAddresses != null && transactionInfo.outputAddresses!.isNotEmpty) {
|
||||
RBFListItems.add(StandardExpandableListItem(
|
||||
title: S.current.outputs, expandableItems: transactionInfo.outputAddresses!));
|
||||
final outputAddresses = transactionInfo.outputAddresses!.map((element) {
|
||||
if (element.contains('OP_RETURN:') && element.length > 40) {
|
||||
return element.substring(0, 40) + '...';
|
||||
}
|
||||
return element;
|
||||
}).toList();
|
||||
|
||||
RBFListItems.add(
|
||||
StandardExpandableListItem(title: S.current.outputs, expandableItems: outputAddresses));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue