@proto-kit/common 0.1.1-develop.1088 → 0.1.1-develop.1313
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/dist/compiling/AtomicCompileHelper.d.ts +13 -0
- package/dist/compiling/AtomicCompileHelper.d.ts.map +1 -0
- package/dist/compiling/AtomicCompileHelper.js +40 -0
- package/dist/compiling/AtomicCompileHelper.js.map +1 -0
- package/dist/compiling/CompilableModule.d.ts +6 -0
- package/dist/compiling/CompilableModule.d.ts.map +1 -0
- package/dist/compiling/CompilableModule.js +2 -0
- package/dist/compiling/CompilableModule.js.map +1 -0
- package/dist/compiling/CompileRegistry.d.ts +26 -0
- package/dist/compiling/CompileRegistry.d.ts.map +1 -0
- package/dist/compiling/CompileRegistry.js +68 -0
- package/dist/compiling/CompileRegistry.js.map +1 -0
- package/dist/compiling/services/ChildVerificationKeyService.d.ts +10 -0
- package/dist/compiling/services/ChildVerificationKeyService.d.ts.map +1 -0
- package/dist/compiling/services/ChildVerificationKeyService.js +27 -0
- package/dist/compiling/services/ChildVerificationKeyService.js.map +1 -0
- package/dist/config/ChildContainerCreatable.js +1 -0
- package/dist/config/ChildContainerCreatable.js.map +1 -0
- package/dist/config/ChildContainerProvider.js +1 -0
- package/dist/config/ChildContainerProvider.js.map +1 -0
- package/dist/config/ConfigurableModule.js +1 -0
- package/dist/config/ConfigurableModule.js.map +1 -0
- package/dist/config/ModuleContainer.d.ts +1 -0
- package/dist/config/ModuleContainer.d.ts.map +1 -1
- package/dist/config/ModuleContainer.js +14 -3
- package/dist/config/ModuleContainer.js.map +1 -0
- package/dist/config/injectAlias.d.ts +18 -0
- package/dist/config/injectAlias.d.ts.map +1 -0
- package/dist/config/injectAlias.js +47 -0
- package/dist/config/injectAlias.js.map +1 -0
- package/dist/dependencyFactory/DependencyFactory.js +1 -0
- package/dist/dependencyFactory/DependencyFactory.js.map +1 -0
- package/dist/dependencyFactory/injectOptional.js +1 -0
- package/dist/dependencyFactory/injectOptional.js.map +1 -0
- package/dist/dummyVerificationKey.d.ts +3 -0
- package/dist/dummyVerificationKey.d.ts.map +1 -0
- package/dist/dummyVerificationKey.js +8 -0
- package/dist/dummyVerificationKey.js.map +1 -0
- package/dist/events/EventEmitter.js +1 -0
- package/dist/events/EventEmitter.js.map +1 -0
- package/dist/events/EventEmitterProxy.d.ts +1 -0
- package/dist/events/EventEmitterProxy.d.ts.map +1 -1
- package/dist/events/EventEmitterProxy.js +12 -0
- package/dist/events/EventEmitterProxy.js.map +1 -0
- package/dist/events/EventEmittingComponent.d.ts +3 -0
- package/dist/events/EventEmittingComponent.d.ts.map +1 -1
- package/dist/events/EventEmittingComponent.js +1 -0
- package/dist/events/EventEmittingComponent.js.map +1 -0
- package/dist/events/ReplayingSingleUseEventEmitter.d.ts +17 -0
- package/dist/events/ReplayingSingleUseEventEmitter.d.ts.map +1 -0
- package/dist/events/ReplayingSingleUseEventEmitter.js +34 -0
- package/dist/events/ReplayingSingleUseEventEmitter.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/log.d.ts +17 -0
- package/dist/log.d.ts.map +1 -1
- package/dist/log.js +40 -1
- package/dist/log.js.map +1 -0
- package/dist/trees/InMemoryMerkleTreeStorage.js +1 -0
- package/dist/trees/InMemoryMerkleTreeStorage.js.map +1 -0
- package/dist/trees/MerkleTreeStore.js +1 -0
- package/dist/trees/MerkleTreeStore.js.map +1 -0
- package/dist/trees/MockAsyncMerkleStore.js +1 -0
- package/dist/trees/MockAsyncMerkleStore.js.map +1 -0
- package/dist/trees/RollupMerkleTree.js +1 -0
- package/dist/trees/RollupMerkleTree.js.map +1 -0
- package/dist/trees/VirtualMerkleTreeStore.js +1 -0
- package/dist/trees/VirtualMerkleTreeStore.js.map +1 -0
- package/dist/types.d.ts +2 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +13 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +40 -0
- package/dist/utils.js.map +1 -0
- package/dist/zkProgrammable/ProvableMethodExecutionContext.js +1 -0
- package/dist/zkProgrammable/ProvableMethodExecutionContext.js.map +1 -0
- package/dist/zkProgrammable/ZkProgrammable.d.ts +6 -5
- package/dist/zkProgrammable/ZkProgrammable.d.ts.map +1 -1
- package/dist/zkProgrammable/ZkProgrammable.js +24 -12
- package/dist/zkProgrammable/ZkProgrammable.js.map +1 -0
- package/dist/zkProgrammable/provableMethod.d.ts.map +1 -1
- package/dist/zkProgrammable/provableMethod.js +11 -13
- package/dist/zkProgrammable/provableMethod.js.map +1 -0
- package/jest.config.cjs +12 -1
- package/package.json +4 -4
- package/src/compiling/AtomicCompileHelper.ts +62 -0
- package/src/compiling/CompilableModule.ts +6 -0
- package/src/compiling/CompileRegistry.ts +78 -0
- package/src/compiling/services/ChildVerificationKeyService.ts +26 -0
- package/src/config/ModuleContainer.ts +20 -5
- package/src/config/injectAlias.ts +70 -0
- package/src/dummyVerificationKey.ts +10 -0
- package/src/events/EventEmitterProxy.ts +27 -3
- package/src/events/EventEmittingComponent.ts +4 -0
- package/src/events/ReplayingSingleUseEventEmitter.ts +42 -0
- package/src/index.ts +6 -0
- package/src/log.ts +47 -1
- package/src/types.ts +10 -1
- package/src/utils.ts +53 -2
- package/src/zkProgrammable/ZkProgrammable.ts +33 -13
- package/src/zkProgrammable/provableMethod.ts +15 -14
- package/test/config/ModuleContainer.test.ts +45 -2
- package/test/config/injectAlias.test.ts +28 -0
- package/test/zkProgrammable/ZkProgrammable.test.ts +7 -7
- package/dist/test/equalProvable.d.ts +0 -20
- package/dist/test/equalProvable.d.ts.map +0 -1
- package/dist/test/equalProvable.js +0 -13
package/package.json
CHANGED
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
"license": "MIT",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
|
-
"version": "0.1.1-develop.
|
|
6
|
+
"version": "0.1.1-develop.1313+4d6b3b6d",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"build": "tsc -p tsconfig.json",
|
|
9
9
|
"dev": "tsc -p tsconfig.json --watch",
|
|
10
10
|
"lint": "eslint ./src ./test",
|
|
11
|
-
"test:file": "node --experimental-vm-modules --experimental-wasm-modules
|
|
11
|
+
"test:file": "node --experimental-vm-modules --experimental-wasm-modules ../../node_modules/jest/bin/jest.js",
|
|
12
12
|
"test": "npm run test:file -- ./test/**",
|
|
13
13
|
"test:watch": "npm run test:file -- ./test/** --watch"
|
|
14
14
|
},
|
|
@@ -23,12 +23,12 @@
|
|
|
23
23
|
"typescript-memoize": "^1.1.1"
|
|
24
24
|
},
|
|
25
25
|
"peerDependencies": {
|
|
26
|
-
"o1js": "^1.
|
|
26
|
+
"o1js": "^1.6.0",
|
|
27
27
|
"tsyringe": "^4.7.0"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"@jest/globals": "^29.5.0",
|
|
31
31
|
"@types/lodash": "^4.14.194"
|
|
32
32
|
},
|
|
33
|
-
"gitHead": "
|
|
33
|
+
"gitHead": "4d6b3b6da51b3edee0fbf25ce72c1f59ec61e891"
|
|
34
34
|
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AreProofsEnabled,
|
|
3
|
+
CompileArtifact,
|
|
4
|
+
MOCK_VERIFICATION_KEY,
|
|
5
|
+
} from "../zkProgrammable/ZkProgrammable";
|
|
6
|
+
import { isSubtypeOfName } from "../utils";
|
|
7
|
+
import { TypedClass } from "../types";
|
|
8
|
+
import { log } from "../log";
|
|
9
|
+
|
|
10
|
+
export type ArtifactRecord = Record<string, CompileArtifact>;
|
|
11
|
+
|
|
12
|
+
export type CompileTarget = {
|
|
13
|
+
name: string;
|
|
14
|
+
compile: () => Promise<CompileArtifact>;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export class AtomicCompileHelper {
|
|
18
|
+
public constructor(private readonly areProofsEnabled: AreProofsEnabled) {}
|
|
19
|
+
|
|
20
|
+
private compilationPromises: {
|
|
21
|
+
[key: string]: Promise<CompileArtifact>;
|
|
22
|
+
} = {};
|
|
23
|
+
|
|
24
|
+
public async compileContract(
|
|
25
|
+
contract: CompileTarget,
|
|
26
|
+
overrideProofsEnabled?: boolean
|
|
27
|
+
): Promise<CompileArtifact> {
|
|
28
|
+
let newPromise = false;
|
|
29
|
+
const { name } = contract;
|
|
30
|
+
if (this.compilationPromises[name] === undefined) {
|
|
31
|
+
const proofsEnabled =
|
|
32
|
+
overrideProofsEnabled ?? this.areProofsEnabled.areProofsEnabled;
|
|
33
|
+
|
|
34
|
+
// We only care about proofs enabled here if it's a contract, because
|
|
35
|
+
// in all other cases, ZkProgrammable already handles this switch, and we
|
|
36
|
+
// want to preserve the artifact layout (which might be more than one
|
|
37
|
+
// entry for ZkProgrammables)
|
|
38
|
+
if (
|
|
39
|
+
proofsEnabled ||
|
|
40
|
+
!isSubtypeOfName(
|
|
41
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
42
|
+
contract as unknown as TypedClass<any>,
|
|
43
|
+
"SmartContract"
|
|
44
|
+
)
|
|
45
|
+
) {
|
|
46
|
+
log.time(`Compiling ${name}`);
|
|
47
|
+
this.compilationPromises[name] = contract.compile();
|
|
48
|
+
newPromise = true;
|
|
49
|
+
} else {
|
|
50
|
+
log.trace(`Compiling ${name} - mock`);
|
|
51
|
+
this.compilationPromises[name] = Promise.resolve({
|
|
52
|
+
verificationKey: MOCK_VERIFICATION_KEY,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
const result = await this.compilationPromises[name];
|
|
57
|
+
if (newPromise) {
|
|
58
|
+
log.timeEnd.info(`Compiling ${name}`);
|
|
59
|
+
}
|
|
60
|
+
return result;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { inject, injectable, singleton } from "tsyringe";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
AreProofsEnabled,
|
|
5
|
+
CompileArtifact,
|
|
6
|
+
} from "../zkProgrammable/ZkProgrammable";
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
ArtifactRecord,
|
|
10
|
+
AtomicCompileHelper,
|
|
11
|
+
CompileTarget,
|
|
12
|
+
} from "./AtomicCompileHelper";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* The CompileRegistry compiles "compilable modules"
|
|
16
|
+
* (i.e. zkprograms, contracts or contractmodules)
|
|
17
|
+
* while making sure they don't get compiled twice in the same process in parallel.
|
|
18
|
+
*/
|
|
19
|
+
@injectable()
|
|
20
|
+
@singleton()
|
|
21
|
+
export class CompileRegistry {
|
|
22
|
+
public constructor(
|
|
23
|
+
@inject("AreProofsEnabled")
|
|
24
|
+
private readonly areProofsEnabled: AreProofsEnabled
|
|
25
|
+
) {
|
|
26
|
+
this.compiler = new AtomicCompileHelper(this.areProofsEnabled);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
private compiler: AtomicCompileHelper;
|
|
30
|
+
|
|
31
|
+
private artifacts: ArtifactRecord = {};
|
|
32
|
+
|
|
33
|
+
private inForceProverBlock = false;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* This function forces compilation even if the artifact itself is in the registry.
|
|
37
|
+
* Basically the statement is: The artifact along is not enough, we need to
|
|
38
|
+
* actually have the prover compiled.
|
|
39
|
+
* This is true for non-sideloaded circuit dependencies.
|
|
40
|
+
*/
|
|
41
|
+
public async forceProverExists(
|
|
42
|
+
f: (registry: CompileRegistry) => Promise<void>
|
|
43
|
+
) {
|
|
44
|
+
this.inForceProverBlock = true;
|
|
45
|
+
await f(this);
|
|
46
|
+
this.inForceProverBlock = false;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
public async compile(target: CompileTarget) {
|
|
50
|
+
if (this.artifacts[target.name] === undefined || this.inForceProverBlock) {
|
|
51
|
+
const artifact = await this.compiler.compileContract(target);
|
|
52
|
+
this.artifacts[target.name] = artifact;
|
|
53
|
+
return artifact;
|
|
54
|
+
}
|
|
55
|
+
return this.artifacts[target.name];
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
public getArtifact(name: string): CompileArtifact | undefined {
|
|
59
|
+
if (this.artifacts[name] === undefined) {
|
|
60
|
+
throw new Error(
|
|
61
|
+
`Artifact for ${name} not available, did you compile it via the CompileRegistry?`
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return this.artifacts[name];
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
public addArtifactsRaw(artifacts: ArtifactRecord) {
|
|
69
|
+
this.artifacts = {
|
|
70
|
+
...this.artifacts,
|
|
71
|
+
...artifacts,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
public getAllArtifacts() {
|
|
76
|
+
return this.artifacts;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { injectable, Lifecycle, scoped } from "tsyringe";
|
|
2
|
+
|
|
3
|
+
import { CompileRegistry } from "../CompileRegistry";
|
|
4
|
+
|
|
5
|
+
@injectable()
|
|
6
|
+
@scoped(Lifecycle.ContainerScoped)
|
|
7
|
+
export class ChildVerificationKeyService {
|
|
8
|
+
private compileRegistry?: CompileRegistry;
|
|
9
|
+
|
|
10
|
+
public setCompileRegistry(registry: CompileRegistry) {
|
|
11
|
+
this.compileRegistry = registry;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
public getVerificationKey(name: string) {
|
|
15
|
+
if (this.compileRegistry === undefined) {
|
|
16
|
+
throw new Error("CompileRegistry hasn't been set yet");
|
|
17
|
+
}
|
|
18
|
+
const artifact = this.compileRegistry.getArtifact(name);
|
|
19
|
+
if (artifact === undefined) {
|
|
20
|
+
throw new Error(
|
|
21
|
+
`Verification Key for child program ${name} not found in registry`
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
return artifact.verificationKey;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
DependencyContainer,
|
|
5
5
|
Frequency,
|
|
6
6
|
InjectionToken,
|
|
7
|
-
|
|
7
|
+
instanceCachingFactory,
|
|
8
8
|
isClassProvider,
|
|
9
9
|
isFactoryProvider,
|
|
10
10
|
isTokenProvider,
|
|
@@ -28,6 +28,7 @@ import {
|
|
|
28
28
|
} from "./ConfigurableModule";
|
|
29
29
|
import { ChildContainerProvider } from "./ChildContainerProvider";
|
|
30
30
|
import { ChildContainerCreatable } from "./ChildContainerCreatable";
|
|
31
|
+
import { getInjectAliases } from "./injectAlias";
|
|
31
32
|
|
|
32
33
|
const errors = {
|
|
33
34
|
configNotSetInContainer: (moduleName: string) =>
|
|
@@ -228,6 +229,16 @@ export class ModuleContainer<
|
|
|
228
229
|
}
|
|
229
230
|
}
|
|
230
231
|
|
|
232
|
+
protected registerAliases(originalToken: string, clas: TypedClass<any>) {
|
|
233
|
+
const aliases = getInjectAliases(clas);
|
|
234
|
+
|
|
235
|
+
aliases.forEach((alias) =>
|
|
236
|
+
this.container.register(alias, {
|
|
237
|
+
useToken: originalToken,
|
|
238
|
+
})
|
|
239
|
+
);
|
|
240
|
+
}
|
|
241
|
+
|
|
231
242
|
/**
|
|
232
243
|
* Register modules into the current container, and registers
|
|
233
244
|
* a respective resolution hook in order to decorate the module
|
|
@@ -250,6 +261,8 @@ export class ModuleContainer<
|
|
|
250
261
|
{ lifecycle: Lifecycle.ContainerScoped }
|
|
251
262
|
);
|
|
252
263
|
this.onAfterModuleResolution(moduleName);
|
|
264
|
+
|
|
265
|
+
this.registerAliases(moduleName, useClass);
|
|
253
266
|
}
|
|
254
267
|
});
|
|
255
268
|
}
|
|
@@ -404,15 +417,17 @@ export class ModuleContainer<
|
|
|
404
417
|
// this enables us to have a singletoned factory
|
|
405
418
|
// that returns the same instance for each resolve
|
|
406
419
|
this.container.register(key, {
|
|
407
|
-
useFactory:
|
|
408
|
-
declaration.useFactory
|
|
409
|
-
),
|
|
420
|
+
useFactory: instanceCachingFactory(declaration.useFactory),
|
|
410
421
|
});
|
|
411
422
|
} else if (isClassProvider(declaration)) {
|
|
412
423
|
this.container.register(key, declaration, {
|
|
413
424
|
lifecycle: Lifecycle.Singleton,
|
|
414
425
|
});
|
|
415
|
-
|
|
426
|
+
this.registerAliases(
|
|
427
|
+
key,
|
|
428
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
429
|
+
declaration.useClass as TypedClass<unknown>
|
|
430
|
+
);
|
|
416
431
|
} else if (isTokenProvider(declaration)) {
|
|
417
432
|
this.container.register(key, declaration, {
|
|
418
433
|
lifecycle: Lifecycle.Singleton,
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { TypedClass } from "../types";
|
|
2
|
+
|
|
3
|
+
export const injectAliasMetadataKey = "protokit-inject-alias";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Attaches metadata to the class that the ModuleContainer can pick up
|
|
7
|
+
* and inject this class in the DI container under the specified aliases.
|
|
8
|
+
* This method supports inheritance, therefore also gets aliases defined
|
|
9
|
+
* on superclasses
|
|
10
|
+
*/
|
|
11
|
+
export function injectAlias(aliases: string[]) {
|
|
12
|
+
return (target: TypedClass<unknown>) => {
|
|
13
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
14
|
+
const superAliases = Reflect.getMetadata(
|
|
15
|
+
injectAliasMetadataKey,
|
|
16
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
17
|
+
Object.getPrototypeOf(target)
|
|
18
|
+
) as string[] | undefined;
|
|
19
|
+
|
|
20
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
21
|
+
const existingAliases = Reflect.getMetadata(
|
|
22
|
+
injectAliasMetadataKey,
|
|
23
|
+
target
|
|
24
|
+
) as string[] | undefined;
|
|
25
|
+
|
|
26
|
+
let allAliases = aliases;
|
|
27
|
+
|
|
28
|
+
if (superAliases !== undefined) {
|
|
29
|
+
allAliases = allAliases.concat(superAliases);
|
|
30
|
+
}
|
|
31
|
+
if (existingAliases !== undefined) {
|
|
32
|
+
allAliases = allAliases.concat(existingAliases);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
Reflect.defineMetadata(
|
|
36
|
+
injectAliasMetadataKey,
|
|
37
|
+
allAliases.filter(
|
|
38
|
+
(value, index, array) => array.indexOf(value) === index
|
|
39
|
+
),
|
|
40
|
+
target
|
|
41
|
+
);
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Marks the class to implement a certain interface T, while also attaching
|
|
47
|
+
* a DI-injection alias as metadata, that will be picked up by the ModuleContainer
|
|
48
|
+
* to allow resolving by that interface name
|
|
49
|
+
* @param name The name of the injection alias, convention is to use the same as the name of T
|
|
50
|
+
*/
|
|
51
|
+
export function implement<T>(name: string) {
|
|
52
|
+
return (
|
|
53
|
+
/**
|
|
54
|
+
* Check if the target class extends RuntimeModule, while
|
|
55
|
+
* also providing static config presets
|
|
56
|
+
*/
|
|
57
|
+
target: TypedClass<T>
|
|
58
|
+
) => {
|
|
59
|
+
injectAlias([name])(target);
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function getInjectAliases(target: TypedClass<unknown>): string[] {
|
|
64
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
65
|
+
const aliases = Reflect.getMetadata(
|
|
66
|
+
injectAliasMetadataKey,
|
|
67
|
+
target
|
|
68
|
+
) as string[];
|
|
69
|
+
return aliases ?? [];
|
|
70
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Field, VerificationKey } from "o1js";
|
|
2
|
+
|
|
3
|
+
export function dummyVerificationKey() {
|
|
4
|
+
return new VerificationKey({
|
|
5
|
+
hash: Field(
|
|
6
|
+
"3392518251768960475377392625298437850623664973002200885669375116181514017494"
|
|
7
|
+
),
|
|
8
|
+
data: "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",
|
|
9
|
+
});
|
|
10
|
+
}
|
|
@@ -6,7 +6,11 @@ import type {
|
|
|
6
6
|
import { StringKeyOf, UnionToIntersection } from "../types";
|
|
7
7
|
|
|
8
8
|
import { EventEmitter } from "./EventEmitter";
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
EventEmittingComponent,
|
|
11
|
+
EventEmittingContainer,
|
|
12
|
+
EventsRecord,
|
|
13
|
+
} from "./EventEmittingComponent";
|
|
10
14
|
|
|
11
15
|
export type CastToEventsRecord<Record> = Record extends EventsRecord
|
|
12
16
|
? Record
|
|
@@ -17,7 +21,13 @@ export type ModuleEvents<ModuleType extends BaseModuleType> =
|
|
|
17
21
|
? Events
|
|
18
22
|
: InstanceType<ModuleType> extends ModuleContainer<infer NestedModules>
|
|
19
23
|
? CastToEventsRecord<ContainerEvents<NestedModules>>
|
|
20
|
-
:
|
|
24
|
+
: // &
|
|
25
|
+
// (InstanceType<ModuleType> extends EventEmittingContainer<
|
|
26
|
+
// infer ContainerEvents
|
|
27
|
+
// >
|
|
28
|
+
// ? ContainerEvents
|
|
29
|
+
// : {})
|
|
30
|
+
EventsRecord;
|
|
21
31
|
|
|
22
32
|
export type ContainerEvents<Modules extends ModulesRecord> = {
|
|
23
33
|
[Key in StringKeyOf<Modules>]: ModuleEvents<Modules[Key]>;
|
|
@@ -27,7 +37,7 @@ export type FlattenObject<Target extends Record<string, EventsRecord>> =
|
|
|
27
37
|
UnionToIntersection<Target[keyof Target]>;
|
|
28
38
|
|
|
29
39
|
export type FlattenedContainerEvents<Modules extends ModulesRecord> =
|
|
30
|
-
FlattenObject<ContainerEvents<Modules>>;
|
|
40
|
+
FlattenObject<ContainerEvents<Modules>>; // & FlattenObject<any>;
|
|
31
41
|
|
|
32
42
|
export class EventEmitterProxy<
|
|
33
43
|
Modules extends ModulesRecord,
|
|
@@ -45,10 +55,24 @@ export class EventEmitterProxy<
|
|
|
45
55
|
this.emit(events, ...args);
|
|
46
56
|
});
|
|
47
57
|
}
|
|
58
|
+
if (this.isEventEmittingContainer(module)) {
|
|
59
|
+
module.containerEvents.onAll((events: any, args: any[]) => {
|
|
60
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
61
|
+
this.emit(events, ...args);
|
|
62
|
+
});
|
|
63
|
+
}
|
|
48
64
|
}
|
|
49
65
|
});
|
|
50
66
|
}
|
|
51
67
|
|
|
68
|
+
private isEventEmittingContainer(
|
|
69
|
+
module: any
|
|
70
|
+
): module is EventEmittingContainer<EventsRecord> {
|
|
71
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
72
|
+
const emitter = module.containerEvents;
|
|
73
|
+
return emitter !== undefined && emitter instanceof EventEmitter;
|
|
74
|
+
}
|
|
75
|
+
|
|
52
76
|
private isEventEmitter(
|
|
53
77
|
module: any
|
|
54
78
|
): module is EventEmittingComponent<EventsRecord> {
|
|
@@ -5,3 +5,7 @@ export type EventsRecord = Record<string, unknown[]>;
|
|
|
5
5
|
export interface EventEmittingComponent<Events extends EventsRecord> {
|
|
6
6
|
events: EventEmitter<Events>;
|
|
7
7
|
}
|
|
8
|
+
|
|
9
|
+
export interface EventEmittingContainer<Events extends EventsRecord> {
|
|
10
|
+
containerEvents: EventEmitter<Events>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { EventsRecord } from "./EventEmittingComponent";
|
|
2
|
+
import { EventEmitter } from "./EventEmitter";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Event Emitter variant that emits a certain event only once to a registered listener.
|
|
6
|
+
* Additionally, if a listener registers to a event that has already been emitted, it
|
|
7
|
+
* re-emits it to said listener.
|
|
8
|
+
* This pattern is especially useful for listening for inclusions of transactions.
|
|
9
|
+
* Those events will only occur once, and listeners could come too late to the party,
|
|
10
|
+
* so we need to make sure they get notified as well in those cases.
|
|
11
|
+
*/
|
|
12
|
+
export class ReplayingSingleUseEventEmitter<
|
|
13
|
+
Events extends EventsRecord,
|
|
14
|
+
> extends EventEmitter<Events> {
|
|
15
|
+
public emitted: Partial<Events> = {};
|
|
16
|
+
|
|
17
|
+
public emit<Key extends keyof Events>(
|
|
18
|
+
event: Key,
|
|
19
|
+
...parameters: Events[Key]
|
|
20
|
+
) {
|
|
21
|
+
super.emit(event, ...parameters);
|
|
22
|
+
this.emitted[event] = parameters;
|
|
23
|
+
this.listeners[event] = [];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
public onAll(listener: (event: keyof Events, args: unknown[]) => void) {
|
|
27
|
+
Object.entries(this.emitted).forEach(([key, params]) => {
|
|
28
|
+
if (params !== undefined) listener(key, params);
|
|
29
|
+
});
|
|
30
|
+
super.onAll(listener);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
public on<Key extends keyof Events>(
|
|
34
|
+
event: Key,
|
|
35
|
+
listener: (...args: Events[Key]) => void
|
|
36
|
+
) {
|
|
37
|
+
if (this.emitted[event] !== undefined) {
|
|
38
|
+
listener(...this.emitted[event]!);
|
|
39
|
+
}
|
|
40
|
+
super.on(event, listener);
|
|
41
|
+
}
|
|
42
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -16,4 +16,10 @@ export * from "./trees/MerkleTreeStore";
|
|
|
16
16
|
export * from "./trees/InMemoryMerkleTreeStorage";
|
|
17
17
|
export * from "./trees/RollupMerkleTree";
|
|
18
18
|
export * from "./events/EventEmitterProxy";
|
|
19
|
+
export * from "./events/ReplayingSingleUseEventEmitter";
|
|
19
20
|
export * from "./trees/MockAsyncMerkleStore";
|
|
21
|
+
export * from "./compiling/AtomicCompileHelper";
|
|
22
|
+
export * from "./compiling/CompileRegistry";
|
|
23
|
+
export * from "./compiling/CompilableModule";
|
|
24
|
+
export * from "./compiling/services/ChildVerificationKeyService";
|
|
25
|
+
export * from "./config/injectAlias";
|
package/src/log.ts
CHANGED
|
@@ -25,6 +25,31 @@ function logProvable(
|
|
|
25
25
|
}
|
|
26
26
|
/* eslint-enable */
|
|
27
27
|
|
|
28
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
29
|
+
if (process.env?.IN_CI ?? false) {
|
|
30
|
+
loglevel.setLevel("ERROR");
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const timeMap: Record<string, number> = {};
|
|
34
|
+
|
|
35
|
+
function time(label = "time") {
|
|
36
|
+
timeMap[label] = Date.now();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function timeLog(label = "time"): string {
|
|
40
|
+
const prev = timeMap[label];
|
|
41
|
+
if (prev === undefined) {
|
|
42
|
+
return "Label not found";
|
|
43
|
+
}
|
|
44
|
+
return `${label} took ${Date.now() - prev}ms`;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function timeEnd(label = "time"): string {
|
|
48
|
+
const str = timeLog(label);
|
|
49
|
+
delete timeMap[label];
|
|
50
|
+
return str;
|
|
51
|
+
}
|
|
52
|
+
|
|
28
53
|
export const log = {
|
|
29
54
|
provable: {
|
|
30
55
|
info: (...args: unknown[]) => {
|
|
@@ -48,6 +73,24 @@ export const log = {
|
|
|
48
73
|
},
|
|
49
74
|
},
|
|
50
75
|
|
|
76
|
+
time,
|
|
77
|
+
|
|
78
|
+
timeLog: {
|
|
79
|
+
info: (label?: string) => loglevel.info(timeLog(label)),
|
|
80
|
+
debug: (label?: string) => loglevel.debug(timeLog(label)),
|
|
81
|
+
error: (label?: string) => loglevel.error(timeLog(label)),
|
|
82
|
+
trace: (label?: string) => loglevel.trace(timeLog(label)),
|
|
83
|
+
warn: (label?: string) => loglevel.warn(timeLog(label)),
|
|
84
|
+
},
|
|
85
|
+
|
|
86
|
+
timeEnd: {
|
|
87
|
+
info: (label?: string) => loglevel.info(timeEnd(label)),
|
|
88
|
+
debug: (label?: string) => loglevel.debug(timeEnd(label)),
|
|
89
|
+
error: (label?: string) => loglevel.error(timeEnd(label)),
|
|
90
|
+
trace: (label?: string) => loglevel.trace(timeEnd(label)),
|
|
91
|
+
warn: (label?: string) => loglevel.warn(timeEnd(label)),
|
|
92
|
+
},
|
|
93
|
+
|
|
51
94
|
info: (...args: unknown[]) => {
|
|
52
95
|
loglevel.info(...args);
|
|
53
96
|
},
|
|
@@ -73,7 +116,10 @@ export const log = {
|
|
|
73
116
|
},
|
|
74
117
|
|
|
75
118
|
setLevel: (level: LogLevelDesc) => {
|
|
76
|
-
|
|
119
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
120
|
+
if (!(process.env?.IN_CI ?? false)) {
|
|
121
|
+
loglevel.setLevel(level);
|
|
122
|
+
}
|
|
77
123
|
},
|
|
78
124
|
|
|
79
125
|
get levels() {
|
package/src/types.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// allows to reference interfaces as 'classes' rather than instances
|
|
2
|
-
import { Bool, Field, PublicKey } from "o1js";
|
|
2
|
+
import { Bool, DynamicProof, Field, Proof, ProofBase, PublicKey } from "o1js";
|
|
3
3
|
|
|
4
4
|
export type TypedClass<Class> = new (...args: any[]) => Class;
|
|
5
5
|
|
|
@@ -47,3 +47,12 @@ export const EMPTY_PUBLICKEY = PublicKey.fromObject({
|
|
|
47
47
|
export type OverwriteObjectType<Base, New> = {
|
|
48
48
|
[Key in keyof Base]: Key extends keyof New ? New[Key] : Base[Key];
|
|
49
49
|
} & New;
|
|
50
|
+
|
|
51
|
+
export type InferProofBase<
|
|
52
|
+
ProofType extends Proof<any, any> | DynamicProof<any, any>,
|
|
53
|
+
> =
|
|
54
|
+
ProofType extends Proof<infer PI, infer PO>
|
|
55
|
+
? ProofBase<PI, PO>
|
|
56
|
+
: ProofType extends DynamicProof<infer PI, infer PO>
|
|
57
|
+
? ProofBase<PI, PO>
|
|
58
|
+
: undefined;
|
package/src/utils.ts
CHANGED
|
@@ -6,6 +6,8 @@ import {
|
|
|
6
6
|
Proof,
|
|
7
7
|
} from "o1js";
|
|
8
8
|
|
|
9
|
+
import { TypedClass } from "./types";
|
|
10
|
+
|
|
9
11
|
export function requireTrue(
|
|
10
12
|
condition: boolean,
|
|
11
13
|
errorOrFunction: Error | (() => Error)
|
|
@@ -17,6 +19,27 @@ export function requireTrue(
|
|
|
17
19
|
}
|
|
18
20
|
}
|
|
19
21
|
|
|
22
|
+
/**
|
|
23
|
+
* Utility function to split an array of type T into a record <K, T[]> based on a
|
|
24
|
+
* function T => K that determines the key of each record
|
|
25
|
+
*/
|
|
26
|
+
export function splitArray<T, K extends string | number>(
|
|
27
|
+
arr: T[],
|
|
28
|
+
split: (t: T) => K
|
|
29
|
+
): Record<K, T[] | undefined> {
|
|
30
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
31
|
+
const record = {} as { [Key in K]: T[] };
|
|
32
|
+
arr.forEach((element) => {
|
|
33
|
+
const k = split(element);
|
|
34
|
+
if (record[k] !== undefined) {
|
|
35
|
+
record[k].push(element);
|
|
36
|
+
} else {
|
|
37
|
+
record[k] = [element];
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
return record;
|
|
41
|
+
}
|
|
42
|
+
|
|
20
43
|
export function range(
|
|
21
44
|
startOrEnd: number,
|
|
22
45
|
endOrNothing?: number | undefined
|
|
@@ -39,7 +62,7 @@ export function reduceSequential<T, U>(
|
|
|
39
62
|
array: T[]
|
|
40
63
|
) => Promise<U>,
|
|
41
64
|
initialValue: U
|
|
42
|
-
) {
|
|
65
|
+
): Promise<U> {
|
|
43
66
|
return array.reduce<Promise<U>>(
|
|
44
67
|
async (previousPromise, current, index, arr) => {
|
|
45
68
|
const previous = await previousPromise;
|
|
@@ -52,7 +75,7 @@ export function reduceSequential<T, U>(
|
|
|
52
75
|
export function mapSequential<T, R>(
|
|
53
76
|
array: T[],
|
|
54
77
|
f: (element: T, index: number, array: T[]) => Promise<R>
|
|
55
|
-
) {
|
|
78
|
+
): Promise<R[]> {
|
|
56
79
|
return array.reduce<Promise<R[]>>(async (r, element, index, a) => {
|
|
57
80
|
const ret = await r;
|
|
58
81
|
const next = await f(element, index, a);
|
|
@@ -147,3 +170,31 @@ type NonMethodKeys<Type> = {
|
|
|
147
170
|
[Key in keyof Type]: Type[Key] extends Function ? never : Key;
|
|
148
171
|
}[keyof Type];
|
|
149
172
|
export type NonMethods<Type> = Pick<Type, NonMethodKeys<Type>>;
|
|
173
|
+
|
|
174
|
+
export const MAX_FIELD = Field(Field.ORDER - 1n);
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Returns a boolean indicating whether a given class is a subclass of another class,
|
|
178
|
+
* indicated by the name parameter.
|
|
179
|
+
*/
|
|
180
|
+
// TODO Change to class reference based comparisons
|
|
181
|
+
export function isSubtypeOfName(
|
|
182
|
+
clas: TypedClass<unknown>,
|
|
183
|
+
name: string
|
|
184
|
+
): boolean {
|
|
185
|
+
if (clas === undefined || clas === null) {
|
|
186
|
+
return false;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
if (clas.name === name) {
|
|
190
|
+
return true;
|
|
191
|
+
}
|
|
192
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
193
|
+
return isSubtypeOfName(Object.getPrototypeOf(clas), name);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// TODO Eventually, replace this by a schema validation library
|
|
197
|
+
export function safeParseJson<T>(json: string) {
|
|
198
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
199
|
+
return JSON.parse(json) as T;
|
|
200
|
+
}
|