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 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.
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.
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.2.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
.