Skip to content

Commit

Permalink
fix: multiple recipient fee calc
Browse files Browse the repository at this point in the history
  • Loading branch information
alter-eggo committed Apr 19, 2024
1 parent b9d8c9c commit b60ea7b
Showing 1 changed file with 32 additions and 33 deletions.
65 changes: 32 additions & 33 deletions src/app/common/transactions/bitcoin/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import BigNumber from 'bignumber.js';
import { AddressType, getAddressInfo, validate } from 'bitcoin-address-validation';
import {
type AddressInfo,
AddressType,
getAddressInfo,
validate,
} from 'bitcoin-address-validation';

import { BTC_P2WPKH_DUST_AMOUNT } from '@shared/constants';
import {
Expand Down Expand Up @@ -207,46 +212,40 @@ export function getSizeInfoMultipleRecipients(payload: {
}) {
const { inputLength, recipients, isSendMax } = payload;

const addressesInfo = recipients.map(recipient => {
return validate(recipient.address) ? getAddressInfo(recipient.address) : null;
});
const outputAddressesTypesWithFallback = addressesInfo.map(addressInfo =>
addressInfo ? addressInfo.type : AddressType.p2wpkh
);

const outputTypesLengthMap = outputAddressesTypesWithFallback.reduce(
(acc: Record<AddressType, number>, outputType) => {
// we add 1 output for change address if not sending max
if (!acc['p2wpkh'] && !isSendMax) {
acc['p2wpkh'] = 1;
}

if (acc[outputType]) {
acc[outputType] = acc[outputType] + 1;
} else {
acc[outputType] = 1;
}

const validAddressesInfo = recipients
.map(recipient => validate(recipient.address) && getAddressInfo(recipient.address))
.filter(Boolean) as AddressInfo[];

function getTxOutputsLengthByPaymentType() {
return validAddressesInfo.reduce(
(acc, { type }) => {
acc[type] = (acc[type] || 0) + 1;
return acc;
},
{} as Record<AddressType, number>
);
}

const outputTypesCount = getTxOutputsLengthByPaymentType();

// Add a change address if not sending max (defaults to p2wpkh)
if (!isSendMax) {
outputTypesCount[AddressType.p2wpkh] = (outputTypesCount[AddressType.p2wpkh] || 0) + 1;
}

// Prepare the output data map for consumption by the txSizer
const outputsData = Object.entries(outputTypesCount).reduce(
(acc, [type, count]) => {
acc[type + '_output_count'] = count;
return acc;
},
{} as Record<AddressType, number>
);

const outputsData = (Object.keys(outputTypesLengthMap) as AddressType[]).map(
outputAddressType => {
return {
[outputAddressType + '_output_count']: outputTypesLengthMap[outputAddressType],
};
}
{} as Record<string, number>
);

const txSizer = new BtcSizeFeeEstimator();
const sizeInfo = txSizer.calcTxSize({
// Only p2wpkh is supported by the wallet
input_script: 'p2wpkh',
input_count: inputLength,
// From the address of the recipient, we infer the output type

...outputsData,
});

Expand Down

0 comments on commit b60ea7b

Please sign in to comment.