Socket
Socket
Sign inDemoInstall

@iov/encoding

Package Overview
Dependencies
Maintainers
3
Versions
77
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@iov/encoding - npm Package Compare versions

Comparing version 0.6.0 to 0.7.0

36

build/encoding.js

@@ -11,2 +11,3 @@ "use strict";

const base64js = __importStar(require("base64-js"));
const bech32 = __importStar(require("bech32"));
const readonly_date_1 = require("readonly-date");

@@ -25,2 +26,3 @@ class Encoding {

}
// tslint:disable-next-line:readonly-array
const listOfInts = [];

@@ -48,2 +50,6 @@ for (let i = 0; i < hexstring.length; i += 2) {

const charCode = x.charCodeAt(0);
// 0x00–0x1F control characters
// 0x20–0x7E printable characters
// 0x7F delete character
// 0x80–0xFF out of 7 bit ascii range
if (charCode < 0x20 || charCode > 0x7e) {

@@ -58,2 +64,6 @@ throw new Error("Cannot encode character that is out of printable ASCII range: " + charCode);

const fromNums = (listOfNumbers) => listOfNumbers.map((x) => {
// 0x00–0x1F control characters
// 0x20–0x7E printable characters
// 0x7F delete character
// 0x80–0xFF out of 7 bit ascii range
if (x < 0x20 || x > 0x7e) {

@@ -67,11 +77,18 @@ throw new Error("Cannot decode character that is out of printable ASCII range: " + x);

static toUtf8(str) {
// Browser and future nodejs (https://github.com/nodejs/node/issues/20365)
if (typeof TextEncoder !== "undefined") {
return new TextEncoder().encode(str);
}
// Use Buffer hack instead of nodejs util.TextEncoder to ensure
// webpack does not bundle the util module for browsers.
return new Uint8Array(Buffer.from(str, "utf8"));
}
static fromUtf8(data) {
// Browser and future nodejs (https://github.com/nodejs/node/issues/20365)
if (typeof TextDecoder !== "undefined") {
return new TextDecoder("utf-8", { fatal: true }).decode(data);
}
// Use Buffer hack instead of nodejs util.TextDecoder to ensure
// webpack does not bundle the util module for browsers.
// Buffer.toString has no fatal option
if (!Encoding.isValidUtf8(data)) {

@@ -94,2 +111,3 @@ throw new Error("Invalid UTF8 data");

const second = +matches[6];
// fractional seconds match either undefined or a string like ".1", ".123456789"
const milliSeconds = matches[7] ? Math.floor(+matches[7] * 1000) : 0;

@@ -99,2 +117,3 @@ let tzOffsetSign;

let tzOffsetMinutes;
// if timezone is undefined, it must be Z or nothing (otherwise the group would have captured).
if (matches[8] === "Z") {

@@ -110,3 +129,3 @@ tzOffsetSign = 1;

}
const tzOffset = tzOffsetSign * (tzOffsetHours * 60 + tzOffsetMinutes) * 60;
const tzOffset = tzOffsetSign * (tzOffsetHours * 60 + tzOffsetMinutes) * 60; // seconds
return new readonly_date_1.ReadonlyDate(readonly_date_1.ReadonlyDate.UTC(year, month - 1, day, hour, minute, second, milliSeconds) - tzOffset * 1000);

@@ -134,2 +153,17 @@ }

exports.Encoding = Encoding;
class Bech32 {
static encode(prefix, data) {
const dataToWords = bech32.toWords(Buffer.from(data));
const encodedData = bech32.encode(prefix, dataToWords);
return encodedData;
}
static decode(address) {
const decodedAddress = bech32.decode(address);
return {
prefix: decodedAddress.prefix,
data: new Uint8Array(bech32.fromWords(decodedAddress.words)),
};
}
}
exports.Bech32 = Bech32;
//# sourceMappingURL=encoding.js.map

@@ -15,2 +15,3 @@ "use strict";

it("decodes from hex", () => {
// simple
expect(encoding_1.Encoding.fromHex("")).toEqual(new Uint8Array([]));

@@ -23,4 +24,6 @@ expect(encoding_1.Encoding.fromHex("00")).toEqual(new Uint8Array([0x00]));

expect(encoding_1.Encoding.fromHex("0123456789abcdef")).toEqual(new Uint8Array([0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef]));
// capital letters
expect(encoding_1.Encoding.fromHex("AA")).toEqual(new Uint8Array([0xaa]));
expect(encoding_1.Encoding.fromHex("aAbBcCdDeEfF")).toEqual(new Uint8Array([0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff]));
// error
expect(() => encoding_1.Encoding.fromHex("a")).toThrow();

@@ -60,11 +63,15 @@ expect(() => encoding_1.Encoding.fromHex("aaa")).toThrow();

expect(encoding_1.Encoding.fromBase64("YWJj")).toEqual(new Uint8Array([0x61, 0x62, 0x63]));
// invalid length
expect(() => encoding_1.Encoding.fromBase64("a")).toThrow();
expect(() => encoding_1.Encoding.fromBase64("aa")).toThrow();
expect(() => encoding_1.Encoding.fromBase64("aaa")).toThrow();
// proper length including invalid character
expect(() => encoding_1.Encoding.fromBase64("aaa!")).toThrow();
expect(() => encoding_1.Encoding.fromBase64("aaa*")).toThrow();
expect(() => encoding_1.Encoding.fromBase64("aaaä")).toThrow();
// proper length plus invalid character
expect(() => encoding_1.Encoding.fromBase64("aaaa!")).toThrow();
expect(() => encoding_1.Encoding.fromBase64("aaaa*")).toThrow();
expect(() => encoding_1.Encoding.fromBase64("aaaaä")).toThrow();
// extra spaces
expect(() => encoding_1.Encoding.fromBase64("aaaa ")).toThrow();

@@ -76,5 +83,9 @@ expect(() => encoding_1.Encoding.fromBase64(" aaaa")).toThrow();

expect(() => encoding_1.Encoding.fromBase64("aa\naa")).toThrow();
// position of =
expect(() => encoding_1.Encoding.fromBase64("=aaa")).toThrow();
expect(() => encoding_1.Encoding.fromBase64("==aa")).toThrow();
// concatenated base64 strings should not be supported
// see https://github.com/beatgammit/base64-js/issues/42
expect(() => encoding_1.Encoding.fromBase64("AAA=AAA=")).toThrow();
// wrong number of =
expect(() => encoding_1.Encoding.fromBase64("a===")).toThrow();

@@ -108,2 +119,8 @@ });

});
it("encodes null character", () => {
expect(encoding_1.Encoding.toUtf8("\u0000")).toEqual(new Uint8Array([0x00]));
});
it("decodes null byte", () => {
expect(encoding_1.Encoding.fromUtf8(new Uint8Array([0x00]))).toEqual("\u0000");
});
it("encodes Basic Multilingual Plane strings", () => {

@@ -124,10 +141,15 @@ expect(encoding_1.Encoding.toUtf8("ö")).toEqual(new Uint8Array([0xc3, 0xb6]));

it("encodes Supplementary Multilingual Plane strings", () => {
// U+1F0A1
expect(encoding_1.Encoding.toUtf8("🂡")).toEqual(new Uint8Array([0xf0, 0x9f, 0x82, 0xa1]));
// U+1034A
expect(encoding_1.Encoding.toUtf8("𐍊")).toEqual(new Uint8Array([0xf0, 0x90, 0x8d, 0x8a]));
});
it("decodes Supplementary Multilingual Plane strings", () => {
// U+1F0A1
expect(encoding_1.Encoding.fromUtf8(new Uint8Array([0xf0, 0x9f, 0x82, 0xa1]))).toEqual("🂡");
// U+1034A
expect(encoding_1.Encoding.fromUtf8(new Uint8Array([0xf0, 0x90, 0x8d, 0x8a]))).toEqual("𐍊");
});
it("throws on invalid utf8 bytes", () => {
// Broken UTF8 example from https://github.com/nodejs/node/issues/16894
expect(() => encoding_1.Encoding.fromUtf8(new Uint8Array([0xf0, 0x80, 0x80]))).toThrow();

@@ -138,5 +160,7 @@ });

it("parses dates with different time zones", () => {
// time zone +/- 0
expect(encoding_1.Encoding.fromRfc3339("2002-10-02T11:12:13+00:00")).toEqual(new Date(Date.UTC(2002, 9, 2, 11, 12, 13)));
expect(encoding_1.Encoding.fromRfc3339("2002-10-02T11:12:13-00:00")).toEqual(new Date(Date.UTC(2002, 9, 2, 11, 12, 13)));
expect(encoding_1.Encoding.fromRfc3339("2002-10-02T11:12:13Z")).toEqual(new Date(Date.UTC(2002, 9, 2, 11, 12, 13)));
// time zone positive (full hours)
expect(encoding_1.Encoding.fromRfc3339("2002-10-02T11:12:13+01:00")).toEqual(new Date(Date.UTC(2002, 9, 2, 11 - 1, 12, 13)));

@@ -146,2 +170,3 @@ expect(encoding_1.Encoding.fromRfc3339("2002-10-02T11:12:13+02:00")).toEqual(new Date(Date.UTC(2002, 9, 2, 11 - 2, 12, 13)));

expect(encoding_1.Encoding.fromRfc3339("2002-10-02T11:12:13+11:00")).toEqual(new Date(Date.UTC(2002, 9, 2, 11 - 11, 12, 13)));
// time zone negative (full hours)
expect(encoding_1.Encoding.fromRfc3339("2002-10-02T11:12:13-01:00")).toEqual(new Date(Date.UTC(2002, 9, 2, 11 + 1, 12, 13)));

@@ -151,11 +176,15 @@ expect(encoding_1.Encoding.fromRfc3339("2002-10-02T11:12:13-02:00")).toEqual(new Date(Date.UTC(2002, 9, 2, 11 + 2, 12, 13)));

expect(encoding_1.Encoding.fromRfc3339("2002-10-02T11:12:13-11:00")).toEqual(new Date(Date.UTC(2002, 9, 2, 11 + 11, 12, 13)));
// time zone positive (minutes only)
expect(encoding_1.Encoding.fromRfc3339("2002-10-02T11:12:13+00:01")).toEqual(new Date(Date.UTC(2002, 9, 2, 11, 12 - 1, 13)));
expect(encoding_1.Encoding.fromRfc3339("2002-10-02T11:12:13+00:30")).toEqual(new Date(Date.UTC(2002, 9, 2, 11, 12 - 30, 13)));
expect(encoding_1.Encoding.fromRfc3339("2002-10-02T11:12:13+00:45")).toEqual(new Date(Date.UTC(2002, 9, 2, 11, 12 - 45, 13)));
// time zone negative (minutes only)
expect(encoding_1.Encoding.fromRfc3339("2002-10-02T11:12:13-00:01")).toEqual(new Date(Date.UTC(2002, 9, 2, 11, 12 + 1, 13)));
expect(encoding_1.Encoding.fromRfc3339("2002-10-02T11:12:13-00:30")).toEqual(new Date(Date.UTC(2002, 9, 2, 11, 12 + 30, 13)));
expect(encoding_1.Encoding.fromRfc3339("2002-10-02T11:12:13-00:45")).toEqual(new Date(Date.UTC(2002, 9, 2, 11, 12 + 45, 13)));
// time zone positive (hours and minutes)
expect(encoding_1.Encoding.fromRfc3339("2002-10-02T11:12:13+01:01")).toEqual(new Date(Date.UTC(2002, 9, 2, 11 - 1, 12 - 1, 13)));
expect(encoding_1.Encoding.fromRfc3339("2002-10-02T11:12:13+04:30")).toEqual(new Date(Date.UTC(2002, 9, 2, 11 - 4, 12 - 30, 13)));
expect(encoding_1.Encoding.fromRfc3339("2002-10-02T11:12:13+10:20")).toEqual(new Date(Date.UTC(2002, 9, 2, 11 - 10, 12 - 20, 13)));
// time zone negative (hours and minutes)
expect(encoding_1.Encoding.fromRfc3339("2002-10-02T11:12:13-01:01")).toEqual(new Date(Date.UTC(2002, 9, 2, 11 + 1, 12 + 1, 13)));

@@ -171,5 +200,7 @@ expect(encoding_1.Encoding.fromRfc3339("2002-10-02T11:12:13-04:30")).toEqual(new Date(Date.UTC(2002, 9, 2, 11 + 4, 12 + 30, 13)));

it("parses dates with low precision fractional seconds", () => {
// 1 digit
expect(encoding_1.Encoding.fromRfc3339("2002-10-02T11:12:13.0Z")).toEqual(new Date(Date.UTC(2002, 9, 2, 11, 12, 13, 0)));
expect(encoding_1.Encoding.fromRfc3339("2002-10-02T11:12:13.1Z")).toEqual(new Date(Date.UTC(2002, 9, 2, 11, 12, 13, 100)));
expect(encoding_1.Encoding.fromRfc3339("2002-10-02T11:12:13.9Z")).toEqual(new Date(Date.UTC(2002, 9, 2, 11, 12, 13, 900)));
// 2 digit
expect(encoding_1.Encoding.fromRfc3339("2002-10-02T11:12:13.00Z")).toEqual(new Date(Date.UTC(2002, 9, 2, 11, 12, 13, 0)));

@@ -180,17 +211,24 @@ expect(encoding_1.Encoding.fromRfc3339("2002-10-02T11:12:13.12Z")).toEqual(new Date(Date.UTC(2002, 9, 2, 11, 12, 13, 120)));

it("parses dates with high precision fractional seconds", () => {
// everything after the 3rd digit is truncated
// 4 digits
expect(encoding_1.Encoding.fromRfc3339("2002-10-02T11:12:13.0000Z")).toEqual(new Date(Date.UTC(2002, 9, 2, 11, 12, 13, 0)));
expect(encoding_1.Encoding.fromRfc3339("2002-10-02T11:12:13.1234Z")).toEqual(new Date(Date.UTC(2002, 9, 2, 11, 12, 13, 123)));
expect(encoding_1.Encoding.fromRfc3339("2002-10-02T11:12:13.9999Z")).toEqual(new Date(Date.UTC(2002, 9, 2, 11, 12, 13, 999)));
// 5 digits
expect(encoding_1.Encoding.fromRfc3339("2002-10-02T11:12:13.00000Z")).toEqual(new Date(Date.UTC(2002, 9, 2, 11, 12, 13, 0)));
expect(encoding_1.Encoding.fromRfc3339("2002-10-02T11:12:13.12345Z")).toEqual(new Date(Date.UTC(2002, 9, 2, 11, 12, 13, 123)));
expect(encoding_1.Encoding.fromRfc3339("2002-10-02T11:12:13.99999Z")).toEqual(new Date(Date.UTC(2002, 9, 2, 11, 12, 13, 999)));
// 6 digits
expect(encoding_1.Encoding.fromRfc3339("2002-10-02T11:12:13.000000Z")).toEqual(new Date(Date.UTC(2002, 9, 2, 11, 12, 13, 0)));
expect(encoding_1.Encoding.fromRfc3339("2002-10-02T11:12:13.123456Z")).toEqual(new Date(Date.UTC(2002, 9, 2, 11, 12, 13, 123)));
expect(encoding_1.Encoding.fromRfc3339("2002-10-02T11:12:13.999999Z")).toEqual(new Date(Date.UTC(2002, 9, 2, 11, 12, 13, 999)));
// 7 digits
expect(encoding_1.Encoding.fromRfc3339("2002-10-02T11:12:13.0000000Z")).toEqual(new Date(Date.UTC(2002, 9, 2, 11, 12, 13, 0)));
expect(encoding_1.Encoding.fromRfc3339("2002-10-02T11:12:13.1234567Z")).toEqual(new Date(Date.UTC(2002, 9, 2, 11, 12, 13, 123)));
expect(encoding_1.Encoding.fromRfc3339("2002-10-02T11:12:13.9999999Z")).toEqual(new Date(Date.UTC(2002, 9, 2, 11, 12, 13, 999)));
// 8 digits
expect(encoding_1.Encoding.fromRfc3339("2002-10-02T11:12:13.00000000Z")).toEqual(new Date(Date.UTC(2002, 9, 2, 11, 12, 13, 0)));
expect(encoding_1.Encoding.fromRfc3339("2002-10-02T11:12:13.12345678Z")).toEqual(new Date(Date.UTC(2002, 9, 2, 11, 12, 13, 123)));
expect(encoding_1.Encoding.fromRfc3339("2002-10-02T11:12:13.99999999Z")).toEqual(new Date(Date.UTC(2002, 9, 2, 11, 12, 13, 999)));
// 9 digits
expect(encoding_1.Encoding.fromRfc3339("2002-10-02T11:12:13.000000000Z")).toEqual(new Date(Date.UTC(2002, 9, 2, 11, 12, 13, 0)));

@@ -201,12 +239,19 @@ expect(encoding_1.Encoding.fromRfc3339("2002-10-02T11:12:13.123456789Z")).toEqual(new Date(Date.UTC(2002, 9, 2, 11, 12, 13, 123)));

it("accepts space separators", () => {
// https://tools.ietf.org/html/rfc3339#section-5.6
// Applications using this syntax may choose, for the sake of readability,
// to specify a full-date and full-time separated by (say) a space character.
expect(encoding_1.Encoding.fromRfc3339("2002-10-02 11:12:13Z")).toEqual(new Date(Date.UTC(2002, 9, 2, 11, 12, 13)));
});
it("throws for invalid format", () => {
// extra whitespace
expect(() => encoding_1.Encoding.fromRfc3339(" 2002-10-02T11:12:13Z")).toThrow();
expect(() => encoding_1.Encoding.fromRfc3339("2002-10-02T11:12:13Z ")).toThrow();
expect(() => encoding_1.Encoding.fromRfc3339("2002-10-02T11:12:13 Z")).toThrow();
// wrong date separators
expect(() => encoding_1.Encoding.fromRfc3339("2002:10-02T11:12:13Z")).toThrow();
expect(() => encoding_1.Encoding.fromRfc3339("2002-10:02T11:12:13Z")).toThrow();
// wrong time separators
expect(() => encoding_1.Encoding.fromRfc3339("2002-10-02T11-12:13Z")).toThrow();
expect(() => encoding_1.Encoding.fromRfc3339("2002-10-02T11:12-13Z")).toThrow();
// wrong separator
expect(() => encoding_1.Encoding.fromRfc3339("2002-10-02TT11:12:13Z")).toThrow();

@@ -219,2 +264,3 @@ expect(() => encoding_1.Encoding.fromRfc3339("2002-10-02 T11:12:13Z")).toThrow();

expect(() => encoding_1.Encoding.fromRfc3339("2002-10-02.11:12:13Z")).toThrow();
// wrong time zone
expect(() => encoding_1.Encoding.fromRfc3339("2002-10-02T11:12:13")).toThrow();

@@ -224,2 +270,3 @@ expect(() => encoding_1.Encoding.fromRfc3339("2002-10-02T11:12:13z")).toThrow();

expect(() => encoding_1.Encoding.fromRfc3339("2002-10-02T11:12:13+0000")).toThrow();
// wrong fractional seconds
expect(() => encoding_1.Encoding.fromRfc3339("2018-07-30T19:21:12345Z")).toThrow();

@@ -234,2 +281,13 @@ expect(() => encoding_1.Encoding.fromRfc3339("2018-07-30T19:21:12.Z")).toThrow();

});
describe("Bech32", () => {
// test data generate using https://github.com/nym-zone/bech32
// bech32 -e -h eth 9d4e856e572e442f0a4b2763e72d08a0e99d8ded
const ethAddressRaw = encoding_1.Encoding.fromHex("9d4e856e572e442f0a4b2763e72d08a0e99d8ded");
it("encodes", () => {
expect(encoding_1.Bech32.encode("eth", ethAddressRaw)).toEqual("eth1n48g2mjh9ezz7zjtya37wtgg5r5emr0drkwlgw");
});
it("decodes", () => {
expect(encoding_1.Bech32.decode("eth1n48g2mjh9ezz7zjtya37wtgg5r5emr0drkwlgw")).toEqual({ prefix: "eth", data: ethAddressRaw });
});
});
//# sourceMappingURL=encoding.spec.js.map
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/* tslint:disable:no-bitwise */
const BN = require("bn.js");
const uint64MaxValue = new BN("18446744073709551615", 10, "be");
class Uint32 {

@@ -8,2 +11,3 @@ static fromBigEndianBytes(bytes) {

}
// tslint:disable-next-line:prefer-for-of
for (let i = 0; i < bytes.length; ++i) {

@@ -14,2 +18,4 @@ if (bytes[i] > 255 || bytes[i] < 0 || Number.isNaN(bytes[i])) {

}
// Use mulitiplication instead of shifting since bitwise operators are defined
// on SIGNED int32 in JavaScript and we don't want to risk surprises
return new Uint32(bytes[0] * Math.pow(2, 24) + bytes[1] * Math.pow(2, 16) + bytes[2] * Math.pow(2, 8) + bytes[3]);

@@ -19,6 +25,6 @@ }

if (Number.isNaN(input)) {
throw new Error("input is not a number");
throw new Error("Input is not a number");
}
if (input < 0 || input > 4294967295) {
throw new Error("input not in uint32 range: " + input.toString());
throw new Error("Input not in uint32 range: " + input.toString());
}

@@ -28,2 +34,4 @@ this.data = input;

toBytesBigEndian() {
// Use division instead of shifting since bitwise operators are defined
// on SIGNED int32 in JavaScript and we don't want to risk surprises
return [

@@ -50,13 +58,13 @@ Math.floor(this.data / Math.pow(2, 24)) & 0xff,

if (Number.isNaN(input)) {
throw new Error("input is not a number");
throw new Error("Input is not a number");
}
if (input < Number.MIN_SAFE_INTEGER || input > Number.MAX_SAFE_INTEGER) {
throw new Error("input not in int53 range: " + input.toString());
throw new Error("Input not in int53 range: " + input.toString());
}
this.data = input;
}
asNumber() {
toNumber() {
return this.data;
}
asString() {
toString() {
return this.data.toString();

@@ -66,2 +74,63 @@ }

exports.Int53 = Int53;
class Uint64 {
static fromBytesBigEndian(bytes) {
if (bytes.length !== 8) {
throw new Error("Invalid input length. Expected 8 bytes.");
}
// tslint:disable-next-line:prefer-for-of
for (let i = 0; i < bytes.length; ++i) {
if (bytes[i] > 255 || bytes[i] < 0 || Number.isNaN(bytes[i])) {
throw new Error("Invalid value in byte. Found: " + bytes[i]);
}
}
// tslint:disable-next-line:readonly-array
const asArray = [];
// tslint:disable-next-line:prefer-for-of
for (let i = 0; i < bytes.length; ++i) {
asArray.push(bytes[i]);
}
return new Uint64(new BN([...asArray]));
}
static fromString(str) {
if (!str.match(/^[0-9]+$/)) {
throw new Error("Invalid string format");
}
return new Uint64(new BN(str, 10, "be"));
}
static fromNumber(input) {
if (Number.isNaN(input)) {
throw new Error("Input is not a number");
}
let bigint;
try {
bigint = new BN(input);
}
catch (_a) {
throw new Error("Input is not a safe integer");
}
return new Uint64(bigint);
}
constructor(data) {
if (data.isNeg()) {
throw new Error("Input is negative");
}
if (data.gt(uint64MaxValue)) {
throw new Error("Input exceeds uint64 range");
}
this.data = data;
}
toBytesBigEndian() {
return this.data.toArray("be", 8);
}
toBytesLittleEndian() {
return this.data.toArray("le", 8);
}
toString() {
return this.data.toString(10);
}
toNumber() {
return this.data.toNumber();
}
}
exports.Uint64 = Uint64;
//# sourceMappingURL=integers.js.map

@@ -16,2 +16,3 @@ "use strict";

it("throws for values out of range", () => {
// tslint:disable:no-unused-expression
expect(() => new integers_1.Uint32(-1)).toThrowError(/not in uint32 range/);

@@ -23,5 +24,8 @@ expect(() => new integers_1.Uint32(4294967296)).toThrowError(/not in uint32 range/);

expect(() => new integers_1.Uint32(Number.POSITIVE_INFINITY)).toThrowError(/not in uint32 range/);
// tslint:enable:no-unused-expression
});
it("throws for invald numbers", () => {
// tslint:disable:no-unused-expression
expect(() => new integers_1.Uint32(NaN)).toThrowError(/not a number/);
// tslint:enable:no-unused-expression
});

@@ -96,2 +100,3 @@ it("can convert back to number", () => {

it("throws for values out of range", () => {
// tslint:disable:no-unused-expression
expect(() => new integers_1.Int53(Number.MIN_SAFE_INTEGER - 1)).toThrowError(/not in int53 range/);

@@ -101,44 +106,177 @@ expect(() => new integers_1.Int53(Number.MAX_SAFE_INTEGER + 1)).toThrowError(/not in int53 range/);

expect(() => new integers_1.Int53(Number.POSITIVE_INFINITY)).toThrowError(/not in int53 range/);
// tslint:enable:no-unused-expression
});
it("throws for invald numbers", () => {
// tslint:disable:no-unused-expression
expect(() => new integers_1.Int53(NaN)).toThrowError(/not a number/);
// tslint:enable:no-unused-expression
});
it("can convert to number", () => {
expect(new integers_1.Int53(0).asNumber()).toEqual(0);
expect(new integers_1.Int53(1).asNumber()).toEqual(1);
expect(new integers_1.Int53(42).asNumber()).toEqual(42);
expect(new integers_1.Int53(1000000000).asNumber()).toEqual(1000000000);
expect(new integers_1.Int53(2147483647).asNumber()).toEqual(2147483647);
expect(new integers_1.Int53(2147483648).asNumber()).toEqual(2147483648);
expect(new integers_1.Int53(4294967295).asNumber()).toEqual(4294967295);
expect(new integers_1.Int53(9007199254740991).asNumber()).toEqual(9007199254740991);
expect(new integers_1.Int53(-1).asNumber()).toEqual(-1);
expect(new integers_1.Int53(-9007199254740991).asNumber()).toEqual(-9007199254740991);
expect(new integers_1.Int53(0).toNumber()).toEqual(0);
expect(new integers_1.Int53(1).toNumber()).toEqual(1);
expect(new integers_1.Int53(42).toNumber()).toEqual(42);
expect(new integers_1.Int53(1000000000).toNumber()).toEqual(1000000000);
expect(new integers_1.Int53(2147483647).toNumber()).toEqual(2147483647);
expect(new integers_1.Int53(2147483648).toNumber()).toEqual(2147483648);
expect(new integers_1.Int53(4294967295).toNumber()).toEqual(4294967295);
expect(new integers_1.Int53(9007199254740991).toNumber()).toEqual(9007199254740991);
expect(new integers_1.Int53(-1).toNumber()).toEqual(-1);
expect(new integers_1.Int53(-9007199254740991).toNumber()).toEqual(-9007199254740991);
});
it("can convert to string", () => {
expect(new integers_1.Int53(0).asString()).toEqual("0");
expect(new integers_1.Int53(1).asString()).toEqual("1");
expect(new integers_1.Int53(42).asString()).toEqual("42");
expect(new integers_1.Int53(1000000000).asString()).toEqual("1000000000");
expect(new integers_1.Int53(2147483647).asString()).toEqual("2147483647");
expect(new integers_1.Int53(2147483648).asString()).toEqual("2147483648");
expect(new integers_1.Int53(4294967295).asString()).toEqual("4294967295");
expect(new integers_1.Int53(9007199254740991).asString()).toEqual("9007199254740991");
expect(new integers_1.Int53(-1).asString()).toEqual("-1");
expect(new integers_1.Int53(-9007199254740991).asString()).toEqual("-9007199254740991");
expect(new integers_1.Int53(0).toString()).toEqual("0");
expect(new integers_1.Int53(1).toString()).toEqual("1");
expect(new integers_1.Int53(42).toString()).toEqual("42");
expect(new integers_1.Int53(1000000000).toString()).toEqual("1000000000");
expect(new integers_1.Int53(2147483647).toString()).toEqual("2147483647");
expect(new integers_1.Int53(2147483648).toString()).toEqual("2147483648");
expect(new integers_1.Int53(4294967295).toString()).toEqual("4294967295");
expect(new integers_1.Int53(9007199254740991).toString()).toEqual("9007199254740991");
expect(new integers_1.Int53(-1).toString()).toEqual("-1");
expect(new integers_1.Int53(-9007199254740991).toString()).toEqual("-9007199254740991");
});
it("can be constructed from string", () => {
expect(integers_1.Int53.fromString("0").asString()).toEqual("0");
expect(integers_1.Int53.fromString("1").asString()).toEqual("1");
expect(integers_1.Int53.fromString("9007199254740991").asString()).toEqual("9007199254740991");
expect(integers_1.Int53.fromString("-1").asString()).toEqual("-1");
expect(integers_1.Int53.fromString("-9007199254740991").asString()).toEqual("-9007199254740991");
expect(integers_1.Int53.fromString("0").toString()).toEqual("0");
expect(integers_1.Int53.fromString("1").toString()).toEqual("1");
expect(integers_1.Int53.fromString("9007199254740991").toString()).toEqual("9007199254740991");
expect(integers_1.Int53.fromString("-1").toString()).toEqual("-1");
expect(integers_1.Int53.fromString("-9007199254740991").toString()).toEqual("-9007199254740991");
});
it("throws for invalid string format", () => {
// tslint:disable:no-unused-expression
expect(() => integers_1.Int53.fromString(" 0")).toThrowError(/invalid string format/i);
expect(() => integers_1.Int53.fromString("+0")).toThrowError(/invalid string format/i);
expect(() => integers_1.Int53.fromString("1e6")).toThrowError(/invalid string format/i);
expect(() => integers_1.Int53.fromString("9007199254740992")).toThrowError(/input not in int53 range/i);
expect(() => integers_1.Int53.fromString("-9007199254740992")).toThrowError(/input not in int53 range/i);
// tslint:enable:no-unused-expression
});
});
describe("Uint64", () => {
it("can be constructed from bytes", () => {
integers_1.Uint64.fromBytesBigEndian([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
integers_1.Uint64.fromBytesBigEndian([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]);
integers_1.Uint64.fromBytesBigEndian([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]);
});
it("can be constructed from Uint8Array", () => {
integers_1.Uint64.fromBytesBigEndian(new Uint8Array([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]));
});
it("throws for wrong number of bytes", () => {
expect(() => integers_1.Uint64.fromBytesBigEndian([])).toThrowError(/invalid input length/i);
expect(() => integers_1.Uint64.fromBytesBigEndian([0x00])).toThrowError(/invalid input length/i);
expect(() => integers_1.Uint64.fromBytesBigEndian([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])).toThrowError(/invalid input length/i);
expect(() => integers_1.Uint64.fromBytesBigEndian([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])).toThrowError(/invalid input length/i);
});
it("throws for wrong byte value", () => {
expect(() => integers_1.Uint64.fromBytesBigEndian([0, 0, 0, 0, 0, 0, 0, 256])).toThrowError(/invalid value in byte/i);
expect(() => integers_1.Uint64.fromBytesBigEndian([0, 0, 0, 0, 0, 0, 0, -1])).toThrowError(/invalid value in byte/i);
expect(() => integers_1.Uint64.fromBytesBigEndian([0, 0, 0, 0, 0, 0, 0, Number.NEGATIVE_INFINITY])).toThrowError(/invalid value in byte/i);
expect(() => integers_1.Uint64.fromBytesBigEndian([0, 0, 0, 0, 0, 0, 0, Number.POSITIVE_INFINITY])).toThrowError(/invalid value in byte/i);
expect(() => integers_1.Uint64.fromBytesBigEndian([0, 0, 0, 0, 0, 0, 0, Number.NaN])).toThrowError(/invalid value in byte/i);
});
it("can be constructed from string", () => {
{
const a = integers_1.Uint64.fromString("0");
expect(a).toBeTruthy();
}
{
const a = integers_1.Uint64.fromString("1");
expect(a).toBeTruthy();
}
{
const a = integers_1.Uint64.fromString("01");
expect(a).toBeTruthy();
}
{
const a = integers_1.Uint64.fromString("9999999999999999999");
expect(a).toBeTruthy();
}
{
const a = integers_1.Uint64.fromString("18446744073709551615");
expect(a).toBeTruthy();
}
});
it("throws for invalid string values", () => {
expect(() => integers_1.Uint64.fromString(" 1")).toThrowError(/invalid string format/i);
expect(() => integers_1.Uint64.fromString("-1")).toThrowError(/invalid string format/i);
expect(() => integers_1.Uint64.fromString("+1")).toThrowError(/invalid string format/i);
expect(() => integers_1.Uint64.fromString("1e6")).toThrowError(/invalid string format/i);
});
it("throws for string values exceeding uint64", () => {
expect(() => integers_1.Uint64.fromString("18446744073709551616")).toThrowError(/input exceeds uint64 range/i);
expect(() => integers_1.Uint64.fromString("99999999999999999999")).toThrowError(/input exceeds uint64 range/i);
});
it("can be constructed from number", () => {
const a = integers_1.Uint64.fromNumber(0);
expect(a.toNumber()).toEqual(0);
const b = integers_1.Uint64.fromNumber(1);
expect(b.toNumber()).toEqual(1);
const c = integers_1.Uint64.fromNumber(Number.MAX_SAFE_INTEGER);
expect(c.toNumber()).toEqual(Number.MAX_SAFE_INTEGER);
});
it("throws when constructed from wrong numbers", () => {
// not a number
expect(() => integers_1.Uint64.fromNumber(Number.NaN)).toThrowError(/input is not a number/i);
// not an integer
expect(() => integers_1.Uint64.fromNumber(Number.NEGATIVE_INFINITY)).toThrowError(/input is not a safe integer/i);
expect(() => integers_1.Uint64.fromNumber(Number.POSITIVE_INFINITY)).toThrowError(/input is not a safe integer/i);
expect(() => integers_1.Uint64.fromNumber(Number.MAX_SAFE_INTEGER + 1)).toThrowError(/input is not a safe integer/i);
// negative integer
expect(() => integers_1.Uint64.fromNumber(-1)).toThrowError(/input is negative/i);
expect(() => integers_1.Uint64.fromNumber(Number.MIN_SAFE_INTEGER)).toThrowError(/input is negative/i);
});
it("can export bytes (big endian)", () => {
expect(integers_1.Uint64.fromBytesBigEndian([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]).toBytesBigEndian()).toEqual([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
expect(integers_1.Uint64.fromBytesBigEndian([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]).toBytesBigEndian()).toEqual([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]);
expect(integers_1.Uint64.fromBytesBigEndian([0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]).toBytesBigEndian()).toEqual([0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
expect(integers_1.Uint64.fromBytesBigEndian([0xab, 0x22, 0xbc, 0x5f, 0xa9, 0x20, 0x4e, 0x0d]).toBytesBigEndian()).toEqual([0xab, 0x22, 0xbc, 0x5f, 0xa9, 0x20, 0x4e, 0x0d]);
expect(integers_1.Uint64.fromBytesBigEndian([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]).toBytesBigEndian()).toEqual([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]);
});
it("can export bytes (little endian)", () => {
expect(integers_1.Uint64.fromBytesBigEndian([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]).toBytesLittleEndian()).toEqual([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
expect(integers_1.Uint64.fromBytesBigEndian([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]).toBytesLittleEndian()).toEqual([0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
expect(integers_1.Uint64.fromBytesBigEndian([0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]).toBytesLittleEndian()).toEqual([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]);
expect(integers_1.Uint64.fromBytesBigEndian([0xab, 0x22, 0xbc, 0x5f, 0xa9, 0x20, 0x4e, 0x0d]).toBytesLittleEndian()).toEqual([0x0d, 0x4e, 0x20, 0xa9, 0x5f, 0xbc, 0x22, 0xab]);
expect(integers_1.Uint64.fromBytesBigEndian([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]).toBytesLittleEndian()).toEqual([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]);
});
it("can export strings", () => {
{
const a = integers_1.Uint64.fromBytesBigEndian([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
expect(a.toString()).toEqual("0");
}
{
const a = integers_1.Uint64.fromBytesBigEndian([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]);
expect(a.toString()).toEqual("1");
}
{
const a = integers_1.Uint64.fromBytesBigEndian([0x8a, 0xc7, 0x23, 0x04, 0x89, 0xe7, 0xff, 0xff]);
expect(a.toString()).toEqual("9999999999999999999");
}
{
const a = integers_1.Uint64.fromBytesBigEndian([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]);
expect(a.toString()).toEqual("18446744073709551615");
}
});
it("can export numbers", () => {
{
const a = integers_1.Uint64.fromBytesBigEndian([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
expect(a.toNumber()).toEqual(0);
}
{
const a = integers_1.Uint64.fromBytesBigEndian([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]);
expect(a.toNumber()).toEqual(1);
}
{
// value too large for 53 bit integer
const a = integers_1.Uint64.fromBytesBigEndian([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]);
expect(() => a.toNumber()).toThrowError(/number can only safely store up to 53 bits/i);
}
{
// Number.MAX_SAFE_INTEGER + 1
const a = integers_1.Uint64.fromBytesBigEndian([0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
expect(() => a.toNumber()).toThrowError(/number can only safely store up to 53 bits/i);
}
});
});
});
//# sourceMappingURL=integers.spec.js.map

9

package.json
{
"name": "@iov/encoding",
"version": "0.6.0",
"version": "0.7.0",
"description": "Encoding helpers for IOV projects",

@@ -33,8 +33,11 @@ "author": "IOV SAS <admin@iov.one>",

"base64-js": "^1.3.0",
"bech32": "^1.1.3",
"bn.js": "^4.11.8",
"readonly-date": "^1.0.0"
},
"devDependencies": {
"@types/base64-js": "^1.2.5"
"@types/base64-js": "^1.2.5",
"@types/bech32": "^1.1.1"
},
"gitHead": "a5259d28a4e22e5ebcf6ae30e4af7c2922647120"
"gitHead": "559a368ef6e16cc8f3fe20b7d8df4a5ac1d995fc"
}

@@ -10,2 +10,11 @@ # @iov/encoding

## Convert between bech32 and hex addresses
```
>> Bech32.encode("tiov", Encoding.fromHex("1234ABCD0000AA0000FFFF0000AA00001234ABCD"))
'tiov1zg62hngqqz4qqq8lluqqp2sqqqfrf27dzrrmea'
>> Encoding.toHex(Bech32.decode("tiov1zg62hngqqz4qqq8lluqqp2sqqqfrf27dzrrmea").data)
'1234abcd0000aa0000ffff0000aa00001234abcd'
```
## API Documentation

@@ -12,0 +21,0 @@

@@ -1,2 +0,2 @@

import { Encoding } from "./encoding";
import { Bech32, Encoding } from "./encoding";

@@ -133,2 +133,10 @@ describe("Encoding", () => {

it("encodes null character", () => {
expect(Encoding.toUtf8("\u0000")).toEqual(new Uint8Array([0x00]));
});
it("decodes null byte", () => {
expect(Encoding.fromUtf8(new Uint8Array([0x00]))).toEqual("\u0000");
});
it("encodes Basic Multilingual Plane strings", () => {

@@ -309,1 +317,15 @@ expect(Encoding.toUtf8("ö")).toEqual(new Uint8Array([0xc3, 0xb6]));

});
describe("Bech32", () => {
// test data generate using https://github.com/nym-zone/bech32
// bech32 -e -h eth 9d4e856e572e442f0a4b2763e72d08a0e99d8ded
const ethAddressRaw = Encoding.fromHex("9d4e856e572e442f0a4b2763e72d08a0e99d8ded");
it("encodes", () => {
expect(Bech32.encode("eth", ethAddressRaw)).toEqual("eth1n48g2mjh9ezz7zjtya37wtgg5r5emr0drkwlgw");
});
it("decodes", () => {
expect(Bech32.decode("eth1n48g2mjh9ezz7zjtya37wtgg5r5emr0drkwlgw")).toEqual({ prefix: "eth", data: ethAddressRaw });
});
});
import * as base64js from "base64-js";
import * as bech32 from "bech32";
import { ReadonlyDate } from "readonly-date";

@@ -163,1 +164,17 @@

}
export class Bech32 {
public static encode(prefix: string, data: Uint8Array): string {
const dataToWords = bech32.toWords(Buffer.from(data));
const encodedData = bech32.encode(prefix, dataToWords);
return encodedData;
}
public static decode(address: string): { readonly prefix: string; readonly data: Uint8Array } {
const decodedAddress = bech32.decode(address);
return {
prefix: decodedAddress.prefix,
data: new Uint8Array(bech32.fromWords(decodedAddress.words)),
};
}
}

@@ -1,2 +0,2 @@

import { Int53, Uint32 } from "./integers";
import { Int53, Uint32, Uint64 } from "./integers";

@@ -131,36 +131,36 @@ describe("Integers", () => {

it("can convert to number", () => {
expect(new Int53(0).asNumber()).toEqual(0);
expect(new Int53(1).asNumber()).toEqual(1);
expect(new Int53(42).asNumber()).toEqual(42);
expect(new Int53(1000000000).asNumber()).toEqual(1000000000);
expect(new Int53(2147483647).asNumber()).toEqual(2147483647);
expect(new Int53(2147483648).asNumber()).toEqual(2147483648);
expect(new Int53(4294967295).asNumber()).toEqual(4294967295);
expect(new Int53(9007199254740991).asNumber()).toEqual(9007199254740991);
expect(new Int53(0).toNumber()).toEqual(0);
expect(new Int53(1).toNumber()).toEqual(1);
expect(new Int53(42).toNumber()).toEqual(42);
expect(new Int53(1000000000).toNumber()).toEqual(1000000000);
expect(new Int53(2147483647).toNumber()).toEqual(2147483647);
expect(new Int53(2147483648).toNumber()).toEqual(2147483648);
expect(new Int53(4294967295).toNumber()).toEqual(4294967295);
expect(new Int53(9007199254740991).toNumber()).toEqual(9007199254740991);
expect(new Int53(-1).asNumber()).toEqual(-1);
expect(new Int53(-9007199254740991).asNumber()).toEqual(-9007199254740991);
expect(new Int53(-1).toNumber()).toEqual(-1);
expect(new Int53(-9007199254740991).toNumber()).toEqual(-9007199254740991);
});
it("can convert to string", () => {
expect(new Int53(0).asString()).toEqual("0");
expect(new Int53(1).asString()).toEqual("1");
expect(new Int53(42).asString()).toEqual("42");
expect(new Int53(1000000000).asString()).toEqual("1000000000");
expect(new Int53(2147483647).asString()).toEqual("2147483647");
expect(new Int53(2147483648).asString()).toEqual("2147483648");
expect(new Int53(4294967295).asString()).toEqual("4294967295");
expect(new Int53(9007199254740991).asString()).toEqual("9007199254740991");
expect(new Int53(0).toString()).toEqual("0");
expect(new Int53(1).toString()).toEqual("1");
expect(new Int53(42).toString()).toEqual("42");
expect(new Int53(1000000000).toString()).toEqual("1000000000");
expect(new Int53(2147483647).toString()).toEqual("2147483647");
expect(new Int53(2147483648).toString()).toEqual("2147483648");
expect(new Int53(4294967295).toString()).toEqual("4294967295");
expect(new Int53(9007199254740991).toString()).toEqual("9007199254740991");
expect(new Int53(-1).asString()).toEqual("-1");
expect(new Int53(-9007199254740991).asString()).toEqual("-9007199254740991");
expect(new Int53(-1).toString()).toEqual("-1");
expect(new Int53(-9007199254740991).toString()).toEqual("-9007199254740991");
});
it("can be constructed from string", () => {
expect(Int53.fromString("0").asString()).toEqual("0");
expect(Int53.fromString("1").asString()).toEqual("1");
expect(Int53.fromString("9007199254740991").asString()).toEqual("9007199254740991");
expect(Int53.fromString("0").toString()).toEqual("0");
expect(Int53.fromString("1").toString()).toEqual("1");
expect(Int53.fromString("9007199254740991").toString()).toEqual("9007199254740991");
expect(Int53.fromString("-1").asString()).toEqual("-1");
expect(Int53.fromString("-9007199254740991").asString()).toEqual("-9007199254740991");
expect(Int53.fromString("-1").toString()).toEqual("-1");
expect(Int53.fromString("-9007199254740991").toString()).toEqual("-9007199254740991");
});

@@ -175,5 +175,149 @@

expect(() => Int53.fromString("9007199254740992")).toThrowError(/input not in int53 range/i);
expect(() => Int53.fromString("-9007199254740992")).toThrowError(/input not in int53 range/i);
// tslint:enable:no-unused-expression
});
});
describe("Uint64", () => {
it("can be constructed from bytes", () => {
Uint64.fromBytesBigEndian([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
Uint64.fromBytesBigEndian([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]);
Uint64.fromBytesBigEndian([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]);
});
it("can be constructed from Uint8Array", () => {
Uint64.fromBytesBigEndian(new Uint8Array([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]));
});
it("throws for wrong number of bytes", () => {
expect(() => Uint64.fromBytesBigEndian([])).toThrowError(/invalid input length/i);
expect(() => Uint64.fromBytesBigEndian([0x00])).toThrowError(/invalid input length/i);
expect(() => Uint64.fromBytesBigEndian([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])).toThrowError(/invalid input length/i);
expect(() => Uint64.fromBytesBigEndian([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])).toThrowError(/invalid input length/i);
});
it("throws for wrong byte value", () => {
expect(() => Uint64.fromBytesBigEndian([0, 0, 0, 0, 0, 0, 0, 256])).toThrowError(/invalid value in byte/i);
expect(() => Uint64.fromBytesBigEndian([0, 0, 0, 0, 0, 0, 0, -1])).toThrowError(/invalid value in byte/i);
expect(() => Uint64.fromBytesBigEndian([0, 0, 0, 0, 0, 0, 0, Number.NEGATIVE_INFINITY])).toThrowError(/invalid value in byte/i);
expect(() => Uint64.fromBytesBigEndian([0, 0, 0, 0, 0, 0, 0, Number.POSITIVE_INFINITY])).toThrowError(/invalid value in byte/i);
expect(() => Uint64.fromBytesBigEndian([0, 0, 0, 0, 0, 0, 0, Number.NaN])).toThrowError(/invalid value in byte/i);
});
it("can be constructed from string", () => {
{
const a = Uint64.fromString("0");
expect(a).toBeTruthy();
}
{
const a = Uint64.fromString("1");
expect(a).toBeTruthy();
}
{
const a = Uint64.fromString("01");
expect(a).toBeTruthy();
}
{
const a = Uint64.fromString("9999999999999999999");
expect(a).toBeTruthy();
}
{
const a = Uint64.fromString("18446744073709551615");
expect(a).toBeTruthy();
}
});
it("throws for invalid string values", () => {
expect(() => Uint64.fromString(" 1")).toThrowError(/invalid string format/i);
expect(() => Uint64.fromString("-1")).toThrowError(/invalid string format/i);
expect(() => Uint64.fromString("+1")).toThrowError(/invalid string format/i);
expect(() => Uint64.fromString("1e6")).toThrowError(/invalid string format/i);
});
it("throws for string values exceeding uint64", () => {
expect(() => Uint64.fromString("18446744073709551616")).toThrowError(/input exceeds uint64 range/i);
expect(() => Uint64.fromString("99999999999999999999")).toThrowError(/input exceeds uint64 range/i);
});
it("can be constructed from number", () => {
const a = Uint64.fromNumber(0);
expect(a.toNumber()).toEqual(0);
const b = Uint64.fromNumber(1);
expect(b.toNumber()).toEqual(1);
const c = Uint64.fromNumber(Number.MAX_SAFE_INTEGER);
expect(c.toNumber()).toEqual(Number.MAX_SAFE_INTEGER);
});
it("throws when constructed from wrong numbers", () => {
// not a number
expect(() => Uint64.fromNumber(Number.NaN)).toThrowError(/input is not a number/i);
// not an integer
expect(() => Uint64.fromNumber(Number.NEGATIVE_INFINITY)).toThrowError(/input is not a safe integer/i);
expect(() => Uint64.fromNumber(Number.POSITIVE_INFINITY)).toThrowError(/input is not a safe integer/i);
expect(() => Uint64.fromNumber(Number.MAX_SAFE_INTEGER + 1)).toThrowError(/input is not a safe integer/i);
// negative integer
expect(() => Uint64.fromNumber(-1)).toThrowError(/input is negative/i);
expect(() => Uint64.fromNumber(Number.MIN_SAFE_INTEGER)).toThrowError(/input is negative/i);
});
it("can export bytes (big endian)", () => {
expect(Uint64.fromBytesBigEndian([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]).toBytesBigEndian()).toEqual([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
expect(Uint64.fromBytesBigEndian([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]).toBytesBigEndian()).toEqual([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]);
expect(Uint64.fromBytesBigEndian([0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]).toBytesBigEndian()).toEqual([0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
expect(Uint64.fromBytesBigEndian([0xab, 0x22, 0xbc, 0x5f, 0xa9, 0x20, 0x4e, 0x0d]).toBytesBigEndian()).toEqual([0xab, 0x22, 0xbc, 0x5f, 0xa9, 0x20, 0x4e, 0x0d]);
expect(Uint64.fromBytesBigEndian([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]).toBytesBigEndian()).toEqual([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]);
});
it("can export bytes (little endian)", () => {
expect(Uint64.fromBytesBigEndian([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]).toBytesLittleEndian()).toEqual([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
expect(Uint64.fromBytesBigEndian([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]).toBytesLittleEndian()).toEqual([0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
expect(Uint64.fromBytesBigEndian([0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]).toBytesLittleEndian()).toEqual([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]);
expect(Uint64.fromBytesBigEndian([0xab, 0x22, 0xbc, 0x5f, 0xa9, 0x20, 0x4e, 0x0d]).toBytesLittleEndian()).toEqual([0x0d, 0x4e, 0x20, 0xa9, 0x5f, 0xbc, 0x22, 0xab]);
expect(Uint64.fromBytesBigEndian([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]).toBytesLittleEndian()).toEqual([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]);
});
it("can export strings", () => {
{
const a = Uint64.fromBytesBigEndian([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
expect(a.toString()).toEqual("0");
}
{
const a = Uint64.fromBytesBigEndian([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]);
expect(a.toString()).toEqual("1");
}
{
const a = Uint64.fromBytesBigEndian([0x8a, 0xc7, 0x23, 0x04, 0x89, 0xe7, 0xff, 0xff]);
expect(a.toString()).toEqual("9999999999999999999");
}
{
const a = Uint64.fromBytesBigEndian([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]);
expect(a.toString()).toEqual("18446744073709551615");
}
});
it("can export numbers", () => {
{
const a = Uint64.fromBytesBigEndian([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
expect(a.toNumber()).toEqual(0);
}
{
const a = Uint64.fromBytesBigEndian([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]);
expect(a.toNumber()).toEqual(1);
}
{
// value too large for 53 bit integer
const a = Uint64.fromBytesBigEndian([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]);
expect(() => a.toNumber()).toThrowError(/number can only safely store up to 53 bits/i);
}
{
// Number.MAX_SAFE_INTEGER + 1
const a = Uint64.fromBytesBigEndian([0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
expect(() => a.toNumber()).toThrowError(/number can only safely store up to 53 bits/i);
}
});
});
});
/* tslint:disable:no-bitwise */
import BN = require("bn.js");
const uint64MaxValue = new BN("18446744073709551615", 10, "be");
export class Uint32 {

@@ -25,7 +28,7 @@ public static fromBigEndianBytes(bytes: ArrayLike<number>): Uint32 {

if (Number.isNaN(input)) {
throw new Error("input is not a number");
throw new Error("Input is not a number");
}
if (input < 0 || input > 4294967295) {
throw new Error("input not in uint32 range: " + input.toString());
throw new Error("Input not in uint32 range: " + input.toString());
}

@@ -65,7 +68,7 @@

if (Number.isNaN(input)) {
throw new Error("input is not a number");
throw new Error("Input is not a number");
}
if (input < Number.MIN_SAFE_INTEGER || input > Number.MAX_SAFE_INTEGER) {
throw new Error("input not in int53 range: " + input.toString());
throw new Error("Input not in int53 range: " + input.toString());
}

@@ -76,9 +79,82 @@

public asNumber(): number {
public toNumber(): number {
return this.data;
}
public asString(): string {
public toString(): string {
return this.data.toString();
}
}
export class Uint64 {
public static fromBytesBigEndian(bytes: ArrayLike<number>): Uint64 {
if (bytes.length !== 8) {
throw new Error("Invalid input length. Expected 8 bytes.");
}
// tslint:disable-next-line:prefer-for-of
for (let i = 0; i < bytes.length; ++i) {
if (bytes[i] > 255 || bytes[i] < 0 || Number.isNaN(bytes[i])) {
throw new Error("Invalid value in byte. Found: " + bytes[i]);
}
}
// tslint:disable-next-line:readonly-array
const asArray: number[] = [];
// tslint:disable-next-line:prefer-for-of
for (let i = 0; i < bytes.length; ++i) {
asArray.push(bytes[i]);
}
return new Uint64(new BN([...asArray]));
}
public static fromString(str: string): Uint64 {
if (!str.match(/^[0-9]+$/)) {
throw new Error("Invalid string format");
}
return new Uint64(new BN(str, 10, "be"));
}
public static fromNumber(input: number): Uint64 {
if (Number.isNaN(input)) {
throw new Error("Input is not a number");
}
let bigint: BN;
try {
bigint = new BN(input);
} catch {
throw new Error("Input is not a safe integer");
}
return new Uint64(bigint);
}
private readonly data: BN;
private constructor(data: BN) {
if (data.isNeg()) {
throw new Error("Input is negative");
}
if (data.gt(uint64MaxValue)) {
throw new Error("Input exceeds uint64 range");
}
this.data = data;
}
public toBytesBigEndian(): ReadonlyArray<number> {
return this.data.toArray("be", 8);
}
public toBytesLittleEndian(): ReadonlyArray<number> {
return this.data.toArray("le", 8);
}
public toString(): string {
return this.data.toString(10);
}
public toNumber(): number {
return this.data.toNumber();
}
}

@@ -6,7 +6,3 @@ {

"outDir": "build",
"rootDir": "src",
"typeRoots": [
"../../node_modules/@types",
"custom_types"
],
"rootDir": "src"
},

@@ -13,0 +9,0 @@ "include": [

@@ -15,1 +15,8 @@ import { ReadonlyDate } from "readonly-date";

}
export declare class Bech32 {
static encode(prefix: string, data: Uint8Array): string;
static decode(address: string): {
readonly prefix: string;
readonly data: Uint8Array;
};
}

@@ -12,4 +12,15 @@ export declare class Uint32 {

constructor(input: number);
asNumber(): number;
asString(): string;
toNumber(): number;
toString(): string;
}
export declare class Uint64 {
static fromBytesBigEndian(bytes: ArrayLike<number>): Uint64;
static fromString(str: string): Uint64;
static fromNumber(input: number): Uint64;
private readonly data;
private constructor();
toBytesBigEndian(): ReadonlyArray<number>;
toBytesLittleEndian(): ReadonlyArray<number>;
toString(): string;
toNumber(): number;
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc