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.
Files changed (102) hide show
  1. package/README.md +1074 -0
  2. package/dist/Rain.d.ts +212 -0
  3. package/dist/Rain.js +401 -0
  4. package/dist/RainAA.d.ts +62 -0
  5. package/dist/RainAA.js +304 -0
  6. package/dist/abi/CreateMarketAbi.d.ts +1125 -0
  7. package/dist/abi/CreateMarketAbi.js +1 -0
  8. package/dist/abi/ERC20Abi.d.ts +89 -0
  9. package/dist/abi/ERC20Abi.js +119 -0
  10. package/dist/abi/MarketsAbi.d.ts +2810 -0
  11. package/dist/abi/MarketsAbi.js +1 -0
  12. package/dist/abi/OracleAbi.d.ts +11 -0
  13. package/dist/abi/OracleAbi.js +15 -0
  14. package/dist/api/comments.d.ts +14 -0
  15. package/dist/api/comments.js +48 -0
  16. package/dist/api/dispute.d.ts +3 -0
  17. package/dist/api/dispute.js +30 -0
  18. package/dist/api/follow.d.ts +6 -0
  19. package/dist/api/follow.js +38 -0
  20. package/dist/api/helpers.d.ts +4 -0
  21. package/dist/api/helpers.js +26 -0
  22. package/dist/api/index.d.ts +14 -0
  23. package/dist/api/index.js +14 -0
  24. package/dist/api/investments.d.ts +21 -0
  25. package/dist/api/investments.js +135 -0
  26. package/dist/api/notifications.d.ts +4 -0
  27. package/dist/api/notifications.js +24 -0
  28. package/dist/api/orders.d.ts +8 -0
  29. package/dist/api/orders.js +40 -0
  30. package/dist/api/points.d.ts +5 -0
  31. package/dist/api/points.js +32 -0
  32. package/dist/api/poolReviews.d.ts +4 -0
  33. package/dist/api/poolReviews.js +23 -0
  34. package/dist/api/pools.d.ts +41 -0
  35. package/dist/api/pools.js +149 -0
  36. package/dist/api/priceData.d.ts +2 -0
  37. package/dist/api/priceData.js +9 -0
  38. package/dist/api/rainBurn.d.ts +3 -0
  39. package/dist/api/rainBurn.js +15 -0
  40. package/dist/api/types.d.ts +292 -0
  41. package/dist/api/types.js +2 -0
  42. package/dist/api/users.d.ts +15 -0
  43. package/dist/api/users.js +60 -0
  44. package/dist/auth/login.d.ts +4 -0
  45. package/dist/auth/login.js +27 -0
  46. package/dist/auth/types.d.ts +16 -0
  47. package/dist/auth/types.js +1 -0
  48. package/dist/config/environments.d.ts +15 -0
  49. package/dist/config/environments.js +41 -0
  50. package/dist/constants/contractmethods.d.ts +15 -0
  51. package/dist/constants/contractmethods.js +15 -0
  52. package/dist/index.d.ts +9 -0
  53. package/dist/index.js +6 -0
  54. package/dist/markets/getDisputeFee.d.ts +5 -0
  55. package/dist/markets/getDisputeFee.js +19 -0
  56. package/dist/markets/getOrderInfo.d.ts +53 -0
  57. package/dist/markets/getOrderInfo.js +80 -0
  58. package/dist/markets/getResolverBondAmount.d.ts +9 -0
  59. package/dist/markets/getResolverBondAmount.js +35 -0
  60. package/dist/markets/getUserOptionLPShares.d.ts +7 -0
  61. package/dist/markets/getUserOptionLPShares.js +17 -0
  62. package/dist/markets/getUserOptionShares.d.ts +8 -0
  63. package/dist/markets/getUserOptionShares.js +17 -0
  64. package/dist/socket/RainSocket.d.ts +175 -0
  65. package/dist/socket/RainSocket.js +186 -0
  66. package/dist/tx/CreateMarket/buildCreateMarketRawTx.d.ts +2 -0
  67. package/dist/tx/CreateMarket/buildCreateMarketRawTx.js +55 -0
  68. package/dist/tx/CreateMarket/createMarketValidation.d.ts +2 -0
  69. package/dist/tx/CreateMarket/createMarketValidation.js +48 -0
  70. package/dist/tx/CreateMarket/helpers.d.ts +3 -0
  71. package/dist/tx/CreateMarket/helpers.js +42 -0
  72. package/dist/tx/buildAddLiquidityRawTx.d.ts +2 -0
  73. package/dist/tx/buildAddLiquidityRawTx.js +23 -0
  74. package/dist/tx/buildApprovalRawTx.d.ts +2 -0
  75. package/dist/tx/buildApprovalRawTx.js +24 -0
  76. package/dist/tx/buildCalculateWinnerRawTx.d.ts +13 -0
  77. package/dist/tx/buildCalculateWinnerRawTx.js +37 -0
  78. package/dist/tx/buildCancelOrdersRawTx.d.ts +3 -0
  79. package/dist/tx/buildCancelOrdersRawTx.js +43 -0
  80. package/dist/tx/buildClaimRawTx.d.ts +2 -0
  81. package/dist/tx/buildClaimRawTx.js +19 -0
  82. package/dist/tx/buildClosePoolRawTx.d.ts +20 -0
  83. package/dist/tx/buildClosePoolRawTx.js +95 -0
  84. package/dist/tx/buildEnterOptionRawTx.d.ts +2 -0
  85. package/dist/tx/buildEnterOptionRawTx.js +25 -0
  86. package/dist/tx/buildMergeRawTx.d.ts +2 -0
  87. package/dist/tx/buildMergeRawTx.js +21 -0
  88. package/dist/tx/buildOpenDisputeRawTx.d.ts +8 -0
  89. package/dist/tx/buildOpenDisputeRawTx.js +39 -0
  90. package/dist/tx/buildPlaceOrderRawTx.d.ts +3 -0
  91. package/dist/tx/buildPlaceOrderRawTx.js +47 -0
  92. package/dist/tx/buildRemoveLiquidityRawTx.d.ts +2 -0
  93. package/dist/tx/buildRemoveLiquidityRawTx.js +23 -0
  94. package/dist/tx/buildSplitRawTx.d.ts +2 -0
  95. package/dist/tx/buildSplitRawTx.js +21 -0
  96. package/dist/tx/types.d.ts +117 -0
  97. package/dist/tx/types.js +10 -0
  98. package/dist/types.d.ts +15 -0
  99. package/dist/types.js +1 -0
  100. package/dist/utils/helpers.d.ts +4 -0
  101. package/dist/utils/helpers.js +28 -0
  102. 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