@fleet-sdk/serializer 0.2.2 → 0.3.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 +21 -0
- package/dist/index.cjs.js +5 -4
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.mts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.esm.js +5 -4
- package/dist/index.esm.js.map +1 -1
- package/package.json +4 -4
- package/src/_test-vectors/boxVectors.ts +0 -207
- package/src/_test-vectors/constantVectors.ts +0 -457
- package/src/_test-vectors/transactionVectors.ts +0 -590
- package/src/coders/bigint.ts +0 -73
- package/src/coders/index.ts +0 -4
- package/src/coders/sigmaReader.ts +0 -81
- package/src/coders/sigmaWriter.ts +0 -106
- package/src/coders/vlq.ts +0 -141
- package/src/coders/zigZag.ts +0 -46
- package/src/index.ts +0 -4
- package/src/serializers/boxSerializer.ts +0 -139
- package/src/serializers/dataSerializer.ts +0 -141
- package/src/serializers/index.ts +0 -4
- package/src/serializers/transactionSerializer.ts +0 -76
- package/src/serializers/typeSerializer.ts +0 -148
- package/src/sigmaConstant.ts +0 -59
- package/src/types/base.ts +0 -46
- package/src/types/constructors.test-d.ts +0 -147
- package/src/types/constructors.ts +0 -144
- package/src/types/descriptors.ts +0 -105
- package/src/types/generics.ts +0 -42
- package/src/types/index.ts +0 -18
- package/src/types/monomorphics.ts +0 -11
- package/src/types/primitives.ts +0 -97
@@ -1,76 +0,0 @@
|
|
1
|
-
import {
|
2
|
-
Amount,
|
3
|
-
BoxCandidate,
|
4
|
-
ContextExtension,
|
5
|
-
DataInput,
|
6
|
-
isDefined,
|
7
|
-
UnsignedInput
|
8
|
-
} from "@fleet-sdk/common";
|
9
|
-
import { SigmaWriter } from "../coders";
|
10
|
-
import { serializeBox } from "./boxSerializer";
|
11
|
-
|
12
|
-
export type MinimalUnsignedTransaction = {
|
13
|
-
inputs: readonly UnsignedInput[];
|
14
|
-
dataInputs: readonly DataInput[];
|
15
|
-
outputs: readonly BoxCandidate<Amount>[];
|
16
|
-
};
|
17
|
-
|
18
|
-
export function serializeTransaction(transaction: MinimalUnsignedTransaction): SigmaWriter {
|
19
|
-
const writer = new SigmaWriter(100_000);
|
20
|
-
|
21
|
-
// write inputs
|
22
|
-
writer.writeVLQ(transaction.inputs.length);
|
23
|
-
transaction.inputs.map((input) => writeInput(writer, input));
|
24
|
-
|
25
|
-
// write data inputs
|
26
|
-
writer.writeVLQ(transaction.dataInputs.length);
|
27
|
-
transaction.dataInputs.map((dataInput) => writer.writeHex(dataInput.boxId));
|
28
|
-
|
29
|
-
// write distinct token IDs
|
30
|
-
const distinctTokenIds = getDistinctTokenIds(transaction.outputs);
|
31
|
-
writer.writeVLQ(distinctTokenIds.length);
|
32
|
-
distinctTokenIds.map((tokenId) => writer.writeHex(tokenId));
|
33
|
-
|
34
|
-
// write outputs
|
35
|
-
writer.writeVLQ(transaction.outputs.length);
|
36
|
-
transaction.outputs.map((output) => serializeBox(output, writer, distinctTokenIds));
|
37
|
-
|
38
|
-
return writer;
|
39
|
-
}
|
40
|
-
|
41
|
-
function writeInput(writer: SigmaWriter, input: UnsignedInput): void {
|
42
|
-
writer.writeHex(input.boxId);
|
43
|
-
writer.write(0); // empty proof
|
44
|
-
writeExtension(writer, input.extension);
|
45
|
-
}
|
46
|
-
|
47
|
-
function writeExtension(writer: SigmaWriter, extension: ContextExtension): void {
|
48
|
-
const keys = Object.keys(extension);
|
49
|
-
let length = 0;
|
50
|
-
|
51
|
-
for (const key of keys) {
|
52
|
-
const ext = extension[key as unknown as keyof ContextExtension];
|
53
|
-
if (isDefined(ext)) {
|
54
|
-
length++;
|
55
|
-
}
|
56
|
-
}
|
57
|
-
|
58
|
-
writer.writeVLQ(length);
|
59
|
-
if (length == 0) {
|
60
|
-
return;
|
61
|
-
}
|
62
|
-
|
63
|
-
for (const key of keys) {
|
64
|
-
const ext = extension[key as unknown as keyof ContextExtension];
|
65
|
-
if (isDefined(ext)) {
|
66
|
-
writer.writeVLQ(Number(key)).writeHex(ext);
|
67
|
-
}
|
68
|
-
}
|
69
|
-
}
|
70
|
-
|
71
|
-
function getDistinctTokenIds(outputs: readonly BoxCandidate<Amount>[]) {
|
72
|
-
const tokenIds = new Set<string>();
|
73
|
-
outputs.flatMap((output) => output.assets.map((asset) => tokenIds.add(asset.tokenId)));
|
74
|
-
|
75
|
-
return Array.from(tokenIds);
|
76
|
-
}
|
@@ -1,148 +0,0 @@
|
|
1
|
-
import { assert, first, last } from "@fleet-sdk/common";
|
2
|
-
import { SigmaReader, SigmaWriter } from "../coders";
|
3
|
-
import { isColl, isTuple, SCollType, STupleType, SType } from "../types";
|
4
|
-
import {
|
5
|
-
constructorCode,
|
6
|
-
descriptors,
|
7
|
-
getPrimitiveType,
|
8
|
-
PRIMITIVE_TYPE_RANGE
|
9
|
-
} from "../types/descriptors";
|
10
|
-
|
11
|
-
export class TypeSerializer {
|
12
|
-
static serialize(type: SType, writer: SigmaWriter) {
|
13
|
-
if (type.embeddable) {
|
14
|
-
writer.write(type.code);
|
15
|
-
} else if (type.code === descriptors.unit.code) {
|
16
|
-
writer.write(type.code);
|
17
|
-
} else if (isColl(type)) {
|
18
|
-
if (type.elementsType.embeddable) {
|
19
|
-
writer.write(descriptors.coll.simpleCollTypeCode + type.elementsType.code);
|
20
|
-
} else if (isColl(type.elementsType)) {
|
21
|
-
const nestedColl = type.elementsType;
|
22
|
-
if (nestedColl.elementsType.embeddable) {
|
23
|
-
writer.write(descriptors.coll.nestedCollTypeCode + nestedColl.elementsType.code);
|
24
|
-
} else {
|
25
|
-
writer.write(descriptors.coll.simpleCollTypeCode);
|
26
|
-
this.serialize(nestedColl, writer);
|
27
|
-
}
|
28
|
-
} else {
|
29
|
-
writer.write(descriptors.coll.simpleCollTypeCode);
|
30
|
-
this.serialize(type.elementsType, writer);
|
31
|
-
}
|
32
|
-
} else if (isTuple(type)) {
|
33
|
-
switch (type.elementsType.length) {
|
34
|
-
case 2: {
|
35
|
-
const left = first(type.elementsType);
|
36
|
-
const right = last(type.elementsType);
|
37
|
-
|
38
|
-
if (left.embeddable) {
|
39
|
-
if (left.code === right.code) {
|
40
|
-
// Symmetric pair of primitive types (`(Int, Int)`, `(Byte,Byte)`, etc.)
|
41
|
-
writer.write(descriptors.tuple.symmetricPairTypeCode + left.code);
|
42
|
-
} else {
|
43
|
-
// Pair of types where first is primitive (`(_, Int)`)
|
44
|
-
writer.write(descriptors.tuple.pairOneTypeCode + left.code);
|
45
|
-
this.serialize(right, writer);
|
46
|
-
}
|
47
|
-
} else if (right.embeddable) {
|
48
|
-
// Pair of types where second is primitive (`(Int, _)`)
|
49
|
-
writer.write(descriptors.tuple.pairTwoTypeCode + right.code);
|
50
|
-
this.serialize(left, writer);
|
51
|
-
} else {
|
52
|
-
// Pair of non-primitive types (`((Int, Byte), (Boolean,Box))`, etc.)
|
53
|
-
writer.write(descriptors.tuple.pairOneTypeCode);
|
54
|
-
this.serialize(left, writer);
|
55
|
-
this.serialize(right, writer);
|
56
|
-
}
|
57
|
-
|
58
|
-
return;
|
59
|
-
}
|
60
|
-
case 3:
|
61
|
-
writer.write(descriptors.tuple.tripleTypeCode);
|
62
|
-
break;
|
63
|
-
case 4:
|
64
|
-
writer.write(descriptors.tuple.quadrupleTypeCode);
|
65
|
-
break;
|
66
|
-
default: {
|
67
|
-
const len = type.elementsType.length;
|
68
|
-
assert(len >= 2 && len <= 255, "Invalid type: tuples must have between 2 and 255 items.");
|
69
|
-
|
70
|
-
// Generic tuple
|
71
|
-
writer.write(descriptors.tuple.genericTupleTypeCode);
|
72
|
-
writer.writeVLQ(len);
|
73
|
-
}
|
74
|
-
}
|
75
|
-
|
76
|
-
for (let i = 0; i < type.elementsType.length; i++) {
|
77
|
-
this.serialize(type.elementsType[i], writer);
|
78
|
-
}
|
79
|
-
} else {
|
80
|
-
throw new Error("Serialization error: type not implemented.");
|
81
|
-
}
|
82
|
-
}
|
83
|
-
|
84
|
-
static deserialize(r: SigmaReader): SType {
|
85
|
-
const byte = r.readByte();
|
86
|
-
assert(byte > 0, `Parsing Error: Unexpected type code '0x${byte.toString(16)}'`);
|
87
|
-
|
88
|
-
if (byte < descriptors.tuple.genericTupleTypeCode) {
|
89
|
-
const ctorCode = Math.floor(byte / PRIMITIVE_TYPE_RANGE);
|
90
|
-
const embdCode = Math.floor(byte % PRIMITIVE_TYPE_RANGE);
|
91
|
-
|
92
|
-
switch (ctorCode) {
|
93
|
-
case constructorCode.embeddable: {
|
94
|
-
return getPrimitiveType(embdCode);
|
95
|
-
}
|
96
|
-
case constructorCode.simpleColl: {
|
97
|
-
const internal = embdCode === 0 ? this.deserialize(r) : getPrimitiveType(embdCode);
|
98
|
-
|
99
|
-
return new SCollType(internal);
|
100
|
-
}
|
101
|
-
case constructorCode.nestedColl: {
|
102
|
-
return new SCollType(new SCollType(getPrimitiveType(embdCode)));
|
103
|
-
}
|
104
|
-
case constructorCode.pairOne: {
|
105
|
-
const internal =
|
106
|
-
embdCode === 0
|
107
|
-
? [this.deserialize(r), this.deserialize(r)] // Pair of non-primitive types (`((Int, Byte), (Boolean,Box))`, etc.)
|
108
|
-
: [getPrimitiveType(embdCode), this.deserialize(r)]; // Pair of types where first is primitive (`(_, Int)`)
|
109
|
-
|
110
|
-
return new STupleType(internal);
|
111
|
-
}
|
112
|
-
case constructorCode.pairTwo: {
|
113
|
-
const internal =
|
114
|
-
embdCode === 0
|
115
|
-
? [this.deserialize(r), this.deserialize(r), this.deserialize(r)] // Triple of types
|
116
|
-
: [this.deserialize(r), getPrimitiveType(embdCode)];
|
117
|
-
|
118
|
-
return new STupleType(internal);
|
119
|
-
}
|
120
|
-
case constructorCode.symmetricPair: {
|
121
|
-
const internal =
|
122
|
-
embdCode === 0
|
123
|
-
? [this.deserialize(r), this.deserialize(r), this.deserialize(r), this.deserialize(r)] // Quadruple of types
|
124
|
-
: [getPrimitiveType(embdCode), getPrimitiveType(embdCode)]; // Symmetric pair of primitive types (`(Int, Int)`, `(Byte,Byte)`, etc.)
|
125
|
-
|
126
|
-
return new STupleType(internal);
|
127
|
-
}
|
128
|
-
}
|
129
|
-
} else {
|
130
|
-
switch (byte) {
|
131
|
-
case descriptors.tuple.genericTupleTypeCode: {
|
132
|
-
const len = r.readVlq();
|
133
|
-
const wrapped = new Array<SType>(len);
|
134
|
-
for (let i = 0; i < len; i++) {
|
135
|
-
wrapped[i] = this.deserialize(r);
|
136
|
-
}
|
137
|
-
|
138
|
-
return new STupleType(wrapped);
|
139
|
-
}
|
140
|
-
case descriptors.unit.code: {
|
141
|
-
return descriptors.unit;
|
142
|
-
}
|
143
|
-
}
|
144
|
-
}
|
145
|
-
|
146
|
-
throw new Error("Not implemented.");
|
147
|
-
}
|
148
|
-
}
|
package/src/sigmaConstant.ts
DELETED
@@ -1,59 +0,0 @@
|
|
1
|
-
import { BytesInput, hex } from "@fleet-sdk/crypto";
|
2
|
-
import { SigmaReader, SigmaWriter } from "./coders";
|
3
|
-
import { DataSerializer } from "./serializers/dataSerializer";
|
4
|
-
import { TypeSerializer } from "./serializers/typeSerializer";
|
5
|
-
import { SType } from "./types";
|
6
|
-
|
7
|
-
export const MAX_CONSTANT_LENGTH = 4096;
|
8
|
-
|
9
|
-
export class SConstant<D = unknown, T extends SType = SType> {
|
10
|
-
readonly #type: T;
|
11
|
-
readonly #data: D;
|
12
|
-
|
13
|
-
constructor(type: T, data: D) {
|
14
|
-
this.#type = type;
|
15
|
-
this.#data = type.coerce(data) as D;
|
16
|
-
}
|
17
|
-
|
18
|
-
static from<D, T extends SType = SType>(bytes: BytesInput): SConstant<D, T> {
|
19
|
-
const reader = new SigmaReader(bytes);
|
20
|
-
const type = TypeSerializer.deserialize(reader);
|
21
|
-
const data = DataSerializer.deserialize(type, reader);
|
22
|
-
|
23
|
-
return new SConstant(type as T, data as D);
|
24
|
-
}
|
25
|
-
|
26
|
-
get type(): T {
|
27
|
-
return this.#type;
|
28
|
-
}
|
29
|
-
|
30
|
-
get data(): D {
|
31
|
-
return this.#data;
|
32
|
-
}
|
33
|
-
|
34
|
-
toBytes(): Uint8Array {
|
35
|
-
const writer = new SigmaWriter(MAX_CONSTANT_LENGTH);
|
36
|
-
TypeSerializer.serialize(this.type, writer);
|
37
|
-
DataSerializer.serialize(this.data, this.type, writer);
|
38
|
-
|
39
|
-
return writer.toBytes();
|
40
|
-
}
|
41
|
-
|
42
|
-
toHex(): string {
|
43
|
-
return hex.encode(this.toBytes());
|
44
|
-
}
|
45
|
-
}
|
46
|
-
|
47
|
-
export function parse<T>(bytes: BytesInput): T;
|
48
|
-
export function parse<T>(bytes: BytesInput, mode: "strict"): T;
|
49
|
-
export function parse<T>(bytes: BytesInput, mode: "safe"): T | undefined;
|
50
|
-
export function parse<T>(bytes: BytesInput, mode: "strict" | "safe" = "strict") {
|
51
|
-
if (mode === "strict") return SConstant.from<T>(bytes).data;
|
52
|
-
if (!bytes) return;
|
53
|
-
|
54
|
-
try {
|
55
|
-
return SConstant.from<T>(bytes).data;
|
56
|
-
} catch {
|
57
|
-
return;
|
58
|
-
}
|
59
|
-
}
|
package/src/types/base.ts
DELETED
@@ -1,46 +0,0 @@
|
|
1
|
-
export abstract class SType<I = unknown, O = I> {
|
2
|
-
abstract get code(): number;
|
3
|
-
abstract get embeddable(): boolean;
|
4
|
-
|
5
|
-
coerce(data: I): O {
|
6
|
-
// a bit hacky but most of types will not need a specific coercion function.
|
7
|
-
return data as unknown as O;
|
8
|
-
}
|
9
|
-
|
10
|
-
abstract toString(): string;
|
11
|
-
}
|
12
|
-
|
13
|
-
export abstract class SMonomorphicType<I, O = I> extends SType<I, O> {
|
14
|
-
abstract get code(): number;
|
15
|
-
|
16
|
-
get embeddable(): boolean {
|
17
|
-
return false;
|
18
|
-
}
|
19
|
-
}
|
20
|
-
|
21
|
-
export abstract class SPrimitiveType<I, O = I> extends SMonomorphicType<I, O> {
|
22
|
-
abstract get code(): number;
|
23
|
-
|
24
|
-
override get embeddable(): boolean {
|
25
|
-
return true;
|
26
|
-
}
|
27
|
-
}
|
28
|
-
|
29
|
-
export abstract class SGenericType<T extends SType | SType[]> extends SType {
|
30
|
-
readonly #internalType: T;
|
31
|
-
|
32
|
-
constructor(type: T) {
|
33
|
-
super();
|
34
|
-
this.#internalType = type;
|
35
|
-
}
|
36
|
-
|
37
|
-
abstract get code(): number;
|
38
|
-
|
39
|
-
get elementsType(): T {
|
40
|
-
return this.#internalType;
|
41
|
-
}
|
42
|
-
|
43
|
-
get embeddable(): boolean {
|
44
|
-
return false;
|
45
|
-
}
|
46
|
-
}
|
@@ -1,147 +0,0 @@
|
|
1
|
-
import { describe, expectTypeOf, it } from "vitest";
|
2
|
-
import { SConstant } from "../sigmaConstant";
|
3
|
-
import {
|
4
|
-
ByteInput,
|
5
|
-
SBigInt,
|
6
|
-
SBool,
|
7
|
-
SByte,
|
8
|
-
SColl,
|
9
|
-
SConstructor,
|
10
|
-
SGroupElement,
|
11
|
-
SInt,
|
12
|
-
SLong,
|
13
|
-
SPair,
|
14
|
-
SShort,
|
15
|
-
SSigmaProp,
|
16
|
-
SUnit
|
17
|
-
} from "./constructors";
|
18
|
-
import { SUnitType } from "./monomorphics";
|
19
|
-
import {
|
20
|
-
SBigIntType,
|
21
|
-
SBoolType,
|
22
|
-
SByteType,
|
23
|
-
SGroupElementType,
|
24
|
-
SIntType,
|
25
|
-
SLongType,
|
26
|
-
SShortType,
|
27
|
-
SSigmaPropType
|
28
|
-
} from "./primitives";
|
29
|
-
|
30
|
-
describe("Constructor proxies types", () => {
|
31
|
-
it("Should ensure correct types for monomorphics.", () => {
|
32
|
-
expectTypeOf(SByte).parameter(0).toMatchTypeOf<number | undefined>();
|
33
|
-
expectTypeOf(SByte()).toMatchTypeOf<SByteType>();
|
34
|
-
expectTypeOf(SByte(1)).toMatchTypeOf<SConstant<number, SByteType>>();
|
35
|
-
|
36
|
-
expectTypeOf(SBool).parameter(0).toMatchTypeOf<boolean | undefined>();
|
37
|
-
expectTypeOf(SBool()).toMatchTypeOf<SBoolType>();
|
38
|
-
expectTypeOf(SBool(true)).toMatchTypeOf<SConstant<boolean, SBoolType>>();
|
39
|
-
|
40
|
-
expectTypeOf(SShort).parameter(0).toMatchTypeOf<number | undefined>();
|
41
|
-
expectTypeOf(SShort()).toMatchTypeOf<SShortType>();
|
42
|
-
expectTypeOf(SShort(1)).toMatchTypeOf<SConstant<number, SShortType>>();
|
43
|
-
|
44
|
-
expectTypeOf(SInt).parameter(0).toMatchTypeOf<number | undefined>();
|
45
|
-
expectTypeOf(SInt()).toMatchTypeOf<SIntType>();
|
46
|
-
expectTypeOf(SInt(1)).toMatchTypeOf<SConstant<number, SIntType>>();
|
47
|
-
|
48
|
-
expectTypeOf(SLong).parameter(0).toMatchTypeOf<string | bigint | undefined>();
|
49
|
-
expectTypeOf(SLong()).toMatchTypeOf<SLongType>();
|
50
|
-
expectTypeOf(SLong(1n)).toMatchTypeOf<SConstant<bigint, SLongType>>();
|
51
|
-
expectTypeOf(SLong("1")).toMatchTypeOf<SConstant<bigint, SLongType>>();
|
52
|
-
|
53
|
-
expectTypeOf(SBigInt).parameter(0).toMatchTypeOf<string | bigint | undefined>();
|
54
|
-
expectTypeOf(SBigInt()).toMatchTypeOf<SBigIntType>();
|
55
|
-
expectTypeOf(SBigInt(1n)).toMatchTypeOf<SConstant<bigint, SBigIntType>>();
|
56
|
-
expectTypeOf(SBigInt("1")).toMatchTypeOf<SConstant<bigint, SBigIntType>>();
|
57
|
-
|
58
|
-
expectTypeOf(SGroupElement).parameter(0).toMatchTypeOf<Uint8Array | string | undefined>();
|
59
|
-
expectTypeOf(SGroupElement()).toMatchTypeOf<SGroupElementType>();
|
60
|
-
expectTypeOf(SGroupElement(Uint8Array.from([1, 2, 3]))).toMatchTypeOf<
|
61
|
-
SConstant<Uint8Array, SGroupElementType>
|
62
|
-
>();
|
63
|
-
expectTypeOf(SGroupElement("deadbeef")).toMatchTypeOf<
|
64
|
-
SConstant<Uint8Array, SGroupElementType>
|
65
|
-
>();
|
66
|
-
|
67
|
-
expectTypeOf(SSigmaProp).parameter(0).toMatchTypeOf<SConstant<Uint8Array> | undefined>();
|
68
|
-
expectTypeOf(SSigmaProp()).toMatchTypeOf<SSigmaPropType>();
|
69
|
-
expectTypeOf(SSigmaProp(SGroupElement("deadbeef"))).toMatchTypeOf<
|
70
|
-
SConstant<SConstant<Uint8Array>, SSigmaPropType>
|
71
|
-
>();
|
72
|
-
|
73
|
-
expectTypeOf(SUnit()).not.toMatchTypeOf<SUnitType>();
|
74
|
-
expectTypeOf(SUnit()).toMatchTypeOf<SConstant<undefined, SUnitType>>();
|
75
|
-
});
|
76
|
-
|
77
|
-
it("Should ensure correct types for generics", () => {
|
78
|
-
expectTypeOf(SColl(SByte)).toMatchTypeOf<SConstructor<number[], SByteType>>();
|
79
|
-
expectTypeOf(SColl(SBool)).toMatchTypeOf<SConstructor<boolean[], SBoolType>>();
|
80
|
-
expectTypeOf(SColl(SShort)).toMatchTypeOf<SConstructor<number[], SShortType>>();
|
81
|
-
expectTypeOf(SColl(SInt)).toMatchTypeOf<SConstructor<number[], SIntType>>();
|
82
|
-
expectTypeOf(SColl(SLong)).toMatchTypeOf<SConstructor<bigint[], SLongType>>();
|
83
|
-
expectTypeOf(SColl(SBigInt)).toMatchTypeOf<SConstructor<bigint[], SBigIntType>>();
|
84
|
-
expectTypeOf(SColl(SGroupElement)).toMatchTypeOf<
|
85
|
-
SConstructor<Uint8Array[], SGroupElementType>
|
86
|
-
>();
|
87
|
-
expectTypeOf(SColl(SSigmaProp)).toMatchTypeOf<
|
88
|
-
SConstructor<SConstant<Uint8Array>[], SSigmaPropType>
|
89
|
-
>();
|
90
|
-
|
91
|
-
expectTypeOf(
|
92
|
-
SColl(SPair(SColl(SByte), SColl(SByte)), [
|
93
|
-
[Uint8Array.from([1, 2, 3]), "deadbeef"],
|
94
|
-
[
|
95
|
-
[1, 2, 3],
|
96
|
-
[4, 5, 6]
|
97
|
-
]
|
98
|
-
]).data
|
99
|
-
).toMatchTypeOf<[ByteInput | number[], ByteInput | number[]][]>();
|
100
|
-
|
101
|
-
expectTypeOf(
|
102
|
-
SColl(SPair(SColl(SBool), SColl(SByte)), [
|
103
|
-
[[true, false], "deadbeef"],
|
104
|
-
[
|
105
|
-
[false, true],
|
106
|
-
[4, 5, 6]
|
107
|
-
]
|
108
|
-
]).data
|
109
|
-
).toMatchTypeOf<[boolean[], ByteInput | number[]][]>();
|
110
|
-
|
111
|
-
expectTypeOf(SColl(SBool, [true, false, true, true]).data).toMatchTypeOf<boolean[]>();
|
112
|
-
|
113
|
-
expectTypeOf(SColl(SByte, "deadbeef").data).toMatchTypeOf<Uint8Array>();
|
114
|
-
expectTypeOf(SColl(SByte, [1, 2]).data).toMatchTypeOf<Uint8Array>();
|
115
|
-
expectTypeOf(SColl(SByte, Uint8Array.from([1])).data).toMatchTypeOf<Uint8Array>();
|
116
|
-
expectTypeOf(SColl(SInt, [1, 2, 3]).data).toMatchTypeOf<number[]>();
|
117
|
-
expectTypeOf(
|
118
|
-
SColl(SColl(SBool), [
|
119
|
-
[true, false],
|
120
|
-
[false, false]
|
121
|
-
]).data
|
122
|
-
).toMatchTypeOf<boolean[][]>();
|
123
|
-
|
124
|
-
expectTypeOf(SPair(SInt(1), SBool(false)).data).toMatchTypeOf<[number, boolean]>();
|
125
|
-
expectTypeOf(SPair(SBool(true), SInt(1)).data).toMatchTypeOf<[boolean, number]>();
|
126
|
-
expectTypeOf(SPair(SInt(1), SLong("1")).data).toMatchTypeOf<[number, bigint]>();
|
127
|
-
expectTypeOf(SPair(SPair(SBool(true), SInt(1)), SLong("1")).data).toMatchTypeOf<
|
128
|
-
[[boolean, number], bigint]
|
129
|
-
>();
|
130
|
-
|
131
|
-
// @ts-expect-error elements should be boolean[]
|
132
|
-
SColl(SPair(SColl(SByte), SColl(SInt)), [[[1, 2, 3], 1]]);
|
133
|
-
// @ts-expect-error elements should be boolean[]
|
134
|
-
SColl(SBool, [true, false, true, 1]);
|
135
|
-
// @ts-expect-error elements should be number[]
|
136
|
-
SColl(SInt, Uint8Array.from([1]));
|
137
|
-
// @ts-expect-error elements should be number[]
|
138
|
-
SColl(SShort, "");
|
139
|
-
// @ts-expect-error elements should be number[]
|
140
|
-
SColl(SShort, {});
|
141
|
-
// @ts-expect-error elements should be boolean[][]
|
142
|
-
SColl(SColl(SBool), [
|
143
|
-
[true, false],
|
144
|
-
[false, "true"]
|
145
|
-
]);
|
146
|
-
});
|
147
|
-
});
|
@@ -1,144 +0,0 @@
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
2
|
-
/* eslint-disable @typescript-eslint/naming-convention */
|
3
|
-
import { isEmpty } from "@fleet-sdk/common";
|
4
|
-
import { SConstant } from "../sigmaConstant";
|
5
|
-
import { SType } from "./base";
|
6
|
-
import { descriptors } from "./descriptors";
|
7
|
-
import { SCollType, STupleType } from "./generics";
|
8
|
-
import { SUnitType } from "./monomorphics";
|
9
|
-
import {
|
10
|
-
SBigIntType,
|
11
|
-
SBoolType,
|
12
|
-
SByteType,
|
13
|
-
SGroupElementType,
|
14
|
-
SIntType,
|
15
|
-
SLongType,
|
16
|
-
SShortType,
|
17
|
-
SSigmaPropType
|
18
|
-
} from "./primitives";
|
19
|
-
|
20
|
-
export type BigIntInput = string | bigint;
|
21
|
-
export type ByteInput = Uint8Array | string;
|
22
|
-
|
23
|
-
export type SConstructor<T = unknown, S extends SType = SType | SCollType<SType>> = (arg?: T) => S;
|
24
|
-
|
25
|
-
type Constructable<T = any> = { new (...args: any): T };
|
26
|
-
type GenericProxyArgs<R> = R extends (...args: any) => unknown ? Parameters<R> : [];
|
27
|
-
|
28
|
-
type SProxy<T extends SType, I, O = I> = {
|
29
|
-
(value: I): SConstant<O, T>;
|
30
|
-
(value?: I): T;
|
31
|
-
};
|
32
|
-
|
33
|
-
/**
|
34
|
-
* Creates a proxy for monomorphic types, this allows constructor
|
35
|
-
* functions to be equivalent to their corresponding type.
|
36
|
-
*
|
37
|
-
* This function will return one instance of `ctor` if not params as set.
|
38
|
-
* Otherwise it will return an `SigmaConstant` instance of `ctor` type.
|
39
|
-
*
|
40
|
-
* @example
|
41
|
-
* // SInt is a proxy for SIntType
|
42
|
-
* (intConstant instanceof SInt) === true
|
43
|
-
* (intConstant instanceof SIntType) === true
|
44
|
-
* @param ctor Class to be proxied.
|
45
|
-
* @param cache If defined, proxy will return this instead of a new instance of `ctor`.
|
46
|
-
* @param forceConstruction If true, bypasses the constant creation and returns a type.
|
47
|
-
* @returns
|
48
|
-
*/
|
49
|
-
function monoProxy<T extends SType, I, O = I>(
|
50
|
-
ctor: Constructable<T>,
|
51
|
-
cache?: T,
|
52
|
-
forceConstruction?: boolean
|
53
|
-
): SProxy<T, I, O> {
|
54
|
-
return new Proxy(ctor, {
|
55
|
-
apply: (target, _, args) => {
|
56
|
-
const instance = cache ?? new target();
|
57
|
-
if (!forceConstruction && isEmpty(args)) return instance;
|
58
|
-
|
59
|
-
return new (SConstant as Constructable)(instance, ...args);
|
60
|
-
}
|
61
|
-
}) as any;
|
62
|
-
}
|
63
|
-
|
64
|
-
/**
|
65
|
-
* Creates a proxy for generic types.
|
66
|
-
*/
|
67
|
-
function genericProxy<T extends SType, R>(
|
68
|
-
ctor: Constructable<T>,
|
69
|
-
handler: (target: Constructable<T>, thisArgs: unknown, args: GenericProxyArgs<R>) => unknown
|
70
|
-
) {
|
71
|
-
return new Proxy(ctor, {
|
72
|
-
apply: handler
|
73
|
-
}) as R;
|
74
|
-
}
|
75
|
-
|
76
|
-
export const SByte = monoProxy<SByteType, number>(SByteType, descriptors.byte);
|
77
|
-
|
78
|
-
export const SBool = monoProxy<SBoolType, boolean>(SBoolType, descriptors.bool);
|
79
|
-
|
80
|
-
export const SShort = monoProxy<SShortType, number>(SShortType, descriptors.short);
|
81
|
-
|
82
|
-
export const SInt = monoProxy<SIntType, number>(SIntType, descriptors.int);
|
83
|
-
|
84
|
-
export const SLong = monoProxy<SLongType, BigIntInput, bigint>(SLongType, descriptors.long);
|
85
|
-
|
86
|
-
export const SBigInt = monoProxy<SBigIntType, BigIntInput, bigint>(SBigIntType, descriptors.bigInt);
|
87
|
-
|
88
|
-
export const SGroupElement = monoProxy<SGroupElementType, ByteInput, Uint8Array>(
|
89
|
-
SGroupElementType,
|
90
|
-
descriptors.groupElement
|
91
|
-
);
|
92
|
-
|
93
|
-
export const SSigmaProp = monoProxy<SSigmaPropType, SConstant<Uint8Array>>(
|
94
|
-
SSigmaPropType,
|
95
|
-
descriptors.sigmaProp
|
96
|
-
);
|
97
|
-
|
98
|
-
type SUnit = (value?: undefined) => SConstant<undefined, SUnitType>;
|
99
|
-
export const SUnit: SUnit = monoProxy(SUnitType, undefined, true);
|
100
|
-
|
101
|
-
type SColl = {
|
102
|
-
<D, T extends SType>(type: SConstructor<D, T>): SConstructor<D[], T>;
|
103
|
-
<D, T extends SByteType>(
|
104
|
-
type: SConstructor<D, T>,
|
105
|
-
elements: ByteInput | D[]
|
106
|
-
): SConstant<Uint8Array, T>;
|
107
|
-
<D, T extends SType>(type: SConstructor<D, T>, elements: D[]): SConstant<D[], T>;
|
108
|
-
};
|
109
|
-
|
110
|
-
export const SColl = genericProxy<SCollType, SColl>(SCollType, (target, _, args) => {
|
111
|
-
const [type, elements] = args;
|
112
|
-
const elementsType = type();
|
113
|
-
if (!elements) return () => new target(elementsType);
|
114
|
-
|
115
|
-
return new SConstant(new target(elementsType), elements);
|
116
|
-
});
|
117
|
-
|
118
|
-
export function STuple(...items: SConstant[]) {
|
119
|
-
return new SConstant(
|
120
|
-
new STupleType(items.map((x) => x.type)),
|
121
|
-
items.map((x) => x.data)
|
122
|
-
);
|
123
|
-
}
|
124
|
-
|
125
|
-
type ByteInputOr<D, T extends SType> = T extends SByteType ? ByteInput | D : D;
|
126
|
-
type SPair = {
|
127
|
-
<L, R>(left: SConstant<L>, right: SConstant<R>): SConstant<[L, R], STupleType>;
|
128
|
-
<LD, RD, LT extends SType, RT extends SType>(
|
129
|
-
left: SConstructor<LD, LT>,
|
130
|
-
right: SConstructor<RD, RT>
|
131
|
-
): SConstructor<[ByteInputOr<LD, LT>, ByteInputOr<RD, RT>]>;
|
132
|
-
};
|
133
|
-
|
134
|
-
export const SPair = genericProxy<STupleType, SPair>(STupleType, (target, _, args) => {
|
135
|
-
const [left, right] = args;
|
136
|
-
|
137
|
-
if (typeof left === "function" && typeof right === "function") {
|
138
|
-
return () => new target([left(), right()]);
|
139
|
-
} else if (left instanceof SConstant && right instanceof SConstant) {
|
140
|
-
return new SConstant(new target([left.type, right.type]), [left.data, right.data]);
|
141
|
-
}
|
142
|
-
|
143
|
-
throw new Error("Invalid tuple declaration.");
|
144
|
-
});
|