diff --git a/packages/api/src/graphql/GraphqlSequencerModule.ts b/packages/api/src/graphql/GraphqlSequencerModule.ts index d44144c39..5342e3702 100644 --- a/packages/api/src/graphql/GraphqlSequencerModule.ts +++ b/packages/api/src/graphql/GraphqlSequencerModule.ts @@ -6,7 +6,6 @@ import { Configurable, log, ModuleContainer, - ModulesConfig, ModulesRecord, TypedClass, } from "@proto-kit/common"; @@ -22,20 +21,13 @@ export type GraphqlModulesRecord = ModulesRecord< TypedClass> >; -export interface GraphqlModulesDefintion< - GraphQLModules extends GraphqlModulesRecord, -> { - modules: GraphQLModules; - config?: ModulesConfig; -} - @closeable() export class GraphqlSequencerModule extends ModuleContainer implements Configurable, SequencerModule, Closeable { public static from( - definition: GraphqlModulesDefintion + definition: GraphQLModules ): TypedClass> { return class ScopedGraphQlContainer extends GraphqlSequencerModule { public constructor() { @@ -58,8 +50,8 @@ export class GraphqlSequencerModule this.graphqlServer.setContainer(this.container); // eslint-disable-next-line guard-for-in - for (const moduleName in this.definition.modules) { - const moduleClass = this.definition.modules[moduleName]; + for (const moduleName in this.definition) { + const moduleClass = this.definition[moduleName]; if ( Object.prototype.isPrototypeOf.call( diff --git a/packages/api/src/graphql/modules/QueryGraphqlModule.ts b/packages/api/src/graphql/modules/QueryGraphqlModule.ts index da2ce8413..1b088a240 100644 --- a/packages/api/src/graphql/modules/QueryGraphqlModule.ts +++ b/packages/api/src/graphql/modules/QueryGraphqlModule.ts @@ -317,7 +317,7 @@ export class QueryGraphqlModule< ): ObjMap> { const types: ObjMap> = {}; - for (const key in container.definition.modules) { + for (const key in container.definition) { const query = containerQuery[key]; const moduleTypes: ObjMap> = {}; diff --git a/packages/common/src/config/ModuleContainer.ts b/packages/common/src/config/ModuleContainer.ts index 3977a21e6..eb832040b 100644 --- a/packages/common/src/config/ModuleContainer.ts +++ b/packages/common/src/config/ModuleContainer.ts @@ -109,18 +109,6 @@ export type RecursivePartial = { [Key in keyof T]?: Partial; }; -/** - * Parameters required when creating a module container instance - */ -export interface ModuleContainerDefinition { - modules: Modules; - // config is optional, as it may be provided by the parent/wrapper class - /** - * @deprecated - */ - config?: ModulesConfig; -} - // Removes all keys with a "never" value from an object export type FilterNeverValues> = { [Key in keyof Type as Type[Key] extends never ? never : Key]: Type[Key]; @@ -156,7 +144,7 @@ export class ModuleContainer< private eventEmitterProxy: EventEmitterProxy | undefined = undefined; - public constructor(public definition: ModuleContainerDefinition) { + public constructor(public definition: Modules) { super(); } @@ -164,7 +152,7 @@ export class ModuleContainer< * @returns list of module names */ public get moduleNames() { - return Object.keys(this.definition.modules); + return Object.keys(this.definition); } /** @@ -209,7 +197,7 @@ export class ModuleContainer< public assertIsValidModuleName( moduleName: string ): asserts moduleName is StringKeyOf { - if (!this.isValidModuleName(this.definition.modules, moduleName)) { + if (!this.isValidModuleName(this.definition, moduleName)) { throw errors.onlyValidModuleNames(moduleName); } } @@ -339,13 +327,20 @@ export class ModuleContainer< public resolveOrFail( moduleName: string, - moduleType: TypedClass + moduleType?: TypedClass ) { + if (!this.container.isRegistered(moduleName)) { + throw new Error(`Dependency with token ${moduleName} not registered`); + } + const instance = this.container.resolve(moduleName); - const isValidModuleInstance = instance instanceof moduleType; - if (!isValidModuleInstance) { - throw errors.validModuleInstance(moduleName, moduleType.name); + if (moduleType !== undefined) { + const isValidModuleInstance = instance instanceof moduleType; + + if (!isValidModuleInstance) { + throw errors.validModuleInstance(moduleName, moduleType.name); + } } return instance; @@ -491,6 +486,6 @@ export class ModuleContainer< }); // register all provided modules when the container is created - this.registerModules(this.definition.modules); + this.registerModules(this.definition); } } diff --git a/packages/common/src/config/Startable.ts b/packages/common/src/config/Startable.ts new file mode 100644 index 000000000..8ecdfc111 --- /dev/null +++ b/packages/common/src/config/Startable.ts @@ -0,0 +1,3 @@ +export interface Startable { + start(): Promise; +} diff --git a/packages/common/src/events/EventEmitterProxy.ts b/packages/common/src/events/EventEmitterProxy.ts index 3b055a298..cb7e46b4c 100644 --- a/packages/common/src/events/EventEmitterProxy.ts +++ b/packages/common/src/events/EventEmitterProxy.ts @@ -45,9 +45,7 @@ export class EventEmitterProxy< public constructor(private readonly container: ModuleContainer) { super(); container.moduleNames.forEach((moduleName) => { - if ( - container.isValidModuleName(container.definition.modules, moduleName) - ) { + if (container.isValidModuleName(container.definition, moduleName)) { const module = container.resolve(moduleName); if (this.isEventEmitter(module)) { module.events.onAll((events: any, args: any[]) => { diff --git a/packages/common/src/index.ts b/packages/common/src/index.ts index 1973cccdb..64ba249e5 100644 --- a/packages/common/src/index.ts +++ b/packages/common/src/index.ts @@ -3,6 +3,7 @@ export * from "./config/ConfigurableModule"; export * from "./config/ChildContainerProvider"; export * from "./config/ChildContainerCreatable"; export * from "./config/injectAlias"; +export * from "./config/Startable"; export * from "./types"; export * from "./zkProgrammable/ZkProgrammable"; export * from "./zkProgrammable/ProvableMethodExecutionContext"; diff --git a/packages/common/test/config/ContainerEvents.test.ts b/packages/common/test/config/ContainerEvents.test.ts index 20029b2f0..e4ab7e633 100644 --- a/packages/common/test/config/ContainerEvents.test.ts +++ b/packages/common/test/config/ContainerEvents.test.ts @@ -42,10 +42,8 @@ describe("test event propagation", () => { expect.assertions(1); const container = new TestContainer({ - modules: { - test: TestModule, - test2: TestModule2, - }, + test: TestModule, + test2: TestModule2, }); container.configure({ diff --git a/packages/common/test/config/ModuleContainer.test.ts b/packages/common/test/config/ModuleContainer.test.ts index a418431ff..669ca0591 100644 --- a/packages/common/test/config/ModuleContainer.test.ts +++ b/packages/common/test/config/ModuleContainer.test.ts @@ -84,12 +84,10 @@ describe("moduleContainer", () => { beforeEach(() => { container = new TestModuleContainer({ - modules: { - TestModule, - OtherTestModule, - // this module would not be assignable to TestModuleContainer - // WrongTestModule, - }, + TestModule, + OtherTestModule, + // this module would not be assignable to TestModuleContainer + // WrongTestModule, }); }); diff --git a/packages/deployment/src/environment/Environment.ts b/packages/deployment/src/environment/Environment.ts index 9ff0f160a..06f8e2baf 100644 --- a/packages/deployment/src/environment/Environment.ts +++ b/packages/deployment/src/environment/Environment.ts @@ -1,12 +1,8 @@ -import { log, assertValidTextLogLevel } from "@proto-kit/common"; -import { AppChain } from "@proto-kit/sdk"; +import { log, assertValidTextLogLevel, Startable } from "@proto-kit/common"; +import { AppChain } from "@proto-kit/sequencer"; import yargs from "yargs"; import { hideBin } from "yargs/helpers"; -export interface Startable { - start(): Promise; -} - export type StartableEnvironment = Record; export class Environment { @@ -75,7 +71,7 @@ export class Environment { // TODO Temporary workaround // eslint-disable-next-line @typescript-eslint/consistent-type-assertions - (appChain as unknown as AppChain).configurePartial({ + (appChain as unknown as AppChain).configurePartial({ Sequencer: { DatabasePruneModule: { pruneOnStartup: prune, diff --git a/packages/indexer/src/Indexer.ts b/packages/indexer/src/Indexer.ts index 41b6c7196..3148b9bb1 100644 --- a/packages/indexer/src/Indexer.ts +++ b/packages/indexer/src/Indexer.ts @@ -1,9 +1,4 @@ -import { - ModuleContainer, - ModuleContainerDefinition, - ModulesRecord, - TypedClass, -} from "@proto-kit/common"; +import { ModuleContainer, ModulesRecord, TypedClass } from "@proto-kit/common"; import { container } from "tsyringe"; import { IndexerModule } from "./IndexerModule"; @@ -16,7 +11,7 @@ export class Indexer< Modules extends IndexerModulesRecord, > extends ModuleContainer { public static from( - definition: ModuleContainerDefinition + definition: Modules ): Indexer { return new Indexer(definition); } diff --git a/packages/indexer/test/GeneratedResolverFactoryGraphqlModule.test.ts b/packages/indexer/test/GeneratedResolverFactoryGraphqlModule.test.ts index 28ee7ecce..3ef0ffe06 100644 --- a/packages/indexer/test/GeneratedResolverFactoryGraphqlModule.test.ts +++ b/packages/indexer/test/GeneratedResolverFactoryGraphqlModule.test.ts @@ -30,14 +30,10 @@ class MockedGeneratedResolverFactoryGraphqlModule extends GeneratedResolverFacto describe("GeneratedResolverFactoryGraphqlModule", () => { const indexer = Indexer.from({ - modules: { - GraphqlServer: GraphqlServer, - Graphql: GraphqlSequencerModule.from({ - modules: { - GeneratedResolverFactory: MockedGeneratedResolverFactoryGraphqlModule, - }, - }), - }, + GraphqlServer: GraphqlServer, + Graphql: GraphqlSequencerModule.from({ + GeneratedResolverFactory: MockedGeneratedResolverFactoryGraphqlModule, + }), }); indexer.configurePartial({ diff --git a/packages/indexer/test/IndexBlockTask.test.ts b/packages/indexer/test/IndexBlockTask.test.ts index f55efdd0c..4967bc6dd 100644 --- a/packages/indexer/test/IndexBlockTask.test.ts +++ b/packages/indexer/test/IndexBlockTask.test.ts @@ -12,13 +12,11 @@ import { IndexBlockTask } from "../src/tasks/IndexBlockTask"; describe("IndexBlockTask", () => { const indexer = Indexer.from({ - modules: { - Database: InMemoryDatabase, - TaskQueue: LocalTaskQueue, - LocalTaskWorkerModule: LocalTaskWorkerModule.from({ - IndexBlockTask: IndexBlockTask, - }), - }, + Database: InMemoryDatabase, + TaskQueue: LocalTaskQueue, + LocalTaskWorkerModule: LocalTaskWorkerModule.from({ + IndexBlockTask: IndexBlockTask, + }), }); indexer.configurePartial({ diff --git a/packages/indexer/test/IndexerNotifier.test.ts b/packages/indexer/test/IndexerNotifier.test.ts index 1e595e5b0..1f7e36ff6 100644 --- a/packages/indexer/test/IndexerNotifier.test.ts +++ b/packages/indexer/test/IndexerNotifier.test.ts @@ -49,26 +49,22 @@ class TestBalances extends Balances { function createAppChain() { const appChain = new TestingAppChain({ - Runtime: Runtime.from({ - modules: VanillaRuntimeModules.with({ + Runtime: Runtime.from( + VanillaRuntimeModules.with({ Balances: TestBalances, - }), - }), - Protocol: Protocol.from({ - modules: VanillaProtocolModules.with({}), - }), - Sequencer: Sequencer.from({ - modules: InMemorySequencerModules.with({ + }) + ), + Protocol: Protocol.from(VanillaProtocolModules.with({})), + Sequencer: Sequencer.from( + InMemorySequencerModules.with({ IndexerNotifier: IndexerNotifier, - }), - }), - - modules: { - Signer: InMemorySigner, - TransactionSender: InMemoryTransactionSender, - QueryTransportModule: StateServiceQueryModule, - NetworkStateTransportModule: BlockStorageNetworkStateModule, - }, + }) + ), + + Signer: InMemorySigner, + TransactionSender: InMemoryTransactionSender, + QueryTransportModule: StateServiceQueryModule, + NetworkStateTransportModule: BlockStorageNetworkStateModule, }); appChain.configurePartial({ diff --git a/packages/module/src/runtime/Runtime.ts b/packages/module/src/runtime/Runtime.ts index 1a5795d96..39f54d544 100644 --- a/packages/module/src/runtime/Runtime.ts +++ b/packages/module/src/runtime/Runtime.ts @@ -103,10 +103,7 @@ export class RuntimeZkProgrammable< const runtimeMethods = runtime.runtimeModuleNames.reduce( (allMethods, runtimeModuleName) => { - runtime.isValidModuleName( - runtime.definition.modules, - runtimeModuleName - ); + runtime.isValidModuleName(runtime.definition, runtimeModuleName); /** * Couldnt find a better way to circumvent the type assertion @@ -272,7 +269,7 @@ export class Runtime implements RuntimeEnvironment, CompilableModule { public static from( - definition: RuntimeDefinition + definition: Modules ): TypedClass> { return class RuntimeScoped extends Runtime { public constructor() { @@ -284,7 +281,9 @@ export class Runtime // runtime modules composed into a ZkProgram public program?: ReturnType; - public definition: RuntimeDefinition; + // No idea why we have to do this, but if we don't re-define it here, + // js can't access it from the superclass somehow + public definition: Modules; public zkProgrammable: ZkProgrammable; @@ -293,7 +292,7 @@ export class Runtime * * @param modules - Configuration object for the constructed Runtime */ - public constructor(definition: RuntimeDefinition) { + public constructor(definition: Modules) { super(definition); this.definition = definition; this.zkProgrammable = new RuntimeZkProgrammable(this); @@ -378,7 +377,7 @@ export class Runtime * @returns A list of names of all the registered module names */ public get runtimeModuleNames() { - return Object.keys(this.definition.modules); + return this.moduleNames; } public async compile(registry: CompileRegistry) { diff --git a/packages/module/test/TestingRuntime.ts b/packages/module/test/TestingRuntime.ts index 5b46ce97d..222276027 100644 --- a/packages/module/test/TestingRuntime.ts +++ b/packages/module/test/TestingRuntime.ts @@ -13,9 +13,7 @@ export function createTestingRuntime( } { const state = new InMemoryStateService(); - const Runtimeclass = Runtime.from({ - modules, - }); + const Runtimeclass = Runtime.from(modules); const runtime = new Runtimeclass(); runtime.configure(config); diff --git a/packages/persistance/test-integration/utils.ts b/packages/persistance/test-integration/utils.ts index e42b336e8..5ca2793e1 100644 --- a/packages/persistance/test-integration/utils.ts +++ b/packages/persistance/test-integration/utils.ts @@ -14,9 +14,9 @@ import { import { Protocol } from "@proto-kit/protocol"; // eslint-disable-next-line import/no-extraneous-dependencies import { - AppChain, AppChainTransaction, BlockStorageNetworkStateModule, + ClientAppChain, InMemorySigner, InMemoryTransactionSender, StateServiceQueryModule, @@ -92,37 +92,29 @@ export function createPrismaAppchain( prismaConnection: PrismaDatabaseConfig["connection"], redisConnection: RedisConnectionConfig ) { - const appChain = AppChain.from({ - Protocol: Protocol.from({ - modules: VanillaProtocolModules.mandatoryModules({}), - }), + const appChain = ClientAppChain.from({ + Protocol: Protocol.from(VanillaProtocolModules.mandatoryModules({})), Runtime: Runtime.from({ - modules: { - Balances: MintableBalances, - }, + Balances: MintableBalances, }), Sequencer: Sequencer.from({ - modules: { - Database: PrismaRedisDatabase, + Database: PrismaRedisDatabase, - Mempool: PrivateMempool, - LocalTaskWorkerModule: LocalTaskWorkerModule.from( - VanillaTaskWorkerModules.withoutSettlement() - ), - BaseLayer: NoopBaseLayer, - BatchProducerModule, - BlockProducerModule, - BlockTrigger: ManualBlockTrigger, - TaskQueue: LocalTaskQueue, - SequencerStartupModule, - }, + Mempool: PrivateMempool, + LocalTaskWorkerModule: LocalTaskWorkerModule.from( + VanillaTaskWorkerModules.withoutSettlement() + ), + BaseLayer: NoopBaseLayer, + BatchProducerModule, + BlockProducerModule, + BlockTrigger: ManualBlockTrigger, + TaskQueue: LocalTaskQueue, + SequencerStartupModule, }), - modules: { - Signer: InMemorySigner, - TransactionSender: InMemoryTransactionSender, - QueryTransportModule: StateServiceQueryModule, - NetworkStateTransportModule: BlockStorageNetworkStateModule, - }, + Signer: InMemorySigner, + TransactionSender: InMemoryTransactionSender, + QueryTransportModule: StateServiceQueryModule, + NetworkStateTransportModule: BlockStorageNetworkStateModule, }); appChain.configurePartial({ diff --git a/packages/processor/src/Processor.ts b/packages/processor/src/Processor.ts index a29cdbab8..2ae7d1014 100644 --- a/packages/processor/src/Processor.ts +++ b/packages/processor/src/Processor.ts @@ -1,9 +1,4 @@ -import { - ModuleContainer, - ModuleContainerDefinition, - ModulesRecord, - TypedClass, -} from "@proto-kit/common"; +import { ModuleContainer, ModulesRecord, TypedClass } from "@proto-kit/common"; import { container } from "tsyringe"; import { ProcessorModule } from "./ProcessorModule"; @@ -16,7 +11,7 @@ export class Processor< Modules extends ProcessorModulesRecord, > extends ModuleContainer { public static from( - definition: ModuleContainerDefinition + definition: Modules ): Processor { return new Processor(definition); } diff --git a/packages/protocol/src/protocol/Protocol.ts b/packages/protocol/src/protocol/Protocol.ts index 8d7c9e021..0d1496d86 100644 --- a/packages/protocol/src/protocol/Protocol.ts +++ b/packages/protocol/src/protocol/Protocol.ts @@ -3,8 +3,8 @@ import { ChildContainerProvider, log, ModuleContainer, - ModulesConfig, ModulesRecord, + Startable, StringKeyOf, TypedClass, } from "@proto-kit/common"; @@ -58,20 +58,15 @@ export type MandatoryProtocolModulesRecord = { LastStateRoot: TypedClass; }; -export interface ProtocolDefinition { - modules: Modules; - config?: ModulesConfig; -} - export class Protocol< Modules extends ProtocolModulesRecord & MandatoryProtocolModulesRecord, > extends ModuleContainer - implements ProtocolEnvironment + implements ProtocolEnvironment, Startable { public static from< Modules extends ProtocolModulesRecord & MandatoryProtocolModulesRecord, - >(modules: ProtocolDefinition): TypedClass> { + >(modules: Modules): TypedClass> { return class ScopedProtocol extends Protocol { public constructor() { super(modules); @@ -79,9 +74,11 @@ export class Protocol< }; } - public definition: ProtocolDefinition; + // No idea why we have to do this, but if we don't re-define it here, + // js can't access it from the superclass somehow + public definition: Modules; - public constructor(definition: ProtocolDefinition) { + public constructor(definition: Modules) { super(definition); this.definition = definition; } @@ -115,7 +112,7 @@ export class Protocol< private isModule( moduleName: keyof Modules ): moduleName is StringKeyOf { - return this.definition.modules[moduleName] !== undefined; + return this.definition[moduleName] !== undefined; } public get blockProver(): BlockProvable { @@ -150,10 +147,8 @@ export class Protocol< ABSTRACT_MODULE_TYPES.forEach((moduleTypeRegistration) => { const abstractType = moduleTypeRegistration.type; - const implementingModules = Object.entries( - this.definition.modules - ).filter(([, value]) => - Object.prototype.isPrototypeOf.call(abstractType, value) + const implementingModules = Object.entries(this.definition).filter( + ([, value]) => Object.prototype.isPrototypeOf.call(abstractType, value) ); const newInjectionToken: string | undefined = @@ -213,7 +208,7 @@ export class Protocol< public async start() { // eslint-disable-next-line guard-for-in - for (const moduleName in this.definition.modules) { + for (const moduleName in this.definition) { const protocolModule = this.resolve(moduleName); log.info( diff --git a/packages/protocol/src/settlement/SettlementContractModule.ts b/packages/protocol/src/settlement/SettlementContractModule.ts index 931c1667b..631842d22 100644 --- a/packages/protocol/src/settlement/SettlementContractModule.ts +++ b/packages/protocol/src/settlement/SettlementContractModule.ts @@ -50,7 +50,7 @@ export class SettlementContractModule< extends ModuleContainer implements ProtocolModule { - public constructor(definition: { modules: SettlementModules }) { + public constructor(definition: SettlementModules) { super(definition); } @@ -62,7 +62,7 @@ export class SettlementContractModule< ): TypedClass> { return class ScopedSettlementContractModule extends SettlementContractModule { public constructor() { - super({ modules }); + super(modules); } }; } diff --git a/packages/protocol/test/TestingProtocol.ts b/packages/protocol/test/TestingProtocol.ts index 5785d3221..6370201e8 100644 --- a/packages/protocol/test/TestingProtocol.ts +++ b/packages/protocol/test/TestingProtocol.ts @@ -15,13 +15,11 @@ import { export function createAndInitTestingProtocol() { const ProtocolClass = Protocol.from({ - modules: { - StateTransitionProver: StateTransitionProver, - BlockProver: BlockProver, - AccountState: AccountStateHook, - BlockHeight: BlockHeightHook, - LastStateRoot: LastStateRootBlockHook, - }, + StateTransitionProver: StateTransitionProver, + BlockProver: BlockProver, + AccountState: AccountStateHook, + BlockHeight: BlockHeightHook, + LastStateRoot: LastStateRootBlockHook, }); const protocol = new ProtocolClass(); @@ -36,16 +34,17 @@ export function createAndInitTestingProtocol() { const appChain = container.createChildContainer(); appChain.register("Runtime", { - useClass: Runtime.from({ - modules: { + useFactory: () => { + const runtime = new (Runtime.from({ Balance, NoopRuntime, - }, - config: { + }))(); + runtime.configure({ Balance: {}, NoopRuntime: {}, - }, - }), + }); + return runtime; + }, }); protocol.create(() => appChain.createChildContainer()); diff --git a/packages/protocol/test/prover/statetransition/StateTransitionProver.test.ts b/packages/protocol/test/prover/statetransition/StateTransitionProver.test.ts index 930a2e49e..3349f487d 100644 --- a/packages/protocol/test/prover/statetransition/StateTransitionProver.test.ts +++ b/packages/protocol/test/prover/statetransition/StateTransitionProver.test.ts @@ -1,4 +1,3 @@ -import { InMemoryAreProofsEnabled } from "@proto-kit/sdk"; import { Bool, Field } from "o1js"; import { InMemoryMerkleTreeStorage, @@ -6,6 +5,7 @@ import { RollupMerkleTree, RollupMerkleTreeWitness, } from "@proto-kit/common"; +import { InMemoryAreProofsEnabled } from "@proto-kit/sequencer"; import { AppliedStateTransitionBatchState, diff --git a/packages/sdk/src/appChain/AppChain.ts b/packages/sdk/src/appChain/AppChain.ts deleted file mode 100644 index f7f052dbe..000000000 --- a/packages/sdk/src/appChain/AppChain.ts +++ /dev/null @@ -1,358 +0,0 @@ -/* eslint-disable @typescript-eslint/consistent-type-assertions */ -import { - AreProofsEnabled, - ModuleContainer, - ModulesConfig, - ModulesRecord, - TypedClass, -} from "@proto-kit/common"; -import { - Runtime, - RuntimeModule, - RuntimeModulesRecord, - MethodIdResolver, - MethodParameterEncoder, -} from "@proto-kit/module"; -import { - NetworkStateQuery, - Query, - QueryBuilderFactory, - Sequencer, - SequencerModulesRecord, - UnsignedTransaction, - QueryTransportModule, - NetworkStateTransportModule, - DummyStateService, - WorkerReadyModule, - ConsoleLoggingFactory, -} from "@proto-kit/sequencer"; -import { - NetworkState, - Protocol, - ProtocolModulesRecord, - RuntimeTransaction, - RuntimeMethodExecutionContext, - ProtocolModule, - StateServiceProvider, - MandatoryProtocolModulesRecord, -} from "@proto-kit/protocol"; -import { Field, PublicKey, UInt64 } from "o1js"; -import { container, DependencyContainer } from "tsyringe"; - -import { AppChainTransaction } from "../transaction/AppChainTransaction"; -import { Signer } from "../transaction/InMemorySigner"; -import { TransactionSender } from "../transaction/InMemoryTransactionSender"; - -import { AppChainModule } from "./AppChainModule"; -import { AreProofsEnabledFactory } from "./AreProofsEnabledFactory"; -import { SharedDependencyFactory } from "./SharedDependencyFactory"; - -export type AppChainModulesRecord = ModulesRecord< - TypedClass> ->; - -export interface AppChainDefinition< - RuntimeModules extends RuntimeModulesRecord, - ProtocolModules extends ProtocolModulesRecord & - MandatoryProtocolModulesRecord, - SequencerModules extends SequencerModulesRecord, - AppChainModules extends AppChainModulesRecord, -> { - Runtime: TypedClass>; - Protocol: TypedClass>; - Sequencer: TypedClass>; - modules: AppChainModules; -} - -export type ExpandAppChainModules< - RuntimeModules extends RuntimeModulesRecord, - ProtocolModules extends ProtocolModulesRecord & - MandatoryProtocolModulesRecord, - SequencerModules extends SequencerModulesRecord, - AppChainModules extends AppChainModulesRecord, -> = AppChainModules & { - Runtime: TypedClass>; - Protocol: TypedClass>; - Sequencer: TypedClass>; -}; - -export interface ExpandAppChainDefinition< - RuntimeModules extends RuntimeModulesRecord, - ProtocolModules extends ProtocolModulesRecord & - MandatoryProtocolModulesRecord, - SequencerModules extends SequencerModulesRecord, - AppChainModules extends AppChainModulesRecord, -> { - modules: ExpandAppChainModules< - RuntimeModules, - ProtocolModules, - SequencerModules, - AppChainModules - >; -} - -/** - * Definition of required arguments for AppChain - */ -export interface AppChainConfig< - RuntimeModules extends RuntimeModulesRecord, - ProtocolModules extends ProtocolModulesRecord & - MandatoryProtocolModulesRecord, - SequencerModules extends SequencerModulesRecord, - AppChainModules extends AppChainModulesRecord, -> { - Runtime: ModulesConfig; - Protocol: ModulesConfig; - Sequencer: ModulesConfig; - AppChain: ModulesConfig; -} - -/** - * AppChain acts as a wrapper connecting Runtime, Protocol and Sequencer - */ -export class AppChain< - RuntimeModules extends RuntimeModulesRecord, - ProtocolModules extends ProtocolModulesRecord & - MandatoryProtocolModulesRecord, - SequencerModules extends SequencerModulesRecord, - AppChainModules extends AppChainModulesRecord, -> extends ModuleContainer< - ExpandAppChainModules< - RuntimeModules, - ProtocolModules, - SequencerModules, - AppChainModules - > -> { - // alternative AppChain constructor - public static from< - RuntimeModules extends RuntimeModulesRecord, - ProtocolModules extends ProtocolModulesRecord & - MandatoryProtocolModulesRecord, - SequencerModules extends SequencerModulesRecord, - AppChainModules extends AppChainModulesRecord, - >( - definition: AppChainDefinition< - RuntimeModules, - ProtocolModules, - SequencerModules, - AppChainModules - > - ) { - return new AppChain(definition); - } - - public definition: ExpandAppChainDefinition< - RuntimeModules, - ProtocolModules, - SequencerModules, - AppChainModules - >; - - public constructor( - definition: AppChainDefinition< - RuntimeModules, - ProtocolModules, - SequencerModules, - AppChainModules - > - ) { - const expandedDefinition: ExpandAppChainDefinition< - RuntimeModules, - ProtocolModules, - SequencerModules, - AppChainModules - > = { - modules: { - Runtime: definition.Runtime, - Protocol: definition.Protocol, - Sequencer: definition.Sequencer, - ...definition.modules, - }, - }; - super(expandedDefinition); - this.definition = expandedDefinition; - } - - public get query(): { - runtime: Query, RuntimeModules>; - protocol: Query, ProtocolModules>; - network: NetworkStateQuery; - } { - const queryTransportModule = this.container.resolve( - "QueryTransportModule" - ); - - const networkStateTransportModule = - this.container.resolve( - "NetworkStateTransportModule" - ); - - const network = new NetworkStateQuery(networkStateTransportModule); - - return { - runtime: QueryBuilderFactory.fromRuntime( - this.runtime, - queryTransportModule - ), - - protocol: QueryBuilderFactory.fromProtocol( - this.protocol, - queryTransportModule - ), - - network, - }; - } - - public get runtime(): Runtime { - return this.resolve("Runtime"); - } - - public get sequencer(): Sequencer { - return this.resolve("Sequencer"); - } - - public get protocol(): Protocol { - return this.resolve("Protocol"); - } - - public async transaction( - sender: PublicKey, - callback: () => Promise, - options?: { nonce?: number } - ): Promise { - const executionContext = container.resolve( - RuntimeMethodExecutionContext - ); - - executionContext.setup({ - transaction: RuntimeTransaction.dummyTransaction(), - networkState: NetworkState.empty(), - }); - executionContext.setSimulated(true); - - const stateServiceProvider = this.container.resolve( - "StateServiceProvider" - ); - stateServiceProvider.setCurrentStateService(new DummyStateService()); - - await callback(); - - stateServiceProvider.popCurrentStateService(); - - const { methodName, moduleName, args } = executionContext.current().result; - - // TODO: extract error - if ( - methodName === undefined || - moduleName === undefined || - args === undefined - ) { - throw new Error( - "Unable to determine moduleName, methodName or args for the transaction" - ); - } - - // forgive me, i'll fix this type issue soon - - const runtimeModule = this.runtime.resolve(moduleName as any); - - const encoder = MethodParameterEncoder.fromMethod( - runtimeModule, - methodName - ); - - const { fields, auxiliary } = encoder.encode(args); - - const retrieveNonce = async (publicKey: PublicKey) => { - const query = this.query.protocol as Query< - ProtocolModule, - MandatoryProtocolModulesRecord - >; - const accountState = await query.AccountState.accountState.get(publicKey); - return accountState?.nonce; - }; - - const nonce = - options?.nonce !== undefined - ? UInt64.from(options.nonce) - : (await retrieveNonce(sender)) ?? UInt64.from(0); - - const unsignedTransaction = new UnsignedTransaction({ - methodId: Field( - this.runtime.dependencyContainer - .resolve("MethodIdResolver") - .getMethodId(moduleName, methodName) - ), - - argsFields: fields, - auxiliaryData: auxiliary, - nonce, - sender, - isMessage: false, - }); - - const signer = this.container.resolve("Signer"); - const transactionSender = - this.container.resolve("TransactionSender"); - - const transaction = new AppChainTransaction(signer, transactionSender); - - transaction.withUnsignedTransaction(unsignedTransaction); - - return transaction; - } - - /** - * Starts the appchain and cross-registers runtime to sequencer - */ - public async start( - proofsEnabled: boolean = false, - dependencyContainer: DependencyContainer = container - ) { - this.create(() => dependencyContainer); - - this.useDependencyFactory(AreProofsEnabledFactory); - this.useDependencyFactory(SharedDependencyFactory); - this.useDependencyFactory(ConsoleLoggingFactory); - - this.container - .resolve("AreProofsEnabled") - .setProofsEnabled(proofsEnabled); - - // These three statements are crucial for dependencies inside any of these - // components to access their siblings inside their constructor. - // This is because when it is the first time they are resolved, create() - // will not be called until after the constructor finished because of - // how tsyringe handles hooks - this.resolve("Runtime"); - this.resolve("Protocol"); - this.resolve("Sequencer"); - - // // Workaround to get protocol and sequencer to have - // // access to the same WitnessProviderReference - // const reference = new StateTransitionWitnessProviderReference(); - // this.registerValue({ - // StateTransitionWitnessProviderReference: reference, - // }); - - // console.log("creating sequencer"); - // this.sequencer.create(() => this.container); - - await this.protocol.start(); - - // this.runtime.start(); - await this.sequencer.start(); - - // Wait for readyness for worker-ish configurations - await this.sequencer.dependencyContainer - .resolve(WorkerReadyModule) - .waitForReady(); - } - - public async close() { - await this.sequencer.close(); - } -} -/* eslint-enable @typescript-eslint/consistent-type-assertions */ diff --git a/packages/sdk/src/appChain/AppChainModule.ts b/packages/sdk/src/appChain/AppChainModule.ts deleted file mode 100644 index 0bde89f73..000000000 --- a/packages/sdk/src/appChain/AppChainModule.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { ConfigurableModule, NoConfig, Presets } from "@proto-kit/common"; -import { RuntimeModulesRecord } from "@proto-kit/module"; -import { - MandatoryProtocolModulesRecord, - ProtocolModulesRecord, -} from "@proto-kit/protocol"; -import { SequencerModulesRecord } from "@proto-kit/sequencer"; -import { injectable } from "tsyringe"; - -import type { AppChain, AppChainModulesRecord } from "./AppChain"; - -@injectable() -export class AppChainModule< - Config = NoConfig, -> extends ConfigurableModule { - public static presets: Presets = {}; - - public appChain?: AppChain< - RuntimeModulesRecord, - MandatoryProtocolModulesRecord & ProtocolModulesRecord, - SequencerModulesRecord, - AppChainModulesRecord - >; -} diff --git a/packages/sdk/src/appChain/ClientAppChain.ts b/packages/sdk/src/appChain/ClientAppChain.ts deleted file mode 100644 index 3236fe8ab..000000000 --- a/packages/sdk/src/appChain/ClientAppChain.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { log, TypedClass } from "@proto-kit/common"; -import { - InMemoryStateService, - Runtime, - RuntimeModulesRecord, -} from "@proto-kit/module"; -import { - MandatoryProtocolModulesRecord, - Protocol, - ProtocolModulesRecord, - StateServiceProvider, -} from "@proto-kit/protocol"; -import { - VanillaProtocolModules, - VanillaRuntimeModules, -} from "@proto-kit/library"; -import { Sequencer, SequencerModulesRecord } from "@proto-kit/sequencer"; -import { container } from "tsyringe"; -import { PrivateKey } from "o1js"; - -import { GraphqlClient } from "../graphql/GraphqlClient"; -import { GraphqlQueryTransportModule } from "../graphql/GraphqlQueryTransportModule"; -import { GraphqlNetworkStateTransportModule } from "../graphql/GraphqlNetworkStateTransportModule"; -import { GraphqlTransactionSender } from "../graphql/GraphqlTransactionSender"; -import { Signer } from "../transaction/InMemorySigner"; - -import { AppChain, AppChainModulesRecord } from "./AppChain"; -import { AppChainModule } from "./AppChainModule"; - -export class ClientAppChain< - RuntimeModules extends RuntimeModulesRecord, - ProtocolModules extends ProtocolModulesRecord & - MandatoryProtocolModulesRecord, - SequencerModules extends SequencerModulesRecord, - AppChainModules extends AppChainModulesRecord, -> extends AppChain< - RuntimeModules, - ProtocolModules, - SequencerModules, - AppChainModules -> { - public static fromRuntime< - RuntimeModules extends RuntimeModulesRecord, - SignerType extends Signer & AppChainModule, - >(runtimeModules: RuntimeModules, signer: TypedClass) { - const appChain = new ClientAppChain({ - Runtime: Runtime.from({ - modules: VanillaRuntimeModules.with(runtimeModules), - }), - Protocol: Protocol.from({ - modules: VanillaProtocolModules.with({}), - }), - Sequencer: Sequencer.from({ - modules: {}, - }), - - modules: { - GraphqlClient, - Signer: signer, - TransactionSender: GraphqlTransactionSender, - QueryTransportModule: GraphqlQueryTransportModule, - NetworkStateTransportModule: GraphqlNetworkStateTransportModule, - }, - }); - - appChain.configurePartial({ - Sequencer: {}, - Protocol: { - BlockProver: {}, - StateTransitionProver: {}, - AccountState: {}, - BlockHeight: {}, - LastStateRoot: {}, - TransactionFee: { - tokenId: 0n, - feeRecipient: PrivateKey.random().toPublicKey().toBase58(), - baseFee: 0n, - perWeightUnitFee: 1n, - methods: {}, - }, - }, - - Signer: {}, - TransactionSender: {}, - QueryTransportModule: {}, - NetworkStateTransportModule: {}, - GraphqlClient: { - url: "http://127.0.0.1:8080/graphql", - }, - }); - - /** - * Register state service provider globally, - * to avoid providing an entire sequencer. - * - * Alternatively we could register the state service provider - * in runtime's container, but i think the event emitter proxy - * instantiates runtime/runtime modules before we can register - * the mock state service provider. - */ - const stateServiceProvider = new StateServiceProvider(); - stateServiceProvider.setCurrentStateService(new InMemoryStateService()); - container.registerInstance("StateServiceProvider", stateServiceProvider); - - return appChain; - } - - public async start() { - log.setLevel("ERROR"); - await super.start(); - } -} diff --git a/packages/sdk/src/client/ClientAppChain.ts b/packages/sdk/src/client/ClientAppChain.ts new file mode 100644 index 000000000..71247b88b --- /dev/null +++ b/packages/sdk/src/client/ClientAppChain.ts @@ -0,0 +1,229 @@ +import { ModuleContainer, TypedClass } from "@proto-kit/common"; +import { + InMemoryStateService, + MethodIdResolver, + MethodParameterEncoder, + Runtime, + RuntimeModule, + RuntimeModulesRecord, +} from "@proto-kit/module"; +import { + MandatoryProtocolModulesRecord, + NetworkState, + Protocol, + ProtocolModule, + ProtocolModulesRecord, + RuntimeMethodExecutionContext, + RuntimeTransaction, + StateServiceProvider, +} from "@proto-kit/protocol"; +import { + DummyStateService, + NetworkStateQuery, + NetworkStateTransportModule, + Query, + QueryBuilderFactory, + QueryTransportModule, + Sequencer, + UnsignedTransaction, + AppChain, + AppChainModule, + MinimalAppChainDefinition, +} from "@proto-kit/sequencer"; +import { container } from "tsyringe"; +import { Field, PublicKey, UInt64 } from "o1js"; + +import { GraphqlClient } from "../graphql/GraphqlClient"; +import { GraphqlQueryTransportModule } from "../graphql/GraphqlQueryTransportModule"; +import { GraphqlNetworkStateTransportModule } from "../graphql/GraphqlNetworkStateTransportModule"; +import { GraphqlTransactionSender } from "../graphql/GraphqlTransactionSender"; +import { Signer } from "../transaction/InMemorySigner"; +import { AppChainTransaction } from "../transaction/AppChainTransaction"; +import { TransactionSender } from "../transaction/InMemoryTransactionSender"; + +export type InferModules>> = + Container extends TypedClass + ? Type extends ModuleContainer + ? Modules + : never + : never; + +export class ClientAppChain< + AppChainModules extends MinimalAppChainDefinition, +> extends AppChain { + public static from( + definition: Modules + ) { + return new ClientAppChain(definition); + } + + public static fromRemoteEndpoint< + RuntimeModules extends RuntimeModulesRecord, + ProtocolModules extends ProtocolModulesRecord & + MandatoryProtocolModulesRecord, + SignerType extends Signer & AppChainModule, + >( + runtime: TypedClass>, + protocol: TypedClass>, + signer: TypedClass + ) { + const appChain = new ClientAppChain({ + Runtime: runtime, + Protocol: protocol, + Sequencer: Sequencer.from({}), + + GraphqlClient, + Signer: signer, + TransactionSender: GraphqlTransactionSender, + QueryTransportModule: GraphqlQueryTransportModule, + NetworkStateTransportModule: GraphqlNetworkStateTransportModule, + }); + + appChain.configurePartial({ + Sequencer: {}, + + Signer: {}, + TransactionSender: {}, + QueryTransportModule: {}, + NetworkStateTransportModule: {}, + }); + + /** + * Register state service provider globally, + * to avoid providing an entire sequencer. + * + * Alternatively we could register the state service provider + * in runtime's container, but i think the event emitter proxy + * instantiates runtime/runtime modules before we can register + * the mock state service provider. + */ + const stateServiceProvider = new StateServiceProvider(); + stateServiceProvider.setCurrentStateService(new InMemoryStateService()); + container.registerInstance("StateServiceProvider", stateServiceProvider); + + return appChain; + } + + public async transaction( + sender: PublicKey, + callback: () => Promise, + options?: { nonce?: number } + ): Promise { + const executionContext = container.resolve( + RuntimeMethodExecutionContext + ); + + executionContext.setup({ + transaction: RuntimeTransaction.dummyTransaction(), + networkState: NetworkState.empty(), + }); + executionContext.setSimulated(true); + + const stateServiceProvider = this.container.resolve( + "StateServiceProvider" + ); + stateServiceProvider.setCurrentStateService(new DummyStateService()); + + await callback(); + + stateServiceProvider.popCurrentStateService(); + + const { methodName, moduleName, args } = executionContext.current().result; + + // TODO: extract error + if ( + methodName === undefined || + moduleName === undefined || + args === undefined + ) { + throw new Error( + "Unable to determine moduleName, methodName or args for the transaction" + ); + } + + const runtimeModule = this.runtime.resolveOrFail(moduleName); + + const encoder = MethodParameterEncoder.fromMethod( + runtimeModule, + methodName + ); + + const { fields, auxiliary } = encoder.encode(args); + + const retrieveNonce = async (publicKey: PublicKey) => { + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions + const query = this.query.protocol as Query< + ProtocolModule, + MandatoryProtocolModulesRecord + >; + const accountState = await query.AccountState.accountState.get(publicKey); + return accountState?.nonce; + }; + + const nonce = + options?.nonce !== undefined + ? UInt64.from(options.nonce) + : (await retrieveNonce(sender)) ?? UInt64.from(0); + + const unsignedTransaction = new UnsignedTransaction({ + methodId: Field( + this.runtime.dependencyContainer + .resolve("MethodIdResolver") + .getMethodId(moduleName, methodName) + ), + + argsFields: fields, + auxiliaryData: auxiliary, + nonce, + sender, + isMessage: false, + }); + + const signer = this.container.resolve("Signer"); + const transactionSender = + this.container.resolve("TransactionSender"); + + const transaction = new AppChainTransaction(signer, transactionSender); + + transaction.withUnsignedTransaction(unsignedTransaction); + + return transaction; + } + + public get query(): { + runtime: Query< + RuntimeModule, + InferModules + >; + protocol: Query< + ProtocolModule, + InferModules + >; + network: NetworkStateQuery; + } { + const queryTransportModule = this.container.resolve( + "QueryTransportModule" + ); + + const networkStateTransportModule = + this.container.resolve( + "NetworkStateTransportModule" + ); + + const network = new NetworkStateQuery(networkStateTransportModule); + + return { + runtime: QueryBuilderFactory.fromRuntime( + this.runtime, + queryTransportModule + ), + + protocol: QueryBuilderFactory.fromProtocol( + this.protocol, + queryTransportModule + ), + + network, + }; + } +} diff --git a/packages/sdk/src/graphql/GraphqlClient.ts b/packages/sdk/src/graphql/GraphqlClient.ts index b523905d3..64939587e 100644 --- a/packages/sdk/src/graphql/GraphqlClient.ts +++ b/packages/sdk/src/graphql/GraphqlClient.ts @@ -1,6 +1,5 @@ import { Client, fetchExchange } from "@urql/core"; - -import { AppChainModule } from "../appChain/AppChainModule"; +import { AppChainModule } from "@proto-kit/sequencer"; export interface GraphqlClientConfig { url: string; diff --git a/packages/sdk/src/graphql/GraphqlNetworkStateTransportModule.ts b/packages/sdk/src/graphql/GraphqlNetworkStateTransportModule.ts index c61f53d35..eb406a5aa 100644 --- a/packages/sdk/src/graphql/GraphqlNetworkStateTransportModule.ts +++ b/packages/sdk/src/graphql/GraphqlNetworkStateTransportModule.ts @@ -1,10 +1,11 @@ import { inject, injectable } from "tsyringe"; -import { NetworkStateTransportModule } from "@proto-kit/sequencer"; +import { + NetworkStateTransportModule, + AppChainModule, +} from "@proto-kit/sequencer"; import { NetworkState } from "@proto-kit/protocol"; import { gql } from "@urql/core"; -import { AppChainModule } from "../appChain/AppChainModule"; - import { GraphqlClient } from "./GraphqlClient"; const errors = { diff --git a/packages/sdk/src/graphql/GraphqlQueryTransportModule.ts b/packages/sdk/src/graphql/GraphqlQueryTransportModule.ts index 7a28965e8..baa01dece 100644 --- a/packages/sdk/src/graphql/GraphqlQueryTransportModule.ts +++ b/packages/sdk/src/graphql/GraphqlQueryTransportModule.ts @@ -1,11 +1,9 @@ -import { QueryTransportModule } from "@proto-kit/sequencer"; +import { QueryTransportModule, AppChainModule } from "@proto-kit/sequencer"; import { Field } from "o1js"; import { inject, injectable } from "tsyringe"; import { gql } from "@urql/core"; import { RollupMerkleTreeWitness } from "@proto-kit/common"; -import { AppChainModule } from "../appChain/AppChainModule"; - import { GraphqlClient } from "./GraphqlClient"; function assertStringArray(array: any): asserts array is string[] { diff --git a/packages/sdk/src/graphql/GraphqlTransactionSender.ts b/packages/sdk/src/graphql/GraphqlTransactionSender.ts index f59263fff..6bf97b774 100644 --- a/packages/sdk/src/graphql/GraphqlTransactionSender.ts +++ b/packages/sdk/src/graphql/GraphqlTransactionSender.ts @@ -1,9 +1,8 @@ import { inject, injectable } from "tsyringe"; -import { PendingTransaction } from "@proto-kit/sequencer"; +import { PendingTransaction, AppChainModule } from "@proto-kit/sequencer"; import { gql } from "@urql/core"; import { TransactionSender } from "../transaction/InMemoryTransactionSender"; -import { AppChainModule } from "../appChain/AppChainModule"; import { GraphqlClient } from "./GraphqlClient"; diff --git a/packages/sdk/src/index.ts b/packages/sdk/src/index.ts index 809c14908..8914eded6 100644 --- a/packages/sdk/src/index.ts +++ b/packages/sdk/src/index.ts @@ -8,9 +8,5 @@ export * from "./graphql/GraphqlClient"; export * from "./graphql/GraphqlQueryTransportModule"; export * from "./graphql/GraphqlTransactionSender"; export * from "./graphql/GraphqlNetworkStateTransportModule"; -export * from "./appChain/AppChain"; -export * from "./appChain/AppChainModule"; -export * from "./appChain/TestingAppChain"; -export * from "./appChain/ClientAppChain"; -export * from "./appChain/AreProofsEnabledFactory"; -export * from "./appChain/SharedDependencyFactory"; +export * from "./client/ClientAppChain"; +export * from "./testing/TestingAppChain"; diff --git a/packages/sdk/src/query/BlockStorageNetworkStateModule.ts b/packages/sdk/src/query/BlockStorageNetworkStateModule.ts index 908b63db6..ee2ea21fd 100644 --- a/packages/sdk/src/query/BlockStorageNetworkStateModule.ts +++ b/packages/sdk/src/query/BlockStorageNetworkStateModule.ts @@ -8,11 +8,10 @@ import { SequencerModulesRecord, BlockQueue, BatchStorage, + AppChainModule, } from "@proto-kit/sequencer"; import { NetworkState } from "@proto-kit/protocol"; -import { AppChainModule } from "../appChain/AppChainModule"; - @injectable() export class BlockStorageNetworkStateModule extends AppChainModule> diff --git a/packages/sdk/src/query/StateServiceQueryModule.ts b/packages/sdk/src/query/StateServiceQueryModule.ts index ec78f44aa..b08af4e26 100644 --- a/packages/sdk/src/query/StateServiceQueryModule.ts +++ b/packages/sdk/src/query/StateServiceQueryModule.ts @@ -5,13 +5,12 @@ import { Sequencer, SequencerModulesRecord, AsyncMerkleTreeStore, + AppChainModule, } from "@proto-kit/sequencer"; import { Field } from "o1js"; import { inject, injectable } from "tsyringe"; import { RollupMerkleTree, RollupMerkleTreeWitness } from "@proto-kit/common"; -import { AppChainModule } from "../appChain/AppChainModule"; - @injectable() export class StateServiceQueryModule extends AppChainModule diff --git a/packages/sdk/src/appChain/TestingAppChain.ts b/packages/sdk/src/testing/TestingAppChain.ts similarity index 63% rename from packages/sdk/src/appChain/TestingAppChain.ts rename to packages/sdk/src/testing/TestingAppChain.ts index f4b3eb3b8..edbd13887 100644 --- a/packages/sdk/src/appChain/TestingAppChain.ts +++ b/packages/sdk/src/testing/TestingAppChain.ts @@ -1,49 +1,25 @@ import { Runtime, RuntimeModulesRecord } from "@proto-kit/module"; -import { - MandatoryProtocolModulesRecord, - Protocol, - ProtocolModulesRecord, -} from "@proto-kit/protocol"; +import { Protocol } from "@proto-kit/protocol"; import { VanillaRuntimeModules, VanillaProtocolModules, InMemorySequencerModules, - VanillaRuntimeModulesRecord, MinimalBalances, } from "@proto-kit/library"; +import { TypedClass } from "@proto-kit/common"; import { - PrivateMempool, - Sequencer, - LocalTaskWorkerModule, - NoopBaseLayer, - BatchProducerModule, ManualBlockTrigger, - LocalTaskQueue, - BlockProducerModule, - InMemoryDatabase, - SequencerModulesRecord, + MinimalAppChainDefinition, + Sequencer, VanillaTaskWorkerModules, } from "@proto-kit/sequencer"; -import { TypedClass } from "@proto-kit/common"; import { PrivateKey } from "o1js"; -import { StateServiceQueryModule } from "../query/StateServiceQueryModule"; import { InMemorySigner } from "../transaction/InMemorySigner"; import { InMemoryTransactionSender } from "../transaction/InMemoryTransactionSender"; +import { StateServiceQueryModule } from "../query/StateServiceQueryModule"; import { BlockStorageNetworkStateModule } from "../query/BlockStorageNetworkStateModule"; - -import { AppChain, AppChainModulesRecord } from "./AppChain"; - -export type TestingSequencerModulesRecord = { - Database: typeof InMemoryDatabase; - Mempool: typeof PrivateMempool; - LocalTaskWorkerModule: typeof LocalTaskWorkerModule; - BaseLayer: typeof NoopBaseLayer; - BatchProducerModule: typeof BatchProducerModule; - BlockProducerModule: typeof BlockProducerModule; - BlockTrigger: typeof ManualBlockTrigger; - TaskQueue: typeof LocalTaskQueue; -}; +import { ClientAppChain } from "../client/ClientAppChain"; // ensures we can override vanilla runtime modules type safely // Partial did not work (idk why) @@ -56,37 +32,21 @@ export type PartialVanillaRuntimeModulesRecord = { export const randomFeeRecipient = PrivateKey.random().toPublicKey().toBase58(); export class TestingAppChain< - RuntimeModules extends RuntimeModulesRecord & VanillaRuntimeModulesRecord, - ProtocolModules extends ProtocolModulesRecord & - MandatoryProtocolModulesRecord, - SequencerModules extends SequencerModulesRecord, - AppChainModules extends AppChainModulesRecord, -> extends AppChain< - RuntimeModules, - ProtocolModules, - SequencerModules, - AppChainModules -> { + AppChainModules extends MinimalAppChainDefinition, +> extends ClientAppChain { public static fromRuntime< RuntimeModules extends RuntimeModulesRecord & PartialVanillaRuntimeModulesRecord, >(runtimeModules: RuntimeModules) { const appChain = new TestingAppChain({ - Runtime: Runtime.from({ - modules: VanillaRuntimeModules.with(runtimeModules), - }), - Protocol: Protocol.from({ - modules: VanillaProtocolModules.with({}), - }), - Sequencer: Sequencer.from({ - modules: InMemorySequencerModules.with({}), - }), - modules: { - Signer: InMemorySigner, - TransactionSender: InMemoryTransactionSender, - QueryTransportModule: StateServiceQueryModule, - NetworkStateTransportModule: BlockStorageNetworkStateModule, - }, + Runtime: Runtime.from(VanillaRuntimeModules.with(runtimeModules)), + Protocol: Protocol.from(VanillaProtocolModules.with({})), + Sequencer: Sequencer.from(InMemorySequencerModules.with({})), + + Signer: InMemorySigner, + TransactionSender: InMemoryTransactionSender, + QueryTransportModule: StateServiceQueryModule, + NetworkStateTransportModule: BlockStorageNetworkStateModule, }); appChain.configurePartial({ diff --git a/packages/sdk/src/transaction/AuroSigner.ts b/packages/sdk/src/transaction/AuroSigner.ts index c46e85364..14c999aec 100644 --- a/packages/sdk/src/transaction/AuroSigner.ts +++ b/packages/sdk/src/transaction/AuroSigner.ts @@ -1,7 +1,6 @@ import { Field, Signature } from "o1js"; import { injectable } from "tsyringe"; - -import { AppChainModule } from "../appChain/AppChainModule"; +import { AppChainModule } from "@proto-kit/sequencer"; import { Signer } from "./InMemorySigner"; diff --git a/packages/sdk/src/transaction/InMemorySigner.ts b/packages/sdk/src/transaction/InMemorySigner.ts index 9e0faa9a8..f71fd60f6 100644 --- a/packages/sdk/src/transaction/InMemorySigner.ts +++ b/packages/sdk/src/transaction/InMemorySigner.ts @@ -1,7 +1,6 @@ import { Field, PrivateKey, Signature } from "o1js"; import { injectable } from "tsyringe"; - -import { AppChainModule } from "../appChain/AppChainModule"; +import { AppChainModule } from "@proto-kit/sequencer"; export interface Signer { sign: (signatureData: Field[]) => Promise; diff --git a/packages/sdk/src/transaction/InMemoryTransactionSender.ts b/packages/sdk/src/transaction/InMemoryTransactionSender.ts index 044145822..6b19dcae9 100644 --- a/packages/sdk/src/transaction/InMemoryTransactionSender.ts +++ b/packages/sdk/src/transaction/InMemoryTransactionSender.ts @@ -3,11 +3,10 @@ import { Sequencer, SequencerModulesRecord, PendingTransaction, + AppChainModule, } from "@proto-kit/sequencer"; import { inject, injectable } from "tsyringe"; -import { AppChainModule } from "../appChain/AppChainModule"; - export interface TransactionSender extends AppChainModule { send: (transaction: PendingTransaction) => Promise; } diff --git a/packages/sdk/test/XYK/XYK.test.ts b/packages/sdk/test/XYK/XYK.test.ts index 142d20b9e..652acee83 100644 --- a/packages/sdk/test/XYK/XYK.test.ts +++ b/packages/sdk/test/XYK/XYK.test.ts @@ -2,7 +2,7 @@ import "reflect-metadata"; import { Balance, BalancesKey, TokenId } from "@proto-kit/library"; import { PrivateKey, Provable, PublicKey } from "o1js"; -import { TestingAppChain } from "../../src/appChain/TestingAppChain"; +import { TestingAppChain } from "../../src/testing/TestingAppChain"; import { TestBalances } from "./TestBalances"; import { PoolKey, XYK } from "./XYK"; diff --git a/packages/sdk/test/blockProof/blockProof.test.ts b/packages/sdk/test/blockProof/blockProof.test.ts index 0dc1cbdb1..f2c81ad29 100644 --- a/packages/sdk/test/blockProof/blockProof.test.ts +++ b/packages/sdk/test/blockProof/blockProof.test.ts @@ -17,7 +17,7 @@ import { ManualBlockTrigger } from "@proto-kit/sequencer"; import { InMemoryStateService } from "@proto-kit/module"; import { BalancesKey, TokenId, UInt64 } from "@proto-kit/library"; -import { TestingAppChain } from "../../src/appChain/TestingAppChain"; +import { TestingAppChain } from "../../src/testing/TestingAppChain"; import { TestBalances } from "./TestBalances"; diff --git a/packages/sdk/test/modularization.test.ts b/packages/sdk/test/modularization.test.ts index 981a1de91..307082a71 100644 --- a/packages/sdk/test/modularization.test.ts +++ b/packages/sdk/test/modularization.test.ts @@ -6,11 +6,9 @@ import { VanillaProtocolModules, VanillaRuntimeModules, } from "@proto-kit/library"; -import { Sequencer, SequencerModule } from "@proto-kit/sequencer"; +import { Sequencer, SequencerModule, AppChain } from "@proto-kit/sequencer"; import { PrivateKey } from "o1js"; -import { AppChain } from "../src"; - class TestRuntimeModule extends RuntimeModule { public initialized = false; @@ -48,22 +46,19 @@ class TestSequencerModule extends SequencerModule { describe("modularization", () => { it("should initialize all modules correctly", async () => { const appChain = AppChain.from({ - Runtime: Runtime.from({ - modules: VanillaRuntimeModules.with({ + Runtime: Runtime.from( + VanillaRuntimeModules.with({ TestRuntimeModule, - }), - }), - Protocol: Protocol.from({ - modules: VanillaProtocolModules.with({ + }) + ), + Protocol: Protocol.from( + VanillaProtocolModules.with({ TestProtocolModule, - }), - }), + }) + ), Sequencer: Sequencer.from({ - modules: { - TestSequencerModule, - }, + TestSequencerModule, }), - modules: {}, }); appChain.configurePartial({ diff --git a/packages/sdk/test/networkstate/NetworkState.test.ts b/packages/sdk/test/networkstate/NetworkState.test.ts index 53d8182dd..921b3bd03 100644 --- a/packages/sdk/test/networkstate/NetworkState.test.ts +++ b/packages/sdk/test/networkstate/NetworkState.test.ts @@ -21,7 +21,7 @@ import { log, RollupMerkleTree, expectDefined } from "@proto-kit/common"; import { Field } from "o1js"; import { container } from "tsyringe"; -import { AppChain, InMemorySigner, TestingAppChain } from "../../src"; +import { InMemorySigner, TestingAppChain } from "../../src"; import { BalanceChild } from "./Balance"; @@ -40,18 +40,22 @@ describe.skip("block production", () => { let blockTrigger: ManualBlockTrigger; - let appchain: AppChain; + let appchain: ReturnType; const tokenId = TokenId.from(0); + function createAppChain() { + return TestingAppChain.fromRuntime({ + Balances: BalanceChild, + }); + } + beforeEach(async () => { // container.reset(); log.setLevel(log.levels.INFO); - const app = TestingAppChain.fromRuntime({ - Balances: BalanceChild, - }); + const app = createAppChain(); app.configurePartial({ Runtime: { diff --git a/packages/sequencer/src/appChain/AppChain.ts b/packages/sequencer/src/appChain/AppChain.ts new file mode 100644 index 000000000..d42984f49 --- /dev/null +++ b/packages/sequencer/src/appChain/AppChain.ts @@ -0,0 +1,111 @@ +import { + AreProofsEnabled, + log, + ModuleContainer, + ModulesRecord, + TypedClass, +} from "@proto-kit/common"; +import { Protocol } from "@proto-kit/protocol"; +import { Runtime } from "@proto-kit/module"; +import { container, DependencyContainer } from "tsyringe"; + +import { Sequencer } from "../sequencer/executor/Sequencer"; +import { ConsoleLoggingFactory } from "../logging/ConsoleLoggingFactory"; +import { WorkerReadyModule } from "../worker/worker/WorkerReadyModule"; + +import { AreProofsEnabledFactory } from "./AreProofsEnabledFactory"; +import { SharedDependencyFactory } from "./SharedDependencyFactory"; +import type { AppChainModule } from "./AppChainModule"; + +export type AppChainModulesRecord = ModulesRecord< + TypedClass> +>; + +export type MinimalAppChainDefinition = AppChainModulesRecord & { + Runtime: TypedClass & Runtime>; + Protocol: TypedClass & Protocol>; + Sequencer: TypedClass & Sequencer>; +}; + +/** + * AppChain acts as a wrapper connecting Runtime, Protocol and Sequencer + */ +export class AppChain< + Modules extends MinimalAppChainDefinition, +> extends ModuleContainer { + // alternative AppChain constructor + public static from( + definition: Modules + ) { + return new AppChain(definition); + } + + public constructor(definition: Modules) { + super(definition); + } + + public get runtime(): InstanceType { + return this.resolveOrFail("Runtime"); + } + + public get sequencer(): InstanceType { + return this.resolveOrFail("Sequencer"); + } + + public get protocol(): InstanceType { + return this.resolveOrFail("Protocol"); + } + + /** + * Starts the appchain and cross-registers runtime to sequencer + */ + public async start( + proofsEnabled: boolean = false, + dependencyContainer: DependencyContainer = container + ) { + this.create(() => dependencyContainer); + + this.useDependencyFactory(AreProofsEnabledFactory); + this.useDependencyFactory(SharedDependencyFactory); + this.useDependencyFactory(ConsoleLoggingFactory); + + this.container + .resolve("AreProofsEnabled") + .setProofsEnabled(proofsEnabled); + + // These three statements are crucial for dependencies inside any of these + // components to access their siblings inside their constructor. + // This is because when it is the first time they are resolved, create() + // will not be called until after the constructor finished because of + // how tsyringe handles hooks + this.resolveOrFail("Runtime"); + this.resolveOrFail("Protocol"); + this.resolveOrFail("Sequencer"); + + // // Workaround to get protocol and sequencer to have + // // access to the same WitnessProviderReference + // const reference = new StateTransitionWitnessProviderReference(); + // this.registerValue({ + // StateTransitionWitnessProviderReference: reference, + // }); + + // console.log("creating sequencer"); + // this.sequencer.create(() => this.container); + + await this.protocol.start(); + + // this.runtime.start(); + await this.sequencer.start(); + + // Wait for readiness for worker-ish configurations + await this.sequencer.dependencyContainer + .resolve(WorkerReadyModule) + .waitForReady(); + + log.info("Started!"); + } + + public async close() { + await this.sequencer.close(); + } +} diff --git a/packages/sequencer/src/appChain/AppChainModule.ts b/packages/sequencer/src/appChain/AppChainModule.ts new file mode 100644 index 000000000..6e586a847 --- /dev/null +++ b/packages/sequencer/src/appChain/AppChainModule.ts @@ -0,0 +1,13 @@ +import { ConfigurableModule, NoConfig, Presets } from "@proto-kit/common"; +import { injectable } from "tsyringe"; + +import type { AppChain } from "./AppChain"; + +@injectable() +export class AppChainModule< + Config = NoConfig, +> extends ConfigurableModule { + public static presets: Presets = {}; + + public appChain?: AppChain; +} diff --git a/packages/sdk/src/appChain/AreProofsEnabledFactory.ts b/packages/sequencer/src/appChain/AreProofsEnabledFactory.ts similarity index 100% rename from packages/sdk/src/appChain/AreProofsEnabledFactory.ts rename to packages/sequencer/src/appChain/AreProofsEnabledFactory.ts diff --git a/packages/sdk/src/appChain/SharedDependencyFactory.ts b/packages/sequencer/src/appChain/SharedDependencyFactory.ts similarity index 100% rename from packages/sdk/src/appChain/SharedDependencyFactory.ts rename to packages/sequencer/src/appChain/SharedDependencyFactory.ts diff --git a/packages/sequencer/src/helpers/query/QueryBuilderFactory.ts b/packages/sequencer/src/helpers/query/QueryBuilderFactory.ts index eb69ca104..338b2376c 100644 --- a/packages/sequencer/src/helpers/query/QueryBuilderFactory.ts +++ b/packages/sequencer/src/helpers/query/QueryBuilderFactory.ts @@ -150,7 +150,7 @@ export const QueryBuilderFactory = { runtime: Runtime, queryTransportModule: QueryTransportModule ): Query, RuntimeModules> { - const { modules } = runtime.definition; + const modules = runtime.definition; return Object.keys(modules).reduce< Query, RuntimeModules> @@ -176,7 +176,7 @@ export const QueryBuilderFactory = { protocol: Protocol, queryTransportModule: QueryTransportModule ): Query, ProtocolModules> { - const { modules } = protocol.definition; + const modules = protocol.definition; return Object.keys(modules).reduce< Query, ProtocolModules> diff --git a/packages/sequencer/src/index.ts b/packages/sequencer/src/index.ts index 476da4de4..04b4a7e79 100644 --- a/packages/sequencer/src/index.ts +++ b/packages/sequencer/src/index.ts @@ -105,3 +105,7 @@ export * from "./logging/Tracer"; export * from "./logging/trace"; export * from "./logging/ConsoleLoggingFactory"; export * from "./logging/ConsoleTracer"; +export * from "./appChain/AppChain"; +export * from "./appChain/AppChainModule"; +export * from "./appChain/AreProofsEnabledFactory"; +export * from "./appChain/SharedDependencyFactory"; diff --git a/packages/sequencer/src/protocol/production/tasks/TransactionProvingTask.ts b/packages/sequencer/src/protocol/production/tasks/TransactionProvingTask.ts index 7a27b2f9c..38473a22c 100644 --- a/packages/sequencer/src/protocol/production/tasks/TransactionProvingTask.ts +++ b/packages/sequencer/src/protocol/production/tasks/TransactionProvingTask.ts @@ -72,7 +72,7 @@ export class TransactionProvingTask private readonly compileRegistry: CompileRegistry ) { super(); - this.blockProver = this.protocol.blockProver; + this.blockProver = protocol.blockProver; } public inputSerializer(): TaskSerializer { diff --git a/packages/sequencer/src/sequencer/builder/SequencerModule.ts b/packages/sequencer/src/sequencer/builder/SequencerModule.ts index 50a66c611..27ab92b27 100644 --- a/packages/sequencer/src/sequencer/builder/SequencerModule.ts +++ b/packages/sequencer/src/sequencer/builder/SequencerModule.ts @@ -4,6 +4,7 @@ import { TypedClass, Presets, NoConfig, + Startable, } from "@proto-kit/common"; import { injectable } from "tsyringe"; @@ -12,9 +13,10 @@ import { injectable } from "tsyringe"; * * start(): Executed to execute any logic required to start the module */ -export abstract class SequencerModule< - Config = NoConfig, -> extends ConfigurableModule { +export abstract class SequencerModule + extends ConfigurableModule + implements Startable +{ public static presets: Presets = {}; /** diff --git a/packages/sequencer/src/sequencer/executor/Sequenceable.ts b/packages/sequencer/src/sequencer/executor/Sequenceable.ts index 683bbad03..b579523f5 100644 --- a/packages/sequencer/src/sequencer/executor/Sequenceable.ts +++ b/packages/sequencer/src/sequencer/executor/Sequenceable.ts @@ -1,3 +1,3 @@ -export interface Sequenceable { - start: () => Promise; -} +import { Startable } from "@proto-kit/common"; + +export interface Sequenceable extends Startable {} diff --git a/packages/sequencer/src/sequencer/executor/Sequencer.ts b/packages/sequencer/src/sequencer/executor/Sequencer.ts index 88e87b99e..138aa2854 100644 --- a/packages/sequencer/src/sequencer/executor/Sequencer.ts +++ b/packages/sequencer/src/sequencer/executor/Sequencer.ts @@ -2,7 +2,6 @@ import { ModuleContainer, ModulesRecord, TypedClass, - ModuleContainerDefinition, log, } from "@proto-kit/common"; import { @@ -37,7 +36,7 @@ export class Sequencer * @returns Sequencer */ public static from( - definition: ModuleContainerDefinition + definition: Modules ): TypedClass> { return class ScopedSequencer extends Sequencer { public constructor() { @@ -78,7 +77,7 @@ export class Sequencer this.useDependencyFactory(MethodIdFactory); // Log startup info - const moduleClassNames = Object.values(this.definition.modules).map( + const moduleClassNames = Object.values(this.definition).map( (clazz) => clazz.name ); log.info("Starting sequencer..."); @@ -88,7 +87,7 @@ export class Sequencer // to ensure every time a module is resolved it gets recorded. const orderedModules: Extract[] = []; // eslint-disable-next-line guard-for-in - for (const moduleName in this.definition.modules) { + for (const moduleName in this.definition) { this.container.afterResolution( moduleName, () => { @@ -102,11 +101,9 @@ export class Sequencer // Iteration #2: We resolve each module and thus populate // the orderedModules list to understand the sequencing. // eslint-disable-next-line guard-for-in - for (const moduleName in this.definition.modules) { - const sequencerModule = this.resolve(moduleName); - log.info( - `Resolving sequencer module ${moduleName} (${sequencerModule.constructor.name})` - ); + for (const moduleName in this.definition) { + log.info(`Resolving sequencer module ${moduleName}`); + this.resolve(moduleName); } // Iteration #3: We now iterate though the orderedModules list diff --git a/packages/sequencer/src/worker/worker/LocalTaskWorkerModule.ts b/packages/sequencer/src/worker/worker/LocalTaskWorkerModule.ts index 5b55fddc8..97aec991a 100644 --- a/packages/sequencer/src/worker/worker/LocalTaskWorkerModule.ts +++ b/packages/sequencer/src/worker/worker/LocalTaskWorkerModule.ts @@ -78,7 +78,7 @@ export class LocalTaskWorkerModule } public constructor(modules: Tasks) { - super({ modules }); + super(modules); // Since we disabled configs for tasks, we initialize the config as empty here const config = Object.keys(modules).reduce>( diff --git a/packages/sequencer/test-integration/workers/modules.ts b/packages/sequencer/test-integration/workers/modules.ts index 7f3481b5d..223abd976 100644 --- a/packages/sequencer/test-integration/workers/modules.ts +++ b/packages/sequencer/test-integration/workers/modules.ts @@ -8,20 +8,14 @@ import { ProvenBalance } from "../../test/integration/mocks/ProvenBalance"; import { ProtocolStateTestHook } from "../../test/integration/mocks/ProtocolStateTestHook"; export const runtimeClass = Runtime.from({ - modules: { - Balance: ProvenBalance, - }, - - config: { - Balance: {}, - }, + Balance: ProvenBalance, }); -export const protocolClass = Protocol.from({ - modules: VanillaProtocolModules.mandatoryModules({ +export const protocolClass = Protocol.from( + VanillaProtocolModules.mandatoryModules({ ProtocolStateTestHook, - }), -}); + }) +); export const runtimeProtocolConfig: ModulesConfig<{ Runtime: typeof runtimeClass; diff --git a/packages/sequencer/test-integration/workers/worker.test.ts b/packages/sequencer/test-integration/workers/worker.test.ts index dfc049ac4..7458ea846 100644 --- a/packages/sequencer/test-integration/workers/worker.test.ts +++ b/packages/sequencer/test-integration/workers/worker.test.ts @@ -1,10 +1,10 @@ import "reflect-metadata"; -import { AppChain } from "@proto-kit/sdk"; import { BullQueue } from "@proto-kit/deployment"; import { container } from "tsyringe"; import { log, sleep } from "@proto-kit/common"; import { + AppChain, LocalTaskWorkerModule, Sequencer, VanillaTaskWorkerModules, @@ -21,19 +21,16 @@ import { MinimumWorkerModules } from "./WorkerModules"; describe("worker", () => { it("spin up and wait", async () => { const sequencerClass = Sequencer.from({ - modules: { - TaskQueue: BullQueue, - LocalTaskWorkerModule: LocalTaskWorkerModule.from( - VanillaTaskWorkerModules.withoutSettlement() - ), - } satisfies MinimumWorkerModules, - }); + TaskQueue: BullQueue, + LocalTaskWorkerModule: LocalTaskWorkerModule.from( + VanillaTaskWorkerModules.withoutSettlement() + ), + } satisfies MinimumWorkerModules); const app = AppChain.from({ Runtime: runtimeClass, Sequencer: sequencerClass, Protocol: protocolClass, - modules: {}, }); app.configure({ diff --git a/packages/sequencer/test-integration/workers/workers-proven.test.ts b/packages/sequencer/test-integration/workers/workers-proven.test.ts index 8a971093c..5724c4e39 100644 --- a/packages/sequencer/test-integration/workers/workers-proven.test.ts +++ b/packages/sequencer/test-integration/workers/workers-proven.test.ts @@ -55,24 +55,21 @@ describe("worker-proven", () => { log.setLevel(log.levels.DEBUG); const sequencerClass = Sequencer.from({ - modules: { - Database: InMemoryDatabase, - Mempool: PrivateMempool, - BaseLayer: NoopBaseLayer, - BatchProducerModule, - BlockProducerModule, - BlockTrigger: ManualBlockTrigger, - TaskQueue: BullQueue, - FeeStrategy: ConstantFeeStrategy, - SequencerStartupModule, - }, + Database: InMemoryDatabase, + Mempool: PrivateMempool, + BaseLayer: NoopBaseLayer, + BatchProducerModule, + BlockProducerModule, + BlockTrigger: ManualBlockTrigger, + TaskQueue: BullQueue, + FeeStrategy: ConstantFeeStrategy, + SequencerStartupModule, }); const app = AppChain.from({ Runtime: runtimeClass, Sequencer: sequencerClass, Protocol: protocolClass, - modules: {}, }); app.configure({ diff --git a/packages/sequencer/test/appchain/AppChain-typing.test.ts b/packages/sequencer/test/appchain/AppChain-typing.test.ts new file mode 100644 index 000000000..168d71f98 --- /dev/null +++ b/packages/sequencer/test/appchain/AppChain-typing.test.ts @@ -0,0 +1,45 @@ +import "reflect-metadata"; +import { Runtime } from "@proto-kit/module"; +import { Balances, VanillaProtocolModules } from "@proto-kit/library"; +import { Protocol, StateTransitionProverType } from "@proto-kit/protocol"; + +import { AppChain, InMemoryDatabase, Sequencer } from "../../src"; + +/* eslint-disable @typescript-eslint/no-unused-vars */ + +function foo() { + // We want this code to only typecheck, not execute + + const app = AppChain.from({ + Runtime: Runtime.from({ + Balances, + }), + Protocol: Protocol.from(VanillaProtocolModules.with({})), + Sequencer: Sequencer.from({ + Database: InMemoryDatabase, + }), + }); + + const case1 = app.protocol.resolve( + "StateTransitionProver" + ) satisfies StateTransitionProverType; + const case2 = app + .resolve("Protocol") + .resolve("StateTransitionProver") satisfies StateTransitionProverType; + + const case3 = app.runtime.resolve("Balances") satisfies Balances; + const case4 = app + .resolve("Runtime") + .resolve("Balances") satisfies Balances; + + const case5 = app.sequencer.resolve("Database") satisfies InMemoryDatabase; + const case6 = app + .resolve("Sequencer") + .resolve("Database") satisfies InMemoryDatabase; +} + +it("dummy", () => { + expect(1).toBe(1); +}); + +/* eslint-enable @typescript-eslint/no-unused-vars */ diff --git a/packages/sequencer/test/integration/BlockProduction.test.ts b/packages/sequencer/test/integration/BlockProduction.test.ts index 049b5d223..ca2fd4939 100644 --- a/packages/sequencer/test/integration/BlockProduction.test.ts +++ b/packages/sequencer/test/integration/BlockProduction.test.ts @@ -20,12 +20,12 @@ import { Protocol, PROTOKIT_PREFIXES, } from "@proto-kit/protocol"; -import { AppChain } from "@proto-kit/sdk"; import { Bool, Field, PrivateKey, PublicKey, Struct, UInt64 } from "o1js"; import "reflect-metadata"; import { container } from "tsyringe"; import { + AppChain, BatchStorage, HistoricalBatchStorage, Sequencer, @@ -92,42 +92,30 @@ describe("block production", () => { // let protocol: Protocol; // eslint-disable-next-line @typescript-eslint/no-unused-vars - let appChain: AppChain; + let appChain: AppChain; let test: BlockTestService; beforeEach(async () => { const runtimeClass = Runtime.from({ - modules: { - Balance, - NoopRuntime, - EventMaker, - }, - - config: { - Balance: {}, - NoopRuntime: {}, - EventMaker: {}, - }, + Balance, + NoopRuntime, + EventMaker, }); - const sequencerClass = Sequencer.from({ - modules: testingSequencerModules({}), - }); + const sequencerClass = Sequencer.from(testingSequencerModules({})); // TODO Analyze how we can get rid of the library import for mandatory modules - const protocolClass = Protocol.from({ - modules: VanillaProtocolModules.mandatoryModules({ + const protocolClass = Protocol.from( + VanillaProtocolModules.mandatoryModules({ ProtocolStateTestHook, - }), - // modules: VanillaProtocolModules.with({}), - }); + }) + ); const app = AppChain.from({ Runtime: runtimeClass, Sequencer: sequencerClass, Protocol: protocolClass, - modules: {}, }); app.configure({ @@ -175,6 +163,7 @@ describe("block production", () => { }); it("should produce a dummy block proof", async () => { + log.setLevel("TRACE"); expect.assertions(26); const privateKey = PrivateKey.random(); diff --git a/packages/sequencer/test/integration/BlockProductionSize.test.ts b/packages/sequencer/test/integration/BlockProductionSize.test.ts index 14ed46a1b..f47279974 100644 --- a/packages/sequencer/test/integration/BlockProductionSize.test.ts +++ b/packages/sequencer/test/integration/BlockProductionSize.test.ts @@ -2,7 +2,6 @@ import { log } from "@proto-kit/common"; import { VanillaProtocolModules } from "@proto-kit/library"; import { Runtime } from "@proto-kit/module"; import { Protocol } from "@proto-kit/protocol"; -import { AppChain } from "@proto-kit/sdk"; import { Bool, PrivateKey, Struct, UInt64 } from "o1js"; import "reflect-metadata"; import { container } from "tsyringe"; @@ -12,6 +11,7 @@ import { PrivateMempool, Sequencer, VanillaTaskWorkerModules, + AppChain, } from "../../src"; import { DefaultTestingSequencerModules, @@ -44,33 +44,23 @@ describe("block limit", () => { log.setLevel(log.levels.INFO); const runtimeClass = Runtime.from({ - modules: { - Balance, - NoopRuntime, - }, - - config: { - Balance: {}, - NoopRuntime: {}, - }, + Balance, + NoopRuntime, }); async function setUpAppChain(maxBlockSize: number | undefined) { - const sequencerClass = Sequencer.from({ - modules: testingSequencerModules({}), - }); + const sequencerClass = Sequencer.from(testingSequencerModules({})); - const protocolClass = Protocol.from({ - modules: VanillaProtocolModules.mandatoryModules({ + const protocolClass = Protocol.from( + VanillaProtocolModules.mandatoryModules({ ProtocolStateTestHook, - }), - }); + }) + ); const app = AppChain.from({ Runtime: runtimeClass, Sequencer: sequencerClass, Protocol: protocolClass, - modules: {}, }); log.setLevel("TRACE"); diff --git a/packages/sequencer/test/integration/Mempool.test.ts b/packages/sequencer/test/integration/Mempool.test.ts index a9b58207b..1eb68606a 100644 --- a/packages/sequencer/test/integration/Mempool.test.ts +++ b/packages/sequencer/test/integration/Mempool.test.ts @@ -1,8 +1,7 @@ import { log, TypedClass } from "@proto-kit/common"; import { VanillaProtocolModules } from "@proto-kit/library"; import { Runtime } from "@proto-kit/module"; -import { MandatoryProtocolModulesRecord, Protocol } from "@proto-kit/protocol"; -import { AppChain } from "@proto-kit/sdk"; +import { Protocol } from "@proto-kit/protocol"; import { Bool, PrivateKey, UInt64 } from "o1js"; import "reflect-metadata"; import { container } from "tsyringe"; @@ -14,6 +13,7 @@ import { SequencerModule, StorageDependencyFactory, VanillaTaskWorkerModules, + AppChain, } from "../../src"; import { DefaultTestingSequencerModules, @@ -29,14 +29,7 @@ describe.each([["InMemory", InMemoryDatabase]])( testName, Database: TypedClass ) => { - let appChain: AppChain< - { Balance: typeof Balance }, - MandatoryProtocolModulesRecord, - DefaultTestingSequencerModules & { - Database: typeof Database; - }, - {} - >; + let appChain: ReturnType; let sequencer: Sequencer< DefaultTestingSequencerModules & { Database: typeof Database } >; @@ -73,33 +66,28 @@ describe.each([["InMemory", InMemoryDatabase]])( ); const user3PublicKey = user3PrivateKey.toPublicKey(); - beforeEach(async () => { - log.setLevel(log.levels.INFO); - + function createAppChain() { const runtimeClass = Runtime.from({ - modules: { - Balance, - }, - - config: { - Balance: {}, - }, + Balance, }); - const sequencerClass = Sequencer.from({ - modules: testingSequencerModules({}), - }); + const sequencerClass = Sequencer.from(testingSequencerModules({})); - const protocolClass = Protocol.from({ - modules: VanillaProtocolModules.mandatoryModules({}), - }); + const protocolClass = Protocol.from( + VanillaProtocolModules.mandatoryModules({}) + ); - appChain = AppChain.from({ + return AppChain.from({ Sequencer: sequencerClass, Runtime: runtimeClass, Protocol: protocolClass, - modules: {}, }); + } + + beforeEach(async () => { + log.setLevel(log.levels.INFO); + + appChain = createAppChain(); appChain.configure({ Runtime: { @@ -116,7 +104,6 @@ describe.each([["InMemory", InMemoryDatabase]])( BaseLayer: {}, TaskQueue: {}, SequencerStartupModule: {}, - ProtocolStartupModule: {}, }, Protocol: { AccountState: {}, diff --git a/packages/sequencer/test/integration/Proven.test.ts b/packages/sequencer/test/integration/Proven.test.ts index 1ba469b83..f3213765c 100644 --- a/packages/sequencer/test/integration/Proven.test.ts +++ b/packages/sequencer/test/integration/Proven.test.ts @@ -16,7 +16,6 @@ import { SettlementSmartContractBase, } from "@proto-kit/protocol"; import { VanillaProtocolModules } from "@proto-kit/library"; -import { AppChain, InMemoryAreProofsEnabled } from "@proto-kit/sdk"; import { container } from "tsyringe"; import { PrivateKey, UInt64 } from "o1js"; @@ -29,6 +28,8 @@ import { SettlementProvingTask, VanillaTaskWorkerModules, WithdrawalQueue, + AppChain, + InMemoryAreProofsEnabled, } from "../../src"; import { SettlementStartupModule } from "../../src/sequencer/SettlementStartupModule"; @@ -41,56 +42,52 @@ const timeout = 300000; describe.skip("Proven", () => { let test: BlockTestService; - let appChain: AppChain; + let appChain: ReturnType; - it( - "should start up and compile", - async () => { - log.setLevel(log.levels.DEBUG); - const runtimeClass = Runtime.from({ - modules: { - Balances: ProvenBalance, - }, + function createAppChain() { + const runtimeClass = Runtime.from({ + Balances: ProvenBalance, + }); - config: { - Balances: {}, + const sequencerClass = Sequencer.from( + testingSequencerModules( + { + BaseLayer: MinaBaseLayer, + SettlementModule, + OutgoingMessageQueue: WithdrawalQueue, }, - }); + { + SettlementProvingTask, + } + ) + ); - const sequencerClass = Sequencer.from({ - modules: testingSequencerModules( - { - BaseLayer: MinaBaseLayer, - SettlementModule, - OutgoingMessageQueue: WithdrawalQueue, - }, - { - SettlementProvingTask, - } - ), - }); + // TODO Analyze how we can get rid of the library import for mandatory modules + const protocolClass = Protocol.from({ + ...VanillaProtocolModules.mandatoryModules({ + ProtocolStateTestHook, + // ProtocolStateTestHook2, + }), + SettlementContractModule: SettlementContractModule.with({ + // FungibleToken: FungibleTokenContractModule, + // FungibleTokenAdmin: FungibleTokenAdminContractModule, + }), + // modules: VanillaProtocolModules.with({}), + }); + + return AppChain.from({ + Runtime: runtimeClass, + Sequencer: sequencerClass, + Protocol: protocolClass, + }); + } - // TODO Analyze how we can get rid of the library import for mandatory modules - const protocolClass = Protocol.from({ - modules: { - ...VanillaProtocolModules.mandatoryModules({ - ProtocolStateTestHook, - // ProtocolStateTestHook2, - }), - SettlementContractModule: SettlementContractModule.with({ - // FungibleToken: FungibleTokenContractModule, - // FungibleTokenAdmin: FungibleTokenAdminContractModule, - }), - }, - // modules: VanillaProtocolModules.with({}), - }); + it( + "should start up and compile", + async () => { + log.setLevel(log.levels.DEBUG); - const app = AppChain.from({ - Runtime: runtimeClass, - Sequencer: sequencerClass, - Protocol: protocolClass, - modules: {}, - }); + const app = createAppChain(); app.configure({ Sequencer: { diff --git a/packages/sequencer/test/integration/StorageIntegration.test.ts b/packages/sequencer/test/integration/StorageIntegration.test.ts index 88213a936..930ff2cfd 100644 --- a/packages/sequencer/test/integration/StorageIntegration.test.ts +++ b/packages/sequencer/test/integration/StorageIntegration.test.ts @@ -1,9 +1,8 @@ import "reflect-metadata"; import { expect } from "@jest/globals"; import { VanillaProtocolModules } from "@proto-kit/library"; -import { MandatoryProtocolModulesRecord, Protocol } from "@proto-kit/protocol"; +import { Protocol } from "@proto-kit/protocol"; import { Runtime } from "@proto-kit/module"; -import { AppChain } from "@proto-kit/sdk"; import { Bool, Field, PrivateKey, UInt64 } from "o1js"; import { TypedClass, expectDefined } from "@proto-kit/common"; @@ -20,6 +19,7 @@ import { StorageDependencyFactory, BlockStorage, VanillaTaskWorkerModules, + AppChain, } from "../../src"; import { DefaultTestingSequencerModules, @@ -52,12 +52,7 @@ describe.each([["InMemory", InMemoryDatabase]])( testName, Database: TypedClass ) => { - let appChain: AppChain< - { Balance: typeof Balance }, - MandatoryProtocolModulesRecord, - DefaultTestingSequencerModules & { Database: typeof Database }, - {} - >; + let appChain: ReturnType; let sequencer: Sequencer< DefaultTestingSequencerModules & { Database: typeof Database } >; @@ -73,29 +68,30 @@ describe.each([["InMemory", InMemoryDatabase]])( const pk = sk.toPublicKey(); let pkNonce = 0; - beforeAll(async () => { - const sequencerClass = Sequencer.from({ - modules: testingSequencerModules({ + function createAppChain() { + const sequencerClass = Sequencer.from( + testingSequencerModules({ Database, - }), - }); + }) + ); const runtimeClass = Runtime.from({ - modules: { - Balance, - }, + Balance, }); - const protocolClass = Protocol.from({ - modules: VanillaProtocolModules.mandatoryModules({}), - }); + const protocolClass = Protocol.from( + VanillaProtocolModules.mandatoryModules({}) + ); - appChain = AppChain.from({ + return AppChain.from({ Sequencer: sequencerClass, Runtime: runtimeClass, Protocol: protocolClass, - modules: {}, }); + } + + beforeAll(async () => { + appChain = createAppChain(); appChain.configure({ Runtime: { diff --git a/packages/sequencer/test/protocol/production/sequencing/atomic-block-production.test.ts b/packages/sequencer/test/protocol/production/sequencing/atomic-block-production.test.ts index 22a12bd41..a9b156023 100644 --- a/packages/sequencer/test/protocol/production/sequencing/atomic-block-production.test.ts +++ b/packages/sequencer/test/protocol/production/sequencing/atomic-block-production.test.ts @@ -2,7 +2,6 @@ import "reflect-metadata"; import { Runtime } from "@proto-kit/module"; import { Protocol } from "@proto-kit/protocol"; import { VanillaProtocolModules } from "@proto-kit/library"; -import { AppChain } from "@proto-kit/sdk"; import { container } from "tsyringe"; import { jest } from "@jest/globals"; import { expectDefined } from "@proto-kit/common"; @@ -12,47 +11,40 @@ import { ManualBlockTrigger, Sequencer, VanillaTaskWorkerModules, + AppChain, + BlockResultService, } from "../../../../src"; import { ProtocolStateTestHook } from "../../../integration/mocks/ProtocolStateTestHook"; -import { - DefaultTestingSequencerModules, - testingSequencerModules, -} from "../../../TestingSequencer"; +import { testingSequencerModules } from "../../../TestingSequencer"; import { Balance } from "../../../integration/mocks/Balance"; -import { BlockResultService } from "../../../../src/protocol/production/sequencing/BlockResultService"; describe("atomic block production", () => { - let appchain: AppChain; + let appchain: ReturnType; let trigger: ManualBlockTrigger; - beforeEach(async () => { + function createAppChain() { const runtimeClass = Runtime.from({ - modules: { - Balance, - }, - - config: { - Balance: {}, - }, + Balance, }); - const sequencerClass = Sequencer.from({ - modules: testingSequencerModules({}), - }); + const sequencerClass = Sequencer.from(testingSequencerModules({})); - const protocolClass = Protocol.from({ - modules: VanillaProtocolModules.mandatoryModules({ + const protocolClass = Protocol.from( + VanillaProtocolModules.mandatoryModules({ ProtocolStateTestHook, - }), - }); + }) + ); - const app = AppChain.from({ + return AppChain.from({ Runtime: runtimeClass, Sequencer: sequencerClass, Protocol: protocolClass, - modules: {}, }); + } + + beforeEach(async () => { + const app = createAppChain(); app.configure({ Sequencer: { diff --git a/packages/sequencer/test/sequencer/executor/Sequencer.test.ts b/packages/sequencer/test/sequencer/executor/Sequencer.test.ts index e1bfe4ea1..f97b32df7 100644 --- a/packages/sequencer/test/sequencer/executor/Sequencer.test.ts +++ b/packages/sequencer/test/sequencer/executor/Sequencer.test.ts @@ -47,11 +47,9 @@ describe("Sequencer close", () => { } const sequencer = new (Sequencer.from({ - modules: { - Foo: CloseableModule, - Bar: CloseableModule, - D: DependencyFactoryModule, - }, + Foo: CloseableModule, + Bar: CloseableModule, + D: DependencyFactoryModule, }))(); sequencer.create(() => container.createChildContainer()); sequencer.configure({ diff --git a/packages/sequencer/test/settlement/Settlement.ts b/packages/sequencer/test/settlement/Settlement.ts index 4fcda0d93..8cb945e80 100644 --- a/packages/sequencer/test/settlement/Settlement.ts +++ b/packages/sequencer/test/settlement/Settlement.ts @@ -18,7 +18,7 @@ import { TokenBridgeTree, } from "@proto-kit/protocol"; import { - AppChain, + ClientAppChain, BlockStorageNetworkStateModule, InMemorySigner, InMemoryTransactionSender, @@ -110,18 +110,16 @@ export const settlementTestFn = ( function setupAppChain() { const runtime = Runtime.from({ - modules: { - Balances, - Withdrawals, - }, + Balances, + Withdrawals, }); // eslint-disable-next-line @typescript-eslint/dot-notation SettlementUtils.prototype["isSignedSettlement"] = () => settlementType === "signed"; - const sequencer = Sequencer.from({ - modules: testingSequencerModules( + const sequencer = Sequencer.from( + testingSequencerModules( { BaseLayer: MinaBaseLayer, SettlementModule: SettlementModule, @@ -130,29 +128,25 @@ export const settlementTestFn = ( { SettlementProvingTask, } - ), - }); + ) + ); - const appchain = AppChain.from({ + const appchain = ClientAppChain.from({ Runtime: runtime, Sequencer: sequencer, Protocol: Protocol.from({ - modules: { - ...VanillaProtocolModules.mandatoryModules({}), - SettlementContractModule: SettlementContractModule.with({ - FungibleToken: FungibleTokenContractModule, - FungibleTokenAdmin: FungibleTokenAdminContractModule, - }), - }, + ...VanillaProtocolModules.mandatoryModules({}), + SettlementContractModule: SettlementContractModule.with({ + FungibleToken: FungibleTokenContractModule, + FungibleTokenAdmin: FungibleTokenAdminContractModule, + }), }), - modules: { - Signer: InMemorySigner, - TransactionSender: InMemoryTransactionSender, - QueryTransportModule: StateServiceQueryModule, - NetworkStateTransportModule: BlockStorageNetworkStateModule, - }, + Signer: InMemorySigner, + TransactionSender: InMemoryTransactionSender, + QueryTransportModule: StateServiceQueryModule, + NetworkStateTransportModule: BlockStorageNetworkStateModule, }); appchain.configure({ diff --git a/packages/stack/src/scripts/graphql/run-graphql.ts b/packages/stack/src/scripts/graphql/run-graphql.ts index 76ddeead3..7ffdeca16 100644 --- a/packages/stack/src/scripts/graphql/run-graphql.ts +++ b/packages/stack/src/scripts/graphql/run-graphql.ts @@ -1,8 +1,7 @@ #!/usr/bin/env ts-node import "reflect-metadata"; -import { sleep } from "@proto-kit/common"; -import { Startable } from "@proto-kit/deployment"; +import { sleep, Startable } from "@proto-kit/common"; import { startServer } from "./server"; diff --git a/packages/stack/src/scripts/graphql/server.ts b/packages/stack/src/scripts/graphql/server.ts index 3a7d50f21..eea84db3a 100644 --- a/packages/stack/src/scripts/graphql/server.ts +++ b/packages/stack/src/scripts/graphql/server.ts @@ -1,6 +1,6 @@ import { - AppChain, BlockStorageNetworkStateModule, + ClientAppChain, InMemorySigner, InMemoryTransactionSender, StateServiceQueryModule, @@ -84,67 +84,49 @@ export class TestBalances extends Balances { export async function startServer() { log.setLevel("DEBUG"); - const appChain = AppChain.from({ - Runtime: Runtime.from({ - modules: VanillaRuntimeModules.with({ + const appChain = ClientAppChain.from({ + Runtime: Runtime.from( + VanillaRuntimeModules.with({ Balances: TestBalances, - }), - }), + }) + ), - Protocol: Protocol.from({ - modules: VanillaProtocolModules.with({}), - }), + Protocol: Protocol.from(VanillaProtocolModules.with({})), Sequencer: Sequencer.from({ - modules: { - Database: InMemoryDatabase, - // Database: PrismaRedisDatabase, - OpenTelemetryServer, - - Mempool: PrivateMempool, - GraphqlServer, - LocalTaskWorkerModule: LocalTaskWorkerModule.from( - VanillaTaskWorkerModules.withoutSettlement() - ), - - BaseLayer: NoopBaseLayer, - BatchProducerModule, - BlockProducerModule, - // BlockTrigger: ManualBlockTrigger, - BlockTrigger: TimedBlockTrigger, - TaskQueue: LocalTaskQueue, - // SettlementModule: SettlementModule, - - Graphql: GraphqlSequencerModule.from({ - modules: { - MempoolResolver, - QueryGraphqlModule, - BatchStorageResolver, - BlockResolver, - NodeStatusResolver, - MerkleWitnessResolver, - }, - - config: { - MempoolResolver: {}, - QueryGraphqlModule: {}, - BatchStorageResolver: {}, - NodeStatusResolver: {}, - MerkleWitnessResolver: {}, - BlockResolver: {}, - }, - }), + Database: InMemoryDatabase, + // Database: PrismaRedisDatabase, + OpenTelemetryServer, + + Mempool: PrivateMempool, + GraphqlServer, + LocalTaskWorkerModule: LocalTaskWorkerModule.from( + VanillaTaskWorkerModules.withoutSettlement() + ), + + BaseLayer: NoopBaseLayer, + BatchProducerModule, + BlockProducerModule, + // BlockTrigger: ManualBlockTrigger, + BlockTrigger: TimedBlockTrigger, + TaskQueue: LocalTaskQueue, + // SettlementModule: SettlementModule, + + Graphql: GraphqlSequencerModule.from({ + MempoolResolver, + QueryGraphqlModule, + BatchStorageResolver, + BlockResolver, + NodeStatusResolver, + MerkleWitnessResolver, + }), - SequencerStartupModule, - }, + SequencerStartupModule, }), - - modules: { - Signer: InMemorySigner, - TransactionSender: InMemoryTransactionSender, - QueryTransportModule: StateServiceQueryModule, - NetworkStateTransportModule: BlockStorageNetworkStateModule, - }, + Signer: InMemorySigner, + TransactionSender: InMemoryTransactionSender, + QueryTransportModule: StateServiceQueryModule, + NetworkStateTransportModule: BlockStorageNetworkStateModule, }); appChain.configure({ diff --git a/packages/stack/src/scripts/worker/app.ts b/packages/stack/src/scripts/worker/app.ts index 65bae77fe..2ae296279 100644 --- a/packages/stack/src/scripts/worker/app.ts +++ b/packages/stack/src/scripts/worker/app.ts @@ -8,15 +8,13 @@ import { ModulesConfig, ModuleContainer, TypedClass } from "@proto-kit/common"; import { TestBalances } from "../graphql/server"; -const runtime = Runtime.from({ - modules: VanillaRuntimeModules.with({ +const runtime = Runtime.from( + VanillaRuntimeModules.with({ Balance2: TestBalances, - }), -}); + }) +); -const protocol = Protocol.from({ - modules: VanillaProtocolModules.mandatoryModules({}), -}); +const protocol = Protocol.from(VanillaProtocolModules.mandatoryModules({})); type ExtractConfigType = T extends TypedClass> diff --git a/packages/stack/src/scripts/worker/client.ts b/packages/stack/src/scripts/worker/client.ts index d0507c6aa..bdf36cd3b 100644 --- a/packages/stack/src/scripts/worker/client.ts +++ b/packages/stack/src/scripts/worker/client.ts @@ -1,12 +1,20 @@ import { ClientAppChain, InMemorySigner } from "@proto-kit/sdk"; -import { VanillaRuntimeModules } from "@proto-kit/library"; +import { + VanillaProtocolModules, + VanillaRuntimeModules, +} from "@proto-kit/library"; +import { Runtime } from "@proto-kit/module"; +import { Protocol } from "@proto-kit/protocol"; import { TestBalances } from "../graphql/server"; -const client = ClientAppChain.fromRuntime( - VanillaRuntimeModules.with({ - Balance2: TestBalances, - }), +const client = ClientAppChain.fromRemoteEndpoint( + Runtime.from( + VanillaRuntimeModules.with({ + Balance2: TestBalances, + }) + ), + Protocol.from(VanillaProtocolModules.mandatoryModules({})), InMemorySigner ); diff --git a/packages/stack/src/scripts/worker/sequencer.ts b/packages/stack/src/scripts/worker/sequencer.ts index 5718af8ca..db0a3433d 100644 --- a/packages/stack/src/scripts/worker/sequencer.ts +++ b/packages/stack/src/scripts/worker/sequencer.ts @@ -1,5 +1,4 @@ import { - AppChain, StateServiceQueryModule, BlockStorageNetworkStateModule, } from "@proto-kit/sdk"; @@ -11,6 +10,7 @@ import { MinaBaseLayer, TimedBlockTrigger, DatabasePruneModule, + AppChain, } from "@proto-kit/sequencer"; import { VanillaGraphqlModules, @@ -23,23 +23,19 @@ import { app } from "./app"; export const sequencer = AppChain.from({ Runtime: app.Runtime, Protocol: app.Protocol, - Sequencer: Sequencer.from({ - modules: SimpleSequencerModules.with({ + Sequencer: Sequencer.from( + SimpleSequencerModules.with({ TaskQueue: BullQueue, Database: InMemoryDatabase, BaseLayer: MinaBaseLayer, BlockTrigger: TimedBlockTrigger, DatabasePruneModule: DatabasePruneModule, GraphqlServer: GraphqlServer, - Graphql: GraphqlSequencerModule.from({ - modules: VanillaGraphqlModules.with({}), - }), - }), - }), - modules: { - QueryTransportModule: StateServiceQueryModule, - NetworkStateTransportModule: BlockStorageNetworkStateModule, - }, + Graphql: GraphqlSequencerModule.from(VanillaGraphqlModules.with({})), + }) + ), + QueryTransportModule: StateServiceQueryModule, + NetworkStateTransportModule: BlockStorageNetworkStateModule, }); sequencer.configure({ diff --git a/packages/stack/src/scripts/worker/worker.ts b/packages/stack/src/scripts/worker/worker.ts index 43e432c8e..b144891eb 100644 --- a/packages/stack/src/scripts/worker/worker.ts +++ b/packages/stack/src/scripts/worker/worker.ts @@ -1,5 +1,4 @@ -import { AppChain } from "@proto-kit/sdk"; -import { Sequencer } from "@proto-kit/sequencer"; +import { Sequencer, AppChain } from "@proto-kit/sequencer"; import { SimpleSequencerModules } from "@proto-kit/library"; import { BullQueue } from "@proto-kit/deployment"; @@ -8,10 +7,7 @@ import { app } from "./app"; export const worker = AppChain.from({ Runtime: app.Runtime, Protocol: app.Protocol, - Sequencer: Sequencer.from({ - modules: SimpleSequencerModules.worker(BullQueue, {}), - }), - modules: {}, + Sequencer: Sequencer.from(SimpleSequencerModules.worker(BullQueue, {})), }); worker.configurePartial({ diff --git a/packages/stack/test/graphql/graphql-server.ts b/packages/stack/test/graphql/graphql-server.ts index 4305ab93b..66c542360 100644 --- a/packages/stack/test/graphql/graphql-server.ts +++ b/packages/stack/test/graphql/graphql-server.ts @@ -1,5 +1,5 @@ import { - AppChain, + ClientAppChain, BlockStorageNetworkStateModule, InMemorySigner, InMemoryTransactionSender, @@ -83,65 +83,48 @@ export class TestBalances extends Balances { export async function startGraphqlServer() { log.setLevel("DEBUG"); - const appChain = AppChain.from({ - Runtime: Runtime.from({ - modules: VanillaRuntimeModules.with({ + const appChain = ClientAppChain.from({ + Runtime: Runtime.from( + VanillaRuntimeModules.with({ Balances: TestBalances, - }), - }), + }) + ), - Protocol: Protocol.from({ - modules: VanillaProtocolModules.with({}), - }), + Protocol: Protocol.from(VanillaProtocolModules.with({})), Sequencer: Sequencer.from({ - modules: { - Database: InMemoryDatabase, - // Database: PrismaRedisDatabase, - - Mempool: PrivateMempool, - GraphqlServer, - LocalTaskWorkerModule: LocalTaskWorkerModule.from( - VanillaTaskWorkerModules.withoutSettlement() - ), - - BaseLayer: NoopBaseLayer, - BatchProducerModule, - BlockProducerModule, - BlockTrigger: ManualBlockTrigger, - TaskQueue: LocalTaskQueue, - // SettlementModule: SettlementModule, - - Graphql: GraphqlSequencerModule.from({ - modules: { - MempoolResolver, - QueryGraphqlModule, - BatchStorageResolver, - BlockResolver, - NodeStatusResolver, - MerkleWitnessResolver, - }, - - config: { - MempoolResolver: {}, - QueryGraphqlModule: {}, - BatchStorageResolver: {}, - NodeStatusResolver: {}, - MerkleWitnessResolver: {}, - BlockResolver: {}, - }, - }), - - SequencerStartupModule, - }, + Database: InMemoryDatabase, + // Database: PrismaRedisDatabase, + + Mempool: PrivateMempool, + GraphqlServer, + LocalTaskWorkerModule: LocalTaskWorkerModule.from( + VanillaTaskWorkerModules.withoutSettlement() + ), + + BaseLayer: NoopBaseLayer, + BatchProducerModule, + BlockProducerModule, + BlockTrigger: ManualBlockTrigger, + TaskQueue: LocalTaskQueue, + // SettlementModule: SettlementModule, + + Graphql: GraphqlSequencerModule.from({ + MempoolResolver, + QueryGraphqlModule, + BatchStorageResolver, + BlockResolver, + NodeStatusResolver, + MerkleWitnessResolver, + }), + + SequencerStartupModule, }), - modules: { - Signer: InMemorySigner, - TransactionSender: InMemoryTransactionSender, - QueryTransportModule: StateServiceQueryModule, - NetworkStateTransportModule: BlockStorageNetworkStateModule, - }, + Signer: InMemorySigner, + TransactionSender: InMemoryTransactionSender, + QueryTransportModule: StateServiceQueryModule, + NetworkStateTransportModule: BlockStorageNetworkStateModule, }); appChain.configure({ diff --git a/packages/stack/test/graphql/graphql.test.ts b/packages/stack/test/graphql/graphql.test.ts index 007c045d3..803626b17 100644 --- a/packages/stack/test/graphql/graphql.test.ts +++ b/packages/stack/test/graphql/graphql.test.ts @@ -12,7 +12,7 @@ import { Field, PrivateKey } from "o1js"; import { sleep } from "@proto-kit/common"; import { ManualBlockTrigger, Sequencer } from "@proto-kit/sequencer"; import { - AppChain, + ClientAppChain, InMemorySigner, GraphqlTransactionSender, GraphqlQueryTransportModule, @@ -27,28 +27,22 @@ import { startGraphqlServer, TestBalances } from "./graphql-server"; const pk = PrivateKey.random(); function prepareClient() { - const appChain = AppChain.from({ - Runtime: Runtime.from({ - modules: VanillaRuntimeModules.with({ + const appChain = ClientAppChain.from({ + Runtime: Runtime.from( + VanillaRuntimeModules.with({ Balances: TestBalances, - }), - }), - - Protocol: Protocol.from({ - modules: VanillaProtocolModules.with({}), - }), - - Sequencer: Sequencer.from({ - modules: {}, - }), - - modules: { - Signer: InMemorySigner, - TransactionSender: GraphqlTransactionSender, - QueryTransportModule: GraphqlQueryTransportModule, - NetworkStateTransportModule: GraphqlNetworkStateTransportModule, - GraphqlClient, - }, + }) + ), + + Protocol: Protocol.from(VanillaProtocolModules.with({})), + + Sequencer: Sequencer.from({}), + + Signer: InMemorySigner, + TransactionSender: GraphqlTransactionSender, + QueryTransportModule: GraphqlQueryTransportModule, + NetworkStateTransportModule: GraphqlNetworkStateTransportModule, + GraphqlClient, }); appChain.configurePartial({