UNPKG

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
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})`; } }