Highlights of what’s new in 0.9.2
An overview of the 0.9.2 release:
Be sure to see the 0.9.0 Release Notes and follow the instructions due to breaking changes since dfx 0.8.4.
Changes to DFX
New Feature: Verify Candid and Motoko stable variable type safety of canister upgrades
Newly deployed Motoko canisters now embed the Candid interface and Motoko stable signatures in the Wasm module.
dfx deploy
and dfx canister install
will automatically check
1) the backward compatible of Candid interface in both upgrade and reinstall mode; 2) the type safety of Motoko stable variable type in upgrade mode to avoid accidentally lossing data;
See Upgrade compatibility for more details.
New Feature: Unified environment variables across build commands
The three canister types that use a custom build tool - assets
, rust
, and custom
- now all support the same set of environment variables during the build task:
-
DFX_VERSION
- The version of DFX that was used to build the canister. -
DFX_NETWORK
- The network name being built for. Usuallyic
orlocal
. -
CANISTER_ID_{canister}
- The canister principal ID of the canister{canister}
registered indfx.json
. -
CANISTER_CANDID_PATH_{canister}
- The path to the Candid interface file for the canister{canister}
among your canister’s dependencies. -
CANISTER_CANDID_{canister}
(deprecated) - the same asCANISTER_CANDID_PATH_{canister}
. This is provided for backwards compatibility withrust
andcustom
canisters, and will be removed in dfx 0.10.0. -
CANISTER_ID
- Same asCANISTER_ID_{self}
, where{self}
is the name of this canister. -
CANISTER_CANDID_PATH
- Same asCANISTER_CANDID_PATH_{self}
, where{self}
is the name of this canister.
New Feature: Support for local ledger calls
If you have an installation of the ICP Ledger (see Ledger Installation Guide), dfx ledger balance
and dfx ledger transfer
now support
--ledger-canister-id
parameter.
Some examples:
$ dfx ledger \
--network local \
balance \
--ledger-canister-id rrkah-fqaaa-aaaaa-aaaaq-cai
1000.00000000 ICP
$ dfx ledger \
--network local \
transfer --amount 0.1 --memo 0 \
--ledger-canister-id rrkah-fqaaa-aaaaa-aaaaq-cai 8af54f1fa09faeca18d294e0787346264f9f1d6189ed20ff14f029a160b787e8
Transfer sent at block height: 1
New Feature: dfx ledger account-id
can now compute canister addresses
The dfx ledger account-id
can now compute addresses of principals and canisters.
The command also supports ledger subaccounts now.
dfx ledger account-id --of-principal 53zcu-tiaaa-aaaaa-qaaba-cai
dfx ledger --network small02 account-id --of-canister ledger_demo
dfx ledger account-id --of-principal 53zcu-tiaaa-aaaaa-qaaba-cai --subaccount 0000000000000000000000000000000000000000000000000000000000000001
New Feature: Print the full error chain in case of a failure
All dfx
commands will now print the full stack of errors that led to the problem, not just the most recent error.
Example:
Error: Subaccount '00000000000000000000000000000000000000000000000000000000000000000' is not a valid hex string
Caused by:
Odd number of digits
Fixed: dfx import will now import pem files created by quill generate
quill generate
currently outputs .pem files without an EC PARAMETERS
section.
dfx identity import
will now correctly identify these as EC keys, rather than Ed25519.
Fixed: retry on failure for ledger create-canister, top-up, transfer
dfx now calls transfer
rather than send_dfx
, and sets the created_at_time field in order to retry the following commands:
-
dfx ledger create-canister
-
dfx ledger top-up
-
dfx ledger transfer
New Feature: Remote canister support
It’s now possible to specify that a canister in dfx.json references a "remote" canister on a specific network, that is, a canister that already exists on that network and is managed by some other project.
Motoko, Rust, and custom canisters may be configured in this way.
This is the general format of the configuration in dfx.json:
{
"canisters": {
"<canister name>": {
"remote": {
"candid": "<path to candid file to use when building on remote networks>"
"id": {
"<network name>": "<principal on network>"
}
}
}
}
}
The "id" field, if set for a given network, specifies the canister ID for the canister on that network. The canister will not be created or installed on these remote networks. For other networks, the canister will be created and installed as usual.
The "candid" field, if set within the remote object, specifies the candid file to build against when building other canisters on a network for which the canister is remote. This definition can differ from the candid definitions for local builds.
For example, if have an installation of the ICP Ledger (see Ledger Installation Guide)
in your dfx.json, you could configure the canister ID of the Ledger canister on the ic network as below. In this case,
the private interfaces would be available for local builds, but only the public interfaces would be available
when building for --network ic
.
{
"canisters": {
"ledger": {
"type": "custom",
"wasm": "ledger.wasm",
"candid": "ledger.private.did",
"remote": {
"candid": "ledger.public.did",
"id": {
"ic": "ryjl3-tyaaa-aaaaa-aaaba-cai"
}
}
},
"app": {
"type": "motoko",
"main": "src/app/main.mo",
"dependencies": [ "ledger" ]
}
}
}
As a second example, suppose that you wanted to write a mock of the ledger in Motoko.
In this case, since the candid definition is provided for remote networks,
dfx build
(with implicit --network local
) will build app against the candid
definitions defined by mock.mo, but dfx build --network ic
will build app against
ledger.public.did
.
This way, you can define public update/query functions to aid in local testing, but
when building/deploying to mainnet, references to methods not found in ledger.public.did
will be reported as compilation errors.
{
"canisters": {
"ledger": {
"type": "motoko",
"main": "src/ledger/mock.mo",
"remote": {
"candid": "ledger.public.did",
"id": {
"ic": "ryjl3-tyaaa-aaaaa-aaaba-cai"
}
}
},
"app": {
"type": "motoko",
"main": "src/app/main.mo",
"dependencies": [ "ledger" ]
}
}
}
New Feature: Generating remote canister bindings
It’s now possible to generate the interface of a remote canister using a .did file using the dfx remote generate-binding <canister name>|--all
command. This makes it easier to write mocks for local development.
Currently, dfx can generate .mo, .rs, .ts, and .js bindings.
This is how you specify how to generate the bindings in dfx.json:
{
"canisters": {
"<canister name>": {
"main": "<path to mo/rs/ts/js file that will be generated>",
"remote": {
"candid": "<path to candid file to use when generating bindings>"
"id": {}
}
}
}
}