Motoko and Rust SDK APIs
This reference describes the current vendored Metra canister SDKs. They use the same protocol V3 method names, argument types, and result shapes against standalone Metra and an icLens Agent. The Agent authorizes active Registry producers and separately granted scoped producer lanes.
Package and state ownership
Section titled “Package and state ownership”| Contract | Motoko | Rust |
|---|---|---|
| Package | mo:metra-client |
metra-ic-client |
| Durable root | Client.State |
ClientState |
| State schema | Client.stateSchemaVersion = 1 |
CLIENT_STATE_SCHEMA_VERSION = 1 |
| Initialize | Client.initialize(policy) |
ClientState::new(policy) |
| Default policy | Client.defaultPolicy() |
CollectionPolicy::default() |
| State facts | snapshot |
snapshot |
| Change policy | configurePolicy |
configure_policy |
| Bind target/generation/stream | configureLane |
configure_lane |
The consuming canister owns persistence, upgrade handling, trusted time, target configuration, and timers. A client is not an actor, automatic exporter, or durable-storage service on behalf of its host.
A stream ID is 16 bytes and must not be reused. Policy changes and lane changes are allowed only at eligible empty, unambiguous boundaries; they are not a way to discard a pending append.
Instrumentation APIs
Section titled “Instrumentation APIs”| Operation | Motoko | Rust | Semantics |
|---|---|---|---|
| Register local descriptor | registerInstrument |
register_instrument |
Returns a local instrument ID; remote registration is separate |
| Enable/disable instrument | setInstrumentEnabled |
set_instrument_enabled |
Requires an eligible empty boundary |
| Gauge | recordGauge |
record_gauge |
Retains the newest series value in the export interval |
| Sum | addSum |
add_sum |
Durably accumulates accepted cumulative additions |
| Histogram | observeHistogram |
observe_histogram |
Cumulative count/buckets/sum/min/max against fixed finite bounds |
| Flush readiness | flushStatus |
flush_status |
Pure empty/not-due/due/recommended state; no network call |
| Unknown consumed outcomes | unknownConsumedOutcomes |
unknown_consumed_outcomes |
Bounded retained delivery evidence |
Both clients support Gauge, monotonic or non-monotonic cumulative Sum, and explicit Histogram. Monotonic sums reject negative additions; non-monotonic sums may accept finite negative additions. The canister SDK collection profile does not export delta instruments.
Scalar values retain signed 64-bit, unsigned 128-bit, or binary64-bit representations. Attribute values support text, Boolean, signed integer, binary64 bits, and bytes. Check typed failures for invalid numeric values and capacity.
Prepared delivery lifecycle
Section titled “Prepared delivery lifecycle”| Stage | Motoko | Rust |
|---|---|---|
| Prepare stream open | prepareOpen |
prepare_open |
| Prepare registration | prepareRegistration |
prepare_registration |
| Prepare group registration or extension | prepareGroupRegistration |
prepare_group_registration |
| Prepare strip append | prepareAppend |
prepare_append |
| Prepare close | prepareClose |
prepare_close |
| Publish attempted state | beginAttempt |
begin_attempt |
| Access retained call | pendingCall |
pending_call |
| Execute | Client.execute |
execute |
| Settle | settleOpen, settleRegistration, settleAppend, settleClose |
settle_open, settle_registration, settle_append, settle_close |
| Preserve ambiguity | markUnknown |
mark_unknown |
| Fetch replicated cursor | Client.reconcileRemote |
reconcile_remote |
| Apply cursor evidence | reconcile |
reconcile |
The transport uses a 30-second bounded wait. Timeout, rejection, or malformed response is an unknown outcome. Preserve the pending tuple and reconcile before another send. A forced flush bypasses the export interval only; it does not bypass point/byte bounds or unresolved delivery.
Protocol V3 transport
Section titled “Protocol V3 transport”| Concern | Vendored SDK transport | Current icLens Agent |
|---|---|---|
| Open | open_producer_stream(streamId) |
Same method and result |
| Register descriptors | register_descriptors(streamId, encodedBlob) |
Same method and result |
| Register or extend group | register_group / extend_group |
Same methods and results |
| Append | append_strips(streamId, sequence, batch) |
Same method and result |
| Close | close_producer_stream(streamId) |
Same method and result |
| Reconcile | reconcile_producer_cursor({ producer; generation; streamId }), update |
Same update-backed method and result |
| Producer authority | Standalone Producer grant/generation | Active Agent Registry resource/revision or Admin-managed forwarder grant/generation |
The Agent checks producer authority before decoding bounded wire envelopes. A Registry producer retains its SDK descriptor scope and receives protected Registry origin; a metrics-only forwarder grant has its own protected origin. Configure the lane generation for the destination Agent before sending prepared bytes.
Use Agent producer methods and the Agent API for the Agent facade. Use the Motoko and Rust guides for current SDK instrumentation. Packages remain source dependencies in the development checkout; this reference does not assert public package availability.
Native Logs, Traces and RUM boundaries
Section titled “Native Logs, Traces and RUM boundaries”The development Agent facade keeps Lumera’s registerRecipe/appendNative
contract and Veyra’s explicit-scope register_producer_in/ingest_packet_in/
get_receipt_in names intentionally, so unmodified native producers can use it.
Grant generations, exact retry receipts and scope-specific quota checks remain
part of intake. Reconciliation methods are explicit updates and are excluded
from query clients.
Headless TypeScript clients use generated bindings from each exact vendored Candid. Included reads pass through the selected Agent gateway; separate reads use the caller’s identity directly. They expose only query methods, reuse the existing read scheduler and current Source/network/root/caller guard, and add no result cache, polling loop, hidden maintenance or paid fallback. Native RUM interpretation and the Veyra codec come from pinned component source, with their license/notice text included in App and Demo output. RUM is aggregate telemetry; its collector is installed separately rather than embedded in the Agent.