降雨 SDK 时速
TypeScript SDK用于Arbitrum One上的雨预测-市场协议.
建立、签署和发送预测的市场交易——从创造市场和贸易选择到声称胜出和流出现场事件.
建筑
┌──────────────────────────────────────────────────────────┐
│ Your Application │
├────────────────────────┬─────────────────────────────────┤
│ Rain │ RainAA │
│ (WHAT to do) │ (HOW to execute) │
│ │ │
│ • Market queries │ • Smart account creation │
│ • Tx builders │ • Gas-sponsored execution │
│ • Position reads │ • Tx submission │
│ • WebSocket streams │ • Session management │
│ • Analytics │ │
├────────────────────────┴─────────────────────────────────┤
│ RawTransaction │
│ { to, data, value? } │
├──────────────────────────────────────────────────────────┤
│ Arbitrum One (on-chain) │
│ Diamond Proxy Pools + AMM per option │
└──────────────────────────────────────────────────────────┘
SDK分为两个独立类:
Rain——无国籍. 获取数据,构建未签名的交易,订阅事件. 不需要钱包.RainAA——国事. 管理Alchemy智能账户,通过账户抽象签名并发送交易.
所有交易建立者返回 a RawTransaction - 打电话者决定如何执行(通过 RainAA或任何供应商.
安装
npm install @buidlrrr/rain-sdk
同伴依赖关系数字 : viem ^2.0.0
快速启动
import { Rain, RainAA } from '@buidlrrr/rain-sdk';
// 1. Initialize (stateless — no wallet needed)
const rain = new Rain({ environment: 'development' });
// 2. Fetch markets
const markets = await rain.getPublicMarkets({ limit: 10 });
// 3. Build a buy transaction
const rawTx = rain.buildBuyOptionRawTx({
marketContractAddress: '0x...',
selectedOption: 1n,
buyAmountInWei: 10_000_000n, // 10 USDT (6 decimals)
});
// 4. Execute via your provider, OR via RainAA:
await yourProvider.sendTransaction(rawTx);
配置
const rain = new Rain({
environment: 'development', // 'development' | 'stage' | 'production'
rpcUrl: 'https://...', // Optional — defaults to public Arbitrum RPCs
wsRpcUrl: 'wss://...', // Required for subscribeToMarketEvents / subscribePriceUpdates
subgraphUrl: 'https://...', // Required for transaction history / price history / analytics
subgraphApiKey: '...', // Optional — TheGraph API key
wsReconnect: { attempts: 5, delay: 1000 }, // Optional — WebSocket auto-reconnect
});
环境
| 环境 | API 密码 | 工厂地址 |
|---|---|---|
development | dev-api.rain.one | 0x05b1fd504583B81bd14c368d59E8c3e354b6C1dc |
stage | stg-api.rain.one | 0xD4900CA167228365806FBA4cB21f7EAe8b6d96BE |
production | prod-api.rain.one | 0xA8640B62D755e42C9ed6A86d0fc65CE09e31F264 |
API 参考
市场查询
getPublicMarkets(params) ——浏览市场
const markets = await rain.getPublicMarkets({
limit: 12,
offset: 0,
sortBy: 'Liquidity', // 'Liquidity' | 'Volumn' | 'latest'
status: 'Live', // 'Live' | 'Trading' | 'Closed' | ...
creator: '0x...', // Optional — filter by creator
});
// Returns: Market[]
// { id, title, totalVolume, status, contractAddress, poolOwnerWalletAddress }
getMarketDetails(marketId) ——全市数据
将雨的API数据与链上读取从菱形代理读取.
const details = await rain.getMarketDetails('698c8f116e985bbfacc7fc01');
// Returns: MarketDetails
// {
// id, title, status, contractAddress,
// options: [{ choiceIndex, optionName, currentPrice, totalFunds, totalVotes }],
// poolState, numberOfOptions, startTime, endTime, oracleEndTime,
// allFunds, allVotes, totalLiquidity, winner, poolFinalized,
// isPublic, baseToken, baseTokenDecimals, poolOwner, resolver,
// resolverIsAI, isDisputed, isAppealed
// }
getMarketPrices(marketId) ——现行期权价格
const prices = await rain.getMarketPrices('698c8f116e985bbfacc7fc01');
// Returns: OptionPrice[]
// [{ choiceIndex: 0, optionName: 'Yes', currentPrice: 650000000000000000n }]
// currentPrice is in 1e18 — divide by 1e18 for decimal (0.65 = 65%)
getMarketVolume(marketId) - 数量细目
const volume = await rain.getMarketVolume('698c8f116e985bbfacc7fc01');
// Returns: MarketVolume
// { marketId, contractAddress, totalVolume, optionVolumes: [{ choiceIndex, optionName, volume }] }
getMarketLiquidity(marketId) - 流动性和订单簿
const liq = await rain.getMarketLiquidity('698c8f116e985bbfacc7fc01');
// Returns: MarketLiquidity
// { marketId, contractAddress, totalLiquidity, allFunds,
// optionLiquidity: [{ choiceIndex, optionName, totalFunds, firstBuyOrderPrice, firstSellOrderPrice }] }
getMarketAddress(marketId) 编号 : getMarketId(marketAddress) ——身份证/地址查询
const address = await rain.getMarketAddress('698c8f116e985bbfacc7fc01');
const id = await rain.getMarketId('0xd262abd3d58038e15736Ec32c4F7b020C2B21dB5');
getProtocolStats() ——全议定书衡量标准
const stats = await rain.getProtocolStats();
// Returns: ProtocolStats
// { tvl, totalVolume, activeMarkets, totalMarkets, uniqueTraders }
交易构建器
所有建筑师返回 RawTransaction —— 说 { to, data, value? }。他们会 没有 发送交易.
buildApprovalTx(params) - ERC20核准
const tx = rain.buildApprovalTx({
tokenAddress: '0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9', // USDT
spender: '0x...', // market contract address
amount: 100_000_000n, // Optional — defaults to max uint256
});
buildCreateMarketTx(params) ——创建市场
返回数组 : [approveTx, createTx] 如果需要批准,或 [createTx] 如果已经批准.
const txs = await rain.buildCreateMarketTx({
marketQuestion: 'Will BTC hit 100k?',
marketOptions: ['Yes', 'No'],
marketTags: ['crypto', 'bitcoin'],
marketDescription: 'Prediction market for BTC price',
isPublic: true,
isPublicPoolResolverAi: false,
creator: '0x996ea23940f4a01610181D04bdB6F862719b63f0',
startTime: 1770836400n,
endTime: 1770922800n,
no_of_options: 2n,
inputAmountWei: 100_000_000n, // 100 USDT (min 10 tokens)
barValues: [50, 50], // Initial probability distribution (%)
baseToken: '0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9',
tokenDecimals: 6,
});
// Execute sequentially
for (const tx of txs) {
await provider.sendTransaction(tx);
}
buildBuyOptionRawTx(params) - 市场购买
const tx = rain.buildBuyOptionRawTx({
marketContractAddress: '0x...',
selectedOption: 1n, // Option index (bigint)
buyAmountInWei: 10_000_000n, // 10 USDT
});
buildLimitBuyOptionTx(params) - 限制购买订单
const tx = rain.buildLimitBuyOptionTx({
marketContractAddress: '0x...',
selectedOption: 1,
pricePerShare: 500000000000000000n, // 0.50 in 1e18
buyAmountInWei: 10_000_000n,
tokenDecimals: 6,
});
buildSellOptionTx(params) - 地点销售订单
const tx = rain.buildSellOptionTx({
marketContractAddress: '0x...',
selectedOption: 1,
pricePerShare: 0.75, // Target price (0-1)
shares: 5_000_000n, // Shares to sell
tokenDecimals: 6,
});
buildCancelBuyOrdersTx(params) 编号 : buildCancelSellOrdersTx(params) - 取消订单
const tx = rain.buildCancelBuyOrdersTx({
marketContractAddress: '0x...',
orders: [
{ option: 1, price: 0.5, orderID: 1n },
{ option: 1, price: 0.6, orderID: 2n },
],
});
buildAddLiquidityTx(params) - 提供流动性
const tx = rain.buildAddLiquidityTx({
marketContractAddress: '0x...',
liquidityAmountInWei: 100_000_000n, // 100 USDT
});
注:流动性一直锁定到市场解析为止。 没有
removeLiquidity- 液化石油气公司通过下列方式收回其份额:buildClaimTx在决议通过后.
buildClaimTx(params) - 索赔胜诉
const tx = await rain.buildClaimTx({
marketId: '698c8f116e985bbfacc7fc01',
walletAddress: '0x996ea23940f4a01610181D04bdB6F862719b63f0',
});
buildResolveMarketTx(params) - 解决市场(管理人员)
将 Close + 选择赢家组合到多步交易阵列中.
const txs = await rain.buildResolveMarketTx({
marketId: '698c8f116e985bbfacc7fc01',
winningOption: 1, // 1-indexed
});
for (const tx of txs) {
await provider.sendTransaction(tx);
}
还可采取个别步骤: buildCloseMarketTx(params) 财务报告和审定财务报表 buildChooseWinnerTx(params)。 。 。 .
buildDepositToSmartAccountTx(params) 编号 : buildWithdrawFromSmartAccountTx(params)
// Deposit: EOA → Smart Account
const depositTx = rain.buildDepositToSmartAccountTx({
tokenAddress: '0x...USDT',
smartAccountAddress: '0x...smartAccount',
amount: 50_000_000n,
});
// Withdraw: Smart Account → EOA
const withdrawTx = rain.buildWithdrawFromSmartAccountTx({
tokenAddress: '0x...USDT',
eoaAddress: '0x...eoa',
amount: 50_000_000n,
});
位置和组合
getPositions(address) ——全市所有据点
const positions = await rain.getPositions('0x...');
// Returns: PositionsResult
// { address, markets: [{ marketId, title, status, contractAddress,
// options: [{ choiceIndex, optionName, shares, sharesInEscrow, amountInEscrow, currentPrice }],
// userLiquidity, claimed, dynamicPayout }] }
getPositionByMarket(address, marketId) ——单一市场状况
const pos = await rain.getPositionByMarket('0x...', '698c8f116e985bbfacc7fc01');
// Returns: PositionByMarket (same shape as a single MarketPosition)
getLPPosition(address, marketId) - LP位置细节
const lp = await rain.getLPPosition('0x...', '698c8f116e985bbfacc7fc01');
// Returns: LPPosition
// { marketId, title, status, contractAddress,
// userLiquidity, totalLiquidity, poolShareBps, liquidityShareBps }
getPortfolioValue(params) - 组合总额
const portfolio = await rain.getPortfolioValue({
address: '0x...',
tokenAddresses: ['0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9'], // USDT
});
// Returns: PortfolioValue
// { address, tokenBalances, positions: [{ marketId, title, dynamicPayout, totalPositionValue }],
// totalPositionValue }
dynamicPayout 每个选项 : [0, 804164316, 0, 0] 如果选项1获胜,则表示~804 UDT支付.
账户管理
getSmartAccountBalance(params) - 库存平衡
const balance = await rain.getSmartAccountBalance({
address: '0x...',
tokenAddresses: ['0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9'],
});
// Returns: AccountBalanceResult { address, balances: [{ token, balance, decimals }] }
getEOAFromSmartAccount(smartAccountAddress) - 反向检索
const eoa = await rain.getEOAFromSmartAccount('0x...smartAccount');
// Returns: '0x...eoa'
交易历史
要求数 subgraphUrl 在构造器配置(或per-method 覆盖)中.
getTransactions(params) ——钱包交易历史
const txs = await rain.getTransactions({
address: '0x...',
first: 20,
skip: 0,
orderBy: 'timestamp',
orderDirection: 'desc',
});
getTransactionDetails(params) ——解码单一交易
const details = await rain.getTransactionDetails({ txHash: '0x...' });
getMarketTransactions(params) - 市场上的所有交易
const trades = await rain.getMarketTransactions({
marketAddress: '0x...',
first: 50,
});
getTradeHistory(params) ——用户在特定市场进行交易
const history = await rain.getTradeHistory({
address: '0x...',
marketAddress: '0x...',
});
分析
getPriceHistory(params) - OHLC蜡烛数据
const candles = await rain.getPriceHistory({
marketAddress: '0x...',
interval: '1h', // '5m' | '15m' | '1h' | '4h' | '1d'
option: 0,
});
// Returns: PriceHistoryResult { candles: [{ open, high, low, close, timestamp }] }
getPnL(params) - 已实现和未实现的P&L
const pnl = await rain.getPnL({
address: '0x...',
marketId: '...', // Optional — omit for aggregate
});
getLeaderboard(params) - 顶级贸易商
const leaders = await rain.getLeaderboard({
timeframe: '7d', // '24h' | '7d' | '30d' | 'all'
sortBy: 'pnl', // 'pnl' | 'volume' | 'winRate'
first: 10,
});
网页订阅
要求数 wsRpcUrl 在构造器配置中.
subscribeToMarketEvents(params) ——连锁直播活动
const rain = new Rain({
environment: 'development',
wsRpcUrl: 'wss://arbitrum-one-rpc.publicnode.com',
});
const unsubscribe = rain.subscribeToMarketEvents({
marketAddress: '0x...',
eventNames: ['EnterOption', 'Sync'], // Optional filter — omit for all events
onEvent: (event) => {
console.log(event.eventName, event.args);
},
onError: (err) => console.error(err),
});
// Stop listening
unsubscribe();
可用事件 :
| 类别 | 活动 |
|---|---|
| 行业 | EnterOption, (中文(简体) ), PlaceBuyOrder, (中文(简体) ), PlaceSellOrder, (中文(简体) ), ExecuteBuyOrder, (中文(简体) ), ExecuteSellOrder, (中文(简体) ), CancelBuyOrder, (中文(简体) ), CancelSellOrder |
| 价格同步 | Sync ——AMM储备再平衡(每个行业每对选项一次) |
| 生命周期 | Claim, (中文(简体) ), ChooseWinner, (中文(简体) ), ClosePool |
subscribePriceUpdates(params) ——实时价格饲料
const unsubscribe = rain.subscribePriceUpdates({
marketAddress: '0x...',
onPriceUpdate: (update) => {
// update.prices: OptionPrice[] — fresh prices after each trade
// update.triggeredBy: MarketTradeEvent — the event that caused the update
console.log(update.prices);
},
onError: (err) => console.error(err),
});
destroyWebSocket() ——清理
await rain.destroyWebSocket();
RainAA——账户摘要
RainAA 用天然气赞助管理Alchemy智能账户.
import { RainAA } from '@buidlrrr/rain-sdk';
import { arbitrum } from 'viem/chains';
const rainAA = new RainAA({
walletClient: yourWalletClient, // viem WalletClient
alchemyApiKey: 'your-alchemy-key',
paymasterPolicyId: 'your-policy-id',
chain: arbitrum,
rpcUrl: 'https://...', // Optional
});
// Connect — derives smart account from EOA
const smartAccountAddress = await rainAA.connect();
console.log('Smart account:', smartAccountAddress);
// Send transactions built by Rain
const rain = new Rain({ environment: 'production' });
const rawTx = rain.buildBuyOptionRawTx({ ... });
const txHash = await rainAA.sendTransaction(rawTx);
// Accessors
rainAA.address; // Smart account address (throws if not connected)
rainAA.client; // Underlying AA client (throws if not connected)
// Disconnect
rainAA.disconnect();
流动:雨+雨AA 一起来
// 1. Rain builds the transaction (WHAT)
const rawTx = rain.buildBuyOptionRawTx({
marketContractAddress: '0x...',
selectedOption: 1n,
buyAmountInWei: 10_000_000n,
});
// 2. RainAA sends it via smart account (HOW)
const txHash = await rainAA.sendTransaction(rawTx);
数据来源
SDK根据方法从三个来源读取:
| 来源 | 用于 | 配置 |
|---|---|---|
| 雨类API | getPublicMarkets, (中文(简体) ), getMarketDetails (部分), buildClaimTx, (中文(简体) ), buildCreateMarketTx | environment (自动) |
| 链上 | getMarketPrices, (中文(简体) ), getMarketVolume, (中文(简体) ), getPositions,所有 tx 构建器 | rpcUrl (自动选定) |
| 子图 | getTransactions, (中文(简体) ), getPriceHistory, (中文(简体) ), getPnL, (中文(简体) ), getLeaderboard | subgraphUrl + 键 subgraphApiKey |
如果 subgraphUrl 未配置.
密钥类型
// Core transaction type — returned by all builders
interface RawTransaction {
to: `0x${string}`;
data: `0x${string}`;
value?: bigint;
}
// Market from listing endpoint
interface Market {
id: string;
title: string;
totalVolume: string;
status: MarketStatus;
contractAddress?: string;
}
// Full market details (API + on-chain)
interface MarketDetails {
id: string;
title: string;
status: MarketStatus;
contractAddress: `0x${string}`;
options: MarketOption[];
poolState: number;
numberOfOptions: bigint;
startTime: bigint;
endTime: bigint;
totalLiquidity: bigint;
// ... and more
}
// Position data per market
interface MarketPosition {
marketId: string;
title: string;
options: OptionPosition[];
userLiquidity: bigint;
claimed: boolean;
dynamicPayout: bigint[];
}
// WebSocket event payload
interface MarketTradeEvent {
eventName: MarketEventName;
marketAddress: `0x${string}`;
blockNumber: bigint;
transactionHash: `0x${string}`;
logIndex: number;
args: Record<string, unknown>;
}
type MarketStatus = 'Live' | 'New' | 'WaitingForResult' | 'UnderDispute' |
'UnderAppeal' | 'ClosingSoon' | 'InReview' | 'InEvaluation' | 'Closed' | 'Trading';
完全方法参考
雨类
| 类别 | 方法 | 回返 | 自动同步 |
|---|---|---|---|
| 市场 | getPublicMarkets(params) | Market[] | 对 |
getMarketDetails(marketId) | MarketDetails | 对 | |
getMarketPrices(marketId) | OptionPrice[] | 对 | |
getMarketVolume(marketId) | MarketVolume | 对 | |
getMarketLiquidity(marketId) | MarketLiquidity | 对 | |
getMarketAddress(marketId) | 0x${string} | 对 | |
getMarketId(marketAddress) | string | 对 | |
getProtocolStats() | ProtocolStats | 对 | |
| Tx 构建器 | buildApprovalTx(params) | RawTransaction | 没有 |
buildCreateMarketTx(params) | RawTransaction[] | 对 | |
buildBuyOptionRawTx(params) | RawTransaction | 没有 | |
buildLimitBuyOptionTx(params) | RawTransaction | 没有 | |
buildSellOptionTx(params) | RawTransaction | 没有 | |
buildCancelBuyOrdersTx(params) | RawTransaction | 没有 | |
buildCancelSellOrdersTx(params) | RawTransaction | 没有 | |
buildAddLiquidityTx(params) | RawTransaction | 没有 | |
buildClaimTx(params) | RawTransaction | 对 | |
buildCloseMarketTx(params) | RawTransaction | 对 | |
buildChooseWinnerTx(params) | RawTransaction | 对 | |
buildResolveMarketTx(params) | RawTransaction[] | 对 | |
buildDepositToSmartAccountTx(p) | RawTransaction | 没有 | |
buildWithdrawFromSmartAccountTx(p) | RawTransaction | 没有 | |
| 职位 | getPositions(address) | PositionsResult | 对 |
getPositionByMarket(addr, id) | PositionByMarket | 对 | |
getLPPosition(addr, id) | LPPosition | 对 | |
getPortfolioValue(params) | PortfolioValue | 对 | |
| 账户 | getSmartAccountBalance(params) | AccountBalanceResult | 对 |
getEOAFromSmartAccount(addr) | 0x${string} | 对 | |
| Tx 历史 | getTransactions(params) | TransactionsResult | 对 |
getTransactionDetails(params) | TransactionDetails | 对 | |
getMarketTransactions(params) | MarketTransactionsResult | 对 | |
getTradeHistory(params) | TradeHistoryResult | 对 | |
| 分析 | getPriceHistory(params) | PriceHistoryResult | 对 |
getPnL(params) | PnLResult | 对 | |
getLeaderboard(params) | LeaderboardResult | 对 | |
| 网络安全套 | subscribeToMarketEvents(params) | Unsubscribe | 没有 |
subscribePriceUpdates(params) | Unsubscribe | 没有 | |
destroyWebSocket() | void | 对 |
雨A级
| 方法 | 回返 | 自动同步 |
|---|---|---|
connect() | 0x${string} | 对 |
sendTransaction(tx) | 0x${string} (哈什语) | 对 |
disconnect() | void | 没有 |
.address | 0x${string} | —— 说 |
.client | 智能钱包客户端 | —— 说 |
发展
# Build
cd rain-sdk && npm run build
# Watch mode
npm run dev
# Run tests
npm test
# Integration tests
npm run test:integration