lotus-sdk
Version:
Central repository for several classes of tools for integrating with, and building for, the Lotusia ecosystem
131 lines (130 loc) • 5.39 kB
JavaScript
import { Preconditions } from '../util/preconditions.js';
import { JSUtil } from '../util/js.js';
import { PublicKey } from '../publickey.js';
import { BitcoreError } from '../errors.js';
import { Signature } from '../crypto/signature.js';
import { BN } from '../crypto/bn.js';
import { isSchnorrSignature } from '../crypto/sigtype.js';
export class TransactionSignature extends Signature {
publicKey;
prevTxId;
outputIndex;
inputIndex;
sigtype;
signature;
constructor(arg) {
super(BN.fromNumber(0), BN.fromNumber(0));
if (arg instanceof TransactionSignature) {
return arg;
}
if (typeof arg === 'object' && arg !== null) {
return this._fromObject(arg);
}
else {
throw new BitcoreError('TransactionSignatures must be instantiated from an object');
}
}
_fromObject(arg) {
this._checkObjectArgs(arg);
this.publicKey = new PublicKey(arg.publicKey);
this.prevTxId = Buffer.isBuffer(arg.prevTxId)
? arg.prevTxId
: Buffer.from(arg.prevTxId, 'hex');
this.outputIndex = arg.outputIndex;
this.inputIndex = arg.inputIndex;
if (arg.signature instanceof Signature) {
this.signature = arg.signature;
}
else if (Buffer.isBuffer(arg.signature)) {
const sigWithoutSighash = arg.signature.length > 64 &&
arg.signature[arg.signature.length - 1] !== 0x30
? arg.signature.subarray(0, -1)
: arg.signature;
if (isSchnorrSignature(sigWithoutSighash)) {
const parsed = Signature.parseSchnorrEncodedSig(arg.signature);
const sig = new Signature(parsed.r, parsed.s);
sig.isSchnorr = true;
if (parsed.nhashtype) {
sig.nhashtype = parsed.nhashtype.readUInt8(0);
}
this.signature = sig;
}
else {
this.signature = Signature.fromDER(arg.signature);
}
}
else {
const buf = Buffer.from(arg.signature, 'hex');
const sigWithoutSighash = buf.length > 64 && buf[buf.length - 1] !== 0x30
? buf.subarray(0, -1)
: buf;
if (isSchnorrSignature(sigWithoutSighash)) {
const parsed = Signature.parseSchnorrEncodedSig(buf);
const sig = new Signature(parsed.r, parsed.s);
sig.isSchnorr = true;
if (parsed.nhashtype) {
sig.nhashtype = parsed.nhashtype.readUInt8(0);
}
this.signature = sig;
}
else {
this.signature = Signature.fromString(arg.signature);
}
}
this.sigtype = arg.sigtype;
return this;
}
_checkObjectArgs(arg) {
Preconditions.checkArgument(arg.publicKey !== undefined, 'publicKey is required');
Preconditions.checkArgument(arg.inputIndex !== undefined, 'inputIndex is required');
Preconditions.checkArgument(arg.outputIndex !== undefined, 'outputIndex is required');
Preconditions.checkState(typeof arg.inputIndex === 'number', 'inputIndex must be a number');
Preconditions.checkState(typeof arg.outputIndex === 'number', 'outputIndex must be a number');
Preconditions.checkArgument(arg.signature !== undefined, 'signature is required');
Preconditions.checkArgument(arg.prevTxId !== undefined, 'prevTxId is required');
Preconditions.checkState(arg.signature instanceof Signature ||
Buffer.isBuffer(arg.signature) ||
JSUtil.isHexa(arg.signature), 'signature must be a buffer or hexa value');
Preconditions.checkState(Buffer.isBuffer(arg.prevTxId) || JSUtil.isHexa(arg.prevTxId), 'prevTxId must be a buffer or hexa value');
Preconditions.checkArgument(arg.sigtype !== undefined, 'sigtype is required');
Preconditions.checkState(typeof arg.sigtype === 'number', 'sigtype must be a number');
}
toObject() {
return {
publicKey: this.publicKey.toString(),
prevTxId: this.prevTxId.toString('hex'),
outputIndex: this.outputIndex,
inputIndex: this.inputIndex,
signature: this.signature.toString(),
sigtype: this.sigtype,
};
}
toJSON = this.toObject;
static fromObject(obj) {
return new TransactionSignature(obj);
}
clone() {
return new TransactionSignature({
publicKey: this.publicKey,
prevTxId: Buffer.from(this.prevTxId),
outputIndex: this.outputIndex,
inputIndex: this.inputIndex,
signature: this.signature,
sigtype: this.sigtype,
});
}
isValid() {
return (this.publicKey !== undefined &&
this.prevTxId !== undefined &&
this.outputIndex >= 0 &&
this.inputIndex >= 0 &&
this.signature !== undefined &&
this.sigtype !== undefined &&
PublicKey.isValid(this.publicKey) &&
this.signature.r !== undefined &&
this.signature.s !== undefined);
}
toString() {
return `TransactionSignature(${this.inputIndex}:${this.outputIndex})`;
}
}