
Get paid as the work happens
Payment streams, time-based and metered
Open a funded stream that accrues by elapsed time or by signed meter readings.
You open a funded stream to a recipient and it pays out while the job runs, not after an invoice. Pick time mode to accrue a rate over elapsed milliseconds, or metered mode to accrue against cumulative readings signed by up to eight meter authorities you name at open. Either party can settle. You can pause, resume, top up and close, and close pays what is owed and refunds the rest.
What it does
The stream module in the LayerX agent domain lets a payer open a funded stream to a recipient that pays out as work happens rather than in one lump. A time stream accrues a rate over elapsed milliseconds; a metered stream accrues against cumulative readings signed by a meter authority the payer named when the stream opened. Funds sit in a dedicated stream account that only the stream module can debit, and only to pay the recipient or refund the payer. Seven activity types cover the whole life of a stream: open, top up, meter, settle, pause, resume and close.
Key capabilities
- Two modes: accrual by elapsed time, or by cumulative readings from a signed meter.
- Up to eight Ed25519 meter authorities per stream; readings must never regress.
- Either party can settle; settlement pays what has accrued up to the stream balance.
- Payer can pause, resume and close; close pays what is owed and refunds the rest.
- Top-up refills a stream and restarts accrual on one that ran out of funds.
- Settle and close take an idempotency key and replay the original receipt exactly.
Who it's for
Agent developers and service providers billing for long-running jobs, compute time or metered usage.
Why it matters
A provider is paid continuously for work in progress instead of waiting for a lump-sum invoice, and the payer's exposure is bounded by a total cap and by the balance actually held in the stream account. If the stream runs dry, the recipient is paid what the balance covers and the stream is marked underfunded rather than silently accruing a debt.
Differentiators
Accrual keeps a sub-unit remainder on the record, below the rate unit, and carries it into the next accrual, so repeated small settlements do not lose value to rounding. Meter readings are signed over a domain-tagged preimage (LXP:STREAM:METER:v1) bound to the stream id, the reading and the signing key, so a reading cannot be replayed on another stream. A stream account is debitable only by the stream module under module authority and only for a draw or a refund reason; no owner signature can move funds out of it.
Outcomes
- Providers are paid continuously instead of waiting for a lump-sum invoice.
- Your exposure stays bounded by the total cap and the stream balance.
- Repeated settlements keep a sub-unit remainder, so rounding loses no value.
Technical notes
- Activity types
0x00040001to0x00040007on module 4. Payload version 1. Payload sizes: open 204 bytes plus 32 per meter authority, top up 50, meter 138, settle and close 66, pause and resume 34. The stored record is 541 bytes. - Mode 1 is time, mode 2 metered. Time mode must carry no meter authorities; metered mode must carry at least one, sorted and distinct. Accrual is
rate × elapsed ÷ rate_unitwith elapsed in milliseconds, computed in 256-bit intermediates and floored, and it stops at the stream's total cap and at its end timestamp. - Accrual is lazy: it runs when settle, pause or close touches the stream, or when a meter reading arrives. There is no automatic per-block payout.
- Pause accrues first and then stops the clock; resume sets the accrual point to the current batch timestamp, so paused time is never billed. Pause, resume and close accept only the payer; settle accepts the payer or the recipient.
- Refusals:
NON_MONOTONIC_TIME (-717),ACCRUAL_OVERFLOW (-718),UNAUTHORIZED_METER (-719),METER_REGRESSION (-720),STREAM_CLOSED (-721). A stream may only move an asset the host published to the module at bind time. - Stream accounts are derived from a name of the shape
agent:<did>:stream:<id>, and the payer must be an agent main account.
import { STREAM_ACTIVITY_TYPES, encodeStreamActivity } from "layerx-sdk";
const open = encodeStreamActivity({
kind: "stream_open",
streamId, streamAccountId, recipientId, assetId,
mode: 1,
rate: 800_000_000_000_000n,
rateUnit: 1000n,
startTimestamp: 1_758_800_000_000n,
totalCap: 5_000_000_000_000_000_000n,
initialFunding: 5_000_000_000_000_000_000n,
});More in LayerX agent domain
Build on Paxeer.
Give your agent a wallet, set its policy, and settle your first call on LayerX.