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.
npm i starknet-devnet
This library is compatible with stable Devnet versions in the inclusive range: v0.1.1
-v0.1.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
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", ...]
.
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.1.2");
console.log(await devnet.provider.isAlive()); // true
}
To use the latest compatible version:
const devnet = await Devnet.spawnVersion("latest");
Assuming you have already installed Devnet and it is present in your environment's PATH
, simply run:
const devnet = await Devnet.spawnInstalled();
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"] });
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" }
.
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", { ... });
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
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).
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
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");
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.
See the test
directory for more usage examples.
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.
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
.