Skip to content

Commit 6624bd4

Browse files
authored
Merge pull request #39 from BitGo/bigint_psbt
feat(psbt): use bigint values
2 parents dfa5e0f + de8e9ce commit 6624bd4

File tree

11 files changed

+848
-675
lines changed

11 files changed

+848
-675
lines changed

package-lock.json

Lines changed: 2 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
],
5151
"dependencies": {
5252
"bech32": "^2.0.0",
53-
"bip174": "^2.0.1",
53+
"bip174": "git+https://github.com/brandonblack/bip174#c2ca5fa9ccdb6244b9617b1d78d77c82c2403185",
5454
"bs58check": "^2.1.2",
5555
"create-hash": "^1.1.0",
5656
"fastpriorityqueue": "^0.7.1",

src/psbt.d.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export interface PsbtTxInput extends TransactionInput {
1313
}
1414
export interface TransactionOutput {
1515
script: Buffer;
16-
value: number;
16+
value: bigint;
1717
}
1818
export interface PsbtTxOutput extends TransactionOutput {
1919
address: string | undefined;
@@ -76,9 +76,9 @@ export declare class Psbt {
7676
addInput(inputData: PsbtInputExtended): this;
7777
addOutputs(outputDatas: PsbtOutputExtended[]): this;
7878
addOutput(outputData: PsbtOutputExtended): this;
79-
extractTransaction(disableFeeCheck?: boolean): Transaction;
79+
extractTransaction(disableFeeCheck?: boolean): Transaction<bigint>;
8080
getFeeRate(): number;
81-
getFee(): number;
81+
getFee(): bigint;
8282
finalizeAllInputs(): this;
8383
finalizeInput(inputIndex: number, finalScriptsFunc?: FinalScriptsFunc): this;
8484
getInputType(inputIndex: number): AllScriptType;
@@ -116,11 +116,11 @@ interface PsbtInputExtended extends PsbtInput, TransactionInput {
116116
declare type PsbtOutputExtended = PsbtOutputExtendedAddress | PsbtOutputExtendedScript;
117117
interface PsbtOutputExtendedAddress extends PsbtOutput {
118118
address: string;
119-
value: number;
119+
value: bigint;
120120
}
121121
interface PsbtOutputExtendedScript extends PsbtOutput {
122122
script: Buffer;
123-
value: number;
123+
value: bigint;
124124
}
125125
interface HDSignerBase {
126126
/**

src/psbt.js

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -256,11 +256,8 @@ class Psbt {
256256
return tx;
257257
}
258258
getFeeRate() {
259-
return getTxCacheValue(
260-
'__FEE_RATE',
261-
'fee rate',
262-
this.data.inputs,
263-
this.__CACHE,
259+
return Number(
260+
getTxCacheValue('__FEE_RATE', 'fee rate', this.data.inputs, this.__CACHE),
264261
);
265262
}
266263
getFee() {
@@ -623,7 +620,7 @@ const transactionFromBuffer = buffer => new PsbtTransaction(buffer);
623620
*/
624621
class PsbtTransaction {
625622
constructor(buffer = Buffer.from([2, 0, 0, 0, 0, 0, 0, 0, 0, 0])) {
626-
this.tx = transaction_1.Transaction.fromBuffer(buffer);
623+
this.tx = transaction_1.Transaction.fromBuffer(buffer, undefined, 'bigint');
627624
checkTxEmpty(this.tx);
628625
Object.defineProperty(this, 'tx', {
629626
enumerable: false,
@@ -656,7 +653,7 @@ class PsbtTransaction {
656653
output.script === undefined ||
657654
output.value === undefined ||
658655
!Buffer.isBuffer(output.script) ||
659-
typeof output.value !== 'number'
656+
typeof output.value !== 'bigint'
660657
) {
661658
throw new Error('Error adding output.');
662659
}
@@ -737,12 +734,15 @@ function check32Bit(num) {
737734
}
738735
}
739736
function checkFees(psbt, cache, opts) {
740-
const feeRate = cache.__FEE_RATE || psbt.getFeeRate();
737+
const feeRate = Number(cache.__FEE_RATE) || psbt.getFeeRate();
741738
const vsize = cache.__EXTRACTED_TX.virtualSize();
742-
const satoshis = feeRate * vsize;
743-
if (feeRate >= opts.maximumFeeRate) {
739+
const satoshis = BigInt(feeRate) * BigInt(vsize);
740+
if (Number(feeRate) >= opts.maximumFeeRate) {
741+
const satoshisPerCoin = BigInt(1e8);
742+
const coinString = (satoshis / satoshisPerCoin).toString();
743+
const satsString = (satoshis % satoshisPerCoin).toString().padStart(8, '0');
744744
throw new Error(
745-
`Warning: You are paying around ${(satoshis / 1e8).toFixed(8)} in ` +
745+
`Warning: You are paying around ${coinString}.${satsString} in ` +
746746
`fees, which is ${feeRate} satoshi per byte for a transaction ` +
747747
`with a VSize of ${vsize} bytes (segwit counted as 0.25 byte per ` +
748748
`byte). Use setMaximumFeeRate method to raise your threshold, or ` +
@@ -1208,7 +1208,11 @@ function witnessStackToScriptWitness(witness) {
12081208
}
12091209
function addNonWitnessTxCache(cache, input, inputIndex) {
12101210
cache.__NON_WITNESS_UTXO_BUF_CACHE[inputIndex] = input.nonWitnessUtxo;
1211-
const tx = transaction_1.Transaction.fromBuffer(input.nonWitnessUtxo);
1211+
const tx = transaction_1.Transaction.fromBuffer(
1212+
input.nonWitnessUtxo,
1213+
undefined,
1214+
'bigint',
1215+
);
12121216
cache.__NON_WITNESS_UTXO_TX_CACHE[inputIndex] = tx;
12131217
const self = cache;
12141218
const selfIndex = inputIndex;
@@ -1232,7 +1236,7 @@ function addNonWitnessTxCache(cache, input, inputIndex) {
12321236
});
12331237
}
12341238
function inputFinalizeGetAmts(inputs, tx, cache, mustFinalize) {
1235-
let inputAmount = 0;
1239+
let inputAmount = BigInt(0);
12361240
inputs.forEach((input, idx) => {
12371241
if (mustFinalize && input.finalScriptSig)
12381242
tx.ins[idx].script = input.finalScriptSig;
@@ -1250,15 +1254,15 @@ function inputFinalizeGetAmts(inputs, tx, cache, mustFinalize) {
12501254
inputAmount += out.value;
12511255
}
12521256
});
1253-
const outputAmount = tx.outs.reduce((total, o) => total + o.value, 0);
1257+
const outputAmount = tx.outs.reduce((total, o) => total + o.value, BigInt(0));
12541258
const fee = inputAmount - outputAmount;
12551259
if (fee < 0) {
12561260
throw new Error('Outputs are spending more than Inputs');
12571261
}
12581262
const bytes = tx.virtualSize();
12591263
cache.__FEE = fee;
12601264
cache.__EXTRACTED_TX = tx;
1261-
cache.__FEE_RATE = Math.floor(fee / bytes);
1265+
cache.__FEE_RATE = fee / BigInt(bytes);
12621266
}
12631267
function nonWitnessUtxoTxFromCache(cache, input, inputIndex) {
12641268
const c = cache.__NON_WITNESS_UTXO_TX_CACHE;

0 commit comments

Comments
 (0)