@ckb-ccc/core 1.22.0 → 1.23.0
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 +71 -0
- package/dist/advanced.d.mts +1 -1
- package/dist/advanced.mjs +1 -1
- package/dist/{advancedBarrel-Daj_LJkz.d.mts → advancedBarrel-BBbQZ2OW.d.mts} +480 -379
- package/dist/advancedBarrel-BBbQZ2OW.d.mts.map +1 -0
- package/dist/advancedBarrel.d.mts +1 -1
- package/dist/advancedBarrel.mjs +1 -1
- package/dist/barrel-Dz1WLXRX.mjs +7 -0
- package/dist/barrel-Dz1WLXRX.mjs.map +1 -0
- package/dist/barrel.d.mts +2 -2
- package/dist/barrel.mjs +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +1 -1
- package/dist/transformers-BHt442Nd.mjs +2 -0
- package/dist/transformers-BHt442Nd.mjs.map +1 -0
- package/dist.commonjs/advanced.d.ts +1 -1
- package/dist.commonjs/advanced.js +1 -1
- package/dist.commonjs/{advancedBarrel-CJL3rfuW.d.ts → advancedBarrel-BS4zFcFI.d.ts} +480 -379
- package/dist.commonjs/advancedBarrel-BS4zFcFI.d.ts.map +1 -0
- package/dist.commonjs/advancedBarrel.d.ts +1 -1
- package/dist.commonjs/advancedBarrel.js +1 -1
- package/dist.commonjs/{barrel-DZkApbAR.js → barrel-CZYID7jh.js} +10 -10
- package/dist.commonjs/barrel-CZYID7jh.js.map +1 -0
- package/dist.commonjs/barrel.d.ts +2 -2
- package/dist.commonjs/barrel.js +1 -1
- package/dist.commonjs/index.d.ts +2 -2
- package/dist.commonjs/index.js +1 -1
- package/dist.commonjs/transformers-CYUULrnt.js +2 -0
- package/dist.commonjs/transformers-CYUULrnt.js.map +1 -0
- package/package.json +1 -1
- package/src/address/index.ts +32 -4
- package/src/ckb/transaction.ts +79 -31
- package/src/client/cache/memory.advanced.ts +18 -3
- package/src/client/client.ts +41 -2
- package/src/client/clientPublicMainnet.ts +9 -2
- package/src/client/clientPublicTestnet.ts +9 -2
- package/src/client/jsonRpc/client.ts +8 -8
- package/src/codec/codec.ts +51 -27
- package/src/codec/entity.ts +26 -16
- package/src/fixedPoint/index.ts +17 -8
- package/src/jsonRpc/transports/webSocket.ts +3 -1
- package/src/molecule/codec.ts +437 -202
- package/src/utils/index.ts +3 -1
- package/dist/advancedBarrel-Daj_LJkz.d.mts.map +0 -1
- package/dist/barrel-CFOWSjcM.mjs +0 -7
- package/dist/barrel-CFOWSjcM.mjs.map +0 -1
- package/dist/transformers-DAMi6ZOq.mjs +0 -2
- package/dist/transformers-DAMi6ZOq.mjs.map +0 -1
- package/dist.commonjs/advancedBarrel-CJL3rfuW.d.ts.map +0 -1
- package/dist.commonjs/barrel-DZkApbAR.js.map +0 -1
- package/dist.commonjs/transformers-C6jbFO7W.js +0 -2
- package/dist.commonjs/transformers-C6jbFO7W.js.map +0 -1
package/src/codec/codec.ts
CHANGED
|
@@ -2,20 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
import { Bytes, bytesFrom, BytesLike } from "../bytes/index.js";
|
|
4
4
|
|
|
5
|
-
export type CodecLike<Encodable, Decoded = Encodable> = {
|
|
5
|
+
export type CodecLike<Encodable, Decoded = Encodable, Context = any> = {
|
|
6
6
|
readonly encode: (encodable: Encodable) => Bytes;
|
|
7
|
-
readonly decode: (
|
|
8
|
-
decodable: BytesLike,
|
|
9
|
-
config?: { isExtraFieldIgnored?: boolean },
|
|
10
|
-
) => Decoded;
|
|
7
|
+
readonly decode: (decodable: BytesLike, context?: Context) => Decoded;
|
|
11
8
|
readonly byteLength?: number;
|
|
12
9
|
};
|
|
13
|
-
export class Codec<Encodable, Decoded = Encodable> {
|
|
10
|
+
export class Codec<Encodable, Decoded = Encodable, Context = any> {
|
|
14
11
|
constructor(
|
|
15
12
|
public readonly encode: (encodable: Encodable) => Bytes,
|
|
16
13
|
public readonly decode: (
|
|
17
14
|
decodable: BytesLike,
|
|
18
|
-
|
|
15
|
+
context?: Context,
|
|
19
16
|
) => Decoded,
|
|
20
17
|
public readonly byteLength?: number, // if provided, treat codec as fixed length
|
|
21
18
|
) {}
|
|
@@ -28,23 +25,23 @@ export class Codec<Encodable, Decoded = Encodable> {
|
|
|
28
25
|
}
|
|
29
26
|
}
|
|
30
27
|
|
|
31
|
-
decodeOr<T>(
|
|
32
|
-
decodable: BytesLike,
|
|
33
|
-
fallback: T,
|
|
34
|
-
config?: { isExtraFieldIgnored?: boolean }, // This is equivalent to "compatible" in the Rust implementation of Molecule.
|
|
35
|
-
) {
|
|
28
|
+
decodeOr<T>(decodable: BytesLike, fallback: T, context?: Context) {
|
|
36
29
|
try {
|
|
37
|
-
return this.decode(decodable,
|
|
30
|
+
return this.decode(decodable, context);
|
|
38
31
|
} catch (_) {
|
|
39
32
|
return fallback;
|
|
40
33
|
}
|
|
41
34
|
}
|
|
42
35
|
|
|
43
|
-
static from<Encodable, Decoded = Encodable>({
|
|
36
|
+
static from<Encodable, Decoded = Encodable, Context = any>({
|
|
44
37
|
encode,
|
|
45
38
|
decode,
|
|
46
39
|
byteLength,
|
|
47
|
-
}: CodecLike<Encodable, Decoded>): Codec<
|
|
40
|
+
}: CodecLike<Encodable, Decoded, Context>): Codec<
|
|
41
|
+
Encodable,
|
|
42
|
+
Decoded,
|
|
43
|
+
Context
|
|
44
|
+
> {
|
|
48
45
|
return new Codec(
|
|
49
46
|
(encodable: Encodable) => {
|
|
50
47
|
const encoded = encode(encodable);
|
|
@@ -55,7 +52,7 @@ export class Codec<Encodable, Decoded = Encodable> {
|
|
|
55
52
|
}
|
|
56
53
|
return encoded;
|
|
57
54
|
},
|
|
58
|
-
(decodable,
|
|
55
|
+
(decodable, context) => {
|
|
59
56
|
const decodableBytes = bytesFrom(decodable);
|
|
60
57
|
if (
|
|
61
58
|
byteLength !== undefined &&
|
|
@@ -65,7 +62,7 @@ export class Codec<Encodable, Decoded = Encodable> {
|
|
|
65
62
|
`Codec.decode: expected byte length ${byteLength}, got ${decodableBytes.byteLength}`,
|
|
66
63
|
);
|
|
67
64
|
}
|
|
68
|
-
return decode(decodable,
|
|
65
|
+
return decode(decodable, context);
|
|
69
66
|
},
|
|
70
67
|
byteLength,
|
|
71
68
|
);
|
|
@@ -77,32 +74,59 @@ export class Codec<Encodable, Decoded = Encodable> {
|
|
|
77
74
|
}: {
|
|
78
75
|
inMap?: (encodable: NewEncodable) => Encodable;
|
|
79
76
|
outMap?: (decoded: Decoded) => NewDecoded;
|
|
80
|
-
}): Codec<NewEncodable, NewDecoded> {
|
|
77
|
+
}): Codec<NewEncodable, NewDecoded, Context> {
|
|
81
78
|
return new Codec(
|
|
82
79
|
(encodable) =>
|
|
83
80
|
this.encode((inMap ? inMap(encodable) : encodable) as Encodable),
|
|
84
|
-
(buffer,
|
|
81
|
+
(buffer, context) =>
|
|
85
82
|
(outMap
|
|
86
|
-
? outMap(this.decode(buffer,
|
|
87
|
-
: this.decode(buffer,
|
|
83
|
+
? outMap(this.decode(buffer, context))
|
|
84
|
+
: this.decode(buffer, context)) as NewDecoded,
|
|
88
85
|
this.byteLength,
|
|
89
86
|
);
|
|
90
87
|
}
|
|
91
88
|
|
|
92
89
|
mapIn<NewEncodable>(
|
|
93
90
|
map: (encodable: NewEncodable) => Encodable,
|
|
94
|
-
): Codec<NewEncodable, Decoded> {
|
|
91
|
+
): Codec<NewEncodable, Decoded, Context> {
|
|
95
92
|
return this.map({ inMap: map });
|
|
96
93
|
}
|
|
97
94
|
|
|
98
95
|
mapOut<NewDecoded>(
|
|
99
96
|
map: (decoded: Decoded) => NewDecoded,
|
|
100
|
-
): Codec<Encodable, NewDecoded> {
|
|
97
|
+
): Codec<Encodable, NewDecoded, Context> {
|
|
101
98
|
return this.map({ outMap: map });
|
|
102
99
|
}
|
|
103
100
|
}
|
|
104
101
|
|
|
105
|
-
export type EncodableType<T extends CodecLike<any, any>> =
|
|
106
|
-
T extends CodecLike<infer Encodable, unknown> ? Encodable : never;
|
|
107
|
-
export type DecodedType<T extends CodecLike<any, any>> =
|
|
108
|
-
T extends CodecLike<any, infer Decoded> ? Decoded : never;
|
|
102
|
+
export type EncodableType<T extends CodecLike<any, any, any>> =
|
|
103
|
+
T extends CodecLike<infer Encodable, unknown, any> ? Encodable : never;
|
|
104
|
+
export type DecodedType<T extends CodecLike<any, any, any>> =
|
|
105
|
+
T extends CodecLike<any, infer Decoded, any> ? Decoded : never;
|
|
106
|
+
|
|
107
|
+
type IsAny<T> = 0 extends 1 & T ? true : false;
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* The context a codec specifically requires when composed with other codecs.
|
|
111
|
+
* Legacy `any` is normalized to `unknown`, while `Extract` preserves that the
|
|
112
|
+
* normalized type is assignable to the codec's original context.
|
|
113
|
+
*/
|
|
114
|
+
export type ContextType<T extends CodecLike<any, any, any>> = T extends {
|
|
115
|
+
readonly decode: (decodable: BytesLike, context?: infer Context) => unknown;
|
|
116
|
+
}
|
|
117
|
+
? Extract<IsAny<Context> extends true ? unknown : Context, Context>
|
|
118
|
+
: unknown;
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* The combined context required by every codec in a record.
|
|
122
|
+
*
|
|
123
|
+
* Map each child context to a function parameter before forming the union so a
|
|
124
|
+
* legacy `any` (normalized to `unknown` by {@link ContextType}) cannot absorb
|
|
125
|
+
* the other contexts. Inferring from the resulting contravariant parameter
|
|
126
|
+
* position converts the function union into an intersection of its contexts.
|
|
127
|
+
*/
|
|
128
|
+
export type ChildContext<T extends Record<string, CodecLike<any, any, any>>> = {
|
|
129
|
+
[K in keyof T]: (context: ContextType<T[K]>) => void;
|
|
130
|
+
}[keyof T] extends (context: infer Context) => void
|
|
131
|
+
? Context
|
|
132
|
+
: unknown;
|
package/src/codec/entity.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { hashCkb } from "../hasher/index.js";
|
|
|
3
3
|
import { Hex, hexFrom } from "../hex/index.js";
|
|
4
4
|
import type { UnionDecoded, UnionMatchHandlers } from "../molecule/codec.js";
|
|
5
5
|
import { Constructor } from "../utils/index.js";
|
|
6
|
-
import type { CodecLike, DecodedType } from "./codec.js";
|
|
6
|
+
import type { CodecLike, ContextType, DecodedType } from "./codec.js";
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* The base class of CCC to create a serializable instance. This should be used with the {@link codec} decorator.
|
|
@@ -15,7 +15,12 @@ export abstract class Entity {
|
|
|
15
15
|
* This should be used with the {@link codec} decorator.
|
|
16
16
|
* @public
|
|
17
17
|
*/
|
|
18
|
-
static Base<
|
|
18
|
+
static Base<
|
|
19
|
+
SubTypeLike,
|
|
20
|
+
SubType = SubTypeLike,
|
|
21
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
22
|
+
Context = any,
|
|
23
|
+
>() {
|
|
19
24
|
abstract class Impl extends Entity {
|
|
20
25
|
/**
|
|
21
26
|
* The bytes length of the entity, if it is fixed, otherwise undefined
|
|
@@ -41,10 +46,11 @@ export abstract class Entity {
|
|
|
41
46
|
* @public
|
|
42
47
|
* @static
|
|
43
48
|
* @param _ - The bytes to decode
|
|
49
|
+
* @param _context - Optional context passed to the codec
|
|
44
50
|
* @returns The decoded entity
|
|
45
51
|
* @throws Will throw an error if the entity is not serializable
|
|
46
52
|
*/
|
|
47
|
-
static decode(_: BytesLike): SubType {
|
|
53
|
+
static decode(_: BytesLike, _context?: Context): SubType {
|
|
48
54
|
throw new Error(
|
|
49
55
|
"decode not implemented, use @ccc.codec to decorate your type",
|
|
50
56
|
);
|
|
@@ -55,10 +61,11 @@ export abstract class Entity {
|
|
|
55
61
|
* @public
|
|
56
62
|
* @static
|
|
57
63
|
* @param _ - The bytes to create the entity from
|
|
64
|
+
* @param _context - Optional context passed to the codec
|
|
58
65
|
* @returns The created entity
|
|
59
66
|
* @throws Will throw an error if the entity is not serializable
|
|
60
67
|
*/
|
|
61
|
-
static fromBytes(_bytes: BytesLike): SubType {
|
|
68
|
+
static fromBytes(_bytes: BytesLike, _context?: Context): SubType {
|
|
62
69
|
throw new Error(
|
|
63
70
|
"fromBytes not implemented, use @ccc.codec to decorate your type",
|
|
64
71
|
);
|
|
@@ -181,14 +188,18 @@ export abstract class Entity {
|
|
|
181
188
|
*/
|
|
182
189
|
static BaseUnion<
|
|
183
190
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
184
|
-
CodecType extends CodecLike<any, UnionDecoded<any, any
|
|
191
|
+
CodecType extends CodecLike<any, UnionDecoded<any, any>, any>,
|
|
185
192
|
SubTypeLike,
|
|
186
193
|
SubType = SubTypeLike,
|
|
187
194
|
>() {
|
|
188
195
|
type Handlers<Result> = UnionMatchHandlers<CodecType, Result>;
|
|
189
196
|
type Decoded = DecodedType<CodecType>;
|
|
190
197
|
|
|
191
|
-
abstract class Impl extends Entity.Base<
|
|
198
|
+
abstract class Impl extends Entity.Base<
|
|
199
|
+
SubTypeLike,
|
|
200
|
+
SubType,
|
|
201
|
+
ContextType<CodecType>
|
|
202
|
+
>() {
|
|
192
203
|
/**
|
|
193
204
|
* The inner decoded object representing the union value.
|
|
194
205
|
* @public
|
|
@@ -263,12 +274,11 @@ export function codec<
|
|
|
263
274
|
Encodable,
|
|
264
275
|
TypeLike extends Encodable,
|
|
265
276
|
Decoded extends TypeLike,
|
|
277
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
278
|
+
Context = any,
|
|
266
279
|
>(codec: {
|
|
267
280
|
encode: (encodable: Encodable) => Bytes;
|
|
268
|
-
decode: (
|
|
269
|
-
decodable: Bytes,
|
|
270
|
-
config?: { isExtraFieldIgnored?: boolean },
|
|
271
|
-
) => Decoded;
|
|
281
|
+
decode: (decodable: Bytes, context?: Context) => Decoded;
|
|
272
282
|
byteLength?: number;
|
|
273
283
|
}) {
|
|
274
284
|
return function <
|
|
@@ -277,8 +287,8 @@ export function codec<
|
|
|
277
287
|
from(decoded: TypeLike): Type;
|
|
278
288
|
byteLength?: number;
|
|
279
289
|
encode(encodable: TypeLike): Bytes;
|
|
280
|
-
decode(bytesLike: BytesLike): Type;
|
|
281
|
-
fromBytes(bytes: BytesLike): Type;
|
|
290
|
+
decode(bytesLike: BytesLike, context?: Context): Type;
|
|
291
|
+
fromBytes(bytes: BytesLike, context?: Context): Type;
|
|
282
292
|
},
|
|
283
293
|
>(Constructor: ConstructorType, ..._: unknown[]) {
|
|
284
294
|
Constructor.byteLength = codec.byteLength;
|
|
@@ -288,13 +298,13 @@ export function codec<
|
|
|
288
298
|
};
|
|
289
299
|
}
|
|
290
300
|
if (Constructor.decode === undefined) {
|
|
291
|
-
Constructor.decode = function (bytesLike: BytesLike) {
|
|
292
|
-
return Constructor.from(codec.decode(bytesFrom(bytesLike)));
|
|
301
|
+
Constructor.decode = function (bytesLike: BytesLike, context?: Context) {
|
|
302
|
+
return Constructor.from(codec.decode(bytesFrom(bytesLike), context));
|
|
293
303
|
};
|
|
294
304
|
}
|
|
295
305
|
if (Constructor.fromBytes === undefined) {
|
|
296
|
-
Constructor.fromBytes = function (bytes: BytesLike) {
|
|
297
|
-
return Constructor.from(codec.decode(bytesFrom(bytes)));
|
|
306
|
+
Constructor.fromBytes = function (bytes: BytesLike, context?: Context) {
|
|
307
|
+
return Constructor.from(codec.decode(bytesFrom(bytes), context));
|
|
298
308
|
};
|
|
299
309
|
}
|
|
300
310
|
|
package/src/fixedPoint/index.ts
CHANGED
|
@@ -30,7 +30,11 @@ export type FixedPointLike = bigint | string | number;
|
|
|
30
30
|
*/
|
|
31
31
|
|
|
32
32
|
export function fixedPointToString(val: FixedPointLike, decimals = 8): string {
|
|
33
|
-
const
|
|
33
|
+
const fp = fixedPointFrom(val, decimals);
|
|
34
|
+
if (fp < 0n) {
|
|
35
|
+
return `-${fixedPointToString(-fp, decimals)}`;
|
|
36
|
+
}
|
|
37
|
+
const str = fp.toString();
|
|
34
38
|
if (decimals === 0) {
|
|
35
39
|
return str;
|
|
36
40
|
}
|
|
@@ -65,15 +69,20 @@ export function fixedPointFrom(val: FixedPointLike, decimals = 8): FixedPoint {
|
|
|
65
69
|
return val;
|
|
66
70
|
}
|
|
67
71
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
72
|
+
let str = typeof val === "number" ? val.toFixed(decimals) : val.toString();
|
|
73
|
+
const isNegative = str.startsWith("-");
|
|
74
|
+
if (isNegative || str.startsWith("+")) {
|
|
75
|
+
str = str.slice(1);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const [l, r] = str.split(".");
|
|
79
|
+
const lVal = l === "" ? 0n : BigInt(l.padEnd(l.length + decimals, "0"));
|
|
80
|
+
if (r === undefined || decimals === 0) {
|
|
81
|
+
return isNegative ? -lVal : lVal;
|
|
74
82
|
}
|
|
75
83
|
|
|
76
|
-
|
|
84
|
+
const unsignedVal = lVal + BigInt(r.slice(0, decimals).padEnd(decimals, "0"));
|
|
85
|
+
return isNegative ? -unsignedVal : unsignedVal;
|
|
77
86
|
}
|
|
78
87
|
|
|
79
88
|
/**
|
|
@@ -209,7 +209,9 @@ export class JsonRpcTransportWebSocket implements JsonRpcTransport {
|
|
|
209
209
|
this.disposed = true;
|
|
210
210
|
const socket = this.socket;
|
|
211
211
|
|
|
212
|
-
if (!socket || socket.readyState === socket.CLOSED)
|
|
212
|
+
if (!socket || socket.readyState === socket.CLOSED) {
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
213
215
|
|
|
214
216
|
await new Promise<void>((resolve) => {
|
|
215
217
|
socket.addEventListener("close", () => resolve(), { once: true });
|