Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

When to use macros

Use #[sapio::contract] on an inherent impl for normal contract authoring. Mark transaction methods with #[action(committed)] or #[action(suggested)], policies with #[policy], and independently sufficient spending policies with #[spend]. The methods remain ordinary Rust methods. The macro generates typed action handles, request schemas and registration.

A policy with only &self is context-free and cached. A policy that also accepts Context is evaluated at its attachment context. The signature expresses the actual dependency.

The explicit low-level API is Action<Contract, Request>. Its constructor takes a transaction-generation callback. with_guards, with_conditions, with_json, and with_defaults add the corresponding capabilities; erase() hides only the individual request type when registering the action. There is no global argument pack. This API is useful for dynamically assembled contracts.

Optional interfaces can still use decl_then!, decl_continuation!, and decl_guard!, implemented by the standalone action/guard attributes. A factory returning None means that the implementation does not provide that interface member. Export optional factories explicitly through declare! {actions, ...} or #[sapio::contract(actions(Self::optional), spends(Self::optional_guard))].

Use #[condition] with compile_if(...) for availability depending on the contract’s value. Its condition algebra distinguishes absent, nullable and required branches; it does not add a spending predicate.