Skip to content

MioQuispe/ICE

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

93 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

image

ICE

ICE is a powerful task runner and CLI tool for the Internet Computer (similar to hardhat). With ICE, you can create composable workflows, simplify complex setups, and manage canister deployments using TypeScript instead of bash, taking the development experience of the Internet Computer to the next level.

Features

  • Composable: Easily build complex workflows.
  • Type-Safe: Get instant feedback on configuration errors.
  • NPM Canisters: Install popular canisters (ICRC1, Ledger, NFID, Internet Identity) with zero setup.
  • Smart Context & dependencies: Automatic setup of actors, users, and other env variables from inside your scripts
  • VSCode Extension: Run tasks directly in your editor with inline results.

Quick Start

  1. Install the necessary packages:

    npm i -S @ice.ts/runner @ice.ts/canisters
  2. Create an ice.config.ts file in your project root:

    import { motokoCanister } from '@ice.ts/runner'
    
    export const my_canister = motokoCanister({
      src: 'canisters/my_canister/main.mo',
    })
  3. Now its available under the exported name:

    npx ice run my_canister
  4. Or deploy all canisters:

    npx ice

    Kapture 2025-02-24 at 16 28 03

Core concepts

Tasks

Tasks are the main building block of ICE. They are composable, type-safe and can depend on other tasks.

In this example ICE will make sure the icrc1_ledger is deployed and and its actor created, prior to running the task.

import { task } from "@ice.ts/runner"

export const mint_tokens = task("mint tokens")
  .deps({
    icrc1_ledger,
  })
  .run(async ({ deps: { icrc1_ledger } }) => {
    const symbol = await icrc1_ledger.actor.icrc1_symbol()
    console.log(symbol)
  })

Run the task:

npx ice run mint_tokens

Dependencies

Define inter-canister or task dependencies easily.

import { motokoCanister } from "@ice.ts/runner"

// Create a canister that depends on another one
export const my_other_canister = motokoCanister({
  src: "canisters/my_other_canister/main.mo",
})
  .deps({ my_canister })

You can also declare requirements and provide them later:

export const MyCanister = () => motokoCanister({
  src: "canisters/my_canister/main.mo",
})
   .dependsOn({ my_other_canister })

Later, we can provide it through .deps(). You’ll get type-level warnings if dependencies aren’t met:

Install args

Pass fully typed install arguments instead of manual candid strings.

import { motokoCanister, task } from "@ice.ts/runner"

export const my_other_canister = motokoCanister({
  src: "canisters/my_other_canister/main.mo",
})
  .deps({ my_canister })
  .installArgs(async ({ deps }) => {
    const someVal = await deps.my_canister.actor.someMethod()
    return [deps.my_canister.canisterId, someVal]
  })

We get type-level warnings for invalid args

Context

Every task and canister gets a shared context with env variables, user info, and more.

import { task } from "@ice.ts/runner";

export const example_task = task("example task")
  .run(async ({ ctx }) => {
    console.log(ctx.users.default.principal)
    console.log(ctx.users.default.accountId)

    // Run another task dynamically
    const result = await ctx.runTask(my_other_task)
  })

Scope

Tasks can also be grouped into scopes for better organization.

import { scope } from "@ice.ts/runner";
import { NNSDapp, NNSGovernance } from "@ice.ts/canisters";

export const my_custom_nns = scope("NNS canisters", {
   nns_dapp: NNSDapp(),
   nns_governance: NNSGovernance(),
   // ...etc.
})

These can now be accessed in the following way:

npx ice run my_custom_nns:nns_dapp
npx ice run my_custom_nns:nns_governance:install

Pre-built canisters

Use popular canisters with a single line of code. ICE provides ready-to-use setups for many common canisters.

import {
  InternetIdentity,
  ICRC1Ledger,
  DIP721,
  Ledger,
  DIP20,
  CapRouter,
  NNS,
  CandidUI,
  ICRC7NFT,
  CyclesWallet,
  CyclesLedger,
  NFID,
} from "@ice.ts/canisters"

export const nns = NNS()
export const icrc7_nft = ICRC7NFT()
export const nfid = NFID()
// And more...

It's that easy.

🔌 VSCode Extension

Install from the Visual Studio Marketplace.

  • Inline CodeLens: Quickly execute tasks directly from your source code.
  • Actor Call Results: results are displayed inline in your code. No more console logs.

Kapture 2025-02-23 at 22 16 11

Community & Support

Feel free to open an issue, PR or join the Discord and message me there.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published