Custom development networks
ICP does not have a public testnet network because canisters deployed to the mainnet can be upgraded and changed. Plus, deployment costs are fairly low compared to other chains.
ICP offers a playground network as a testnet-like environment for small-scale, temporary testing. Canisters deployed to the playground are restricted to certain parameters:
- Cycle transfer instructions are silently ignored by the playground. Canisters cannot make calls that require cycles be attached to the call.
- Canisters can use at most 1GiB of memory.
- Canisters can call the management canister to manage themselves without being the controller.
- Deployed canisters expire after 20 minutes. Upgrades to canisters reset this timer. When the timer runs out, the canister(s) will be uninstalled.
- Wasm files can't be gzipped.
- Wasm files will be analyzed to remove any potentially expensive or malicious operations.
For advanced developers and use cases that want to use a testnet environment without these restrictions, there are two options:
Custom playground: Deploy your own instance of the playground, allowing you to control the playground settings, remove restrictions, and modify the canister pool. This option costs cycles, as you will need to fund your instance of the playground with cycles that will be used to fund the canisters deployed to your playground.
Custom dfx network: Use the
dfx
named network feature to create a local network that is segmented away from the default local network created bydfx
.
Custom playground
Using your own instance of the playground allows for extensive customization, such as:
Enabling access control by restricting the playground's usage to only allow certain principals.
Configuring more generous canister timeouts and the number of available cycles.
Allowing some or all of the functions that the public playground does not allow, such as sending cycles to other canisters.
Using a custom playground can also help simplify development for teams since the whole team can use a custom playground without needing to manage individual cycle balances.
Creating a custom playground instance
Step 1: Install the Motoko playground locally following the instructions in the playground's repository.
Step 2: Edit the
service/pool/Main.mo
file to change the custom playground settings, such as:Add access control as desired, such as creating an
allowList
of principals that are permitted to use the custom playground.Configure the canister's time to live.
Change the Wasm transformation to fit your desired configuration. In some cases, this may just be
wasm = args.wasm_module
, since if there is anallowlist
in place, the principals allowed to install canisters can be trusted.
Step 3: Lastly, define the local playground network in your project's
dfx.json
file.
In this definition, you will need to set the playground canister's ID (the pool
canister ID) and define the amount of seconds before a canister is returned to the pool, as shown below:
"<network name>": {
"playground": {
"playground_canister": "<canister pool id>",
"timeout_seconds": <amount of seconds after which a canister is returned to the pool>
},
"providers": [
"https://icp0.io"
]
}
If the value <network name>
is set as playground
, then the command dfx deploy --playground
will deploy to your custom playground. Otherwise, the command has to use --network <network name>
.
This network definition can also go into the networks.json
file, so it applies to every project. To see where the networks.json
file is located, use the command dfx info networks-json-path
.
Step 4: To use the custom playground, deploy it locally.
Custom dfx network
In a custom network, it is possible to run any dfx
command that would otherwise take --network ic
but using --network myNetwork
instead. myNetwork
can be replaced with any other name, except the three reserved ones: ic
, local
, and playground
. Using a custom local network allows you to test integrations with services and estimate deployment costs.
Networks are defined in two ways: assumed and explicitly configured. dfx
only contains the ic
network as an assumed environment. All other networks are explicitly configured in the networks.json
or dfx.json
files. The "networks" section of dfx.json
should contain at least the local network, which gets chosen by default if no other network is specified with the --network
flag.
You can create a custom-named network for each project, therefore creating a synthetic network that is segmented from the other locally tested projects in your environment, or you can create system-wide networks that can be used by any project.
Creating a system-wide custom dfx network
Custom networks can be configured in the networks.json
configuration file for dfx
, which can be found using the following dfx
command:
dfx info networks-json-path
This will return the file path where your system's networks.json
file is located. Networks defined in this file can be used by any project in your local environment.
Step 1: Edit the
networks.json
file to define a binding address such aslocalhost
or any other domain name.
For example:
{
"myNetwork1": {
"bind": "localhost:4943",
"replica": {
"subnet_type": "application"
}
}
}
To define multiple networks, use multiple definitions on different domain names:
{
"myNetwork1": {
"bind": "localhost:4943",
"replica": {
"subnet_type": "application"
}
},
"myNetwork2": {
"bind": "127.0.0.1:4943",
"replica": {
"subnet_type": "application"
}
}
}
Step 2: Deploy to one of these networks with
dfx deploy
:
dfx deploy --network myNetwork2
Creating a project-specific custom dfx
network
Alternatively, networks can also be defined in a project's dfx.json
file. Only canisters defined in that dfx.json
file can be deployed to that network.
To define a project-specific network, add a "networks" section to your dfx.json
file:
"networks": {
"myNetwork": {
"providers": [
"https://icp0.io"
],
"type": "persistent"
}
}
This definition uses the following parameters:
providers
: The network provider; can belocalhost
or any other domain name. Domain names must be a full URL, such ashttps://domain.com
.type
: The type of network, eitherephemeral
orpersistent
. Ephemeral networks do not retain the same IDs for canisters, while persistent networks will retain the same canister IDs.
If you are using a cycles wallet, the cycles wallet for each network is stored separately.