@nori-zk/mina-token-bridge
Version:
A Mina zk-program contract allowing users to mint tokens on Nori Bridge.
209 lines (208 loc) • 12.5 kB
TypeScript
import { getBridgeStateTopic$, getBridgeTimingsTopic$, getEthStateTopic$ } from './topics.js';
import { KeyTransitionStageMessageTypes } from '@nori-zk/pts-types';
/**
* Represents the various processing states a bridge deposit can pass through before minting is possible or missed.
*
* - `WaitingForEthFinality`: The deposit is awaiting Ethereum chain finality before processing can begin.
* - `WaitingForCurrentJobCompletion`: The deposit is included in the current bridge job but must wait for it to finalize.
* - `WaitingForPreviousJobCompletion`: The deposit is not part of the current job and must wait for its job window to open.
* - `ReadyToMint`: The deposit has passed all required stages and is now eligible for minting.
* - `MissedMintingOpportunity`: The deposit missed its minting window.
*/
export declare enum BridgeDepositProcessingStatus {
WaitingForEthFinality = "WaitingForEthFinality",
WaitingForCurrentJobCompletion = "WaitingForCurrentJobCompletion",
WaitingForPreviousJobCompletion = "WaitingForPreviousJobCompletion",
ReadyToMint = "ReadyToMint",
MissedMintingOpportunity = "MissedMintingOpportunity"
}
/**
* Monitors the status of a bridge deposit and emits a stream of updates regarding its processing state.
*
* The stream emits objects containing the current bridge state, estimated time remaining, elapsed time,
* deposit processing status, and the original deposit block number. It transitions through various statuses such as
* WaitingForEthFinality, WaitingForCurrentJobCompletion, ReadyToMint, or MissedMintingOpportunity.
*
* The observable completes once the deposit is considered a missed minting opportunity.
*
* @param depositBlockNumber The block number in which the deposit occurred.
* @param ethStateTopic$ Observable stream of Ethereum finality data.
* @param bridgeStateTopic$ Observable stream of the bridge state machine.
* @param bridgeTimingsTopic$ Observable stream of bridge timing configuration.
* @returns An observable emitting periodic updates about the deposit's processing status.
*/
export declare const getDepositProcessingStatus$: (depositBlockNumber: number, ethStateTopic$: ReturnType<typeof getEthStateTopic$>, bridgeStateTopic$: ReturnType<typeof getBridgeStateTopic$>, bridgeTimingsTopic$: ReturnType<typeof getBridgeTimingsTopic$>) => import("rxjs").Observable<{
time_remaining_sec: number;
elapsed_sec: number;
deposit_processing_status: BridgeDepositProcessingStatus;
deposit_block_number: number;
stage_name: KeyTransitionStageMessageTypes;
input_slot: number;
input_block_number: number;
output_slot: number;
output_block_number: number;
last_finalized_job: "unknown" | {
input_slot: number;
input_block_number: number;
output_slot: number;
output_block_number: number;
};
}>;
/**
* Waits until a deposit reaches the `ReadyToMint` status, or throws if the opportunity is missed.
*
* Resolves as soon as the deposit processing status becomes `ReadyToMint`. Throws an error
* if the deposit transitions to `MissedMintingOpportunity` instead.
*
* @param depositProcessingStatus$ Observable emitting deposit processing updates.
* @returns A promise resolving to true once the deposit is ready to mint.
* @throws Error if the minting opportunity is missed.
*/
export declare function canMint(depositProcessingStatus$: ReturnType<typeof getDepositProcessingStatus$>): Promise<boolean>;
export declare const canMintStatus: readonly [BridgeDepositProcessingStatus.MissedMintingOpportunity, BridgeDepositProcessingStatus.ReadyToMint, "Waiting"];
export declare const canMintWaitingStatuses: BridgeDepositProcessingStatus[];
export type CanMintStatus = (typeof canMintStatus)[number];
/**
* Emits the current minting status as one of three possible values:
* `ReadyToMint`, `MissedMintingOpportunity`, or `'Waiting'`.
*
* - Emits `'Waiting'` when the deposit is in any of the waiting states defined in `canMintWaitingStatuses`.
* - Emits `BridgeDepositProcessingStatus.ReadyToMint` when the deposit is ready to mint.
* - Emits `BridgeDepositProcessingStatus.MissedMintingOpportunity` and completes when the minting opportunity has been missed.
*
* Any other deposit processing statuses are ignored (no emission).
* Duplicate consecutive statuses are suppressed.
*
* @param depositProcessingStatus$ Observable emitting deposit processing updates.
* @returns Observable emitting the trinary mint status (`ReadyToMint`, `MissedMintingOpportunity`, or `'Waiting'`).
*/
export declare function getCanMint$(depositProcessingStatus$: ReturnType<typeof getDepositProcessingStatus$>): import("rxjs").Observable<BridgeDepositProcessingStatus.ReadyToMint | BridgeDepositProcessingStatus.MissedMintingOpportunity | "Waiting">;
/**
* Waits until the deposit is eligible for mint proof generation, based on bridge state.
*
* Specifically, resolves when:
* - Deposit status is `ReadyToMint`, or
* - Deposit status is `WaitingForCurrentJobCompletion` and the stage index is at or beyond `ProofConversionJobSucceeded`, or
* - Deposit is in the last deposit window (between the last finalized job’s input and output blocks),
* the current job’s stage index is before `EthProcessorTransactionSubmitSucceeded`,
* and the current job’s block range is not identical to the last finalized job’s block range
* (edge case occurring when last finalized job updates at the `EthProcessorTransactionFinalizationSucceeded` event).
*
* Emits a warning if the deposit is in the last window and the stage index is greater than
* `ProofConversionJobSucceeded` (excluding the above edge case).
*
* Throws an error if the deposit processing status becomes `MissedMintingOpportunity`.
*
* @param depositProcessingStatus$ Observable emitting deposit processing updates.
* @returns A promise resolving to true when mint proof generation is ready.
* @throws Error if the minting opportunity is missed.
*/
export declare function readyToComputeMintProof(depositProcessingStatus$: ReturnType<typeof getDepositProcessingStatus$>): Promise<boolean>;
export declare const canComputeEthProof: readonly ["Waiting", "CanCompute", BridgeDepositProcessingStatus.MissedMintingOpportunity];
export type CanComputEthProof = (typeof canComputeEthProof)[number];
/**
* Emits the current proof computation status as one of three possible values:
* `'CanCompute'`, `'Waiting'`, or `BridgeDepositProcessingStatus.MissedMintingOpportunity`.
*
* - Emits `'Waiting'` if none of the above conditions are met and the opportunity has not been missed.
* - Emits `'CanCompute'` if:
* - Deposit status is `ReadyToMint`, or
* - Deposit status is `WaitingForCurrentJobCompletion` and the stage is at or beyond `ProofConversionJobSucceeded`, or
* - Deposit is in the last deposit window, the current job stage index is before `EthProcessorTransactionSubmitSucceeded`,
* and the current job’s block range is not identical to the last finalized job’s block range (edge-case avoidance).
* - Emits `BridgeDepositProcessingStatus.MissedMintingOpportunity` and completes if the deposit transitions to a missed opportunity state.
*
* Consecutive duplicate values are suppressed.
* Null intermediate values (indeterminate state) are not emitted.
*
* @param depositProcessingStatus$ Observable emitting deposit processing updates.
* @returns Observable emitting `'canCompute'`, `'waiting'`, or `MissedMintingOpportunity`.
*/
export declare function getCanComputeEthProof$(depositProcessingStatus$: ReturnType<typeof getDepositProcessingStatus$>): import("rxjs").Observable<BridgeDepositProcessingStatus.MissedMintingOpportunity | "Waiting" | "CanCompute">;
/**
* Waits for the next combined emission of Ethereum finalization state, bridge state, and bridge timing data.
*
* **Unsafe Method Warning:** Awaiting this function before calling getDepositProcessingStatus may incorrectly
* identify a deposit as having missed its minting opportunity if the bridge has finalized the deposit’s proof
* window, started processing a new job that has not yet emitted an `EthProcessorTransactionFinalizationSucceeded`
* transition notice, and a websocket server restart caused loss of the last finalized job state. However, using
* the safe method may require the user to wait for the current bridge job to complete, which could take many minutes,
* before locking is allowed.
*
* Using this “unsafe” method trades accuracy for speed: it returns as soon as all three streams emit once,
* potentially allowing a user to lock sooner, at the risk of misclassification of the deposit status.
*
* @param ethStateTopic$ Observable stream of Ethereum finalization state.
* @param bridgeStateTopic$ Observable stream of the bridge’s processing state.
* @param bridgeTimingsTopic$ Observable stream of the bridge’s timing parameters.
* @returns A promise resolving to a tuple [ethState, bridgeState, bridgeTimings] containing the latest
* values from each stream.
*/
export declare function bridgeStatusesKnownEnoughToLockUnsafe(ethStateTopic$: ReturnType<typeof getEthStateTopic$>, bridgeStateTopic$: ReturnType<typeof getBridgeStateTopic$>, bridgeTimingsTopic$: ReturnType<typeof getBridgeTimingsTopic$>): Promise<[{
latest_finality_block_number: number;
latest_finality_slot: number;
}, {
stage_name: KeyTransitionStageMessageTypes;
input_slot: number;
input_block_number: number;
output_slot: number;
output_block_number: number;
elapsed_sec: number;
last_finalized_job: "unknown" | {
input_slot: number;
input_block_number: number;
output_slot: number;
output_block_number: number;
};
}, {
message_type: "TransitionTiming";
extension: import("@nori-zk/pts-types").KeyTransitionStageEstimatedTransitionTime;
datetime_iso: string;
topic: "timings.notices.transition";
}]>;
/**
* Waits for the next combined emission of Ethereum finalization state, bridge state, and bridge timing data,
* ensuring that the last finalized bridge job is known before resolving.
*
* **Safe Method Guarantee:** Awaiting this function guarantees accurate classification of the deposit status
* when using the getDepositProcessingStatus function by waiting until the bridge reports a known `last_finalized_job`.
* This ensures the minting opportunity window for the deposit can be definitively determined.
*
* This prevents unsafe assumptions that could occur if the bridge has finalized the deposit’s proof window
* and started processing a new job, **and** a websocket server restart caused loss of the last finalized job state—
* leading to incorrect classification of the current deposit as having missed its minting opportunity.
*
* However, this safety comes at the cost of responsiveness: users may be forced to wait until the current job
* has been finalized (which may take up to 30 minutes) before locking is permitted.
*
* This method prioritizes correctness over responsiveness, and should be used in user-facing flows where
* reliable deposit status is required.
*
* @param ethStateTopic$ Observable stream of Ethereum finalization state.
* @param bridgeStateTopic$ Observable stream of the bridge’s processing state.
* @param bridgeTimingsTopic$ Observable stream of the bridge’s timing parameters.
* @returns A promise resolving to a tuple [ethState, bridgeState, bridgeTimings] only when the last
* finalized job is known.
*/
export declare function bridgeStatusesKnownEnoughToLockSafe(ethStateTopic$: ReturnType<typeof getEthStateTopic$>, bridgeStateTopic$: ReturnType<typeof getBridgeStateTopic$>, bridgeTimingsTopic$: ReturnType<typeof getBridgeTimingsTopic$>): Promise<[{
latest_finality_block_number: number;
latest_finality_slot: number;
}, {
stage_name: KeyTransitionStageMessageTypes;
input_slot: number;
input_block_number: number;
output_slot: number;
output_block_number: number;
elapsed_sec: number;
last_finalized_job: "unknown" | {
input_slot: number;
input_block_number: number;
output_slot: number;
output_block_number: number;
};
}, {
message_type: "TransitionTiming";
extension: import("@nori-zk/pts-types").KeyTransitionStageEstimatedTransitionTime;
datetime_iso: string;
topic: "timings.notices.transition";
}]>;