mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-11-20 12:15:51 +00:00
Browser Compatibility Updates (#107)
* BigInt -> big-integer to support older browsers * Buffer read/write BigUInt64 removed for browser compatibility.
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
"test": "test"
|
||||
},
|
||||
"dependencies": {
|
||||
"big-integer": "^1.6.48",
|
||||
"create-hash": "^1.2.0",
|
||||
"decimal.js": "^10.2.0",
|
||||
"ripple-address-codec": "^4.1.1"
|
||||
|
||||
@@ -9,6 +9,7 @@ import { sha512Half, transactionID } from "./hashes";
|
||||
import { FieldInstance } from "./enums";
|
||||
import { STObject } from "./types/st-object";
|
||||
import { JsonObject } from "./types/serialized-type";
|
||||
import * as bigInt from "big-integer";
|
||||
|
||||
/**
|
||||
* Construct a BinaryParser
|
||||
@@ -102,9 +103,10 @@ interface ClaimObject extends JsonObject {
|
||||
* @returns the serialized object with appropriate prefix
|
||||
*/
|
||||
function signingClaimData(claim: ClaimObject): Buffer {
|
||||
const num = bigInt(String(claim.amount));
|
||||
const prefix = HashPrefix.paymentChannelClaim;
|
||||
const channel = coreTypes.Hash256.from(claim.channel).toBytes();
|
||||
const amount = coreTypes.UInt64.from(BigInt(claim.amount)).toBytes();
|
||||
const amount = coreTypes.UInt64.from(num).toBytes();
|
||||
|
||||
const bytesList = new BytesList();
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import { UInt32 } from "./types/uint-32";
|
||||
import { UInt8 } from "./types/uint-8";
|
||||
import { BinaryParser } from "./serdes/binary-parser";
|
||||
import { JsonObject } from "./types/serialized-type";
|
||||
import * as bigInt from "big-integer";
|
||||
|
||||
/**
|
||||
* Computes the hash of a list of objects
|
||||
@@ -119,7 +120,7 @@ function accountStateHash(param: Array<JsonObject>): Hash256 {
|
||||
*/
|
||||
interface ledgerObject {
|
||||
ledger_index: number;
|
||||
total_coins: string | number | bigint;
|
||||
total_coins: string | number | bigInt.BigInteger;
|
||||
parent_hash: string;
|
||||
transaction_hash: string;
|
||||
account_hash: string;
|
||||
@@ -142,7 +143,9 @@ function ledgerHash(header: ledgerObject): Hash256 {
|
||||
assert(header.close_flags !== undefined);
|
||||
|
||||
UInt32.from<number>(header.ledger_index).toBytesSink(hash);
|
||||
UInt64.from<bigint>(BigInt(header.total_coins)).toBytesSink(hash);
|
||||
UInt64.from<bigInt.BigInteger>(
|
||||
bigInt(String(header.total_coins))
|
||||
).toBytesSink(hash);
|
||||
Hash256.from<string>(header.parent_hash).toBytesSink(hash);
|
||||
Hash256.from<string>(header.transaction_hash).toBytesSink(hash);
|
||||
Hash256.from<string>(header.account_hash).toBytesSink(hash);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { coreTypes } from "./types";
|
||||
import { Decimal } from "decimal.js";
|
||||
import * as bigInt from "big-integer";
|
||||
|
||||
/**
|
||||
* class for encoding and decoding quality
|
||||
@@ -15,7 +16,7 @@ class quality {
|
||||
const decimal = new Decimal(quality);
|
||||
const exponent = decimal.e - 15;
|
||||
const qualityString = decimal.times(`1e${-exponent}`).abs().toString();
|
||||
const bytes = coreTypes.UInt64.from(BigInt(qualityString)).toBytes();
|
||||
const bytes = coreTypes.UInt64.from(bigInt(qualityString)).toBytes();
|
||||
bytes[0] = exponent + 100;
|
||||
return bytes;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import { BinaryParser } from "../serdes/binary-parser";
|
||||
import { AccountID } from "./account-id";
|
||||
import { Currency } from "./currency";
|
||||
import { JsonObject, SerializedType } from "./serialized-type";
|
||||
import * as bigInt from "big-integer";
|
||||
|
||||
/**
|
||||
* Constants for validating amounts
|
||||
@@ -14,6 +15,7 @@ const MAX_IOU_EXPONENT = 80;
|
||||
const MAX_IOU_PRECISION = 16;
|
||||
const MAX_DROPS = new Decimal("1e17");
|
||||
const MIN_XRP = new Decimal("1e-6");
|
||||
const mask = bigInt(0x00000000ffffffff);
|
||||
|
||||
/**
|
||||
* decimal.js configuration for Amount IOUs
|
||||
@@ -69,12 +71,17 @@ class Amount extends SerializedType {
|
||||
return value;
|
||||
}
|
||||
|
||||
const amount = Buffer.alloc(8);
|
||||
let amount = Buffer.alloc(8);
|
||||
if (typeof value === "string") {
|
||||
Amount.assertXrpIsValid(value);
|
||||
|
||||
const number = BigInt(value);
|
||||
amount.writeBigUInt64BE(number);
|
||||
const number = bigInt(value);
|
||||
|
||||
const intBuf = [Buffer.alloc(4), Buffer.alloc(4)];
|
||||
intBuf[0].writeUInt32BE(Number(number.shiftRight(32)));
|
||||
intBuf[1].writeUInt32BE(Number(number.and(mask)));
|
||||
|
||||
amount = Buffer.concat(intBuf);
|
||||
|
||||
amount[0] |= 0x40;
|
||||
|
||||
@@ -92,7 +99,13 @@ class Amount extends SerializedType {
|
||||
.times(`1e${-(number.e - 15)}`)
|
||||
.abs()
|
||||
.toString();
|
||||
amount.writeBigUInt64BE(BigInt(integerNumberString));
|
||||
|
||||
const num = bigInt(integerNumberString);
|
||||
const intBuf = [Buffer.alloc(4), Buffer.alloc(4)];
|
||||
intBuf[0].writeUInt32BE(Number(num.shiftRight(32)));
|
||||
intBuf[1].writeUInt32BE(Number(num.and(mask)));
|
||||
|
||||
amount = Buffer.concat(intBuf);
|
||||
|
||||
amount[0] |= 0x80;
|
||||
|
||||
@@ -136,9 +149,13 @@ class Amount extends SerializedType {
|
||||
const bytes = this.bytes;
|
||||
const isPositive = bytes[0] & 0x40;
|
||||
const sign = isPositive ? "" : "-";
|
||||
|
||||
bytes[0] &= 0x3f;
|
||||
return `${sign}${bytes.readBigUInt64BE().toString()}`;
|
||||
|
||||
const msb = bigInt(bytes.slice(0, 4).readUInt32BE());
|
||||
const lsb = bigInt(bytes.slice(4).readUInt32BE());
|
||||
const num = msb.shiftLeft(32).or(lsb);
|
||||
|
||||
return `${sign}${num.toString()}`;
|
||||
} else {
|
||||
const parser = new BinaryParser(this.toString());
|
||||
const mantissa = parser.read(8);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { BytesList } from "../serdes/binary-serializer";
|
||||
import { BinaryParser } from "../serdes/binary-parser";
|
||||
import * as bigInt from "big-integer";
|
||||
|
||||
type JSON = string | number | boolean | null | undefined | JSON[] | JsonObject;
|
||||
|
||||
@@ -20,7 +21,9 @@ class SerializedType {
|
||||
return this.fromParser(parser, hint);
|
||||
}
|
||||
|
||||
static from(value: SerializedType | JSON | bigint): SerializedType {
|
||||
static from(
|
||||
value: SerializedType | JSON | bigInt.BigInteger
|
||||
): SerializedType {
|
||||
throw new Error("from not implemented");
|
||||
return this.from(value);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import { UInt } from "./uint";
|
||||
import { BinaryParser } from "../serdes/binary-parser";
|
||||
import * as bigInt from "big-integer";
|
||||
import { isInstance } from "big-integer";
|
||||
|
||||
const HEX_REGEX = /^[A-F0-9]{16}$/;
|
||||
const mask = bigInt(0x00000000ffffffff);
|
||||
|
||||
/**
|
||||
* Derived UInt class for serializing/deserializing 64 bit UInt
|
||||
@@ -23,10 +26,12 @@ class UInt64 extends UInt {
|
||||
/**
|
||||
* Construct a UInt64 object
|
||||
*
|
||||
* @param val A UInt64, hex-string, bigint, or number
|
||||
* @param val A UInt64, hex-string, bigInt, or number
|
||||
* @returns A UInt64 object
|
||||
*/
|
||||
static from<T extends UInt64 | string | bigint | number>(val: T): UInt64 {
|
||||
static from<T extends UInt64 | string | bigInt.BigInteger | number>(
|
||||
val: T
|
||||
): UInt64 {
|
||||
if (val instanceof UInt64) {
|
||||
return val;
|
||||
}
|
||||
@@ -37,8 +42,14 @@ class UInt64 extends UInt {
|
||||
if (val < 0) {
|
||||
throw new Error("value must be an unsigned integer");
|
||||
}
|
||||
buf.writeBigUInt64BE(BigInt(val));
|
||||
return new UInt64(buf);
|
||||
|
||||
const number = bigInt(val);
|
||||
|
||||
const intBuf = [Buffer.alloc(4), Buffer.alloc(4)];
|
||||
intBuf[0].writeUInt32BE(Number(number.shiftRight(32)));
|
||||
intBuf[1].writeUInt32BE(Number(number.and(mask)));
|
||||
|
||||
return new UInt64(Buffer.concat(intBuf));
|
||||
}
|
||||
|
||||
if (typeof val === "string") {
|
||||
@@ -49,9 +60,12 @@ class UInt64 extends UInt {
|
||||
return new UInt64(buf);
|
||||
}
|
||||
|
||||
if (typeof val === "bigint") {
|
||||
buf.writeBigUInt64BE(val);
|
||||
return new UInt64(buf);
|
||||
if (isInstance(val)) {
|
||||
const intBuf = [Buffer.alloc(4), Buffer.alloc(4)];
|
||||
intBuf[0].writeUInt32BE(Number(val.shiftRight(bigInt(32))));
|
||||
intBuf[1].writeUInt32BE(Number(val.and(mask)));
|
||||
|
||||
return new UInt64(Buffer.concat(intBuf));
|
||||
}
|
||||
|
||||
throw new Error("Cannot construct UInt64 from given value");
|
||||
@@ -71,8 +85,10 @@ class UInt64 extends UInt {
|
||||
*
|
||||
* @returns the number represented buy this.bytes
|
||||
*/
|
||||
valueOf(): bigint {
|
||||
return this.bytes.readBigUInt64BE();
|
||||
valueOf(): bigInt.BigInteger {
|
||||
const msb = bigInt(this.bytes.slice(0, 4).readUInt32BE());
|
||||
const lsb = bigInt(this.bytes.slice(4).readUInt32BE());
|
||||
return msb.shiftLeft(bigInt(32)).or(lsb);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
import * as bigInt from "big-integer";
|
||||
import { Comparable } from "./serialized-type";
|
||||
|
||||
/**
|
||||
* Compare numbers and bigints n1 and n2
|
||||
* Compare numbers and bigInts n1 and n2
|
||||
*
|
||||
* @param n1 First object to compare
|
||||
* @param n2 Second object to compare
|
||||
* @returns -1, 0, or 1, depending on how the two objects compare
|
||||
*/
|
||||
function compare(n1: number | bigint, n2: number | bigint): number {
|
||||
function compare(
|
||||
n1: number | bigInt.BigInteger,
|
||||
n2: number | bigInt.BigInteger
|
||||
): number {
|
||||
return n1 < n2 ? -1 : n1 == n2 ? 0 : 1;
|
||||
}
|
||||
|
||||
@@ -46,7 +50,7 @@ abstract class UInt extends Comparable {
|
||||
*
|
||||
* @returns the value
|
||||
*/
|
||||
abstract valueOf(): number | bigint;
|
||||
abstract valueOf(): number | bigInt.BigInteger;
|
||||
}
|
||||
|
||||
export { UInt };
|
||||
|
||||
@@ -5,6 +5,7 @@ const { encode, decode } = require("../dist");
|
||||
const { makeParser, BytesList, BinarySerializer } = binary;
|
||||
const { coreTypes } = require("../dist/types");
|
||||
const { UInt8, UInt16, UInt32, UInt64, STObject } = coreTypes;
|
||||
const bigInt = require("big-integer");
|
||||
|
||||
const { loadFixture } = require("./utils");
|
||||
const fixtures = loadFixture("data-driven-tests.json");
|
||||
@@ -162,7 +163,7 @@ check(UInt64, 0xfeffffff, [0, 0, 0, 0, 254, 255, 255, 255]);
|
||||
check(UInt64, -1, "throws");
|
||||
check(UInt64, 0, [0, 0, 0, 0, 0, 0, 0, 0]);
|
||||
check(UInt64, 1, [0, 0, 0, 0, 0, 0, 0, 1]);
|
||||
check(UInt64, BigInt(1), [0, 0, 0, 0, 0, 0, 0, 1]);
|
||||
check(UInt64, bigInt(1), [0, 0, 0, 0, 0, 0, 0, 1]);
|
||||
|
||||
function deliverMinTest() {
|
||||
test("can serialize DeliverMin", () => {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user