Icp-cli announcements and feedback discussion

Being completely honest :slight_smile: When I was deploying with dfx, I didn’t have to manually generate the DID file dfx handled it automatically. Now you need to run it like this: $(mops toolchain bin moc) --idl $(mops sources) -o project_name.did src/main.mo. Another issue is the lack of Vue.js and Internet Identity templates. I understand that you can create them yourself, but for new projects they were a huge convenience, especially when working across several virtual machines and different computers. Creating them manually is a struggle the documentation exists, but you really have to jump through hoops, which makes the entry barrier immediately quite high.
Tools should be simple and intuitive, but I get the impression that the level of complexity is increasing at the expense of user experience, which will probably discourage many people.
I understand that it’s more convenient for teams sure, but for me just a simple Joe coding from my parents’ basement dfx was more convenient because it handled a lot of things automatically.

The general I get where you are coming from, does not apply anymore. Times change either you roll with it or get left behind. No personal offence so please take it as it is just pure advice. DFX is deprecated, let’s all just roll with it.

Hi @KryL,

I understand having to generate the did files is a pain at the moment. Some of this functionality is being moved into mops which is a cleaner separation of duty. Soon we’ll have the recipes using commands such as mops build to simplify the setup.

In general you should not have to make calls to moc directly, everything will be done through mops. At some point there will be a simple command to generate the did file for a motoko canister.
The name of the command is to be determined, but something along the lines of:

mops candid <canister> --output output.did

As far as examples you would like to see, you mention:

Another issue is the lack of Vue.js and Internet Identity templates.

We can add that to our templates. If you’ve already created one, maybe you could send the example my way and I can adapt it.

Yes I managed to connect Vue.js by adapting the old dfx 0.31.0 template that already included Vue.js, using advice from kind colleagues above and your Ask AI tool (I recommend it) to make it run on icp cli. If this could be useful for you in creating a template, then sure

I have recognized that an installed canister is removed after stopping and restarting the network, which was not the case in previous dfx versions.

What is this behavior, and what is the intention behind this change?

hi @rbole,

When you start the local network for your project, you are always starting a freshly initialized network. This ensures that you’re always starting from a fresh state and the behavior is consistent after a restart (some leftover state from a previous run or from another project will not affect your current setup).

If you care about maintaining state across restarts there are a couple of options:

  1. You can write a script that makes calls to the local network to finish initializing it. This way, every time you start the network you will reinitialize it to some known state. This makes the environment reproducible if you are collaborating on it with other people (everyone can bring up a local network to the same state on their machine)

  2. If you want to maintain state, you can create a dockerized network that will keep its state and possibly persist it across restarts. You will be able to use it in your project as a “connected network” and possibly share the same network across different projects.

Could you explain your use case and what benefits you see to the state being persisted across restarts and what you’re looking to do?

Ok, i want only mention this difference between the dfx version.

:waving_hand: @KryL

We just merged a PR into the templates repo that adds an option for a vue frontend to the hello-world example.

You can try it out like this:

icp new --subfolder hello-world <project-name>

Feedback is welcome - PRs with improvements is even welcome-er :wink:

Works like a charm, guys.
This templeate will be really helpful for new projects. Thanks a lot :slight_smile:

After making changes in Motoko:

  1. (only once) initialize mops
    mops init

  2. (only once ) set toolchain
    mops toolchain use moc latest

  3. Update .did file after changes in Motoko file
    $(mops toolchain bin moc) --idl $(mops sources) -o backend/backend.did backend/src/main.mo

  4. Deploy canisters again by icp deploy
    icp deploy

Heads up that there’s a new PR to improve the templates so that you can start the frontends with npm run preview if you want to iterate quickly.

Regarding steps you’re outlining:

Yes you need to do this when:

  • You update the types
  • You add/remove/modify methods on your canister

It’s potentially a big deal if you’ve changed the canister interface. So it should be checked in to git and you should be cautious when the file is dirty.

That’s very nice, thank you for your reply.

Missing permissions of newly added controller

I added a new controller to an existing canisters with the ICP CLI using the following command:

icp canister settings update --add-controller new_controller_principal my_canister -e ic

When I deployed using the just added identity, everything works well for backend canisters. However, for frontend canisters I get an error because of the asset canisters in the “Syncing Canisters” step:

[my_frontend_canister] ✘ Failed to sync canister: failed to synchronize asset canister: Failed to create batch                                                  
ERR ----- Failed to sync canister 'my_frontend_canister': my_frontend_canister_principal -----
ERR 'failed to synchronize asset canister: Failed to create batch'
ERR   caused by: Failed to create batch
ERR   caused by: The replica returned a rejection error: reject code CanisterReject, reject message Caller does not have Prepare permission, error code Some("IC0406")
ERR [my_frontend_canister] Sync output:
ERR [my_frontend_canister] Syncing: assets (directory: src/frontend/dist) 1 of 1:
ERR [my_frontend_canister] <no output>
Error: Canister(s) ["my_frontend_canister"] failed to sync.

I had to call the “grant_permission” update function with the old identity manually in order to use my new controller:

icp canister call my_frontend_canister grant_permission \
  '(record { to_principal = principal "new_controller_principal"; permission = variant { Prepare } })' \
  --identity old_controller_identity \
  -e ic
icp canister call my_frontend_canister grant_permission \
  '(record { to_principal = principal "new_controller_principal"; permission = variant { Commit } })' \
  --identity old_controller_identity \
  -e ic

I’m not sure whether this has been discussed already (couldn’t find anything with the search). Just posting this as I think it will be nice to have this done implicitly when adding the controller or at least be able to pass an option that does it.

In the very first command you wrote, you specified « my_canister » not « my_frontend_canister » - so it seems you have granted permissions to only one of your canisters?

You can check by doing

icp canister status -e ic

That should print all your canisters and their controllers

I added my new identity as a controller for both the backend and frontend canister. I did see it listed as a controller for both. Only for the frontend canister I did have to explicitly grant the “Prepare” and “Commit” permissions though. After that the syncing step worked.

Ah right - that’s a feature specific to the asset canister to separate permissions and the cli doesn’t know about it.

There are cases where you want that type of fine grained control and a controller shouldn’t necessarily be able to change the assets.

Normally if you use ‘canister call’ without arguments there’s a wizard that will guide you to write the candid payload

icp-cli v0.3.0 is released

Hi folks,

I’m excited to announce that icp-cli v0.3.0 is released. As usual, it’s on npm already and will be available on homebrew soon.

We’re planning for this to be the last 0.x release before an official v1.0 next week. Read on for important information.

Agent skills and icp-cli docs have been updated.

Highlights

:warning: Breaking change to asset syncing

First a reminder that it’s been our goal for icp-cli to decouple to the cli tool from the build toolchains, local network runtimes… and as of this release from the asset canister.

The asset canister is probably one of the most used canisters in the ecosystem. Until this release syncing assets was built into the cli tool which meant that the cli had to maintain compatibility with the asset canister. That deep coupling is no longer necessary with the introduction of the “sync plugins”. Going forward the sync process will happen through a sandbox wasm plugin and lives outside of the cli itself.

What this means to you

  • In your icp.yaml configuration, the sync step of type “assets” no longer works. You’ll get an error message about it.
  • If you are using the @dfinity/asset-canister recipe, you should upgrade to v2.2.1

Consult the migration guide: Upgrading from icp-cli 0.2 | ICP CLI

Login with Internet Identity

You are now able to link a web identity and use it with icp-cli. This means your principal in icp-cli will be the same principal that you would get if you had logged in through the web UI.
This is great if you want to programmatically interact with a canister without having to grant permissions to yet another identity.

More information here: Linking Web Based Identities

I have upgraded to the latest CLI version 0.3.0 and changed the recipe as per the migration guide:

canisters:
  - name: my_frontend
    recipe:
      type: "@dfinity/asset-canister@v2.2.0"
      configuration:
        dir: src/frontend/dist
        build:
          - cd src/frontend && npm install
          - cd src/frontend && npm run build

However, I’m running into issues with relative paths it seems.

icp deploy my_frontend -e ic
Building canisters:
[my_frontend] ✔ Built successfully
Creating canisters:
All canisters already exist
Setting environment variables:
[my_frontend] ✔ Environment variables updated successfully                                                                                                                                 
[my_frontend] ✔ Canister settings updated successfully
Checking compatibility:
[my_frontend] ✔ Compatible
Installing canisters:
[my_frontend] ✔ Installed successfully
Syncing canisters:
[my_frontend] ✘ Failed to sync canister: failed to run plugin
ERR ----- Failed to sync canister 'my_frontend': xxxxxxxxxxxxxxx -----
ERR 'failed to run plugin'
ERR   caused by: plugin returned error: canonicalize src/frontend/dist: No such file or directory (os error 44)
ERR [my_frontend] Sync output:
ERR [my_frontend] Syncing: plugin url: https://github.com/dfinity/certified-assets/releases/download/migration-v2.2.0-209d688/sync_plugin.wasm 1 of 1:
ERR [my_frontend] > Using cached file
ERR [my_frontend] > sync plugin (legacy assetstorage / .ic-assets.json5): starting for canister xxxxxxxxxxxxxxxxx (environment: ic)
ERR [my_frontend] > api_version: 2
Error: Canister(s) ["my_frontend"] failed to sync.

I verified that the assets are being built under src/frontend/dist and the “preopen” step also works.

I’m not familiar with the sandbox setup but I see it’s this line that fails: certified-assets/crates/sync-core/src/scan.rs at 47a7ff2cbb12351117ab1acf4260397de04b6480 · dfinity/certified-assets · GitHub

Thanks for the report @mattigrthr - I’m going to try to reproduce it.
if you can share a a minimal example with your setup that would be great.

@mattigrthr - can you try setting the asset canister version to 2.2.1 instead?

(I’ll fix the instructions)

getting an error in this