Token streaming and vesting protocol. Sablier Lockup (v2/v4) creates fixed-term linear, tranched, or dynamic streams (incl. price-gated unlocks); Sablier Flow handles open-ended streaming; Merkle Airdrops bundle vesting with claims. Streams are NFTs.
- 01team / investor vesting
- 02linear or cliff token unlocks
- 03merkle airdrops with vesting
- 04price-gated unlocks (Lockup v4)
- 05salary streaming (Flow)
- pnpm add @sablier/lockup viem
| Variable | Scope | Description |
|---|---|---|
| SABLIER_CHAIN_ID | Client | Numeric chain id. Sablier deploys per-chain Lockup, Flow, and MerkleFactory contracts — addresses live in the @sablier/deployments package. |
Use Sablier Lockup for fixed-term vesting. Approve the LockupLinear contract for the token amount, then call `createWithDurations({ sender, recipient, totalAmount, asset, cancelable, transferable, durations: { cliff, total }, broker })` — it mints an ERC-721 to the recipient representing the stream. For tranched/cliff schedules use `LockupTranched.createWithTimestamps`; for arbitrary curves use `LockupDynamic`. Recipients withdraw via `withdrawMax(streamId, to)` or `withdrawMaxAndTransfer`. For airdrops, deploy a campaign through `SablierMerkleFactory.createMerkleLL` (Lockup-Linear) or `createMerkleInstant` and recipients call `claim(index, recipient, amount, merkleProof)`. Read state from the GraphQL subgraph at `https://subgraphs.sablier.com`.
- ⚑Stream cancelability is set at creation — pass `cancelable: true` if you need to claw back; `false` makes the stream irrevocable forever.
- ⚑Lockup streams are ERC-721s; recipients can transfer them (when `transferable: true`) — gating airdrops on the original recipient address won't catch resold streams.
- ⚑v4 Lockup adds a `granularity` parameter on LockupLinear for fixed-period unlocks; passing `0` reverts to true linear (per-second) — the most common migration bug from v2.
- ⚑Price-Gated Lockup (LPG) requires a Chainlink price feed; unlocks fire once the feed crosses the trigger, not on a calendar — UI must show "unlocks at price X" not "unlocks at date Y".
- ⚑Merkle Lockup campaigns embed the stream parameters in the leaves — you cannot change cliff/duration after deploying the factory campaign without redeploying.
- ⚑Sablier on Solana is a separate program (Anchor) — EVM SDK calls do not apply.