Skip to content

Commit

Permalink
Merge pull request #3547 from dfinity/canpack-docs
Browse files Browse the repository at this point in the history
add: Canpack doc page
  • Loading branch information
jessiemongeon1 authored Sep 27, 2024
2 parents 21f632a + 4982ad8 commit 04c9255
Show file tree
Hide file tree
Showing 3 changed files with 161 additions and 1 deletion.
6 changes: 5 additions & 1 deletion docs/developer-docs/developer-tools/dev-tools-overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,11 @@ Additionally, there are several community-developed and maintained agents:

- Ruby [`ic_agent` by Terry.Tu](https://github.com/tuminfei/ic_agent)

## Onchain libraries
### Canpack

- [Canpack](/docs/current/developer-docs/developer-tools/off-chain/canpack): A tool used to facilitate communication between canisters written in different languages; currently supports calling Rust crates from Motoko canisters.

## On-chain libraries

### Canister development kits (CDKs)

Expand Down
155 changes: 155 additions & 0 deletions docs/developer-docs/developer-tools/off-chain/canpack.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
---
keywords: [intermediate, canpack, code generation tool, motoko, rust]
---

import { MarkdownChipRow } from "/src/components/Chip/MarkdownChipRow";

# Canpack

<MarkdownChipRow labels={["Intermediate", "Motoko", "Rust" ]} />

## Overview

Canpack is a code generation tool designed to simplify communication across canisters written in different languages. It currently supports calling a Rust crate from Motoko code. Canpack generates a separate canister for the host language, then combines the other language's code fragments that are defined across different libraries.

Canpack supports the [Mops](https://mops.one/) package manager.

:::caution
Canpack is still in early development. Breaking changes may be introduced at any time.
:::

## Installation

### Prerequisites

- [x] You have [Node.js](https://nodejs.org/en/) installed.

- [x] You have downloaded and installed the [IC SDK](/docs/current/developer-docs/getting-started/install/).

- [x] You have [Rust](https://www.rust-lang.org/tools/install) installed.

Then, install the Canpack CLI using `npm`:

```
npm install -g canpack
```

## Using Canpack

In a project directory that contains a `dfx.json` and `mops.toml` file, you can use Canpack by first creating a new file called `canpack.json` with the following content:

```json
{
    "canisters": {
        "motoko_rust": {
            "type": "rust",
            "parts": [{
                "package": "canpack-example-hello",
                "version": "^0.1"
            }]
        }
    }
}
```

Then, generate the required files using the command: 

```bash
canpack
```

In the project's `dfx.json` file, configure the `"dependencies"` for your project's Motoko canister:

```json
{
    "canisters": {
        "my_project_backend": {
            "dependencies": ["motoko_rust"],
            "main": "src/my_project_backend/main.mo",
            "type": "motoko"
        }
    },
}
```

Then, to write a Motoko canister that imports Rust crates, import `Rust` from the `motoko_rust` canister:

```motoko no-repl
import Rust "canister:motoko_rust";
actor {
    public composite query func hello(name: Text) : async Text {
        await Rust.canpack_example_hello(name)
    }
}
```

Motoko canisters can import any Rust crate that is compatible with Canpack. Canpack supports any IC Wasm-compatible crate.

### Adding Canpack support to a crate

To add Canpack support to a Rust crate, export a Rust function with `canpack::export!`:

```rust
canpack::export! {
    pub fn canpack_example_hello(name: String) -> String {
        format!("Hello, {name}!")
    }
}
```

`canpack::export!` requires that you add [`canpack`](https://crates.io/crates/canpack) as a dependency in your `Cargo.toml` file.

### Reference local data

You can also reference local data, such as methods and constants:

```rust
const WELCOME: &str = "Welcome";

fn hello(salutation: &str, name: String) -> String {
    format!("{salutation}, {name}!")
}

canpack::export! {
    pub fn canpack_example_hello(name: String) -> String {
        hello(WELCOME, name)
    }
}
```

### Candid methods

To configure an automatically generated Candid method for a function, use the `#[canpack]` attribute, 

```rust
canpack::export! {
    #[canpack(composite_query, rename = "canpack_example_hello")]
    pub fn hello(name: String) -> String {
        format!("Hello, {name}!")
    }
}
```

Alternatively, you can manually define a Candid method through the `canpack!` macro:

```rust
pub fn hello(name: String) -> String {
    format!("Hello, {name}!")
}

#[macro_export]
macro_rules! canpack {
    () => {
        #[ic_cdk::query]
        #[candid::candid_method(query)]
        fn canpack_example_hello(name: String) -> String {
            $crate::hello(name)
        }
    };
}
```

## Resources

Canpack is open to [contributions](https://github.com/dfinity/canpack/blob/main/.github/CONTRIBUTING.md) and encourages you to report bugs, ask questions, or request features using the project's [GitHub issues](https://github.com/dfinity/canpack/issues).
1 change: 1 addition & 0 deletions sidebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,7 @@ const sidebars = {
"developer-docs/developer-tools/off-chain/agents/rust-agent",
],
},
"developer-docs/developer-tools/off-chain/canpack",
"developer-docs/developer-tools/off-chain/canbench",
],
},
Expand Down

0 comments on commit 04c9255

Please sign in to comment.