@proto-kit/common 0.1.1-develop.1086
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/LICENSE.md +201 -0
- package/dist/config/ChildContainerCreatable.d.ts +5 -0
- package/dist/config/ChildContainerCreatable.d.ts.map +1 -0
- package/dist/config/ChildContainerCreatable.js +1 -0
- package/dist/config/ChildContainerProvider.d.ts +5 -0
- package/dist/config/ChildContainerProvider.d.ts.map +1 -0
- package/dist/config/ChildContainerProvider.js +1 -0
- package/dist/config/ConfigurableModule.d.ts +25 -0
- package/dist/config/ConfigurableModule.d.ts.map +1 -0
- package/dist/config/ConfigurableModule.js +23 -0
- package/dist/config/ModuleContainer.d.ts +161 -0
- package/dist/config/ModuleContainer.d.ts.map +1 -0
- package/dist/config/ModuleContainer.js +278 -0
- package/dist/dependencyFactory/DependencyFactory.d.ts +29 -0
- package/dist/dependencyFactory/DependencyFactory.d.ts.map +1 -0
- package/dist/dependencyFactory/DependencyFactory.js +1 -0
- package/dist/dependencyFactory/injectOptional.d.ts +16 -0
- package/dist/dependencyFactory/injectOptional.d.ts.map +1 -0
- package/dist/dependencyFactory/injectOptional.js +39 -0
- package/dist/events/EventEmitter.d.ts +19 -0
- package/dist/events/EventEmitter.d.ts.map +1 -0
- package/dist/events/EventEmitter.js +34 -0
- package/dist/events/EventEmitterProxy.d.ts +17 -0
- package/dist/events/EventEmitterProxy.d.ts.map +1 -0
- package/dist/events/EventEmitterProxy.js +23 -0
- package/dist/events/EventEmittingComponent.d.ts +6 -0
- package/dist/events/EventEmittingComponent.d.ts.map +1 -0
- package/dist/events/EventEmittingComponent.js +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/log.d.ts +20 -0
- package/dist/log.d.ts.map +1 -0
- package/dist/log.js +75 -0
- package/dist/test/equalProvable.d.ts +20 -0
- package/dist/test/equalProvable.d.ts.map +1 -0
- package/dist/test/equalProvable.js +13 -0
- package/dist/trees/InMemoryMerkleTreeStorage.d.ts +11 -0
- package/dist/trees/InMemoryMerkleTreeStorage.d.ts.map +1 -0
- package/dist/trees/InMemoryMerkleTreeStorage.js +12 -0
- package/dist/trees/MerkleTreeStore.d.ts +5 -0
- package/dist/trees/MerkleTreeStore.d.ts.map +1 -0
- package/dist/trees/MerkleTreeStore.js +1 -0
- package/dist/trees/MockAsyncMerkleStore.d.ts +9 -0
- package/dist/trees/MockAsyncMerkleStore.d.ts.map +1 -0
- package/dist/trees/MockAsyncMerkleStore.js +19 -0
- package/dist/trees/RollupMerkleTree.d.ts +147 -0
- package/dist/trees/RollupMerkleTree.d.ts.map +1 -0
- package/dist/trees/RollupMerkleTree.js +217 -0
- package/dist/trees/VirtualMerkleTreeStore.d.ts +13 -0
- package/dist/trees/VirtualMerkleTreeStore.d.ts.map +1 -0
- package/dist/trees/VirtualMerkleTreeStore.js +17 -0
- package/dist/types.d.ts +26 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +11 -0
- package/dist/utils.d.ts +35 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +73 -0
- package/dist/zkProgrammable/ProvableMethodExecutionContext.d.ts +54 -0
- package/dist/zkProgrammable/ProvableMethodExecutionContext.d.ts.map +1 -0
- package/dist/zkProgrammable/ProvableMethodExecutionContext.js +96 -0
- package/dist/zkProgrammable/ZkProgrammable.d.ts +39 -0
- package/dist/zkProgrammable/ZkProgrammable.d.ts.map +1 -0
- package/dist/zkProgrammable/ZkProgrammable.js +67 -0
- package/dist/zkProgrammable/provableMethod.d.ts +19 -0
- package/dist/zkProgrammable/provableMethod.d.ts.map +1 -0
- package/dist/zkProgrammable/provableMethod.js +73 -0
- package/jest.config.cjs +1 -0
- package/package.json +34 -0
- package/src/config/ChildContainerCreatable.ts +5 -0
- package/src/config/ChildContainerProvider.ts +5 -0
- package/src/config/ConfigurableModule.ts +57 -0
- package/src/config/ModuleContainer.ts +472 -0
- package/src/dependencyFactory/DependencyFactory.ts +57 -0
- package/src/dependencyFactory/injectOptional.ts +41 -0
- package/src/events/EventEmitter.ts +61 -0
- package/src/events/EventEmitterProxy.ts +59 -0
- package/src/events/EventEmittingComponent.ts +7 -0
- package/src/index.ts +19 -0
- package/src/log.ts +97 -0
- package/src/trees/InMemoryMerkleTreeStorage.ts +17 -0
- package/src/trees/MerkleTreeStore.ts +5 -0
- package/src/trees/MockAsyncMerkleStore.ts +30 -0
- package/src/trees/RollupMerkleTree.ts +356 -0
- package/src/trees/VirtualMerkleTreeStore.ts +20 -0
- package/src/types.ts +49 -0
- package/src/utils.ts +149 -0
- package/src/zkProgrammable/ProvableMethodExecutionContext.ts +122 -0
- package/src/zkProgrammable/ZkProgrammable.ts +131 -0
- package/src/zkProgrammable/provableMethod.ts +123 -0
- package/test/config/ContainerEvents.test.ts +67 -0
- package/test/config/ModuleContainer.test.ts +172 -0
- package/test/trees/MerkleTree.test.ts +106 -0
- package/test/tsconfig.json +7 -0
- package/test/zkProgrammable/ZkProgrammable.test.ts +304 -0
- package/tsconfig.json +8 -0
package/dist/utils.js
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { Field, Poseidon, } from "o1js";
|
|
2
|
+
export function requireTrue(condition, errorOrFunction) {
|
|
3
|
+
if (!condition) {
|
|
4
|
+
throw typeof errorOrFunction === "function"
|
|
5
|
+
? errorOrFunction()
|
|
6
|
+
: errorOrFunction;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
export function range(startOrEnd, endOrNothing) {
|
|
10
|
+
let end = endOrNothing;
|
|
11
|
+
let start = startOrEnd;
|
|
12
|
+
if (end === undefined) {
|
|
13
|
+
end = startOrEnd;
|
|
14
|
+
start = 0;
|
|
15
|
+
}
|
|
16
|
+
return Array.from({ length: end - start }, (ignored, index) => index + start);
|
|
17
|
+
}
|
|
18
|
+
export function reduceSequential(array, callbackfn, initialValue) {
|
|
19
|
+
return array.reduce(async (previousPromise, current, index, arr) => {
|
|
20
|
+
const previous = await previousPromise;
|
|
21
|
+
return await callbackfn(previous, current, index, arr);
|
|
22
|
+
}, Promise.resolve(initialValue));
|
|
23
|
+
}
|
|
24
|
+
export function mapSequential(array, f) {
|
|
25
|
+
return array.reduce(async (r, element, index, a) => {
|
|
26
|
+
const ret = await r;
|
|
27
|
+
const next = await f(element, index, a);
|
|
28
|
+
ret.push(next);
|
|
29
|
+
return ret;
|
|
30
|
+
}, Promise.resolve([]));
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Computes a dummy value for the given value type.
|
|
34
|
+
*
|
|
35
|
+
* @param valueType - Value type to generate the dummy value for
|
|
36
|
+
* @returns Dummy value for the given value type
|
|
37
|
+
*/
|
|
38
|
+
export function dummyValue(valueType) {
|
|
39
|
+
const length = valueType.sizeInFields();
|
|
40
|
+
const fields = Array.from({ length }, () => Field(0));
|
|
41
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
42
|
+
return valueType.fromFields(fields);
|
|
43
|
+
}
|
|
44
|
+
export function noop() { }
|
|
45
|
+
export async function sleep(ms) {
|
|
46
|
+
await new Promise((resolve) => {
|
|
47
|
+
setTimeout(resolve, ms);
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
export function filterNonNull(value) {
|
|
51
|
+
return value !== null;
|
|
52
|
+
}
|
|
53
|
+
export function filterNonUndefined(value) {
|
|
54
|
+
return value !== undefined;
|
|
55
|
+
}
|
|
56
|
+
const encoder = new TextEncoder();
|
|
57
|
+
// Copied from o1js binable.ts:317
|
|
58
|
+
export function prefixToField(prefix) {
|
|
59
|
+
const fieldSize = Field.sizeInBytes;
|
|
60
|
+
if (prefix.length >= fieldSize)
|
|
61
|
+
throw Error("prefix too long");
|
|
62
|
+
const stringBytes = [...encoder.encode(prefix)];
|
|
63
|
+
return Field.fromBytes(stringBytes.concat(Array(fieldSize - stringBytes.length).fill(0)));
|
|
64
|
+
}
|
|
65
|
+
export function hashWithPrefix(prefix, input) {
|
|
66
|
+
const salt = Poseidon.update([Field(0), Field(0), Field(0)], [prefixToField(prefix)]);
|
|
67
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
68
|
+
return Poseidon.update(salt, input)[0];
|
|
69
|
+
}
|
|
70
|
+
// end copy
|
|
71
|
+
export function expectDefined(value) {
|
|
72
|
+
expect(value).toBeDefined();
|
|
73
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { Proof } from "o1js";
|
|
2
|
+
import type { ArgumentTypes } from "./provableMethod";
|
|
3
|
+
export declare class ProvableMethodExecutionResult {
|
|
4
|
+
moduleName?: string;
|
|
5
|
+
methodName?: string;
|
|
6
|
+
args?: ArgumentTypes;
|
|
7
|
+
prover?: () => Promise<Proof<unknown, unknown>>;
|
|
8
|
+
prove<ProofType extends Proof<unknown, unknown>>(): Promise<ProofType>;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Execution context used to wrap runtime module methods,
|
|
12
|
+
* allowing them to post relevant information (such as execution status)
|
|
13
|
+
* into the context without any unnecessary 'prop drilling'.
|
|
14
|
+
*/
|
|
15
|
+
export declare class ProvableMethodExecutionContext {
|
|
16
|
+
id: string;
|
|
17
|
+
methods: string[];
|
|
18
|
+
result: ProvableMethodExecutionResult;
|
|
19
|
+
/**
|
|
20
|
+
* Adds a method prover to the current execution context,
|
|
21
|
+
* which can be collected and ran asynchronously at a later point in time.
|
|
22
|
+
*
|
|
23
|
+
* @param prove - Prover function to be ran later,
|
|
24
|
+
* when the method execution needs to be proven
|
|
25
|
+
*/
|
|
26
|
+
setProver(prover: () => Promise<Proof<unknown, unknown>>): void;
|
|
27
|
+
/**
|
|
28
|
+
* Adds a method to the method execution stack, reseting the execution context
|
|
29
|
+
* in a case a new top-level (non nested) method call is made.
|
|
30
|
+
*
|
|
31
|
+
* @param methodName - Name of the method being captured in the context
|
|
32
|
+
*/
|
|
33
|
+
beforeMethod(moduleName: string, methodName: string, args: ArgumentTypes): void;
|
|
34
|
+
/**
|
|
35
|
+
* Removes the latest method from the execution context stack,
|
|
36
|
+
* keeping track of the amount of 'unfinished' methods. Allowing
|
|
37
|
+
* for the context to distinguish between top-level and nested method calls.
|
|
38
|
+
*/
|
|
39
|
+
afterMethod(): void;
|
|
40
|
+
get isTopLevel(): boolean;
|
|
41
|
+
get isFinished(): boolean;
|
|
42
|
+
/**
|
|
43
|
+
* @returns - Current execution context state
|
|
44
|
+
*/
|
|
45
|
+
current(): {
|
|
46
|
+
isFinished: boolean;
|
|
47
|
+
result: ProvableMethodExecutionResult;
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Manually clears/resets the execution context
|
|
51
|
+
*/
|
|
52
|
+
clear(): void;
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=ProvableMethodExecutionContext.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProvableMethodExecutionContext.d.ts","sourceRoot":"","sources":["../../src/zkProgrammable/ProvableMethodExecutionContext.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,MAAM,CAAC;AAIlC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAWtD,qBAAa,6BAA6B;IACjC,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,IAAI,CAAC,EAAE,aAAa,CAAC;IAErB,MAAM,CAAC,EAAE,MAAM,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;IAE1C,KAAK,CAChB,SAAS,SAAS,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,KACtC,OAAO,CAAC,SAAS,CAAC;CAaxB;AAED;;;;GAIG;AACH,qBACa,8BAA8B;IAClC,EAAE,SAAc;IAEhB,OAAO,EAAE,MAAM,EAAE,CAAM;IAEvB,MAAM,EAAE,6BAA6B,CACN;IAGtC;;;;;;OAMG;IACI,SAAS,CAAC,MAAM,EAAE,MAAM,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAI/D;;;;;OAKG;IACI,YAAY,CACjB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,aAAa;IAYrB;;;;OAIG;IACI,WAAW;IAIlB,IAAW,UAAU,YAEpB;IAED,IAAW,UAAU,YAEpB;IAED;;OAEG;IACI,OAAO;;;;IAOd;;OAEG;IACI,KAAK;CAGb"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { singleton } from "tsyringe";
|
|
8
|
+
import uniqueId from "lodash/uniqueId";
|
|
9
|
+
const errors = {
|
|
10
|
+
moduleOrMethodNameNotSet: () => new Error("Module or method name not set"),
|
|
11
|
+
proverNotSet: (moduleName, methodName) => new Error(`Prover not set for '${moduleName}.${methodName}', did you forget to decorate your method?`),
|
|
12
|
+
};
|
|
13
|
+
export class ProvableMethodExecutionResult {
|
|
14
|
+
async prove() {
|
|
15
|
+
if (!this.prover) {
|
|
16
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
17
|
+
if (!this.moduleName || !this.methodName) {
|
|
18
|
+
throw errors.moduleOrMethodNameNotSet();
|
|
19
|
+
}
|
|
20
|
+
throw errors.proverNotSet(this.moduleName, this.methodName);
|
|
21
|
+
}
|
|
22
|
+
// turn the prover result into the desired proof type
|
|
23
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
24
|
+
return (await this.prover());
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Execution context used to wrap runtime module methods,
|
|
29
|
+
* allowing them to post relevant information (such as execution status)
|
|
30
|
+
* into the context without any unnecessary 'prop drilling'.
|
|
31
|
+
*/
|
|
32
|
+
export let ProvableMethodExecutionContext = class ProvableMethodExecutionContext {
|
|
33
|
+
constructor() {
|
|
34
|
+
this.id = uniqueId();
|
|
35
|
+
this.methods = [];
|
|
36
|
+
this.result = new ProvableMethodExecutionResult();
|
|
37
|
+
}
|
|
38
|
+
// TODO See if we should make this class generic, bc I think we can persist the type
|
|
39
|
+
/**
|
|
40
|
+
* Adds a method prover to the current execution context,
|
|
41
|
+
* which can be collected and ran asynchronously at a later point in time.
|
|
42
|
+
*
|
|
43
|
+
* @param prove - Prover function to be ran later,
|
|
44
|
+
* when the method execution needs to be proven
|
|
45
|
+
*/
|
|
46
|
+
setProver(prover) {
|
|
47
|
+
this.result.prover = prover;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Adds a method to the method execution stack, reseting the execution context
|
|
51
|
+
* in a case a new top-level (non nested) method call is made.
|
|
52
|
+
*
|
|
53
|
+
* @param methodName - Name of the method being captured in the context
|
|
54
|
+
*/
|
|
55
|
+
beforeMethod(moduleName, methodName, args) {
|
|
56
|
+
if (this.isFinished) {
|
|
57
|
+
this.clear();
|
|
58
|
+
this.result.moduleName = moduleName;
|
|
59
|
+
this.result.methodName = methodName;
|
|
60
|
+
this.result.args = args;
|
|
61
|
+
}
|
|
62
|
+
this.methods.push(methodName);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Removes the latest method from the execution context stack,
|
|
66
|
+
* keeping track of the amount of 'unfinished' methods. Allowing
|
|
67
|
+
* for the context to distinguish between top-level and nested method calls.
|
|
68
|
+
*/
|
|
69
|
+
afterMethod() {
|
|
70
|
+
this.methods.pop();
|
|
71
|
+
}
|
|
72
|
+
get isTopLevel() {
|
|
73
|
+
return this.methods.length === 1;
|
|
74
|
+
}
|
|
75
|
+
get isFinished() {
|
|
76
|
+
return this.methods.length === 0;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* @returns - Current execution context state
|
|
80
|
+
*/
|
|
81
|
+
current() {
|
|
82
|
+
return {
|
|
83
|
+
isFinished: this.isFinished,
|
|
84
|
+
result: this.result,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Manually clears/resets the execution context
|
|
89
|
+
*/
|
|
90
|
+
clear() {
|
|
91
|
+
this.result = new ProvableMethodExecutionResult();
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
ProvableMethodExecutionContext = __decorate([
|
|
95
|
+
singleton()
|
|
96
|
+
], ProvableMethodExecutionContext);
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { ZkProgram, FlexibleProvablePure, Proof, Field, Provable } from "o1js";
|
|
2
|
+
export interface CompileArtifact {
|
|
3
|
+
verificationKey: {
|
|
4
|
+
data: string;
|
|
5
|
+
hash: Field;
|
|
6
|
+
};
|
|
7
|
+
}
|
|
8
|
+
export interface AreProofsEnabled {
|
|
9
|
+
areProofsEnabled: boolean;
|
|
10
|
+
setProofsEnabled: (areProofsEnabled: boolean) => void;
|
|
11
|
+
}
|
|
12
|
+
export interface Verify<PublicInput, PublicOutput> {
|
|
13
|
+
(proof: Proof<PublicInput, PublicOutput>): Promise<boolean>;
|
|
14
|
+
}
|
|
15
|
+
export interface Compile {
|
|
16
|
+
(): Promise<CompileArtifact>;
|
|
17
|
+
}
|
|
18
|
+
export interface PlainZkProgram<PublicInput = undefined, PublicOutput = void> {
|
|
19
|
+
compile: Compile;
|
|
20
|
+
verify: Verify<PublicInput, PublicOutput>;
|
|
21
|
+
Proof: ReturnType<typeof ZkProgram.Proof<FlexibleProvablePure<PublicInput>, FlexibleProvablePure<PublicOutput>>>;
|
|
22
|
+
methods: Record<string, ((...args: any) => Promise<Proof<PublicInput, PublicOutput>>) | ((publicInput: PublicInput, ...args: any) => Promise<Proof<PublicInput, PublicOutput>>)>;
|
|
23
|
+
analyzeMethods: () => Promise<Record<string, Awaited<ReturnType<typeof Provable.constraintSystem>>>>;
|
|
24
|
+
}
|
|
25
|
+
export declare function verifyToMockable<PublicInput, PublicOutput>(verify: Verify<PublicInput, PublicOutput>, { areProofsEnabled }: AreProofsEnabled): (proof: Proof<PublicInput, PublicOutput>) => Promise<boolean>;
|
|
26
|
+
export declare const MOCK_VERIFICATION_KEY: {
|
|
27
|
+
data: string;
|
|
28
|
+
hash: import("o1js/dist/node/lib/provable/field").Field;
|
|
29
|
+
};
|
|
30
|
+
export declare function compileToMockable(compile: Compile, { areProofsEnabled }: AreProofsEnabled): () => Promise<CompileArtifact>;
|
|
31
|
+
export declare abstract class ZkProgrammable<PublicInput = undefined, PublicOutput = void> {
|
|
32
|
+
abstract get appChain(): AreProofsEnabled | undefined;
|
|
33
|
+
abstract zkProgramFactory(): PlainZkProgram<PublicInput, PublicOutput>[];
|
|
34
|
+
get zkProgram(): PlainZkProgram<PublicInput, PublicOutput>[];
|
|
35
|
+
}
|
|
36
|
+
export interface WithZkProgrammable<PublicInput = undefined, PublicOutput = void> {
|
|
37
|
+
zkProgrammable: ZkProgrammable<PublicInput, PublicOutput>;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=ZkProgrammable.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ZkProgrammable.d.ts","sourceRoot":"","sources":["../../src/zkProgrammable/ZkProgrammable.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,oBAAoB,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AAY/E,MAAM,WAAW,eAAe;IAC9B,eAAe,EAAE;QACf,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,KAAK,CAAC;KACb,CAAC;CACH;AAED,MAAM,WAAW,gBAAgB;IAC/B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,gBAAgB,EAAE,CAAC,gBAAgB,EAAE,OAAO,KAAK,IAAI,CAAC;CACvD;AAED,MAAM,WAAW,MAAM,CAAC,WAAW,EAAE,YAAY;IAC/C,CAAC,KAAK,EAAE,KAAK,CAAC,WAAW,EAAE,YAAY,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC7D;AAED,MAAM,WAAW,OAAO;IACtB,IAAI,OAAO,CAAC,eAAe,CAAC,CAAC;CAC9B;AAED,MAAM,WAAW,cAAc,CAAC,WAAW,GAAG,SAAS,EAAE,YAAY,GAAG,IAAI;IAC1E,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;IAC1C,KAAK,EAAE,UAAU,CACf,OAAO,SAAS,CAAC,KAAK,CACpB,oBAAoB,CAAC,WAAW,CAAC,EACjC,oBAAoB,CAAC,YAAY,CAAC,CACnC,CACF,CAAC;IACF,OAAO,EAAE,MAAM,CACb,MAAM,EACJ,CAAC,CAAC,GAAG,IAAI,EAAE,GAAG,KAAK,OAAO,CAAC,KAAK,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC,CAAC,GAC7D,CAAC,CACC,WAAW,EAAE,WAAW,EACxB,GAAG,IAAI,EAAE,GAAG,KACT,OAAO,CAAC,KAAK,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC,CAAC,CAClD,CAAC;IACF,cAAc,EAAE,MAAM,OAAO,CAC3B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,QAAQ,CAAC,gBAAgB,CAAC,CAAC,CAAC,CACtE,CAAC;CACH;AAED,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,YAAY,EACxD,MAAM,EAAE,MAAM,CAAC,WAAW,EAAE,YAAY,CAAC,EACzC,EAAE,gBAAgB,EAAE,EAAE,gBAAgB,WAEjB,MAAM,WAAW,EAAE,YAAY,CAAC,sBAiBtD;AAED,eAAO,MAAM,qBAAqB;;;CAGjC,CAAC;AAEF,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,OAAO,EAChB,EAAE,gBAAgB,EAAE,EAAE,gBAAgB,GACrC,MAAM,OAAO,CAAC,eAAe,CAAC,CAUhC;AAED,8BAAsB,cAAc,CAClC,WAAW,GAAG,SAAS,EACvB,YAAY,GAAG,IAAI;IAEnB,aAAoB,QAAQ,IAAI,gBAAgB,GAAG,SAAS,CAAC;aAE7C,gBAAgB,IAAI,cAAc,CAChD,WAAW,EACX,YAAY,CACb,EAAE;IAEH,IACW,SAAS,IAAI,cAAc,CAAC,WAAW,EAAE,YAAY,CAAC,EAAE,CAalE;CACF;AAED,MAAM,WAAW,kBAAkB,CACjC,WAAW,GAAG,SAAS,EACvB,YAAY,GAAG,IAAI;IAEnB,cAAc,EAAE,cAAc,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;CAC3D"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
import { Field } from "o1js";
|
|
11
|
+
import { Memoize } from "typescript-memoize";
|
|
12
|
+
import { log } from "../log";
|
|
13
|
+
import { MOCK_PROOF } from "./provableMethod";
|
|
14
|
+
const errors = {
|
|
15
|
+
appChainNotSet: (name) => new Error(`Appchain was not injected for: ${name}`),
|
|
16
|
+
};
|
|
17
|
+
export function verifyToMockable(verify, { areProofsEnabled }) {
|
|
18
|
+
return async (proof) => {
|
|
19
|
+
if (areProofsEnabled) {
|
|
20
|
+
let verified = false;
|
|
21
|
+
try {
|
|
22
|
+
verified = await verify(proof);
|
|
23
|
+
}
|
|
24
|
+
catch (error) {
|
|
25
|
+
// silently fail verification
|
|
26
|
+
log.error(error);
|
|
27
|
+
verified = false;
|
|
28
|
+
}
|
|
29
|
+
return verified;
|
|
30
|
+
}
|
|
31
|
+
return proof.proof === MOCK_PROOF;
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
export const MOCK_VERIFICATION_KEY = {
|
|
35
|
+
data: "mock-verification-key",
|
|
36
|
+
hash: Field(0),
|
|
37
|
+
};
|
|
38
|
+
export function compileToMockable(compile, { areProofsEnabled }) {
|
|
39
|
+
return async () => {
|
|
40
|
+
if (areProofsEnabled) {
|
|
41
|
+
return await compile();
|
|
42
|
+
}
|
|
43
|
+
return {
|
|
44
|
+
verificationKey: MOCK_VERIFICATION_KEY,
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
export class ZkProgrammable {
|
|
49
|
+
get zkProgram() {
|
|
50
|
+
const zkProgram = this.zkProgramFactory();
|
|
51
|
+
return zkProgram.map((bucket) => {
|
|
52
|
+
if (!this.appChain) {
|
|
53
|
+
throw errors.appChainNotSet(this.constructor.name);
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
...bucket,
|
|
57
|
+
verify: verifyToMockable(bucket.verify, this.appChain),
|
|
58
|
+
compile: compileToMockable(bucket.compile, this.appChain),
|
|
59
|
+
};
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
__decorate([
|
|
64
|
+
Memoize(),
|
|
65
|
+
__metadata("design:type", Array),
|
|
66
|
+
__metadata("design:paramtypes", [])
|
|
67
|
+
], ZkProgrammable.prototype, "zkProgram", null);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Proof, DynamicProof } from "o1js";
|
|
2
|
+
import { ProvableMethodExecutionContext } from "./ProvableMethodExecutionContext";
|
|
3
|
+
import type { WithZkProgrammable, ZkProgrammable } from "./ZkProgrammable";
|
|
4
|
+
export type O1JSPrimitive = object | string | boolean | number;
|
|
5
|
+
export type ArgumentTypes = (O1JSPrimitive | Proof<unknown, unknown> | DynamicProof<unknown, unknown>)[];
|
|
6
|
+
export type DecoratedMethod = (...args: ArgumentTypes) => Promise<unknown>;
|
|
7
|
+
export declare const MOCK_PROOF = "mock-proof";
|
|
8
|
+
export declare function toProver(methodName: string, simulatedMethod: DecoratedMethod, isFirstParameterPublicInput: boolean, ...args: ArgumentTypes): (this: ZkProgrammable<any, any>) => Promise<Proof<any, any>>;
|
|
9
|
+
/**
|
|
10
|
+
* Decorates a provable method on a 'prover class', depending on
|
|
11
|
+
* if proofs are enabled or not, either runs the respective zkProgram prover,
|
|
12
|
+
* or simulates the method execution and issues a mock proof.
|
|
13
|
+
*
|
|
14
|
+
* @param isFirstParameterPublicInput
|
|
15
|
+
* @param executionContext
|
|
16
|
+
* @returns
|
|
17
|
+
*/
|
|
18
|
+
export declare function provableMethod(isFirstParameterPublicInput?: boolean, executionContext?: ProvableMethodExecutionContext): <Target extends ZkProgrammable<any, any> | WithZkProgrammable<any, any>>(target: Target, methodName: string, descriptor: TypedPropertyDescriptor<(...args: any[]) => Promise<any> | any>) => TypedPropertyDescriptor<(...args: any[]) => Promise<any> | any>;
|
|
19
|
+
//# sourceMappingURL=provableMethod.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provableMethod.d.ts","sourceRoot":"","sources":["../../src/zkProgrammable/provableMethod.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AAG3C,OAAO,EAAE,8BAA8B,EAAE,MAAM,kCAAkC,CAAC;AAClF,OAAO,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAG3E,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;AAC/D,MAAM,MAAM,aAAa,GAAG,CACxB,aAAa,GACb,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,GACvB,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CACjC,EAAE,CAAC;AAEJ,MAAM,MAAM,eAAe,GAAG,CAAC,GAAG,IAAI,EAAE,aAAa,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAE3E,eAAO,MAAM,UAAU,eAAe,CAAC;AAEvC,wBAAgB,QAAQ,CACtB,UAAU,EAAE,MAAM,EAClB,eAAe,EAAE,eAAe,EAChC,2BAA2B,EAAE,OAAO,EACpC,GAAG,IAAI,EAAE,aAAa,UAEa,eAAe,GAAG,EAAE,GAAG,CAAC,8BAiC5D;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,2BAA2B,UAAO,EAClC,gBAAgB,GAAE,8BAEjB,wGAMa,MAAM,gDAC4B,GAAG,EAAE,KAAK,QAAQ,GAAG,CAAC,GAAG,GAAG,wCAA5B,GAAG,EAAE,KAAK,QAAQ,GAAG,CAAC,GAAG,GAAG,EA2C7E"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { container } from "tsyringe";
|
|
2
|
+
import { ProvableMethodExecutionContext } from "./ProvableMethodExecutionContext";
|
|
3
|
+
export const MOCK_PROOF = "mock-proof";
|
|
4
|
+
export function toProver(methodName, simulatedMethod, isFirstParameterPublicInput, ...args) {
|
|
5
|
+
return async function prover() {
|
|
6
|
+
const areProofsEnabled = this.appChain?.areProofsEnabled;
|
|
7
|
+
if (areProofsEnabled ?? false) {
|
|
8
|
+
for (const prog of this.zkProgram) {
|
|
9
|
+
if (Object.keys(prog.methods).includes(methodName)) {
|
|
10
|
+
const programProvableMethod = prog.methods[methodName];
|
|
11
|
+
// eslint-disable-next-line no-await-in-loop
|
|
12
|
+
return await Reflect.apply(programProvableMethod, this, args);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
// create a mock proof by simulating method execution in JS
|
|
17
|
+
const publicOutput = await Reflect.apply(simulatedMethod, this, args);
|
|
18
|
+
const zkProgram = this.zkProgram.find((prog) => {
|
|
19
|
+
return Object.keys(prog.methods).includes(methodName);
|
|
20
|
+
}) ?? this.zkProgram[0];
|
|
21
|
+
return new zkProgram.Proof({
|
|
22
|
+
proof: MOCK_PROOF,
|
|
23
|
+
// TODO: provide undefined if public input is not used
|
|
24
|
+
publicInput: isFirstParameterPublicInput ? args[0] : undefined,
|
|
25
|
+
publicOutput,
|
|
26
|
+
/**
|
|
27
|
+
* We set this to the max possible number, to avoid having
|
|
28
|
+
* to manually count in-circuit proof verifications
|
|
29
|
+
*/
|
|
30
|
+
maxProofsVerified: 2,
|
|
31
|
+
});
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Decorates a provable method on a 'prover class', depending on
|
|
36
|
+
* if proofs are enabled or not, either runs the respective zkProgram prover,
|
|
37
|
+
* or simulates the method execution and issues a mock proof.
|
|
38
|
+
*
|
|
39
|
+
* @param isFirstParameterPublicInput
|
|
40
|
+
* @param executionContext
|
|
41
|
+
* @returns
|
|
42
|
+
*/
|
|
43
|
+
export function provableMethod(isFirstParameterPublicInput = true, executionContext = container.resolve(ProvableMethodExecutionContext)) {
|
|
44
|
+
return (target, methodName, descriptor) => {
|
|
45
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
46
|
+
const simulatedMethod = descriptor.value;
|
|
47
|
+
descriptor.value = async function value(...args) {
|
|
48
|
+
const prover = toProver(methodName, simulatedMethod, isFirstParameterPublicInput, ...args);
|
|
49
|
+
executionContext.beforeMethod(this.constructor.name, methodName, args);
|
|
50
|
+
/**
|
|
51
|
+
* Check if the method is called at the top level,
|
|
52
|
+
* if yes then create a prover.
|
|
53
|
+
*/
|
|
54
|
+
if (executionContext.isTopLevel) {
|
|
55
|
+
executionContext.setProver(prover.bind(this));
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Regardless of if the method is called from the top level
|
|
59
|
+
* or not, execute its simulated (Javascript) version and
|
|
60
|
+
* return the result.
|
|
61
|
+
*/
|
|
62
|
+
let result;
|
|
63
|
+
try {
|
|
64
|
+
result = Reflect.apply(simulatedMethod, this, args);
|
|
65
|
+
}
|
|
66
|
+
finally {
|
|
67
|
+
executionContext.afterMethod();
|
|
68
|
+
}
|
|
69
|
+
return result;
|
|
70
|
+
};
|
|
71
|
+
return descriptor;
|
|
72
|
+
};
|
|
73
|
+
}
|
package/jest.config.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require("../../jest.config.cjs");
|
package/package.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@proto-kit/common",
|
|
3
|
+
"license": "MIT",
|
|
4
|
+
"private": false,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"version": "0.1.1-develop.1086+eeb4563a",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "tsc -p tsconfig.json",
|
|
9
|
+
"dev": "tsc -p tsconfig.json --watch",
|
|
10
|
+
"lint": "eslint ./src ./test",
|
|
11
|
+
"test:file": "node --experimental-vm-modules --experimental-wasm-modules --experimental-wasm-threads ../../node_modules/jest/bin/jest.js",
|
|
12
|
+
"test": "npm run test:file -- ./test/**",
|
|
13
|
+
"test:watch": "npm run test:file -- ./test/** --watch"
|
|
14
|
+
},
|
|
15
|
+
"main": "dist/index.js",
|
|
16
|
+
"publishConfig": {
|
|
17
|
+
"access": "public"
|
|
18
|
+
},
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"lodash": "^4.17.21",
|
|
21
|
+
"loglevel": "^1.8.1",
|
|
22
|
+
"reflect-metadata": "^0.1.13",
|
|
23
|
+
"typescript-memoize": "^1.1.1"
|
|
24
|
+
},
|
|
25
|
+
"peerDependencies": {
|
|
26
|
+
"o1js": "^1.1.0",
|
|
27
|
+
"tsyringe": "^4.7.0"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@jest/globals": "^29.5.0",
|
|
31
|
+
"@types/lodash": "^4.14.194"
|
|
32
|
+
},
|
|
33
|
+
"gitHead": "eeb4563a685b29525358ec7404fa9f0251d258d4"
|
|
34
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { noop } from "../utils";
|
|
2
|
+
|
|
3
|
+
import { ChildContainerProvider } from "./ChildContainerProvider";
|
|
4
|
+
import type { BaseModuleInstanceType } from "./ModuleContainer";
|
|
5
|
+
|
|
6
|
+
const errors = {
|
|
7
|
+
configNotSet: (moduleName: string) =>
|
|
8
|
+
new Error(
|
|
9
|
+
`Trying to retrieve config of ${moduleName}, which was not yet set`
|
|
10
|
+
),
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
// defines how presets can be provided, either a function or a record
|
|
14
|
+
export type Preset<Config> = Config | ((...args: unknown[]) => Config);
|
|
15
|
+
export type Presets<Config> = Record<string, Preset<Config>>;
|
|
16
|
+
|
|
17
|
+
// describes the interface of a configurable module
|
|
18
|
+
export interface Configurable<Config> {
|
|
19
|
+
config: Config;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export type NoConfig = Record<never, never>;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Used by various module sub-types that may need to be configured
|
|
26
|
+
*/
|
|
27
|
+
export class ConfigurableModule<Config = NoConfig>
|
|
28
|
+
implements BaseModuleInstanceType
|
|
29
|
+
{
|
|
30
|
+
/**
|
|
31
|
+
* Store the config separately, so that we can apply additional
|
|
32
|
+
* checks when retrieving it via the getter
|
|
33
|
+
*/
|
|
34
|
+
protected currentConfig: Config | undefined;
|
|
35
|
+
|
|
36
|
+
// retrieve the existing config
|
|
37
|
+
public get config(): Config {
|
|
38
|
+
if (this.currentConfig === undefined) {
|
|
39
|
+
throw errors.configNotSet(this.constructor.name);
|
|
40
|
+
}
|
|
41
|
+
return this.currentConfig;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// set the config
|
|
45
|
+
public set config(config: Config) {
|
|
46
|
+
this.currentConfig = config;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
public create(childContainerProvider: ChildContainerProvider): void {
|
|
50
|
+
noop();
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Helps ensure that the target class implements static presets
|
|
55
|
+
export interface StaticConfigurableModule<Config> {
|
|
56
|
+
presets: Presets<Config>;
|
|
57
|
+
}
|