FIX: switch to sat/vbyte instead of sat/byte

This commit is contained in:
Overtorment 2021-09-14 13:30:41 +01:00
parent b226e31cd3
commit b36252d015
16 changed files with 66 additions and 31 deletions

View File

@ -180,7 +180,7 @@ export class HDSegwitBech32Transaction {
}
const fee = wentIn - wasSpent;
let feeRate = Math.floor(fee / (this._txhex.length / 2));
let feeRate = Math.floor(fee / this._txDecoded.virtualSize());
if (feeRate === 0) feeRate = 1;
// lets take a look at change
@ -356,7 +356,7 @@ export class HDSegwitBech32Transaction {
myAddress,
HDSegwitBech32Wallet.defaultRBFSequence,
);
const combinedFeeRate = (oldFee + fee) / (this._txhex.length / 2 + tx.toHex().length / 2); // avg
const combinedFeeRate = (oldFee + fee) / (this._txDecoded.virtualSize() + tx.virtualSize()); // avg
if (Math.round(combinedFeeRate) < newFeerate) {
add *= 2;
if (!add) add = 2;

View File

@ -853,6 +853,16 @@ export class AbstractHDElectrumWallet extends AbstractHDWallet {
*/
createTransaction(utxos, targets, feeRate, changeAddress, sequence, skipSigning = false, masterFingerprint) {
if (targets.length === 0) throw new Error('No destination provided');
// compensating for coinselect inability to deal with segwit inputs, and overriding script length for proper vbytes calculation
for (const u of utxos) {
// this is a hacky way to distinguish native/wrapped segwit, but its good enough for our case since we have only
// those 2 wallet types
if (this._getExternalAddressByIndex(0).startsWith('bc1')) {
u.script = { length: 27 };
} else if (this._getExternalAddressByIndex(0).startsWith('3')) {
u.script = { length: 50 };
}
}
const { inputs, outputs, fee } = this.coinselect(utxos, targets, feeRate, changeAddress);
sequence = sequence || AbstractHDElectrumWallet.defaultRBFSequence;

View File

@ -58,6 +58,10 @@ export class SegwitBech32Wallet extends LegacyWallet {
createTransaction(utxos, targets, feeRate, changeAddress, sequence, skipSigning = false, masterFingerprint) {
if (targets.length === 0) throw new Error('No destination provided');
// compensating for coinselect inability to deal with segwit inputs, and overriding script length for proper vbytes calculation
for (const u of utxos) {
u.script = { length: 27 };
}
const { inputs, outputs, fee } = this.coinselect(utxos, targets, feeRate, changeAddress);
sequence = sequence || 0xffffffff; // disable RBF by default
const psbt = new bitcoin.Psbt();

View File

@ -80,6 +80,10 @@ export class SegwitP2SHWallet extends LegacyWallet {
*/
createTransaction(utxos, targets, feeRate, changeAddress, sequence, skipSigning = false, masterFingerprint) {
if (targets.length === 0) throw new Error('No destination provided');
// compensating for coinselect inability to deal with segwit inputs, and overriding script length for proper vbytes calculation
for (const u of utxos) {
u.script = { length: 50 };
}
const { inputs, outputs, fee } = this.coinselect(utxos, targets, feeRate, changeAddress);
sequence = sequence || 0xffffffff; // disable RBF by default
const psbt = new bitcoin.Psbt();

View File

@ -130,7 +130,7 @@ export default class Selftest extends Component {
const tx = bitcoin.Transaction.fromHex(txNew.tx.toHex());
assertStrictEqual(
txNew.tx.toHex(),
'020000000001010c86eb9013616e38b4752e56e5683e864cb34fcd7fe790bdc006b60c08446ba50000000017160014139dc70d73097f9d775f8a3280ba3e3435515641ffffffff02905f0100000000001976a914aa381cd428a4e91327fd4434aa0a08ff131f1a5a88ac6e3303000000000017a914749118baa93fb4b88c28909c8bf0a8202a0484f4870247304402205f0bcb0d9968b3c410e2a3699369bf4149bb56ade18b63356b45285a34d64600022043ac1271f3900ea1000a66b9a9d9ceb3e6e4a4ef45c4da0f55b691ad4b64fcb1012103a5de146762f84055db3202c1316cd9008f16047f4f408c1482fdb108217eda0800000000',
'020000000001010c86eb9013616e38b4752e56e5683e864cb34fcd7fe790bdc006b60c08446ba50000000017160014139dc70d73097f9d775f8a3280ba3e3435515641ffffffff02905f0100000000001976a914aa381cd428a4e91327fd4434aa0a08ff131f1a5a88aca73303000000000017a914749118baa93fb4b88c28909c8bf0a8202a0484f4870248304502210080545d30e3d30dff272ab11c91fd6150170b603239b48c3d56a3fa66bf240085022003762404e1b45975adc89f61ec1569fa19d6d4a8d405e060897754c489ebeade012103a5de146762f84055db3202c1316cd9008f16047f4f408c1482fdb108217eda0800000000',
);
assertStrictEqual(tx.ins.length, 1);
assertStrictEqual(tx.outs.length, 2);

View File

@ -15,11 +15,13 @@ import loc from '../../loc';
import { DynamicQRCode } from '../../components/DynamicQRCode';
import { isDesktop } from '../../blue_modules/environment';
import { useNavigation, useRoute, useTheme } from '@react-navigation/native';
const bitcoin = require('bitcoinjs-lib');
const currency = require('../../blue_modules/currency');
const SendCreate = () => {
const { fee, recipients, memo = '', satoshiPerByte, psbt, showAnimatedQr, tx } = useRoute().params;
const size = Math.round(tx.length / 2);
const transaction = bitcoin.Transaction.fromHex(tx);
const size = transaction.virtualSize();
const { colors } = useTheme();
const { setOptions } = useNavigation();

View File

@ -180,7 +180,7 @@ const PsbtMultisig = () => {
try {
const tx = psbt.extractTransaction().toHex();
const satoshiPerByte = Math.round(getFee() / (tx.length / 2));
const satoshiPerByte = Math.round(getFee() / psbt.extractTransaction().virtualSize());
navigate('Confirm', {
fee: new BigNumber(getFee()).dividedBy(100000000).toNumber(),
memo,

View File

@ -527,7 +527,7 @@ describe('BlueWallet UI Tests', () => {
await yo('TransactionValue');
expect(element(by.id('TransactionValue'))).toHaveText('0.0001');
const transactionFee = await extractTextFromElementById('TransactionFee');
assert.ok(transactionFee.startsWith('Fee: 0.00000452 BTC'), 'Unexpected tx fee: ' + transactionFee);
assert.ok(transactionFee.startsWith('Fee: 0.00000292 BTC'), 'Unexpected tx fee: ' + transactionFee);
await element(by.id('TransactionDetailsButton')).tap();
let txhex = await extractTextFromElementById('TxhexInput');
@ -541,7 +541,8 @@ describe('BlueWallet UI Tests', () => {
// checking fee rate:
const totalIns = 100000; // we hardcode it since we know it in advance
const totalOuts = transaction.outs.map(el => el.value).reduce((a, b) => a + b, 0);
assert.strictEqual(Math.round((totalIns - totalOuts) / (txhex.length / 2)), feeRate);
const tx = bitcoin.Transaction.fromHex(txhex);
assert.strictEqual(Math.round((totalIns - totalOuts) / tx.virtualSize()), feeRate);
assert.strictEqual(transactionFee.split(' ')[1] * 100000000, totalIns - totalOuts);
if (device.getPlatform() === 'ios') {
@ -1109,7 +1110,7 @@ describe('BlueWallet UI Tests', () => {
const psbt1 = bitcoin.Psbt.fromHex(psbthex1);
assert.strictEqual(psbt1.txOutputs.length, 1);
assert.strictEqual(psbt1.txOutputs[0].address, 'bc1q063ctu6jhe5k4v8ka99qac8rcm2tzjjnuktyrl');
assert.strictEqual(psbt1.txOutputs[0].value, 99808);
assert.strictEqual(psbt1.txOutputs[0].value, 99888);
assert.strictEqual(psbt1.data.inputs.length, 1);
assert.strictEqual(psbt1.data.inputs[0].witnessUtxo.value, 100000);
@ -1136,7 +1137,7 @@ describe('BlueWallet UI Tests', () => {
const psbt2 = bitcoin.Psbt.fromHex(psbthex2);
assert.strictEqual(psbt2.txOutputs.length, 1);
assert.strictEqual(psbt2.txOutputs[0].address, 'bc1q063ctu6jhe5k4v8ka99qac8rcm2tzjjnuktyrl');
assert.strictEqual(psbt2.txOutputs[0].value, 5334);
assert.strictEqual(psbt2.txOutputs[0].value, 5414);
assert.strictEqual(psbt2.data.inputs.length, 1);
assert.strictEqual(psbt2.data.inputs[0].witnessUtxo.value, 5526);

View File

@ -78,7 +78,7 @@ describe('HDSegwitBech32Transaction', () => {
const { fee, feeRate, targets, changeAmount, utxos } = await tt.getInfo();
assert.strictEqual(fee, 4464);
assert.strictEqual(changeAmount, 103686);
assert.strictEqual(feeRate, 12);
assert.strictEqual(feeRate, 21);
assert.strictEqual(targets.length, 1);
assert.strictEqual(targets[0].value, 200000);
assert.strictEqual(targets[0].address, '3NLnALo49CFEF4tCRhCvz45ySSfz3UktZC');
@ -113,7 +113,7 @@ describe('HDSegwitBech32Transaction', () => {
assert.strictEqual(await tt.canCancelTx(), true);
const { tx } = await tt.createRBFcancelTx(15);
const { tx } = await tt.createRBFcancelTx(25);
const createdTx = bitcoin.Transaction.fromHex(tx.toHex());
assert.strictEqual(createdTx.ins.length, 2);
@ -121,8 +121,8 @@ describe('HDSegwitBech32Transaction', () => {
const addr = SegwitBech32Wallet.scriptPubKeyToAddress(createdTx.outs[0].script);
assert.ok(hd.weOwnAddress(addr));
const actualFeerate = (108150 + 200000 - createdTx.outs[0].value) / (tx.toHex().length / 2);
assert.strictEqual(Math.round(actualFeerate), 15);
const actualFeerate = (108150 + 200000 - createdTx.outs[0].value) / tx.virtualSize();
assert.strictEqual(Math.round(actualFeerate), 25);
const tt2 = new HDSegwitBech32Transaction(tx.toHex(), null, hd);
assert.strictEqual(await tt2.canCancelTx(), false); // newly created cancel tx is not cancellable anymore
@ -141,7 +141,7 @@ describe('HDSegwitBech32Transaction', () => {
assert.strictEqual(await tt.canCancelTx(), true);
assert.strictEqual(await tt.canBumpTx(), true);
const { tx } = await tt.createRBFbumpFee(17);
const { tx } = await tt.createRBFbumpFee(27);
const createdTx = bitcoin.Transaction.fromHex(tx.toHex());
assert.strictEqual(createdTx.ins.length, 2);
@ -152,8 +152,8 @@ describe('HDSegwitBech32Transaction', () => {
const addr1 = SegwitBech32Wallet.scriptPubKeyToAddress(createdTx.outs[1].script);
assert.ok(hd.weOwnAddress(addr1));
const actualFeerate = (108150 + 200000 - (createdTx.outs[0].value + createdTx.outs[1].value)) / (tx.toHex().length / 2);
assert.strictEqual(Math.round(actualFeerate), 17);
const actualFeerate = (108150 + 200000 - (createdTx.outs[0].value + createdTx.outs[1].value)) / tx.virtualSize();
assert.strictEqual(Math.round(actualFeerate), 28);
const tt2 = new HDSegwitBech32Transaction(tx.toHex(), null, hd);
assert.strictEqual(await tt2.canCancelTx(), true); // new tx is still cancellable since we only bumped fees
@ -184,7 +184,7 @@ describe('HDSegwitBech32Transaction', () => {
);
const { tx, fee } = await tt.createCPFPbumpFee(20);
const avgFeeRate = (oldFee + fee) / (tt._txhex.length / 2 + tx.toHex().length / 2);
const avgFeeRate = (oldFee + fee) / (tt._txDecoded.virtualSize() + tx.virtualSize());
assert.ok(Math.round(avgFeeRate) >= 20);
});
});

View File

@ -230,7 +230,7 @@ describe('Bech32 Segwit HD (BIP84)', () => {
changeAddress,
);
assert.strictEqual(Math.round(fee / tx.byteLength()), 13);
assert.strictEqual(Math.round(fee / tx.virtualSize()), 13);
let totalInput = 0;
for (const inp of inputs) {

View File

@ -75,12 +75,12 @@ it('HD (BIP49) can create TX', async () => {
let tx = bitcoin.Transaction.fromHex(txNew.tx.toHex());
assert.strictEqual(
txNew.tx.toHex(),
'0200000000010187c9acd9d5714845343b18abaa26cb83299be2487c22da9c0e270f241b4d9cfe0000000017160014a239b6a0cbc7aadc2e77643de36306a6167fad150000008002f40100000000000017a914a3a65daca3064280ae072b9d6773c027b30abace87ba6200000000000017a9140acff2c37ed45110baece4bb9d4dcc0c6309dbbd8702483045022100a14eb345f26933b29ba2a68075994ecf10f16286611c1d34ccd5850d977c25620220050e80c62ba64d99101253d94f756791f881bdb92100885fbe5ea3e29964573001210202ac3bd159e54dc31e65842ad5f9a10b4eb024e83864a319b27de65ee08b2a3900000000',
'0200000000010187c9acd9d5714845343b18abaa26cb83299be2487c22da9c0e270f241b4d9cfe0000000017160014a239b6a0cbc7aadc2e77643de36306a6167fad150000008002f40100000000000017a914a3a65daca3064280ae072b9d6773c027b30abace87f36200000000000017a9140acff2c37ed45110baece4bb9d4dcc0c6309dbbd8702483045022100fdddfc8f2f85181b0eb95d9f2ebd506b611318b85419889f9b7e4648cb9912e002206c963079673dfcfeea53120592d995dfab5f0e12f4c0054cace0cda90c481d2001210202ac3bd159e54dc31e65842ad5f9a10b4eb024e83864a319b27de65ee08b2a3900000000',
);
assert.strictEqual(tx.ins.length, 1);
assert.strictEqual(tx.outs.length, 2);
assert.strictEqual(tx.outs[0].value, 500);
assert.strictEqual(tx.outs[1].value, 25274);
assert.strictEqual(tx.outs[1].value, 25331);
let toAddress = bitcoin.address.fromOutputScript(tx.outs[0].script);
const changeAddress = bitcoin.address.fromOutputScript(tx.outs[1].script);
assert.strictEqual('3GcKN7q7gZuZ8eHygAhHrvPa5zZbG5Q1rK', toAddress);
@ -94,6 +94,9 @@ it('HD (BIP49) can create TX', async () => {
5,
hd._getInternalAddressByIndex(hd.next_free_change_address_index),
);
const satPerVbyte = txNew.fee / tx.virtualSize();
assert.strictEqual(Math.round(satPerVbyte), 6); // so_close.jpg
tx = bitcoin.Transaction.fromHex(txNew.tx.toHex());
assert.strictEqual(tx.ins.length, 1);
assert.strictEqual(tx.outs.length, 1);

View File

@ -23,6 +23,8 @@ describe('Legacy wallet', () => {
let txNew = l.createTransaction(utxos, [{ value: 90000, address: '1GX36PGBUrF8XahZEGQqHqnJGW2vCZteoB' }], 1, l.getAddress());
let tx = bitcoin.Transaction.fromHex(txNew.tx.toHex());
const satPerVbyte = txNew.fee / tx.virtualSize();
assert.strictEqual(satPerVbyte, 1);
assert.strictEqual(
txNew.tx.toHex(),
'0200000001c4ce4282c157a7f1e4524d153d3a251669f10673ad24e49f6d2994a033e944cc000000006b48304502210091e58bd2021f2eeea8d39d7f7b053c9ccc52a747b60f1c3584ba33285e2d150602205b2d35a2536cbe157015e8c54a26f5fc350cc7c72b5ca80b9e548917993f652201210337c09b3cb889801638078fd4e6998218b28c92d338ea2602720a88847aedceb3ffffffff02905f0100000000001976a914aa381cd428a4e91327fd4434aa0a08ff131f1a5a88ac2e260000000000001976a91426e01119d265aa980390c49eece923976c218f1588ac00000000',

View File

@ -76,12 +76,17 @@ describe('PayjoinTransaction', () => {
const w = new HDSegwitBech32Wallet();
w.setSecret(process.env.MNEMONICS_COLDCARD);
// bitcoin:bc1qy0ydthpa35m37pvwl5tu76j0srcmcwtmaur3aw?amount=0.0001&pj=https://btc.donate.kukks.org/BTC/pj
const { tx: txOrigin, psbt: psbtOrigin } = w.createTransaction(
utxos,
[{ address: 'bc1qy0ydthpa35m37pvwl5tu76j0srcmcwtmaur3aw', value: 10000 }],
7,
w._getInternalAddressByIndex(0),
// because `createTransaction()` has now readjusted coinselect algo, actual created psbt differs, and wont work
// with hardcoded psbt from btcpayserver. so instead of redoing whole process to get fresh psbt, we hardcode
// created cransaction:
const psbtOrigin = bitcoin.Psbt.fromBase64(
'cHNidP8BAHECAAAAARQ28UTNRyxErPb95WFKR0oaiSTEl4x0MUOLwXkkmIyOAAAAAAAAAACAAhAnAAAAAAAAFgAUI8jV3D2NNx8Fjv0Xz2pPgPG8OXtiWQEAAAAAABYAFF8XCHdkg2yGn81L+plhb9iWamgBAAAAAAABAR+ghgEAAAAAABYAFFS9qGo3Nrma3Tb912mSqTHUqwnKAQhsAkgwRQIhAKsmnGPh1vqoW5zlhjJUUs9rcdG9xMwtlf4Hoij7ul+XAiANlyXTuYshsmTIz6/734ChqQzAGp/HreRulypr0wevswEhAolzW1ViXE+a+hqxD825RNPNdq2Gd7dhUeJ4atRH12vaAAAiAgL1DWeV+AfIP5RRB5zHv5vuXsIt8+rF9rrsji3FhQlhzBgAAAAAVAAAgAAAAIAAAACAAQAAAAAAAAAA',
);
const txOrigin = bitcoin.Transaction.fromHex(
'020000000001011436f144cd472c44acf6fde5614a474a1a8924c4978c7431438bc17924988c8e00000000000000008002102700000000000016001423c8d5dc3d8d371f058efd17cf6a4f80f1bc397b62590100000000001600145f17087764836c869fcd4bfa99616fd8966a680102483045022100ab269c63e1d6faa85b9ce586325452cf6b71d1bdc4cc2d95fe07a228fbba5f9702200d9725d3b98b21b264c8cfaffbdf80a1a90cc01a9fc7ade46e972a6bd307afb301210289735b55625c4f9afa1ab10fcdb944d3cd76ad8677b76151e2786ad447d76bda00000000',
);
assert.strictEqual(txOrigin.ins.length, 1);
assert.strictEqual(txOrigin.outs.length, 2);

View File

@ -20,9 +20,11 @@ describe('Segwit P2SH wallet', () => {
let txNew = wallet.createTransaction(utxos, [{ value: 90000, address: '1GX36PGBUrF8XahZEGQqHqnJGW2vCZteoB' }], 1, wallet.getAddress());
let tx = bitcoin.Transaction.fromHex(txNew.tx.toHex());
const satPerVbyte = txNew.fee / tx.virtualSize();
assert.strictEqual(Math.round(satPerVbyte), 1);
assert.strictEqual(
txNew.tx.toHex(),
'02000000000101ebff950f972e51ea4791f635fef777d5ed0162bacf74f03f5819b976c08bd1570000000000ffffffff02905f0100000000001976a914aa381cd428a4e91327fd4434aa0a08ff131f1a5a88ac2e2600000000000016001488fefdd8967886b32760995c1c36289f44f791850247304402206272d7ba35177bbcccbf52a49a9466e7692252ebbb36753c50ea99c6de8ddb6402204975c76d894b6811b86bab9f2544e7ade7d4f4f7e6a543a60d0af1b854c493a601210314cf2bf53f221e58c5adc1dd95adba9239b248f39b09eb2c550aadc1926fe7aa00000000',
'02000000000101ebff950f972e51ea4791f635fef777d5ed0162bacf74f03f5819b976c08bd1570000000000ffffffff02905f0100000000001976a914aa381cd428a4e91327fd4434aa0a08ff131f1a5a88ac7e2600000000000016001488fefdd8967886b32760995c1c36289f44f7918502483045022100fc0ba843588a5156878cd9d6e3c6b0cbce6acd5c8cf04dc09dcb8d0f23da07f002207a2d5bed25936b1eeda7e836a4734f5a0e66b4996aff64b3b3759ae81805722301210314cf2bf53f221e58c5adc1dd95adba9239b248f39b09eb2c550aadc1926fe7aa00000000',
);
assert.strictEqual(tx.ins.length, 1);
assert.strictEqual(tx.outs.length, 2);

View File

@ -21,9 +21,11 @@ describe('Segwit P2SH wallet', () => {
let txNew = wallet.createTransaction(utxos, [{ value: 90000, address: '1GX36PGBUrF8XahZEGQqHqnJGW2vCZteoB' }], 1, wallet.getAddress());
let tx = bitcoin.Transaction.fromHex(txNew.tx.toHex());
const satPerVbyte = txNew.fee / tx.virtualSize();
assert.strictEqual(Math.round(satPerVbyte), 1);
assert.strictEqual(
txNew.tx.toHex(),
'020000000001010c86eb9013616e38b4752e56e5683e864cb34fcd7fe790bdc006b60c08446ba50000000017160014139dc70d73097f9d775f8a3280ba3e3435515641ffffffff02905f0100000000001976a914aa381cd428a4e91327fd4434aa0a08ff131f1a5a88ac6e3303000000000017a914749118baa93fb4b88c28909c8bf0a8202a0484f4870247304402205f0bcb0d9968b3c410e2a3699369bf4149bb56ade18b63356b45285a34d64600022043ac1271f3900ea1000a66b9a9d9ceb3e6e4a4ef45c4da0f55b691ad4b64fcb1012103a5de146762f84055db3202c1316cd9008f16047f4f408c1482fdb108217eda0800000000',
'020000000001010c86eb9013616e38b4752e56e5683e864cb34fcd7fe790bdc006b60c08446ba50000000017160014139dc70d73097f9d775f8a3280ba3e3435515641ffffffff02905f0100000000001976a914aa381cd428a4e91327fd4434aa0a08ff131f1a5a88aca73303000000000017a914749118baa93fb4b88c28909c8bf0a8202a0484f4870248304502210080545d30e3d30dff272ab11c91fd6150170b603239b48c3d56a3fa66bf240085022003762404e1b45975adc89f61ec1569fa19d6d4a8d405e060897754c489ebeade012103a5de146762f84055db3202c1316cd9008f16047f4f408c1482fdb108217eda0800000000',
);
assert.strictEqual(tx.ins.length, 1);
assert.strictEqual(tx.outs.length, 2);

View File

@ -110,7 +110,7 @@ describe('Watch only wallet', () => {
assert.strictEqual(
psbt.toBase64(),
'cHNidP8BAFMCAAAAAfTUAYKfU/lPbuIV0AsoBIURL2tAz7iaObvEMcXQBW94AAAAAAAAAACAAdDPAwAAAAAAF6kUUatl8TFvnlvB8H/KsqbnR6kpUluHAAAAAAABASCQ0AMAAAAAABepFDzN1E7LDjAMNARzCHsU4rXqBf55hwEEFgAUG3vPJhyWYtt/ikPpOCW6jCqkmxsiBgLHMhb0QhE8eyJBnE9syGAtMehGmHe1sxpm+TlxjgFXERgAAAAAMQAAgAAAAIAAAACAAAAAAAAAAAAAAA==',
'cHNidP8BAFMCAAAAAfTUAYKfU/lPbuIV0AsoBIURL2tAz7iaObvEMcXQBW94AAAAAAAAAACAAQnQAwAAAAAAF6kUUatl8TFvnlvB8H/KsqbnR6kpUluHAAAAAAABASCQ0AMAAAAAABepFDzN1E7LDjAMNARzCHsU4rXqBf55hwEEFgAUG3vPJhyWYtt/ikPpOCW6jCqkmxsiBgLHMhb0QhE8eyJBnE9syGAtMehGmHe1sxpm+TlxjgFXERgAAAAAMQAAgAAAAIAAAACAAAAAAAAAAAAAAA==',
);
});
@ -141,7 +141,7 @@ describe('Watch only wallet', () => {
assert.strictEqual(
psbt.toBase64(),
'cHNidP8BAHECAAAAAYBbjCRXw4r66Ly1aI/SCvis+CDQsCdQej1BhCoDnjt/AAAAAAAAAACAAogTAAAAAAAAFgAUwM681sPTyox13F7GLr5VMw75EOK2OQAAAAAAABYAFOc6kh7rlKStRwwMvbaeu+oFvB4MAAAAAAABAR8gTgAAAAAAABYAFL8PIBBJ6JHVhwsE61MPwWtjtptAIgYDWOHbOE3D4KiuoR7kHtmTtFZ7KXQB+8zb51QALLJxTx8YAAAAAFQAAIAAAACAAAAAgAAAAAAAAAAAAAAiAgM005BVD8MgH5kiSGnwXSfzaxLeDSl3y17Vhrx3F/9XxBgAAAAAVAAAgAAAAIAAAACAAQAAAAAAAAAA',
'cHNidP8BAHECAAAAAYBbjCRXw4r66Ly1aI/SCvis+CDQsCdQej1BhCoDnjt/AAAAAAAAAACAAogTAAAAAAAAFgAUwM681sPTyox13F7GLr5VMw75EOIGOgAAAAAAABYAFOc6kh7rlKStRwwMvbaeu+oFvB4MAAAAAAABAR8gTgAAAAAAABYAFL8PIBBJ6JHVhwsE61MPwWtjtptAIgYDWOHbOE3D4KiuoR7kHtmTtFZ7KXQB+8zb51QALLJxTx8YAAAAAFQAAIAAAACAAAAAgAAAAAAAAAAAAAAiAgM005BVD8MgH5kiSGnwXSfzaxLeDSl3y17Vhrx3F/9XxBgAAAAAVAAAgAAAAIAAAACAAQAAAAAAAAAA',
);
});
@ -181,7 +181,7 @@ describe('Watch only wallet', () => {
);
assert.strictEqual(
psbt.toBase64(),
'cHNidP8BAHECAAAAASJiwHJP3qYi80+cYjHn/n8TiJJR6jRbJFx67gnclfVdAAAAAAAAAACAAogTAAAAAAAAFgAUb3eWXdETtv7KGyXiUxyIS+Q3wJ003QAAAAAAABYAFF8XCHdkg2yGn81L+plhb9iWamgBAAAAAAABAR8oBAEAAAAAABYAFBAk4ma75DYqawitVrni8qlFzNykIgYDNK9TxoCjQ8P0+qI2Hu4hrnXnJuYAC3h2puZbgRORp+sYFo3WA1QAAIAAAACAAAAAgAAAAAAAAAAAAAAiAgL1DWeV+AfIP5RRB5zHv5vuXsIt8+rF9rrsji3FhQlhzBgWjdYDVAAAgAAAAIAAAACAAQAAAAAAAAAA',
'cHNidP8BAHECAAAAASJiwHJP3qYi80+cYjHn/n8TiJJR6jRbJFx67gnclfVdAAAAAAAAAACAAogTAAAAAAAAFgAUb3eWXdETtv7KGyXiUxyIS+Q3wJ0U5AAAAAAAABYAFF8XCHdkg2yGn81L+plhb9iWamgBAAAAAAABAR8oBAEAAAAAABYAFBAk4ma75DYqawitVrni8qlFzNykIgYDNK9TxoCjQ8P0+qI2Hu4hrnXnJuYAC3h2puZbgRORp+sYFo3WA1QAAIAAAACAAAAAgAAAAAAAAAAAAAAiAgL1DWeV+AfIP5RRB5zHv5vuXsIt8+rF9rrsji3FhQlhzBgWjdYDVAAAgAAAAIAAAACAAQAAAAAAAAAA',
);
});
@ -221,7 +221,7 @@ describe('Watch only wallet', () => {
);
assert.strictEqual(
psbt.toBase64(),
'cHNidP8BAHECAAAAASJiwHJP3qYi80+cYjHn/n8TiJJR6jRbJFx67gnclfVdAAAAAAAAAACAAogTAAAAAAAAFgAUb3eWXdETtv7KGyXiUxyIS+Q3wJ003QAAAAAAABYAFF8XCHdkg2yGn81L+plhb9iWamgBAAAAAAABAR8oBAEAAAAAABYAFBAk4ma75DYqawitVrni8qlFzNykIgYDNK9TxoCjQ8P0+qI2Hu4hrnXnJuYAC3h2puZbgRORp+sYFo3WA1QAAIAAAACAAAAAgAAAAAAAAAAAAAAiAgL1DWeV+AfIP5RRB5zHv5vuXsIt8+rF9rrsji3FhQlhzBgWjdYDVAAAgAAAAIAAAACAAQAAAAAAAAAA',
'cHNidP8BAHECAAAAASJiwHJP3qYi80+cYjHn/n8TiJJR6jRbJFx67gnclfVdAAAAAAAAAACAAogTAAAAAAAAFgAUb3eWXdETtv7KGyXiUxyIS+Q3wJ0U5AAAAAAAABYAFF8XCHdkg2yGn81L+plhb9iWamgBAAAAAAABAR8oBAEAAAAAABYAFBAk4ma75DYqawitVrni8qlFzNykIgYDNK9TxoCjQ8P0+qI2Hu4hrnXnJuYAC3h2puZbgRORp+sYFo3WA1QAAIAAAACAAAAAgAAAAAAAAAAAAAAiAgL1DWeV+AfIP5RRB5zHv5vuXsIt8+rF9rrsji3FhQlhzBgWjdYDVAAAgAAAAIAAAACAAQAAAAAAAAAA',
);
});