Authoring Petals
The petal authoring surface is a small Rust framework.
Project Setup
Petals should be normal Rust crates. Do not clone the full Bloom source tree just to write one.
Start with:
Add the Bloom petal crates by git URL:
[dependencies]
bloom-resource = { git = "https://github.com/bloom-directory/bloom.git" }
bloom-resource-macros = { git = "https://github.com/bloom-directory/bloom.git" }
Set the library crate types:
Build only your petal:
The Bloom CLI and chain are deployment tools. They do not need to be workspace siblings of your petal crate.
For object-heavy petals, also add:
#[bloom::petal]
Apply #[bloom::petal] to an inline module:
use bloom_resource_macros as bloom;
#[bloom::petal(path = "/bloom/examples/math", version = "0.1.0")]
pub mod math {
pub fn add(a: u128, b: u128) -> u128 {
a + b
}
}
Every pub fn inside the module becomes part of the petal ABI. Private helpers
remain normal Rust helpers.
The macro records:
- module path;
- framework version;
- object declarations;
- capability declarations;
- public function names, arguments, returns, signers, and required caps;
- invariants.
#[bloom::object]
Use #[bloom::object] for durable resource types.
#[bloom::object(abilities = "key, store", phantom = "T")]
pub struct Supply<T> {
pub id: UID,
pub total: u128,
pub _phantom: core::marker::PhantomData<T>,
}
Recognized forms:
#[bloom::object]
#[bloom::object(abilities = "key, store")]
#[bloom::object(abilities = "key, store, copy, drop")]
#[bloom::object(no_abilities)]
#[bloom::object(phantom = "T, U")]
Plain generic payload fields are rejected unless they are phantom parameters or wrapped in Bloom runtime resource types. This keeps object payload layout explicit.
#[bloom::capability]
Capabilities are authority resources:
#[bloom::capability(phantom = "T")]
pub struct MintCap<T> {
pub id: UID,
pub _phantom: core::marker::PhantomData<T>,
}
The macro is sugar for a key/store/copy object declaration plus the runtime
marker trait. A function that takes &Capability<MintCap<T>> is cap-gated.
Function Arguments
Common argument types:
| Rust shape | PTB arg kind |
|---|---|
u8, u64, u128, bool, bytes, strings |
constant |
&Signer |
signer reference |
&Resource<T> |
read-only object |
&mut Resource<T> |
mutable object |
Resource<T> |
consumed object |
&Capability<T> |
capability proof |
Coin<T> / &mut Coin<T> |
fungible object handle |
Generic functions are called with runtime TypeTag values. The macro emits one
real export and binds the concrete type arguments for the duration of the call.
Error Style
Petal entry points normally return the success type directly. Host wrappers
return Result<T, PetalError>, and the examples often use expect(...) at the
entry-point boundary. A panic or trap becomes a petal abort and reverts the PTB.
For testability, production petals often split logic into:
- a public
#[bloom::petal]function with the simple ABI; - an internal
opsmodule withResult-returning helpers and payload codecs.