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);
|
const input = utils_1.checkForInput(this.data.inputs, inputIndex);
|
||||||
return pubkeyInInput(pubkey, input, inputIndex, this.__CACHE);
|
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) {
|
outputHasPubkey(outputIndex, pubkey) {
|
||||||
const output = utils_1.checkForOutput(this.data.outputs, outputIndex);
|
const output = utils_1.checkForOutput(this.data.outputs, outputIndex);
|
||||||
return pubkeyInOutput(pubkey, output, outputIndex, this.__CACHE);
|
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() {
|
validateSignaturesOfAllInputs() {
|
||||||
utils_1.checkForInput(this.data.inputs, 0); // making sure we have at least one
|
utils_1.checkForInput(this.data.inputs, 0); // making sure we have at least one
|
||||||
const results = range(this.data.inputs.length).map(idx =>
|
const results = range(this.data.inputs.length).map(idx =>
|
||||||
|
@ -696,6 +710,13 @@ const isP2PKH = isPaymentFactory(payments.p2pkh);
|
||||||
const isP2WPKH = isPaymentFactory(payments.p2wpkh);
|
const isP2WPKH = isPaymentFactory(payments.p2wpkh);
|
||||||
const isP2WSHScript = isPaymentFactory(payments.p2wsh);
|
const isP2WSHScript = isPaymentFactory(payments.p2wsh);
|
||||||
const isP2SHScript = isPaymentFactory(payments.p2sh);
|
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) {
|
function check32Bit(num) {
|
||||||
if (
|
if (
|
||||||
typeof num !== 'number' ||
|
typeof num !== 'number' ||
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import * as assert from 'assert';
|
import * as assert from 'assert';
|
||||||
|
import * as crypto from 'crypto';
|
||||||
import { describe, it } from 'mocha';
|
import { describe, it } from 'mocha';
|
||||||
|
|
||||||
import { bip32, ECPair, networks as NETWORKS, payments, Psbt } from '..';
|
import { bip32, ECPair, networks as NETWORKS, payments, Psbt } from '..';
|
||||||
|
@ -641,6 +642,29 @@ describe(`Psbt`, () => {
|
||||||
].forEach(getInputTypeTest);
|
].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', () => {
|
describe('inputHasPubkey', () => {
|
||||||
it('should throw', () => {
|
it('should throw', () => {
|
||||||
const psbt = new Psbt();
|
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', () => {
|
describe('outputHasPubkey', () => {
|
||||||
it('should throw', () => {
|
it('should throw', () => {
|
||||||
const psbt = new Psbt();
|
const psbt = new Psbt();
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { Psbt as PsbtBase } from 'bip174';
|
import { Psbt as PsbtBase } from 'bip174';
|
||||||
import * as varuint from 'bip174/src/lib/converter/varint';
|
import * as varuint from 'bip174/src/lib/converter/varint';
|
||||||
import {
|
import {
|
||||||
|
Bip32Derivation,
|
||||||
KeyValue,
|
KeyValue,
|
||||||
PartialSig,
|
PartialSig,
|
||||||
PsbtGlobalUpdate,
|
PsbtGlobalUpdate,
|
||||||
|
@ -377,11 +378,27 @@ export class Psbt {
|
||||||
return pubkeyInInput(pubkey, input, inputIndex, this.__CACHE);
|
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 {
|
outputHasPubkey(outputIndex: number, pubkey: Buffer): boolean {
|
||||||
const output = checkForOutput(this.data.outputs, outputIndex);
|
const output = checkForOutput(this.data.outputs, outputIndex);
|
||||||
return pubkeyInOutput(pubkey, output, outputIndex, this.__CACHE);
|
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 {
|
validateSignaturesOfAllInputs(): boolean {
|
||||||
checkForInput(this.data.inputs, 0); // making sure we have at least one
|
checkForInput(this.data.inputs, 0); // making sure we have at least one
|
||||||
const results = range(this.data.inputs.length).map(idx =>
|
const results = range(this.data.inputs.length).map(idx =>
|
||||||
|
@ -905,6 +922,16 @@ const isP2WPKH = isPaymentFactory(payments.p2wpkh);
|
||||||
const isP2WSHScript = isPaymentFactory(payments.p2wsh);
|
const isP2WSHScript = isPaymentFactory(payments.p2wsh);
|
||||||
const isP2SHScript = isPaymentFactory(payments.p2sh);
|
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 {
|
function check32Bit(num: number): void {
|
||||||
if (
|
if (
|
||||||
typeof num !== 'number' ||
|
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;
|
finalizeInput(inputIndex: number, finalScriptsFunc?: FinalScriptsFunc): this;
|
||||||
getInputType(inputIndex: number): AllScriptType;
|
getInputType(inputIndex: number): AllScriptType;
|
||||||
inputHasPubkey(inputIndex: number, pubkey: Buffer): boolean;
|
inputHasPubkey(inputIndex: number, pubkey: Buffer): boolean;
|
||||||
|
inputHasHDKey(inputIndex: number, root: HDSigner): boolean;
|
||||||
outputHasPubkey(outputIndex: number, pubkey: Buffer): boolean;
|
outputHasPubkey(outputIndex: number, pubkey: Buffer): boolean;
|
||||||
|
outputHasHDKey(outputIndex: number, root: HDSigner): boolean;
|
||||||
validateSignaturesOfAllInputs(): boolean;
|
validateSignaturesOfAllInputs(): boolean;
|
||||||
validateSignaturesOfInput(inputIndex: number, pubkey?: Buffer): boolean;
|
validateSignaturesOfInput(inputIndex: number, pubkey?: Buffer): boolean;
|
||||||
signAllInputsHD(hdKeyPair: HDSigner, sighashTypes?: number[]): this;
|
signAllInputsHD(hdKeyPair: HDSigner, sighashTypes?: number[]): this;
|
||||||
|
|
Loading…
Add table
Reference in a new issue