libnexa-ts
Version:
A pure and powerful Nexa SDK library.
136 lines (115 loc) • 4.03 kB
text/typescript
import Script from "../../script/script";
import Output from "../output";
import type { IInput } from "../interfaces";
import BufferUtils from "../../../utils/buffer.utils";
import ValidationUtils from "../../../utils/validation.utils";
import type BufferReader from "../../../encoding/bufferreader";
import BufferWriter from "../../../encoding/bufferwriter";
import BN from "../../../crypto/bn.extension";
import type PrivateKey from "../../../keys/privatekey";
import type TxSignature from "../txsignature";
export enum InputType {
UTXO = 0,
READ_ONLY = 1
}
export default class Input implements IInput {
public static readonly SEQUENCE_FINAL = 0xffffffff;
public type!: InputType;
public outpoint!: Uint8Array;
public amount!: bigint;
public sequenceNumber!: number
public output?: Output;
private _scriptSig!: Script;
constructor(params?: IInput) {
if (params) {
this._set(params);
}
}
public get scriptSig(): Script {
return this._scriptSig;
}
public set scriptSig(script: string | Script) {
if (script instanceof Script) {
this._scriptSig = script;
} else if (typeof script === 'string') {
this._scriptSig = Script.fromString(script);
} else {
throw new TypeError('Invalid argument type: script');
}
}
private _set(params: IInput): void {
this.type = InputType.UTXO;
if (params.scriptSig == null) {
throw new TypeError('Need a script to create an input');
}
this.scriptSig = params.scriptSig;
this.outpoint = BufferUtils.isBuffer(params.outpoint) ? params.outpoint : BufferUtils.hexToBuffer(params.outpoint);
this.amount = BigInt(params.amount);
this.sequenceNumber = params.sequenceNumber == null ? Input.SEQUENCE_FINAL : params.sequenceNumber;
if (params.output) {
this.output = params.output instanceof Output ? params.output : Output.fromObject(params.output);
}
}
public static fromObject(obj: IInput): Input {
ValidationUtils.validateArgument(typeof obj === 'object' && obj !== null, "obj");
return new Input(obj);
}
public toJSON = this.toObject;
public toObject(): IInput {
return {
type: this.type,
outpoint: BufferUtils.bufferToHex(this.outpoint),
amount: this.amount.toString(),
sequenceNumber: this.sequenceNumber,
scriptSig: this.scriptSig.toHex(),
output: this.output?.toObject()
};
}
public static fromBufferReader(br: BufferReader): Input {
let input = new Input();
input.type = br.readUInt8();
input.outpoint = br.readReverse(32);
input.scriptSig = Script.fromBuffer(br.readVarLengthBuffer());
input.sequenceNumber = br.readUInt32LE();
input.amount = br.readUInt64LEBN().toBigInt();
return input;
}
public toBufferWriter(writer?: BufferWriter, includeScript = true): BufferWriter {
if (!writer) {
writer = new BufferWriter();
}
writer.writeUInt8(this.type);
writer.writeReverse(this.outpoint);
if (includeScript) {
writer.writeVarLengthBuf(this.scriptSig.toBuffer());
}
writer.writeUInt32LE(this.sequenceNumber);
writer.writeUInt64LEBN(BN.fromBigInt(this.amount));
return writer;
}
public estimateSize(): number {
return this.toBufferWriter().toBuffer().length;
}
public isFinal(): boolean {
return this.sequenceNumber !== Input.SEQUENCE_FINAL;
}
public clearSignatures(): this {
this.scriptSig = Script.empty();
return this;
}
public getSubscript(): Script {
throw Error(`Abstract Method Invocation: Input#getSubscript`);
}
/**
* @returns true if the provided private key can sign this input
*/
public canSign(_privateKey: PrivateKey): boolean {
throw Error(`Abstract Method Invocation: Input#canSign`);
}
public isFullySigned(): boolean {
throw Error(`Abstract Method Invocation: Input#isFullySigned`);
}
public addSignature(_signature: TxSignature): this {
throw Error(`Abstract Method Invocation: Input#addSignature`);
}
}