Add hasHDKey
This commit is contained in:
parent
5d19abfb85
commit
f87a20caa7
4 changed files with 105 additions and 0 deletions
21
src/psbt.js
21
src/psbt.js
|
@ -305,10 +305,24 @@ class Psbt {
|
|||
const input = utils_1.checkForInput(this.data.inputs, inputIndex);
|
||||
return pubkeyInInput(pubkey, input, inputIndex, this.__CACHE);
|
||||
}
|
||||
inputHasHDKey(inputIndex, root) {
|
||||
const input = utils_1.checkForInput(this.data.inputs, inputIndex);
|
||||
const derivationIsMine = bip32DerivationIsMine(root);
|
||||
return (
|
||||
!!input.bip32Derivation && input.bip32Derivation.some(derivationIsMine)
|
||||
);
|
||||
}
|
||||
outputHasPubkey(outputIndex, pubkey) {
|
||||
const output = utils_1.checkForOutput(this.data.outputs, outputIndex);
|
||||
return pubkeyInOutput(pubkey, output, outputIndex, this.__CACHE);
|
||||
}
|
||||
outputHasHDKey(outputIndex, root) {
|
||||
const output = utils_1.checkForOutput(this.data.outputs, outputIndex);
|
||||
const derivationIsMine = bip32DerivationIsMine(root);
|
||||
return (
|
||||
!!output.bip32Derivation && output.bip32Derivation.some(derivationIsMine)
|
||||
);
|
||||
}
|
||||
validateSignaturesOfAllInputs() {
|
||||
utils_1.checkForInput(this.data.inputs, 0); // making sure we have at least one
|
||||
const results = range(this.data.inputs.length).map(idx =>
|
||||
|
@ -696,6 +710,13 @@ const isP2PKH = isPaymentFactory(payments.p2pkh);
|
|||
const isP2WPKH = isPaymentFactory(payments.p2wpkh);
|
||||
const isP2WSHScript = isPaymentFactory(payments.p2wsh);
|
||||
const isP2SHScript = isPaymentFactory(payments.p2sh);
|
||||
function bip32DerivationIsMine(root) {
|
||||
return d => {
|
||||
if (!d.masterFingerprint.equals(root.fingerprint)) return false;
|
||||
if (!root.derivePath(d.path).publicKey.equals(d.pubkey)) return false;
|
||||
return true;
|
||||
};
|
||||
}
|
||||
function check32Bit(num) {
|
||||
if (
|
||||
typeof num !== 'number' ||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import * as assert from 'assert';
|
||||
import * as crypto from 'crypto';
|
||||
import { describe, it } from 'mocha';
|
||||
|
||||
import { bip32, ECPair, networks as NETWORKS, payments, Psbt } from '..';
|
||||
|
@ -641,6 +642,29 @@ describe(`Psbt`, () => {
|
|||
].forEach(getInputTypeTest);
|
||||
});
|
||||
|
||||
describe('inputHasHDKey', () => {
|
||||
it('should return true if HD key is present', () => {
|
||||
const root = bip32.fromSeed(crypto.randomBytes(32));
|
||||
const root2 = bip32.fromSeed(crypto.randomBytes(32));
|
||||
const path = "m/0'/0";
|
||||
const psbt = new Psbt();
|
||||
psbt.addInput({
|
||||
hash:
|
||||
'0000000000000000000000000000000000000000000000000000000000000000',
|
||||
index: 0,
|
||||
bip32Derivation: [
|
||||
{
|
||||
masterFingerprint: root.fingerprint,
|
||||
path,
|
||||
pubkey: root.derivePath(path).publicKey,
|
||||
},
|
||||
],
|
||||
});
|
||||
assert.strictEqual(psbt.inputHasHDKey(0, root), true);
|
||||
assert.strictEqual(psbt.inputHasHDKey(0, root2), false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('inputHasPubkey', () => {
|
||||
it('should throw', () => {
|
||||
const psbt = new Psbt();
|
||||
|
@ -712,6 +736,37 @@ describe(`Psbt`, () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('outputHasHDKey', () => {
|
||||
it('should return true if HD key is present', () => {
|
||||
const root = bip32.fromSeed(crypto.randomBytes(32));
|
||||
const root2 = bip32.fromSeed(crypto.randomBytes(32));
|
||||
const path = "m/0'/0";
|
||||
const psbt = new Psbt();
|
||||
psbt
|
||||
.addInput({
|
||||
hash:
|
||||
'0000000000000000000000000000000000000000000000000000000000000000',
|
||||
index: 0,
|
||||
})
|
||||
.addOutput({
|
||||
script: Buffer.from(
|
||||
'0014000102030405060708090a0b0c0d0e0f00010203',
|
||||
'hex',
|
||||
),
|
||||
value: 2000,
|
||||
bip32Derivation: [
|
||||
{
|
||||
masterFingerprint: root.fingerprint,
|
||||
path,
|
||||
pubkey: root.derivePath(path).publicKey,
|
||||
},
|
||||
],
|
||||
});
|
||||
assert.strictEqual(psbt.outputHasHDKey(0, root), true);
|
||||
assert.strictEqual(psbt.outputHasHDKey(0, root2), false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('outputHasPubkey', () => {
|
||||
it('should throw', () => {
|
||||
const psbt = new Psbt();
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { Psbt as PsbtBase } from 'bip174';
|
||||
import * as varuint from 'bip174/src/lib/converter/varint';
|
||||
import {
|
||||
Bip32Derivation,
|
||||
KeyValue,
|
||||
PartialSig,
|
||||
PsbtGlobalUpdate,
|
||||
|
@ -377,11 +378,27 @@ export class Psbt {
|
|||
return pubkeyInInput(pubkey, input, inputIndex, this.__CACHE);
|
||||
}
|
||||
|
||||
inputHasHDKey(inputIndex: number, root: HDSigner): boolean {
|
||||
const input = checkForInput(this.data.inputs, inputIndex);
|
||||
const derivationIsMine = bip32DerivationIsMine(root);
|
||||
return (
|
||||
!!input.bip32Derivation && input.bip32Derivation.some(derivationIsMine)
|
||||
);
|
||||
}
|
||||
|
||||
outputHasPubkey(outputIndex: number, pubkey: Buffer): boolean {
|
||||
const output = checkForOutput(this.data.outputs, outputIndex);
|
||||
return pubkeyInOutput(pubkey, output, outputIndex, this.__CACHE);
|
||||
}
|
||||
|
||||
outputHasHDKey(outputIndex: number, root: HDSigner): boolean {
|
||||
const output = checkForOutput(this.data.outputs, outputIndex);
|
||||
const derivationIsMine = bip32DerivationIsMine(root);
|
||||
return (
|
||||
!!output.bip32Derivation && output.bip32Derivation.some(derivationIsMine)
|
||||
);
|
||||
}
|
||||
|
||||
validateSignaturesOfAllInputs(): boolean {
|
||||
checkForInput(this.data.inputs, 0); // making sure we have at least one
|
||||
const results = range(this.data.inputs.length).map(idx =>
|
||||
|
@ -905,6 +922,16 @@ const isP2WPKH = isPaymentFactory(payments.p2wpkh);
|
|||
const isP2WSHScript = isPaymentFactory(payments.p2wsh);
|
||||
const isP2SHScript = isPaymentFactory(payments.p2sh);
|
||||
|
||||
function bip32DerivationIsMine(
|
||||
root: HDSigner,
|
||||
): (d: Bip32Derivation) => boolean {
|
||||
return (d: Bip32Derivation): boolean => {
|
||||
if (!d.masterFingerprint.equals(root.fingerprint)) return false;
|
||||
if (!root.derivePath(d.path).publicKey.equals(d.pubkey)) return false;
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
function check32Bit(num: number): void {
|
||||
if (
|
||||
typeof num !== 'number' ||
|
||||
|
|
2
types/psbt.d.ts
vendored
2
types/psbt.d.ts
vendored
|
@ -71,7 +71,9 @@ export declare class Psbt {
|
|||
finalizeInput(inputIndex: number, finalScriptsFunc?: FinalScriptsFunc): this;
|
||||
getInputType(inputIndex: number): AllScriptType;
|
||||
inputHasPubkey(inputIndex: number, pubkey: Buffer): boolean;
|
||||
inputHasHDKey(inputIndex: number, root: HDSigner): boolean;
|
||||
outputHasPubkey(outputIndex: number, pubkey: Buffer): boolean;
|
||||
outputHasHDKey(outputIndex: number, root: HDSigner): boolean;
|
||||
validateSignaturesOfAllInputs(): boolean;
|
||||
validateSignaturesOfInput(inputIndex: number, pubkey?: Buffer): boolean;
|
||||
signAllInputsHD(hdKeyPair: HDSigner, sighashTypes?: number[]): this;
|
||||
|
|
Loading…
Add table
Reference in a new issue