From 2c97256a9466dcd495e2c4ec1da8cd2453adc8b5 Mon Sep 17 00:00:00 2001 From: Raphael Panic Date: Tue, 10 Mar 2026 23:33:37 -0300 Subject: [PATCH 1/7] Added protocol constant print function --- packages/protocol/src/Constants.ts | 12 ++++++++++++ .../src/sequencer/SequencerStartupModule.ts | 3 +++ 2 files changed, 15 insertions(+) diff --git a/packages/protocol/src/Constants.ts b/packages/protocol/src/Constants.ts index 30f2a732c..2ae8ce0bf 100644 --- a/packages/protocol/src/Constants.ts +++ b/packages/protocol/src/Constants.ts @@ -1,3 +1,5 @@ +import { log } from "@proto-kit/common"; + const constants = { STATE_TRANSITION_BATCH_SIZE: 4, BLOCK_ARGUMENT_BATCH_SIZE: 4, @@ -18,4 +20,14 @@ export const Constants = { return constants[name]; } }, + + printAllConstants() { + const constantsString = Object.keys(constants) + .map((name) => { + const constant = Constants.getConstant(name as any, (x) => x); + return `${name}=${constant}`; + }) + .join(", "); + log.info("Protocol constants: ", constantsString); + }, }; diff --git a/packages/sequencer/src/sequencer/SequencerStartupModule.ts b/packages/sequencer/src/sequencer/SequencerStartupModule.ts index ee707749d..d72f3683f 100644 --- a/packages/sequencer/src/sequencer/SequencerStartupModule.ts +++ b/packages/sequencer/src/sequencer/SequencerStartupModule.ts @@ -4,6 +4,7 @@ import { ContractArgsRegistry, MandatoryProtocolModulesRecord, Protocol, + ProtocolConstants, RuntimeVerificationKeyRootService, } from "@proto-kit/protocol"; import { @@ -143,6 +144,8 @@ export class SequencerStartupModule } public async start() { + ProtocolConstants.printAllConstants(); + const flow = this.flowCreator.createFlow("compile-circuits", {}); this.protocol.dependencyContainer From 10e6cb6a03033007ae7602df1340219b1ac8e35d Mon Sep 17 00:00:00 2001 From: Raphael Panic Date: Thu, 12 Mar 2026 19:00:12 -0300 Subject: [PATCH 2/7] Fixed printAllConstants --- packages/protocol/src/Constants.ts | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/packages/protocol/src/Constants.ts b/packages/protocol/src/Constants.ts index 2ae8ce0bf..1e2de64dd 100644 --- a/packages/protocol/src/Constants.ts +++ b/packages/protocol/src/Constants.ts @@ -11,6 +11,7 @@ const prefix = "PROTOKIT"; export const Constants = { getConstant( name: Key, + // TODO Remove this pattern and delegate parsing to the called - this is bad imo transform: (arg: string) => (typeof constants)[Key] ): (typeof constants)[Key] { const env = process.env[name] ?? process.env[`${prefix}_${name}`]; @@ -22,12 +23,14 @@ export const Constants = { }, printAllConstants() { - const constantsString = Object.keys(constants) - .map((name) => { - const constant = Constants.getConstant(name as any, (x) => x); - return `${name}=${constant}`; - }) - .join(", "); + const constantsString = + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions + (Object.keys(constants) as (keyof typeof constants)[]) + .map((name) => { + const constant = Constants.getConstant(name, parseInt); + return `${name}=${constant}`; + }) + .join(", "); log.info("Protocol constants: ", constantsString); }, }; From f385dfc5c1fd6459234e39f83c2451d66c881c16 Mon Sep 17 00:00:00 2001 From: Raphael Panic Date: Tue, 17 Mar 2026 17:01:56 +0100 Subject: [PATCH 3/7] Fixed env import order issue in CLI --- packages/cli/src/scripts/settlement/deploy.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cli/src/scripts/settlement/deploy.ts b/packages/cli/src/scripts/settlement/deploy.ts index 2d206fb16..349c7e1e9 100644 --- a/packages/cli/src/scripts/settlement/deploy.ts +++ b/packages/cli/src/scripts/settlement/deploy.ts @@ -11,6 +11,7 @@ import { loadUserModules } from "../../utils/loadUserModules"; export default async function (options: LoadEnvOptions) { try { + loadEnvironmentVariables(options); const { Provable, PublicKey } = await import("o1js"); const { Runtime } = await import("@proto-kit/module"); const { Protocol } = await import("@proto-kit/protocol"); @@ -18,7 +19,6 @@ export default async function (options: LoadEnvOptions) { await import("@proto-kit/sequencer"); const { DefaultModules, DefaultConfigs } = await import("@proto-kit/stack"); - loadEnvironmentVariables(options); const { runtime, protocol } = await loadUserModules(); const appChain = AppChain.from({ Runtime: Runtime.from(runtime.modules), From 11af687a291898802e8cd5499c0891147573ead1 Mon Sep 17 00:00:00 2001 From: Raphael Panic Date: Tue, 17 Mar 2026 17:30:51 +0100 Subject: [PATCH 4/7] Added trace logs to reloadAccount --- .../transactions/MinaTransactionSimulator.ts | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/packages/sequencer/src/settlement/transactions/MinaTransactionSimulator.ts b/packages/sequencer/src/settlement/transactions/MinaTransactionSimulator.ts index b3d8713a2..5d37c5a71 100644 --- a/packages/sequencer/src/settlement/transactions/MinaTransactionSimulator.ts +++ b/packages/sequencer/src/settlement/transactions/MinaTransactionSimulator.ts @@ -18,7 +18,7 @@ import { } from "@proto-kit/protocol"; import { match } from "ts-pattern"; import { inject, injectable } from "tsyringe"; -import { hashWithPrefix, noop, range } from "@proto-kit/common"; +import { hashWithPrefix, log, noop, range } from "@proto-kit/common"; import { distinctByPredicate } from "../../helpers/utils"; import type { MinaBaseLayer } from "../../protocol/baselayer/MinaBaseLayer"; @@ -173,17 +173,24 @@ export class MinaTransactionSimulator { const getAccountSafe = () => { try { return Mina.getAccount(publicKey, tokenId); - } catch { + } catch (e) { + log.trace(e); return undefined; } }; const account = match(fetchedAccount) .with(undefined, () => getAccountSafe()) - .with({ account: undefined }, () => getAccountSafe()) + .with({ account: undefined }, (e) => { + log.trace(e.error); + return getAccountSafe(); + }) .with({ error: undefined }, (v) => v.account) .exhaustive(); if (account !== undefined) { + log.trace( + `Reloaded account ${account.publicKey.toBase58()}, ${account.balance.toJSON()} MINA` + ); addCachedAccount(account); this.loaded[key] = account; } From 64a3617261acfe4370645fae0e4f9df39a4d9ccc Mon Sep 17 00:00:00 2001 From: Raphael Panic Date: Tue, 17 Mar 2026 18:30:54 +0100 Subject: [PATCH 5/7] Fixed deploy script configuration --- packages/cli/src/scripts/settlement/deploy.ts | 74 ++++++++++++++++--- 1 file changed, 64 insertions(+), 10 deletions(-) diff --git a/packages/cli/src/scripts/settlement/deploy.ts b/packages/cli/src/scripts/settlement/deploy.ts index 349c7e1e9..14e49c581 100644 --- a/packages/cli/src/scripts/settlement/deploy.ts +++ b/packages/cli/src/scripts/settlement/deploy.ts @@ -1,6 +1,5 @@ import "reflect-metadata"; import { container } from "tsyringe"; -import type { Environment } from "@proto-kit/stack"; import { loadEnvironmentVariables, @@ -12,13 +11,27 @@ import { loadUserModules } from "../../utils/loadUserModules"; export default async function (options: LoadEnvOptions) { try { loadEnvironmentVariables(options); - const { Provable, PublicKey } = await import("o1js"); + const { Provable, PublicKey, PrivateKey } = await import("o1js"); const { Runtime } = await import("@proto-kit/module"); const { Protocol } = await import("@proto-kit/protocol"); - const { AppChain, Sequencer, SettlementModule, InMemoryDatabase } = - await import("@proto-kit/sequencer"); + const { + AppChain, + Sequencer, + SettlementModule, + InMemoryDatabase, + BatchProducerModule, + BridgingModule, + ConstantFeeStrategy, + InMemoryMinaSigner, + MinaBaseLayer, + PrivateMempool, + LocalTaskQueue, + LocalTaskWorkerModule, + VanillaTaskWorkerModules, + SequencerStartupModule, + } = await import("@proto-kit/sequencer"); - const { DefaultModules, DefaultConfigs } = await import("@proto-kit/stack"); + const { DefaultConfigs } = await import("@proto-kit/stack"); const { runtime, protocol } = await loadUserModules(); const appChain = AppChain.from({ Runtime: Runtime.from(runtime.modules), @@ -28,7 +41,18 @@ export default async function (options: LoadEnvOptions) { }), Sequencer: Sequencer.from({ Database: InMemoryDatabase, - ...DefaultModules.settlementScript(), + BaseLayer: MinaBaseLayer, + FeeStrategy: ConstantFeeStrategy, + BatchProducerModule, + SettlementModule, + SettlementSigner: InMemoryMinaSigner, + BridgingModule, + Mempool: PrivateMempool, + TaskQueue: LocalTaskQueue, + LocalTaskWorker: LocalTaskWorkerModule.from( + VanillaTaskWorkerModules.allTasks() + ), + SequencerStartupModule, }), }); @@ -40,16 +64,46 @@ export default async function (options: LoadEnvOptions) { }, Sequencer: { ...DefaultConfigs.inMemoryDatabase(), - ...DefaultConfigs.settlementScript({ - // eslint-disable-next-line @typescript-eslint/consistent-type-assertions - preset: options.env as Environment, - }), + BaseLayer: { + network: { + // eslint-disable-next-line max-len + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions,@typescript-eslint/no-unsafe-assignment + type: process.env.MINA_NETWORK as any, + graphql: process.env.MINA_NODE_GRAPHQL!, + archive: process.env.MINA_ARCHIVE_GRAPHQL!, + accountManager: process.env.MINA_ACCOUNT_MANAGER!, + }, + }, + SettlementSigner: { + feepayer: PrivateKey.fromBase58( + process.env.PROTOKIT_SEQUENCER_PRIVATE_KEY! + ), + contractKeys: [ + PrivateKey.fromBase58( + process.env.PROTOKIT_SETTLEMENT_CONTRACT_PRIVATE_KEY! + ), + PrivateKey.fromBase58( + process.env.PROTOKIT_DISPATCHER_CONTRACT_PRIVATE_KEY! + ), + PrivateKey.fromBase58( + process.env.PROTOKIT_MINA_BRIDGE_CONTRACT_PRIVATE_KEY! + ), + ], + }, + FeeStrategy: {}, + BatchProducerModule: {}, SettlementModule: { addresses: undefined, }, BridgingModule: { addresses: undefined, }, + SequencerStartupModule: {}, + TaskQueue: { + simulatedDuration: 0, + }, + LocalTaskWorker: VanillaTaskWorkerModules.defaultConfig(), + Mempool: {}, }, }); From 279ef0fe60cc23d5439084b3236adccf7e8ecb99 Mon Sep 17 00:00:00 2001 From: Raphael Panic Date: Wed, 18 Mar 2026 15:40:53 +0100 Subject: [PATCH 6/7] Added nonce fetching for deploy script --- .../bridging/BridgingDeployInteraction.ts | 9 +++++-- .../vanilla/VanillaDeployInteraction.ts | 9 +++++-- .../transactions/MinaTransactionSimulator.ts | 2 ++ .../src/settlement/utils/SettlementUtils.ts | 26 ++++++++++++++++++- 4 files changed, 41 insertions(+), 5 deletions(-) diff --git a/packages/sequencer/src/settlement/interactions/bridging/BridgingDeployInteraction.ts b/packages/sequencer/src/settlement/interactions/bridging/BridgingDeployInteraction.ts index c1c24d4a4..9fa2e6194 100644 --- a/packages/sequencer/src/settlement/interactions/bridging/BridgingDeployInteraction.ts +++ b/packages/sequencer/src/settlement/interactions/bridging/BridgingDeployInteraction.ts @@ -21,6 +21,8 @@ import { SettlementUtils } from "../../utils/SettlementUtils"; @injectable() export class BridgingDeployInteraction implements DeployInteraction { + private utils: SettlementUtils; + public constructor( @inject("AddressRegistry") private readonly addressRegistry: AddressRegistry, @@ -33,7 +35,9 @@ export class BridgingDeployInteraction implements DeployInteraction { private readonly feeStrategy: FeeStrategy, @inject("TransactionSender") private readonly transactionSender: MinaTransactionSender - ) {} + ) { + this.utils = new SettlementUtils(this.baseLayer, this.signer); + } protected settlementContractModule(): SettlementContractModule { return this.protocol.dependencyContainer.resolve( @@ -59,7 +63,8 @@ export class BridgingDeployInteraction implements DeployInteraction { const feepayer = this.signer.getFeepayerKey(); - const nonce = options?.nonce ?? 0; + const nonce = + options?.nonce ?? (await this.utils.fetchNonce(feepayer)) ?? 0; const sm = this.settlementContractModule(); const { diff --git a/packages/sequencer/src/settlement/interactions/vanilla/VanillaDeployInteraction.ts b/packages/sequencer/src/settlement/interactions/vanilla/VanillaDeployInteraction.ts index c5fb126fe..448630418 100644 --- a/packages/sequencer/src/settlement/interactions/vanilla/VanillaDeployInteraction.ts +++ b/packages/sequencer/src/settlement/interactions/vanilla/VanillaDeployInteraction.ts @@ -21,6 +21,8 @@ import { SettlementUtils } from "../../utils/SettlementUtils"; @injectable() export class VanillaDeployInteraction implements DeployInteraction { + private utils: SettlementUtils; + public constructor( @inject("AddressRegistry") private readonly addressRegistry: AddressRegistry, @@ -33,7 +35,9 @@ export class VanillaDeployInteraction implements DeployInteraction { private readonly feeStrategy: FeeStrategy, @inject("TransactionSender") private readonly transactionSender: MinaTransactionSender - ) {} + ) { + this.utils = new SettlementUtils(this.baseLayer, this.signer); + } protected settlementContractModule(): SettlementContractModule { return this.protocol.dependencyContainer.resolve( @@ -62,7 +66,8 @@ export class VanillaDeployInteraction implements DeployInteraction { const feepayer = this.signer.getFeepayerKey(); - const nonce = options?.nonce ?? 0; + const nonce = + options?.nonce ?? (await this.utils.fetchNonce(feepayer)) ?? 0; const sm = this.settlementContractModule(); const { SettlementContract: settlementContract } = sm.createContracts({ diff --git a/packages/sequencer/src/settlement/transactions/MinaTransactionSimulator.ts b/packages/sequencer/src/settlement/transactions/MinaTransactionSimulator.ts index 5d37c5a71..0323312b0 100644 --- a/packages/sequencer/src/settlement/transactions/MinaTransactionSimulator.ts +++ b/packages/sequencer/src/settlement/transactions/MinaTransactionSimulator.ts @@ -181,6 +181,8 @@ export class MinaTransactionSimulator { const account = match(fetchedAccount) .with(undefined, () => getAccountSafe()) .with({ account: undefined }, (e) => { + // TODO Check if it's a "account not found" error, and if it's not then display the error + // (as it's probably networking related) log.trace(e.error); return getAccountSafe(); }) diff --git a/packages/sequencer/src/settlement/utils/SettlementUtils.ts b/packages/sequencer/src/settlement/utils/SettlementUtils.ts index 9c9f2bba8..f0824a6dc 100644 --- a/packages/sequencer/src/settlement/utils/SettlementUtils.ts +++ b/packages/sequencer/src/settlement/utils/SettlementUtils.ts @@ -2,12 +2,13 @@ import { Bool, fetchAccount, Field, + Mina, PrivateKey, PublicKey, Transaction, UInt32, } from "o1js"; -import { mapSequential } from "@proto-kit/common"; +import { log, mapSequential } from "@proto-kit/common"; import type { MinaBaseLayer } from "../../protocol/baselayer/MinaBaseLayer"; import { MinaSigner } from "../MinaSigner"; @@ -27,6 +28,29 @@ export class SettlementUtils { private readonly signer: MinaSigner ) {} + public async fetchNonce(publicKey: PublicKey): Promise { + const account = await this.safeFetchAccount(publicKey); + if (account !== undefined) { + return parseInt(account.nonce.toString(), 10); + } + return undefined; + } + + public async safeFetchAccount(publicKey: PublicKey, tokenId?: Field) { + const isLocal = this.baseLayer.isLocalBlockChain(); + if (isLocal && Mina.hasAccount(publicKey, tokenId)) { + return Mina.getAccount(publicKey, tokenId); + } else if (!isLocal) { + const fetchResult = await fetchAccount({ publicKey, tokenId }); + if (fetchResult.account !== undefined) { + return fetchResult.account; + } else { + log.info(fetchResult.error); + } + } + return undefined; + } + public signTransaction( tx: Transaction, options: SignTransactionOptions = {} From af176cb9b8a005878698b46ac2cb99916b4f75ca Mon Sep 17 00:00:00 2001 From: Raphael Panic Date: Wed, 18 Mar 2026 16:43:32 +0100 Subject: [PATCH 7/7] Added retry option to bull queue --- packages/deployment/src/queue/BullQueue.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/deployment/src/queue/BullQueue.ts b/packages/deployment/src/queue/BullQueue.ts index 2a4f4e640..8c037fa8d 100644 --- a/packages/deployment/src/queue/BullQueue.ts +++ b/packages/deployment/src/queue/BullQueue.ts @@ -94,6 +94,9 @@ export class BullQueue const queue = new Queue(queueName, { connection: redis, + defaultJobOptions: { + attempts: this.config.retryAttempts ?? 2, + }, }); const events = new QueueEvents(queueName, { connection: redis });