Quickstart
To start using NEBRA UPA in your application you'll need to
Submit proofs to the UPA from your app Submitting Proofs to UPA
Query the UPA contract Querying the UPA Contract
Modify your deployment Deployment
Set up a UPA-enabled test environment Test Environment
This guide will take you through those steps, using our SDK. Here we keep the code concise and just stub out the main ideas. For a working example, check out our Demo app.
Submitting Proofs to UPA
Your app will submit proof to the UPA using our SDK. Add it to your project with
If you're using SnarkJS to generate Groth16 proofs, then your app may look something like this:
In this example, your application's smart contract verifies proofs on-chain. Let's see how to save on gas using NEBRA's UPA:
We've used the UpaClient from the SDK to
Submit the proof to the UPA smart contract using
upaClient.submitProofs.awaitwhile the UPA aggregates the proof usingupaClient.waitForProofVerified
Note that the proof is only submitted to the UPA contract. It is no longer part of your app's transaction calldata. Instead, your app now queries the UPA contract for the verification result.
Querying the UPA Contract
Prior to using NEBRA's UPA, your app has an on-chain contract that verifies Groth16 proofs and executes some business logic.
If you're using SnarkJS, it may look something like this:
As you know, verifying with this.verifyProof is expensive. Let's instead query the UPA contract. We need
A reference to the UPA contract (See Deployments)
Your application's
circuitId(computed with SDK below)
We'll add those data to your contract's state. Then we'll query the UPA contract instead of verifying proofs directly.
Congratulations, you are now saving gas. 🎉
Deployment
Above we added two things to your smart contract's state:
upaContractinterface to the UPAcircuitIdidentifying your app's verification key to the UPA
You'll need to supply that information when deploying your new contract. The circuitId will be computed below using our SDK and the latest UPA contract deployment can be found in Deployments.
The deployment may look something like this
Here the upaInstanceFile is a JSON file containing the UPA contract address, as well as its deployment's transaction id and block number
The latest deployment information: Deployments
To summarize, your app now deploys using
upaContract: A reference to NEBRA's UPA deployment, loaded from filecircuitId: An app identifier, computed from your app's VK
Register App
The UPA only accepts proofs from registered verification keys. Registration is permissionless. You'll use one of the two methods demonstrated in Registering applications
Test Environment
The basic ingredients of a UPA-enabled test environment are a
Local test network (we'll use a Hardhat node)
UPA contract deployment
Dev Aggregator
The Dev Aggregator simulates NEBRA's off-chain worker. It monitors the local testnet for proof submissions and produces aggregated proofs. Without this running you could still submit proofs to the UPA contract, but they would never be marked as verified.
The UPA contract is deployed with the upa tool
and the Dev Aggregator is then deployed with
For more complete instructions, see Testing workflow.
Congrats, you're up and running!
If you need to see anything we did here in more detail, go check out our Demo App.
Last updated
Was this helpful?

