lotus-sdk
Version:
Central repository for several classes of tools for integrating with, and building for, the Lotusia ecosystem
236 lines (235 loc) • 6.6 kB
JavaScript
import BN from 'bn.js';
class BNWrapper {
_bn;
static Zero = new BNWrapper(0);
static One = new BNWrapper(1);
static Minus1 = new BNWrapper(-1);
constructor(n, base) {
if (n instanceof BN) {
this._bn = n.clone();
}
else if (Buffer.isBuffer(n)) {
if (base === 'le' || base === 'be') {
this._bn = new BN(n, undefined, base);
}
else {
this._bn = new BN(n, base || 'hex');
}
}
else {
const validBase = base === 'hex' || typeof base === 'number' ? base : undefined;
this._bn = new BN(n, validBase);
}
}
static fromString(str, base) {
return new BNWrapper(str, base);
}
static fromBuffer(buf, opts) {
let buffer = buf;
if (opts?.size) {
buffer = Buffer.alloc(opts.size);
buf.copy(buffer, opts.size - buf.length);
}
if (opts?.endian === 'little') {
buffer = BNWrapper.reversebuf(buffer);
}
return new BNWrapper(buffer, 'hex');
}
static fromSM(buf, opts) {
if (buf.length === 0) {
return BNWrapper.fromBuffer(Buffer.from([0]));
}
let endian = 'big';
if (opts) {
endian = opts.endian || 'big';
}
let buffer = buf;
if (endian === 'little') {
buffer = BNWrapper.reversebuf(buf);
}
let result;
if (buffer[0] & 0x80) {
buffer[0] = buffer[0] & 0x7f;
result = BNWrapper.fromBuffer(buffer);
result = result.neg();
}
else {
result = BNWrapper.fromBuffer(buffer);
}
return result;
}
static fromScriptNumBuffer(buf, fRequireMinimal, size) {
const nMaxNumSize = size || 4;
if (buf.length > nMaxNumSize) {
throw new Error('script number overflow');
}
if (fRequireMinimal && buf.length > 0) {
if ((buf[buf.length - 1] & 0x7f) === 0) {
if (buf.length <= 1 || (buf[buf.length - 2] & 0x80) === 0) {
throw new Error('non-minimally encoded script number');
}
}
}
return BNWrapper.fromSM(buf, { endian: 'little' });
}
static reversebuf(buf) {
const buf2 = Buffer.alloc(buf.length);
for (let i = 0; i < buf.length; i++) {
buf2[i] = buf[buf.length - 1 - i];
}
return buf2;
}
static trim(buf, natlen) {
return buf.subarray(natlen - buf.length, buf.length);
}
static pad(buf, natlen, size) {
const rbuf = Buffer.alloc(size);
for (let i = 0; i < buf.length; i++) {
rbuf[rbuf.length - 1 - i] = buf[buf.length - 1 - i];
}
for (let i = 0; i < size - natlen; i++) {
rbuf[i] = 0;
}
return rbuf;
}
static fromNumber(n) {
return new BNWrapper(n);
}
toNumber() {
return parseInt(this.toString(10), 10);
}
add(r) {
return new BNWrapper(this._bn.add(r._bn));
}
mod(r) {
return new BNWrapper(this._bn.mod(r._bn));
}
umod(r) {
return new BNWrapper(this._bn.umod(r._bn));
}
get bn() {
return this._bn;
}
toString(base) {
return this._bn.toString(base);
}
toBuffer(opts) {
let buf;
if (opts && opts.size) {
buf = this._bn.toArrayLike(Buffer, opts.endian === 'little' ? 'le' : 'be');
if (buf.length === opts.size) {
}
else if (buf.length > opts.size) {
buf = buf.subarray(buf.length - opts.size);
}
else if (buf.length < opts.size) {
const padded = Buffer.alloc(opts.size);
buf.copy(padded, opts.size - buf.length);
buf = padded;
}
}
else {
buf = this._bn.toArrayLike(Buffer, opts?.endian === 'little' ? 'le' : 'be');
}
return buf;
}
toArrayLike(ArrayType, endian, length) {
return this._bn.toArrayLike(ArrayType, endian || 'be', length);
}
mul(r) {
return new BNWrapper(this._bn.mul(r._bn));
}
sub(r) {
return new BNWrapper(this._bn.sub(r._bn));
}
pow(r) {
return new BNWrapper(this._bn.pow(r._bn));
}
div(r) {
return new BNWrapper(this._bn.div(r._bn));
}
modPow(exponent, modulus) {
return new BNWrapper(this._bn.pow(exponent._bn).mod(modulus._bn));
}
and(other) {
const otherBN = other instanceof BNWrapper ? other._bn : new BN(other);
return new BNWrapper(this._bn.and(otherBN));
}
neg() {
return new BNWrapper(this._bn.neg());
}
invm(r) {
return new BNWrapper(this._bn.invm(r._bn));
}
eq(other) {
return this._bn.eq(other._bn);
}
lt(other) {
return this._bn.lt(other._bn);
}
gt(other) {
return this._bn.gt(other._bn);
}
lte(other) {
return this._bn.lte(other._bn);
}
gte(other) {
return this._bn.gte(other._bn);
}
isZero() {
return this._bn.isZero();
}
isNeg() {
return this._bn.isNeg();
}
isOdd() {
return this._bn.isOdd();
}
isEven() {
return this._bn.isEven();
}
toSMBigEndian() {
let buf;
if (this.cmp(BNWrapper.Zero) === -1) {
buf = this.neg().toBuffer();
if (buf[0] & 0x80) {
buf = Buffer.concat([Buffer.from([0x80]), buf]);
}
else {
buf[0] = buf[0] | 0x80;
}
}
else {
buf = this.toBuffer();
if (buf[0] & 0x80) {
buf = Buffer.concat([Buffer.from([0x00]), buf]);
}
}
if (buf.length === 1 && buf[0] === 0) {
buf = Buffer.from([]);
}
return buf;
}
toSM(opts) {
const endian = opts ? opts.endian : 'big';
let buf = this.toSMBigEndian();
if (endian === 'little') {
buf = BNWrapper.reversebuf(buf);
}
return buf;
}
toScriptNumBuffer() {
return this.toSM({ endian: 'little' });
}
cmp(other) {
return this._bn.cmp(other._bn);
}
copy(other) {
this._bn = other._bn.clone();
return this;
}
clone() {
return new BNWrapper(this._bn.clone());
}
}
export { BNWrapper as BN };