@midnight-ntwrk/wallet-sdk-capabilities 4.0.0-beta.2 → 4.0.0-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/README.md +27 -3
  2. package/dist/chainVersion/chainVersionProbe.d.ts +95 -0
  3. package/dist/chainVersion/chainVersionProbe.js +83 -0
  4. package/dist/chainVersion/index.d.ts +1 -0
  5. package/dist/chainVersion/index.js +13 -0
  6. package/dist/codecs/index.d.ts +1 -0
  7. package/dist/codecs/index.js +13 -0
  8. package/dist/codecs/ledgerParameters.d.ts +81 -0
  9. package/dist/codecs/ledgerParameters.js +63 -0
  10. package/dist/index.d.ts +3 -0
  11. package/dist/index.js +3 -0
  12. package/dist/pendingTransactions/pendingTransactions.d.ts +113 -9
  13. package/dist/pendingTransactions/pendingTransactions.js +147 -30
  14. package/dist/pendingTransactions/pendingTransactionsService.d.ts +25 -9
  15. package/dist/pendingTransactions/pendingTransactionsService.js +33 -21
  16. package/dist/proving/index.d.ts +2 -0
  17. package/dist/proving/index.js +2 -0
  18. package/dist/proving/provingService.d.ts +175 -15
  19. package/dist/proving/provingService.js +104 -11
  20. package/dist/proving/v8ProvingService.d.ts +53 -0
  21. package/dist/proving/v8ProvingService.js +71 -0
  22. package/dist/proving/versionedProving.d.ts +42 -0
  23. package/dist/proving/versionedProving.js +103 -0
  24. package/dist/signatures/index.d.ts +2 -0
  25. package/dist/signatures/index.js +14 -0
  26. package/dist/signatures/signing.d.ts +37 -0
  27. package/dist/signatures/signing.js +13 -0
  28. package/dist/signatures/v8Signatures.d.ts +54 -0
  29. package/dist/signatures/v8Signatures.js +62 -0
  30. package/dist/simulation/ForkSimulator.d.ts +114 -0
  31. package/dist/simulation/ForkSimulator.js +209 -0
  32. package/dist/simulation/LedgerTranslation.d.ts +53 -0
  33. package/dist/simulation/LedgerTranslation.js +56 -0
  34. package/dist/simulation/core/VersionTimeline.d.ts +54 -0
  35. package/dist/simulation/core/VersionTimeline.js +56 -0
  36. package/dist/simulation/core/blocks.d.ts +38 -0
  37. package/dist/simulation/core/blocks.js +52 -0
  38. package/dist/simulation/core/index.d.ts +13 -0
  39. package/dist/simulation/core/index.js +25 -0
  40. package/dist/simulation/core/strictness.d.ts +29 -0
  41. package/dist/simulation/core/strictness.js +39 -0
  42. package/dist/simulation/index.d.ts +22 -2
  43. package/dist/simulation/index.js +25 -14
  44. package/dist/simulation/v8/Simulator.d.ts +231 -0
  45. package/dist/simulation/v8/Simulator.js +503 -0
  46. package/dist/simulation/{SimulatorState.d.ts → v8/SimulatorState.d.ts} +31 -44
  47. package/dist/simulation/v8/SimulatorState.js +290 -0
  48. package/dist/simulation/v8/index.d.ts +2 -0
  49. package/dist/simulation/v8/index.js +26 -0
  50. package/dist/simulation/{Simulator.d.ts → v9/Simulator.d.ts} +57 -6
  51. package/dist/simulation/{Simulator.js → v9/Simulator.js} +68 -18
  52. package/dist/simulation/v9/SimulatorState.d.ts +336 -0
  53. package/dist/simulation/{SimulatorState.js → v9/SimulatorState.js} +34 -67
  54. package/dist/simulation/v9/index.d.ts +2 -0
  55. package/dist/simulation/v9/index.js +26 -0
  56. package/dist/submission/submissionService.d.ts +2 -1
  57. package/dist/submission/submissionService.js +1 -1
  58. package/dist/validation/blockData.d.ts +42 -2
  59. package/dist/validation/blockData.js +55 -8
  60. package/dist/validation/index.d.ts +2 -0
  61. package/dist/validation/index.js +2 -0
  62. package/dist/validation/v8ValidationService.d.ts +29 -0
  63. package/dist/validation/v8ValidationService.js +48 -0
  64. package/dist/validation/validationService.d.ts +132 -17
  65. package/dist/validation/validationService.js +88 -42
  66. package/dist/validation/versionedValidation.d.ts +46 -0
  67. package/dist/validation/versionedValidation.js +55 -0
  68. package/package.json +23 -9
@@ -0,0 +1,54 @@
1
+ import { type ProtocolVersion } from '@midnight-ntwrk/wallet-sdk-abstractions';
2
+ /**
3
+ * A protocol version scheduled to activate at a block height — a fork on the simulated chain.
4
+ *
5
+ * The version itself is always supplied by the caller: the protocol version of the real fork is not final, so nothing
6
+ * in the simulator may assume a particular value.
7
+ */
8
+ export type ScheduledFork = Readonly<{
9
+ /** Height of the first block produced under {@link version}. */
10
+ atBlock: bigint;
11
+ /** Version that activates at {@link atBlock}. */
12
+ version: ProtocolVersion.ProtocolVersion;
13
+ }>;
14
+ /**
15
+ * The version-timeline part of a simulator state — the current version plus any scheduled activations.
16
+ *
17
+ * Every simulator state satisfies this structurally, so the functions below apply to all of them without knowing which
18
+ * ledger the state's other fields belong to.
19
+ */
20
+ export type VersionTimeline = Readonly<{
21
+ protocolVersion: ProtocolVersion.ProtocolVersion;
22
+ scheduledForks: readonly ScheduledFork[];
23
+ }>;
24
+ /** Get the protocol version the chain is currently on. */
25
+ export declare const getProtocolVersion: (timeline: VersionTimeline) => ProtocolVersion.ProtocolVersion;
26
+ /**
27
+ * Resolve the protocol version a block of the given height is produced under: the highest scheduled version whose
28
+ * activation height has been reached, or the chain's current version when no schedule applies.
29
+ *
30
+ * Scheduling a version at a height the chain has already passed therefore activates it on the next block rather than
31
+ * rewriting history — produced blocks keep the version they were produced under.
32
+ *
33
+ * @param timeline - Current version timeline
34
+ * @param blockNumber - Height of the block being produced
35
+ */
36
+ export declare const protocolVersionAt: {
37
+ (blockNumber: bigint): (timeline: VersionTimeline) => ProtocolVersion.ProtocolVersion;
38
+ (timeline: VersionTimeline, blockNumber: bigint): ProtocolVersion.ProtocolVersion;
39
+ };
40
+ /**
41
+ * Set the protocol version blocks produced from now on are stamped with. Already-produced blocks are untouched.
42
+ *
43
+ * @param state - Current simulator state
44
+ * @param version - Version to switch the chain to
45
+ */
46
+ export declare const setProtocolVersion: <TState extends VersionTimeline>(state: TState, version: ProtocolVersion.ProtocolVersion) => TState;
47
+ /**
48
+ * Schedule a protocol version to activate at a block height — a fork on the simulated chain.
49
+ *
50
+ * @param state - Current simulator state
51
+ * @param atBlock - Height of the first block produced under `version`
52
+ * @param version - Version that activates at `atBlock`
53
+ */
54
+ export declare const scheduleFork: <TState extends VersionTimeline>(state: TState, atBlock: bigint, version: ProtocolVersion.ProtocolVersion) => TState;
@@ -0,0 +1,56 @@
1
+ // This file is part of MIDNIGHT-WALLET-SDK.
2
+ // Copyright (C) Midnight Foundation
3
+ // SPDX-License-Identifier: Apache-2.0
4
+ // Licensed under the Apache License, Version 2.0 (the "License");
5
+ // You may not use this file except in compliance with the License.
6
+ // You may obtain a copy of the License at
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ // Unless required by applicable law or agreed to in writing, software
9
+ // distributed under the License is distributed on an "AS IS" BASIS,
10
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ // See the License for the specific language governing permissions and
12
+ // limitations under the License.
13
+ /**
14
+ * A simulated chain's protocol-version timeline.
15
+ *
16
+ * Which protocol version a chain is on, and when it changes, is the same question whichever ledger the chain runs — so
17
+ * it is answered once here and shared by every simulator, rather than duplicated per ledger version.
18
+ *
19
+ * Nothing in this module refers to a ledger type. Functions are stated over the smallest structure they need
20
+ * ({@link VersionTimeline}), which every simulator state satisfies.
21
+ */
22
+ import { Function as EFunction } from 'effect';
23
+ /** Get the protocol version the chain is currently on. */
24
+ export const getProtocolVersion = (timeline) => timeline.protocolVersion;
25
+ /**
26
+ * Resolve the protocol version a block of the given height is produced under: the highest scheduled version whose
27
+ * activation height has been reached, or the chain's current version when no schedule applies.
28
+ *
29
+ * Scheduling a version at a height the chain has already passed therefore activates it on the next block rather than
30
+ * rewriting history — produced blocks keep the version they were produced under.
31
+ *
32
+ * @param timeline - Current version timeline
33
+ * @param blockNumber - Height of the block being produced
34
+ */
35
+ export const protocolVersionAt = EFunction.dual(2, (timeline, blockNumber) => timeline.scheduledForks.reduce((version, fork) => (fork.atBlock <= blockNumber && fork.version > version ? fork.version : version), timeline.protocolVersion));
36
+ /**
37
+ * Set the protocol version blocks produced from now on are stamped with. Already-produced blocks are untouched.
38
+ *
39
+ * @param state - Current simulator state
40
+ * @param version - Version to switch the chain to
41
+ */
42
+ export const setProtocolVersion = (state, version) => ({
43
+ ...state,
44
+ protocolVersion: version,
45
+ });
46
+ /**
47
+ * Schedule a protocol version to activate at a block height — a fork on the simulated chain.
48
+ *
49
+ * @param state - Current simulator state
50
+ * @param atBlock - Height of the first block produced under `version`
51
+ * @param version - Version that activates at `atBlock`
52
+ */
53
+ export const scheduleFork = (state, atBlock, version) => ({
54
+ ...state,
55
+ scheduledForks: [...state.scheduledForks, { atBlock, version }],
56
+ });
@@ -0,0 +1,38 @@
1
+ /**
2
+ * The context a block is executed against.
3
+ *
4
+ * Structurally the ledger's own `BlockContext`, which is a plain record and is defined identically by ledger-v8 and
5
+ * ledger-v9 — so it is stated once here and a value of this type is accepted by either ledger.
6
+ */
7
+ export type BlockContext = Readonly<{
8
+ /** Hash of the parent block */
9
+ parentBlockHash: string;
10
+ /** Seconds elapsed since the UNIX epoch */
11
+ secondsSinceEpoch: bigint;
12
+ /** Maximum expected error on {@link secondsSinceEpoch}, as a positive number of seconds */
13
+ secondsSinceEpochErr: number;
14
+ /** Seconds since the previous block */
15
+ lastBlockTime: bigint;
16
+ }>;
17
+ /** The part of a produced block that block timing needs — its height and when it was produced. */
18
+ export type PreviousBlock = Readonly<{
19
+ number: bigint;
20
+ timestamp: Date;
21
+ }>;
22
+ /**
23
+ * Compute block hash from block number. Uses a deterministic hash based on block number for easy recomputation.
24
+ *
25
+ * @param blockNumber - The block number to compute hash for
26
+ * @returns A deterministic 64-character hex hash
27
+ */
28
+ export declare const blockHash: (blockNumber: bigint) => Promise<string>;
29
+ /**
30
+ * Create the next block context from the previous block.
31
+ *
32
+ * @param previousBlock - The previous block (or undefined for genesis)
33
+ * @param blockTime - The timestamp for the new block
34
+ * @param blockNumber - Height of the new block, overriding the height derived from `previousBlock`. Needed for a
35
+ * genesis block that continues an existing chain's numbering, as a ledger-v9 chain's does.
36
+ * @returns A BlockContext suitable for transaction processing
37
+ */
38
+ export declare const nextBlockContextFromBlock: (previousBlock: PreviousBlock | undefined, blockTime: Date, blockNumber?: bigint) => Promise<BlockContext>;
@@ -0,0 +1,52 @@
1
+ // This file is part of MIDNIGHT-WALLET-SDK.
2
+ // Copyright (C) Midnight Foundation
3
+ // SPDX-License-Identifier: Apache-2.0
4
+ // Licensed under the Apache License, Version 2.0 (the "License");
5
+ // You may not use this file except in compliance with the License.
6
+ // You may obtain a copy of the License at
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ // Unless required by applicable law or agreed to in writing, software
9
+ // distributed under the License is distributed on an "AS IS" BASIS,
10
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ // See the License for the specific language governing permissions and
12
+ // limitations under the License.
13
+ /**
14
+ * Block identity and timing for a simulated chain — how a block is hashed and what context it is executed against.
15
+ *
16
+ * Neither depends on the ledger a chain runs, so both are shared by every simulator.
17
+ */
18
+ import { DateOps } from '@midnight-ntwrk/wallet-sdk-utilities';
19
+ /**
20
+ * Compute block hash from block number. Uses a deterministic hash based on block number for easy recomputation.
21
+ *
22
+ * @param blockNumber - The block number to compute hash for
23
+ * @returns A deterministic 64-character hex hash
24
+ */
25
+ export const blockHash = async (blockNumber) => {
26
+ const input = `block-${blockNumber.toString()}`;
27
+ const hashBuffer = await globalThis.crypto.subtle.digest('SHA-256', new TextEncoder().encode(input));
28
+ const { Encoding } = await import('effect');
29
+ return Encoding.encodeHex(new Uint8Array(hashBuffer));
30
+ };
31
+ /**
32
+ * Create the next block context from the previous block.
33
+ *
34
+ * @param previousBlock - The previous block (or undefined for genesis)
35
+ * @param blockTime - The timestamp for the new block
36
+ * @param blockNumber - Height of the new block, overriding the height derived from `previousBlock`. Needed for a
37
+ * genesis block that continues an existing chain's numbering, as a ledger-v9 chain's does.
38
+ * @returns A BlockContext suitable for transaction processing
39
+ */
40
+ export const nextBlockContextFromBlock = async (previousBlock, blockTime, blockNumber) => {
41
+ const nextBlockNumber = blockNumber ?? (previousBlock !== undefined ? previousBlock.number + 1n : 0n);
42
+ const hash = await blockHash(nextBlockNumber);
43
+ const blockSeconds = DateOps.dateToSeconds(blockTime);
44
+ const previousSeconds = previousBlock !== undefined ? DateOps.dateToSeconds(previousBlock.timestamp) : blockSeconds - 1n;
45
+ const timeSinceLastBlock = blockSeconds - previousSeconds;
46
+ return {
47
+ parentBlockHash: hash,
48
+ secondsSinceEpoch: blockSeconds,
49
+ secondsSinceEpochErr: 1, // Clock error tolerance in seconds (reasonable default for simulator)
50
+ lastBlockTime: timeSinceLastBlock > 0n ? timeSinceLastBlock : 1n,
51
+ };
52
+ };
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Simulator internals that are the same whichever ledger a simulated chain runs.
3
+ *
4
+ * The ledger-v8 and ledger-v9 simulators are otherwise twins, so anything here is written once instead of once per
5
+ * version. The rule for what belongs: it must not name a ledger type. Everything that constructs or applies ledger
6
+ * objects — the ledger state, transactions, strictness objects, genesis minting — stays in the per-version simulators,
7
+ * because that is what genuinely differs between them.
8
+ *
9
+ * Not a published entry point; re-exported through each version's barrel.
10
+ */
11
+ export { getProtocolVersion, protocolVersionAt, scheduleFork, setProtocolVersion, type ScheduledFork, type VersionTimeline, } from './VersionTimeline.js';
12
+ export { blockHash, nextBlockContextFromBlock, type BlockContext, type PreviousBlock } from './blocks.js';
13
+ export { defaultStrictness, genesisStrictness, type StrictnessConfig } from './strictness.js';
@@ -0,0 +1,25 @@
1
+ // This file is part of MIDNIGHT-WALLET-SDK.
2
+ // Copyright (C) Midnight Foundation
3
+ // SPDX-License-Identifier: Apache-2.0
4
+ // Licensed under the Apache License, Version 2.0 (the "License");
5
+ // You may not use this file except in compliance with the License.
6
+ // You may obtain a copy of the License at
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ // Unless required by applicable law or agreed to in writing, software
9
+ // distributed under the License is distributed on an "AS IS" BASIS,
10
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ // See the License for the specific language governing permissions and
12
+ // limitations under the License.
13
+ /**
14
+ * Simulator internals that are the same whichever ledger a simulated chain runs.
15
+ *
16
+ * The ledger-v8 and ledger-v9 simulators are otherwise twins, so anything here is written once instead of once per
17
+ * version. The rule for what belongs: it must not name a ledger type. Everything that constructs or applies ledger
18
+ * objects — the ledger state, transactions, strictness objects, genesis minting — stays in the per-version simulators,
19
+ * because that is what genuinely differs between them.
20
+ *
21
+ * Not a published entry point; re-exported through each version's barrel.
22
+ */
23
+ export { getProtocolVersion, protocolVersionAt, scheduleFork, setProtocolVersion, } from './VersionTimeline.js';
24
+ export { blockHash, nextBlockContextFromBlock } from './blocks.js';
25
+ export { defaultStrictness, genesisStrictness } from './strictness.js';
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Which well-formedness checks a simulated chain enforces, as plain configuration.
3
+ *
4
+ * The configuration and its presets say nothing about a ledger, so they are shared. Turning one into the ledger's
5
+ * `WellFormedStrictness` object is per-ledger and stays with each simulator (`createStrictness`).
6
+ */
7
+ /** Configuration for well-formedness strictness checks. All options default to false for testing flexibility. */
8
+ export type StrictnessConfig = Readonly<{
9
+ enforceBalancing?: boolean;
10
+ verifyNativeProofs?: boolean;
11
+ verifyContractProofs?: boolean;
12
+ enforceLimits?: boolean;
13
+ verifySignatures?: boolean;
14
+ }>;
15
+ /**
16
+ * Default strictness for post-genesis blocks.
17
+ *
18
+ * In a realistic simulation:
19
+ *
20
+ * - Signatures should be verified (verifySignatures: true)
21
+ * - Proofs cannot be verified because they're erased (verifyNativeProofs/verifyContractProofs: false)
22
+ * - Limits should be enforced (enforceLimits: true)
23
+ * - Balancing must be enforced (enforceBalancing: true) - transactions must pay fees
24
+ *
25
+ * Note: Genesis blocks typically disable all strictness to allow initial token distribution.
26
+ */
27
+ export declare const defaultStrictness: StrictnessConfig;
28
+ /** Strictness for genesis blocks - all checks disabled to allow initial token distribution. */
29
+ export declare const genesisStrictness: StrictnessConfig;
@@ -0,0 +1,39 @@
1
+ // This file is part of MIDNIGHT-WALLET-SDK.
2
+ // Copyright (C) Midnight Foundation
3
+ // SPDX-License-Identifier: Apache-2.0
4
+ // Licensed under the Apache License, Version 2.0 (the "License");
5
+ // You may not use this file except in compliance with the License.
6
+ // You may obtain a copy of the License at
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ // Unless required by applicable law or agreed to in writing, software
9
+ // distributed under the License is distributed on an "AS IS" BASIS,
10
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ // See the License for the specific language governing permissions and
12
+ // limitations under the License.
13
+ /**
14
+ * Default strictness for post-genesis blocks.
15
+ *
16
+ * In a realistic simulation:
17
+ *
18
+ * - Signatures should be verified (verifySignatures: true)
19
+ * - Proofs cannot be verified because they're erased (verifyNativeProofs/verifyContractProofs: false)
20
+ * - Limits should be enforced (enforceLimits: true)
21
+ * - Balancing must be enforced (enforceBalancing: true) - transactions must pay fees
22
+ *
23
+ * Note: Genesis blocks typically disable all strictness to allow initial token distribution.
24
+ */
25
+ export const defaultStrictness = {
26
+ enforceBalancing: true,
27
+ verifyNativeProofs: false,
28
+ verifyContractProofs: false,
29
+ enforceLimits: true,
30
+ verifySignatures: true,
31
+ };
32
+ /** Strictness for genesis blocks - all checks disabled to allow initial token distribution. */
33
+ export const genesisStrictness = {
34
+ enforceBalancing: false,
35
+ verifyNativeProofs: false,
36
+ verifyContractProofs: false,
37
+ enforceLimits: false,
38
+ verifySignatures: false,
39
+ };
@@ -1,2 +1,22 @@
1
- export { getLastBlock, getCurrentBlockNumber, getCurrentTime, getBlockByNumber, getLastBlockResults, getLastBlockEvents, getBlockEventsFrom, getBlockEventsSince, hasPendingTransactions, resolveFullness, allMempoolTransactions, blankState, addToMempool, removeFromMempool, advanceTime, updateLedger, appendBlock, applyTransaction, processTransaction, processTransactions, createBlock, createEmptyBlock, type TransactionProcessingResult, createStrictness, blockHash, assignStrictness, assignStrictnessToAll, defaultStrictness, genesisStrictness, type SimulatorState, type Block, type BlockTransaction, type BlockInfo, type PendingTransaction, type ReadyTransaction, type BlockProductionRequest, type BlockProducer, type FullnessSpec, type GenesisMint, type StrictnessConfig, } from './SimulatorState.js';
2
- export { Simulator, immediateBlockProducer, type SimulatorConfig } from './Simulator.js';
1
+ /**
2
+ * Simulated ledger environments for wallet testing.
3
+ *
4
+ * There is one simulator per ledger version, in `v8/` and `v9/`. They are twins: the same simulator over a different
5
+ * ledger, so a chain on either side of the hard fork is driven with the same API. Their shared, ledger-agnostic
6
+ * internals live in `core/`.
7
+ *
8
+ * - **{@link V9}** — the ledger-v9 line. Also re-exported unqualified below, so `Simulator` and friends mean the v9
9
+ * simulator; this is what existing code gets.
10
+ * - **{@link V8}** — the ledger-v8 line. Used to drive a chain before the v9 fork, standalone or via {@link ForkSimulator}.
11
+ * - **{@link ForkSimulator}** — the two composed into a single chain that crosses the fork.
12
+ *
13
+ * Both namespaces are needed at once only when working across the boundary; the qualified form is what keeps the two
14
+ * apart, since the twins export identical names over structurally distinct ledger types.
15
+ */
16
+ export * from './v9/index.js';
17
+ /** The ledger-v9 simulator. Same as the unqualified exports above, named for symmetry with {@link V8}. */
18
+ export * as V9 from './v9/index.js';
19
+ /** The ledger-v8 simulator. */
20
+ export * as V8 from './v8/index.js';
21
+ export { ForkSimulator, type ForkSimulatorConfig } from './ForkSimulator.js';
22
+ export { LedgerTranslationError, translatorFromAsync, unavailableTranslator, type LedgerStateTranslator, } from './LedgerTranslation.js';
@@ -10,17 +10,28 @@
10
10
  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
11
  // See the License for the specific language governing permissions and
12
12
  // limitations under the License.
13
- // Re-export everything from SimulatorState
14
- export {
15
- // State accessor functions (composable with simulator.query())
16
- getLastBlock, getCurrentBlockNumber, getCurrentTime, getBlockByNumber, getLastBlockResults, getLastBlockEvents, getBlockEventsFrom, getBlockEventsSince, hasPendingTransactions,
17
- // State transformation functions
18
- resolveFullness, allMempoolTransactions, blankState, addToMempool, removeFromMempool, advanceTime, updateLedger, appendBlock, applyTransaction,
19
- // Block production functions
20
- processTransaction, processTransactions, createBlock, createEmptyBlock,
21
- // Helper functions
22
- createStrictness, blockHash, assignStrictness, assignStrictnessToAll,
23
- // Strictness constants
24
- defaultStrictness, genesisStrictness, } from './SimulatorState.js';
25
- // Re-export from Simulator
26
- export { Simulator, immediateBlockProducer } from './Simulator.js';
13
+ /**
14
+ * Simulated ledger environments for wallet testing.
15
+ *
16
+ * There is one simulator per ledger version, in `v8/` and `v9/`. They are twins: the same simulator over a different
17
+ * ledger, so a chain on either side of the hard fork is driven with the same API. Their shared, ledger-agnostic
18
+ * internals live in `core/`.
19
+ *
20
+ * - **{@link V9}** — the ledger-v9 line. Also re-exported unqualified below, so `Simulator` and friends mean the v9
21
+ * simulator; this is what existing code gets.
22
+ * - **{@link V8}** — the ledger-v8 line. Used to drive a chain before the v9 fork, standalone or via {@link ForkSimulator}.
23
+ * - **{@link ForkSimulator}** — the two composed into a single chain that crosses the fork.
24
+ *
25
+ * Both namespaces are needed at once only when working across the boundary; the qualified form is what keeps the two
26
+ * apart, since the twins export identical names over structurally distinct ledger types.
27
+ */
28
+ // The ledger-v9 simulator, unqualified: the default for code that does not span a fork.
29
+ export * from './v9/index.js';
30
+ /** The ledger-v9 simulator. Same as the unqualified exports above, named for symmetry with {@link V8}. */
31
+ export * as V9 from './v9/index.js';
32
+ /** The ledger-v8 simulator. */
33
+ export * as V8 from './v8/index.js';
34
+ // A chain that crosses the fork, built from both twins.
35
+ export { ForkSimulator } from './ForkSimulator.js';
36
+ // Carrying ledger state across the fork.
37
+ export { LedgerTranslationError, translatorFromAsync, unavailableTranslator, } from './LedgerTranslation.js';
@@ -0,0 +1,231 @@
1
+ /**
2
+ * Unified Simulator for wallet testing.
3
+ *
4
+ * This module provides a simulated ledger environment for testing wallet functionality without requiring a real
5
+ * blockchain node. It supports:
6
+ *
7
+ * - Optional genesis mints for pre-funded accounts (shielded, unshielded, or Night tokens)
8
+ * - Transaction submission with configurable strictness
9
+ * - Night token rewards via rewardNight()
10
+ * - Time advancement for TTL and time-sensitive tests
11
+ */
12
+ import { type Array as Arr, Effect, type Scope, Stream, SubscriptionRef } from 'effect';
13
+ import { type ProofErasedTransaction, type SignatureVerifyingKey } from '@midnight-ntwrk/ledger-v8';
14
+ import { LedgerOps } from '@midnight-ntwrk/wallet-sdk-utilities';
15
+ import { NetworkId, ProtocolVersion } from '@midnight-ntwrk/wallet-sdk-abstractions';
16
+ import { type Block, type BlockProducer, type FullnessSpec, type GenesisMint, type SimulatorState, type StrictnessConfig } from './SimulatorState.js';
17
+ export type { SimulatorState, Block, BlockTransaction, PendingTransaction, BlockInfo, BlockProductionRequest, BlockProducer, FullnessSpec, GenesisMint, ScheduledFork, StrictnessConfig, } from './SimulatorState.js';
18
+ export { getLastBlock, getCurrentBlockNumber, getBlockByNumber, getLastBlockResults, getLastBlockEvents, hasPendingTransactions, getCurrentTime, getProtocolVersion, protocolVersionAt, applyTransaction, defaultStrictness, genesisStrictness, createStrictness, } from './SimulatorState.js';
19
+ /**
20
+ * Default block producer: produces a block for each state change with non-empty mempool.
21
+ *
22
+ * By default, uses post-genesis strictness (balancing, signatures, limits enforced). This ensures realistic simulation
23
+ * where transactions must be properly balanced (pay fees).
24
+ *
25
+ * @param fullness - Static fullness (0-1) or callback based on state
26
+ * @param strictness - Strictness config (defaults to defaultStrictness)
27
+ */
28
+ export declare const immediateBlockProducer: (fullness?: FullnessSpec, strictness?: StrictnessConfig) => BlockProducer;
29
+ /** Simulator initialization configuration. */
30
+ export type SimulatorConfig = Readonly<{
31
+ /**
32
+ * Pre-funded accounts to create at genesis. When provided, creates a genesis block with transactions minting tokens
33
+ * to recipients. When omitted, the simulator starts with an empty ledger.
34
+ */
35
+ genesisMints?: Arr.NonEmptyArray<GenesisMint>;
36
+ /** Network identifier. Defaults to Undeployed. */
37
+ networkId?: NetworkId.NetworkId;
38
+ /** Custom block producer. Defaults to immediateBlockProducer(). */
39
+ blockProducer?: BlockProducer;
40
+ /**
41
+ * Protocol version the chain starts on. Defaults to {@link ProtocolVersion.MinSupportedVersion}.
42
+ *
43
+ * The version a fork activates is never built in — schedule it with {@link Simulator.scheduleFork} or switch to it
44
+ * with {@link Simulator.setProtocolVersion}.
45
+ */
46
+ protocolVersion?: ProtocolVersion.ProtocolVersion;
47
+ /**
48
+ * Height of the genesis block. Defaults to 0.
49
+ *
50
+ * Set this to continue an existing chain's numbering, as a ledger-v9 chain does from the fork height.
51
+ */
52
+ genesisBlockNumber?: bigint;
53
+ /**
54
+ * Timestamp of the genesis block, from which simulator time advances. Defaults to the epoch.
55
+ *
56
+ * Set this to continue an existing chain's timeline, so that time-sensitive behaviour does not restart at the epoch.
57
+ */
58
+ genesisTime?: Date;
59
+ }>;
60
+ /**
61
+ * Unified simulator for wallet testing.
62
+ *
63
+ * Provides a simulated ledger environment for testing wallet functionality without a real blockchain. Optionally
64
+ * pre-funds accounts via genesis mints.
65
+ *
66
+ * @example
67
+ * ```typescript
68
+ * // Empty ledger (useful for dust/Night token testing via rewardNight)
69
+ * const simulator = yield* Simulator.init({});
70
+ *
71
+ * // Pre-funded accounts (useful for token transfer testing)
72
+ * const simulator = yield* Simulator.init({
73
+ * genesisMints: [{ amount: 1000n, tokenType, shieldedRecipient: secretKeys }],
74
+ * });
75
+ * ```;
76
+ */
77
+ export declare class Simulator {
78
+ #private;
79
+ /**
80
+ * Initialize a new simulator.
81
+ *
82
+ * @example
83
+ * ```typescript
84
+ * // Empty ledger - use rewardNight() for Night tokens
85
+ * const simulator = yield* Simulator.init({});
86
+ *
87
+ * // Pre-funded accounts for token transfer testing
88
+ * const simulator = yield* Simulator.init({
89
+ * genesisMints: [{ amount: 1000n, tokenType, shieldedRecipient: secretKeys }],
90
+ * });
91
+ *
92
+ * // With custom network ID
93
+ * const simulator = yield* Simulator.init({
94
+ * networkId: NetworkId.Preview,
95
+ * genesisMints: [...],
96
+ * });
97
+ * ```;
98
+ *
99
+ * @param config - Configuration options (all optional)
100
+ * @returns Effect that produces a Simulator instance
101
+ */
102
+ static init(config?: SimulatorConfig): Effect.Effect<Simulator, never, Scope.Scope>;
103
+ /** Initialize simulator with blank ledger state. */
104
+ private static initBlank;
105
+ /**
106
+ * Initialize simulator with genesis mints (pre-funded accounts). Supports shielded and unshielded token mints. Night
107
+ * tokens are auto-detected by comparing tokenType with `Token.night`.
108
+ */
109
+ private static initWithGenesis;
110
+ /**
111
+ * Create a Simulator from an initial state with proper stream setup.
112
+ *
113
+ * The low-level constructor behind {@link Simulator.init}. Use it when the initial state cannot be expressed as a
114
+ * config — most importantly a ledger-v9 chain, whose ledger is handed over from the chain before it.
115
+ *
116
+ * @param initialState - State the simulator starts from
117
+ * @param blockProducer - Custom block producer (defaults to immediateBlockProducer())
118
+ */
119
+ static fromState(initialState: SimulatorState, blockProducer?: BlockProducer): Effect.Effect<Simulator, never, Scope.Scope>;
120
+ /** Observable stream of simulator state changes. */
121
+ readonly state$: Stream.Stream<SimulatorState>;
122
+ constructor(stateRef: SubscriptionRef.SubscriptionRef<SimulatorState>, state$: Stream.Stream<SimulatorState>);
123
+ /** Get the current simulator state. */
124
+ getLatestState(): Effect.Effect<SimulatorState>;
125
+ /**
126
+ * Distribute Night tokens to a recipient and submit claim transaction to mempool. Used for testing dust token
127
+ * generation.
128
+ *
129
+ * This method:
130
+ *
131
+ * 1. Modifies the ledger to make Night tokens claimable
132
+ * 2. Creates and submits a ClaimRewardsTransaction to the mempool
133
+ * 3. The block producer will process the transaction
134
+ *
135
+ * @param verifyingKey - Signature verifying key (recipient address is derived from it)
136
+ * @param amount - Amount of Night tokens to distribute
137
+ */
138
+ rewardNight(verifyingKey: SignatureVerifyingKey, amount: bigint): Effect.Effect<Block, LedgerOps.LedgerError>;
139
+ /**
140
+ * Submit a transaction and wait for it to be included in a block.
141
+ *
142
+ * This method adds the transaction to the mempool and blocks until the block producer includes it in a block. Use
143
+ * this when you need confirmation that the transaction was processed.
144
+ *
145
+ * For fire-and-forget scenarios where you don't need to wait for block inclusion, use `submitAndForget` instead.
146
+ *
147
+ * @param tx - Transaction to submit (proofs erased)
148
+ * @param options - Optional submission options
149
+ * @param options.strictness - Override well-formedness strictness
150
+ * @returns The block containing the transaction
151
+ */
152
+ submitTransaction(tx: ProofErasedTransaction, options?: {
153
+ strictness?: StrictnessConfig;
154
+ }): Effect.Effect<Block, LedgerOps.LedgerError>;
155
+ /**
156
+ * Submit a transaction without waiting for block inclusion.
157
+ *
158
+ * This method adds the transaction to the mempool and returns immediately. The block producer will process it
159
+ * asynchronously. Use this for fire-and-forget scenarios or when testing custom block producers with batched
160
+ * transactions.
161
+ *
162
+ * To wait for block inclusion, use `submitTransaction` instead.
163
+ *
164
+ * @param tx - Transaction to submit (proofs erased)
165
+ * @param options - Optional options
166
+ * @param options.strictness - Override well-formedness strictness
167
+ */
168
+ submitAndForget(tx: ProofErasedTransaction, options?: {
169
+ strictness?: StrictnessConfig;
170
+ }): Effect.Effect<void>;
171
+ /**
172
+ * Produce a block with no transactions, advancing the chain by one height.
173
+ *
174
+ * Bypasses the configured block producer, which only produces when there is something in the mempool. Use it to reach
175
+ * a given height without traffic — a fork happens at a height whether or not transactions were submitted.
176
+ *
177
+ * @returns The produced block
178
+ */
179
+ produceEmptyBlock(): Effect.Effect<Block, LedgerOps.LedgerError>;
180
+ /**
181
+ * Switch the chain to a protocol version, effective for blocks produced from now on. Already-produced blocks keep the
182
+ * version they were produced under.
183
+ *
184
+ * @param version - Version to switch the chain to
185
+ */
186
+ setProtocolVersion(version: ProtocolVersion.ProtocolVersion): Effect.Effect<void>;
187
+ /**
188
+ * Schedule a protocol version to activate at a block height — a fork on the simulated chain. The block produced at
189
+ * that height, and every block after it, is stamped with `version`.
190
+ *
191
+ * @param atBlock - Height of the first block produced under `version`
192
+ * @param version - Version that activates at `atBlock`
193
+ */
194
+ scheduleFork(atBlock: bigint, version: ProtocolVersion.ProtocolVersion): Effect.Effect<void>;
195
+ /**
196
+ * Fast-forward the simulator time by the given number of seconds. Does not produce a block - only advances the
197
+ * internal clock. Useful for testing time-sensitive functionality like TTL.
198
+ *
199
+ * @param seconds - Number of seconds to advance (must be positive)
200
+ */
201
+ fastForward(seconds: bigint): Effect.Effect<void>;
202
+ /**
203
+ * Query the simulator state with a custom function. This is a generic query mechanism that allows extracting any
204
+ * information from the current state without modifying it.
205
+ *
206
+ * @example
207
+ * ```typescript
208
+ * // Query fee prices
209
+ * const feePrices = yield* simulator.query(state => state.ledger.parameters.feePrices);
210
+ *
211
+ * // Use composable state accessors
212
+ * const blockNumber = yield* simulator.query(getCurrentBlockNumber);
213
+ * const lastBlock = yield* simulator.query(getLastBlock);
214
+ * const events = yield* simulator.query(getLastBlockEvents);
215
+ *
216
+ * // Query UTXOs for an address
217
+ * const utxos = yield* simulator.query(state => Array.from(state.ledger.utxo.filter(address)));
218
+ *
219
+ * // Complex query returning multiple values
220
+ * const info = yield* simulator.query(state => ({
221
+ * networkId: state.networkId,
222
+ * blockNumber: getCurrentBlockNumber(state),
223
+ * feePrices: state.ledger.parameters.feePrices,
224
+ * }));
225
+ * ```;
226
+ *
227
+ * @param fn - Function that receives the current state and returns a result
228
+ * @returns The result of applying the function to the current state
229
+ */
230
+ query<T>(fn: (state: SimulatorState) => T): Effect.Effect<T>;
231
+ }