Merge pull request #442 from CosmWasm/fromBytes
Add Uint32.fromBytes/Uint64.fromBytes/Uint32.fromString
This commit is contained in:
commit
70b213d13d
@ -63,6 +63,11 @@
|
||||
Launchpad. Two new classes are provided: `LedgerSigner` (for most use cases)
|
||||
and `LaunchpadLedger` for more fine-grained access.
|
||||
- @cosmjs/math: Add `.multiply` method to `Decimal` class.
|
||||
- @cosmjs/math: Deprecate `Uint32.fromBigEndianBytes` in favour of
|
||||
`Uint32.fromBytes`, which supports both big and little endian.
|
||||
- @cosmjs/math: Deprecate `Uint64.fromBytesBigEndian` in favour of
|
||||
`Uint64.fromBytes`, which supports both big and little endian.
|
||||
- @cosmjs/math: Add `Uint32.fromString`.
|
||||
- @cosmjs/tendermint-rpc: Make `BroadcastTxCommitResponse.height` non-optional.
|
||||
- @cosmjs/tendermint-rpc: Make `TxProof.proof.leafHash` non-optional because it
|
||||
is always set.
|
||||
|
||||
@ -2,6 +2,88 @@ import { Int53, Uint32, Uint53, Uint64 } from "./integers";
|
||||
|
||||
describe("Integers", () => {
|
||||
describe("Uint32", () => {
|
||||
describe("fromBytes", () => {
|
||||
it("can be constructed from to byte array", () => {
|
||||
expect(Uint32.fromBytes([0, 0, 0, 0]).toNumber()).toEqual(0);
|
||||
expect(Uint32.fromBytes([0, 0, 0, 1]).toNumber()).toEqual(1);
|
||||
expect(Uint32.fromBytes([0, 0, 0, 42]).toNumber()).toEqual(42);
|
||||
expect(Uint32.fromBytes([0x3b, 0x9a, 0xca, 0x00]).toNumber()).toEqual(1000000000);
|
||||
expect(Uint32.fromBytes([0x7f, 0xff, 0xff, 0xff]).toNumber()).toEqual(2147483647);
|
||||
expect(Uint32.fromBytes([0x80, 0x00, 0x00, 0x00]).toNumber()).toEqual(2147483648);
|
||||
expect(Uint32.fromBytes([0xff, 0xff, 0xff, 0xff]).toNumber()).toEqual(4294967295);
|
||||
});
|
||||
|
||||
it("can be constructed from Buffer", () => {
|
||||
expect(Uint32.fromBytes(Buffer.from([0, 0, 0, 0])).toNumber()).toEqual(0);
|
||||
expect(Uint32.fromBytes(Buffer.from([0, 0, 0, 1])).toNumber()).toEqual(1);
|
||||
expect(Uint32.fromBytes(Buffer.from([0, 0, 0, 42])).toNumber()).toEqual(42);
|
||||
expect(Uint32.fromBytes(Buffer.from([0x3b, 0x9a, 0xca, 0x00])).toNumber()).toEqual(1000000000);
|
||||
expect(Uint32.fromBytes(Buffer.from([0x7f, 0xff, 0xff, 0xff])).toNumber()).toEqual(2147483647);
|
||||
expect(Uint32.fromBytes(Buffer.from([0x80, 0x00, 0x00, 0x00])).toNumber()).toEqual(2147483648);
|
||||
expect(Uint32.fromBytes(Buffer.from([0xff, 0xff, 0xff, 0xff])).toNumber()).toEqual(4294967295);
|
||||
});
|
||||
|
||||
it("throws for invalid input length", () => {
|
||||
expect(() => Uint32.fromBytes([])).toThrowError(/Invalid input length/);
|
||||
expect(() => Uint32.fromBytes([0, 0, 0])).toThrowError(/Invalid input length/);
|
||||
expect(() => Uint32.fromBytes([0, 0, 0, 0, 0])).toThrowError(/Invalid input length/);
|
||||
});
|
||||
|
||||
it("throws for invalid values", () => {
|
||||
expect(() => Uint32.fromBytes([0, 0, 0, -1])).toThrowError(/Invalid value in byte/);
|
||||
expect(() => Uint32.fromBytes([0, 0, 0, 1.5])).toThrowError(/Invalid value in byte/);
|
||||
expect(() => Uint32.fromBytes([0, 0, 0, 256])).toThrowError(/Invalid value in byte/);
|
||||
expect(() => Uint32.fromBytes([0, 0, 0, NaN])).toThrowError(/Invalid value in byte/);
|
||||
expect(() => Uint32.fromBytes([0, 0, 0, Number.NEGATIVE_INFINITY])).toThrowError(
|
||||
/Invalid value in byte/,
|
||||
);
|
||||
expect(() => Uint32.fromBytes([0, 0, 0, Number.POSITIVE_INFINITY])).toThrowError(
|
||||
/Invalid value in byte/,
|
||||
);
|
||||
});
|
||||
|
||||
it("works for big and little endian", () => {
|
||||
const b = Uint32.fromBytes([0x00, 0xa6, 0xb7, 0xd8], "be");
|
||||
expect(b.toNumber()).toEqual(0xa6b7d8);
|
||||
|
||||
const l = Uint32.fromBytes([0xa6, 0xb7, 0xd8, 0x00], "le");
|
||||
expect(l.toNumber()).toEqual(0xd8b7a6);
|
||||
});
|
||||
});
|
||||
|
||||
describe("fromString", () => {
|
||||
it("can be constructed from string", () => {
|
||||
{
|
||||
const a = Uint32.fromString("0");
|
||||
expect(a.toNumber()).toEqual(0);
|
||||
}
|
||||
{
|
||||
const a = Uint32.fromString("1");
|
||||
expect(a.toNumber()).toEqual(1);
|
||||
}
|
||||
{
|
||||
const a = Uint32.fromString("01");
|
||||
expect(a.toNumber()).toEqual(1);
|
||||
}
|
||||
{
|
||||
const a = Uint32.fromString("4294967295");
|
||||
expect(a.toNumber()).toEqual(4294967295);
|
||||
}
|
||||
});
|
||||
|
||||
it("throws for invalid string values", () => {
|
||||
expect(() => Uint32.fromString(" 1")).toThrowError(/invalid string format/i);
|
||||
expect(() => Uint32.fromString("-1")).toThrowError(/invalid string format/i);
|
||||
expect(() => Uint32.fromString("+1")).toThrowError(/invalid string format/i);
|
||||
expect(() => Uint32.fromString("1e6")).toThrowError(/invalid string format/i);
|
||||
});
|
||||
|
||||
it("throws for string values exceeding uint32", () => {
|
||||
expect(() => Uint32.fromString("4294967296")).toThrowError(/input not in uint32 range/i);
|
||||
expect(() => Uint32.fromString("99999999999999999999")).toThrowError(/input not in uint32 range/i);
|
||||
});
|
||||
});
|
||||
|
||||
it("can be constructed", () => {
|
||||
expect(new Uint32(0)).toBeTruthy();
|
||||
expect(new Uint32(1)).toBeTruthy();
|
||||
@ -79,55 +161,6 @@ describe("Integers", () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("fromBigEndianBytes", () => {
|
||||
it("can be constructed from to byte array", () => {
|
||||
expect(Uint32.fromBigEndianBytes([0, 0, 0, 0]).toNumber()).toEqual(0);
|
||||
expect(Uint32.fromBigEndianBytes([0, 0, 0, 1]).toNumber()).toEqual(1);
|
||||
expect(Uint32.fromBigEndianBytes([0, 0, 0, 42]).toNumber()).toEqual(42);
|
||||
expect(Uint32.fromBigEndianBytes([0x3b, 0x9a, 0xca, 0x00]).toNumber()).toEqual(1000000000);
|
||||
expect(Uint32.fromBigEndianBytes([0x7f, 0xff, 0xff, 0xff]).toNumber()).toEqual(2147483647);
|
||||
expect(Uint32.fromBigEndianBytes([0x80, 0x00, 0x00, 0x00]).toNumber()).toEqual(2147483648);
|
||||
expect(Uint32.fromBigEndianBytes([0xff, 0xff, 0xff, 0xff]).toNumber()).toEqual(4294967295);
|
||||
});
|
||||
|
||||
it("can be constructed from Buffer", () => {
|
||||
expect(Uint32.fromBigEndianBytes(Buffer.from([0, 0, 0, 0])).toNumber()).toEqual(0);
|
||||
expect(Uint32.fromBigEndianBytes(Buffer.from([0, 0, 0, 1])).toNumber()).toEqual(1);
|
||||
expect(Uint32.fromBigEndianBytes(Buffer.from([0, 0, 0, 42])).toNumber()).toEqual(42);
|
||||
expect(Uint32.fromBigEndianBytes(Buffer.from([0x3b, 0x9a, 0xca, 0x00])).toNumber()).toEqual(
|
||||
1000000000,
|
||||
);
|
||||
expect(Uint32.fromBigEndianBytes(Buffer.from([0x7f, 0xff, 0xff, 0xff])).toNumber()).toEqual(
|
||||
2147483647,
|
||||
);
|
||||
expect(Uint32.fromBigEndianBytes(Buffer.from([0x80, 0x00, 0x00, 0x00])).toNumber()).toEqual(
|
||||
2147483648,
|
||||
);
|
||||
expect(Uint32.fromBigEndianBytes(Buffer.from([0xff, 0xff, 0xff, 0xff])).toNumber()).toEqual(
|
||||
4294967295,
|
||||
);
|
||||
});
|
||||
|
||||
it("throws for invalid input length", () => {
|
||||
expect(() => Uint32.fromBigEndianBytes([])).toThrowError(/Invalid input length/);
|
||||
expect(() => Uint32.fromBigEndianBytes([0, 0, 0])).toThrowError(/Invalid input length/);
|
||||
expect(() => Uint32.fromBigEndianBytes([0, 0, 0, 0, 0])).toThrowError(/Invalid input length/);
|
||||
});
|
||||
|
||||
it("throws for invalid values", () => {
|
||||
expect(() => Uint32.fromBigEndianBytes([0, 0, 0, -1])).toThrowError(/Invalid value in byte/);
|
||||
expect(() => Uint32.fromBigEndianBytes([0, 0, 0, 1.5])).toThrowError(/Invalid value in byte/);
|
||||
expect(() => Uint32.fromBigEndianBytes([0, 0, 0, 256])).toThrowError(/Invalid value in byte/);
|
||||
expect(() => Uint32.fromBigEndianBytes([0, 0, 0, NaN])).toThrowError(/Invalid value in byte/);
|
||||
expect(() => Uint32.fromBigEndianBytes([0, 0, 0, Number.NEGATIVE_INFINITY])).toThrowError(
|
||||
/Invalid value in byte/,
|
||||
);
|
||||
expect(() => Uint32.fromBigEndianBytes([0, 0, 0, Number.POSITIVE_INFINITY])).toThrowError(
|
||||
/Invalid value in byte/,
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("Int53", () => {
|
||||
@ -284,48 +317,50 @@ describe("Integers", () => {
|
||||
});
|
||||
|
||||
describe("Uint64", () => {
|
||||
describe("fromBigEndianBytes", () => {
|
||||
describe("fromBytes", () => {
|
||||
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]);
|
||||
Uint64.fromBytes([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
|
||||
Uint64.fromBytes([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]);
|
||||
Uint64.fromBytes([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]));
|
||||
Uint64.fromBytes(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(
|
||||
expect(() => Uint64.fromBytes([])).toThrowError(/invalid input length/i);
|
||||
expect(() => Uint64.fromBytes([0x00])).toThrowError(/invalid input length/i);
|
||||
expect(() => Uint64.fromBytes([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])).toThrowError(
|
||||
/invalid input length/i,
|
||||
);
|
||||
expect(() => Uint64.fromBytes([0x00, 0x00, 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(
|
||||
expect(() => Uint64.fromBytes([0, 0, 0, 0, 0, 0, 0, 256])).toThrowError(/invalid value in byte/i);
|
||||
expect(() => Uint64.fromBytes([0, 0, 0, 0, 0, 0, 0, -1])).toThrowError(/invalid value in byte/i);
|
||||
expect(() => Uint64.fromBytes([0, 0, 0, 0, 0, 0, 0, 1.5])).toThrowError(/invalid value in byte/i);
|
||||
expect(() => Uint64.fromBytes([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, -1])).toThrowError(
|
||||
expect(() => Uint64.fromBytes([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, 1.5])).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(
|
||||
expect(() => Uint64.fromBytes([0, 0, 0, 0, 0, 0, 0, Number.NaN])).toThrowError(
|
||||
/invalid value in byte/i,
|
||||
);
|
||||
});
|
||||
|
||||
it("works for big and little endian", () => {
|
||||
const b = Uint64.fromBytes([0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0xb7, 0xd8], "be");
|
||||
expect(b.toNumber()).toEqual(0xa6b7d8);
|
||||
|
||||
const l = Uint64.fromBytes([0xa6, 0xb7, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00], "le");
|
||||
expect(l.toNumber()).toEqual(0xd8b7a6);
|
||||
});
|
||||
});
|
||||
|
||||
describe("fromString", () => {
|
||||
@ -396,77 +431,77 @@ describe("Integers", () => {
|
||||
});
|
||||
|
||||
it("can export bytes (big endian)", () => {
|
||||
expect(
|
||||
Uint64.fromBytesBigEndian([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]).toBytesBigEndian(),
|
||||
).toEqual(new Uint8Array([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]));
|
||||
expect(
|
||||
Uint64.fromBytesBigEndian([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]).toBytesBigEndian(),
|
||||
).toEqual(new Uint8Array([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]));
|
||||
expect(
|
||||
Uint64.fromBytesBigEndian([0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]).toBytesBigEndian(),
|
||||
).toEqual(new Uint8Array([0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]));
|
||||
expect(
|
||||
Uint64.fromBytesBigEndian([0xab, 0x22, 0xbc, 0x5f, 0xa9, 0x20, 0x4e, 0x0d]).toBytesBigEndian(),
|
||||
).toEqual(new Uint8Array([0xab, 0x22, 0xbc, 0x5f, 0xa9, 0x20, 0x4e, 0x0d]));
|
||||
expect(
|
||||
Uint64.fromBytesBigEndian([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]).toBytesBigEndian(),
|
||||
).toEqual(new Uint8Array([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]));
|
||||
expect(Uint64.fromBytes([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]).toBytesBigEndian()).toEqual(
|
||||
new Uint8Array([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]),
|
||||
);
|
||||
expect(Uint64.fromBytes([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]).toBytesBigEndian()).toEqual(
|
||||
new Uint8Array([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]),
|
||||
);
|
||||
expect(Uint64.fromBytes([0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]).toBytesBigEndian()).toEqual(
|
||||
new Uint8Array([0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]),
|
||||
);
|
||||
expect(Uint64.fromBytes([0xab, 0x22, 0xbc, 0x5f, 0xa9, 0x20, 0x4e, 0x0d]).toBytesBigEndian()).toEqual(
|
||||
new Uint8Array([0xab, 0x22, 0xbc, 0x5f, 0xa9, 0x20, 0x4e, 0x0d]),
|
||||
);
|
||||
expect(Uint64.fromBytes([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]).toBytesBigEndian()).toEqual(
|
||||
new Uint8Array([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(),
|
||||
Uint64.fromBytes([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]).toBytesLittleEndian(),
|
||||
).toEqual(new Uint8Array([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]));
|
||||
expect(
|
||||
Uint64.fromBytesBigEndian([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]).toBytesLittleEndian(),
|
||||
Uint64.fromBytes([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]).toBytesLittleEndian(),
|
||||
).toEqual(new Uint8Array([0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]));
|
||||
expect(
|
||||
Uint64.fromBytesBigEndian([0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]).toBytesLittleEndian(),
|
||||
Uint64.fromBytes([0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]).toBytesLittleEndian(),
|
||||
).toEqual(new Uint8Array([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]));
|
||||
expect(
|
||||
Uint64.fromBytesBigEndian([0xab, 0x22, 0xbc, 0x5f, 0xa9, 0x20, 0x4e, 0x0d]).toBytesLittleEndian(),
|
||||
Uint64.fromBytes([0xab, 0x22, 0xbc, 0x5f, 0xa9, 0x20, 0x4e, 0x0d]).toBytesLittleEndian(),
|
||||
).toEqual(new Uint8Array([0x0d, 0x4e, 0x20, 0xa9, 0x5f, 0xbc, 0x22, 0xab]));
|
||||
expect(
|
||||
Uint64.fromBytesBigEndian([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]).toBytesLittleEndian(),
|
||||
Uint64.fromBytes([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]).toBytesLittleEndian(),
|
||||
).toEqual(new Uint8Array([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]));
|
||||
});
|
||||
|
||||
it("can export strings", () => {
|
||||
{
|
||||
const a = Uint64.fromBytesBigEndian([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
|
||||
const a = Uint64.fromBytes([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]);
|
||||
const a = Uint64.fromBytes([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]);
|
||||
const a = Uint64.fromBytes([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]);
|
||||
const a = Uint64.fromBytes([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]);
|
||||
const a = Uint64.fromBytes([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]);
|
||||
const a = Uint64.fromBytes([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]);
|
||||
const a = Uint64.fromBytes([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]);
|
||||
const a = Uint64.fromBytes([0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
|
||||
expect(() => a.toNumber()).toThrowError(/number can only safely store up to 53 bits/i);
|
||||
}
|
||||
});
|
||||
|
||||
@ -14,8 +14,27 @@ interface WithByteConverters {
|
||||
readonly toBytesLittleEndian: () => Uint8Array;
|
||||
}
|
||||
|
||||
interface IntegerStatic<T> {
|
||||
readonly fromString: (str: string) => T;
|
||||
}
|
||||
|
||||
interface FixedLengthIntegerStatic<T> {
|
||||
readonly fromBytes: (bytes: ArrayLike<number>, endianess: "be" | "le") => T;
|
||||
}
|
||||
|
||||
export class Uint32 implements Integer, WithByteConverters {
|
||||
/** @deprecated use Uint32.fromBytes */
|
||||
public static fromBigEndianBytes(bytes: ArrayLike<number>): Uint32 {
|
||||
return Uint32.fromBytes(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Uint32 from a fixed length byte array.
|
||||
*
|
||||
* @param bytes a list of exactly 4 bytes
|
||||
* @param endianess defaults to big endian
|
||||
*/
|
||||
public static fromBytes(bytes: ArrayLike<number>, endianess: "be" | "le" = "be"): Uint32 {
|
||||
if (bytes.length !== 4) {
|
||||
throw new Error("Invalid input length. Expected 4 bytes.");
|
||||
}
|
||||
@ -26,9 +45,18 @@ export class Uint32 implements Integer, WithByteConverters {
|
||||
}
|
||||
}
|
||||
|
||||
const beBytes = endianess === "be" ? bytes : Array.from(bytes).reverse();
|
||||
|
||||
// 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] * 2 ** 24 + bytes[1] * 2 ** 16 + bytes[2] * 2 ** 8 + bytes[3]);
|
||||
return new Uint32(beBytes[0] * 2 ** 24 + beBytes[1] * 2 ** 16 + beBytes[2] * 2 ** 8 + beBytes[3]);
|
||||
}
|
||||
|
||||
public static fromString(str: string): Uint32 {
|
||||
if (!str.match(/^[0-9]+$/)) {
|
||||
throw new Error("Invalid string format");
|
||||
}
|
||||
return new Uint32(Number.parseInt(str, 10));
|
||||
}
|
||||
|
||||
protected readonly data: number;
|
||||
@ -142,7 +170,18 @@ export class Uint53 implements Integer {
|
||||
}
|
||||
|
||||
export class Uint64 implements Integer, WithByteConverters {
|
||||
/** @deprecated use Uint64.fromBytes */
|
||||
public static fromBytesBigEndian(bytes: ArrayLike<number>): Uint64 {
|
||||
return Uint64.fromBytes(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Uint64 from a fixed length byte array.
|
||||
*
|
||||
* @param bytes a list of exactly 8 bytes
|
||||
* @param endianess defaults to big endian
|
||||
*/
|
||||
public static fromBytes(bytes: ArrayLike<number>, endianess: "be" | "le" = "be"): Uint64 {
|
||||
if (bytes.length !== 8) {
|
||||
throw new Error("Invalid input length. Expected 8 bytes.");
|
||||
}
|
||||
@ -153,12 +192,8 @@ export class Uint64 implements Integer, WithByteConverters {
|
||||
}
|
||||
}
|
||||
|
||||
const asArray: number[] = [];
|
||||
for (let i = 0; i < bytes.length; ++i) {
|
||||
asArray.push(bytes[i]);
|
||||
}
|
||||
|
||||
return new Uint64(new BN([...asArray]));
|
||||
const beBytes = endianess === "be" ? Array.from(bytes) : Array.from(bytes).reverse();
|
||||
return new Uint64(new BN(beBytes));
|
||||
}
|
||||
|
||||
public static fromString(str: string): Uint64 {
|
||||
@ -214,3 +249,10 @@ export class Uint64 implements Integer, WithByteConverters {
|
||||
return this.data.toNumber();
|
||||
}
|
||||
}
|
||||
|
||||
// Assign classes to unused variables in order to verify static interface conformance at compile time.
|
||||
// Workaround for https://github.com/microsoft/TypeScript/issues/33892
|
||||
const _int53Class: IntegerStatic<Int53> = Int53;
|
||||
const _uint53Class: IntegerStatic<Uint53> = Uint53;
|
||||
const _uint32Class: IntegerStatic<Uint32> & FixedLengthIntegerStatic<Uint32> = Uint32;
|
||||
const _uint64Class: IntegerStatic<Uint64> & FixedLengthIntegerStatic<Uint64> = Uint64;
|
||||
|
||||
17
packages/math/types/integers.d.ts
vendored
17
packages/math/types/integers.d.ts
vendored
@ -8,7 +8,16 @@ interface WithByteConverters {
|
||||
readonly toBytesLittleEndian: () => Uint8Array;
|
||||
}
|
||||
export declare class Uint32 implements Integer, WithByteConverters {
|
||||
/** @deprecated use Uint32.fromBytes */
|
||||
static fromBigEndianBytes(bytes: ArrayLike<number>): Uint32;
|
||||
/**
|
||||
* Creates a Uint32 from a fixed length byte array.
|
||||
*
|
||||
* @param bytes a list of exactly 4 bytes
|
||||
* @param endianess defaults to big endian
|
||||
*/
|
||||
static fromBytes(bytes: ArrayLike<number>, endianess?: "be" | "le"): Uint32;
|
||||
static fromString(str: string): Uint32;
|
||||
protected readonly data: number;
|
||||
constructor(input: number);
|
||||
toBytesBigEndian(): Uint8Array;
|
||||
@ -31,7 +40,15 @@ export declare class Uint53 implements Integer {
|
||||
toString(): string;
|
||||
}
|
||||
export declare class Uint64 implements Integer, WithByteConverters {
|
||||
/** @deprecated use Uint64.fromBytes */
|
||||
static fromBytesBigEndian(bytes: ArrayLike<number>): Uint64;
|
||||
/**
|
||||
* Creates a Uint64 from a fixed length byte array.
|
||||
*
|
||||
* @param bytes a list of exactly 8 bytes
|
||||
* @param endianess defaults to big endian
|
||||
*/
|
||||
static fromBytes(bytes: ArrayLike<number>, endianess?: "be" | "le"): Uint64;
|
||||
static fromString(str: string): Uint64;
|
||||
static fromNumber(input: number): Uint64;
|
||||
private readonly data;
|
||||
|
||||
@ -111,7 +111,7 @@ export function setupIbcExtension(base: QueryClient): IbcExtension {
|
||||
// key: https://github.com/cosmos/cosmos-sdk/blob/ef0a7344af345882729598bc2958a21143930a6b/x/ibc/24-host/keys.go#L133-L136
|
||||
const key = toAscii(`seqAcks/ports/${portId}/channels/${channelId}/nextSequenceAck`);
|
||||
const responseData = await base.queryVerified("ibc", key);
|
||||
return responseData.length ? Uint64.fromBytesBigEndian(responseData).toNumber() : null;
|
||||
return responseData.length ? Uint64.fromBytes(responseData).toNumber() : null;
|
||||
},
|
||||
|
||||
unverified: {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user