Awesome
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:
-
Know the port it is using. It is logged on Devnet startup and is also a part of
devnet.provider.url
. -
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
.