2019-06-24 12:20:15 +02:00
|
|
|
import { Psbt as PsbtBase } from 'bip174';
|
2019-10-28 03:40:56 +01:00
|
|
|
import { KeyValue, PsbtGlobalUpdate, PsbtInput, PsbtInputUpdate, PsbtOutput, PsbtOutputUpdate, TransactionInput } from 'bip174/src/lib/interfaces';
|
2019-07-03 08:34:18 +02:00
|
|
|
import { Signer, SignerAsync } from './ecpair';
|
2019-07-01 12:57:35 +02:00
|
|
|
import { Network } from './networks';
|
2020-04-26 10:22:38 +02:00
|
|
|
import { Input, Output, Transaction } from './transaction';
|
2019-07-18 07:20:44 +02:00
|
|
|
/**
|
|
|
|
* Psbt class can parse and generate a PSBT binary based off of the BIP174.
|
|
|
|
* There are 6 roles that this class fulfills. (Explained in BIP174)
|
|
|
|
*
|
|
|
|
* Creator: This can be done with `new Psbt()`
|
|
|
|
* Updater: This can be done with `psbt.addInput(input)`, `psbt.addInputs(inputs)`,
|
|
|
|
* `psbt.addOutput(output)`, `psbt.addOutputs(outputs)` when you are looking to
|
|
|
|
* add new inputs and outputs to the PSBT, and `psbt.updateGlobal(itemObject)`,
|
|
|
|
* `psbt.updateInput(itemObject)`, `psbt.updateOutput(itemObject)`
|
|
|
|
* addInput requires hash: Buffer | string; and index: number; as attributes
|
|
|
|
* and can also include any attributes that are used in updateInput method.
|
|
|
|
* addOutput requires script: Buffer; and value: number; and likewise can include
|
|
|
|
* data for updateOutput.
|
|
|
|
* For a list of what attributes should be what types. Check the bip174 library.
|
|
|
|
* Also, check the integration tests for some examples of usage.
|
2019-07-19 10:21:31 +02:00
|
|
|
* Signer: There are a few methods. signAllInputs and signAllInputsAsync, which will search all input
|
2019-07-18 07:20:44 +02:00
|
|
|
* information for your pubkey or pubkeyhash, and only sign inputs where it finds
|
|
|
|
* your info. Or you can explicitly sign a specific input with signInput and
|
|
|
|
* signInputAsync. For the async methods you can create a SignerAsync object
|
|
|
|
* and use something like a hardware wallet to sign with. (You must implement this)
|
|
|
|
* Combiner: psbts can be combined easily with `psbt.combine(psbt2, psbt3, psbt4 ...)`
|
|
|
|
* the psbt calling combine will always have precedence when a conflict occurs.
|
|
|
|
* Combine checks if the internal bitcoin transaction is the same, so be sure that
|
|
|
|
* all sequences, version, locktime, etc. are the same before combining.
|
|
|
|
* Input Finalizer: This role is fairly important. Not only does it need to construct
|
|
|
|
* the input scriptSigs and witnesses, but it SHOULD verify the signatures etc.
|
2019-07-19 07:53:54 +02:00
|
|
|
* Before running `psbt.finalizeAllInputs()` please run `psbt.validateSignaturesOfAllInputs()`
|
2019-07-18 07:20:44 +02:00
|
|
|
* Running any finalize method will delete any data in the input(s) that are no longer
|
|
|
|
* needed due to the finalized scripts containing the information.
|
|
|
|
* Transaction Extractor: This role will perform some checks before returning a
|
|
|
|
* Transaction object. Such as fee rate not being larger than maximumFeeRate etc.
|
|
|
|
*/
|
2019-07-11 10:17:49 +02:00
|
|
|
export declare class Psbt {
|
|
|
|
readonly data: PsbtBase;
|
|
|
|
static fromBase64(data: string, opts?: PsbtOptsOptional): Psbt;
|
|
|
|
static fromHex(data: string, opts?: PsbtOptsOptional): Psbt;
|
|
|
|
static fromBuffer(buffer: Buffer, opts?: PsbtOptsOptional): Psbt;
|
2019-07-05 09:42:13 +02:00
|
|
|
private __CACHE;
|
2019-07-04 04:26:23 +02:00
|
|
|
private opts;
|
2019-07-11 10:17:49 +02:00
|
|
|
constructor(opts?: PsbtOptsOptional, data?: PsbtBase);
|
2019-07-05 09:42:13 +02:00
|
|
|
readonly inputCount: number;
|
2020-04-26 10:34:11 +02:00
|
|
|
readonly version: number;
|
|
|
|
readonly locktime: number;
|
|
|
|
readonly inputs: Input[];
|
|
|
|
readonly outputs: Output[];
|
2019-07-11 10:17:49 +02:00
|
|
|
combine(...those: Psbt[]): this;
|
2019-07-09 11:03:15 +02:00
|
|
|
clone(): Psbt;
|
2019-07-05 05:28:04 +02:00
|
|
|
setMaximumFeeRate(satoshiPerByte: number): void;
|
2019-07-04 06:42:34 +02:00
|
|
|
setVersion(version: number): this;
|
|
|
|
setLocktime(locktime: number): this;
|
2019-07-19 07:53:54 +02:00
|
|
|
setInputSequence(inputIndex: number, sequence: number): this;
|
2019-08-07 10:37:52 +02:00
|
|
|
addInputs(inputDatas: PsbtInputExtended[]): this;
|
|
|
|
addInput(inputData: PsbtInputExtended): this;
|
|
|
|
addOutputs(outputDatas: PsbtOutputExtended[]): this;
|
|
|
|
addOutput(outputData: PsbtOutputExtended): this;
|
2019-07-05 05:28:04 +02:00
|
|
|
extractTransaction(disableFeeCheck?: boolean): Transaction;
|
|
|
|
getFeeRate(): number;
|
2019-08-26 12:15:05 +02:00
|
|
|
getFee(): number;
|
2019-07-09 08:45:56 +02:00
|
|
|
finalizeAllInputs(): this;
|
2019-10-28 03:40:56 +01:00
|
|
|
finalizeInput(inputIndex: number, finalScriptsFunc?: FinalScriptsFunc): this;
|
2019-07-19 07:53:54 +02:00
|
|
|
validateSignaturesOfAllInputs(): boolean;
|
|
|
|
validateSignaturesOfInput(inputIndex: number, pubkey?: Buffer): boolean;
|
|
|
|
signAllInputsHD(hdKeyPair: HDSigner, sighashTypes?: number[]): this;
|
2019-07-19 10:21:31 +02:00
|
|
|
signAllInputsHDAsync(hdKeyPair: HDSigner | HDSignerAsync, sighashTypes?: number[]): Promise<void>;
|
2019-07-19 04:42:45 +02:00
|
|
|
signInputHD(inputIndex: number, hdKeyPair: HDSigner, sighashTypes?: number[]): this;
|
|
|
|
signInputHDAsync(inputIndex: number, hdKeyPair: HDSigner | HDSignerAsync, sighashTypes?: number[]): Promise<void>;
|
2019-07-19 07:53:54 +02:00
|
|
|
signAllInputs(keyPair: Signer, sighashTypes?: number[]): this;
|
2019-07-19 10:21:31 +02:00
|
|
|
signAllInputsAsync(keyPair: Signer | SignerAsync, sighashTypes?: number[]): Promise<void>;
|
2019-07-10 04:15:12 +02:00
|
|
|
signInput(inputIndex: number, keyPair: Signer, sighashTypes?: number[]): this;
|
2019-07-18 07:20:44 +02:00
|
|
|
signInputAsync(inputIndex: number, keyPair: Signer | SignerAsync, sighashTypes?: number[]): Promise<void>;
|
2019-07-11 10:17:49 +02:00
|
|
|
toBuffer(): Buffer;
|
|
|
|
toHex(): string;
|
|
|
|
toBase64(): string;
|
2019-07-18 04:43:24 +02:00
|
|
|
updateGlobal(updateData: PsbtGlobalUpdate): this;
|
|
|
|
updateInput(inputIndex: number, updateData: PsbtInputUpdate): this;
|
|
|
|
updateOutput(outputIndex: number, updateData: PsbtOutputUpdate): this;
|
2019-07-11 10:17:49 +02:00
|
|
|
addUnknownKeyValToGlobal(keyVal: KeyValue): this;
|
|
|
|
addUnknownKeyValToInput(inputIndex: number, keyVal: KeyValue): this;
|
|
|
|
addUnknownKeyValToOutput(outputIndex: number, keyVal: KeyValue): this;
|
|
|
|
clearFinalizedInput(inputIndex: number): this;
|
2019-06-24 12:20:15 +02:00
|
|
|
}
|
2019-07-04 04:26:23 +02:00
|
|
|
interface PsbtOptsOptional {
|
|
|
|
network?: Network;
|
2019-07-05 05:28:04 +02:00
|
|
|
maximumFeeRate?: number;
|
2019-07-04 04:26:23 +02:00
|
|
|
}
|
2019-08-07 10:37:52 +02:00
|
|
|
interface PsbtInputExtended extends PsbtInput, TransactionInput {
|
|
|
|
}
|
2019-09-02 11:41:31 +02:00
|
|
|
declare type PsbtOutputExtended = PsbtOutputExtendedAddress | PsbtOutputExtendedScript;
|
|
|
|
interface PsbtOutputExtendedAddress extends PsbtOutput {
|
|
|
|
address: string;
|
|
|
|
value: number;
|
|
|
|
}
|
|
|
|
interface PsbtOutputExtendedScript extends PsbtOutput {
|
|
|
|
script: Buffer;
|
|
|
|
value: number;
|
2019-08-07 10:37:52 +02:00
|
|
|
}
|
2019-07-19 04:42:45 +02:00
|
|
|
interface HDSignerBase {
|
|
|
|
/**
|
|
|
|
* DER format compressed publicKey buffer
|
|
|
|
*/
|
|
|
|
publicKey: Buffer;
|
|
|
|
/**
|
|
|
|
* The first 4 bytes of the sha256-ripemd160 of the publicKey
|
|
|
|
*/
|
|
|
|
fingerprint: Buffer;
|
|
|
|
}
|
|
|
|
interface HDSigner extends HDSignerBase {
|
|
|
|
/**
|
|
|
|
* The path string must match /^m(\/\d+'?)+$/
|
|
|
|
* ex. m/44'/0'/0'/1/23 levels with ' must be hard derivations
|
|
|
|
*/
|
|
|
|
derivePath(path: string): HDSigner;
|
|
|
|
/**
|
|
|
|
* Input hash (the "message digest") for the signature algorithm
|
|
|
|
* Return a 64 byte signature (32 byte r and 32 byte s in that order)
|
|
|
|
*/
|
|
|
|
sign(hash: Buffer): Buffer;
|
|
|
|
}
|
|
|
|
/**
|
|
|
|
* Same as above but with async sign method
|
|
|
|
*/
|
|
|
|
interface HDSignerAsync extends HDSignerBase {
|
|
|
|
derivePath(path: string): HDSignerAsync;
|
|
|
|
sign(hash: Buffer): Promise<Buffer>;
|
|
|
|
}
|
2019-10-28 03:40:56 +01:00
|
|
|
/**
|
|
|
|
* This function must do two things:
|
|
|
|
* 1. Check if the `input` can be finalized. If it can not be finalized, throw.
|
|
|
|
* ie. `Can not finalize input #${inputIndex}`
|
|
|
|
* 2. Create the finalScriptSig and finalScriptWitness Buffers.
|
|
|
|
*/
|
|
|
|
declare type FinalScriptsFunc = (inputIndex: number, // Which input is it?
|
|
|
|
input: PsbtInput, // The PSBT input contents
|
|
|
|
script: Buffer, // The "meaningful" locking script Buffer (redeemScript for P2SH etc.)
|
|
|
|
isSegwit: boolean, // Is it segwit?
|
|
|
|
isP2SH: boolean, // Is it P2SH?
|
|
|
|
isP2WSH: boolean) => {
|
2019-10-10 04:01:54 +02:00
|
|
|
finalScriptSig: Buffer | undefined;
|
|
|
|
finalScriptWitness: Buffer | undefined;
|
|
|
|
};
|
2019-07-04 04:26:23 +02:00
|
|
|
export {};
|