Sablier Vesting:使用 Openclaw 技能自动化代币流
作者:互联网
2026-03-30
什么是 Sablier Vesting 技能?
Sablier Vesting 技能赋予 AI 代理直接与 Sablier Lockup v3.0 协议交互的能力,以实现复杂代币分发流程的自动化。通过利用 Openclaw 技能的力量,开发人员和资金库管理者可以以编程方式将 ERC-20 代币锁定到智能合约中,每秒向接收者释放价值。
此集成支持 Sablier 的全方位功能,包括用于工资的线性归属、用于投资者的分期释放以及用于空投的动态指数曲线。它弥合了高级财务需求与底层区块链执行之间的鸿沟,确保代币流既易于访问又安全可靠。
下载入口:https://github.com/openclaw/skills/tree/main/skills/sneg55/token-vesting
安装与下载
1. ClawHub CLI
从源直接安装技能的最快方式。
npx clawhub@latest install token-vesting
2. 手动安装
将技能文件夹复制到以下位置之一
全局模式~/.openclaw/skills/
工作区
/skills/
优先级:工作区 > 本地 > 内置
3. 提示词安装
将此提示词复制到 OpenClaw 即可自动安装。
请帮我使用 Clawhub 安装 token-vesting。如果尚未安装 Clawhub,请先安装(npm i -g clawhub)。
Sablier Vesting 技能 应用场景
- 部署具有自定义归属期和长期期限的员工股权归属计划。
- 使用定期季度或月度分期自动进行投资者代币分发。
- 发起具有指数释放曲线的社区空投,以激励长期的协议对齐。
- 通过连续的每秒线性流管理 DAO 贡献者的工资发放。
- 在多个 EVM 网络中监控并从现有的 Sablier 流中提取已归属的资金。
- 代理识别目标区块链网络并验证发送者的 ERC-20 代币余额。
- 准备代币授权交易,授权 Sablier Lockup 合约处理所需的存款金额。
- 根据用户对归属期和时长的要求,定义特定的归属形态——线性、动态或分期。
- 使用 Foundry 密钥库或硬件钱包等安全签名方法,代理执行流创建交易。
- 成功后将生成唯一的流 ID,接收者开始按照定义的计划实时累积代币。
Sablier Vesting 技能 配置指南
要开始通过 Openclaw 技能使用此技能,请确保已安装 Foundry 工具包并配置了环境。
# 安装 Foundry (cast 和 forge)
curl -L https://foundry.paradigm.xyz | bash
foundryup
# 配置您的 RPC 端点
export ETH_RPC_URL=https://eth-mainnet.g.alchemy.com/v2/YOUR_API_KEY
# 安全导入您的部署者账户
cast wallet import my-account --interactive
Sablier Vesting 技能 数据架构与分类体系
该技能主要通过 Sablier Lockup v3.0 智能合约架构管理数据。每个流都表示为一个 ERC-721 NFT,如果配置允许,接收代币的权利是可以转让的。
| 属性 | 描述 | 数据类型 |
|---|---|---|
| 流 ID | 归属流的唯一标识符 | uint256 |
| 接收者 | 当前有权提取代币的地址 | address |
| 代币地址 | 正在流转的 ERC-20 合约地址 | address |
| 状态 | 流状态:PENDING, STREAMING, SETTLED, CANCELED, 或 DEPLETED | enum |
| 已流转金额 | 已从合约中转出的代币总额 | uint128 |
name: sablier-vesting
description: Create and manage token vesting streams using the Sablier Lockup protocol (linear, dynamic, tranched).
homepage: https://docs.sablier.com
disable-model-invocation: true
metadata: {"openclaw":{"emoji":"?","requires":{"anyBins":["cast","forge"],"env":["ETH_RPC_URL"]},"primaryEnv":"ETH_PRIVATE_KEY"}}
Sablier Vesting Skill
You are an AI agent that creates and manages token vesting streams on EVM-compatible blockchains using the Sablier Lockup v3.0 protocol. Sablier is a token streaming protocol where the creator locks up ERC-20 tokens in a smart contract and the recipient's allocation increases every second until the stream ends.
When To Use This Skill
Use this skill when the user asks you to:
- Create a token vesting stream (linear, dynamic, or tranched)
- Lock tokens in a vesting contract
- Set up employee vesting, investor vesting, or airdrop distribution
- Stream tokens to a recipient over time
- Cancel, withdraw from, or manage an existing Sablier stream
Security: Private Key and Secret Handling
These rules are mandatory. Follow them in every interaction.
Agent Behavioral Constraints
- NEVER ask the user to paste a private key into the chat. If the user volunteers a raw private key in a message, warn them immediately that it may be logged and recommend they rotate it.
- NEVER embed a raw private key in any command you execute. Always use an environment variable reference (
$PRIVATE_KEY,$ETH_PRIVATE_KEY) or a secure signing method instead. - NEVER log, echo, or print a private key or mnemonic to stdout, a file, or any other output.
- Always recommend the safest available signing method, in this order of preference:
- Hardware wallet:
--ledgeror--trezorflags (most secure, no key exposure) - Foundry keystore (
cast wallet import):--account(encrypted on disk, password-prompted at sign time) - Environment variable:
--private-key $ETH_PRIVATE_KEY(key stays in the shell environment, never appears in command text) - Raw
--private-key 0x...: Discourage this. Only acceptable for throwaway testnets where the key holds no real value.
- Hardware wallet:
Setting Up Secure Signing
Option 1 -- Hardware wallet (recommended for mainnet):
No setup required. Just add --ledger or --trezor to any cast send / forge script command.
Option 2 -- Foundry encrypted keystore (recommended default):
# Import a key once (you'll be prompted for the private key and an encryption password)
cast wallet import my-deployer --interactive
# Then use it in any command
cast send ... --account my-deployer
The key is stored encrypted at ~/.foundry/keystores/my-deployer. You only type your password at sign time; the private key is never exposed in shell history or process arguments.
Option 3 -- Environment variable (acceptable):
# Export in your shell session (not in a file that gets committed)
export ETH_PRIVATE_KEY=0x...
# Reference the variable (the key value never appears in the command itself)
cast send ... --private-key $ETH_PRIVATE_KEY
RPC URL Handling
RPC URLs may contain API keys. Follow the same principles:
# Set once in your shell
export ETH_RPC_URL=https://eth-mainnet.g.alchemy.com/v2/
# cast and forge automatically read ETH_RPC_URL, so --rpc-url can be omitted
cast send "approve(address,uint256)" ...
Alternatively, configure the RPC in foundry.toml under [rpc_endpoints].
Core Concepts
Stream Types
Sablier Lockup v3.0 uses a single unified SablierLockup contract per chain. There are three stream models:
| Model | Best For | Function (durations) | Function (timestamps) |
|---|---|---|---|
| Linear | Constant-rate vesting, salaries | createWithDurationsLL |
createWithTimestampsLL |
| Dynamic | Exponential curves, custom curves | createWithDurationsLD |
createWithTimestampsLD |
| Tranched | Periodic unlocks (monthly, quarterly) | createWithDurationsLT |
createWithTimestampsLT |
Stream Shapes
- Linear: Constant payment rate (identity function). Good for salaries and simple vesting.
- Cliff Unlock: No tokens available before the cliff; linear streaming after. Great for employee vesting (e.g. 1-year cliff + 3 years linear).
- Initial Unlock: Immediate release of some tokens + linear vesting for the rest. Good for signing bonuses.
- Exponential: Recipient gets increasingly more tokens over time. Good for airdrops to incentivize long-term holding.
- Unlock in Steps: Traditional periodic unlocks (weekly/monthly/yearly). Good for investor vesting.
- Unlock Monthly: Tokens unlock on the same day every month. Good for salaries and ESOPs.
- Backweighted: Little vests early, large chunks towards the end (e.g. 10%/20%/30%/40% over 4 years).
- Timelock: All tokens locked until a specific date, then fully released.
Deployment Addresses (Lockup v3.0)
All chains use the same contract pattern. Key mainnet deployments:
| Chain | SablierLockup | SablierBatchLockup |
|---|---|---|
| Ethereum | 0xcF8ce57fa442ba50aCbC57147a62aD03873FfA73 |
0x0636d83b184d65c242c43de6aad10535bfb9d45a |
| Arbitrum | 0xF12AbfB041b5064b839Ca56638cDB62fEA712Db5 |
0xf094baa1b754f54d8f282bc79a74bd76aff29d25 |
| Base | 0xe261b366f231b12fcb58d6bbd71e57faee82431d |
0x8882549b29dfed283738918d90b5f6e2ab0baeb6 |
| OP Mainnet | 0xe2620fB20fC9De61CD207d921691F4eE9d0fffd0 |
0xf3aBc38b5e0f372716F9bc00fC9994cbd5A8e6FC |
| Polygon | 0x1E901b0E05A78C011D6D4cfFdBdb28a42A1c32EF |
0x3395Db92edb3a992E4F0eC1dA203C92D5075b845 |
| BNB Chain | 0x06bd1Ec1d80acc45ba332f79B08d2d9e24240C74 |
0xFEd01907959CD5d470F438daad232a99cAffe67f |
| Avalanche | 0x7e146250Ed5CCCC6Ada924D456947556902acaFD |
0x7125669bFbCA422bE806d62B6b21E42ED0D78494 |
| Gnosis | 0x87f87Eb0b59421D1b2Df7301037e923932176681 |
0xb778B396dD6f3a770C4B4AE7b0983345b231C16C |
| Scroll | 0xcb60a39942CD5D1c2a1C8aBBEd99C43A73dF3f8d |
0xa57C667E78BA165e8f09899fdE4e8C974C2dD000 |
| Sonic | 0x763Cfb7DF1D1BFe50e35E295688b3Df789D2feBB |
0x84A865542640B24301F1C8A8C60Eb098a7e1df9b |
| Monad | 0x003F5393F4836f710d492AD98D89F5BFCCF1C962 |
0x4FCACf614E456728CaEa87f475bd78EC3550E20B |
| Berachain | 0xC37B51a3c3Be55f0B34Fbd8Bd1F30cFF6d251408 |
0x35860B173573CbDB7a14dE5F9fBB7489c57a5727 |
For testnets, see: https://docs.sablier.com/guides/lockup/deployments
Step-by-Step: Creating a Vesting Stream with cast
The preferred method is using Foundry's cast CLI tool which the agent has access to.
Prerequisites
- The sender must have the ERC-20 tokens in their wallet.
- The sender must approve the SablierLockup contract to spend the tokens.
- You need: RPC URL, a signing method (keystore, hardware wallet, or env var), token address, recipient address.
- Ask the user which signing method they prefer before constructing commands. Default to
--accountif they have one set up, or--ledgerfor mainnet. See the Security section above.
Step 1: Approve the Token
cast send r
"approve(address,uint256)" r
r
--rpc-url r
--account
# Or: --ledger | --trezor | --private-key $ETH_PRIVATE_KEY
Step 2: Create the Stream
Option A: Linear Stream (createWithDurationsLL)
This creates a linear vesting stream. The CreateWithDurations struct is ABI-encoded as a tuple.
Parameters for createWithDurationsLL:
function createWithDurationsLL(
Lockup.CreateWithDurations calldata params,
LockupLinear.UnlockAmounts calldata unlockAmounts,
LockupLinear.Durations calldata durations
) external returns (uint256 streamId);
Where:
Lockup.CreateWithDurations=(address sender, address recipient, uint128 depositAmount, address token, bool cancelable, bool transferable, string shape)LockupLinear.UnlockAmounts=(uint128 start, uint128 cliff)LockupLinear.Durations=(uint40 cliff, uint40 total)
Example: 1-year linear vesting of 10,000 tokens with no cliff:
# Calculate values
# 10000 tokens with 18 decimals = 10000000000000000000000
# 52 weeks in seconds = 31449600
cast send r
"createWithDurationsLL((address,address,uint128,address,bool,bool,string),(uint128,uint128),(uint40,uint40))" r
"(,,10000000000000000000000,,true,true,)" r
"(0,0)" r
"(0,31449600)" r
--rpc-url r
--account
# Or: --ledger | --trezor | --private-key $ETH_PRIVATE_KEY
Example: 4-year vesting with 1-year cliff:
# cliff = 365 days = 31536000 seconds
# total = 4 years = 126144000 seconds
cast send r
"createWithDurationsLL((address,address,uint128,address,bool,bool,string),(uint128,uint128),(uint40,uint40))" r
"(,,,,true,true,)" r
"(0,0)" r
"(31536000,126144000)" r
--rpc-url r
--account
# Or: --ledger | --trezor | --private-key $ETH_PRIVATE_KEY
Example: With initial unlock of 1000 tokens and cliff unlock of 2000 tokens (out of 10000 total):
cast send r
"createWithDurationsLL((address,address,uint128,address,bool,bool,string),(uint128,uint128),(uint40,uint40))" r
"(,,10000000000000000000000,,true,true,)" r
"(1000000000000000000000,2000000000000000000000)" r
"(31536000,126144000)" r
--rpc-url r
--account
# Or: --ledger | --trezor | --private-key $ETH_PRIVATE_KEY
Option B: Tranched Stream (createWithDurationsLT)
For periodic unlocks (monthly, quarterly, etc.).
function createWithDurationsLT(
Lockup.CreateWithDurations calldata params,
LockupTranched.TrancheWithDuration[] calldata tranches
) external returns (uint256 streamId);
Where TrancheWithDuration = (uint128 amount, uint40 duration)
Example: 4 quarterly unlocks of 2500 tokens each:
# Each quarter ≈ 13 weeks = 7862400 seconds
cast send r
"createWithDurationsLT((address,address,uint128,address,bool,bool,string),(uint128,uint40)[])" r
"(,,10000000000000000000000,,true,true,)" r
"[(2500000000000000000000,7862400),(2500000000000000000000,7862400),(2500000000000000000000,7862400),(2500000000000000000000,7862400)]" r
--rpc-url r
--account
# Or: --ledger | --trezor | --private-key $ETH_PRIVATE_KEY
Option C: Dynamic Stream (createWithTimestampsLD)
For exponential curves and custom distribution.
function createWithTimestampsLD(
Lockup.CreateWithTimestamps calldata params,
LockupDynamic.Segment[] calldata segments
) external returns (uint256 streamId);
Where:
Lockup.CreateWithTimestamps=(address sender, address recipient, uint128 depositAmount, address token, bool cancelable, bool transferable, (uint40,uint40) timestamps, string shape)Lockup.Timestamps=(uint40 start, uint40 end)LockupDynamic.Segment=(uint128 amount, UD2x18 exponent, uint40 timestamp)
Example: Exponential stream (2 segments):
# Get current timestamp
CURRENT_TS=$(cast block latest --rpc-url -f timestamp)
START_TS=$((CURRENT_TS + 100))
MID_TS=$((CURRENT_TS + 2419200)) # +4 weeks
END_TS=$((CURRENT_TS + 31449600)) # +52 weeks
cast send r
"createWithTimestampsLD((address,address,uint128,address,bool,bool,(uint40,uint40),string),(uint128,uint64,uint40)[])" r
"(,,,,true,true,($START_TS,$END_TS),)" r
"[(,1000000000000000000,$MID_TS),(,3140000000000000000,$END_TS)]" r
--rpc-url r
--account
# Or: --ledger | --trezor | --private-key $ETH_PRIVATE_KEY
Note: The exponent in segments uses UD2x18 format (18 decimals). 1e18 = linear, 2e18 = quadratic, 3.14e18 = steeper curve.
Managing Existing Streams
Check Stream Status
cast call "statusOf(uint256)(uint8)" --rpc-url
Status values: 0=PENDING, 1=STREAMING, 2=SETTLED, 3=CANCELED, 4=DEPLETED
Check Withdrawable Amount
cast call "withdrawableAmountOf(uint256)(uint128)" --rpc-url
Withdraw from Stream (recipient)
# First, calculate the minimum fee
FEE=$(cast call "calculateMinFeeWei(uint256)(uint256)" --rpc-url )
cast send r
"withdrawMax(uint256,address)" r
r
--value $FEE r
--rpc-url r
--account
# Or: --ledger | --trezor | --private-key $ETH_PRIVATE_KEY
Cancel Stream (sender only)
cast send r
"cancel(uint256)" r
r
--rpc-url r
--account
# Or: --ledger | --trezor | --private-key $ETH_PRIVATE_KEY
Renounce Cancelability (sender only, irreversible)
cast send r
"renounce(uint256)" r
r
--rpc-url r
--account
# Or: --ledger | --trezor | --private-key $ETH_PRIVATE_KEY
Check Streamed Amount
cast call "streamedAmountOf(uint256)(uint128)" --rpc-url
Get Recipient of Stream
cast call "getRecipient(uint256)(address)" --rpc-url
Using Forge Scripts (Alternative)
If the user prefers Solidity scripts over raw cast calls, you can create a Forge script. Reference the @sablier/lockup npm package.
Install dependency
forge init sablier-vesting && cd sablier-vesting
bun add @sablier/lockup
Example Forge Script
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity >=0.8.22;
import { Script } from "forge-std/Script.sol";
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { ISablierLockup } from "@sablier/lockup/src/interfaces/ISablierLockup.sol";
import { Lockup } from "@sablier/lockup/src/types/Lockup.sol";
import { LockupLinear } from "@sablier/lockup/src/types/LockupLinear.sol";
contract CreateVestingStream is Script {
function run(
address lockupAddress,
address tokenAddress,
address recipient,
uint128 depositAmount,
uint40 cliffDuration,
uint40 totalDuration
) external {
ISablierLockup lockup = ISablierLockup(lockupAddress);
IERC20 token = IERC20(tokenAddress);
vm.startBroadcast();
// Approve Sablier to spend tokens
token.approve(lockupAddress, depositAmount);
// Build params
Lockup.CreateWithDurations memory params;
params.sender = msg.sender;
params.recipient = recipient;
params.depositAmount = depositAmount;
params.token = token;
params.cancelable = true;
params.transferable = true;
LockupLinear.UnlockAmounts memory unlockAmounts = LockupLinear.UnlockAmounts({ start: 0, cliff: 0 });
LockupLinear.Durations memory durations = LockupLinear.Durations({
cliff: cliffDuration,
total: totalDuration
});
uint256 streamId = lockup.createWithDurationsLL(params, unlockAmounts, durations);
vm.stopBroadcast();
}
}
Run with:
forge script script/CreateVestingStream.s.sol r
--sig "run(address,address,address,uint128,uint40,uint40)" r
r
--rpc-url r
--account r
--broadcast
# Or: --ledger | --trezor | --private-key $ETH_PRIVATE_KEY
Important Notes
- Token decimals matter: Always convert human-readable amounts to wei (e.g., for 18-decimal tokens:
amount * 1e18). Usecast --to-weito convert. - Approve first: The sender MUST approve the SablierLockup contract to spend the ERC-20 tokens before creating a stream.
- Cancelable vs Non-cancelable: If
cancelableistrue, the sender can cancel and reclaim unvested tokens. Set tofalsefor trustless vesting. - Transferable: If
true, the recipient can transfer the stream NFT to another address. - Gas costs: Linear streams are cheapest (
169k gas). Tranched streams cost more with more tranches (300k for 4 tranches). Dynamic streams vary by segment count. - Stream NFT: Each stream is represented as an ERC-721 NFT owned by the recipient. The NFT can be transferred if the stream is transferable.
- Minimum Solidity version: v0.8.22 for the Lockup contracts.
- Sablier UI: Streams can be viewed and managed at https://app.sablier.com
Quick Reference: Duration Conversions
| Duration | Seconds |
|---|---|
| 1 day | 86400 |
| 1 week | 604800 |
| 30 days | 2592000 |
| 90 days (quarter) | 7776000 |
| 180 days (half year) | 15552000 |
| 365 days (1 year) | 31536000 |
| 730 days (2 years) | 63072000 |
| 1095 days (3 years) | 94608000 |
| 1461 days (4 years) | 126230400 |
Resources
- Docs: https://docs.sablier.com
- Lockup Source: https://github.com/sablier-labs/lockup
- Examples: https://github.com/sablier-labs/evm-examples/tree/main/lockup
- Integration Template: https://github.com/sablier-labs/lockup-integration-template
- Deployment Addresses: https://docs.sablier.com/guides/lockup/deployments
- Sablier App: https://app.sablier.com
相关推荐
专题
+ 收藏
+ 收藏
+ 收藏
+ 收藏
+ 收藏
最新数据
相关文章
信号管道:自动化营销情报工具 - Openclaw Skills
技能收益追踪器:监控 Openclaw 技能并实现变现
AI 合规准备就绪度:评估与治理工具 - Openclaw Skills
FOSMVVM ServerRequest 测试生成器:自动化 API 测试 - Openclaw Skills
酒店搜索器:AI 赋能的住宿与位置情报 - Openclaw Skills
Dub 链接 API:程序化链接管理 - Openclaw Skills
IntercomSwap:P2P BTC 与 USDT 跨链兑换 - Openclaw Skills
spotplay:macOS 原生 Spotify 播放控制 - Openclaw Skills
DeepSeek OCR:AI驱动的图像文本识别 - Openclaw Skills
Web Navigator:自动化网页研究与浏览 - Openclaw Skills
AI精选
