Socket
Socket
Sign inDemoInstall

bip174

Package Overview
Dependencies
Maintainers
4
Versions
23
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

bip174 - npm Package Compare versions

Comparing version 0.0.15 to 1.0.0

5

package.json
{
"name": "bip174",
"version": "0.0.15",
"version": "1.0.0",
"description": "",

@@ -35,3 +35,4 @@ "main": "src/lib/psbt.js",

"@types/tape": "4.2.33",
"json-buffer": "^3.0.1",
"bitcoinjs-lib": "^5.0.5",
"buffer-json": "^2.0.0",
"nyc": "^14.1.1",

@@ -38,0 +39,0 @@ "prettier": "^1.18.2",

41

README.md

@@ -9,7 +9,7 @@ # bip174

## Under heavy development
## Bitcoin users, use bitcoinjs-lib's Psbt class.
TODO: Increase coverage. Squish bugs.
This library is separate as an attempt to separate Bitcoin specific logic from the encoding format.
WARNING: Until v1.0.0 release, this library will be in flux and have many bugs. Be warned.
I apologize if this library is hard to use. Removing Bitcoin specific logic from "Partially Signed BITCOIN Transaction" format was kind of hard.

@@ -32,7 +32,6 @@ ## Responsibilities Covered

## Static methods and addInput / addOutput require function parameters
## Static methods and addInput / addOutput require an abstract Transaction object
* Static methods: They require a Transaction input/output count getter. The function is `(txBuffer: Buffer) => { inputCount: number; outputCount: number; }` and takes in the Buffer of the value in the 0x00 key of the globalMap.
* addInput/addOutput methods: They require a function to modify the Buffer of the Transaction and return it. `(input: T, txBuffer: Buffer) => Buffer` where T is the same type you passed in the first argument.
* **WARNING** If `T` type has attributes that are named the same as any corresponding input or output types (`witnessUtxo` etc.) the addOutput and addInput functions will try to add them. This allows you to add the input/output attributes to your `T` type and it will automatically add them all in one try.
* Static methods: You must pass a `TransactionFromBuffer` typed function. See `ts_src/lib/interfaces.ts` for info on the `Transaction` interface and the `TransactionFromBuffer` function.
* addInput/addOutput methods: The constructor takes a `Transaction` abstract interface that has an addInput/addOutput method which will be called.

@@ -42,15 +41,29 @@ ## Example

const { Psbt } = require('bip174')
const { inputAdder, outputAdder } = require('./someImplementation')
// See tests/utils/txTools file for an example of a simple Bitcoin Transaction parser.
const { PsbtTransaction , pTxFromBuffer } = require('./someImplementation')
// Psbt requires a Transaction interface to create an instance, as well as
// A function that turns a buffer into that interface. See Transaction and TransactionFromBuffer
// in ts_src/lib/interfaces.ts ...
// See tests/utils/txTools file for an example of a simple Bitcoin Transaction.
// Also see BitcoinJS-lib for an extended class that uses the Transaction class internally.
// Anyone using this library for Bitcoin specifically should use bitcoinjs-lib
const psbt = new Psbt()
// Your PsbtTransaction will have a toBuffer function to allow for serialization
const tx = pTxFromBuffer(someTransactionBuffer);
const psbt = new Psbt(tx)
// OR
// This will parse the PSBT, and use the function you pass to parse the Transaction part
// the function should throw if the scriptSig section is not empty
const psbt = Psbt.fromBuffer(somePsbtBuffer, pTxFromBuffer)
psbt.addInput({
hash: '865dce988413971fd812d0e81a3395ed916a87ea533e1a16c0f4e15df96fa7d4',
index: 3,
}, inputAdder)
})
psbt.addInput({
hash: 'ff5dce988413971fd812d0e81a3395ed916a87ea533e1a16c0f4e15df96fa7d4',
index: 1,
}, inputAdder)
})
psbt.addOutput({

@@ -62,3 +75,3 @@ script: Buffer.from(

value: 1234567890,
}, outputAdder)
})
psbt.addOutput({

@@ -70,3 +83,3 @@ script: Buffer.from(

value: 987654321,
}, outputAdder)
})
psbt.addRedeemScriptToInput(0, Buffer.from(

@@ -73,0 +86,0 @@ '00208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b2028903',

'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
const parser_1 = require('../parser');
/*
Possible outcomes:
1. Update TX with new inputs or outputs. Keep as much as possible never remove.
- Check sigs and sighashes on self, depending on state, reject merge (Don't want to invalidate sigs)
- New inputs must have WITNESS_TXOUT or NON_WITNESS_TXOUT
- If prevoutScript is PS2H must have RedeemScript, P2WSH must have WitnessScript
- If Redeemscript is P2WSH, must have WitnessScript
- If no sighashType is explicitly shown, add SIGHASH_ALL
- New outputs are copied over as-is
- Before adding
2.
TODO:
1. Create self input and output indexes where key is txid:vout for input and scriptPubkey for output.
2. For each input in self:
1. Get all partialSig
2. Get SigHashType
3. If no sigs, inputs and outputs can be added.
4. If all inputs with sig(s) have SIGHASH_ANYONECANPAY, inputs can be added.
5. If all inputs with sig(s) have SIGHASH_NONE, outputs can be added.
6. If any inputs with sig(s) have SIGHASH_SINGLE,
*/
function combine(psbts) {

@@ -42,3 +20,6 @@ const self = psbts[0];

const otherTx = getTx(other);
if (otherTx === undefined || !otherTx.equals(selfTx)) {
if (
otherTx === undefined ||
!otherTx.toBuffer().equals(selfTx.toBuffer())
) {
throw new Error(

@@ -82,3 +63,3 @@ 'Combine: One of the Psbts does not have the same transaction.',

}
return parser_1.psbtFromKeyVals({
return parser_1.psbtFromKeyVals(selfTx, {
globalMapKeyVals: selfKeyVals.globalKeyVals,

@@ -95,2 +76,3 @@ inputKeyVals: selfKeyVals.inputKeyVals,

selfKeyVals.push(newKv);
selfSet.add(key);
};

@@ -97,0 +79,0 @@ }

import { GlobalXpub, KeyValue } from '../../interfaces';
export declare function decode(keyVal: KeyValue): GlobalXpub;
export declare function encode(data: GlobalXpub): KeyValue;
export declare const expected = "{ masterFingerprint: Buffer; extendedPubkey: Buffer; path: string; }";
export declare function check(data: any): data is GlobalXpub;
export declare function canAddToArray(array: GlobalXpub[], item: GlobalXpub, dupeSet: Set<string>): boolean;

@@ -58,1 +58,27 @@ 'use strict';

exports.encode = encode;
exports.expected =
'{ masterFingerprint: Buffer; extendedPubkey: Buffer; path: string; }';
function check(data) {
const epk = data.extendedPubkey;
const mfp = data.masterFingerprint;
const p = data.path;
return (
Buffer.isBuffer(epk) &&
epk.length === 78 &&
[2, 3].indexOf(epk[45]) > -1 &&
Buffer.isBuffer(mfp) &&
mfp.length === 4 &&
typeof p === 'string' &&
!!p.match(/^m(\/\d+'?)+$/)
);
}
exports.check = check;
function canAddToArray(array, item, dupeSet) {
const dupeString = item.extendedPubkey.toString('hex');
if (dupeSet.has(dupeString)) return false;
dupeSet.add(dupeString);
return (
array.filter(v => v.extendedPubkey.equals(item.extendedPubkey)).length === 0
);
}
exports.canAddToArray = canAddToArray;

@@ -1,3 +0,2 @@

import { KeyValue, UnsignedTx } from '../../interfaces';
export declare function decode(keyVal: KeyValue): UnsignedTx;
export declare function encode(data: UnsignedTx): KeyValue;
import { KeyValue, Transaction } from '../../interfaces';
export declare function encode(data: Transaction): KeyValue;
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
const typeFields_1 = require('../../typeFields');
function decode(keyVal) {
if (keyVal.key[0] !== typeFields_1.GlobalTypes.UNSIGNED_TX) {
throw new Error(
'Decode Error: could not decode unsignedTx with key 0x' +
keyVal.key.toString('hex'),
);
}
return keyVal.value;
}
exports.decode = decode;
function encode(data) {
const key = Buffer.from([typeFields_1.GlobalTypes.UNSIGNED_TX]);
return {
key,
value: data,
key: Buffer.from([typeFields_1.GlobalTypes.UNSIGNED_TX]),
value: data.toBuffer(),
};
}
exports.encode = encode;

@@ -27,2 +27,5 @@ /// <reference types="node" />

encode: (data: import("../interfaces").Bip32Derivation) => import("../interfaces").KeyValue;
check: (data: any) => data is import("../interfaces").Bip32Derivation;
expected: string;
canAddToArray: (array: import("../interfaces").Bip32Derivation[], item: import("../interfaces").Bip32Derivation, dupeSet: Set<string>) => boolean;
};

@@ -32,2 +35,5 @@ redeemScript: {

encode: (data: Buffer) => import("../interfaces").KeyValue;
check: (data: any) => data is Buffer;
expected: string;
canAdd: (currentData: any, newData: any) => boolean;
};

@@ -37,2 +43,5 @@ witnessScript: {

encode: (data: Buffer) => import("../interfaces").KeyValue;
check: (data: any) => data is Buffer;
expected: string;
canAdd: (currentData: any, newData: any) => boolean;
};

@@ -45,2 +54,5 @@ checkPubkey: (keyVal: import("../interfaces").KeyValue) => Buffer | undefined;

encode: (data: import("../interfaces").Bip32Derivation) => import("../interfaces").KeyValue;
check: (data: any) => data is import("../interfaces").Bip32Derivation;
expected: string;
canAddToArray: (array: import("../interfaces").Bip32Derivation[], item: import("../interfaces").Bip32Derivation, dupeSet: Set<string>) => boolean;
};

@@ -50,2 +62,5 @@ redeemScript: {

encode: (data: Buffer) => import("../interfaces").KeyValue;
check: (data: any) => data is Buffer;
expected: string;
canAdd: (currentData: any, newData: any) => boolean;
};

@@ -55,2 +70,5 @@ witnessScript: {

encode: (data: Buffer) => import("../interfaces").KeyValue;
check: (data: any) => data is Buffer;
expected: string;
canAdd: (currentData: any, newData: any) => boolean;
};

@@ -57,0 +75,0 @@ checkPubkey: (keyVal: import("../interfaces").KeyValue) => Buffer | undefined;

import { FinalScriptSig, KeyValue } from '../../interfaces';
export declare function decode(keyVal: KeyValue): FinalScriptSig;
export declare function encode(data: FinalScriptSig): KeyValue;
export declare const expected = "Buffer";
export declare function check(data: any): data is FinalScriptSig;
export declare function canAdd(currentData: any, newData: any): boolean;

@@ -22,1 +22,10 @@ 'use strict';

exports.encode = encode;
exports.expected = 'Buffer';
function check(data) {
return Buffer.isBuffer(data);
}
exports.check = check;
function canAdd(currentData, newData) {
return !!currentData && !!newData && currentData.finalScriptSig === undefined;
}
exports.canAdd = canAdd;
import { FinalScriptWitness, KeyValue } from '../../interfaces';
export declare function decode(keyVal: KeyValue): FinalScriptWitness;
export declare function encode(data: FinalScriptWitness): KeyValue;
export declare const expected = "Buffer";
export declare function check(data: any): data is FinalScriptWitness;
export declare function canAdd(currentData: any, newData: any): boolean;

@@ -22,1 +22,12 @@ 'use strict';

exports.encode = encode;
exports.expected = 'Buffer';
function check(data) {
return Buffer.isBuffer(data);
}
exports.check = check;
function canAdd(currentData, newData) {
return (
!!currentData && !!newData && currentData.finalScriptWitness === undefined
);
}
exports.canAdd = canAdd;
import { KeyValue, NonWitnessUtxo } from '../../interfaces';
export declare function decode(keyVal: KeyValue): NonWitnessUtxo;
export declare function encode(data: NonWitnessUtxo): KeyValue;
export declare const expected = "Buffer";
export declare function check(data: any): data is NonWitnessUtxo;
export declare function canAdd(currentData: any, newData: any): boolean;

@@ -21,1 +21,15 @@ 'use strict';

exports.encode = encode;
exports.expected = 'Buffer';
function check(data) {
return Buffer.isBuffer(data);
}
exports.check = check;
function canAdd(currentData, newData) {
return (
!!currentData &&
!!newData &&
currentData.witnessUtxo === undefined &&
currentData.nonWitnessUtxo === undefined
);
}
exports.canAdd = canAdd;
import { KeyValue, PartialSig } from '../../interfaces';
export declare function decode(keyVal: KeyValue): PartialSig;
export declare function encode(pSig: PartialSig): KeyValue;
export declare const expected = "{ pubkey: Buffer; signature: Buffer; }";
export declare function check(data: any): data is PartialSig;
export declare function canAddToArray(array: PartialSig[], item: PartialSig, dupeSet: Set<string>): boolean;

@@ -35,1 +35,32 @@ 'use strict';

exports.encode = encode;
exports.expected = '{ pubkey: Buffer; signature: Buffer; }';
function check(data) {
return (
Buffer.isBuffer(data.pubkey) &&
Buffer.isBuffer(data.signature) &&
[33, 65].includes(data.pubkey.length) &&
[2, 3, 4].includes(data.pubkey[0]) &&
isDerSigWithSighash(data.signature)
);
}
exports.check = check;
function isDerSigWithSighash(buf) {
if (!Buffer.isBuffer(buf) || buf.length < 9) return false;
if (buf[0] !== 0x30) return false;
if (buf.length !== buf[1] + 3) return false;
if (buf[2] !== 0x02) return false;
const rLen = buf[3];
if (rLen > 33 || rLen < 1) return false;
if (buf[3 + rLen + 1] !== 0x02) return false;
const sLen = buf[3 + rLen + 2];
if (sLen > 33 || sLen < 1) return false;
if (buf.length !== 3 + rLen + 2 + sLen + 2) return false;
return true;
}
function canAddToArray(array, item, dupeSet) {
const dupeString = item.pubkey.toString('hex');
if (dupeSet.has(dupeString)) return false;
dupeSet.add(dupeString);
return array.filter(v => v.pubkey.equals(item.pubkey)).length === 0;
}
exports.canAddToArray = canAddToArray;
import { KeyValue, PorCommitment } from '../../interfaces';
export declare function decode(keyVal: KeyValue): PorCommitment;
export declare function encode(data: PorCommitment): KeyValue;
export declare const expected = "string";
export declare function check(data: any): data is PorCommitment;
export declare function canAdd(currentData: any, newData: any): boolean;

@@ -22,1 +22,10 @@ 'use strict';

exports.encode = encode;
exports.expected = 'string';
function check(data) {
return typeof data === 'string';
}
exports.check = check;
function canAdd(currentData, newData) {
return !!currentData && !!newData && currentData.porCommitment === undefined;
}
exports.canAdd = canAdd;
import { KeyValue, SighashType } from '../../interfaces';
export declare function decode(keyVal: KeyValue): SighashType;
export declare function encode(data: SighashType): KeyValue;
export declare const expected = "number";
export declare function check(data: any): data is SighashType;
export declare function canAdd(currentData: any, newData: any): boolean;

@@ -24,1 +24,10 @@ 'use strict';

exports.encode = encode;
exports.expected = 'number';
function check(data) {
return typeof data === 'number';
}
exports.check = check;
function canAdd(currentData, newData) {
return !!currentData && !!newData && currentData.sighashType === undefined;
}
exports.canAdd = canAdd;
import { KeyValue, WitnessUtxo } from '../../interfaces';
export declare function decode(keyVal: KeyValue): WitnessUtxo;
export declare function encode(data: WitnessUtxo): KeyValue;
export declare const expected = "{ script: Buffer; value: number; }";
export declare function check(data: any): data is WitnessUtxo;
export declare function canAdd(currentData: any, newData: any): boolean;

@@ -40,1 +40,15 @@ 'use strict';

exports.encode = encode;
exports.expected = '{ script: Buffer; value: number; }';
function check(data) {
return Buffer.isBuffer(data.script) && typeof data.value === 'number';
}
exports.check = check;
function canAdd(currentData, newData) {
return (
!!currentData &&
!!newData &&
currentData.witnessUtxo === undefined &&
currentData.nonWitnessUtxo === undefined
);
}
exports.canAdd = canAdd;

@@ -5,2 +5,5 @@ import { Bip32Derivation, KeyValue } from '../../interfaces';

encode: (data: Bip32Derivation) => KeyValue;
check: (data: any) => data is Bip32Derivation;
expected: string;
canAddToArray: (array: Bip32Derivation[], item: Bip32Derivation, dupeSet: Set<string>) => boolean;
};

@@ -5,6 +5,2 @@ 'use strict';

function makeConverter(TYPE_BYTE) {
return {
decode,
encode,
};
function decode(keyVal) {

@@ -64,3 +60,28 @@ if (keyVal.key[0] !== TYPE_BYTE) {

}
const expected =
'{ masterFingerprint: Buffer; pubkey: Buffer; path: string; }';
function check(data) {
return (
Buffer.isBuffer(data.pubkey) &&
Buffer.isBuffer(data.masterFingerprint) &&
typeof data.path === 'string' &&
[33, 65].includes(data.pubkey.length) &&
[2, 3, 4].includes(data.pubkey[0]) &&
data.masterFingerprint.length === 4
);
}
function canAddToArray(array, item, dupeSet) {
const dupeString = item.pubkey.toString('hex');
if (dupeSet.has(dupeString)) return false;
dupeSet.add(dupeString);
return array.filter(v => v.pubkey.equals(item.pubkey)).length === 0;
}
return {
decode,
encode,
check,
expected,
canAddToArray,
};
}
exports.makeConverter = makeConverter;

@@ -5,2 +5,5 @@ import { KeyValue, RedeemScript } from '../../interfaces';

encode: (data: RedeemScript) => KeyValue;
check: (data: any) => data is RedeemScript;
expected: string;
canAdd: (currentData: any, newData: any) => boolean;
};
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
function makeConverter(TYPE_BYTE) {
return {
decode,
encode,
};
function decode(keyVal) {

@@ -24,3 +20,17 @@ if (keyVal.key[0] !== TYPE_BYTE) {

}
const expected = 'Buffer';
function check(data) {
return Buffer.isBuffer(data);
}
function canAdd(currentData, newData) {
return !!currentData && !!newData && currentData.redeemScript === undefined;
}
return {
decode,
encode,
check,
expected,
canAdd,
};
}
exports.makeConverter = makeConverter;

@@ -5,2 +5,5 @@ import { KeyValue, WitnessScript } from '../../interfaces';

encode: (data: WitnessScript) => KeyValue;
check: (data: any) => data is WitnessScript;
expected: string;
canAdd: (currentData: any, newData: any) => boolean;
};
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
function makeConverter(TYPE_BYTE) {
return {
decode,
encode,
};
function decode(keyVal) {

@@ -24,3 +20,19 @@ if (keyVal.key[0] !== TYPE_BYTE) {

}
const expected = 'Buffer';
function check(data) {
return Buffer.isBuffer(data);
}
function canAdd(currentData, newData) {
return (
!!currentData && !!newData && currentData.witnessScript === undefined
);
}
return {
decode,
encode,
check,
expected,
canAdd,
};
}
exports.makeConverter = makeConverter;
/// <reference types="node" />
export declare type TransactionFromBuffer = (buffer: Buffer) => Transaction;
export interface Transaction {
getInputOutputCounts(): {
inputCount: number;
outputCount: number;
};
addInput(objectArg: any): void;
addOutput(objectArg: any): void;
toBuffer(): Buffer;
}
export interface KeyValue {

@@ -6,9 +16,13 @@ key: Buffer;

}
export interface PsbtGlobal {
unknownKeyVals: KeyValue[];
unsignedTx?: UnsignedTx;
globalXpub?: GlobalXpub;
export interface PsbtGlobal extends PsbtGlobalUpdate {
unsignedTx: Transaction;
unknownKeyVals?: KeyValue[];
}
export interface PsbtInput {
unknownKeyVals: KeyValue[];
export interface PsbtGlobalUpdate {
globalXpub?: GlobalXpub[];
}
export interface PsbtInput extends PsbtInputUpdate {
unknownKeyVals?: KeyValue[];
}
export interface PsbtInputUpdate {
partialSig?: PartialSig[];

@@ -25,4 +39,9 @@ nonWitnessUtxo?: NonWitnessUtxo;

}
export interface PsbtOutput {
unknownKeyVals: KeyValue[];
export interface PsbtInputExtended extends PsbtInput {
[index: string]: any;
}
export interface PsbtOutput extends PsbtOutputUpdate {
unknownKeyVals?: KeyValue[];
}
export interface PsbtOutputUpdate {
redeemScript?: RedeemScript;

@@ -32,3 +51,5 @@ witnessScript?: WitnessScript;

}
export declare type UnsignedTx = Buffer;
export interface PsbtOutputExtended extends PsbtOutput {
[index: string]: any;
}
export interface GlobalXpub {

@@ -39,3 +60,2 @@ extendedPubkey: Buffer;

}
export declare function isGlobalXpub(data: any): data is GlobalXpub;
export interface PartialSig {

@@ -45,3 +65,2 @@ pubkey: Buffer;

}
export declare function isPartialSig(data: any): data is PartialSig;
export interface Bip32Derivation {

@@ -52,3 +71,2 @@ masterFingerprint: Buffer;

}
export declare function isBip32Derivation(data: any): data is Bip32Derivation;
export interface WitnessUtxo {

@@ -58,3 +76,2 @@ script: Buffer;

}
export declare function isWitnessUtxo(data: any): data is WitnessUtxo;
export declare type NonWitnessUtxo = Buffer;

@@ -75,32 +92,10 @@ export declare type SighashType = number;

sequence?: number;
unknownKeyVals?: KeyValue[];
partialSig?: PartialSig[];
nonWitnessUtxo?: NonWitnessUtxo;
witnessUtxo?: WitnessUtxo;
sighashType?: SighashType;
redeemScript?: RedeemScript;
witnessScript?: WitnessScript;
bip32Derivation?: Bip32Derivation[];
finalScriptSig?: FinalScriptSig;
finalScriptWitness?: FinalScriptWitness;
porCommitment?: PorCommitment;
}
export declare type TransactionInputAdder = (input: TransactionInput, txBuffer: Buffer) => Buffer;
interface TransactionOutputBase {
export interface TransactionOutput {
script: Buffer;
value: number;
unknownKeyVals?: KeyValue[];
redeemScript?: RedeemScript;
witnessScript?: WitnessScript;
bip32Derivation?: Bip32Derivation[];
}
export interface TransactionOutputAddress extends TransactionOutputBase {
address: string;
}
export interface TransactionOutputScript extends TransactionOutputBase {
script: Buffer;
}
export declare type TransactionOutput = TransactionOutputAddress | TransactionOutputScript;
export declare type TransactionOutputAdder = (output: TransactionOutput, txBuffer: Buffer) => Buffer;
export declare type TransactionVersionSetter = (version: number, txBuffer: Buffer) => Buffer;
export declare type TransactionLocktimeSetter = (locktime: number, txBuffer: Buffer) => Buffer;
export {};
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
function isGlobalXpub(data) {
return (
Buffer.isBuffer(data.extendedPubkey) &&
Buffer.isBuffer(data.masterFingerprint) &&
typeof data.path === 'string' &&
data.extendedPubkey.length === 78 &&
[2, 3].includes(data.extendedPubkey[45]) &&
data.masterFingerprint.length === 4
);
}
exports.isGlobalXpub = isGlobalXpub;
function isPartialSig(data) {
return (
Buffer.isBuffer(data.pubkey) &&
Buffer.isBuffer(data.signature) &&
[33, 65].includes(data.pubkey.length) &&
[2, 3, 4].includes(data.pubkey[0]) &&
isDerSigWithSighash(data.signature)
);
}
exports.isPartialSig = isPartialSig;
function isDerSigWithSighash(buf) {
if (!Buffer.isBuffer(buf) || buf.length < 9) return false;
if (buf[0] !== 0x30) return false;
if (buf.length !== buf[1] + 3) return false;
if (buf[2] !== 0x02) return false;
const rLen = buf[3];
if (rLen > 33 || rLen < 1) return false;
if (buf[3 + rLen + 1] !== 0x02) return false;
const sLen = buf[3 + rLen + 2];
if (sLen > 33 || sLen < 1) return false;
if (buf.length !== 3 + rLen + 2 + sLen + 2) return false;
return true;
}
function isBip32Derivation(data) {
return (
Buffer.isBuffer(data.pubkey) &&
Buffer.isBuffer(data.masterFingerprint) &&
typeof data.path === 'string' &&
[33, 65].includes(data.pubkey.length) &&
[2, 3, 4].includes(data.pubkey[0]) &&
data.masterFingerprint.length === 4
);
}
exports.isBip32Derivation = isBip32Derivation;
function isWitnessUtxo(data) {
return Buffer.isBuffer(data.script) && typeof data.value === 'number';
}
exports.isWitnessUtxo = isWitnessUtxo;
/// <reference types="node" />
import { KeyValue, TransactionIOCountGetter } from '../interfaces';
import { KeyValue, Transaction, TransactionFromBuffer } from '../interfaces';
import { PsbtAttributes } from './index';
export declare function psbtFromBuffer(buffer: Buffer, txCountGetter: TransactionIOCountGetter): PsbtAttributes;
export declare function psbtFromBuffer(buffer: Buffer, txGetter: TransactionFromBuffer): PsbtAttributes;
interface PsbtFromKeyValsArg {

@@ -11,3 +11,3 @@ globalMapKeyVals: KeyValue[];

export declare function checkKeyBuffer(type: string, keyBuf: Buffer, keyNum: number): void;
export declare function psbtFromKeyVals({ globalMapKeyVals, inputKeyVals, outputKeyVals, }: PsbtFromKeyValsArg): PsbtAttributes;
export declare function psbtFromKeyVals(unsignedTx: Transaction, { globalMapKeyVals, inputKeyVals, outputKeyVals }: PsbtFromKeyValsArg): PsbtAttributes;
export {};

@@ -7,3 +7,3 @@ 'use strict';

const typeFields_1 = require('../typeFields');
function psbtFromBuffer(buffer, txCountGetter) {
function psbtFromBuffer(buffer, txGetter) {
let offset = 0;

@@ -72,6 +72,5 @@ function varSlice() {

}
const unsignedTx = txCountGetter(unsignedTxMaps[0].value);
const unsignedTx = txGetter(unsignedTxMaps[0].value);
// Get input and output counts to loop the respective fields
const inputCount = unsignedTx.inputCount;
const outputCount = unsignedTx.outputCount;
const { inputCount, outputCount } = unsignedTx.getInputOutputCounts();
const inputKeyVals = [];

@@ -120,3 +119,7 @@ const outputKeyVals = [];

}
return psbtFromKeyVals({ globalMapKeyVals, inputKeyVals, outputKeyVals });
return psbtFromKeyVals(unsignedTx, {
globalMapKeyVals,
inputKeyVals,
outputKeyVals,
});
}

@@ -132,7 +135,11 @@ exports.psbtFromBuffer = psbtFromBuffer;

exports.checkKeyBuffer = checkKeyBuffer;
function psbtFromKeyVals({ globalMapKeyVals, inputKeyVals, outputKeyVals }) {
function psbtFromKeyVals(
unsignedTx,
{ globalMapKeyVals, inputKeyVals, outputKeyVals },
) {
// That was easy :-)
const globalMap = {
unknownKeyVals: [],
unsignedTx,
};
let txCount = 0;
for (const keyVal of globalMapKeyVals) {

@@ -148,12 +155,16 @@ // If a globalMap item needs pubkey, uncomment

);
if (globalMap.unsignedTx !== undefined) {
if (txCount > 0) {
throw new Error('Format Error: GlobalMap has multiple UNSIGNED_TX');
}
globalMap.unsignedTx = convert.globals.unsignedTx.decode(keyVal);
txCount++;
break;
case typeFields_1.GlobalTypes.GLOBAL_XPUB:
globalMap.globalXpub = convert.globals.globalXpub.decode(keyVal);
if (globalMap.globalXpub === undefined) {
globalMap.globalXpub = [];
}
globalMap.globalXpub.push(convert.globals.globalXpub.decode(keyVal));
break;
default:
// This will allow inclusion during serialization.
if (!globalMap.unknownKeyVals) globalMap.unknownKeyVals = [];
globalMap.unknownKeyVals.push(keyVal);

@@ -169,5 +180,3 @@ }

for (const index of tools_1.range(inputCount)) {
const input = {
unknownKeyVals: [],
};
const input = {};
for (const keyVal of inputKeyVals[index]) {

@@ -283,2 +292,3 @@ convert.inputs.checkPubkey(keyVal);

// This will allow inclusion during serialization.
if (!input.unknownKeyVals) input.unknownKeyVals = [];
input.unknownKeyVals.push(keyVal);

@@ -290,5 +300,3 @@ }

for (const index of tools_1.range(outputCount)) {
const output = {
unknownKeyVals: [],
};
const output = {};
for (const keyVal of outputKeyVals[index]) {

@@ -328,2 +336,3 @@ convert.outputs.checkPubkey(keyVal);

default:
if (!output.unknownKeyVals) output.unknownKeyVals = [];
output.unknownKeyVals.push(keyVal);

@@ -330,0 +339,0 @@ }

@@ -12,12 +12,8 @@ 'use strict';

const globalBuffer = tools_1.keyValsToBuffer(globalKeyVals);
const inputBuffers = [];
const outputBuffers = [];
inputKeyVals.forEach(input => {
inputBuffers.push(tools_1.keyValsToBuffer(input));
});
outputKeyVals.forEach(output => {
outputBuffers.push(tools_1.keyValsToBuffer(output));
});
if (inputBuffers.length === 0) inputBuffers.push(Buffer.from([0]));
if (outputBuffers.length === 0) outputBuffers.push(Buffer.from([0]));
const keyValsOrEmptyToBuffer = keyVals =>
keyVals.length === 0
? [Buffer.from([0])]
: keyVals.map(tools_1.keyValsToBuffer);
const inputBuffers = keyValsOrEmptyToBuffer(inputKeyVals);
const outputBuffers = keyValsOrEmptyToBuffer(outputKeyVals);
const header = Buffer.allocUnsafe(5);

@@ -64,5 +60,7 @@ header.writeUIntBE(0x70736274ff, 0, 5);

// Get other keyVals that have not yet been gotten
const otherKeyVals = keyValMap.unknownKeyVals.filter(keyVal => {
return !keyHexes.has(keyVal.key.toString('hex'));
});
const otherKeyVals = keyValMap.unknownKeyVals
? keyValMap.unknownKeyVals.filter(keyVal => {
return !keyHexes.has(keyVal.key.toString('hex'));
})
: [];
return keyVals.concat(otherKeyVals).sort(sortKeyVals);

@@ -69,0 +67,0 @@ }

/// <reference types="node" />
import { Bip32Derivation, FinalScriptSig, FinalScriptWitness, GlobalXpub, KeyValue, NonWitnessUtxo, PartialSig, PorCommitment, PsbtGlobal, PsbtInput, PsbtOutput, RedeemScript, SighashType, TransactionIOCountGetter, TransactionLocktimeSetter, TransactionVersionSetter, WitnessScript, WitnessUtxo } from './interfaces';
import { KeyValue, PsbtGlobal, PsbtGlobalUpdate, PsbtInput, PsbtInputExtended, PsbtInputUpdate, PsbtOutput, PsbtOutputExtended, PsbtOutputUpdate, Transaction, TransactionFromBuffer } from './interfaces';
export declare class Psbt {
static fromTransaction<T extends typeof Psbt>(this: T, txBuf: Buffer, txCountGetter: TransactionIOCountGetter): InstanceType<T>;
static fromBase64<T extends typeof Psbt>(this: T, data: string, txCountGetter: TransactionIOCountGetter): InstanceType<T>;
static fromHex<T extends typeof Psbt>(this: T, data: string, txCountGetter: TransactionIOCountGetter): InstanceType<T>;
static fromBuffer<T extends typeof Psbt>(this: T, buffer: Buffer, txCountGetter: TransactionIOCountGetter): InstanceType<T>;
static fromBase64<T extends typeof Psbt>(this: T, data: string, txFromBuffer: TransactionFromBuffer): InstanceType<T>;
static fromHex<T extends typeof Psbt>(this: T, data: string, txFromBuffer: TransactionFromBuffer): InstanceType<T>;
static fromBuffer<T extends typeof Psbt>(this: T, buffer: Buffer, txFromBuffer: TransactionFromBuffer): InstanceType<T>;
readonly inputs: PsbtInput[];
readonly outputs: PsbtOutput[];
readonly globalMap: PsbtGlobal;
constructor(tx: Transaction);
toBase64(): string;
toHex(): string;
toBuffer(): Buffer;
setVersion(version: number, transactionVersionSetter?: TransactionVersionSetter): this;
setLocktime(locktime: number, transactionLocktimeSetter?: TransactionLocktimeSetter): this;
addGlobalXpubToGlobal(globalXpub: GlobalXpub): this;
addNonWitnessUtxoToInput(inputIndex: number, nonWitnessUtxo: NonWitnessUtxo): this;
addWitnessUtxoToInput(inputIndex: number, witnessUtxo: WitnessUtxo): this;
addPartialSigToInput(inputIndex: number, partialSig: PartialSig): this;
addSighashTypeToInput(inputIndex: number, sighashType: SighashType): this;
addRedeemScriptToInput(inputIndex: number, redeemScript: RedeemScript): this;
addWitnessScriptToInput(inputIndex: number, witnessScript: WitnessScript): this;
addBip32DerivationToInput(inputIndex: number, bip32Derivation: Bip32Derivation): this;
addFinalScriptSigToInput(inputIndex: number, finalScriptSig: FinalScriptSig): this;
addFinalScriptWitnessToInput(inputIndex: number, finalScriptWitness: FinalScriptWitness): this;
addPorCommitmentToInput(inputIndex: number, porCommitment: PorCommitment): this;
addRedeemScriptToOutput(outputIndex: number, redeemScript: RedeemScript): this;
addWitnessScriptToOutput(outputIndex: number, witnessScript: WitnessScript): this;
addBip32DerivationToOutput(outputIndex: number, bip32Derivation: Bip32Derivation): this;
updateGlobal(updateData: PsbtGlobalUpdate): this;
updateInput(inputIndex: number, updateData: PsbtInputUpdate): this;
updateOutput(outputIndex: number, updateData: PsbtOutputUpdate): this;
addUnknownKeyValToGlobal(keyVal: KeyValue): this;
addUnknownKeyValToInput(inputIndex: number, keyVal: KeyValue): this;
addUnknownKeyValToOutput(outputIndex: number, keyVal: KeyValue): this;
addInput<T>(inputData: T, transactionInputAdder: (input: T, txBuffer: Buffer) => Buffer): this;
addOutput<T>(outputData: T, transactionOutputAdder: (output: T, txBuffer: Buffer) => Buffer, allowNoInput?: boolean): this;
addInput(inputData: PsbtInputExtended): this;
addOutput(outputData: PsbtOutputExtended): this;
clearFinalizedInput(inputIndex: number): this;

@@ -36,0 +23,0 @@ combine(...those: this[]): this;

'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
const combiner_1 = require('./combiner');
const interfaces_1 = require('./interfaces');
const parser_1 = require('./parser');
const typeFields_1 = require('./typeFields');
const utils_1 = require('./utils');
// version 1, locktime 0, 0 ins, 0 outs
const DEFAULT_UNSIGNED_TX = Buffer.from('01000000000000000000', 'hex');
class Psbt {
constructor() {
constructor(tx) {
this.inputs = [];
this.outputs = [];
this.globalMap = {
unknownKeyVals: [],
unsignedTx: Buffer.from(DEFAULT_UNSIGNED_TX),
unsignedTx: tx,
};
}
static fromTransaction(txBuf, txCountGetter) {
const result = txCountGetter(txBuf);
const psbt = new this();
psbt.globalMap.unsignedTx = txBuf;
while (result.inputCount > 0) {
psbt.inputs.push({
unknownKeyVals: [],
});
result.inputCount--;
}
while (result.outputCount > 0) {
psbt.outputs.push({
unknownKeyVals: [],
});
result.outputCount--;
}
return psbt;
}
static fromBase64(data, txCountGetter) {
static fromBase64(data, txFromBuffer) {
const buffer = Buffer.from(data, 'base64');
return this.fromBuffer(buffer, txCountGetter);
return this.fromBuffer(buffer, txFromBuffer);
}
static fromHex(data, txCountGetter) {
static fromHex(data, txFromBuffer) {
const buffer = Buffer.from(data, 'hex');
return this.fromBuffer(buffer, txCountGetter);
return this.fromBuffer(buffer, txFromBuffer);
}
static fromBuffer(buffer, txCountGetter) {
const psbt = new this();
const results = parser_1.psbtFromBuffer(buffer, txCountGetter);
static fromBuffer(buffer, txFromBuffer) {
const results = parser_1.psbtFromBuffer(buffer, txFromBuffer);
const psbt = new this(results.globalMap.unsignedTx);
Object.assign(psbt, results);

@@ -62,157 +40,16 @@ return psbt;

}
setVersion(version, transactionVersionSetter) {
let func;
if (transactionVersionSetter !== undefined) {
func = transactionVersionSetter;
} else {
func = utils_1.defaultVersionSetter;
}
const updated = func(version, this.globalMap.unsignedTx);
utils_1.insertTxInGlobalMap(updated, this.globalMap);
updateGlobal(updateData) {
utils_1.updateGlobal(updateData, this.globalMap);
return this;
}
setLocktime(locktime, transactionLocktimeSetter) {
let func;
if (transactionLocktimeSetter !== undefined) {
func = transactionLocktimeSetter;
} else {
func = utils_1.defaultLocktimeSetter;
}
const updated = func(locktime, this.globalMap.unsignedTx);
utils_1.insertTxInGlobalMap(updated, this.globalMap);
return this;
}
addGlobalXpubToGlobal(globalXpub) {
if (!interfaces_1.isGlobalXpub(globalXpub)) {
throw new Error(
'globalXpub should be { masterFingerprint: Buffer; extendedPubkey: ' +
'Buffer; path: string; }',
);
}
this.globalMap.globalXpub = globalXpub;
return this;
}
addNonWitnessUtxoToInput(inputIndex, nonWitnessUtxo) {
updateInput(inputIndex, updateData) {
const input = utils_1.checkForInput(this.inputs, inputIndex);
if (input.nonWitnessUtxo || input.witnessUtxo) {
throw new Error(`Input #${inputIndex} already has a Utxo attribute`);
}
if (!Buffer.isBuffer(nonWitnessUtxo)) {
throw new Error('nonWitnessUtxo should be a Buffer of a Transaction');
}
input.nonWitnessUtxo = nonWitnessUtxo;
utils_1.updateInput(updateData, input);
return this;
}
addWitnessUtxoToInput(inputIndex, witnessUtxo) {
const input = utils_1.checkForInput(this.inputs, inputIndex);
if (input.nonWitnessUtxo || input.witnessUtxo) {
throw new Error(`Input #${inputIndex} already has a Utxo attribute`);
}
if (!interfaces_1.isWitnessUtxo(witnessUtxo)) {
throw new Error(
'witnessUtxo should be { script: Buffer; value: number; }',
);
}
input.witnessUtxo = witnessUtxo;
return this;
}
addPartialSigToInput(inputIndex, partialSig) {
const input = utils_1.checkForInput(this.inputs, inputIndex);
if (!interfaces_1.isPartialSig(partialSig)) {
throw new Error(
'partialSig should be { pubkey: Buffer; signature: Buffer; }',
);
}
if (input.partialSig === undefined) input.partialSig = [];
input.partialSig.push(partialSig);
return this;
}
addSighashTypeToInput(inputIndex, sighashType) {
const input = utils_1.checkForInput(this.inputs, inputIndex);
if (typeof sighashType !== 'number') {
throw new Error('sighashType should be a number');
}
input.sighashType = sighashType;
return this;
}
addRedeemScriptToInput(inputIndex, redeemScript) {
const input = utils_1.checkForInput(this.inputs, inputIndex);
if (!Buffer.isBuffer(redeemScript)) {
throw new Error('redeemScript should be a Buffer');
}
input.redeemScript = redeemScript;
return this;
}
addWitnessScriptToInput(inputIndex, witnessScript) {
const input = utils_1.checkForInput(this.inputs, inputIndex);
if (!Buffer.isBuffer(witnessScript)) {
throw new Error('witnessScript should be a Buffer');
}
input.witnessScript = witnessScript;
return this;
}
addBip32DerivationToInput(inputIndex, bip32Derivation) {
const input = utils_1.checkForInput(this.inputs, inputIndex);
if (!interfaces_1.isBip32Derivation(bip32Derivation)) {
throw new Error(
'bip32Derivation should be { masterFingerprint: Buffer; pubkey: ' +
'Buffer; path: string; }',
);
}
if (input.bip32Derivation === undefined) input.bip32Derivation = [];
input.bip32Derivation.push(bip32Derivation);
return this;
}
addFinalScriptSigToInput(inputIndex, finalScriptSig) {
const input = utils_1.checkForInput(this.inputs, inputIndex);
if (!Buffer.isBuffer(finalScriptSig)) {
throw new Error('finalScriptSig should be a Buffer');
}
input.finalScriptSig = finalScriptSig;
return this;
}
addFinalScriptWitnessToInput(inputIndex, finalScriptWitness) {
const input = utils_1.checkForInput(this.inputs, inputIndex);
if (!Buffer.isBuffer(finalScriptWitness)) {
throw new Error('finalScriptWitness should be a Buffer');
}
input.finalScriptWitness = finalScriptWitness;
return this;
}
addPorCommitmentToInput(inputIndex, porCommitment) {
const input = utils_1.checkForInput(this.inputs, inputIndex);
if (typeof porCommitment !== 'string') {
throw new Error('porCommitment should be a string');
}
input.porCommitment = porCommitment;
return this;
}
addRedeemScriptToOutput(outputIndex, redeemScript) {
updateOutput(outputIndex, updateData) {
const output = utils_1.checkForOutput(this.outputs, outputIndex);
if (!Buffer.isBuffer(redeemScript)) {
throw new Error('redeemScript should be a Buffer');
}
output.redeemScript = redeemScript;
utils_1.updateOutput(updateData, output);
return this;
}
addWitnessScriptToOutput(outputIndex, witnessScript) {
const output = utils_1.checkForOutput(this.outputs, outputIndex);
if (!Buffer.isBuffer(witnessScript)) {
throw new Error('witnessScript should be a Buffer');
}
output.witnessScript = witnessScript;
return this;
}
addBip32DerivationToOutput(outputIndex, bip32Derivation) {
const output = utils_1.checkForOutput(this.outputs, outputIndex);
if (!interfaces_1.isBip32Derivation(bip32Derivation)) {
throw new Error(
'bip32Derivation should be { masterFingerprint: Buffer; pubkey: ' +
'Buffer; path: string; }',
);
}
if (output.bip32Derivation === undefined) output.bip32Derivation = [];
output.bip32Derivation.push(bip32Derivation);
return this;
}
addUnknownKeyValToGlobal(keyVal) {

@@ -224,2 +61,3 @@ utils_1.checkHasKey(

);
if (!this.globalMap.unknownKeyVals) this.globalMap.unknownKeyVals = [];
this.globalMap.unknownKeyVals.push(keyVal);

@@ -235,2 +73,3 @@ return this;

);
if (!input.unknownKeyVals) input.unknownKeyVals = [];
input.unknownKeyVals.push(keyVal);

@@ -246,13 +85,8 @@ return this;

);
if (!output.unknownKeyVals) output.unknownKeyVals = [];
output.unknownKeyVals.push(keyVal);
return this;
}
addInput(inputData, transactionInputAdder) {
if (transactionInputAdder === undefined) {
throw new Error('You must pass a function to handle the input.');
}
const txBuf = this.getTransaction();
let newTxBuf;
newTxBuf = transactionInputAdder(inputData, txBuf);
utils_1.insertTxInGlobalMap(newTxBuf, this.globalMap);
addInput(inputData) {
this.globalMap.unsignedTx.addInput(inputData);
this.inputs.push({

@@ -269,18 +103,7 @@ unknownKeyVals: [],

);
utils_1.addInputAttributes(this, inputData);
utils_1.addInputAttributes(this.inputs, inputData);
return this;
}
addOutput(outputData, transactionOutputAdder, allowNoInput) {
if (!allowNoInput && this.inputs.length === 0) {
throw new Error(
'Add Output: can not add an output before adding an input.',
);
}
if (transactionOutputAdder === undefined) {
throw new Error('You must pass a function to handle the output.');
}
const txBuf = this.getTransaction();
let newTxBuf;
newTxBuf = transactionOutputAdder(outputData, txBuf);
utils_1.insertTxInGlobalMap(newTxBuf, this.globalMap);
addOutput(outputData) {
this.globalMap.unsignedTx.addOutput(outputData);
this.outputs.push({

@@ -297,3 +120,3 @@ unknownKeyVals: [],

);
utils_1.addOutputAttributes(this, outputData);
utils_1.addOutputAttributes(this.outputs, outputData);
return this;

@@ -328,5 +151,5 @@ }

getTransaction() {
return utils_1.getTransactionFromGlobalMap(this.globalMap);
return this.globalMap.unsignedTx.toBuffer();
}
}
exports.Psbt = Psbt;
/// <reference types="node" />
import { KeyValue, PsbtGlobal, PsbtInput, PsbtOutput } from './interfaces';
import { Psbt } from './psbt';
import { KeyValue, PsbtGlobal, PsbtGlobalUpdate, PsbtInput, PsbtInputUpdate, PsbtOutput, PsbtOutputUpdate } from './interfaces';
export declare function checkForInput(inputs: PsbtInput[], inputIndex: number): PsbtInput;
export declare function checkForOutput(outputs: PsbtOutput[], outputIndex: number): PsbtOutput;
export declare function checkHasKey(checkKeyVal: KeyValue, keyVals: KeyValue[], enumLength: number): void;
export declare function checkHasKey(checkKeyVal: KeyValue, keyVals: KeyValue[] | undefined, enumLength: number): void;
export declare function getEnumLength(myenum: any): number;
export declare function getTransactionFromGlobalMap(globalMap: PsbtGlobal): Buffer;
export declare function inputCheckUncleanFinalized(inputIndex: number, input: PsbtInput): void;
export declare function insertTxInGlobalMap(txBuf: Buffer, globalMap: PsbtGlobal): void;
export declare function addInputAttributes<T extends typeof Psbt>(psbt: InstanceType<T>, data: any): void;
export declare function addOutputAttributes<T extends typeof Psbt>(psbt: InstanceType<T>, data: any): void;
export declare const updateGlobal: (updateData: PsbtGlobalUpdate, mainData: PsbtGlobal) => void;
export declare const updateInput: (updateData: PsbtInputUpdate, mainData: PsbtInput) => void;
export declare const updateOutput: (updateData: PsbtOutputUpdate, mainData: PsbtOutput) => void;
export declare function addInputAttributes(inputs: PsbtInput[], data: any): void;
export declare function addOutputAttributes(outputs: PsbtOutput[], data: any): void;
export declare function defaultVersionSetter(version: number, txBuf: Buffer): Buffer;
export declare function defaultLocktimeSetter(locktime: number, txBuf: Buffer): Buffer;
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
const typeFields_1 = require('./typeFields');
const converter = require('./converter');
function checkForInput(inputs, inputIndex) {

@@ -22,3 +22,6 @@ const input = inputs[inputIndex];

}
if (keyVals.filter(kv => kv.key.equals(checkKeyVal.key)).length !== 0) {
if (
keyVals &&
keyVals.filter(kv => kv.key.equals(checkKeyVal.key)).length !== 0
) {
throw new Error(`Duplicate Key: ${checkKeyVal.key.toString('hex')}`);

@@ -38,17 +41,2 @@ }

exports.getEnumLength = getEnumLength;
function getTransactionFromGlobalMap(globalMap) {
const txKeyVals = globalMap.unknownKeyVals.filter(
kv => kv.key[0] === typeFields_1.GlobalTypes.UNSIGNED_TX,
);
const len = txKeyVals.length;
const tx = globalMap.unsignedTx;
const hasTx = tx !== undefined ? 1 : 0;
if (len + hasTx !== 1) {
throw new Error(
`Extract Transaction: Expected one Transaction, got ${len + hasTx}`,
);
}
return tx !== undefined ? tx : txKeyVals[0].value;
}
exports.getTransactionFromGlobalMap = getTransactionFromGlobalMap;
function inputCheckUncleanFinalized(inputIndex, input) {

@@ -74,40 +62,66 @@ let result = false;

exports.inputCheckUncleanFinalized = inputCheckUncleanFinalized;
function insertTxInGlobalMap(txBuf, globalMap) {
const txKeyVals = globalMap.unknownKeyVals.filter(
kv => kv.key[0] === typeFields_1.GlobalTypes.UNSIGNED_TX,
function throwForUpdateMaker(typeName, name, expected, data) {
throw new Error(
`Data for ${typeName} key ${name} is incorrect: Expected ` +
`${expected} and got ${JSON.stringify(data)}`,
);
const len = txKeyVals.length;
const tx = globalMap.unsignedTx;
const hasTx = tx !== undefined ? 1 : 0;
if (len + hasTx !== 1) {
throw new Error(
`Extract Transaction: Expected one Transaction, got ${len + hasTx}`,
);
}
if (tx !== undefined) globalMap.unsignedTx = txBuf;
else txKeyVals[0].value = txBuf;
}
exports.insertTxInGlobalMap = insertTxInGlobalMap;
function addInputAttributes(psbt, data) {
const inputIndex = psbt.inputs.length - 1;
for (const name of typeFields_1.INPUT_TYPE_NAMES) {
const item = data[name];
if (item) {
const nameUpper = name.replace(/^\S/, s => s.toUpperCase());
function updateMaker(typeName) {
return (updateData, mainData) => {
for (const name of Object.keys(updateData)) {
// @ts-ignore
psbt[`add${nameUpper}ToInput`](inputIndex, item);
const data = updateData[name];
// @ts-ignore
const { canAdd, canAddToArray, check, expected } =
// @ts-ignore
converter[typeName + 's'][name] || {};
const isArray = !!canAddToArray;
// If unknown data. ignore and do not add
if (check) {
if (isArray) {
if (
!Array.isArray(data) ||
// @ts-ignore
(mainData[name] && !Array.isArray(mainData[name]))
) {
throw new Error(`Key type ${name} must be an array`);
}
if (!data.every(v => check(v))) {
throwForUpdateMaker(typeName, name, expected, data);
}
// @ts-ignore
const arr = mainData[name] || [];
const dupeCheckSet = new Set();
if (!data.every(v => canAddToArray(arr, v, dupeCheckSet))) {
throw new Error('Can not add duplicate data to array');
}
// @ts-ignore
mainData[name] = arr.concat(data);
} else {
if (!check(data)) {
throwForUpdateMaker(typeName, name, expected, data);
}
if (!canAdd(mainData, data)) {
throw new Error(`Can not add duplicate data to ${typeName}`);
}
// @ts-ignore
mainData[name] = data;
}
}
}
}
};
}
exports.updateGlobal = updateMaker('global');
exports.updateInput = updateMaker('input');
exports.updateOutput = updateMaker('output');
function addInputAttributes(inputs, data) {
const index = inputs.length - 1;
const input = checkForInput(inputs, index);
exports.updateInput(data, input);
}
exports.addInputAttributes = addInputAttributes;
function addOutputAttributes(psbt, data) {
const outputIndex = psbt.outputs.length - 1;
for (const name of typeFields_1.OUTPUT_TYPE_NAMES) {
const item = data[name];
if (item) {
const nameUpper = name.replace(/^\S/, s => s.toUpperCase());
// @ts-ignore
psbt[`add${nameUpper}ToOutput`](outputIndex, item);
}
}
function addOutputAttributes(outputs, data) {
const index = outputs.length - 1;
const output = checkForInput(outputs, index);
exports.updateOutput(data, output);
}

@@ -114,0 +128,0 @@ exports.addOutputAttributes = addOutputAttributes;

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc