Documentation
OPflow Docs
Everything you need to know about streaming OP20 tokens on Bitcoin L1.
Overview
OPflow enables continuous OP20 token streams on Bitcoin L1 via OP_NET smart contracts. Instead of sending a lump sum, you lock tokens in a stream that releases them to a recipient continuously over time — every Bitcoin block (~10 minutes).
The StreamManager contract custodies your OP20 tokens for the duration of the stream. On withdrawal, it transfers the earned portion directly to the recipient. On cancellation, it splits the remaining tokens between both parties. All state and math is computed on-chain.
Use Cases
- Salary streaming — pay your team by the block
- Token vesting — cliff + linear schedules for investors and teams
- Subscriptions — per-second SaaS payments
- DAO treasury — contributor grants with stepped unlocks
How It Works
Create a Stream
The sender deposits tokens into the StreamManager contract, specifying a recipient, amount, start block, end block, and curve type. The contract transfers the tokens from the sender and records the stream parameters.
Value Accrues
Every block, more tokens become claimable by the recipient. The exact amount depends on the stream's curve type — linear, cliff+linear, stepped, or exponential. The contract computes this on-chain using block heights.
Withdraw Anytime
The recipient can withdraw any amount up to their currently claimable balance at any time. No intermediaries, no delays — just a contract call. Partial withdrawals are supported.
Stream Types
OPflow supports four vesting curve types, each suited to different payment patterns.
Linear
earned = deposit × elapsed / duration
Constant rate over time. Best for salaries, subscriptions, and simple token distributions. The recipient earns the same amount every block.
Cliff + Linear
0 before cliff, then linear
Nothing is claimable until the cliff block. After the cliff, the full accrued amount since start unlocks at once, then continues linearly. Standard for employee token vesting.
Stepped
earned = deposit × completedSteps / totalSteps
Payments unlock in discrete steps of 144 blocks (~1 day). Creates a staircase pattern where value accumulates but only becomes claimable at step boundaries. Good for milestone-based payouts.
Exponential (Quadratic)
earned = deposit × (elapsed / duration)²
Early withdrawals are small, later ones are large. The quadratic curve front-loads accrual towards the end — ideal for retention incentives and back-weighted vesting.
Creating Streams
To create a stream, you need:
| Parameter | Type | Description |
|---|---|---|
| recipient | address | Who receives the stream |
| tokenAddress | address | OP20 token to stream |
| depositAmount | uint256 | Total amount to stream |
| startBlock | uint256 | Block height when stream begins |
| endBlock | uint256 | Block height when stream ends |
| cliffBlock | uint256 | Cliff block (0 = no cliff) |
| cancelable | uint256 | 1 = sender can cancel, 0 = locked |
| streamType | uint256 | 0=linear, 1=cliff, 2=stepped, 3=exponential |
Important
increaseAllowance. The OPflow app handles this automatically.Withdrawing
Only the stream's recipient can withdraw. Call withdraw(streamId, amount) with any amount up to the currently claimable balance.
- Partial withdrawals are supported — withdraw what you need, leave the rest
- When the full deposit has been claimed, the stream is automatically marked inactive
- Withdrawals transfer tokens directly to the recipient's address
Cancelling
If a stream was created with cancelable = 1, the sender can cancel it at any time. On cancellation:
- The recipient receives their earned but unclaimed tokens
- The sender is refunded the unearned remainder
- The stream is marked inactive — no further withdrawals are possible
Non-cancelable streams
cancelable = 0, the stream cannot be cancelled by anyone. The tokens are irrevocably committed to the vesting schedule. Use this for trustless token locks.Contract Reference
The StreamManager contract exposes the following methods:
(address, address, uint256, uint256, uint256, uint256, uint256, uint256)
Returns: uint256 (streamId)
(uint256 streamId, uint256 amount)
Returns: uint256 (remaining claimable)
(uint256 streamId)
Returns: uint256 (sender refund)
(uint256 streamId)
Returns: all stream fields
(uint256 streamId)
Returns: uint256 (claimable amount)
(address)
Returns: uint256[] (stream IDs)
(address)
Returns: uint256[] (stream IDs)
FAQ
What tokens can I stream?
Any OP20 token deployed on OP_NET. The token must support the standard allowance/transfer interface. Native BTC streaming is not yet supported but is planned.
What happens if I withdraw nothing for a long time?
Nothing changes — your claimable balance keeps growing. You can withdraw everything at once, even after the stream ends.
Can I stream Bitcoin directly?
Streams use OP20 tokens. To stream BTC value, use a wrapped BTC token (like WBTC) on OP_NET.
How precise is the timing?
Streams use Bitcoin block heights. Each block is ~10 minutes. The contract computes exact amounts using integer math with no rounding errors.
What if the recipient never withdraws?
The tokens remain locked in the contract. After the stream ends, 100% becomes claimable. There is no expiry.