Running a light-weight GUI

Useful for trying Nightfall's API

Note: the GUI is yet to be merged into master. Currently you can access it in this PR. That should change quite soon.

Nightfall does not support a production-grade GUI. Nightfall is designed for enterprise solutions, where the integration point is its APIs, for example integrating with an ERP solution.

However, it is sometimes useful to be able to exercise the APIs for test and demonstration purposes. Nightfall does ship with a light-weight GUI for this purpose. Please bear in mind that this UI is not intended for any form of serious use, certainly not in production. It is a very light wrapper around Nightfall's endpoints. It only supports ERC20 tokens, although Nightfall itself natively handles ERC721 and ERC1155 contracts too. If you do something wrong, expect the GUI to error and not always handle the error. We may improve that in the future but this isn't intended to be a fully-fledged application.

This page shows you how to use it.

Before you start, make sure you have managed to stand up a locally running instance of Nightfall. These instruction focus on running locally with a mocked ERC20 contract, but it's equally possible to use it against a real ERC20 contract and Nightfall instance deployed on either Mumbai or Polygon PoS (although if you are using this against Polygon PoS you should probably read the last couple of paragraphs again).

Finally, a fairly obvious security note: we've given you some test keys and mnemonics for use with a local Ganache instance below. Don't reuse these anywhere else because everybody knows them!

Set up Metamask

We'll assume you know your way around Metamask; the details are really out of scope for this discussion.

Metamask will do the transaction signing for you. It can self-configure for Mumbai and Polygon PoS but for running against a local Ganache instance, you'll need to set up a configuration that looks like this:

You should also import two test accounts. These will automatically be funded by the Ganache instance you are about to run up. The private keys are below. If you re going to run on Mumbai or Polygon PoS you'll need to provide your own accounts!

  • 4775af73d6dc84a0ae76f8726bda4b9ecf187c377229cb39e1afa7a18236a69e

  • abf4ed9f30bd1e4a290310d726c7bbdf39cd75a25eebd9a3a4874e10b4a0c4ce

Use the first account with user1 below and the second with user2. Only the user1 account starts with any funds if you are running locally.

Run up Nightfall locally

Now we'll get Nightfall running so that we can connect to it's APIs:

export NF_SERVICES_TO_START='client,blockchain,optimist,worker,deployer'
bin/setup-nightfall # This isn't needed if you have already built your container images
bin/start-nightfall -g -d

Wait a few minutes for it to start. It's done when the logging output pauses and you see:

nightfall_3-deployer-1 exited with code 0

If you see anything else, check back through the logs to see what went wrong and fix it before proceeding.

Next you need to start a Proposer application. The Proposer will sign Layer 2 block transactions that the Optimist container makes and send them to the blockchain. We'll use the default Proposer application that comes with Nightfall. Start it in a new terminal at the root of the Nightfall repo:

npm run start-proposer

This will start, register itself with the Optimist container, and begin listening for blocks. You'll see it output the same logging line continuously; it's checking to see if it is the current Proposer or not:

nightfall_3-proposer-1  | [2023-05-04 10:14:35.878] INFO: Checking Proposer...

Start the GUI

In another terminal, at the root of the Nightfall repo, execute the following commands to start the UI:

cd demo-ui
npm ci
npm start

This will start the GUI webpage in your browser (it takes a minute or so):

At this point open up Metamask and connect your accounts to the page. Make sure you have the correct network selected (nightfall-localhost if you are running locally).

Now enter the ERC20 contract address that you wish to interact with. If you are running locally, with Ganache started with the start-nightfall script as above, the address should be 0x4315287906f3fcf2345ad1bfe0f682457b041fa7but check it by scrolling through the logs to see where the ERC20Mock contract was deployed. We've noticed that it is sometimes different, even though Ganache is set to be deterministic. If it is different (e.g. 0x002...) then use that address instead.

Hit the configure button.

This will take you to the next page, where you can set up some test users. If you have any trouble, try refreshing the page and re-entering the ERC20 address.

It's best to make two users so that you can transfer tokens between them. Call them user1 and user2 (it doesn't actually matter what you call them).

Using Metamask, select the account that you wish to use for user1 (if running locally, this should be 0x9C8B2276D490141Ae1440Da660E470E7C0349C63because that is the only one that has any ERC20 tokens in it.

Enter user1 as the username and then enter a bip39 mnemonic which will be used to generate user1's ZKP keys. This will work (only use this for a local test or someone may steal your money!):

trip differ bamboo bundle bonus luxury strike mad merry muffin nose auction

Switch to another account in Metamask and then do the same for user2:

control series album tribe category saddle prosper enforce moon eternal talk fame

Once this is done, you should see the accounts with their Layer 1 balances to the right of the screen:

Switch back to the user1 account and make sure it has the green connection symbol next to it.

Creating transactions


Now we can use Nightfall to create transactions. Note that we have no Layer 2 funds at the moment. Thus we need to create a deposit transaction, two actually:

Click the deposit button on the left to select the deposit transaction type, then enter the amount. This must be more than 10 because the proposer will take that as a fee and then your transaction won't go through. A number like 1000 is good; you have plenty of pretend money.

Click the deposit button below the value you entered. It takes a few moments but then Metamask will pop up to ask you to approve Nightfall to take money from your account. Approve an amount that is at least equal to your deposit value, preferably much more so you don't need to approve again.

Nightfall will then take the payment from your ERC20 balance and create a Deposit transaction. Metamask will ask you to confirm the transaction.

Make another deposit. It's best to have two so that the transfer circuit can work (more detail on this in the How Nightfall Works section. You can make more if you wish, but there's no particular need.

At this point we have two deposit transaction posted on-chain. However, as yet, they're not incorporated into a Layer 2 block. We can force Nightfall to do that by pressing the Make Block Now button (normally it would wait for more transactions).

Give it a moment and you should see the block created in the log output, and the Layer 2 balance will update to show your deposits. If nothing appears to happen, re-fetch the Layer 2 balances with the Fetch Balances button


Now that we have assets in Layer 2, we can transfer them to someone else (we can also transfer them to ourselves, and there is utility in doing so; it ensures that a sender no longer has information on the commitments you own). Try transferring to user2. The process should be self-evident but there are a couple of points to note:

  • When you select user2 as the recipient, it's actually their ZKP public key that is being used to identify them.

  • You cannot transfer more than the total amount in your two commitments. This is fundamental to the way that the transfer circuit works. Nightfall uses an algorithm to select the most suitable input commitments for a transfer if you have more than two. It tries to minimise the number of small 'change' commitments that you accrue.

  • When you create a Layer 2 block, the transfer will proceed and user2 will get the amount that you sent; any change will be sent to you as a change commitment.


The withdraw is similar and you should be able to create a Withdraw transaction in the same way as Deposit and Transfer. The only thing to note is that you will not be able to finalise your Withdraw (recover your funds into Layer 1) for a week. This is to provide time for a challenge of an incorrect Layer 2 block and is a consequence of the Optimistic rollup. This limitation can be removed by using a Liquidity Provider (see Nightfall's Actors) but the simple GUI does not support that functionality.

Last updated