This framework allows for an IC canister to be piggybacked on IoT devices for:
- additional compute off-chain where reasonable or just
- to provide a bridge between the IoT device and the IC.
🚧 No security is done in any part of the project. Still in PoC state.
Release notes and unreleased changes can be found in the CHANGELOG.
- Rust toolchain. You can install it using rustup. To compile the application.
- The dfx tool. To create a local network and deploy the canister.
- Ngrok. To allow your harness node to be accessible on the public internet. You can get started here.
This sample code can be found here.
This is the whole application:
use candid::{Decode, Encode};
use harness_cdk::prelude::*;
#[harness]
fn hello(msg: String) -> String {
format!("Hello, {msg}!")
}
harness_export!();
There is no cli tool yet and none is planned atm. You can use the following script to build your canister, here We run the build script:
chmod +x ./build.sh #This should allow the script to be executable
./build.sh
The next step will be to start our node, in another tab:
cd harness-node
HARNESS_PORT='8080' cargo run
Now we can server our harness node to the public internet using ngrok:
ngrok http 8080
Now that everything is set up, we can start interacting with our system.
-
First we can check the health of our system:
curl http://localhost:8080/hello
-
We can then register our harness node to the canister:
dfx canister call <canister_id> register_device '("http://<ngrok-url>")'
-
Next we need to pull the harness code from the canister for our server to load.
curl --header "Content-Type: application/json" \ --request POST \ --data '{"canister_id":"<canister_id>","program_id":"hello","url":"<icp_replica_url>"}' \ http://localhost:8080/program
-
Finally we can call out canister, which will arbiter the call to the harness node.
dfx canister call <canister_id> hello '("World")'
Below is the diagrammatic representation of the Harness system:
graph TD;
A[Caller from the Internet] <-->|Canister query| B((ICP Canister))
subgraph B[ICP Canister]
E[Static App Binary]
end
B <--> |httpOutcall| C[Harness Node]
subgraph C[Harness Node]
D[Loaded App Binary]
F[IO] <-->|waPC call| D
end
Below is the sequence diagram of the Harness system:
sequenceDiagram
participant C as Harness Node
participant B as ICP Canister
participant E as Static App Binary
participant D as Loaded App Binary
participant A as Caller from the Internet
C ->> B: Query Canister to load Application Binary
B ->> E: Access Static App Binary
B ->> C: Return Application Binary
C ->> D: Load Application Binary
C ->> B: Provide URL of Harness Node
A ->> B: Canister query
B ->> C: httpOutcall to Harness Node
C ->> D: Invoke the Binary(waPC call)
D ->> C: Invocation Result(waPC response)
C ->> B: httpOutcall response
B ->> A: Response to Caller