Skip to content

Commit

Permalink
feat(utxo-lib): parse basic info from the psbt
Browse files Browse the repository at this point in the history
TICKET: BTC-637
  • Loading branch information
davidkaplanbitgo committed Nov 29, 2023
1 parent 92af608 commit 2742e1b
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 1 deletion.
1 change: 1 addition & 0 deletions modules/utxo-lib/src/bitgo/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export * from './dash';
export * from './parseInput';
export * from './signature';
export * from './transaction';
export * from './transactionAmounts';
export * from './types';
export * from './Unspent';
export * from './UtxoPsbt';
Expand Down
37 changes: 37 additions & 0 deletions modules/utxo-lib/src/bitgo/transactionAmounts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { UtxoPsbt } from './UtxoPsbt';
import { createTransactionFromBuffer } from './transaction';

export function getTransactionAmountsFromPsbt(psbt: UtxoPsbt): {
inputCount: number;
outputCount: number;
inputAmount: bigint;
outputAmount: bigint;
fee: bigint;
} {
const inputCount = psbt.data.inputs.length;
const outputCount = psbt.data.outputs.length;
const txInputs = psbt.txInputs;
const txOutputs = psbt.txOutputs;
const inputAmount = psbt.data.inputs.reduce((acc, input, inputIndex) => {
if (input.witnessUtxo) {
return acc + BigInt(input.witnessUtxo.value);
} else if (input.nonWitnessUtxo) {
const tx = createTransactionFromBuffer(input.nonWitnessUtxo, psbt.network, { amountType: 'bigint' });
return acc + tx.outs[txInputs[inputIndex].index].value;
} else {
throw new Error('missing witnessUtxo and nonWitnessUtxo');
}
}, BigInt(0));
const outputAmount = psbt.data.outputs.reduce(
(acc, output, outputIndex) => acc + txOutputs[outputIndex].value,
BigInt(0)
);
const fee = inputAmount - outputAmount;
return {
inputCount,
outputCount,
inputAmount,
outputAmount,
fee,
};
}
14 changes: 13 additions & 1 deletion modules/utxo-lib/test/bitgo/psbt/Psbt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ import {
deleteWitnessUtxoForNonSegwitInputs,
getPsbtInputScriptType,
withUnsafeNonSegwit,
getTransactionAmountsFromPsbt,
WalletUnspent,
} from '../../../src/bitgo';
import {
createOutputScript2of3,
Expand Down Expand Up @@ -876,8 +878,9 @@ function testUtxoPsbt(coinNetwork: Network) {
describe(`Testing UtxoPsbt (de)serialization for ${getNetworkName(coinNetwork)} network`, function () {
let psbt: UtxoPsbt;
let psbtHex: string;
let unspents: (WalletUnspent<bigint> | Unspent<bigint>)[];
before(async function () {
const unspents = mockUnspents(rootWalletKeys, ['p2sh'], BigInt('10000000000000'), coinNetwork);
unspents = mockUnspents(rootWalletKeys, ['p2sh'], BigInt('10000000000000'), coinNetwork);
const txBuilderParams = {
signer: 'user',
cosigner: 'bitgo',
Expand Down Expand Up @@ -905,6 +908,15 @@ function testUtxoPsbt(coinNetwork: Network) {
assert.deepStrictEqual(createPsbtFromHex(psbtHex, coinNetwork, false).toBuffer(), psbt.toBuffer());
});

it('should be able to get transaction info from psbt', function () {
const txInfo = getTransactionAmountsFromPsbt(psbt);
assert.strictEqual(txInfo.fee, FEE);
assert.strictEqual(txInfo.inputCount, unspents.length);
assert.strictEqual(txInfo.inputAmount, BigInt('10000000000000') * BigInt(unspents.length));
assert.strictEqual(txInfo.outputAmount, BigInt('10000000000000') * BigInt(unspents.length) - FEE);
assert.strictEqual(txInfo.outputCount, psbt.data.outputs.length);
});

function deserializeBip32PathsCorrectly(bip32PathsAbsolute: boolean): void {
function checkDerivationPrefix(bip32Derivation: { path: string }): void {
const path = bip32Derivation.path.split('/');
Expand Down

0 comments on commit 2742e1b

Please sign in to comment.