Nightfall APIs - The Nf3 class

The Nodejs and Javascript API for Nightfall

The Nf3 class is by far the easiest way to interact with a Nightfall node from either an Nodejs or Javascript app. The major methods in this class appear throughout this book, but a complete API description is given here as a JSDoc and some are further detailed in this chapter:

Nf3 is a bit of a Swiss Army Knife and it contains APIs for all of the Nightfall actors. Therefore, depending on which actor is being supported, only some of the objects methods will be needed. The most widely used ones are these:

Object construction and initialisation

An Nf3 object requires some asynchronous processes to run before it is fully initialised. It is an anti-pattern to put asyncs in an object's constructor and so the creating an Nf3 object is a two step process:

Construction

const nf3 = new Nf3
(
    ethereumSigningKey,
    environment = {
      clientApiUrl: 'http://localhost:8080',
      optimistApiUrl: 'http://localhost:8081',
      optimistWsUrl: 'ws://localhost:8082',
      web3WsUrl: 'ws://localhost:8546',
    },
    zkpKeys,
    clientApiAuthenticationKey,
  );

Where:

  • ethereumSigningKey is a hex string containing the Ethereum signing key (private key) of the actor who will use the object.

  • environment contains the URLs for the APIs of the various Nightfall containers that nf3 will communicate with. These are not necessarily all needed for every actor. For example a User will only interact with the Client container and the blockchain. Therefore they do not need to set the Optimist URLs (although there is no harm in so doing).

  • zkpKeys is an object of class ZkpKeys, containing the Users zkp keys. These can be set later via the setZkpKeys method if they are not know at the point of construction and can be generated by calling the Client container's generateZkpKeys endpoint or, more conveniently when the nf3 object is initialised, which will both generate them from a BIP39 mnemonic and set them in the nf3 object.

  • clientApiAuthenticationKey this can be set if any of the nightfall containers is using an API key. This is optional and a configurable item (see the chapter on configuring).

Initialisation

After construction, some async tasks need to be run to initialise the nf3 object. Once that is done, it is ready for use.

await nf3.init(mnemonic, contractAddressProvider);

Where:

  • mnemonic is a BIP39 mnemonic, use to generate a User's zkp keys. It can be left undefined if the keys are already set at construction or will be set later using the setZkpKeys method. It is not needed for a Proposer or Challenger and can also be left undefined in these cases.

  • contractAddressProvider : The nf3 object needs find the address and ABI of Nightfall's deployed contracts, so that it interact with them. Both the Client and Optimist containers have an endpoint for this purpose. This string is used to select which of the two possibilities nf3 should use. Either 'client' or 'optimist' are acceptable values. For example, a User may have no connection to an Optimist and so would choose 'client'. Similarly a Proposer would probably choose 'optimist'.

User Methods

The main methods of interest to the User are covered in the Basic Nightfall Workflow page.

[ToDo add more methods]

Proposer Methods

A Proposer must be registered with the Nightfall contracts and, as part of the registration, pay a redeemable staking fee before they can submit Layer 2 blocks to Nightfall. This is currently 20kMatic on Polygon PoS and 1MWei on Mumbai. The registration Operation also connects the Proposer to its Optimist container via a websocket. Optimist will use this websocket to send assembled blocks, embedded in proposeBlock transactions, to the Proposer, which it can then sign and send to the blockchain.

await nf3.registerProposer(url, stake, fee);

Where:

  • url is the URL on which the Proposer will listed for Nightfall transactions that are sent directly to it (Transfer and Withdraw; this won't work with Deposit) to avoid Gas fees.

  • stake The amount of stake it is going to pay. This must be at least the minimum amount set for the blockchain in question (see above). Paying more buys more time slots in which the Proposer can make blocks. Make sure there is enough in the Proposer's account to pay the stake.

  • fee This is the amount that the Proposer charges for incorporating a transaction into a block.

After the Proposer is registered, Nf3 can be used to start listening on its websocket for blocks to Propose:

await nf3.startProposer();

This method will start listening for layer 2 blocks, and will send them to the blockchain via a proposeBlock function call in State.sol.

The above method returns an event emitter which will emit a transaction receipt event for each transaction, a rollback event for any rollbacks that occur and an error event for any errors.

Challenger methods

There is no need to register Challengers because anyone can challenge and there is no need to stake. It's very much a case of the more the merrier. This means we can just start up a challenger and it will automatically listen for challenges coming from its Optimist, sign the challenge transactions and send them to the blockchain. Don't forget to give the Challener enough funds so that it can afford to raise challenges.

await nf3.startChallenger();

Last updated