Jade Framework
Jade is a development framework for building polkadot JAM services developed by SpaceJam.
Installation
cargo install jade
Quick Start
jade new my-service
cd my-service
cargo nextest run
Service Structure
Jade currently supports two types of services: authorizer service and general service, there is also corevm service
supported in our toolkit but it has not been
official integrated in JAM implementations yet.
[no_std]
: we need to avoid standard rust library on buildingriscv64
services for making our compiled binaries compatible with the JAM virtual machines.#[jade::is_authorized]
: the entrypoint of theis_authorized
logic.#[jade::refine]
: the entrypoint of therefine
logic.#[jade::accumulate]
: the entrypoint of theaccumulate
logic.
Note that authorizer service and general service are different service types, you cannot declare both
#[jade::is_authorized]
and#[jade::refine]
(or#[jade::accumulate]
) in the same service.
Authorizer Service
#![allow(unused)] #![cfg_attr(target_arch = "riscv64", no_std)] fn main() { use jade::prelude::{AuthTrace, CoreIndex}; #[jade::is_authorized] fn is_authorized(_core_index: CoreIndex) -> AuthTrace { Default::default() } }
General Service
#![allow(unused)] #![cfg_attr(target_arch = "riscv64", no_std)] fn main() { use jade::prelude::{AuthTrace, CoreIndex}; #[jade::refine] fn refine( core: u16, index: u16, id: u32, payload: Vec<u8>, package_hash: OpaqueHash, ) -> Vec<u8> { // ... refine logic here } #[jade::accumulate] fn accumulate(now: u32, id: u32, results: Vec<Operand>) -> Option<OpaqueHash> { // ... accumulate logic here } }
Build Service
There are two ways to build a service: using jade command line tool or using rust build script.
Using jade command line tool
cargo install jade
cd my-service
jade build
Using rust build script
# my-service/Cargo.toml
#
# ...
#
[build-dependencies]
cjam = "*"
// my-service/build.rs fn main() { cjam::util::build( env!("CARGO_PKG_NAME"), // or Some(cjam::ModuleType::Authorizer) Some(cjam::ModuleType::Service), ).ok(); }
Service Testing
Jade provides a testing module for testing your service.
#![allow(unused)] fn main() { //! stoken/tests/main.rs use jade::testing::Jam; use stoken::{Holders, Instruction, SERVICE}; const AUTHORIZER_ID: u32 = 500; const SERVICE_ID: u32 = 501; const ALICE: u32 = 0; #[test] fn test_mint() { // initialize the logger jade::testing::util::init_logger(); // Set up JAM with authorization using the null authorizer service let mut jam = Jam::default().with_auth(AUTHORIZER_ID, nauth::SERVICE.to_vec()); jam.add_service(SERVICE_ID, SERVICE.to_vec()); // 1. send a mint instruction let amount = 100; let instr = vec![Instruction::Mint { to: ALICE, amount }]; let info = jam .execute(SERVICE_ID, codec::encode(&instr).unwrap()) .expect("failed to execute work item"); // 2. check the balance let holders: Holders = info .get_storage(SERVICE_ID, Holders::key()) .expect("failed to get holders"); assert_eq!(holders.balance(ALICE), amount); } }