# Write a module Rust with the wasm target (`rustup target add wasm32-unknown-unknown`) and [the CLI](cli.md). ```bash run atlibs new my-module ``` ```output my-module/ (cd my-module && cargo test && cargo wasm && atlibs run my-module describe '{"did":""}') ``` The SDK is pinned at the commit your CLI was built from: ```bash run grep '^abi' my-module/Cargo.toml ``` ```output abi = { git = "https://knotless.dev/johnandersen777.bsky.social/atlibs", rev = "…" } ``` The module: one entry, `describe`, run once per event. ```bash run sed -n '1,/^entries!/p' my-module/modules/my-module/src/lib.rs ``` ```output use abi::{Call, Did, Event, Handle, Run, entries}; use serde::Deserialize; use serde_json::json; #[derive(Deserialize)] struct Args { did: Did, } // The host calls this once per event. Start: ask the account's PDS. Result: answer. fn describe_handler(run: Run) -> Result { Ok(match run.event { Event::Start => Handle::new().call( Call::new("repo", "com.atproto.repo.describeRepo") .params(json!({ "repo": run.args.did })) .service(run.args.did.as_str()), ), Event::Result { id, result, .. } if id == "repo" => { let repo = result.output()?; let collections = repo["collections"].as_array().map_or(0, Vec::len); Handle::new().result(json!({ "handle": repo["handle"], "collections": collections })).done() } _ => Handle::new(), }) } entries!(describe => describe_handler); ``` What it may call, the form a host shows for it, and what a composition may set (`config`): ```bash run cat my-module/modules/my-module/module.json ``` ```output { "name": "my-module", "description": "Describe an account's repo: its handle and how many collections it has.", "actions": [{ "entry": "describe", "label": "Describe", "readOnly": true, "fields": [{ "key": "did", "label": "DID", "required": true }] }], "config": [{ "key": "did", "label": "DID", "description": "The account a composition's instance describes." }], "calls": ["com.atproto.repo.describeRepo"] } ``` ## Test, build, run The tests (in `lib.rs`) feed the handler events; no network. ```bash run=network cd my-module cargo test 2>&1 | grep '^test ' | LC_ALL=C sort cargo wasm 2>&1 | tail -1 atlibs run my-module describe '{"did":"did:plc:ocnuqjlzgohypj3zoznermms"}' ``` ```output test tests::result_counts_collections ... ok test tests::start_calls_describe_repo ... ok … "result": { "collections": …, "handle": "bobvmbuilder.bsky.social" }, ``` More: [the SDK](../modules/write.md), [calls](../modules/calls.md), [tests with the real host loop](../modules/test.md). Previous: [Rust](rust.md) | Next: [Publish](publish.md)