Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
466826d
feat: implement a separate MinaSigner interface
saitunc Nov 21, 2025
3c73e32
feat: add MinaSigner interface to Settlement module
saitunc Nov 21, 2025
0c3a43c
feat: change MinaSigner config type and signing logics
saitunc Nov 28, 2025
55819cd
refactor: update signTransaction utility function with MinaSigner
saitunc Nov 28, 2025
ac04e3a
refactor: update signing functions with MinaSigner based ones
saitunc Nov 28, 2025
92632d2
refactor: update address check in settlement contract
saitunc Nov 28, 2025
57a5579
refactor: update bridging module tx signings w/ MinaSigner
saitunc Nov 28, 2025
e88e104
refactor: inject MinaSigner optionally to SequencerStartupModule
saitunc Nov 28, 2025
172b906
refactor: update settlementTestFn with MinaSigner functions
saitunc Nov 28, 2025
aebb1ba
fix: resolve container is Signer instead of MinaSigner
saitunc Nov 28, 2025
cef40c0
refactor: remove unnecessary conditional checks
saitunc Nov 28, 2025
743972c
style: run lint fix
saitunc Nov 28, 2025
868b15c
refactor: remove keeping private keys in SettlementModule
saitunc Dec 1, 2025
6429f3a
refactor: remove logs and private key config to settlement module
saitunc Dec 1, 2025
e2097f4
refactor: rename signer to feepayer to remove ambiguity
saitunc Dec 2, 2025
f0a65ba
refactor: update message signing function to specify signer key
saitunc Dec 3, 2025
c2ad307
refactor: move isSignedSEttlement to MinaBaseLayer
saitunc Dec 3, 2025
59b5eb9
refactor: remove signWithContract flag in signTransaction method
saitunc Dec 4, 2025
0ad1b91
feat: add key registration to InMemoryMinaSigner
saitunc Dec 4, 2025
b480c5d
refactor: use PublicKey instead of PrivateKey in bridging module
saitunc Dec 4, 2025
5982b19
style: run lint fix
saitunc Dec 4, 2025
cb89177
refactor: remove additionalKeys since it is not needed
saitunc Dec 4, 2025
fddf408
fix: input of deployandinitialize after rebase in Settlement.ts
saitunc Dec 5, 2025
1b34ed8
style: run lint fix
saitunc Dec 5, 2025
e24c1e2
refactor: update input type of signWithKey from string to PublicKey
saitunc Dec 8, 2025
b440748
refactor: remove unnecessary functions and use signer api directly
saitunc Dec 8, 2025
a81983b
refactor: remove tokenController to store all keys in tokenBridgeKeys
saitunc Dec 8, 2025
0896dbf
style: run fix lint
saitunc Dec 8, 2025
4194c66
refactor: remove unused areProofsEnabled from SettlementUtils
saitunc Dec 8, 2025
9c0f342
docs: add TSDocs for MinaSigner
saitunc Dec 10, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/sdk/src/transaction/AuroSigner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { AppChainModule } from "@proto-kit/sequencer";

import { Signer } from "./InMemorySigner";

// Will be implemented for MinaSigner here.
@injectable()
export class AuroSigner extends AppChainModule<unknown> implements Signer {
public async sign(message: Field[]): Promise<Signature> {
Expand Down
1 change: 1 addition & 0 deletions packages/sequencer/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ export * from "./state/state/DummyStateService";
export * from "./state/state/CachedStateService";
export * from "./state/lmt/AsyncLinkedMerkleTreeDatabase";
export * from "./state/lmt/CachedLinkedLeafStore";
export * from "./settlement/MinaSigner";
export * from "./settlement/SettlementModule";
export * from "./settlement/BridgingModule";
export * from "./settlement/messages/outgoing/DefaultOutgoingMessageAdapter";
Expand Down
8 changes: 8 additions & 0 deletions packages/sequencer/src/protocol/baselayer/MinaBaseLayer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,14 @@ export class MinaBaseLayer
return this.config.network.type === "local";
}

/**
* Signed settlement happens when proofs are disabled and the network is remote
* This is because on local network we can use mock proofs, while on remotes ones we can't
*/
public isSignedSettlement(): boolean {
return !this.areProofsEnabled.areProofsEnabled && !this.isLocalBlockChain();
}

public async start(): Promise<void> {
const { network } = this.config;

Expand Down
9 changes: 2 additions & 7 deletions packages/sequencer/src/sequencer/SequencerStartupModule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import {
} from "../protocol/production/tasks/CircuitCompilerTask";
import { VerificationKeyService } from "../protocol/runtime/RuntimeVerificationKeyService";
import type { MinaBaseLayer } from "../protocol/baselayer/MinaBaseLayer";
import { SettlementUtils } from "../settlement/utils/SettlementUtils";
import { NoopBaseLayer } from "../protocol/baselayer/NoopBaseLayer";

import { SequencerModule, sequencerModule } from "./builder/SequencerModule";
Expand Down Expand Up @@ -140,13 +139,9 @@ export class SequencerStartupModule
.resolve(ChildVerificationKeyService)
.setCompileRegistry(this.compileRegistry);

// TODO Find a way to generalize this or at least make it nicer - too much logic here
const isSignedSettlement =
this.baseLayer !== undefined && !(this.baseLayer instanceof NoopBaseLayer)
? new SettlementUtils(
this.areProofsEnabled,
this.baseLayer
).isSignedSettlement()
this.baseLayer && !(this.baseLayer instanceof NoopBaseLayer)
? this.baseLayer.isSignedSettlement()
: undefined;

log.info("Compiling Protocol circuits, this can take a few minutes");
Expand Down
87 changes: 40 additions & 47 deletions packages/sequencer/src/settlement/BridgingModule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import {
AccountUpdate,
Field,
Mina,
PrivateKey,
Provable,
PublicKey,
TokenContract,
Expand All @@ -32,7 +31,6 @@ import {
UInt32,
} from "o1js";
import {
AreProofsEnabled,
filterNonUndefined,
LinkedMerkleTree,
log,
Expand All @@ -55,16 +53,17 @@ import { SettlementUtils } from "./utils/SettlementUtils";
import { MinaTransactionSender } from "./transactions/MinaTransactionSender";
import { OutgoingMessageCollector } from "./messages/outgoing/OutgoingMessageCollector";
import { ArchiveNode } from "./utils/ArchiveNode";
import { MinaSigner } from "./MinaSigner";

export type SettlementTokenConfig = Record<
string,
| {
bridgingContractPrivateKey?: PrivateKey;
bridgingContractPublicKey?: PublicKey;
}
| {
tokenOwner: FungibleToken;
bridgingContractPrivateKey?: PrivateKey;
tokenOwnerPrivateKey?: PrivateKey;
bridgingContractPublicKey?: PublicKey;
tokenOwnerPublicKey?: PublicKey;
}
>;

Expand Down Expand Up @@ -97,12 +96,12 @@ export class BridgingModule {
private readonly linkedLeafStore: AsyncLinkedLeafStore,
@inject("FeeStrategy")
private readonly feeStrategy: FeeStrategy,
@inject("AreProofsEnabled") areProofsEnabled: AreProofsEnabled,
@inject("BaseLayer") private readonly baseLayer: MinaBaseLayer,
@inject("SettlementSigner") private readonly signer: MinaSigner,
@inject("TransactionSender")
private readonly transactionSender: MinaTransactionSender
) {
this.utils = new SettlementUtils(areProofsEnabled, baseLayer);
this.utils = new SettlementUtils(baseLayer, signer);
}

private getMessageProcessors() {
Expand Down Expand Up @@ -182,8 +181,8 @@ export class BridgingModule {
}

private async fetchFeepayerNonce() {
const { feepayer } = this.settlementModule.config;
return await this.transactionSender.getNextNonce(feepayer.toPublicKey());
const feepayer = this.signer.getFeepayerKey();
return await this.transactionSender.getNextNonce(feepayer);
}

public async sendRollupTransactions(
Expand Down Expand Up @@ -244,32 +243,30 @@ export class BridgingModule {
options:
| {
nonce: number;
bridgingContractPrivateKey?: PrivateKey;
bridgingContractPublicKey?: PublicKey;
}
| {
nonce: number;
tokenOwner: FungibleToken;
bridgingContractPrivateKey?: PrivateKey;
tokenOwnerPrivateKey?: PrivateKey;
bridgingContractPublicKey?: PublicKey;
tokenOwnerPublicKey?: PublicKey;
}
) {
return await match(options)
.with(
{
nonce: Pattern.number,
tokenOwner: Pattern.instanceOf(FungibleToken),
bridgingContractPrivateKey: Pattern.optional(
Pattern.instanceOf(PrivateKey)
),
tokenOwnerPrivateKey: Pattern.optional(
Pattern.instanceOf(PrivateKey)
bridgingContractPublicKey: Pattern.optional(
Pattern.instanceOf(PublicKey)
),
tokenOwnerPublicKey: Pattern.optional(Pattern.instanceOf(PublicKey)),
},
({
nonce,
tokenOwner,
bridgingContractPrivateKey,
tokenOwnerPrivateKey,
bridgingContractPublicKey,
tokenOwnerPublicKey,
}) => {
return this.sendRollupTransactionsBase(
async (au: AccountUpdate) => {
Expand All @@ -280,8 +277,8 @@ export class BridgingModule {
{
nonce,
contractKeys: [
bridgingContractPrivateKey,
tokenOwnerPrivateKey,
bridgingContractPublicKey,
tokenOwnerPublicKey,
].filter(filterNonUndefined),
}
);
Expand All @@ -290,20 +287,20 @@ export class BridgingModule {
.with(
{
nonce: Pattern.number,
bridgingContractPrivateKey: Pattern.optional(
Pattern.instanceOf(PrivateKey)
bridgingContractPublicKey: Pattern.optional(
Pattern.instanceOf(PublicKey)
),
},
({ nonce, bridgingContractPrivateKey }) => {
({ nonce, bridgingContractPublicKey }) => {
return this.sendRollupTransactionsBase(
async () => {},
TokenId.default,
events,
{
nonce,
contractKeys:
bridgingContractPrivateKey !== undefined
? [bridgingContractPrivateKey]
bridgingContractPublicKey !== undefined
? [bridgingContractPublicKey]
: [],
}
);
Expand Down Expand Up @@ -354,7 +351,7 @@ export class BridgingModule {
public async pullStateRoot(
tokenWrapper: (au: AccountUpdate) => Promise<void>,
tokenId: Field,
options: { nonce: number; contractKeys: PrivateKey[] }
options: { nonce: number; contractKeys: PublicKey[] }
): Promise<
| { nonceUsed: false }
| { nonceUsed: true; tx: Mina.Transaction<false, true> }
Expand All @@ -381,12 +378,12 @@ export class BridgingModule {

if (settledRoot.toBigInt() !== (tokenBridgeRoot?.toBigInt() ?? -1n)) {
// Create transaction
const { feepayer } = this.settlementModule.config;
const feepayer = this.signer.getFeepayerKey();
let { nonce } = options;

const tx = await Mina.transaction(
{
sender: feepayer.toPublicKey(),
sender: feepayer,
// eslint-disable-next-line no-plusplus
nonce: nonce++,
fee: this.feeStrategy.getFee(),
Expand All @@ -398,11 +395,9 @@ export class BridgingModule {
}
);

const signedTx = this.utils.signTransaction(
tx,
[feepayer],
options.contractKeys
);
const signedTx = this.utils.signTransaction(tx, {
signingWithSignatureCheck: options.contractKeys,
});

await this.transactionSender.proveAndSendTransaction(
signedTx,
Expand All @@ -423,13 +418,13 @@ export class BridgingModule {
tokenWrapper: (au: AccountUpdate) => Promise<void>,
tokenId: Field,
events: OutgoingMessageEvent<any>[],
options: { nonce: number; contractKeys: PrivateKey[] }
options: { nonce: number; contractKeys: PublicKey[] }
): Promise<
{
tx: Transaction<false, true>;
}[]
> {
const { feepayer } = this.settlementModule.config;
const feepayer = this.signer.getFeepayerKey();
let { nonce } = options;

const txs: {
Expand All @@ -444,7 +439,10 @@ export class BridgingModule {
);
}

if (this.utils.isSignedSettlement() && options.contractKeys.length === 0) {
if (
this.baseLayer.isSignedSettlement() &&
options.contractKeys.length === 0
) {
throw new Error(
"Bridging contract private key for signed settlement has to be provided"
);
Expand Down Expand Up @@ -503,7 +501,7 @@ export class BridgingModule {

const tx = await Mina.transaction(
{
sender: feepayer.toPublicKey(),
sender: feepayer,
// eslint-disable-next-line no-plusplus
nonce: nonce++,
fee: this.feeStrategy.getFee(),
Expand All @@ -525,21 +523,16 @@ export class BridgingModule {
});

// Pay account creation fees for internal token accounts
AccountUpdate.fundNewAccount(
feepayer.toPublicKey(),
numNewAccountsNumber
);
AccountUpdate.fundNewAccount(feepayer, numNewAccountsNumber);
}
);

log.debug("Sending rollup transaction:");
log.debug(tx.toPretty());

const signedTx = this.utils.signTransaction(
tx,
[feepayer],
options.contractKeys
);
const signedTx = this.utils.signTransaction(tx, {
signingWithSignatureCheck: [...options.contractKeys],
});

await this.transactionSender.proveAndSendTransaction(
signedTx,
Expand Down
Loading