This repository contains the code for the NEAR MPC node that powers Chain Signatures.
There are two main parts of the binary: NEAR indexer and MPC signing.
The indexer is a NEAR node that tracks the shard where the signing smart contract lives (for mainnet, v1.signer). See the indexer design doc for details. It monitors incoming requests by looking at successful calls to the sign function. Each request is hashed and mapped to a specific node in the MPC network — the leader for that request. The leader initiates the signing process and submits the final signature back to the smart contract. If the leader is offline, a secondary leader can take over.
The node supports multiple threshold signature schemes, organized into domains. Each domain has a unique ID, a signature scheme, and a purpose (signing, foreign-chain transactions, or confidential key derivation). All schemes share the same FROST-based distributed key generation (DKG) but differ in their signing workflows.
OT-based ECDSA (Secp256k1) — Originally derived from Cait-Sith. Uses an offline phase with two protocols:
- Triple generation: runs continuously in the background (target: up to 1M Beaver triples per node).
- Presignature generation: also runs in the background; each presignature consumes two triples.
- Signing: one round of communication using a presignature.
Robust ECDSA (Secp256k1) — Based on DJNPO20. Skips triple generation entirely:
- Presignature generation: a single 3-round protocol using degree-2t polynomials.
- Signing: one round, same as OT-based ECDSA.
EdDSA (Ed25519) — Based on FROST threshold signatures:
- Presignature generation: participants exchange nonce commitments.
- Signing: one round using a presignature.
For each scheme, the participating set is fixed from the offline phase through to signature generation: if a presignature is generated by a specific set of participants, the resulting signature uses the same set.
Confidential Key Derivation (BLS12-381) — Derives application-specific keys without revealing the master secret. Takes an application ID and produces a derived key using oblivious transfer and Diffie-Hellman.
Foreign chain transaction verification — The network can verify transactions on foreign chains (Ethereum, Solana, Bitcoin, etc.) before signing. Nodes independently query configured RPC providers, run deterministic extractors over the results, and produce a threshold signature over the observed values. This enables NEAR contracts to react to external chain events without a trusted relayer. See docs/foreign-chain-transactions.md for the full design.
MPC nodes can run inside a trusted execution environment (TEE). For more details, see the TEE design doc.
All crates are organized in a Cargo workspace under crates/.
- Nearcore Node: Included as a submodule in
/libs, used only for system tests (pytest). Not required for building the node or contract. - Other Dependencies: All other dependencies are handled by Cargo.
A Nix flake provides a reproducible development environment with the Rust toolchain, LLVM/Clang, NEAR CLI, and all system dependencies pre-configured. Run nix develop to enter the shell.
For setup details (direnv integration, VS Code config, verification), see docs/nix-dev-environment.md.
Build the MPC node:
cargo build -p mpc-node --releaseBuild the smart contract:
cargo near build non-reproducible-wasm --features abi --profile=release-contract \
--manifest-path crates/contract/Cargo.toml --lockedThe Rust toolchain version is pinned in rust-toolchain.toml; rustup handles installation automatically.
We use the following terminology when referring to tests:
- unit test -> a rust test in
/srcfolder (per crate) - integration test -> a rust test in
/testsfolder (per crate) - system test -> a pytest in the
/pytestfolder
- Unit and integration tests: Run with
cargo nextest run --cargo-profile=test-release - System tests: See the README in the
/pytestdirectory.
Both the node and launcher Docker images support reproducible builds, ensuring identical binaries from the same source. Run ./deployment/build-images.sh from the project root.
For prerequisites and options, see docs/reproducible-builds.md.
This project follows a standard release process with semantic versioning. Each release includes both the MPC node binary and the chain signatures contract as a single bundle.
For detailed information about our release process, compatibility guarantees, and procedures, see RELEASES.md.
Key Release Principles:
- Releases are created from the
mainbranch using semantic versioning. - Minor versions maintain backward compatibility with previous node versions.
- Major versions ensure contract compatibility with the previous major version.
We welcome contributions in the form of issues, feature requests, and pull requests. Please ensure any changes are well-documented and tested. For major changes, open an issue to discuss the proposed modifications first.
We run several checks in CI that require tools beyond the default Rust toolchain. The nix environment installs all of them automatically.
cargo-makecargo-nextestcargo-sortcargo-shearcargo-denyzizmorrufflycheepython(3.11) withtree-sitterandtree-sitter-rust
This set does not include all checks, but only the most common reasons for CI
failures. Therefore, we suggest running these checks locally before opening a
PR. Running these checks with the correct parameters can be done easily with
cargo-make.
Running fast checks:
cargo make check-all-fastRunning all cargo-make supported checks:
cargo make check-all