@ckb-lumos/codec
Advanced tools
Comparing version 0.0.0-canary-a49c050-20230723075710 to 0.0.0-canary-ad0f66d-20240701081046
@@ -14,3 +14,3 @@ export interface Codec<Packed, Unpacked, Packable = Unpacked, Unpackable = Packed> { | ||
/** | ||
* This function helps to create a codec that can | ||
* Create a codec to deal with bytes-like data. | ||
* @param codec | ||
@@ -17,0 +17,0 @@ */ |
@@ -14,3 +14,3 @@ "use strict"; | ||
/** | ||
* This function helps to create a codec that can | ||
* Create a codec to deal with bytes-like data. | ||
* @param codec | ||
@@ -17,0 +17,0 @@ */ |
@@ -12,6 +12,6 @@ import { AnyCodec, BytesCodec, BytesLike, FixedBytesCodec, PackParam, UnpackResult } from "./base"; | ||
export declare const Bytes: BytesCodec<string, BytesLike>; | ||
export declare const BytesOpt: import("./molecule/layout").OptionCodec<BytesCodec<string, BytesLike>>; | ||
export declare const BytesVec: import("./molecule/layout").ArrayCodec<BytesCodec<string, BytesLike>>; | ||
export declare const BytesOpt: import("./molecule").OptionLayoutCodec<BytesCodec<string, BytesLike>>; | ||
export declare const BytesVec: import("./molecule").ArrayLayoutCodec<BytesCodec<string, BytesLike>>; | ||
export declare const Byte32: FixedBytesCodec<string, BytesLike>; | ||
export declare const Byte32Vec: import("./molecule/layout").ArrayCodec<FixedBytesCodec<string, BytesLike>>; | ||
export declare const Byte32Vec: import("./molecule").ArrayLayoutCodec<FixedBytesCodec<string, BytesLike>>; | ||
export declare function WitnessArgsOf<LockCodec extends AnyCodec, InputTypeCodec extends AnyCodec, OutputTypeCodec extends AnyCodec>(payload: { | ||
@@ -18,0 +18,0 @@ lock: LockCodec; |
@@ -31,15 +31,10 @@ "use strict"; | ||
// vector Bytes <byte> | ||
const Bytes = (0, _molecule.byteVecOf)({ | ||
const Bytes = exports.Bytes = (0, _molecule.byteVecOf)({ | ||
pack: _bytes.bytify, | ||
unpack: _bytes.hexify | ||
}); | ||
exports.Bytes = Bytes; | ||
const BytesOpt = (0, _molecule.option)(Bytes); | ||
exports.BytesOpt = BytesOpt; | ||
const BytesVec = (0, _molecule.vector)(Bytes); | ||
exports.BytesVec = BytesVec; | ||
const Byte32 = createFixedHexBytesCodec(32); | ||
exports.Byte32 = Byte32; | ||
const Byte32Vec = (0, _molecule.vector)(Byte32); | ||
exports.Byte32Vec = Byte32Vec; | ||
const BytesOpt = exports.BytesOpt = (0, _molecule.option)(Bytes); | ||
const BytesVec = exports.BytesVec = (0, _molecule.vector)(Bytes); | ||
const Byte32 = exports.Byte32 = createFixedHexBytesCodec(32); | ||
const Byte32Vec = exports.Byte32Vec = (0, _molecule.vector)(Byte32); | ||
function WitnessArgsOf(payload) { | ||
@@ -65,3 +60,3 @@ return (0, _molecule.table)({ | ||
*/ | ||
const WitnessArgs = WitnessArgsOf({ | ||
const WitnessArgs = exports.WitnessArgs = WitnessArgsOf({ | ||
lock: HexifyCodec, | ||
@@ -71,3 +66,2 @@ input_type: HexifyCodec, | ||
}); | ||
exports.WitnessArgs = WitnessArgs; | ||
//# sourceMappingURL=blockchain.js.map |
@@ -22,15 +22,32 @@ "use strict"; | ||
} | ||
const CHAR_0 = "0".charCodeAt(0); // 48 | ||
const CHAR_9 = "9".charCodeAt(0); // 57 | ||
const CHAR_A = "A".charCodeAt(0); // 65 | ||
const CHAR_F = "F".charCodeAt(0); // 70 | ||
const CHAR_a = "a".charCodeAt(0); // 97 | ||
// const CHAR_f = "f".charCodeAt(0); // 102 | ||
function bytifyHex(hex) { | ||
(0, _utils.assertHexString)(hex); | ||
hex = hex.slice(2); | ||
const uint8s = []; | ||
for (let i = 0; i < hex.length; i += 2) { | ||
uint8s.push(parseInt(hex.substr(i, 2), 16)); | ||
const u8a = Uint8Array.from({ | ||
length: hex.length / 2 - 1 | ||
}); | ||
for (let i = 2, j = 0; i < hex.length; i = i + 2, j++) { | ||
const c1 = hex.charCodeAt(i); | ||
const c2 = hex.charCodeAt(i + 1); | ||
// prettier-ignore | ||
const n1 = c1 <= CHAR_9 ? c1 - CHAR_0 : c1 <= CHAR_F ? c1 - CHAR_A + 10 : c1 - CHAR_a + 10; | ||
// prettier-ignore | ||
const n2 = c2 <= CHAR_9 ? c2 - CHAR_0 : c2 <= CHAR_F ? c2 - CHAR_A + 10 : c2 - CHAR_a + 10; | ||
u8a[j] = n1 << 4 | n2; | ||
} | ||
return Uint8Array.from(uint8s); | ||
return u8a; | ||
} | ||
function bytifyArrayLike(xs) { | ||
const isValidU8Vec = Array.from(xs).every(v => v >= 0 && v <= 255); | ||
if (!isValidU8Vec) { | ||
throw new Error("invalid ArrayLike, all elements must be 0-255"); | ||
for (let i = 0; i < xs.length; i++) { | ||
const v = xs[i]; | ||
if (v < 0 || v > 255 || !Number.isInteger(v)) { | ||
throw new Error("invalid ArrayLike, all elements must be 0-255"); | ||
} | ||
} | ||
@@ -63,2 +80,5 @@ return Uint8Array.from(xs); | ||
} | ||
const HEX_CACHE = Array.from({ | ||
length: 256 | ||
}).map((_, i) => i.toString(16).padStart(2, "0")); | ||
/** | ||
@@ -72,3 +92,7 @@ * convert a {@link BytesLike} to an even length hex string prefixed with "0x" | ||
function hexify(buf) { | ||
const hex = Array.from(bytify(buf)).map(b => b.toString(16).padStart(2, "0")).join(""); | ||
let hex = ""; | ||
const u8a = bytify(buf); | ||
for (let i = 0; i < u8a.length; i++) { | ||
hex += HEX_CACHE[u8a[i]]; | ||
} | ||
return "0x" + hex; | ||
@@ -75,0 +99,0 @@ } |
@@ -8,8 +8,4 @@ "use strict"; | ||
exports.isCodecExecuteError = isCodecExecuteError; | ||
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } | ||
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); } | ||
function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } | ||
// lc for lumos codec | ||
const CODEC_OPTIONAL_PATH = "__lc_option__"; | ||
exports.CODEC_OPTIONAL_PATH = CODEC_OPTIONAL_PATH; | ||
const CODEC_OPTIONAL_PATH = exports.CODEC_OPTIONAL_PATH = "__lc_option__"; | ||
class CodecBaseParseError extends Error { | ||
@@ -32,8 +28,8 @@ constructor(message, expectedType) { | ||
class CodecExecuteError extends Error { | ||
name = CODEC_EXECUTE_ERROR_NAME; | ||
constructor(origin) { | ||
super(); | ||
_defineProperty(this, "name", CODEC_EXECUTE_ERROR_NAME); | ||
_defineProperty(this, "keys", []); | ||
this.origin = origin; | ||
} | ||
keys = []; | ||
updateKey(key) { | ||
@@ -56,3 +52,5 @@ this.keys.push(key); | ||
const path = this.keys.reduceRight(reducer, "input"); | ||
return `Expect type ${this.origin.expectedType} at ${path} but got error: ${this.origin.message} | ||
const text = this.origin instanceof CodecBaseParseError ? `Expect type ${this.origin.expectedType} at ${path} but got error:` : `Error at ${path}:`; // this.origin can be an Error at runtime | ||
return `${text} ${this.origin.message} | ||
${(_this$origin$stack = this.origin.stack) === null || _this$origin$stack === void 0 ? void 0 : _this$origin$stack.replace(/Error:.+?\n/, "")} | ||
@@ -59,0 +57,0 @@ `; |
@@ -53,4 +53,4 @@ "use strict"; | ||
exports.molecule = _molecule; | ||
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } | ||
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } | ||
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } | ||
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } | ||
//# sourceMappingURL=index.js.map |
export { byteOf, byteArrayOf, byteVecOf } from "./helper"; | ||
export { table, array, option, struct, vector, union } from "./layout"; | ||
export type { ObjectLayoutCodec, ArrayLayoutCodec, OptionLayoutCodec, UnionLayoutCodec, } from "./layout"; | ||
//# sourceMappingURL=index.d.ts.map |
@@ -20,3 +20,6 @@ /** | ||
type PartialNullable<O extends Record<string, unknown>> = Partial<Pick<O, NullableKeys<O>>> & Pick<O, NonNullableKeys<O>>; | ||
export type ObjectCodec<T extends Record<string, BytesCodec>> = BytesCodec<PartialNullable<{ | ||
/** | ||
* A codec for struct and table of Molecule | ||
*/ | ||
export type ObjectLayoutCodec<T extends Record<string, BytesCodec>> = BytesCodec<PartialNullable<{ | ||
[key in keyof T]: UnpackResult<T[key]>; | ||
@@ -26,7 +29,16 @@ }>, PartialNullable<{ | ||
}>>; | ||
export interface OptionCodec<T extends BytesCodec> extends BytesCodec<UnpackResult<T> | undefined> { | ||
/** | ||
* A codec for option of Molecule | ||
*/ | ||
export interface OptionLayoutCodec<T extends BytesCodec> extends BytesCodec<UnpackResult<T> | undefined> { | ||
pack: (packable?: PackParam<T>) => Uint8Array; | ||
} | ||
export type ArrayCodec<T extends BytesCodec> = BytesCodec<Array<UnpackResult<T>>, Array<PackParam<T>>>; | ||
export type UnionCodec<T extends Record<string, BytesCodec>> = BytesCodec<{ | ||
/** | ||
* A code for array and vector of Molecule | ||
*/ | ||
export type ArrayLayoutCodec<T extends BytesCodec> = BytesCodec<Array<UnpackResult<T>>, Array<PackParam<T>>>; | ||
/** | ||
* A molecule codec for ` | ||
*/ | ||
export type UnionLayoutCodec<T extends Record<string, BytesCodec>> = BytesCodec<{ | ||
[key in keyof T]: { | ||
@@ -48,3 +60,3 @@ type: key; | ||
*/ | ||
export declare function array<T extends FixedBytesCodec>(itemCodec: T, itemCount: number): ArrayCodec<T> & Fixed; | ||
export declare function array<T extends FixedBytesCodec>(itemCodec: T, itemCount: number): ArrayLayoutCodec<T> & Fixed; | ||
/** | ||
@@ -56,3 +68,3 @@ * Struct is a fixed-size type: all fields in struct are fixed-size and it has a fixed quantity of fields. | ||
*/ | ||
export declare function struct<T extends Record<string, FixedBytesCodec>>(shape: T, fields: (keyof T)[]): ObjectCodec<T> & Fixed; | ||
export declare function struct<T extends Record<string, FixedBytesCodec>>(shape: T, fields: (keyof T)[]): ObjectLayoutCodec<T> & Fixed; | ||
/** | ||
@@ -62,3 +74,3 @@ * Vector with fixed size item codec | ||
*/ | ||
export declare function fixvec<T extends FixedBytesCodec>(itemCodec: T): ArrayCodec<T>; | ||
export declare function fixvec<T extends FixedBytesCodec>(itemCodec: T): ArrayLayoutCodec<T>; | ||
/** | ||
@@ -69,3 +81,3 @@ * Vector with dynamic size item codec | ||
*/ | ||
export declare function dynvec<T extends BytesCodec>(itemCodec: T): ArrayCodec<T>; | ||
export declare function dynvec<T extends BytesCodec>(itemCodec: T): ArrayLayoutCodec<T>; | ||
/** | ||
@@ -75,3 +87,3 @@ * General vector codec, if `itemCodec` is fixed size type, it will create a fixvec codec, otherwise a dynvec codec will be created. | ||
*/ | ||
export declare function vector<T extends BytesCodec>(itemCodec: T): ArrayCodec<T>; | ||
export declare function vector<T extends BytesCodec>(itemCodec: T): ArrayLayoutCodec<T>; | ||
/** | ||
@@ -82,12 +94,17 @@ * Table is a dynamic-size type. It can be considered as a dynvec but the length is fixed. | ||
*/ | ||
export declare function table<T extends Record<string, BytesCodec>>(shape: T, fields: (keyof T)[]): ObjectCodec<T>; | ||
export declare function table<T extends Record<string, BytesCodec>>(shape: T, fields: (keyof T)[]): ObjectLayoutCodec<T>; | ||
/** | ||
* Union is a dynamic-size type. | ||
* Serializing a union has two steps: | ||
* - Serialize a item type id in bytes as a 32 bit unsigned integer in little-endian. The item type id is the index of the inner items, and it's starting at 0. | ||
* - Serialize an item type id in bytes as a 32 bit unsigned integer in little-endian. The item type id is the index of the inner items, and it's starting at 0. | ||
* - Serialize the inner item. | ||
* @param itemCodec the union item record | ||
* @param fields the list of itemCodec's keys. It's also provide an order for pack/unpack. | ||
* @param fields the union item keys, can be an array or an object with custom id | ||
* @example | ||
* // without custom id | ||
* union({ cafe: Uint8, bee: Uint8 }, ['cafe', 'bee']) | ||
* // with custom id | ||
* union({ cafe: Uint8, bee: Uint8 }, { cafe: 0xcafe, bee: 0xbee }) | ||
*/ | ||
export declare function union<T extends Record<string, BytesCodec>>(itemCodec: T, fields: (keyof T)[]): UnionCodec<T>; | ||
export declare function union<T extends Record<string, BytesCodec>>(itemCodec: T, fields: (keyof T)[] | Record<keyof T, number>): UnionLayoutCodec<T>; | ||
/** | ||
@@ -100,4 +117,4 @@ * Option is a dynamic-size type. | ||
*/ | ||
export declare function option<T extends BytesCodec>(itemCodec: T): OptionCodec<T>; | ||
export declare function option<T extends BytesCodec>(itemCodec: T): OptionLayoutCodec<T>; | ||
export {}; | ||
//# sourceMappingURL=layout.d.ts.map |
@@ -34,2 +34,18 @@ "use strict"; | ||
/** | ||
* A codec for struct and table of Molecule | ||
*/ | ||
/** | ||
* A codec for option of Molecule | ||
*/ | ||
/** | ||
* A code for array and vector of Molecule | ||
*/ | ||
/** | ||
* A molecule codec for ` | ||
*/ | ||
/** | ||
* The array is a fixed-size type: it has a fixed-size inner type and a fixed length. | ||
@@ -242,12 +258,27 @@ * The size of an array is the size of inner type times the length. | ||
* Serializing a union has two steps: | ||
* - Serialize a item type id in bytes as a 32 bit unsigned integer in little-endian. The item type id is the index of the inner items, and it's starting at 0. | ||
* - Serialize an item type id in bytes as a 32 bit unsigned integer in little-endian. The item type id is the index of the inner items, and it's starting at 0. | ||
* - Serialize the inner item. | ||
* @param itemCodec the union item record | ||
* @param fields the list of itemCodec's keys. It's also provide an order for pack/unpack. | ||
* @param fields the union item keys, can be an array or an object with custom id | ||
* @example | ||
* // without custom id | ||
* union({ cafe: Uint8, bee: Uint8 }, ['cafe', 'bee']) | ||
* // with custom id | ||
* union({ cafe: Uint8, bee: Uint8 }, { cafe: 0xcafe, bee: 0xbee }) | ||
*/ | ||
function union(itemCodec, fields) { | ||
checkShape(itemCodec, Array.isArray(fields) ? fields : Object.keys(fields)); | ||
// check duplicated id | ||
if (!Array.isArray(fields)) { | ||
const ids = Object.values(fields); | ||
if (ids.length !== new Set(ids).size) { | ||
throw new Error(`Duplicated id in union: ${ids.join(", ")}`); | ||
} | ||
} | ||
return (0, _base.createBytesCodec)({ | ||
pack(obj) { | ||
const availableFields = Object.keys(itemCodec); | ||
const type = obj.type; | ||
const typeName = `Union(${fields.join(" | ")})`; | ||
const typeName = `Union(${availableFields.join(" | ")})`; | ||
@@ -258,7 +289,7 @@ /* c8 ignore next */ | ||
} | ||
const fieldIndex = fields.indexOf(type); | ||
if (fieldIndex === -1) { | ||
const fieldId = Array.isArray(fields) ? fields.indexOf(type) : fields[type]; | ||
if (fieldId < 0) { | ||
throw new _error.CodecBaseParseError(`Unknown union type: ${String(obj.type)}`, typeName); | ||
} | ||
const packedFieldIndex = _number.Uint32LE.pack(fieldIndex); | ||
const packedFieldIndex = _number.Uint32LE.pack(fieldId); | ||
const packedBody = itemCodec[type].pack(obj.value); | ||
@@ -268,4 +299,13 @@ return (0, _bytes.concat)(packedFieldIndex, packedBody); | ||
unpack(buf) { | ||
const typeIndex = _number.Uint32LE.unpack(buf.slice(0, 4)); | ||
const type = fields[typeIndex]; | ||
const fieldId = _number.Uint32LE.unpack(buf.slice(0, 4)); | ||
const type = (() => { | ||
if (Array.isArray(fields)) { | ||
return fields[fieldId]; | ||
} | ||
const entry = Object.entries(fields).find(([, id]) => id === fieldId); | ||
return entry === null || entry === void 0 ? void 0 : entry[0]; | ||
})(); | ||
if (!type) { | ||
throw new Error(`Unknown union field id: ${fieldId}, only ${fields} are allowed`); | ||
} | ||
return { | ||
@@ -272,0 +312,0 @@ type, |
import { BI, BIish } from "@ckb-lumos/bi"; | ||
import { FixedBytesCodec } from "../base"; | ||
export { BI, BIish }; | ||
export declare const Uint8: FixedBytesCodec<number, BIish>; | ||
@@ -4,0 +5,0 @@ export declare const Uint16LE: FixedBytesCodec<number, BIish>; |
@@ -6,2 +6,14 @@ "use strict"; | ||
}); | ||
Object.defineProperty(exports, "BI", { | ||
enumerable: true, | ||
get: function () { | ||
return _bi.BI; | ||
} | ||
}); | ||
Object.defineProperty(exports, "BIish", { | ||
enumerable: true, | ||
get: function () { | ||
return _bi.BIish; | ||
} | ||
}); | ||
exports.Uint8 = exports.Uint64LE = exports.Uint64BE = exports.Uint64 = exports.Uint512LE = exports.Uint512BE = exports.Uint512 = exports.Uint32LE = exports.Uint32BE = exports.Uint32 = exports.Uint256LE = exports.Uint256BE = exports.Uint256 = exports.Uint16LE = exports.Uint16BE = exports.Uint16 = exports.Uint128LE = exports.Uint128BE = exports.Uint128 = void 0; | ||
@@ -66,58 +78,39 @@ var _bi = require("@ckb-lumos/bi"); | ||
}; | ||
const Uint8 = createUintNumberCodec(1); | ||
exports.Uint8 = Uint8; | ||
const Uint16LE = createUintNumberCodec(2, true); | ||
exports.Uint16LE = Uint16LE; | ||
const Uint16BE = createUintNumberCodec(2); | ||
const Uint8 = exports.Uint8 = createUintNumberCodec(1); | ||
const Uint16LE = exports.Uint16LE = createUintNumberCodec(2, true); | ||
const Uint16BE = exports.Uint16BE = createUintNumberCodec(2); | ||
/** | ||
* @alias Uint16LE | ||
*/ | ||
exports.Uint16BE = Uint16BE; | ||
const Uint16 = Uint16LE; | ||
exports.Uint16 = Uint16; | ||
const Uint32LE = createUintNumberCodec(4, true); | ||
exports.Uint32LE = Uint32LE; | ||
const Uint32BE = createUintNumberCodec(4); | ||
const Uint16 = exports.Uint16 = Uint16LE; | ||
const Uint32LE = exports.Uint32LE = createUintNumberCodec(4, true); | ||
const Uint32BE = exports.Uint32BE = createUintNumberCodec(4); | ||
/** | ||
* @alias Uint32LE | ||
*/ | ||
exports.Uint32BE = Uint32BE; | ||
const Uint32 = Uint32LE; | ||
exports.Uint32 = Uint32; | ||
const Uint64LE = createUintBICodec(8, true); | ||
exports.Uint64LE = Uint64LE; | ||
const Uint64BE = createUintBICodec(8); | ||
const Uint32 = exports.Uint32 = Uint32LE; | ||
const Uint64LE = exports.Uint64LE = createUintBICodec(8, true); | ||
const Uint64BE = exports.Uint64BE = createUintBICodec(8); | ||
/** | ||
* @alias Uint64LE | ||
*/ | ||
exports.Uint64BE = Uint64BE; | ||
const Uint64 = Uint64LE; | ||
exports.Uint64 = Uint64; | ||
const Uint128LE = createUintBICodec(16, true); | ||
exports.Uint128LE = Uint128LE; | ||
const Uint128BE = createUintBICodec(16); | ||
const Uint64 = exports.Uint64 = Uint64LE; | ||
const Uint128LE = exports.Uint128LE = createUintBICodec(16, true); | ||
const Uint128BE = exports.Uint128BE = createUintBICodec(16); | ||
/** | ||
* @alias Uint128LE | ||
*/ | ||
exports.Uint128BE = Uint128BE; | ||
const Uint128 = Uint128LE; | ||
exports.Uint128 = Uint128; | ||
const Uint256LE = createUintBICodec(32, true); | ||
exports.Uint256LE = Uint256LE; | ||
const Uint256BE = createUintBICodec(32); | ||
const Uint128 = exports.Uint128 = Uint128LE; | ||
const Uint256LE = exports.Uint256LE = createUintBICodec(32, true); | ||
const Uint256BE = exports.Uint256BE = createUintBICodec(32); | ||
/** | ||
* @alias Uint256LE | ||
*/ | ||
exports.Uint256BE = Uint256BE; | ||
const Uint256 = Uint256LE; | ||
exports.Uint256 = Uint256; | ||
const Uint512LE = createUintBICodec(64, true); | ||
exports.Uint512LE = Uint512LE; | ||
const Uint512BE = createUintBICodec(64); | ||
const Uint256 = exports.Uint256 = Uint256LE; | ||
const Uint512LE = exports.Uint512LE = createUintBICodec(64, true); | ||
const Uint512BE = exports.Uint512BE = createUintBICodec(64); | ||
/** | ||
* @alias Uint512LE | ||
*/ | ||
exports.Uint512BE = Uint512BE; | ||
const Uint512 = Uint512LE; | ||
exports.Uint512 = Uint512; | ||
const Uint512 = exports.Uint512 = Uint512LE; | ||
//# sourceMappingURL=uint.js.map |
export declare function assertHexDecimal(str: string, byteLength?: number): void; | ||
/** | ||
* Assert if a string is a valid hex string that is matched with /^0x([0-9a-fA-F][0-9a-fA-F])*$/ | ||
* @param str | ||
* @param byteLength | ||
*/ | ||
export declare function assertHexString(str: string, byteLength?: number): void; | ||
@@ -3,0 +8,0 @@ export declare function assertUtf8String(str: string): void; |
@@ -14,39 +14,51 @@ "use strict"; | ||
var _error = require("./error"); | ||
const HEX_DECIMAL_REGEX = /^0x([0-9a-fA-F])+$/; | ||
const HEX_DECIMAL_WITH_BYTELENGTH_REGEX_MAP = new Map(); | ||
function assertHexDecimal(str, byteLength) { | ||
if (byteLength) { | ||
let regex = HEX_DECIMAL_WITH_BYTELENGTH_REGEX_MAP.get(byteLength); | ||
if (!regex) { | ||
const newRegex = new RegExp(`^0x([0-9a-fA-F]){1,${byteLength * 2}}$`); | ||
HEX_DECIMAL_WITH_BYTELENGTH_REGEX_MAP.set(byteLength, newRegex); | ||
regex = newRegex; | ||
const CHAR_0 = "0".charCodeAt(0); // 48 | ||
const CHAR_9 = "9".charCodeAt(0); // 57 | ||
const CHAR_A = "A".charCodeAt(0); // 65 | ||
const CHAR_F = "F".charCodeAt(0); // 70 | ||
const CHAR_a = "a".charCodeAt(0); // 97 | ||
const CHAR_f = "f".charCodeAt(0); // 102 | ||
function assertStartsWith0x(str) { | ||
if (!str || !str.startsWith("0x")) { | ||
throw new Error("Invalid hex string, expect starts with 0x"); | ||
} | ||
} | ||
function assertHexChars(str) { | ||
const strLen = str.length; | ||
for (let i = 2; i < strLen; i++) { | ||
const char = str[i].charCodeAt(0); | ||
if (char >= CHAR_0 && char <= CHAR_9 || char >= CHAR_a && char <= CHAR_f || char >= CHAR_A && char <= CHAR_F) { | ||
continue; | ||
} | ||
if (!regex.test(str)) { | ||
throw new Error("Invalid hex decimal!"); | ||
} | ||
} else { | ||
if (!HEX_DECIMAL_REGEX.test(str)) { | ||
throw new Error("Invalid hex decimal!"); | ||
} | ||
throw new Error(`Invalid hex character ${str[i]} in the string ${str}`); | ||
} | ||
} | ||
const HEX_STRING_REGEX = /^0x([0-9a-fA-F][0-9a-fA-F])*$/; | ||
const HEX_STRING_WITH_BYTELENGTH_REGEX_MAP = new Map(); | ||
function assertHexDecimal(str, byteLength) { | ||
assertStartsWith0x(str); | ||
if (str.length === 2) { | ||
throw new Error("Invalid hex decimal length, should be at least 1 character, the '0x' is incorrect, should be '0x0'"); | ||
} | ||
const strLen = str.length; | ||
if (typeof byteLength === "number" && strLen > byteLength * 2 + 2) { | ||
throw new Error(`Invalid hex decimal length, should be less than ${byteLength} bytes, got ${strLen / 2 - 1} bytes`); | ||
} | ||
assertHexChars(str); | ||
} | ||
/** | ||
* Assert if a string is a valid hex string that is matched with /^0x([0-9a-fA-F][0-9a-fA-F])*$/ | ||
* @param str | ||
* @param byteLength | ||
*/ | ||
function assertHexString(str, byteLength) { | ||
if (byteLength) { | ||
let regex = HEX_STRING_WITH_BYTELENGTH_REGEX_MAP.get(byteLength); | ||
if (!regex) { | ||
const newRegex = new RegExp(`^0x([0-9a-fA-F][0-9a-fA-F]){${byteLength}}$`); | ||
HEX_STRING_WITH_BYTELENGTH_REGEX_MAP.set(byteLength, newRegex); | ||
regex = newRegex; | ||
} | ||
if (!regex.test(str)) { | ||
throw new Error("Invalid hex string!"); | ||
} | ||
} else { | ||
if (!HEX_STRING_REGEX.test(str)) { | ||
throw new Error("Invalid hex string!"); | ||
} | ||
assertStartsWith0x(str); | ||
const strLen = str.length; | ||
if (strLen % 2) { | ||
throw new Error("Invalid hex string length, must be even!"); | ||
} | ||
if (typeof byteLength === "number" && strLen !== byteLength * 2 + 2) { | ||
throw new Error("Invalid hex string length, not match with byteLength!"); | ||
} | ||
assertHexChars(str); | ||
} | ||
@@ -56,2 +68,3 @@ function assertUtf8String(str) { | ||
const c = str.charCodeAt(i); | ||
/* eslint-disable @typescript-eslint/no-magic-numbers */ | ||
if (c > 0xff) { | ||
@@ -58,0 +71,0 @@ throw new Error("Invalid UTF-8 raw string!"); |
{ | ||
"name": "@ckb-lumos/codec", | ||
"version": "0.0.0-canary-a49c050-20230723075710", | ||
"version": "0.0.0-canary-ad0f66d-20240701081046", | ||
"description": "Make your own molecule binding in JavaScript(TypeScript)", | ||
@@ -22,3 +22,3 @@ "author": "", | ||
"dependencies": { | ||
"@ckb-lumos/bi": "0.0.0-canary-a49c050-20230723075710" | ||
"@ckb-lumos/bi": "0.0.0-canary-ad0f66d-20240701081046" | ||
}, | ||
@@ -40,2 +40,3 @@ "publishConfig": { | ||
"devDependencies": { | ||
"@ckb-lumos/crypto": "0.0.0-canary-ad0f66d-20240701081046", | ||
"escape-string-regexp": "^4.0.0", | ||
@@ -42,0 +43,0 @@ "js-yaml": "^4.1.0" |
@@ -170,3 +170,3 @@ # @ckb-lumos/codec | ||
will have encountered more complex scripts | ||
like [OmniLock](https://github.com/XuJiandong/docs-bank/blob/master/omni_lock.md), where it is easy to get confused | ||
like [OmniLock](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0042-omnilock/0042-omnilock.md), where it is easy to get confused | ||
about how to handle bytes when we want to sign it, if we can combine `WitnessArgs.lock(BytesOpt)` | ||
@@ -173,0 +173,0 @@ with `OmniLockWitnessLock.signature(BytesOpt)`, then it will be easier to do the signing, we can check |
@@ -68,3 +68,3 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ | ||
/** | ||
* This function helps to create a codec that can | ||
* Create a codec to deal with bytes-like data. | ||
* @param codec | ||
@@ -71,0 +71,0 @@ */ |
@@ -17,18 +17,35 @@ import { BytesLike } from "./base"; | ||
const CHAR_0 = "0".charCodeAt(0); // 48 | ||
const CHAR_9 = "9".charCodeAt(0); // 57 | ||
const CHAR_A = "A".charCodeAt(0); // 65 | ||
const CHAR_F = "F".charCodeAt(0); // 70 | ||
const CHAR_a = "a".charCodeAt(0); // 97 | ||
// const CHAR_f = "f".charCodeAt(0); // 102 | ||
function bytifyHex(hex: string): Uint8Array { | ||
assertHexString(hex); | ||
hex = hex.slice(2); | ||
const uint8s = []; | ||
for (let i = 0; i < hex.length; i += 2) { | ||
uint8s.push(parseInt(hex.substr(i, 2), 16)); | ||
const u8a = Uint8Array.from({ length: hex.length / 2 - 1 }); | ||
for (let i = 2, j = 0; i < hex.length; i = i + 2, j++) { | ||
const c1 = hex.charCodeAt(i); | ||
const c2 = hex.charCodeAt(i + 1); | ||
// prettier-ignore | ||
const n1 = c1 <= CHAR_9 ? c1 - CHAR_0 : c1 <= CHAR_F ? c1 - CHAR_A + 10 : c1 - CHAR_a + 10 | ||
// prettier-ignore | ||
const n2 = c2 <= CHAR_9 ? c2 - CHAR_0 : c2 <= CHAR_F ? c2 - CHAR_A + 10 : c2 - CHAR_a + 10 | ||
u8a[j] = (n1 << 4) | n2; | ||
} | ||
return Uint8Array.from(uint8s); | ||
return u8a; | ||
} | ||
function bytifyArrayLike(xs: ArrayLike<number>): Uint8Array { | ||
const isValidU8Vec = Array.from(xs).every((v) => v >= 0 && v <= 255); | ||
if (!isValidU8Vec) { | ||
throw new Error("invalid ArrayLike, all elements must be 0-255"); | ||
for (let i = 0; i < xs.length; i++) { | ||
const v = xs[i]; | ||
if (v < 0 || v > 255 || !Number.isInteger(v)) { | ||
throw new Error("invalid ArrayLike, all elements must be 0-255"); | ||
} | ||
} | ||
@@ -65,2 +82,6 @@ | ||
} | ||
const HEX_CACHE = Array.from({ length: 256 }).map((_, i) => | ||
i.toString(16).padStart(2, "0") | ||
); | ||
/** | ||
@@ -74,5 +95,9 @@ * convert a {@link BytesLike} to an even length hex string prefixed with "0x" | ||
export function hexify(buf: BytesLike): string { | ||
const hex = Array.from(bytify(buf)) | ||
.map((b) => b.toString(16).padStart(2, "0")) | ||
.join(""); | ||
let hex = ""; | ||
const u8a = bytify(buf); | ||
for (let i = 0; i < u8a.length; i++) { | ||
hex += HEX_CACHE[u8a[i]]; | ||
} | ||
return "0x" + hex; | ||
@@ -79,0 +104,0 @@ } |
@@ -49,6 +49,8 @@ // lc for lumos codec | ||
const path = this.keys.reduceRight(reducer, "input"); | ||
const text = | ||
this.origin instanceof CodecBaseParseError | ||
? `Expect type ${this.origin.expectedType} at ${path} but got error:` | ||
: `Error at ${path}:`; // this.origin can be an Error at runtime | ||
return `Expect type ${this.origin.expectedType} at ${path} but got error: ${ | ||
this.origin.message | ||
} | ||
return `${text} ${this.origin.message} | ||
${this.origin.stack?.replace(/Error:.+?\n/, "")} | ||
@@ -55,0 +57,0 @@ `; |
export { byteOf, byteArrayOf, byteVecOf } from "./helper"; | ||
export { table, array, option, struct, vector, union } from "./layout"; | ||
export type { | ||
ObjectLayoutCodec, | ||
ArrayLayoutCodec, | ||
OptionLayoutCodec, | ||
UnionLayoutCodec, | ||
} from "./layout"; |
@@ -44,8 +44,15 @@ /** | ||
export type ObjectCodec<T extends Record<string, BytesCodec>> = BytesCodec< | ||
PartialNullable<{ [key in keyof T]: UnpackResult<T[key]> }>, | ||
PartialNullable<{ [key in keyof T]: PackParam<T[key]> }> | ||
>; | ||
/** | ||
* A codec for struct and table of Molecule | ||
*/ | ||
export type ObjectLayoutCodec<T extends Record<string, BytesCodec>> = | ||
BytesCodec< | ||
PartialNullable<{ [key in keyof T]: UnpackResult<T[key]> }>, | ||
PartialNullable<{ [key in keyof T]: PackParam<T[key]> }> | ||
>; | ||
export interface OptionCodec<T extends BytesCodec> | ||
/** | ||
* A codec for option of Molecule | ||
*/ | ||
export interface OptionLayoutCodec<T extends BytesCodec> | ||
extends BytesCodec<UnpackResult<T> | undefined> { | ||
@@ -55,3 +62,6 @@ pack: (packable?: PackParam<T>) => Uint8Array; | ||
export type ArrayCodec<T extends BytesCodec> = BytesCodec< | ||
/** | ||
* A code for array and vector of Molecule | ||
*/ | ||
export type ArrayLayoutCodec<T extends BytesCodec> = BytesCodec< | ||
Array<UnpackResult<T>>, | ||
@@ -61,3 +71,6 @@ Array<PackParam<T>> | ||
export type UnionCodec<T extends Record<string, BytesCodec>> = BytesCodec< | ||
/** | ||
* A molecule codec for ` | ||
*/ | ||
export type UnionLayoutCodec<T extends Record<string, BytesCodec>> = BytesCodec< | ||
{ [key in keyof T]: { type: key; value: UnpackResult<T[key]> } }[keyof T], | ||
@@ -76,3 +89,3 @@ { [key in keyof T]: { type: key; value: PackParam<T[key]> } }[keyof T] | ||
itemCount: number | ||
): ArrayCodec<T> & Fixed { | ||
): ArrayLayoutCodec<T> & Fixed { | ||
const enhancedArrayCodec = createArrayCodec(itemCodec); | ||
@@ -124,3 +137,3 @@ return createFixedBytesCodec({ | ||
fields: (keyof T)[] | ||
): ObjectCodec<T> & Fixed { | ||
): ObjectLayoutCodec<T> & Fixed { | ||
checkShape(shape, fields); | ||
@@ -139,7 +152,5 @@ const objectCodec = createObjectCodec(shape); | ||
unpack(buf) { | ||
const result = {} as PartialNullable< | ||
{ | ||
[key in keyof T]: UnpackResult<T[key]>; | ||
} | ||
>; | ||
const result = {} as PartialNullable<{ | ||
[key in keyof T]: UnpackResult<T[key]>; | ||
}>; | ||
let offset = 0; | ||
@@ -164,3 +175,5 @@ | ||
*/ | ||
export function fixvec<T extends FixedBytesCodec>(itemCodec: T): ArrayCodec<T> { | ||
export function fixvec<T extends FixedBytesCodec>( | ||
itemCodec: T | ||
): ArrayLayoutCodec<T> { | ||
return createBytesCodec({ | ||
@@ -193,3 +206,5 @@ pack(items) { | ||
*/ | ||
export function dynvec<T extends BytesCodec>(itemCodec: T): ArrayCodec<T> { | ||
export function dynvec<T extends BytesCodec>( | ||
itemCodec: T | ||
): ArrayLayoutCodec<T> { | ||
return createBytesCodec({ | ||
@@ -254,3 +269,5 @@ pack(obj) { | ||
*/ | ||
export function vector<T extends BytesCodec>(itemCodec: T): ArrayCodec<T> { | ||
export function vector<T extends BytesCodec>( | ||
itemCodec: T | ||
): ArrayLayoutCodec<T> { | ||
if (isFixedCodec(itemCodec)) { | ||
@@ -270,3 +287,3 @@ return fixvec(itemCodec); | ||
fields: (keyof T)[] | ||
): ObjectCodec<T> { | ||
): ObjectLayoutCodec<T> { | ||
checkShape(shape, fields); | ||
@@ -309,7 +326,5 @@ return createBytesCodec({ | ||
if (totalSize <= 4 || fields.length === 0) { | ||
return {} as PartialNullable< | ||
{ | ||
[key in keyof T]: UnpackResult<T[key]>; | ||
} | ||
>; | ||
return {} as PartialNullable<{ | ||
[key in keyof T]: UnpackResult<T[key]>; | ||
}>; | ||
} else { | ||
@@ -329,7 +344,5 @@ const offsets = fields.map((_, index) => | ||
} | ||
return obj as PartialNullable< | ||
{ | ||
[key in keyof T]: UnpackResult<T[key]>; | ||
} | ||
>; | ||
return obj as PartialNullable<{ | ||
[key in keyof T]: UnpackResult<T[key]>; | ||
}>; | ||
} | ||
@@ -343,15 +356,32 @@ }, | ||
* Serializing a union has two steps: | ||
* - Serialize a item type id in bytes as a 32 bit unsigned integer in little-endian. The item type id is the index of the inner items, and it's starting at 0. | ||
* - Serialize an item type id in bytes as a 32 bit unsigned integer in little-endian. The item type id is the index of the inner items, and it's starting at 0. | ||
* - Serialize the inner item. | ||
* @param itemCodec the union item record | ||
* @param fields the list of itemCodec's keys. It's also provide an order for pack/unpack. | ||
* @param fields the union item keys, can be an array or an object with custom id | ||
* @example | ||
* // without custom id | ||
* union({ cafe: Uint8, bee: Uint8 }, ['cafe', 'bee']) | ||
* // with custom id | ||
* union({ cafe: Uint8, bee: Uint8 }, { cafe: 0xcafe, bee: 0xbee }) | ||
*/ | ||
export function union<T extends Record<string, BytesCodec>>( | ||
itemCodec: T, | ||
fields: (keyof T)[] | ||
): UnionCodec<T> { | ||
fields: (keyof T)[] | Record<keyof T, number> | ||
): UnionLayoutCodec<T> { | ||
checkShape(itemCodec, Array.isArray(fields) ? fields : Object.keys(fields)); | ||
// check duplicated id | ||
if (!Array.isArray(fields)) { | ||
const ids = Object.values(fields); | ||
if (ids.length !== new Set(ids).size) { | ||
throw new Error(`Duplicated id in union: ${ids.join(", ")}`); | ||
} | ||
} | ||
return createBytesCodec({ | ||
pack(obj) { | ||
const availableFields: (keyof T)[] = Object.keys(itemCodec); | ||
const type = obj.type; | ||
const typeName = `Union(${fields.join(" | ")})`; | ||
const typeName = `Union(${availableFields.join(" | ")})`; | ||
@@ -366,4 +396,7 @@ /* c8 ignore next */ | ||
const fieldIndex = fields.indexOf(type); | ||
if (fieldIndex === -1) { | ||
const fieldId = Array.isArray(fields) | ||
? fields.indexOf(type) | ||
: fields[type]; | ||
if (fieldId < 0) { | ||
throw new CodecBaseParseError( | ||
@@ -374,3 +407,3 @@ `Unknown union type: ${String(obj.type)}`, | ||
} | ||
const packedFieldIndex = Uint32LE.pack(fieldIndex); | ||
const packedFieldIndex = Uint32LE.pack(fieldId); | ||
const packedBody = itemCodec[type].pack(obj.value); | ||
@@ -380,4 +413,19 @@ return concat(packedFieldIndex, packedBody); | ||
unpack(buf) { | ||
const typeIndex = Uint32LE.unpack(buf.slice(0, 4)); | ||
const type = fields[typeIndex]; | ||
const fieldId = Uint32LE.unpack(buf.slice(0, 4)); | ||
const type: keyof T | undefined = (() => { | ||
if (Array.isArray(fields)) { | ||
return fields[fieldId]; | ||
} | ||
const entry = Object.entries(fields).find(([, id]) => id === fieldId); | ||
return entry?.[0]; | ||
})(); | ||
if (!type) { | ||
throw new Error( | ||
`Unknown union field id: ${fieldId}, only ${fields} are allowed` | ||
); | ||
} | ||
return { type, value: itemCodec[type].unpack(buf.slice(4)) }; | ||
@@ -395,3 +443,5 @@ }, | ||
*/ | ||
export function option<T extends BytesCodec>(itemCodec: T): OptionCodec<T> { | ||
export function option<T extends BytesCodec>( | ||
itemCodec: T | ||
): OptionLayoutCodec<T> { | ||
return createBytesCodec({ | ||
@@ -398,0 +448,0 @@ pack(obj?) { |
@@ -5,2 +5,4 @@ import { BI, BIish } from "@ckb-lumos/bi"; | ||
export { BI, BIish }; | ||
function assertNumberRange( | ||
@@ -7,0 +9,0 @@ value: BIish, |
@@ -7,44 +7,72 @@ import { | ||
const HEX_DECIMAL_REGEX = /^0x([0-9a-fA-F])+$/; | ||
const HEX_DECIMAL_WITH_BYTELENGTH_REGEX_MAP = new Map<number, RegExp>(); | ||
const CHAR_0 = "0".charCodeAt(0); // 48 | ||
const CHAR_9 = "9".charCodeAt(0); // 57 | ||
const CHAR_A = "A".charCodeAt(0); // 65 | ||
const CHAR_F = "F".charCodeAt(0); // 70 | ||
const CHAR_a = "a".charCodeAt(0); // 97 | ||
const CHAR_f = "f".charCodeAt(0); // 102 | ||
export function assertHexDecimal(str: string, byteLength?: number): void { | ||
if (byteLength) { | ||
let regex = HEX_DECIMAL_WITH_BYTELENGTH_REGEX_MAP.get(byteLength); | ||
if (!regex) { | ||
const newRegex = new RegExp(`^0x([0-9a-fA-F]){1,${byteLength * 2}}$`); | ||
HEX_DECIMAL_WITH_BYTELENGTH_REGEX_MAP.set(byteLength, newRegex); | ||
regex = newRegex; | ||
function assertStartsWith0x(str: string): void { | ||
if (!str || !str.startsWith("0x")) { | ||
throw new Error("Invalid hex string, expect starts with 0x"); | ||
} | ||
} | ||
function assertHexChars(str: string): void { | ||
const strLen = str.length; | ||
for (let i = 2; i < strLen; i++) { | ||
const char = str[i].charCodeAt(0); | ||
if ( | ||
(char >= CHAR_0 && char <= CHAR_9) || | ||
(char >= CHAR_a && char <= CHAR_f) || | ||
(char >= CHAR_A && char <= CHAR_F) | ||
) { | ||
continue; | ||
} | ||
if (!regex.test(str)) { | ||
throw new Error("Invalid hex decimal!"); | ||
} | ||
} else { | ||
if (!HEX_DECIMAL_REGEX.test(str)) { | ||
throw new Error("Invalid hex decimal!"); | ||
} | ||
throw new Error(`Invalid hex character ${str[i]} in the string ${str}`); | ||
} | ||
} | ||
const HEX_STRING_REGEX = /^0x([0-9a-fA-F][0-9a-fA-F])*$/; | ||
const HEX_STRING_WITH_BYTELENGTH_REGEX_MAP = new Map<number, RegExp>(); | ||
export function assertHexDecimal(str: string, byteLength?: number): void { | ||
assertStartsWith0x(str); | ||
if (str.length === 2) { | ||
throw new Error( | ||
"Invalid hex decimal length, should be at least 1 character, the '0x' is incorrect, should be '0x0'" | ||
); | ||
} | ||
const strLen = str.length; | ||
if (typeof byteLength === "number" && strLen > byteLength * 2 + 2) { | ||
throw new Error( | ||
`Invalid hex decimal length, should be less than ${byteLength} bytes, got ${ | ||
strLen / 2 - 1 | ||
} bytes` | ||
); | ||
} | ||
assertHexChars(str); | ||
} | ||
/** | ||
* Assert if a string is a valid hex string that is matched with /^0x([0-9a-fA-F][0-9a-fA-F])*$/ | ||
* @param str | ||
* @param byteLength | ||
*/ | ||
export function assertHexString(str: string, byteLength?: number): void { | ||
if (byteLength) { | ||
let regex = HEX_STRING_WITH_BYTELENGTH_REGEX_MAP.get(byteLength); | ||
if (!regex) { | ||
const newRegex = new RegExp( | ||
`^0x([0-9a-fA-F][0-9a-fA-F]){${byteLength}}$` | ||
); | ||
HEX_STRING_WITH_BYTELENGTH_REGEX_MAP.set(byteLength, newRegex); | ||
regex = newRegex; | ||
} | ||
if (!regex.test(str)) { | ||
throw new Error("Invalid hex string!"); | ||
} | ||
} else { | ||
if (!HEX_STRING_REGEX.test(str)) { | ||
throw new Error("Invalid hex string!"); | ||
} | ||
assertStartsWith0x(str); | ||
const strLen = str.length; | ||
if (strLen % 2) { | ||
throw new Error("Invalid hex string length, must be even!"); | ||
} | ||
if (typeof byteLength === "number" && strLen !== byteLength * 2 + 2) { | ||
throw new Error("Invalid hex string length, not match with byteLength!"); | ||
} | ||
assertHexChars(str); | ||
} | ||
@@ -55,2 +83,3 @@ | ||
const c = str.charCodeAt(i); | ||
/* eslint-disable @typescript-eslint/no-magic-numbers */ | ||
if (c > 0xff) { | ||
@@ -57,0 +86,0 @@ throw new Error("Invalid UTF-8 raw string!"); |
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
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
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
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
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
183536
2592
3
+ Added@ckb-lumos/bi@0.0.0-canary-ad0f66d-20240701081046(transitive)
- Removed@ckb-lumos/bi@0.0.0-canary-a49c050-20230723075710(transitive)