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. Usually ic or local.

  • CANISTER_ID_{canister} - The canister principal ID of the canister {canister} registered in dfx.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 as CANISTER_CANDID_PATH_{canister}. This is provided for backwards compatibility with rust and custom canisters, and will be removed in dfx 0.10.0.

  • CANISTER_ID - Same as CANISTER_ID_{self}, where {self} is the name of this canister.

  • CANISTER_CANDID_PATH - Same as CANISTER_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": {}
      }
    }
  }
}

Motoko

Updated Motoko from 0.6.20 to 0.6.21.

Replica

Updated replica to blessed commit 04fe8b0a1262f07c0cec1fdfa838a37607370a61. This incorporates the following executed proposals:

ic-ref

Upgraded from a432156f24faa16d387c9d36815f7ddc5d50e09f to ab8e3f5a04f0f061b8157c2889f8f5de05f952bb

  • Support 128-bit system api for cycles

  • Include canister_ranges in the state tree

  • Removed limit on cycles in a canister