@haneullabs/bcs 2.0.3 → 2.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +46 -0
- package/README.md +1 -1
- package/dist/bcs-type.d.mts +15 -50
- package/dist/bcs-type.d.mts.map +1 -1
- package/dist/bcs-type.mjs +4 -5
- package/dist/bcs-type.mjs.map +1 -1
- package/dist/bcs.d.mts +5 -6
- package/dist/bcs.d.mts.map +1 -1
- package/dist/bcs.mjs +137 -5
- package/dist/bcs.mjs.map +1 -1
- package/dist/index.mjs +1 -2
- package/dist/reader.d.mts.map +1 -1
- package/dist/reader.mjs +3 -3
- package/dist/reader.mjs.map +1 -1
- package/dist/types.d.mts +4 -5
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs +1 -1
- package/dist/uleb.d.mts.map +1 -1
- package/dist/uleb.mjs +5 -2
- package/dist/uleb.mjs.map +1 -1
- package/dist/utils.d.mts +0 -1
- package/dist/utils.d.mts.map +1 -1
- package/dist/utils.mjs +1 -2
- package/dist/utils.mjs.map +1 -1
- package/dist/writer.d.mts +1 -6
- package/dist/writer.d.mts.map +1 -1
- package/dist/writer.mjs +1 -2
- package/dist/writer.mjs.map +1 -1
- package/docs/index.md +11 -5
- package/docs/llms-index.md +1 -3
- package/package.json +10 -10
- package/src/bcs.ts +9 -2
- package/src/uleb.ts +4 -0
package/dist/writer.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"writer.mjs","names":[],"sources":["../src/writer.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { Encoding } from './types.js';\nimport { ulebEncode } from './uleb.js';\nimport { encodeStr } from './utils.js';\n\nexport interface BcsWriterOptions {\n\t/** The initial size (in bytes) of the buffer tht will be allocated */\n\tinitialSize?: number;\n\t/** The maximum size (in bytes) that the buffer is allowed to grow to */\n\tmaxSize?: number;\n\t/** The amount of bytes that will be allocated whenever additional memory is required */\n\tallocateSize?: number;\n}\n\n/**\n * Class used to write BCS data into a buffer. Initializer requires\n * some size of a buffer to init; default value for this buffer is 1KB.\n *\n * Most methods are chainable, so it is possible to write them in one go.\n *\n * @example\n * let serialized = new BcsWriter()\n * .write8(10)\n * .write32(1000000)\n * .write64(10000001000000)\n * .hex();\n */\n\n/**\n * Set of methods that allows data encoding/decoding as standalone\n * BCS value or a part of a composed structure/vector.\n */\nexport class BcsWriter {\n\tprivate dataView: DataView<ArrayBuffer>;\n\tprivate bytePosition: number = 0;\n\tprivate size: number;\n\tprivate maxSize: number;\n\tprivate allocateSize: number;\n\n\tconstructor({\n\t\tinitialSize = 1024,\n\t\tmaxSize = Infinity,\n\t\tallocateSize = 1024,\n\t}: BcsWriterOptions = {}) {\n\t\tthis.size = initialSize;\n\t\tthis.maxSize = maxSize;\n\t\tthis.allocateSize = allocateSize;\n\t\tthis.dataView = new DataView(new ArrayBuffer(initialSize));\n\t}\n\n\tprivate ensureSizeOrGrow(bytes: number) {\n\t\tconst requiredSize = this.bytePosition + bytes;\n\t\tif (requiredSize > this.size) {\n\t\t\tconst nextSize = Math.min(\n\t\t\t\tthis.maxSize,\n\t\t\t\tMath.max(this.size + requiredSize, this.size + this.allocateSize),\n\t\t\t);\n\t\t\tif (requiredSize > nextSize) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Attempting to serialize to BCS, but buffer does not have enough size. Allocated size: ${this.size}, Max size: ${this.maxSize}, Required size: ${requiredSize}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tthis.size = nextSize;\n\t\t\tconst nextBuffer = new ArrayBuffer(this.size);\n\t\t\tnew Uint8Array(nextBuffer).set(new Uint8Array(this.dataView.buffer));\n\t\t\tthis.dataView = new DataView(nextBuffer);\n\t\t}\n\t}\n\n\t/**\n\t * Shift current cursor position by `bytes`.\n\t *\n\t * @param {Number} bytes Number of bytes to\n\t * @returns {this} Self for possible chaining.\n\t */\n\tshift(bytes: number): this {\n\t\tthis.bytePosition += bytes;\n\t\treturn this;\n\t}\n\t/**\n\t * Write a U8 value into a buffer and shift cursor position by 1.\n\t * @param {Number} value Value to write.\n\t * @returns {this}\n\t */\n\twrite8(value: number | bigint): this {\n\t\tthis.ensureSizeOrGrow(1);\n\t\tthis.dataView.setUint8(this.bytePosition, Number(value));\n\t\treturn this.shift(1);\n\t}\n\n\t/**\n\t * Write a U8 value into a buffer and shift cursor position by 1.\n\t * @param {Number} value Value to write.\n\t * @returns {this}\n\t */\n\twriteBytes(bytes: Uint8Array): this {\n\t\tthis.ensureSizeOrGrow(bytes.length);\n\n\t\tfor (let i = 0; i < bytes.length; i++) {\n\t\t\tthis.dataView.setUint8(this.bytePosition + i, bytes[i]);\n\t\t}\n\n\t\treturn this.shift(bytes.length);\n\t}\n\t/**\n\t * Write a U16 value into a buffer and shift cursor position by 2.\n\t * @param {Number} value Value to write.\n\t * @returns {this}\n\t */\n\twrite16(value: number | bigint): this {\n\t\tthis.ensureSizeOrGrow(2);\n\t\tthis.dataView.setUint16(this.bytePosition, Number(value), true);\n\t\treturn this.shift(2);\n\t}\n\t/**\n\t * Write a U32 value into a buffer and shift cursor position by 4.\n\t * @param {Number} value Value to write.\n\t * @returns {this}\n\t */\n\twrite32(value: number | bigint): this {\n\t\tthis.ensureSizeOrGrow(4);\n\t\tthis.dataView.setUint32(this.bytePosition, Number(value), true);\n\t\treturn this.shift(4);\n\t}\n\t/**\n\t * Write a U64 value into a buffer and shift cursor position by 8.\n\t * @param {bigint} value Value to write.\n\t * @returns {this}\n\t */\n\twrite64(value: number | bigint): this {\n\t\ttoLittleEndian(BigInt(value), 8).forEach((el) => this.write8(el));\n\n\t\treturn this;\n\t}\n\t/**\n\t * Write a U128 value into a buffer and shift cursor position by 16.\n\t *\n\t * @param {bigint} value Value to write.\n\t * @returns {this}\n\t */\n\twrite128(value: number | bigint): this {\n\t\ttoLittleEndian(BigInt(value), 16).forEach((el) => this.write8(el));\n\n\t\treturn this;\n\t}\n\t/**\n\t * Write a U256 value into a buffer and shift cursor position by 16.\n\t *\n\t * @param {bigint} value Value to write.\n\t * @returns {this}\n\t */\n\twrite256(value: number | bigint): this {\n\t\ttoLittleEndian(BigInt(value), 32).forEach((el) => this.write8(el));\n\n\t\treturn this;\n\t}\n\t/**\n\t * Write a ULEB value into a buffer and shift cursor position by number of bytes\n\t * written.\n\t * @param {Number} value Value to write.\n\t * @returns {this}\n\t */\n\twriteULEB(value: number): this {\n\t\tulebEncode(value).forEach((el) => this.write8(el));\n\t\treturn this;\n\t}\n\t/**\n\t * Write a vector into a buffer by first writing the vector length and then calling\n\t * a callback on each passed value.\n\t *\n\t * @param {Array<Any>} vector Array of elements to write.\n\t * @param {WriteVecCb} cb Callback to call on each element of the vector.\n\t * @returns {this}\n\t */\n\twriteVec(vector: any[], cb: (writer: BcsWriter, el: any, i: number, len: number) => void): this {\n\t\tthis.writeULEB(vector.length);\n\t\tArray.from(vector).forEach((el, i) => cb(this, el, i, vector.length));\n\t\treturn this;\n\t}\n\n\t/**\n\t * Adds support for iterations over the object.\n\t * @returns {Uint8Array}\n\t */\n\t// oxlint-disable-next-line require-yields\n\t*[Symbol.iterator](): Iterator<number, Iterable<number>> {\n\t\tfor (let i = 0; i < this.bytePosition; i++) {\n\t\t\tyield this.dataView.getUint8(i);\n\t\t}\n\t\treturn this.toBytes();\n\t}\n\n\t/**\n\t * Get underlying buffer taking only value bytes (in case initial buffer size was bigger).\n\t * @returns {Uint8Array} Resulting bcs.\n\t */\n\ttoBytes(): Uint8Array<ArrayBuffer> {\n\t\treturn new Uint8Array(this.dataView.buffer.slice(0, this.bytePosition));\n\t}\n\n\t/**\n\t * Represent data as 'hex' or 'base64'\n\t * @param encoding Encoding to use: 'base64' or 'hex'\n\t */\n\ttoString(encoding: Encoding): string {\n\t\treturn encodeStr(this.toBytes(), encoding);\n\t}\n}\n\nfunction toLittleEndian(bigint: bigint, size: number) {\n\tconst result = new Uint8Array(size);\n\tlet i = 0;\n\twhile (bigint > 0) {\n\t\tresult[i] = Number(bigint % BigInt(256));\n\t\tbigint = bigint / BigInt(256);\n\t\ti += 1;\n\t}\n\treturn result;\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"writer.mjs","names":[],"sources":["../src/writer.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { Encoding } from './types.js';\nimport { ulebEncode } from './uleb.js';\nimport { encodeStr } from './utils.js';\n\nexport interface BcsWriterOptions {\n\t/** The initial size (in bytes) of the buffer tht will be allocated */\n\tinitialSize?: number;\n\t/** The maximum size (in bytes) that the buffer is allowed to grow to */\n\tmaxSize?: number;\n\t/** The amount of bytes that will be allocated whenever additional memory is required */\n\tallocateSize?: number;\n}\n\n/**\n * Class used to write BCS data into a buffer. Initializer requires\n * some size of a buffer to init; default value for this buffer is 1KB.\n *\n * Most methods are chainable, so it is possible to write them in one go.\n *\n * @example\n * let serialized = new BcsWriter()\n * .write8(10)\n * .write32(1000000)\n * .write64(10000001000000)\n * .hex();\n */\n\n/**\n * Set of methods that allows data encoding/decoding as standalone\n * BCS value or a part of a composed structure/vector.\n */\nexport class BcsWriter {\n\tprivate dataView: DataView<ArrayBuffer>;\n\tprivate bytePosition: number = 0;\n\tprivate size: number;\n\tprivate maxSize: number;\n\tprivate allocateSize: number;\n\n\tconstructor({\n\t\tinitialSize = 1024,\n\t\tmaxSize = Infinity,\n\t\tallocateSize = 1024,\n\t}: BcsWriterOptions = {}) {\n\t\tthis.size = initialSize;\n\t\tthis.maxSize = maxSize;\n\t\tthis.allocateSize = allocateSize;\n\t\tthis.dataView = new DataView(new ArrayBuffer(initialSize));\n\t}\n\n\tprivate ensureSizeOrGrow(bytes: number) {\n\t\tconst requiredSize = this.bytePosition + bytes;\n\t\tif (requiredSize > this.size) {\n\t\t\tconst nextSize = Math.min(\n\t\t\t\tthis.maxSize,\n\t\t\t\tMath.max(this.size + requiredSize, this.size + this.allocateSize),\n\t\t\t);\n\t\t\tif (requiredSize > nextSize) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Attempting to serialize to BCS, but buffer does not have enough size. Allocated size: ${this.size}, Max size: ${this.maxSize}, Required size: ${requiredSize}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tthis.size = nextSize;\n\t\t\tconst nextBuffer = new ArrayBuffer(this.size);\n\t\t\tnew Uint8Array(nextBuffer).set(new Uint8Array(this.dataView.buffer));\n\t\t\tthis.dataView = new DataView(nextBuffer);\n\t\t}\n\t}\n\n\t/**\n\t * Shift current cursor position by `bytes`.\n\t *\n\t * @param {Number} bytes Number of bytes to\n\t * @returns {this} Self for possible chaining.\n\t */\n\tshift(bytes: number): this {\n\t\tthis.bytePosition += bytes;\n\t\treturn this;\n\t}\n\t/**\n\t * Write a U8 value into a buffer and shift cursor position by 1.\n\t * @param {Number} value Value to write.\n\t * @returns {this}\n\t */\n\twrite8(value: number | bigint): this {\n\t\tthis.ensureSizeOrGrow(1);\n\t\tthis.dataView.setUint8(this.bytePosition, Number(value));\n\t\treturn this.shift(1);\n\t}\n\n\t/**\n\t * Write a U8 value into a buffer and shift cursor position by 1.\n\t * @param {Number} value Value to write.\n\t * @returns {this}\n\t */\n\twriteBytes(bytes: Uint8Array): this {\n\t\tthis.ensureSizeOrGrow(bytes.length);\n\n\t\tfor (let i = 0; i < bytes.length; i++) {\n\t\t\tthis.dataView.setUint8(this.bytePosition + i, bytes[i]);\n\t\t}\n\n\t\treturn this.shift(bytes.length);\n\t}\n\t/**\n\t * Write a U16 value into a buffer and shift cursor position by 2.\n\t * @param {Number} value Value to write.\n\t * @returns {this}\n\t */\n\twrite16(value: number | bigint): this {\n\t\tthis.ensureSizeOrGrow(2);\n\t\tthis.dataView.setUint16(this.bytePosition, Number(value), true);\n\t\treturn this.shift(2);\n\t}\n\t/**\n\t * Write a U32 value into a buffer and shift cursor position by 4.\n\t * @param {Number} value Value to write.\n\t * @returns {this}\n\t */\n\twrite32(value: number | bigint): this {\n\t\tthis.ensureSizeOrGrow(4);\n\t\tthis.dataView.setUint32(this.bytePosition, Number(value), true);\n\t\treturn this.shift(4);\n\t}\n\t/**\n\t * Write a U64 value into a buffer and shift cursor position by 8.\n\t * @param {bigint} value Value to write.\n\t * @returns {this}\n\t */\n\twrite64(value: number | bigint): this {\n\t\ttoLittleEndian(BigInt(value), 8).forEach((el) => this.write8(el));\n\n\t\treturn this;\n\t}\n\t/**\n\t * Write a U128 value into a buffer and shift cursor position by 16.\n\t *\n\t * @param {bigint} value Value to write.\n\t * @returns {this}\n\t */\n\twrite128(value: number | bigint): this {\n\t\ttoLittleEndian(BigInt(value), 16).forEach((el) => this.write8(el));\n\n\t\treturn this;\n\t}\n\t/**\n\t * Write a U256 value into a buffer and shift cursor position by 16.\n\t *\n\t * @param {bigint} value Value to write.\n\t * @returns {this}\n\t */\n\twrite256(value: number | bigint): this {\n\t\ttoLittleEndian(BigInt(value), 32).forEach((el) => this.write8(el));\n\n\t\treturn this;\n\t}\n\t/**\n\t * Write a ULEB value into a buffer and shift cursor position by number of bytes\n\t * written.\n\t * @param {Number} value Value to write.\n\t * @returns {this}\n\t */\n\twriteULEB(value: number): this {\n\t\tulebEncode(value).forEach((el) => this.write8(el));\n\t\treturn this;\n\t}\n\t/**\n\t * Write a vector into a buffer by first writing the vector length and then calling\n\t * a callback on each passed value.\n\t *\n\t * @param {Array<Any>} vector Array of elements to write.\n\t * @param {WriteVecCb} cb Callback to call on each element of the vector.\n\t * @returns {this}\n\t */\n\twriteVec(vector: any[], cb: (writer: BcsWriter, el: any, i: number, len: number) => void): this {\n\t\tthis.writeULEB(vector.length);\n\t\tArray.from(vector).forEach((el, i) => cb(this, el, i, vector.length));\n\t\treturn this;\n\t}\n\n\t/**\n\t * Adds support for iterations over the object.\n\t * @returns {Uint8Array}\n\t */\n\t// oxlint-disable-next-line require-yields\n\t*[Symbol.iterator](): Iterator<number, Iterable<number>> {\n\t\tfor (let i = 0; i < this.bytePosition; i++) {\n\t\t\tyield this.dataView.getUint8(i);\n\t\t}\n\t\treturn this.toBytes();\n\t}\n\n\t/**\n\t * Get underlying buffer taking only value bytes (in case initial buffer size was bigger).\n\t * @returns {Uint8Array} Resulting bcs.\n\t */\n\ttoBytes(): Uint8Array<ArrayBuffer> {\n\t\treturn new Uint8Array(this.dataView.buffer.slice(0, this.bytePosition));\n\t}\n\n\t/**\n\t * Represent data as 'hex' or 'base64'\n\t * @param encoding Encoding to use: 'base64' or 'hex'\n\t */\n\ttoString(encoding: Encoding): string {\n\t\treturn encodeStr(this.toBytes(), encoding);\n\t}\n}\n\nfunction toLittleEndian(bigint: bigint, size: number) {\n\tconst result = new Uint8Array(size);\n\tlet i = 0;\n\twhile (bigint > 0) {\n\t\tresult[i] = Number(bigint % BigInt(256));\n\t\tbigint = bigint / BigInt(256);\n\t\ti += 1;\n\t}\n\treturn result;\n}\n"],"mappings":"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"}
|
package/docs/index.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# BCS - Binary Canonical Serialization
|
|
2
2
|
|
|
3
|
-
> Encode and decode Haneul Move types with Binary Canonical Serialization
|
|
3
|
+
> Encode and decode Haneul Move types with Binary Canonical Serialization.
|
|
4
4
|
|
|
5
5
|
This small and lightweight library implements
|
|
6
6
|
[Binary Canonical Serialization (BCS)](https://github.com/zefchain/bcs) in TypeScript, making BCS
|
|
@@ -8,16 +8,17 @@ available in both Browser and NodeJS environments in a type-safe way.`
|
|
|
8
8
|
|
|
9
9
|
## Install
|
|
10
10
|
|
|
11
|
-
To install, add the [`@haneullabs/bcs`](https://www.npmjs.com/package/@haneullabs/bcs) package to
|
|
12
|
-
|
|
11
|
+
To install, add the [`@haneullabs/bcs`](https://www.npmjs.com/package/@haneullabs/bcs) package to your
|
|
12
|
+
project:
|
|
13
13
|
|
|
14
|
-
```
|
|
14
|
+
```npm
|
|
15
15
|
npm i @haneullabs/bcs
|
|
16
16
|
```
|
|
17
17
|
|
|
18
18
|
## Quickstart
|
|
19
19
|
|
|
20
20
|
```ts
|
|
21
|
+
|
|
21
22
|
// define UID as a 32-byte array, then add a transform to/from hex strings
|
|
22
23
|
const UID = bcs.fixedArray(32, bcs.u8()).transform({
|
|
23
24
|
input: (id: string) => fromHex(id),
|
|
@@ -70,6 +71,7 @@ following table lists the primitive types available:
|
|
|
70
71
|
| `byteVector` | `Uint8Array` | `Iterable<number>` | Variable length bytes |
|
|
71
72
|
|
|
72
73
|
```ts
|
|
74
|
+
|
|
73
75
|
// Integers
|
|
74
76
|
const u8 = bcs.u8().serialize(100).toBytes();
|
|
75
77
|
const u64 = bcs.u64().serialize(1000000n).toBytes();
|
|
@@ -111,6 +113,7 @@ For most use-cases you'll want to combine primitive types into more complex type
|
|
|
111
113
|
| `map(K, V)` | A map of keys of type `K` to values of type `V` |
|
|
112
114
|
|
|
113
115
|
```ts
|
|
116
|
+
|
|
114
117
|
// Vectors
|
|
115
118
|
const intList = bcs.vector(bcs.u8()).serialize([1, 2, 3, 4, 5]).toBytes();
|
|
116
119
|
const stringList = bcs.vector(bcs.string()).serialize(['a', 'b', 'c']).toBytes();
|
|
@@ -242,6 +245,7 @@ represent an address as a hex string, but the BCS serialization format for addre
|
|
|
242
245
|
array. To handle this, you can use the `transform` API to map between the two formats:
|
|
243
246
|
|
|
244
247
|
```ts
|
|
248
|
+
|
|
245
249
|
const Address = bcs.bytes(32).transform({
|
|
246
250
|
// To change the input type, you need to provide a type definition for the input
|
|
247
251
|
input: (val: string) => fromHex(val),
|
|
@@ -306,6 +310,7 @@ preserves type information for the serialized bytes, and can be used to get raw
|
|
|
306
310
|
formats.
|
|
307
311
|
|
|
308
312
|
```ts
|
|
313
|
+
|
|
309
314
|
const serializedString = bcs.string().serialize('this is a string');
|
|
310
315
|
|
|
311
316
|
// SerializedBcs.toBytes() returns a Uint8Array
|
|
@@ -337,6 +342,7 @@ You can infer these types in one of 2 ways, either using the `$inferType` and `$
|
|
|
337
342
|
properties on a `BcsType`, or using the `InferBcsType` and `InferBcsInput` type helpers.
|
|
338
343
|
|
|
339
344
|
```ts
|
|
345
|
+
|
|
340
346
|
const MyStruct = bcs.struct('MyStruct', {
|
|
341
347
|
id: bcs.u64(),
|
|
342
348
|
name: bcs.string(),
|
|
@@ -349,4 +355,4 @@ type MyStructInput = typeof MyStruct.$inferInput; // { id: number | string | big
|
|
|
349
355
|
// using the InferBcsType and InferBcsInput type helpers
|
|
350
356
|
type MyStructType = InferBcsType<typeof MyStruct>; // { id: string; name: string; }
|
|
351
357
|
type MyStructInput = InferBcsInput<typeof MyStruct>; // { id: number | string | bigint; name: string; }
|
|
352
|
-
```
|
|
358
|
+
```
|
package/docs/llms-index.md
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
# BCS
|
|
2
|
-
|
|
3
2
|
> Encoding and decoding Haneul objects
|
|
4
3
|
|
|
5
|
-
- [BCS - Binary Canonical Serialization](
|
|
6
|
-
Binary Canonical Serialization
|
|
4
|
+
- [BCS - Binary Canonical Serialization](..md): Encode and decode Haneul Move types with Binary Canonical Serialization.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@haneullabs/bcs",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.2",
|
|
4
4
|
"description": "BCS - Canonical Binary Serialization implementation for JavaScript",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Haneul Labs <build@haneul-labs.com>",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
],
|
|
24
24
|
"repository": {
|
|
25
25
|
"type": "git",
|
|
26
|
-
"url": "git+https://github.com/GeunhwaJeong/ts-sdks.git"
|
|
26
|
+
"url": "git+https://github.com/GeunhwaJeong/haneul-ts-sdks.git"
|
|
27
27
|
},
|
|
28
28
|
"keywords": [
|
|
29
29
|
"bcs",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"serde"
|
|
35
35
|
],
|
|
36
36
|
"bugs": {
|
|
37
|
-
"url": "https://github.com/GeunhwaJeong/ts-sdks/issues"
|
|
37
|
+
"url": "https://github.com/GeunhwaJeong/haneul-ts-sdks/issues"
|
|
38
38
|
},
|
|
39
39
|
"size-limit": [
|
|
40
40
|
{
|
|
@@ -44,19 +44,19 @@
|
|
|
44
44
|
],
|
|
45
45
|
"homepage": "https://sdk.haneul-labs.com/bcs",
|
|
46
46
|
"devDependencies": {
|
|
47
|
-
"@size-limit/preset-small-lib": "^
|
|
48
|
-
"size-limit": "^
|
|
49
|
-
"typescript": "^
|
|
50
|
-
"vitest": "^4.
|
|
47
|
+
"@size-limit/preset-small-lib": "^13.0.3",
|
|
48
|
+
"size-limit": "^13.0.3",
|
|
49
|
+
"typescript": "^7.0.2",
|
|
50
|
+
"vitest": "^4.1.11"
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
|
-
"@scure/base": "^2.
|
|
54
|
-
"@haneullabs/utils": "^0.
|
|
53
|
+
"@scure/base": "^2.3.0",
|
|
54
|
+
"@haneullabs/utils": "^0.4.1"
|
|
55
55
|
},
|
|
56
56
|
"scripts": {
|
|
57
57
|
"clean": "rm -rf tsconfig.tsbuildinfo ./dist",
|
|
58
58
|
"build": "rm -rf dist && tsc --noEmit && tsdown",
|
|
59
|
-
"build:docs": "
|
|
59
|
+
"build:docs": "node ../docs/scripts/build-docs.ts",
|
|
60
60
|
"test": "vitest run --typecheck",
|
|
61
61
|
"test:watch": "vitest --typecheck",
|
|
62
62
|
"prettier:check": "prettier -c --ignore-unknown .",
|
package/src/bcs.ts
CHANGED
|
@@ -316,7 +316,13 @@ export const bcs = {
|
|
|
316
316
|
bool(options?: BcsTypeOptions<boolean>) {
|
|
317
317
|
return fixedSizeBcsType({
|
|
318
318
|
size: 1,
|
|
319
|
-
read: (reader) =>
|
|
319
|
+
read: (reader) => {
|
|
320
|
+
const value = reader.read8();
|
|
321
|
+
if (value > 1) {
|
|
322
|
+
throw new TypeError(`Invalid bool value: expected 0 or 1, found ${value}`);
|
|
323
|
+
}
|
|
324
|
+
return value === 1;
|
|
325
|
+
},
|
|
320
326
|
write: (value, writer) => writer.write8(value ? 1 : 0),
|
|
321
327
|
...options,
|
|
322
328
|
name: (options?.name ?? 'bool') as 'bool',
|
|
@@ -413,7 +419,8 @@ export const bcs = {
|
|
|
413
419
|
string(options?: BcsTypeOptions<string>) {
|
|
414
420
|
return stringLikeBcsType({
|
|
415
421
|
toBytes: (value) => new TextEncoder().encode(value),
|
|
416
|
-
fromBytes: (bytes) =>
|
|
422
|
+
fromBytes: (bytes) =>
|
|
423
|
+
new TextDecoder('utf-8', { fatal: true, ignoreBOM: true }).decode(bytes),
|
|
417
424
|
...options,
|
|
418
425
|
name: (options?.name ?? 'string') as 'string',
|
|
419
426
|
});
|
package/src/uleb.ts
CHANGED
|
@@ -43,6 +43,10 @@ export function ulebDecode(arr: number[] | Uint8Array): {
|
|
|
43
43
|
len += 1;
|
|
44
44
|
total += BigInt(byte & 0x7f) << shift;
|
|
45
45
|
if ((byte & 0x80) === 0) {
|
|
46
|
+
// A trailing zero group adds no value, so the encoding is not minimal
|
|
47
|
+
if (byte === 0 && len > 1) {
|
|
48
|
+
throw new Error('ULEB decode error: non-canonical encoding');
|
|
49
|
+
}
|
|
46
50
|
break;
|
|
47
51
|
}
|
|
48
52
|
shift += 7n;
|