Dependencies
Nargo allows you to upload packages to GitHub and use them as dependencies.
Specifying a dependency
Specifying a dependency requires a tag
to a specific commit and a git
url to the url containing the package.
Without a tag
, there would be no versioning and dependencies would change each time you compile your project.
For example, to add the bignum library to your project, add it to Nargo.toml:
# Nargo.toml
[dependencies]
bignum = { tag = "v0.8.0", git = "https://github.com/noir-lang/noir-bignum" }
If the module is in a subdirectory, you can define a subdirectory in your git repository, for example:
# Nargo.toml
[dependencies]
blob = {tag ="v1.2.1", git = "https://github.com/AztecProtocol/aztec-packages", directory = "noir-projects/noir-protocol-circuits/crates/blob"}
Currently, there are no requirements applied on the contents of tag
. Requirements based on semver 2.0 guidelines could be introduced in the future.
Specifying a local dependency
You can also specify dependencies that are local to your machine.
For example, this file structure has a library and binary crate
├── binary_crate
│ ├── Nargo.toml
│ └── src
│ └── main.nr
└── lib_a
├── Nargo.toml
└── src
└── lib.nr
Inside of the binary crate, you can specify:
# Nargo.toml
[dependencies]
lib_a = { path = "../lib_a" }
Importing dependencies
You can import a dependency to a Noir file using the following syntax. For example, to import the ecrecover-noir library and local lib_a referenced above:
use ecrecover;
use lib_a;
You can also import only the specific parts of dependency that you want to use, like so:
use std::hash::blake3;
use std::scalar_mul::fixed_base_embedded_curve;
Lastly, You can import multiple items in the same line by enclosing them in curly braces:
use std::hash::{blake2s, blake3};
We don't have a way to consume libraries from inside a workspace as external dependencies right now.
Inside a workspace, these are consumed as { path = "../to_lib" }
dependencies in Nargo.toml.
Dependencies of Dependencies
Note that when you import a dependency, you also get access to all of the dependencies of that package.
For example, the phy_vector library imports an fraction library. If you're importing the phy_vector library, then you can access the functions in fractions library like so:
use phy_vector;
fn main(x : Field, y : pub Field) {
//...
let f = phy_vector::fraction::toFraction(true, 2, 1);
//...
}
Available Libraries
Noir does not currently have an official package manager. You can find a list of available Noir libraries in the awesome-noir repo here.
Some libraries that are available today include:
- Standard Library - the Noir Standard Library
- Ethereum Storage Proof Verification - a library that contains the primitives necessary for RLP decoding (in the form of look-up table construction) and Ethereum state and storage proof verification (or verification of any trie proof involving 32-byte long keys)
- BigInt - a library that provides a custom BigUint56 data type, allowing for computations on large unsigned integers
- ECrecover - a library to verify an ECDSA signature and return the source Ethereum address
- Sparse Merkle Tree Verifier - a library for verification of sparse Merkle trees
- Signed Int - a library for accessing a custom Signed Integer data type, allowing access to negative numbers on Noir
- Fraction - a library for accessing fractional number data type in Noir, allowing results that aren't whole numbers