Routes
Routes are the named entry points of an entity — the primary interface
callers use to interact with it. Invoking a route runs its preconditions,
member transforms, and action list. How a host dispatches to a route (EVM
call, test harness, …) is target-specific; the .cam
surface stays the same.
Routes block
entity Wallet {
routes {
init setup(owner: address) => []
deposit()
where msg::value > 0 : throw ZeroDeposit()
=> []
withdraw(amount: U256)
where msg::sender == m_owner : throw Unauthorized()
&& m_balance >= amount : throw InsufficientBalance(m_balance, amount)
=> [
~> msg::sender with { value: amount }
]
view get_balance() -> U256 => [
return(m_balance)
]
pure compute_fee(amount: U256, rate: u64) -> U256 => [
return(amount * (rate as U256) / 10000)
]
accept receive() => []
}
}
Route kinds
| Kind | Keyword | State | Side effects | Use |
|---|---|---|---|---|
| Regular | (none) | Read + write | Yes | Mutations |
| View | view | Read only | No | Queries |
| Pure | pure | None | No | Stateless computation |
| Init / constructor | init (or constructor-style) | Write | Yes | One-time setup |
| Private | private | Read + write | Yes | In-entity only; use with call |
| Receive | accept receive() | Read + write | Yes | Plain ETH receiver |
| Fallback | fallback() | Read + write | Yes | Unknown selector |
Details:
Private routes
A private route is part of the entity’s logic but not an external entry
point. Other routes invoke it with the call action:
entity Service {
routes {
run() => [
call finalize_step()
]
private finalize_step() => []
}
m_done: bool {
in finalize_step() => true
}
}
See Call (Private Routes) for restrictions and per-target lowering.
Anatomy
[modifier] name(parameters) [from clause] [where clause] [-> ReturnType] => [actions]
| Part | Required | Description |
|---|---|---|
| Modifier | No | view, pure, init, private, or accept on receive |
| Name | Yes | Route identifier (receive / fallback are reserved on EVM) |
| Parameters | Yes | Typed list (empty for receive / fallback) |
| From clause | No | Sender verification — From Clause |
| Where clause | No | Preconditions — Where Clause |
| Return type | No | -> T when returning a value (V42 if return(expr) lacks it) |
| Actions | Yes | => [ … ] (may be empty when only transforms apply) |
Clauses
From
release()
from Buyer(m_buyer_id) : throw Unauthorized()
=> []
Where
withdraw(amount: U256)
where m_balance >= amount : throw InsufficientBalance(m_balance, amount)
=> []
Prefer named errors — Custom Errors.
Actions
Sends, deploys, emits, conditionals, returns, and local bindings:
transfer(to: address, amount: U256) => [
let fee = compute_fee(amount);
Transfer(amount - fee) ~> to,
Transfer(fee) ~> m_treasury
]
See Route Actions.
Members
Members name the routes that update them:
m_balance: U256 {
in deposit(_) => m_balance + msg::value
in withdraw(amount) => m_balance - amount
}
Empty action lists
routes {
increment() => []
}
m_count: u64 {
in increment() => m_count + 1
}
The [] is still required syntactically.