rain-sdk-v2 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1074 -0
- package/dist/Rain.d.ts +212 -0
- package/dist/Rain.js +401 -0
- package/dist/RainAA.d.ts +62 -0
- package/dist/RainAA.js +304 -0
- package/dist/abi/CreateMarketAbi.d.ts +1125 -0
- package/dist/abi/CreateMarketAbi.js +1 -0
- package/dist/abi/ERC20Abi.d.ts +89 -0
- package/dist/abi/ERC20Abi.js +119 -0
- package/dist/abi/MarketsAbi.d.ts +2810 -0
- package/dist/abi/MarketsAbi.js +1 -0
- package/dist/abi/OracleAbi.d.ts +11 -0
- package/dist/abi/OracleAbi.js +15 -0
- package/dist/api/comments.d.ts +14 -0
- package/dist/api/comments.js +48 -0
- package/dist/api/dispute.d.ts +3 -0
- package/dist/api/dispute.js +30 -0
- package/dist/api/follow.d.ts +6 -0
- package/dist/api/follow.js +38 -0
- package/dist/api/helpers.d.ts +4 -0
- package/dist/api/helpers.js +26 -0
- package/dist/api/index.d.ts +14 -0
- package/dist/api/index.js +14 -0
- package/dist/api/investments.d.ts +21 -0
- package/dist/api/investments.js +135 -0
- package/dist/api/notifications.d.ts +4 -0
- package/dist/api/notifications.js +24 -0
- package/dist/api/orders.d.ts +8 -0
- package/dist/api/orders.js +40 -0
- package/dist/api/points.d.ts +5 -0
- package/dist/api/points.js +32 -0
- package/dist/api/poolReviews.d.ts +4 -0
- package/dist/api/poolReviews.js +23 -0
- package/dist/api/pools.d.ts +41 -0
- package/dist/api/pools.js +149 -0
- package/dist/api/priceData.d.ts +2 -0
- package/dist/api/priceData.js +9 -0
- package/dist/api/rainBurn.d.ts +3 -0
- package/dist/api/rainBurn.js +15 -0
- package/dist/api/types.d.ts +292 -0
- package/dist/api/types.js +2 -0
- package/dist/api/users.d.ts +15 -0
- package/dist/api/users.js +60 -0
- package/dist/auth/login.d.ts +4 -0
- package/dist/auth/login.js +27 -0
- package/dist/auth/types.d.ts +16 -0
- package/dist/auth/types.js +1 -0
- package/dist/config/environments.d.ts +15 -0
- package/dist/config/environments.js +41 -0
- package/dist/constants/contractmethods.d.ts +15 -0
- package/dist/constants/contractmethods.js +15 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +6 -0
- package/dist/markets/getDisputeFee.d.ts +5 -0
- package/dist/markets/getDisputeFee.js +19 -0
- package/dist/markets/getOrderInfo.d.ts +53 -0
- package/dist/markets/getOrderInfo.js +80 -0
- package/dist/markets/getResolverBondAmount.d.ts +9 -0
- package/dist/markets/getResolverBondAmount.js +35 -0
- package/dist/markets/getUserOptionLPShares.d.ts +7 -0
- package/dist/markets/getUserOptionLPShares.js +17 -0
- package/dist/markets/getUserOptionShares.d.ts +8 -0
- package/dist/markets/getUserOptionShares.js +17 -0
- package/dist/socket/RainSocket.d.ts +175 -0
- package/dist/socket/RainSocket.js +186 -0
- package/dist/tx/CreateMarket/buildCreateMarketRawTx.d.ts +2 -0
- package/dist/tx/CreateMarket/buildCreateMarketRawTx.js +55 -0
- package/dist/tx/CreateMarket/createMarketValidation.d.ts +2 -0
- package/dist/tx/CreateMarket/createMarketValidation.js +48 -0
- package/dist/tx/CreateMarket/helpers.d.ts +3 -0
- package/dist/tx/CreateMarket/helpers.js +42 -0
- package/dist/tx/buildAddLiquidityRawTx.d.ts +2 -0
- package/dist/tx/buildAddLiquidityRawTx.js +23 -0
- package/dist/tx/buildApprovalRawTx.d.ts +2 -0
- package/dist/tx/buildApprovalRawTx.js +24 -0
- package/dist/tx/buildCalculateWinnerRawTx.d.ts +13 -0
- package/dist/tx/buildCalculateWinnerRawTx.js +37 -0
- package/dist/tx/buildCancelOrdersRawTx.d.ts +3 -0
- package/dist/tx/buildCancelOrdersRawTx.js +43 -0
- package/dist/tx/buildClaimRawTx.d.ts +2 -0
- package/dist/tx/buildClaimRawTx.js +19 -0
- package/dist/tx/buildClosePoolRawTx.d.ts +20 -0
- package/dist/tx/buildClosePoolRawTx.js +95 -0
- package/dist/tx/buildEnterOptionRawTx.d.ts +2 -0
- package/dist/tx/buildEnterOptionRawTx.js +25 -0
- package/dist/tx/buildMergeRawTx.d.ts +2 -0
- package/dist/tx/buildMergeRawTx.js +21 -0
- package/dist/tx/buildOpenDisputeRawTx.d.ts +8 -0
- package/dist/tx/buildOpenDisputeRawTx.js +39 -0
- package/dist/tx/buildPlaceOrderRawTx.d.ts +3 -0
- package/dist/tx/buildPlaceOrderRawTx.js +47 -0
- package/dist/tx/buildRemoveLiquidityRawTx.d.ts +2 -0
- package/dist/tx/buildRemoveLiquidityRawTx.js +23 -0
- package/dist/tx/buildSplitRawTx.d.ts +2 -0
- package/dist/tx/buildSplitRawTx.js +21 -0
- package/dist/tx/types.d.ts +117 -0
- package/dist/tx/types.js +10 -0
- package/dist/types.d.ts +15 -0
- package/dist/types.js +1 -0
- package/dist/utils/helpers.d.ts +4 -0
- package/dist/utils/helpers.js +28 -0
- package/package.json +66 -0
package/README.md
ADDED
|
@@ -0,0 +1,1074 @@
|
|
|
1
|
+
# Rain SDK V2
|
|
2
|
+
|
|
3
|
+
TypeScript SDK for the Rain prediction markets protocol on Arbitrum One. Provides transaction builders for market creation, trading, liquidity management, order book operations, dispute resolution, and smart account (Account Abstraction) support.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install rain-sdk-v2 viem
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
### Optional (for Smart Account / Account Abstraction)
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install @alchemy/aa-core @account-kit/infra @account-kit/wallet-client
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Quick Start
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
import { Rain, RainAA, TradingModel, OptionSide } from 'rain-sdk-v2';
|
|
21
|
+
import { createWalletClient, custom, parseUnits, parseEther } from 'viem';
|
|
22
|
+
import { arbitrum } from 'viem/chains';
|
|
23
|
+
|
|
24
|
+
// Initialize SDK
|
|
25
|
+
const rain = new Rain({
|
|
26
|
+
environment: 'development', // 'development' | 'stage' | 'production'
|
|
27
|
+
rpcUrl: 'https://arb1.arbitrum.io/rpc', // optional, uses random public RPC if omitted
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
// Get environment config
|
|
31
|
+
const config = rain.getEnvironmentConfig();
|
|
32
|
+
console.log(config.usdt_token); // USDT contract address
|
|
33
|
+
console.log(config.market_factory_address); // Factory contract
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Classes
|
|
39
|
+
|
|
40
|
+
### `Rain`
|
|
41
|
+
|
|
42
|
+
Stateless class for building transactions and querying on-chain data. Does not require a wallet.
|
|
43
|
+
|
|
44
|
+
#### Constructor
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
const rain = new Rain(config?: RainCoreConfig);
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
| Parameter | Type | Default | Description |
|
|
51
|
+
|-----------|------|---------|-------------|
|
|
52
|
+
| `environment` | `'development' \| 'stage' \| 'production'` | `'development'` | Target environment |
|
|
53
|
+
| `rpcUrl` | `string` | Random public RPC | Custom Arbitrum RPC URL |
|
|
54
|
+
| `apiUrl` | `string` | From environment | Custom API URL |
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
### `RainAA`
|
|
59
|
+
|
|
60
|
+
Stateful class for smart account (Account Abstraction) management with Alchemy gas sponsorship.
|
|
61
|
+
|
|
62
|
+
#### Constructor
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
const rainAA = new RainAA(config: RainConfig);
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
| Parameter | Type | Required | Description |
|
|
69
|
+
|-----------|------|----------|-------------|
|
|
70
|
+
| `walletClient` | `WalletClient` | Yes | Viem wallet client |
|
|
71
|
+
| `alchemyApiKey` | `string` | Yes | Alchemy API key |
|
|
72
|
+
| `paymasterPolicyId` | `string` | Yes | Alchemy paymaster policy ID |
|
|
73
|
+
| `chain` | `Chain` | Yes | Viem chain (e.g. `arbitrum`) |
|
|
74
|
+
| `rpcUrl` | `string` | No | Custom RPC URL |
|
|
75
|
+
|
|
76
|
+
#### Methods
|
|
77
|
+
|
|
78
|
+
##### `connect()`
|
|
79
|
+
|
|
80
|
+
Initializes the smart account. Returns the smart account address.
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
const smartAccountAddress = await rainAA.connect();
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
##### `sendTransaction(rawTx: RawTransaction)`
|
|
87
|
+
|
|
88
|
+
Sends a transaction from the smart account (gas-sponsored).
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
const hash = await rainAA.sendTransaction(rawTx);
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
##### `disconnect()`
|
|
95
|
+
|
|
96
|
+
Resets the connection state.
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
rainAA.disconnect();
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
##### `address` (getter)
|
|
103
|
+
|
|
104
|
+
Returns the smart account address. Throws if not connected.
|
|
105
|
+
|
|
106
|
+
##### `client` (getter)
|
|
107
|
+
|
|
108
|
+
Returns the smart wallet client instance. Throws if not connected.
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## Transaction Builders
|
|
113
|
+
|
|
114
|
+
All transaction builders return `RawTransaction` (or `RawTransaction[]` for multi-step operations):
|
|
115
|
+
|
|
116
|
+
```typescript
|
|
117
|
+
interface RawTransaction {
|
|
118
|
+
to: `0x${string}`;
|
|
119
|
+
data: `0x${string}`;
|
|
120
|
+
value?: bigint;
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
### Market Creation
|
|
127
|
+
|
|
128
|
+
#### `buildCreateMarketTx(params: CreateMarketTxParams): Promise<RawTransaction[]>`
|
|
129
|
+
|
|
130
|
+
Creates a new prediction market. Returns approval TX (if needed) + createPool TX.
|
|
131
|
+
|
|
132
|
+
```typescript
|
|
133
|
+
const txs = await rain.buildCreateMarketTx({
|
|
134
|
+
marketQuestion: 'Will ETH reach $5000 by end of 2025?',
|
|
135
|
+
marketOptions: ['Yes', 'No', 'Maybe'],
|
|
136
|
+
marketTags: ['crypto'],
|
|
137
|
+
marketDescription: 'Prediction on ETH price target',
|
|
138
|
+
isPublic: true,
|
|
139
|
+
isPublicPoolResolverAi: true, // true = AI resolver, false = manual resolver
|
|
140
|
+
creator: '0x...', // smart account or EOA address
|
|
141
|
+
startTime: BigInt(Math.floor(Date.now() / 1000) + 120), // 2 min from now
|
|
142
|
+
endTime: BigInt(Math.floor(Date.now() / 1000) + 86400), // 24h from now
|
|
143
|
+
no_of_options: 3n,
|
|
144
|
+
disputeTimer: 60, // seconds (set by SDK from environment)
|
|
145
|
+
inputAmountWei: parseUnits('10', 6), // 10 USDT initial liquidity
|
|
146
|
+
barValues: [33.33, 33.33, 33.34], // probability distribution (0-100, sums to 100)
|
|
147
|
+
baseToken: config.usdt_token, // USDT address
|
|
148
|
+
tradingModel: TradingModel.AMM, // AMM = 0, OrderBook = 1
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
// Approval amount = liquidity + (oracleFixedFeePerOption * numberOfOptions)
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
| Parameter | Type | Description |
|
|
155
|
+
|-----------|------|-------------|
|
|
156
|
+
| `marketQuestion` | `string` | The market question |
|
|
157
|
+
| `marketOptions` | `string[]` | Option labels (3-26 options) |
|
|
158
|
+
| `marketTags` | `string[]` | Tags (1-3) |
|
|
159
|
+
| `marketDescription` | `string` | Description |
|
|
160
|
+
| `isPublic` | `boolean` | Public market |
|
|
161
|
+
| `isPublicPoolResolverAi` | `boolean` | `true` for AI resolver, `false` for manual |
|
|
162
|
+
| `creator` | `0x${string}` | Creator/pool owner address |
|
|
163
|
+
| `startTime` | `bigint` | Unix timestamp (seconds) |
|
|
164
|
+
| `endTime` | `bigint` | Unix timestamp (seconds) |
|
|
165
|
+
| `no_of_options` | `bigint` | Number of options |
|
|
166
|
+
| `inputAmountWei` | `bigint` | Initial liquidity in base token wei |
|
|
167
|
+
| `barValues` | `number[]` | Probability distribution (0-100 scale) |
|
|
168
|
+
| `baseToken` | `0x${string}` | Base token address (USDT) |
|
|
169
|
+
| `tradingModel` | `TradingModel` | `AMM (0)` or `OrderBook (1)` |
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
### Trading
|
|
174
|
+
|
|
175
|
+
#### `buildEnterOptionTx(params: EnterOptionTxParams): RawTransaction`
|
|
176
|
+
|
|
177
|
+
Buy shares of an option (AMM trade).
|
|
178
|
+
|
|
179
|
+
```typescript
|
|
180
|
+
const tx = rain.buildEnterOptionTx({
|
|
181
|
+
marketContractAddress: '0x...',
|
|
182
|
+
selectedOption: 1n, // 1-based option index
|
|
183
|
+
optionSide: OptionSide.Yes, // Yes = 1, No = 2
|
|
184
|
+
buyAmountInWei: parseUnits('5', 6), // 5 USDT
|
|
185
|
+
});
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
| Parameter | Type | Description |
|
|
189
|
+
|-----------|------|-------------|
|
|
190
|
+
| `marketContractAddress` | `0x${string}` | Market contract address |
|
|
191
|
+
| `selectedOption` | `bigint` | Option index (1-based) |
|
|
192
|
+
| `optionSide` | `OptionSide` | `Yes (1)` or `No (2)` |
|
|
193
|
+
| `buyAmountInWei` | `bigint` | Amount in base token wei |
|
|
194
|
+
|
|
195
|
+
> **Note:** Requires prior ERC20 approval to the market contract.
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
### Split & Merge
|
|
200
|
+
|
|
201
|
+
#### `buildSplitTx(params: SplitTxParams): RawTransaction`
|
|
202
|
+
|
|
203
|
+
Split base tokens into equal Yes + No shares for an option.
|
|
204
|
+
|
|
205
|
+
```typescript
|
|
206
|
+
const tx = rain.buildSplitTx({
|
|
207
|
+
marketContractAddress: '0x...',
|
|
208
|
+
option: 1n,
|
|
209
|
+
amount: parseUnits('5', 6), // 5 USDT -> 5 Yes shares + 5 No shares
|
|
210
|
+
});
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
> **Note:** Requires prior ERC20 approval to the market contract.
|
|
214
|
+
|
|
215
|
+
#### `buildMergeTx(params: MergeTxParams): RawTransaction`
|
|
216
|
+
|
|
217
|
+
Merge equal Yes + No share pairs back into base tokens.
|
|
218
|
+
|
|
219
|
+
```typescript
|
|
220
|
+
const tx = rain.buildMergeTx({
|
|
221
|
+
marketContractAddress: '0x...',
|
|
222
|
+
option: 1n,
|
|
223
|
+
amount: 5000000n, // raw shares amount (from getUserOptionShares)
|
|
224
|
+
});
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
> **Note:** No approval needed. Burns your shares and returns base token.
|
|
228
|
+
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
### Liquidity
|
|
232
|
+
|
|
233
|
+
#### `buildAddLiquidityTx(params: AddLiquidityTxParams): RawTransaction`
|
|
234
|
+
|
|
235
|
+
Add liquidity to a specific option.
|
|
236
|
+
|
|
237
|
+
```typescript
|
|
238
|
+
const tx = rain.buildAddLiquidityTx({
|
|
239
|
+
marketContractAddress: '0x...',
|
|
240
|
+
option: 1n,
|
|
241
|
+
totalAmountInWei: parseUnits('10', 6), // 10 USDT
|
|
242
|
+
});
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
> **Note:** Requires prior ERC20 approval to the market contract.
|
|
246
|
+
|
|
247
|
+
#### `buildRemoveLiquidityTx(params: RemoveLiquidityTxParams): RawTransaction`
|
|
248
|
+
|
|
249
|
+
Remove liquidity by burning LP shares.
|
|
250
|
+
|
|
251
|
+
```typescript
|
|
252
|
+
const lpShares = await rain.getUserOptionLPShares({
|
|
253
|
+
marketContractAddress: '0x...',
|
|
254
|
+
option: 1n,
|
|
255
|
+
userAddress: '0x...',
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
const tx = rain.buildRemoveLiquidityTx({
|
|
259
|
+
marketContractAddress: '0x...',
|
|
260
|
+
option: 1n,
|
|
261
|
+
lpShares, // raw LP shares amount
|
|
262
|
+
});
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
### Order Book
|
|
268
|
+
|
|
269
|
+
#### `buildPlaceBuyOrderTx(params: PlaceBuyOrderTxParams): RawTransaction`
|
|
270
|
+
|
|
271
|
+
Place a limit buy order.
|
|
272
|
+
|
|
273
|
+
```typescript
|
|
274
|
+
const tx = rain.buildPlaceBuyOrderTx({
|
|
275
|
+
marketContractAddress: '0x...',
|
|
276
|
+
option: 1n,
|
|
277
|
+
optionSide: OptionSide.Yes,
|
|
278
|
+
price: parseEther('0.5'), // 50% price in 1e18 scale
|
|
279
|
+
amount: parseUnits('10', 6), // 10 USDT
|
|
280
|
+
});
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
> **Note:** Requires prior ERC20 approval to the market contract. Available when AMM pool is closed.
|
|
284
|
+
|
|
285
|
+
#### `buildPlaceSellOrderTx(params: PlaceSellOrderTxParams): RawTransaction`
|
|
286
|
+
|
|
287
|
+
Place a limit sell order.
|
|
288
|
+
|
|
289
|
+
```typescript
|
|
290
|
+
const tx = rain.buildPlaceSellOrderTx({
|
|
291
|
+
marketContractAddress: '0x...',
|
|
292
|
+
option: 1n,
|
|
293
|
+
optionSide: OptionSide.Yes,
|
|
294
|
+
price: parseEther('0.7'), // 70% price in 1e18 scale
|
|
295
|
+
shares: 5000000n, // shares to sell (from getUserOptionShares)
|
|
296
|
+
});
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
> **Note:** No approval needed. Shares are escrowed by the contract.
|
|
300
|
+
|
|
301
|
+
#### `buildCancelBuyOrdersTx(params: CancelBuyOrdersTxParams): RawTransaction`
|
|
302
|
+
|
|
303
|
+
Cancel one or more buy orders.
|
|
304
|
+
|
|
305
|
+
```typescript
|
|
306
|
+
const tx = rain.buildCancelBuyOrdersTx({
|
|
307
|
+
marketContractAddress: '0x...',
|
|
308
|
+
option: 1n,
|
|
309
|
+
optionSides: [1, 1], // Yes, Yes
|
|
310
|
+
prices: [parseEther('0.5'), parseEther('0.6')],
|
|
311
|
+
orderIDs: [1n, 2n], // from PlaceBuyOrder event
|
|
312
|
+
});
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
#### `buildCancelSellOrdersTx(params: CancelSellOrdersTxParams): RawTransaction`
|
|
316
|
+
|
|
317
|
+
Cancel one or more sell orders. Same interface as `buildCancelBuyOrdersTx`.
|
|
318
|
+
|
|
319
|
+
---
|
|
320
|
+
|
|
321
|
+
### Market Resolution
|
|
322
|
+
|
|
323
|
+
#### `buildClosePoolAITx(params: ClosePoolAITxParams): Promise<RawTransaction[]>`
|
|
324
|
+
|
|
325
|
+
Close a market pool with AI resolver. Returns approval (for resolver bond) + closePool TX.
|
|
326
|
+
|
|
327
|
+
```typescript
|
|
328
|
+
const txs = await rain.buildClosePoolAITx({
|
|
329
|
+
marketContractAddress: '0x...',
|
|
330
|
+
option: 1n,
|
|
331
|
+
});
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
#### `buildClosePoolManualTx(params: ClosePoolManualTxParams): Promise<RawTransaction[]>`
|
|
335
|
+
|
|
336
|
+
Close a market pool with manual resolver, proposing a winner side. Returns approval (for resolver bond) + closePool TX.
|
|
337
|
+
|
|
338
|
+
```typescript
|
|
339
|
+
const txs = await rain.buildClosePoolManualTx({
|
|
340
|
+
marketContractAddress: '0x...',
|
|
341
|
+
option: 1n,
|
|
342
|
+
proposedWinner: 1, // 1 = Yes, 2 = No
|
|
343
|
+
});
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
#### `buildChooseWinnerTx(params: ChooseWinnerTxParams): RawTransaction`
|
|
347
|
+
|
|
348
|
+
Finalize the winner after pool is closed.
|
|
349
|
+
|
|
350
|
+
```typescript
|
|
351
|
+
const tx = rain.buildChooseWinnerTx({
|
|
352
|
+
marketContractAddress: '0x...',
|
|
353
|
+
option: 1n,
|
|
354
|
+
optionSide: 1, // 1 = Yes, 2 = No
|
|
355
|
+
});
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
#### `buildCalculateWinnerTx(params: CalculateWinnerTxParams): Promise<RawTransaction>`
|
|
359
|
+
|
|
360
|
+
Calculate winner via the oracle resolver. Must be called before `claim`. Reads `optionResolver(option)` from the market and calls `calculateWinner()` on that resolver contract.
|
|
361
|
+
|
|
362
|
+
```typescript
|
|
363
|
+
const tx = await rain.buildCalculateWinnerTx({
|
|
364
|
+
marketContractAddress: '0x...',
|
|
365
|
+
option: 1n,
|
|
366
|
+
});
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
---
|
|
370
|
+
|
|
371
|
+
### Claiming
|
|
372
|
+
|
|
373
|
+
#### `buildClaimTx(params: ClaimTxParams): RawTransaction`
|
|
374
|
+
|
|
375
|
+
Claim winnings after market resolution. Call `buildCalculateWinnerTx` first.
|
|
376
|
+
|
|
377
|
+
```typescript
|
|
378
|
+
const tx = rain.buildClaimTx({
|
|
379
|
+
marketContractAddress: '0x...',
|
|
380
|
+
option: 1n,
|
|
381
|
+
});
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
---
|
|
385
|
+
|
|
386
|
+
### Dispute / Appeal
|
|
387
|
+
|
|
388
|
+
#### `buildOpenDisputeTx(params: OpenDisputeTxParams): Promise<RawTransaction[]>`
|
|
389
|
+
|
|
390
|
+
Open a dispute (or appeal if dispute already exists). Returns approval (for dispute fee) + openDispute TX. The fee is read from `getDisputeAppealFee(option)`.
|
|
391
|
+
|
|
392
|
+
```typescript
|
|
393
|
+
const txs = await rain.buildOpenDisputeTx({
|
|
394
|
+
marketContractAddress: '0x...',
|
|
395
|
+
option: 1n,
|
|
396
|
+
});
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
> **Note:** Call once to open dispute. Call again (after dispute window) to appeal.
|
|
400
|
+
|
|
401
|
+
---
|
|
402
|
+
|
|
403
|
+
### Token Approval
|
|
404
|
+
|
|
405
|
+
#### `buildApprovalTx(params: ApproveTxParams): RawTransaction`
|
|
406
|
+
|
|
407
|
+
Build an ERC20 approve transaction.
|
|
408
|
+
|
|
409
|
+
```typescript
|
|
410
|
+
const tx = rain.buildApprovalTx({
|
|
411
|
+
tokenAddress: config.usdt_token,
|
|
412
|
+
spender: '0x...', // market contract address
|
|
413
|
+
amount: parseUnits('100', 6), // 100 USDT
|
|
414
|
+
});
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
---
|
|
418
|
+
|
|
419
|
+
## Read Methods (On-Chain Queries)
|
|
420
|
+
|
|
421
|
+
### `getTokenAllowance(params): Promise<bigint>`
|
|
422
|
+
|
|
423
|
+
Check current ERC20 allowance.
|
|
424
|
+
|
|
425
|
+
```typescript
|
|
426
|
+
const allowance = await rain.getTokenAllowance({
|
|
427
|
+
tokenAddress: config.usdt_token,
|
|
428
|
+
owner: '0x...', // your address
|
|
429
|
+
spender: '0x...', // market contract
|
|
430
|
+
});
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
### `getUserOptionLPShares(params): Promise<bigint>`
|
|
434
|
+
|
|
435
|
+
Get user's LP shares for a specific option.
|
|
436
|
+
|
|
437
|
+
```typescript
|
|
438
|
+
const lpShares = await rain.getUserOptionLPShares({
|
|
439
|
+
marketContractAddress: '0x...',
|
|
440
|
+
option: 1n,
|
|
441
|
+
userAddress: '0x...',
|
|
442
|
+
});
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
### `getUserOptionShares(params): Promise<bigint>`
|
|
446
|
+
|
|
447
|
+
Get user's Yes or No shares for a specific option.
|
|
448
|
+
|
|
449
|
+
```typescript
|
|
450
|
+
const yesShares = await rain.getUserOptionShares({
|
|
451
|
+
marketContractAddress: '0x...',
|
|
452
|
+
option: 1n,
|
|
453
|
+
optionSide: 1, // 1 = Yes, 2 = No
|
|
454
|
+
userAddress: '0x...',
|
|
455
|
+
});
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
### `getUserActiveBuyOrders(params): Promise<bigint>`
|
|
459
|
+
|
|
460
|
+
Get count of user's active buy orders.
|
|
461
|
+
|
|
462
|
+
```typescript
|
|
463
|
+
const count = await rain.getUserActiveBuyOrders({
|
|
464
|
+
marketContractAddress: '0x...',
|
|
465
|
+
userAddress: '0x...',
|
|
466
|
+
});
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
### `getUserActiveSellOrders(params): Promise<bigint>`
|
|
470
|
+
|
|
471
|
+
Get count of user's active sell orders.
|
|
472
|
+
|
|
473
|
+
```typescript
|
|
474
|
+
const count = await rain.getUserActiveSellOrders({
|
|
475
|
+
marketContractAddress: '0x...',
|
|
476
|
+
userAddress: '0x...',
|
|
477
|
+
});
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
### `getFirstBuyOrderPrice(params): Promise<bigint>`
|
|
481
|
+
|
|
482
|
+
Get the best (first) buy order price for an option/side.
|
|
483
|
+
|
|
484
|
+
```typescript
|
|
485
|
+
const price = await rain.getFirstBuyOrderPrice({
|
|
486
|
+
marketContractAddress: '0x...',
|
|
487
|
+
option: 1n,
|
|
488
|
+
optionSide: 1, // Yes
|
|
489
|
+
});
|
|
490
|
+
// price is in 1e18 scale. 500000000000000000n = 0.5 = 50%
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
### `getFirstSellOrderPrice(params): Promise<bigint>`
|
|
494
|
+
|
|
495
|
+
Get the best (first) sell order price for an option/side.
|
|
496
|
+
|
|
497
|
+
### `getBuyOrdersAtPrice(params): Promise<OrderLevelInfo>`
|
|
498
|
+
|
|
499
|
+
Get order book info at a specific price level.
|
|
500
|
+
|
|
501
|
+
```typescript
|
|
502
|
+
const info = await rain.getBuyOrdersAtPrice({
|
|
503
|
+
marketContractAddress: '0x...',
|
|
504
|
+
option: 1n,
|
|
505
|
+
optionSide: 1,
|
|
506
|
+
price: parseEther('0.5'),
|
|
507
|
+
});
|
|
508
|
+
// { headIndex, tailIndex, count, isInitialized }
|
|
509
|
+
```
|
|
510
|
+
|
|
511
|
+
### `getSellOrdersAtPrice(params): Promise<OrderLevelInfo>`
|
|
512
|
+
|
|
513
|
+
Same as above for sell orders.
|
|
514
|
+
|
|
515
|
+
### `checkOrderExists(params): Promise<{ exists: boolean; index: bigint }>`
|
|
516
|
+
|
|
517
|
+
Check if a specific order exists.
|
|
518
|
+
|
|
519
|
+
```typescript
|
|
520
|
+
const result = await rain.checkOrderExists({
|
|
521
|
+
marketContractAddress: '0x...',
|
|
522
|
+
option: 1n,
|
|
523
|
+
optionSide: 1,
|
|
524
|
+
price: parseEther('0.5'),
|
|
525
|
+
orderID: 1n,
|
|
526
|
+
});
|
|
527
|
+
```
|
|
528
|
+
|
|
529
|
+
---
|
|
530
|
+
|
|
531
|
+
## Authentication
|
|
532
|
+
|
|
533
|
+
### `login(params: LoginParams): Promise<LoginResult>`
|
|
534
|
+
|
|
535
|
+
Wallet-based login to the Rain backend.
|
|
536
|
+
|
|
537
|
+
```typescript
|
|
538
|
+
const result = await rain.login({
|
|
539
|
+
signature: '0x...', // personal_sign of lowercased wallet address
|
|
540
|
+
walletAddress: '0x...', // EOA address
|
|
541
|
+
smartWalletAddress: '0x...', // Smart account address
|
|
542
|
+
referredBy: 'CODE', // optional referral code
|
|
543
|
+
});
|
|
544
|
+
|
|
545
|
+
console.log(result.accessToken); // JWT token
|
|
546
|
+
console.log(result.userId); // Backend user ID
|
|
547
|
+
```
|
|
548
|
+
|
|
549
|
+
---
|
|
550
|
+
|
|
551
|
+
## Configuration
|
|
552
|
+
|
|
553
|
+
### `getEnvironmentConfig()`
|
|
554
|
+
|
|
555
|
+
Returns the current environment configuration.
|
|
556
|
+
|
|
557
|
+
```typescript
|
|
558
|
+
const config = rain.getEnvironmentConfig();
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
Returns:
|
|
562
|
+
| Field | Description |
|
|
563
|
+
|-------|-------------|
|
|
564
|
+
| `apiUrl` | Backend API URL |
|
|
565
|
+
| `market_factory_address` | Factory contract address |
|
|
566
|
+
| `dispute_initial_timer` | Dispute timer in seconds |
|
|
567
|
+
| `oracle_fixed_fee_per_option` | Oracle fee per option in base token wei |
|
|
568
|
+
| `usdt_symbol` | USDT token symbol |
|
|
569
|
+
| `usdt_token` | USDT token address |
|
|
570
|
+
| `rain_token` | RAIN token address |
|
|
571
|
+
|
|
572
|
+
---
|
|
573
|
+
|
|
574
|
+
## Enums
|
|
575
|
+
|
|
576
|
+
### `TradingModel`
|
|
577
|
+
|
|
578
|
+
```typescript
|
|
579
|
+
enum TradingModel {
|
|
580
|
+
AMM = 0,
|
|
581
|
+
OrderBook = 1,
|
|
582
|
+
}
|
|
583
|
+
```
|
|
584
|
+
|
|
585
|
+
### `OptionSide`
|
|
586
|
+
|
|
587
|
+
```typescript
|
|
588
|
+
enum OptionSide {
|
|
589
|
+
Yes = 1,
|
|
590
|
+
No = 2,
|
|
591
|
+
}
|
|
592
|
+
```
|
|
593
|
+
|
|
594
|
+
---
|
|
595
|
+
|
|
596
|
+
## Environments
|
|
597
|
+
|
|
598
|
+
| Environment | API | Factory |
|
|
599
|
+
|-------------|-----|---------|
|
|
600
|
+
| `development` | `https://dev-api.rain.one` | `0xBD99...0adE` |
|
|
601
|
+
| `stage` | `https://stg-api.rain.one` | `0xD490...96BE` |
|
|
602
|
+
| `production` | `https://prod-api.rain.one` | `0xA864...F264` |
|
|
603
|
+
|
|
604
|
+
---
|
|
605
|
+
|
|
606
|
+
## Typical Flow
|
|
607
|
+
|
|
608
|
+
```
|
|
609
|
+
1. Create Market (buildCreateMarketTx)
|
|
610
|
+
2. Wait for startTime to pass
|
|
611
|
+
3. Enter Option (buildEnterOptionTx) / Split (buildSplitTx)
|
|
612
|
+
4. Place Orders (buildPlaceBuyOrderTx / buildPlaceSellOrderTx)
|
|
613
|
+
5. Wait for endTime to pass
|
|
614
|
+
6. Close Pool (buildClosePoolAITx / buildClosePoolManualTx)
|
|
615
|
+
7. Calculate Winner (buildCalculateWinnerTx)
|
|
616
|
+
8. Claim (buildClaimTx)
|
|
617
|
+
```
|
|
618
|
+
|
|
619
|
+
If disputed:
|
|
620
|
+
```
|
|
621
|
+
6b. Open Dispute (buildOpenDisputeTx)
|
|
622
|
+
6c. Appeal (buildOpenDisputeTx again)
|
|
623
|
+
```
|
|
624
|
+
|
|
625
|
+
---
|
|
626
|
+
|
|
627
|
+
## REST API Methods
|
|
628
|
+
|
|
629
|
+
The SDK wraps all Rain backend REST API endpoints. Each method requires `accessToken` for authenticated routes.
|
|
630
|
+
|
|
631
|
+
### Users
|
|
632
|
+
|
|
633
|
+
```typescript
|
|
634
|
+
// Find user by wallet address (public)
|
|
635
|
+
const user = await rain.findUserByWalletAddress({ walletAddress: '0x...' });
|
|
636
|
+
|
|
637
|
+
// Get authenticated user's profile
|
|
638
|
+
const profile = await rain.getUserProfile(accessToken);
|
|
639
|
+
|
|
640
|
+
// View another user's profile
|
|
641
|
+
const profile = await rain.viewUserProfile({ userId: '...' }, accessToken);
|
|
642
|
+
|
|
643
|
+
// Update profile
|
|
644
|
+
await rain.updateUserProfile({
|
|
645
|
+
name: 'John',
|
|
646
|
+
bio: 'Trader',
|
|
647
|
+
profilePic: 'https://...',
|
|
648
|
+
twitterLink: 'https://...',
|
|
649
|
+
}, accessToken);
|
|
650
|
+
|
|
651
|
+
// Get total user count (public)
|
|
652
|
+
const count = await rain.getUsersTotalCount();
|
|
653
|
+
|
|
654
|
+
// Remove profile picture
|
|
655
|
+
await rain.removeUserProfilePic(accessToken);
|
|
656
|
+
|
|
657
|
+
// Get user activity history (deposits, withdrawals, trades, rewards)
|
|
658
|
+
const history = await rain.getUserHistory({ limit: 20, offset: 1 }, accessToken);
|
|
659
|
+
|
|
660
|
+
// Check if access token is still valid
|
|
661
|
+
const status = await rain.checkTokenExpiration(accessToken);
|
|
662
|
+
```
|
|
663
|
+
|
|
664
|
+
### Comments
|
|
665
|
+
|
|
666
|
+
```typescript
|
|
667
|
+
// Create a comment
|
|
668
|
+
await rain.createComment({ comment: 'Great market!', poolId: '...' }, accessToken);
|
|
669
|
+
|
|
670
|
+
// Reply to a comment
|
|
671
|
+
await rain.createComment({ comment: 'I agree', poolId: '...', parentCommentId: '...' }, accessToken);
|
|
672
|
+
|
|
673
|
+
// Get comments for a pool
|
|
674
|
+
const comments = await rain.getCommentsListing({ poolId: '...', limit: 10, offset: 0 });
|
|
675
|
+
|
|
676
|
+
// Update a comment
|
|
677
|
+
await rain.updateComment({ commentId: '...', comment: 'Updated text' }, accessToken);
|
|
678
|
+
|
|
679
|
+
// Like / Unlike a comment
|
|
680
|
+
await rain.likeComment({ commentId: '...' }, accessToken);
|
|
681
|
+
await rain.unlikeComment({ commentId: '...' }, accessToken);
|
|
682
|
+
|
|
683
|
+
// Get comment count for a pool
|
|
684
|
+
const count = await rain.getCommentsCount({ poolId: '...' });
|
|
685
|
+
```
|
|
686
|
+
|
|
687
|
+
### Pools
|
|
688
|
+
|
|
689
|
+
```typescript
|
|
690
|
+
// Get public pools (paginated, filterable)
|
|
691
|
+
const pools = await rain.getPublicPools({ limit: 10, offset: 0, status: 'Live', sortBy: 'trending' });
|
|
692
|
+
|
|
693
|
+
// Get private pools
|
|
694
|
+
const pools = await rain.getPrivatePools({ limit: 10, offset: 0 }, accessToken);
|
|
695
|
+
|
|
696
|
+
// Get pool by ID
|
|
697
|
+
const pool = await rain.getPoolById({ id: '...' });
|
|
698
|
+
|
|
699
|
+
// Get pool by contract address
|
|
700
|
+
const pool = await rain.getPoolByContractAddress({ contractAddress: '0x...' });
|
|
701
|
+
|
|
702
|
+
// Search pools
|
|
703
|
+
const results = await rain.searchPool({ query: 'bitcoin', limit: 10, offset: 0 });
|
|
704
|
+
|
|
705
|
+
// Get featured pools
|
|
706
|
+
const featured = await rain.getFeaturedPools({ limit: 10, offset: 0 });
|
|
707
|
+
|
|
708
|
+
// Get all pools count
|
|
709
|
+
const count = await rain.getAllPoolsCount();
|
|
710
|
+
|
|
711
|
+
// Get related pools
|
|
712
|
+
const related = await rain.getRelatedPools({ poolId: '...' });
|
|
713
|
+
|
|
714
|
+
// Get pool resolution history (per sub-pool)
|
|
715
|
+
const history = await rain.getPoolResolutionHistory({ poolId: '...', subPool: '...' });
|
|
716
|
+
|
|
717
|
+
// Access a private pool
|
|
718
|
+
const access = await rain.accessPool({ poolId: '...', accessCode: '1234' });
|
|
719
|
+
|
|
720
|
+
// Verify access code
|
|
721
|
+
await rain.verifyAccessCode({ poolId: '...', accessCode: '1234' }, accessToken);
|
|
722
|
+
|
|
723
|
+
// Get pools created by a user
|
|
724
|
+
const pools = await rain.getPoolListingByCreator({ limit: 10, offset: 0 }, accessToken);
|
|
725
|
+
|
|
726
|
+
// Get total participants in a pool
|
|
727
|
+
const count = await rain.getPoolTotalParticipants({ poolId: '...' });
|
|
728
|
+
|
|
729
|
+
// Get total pools created by user
|
|
730
|
+
const count = await rain.getTotalPoolsCreatedByUser(accessToken);
|
|
731
|
+
|
|
732
|
+
// Get total predictions by user
|
|
733
|
+
const count = await rain.getTotalPredictionsByUser(accessToken);
|
|
734
|
+
|
|
735
|
+
// Update streaming status
|
|
736
|
+
await rain.updateStreaming({ poolId: '...', streaming: true }, accessToken);
|
|
737
|
+
|
|
738
|
+
// Update pool resolution time
|
|
739
|
+
await rain.updatePoolResolutionTime({ poolId: '...', newEndDate: '...' }, accessToken);
|
|
740
|
+
|
|
741
|
+
// Find pool fallback
|
|
742
|
+
const pool = await rain.findPoolFallback({ poolId: '...' });
|
|
743
|
+
|
|
744
|
+
// Sign oracles extend time
|
|
745
|
+
await rain.signOraclesExtendTime({ poolId: '...' }, accessToken);
|
|
746
|
+
```
|
|
747
|
+
|
|
748
|
+
### Investments
|
|
749
|
+
|
|
750
|
+
```typescript
|
|
751
|
+
// Get user's total investment in a pool
|
|
752
|
+
const investment = await rain.getUserTotalInvestment({ poolId: '...' }, accessToken);
|
|
753
|
+
|
|
754
|
+
// Get options total volume for a pool
|
|
755
|
+
const volume = await rain.getOptionsTotalVolume({ poolId: '...' });
|
|
756
|
+
|
|
757
|
+
// Get pool activity (trades)
|
|
758
|
+
const activity = await rain.getPoolActivity({ poolId: '...', limit: 10, offset: 0 });
|
|
759
|
+
|
|
760
|
+
// Get top holders in a pool
|
|
761
|
+
const holders = await rain.getTopHolders({ poolId: '...', limit: 10, offset: 0 });
|
|
762
|
+
|
|
763
|
+
// Get user's invested pools
|
|
764
|
+
const pools = await rain.getUserInvestedPools({ limit: 10, offset: 0 }, accessToken);
|
|
765
|
+
|
|
766
|
+
// Get platform TVL
|
|
767
|
+
const tvl = await rain.getPlatformTvl();
|
|
768
|
+
|
|
769
|
+
// Get investment volume graph
|
|
770
|
+
const graph = await rain.getInvestmentVolumeGraph({ period: '7d' }, accessToken);
|
|
771
|
+
|
|
772
|
+
// Calculate user PNL
|
|
773
|
+
const pnl = await rain.calculateUserPnl({ walletAddress: '0x...' }, accessToken);
|
|
774
|
+
|
|
775
|
+
// Get user total volume
|
|
776
|
+
const volume = await rain.calculateUserTotalVolume(accessToken);
|
|
777
|
+
|
|
778
|
+
// Get PNL graph
|
|
779
|
+
const graph = await rain.getUserPnlGraph({ period: '30d' }, accessToken);
|
|
780
|
+
|
|
781
|
+
// Get TVL graph
|
|
782
|
+
const graph = await rain.getTvlGraph();
|
|
783
|
+
|
|
784
|
+
// Get PNL per pool
|
|
785
|
+
const pnl = await rain.calculateUserPnlPerPool(accessToken);
|
|
786
|
+
|
|
787
|
+
// Get PNL by specific pool
|
|
788
|
+
const pnl = await rain.getPnlByPoolId({ poolId: '...' }, accessToken);
|
|
789
|
+
|
|
790
|
+
// Get top winners and losers
|
|
791
|
+
const leaderboard = await rain.getTopWinnersLosers({ limit: 10, period: '7d' });
|
|
792
|
+
|
|
793
|
+
// Get user overall investment
|
|
794
|
+
const overall = await rain.getUserOverallInvestment(accessToken);
|
|
795
|
+
|
|
796
|
+
// Get platform volume
|
|
797
|
+
const volume = await rain.getPlatformVolume();
|
|
798
|
+
|
|
799
|
+
// Get user invested live pools count
|
|
800
|
+
const count = await rain.getUserInvestedLivePoolsCount(accessToken);
|
|
801
|
+
|
|
802
|
+
// Calculate user open interest
|
|
803
|
+
const oi = await rain.calculateUserOpenInterest(accessToken);
|
|
804
|
+
```
|
|
805
|
+
|
|
806
|
+
### Orders
|
|
807
|
+
|
|
808
|
+
```typescript
|
|
809
|
+
// Get user's orders
|
|
810
|
+
const orders = await rain.getUserOrders({ limit: 10, offset: 1, filter: 'pending' }, accessToken);
|
|
811
|
+
|
|
812
|
+
// Get order book for a pool
|
|
813
|
+
const book = await rain.getOrderBook({ pool: '...' });
|
|
814
|
+
|
|
815
|
+
// Get user's orders for a specific pool
|
|
816
|
+
const orders = await rain.getUserOrderByPoolId({ poolId: '...' }, accessToken);
|
|
817
|
+
|
|
818
|
+
// Get all orders for a pool
|
|
819
|
+
const orders = await rain.getOrdersListingByPool({ pool: '...', limit: 10, offset: 1 });
|
|
820
|
+
|
|
821
|
+
// Get order by ID
|
|
822
|
+
const order = await rain.getOrderById({ orderId: '...' });
|
|
823
|
+
```
|
|
824
|
+
|
|
825
|
+
### Points
|
|
826
|
+
|
|
827
|
+
```typescript
|
|
828
|
+
// Get user points
|
|
829
|
+
const points = await rain.getUserPoints(accessToken);
|
|
830
|
+
|
|
831
|
+
// Get user points graph
|
|
832
|
+
const graph = await rain.getUserPointsGraph(accessToken);
|
|
833
|
+
|
|
834
|
+
// Add user points
|
|
835
|
+
await rain.addUserPoints({ points: 100, reason: '...' }, accessToken);
|
|
836
|
+
|
|
837
|
+
// User successful onboarding
|
|
838
|
+
await rain.userSuccessfulOnboarding({ step: '...' }, accessToken);
|
|
839
|
+
```
|
|
840
|
+
|
|
841
|
+
### Notifications
|
|
842
|
+
|
|
843
|
+
```typescript
|
|
844
|
+
// Get notifications
|
|
845
|
+
const notifs = await rain.getNotifications({ limit: 20, offset: 0 }, accessToken);
|
|
846
|
+
|
|
847
|
+
// Mark all as read
|
|
848
|
+
await rain.markAllNotificationsAsRead(accessToken);
|
|
849
|
+
|
|
850
|
+
// Mark single notification as read
|
|
851
|
+
await rain.markNotificationAsRead({ notificationId: '...' }, accessToken);
|
|
852
|
+
```
|
|
853
|
+
|
|
854
|
+
### Price Data
|
|
855
|
+
|
|
856
|
+
```typescript
|
|
857
|
+
// Get price data for a pool
|
|
858
|
+
const prices = await rain.getPriceData({ poolId: '...', interval: '1h' });
|
|
859
|
+
```
|
|
860
|
+
|
|
861
|
+
### Pool Reviews
|
|
862
|
+
|
|
863
|
+
```typescript
|
|
864
|
+
// Add review
|
|
865
|
+
await rain.addReview({ poolId: '...', rating: 5, review: 'Great!' }, accessToken);
|
|
866
|
+
|
|
867
|
+
// Get user's reviews
|
|
868
|
+
const reviews = await rain.getUserReviews(accessToken);
|
|
869
|
+
|
|
870
|
+
// Get pools by creator with reviews
|
|
871
|
+
const pools = await rain.getPoolsByCreatorReviews(accessToken);
|
|
872
|
+
```
|
|
873
|
+
|
|
874
|
+
### Follow
|
|
875
|
+
|
|
876
|
+
```typescript
|
|
877
|
+
// Toggle follow a user
|
|
878
|
+
await rain.toggleFollow({ userId: '...' }, accessToken);
|
|
879
|
+
|
|
880
|
+
// Check if following
|
|
881
|
+
const status = await rain.checkFollow({ userId: '...' }, accessToken);
|
|
882
|
+
|
|
883
|
+
// Get followers
|
|
884
|
+
const followers = await rain.getFollowers({ userId: '...', limit: 20, offset: 0 });
|
|
885
|
+
|
|
886
|
+
// Get following
|
|
887
|
+
const following = await rain.getFollowing({ userId: '...', limit: 20, offset: 0 });
|
|
888
|
+
|
|
889
|
+
// Get follow stats
|
|
890
|
+
const stats = await rain.getFollowStats({ userId: '...' });
|
|
891
|
+
```
|
|
892
|
+
|
|
893
|
+
### Rain Burn
|
|
894
|
+
|
|
895
|
+
```typescript
|
|
896
|
+
// Get total RAIN burned
|
|
897
|
+
const burned = await rain.getTotalBurned();
|
|
898
|
+
|
|
899
|
+
// Get burn per pool
|
|
900
|
+
const burn = await rain.getBurnPerPool({ poolId: '...' });
|
|
901
|
+
```
|
|
902
|
+
|
|
903
|
+
### Dispute
|
|
904
|
+
|
|
905
|
+
```typescript
|
|
906
|
+
// Create dispute message (with optional file upload)
|
|
907
|
+
await rain.createDisputeMessage({
|
|
908
|
+
pool: '...',
|
|
909
|
+
role: 'disputer',
|
|
910
|
+
messageType: 'text',
|
|
911
|
+
evidence: { description: '...' },
|
|
912
|
+
}, accessToken);
|
|
913
|
+
|
|
914
|
+
// Get dispute conversation for a sub-pool
|
|
915
|
+
const convo = await rain.getPoolDisputeConvo({ poolId: '...', subPool: '...', limit: 50, offset: 0 }, accessToken);
|
|
916
|
+
```
|
|
917
|
+
|
|
918
|
+
---
|
|
919
|
+
|
|
920
|
+
## WebSocket Events (Socket.IO)
|
|
921
|
+
|
|
922
|
+
Real-time event subscriptions via Socket.IO.
|
|
923
|
+
|
|
924
|
+
### Setup
|
|
925
|
+
|
|
926
|
+
```typescript
|
|
927
|
+
import { RainSocket } from 'rain-sdk-v2';
|
|
928
|
+
|
|
929
|
+
const socket = new RainSocket('https://dev-api.rain.one');
|
|
930
|
+
socket.connect();
|
|
931
|
+
```
|
|
932
|
+
|
|
933
|
+
### Pool-Scoped Events
|
|
934
|
+
|
|
935
|
+
Subscribe to events for a specific pool using `poolId`:
|
|
936
|
+
|
|
937
|
+
```typescript
|
|
938
|
+
// Trading events
|
|
939
|
+
const unsub = socket.onEnterOption(poolId, (data) => {
|
|
940
|
+
console.log(data.enterOption, data.pool, data.subPool);
|
|
941
|
+
});
|
|
942
|
+
|
|
943
|
+
socket.onExitOption(poolId, (data) => { /* data.exitOption, pool, subPool */ });
|
|
944
|
+
socket.onLiquidity(poolId, (data) => { /* data.enterLiquidity, pool, subPool */ });
|
|
945
|
+
socket.onSplit(poolId, (data) => { /* data.split, pool, subPool */ });
|
|
946
|
+
socket.onMerge(poolId, (data) => { /* data.merge, pool, subPool */ });
|
|
947
|
+
socket.onRemoveLiquidity(poolId, (data) => { /* data.removeLiquidity, pool, subPool */ });
|
|
948
|
+
|
|
949
|
+
// Price updates
|
|
950
|
+
socket.onSyncPrice(poolId, (data) => {
|
|
951
|
+
// data.prices = [{ side: 1, price: 0.62, percentage: 62, subPoolIndex: 1 }, ...]
|
|
952
|
+
// data.pool, data.subPool
|
|
953
|
+
});
|
|
954
|
+
|
|
955
|
+
// Order book events
|
|
956
|
+
socket.onOrderCreated(poolId, (data) => { /* data.order, pool, subPool */ });
|
|
957
|
+
socket.onOrderCancelled(poolId, (data) => { /* data.order, pool, subPool */ });
|
|
958
|
+
socket.onOrderFilled(poolId, (data) => { /* data.filledOrder, data.pendingOrder?, pool, subPool */ });
|
|
959
|
+
|
|
960
|
+
// Pool lifecycle
|
|
961
|
+
socket.onPoolClosed(poolId, (data) => { /* data.pool, data.subPool? */ });
|
|
962
|
+
socket.onPoolReverted(poolId, (data) => { /* data.pool, data.subPool */ });
|
|
963
|
+
socket.onPoolTokenSet(poolId, (data) => { /* data.pool */ });
|
|
964
|
+
socket.onStreamingStatusChanged(poolId, (data) => { /* data.pool */ });
|
|
965
|
+
|
|
966
|
+
// Resolution events
|
|
967
|
+
socket.onWinner(poolId, (data) => { /* data.pool, data.subPool */ });
|
|
968
|
+
socket.onWinnerProposer(poolId, (data) => { /* data.pool, data.subPool */ });
|
|
969
|
+
socket.onRevealWinnerAvailable(poolId, (data) => { /* data.subPoolId */ });
|
|
970
|
+
|
|
971
|
+
// Dispute & Appeal events
|
|
972
|
+
socket.onDisputeOpened(poolId, (data) => { /* data.subPool, data.eventType */ });
|
|
973
|
+
socket.onOracleCreated(poolId, (data) => { /* data.pool, data.subPool */ });
|
|
974
|
+
socket.onDisputeTimeExtended(poolId, (data) => { /* data.pool, data.subPool */ });
|
|
975
|
+
socket.onAppealOpened(poolId, (data) => { /* data.pool, data.subPool */ });
|
|
976
|
+
socket.onAppealWinnerCalculated(poolId, (data) => { /* data.subPool */ });
|
|
977
|
+
socket.onDisputeWinner(poolId, (data) => { /* data.subPool, data.eventType */ });
|
|
978
|
+
socket.onAppealWinner(poolId, (data) => { /* data.subPool, data.eventType, data.winnerFinalized */ });
|
|
979
|
+
|
|
980
|
+
// Claim events (pool-scoped broadcast)
|
|
981
|
+
socket.onClaimReward(poolId, (data) => { /* data.claimReward, pool, subPool */ });
|
|
982
|
+
```
|
|
983
|
+
|
|
984
|
+
### User-Scoped Events
|
|
985
|
+
|
|
986
|
+
Events targeted to a specific user (require `userId`):
|
|
987
|
+
|
|
988
|
+
```typescript
|
|
989
|
+
// Personal claim reward
|
|
990
|
+
socket.onUserClaimReward(poolId, userId, (data) => { /* data.claimReward, pool, subPool */ });
|
|
991
|
+
|
|
992
|
+
// Dispute bond refunded (disputer won)
|
|
993
|
+
socket.onDisputeRefund(poolId, userId, (data) => { /* data.claimReward, pool, subPool */ });
|
|
994
|
+
|
|
995
|
+
// Appeal fee refunded (appealer won)
|
|
996
|
+
socket.onAppealRefund(poolId, userId, (data) => { /* data.claimReward, pool, subPool */ });
|
|
997
|
+
|
|
998
|
+
// Resolution bond refunded (proposer was correct)
|
|
999
|
+
socket.onResolutionRefund(poolId, userId, (data) => { /* data.claimReward, pool, subPool */ });
|
|
1000
|
+
|
|
1001
|
+
// Resolver closing share reward
|
|
1002
|
+
socket.onResolverReward(poolId, userId, (data) => { /* data.claimReward, pool, subPool */ });
|
|
1003
|
+
|
|
1004
|
+
// Personal notifications
|
|
1005
|
+
socket.onNotifications(userId, (data) => {
|
|
1006
|
+
// data._id, userId, type, message, pool, subPool, createdAt, read
|
|
1007
|
+
});
|
|
1008
|
+
```
|
|
1009
|
+
|
|
1010
|
+
### Global Events
|
|
1011
|
+
|
|
1012
|
+
```typescript
|
|
1013
|
+
// New pool created
|
|
1014
|
+
socket.onNewPool((data) => { /* data.pool, data.subMarkets */ });
|
|
1015
|
+
```
|
|
1016
|
+
|
|
1017
|
+
### Generic Subscription
|
|
1018
|
+
|
|
1019
|
+
```typescript
|
|
1020
|
+
// Subscribe to any channel directly
|
|
1021
|
+
const unsub = socket.onChannel('custom-event/123', (data) => { ... });
|
|
1022
|
+
|
|
1023
|
+
// Unsubscribe
|
|
1024
|
+
unsub();
|
|
1025
|
+
```
|
|
1026
|
+
|
|
1027
|
+
### Cleanup
|
|
1028
|
+
|
|
1029
|
+
```typescript
|
|
1030
|
+
socket.disconnect();
|
|
1031
|
+
```
|
|
1032
|
+
|
|
1033
|
+
### All Socket Event Channels
|
|
1034
|
+
|
|
1035
|
+
| Channel | Description |
|
|
1036
|
+
|---------|-------------|
|
|
1037
|
+
| `pool` | New pool created |
|
|
1038
|
+
| `pool-token-set/{poolId}` | Token set for pool |
|
|
1039
|
+
| `pool-closed/{poolId}` | Pool/SubPool finalized |
|
|
1040
|
+
| `pool-reverted/{poolId}` | Resolution reverted |
|
|
1041
|
+
| `streamingStatusChanged/{poolId}` | Streaming toggled |
|
|
1042
|
+
| `enter-option/{poolId}` | Shares bought (AMM or order match) |
|
|
1043
|
+
| `exit-option/{poolId}` | Shares sold (order match) |
|
|
1044
|
+
| `liquidity/{poolId}` | Liquidity added |
|
|
1045
|
+
| `split/{poolId}` | Tokens split into Yes+No |
|
|
1046
|
+
| `merge/{poolId}` | Yes+No merged back |
|
|
1047
|
+
| `remove-liquidity/{poolId}` | Liquidity removed |
|
|
1048
|
+
| `sync-price/{poolId}` | Price update |
|
|
1049
|
+
| `order-created/{poolId}` | New order placed |
|
|
1050
|
+
| `order-cancelled/{poolId}` | Order cancelled |
|
|
1051
|
+
| `order-filled/{poolId}` | Order filled (full/partial) |
|
|
1052
|
+
| `winner/{poolId}` | Winner proposed |
|
|
1053
|
+
| `winner-proposer/{poolId}` | Proposer recorded |
|
|
1054
|
+
| `reveal-winner-available/{poolId}` | Appeal winner ready |
|
|
1055
|
+
| `dispute-opened/{poolId}` | Dispute opened |
|
|
1056
|
+
| `oracle-created/{poolId}` | Dispute oracle deployed |
|
|
1057
|
+
| `dispute-time-extented/{poolId}` | Deadline extended |
|
|
1058
|
+
| `appeal-opened/{poolId}` | Appeal filed |
|
|
1059
|
+
| `appeal-winner-calculated/{poolId}` | Oracle calculated winner |
|
|
1060
|
+
| `dispute-winner/{poolId}` | Dispute decided (LEX) |
|
|
1061
|
+
| `appeal-winner/{poolId}` | Final appeal winner |
|
|
1062
|
+
| `claim-reward/{poolId}` | Reward claimed (broadcast) |
|
|
1063
|
+
| `claim-reward/{poolId}/{userId}` | Reward claimed (personal) |
|
|
1064
|
+
| `dispute-refund/{poolId}/{userId}` | Dispute bond refunded |
|
|
1065
|
+
| `appeal-refund/{poolId}/{userId}` | Appeal fee refunded |
|
|
1066
|
+
| `resolution-refund/{poolId}/{userId}` | Resolution bond refunded |
|
|
1067
|
+
| `resolver-reward/{poolId}/{userId}` | Resolver reward |
|
|
1068
|
+
| `notifications/{userId}` | Personal notifications |
|
|
1069
|
+
|
|
1070
|
+
---
|
|
1071
|
+
|
|
1072
|
+
## License
|
|
1073
|
+
|
|
1074
|
+
MIT
|