o1js Documentation

repository·main·Indexed 20 days ago

https://github.com/o1-labs/o1js

A TypeScript framework for zk-SNARKs and zkApps that enables developers to build applications powered by zero-knowledge cryptography. It supports writing, proving, and verifying zk circuits in Node.js and browser environments, with specialized support for the Mina Protocol. The library includes the ZkFunction and ZkProgram APIs for circuit creation, a multi-layered binding architecture connecting TypeScript to Rust and OCaml, and the mina-signer SDK for signing messages, payments, and delegations.

Tokens
16.4K
Snippets
56
Records
82
Agent score
70%

What's inside o1js

  1. Explore crypto primitives in o1js

    main

    The src/examples/crypto/ directory contains implementation examples for advanced cryptographic primitives that can be used within provable o1js code. These examples demonstrate how to handle operations that fall outside the standard field arithmetic of the Mina blockchain.

    Available examples include:

    • Non-native field arithmetic: Using foreign-field.ts to perform arithmetic on fields other than the native Mina field.
    • Non-native ECDSA verification: Using ecdsa.ts to verify Elliptic Curve Digital Signature Algorithm signatures.
    • Provable big integer arithmetic: Using bigint.ts for arithmetic involving large integers.
    • RSA signature verification: A low-level implementation found in the rsa/ directory, which utilizes a custom bigint type optimized with efficient o1js range checks.
  2. Optimize Nix storage and runtime

    main

    Nix can consume significant disk space because nix develop creates new generations. Use these strategies to manage storage:

    Storage Management

    • Enable Auto-optimise: It is recommended to set auto-optimise-store = true in your Nix configuration. This replaces duplicate files with symlinks.
    • Manual Optimization: Run nix-store --optimize to clean up the store retroactively.
    • Garbage Collection: Run nix-store --gc to free space. To prevent the GC from removing essential dev-shell roots, consider using direnv and nix-direnv.

    Runtime Optimization

    When using the project's flake.nix, you can accept optimized settings (like max-jobs = auto and mina-nix-cache usage) by using the following flag:

    nix develop o1js#default --accept-flake-config
  3. Understand the o1js bindings architecture

    main

    o1js uses a multi-layered binding architecture to connect high-level TypeScript code to lower-level proof systems and transaction logic written in Rust and OCaml.

    Key components include:

    • Compiled Artifacts (/compiled): JS and Wasm files generated via js_of_ocaml (from OCaml) and wasm-bindgen (from Rust). These allow developers to use o1js with standard JS tooling without needing a full OCaml/Rust build environment.
    • Crypto Primitives (/crypto): Pure TypeScript implementations of finite field and elliptic curve arithmetic, used by packages like mina-signer for hashing and signing.
    • JS Wrappers (/js): Environment-specific wrappers (Node.js vs. Web) for the compiled artifacts, including worker management for Rust rayon support.
    • Core Logic (/lib): Low-level TypeScript that provides generic interfaces for proof systems and blockchain protocols.
    • Mina Protocol Specialization (/mina-transaction): TypeScript modules and types specialized for the Mina zkApp protocol, largely auto-generated from OCaml.
    • OCaml Integration (/ocaml): The OCaml library that exposes Snarky, Pickles, and Mina transaction logic to JavaScript, along with scripts for TypeScript auto-generation.
  4. Use ZkProgram to create proofs outside of smart contracts

    main
    The ZkProgram API is the primary interface in o1js for generating zero-knowledge proofs for general-purpose computations that occur outside the context of a Mina smart contract. While smart contracts are used for stateful logic on-chain, ZkProgram allows you to execute arbitrary logic and produce a proof of correctness that can later be verified.
  5. Understanding the difference between ZkFunction and ZkProgram

    main

    In o1js, you can choose between two primary abstractions for writing circuits: ZkFunction and ZkProgram.

    • ZkFunction: A simple API designed to write a single circuit and create proofs for it. It uses Kimchi directly without passing through Pickles. This makes it much faster than ZkProgram, but it does not support recursion.
    • ZkProgram: A more complex abstraction that uses Pickles. It supports recursion but is slower than ZkFunction.

    Important Compatibility Note: Proofs generated using ZkFunction are not compatible with Mina zkApps.

  6. How to use hash functions in o1js

    main

    Hash functions in o1js are located under the Hash namespace. These functions operate over binary data and require binary arithmetic. To use them effectively, you may need to extend the Bytes class to specify the required length of the byte arrays being hashed.

    For specific implementations, refer to the documentation for:

    • Keccak
    • SHA-256
  7. Build o1js using Nix

    main

    o1js uses the Nix registry to manage git submodules. You can enter a development shell that provides all dependencies required for npm scripts (including npm run build:bindings-all) using one of the following methods:

    • Run ./pin.sh and then nix develop o1js#default
    • Use direnv with the provided .envrc file.
  8. Enable Nix Flakes (recommended)

    main

    The project uses Nix Flakes for packaging. It is highly recommended to enable flakes for better performance and convenience. Ensure you are running Nix $\geqslant$ 2.5.

    To enable flakes, create or update your nix.conf file (preferably in your user config directory) with the following line:

    mkdir -p "${XDG_CONFIG_HOME-${HOME}/.config}/nix"
    echo 'experimental-features = nix-command flakes' > "${XDG_CONFIG_HOME-${HOME}/.config}/nix/nix.conf"

    Verify flake support is active by running:

    nix flake metadata github:nixos/nixpkgs
    mkdir -p "${XDG_CONFIG_HOME-${HOME}/.config}/nix"
    echo 'experimental-features = nix-command flakes' > "${XDG_CONFIG_HOME-${HOME}/.config}/nix/nix.conf"
  9. Profile o1js and zkApps using Chrome Debugger

    main

    To optimize performance or profile your zkApp, you can use the Chrome Debugger with Node.js.

    Use the provided run-debug script, which starts a Node.js process with the --inspect-brk flag (pausing execution until a debugger is attached) and --enable-source-maps (allowing you to debug o1js code directly).

    Steps:

    1. Run the script: ./run-debug <path-to-your-zkapp> --bundle.
    2. Open Chrome and navigate to chrome://inspect.
    3. Attach the Chrome Debugger to the Node.js process to set breakpoints, inspect variables, and profile performance.
    ./run-debug <path-to-your-zkapp> --bundle
  10. Run o1js tests

    main

    The project includes unit, integration, and end-to-end tests.

    Unit and Integration Tests

    • Standard test suite: npm run test or npm run test:unit.
    • Integration tests: npm run test:integration.
    • Individual Jest tests: ./jest <path/to/test.ts>.

    Special Requirements

    • mina-signer tests: You must build from inside the src/mina-signer directory first:
      cd src/mina-signer
      npm run build
      cd ../..
      npm run test

    End-to-End (E2E) Browser Tests

    E2E tests are not run by default. To run them:

    npm install
    npm run e2e:install
    npm run build:web
    npm run e2e:prepare-server
    npm run test:e2e
    npm run e2e:show-report
    npm run test
  11. How to handle binding artifacts for internal contributors

    main

    Internal contributors with an open PR can use npm run build:bindings-download on any commit where CI has run (or is currently running). If CI is in progress, the command uses gh run watch to monitor progress.

    If you encounter a merge conflict where CI does not run on every new commit, use:

    npm run build:bindings-remote

    This triggers a self-hosted runner to build the bindings for your specific commit and downloads them once finished.