### Quick Start: Create and Use a Simulator Source: https://github.com/openzeppelin/compact-contracts/blob/main/packages/simulator/README.md This snippet demonstrates the initial setup and usage of the simulator. It involves defining contract argument types, extracting ledger types, creating the simulator instance, and instantiating it with contract arguments and options. ```typescript import { createSimulator } from '@openzeppelin-compact/contracts-simulator'; import { Contract, ledger } from './artifacts/MyContract/contract/index.js'; // 1. Define your contract arguments type type MyContractArgs = readonly [owner: Uint8Array, value: bigint]; // 2. Define the extracted ledger type type MyContractLedger = ReturnType; // 3. Create the simulator const MySimulator = createSimulator< MyPrivateState, ReturnType, ReturnType, MyContractArgs >({ contractFactory: (witnesses) => new Contract(witnesses), defaultPrivateState: () => MyPrivateState.generate(), contractArgs: (owner, value) => [owner, value], ledgerExtractor: (state) => ledger(state), witnessesFactory: () => MyWitnesses(), }); // 4. Use it! const sim = new MySimulator([ownerAddress, 100n], { coinPK: deployerPK }); ``` -------------------------------- ### Compiler Output Example Source: https://github.com/openzeppelin/compact-contracts/blob/main/packages/compact/README.md Example log output from the `compact-compiler` indicating the start of the process, toolchain versions, files found, and successful compilation of contracts. ```bash ℹ [COMPILE] Compact compiler started ℹ [COMPILE] Compact developer tools: compact 0.4.0 ℹ [COMPILE] Compact toolchain: Compactc version: 0.29.0 ℹ [COMPILE] Found 2 .compact file(s) to compile ✔ [COMPILE] [1/2] Compiled AccessControl.compact Compactc version: 0.29.0 ✔ [COMPILE] [2/2] Compiled Token.compact Compactc version: 0.29.0 ``` -------------------------------- ### Install Dependencies and Prepare Environment Source: https://github.com/openzeppelin/compact-contracts/blob/main/README.md Install project dependencies using nvm and yarn, and prepare the Compact environment. This step is crucial after adding the submodule. ```bash nvm install && \ yarn && \ SKIP_ZK=true yarn compact ``` -------------------------------- ### Clone and Set Up Project Source: https://github.com/openzeppelin/compact-contracts/blob/main/README.md Clone the OpenZeppelin Contracts for Compact repository and install its dependencies using nvm, yarn, and turbo. ```bash git clone git@github.com:OpenZeppelin/compact-contracts.git cd compact-contracts nvm install && \ yarn && \ turbo compact ``` -------------------------------- ### Compile Contract Version Source: https://github.com/openzeppelin/compact-contracts/blob/main/README.md Verify the installed Compact compiler version. Ensure `compact` is in your PATH. ```bash compact compile --version Compactc version: 0.29.0 0.29.0 ``` -------------------------------- ### Verify Compact Installation Source: https://github.com/openzeppelin/compact-contracts/blob/main/packages/compact/README.md Verify that the Midnight Compact toolchain is installed and accessible in your system's PATH. ```bash compact compile --version ``` -------------------------------- ### Custom Contract with OpenZeppelin Modules Source: https://github.com/openzeppelin/compact-contracts/blob/main/README.md Example of a custom Compact contract importing and utilizing OpenZeppelin modules for access control, pausing, and fungible tokens. Imports should be done through node_modules to prevent state conflicts. ```typescript // MyContract.compact pragma language_version >= 0.18.0; import CompactStandardLibrary; import "./compact-contracts/node_modules/@openzeppelin/compact-contracts/src/access/Ownable" prefix Ownable_; import "./compact-contracts/node_modules/@openzeppelin/compact-contracts/src/security/Pausable" prefix Pausable_; import "./compact-contracts/node_modules/@openzeppelin/compact-contracts/src/token/FungibleToken" prefix FungibleToken_; constructor( _name: Opaque<"string">, _symbol: Opaque<"string">, _decimals: Uint<8>, _recipient: Either, _amount: Uint<128>, _initOwner: Either, ) { Ownable_initialize(_initOwner); FungibleToken_initialize(_name, _symbol, _decimals); FungibleToken__mint(_recipient, _amount); } export circuit transfer( to: Either, value: Uint<128>, ): Boolean { Pausable_assertNotPaused(); return FungibleToken_transfer(to, value); } export circuit pause(): [] { Ownable_assertOnlyOwner(); Pausable__pause(); } export circuit unpause(): [] { Ownable_assertOnlyOwner(); Pausable__unpause(); } (...) ``` -------------------------------- ### Circuit Types: Pure Circuits Example Source: https://github.com/openzeppelin/compact-contracts/blob/main/packages/simulator/README.md This snippet demonstrates how to define and call pure circuits within the simulator. Pure circuits compute outputs from inputs without reading or modifying contract state. ```typescript public add(a: bigint, b: bigint): bigint { return this.circuits.pure.add(a, b); } public calculateFee(amount: bigint): bigint { return this.circuits.pure.calculateFee(amount); } ``` -------------------------------- ### Circuit Types: Impure Circuits Example Source: https://github.com/openzeppelin/compact-contracts/blob/main/packages/simulator/README.md This code shows how to define and call impure circuits. Impure circuits are capable of reading and/or modifying the contract's state. ```typescript public deposit(amount: bigint): void { this.circuits.impure.deposit(amount); } public getBalance(): bigint { return this.circuits.impure.getBalance(); } ``` -------------------------------- ### Initialize Project and Add Submodule Source: https://github.com/openzeppelin/compact-contracts/blob/main/README.md Create a new project directory, initialize git, and add OpenZeppelin Contracts for Compact as a git submodule. ```bash mkdir my-project cd my-project git init && \ git submodule add https://github.com/OpenZeppelin/compact-contracts.git ``` -------------------------------- ### Deploy Documentation Source: https://github.com/openzeppelin/compact-contracts/blob/main/RELEASING.md From the released tag, create and push a new branch to deploy the corresponding version to the documentation site. ```sh git checkout -b docs-v0.2.0 git push origin docs-v0.2.0 ``` -------------------------------- ### Compile All Contracts (Flattened Output) Source: https://github.com/openzeppelin/compact-contracts/blob/main/packages/compact/README.md Use the `compact-compiler` to compile all `.compact` files in the project. Artifacts are placed directly in the output directory. ```bash compact-compiler ``` -------------------------------- ### Builder Build Specific Directory and Skip Proving Key Generation Source: https://github.com/openzeppelin/compact-contracts/blob/main/packages/compact/README.md Build a specific directory with `compact-builder` and skip proving key generation. Note: Builder always includes ZK proofs, this option might be a typo in the source. ```bash compact-builder --dir token --skip-zk ``` -------------------------------- ### Run Project Tests Source: https://github.com/openzeppelin/compact-contracts/blob/main/README.md Execute all tests within the OpenZeppelin Contracts for Compact project using the `turbo test` command. ```bash turbo test ``` -------------------------------- ### Full Builder Build Source: https://github.com/openzeppelin/compact-contracts/blob/main/packages/compact/README.md Execute the full build process using `compact-builder`, which includes compilation, TypeScript compilation, and artifact copying. ```bash compact-builder ``` -------------------------------- ### Development Build Command Source: https://github.com/openzeppelin/compact-contracts/blob/main/packages/compact/README.md Build the compact-contracts package locally using `yarn build` within the `packages/compact` directory. ```bash yarn build ``` -------------------------------- ### Programmatic Compiler from Arguments Source: https://github.com/openzeppelin/compact-contracts/blob/main/packages/compact/README.md Use the `CompactCompiler.fromArgs` factory method to initialize the compiler by parsing CLI-style arguments. ```typescript // Using factory method (parses CLI-style args) const compiler = CompactCompiler.fromArgs([ '--dir', 'security', '--skip-zk', '+0.29.0' ]); await compiler.compile(); ``` -------------------------------- ### Programmatic Compiler Initialization Source: https://github.com/openzeppelin/compact-contracts/blob/main/packages/compact/README.md Instantiate the `CompactCompiler` programmatically, passing flags, target directory, and toolchain version as arguments. ```typescript import { CompactCompiler } from '@openzeppelin-compact/compact'; const compiler = new CompactCompiler( '--skip-zk', 'security', '0.29.0', ); await compiler.compile(); ``` -------------------------------- ### Combine Compiler Options Source: https://github.com/openzeppelin/compact-contracts/blob/main/packages/compact/README.md Combine multiple `compact-compiler` options, such as specifying a directory and skipping ZK proof generation. ```bash compact-compiler --dir access --skip-zk ``` -------------------------------- ### Builder CLI Source: https://github.com/openzeppelin/compact-contracts/blob/main/packages/compact/README.md Command-line interface for compiling and building Compact smart contracts, including TypeScript compilation and artifact copying. It accepts compiler options but always includes ZK proofs. ```APIDOC ## Builder CLI The builder runs the compiler as a prerequisite, then executes additional build steps: 1. Clean `dist/` directory 2. Compile TypeScript (`tsc --project tsconfig.build.json`) 3. Copy .compact files preserving structure (excludes Mock* files and archive/) 4. Copy package.json and README for distribution ### Usage ```bash compact-builder [options] ``` Accepts all compiler options except `--skip-zk` (builds always include ZK proofs). ### Examples ```bash # Full build compact-builder # Build specific directory compact-builder --dir token # Build specific directory and skip proving key generation compact-builder --dir token --skip-zk ``` -------------------------------- ### Core Concepts: Creating a Base Simulator Source: https://github.com/openzeppelin/compact-contracts/blob/main/packages/simulator/README.md This code defines the base simulator configuration, including types for private state, ledger, witnesses, and constructor arguments. It sets up the contract factory, default private state, argument mapping, ledger extraction, and witness factory. ```typescript import { createSimulator } from '@openzeppelin-compact/contracts-simulator'; import { Contract as MyContract, ledger } from './artifacts/MyContract/contract/index.js'; import { MyContractWitnesses, MyContractPrivateState } from './MyContractWitnesses.js'; // Define contract constructor arguments as a tuple type type MyContractArgs = readonly [arg1: bigint, arg2: string]; // Define the extracted ledger type type MyContractLedger = ReturnType; // Create the base simulator with full type information const MyContractSimulatorBase = createSimulator< MyContractPrivateState, // Private state type ReturnType, // Ledger state type ReturnType, // Witnesses type MyContractArgs // Constructor args type >({ contractFactory: (witnesses) => new MyContract(witnesses), defaultPrivateState: () => MyContractPrivateState.generate(), contractArgs: (arg1, arg2) => [arg1, arg2], ledgerExtractor: (state) => ledger(state), witnessesFactory: () => MyContractWitnesses(), // Note: Must be a function! }); ``` -------------------------------- ### Basic Contract Test Structure with Vitest Source: https://github.com/openzeppelin/compact-contracts/blob/main/packages/simulator/README.md Set up a basic test structure for a contract using Vitest, including importing necessary modules, defining the simulator, and writing a test case for ownership transfer. ```typescript import { encodeCoinPublicKey } from '@midnight-ntwrk/compact-runtime'; import { describe, it, expect, beforeEach } from 'vitest'; import { MyContractSimulator } from './MyContractSimulator'; describe('MyContract', () => { let simulator: MyContractSimulator; let owner = '0'.repeat(63) + '1'; let zOwner = { bytes: encodeCoinPublicKey(owner) }; beforeEach(() => { simulator = new MyContractSimulator( zOwner, { privateState: MyPrivateState.generate() } ); }); it('should transfer ownership', () => { let newOwner = '0'.repeat(63) + '2'; let zNewOwner = { bytes: encodeCoinPublicKey(newOwner) }; simulator.as(owner).transferOwnership(zNewOwner); expect(simulator.getPublicState()._owner).toEqual(zNewOwner); }); }); ``` -------------------------------- ### Compile Custom Contract Source: https://github.com/openzeppelin/compact-contracts/blob/main/README.md Compile your custom Compact contract using the `compact compile` command. Specify the input contract file and the output directory for artifacts. ```bash % compact compile MyContract.compact artifacts/MyContract Compiling 3 circuits: circuit "pause" (k=10, rows=125) circuit "transfer" (k=11, rows=1180) circuit "unpause" (k=10, rows=121) Overall progress [====================] 3/3 ``` -------------------------------- ### Development Test Command Source: https://github.com/openzeppelin/compact-contracts/blob/main/packages/compact/README.md Run the test suite for the compact-contracts package using `yarn test`. ```bash yarn test ``` -------------------------------- ### Compiler CLI Source: https://github.com/openzeppelin/compact-contracts/blob/main/packages/compact/README.md Command-line interface for compiling .compact files to artifacts. Supports options for specifying directories, skipping ZK proofs, and using specific toolchain versions. ```APIDOC ## Compiler CLI ### Usage ```bash compact-compiler [options] ``` ### Options | Option | Description | Default | |---|---|---| | `--dir ` | Compile specific subdirectory within src | (all) | | `--skip-zk` | Skip zero-knowledge proof generation | `false` | | `+` | Use specific toolchain version (e.g., `+0.29.0`) | (default) | ### Environment Variables | Variable | Description | |---|---| | `SKIP_ZK=true` | Equivalent to `--skip-zk` flag | ### Examples ```bash # Compile all contracts (flattened output) compact-compiler # Compile specific directory only compact-compiler --dir security # Skip ZK proof generation (faster, for development) compact-compiler --skip-zk # Use specific toolchain version compact-compiler +0.29.0 # Combine options compact-compiler --dir access --skip-zk # Use environment variable SKIP_ZK=true compact-compiler ``` ``` -------------------------------- ### Use Specific Toolchain Version Source: https://github.com/openzeppelin/compact-contracts/blob/main/packages/compact/README.md Specify a particular version of the Compact toolchain to use for compilation with the `+` syntax. ```bash compact-compiler +0.29.0 ``` -------------------------------- ### Targeted Compilation with Turbo Source: https://github.com/openzeppelin/compact-contracts/blob/main/README.md Compile specific modules of the OpenZeppelin Contracts for Compact library using `turbo` filters. This is useful for faster development cycles. ```bash turbo compact:access turbo compact:archive ``` -------------------------------- ### Simulator Test Directory Structure Source: https://github.com/openzeppelin/compact-contracts/blob/main/packages/simulator/test/README.md This bash snippet shows the directory structure for the simulator tests. ```bash test/ ├── fixtures/ ├── integration/ └── unit/ ``` -------------------------------- ### Clean Project Environment Source: https://github.com/openzeppelin/compact-contracts/blob/main/README.md Remove build artifacts and cached data from the project. These are destructive commands and should be used with caution. ```bash # WARNING! # These are destructive commands turbo clean rm -rf .turbo/ ``` -------------------------------- ### Builder Build Specific Directory Source: https://github.com/openzeppelin/compact-contracts/blob/main/packages/compact/README.md Use the `compact-builder` with the `--dir` option to build only a specific directory. ```bash compact-builder --dir token ``` -------------------------------- ### Format and Lint Code Source: https://github.com/openzeppelin/compact-contracts/blob/main/README.md Apply and check code formatting and linting rules using Biome. Use `turbo fmt-and-lint:fix` to automatically fix issues. ```bash turbo fmt-and-lint turbo fmt-and-lint:fix ``` -------------------------------- ### Development Type-Check Command Source: https://github.com/openzeppelin/compact-contracts/blob/main/packages/compact/README.md Perform a type-check of the compact-contracts package without building using `yarn types`. ```bash yarn types ``` -------------------------------- ### BaseSimulatorOptions Interface Source: https://github.com/openzeppelin/compact-contracts/blob/main/packages/simulator/README.md The `BaseSimulatorOptions` interface defines optional parameters for configuring the simulator, such as initial private state, custom witnesses, coin public key, and contract address. ```typescript interface BaseSimulatorOptions { privateState?: P; // Initial private state witnesses?: W; // Custom witness implementations coinPK?: CoinPublicKey; // Coin public key (default: '0'.repeat(64)) contractAddress?: ContractAddress; // Contract address (default: sampleContractAddress()) } ``` -------------------------------- ### Compact Contract Directory Structure Source: https://github.com/openzeppelin/compact-contracts/blob/main/contracts/README.md Illustrates the standard internal layout for modules within the `src/` directory. Each module contains contract sources, TypeScript witness implementations, and a test suite with mocks and simulators. ```plaintext / ├── .compact # Contract source ├── witnesses/ # TypeScript witness implementations └── test/ ├── .test.ts # Test suite ├── mocks/ # Mock contracts (test-only — see warning below) └── simulators/ # Simulator helpers for testing ``` -------------------------------- ### Development Clean Command Source: https://github.com/openzeppelin/compact-contracts/blob/main/packages/compact/README.md Clean the build artifacts and temporary files for the compact-contracts package using `yarn clean`. ```bash yarn clean ``` -------------------------------- ### Core Simulator Methods Source: https://github.com/openzeppelin/compact-contracts/blob/main/packages/simulator/README.md Key methods for interacting with and controlling the simulated contract environment. These methods allow for simulating different callers, managing caller context, overriding witness functions, and retrieving contract state. ```APIDOC ## Core Methods | Method | Description | |--------|-------------| | `as(caller)` | Execute next operation as specified caller | | `setPersistentCaller(caller)` | Set persistent caller for all operations | | `resetCaller()` | Clears the caller context | | `overrideWitness(key, fn)` | Override a specific witness function | | `getPrivateState()` | Get current private state | | `getPublicState()` | Get current public ledger state | | `getContractState()` | Get full contract state | ``` -------------------------------- ### Programmatic API - CompactCompiler Source: https://github.com/openzeppelin/compact-contracts/blob/main/packages/compact/README.md Programmatic interface for the Compact compiler. Allows instantiation with flags, target directory, and version, and provides methods for compilation and environment validation. ```APIDOC ## Programmatic API The compiler can be used programmatically: ```typescript import { CompactCompiler } from '@openzeppelin-compact/compact'; const compiler = new CompactCompiler( '--skip-zk', 'security', '0.29.0', ); await compiler.compile(); // Using factory method (parses CLI-style args) const compiler = CompactCompiler.fromArgs([ '--dir', 'security', '--skip-zk', '+0.29.0' ]); await compiler.compile(); ``` ### Classes and Types ```typescript // Main compiler class class CompactCompiler { constructor(flags = '', targetDir?: string, version?: string, execFn?: ExecFunction) static fromArgs(args: string[], env?: NodeJS.ProcessEnv): CompactCompiler; compile(): Promise; validateEnvironment(): Promise; } ``` ``` -------------------------------- ### Programmatic API - CompactBuilder Source: https://github.com/openzeppelin/compact-contracts/blob/main/packages/compact/README.md Programmatic interface for the Compact builder, which orchestrates compilation and additional build steps. It can be instantiated with compiler flags. ```APIDOC ### Classes and Types ```typescript // Builder class class CompactBuilder { constructor(compilerFlags = '') build(): Promise; } ``` ``` -------------------------------- ### Switch Node Version with NVM Source: https://github.com/openzeppelin/compact-contracts/blob/main/README.md If you face Node version conflicts, use NVM (Node Version Manager) to switch to the required version for the project. ```bash nvm use ``` -------------------------------- ### Create New Release Branch Source: https://github.com/openzeppelin/compact-contracts/blob/main/RELEASING.md Use this command to create a new branch for the release. This is typically 'main' unless performing a hotfix. ```sh git checkout -b release-v0.2.0 ``` -------------------------------- ### Use Environment Variable to Skip ZK Source: https://github.com/openzeppelin/compact-contracts/blob/main/packages/compact/README.md Alternatively, skip zero-knowledge proof generation by setting the `SKIP_ZK` environment variable to `true`. ```bash SKIP_ZK=true compact-compiler ``` -------------------------------- ### Key Encoding for Contract Parameters Source: https://github.com/openzeppelin/compact-contracts/blob/main/packages/simulator/README.md Differentiate between CoinPublicKey (hex string) for simulator context and ZswapCoinPublicKey (encoded) for contract parameters. Use the correct format for contract interactions. ```typescript // For testing, create mock 64-character hex keys const alice = '0'.repeat(63) + '1'; // CoinPublicKey format const bob = '0'.repeat(63) + '2'; // Encode for contract use const zAlice = { bytes: encodeCoinPublicKey(alice) }; // ZswapCoinPublicKey format const zBob = { bytes: encodeCoinPublicKey(bob) }; // Incorrect - using wrong format for `bob` simulator.as(alice).transfer(bob, 100n); // ❌ Contracts need encoded format // Correct - encoded as ZswapCoinPublicKey simulator.as(alice).transfer(zBob, 100n); // ✅ simulator.as(alice).transferFrom(zAlice, zBob, 100n); // ✅ ``` -------------------------------- ### Core Concepts: Extending the Base Simulator Source: https://github.com/openzeppelin/compact-contracts/blob/main/packages/simulator/README.md This code shows how to extend the base simulator class to create a user-friendly simulator API. It bundles constructor arguments for the parent class and wraps contract circuits with callable methods for easier interaction. ```typescript export class MyContractSimulator extends MyContractSimulatorBase { constructor( arg1: bigint, arg2: string, options: BaseSimulatorOptions< MyContractPrivateState, ReturnType > = {} ) { // Bundle args into tuple for parent class super([arg1, arg2], options); } // Wrap contract's circuits with callable methods public getValue(): bigint { return this.circuits.impure.getValue(); } public setValue(val: bigint): void { this.circuits.impure.setValue(val); } public transfer(to: Uint8Array, amount: bigint): void { this.circuits.impure.transfer(to, amount); } } ``` -------------------------------- ### Skip ZK Proof Generation Source: https://github.com/openzeppelin/compact-contracts/blob/main/packages/compact/README.md For faster development cycles, skip zero-knowledge proof generation during compilation using the `--skip-zk` flag. ```bash compact-compiler --skip-zk ``` -------------------------------- ### Compile Specific Directory Source: https://github.com/openzeppelin/compact-contracts/blob/main/packages/compact/README.md Compile only the `.compact` files within a specified subdirectory using the `--dir` option. ```bash compact-compiler --dir security ``` -------------------------------- ### Witness Factory Pattern: Handling Empty Witnesses Source: https://github.com/openzeppelin/compact-contracts/blob/main/packages/simulator/README.md This snippet illustrates the required pattern for the `witnessesFactory` in the simulator. Even if a Compact contract has no witnesses, the factory must be a function that returns an object, typically an empty object. ```typescript // Some Compact contract examples use: export const MyContractWitnesses = {}; // But for the simulator, wrap it in a generic function: export const MyContractWitnesses = () => ({}); ``` -------------------------------- ### Tag and Push Release Source: https://github.com/openzeppelin/compact-contracts/blob/main/RELEASING.md After merging the release branch and pulling changes, create a Git tag for the release and push it to the main repository. Ensure changes are pulled before tagging to avoid validation failures. ```sh git pull git tag v0.2.0 git push origin v0.2.0 ``` -------------------------------- ### Clean Turbo Cache Source: https://github.com/openzeppelin/compact-contracts/blob/main/README.md Use this command to clean the turbo cache if you encounter issues. It removes the turbo cache directory. ```bash turbo clean && rm -rf .turbo/ ``` -------------------------------- ### Manage Caller Context with Simulator Source: https://github.com/openzeppelin/compact-contracts/blob/main/packages/simulator/README.md Simulate different users interacting with the contract using one-off or persistent caller contexts. Reset the caller context when finished. ```typescript // One-off caller context simulator.as(alice).transfer(zBob, 100n); simulator.as(bob).withdraw(50n); // Persistent caller context simulator.setPersistentCaller(alice); simulator.deposit(100n); // Called by alice simulator.transfer(zBob, 50n); // Called by alice // Reset caller context simulator.resetCaller(); ``` -------------------------------- ### Skip ZK Keys During Compilation Source: https://github.com/openzeppelin/compact-contracts/blob/main/README.md Skip the generation of ZK prover and verifier keys during compilation to speed up development. This can be done via a filter or an environment variable. ```bash # Individual module compilation (recommended for development) turbo compact:token --filter=@openzeppelin/compact-contracts -- --skip-zk # Full compilation with skip-zk (use environment variable) SKIP_ZK=true turbo compact ``` -------------------------------- ### Import Compact Error Types Source: https://github.com/openzeppelin/compact-contracts/blob/main/packages/compact/README.md Import specific error types from the `@openzeppelin-compact/compact` package to handle potential issues during compilation or environment validation. ```typescript import { CompactCliNotFoundError, // Compact CLI not in PATH CompilationError, // Compilation failed (includes file path) DirectoryNotFoundError, // Target directory doesn't exist } from '@openzeppelin-compact/compact'; ``` -------------------------------- ### Error Types Source: https://github.com/openzeppelin/compact-contracts/blob/main/packages/compact/README.md Importable error types for handling specific issues within the Compact compiler and builder, such as CLI not found, compilation failures, or directory errors. ```APIDOC ### Error Types ```typescript import { CompactCliNotFoundError, // Compact CLI not in PATH CompilationError, // Compilation failed (includes file path) DirectoryNotFoundError, // Target directory doesn't exist } from '@openzeppelin-compact/compact'; ``` ``` -------------------------------- ### Test Multi-User Token Transfers Source: https://github.com/openzeppelin/compact-contracts/blob/main/packages/simulator/README.md Simulate multi-user token transfers to verify balance updates and inter-user transactions. This test case covers deposits and transfers between different users. ```typescript it('should handle multi-user token transfers', () => { // PKs const alice = '0'.repeat(63) + '1'; const zAlice = { bytes: encodeCoinPublicKey(alice) }; const bob = '0'.repeat(63) + '2'; const zBob = { bytes: encodeCoinPublicKey(bob) }; const charlie = '0'.repeat(63) + '3'; const zCharlie = { bytes: encodeCoinPublicKey(charlie) }; // Alice deposits simulator.as(alice).deposit(1000n); // Alice transfers to Bob simulator.as(alice).transfer(zBob, 300n); // Bob transfers to Charlie simulator.as(bob).transfer(zCharlie, 100n); const state = simulator.getPublicState(); expect(state._balances.lookup(zAlice)).toBe(700n); expect(state._balances.lookup(zBob)).toBe(200n); expect(state._balances.lookup(zCharlie)).toBe(100n); }); ``` -------------------------------- ### Define Contract with No Constructor Arguments Source: https://github.com/openzeppelin/compact-contracts/blob/main/packages/simulator/README.md Use `createSimulator` with an empty tuple type for `NoArgs` and an empty array for `contractArgs` when defining a contract that takes no constructor arguments. ```typescript type NoArgs = readonly []; const SimpleSimulatorBase = createSimulator< SimplePrivateState, ReturnType, ReturnType, NoArgs // Empty tuple for no arguments >({ contractFactory: (witnesses) => new SimpleContract(witnesses), defaultPrivateState: () => SimplePrivateState.generate(), contractArgs: () => [], // Return empty array ledgerExtractor: (state) => ledger(state), witnessesFactory: () => SimpleWitnesses(), }); export class SimpleSimulator extends SimpleSimulatorBase { constructor(options: BaseSimulatorOptions<...> = {}) { super([], options); // Pass empty array } } ``` -------------------------------- ### Push Release Branch Source: https://github.com/openzeppelin/compact-contracts/blob/main/RELEASING.md Push the newly created release branch to the remote repository to trigger CI/CD workflows for version bumping. ```sh git push origin release-v0.2.0 ``` -------------------------------- ### Inspect Contract State Source: https://github.com/openzeppelin/compact-contracts/blob/main/packages/simulator/README.md Access different levels of contract state, including private state, public ledger state, and the complete contract state. Also access the full circuit context. ```typescript // Get private state const privateState = simulator.getPrivateState(); console.log('Secret value:', privateState.secretValue); // Get public ledger state const ledgerState = simulator.getPublicState(); console.log('Public state:', ledgerState); // Get full contract state const contractState = simulator.getContractState(); // Access complete circuit context const context = simulator.circuitContext; console.log('Zswap inputs', context.currentZswapLocalState.inputs); ``` -------------------------------- ### Override Witness for Deterministic Testing Source: https://github.com/openzeppelin/compact-contracts/blob/main/packages/simulator/README.md Override witness functions with fixed values for deterministic testing or to track witness calls. This is useful for testing edge cases and ensuring predictable behavior. ```typescript // Override with fixed value for deterministic testing const fixedNonce = new Uint8Array(32).fill(42); simulator.overrideWitness('secretNonce', (context) => { return [context.privateState, fixedNonce]; }); // Track witness calls let callCount = 0; simulator.overrideWitness('secretValue', (context) => { callCount++; return [context.privateState, context.privateState.secretValue]; }); simulator.someOperation(); console.log(`Witness called ${callCount} times`); // Test error conditions simulator.overrideWitness('requiredValue', (context) => { return [context.privateState, null]; // Return invalid data }); ``` -------------------------------- ### Test Witness Overrides with Custom Behavior Source: https://github.com/openzeppelin/compact-contracts/blob/main/packages/simulator/README.md Test custom witness behavior by overriding a witness function and asserting that it was called with specific logic. This verifies the correct execution of custom witness logic. ```typescript it('should handle custom witness behavior', () => { const customValue = new Uint8Array(32).fill(99); let wasCalled = false; simulator.overrideWitness('secretValue', (context) => { wasCalled = true; return [context.privateState, customValue]; }); simulator.performOperation(); expect(wasCalled).toBe(true); }); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.