Skip to content

0xSpaceShard/starknet-devnet-js

Repository files navigation

npm package

Introduction

Using this JavaScript/TypeScript library, you can spawn Starknet Devnet without installing and running it in a separate terminal. You can interact with it via its specific Devnet API. To interact with any Starknet node or network (including Starknet Devnet) via the Starknet JSON-RPC API, see starknet.js.

Installation

npm i starknet-devnet

Compatibility

Devnet compatibility

This library version is compatible with Devnet v0.2.2.

Devnet's balance checking functionality is not provided in this library because it is simply replaceable using starknet.js, as witnessed by the getAccountBalance function.

Environment compatibility

This library is intended for use with Node.js, not in a browser environment. In browsers, you can only use DevnetProvider for connecting to an already running Devnet instance, but you cannot spawn a new Devnet, because that relies on modules not present in the browser engine.

To enable the use of DevnetProvider in browser, you need to configure sources for modules otherwise reported as not found. See this issue and this SO answer for more info, but generally, if using webpack, it should be enough to populate a config file with the desired polyfill implementations or with false values.

Usage

Spawn a new Devnet

This library allows you to spawn a Devnet instance inside your program, without a separate terminal. It finds a random free port, and releases all used resources on exit. You can specify a port of your choice via args: ["--port", ...].

Spawn a version without manual installation

Assuming your machine has a supported OS (macOS or Linux) and supported architecture (arm64/aarch64 or x64/x86_64), using Devnet.spawnVersion will quickly install and spawn a new Devnet.

import { Devnet } from "starknet-devnet";

async function main() {
    // Specify anything from https://github.com/0xSpaceShard/starknet-devnet-rs/releases
    // Be sure to include the 'v' if it's in the version name.
    const devnet = await Devnet.spawnVersion("v0.2.2");
    console.log(await devnet.provider.isAlive()); // true
}

To use the latest compatible version:

const devnet = await Devnet.spawnVersion("latest");

Spawn an already installed Devnet

Assuming you have already installed Devnet and it is present in your environment's PATH, simply run:

const devnet = await Devnet.spawnInstalled();

Specify Devnet arguments

You can use the same CLI arguments you would pass to a Devnet running in a terminal:

const devnet = await Devnet.spawnInstalled({ args: ["--predeployed-accounts", "3"] });

Devnet output

By default, the spawned Devnet inherits the output streams of the main program in which it is invoked. If you invoke your program in a terminal without any stream redirections, it will print Devnet logs in that same terminal together with your program output. This can be overriden:

const outputStream = fs.createWriteStream("devnet-out.txt");
await events.once(outputStream, "open"); // necessary if specifying a --port, otherwise omissible
const devnet = await Devnet.spawnInstalled({
    stdout: outputStream,
    stderr: /* what you will, could be the same as stdout */,
});
// do stuff with devnet and then close the stream
outputStream.end();

To track the output in a separate terminal, open a new terminal and run:

tail -f devnet-out.txt

To ignore the output completely, specify { stdout: "ignore", stderr: "ignore" }.

Spawn a custom build

If you have a custom build of Devnet or have multiple custom versions present locally:

// provide the command
const devnet = await Devnet.spawnCommand("my-devnet-command", { ... });
// or specify the path
const devnet = await Devnet.spawnCommand("/path/to/my-devnet-command", { ... });

Killing

By default, the Devnet subprocess automatically exits and releases the used resources on program end, but you can send it a signal if needed:

const devnet = await Devnet.spawnInstalled();
devnet.kill(...); // defaults to SIGTERM

Keeping alive

To keep the spawned Devnet alive after your program exits, set the keepAlive flag:

const devnet = await Devnet.spawnInstalled({ keepAlive: true });

In that case, you must take care of the spawned process after the program exits. To kill it, you need to:

  1. Know the port it is using. It is logged on Devnet startup and is also a part of devnet.provider.url.

  2. Kill the process using the port, which you can do:

    a. In JS, by relying on the cross-port-killer library.

    b. From shell, by executing lsof -i :<PORT> | awk 'NR==2{print $2}' | xargs kill (substitute <PORT> with yours).

Connect to a running instance

If there already is a running Devnet instance (e.g. in another terminal or in another JS/TS program), you can simply connect to it by importing DevnetProvider. Read more about different ways of running Devnet.

import { DevnetProvider } from "starknet-devnet";
const devnet = new DevnetProvider(); // accepts an optional configuration object
console.log(await devnet.isAlive()); // true

Enabling Starknet API support

Since this library only supports the Devnet-specific API, to interact via Starknet JSON-RPC API, use starknet.js.

E.g. to get the latest block after spawning Devnet, you would need to do:

import { Devnet } from "starknet-devnet";
import * as starknet from "starknet";

const devnet = await Devnet.spawnInstalled();
const starknetProvider = new starknet.RpcProvider({ nodeUrl: devnet.provider.url });

const block = await starknetProvider.getBlock("latest");

L1-L2 communication

Assuming there is an L1 provider running (e.g. anvil), use the postman property of DevnetProvider to achieve L1-L2 communication. See this example for more info.

Examples

See the test directory for more usage examples.

Contribute

If you spot a problem or room for improvement, check if an issue for it already exists. If not, create a new one. You are welcome to open a PR yourself to close the issue. Once you open a PR, you will see a template with a list of steps - please follow them.

Test

Before running the tests with npm test, follow the steps defined in the CI/CD config file. If your new test relies on environment variables, load them with getEnvVar. Conversely, to find all environment variables that need to be set before running existing tests, search the repo for getEnvVar.