mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2024-11-17 01:37:54 +00:00
dirty hack for showing firo transactions right away until we can add functionality to sparkmobile
This commit is contained in:
parent
3cf0d82085
commit
b11694220b
5 changed files with 282 additions and 28 deletions
|
@ -1,4 +1,5 @@
|
|||
import 'package:cw_wownero/pending_wownero_transaction.dart';
|
||||
import 'package:stackwallet/models/isar/models/blockchain_data/v2/transaction_v2.dart';
|
||||
import 'package:stackwallet/models/isar/models/isar_models.dart';
|
||||
import 'package:stackwallet/models/paynym/paynym_account_lite.dart';
|
||||
import 'package:stackwallet/utilities/amount/amount.dart';
|
||||
|
@ -64,6 +65,8 @@ class TxData {
|
|||
})>? sparkRecipients;
|
||||
final List<TxData>? sparkMints;
|
||||
|
||||
final TransactionV2? tempTx;
|
||||
|
||||
TxData({
|
||||
this.feeRateType,
|
||||
this.feeRateAmount,
|
||||
|
@ -96,6 +99,7 @@ class TxData {
|
|||
this.tezosOperationsList,
|
||||
this.sparkRecipients,
|
||||
this.sparkMints,
|
||||
this.tempTx,
|
||||
});
|
||||
|
||||
Amount? get amount => recipients != null && recipients!.isNotEmpty
|
||||
|
@ -153,6 +157,7 @@ class TxData {
|
|||
})>?
|
||||
sparkRecipients,
|
||||
List<TxData>? sparkMints,
|
||||
TransactionV2? tempTx,
|
||||
}) {
|
||||
return TxData(
|
||||
feeRateType: feeRateType ?? this.feeRateType,
|
||||
|
@ -187,6 +192,7 @@ class TxData {
|
|||
tezosOperationsList: tezosOperationsList ?? this.tezosOperationsList,
|
||||
sparkRecipients: sparkRecipients ?? this.sparkRecipients,
|
||||
sparkMints: sparkMints ?? this.sparkMints,
|
||||
tempTx: tempTx ?? this.tempTx,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -223,5 +229,6 @@ class TxData {
|
|||
'tezosOperationsList: $tezosOperationsList, '
|
||||
'sparkRecipients: $sparkRecipients, '
|
||||
'sparkMints: $sparkMints, '
|
||||
'tempTx: $tempTx, '
|
||||
'}';
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ import 'package:stackwallet/utilities/util.dart';
|
|||
import 'package:stackwallet/wallets/crypto_currency/coins/firo.dart';
|
||||
import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
|
||||
import 'package:stackwallet/wallets/isar/models/spark_coin.dart';
|
||||
import 'package:stackwallet/wallets/models/tx_data.dart';
|
||||
import 'package:stackwallet/wallets/wallet/intermediate/bip39_hd_wallet.dart';
|
||||
import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/electrumx_interface.dart';
|
||||
import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/lelantus_interface.dart';
|
||||
|
@ -41,8 +42,23 @@ class FiroWallet extends Bip39HDWallet
|
|||
FilterOperation? get receivingAddressFilterOperation =>
|
||||
FilterGroup.and(standardReceivingAddressFilters);
|
||||
|
||||
final Set<String> _unconfirmedTxids = {};
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
@override
|
||||
Future<TxData> updateSentCachedTxData({required TxData txData}) async {
|
||||
if (txData.tempTx != null) {
|
||||
await mainDB.updateOrPutTransactionV2s([txData.tempTx!]);
|
||||
_unconfirmedTxids.add(txData.tempTx!.txid);
|
||||
Logging.instance.log(
|
||||
"Added firo unconfirmed: ${txData.tempTx!.txid}",
|
||||
level: LogLevel.Info,
|
||||
);
|
||||
}
|
||||
return txData;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> updateTransactions() async {
|
||||
List<Address> allAddressesOld = await fetchAddressesForElectrumXScan();
|
||||
|
@ -487,7 +503,16 @@ class FiroWallet extends Bip39HDWallet
|
|||
otherData: otherData,
|
||||
);
|
||||
|
||||
txns.add(tx);
|
||||
if (_unconfirmedTxids.contains(tx.txid)) {
|
||||
if (tx.isConfirmed(await chainHeight, cryptoCurrency.minConfirms)) {
|
||||
txns.add(tx);
|
||||
_unconfirmedTxids.removeWhere((e) => e == tx.txid);
|
||||
} else {
|
||||
// don't update in db until confirmed
|
||||
}
|
||||
} else {
|
||||
txns.add(tx);
|
||||
}
|
||||
}
|
||||
|
||||
await mainDB.updateOrPutTransactionV2s(txns);
|
||||
|
|
|
@ -368,7 +368,7 @@ abstract class Wallet<T extends CryptoCurrency> {
|
|||
Future<void> updateTransactions();
|
||||
Future<void> updateBalance();
|
||||
|
||||
// returns true if new utxos were added to local db
|
||||
/// returns true if new utxos were added to local db
|
||||
Future<bool> updateUTXOs();
|
||||
|
||||
/// updates the wallet info's cachedChainHeight
|
||||
|
@ -381,6 +381,14 @@ abstract class Wallet<T extends CryptoCurrency> {
|
|||
Future<bool> pingCheck();
|
||||
|
||||
//===========================================
|
||||
/// add transaction to local db temporarily. Used for quickly updating ui
|
||||
/// before refresh can fetch data from server
|
||||
Future<TxData> updateSentCachedTxData({required TxData txData}) async {
|
||||
if (txData.tempTx != null) {
|
||||
await mainDB.updateOrPutTransactionV2s([txData.tempTx!]);
|
||||
}
|
||||
return txData;
|
||||
}
|
||||
|
||||
NodeModel getCurrentNode() {
|
||||
final node = nodeService.getPrimaryNodeFor(coin: cryptoCurrency.coin) ??
|
||||
|
|
|
@ -8,6 +8,9 @@ import 'package:decimal/decimal.dart';
|
|||
import 'package:isar/isar.dart';
|
||||
import 'package:stackwallet/electrumx_rpc/cached_electrumx_client.dart';
|
||||
import 'package:stackwallet/electrumx_rpc/electrumx_client.dart';
|
||||
import 'package:stackwallet/models/isar/models/blockchain_data/v2/input_v2.dart';
|
||||
import 'package:stackwallet/models/isar/models/blockchain_data/v2/output_v2.dart';
|
||||
import 'package:stackwallet/models/isar/models/blockchain_data/v2/transaction_v2.dart';
|
||||
import 'package:stackwallet/models/isar/models/isar_models.dart';
|
||||
import 'package:stackwallet/models/paymint/fee_object_model.dart';
|
||||
import 'package:stackwallet/models/signing_data.dart';
|
||||
|
@ -172,7 +175,7 @@ mixin ElectrumXInterface on Bip39HDWallet {
|
|||
);
|
||||
}
|
||||
|
||||
final int vSizeForOneOutput = buildTransaction(
|
||||
final int vSizeForOneOutput = (await buildTransaction(
|
||||
utxoSigningData: utxoSigningData,
|
||||
txData: txData.copyWith(
|
||||
recipients: _helperRecipientsConvert(
|
||||
|
@ -180,7 +183,8 @@ mixin ElectrumXInterface on Bip39HDWallet {
|
|||
[satoshisBeingUsed - 1],
|
||||
),
|
||||
),
|
||||
).vSize!;
|
||||
))
|
||||
.vSize!;
|
||||
int feeForOneOutput = satsPerVByte != null
|
||||
? (satsPerVByte * vSizeForOneOutput)
|
||||
: estimateTxFee(
|
||||
|
@ -200,7 +204,7 @@ mixin ElectrumXInterface on Bip39HDWallet {
|
|||
}
|
||||
|
||||
final int amount = satoshiAmountToSend - feeForOneOutput;
|
||||
final data = buildTransaction(
|
||||
final data = await buildTransaction(
|
||||
txData: txData.copyWith(
|
||||
recipients: _helperRecipientsConvert(
|
||||
[recipientAddress],
|
||||
|
@ -221,7 +225,7 @@ mixin ElectrumXInterface on Bip39HDWallet {
|
|||
|
||||
final int vSizeForOneOutput;
|
||||
try {
|
||||
vSizeForOneOutput = buildTransaction(
|
||||
vSizeForOneOutput = (await buildTransaction(
|
||||
utxoSigningData: utxoSigningData,
|
||||
txData: txData.copyWith(
|
||||
recipients: _helperRecipientsConvert(
|
||||
|
@ -229,7 +233,8 @@ mixin ElectrumXInterface on Bip39HDWallet {
|
|||
[satoshisBeingUsed - 1],
|
||||
),
|
||||
),
|
||||
).vSize!;
|
||||
))
|
||||
.vSize!;
|
||||
} catch (e) {
|
||||
Logging.instance.log("vSizeForOneOutput: $e", level: LogLevel.Error);
|
||||
rethrow;
|
||||
|
@ -237,7 +242,7 @@ mixin ElectrumXInterface on Bip39HDWallet {
|
|||
|
||||
final int vSizeForTwoOutPuts;
|
||||
try {
|
||||
vSizeForTwoOutPuts = buildTransaction(
|
||||
vSizeForTwoOutPuts = (await buildTransaction(
|
||||
utxoSigningData: utxoSigningData,
|
||||
txData: txData.copyWith(
|
||||
recipients: _helperRecipientsConvert(
|
||||
|
@ -248,7 +253,8 @@ mixin ElectrumXInterface on Bip39HDWallet {
|
|||
],
|
||||
),
|
||||
),
|
||||
).vSize!;
|
||||
))
|
||||
.vSize!;
|
||||
} catch (e) {
|
||||
Logging.instance.log("vSizeForTwoOutPuts: $e", level: LogLevel.Error);
|
||||
rethrow;
|
||||
|
@ -312,7 +318,7 @@ mixin ElectrumXInterface on Bip39HDWallet {
|
|||
Logging.instance
|
||||
.log('Estimated fee: $feeForTwoOutputs', level: LogLevel.Info);
|
||||
|
||||
var txn = buildTransaction(
|
||||
var txn = await buildTransaction(
|
||||
utxoSigningData: utxoSigningData,
|
||||
txData: txData.copyWith(
|
||||
recipients: _helperRecipientsConvert(
|
||||
|
@ -343,7 +349,7 @@ mixin ElectrumXInterface on Bip39HDWallet {
|
|||
level: LogLevel.Info);
|
||||
Logging.instance.log('Adjusted Estimated fee: $feeForTwoOutputs',
|
||||
level: LogLevel.Info);
|
||||
txn = buildTransaction(
|
||||
txn = await buildTransaction(
|
||||
utxoSigningData: utxoSigningData,
|
||||
txData: txData.copyWith(
|
||||
recipients: _helperRecipientsConvert(
|
||||
|
@ -374,7 +380,7 @@ mixin ElectrumXInterface on Bip39HDWallet {
|
|||
level: LogLevel.Info);
|
||||
Logging.instance
|
||||
.log('Estimated fee: $feeForOneOutput', level: LogLevel.Info);
|
||||
final txn = buildTransaction(
|
||||
final txn = await buildTransaction(
|
||||
utxoSigningData: utxoSigningData,
|
||||
txData: txData.copyWith(
|
||||
recipients: _helperRecipientsConvert(
|
||||
|
@ -406,7 +412,7 @@ mixin ElectrumXInterface on Bip39HDWallet {
|
|||
level: LogLevel.Info);
|
||||
Logging.instance
|
||||
.log('Estimated fee: $feeForOneOutput', level: LogLevel.Info);
|
||||
final txn = buildTransaction(
|
||||
final txn = await buildTransaction(
|
||||
utxoSigningData: utxoSigningData,
|
||||
txData: txData.copyWith(
|
||||
recipients: _helperRecipientsConvert(
|
||||
|
@ -438,7 +444,7 @@ mixin ElectrumXInterface on Bip39HDWallet {
|
|||
level: LogLevel.Info);
|
||||
Logging.instance
|
||||
.log('Estimated fee: $feeForOneOutput', level: LogLevel.Info);
|
||||
final txn = buildTransaction(
|
||||
final txn = await buildTransaction(
|
||||
utxoSigningData: utxoSigningData,
|
||||
txData: txData.copyWith(
|
||||
recipients: _helperRecipientsConvert(
|
||||
|
@ -615,10 +621,10 @@ mixin ElectrumXInterface on Bip39HDWallet {
|
|||
}
|
||||
|
||||
/// Builds and signs a transaction
|
||||
TxData buildTransaction({
|
||||
Future<TxData> buildTransaction({
|
||||
required TxData txData,
|
||||
required List<SigningData> utxoSigningData,
|
||||
}) {
|
||||
}) async {
|
||||
Logging.instance
|
||||
.log("Starting buildTransaction ----------", level: LogLevel.Info);
|
||||
|
||||
|
@ -637,7 +643,12 @@ mixin ElectrumXInterface on Bip39HDWallet {
|
|||
wif: cryptoCurrency.networkParams.wifPrefix,
|
||||
),
|
||||
);
|
||||
txb.setVersion(1); // TODO possibly override this for certain coins?
|
||||
const version = 1; // TODO possibly override this for certain coins?
|
||||
txb.setVersion(version);
|
||||
|
||||
// temp tx data to show in gui while waiting for real data from server
|
||||
final List<InputV2> tempInputs = [];
|
||||
final List<OutputV2> tempOutputs = [];
|
||||
|
||||
// Add transaction inputs
|
||||
for (var i = 0; i < utxoSigningData.length; i++) {
|
||||
|
@ -649,6 +660,25 @@ mixin ElectrumXInterface on Bip39HDWallet {
|
|||
utxoSigningData[i].output!,
|
||||
cryptoCurrency.networkParams.bech32Hrp,
|
||||
);
|
||||
|
||||
tempInputs.add(
|
||||
InputV2.isarCantDoRequiredInDefaultConstructor(
|
||||
scriptSigHex: txb.inputs.first.script?.toHex,
|
||||
sequence: 0xffffffff - 1,
|
||||
outpoint: OutpointV2.isarCantDoRequiredInDefaultConstructor(
|
||||
txid: utxoSigningData[i].utxo.txid,
|
||||
vout: utxoSigningData[i].utxo.vout,
|
||||
),
|
||||
addresses: utxoSigningData[i].utxo.address == null
|
||||
? []
|
||||
: [utxoSigningData[i].utxo.address!],
|
||||
valueStringSats: utxoSigningData[i].utxo.value.toString(),
|
||||
witness: null,
|
||||
innerRedeemScriptAsm: null,
|
||||
coinbase: null,
|
||||
walletOwns: true,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// Add transaction output
|
||||
|
@ -658,6 +688,24 @@ mixin ElectrumXInterface on Bip39HDWallet {
|
|||
txData.recipients![i].amount.raw.toInt(),
|
||||
cryptoCurrency.networkParams.bech32Hrp,
|
||||
);
|
||||
|
||||
tempOutputs.add(
|
||||
OutputV2.isarCantDoRequiredInDefaultConstructor(
|
||||
scriptPubKeyHex: "000000",
|
||||
valueStringSats: txData.recipients![i].amount.raw.toString(),
|
||||
addresses: [
|
||||
txData.recipients![i].address.toString(),
|
||||
],
|
||||
walletOwns: (await mainDB.isar.addresses
|
||||
.where()
|
||||
.walletIdEqualTo(walletId)
|
||||
.filter()
|
||||
.valueEqualTo(txData.recipients![i].address)
|
||||
.valueProperty()
|
||||
.findFirst()) !=
|
||||
null,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
|
@ -683,6 +731,22 @@ mixin ElectrumXInterface on Bip39HDWallet {
|
|||
return txData.copyWith(
|
||||
raw: builtTx.toHex(),
|
||||
vSize: vSize,
|
||||
tempTx: TransactionV2(
|
||||
walletId: walletId,
|
||||
blockHash: null,
|
||||
hash: builtTx.getId(),
|
||||
txid: builtTx.getId(),
|
||||
height: null,
|
||||
timestamp: DateTime.timestamp().millisecondsSinceEpoch ~/ 1000,
|
||||
inputs: List.unmodifiable(tempInputs),
|
||||
outputs: List.unmodifiable(tempOutputs),
|
||||
version: version,
|
||||
type: tempOutputs.map((e) => e.walletOwns).fold(true, (p, e) => p &= e)
|
||||
? TransactionType.sentToSelf
|
||||
: TransactionType.outgoing,
|
||||
subType: TransactionSubType.none,
|
||||
otherData: null,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1749,7 +1813,7 @@ mixin ElectrumXInterface on Bip39HDWallet {
|
|||
// mark utxos as used
|
||||
await mainDB.putUTXOs(txData.usedUTXOs!);
|
||||
|
||||
return txData;
|
||||
return await updateSentCachedTxData(txData: txData);
|
||||
} catch (e, s) {
|
||||
Logging.instance.log("Exception rethrown from confirmSend(): $e\n$s",
|
||||
level: LogLevel.Error);
|
||||
|
|
|
@ -7,6 +7,9 @@ import 'package:flutter/foundation.dart';
|
|||
import 'package:flutter_libsparkmobile/flutter_libsparkmobile.dart';
|
||||
import 'package:isar/isar.dart';
|
||||
import 'package:stackwallet/models/balance.dart';
|
||||
import 'package:stackwallet/models/isar/models/blockchain_data/v2/input_v2.dart';
|
||||
import 'package:stackwallet/models/isar/models/blockchain_data/v2/output_v2.dart';
|
||||
import 'package:stackwallet/models/isar/models/blockchain_data/v2/transaction_v2.dart';
|
||||
import 'package:stackwallet/models/isar/models/isar_models.dart';
|
||||
import 'package:stackwallet/models/signing_data.dart';
|
||||
import 'package:stackwallet/utilities/amount/amount.dart';
|
||||
|
@ -331,6 +334,10 @@ mixin SparkInterface on Bip39HDWallet, ElectrumXInterface {
|
|||
);
|
||||
}
|
||||
|
||||
// temp tx data to show in gui while waiting for real data from server
|
||||
final List<InputV2> tempInputs = [];
|
||||
final List<OutputV2> tempOutputs = [];
|
||||
|
||||
for (int i = 0; i < (txData.recipients?.length ?? 0); i++) {
|
||||
if (txData.recipients![i].amount.raw == BigInt.zero) {
|
||||
continue;
|
||||
|
@ -354,8 +361,62 @@ mixin SparkInterface on Bip39HDWallet, ElectrumXInterface {
|
|||
scriptPubKey,
|
||||
recipientsWithFeeSubtracted[i].amount.raw.toInt(),
|
||||
);
|
||||
|
||||
tempOutputs.add(
|
||||
OutputV2.isarCantDoRequiredInDefaultConstructor(
|
||||
scriptPubKeyHex: scriptPubKey.toHex,
|
||||
valueStringSats: recipientsWithFeeSubtracted[i].amount.raw.toString(),
|
||||
addresses: [
|
||||
recipientsWithFeeSubtracted[i].address.toString(),
|
||||
],
|
||||
walletOwns: (await mainDB.isar.addresses
|
||||
.where()
|
||||
.walletIdEqualTo(walletId)
|
||||
.filter()
|
||||
.valueEqualTo(recipientsWithFeeSubtracted[i].address)
|
||||
.valueProperty()
|
||||
.findFirst()) !=
|
||||
null,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
if (sparkRecipientsWithFeeSubtracted != null) {
|
||||
for (final recip in sparkRecipientsWithFeeSubtracted) {
|
||||
tempOutputs.add(
|
||||
OutputV2.isarCantDoRequiredInDefaultConstructor(
|
||||
scriptPubKeyHex: Uint8List.fromList([OP_SPARKSMINT]).toHex,
|
||||
valueStringSats: recip.amount.raw.toString(),
|
||||
addresses: [
|
||||
recip.address.toString(),
|
||||
],
|
||||
walletOwns: (await mainDB.isar.addresses
|
||||
.where()
|
||||
.walletIdEqualTo(walletId)
|
||||
.filter()
|
||||
.valueEqualTo(recip.address)
|
||||
.valueProperty()
|
||||
.findFirst()) !=
|
||||
null,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
tempInputs.add(
|
||||
InputV2.isarCantDoRequiredInDefaultConstructor(
|
||||
scriptSigHex: "d3",
|
||||
sequence: 0xffffffff,
|
||||
outpoint: null,
|
||||
addresses: [],
|
||||
valueStringSats: "0",
|
||||
witness: null,
|
||||
innerRedeemScriptAsm: null,
|
||||
coinbase: null,
|
||||
walletOwns: true,
|
||||
),
|
||||
);
|
||||
|
||||
final extractedTx = txb.buildIncomplete();
|
||||
extractedTx.addInput(
|
||||
'0000000000000000000000000000000000000000000000000000000000000000'
|
||||
|
@ -412,12 +473,33 @@ mixin SparkInterface on Bip39HDWallet, ElectrumXInterface {
|
|||
);
|
||||
}
|
||||
|
||||
final fee = Amount(
|
||||
rawValue: BigInt.from(spend.fee),
|
||||
fractionDigits: cryptoCurrency.fractionDigits,
|
||||
);
|
||||
return txData.copyWith(
|
||||
raw: rawTxHex,
|
||||
vSize: extractedTx.virtualSize(),
|
||||
fee: Amount(
|
||||
rawValue: BigInt.from(spend.fee),
|
||||
fractionDigits: cryptoCurrency.fractionDigits,
|
||||
fee: fee,
|
||||
tempTx: TransactionV2(
|
||||
walletId: walletId,
|
||||
blockHash: null,
|
||||
hash: extractedTx.getId(),
|
||||
txid: extractedTx.getId(),
|
||||
timestamp: DateTime.timestamp().millisecondsSinceEpoch ~/ 1000,
|
||||
inputs: List.unmodifiable(tempInputs),
|
||||
outputs: List.unmodifiable(tempOutputs),
|
||||
type: tempOutputs.map((e) => e.walletOwns).fold(true, (p, e) => p &= e)
|
||||
? TransactionType.sentToSelf
|
||||
: TransactionType.outgoing,
|
||||
subType: TransactionSubType.sparkSpend,
|
||||
otherData: jsonEncode(
|
||||
{
|
||||
"anonFees": fee.toJsonString(),
|
||||
},
|
||||
),
|
||||
height: null,
|
||||
version: 3,
|
||||
),
|
||||
// TODO used coins
|
||||
);
|
||||
|
@ -448,7 +530,7 @@ mixin SparkInterface on Bip39HDWallet, ElectrumXInterface {
|
|||
// // mark utxos as used
|
||||
// await mainDB.putUTXOs(txData.usedUTXOs!);
|
||||
|
||||
return txData;
|
||||
return await updateSentCachedTxData(txData: txData);
|
||||
} catch (e, s) {
|
||||
Logging.instance.log("Exception rethrown from confirmSend(): $e\n$s",
|
||||
level: LogLevel.Error);
|
||||
|
@ -702,7 +784,7 @@ mixin SparkInterface on Bip39HDWallet, ElectrumXInterface {
|
|||
: currentHeight;
|
||||
const txVersion = 1;
|
||||
final List<SigningData> vin = [];
|
||||
final List<(dynamic, int)> vout = [];
|
||||
final List<(dynamic, int, String?)> vout = [];
|
||||
|
||||
BigInt nFeeRet = BigInt.zero;
|
||||
|
||||
|
@ -821,13 +903,15 @@ mixin SparkInterface on Bip39HDWallet, ElectrumXInterface {
|
|||
final dummyTxb = btc.TransactionBuilder(network: _bitcoinDartNetwork);
|
||||
dummyTxb.setVersion(txVersion);
|
||||
dummyTxb.setLockTime(lockTime);
|
||||
for (final recipient in dummyRecipients) {
|
||||
for (int i = 0; i < dummyRecipients.length; i++) {
|
||||
final recipient = dummyRecipients[i];
|
||||
if (recipient.amount < cryptoCurrency.dustLimit.raw.toInt()) {
|
||||
throw Exception("Output amount too small");
|
||||
}
|
||||
vout.add((
|
||||
recipient.scriptPubKey,
|
||||
recipient.amount,
|
||||
singleTxOutputs[i].address,
|
||||
));
|
||||
}
|
||||
|
||||
|
@ -860,7 +944,7 @@ mixin SparkInterface on Bip39HDWallet, ElectrumXInterface {
|
|||
final changeAddress = await getCurrentChangeAddress();
|
||||
vout.insert(
|
||||
nChangePosInOut,
|
||||
(changeAddress!.value, nChange.toInt()),
|
||||
(changeAddress!.value, nChange.toInt(), null),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -942,8 +1026,13 @@ mixin SparkInterface on Bip39HDWallet, ElectrumXInterface {
|
|||
);
|
||||
|
||||
int i = 0;
|
||||
for (final recipient in recipients) {
|
||||
final out = (recipient.scriptPubKey, recipient.amount);
|
||||
for (int i = 0; i < recipients.length; i++) {
|
||||
final recipient = recipients[i];
|
||||
final out = (
|
||||
recipient.scriptPubKey,
|
||||
recipient.amount,
|
||||
singleTxOutputs[i].address,
|
||||
);
|
||||
while (i < vout.length) {
|
||||
if (vout[i].$1 is Uint8List &&
|
||||
(vout[i].$1 as Uint8List).isNotEmpty &&
|
||||
|
@ -973,6 +1062,10 @@ mixin SparkInterface on Bip39HDWallet, ElectrumXInterface {
|
|||
continue;
|
||||
}
|
||||
|
||||
// temp tx data to show in gui while waiting for real data from server
|
||||
final List<InputV2> tempInputs = [];
|
||||
final List<OutputV2> tempOutputs = [];
|
||||
|
||||
// sign
|
||||
final txb = btc.TransactionBuilder(network: _bitcoinDartNetwork);
|
||||
txb.setVersion(txVersion);
|
||||
|
@ -985,10 +1078,50 @@ mixin SparkInterface on Bip39HDWallet, ElectrumXInterface {
|
|||
1, // minus 1 is important. 0xffffffff on its own will burn funds
|
||||
input.output,
|
||||
);
|
||||
|
||||
tempInputs.add(
|
||||
InputV2.isarCantDoRequiredInDefaultConstructor(
|
||||
scriptSigHex: txb.inputs.first.script?.toHex,
|
||||
sequence: 0xffffffff - 1,
|
||||
outpoint: OutpointV2.isarCantDoRequiredInDefaultConstructor(
|
||||
txid: input.utxo.txid,
|
||||
vout: input.utxo.vout,
|
||||
),
|
||||
addresses: input.utxo.address == null ? [] : [input.utxo.address!],
|
||||
valueStringSats: input.utxo.value.toString(),
|
||||
witness: null,
|
||||
innerRedeemScriptAsm: null,
|
||||
coinbase: null,
|
||||
walletOwns: true,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
for (final output in vout) {
|
||||
txb.addOutput(output.$1, output.$2);
|
||||
final addressOrScript = output.$1;
|
||||
final value = output.$2;
|
||||
txb.addOutput(addressOrScript, value);
|
||||
|
||||
tempOutputs.add(
|
||||
OutputV2.isarCantDoRequiredInDefaultConstructor(
|
||||
scriptPubKeyHex:
|
||||
addressOrScript is Uint8List ? addressOrScript.toHex : "000000",
|
||||
valueStringSats: value.toString(),
|
||||
addresses: [
|
||||
if (addressOrScript is String) addressOrScript.toString(),
|
||||
],
|
||||
walletOwns: (await mainDB.isar.addresses
|
||||
.where()
|
||||
.walletIdEqualTo(walletId)
|
||||
.filter()
|
||||
.valueEqualTo(addressOrScript is Uint8List
|
||||
? output.$3!
|
||||
: addressOrScript as String)
|
||||
.valueProperty()
|
||||
.findFirst()) !=
|
||||
null,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
|
@ -1035,6 +1168,23 @@ mixin SparkInterface on Bip39HDWallet, ElectrumXInterface {
|
|||
fractionDigits: cryptoCurrency.fractionDigits,
|
||||
),
|
||||
usedUTXOs: vin.map((e) => e.utxo).toList(),
|
||||
tempTx: TransactionV2(
|
||||
walletId: walletId,
|
||||
blockHash: null,
|
||||
hash: builtTx.getId(),
|
||||
txid: builtTx.getId(),
|
||||
timestamp: DateTime.timestamp().millisecondsSinceEpoch ~/ 1000,
|
||||
inputs: List.unmodifiable(tempInputs),
|
||||
outputs: List.unmodifiable(tempOutputs),
|
||||
type:
|
||||
tempOutputs.map((e) => e.walletOwns).fold(true, (p, e) => p &= e)
|
||||
? TransactionType.sentToSelf
|
||||
: TransactionType.outgoing,
|
||||
subType: TransactionSubType.sparkMint,
|
||||
otherData: null,
|
||||
height: null,
|
||||
version: 3,
|
||||
),
|
||||
);
|
||||
|
||||
if (nFeeRet.toInt() < data.vSize!) {
|
||||
|
|
Loading…
Reference in a new issue