@rainprotocolsdk/sdk 2.1.1 → 2.2.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 CHANGED
@@ -1,932 +1,926 @@
1
- # Rain SDK Documentation
1
+ # Rain Builders — SDK Guide
2
2
 
3
- ## Overview
3
+ Build complete prediction markets, trading applications, and custom integrations powered by Rain's automated protocol.
4
4
 
5
- Rain SDK is designed as a **clean, modular, and extensible TypeScript SDK** for interacting with Rain markets and preparing on-chain transactions.
5
+ The Rain SDK provides the TypeScript tools you need to interact with our protocol on Arbitrum One. You can use it to build, sign, and send transactions for everything from creating new markets to trading options and claiming winnings.
6
6
 
7
- The SDK is intentionally split into two layers:
7
+ Whether you're building a custom frontend, routing trades for your users, or launching specialized pools, the SDK handles the technical execution. By integrating Rain, you plug directly into our automated market maker (AMM) liquidity for logic-based forecasts.
8
8
 
9
- * **Rain** Stateless, public-facing utilities (data fetching, raw transaction builders)
10
- * **RainAA** → Stateful Account Abstraction layer (smart accounts)
9
+ If you're building high-speed applications, you can tap into our **RNG Layer**. This system uses verifiable randomness through Chainlink VRF to power mathematically-driven risk scenarios. Instead of using the individual pools required for standard prediction markets, the RNG Layer draws from a single shared liquidity pool. This gives your users instant settlement for fast-paced, random markets across any application built on this layer.
11
10
 
12
- ---
11
+ You can also give your users a simpler trading experience. The SDK includes an **account abstraction module**. This lets you manage smart accounts and sponsor gas fees, so your users can trade without worrying about network costs.
13
12
 
14
- ## Installation
13
+ Our Builder Program supports platforms that drive volume or create unique markets. You bring the users and the ideas, and the SDK provides the on-chain infrastructure.
15
14
 
16
- ```bash
17
- npm install @rainprotocolsdk/sdk
18
- ```
15
+ ---
19
16
 
20
- or
17
+ ## What You Can Build
21
18
 
22
- ```bash
23
- yarn add @rainprotocolsdk/sdk
24
- ```
19
+ The SDK gives you direct access to the protocol's core functions. Here is what you can do right away.
25
20
 
26
- ---
21
+ - **Permissionless Market Creation** — Launch public or private markets on any verifiable event. You define the options, set the resolution rules, and provide the initial liquidity in a single transaction. Rain is open for anyone to build on, so you never need our approval to start a new pool.
22
+ - **Trading** — Construct interfaces for your users to buy and sell outcome shares against the AMM with market and limit orders.
23
+ - **Gas-Sponsored Execution** — Route transactions through the `RainAA` module. We use Alchemy smart accounts to cover gas costs. Your users can trade and interact with the protocol without needing to hold native ETH in their wallets.
24
+ - **Live Data Streams** — Connect to our WebSockets via `RainSocket` to receive real-time trade events, order activity, dispute updates, and market resolution notifications directly in your front end.
27
25
 
28
- ### Initialization
26
+ ---
29
27
 
30
- ```ts
31
- import { Rain } from "@rainprotocolsdk/sdk";
28
+ ## SDK Architecture: The Two Pillars
32
29
 
33
- const rain = new Rain();
34
- ```
30
+ The SDK is split into two independent classes. This structure separates the logical transaction building from the actual execution.
35
31
 
36
- ### Constructor Parameters
32
+ | Module | Role | Core Functions | Wallet Required |
33
+ | ------------------- | ---------------------- | ------------------------------------------------------------------- | --------------- |
34
+ | `Rain` (Stateless) | Defines **what** to do | Market queries, transaction builders | No |
35
+ | `RainAA` (Stateful) | Defines **how** to execute | Smart account creation, gas-sponsored execution, session management | Yes |
37
36
 
38
- ```ts
39
- interface RainCoreConfig {
40
- environment?: "development" | "stage" | "production"; // default: "development"
41
- rpcUrl?: string; // optional custom RPC URL
42
- }
43
- ```
37
+ ### The Execution Flow
44
38
 
45
- ---
39
+ 1. **Your Application** — The user interacts with your custom frontend.
40
+ 2. **The `Rain` Class** — Your application calls a method here to build an action. All transaction builders return an unsigned `RawTransaction` containing the `to`, `data`, and optional `value` fields.
41
+ 3. **The `RainAA` Class** — You pass that `RawTransaction` into this module. It manages the Alchemy smart accounts and signs the transaction via account abstraction, covering the network fees.
42
+ 4. **Arbitrum One** — The transaction settles on-chain, interacting with our Diamond Proxy pools and the specific AMM for that option.
46
43
 
47
- ## login
44
+ ### The `Rain` Class (Stateless)
48
45
 
49
- Authenticates a user against the Rain backend using a wallet signature and returns a JWT access token.
46
+ `Rain` operates without state. It fetches data and builds unsigned transactions. It does not require a connected wallet.
50
47
 
51
- The caller is responsible for signing the message pass the resulting signature along with the wallet addresses.
48
+ You use this class to query the protocol and construct actions. Because it returns a standard `RawTransaction`, you retain the freedom to decide how to execute it — whether you use `RainAA`, `wagmi`, `ethers`, or another custom provider.
52
49
 
53
- ### Method Signature
50
+ ### The `RainAA` Class (Stateful Execution)
54
51
 
55
- ```ts
56
- login(params: LoginParams): Promise<LoginResult>
57
- ```
52
+ `RainAA` maintains state. It handles the mechanics of account abstraction.
58
53
 
59
- ### Parameters
54
+ Once your stateless class generates the transaction data, you pass it here. This module takes care of the execution. It sponsors gas costs so your users do not need native ETH to trade.
60
55
 
61
- ```ts
62
- interface LoginParams {
63
- signature: string; // personal_sign of the lowercased wallet address
64
- walletAddress: string; // EOA wallet address
65
- smartWalletAddress: string; // Smart account / AA wallet address
66
- referredBy?: string; // Optional referral code
67
- }
68
- ```
56
+ ---
69
57
 
70
- ### Return Type
58
+ ## Quick Start
71
59
 
72
- ```ts
73
- interface LoginResult {
74
- accessToken: string; // JWT token for authenticated API calls
75
- userId: string; // Backend user ID
76
- }
77
- ```
60
+ The Rain SDK is designed to get you reading data and building transactions as quickly as possible. Because the core `Rain` class is stateless, you can start fetching markets and building trade payloads without requiring users to connect a wallet upfront.
78
61
 
79
- ### Example
62
+ ### Installation
80
63
 
81
- ```ts
82
- // 1. Sign the message with your wallet provider
83
- const signature = await walletClient.signMessage({
84
- message: walletAddress.toLowerCase(),
85
- });
64
+ First, install the SDK into your project using your preferred package manager.
86
65
 
87
- // 2. Login
88
- const { accessToken, userId } = await rain.login({
89
- signature,
90
- walletAddress: "0x996ea23940f4a01610181D04bdB6F862719b63f0",
91
- smartWalletAddress: "0xSmartAccountAddress...",
92
- referredBy: "REFCODE123", // optional
93
- });
66
+ ```bash
67
+ npm install @rainprotocolsdk/sdk
68
+ npm install viem@^2.0.0 # Required peer dependency
94
69
  ```
95
70
 
96
- ---
71
+ ### Your First Trade Flow
97
72
 
98
- ## getPublicMarkets
73
+ Here is a complete example of how you initialize the client, read active markets from the protocol, build a transaction to buy shares, and execute it.
99
74
 
100
- Fetches public market data from the Rain backend.
75
+ **1. Initialize (stateless no wallet needed)**
101
76
 
102
- ### Method Signature
77
+ You set up the `Rain` class by pointing it to the development environment. This automatically configures the correct factory addresses and API endpoints.
103
78
 
104
79
  ```ts
105
- getPublicMarkets(params: GetMarketsParams): Promise<Market[]>;
80
+ const rain = new Rain({ environment: 'development' });
106
81
  ```
107
82
 
108
- ### Parameters
83
+ **2. Fetch Markets**
109
84
 
110
- ```ts
111
- interface GetMarketsParams {
112
- limit?: number;
113
- offset?: number;
114
- sortBy?: "Liquidity" | "Volumn" | "latest";
115
- status?: 'Live' | 'New' | 'WaitingForResult' | 'UnderDispute' | 'UnderAppeal' | 'ClosingSoon' | 'InReview' | 'InEvaluation' | 'Closed' | 'Trading';
116
- }
117
- ```
118
-
119
- ### Example
85
+ You query the protocol for a list of active markets. This pulls data directly from the Rain API.
120
86
 
121
87
  ```ts
122
- const markets = await rain.getPublicMarkets({
123
- limit: 12,
124
- offset: 1,
125
- sortBy: "Liquidity",
126
- status: "Live",
127
- });
88
+ const markets = await rain.getPublicMarkets({ limit: 10 });
128
89
  ```
129
90
 
130
- ---
131
-
132
- ## getMarketById
91
+ **3. Build a Buy Transaction**
133
92
 
134
- Fetches a single market by its ID from the Rain backend.
135
-
136
- ### Method Signature
93
+ You define exactly what you want to do. In this case, you are building the raw transaction data to buy $10 worth of shares in Option 1.
137
94
 
138
95
  ```ts
139
- getMarketById(params: GetMarketByIdParams): Promise<Market>
96
+ const rawTx = rain.buildBuyOptionRawTx({
97
+ marketContractAddress: '0x...',
98
+ selectedOption: 1n,
99
+ buyAmountInWei: 10_000_000n, // 10 USDT (Arbitrum USDT uses 6 decimals)
100
+ });
140
101
  ```
141
102
 
142
- ### Parameters
103
+ **4. Execute**
104
+
105
+ The SDK hands you back an unsigned `RawTransaction` (`{ to, data, value }`). You then pass this payload to your user's standard wallet provider, or route it through the `RainAA` class for gasless execution.
143
106
 
144
107
  ```ts
145
- interface GetMarketByIdParams {
146
- marketId: string; // MongoDB _id of the market
147
- }
108
+ await yourProvider.sendTransaction(rawTx);
148
109
  ```
149
110
 
150
- ### Validations
111
+ ---
151
112
 
152
- | Parameter | Type | Required | Description |
153
- | ---------- | -------- | -------- | ---------------------- |
154
- | `marketId` | `string` | ✅ | Unique market `_id` |
113
+ ## Authentication
155
114
 
156
- ### Example
115
+ Before accessing protected endpoints, users must authenticate with the Rain API.
157
116
 
158
117
  ```ts
159
- const market = await rain.getMarketById({
160
- marketId: "698c8f116e985bbfacc7fc01",
118
+ const result = await rain.login({
119
+ walletAddress: '0x996ea23940f4a01610181D04bdB6F862719b63f0',
120
+ signature: '0x...', // Signed message from user's wallet
161
121
  });
122
+ // Returns: { accessToken, userId, ... }
162
123
  ```
163
124
 
125
+ The `accessToken` returned is required for methods that need user context, such as `getUserInvestments`, `buildClaimTx`, and `buildExtendTimeTx`.
126
+
164
127
  ---
165
128
 
166
- ## getUserInvestments
129
+ ## Creating a Market
167
130
 
168
- Fetches a user's invested markets from the Rain backend. Requires a valid access token.
131
+ Launch your own prediction markets on any verifiable event.
169
132
 
170
- ### Method Signature
133
+ One of the core features of building on Rain is permissionless market creation. You do not need approval to start a new pool. If an event has a verifiable outcome, you can build a market around it using the SDK.
171
134
 
172
- ```ts
173
- getUserInvestments(params: GetUserInvestmentsParams): Promise<UserInvestment[]>
174
- ```
135
+ When you create a market, you define the question, set the possible options, and provide the initial liquidity. This liquidity allows the Automated Market Maker (AMM) to start pricing shares immediately.
175
136
 
176
- ### Parameters
137
+ ### Public vs. Private Markets
177
138
 
178
- ```ts
179
- interface GetUserInvestmentsParams {
180
- walletAddress: string; // User's wallet address
181
- accessToken: string; // JWT from Rain auth (login)
182
- limit?: number;
183
- offset?: number;
184
- status?: 'Live' | 'New' | 'WaitingForResult' | 'UnderDispute' | 'UnderAppeal' | 'ClosingSoon' | 'InReview' | 'InEvaluation' | 'Closed' | 'Trading';
185
- }
186
- ```
139
+ Before writing the code, you need to decide what kind of market you are building using the `isPublic` parameter.
187
140
 
188
- ### Validations
141
+ - **Public Markets** — These are open to anyone and are great for topics like sports, politics, or global events. The market can be resolved either by a specialized AI oracle or by the market creator.
142
+ - **Private Markets** — These are designed for specific groups or topics and require a secret access code to join. The person who creates the pool acts as the resolver and decides the outcome.
189
143
 
190
- | Parameter | Type | Required | Description |
191
- | --------------- | ------------- | -------- | ------------------------------------ |
192
- | `walletAddress` | `string` | ✅ | The user's wallet address |
193
- | `accessToken` | `string` | ✅ | JWT returned from `login()` |
194
- | `limit` | `number` | ❌ | Number of results per page |
195
- | `offset` | `number` | ❌ | Pagination offset |
196
- | `status` | `MarketStatus`| ❌ | Filter by market status |
144
+ ### Building the Transaction
197
145
 
198
- ### Example
146
+ You use the stateless `Rain` class to construct the transaction. The `buildCreateMarketTx` method requires specific parameters to set the probabilities, dates, and token decimals.
147
+
148
+ Because creating a market usually requires approving the token spend first, this method returns an array of raw transactions that you must execute in order.
199
149
 
200
150
  ```ts
201
- const investments = await rain.getUserInvestments({
202
- walletAddress: "0x996ea23940f4a01610181D04bdB6F862719b63f0",
203
- accessToken: "eyJhbGciOi...",
204
- limit: 10,
205
- offset: 1,
206
- status: "Live",
151
+ import { Rain } from '@rainprotocolsdk/sdk';
152
+
153
+ const rain = new Rain({ environment: 'production' });
154
+
155
+ // buildCreateMarketTx returns an array: [approveTx, createTx] or just [createTx]
156
+ const txs = await rain.buildCreateMarketTx({
157
+ marketQuestion: 'Will BTC hit 100k?',
158
+ marketOptions: ['Yes', 'No', 'Maybe'],
159
+ marketTags: ['crypto', 'bitcoin'],
160
+ marketDescription: 'Prediction market for BTC price',
161
+ isPublic: true,
162
+ isPublicPoolResolverAi: false,
163
+ creator: '0x996ea23940f4a01610181D04bdB6F862719b63f0',
164
+ startTime: 1770836400n,
165
+ endTime: 1770922800n,
166
+ no_of_options: 3n,
167
+ inputAmountWei: 100_000_000n, // 100 USDT (min 10 tokens)
168
+ barValues: [34, 33, 33], // Initial probability distribution (%)
169
+ baseToken: '0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9',
170
+ tokenDecimals: 6,
207
171
  });
208
- ```
209
172
 
210
- ---
173
+ // Execute sequentially
174
+ for (const tx of txs) {
175
+ await yourProvider.sendTransaction(tx);
176
+ }
177
+ ```
211
178
 
212
- ## buildApprovalTx
179
+ ### Breaking Down the Parameters
213
180
 
214
- Builds a raw ERC20 approval transaction if needed.
181
+ - **Text Fields** `marketQuestion`, `marketDescription`, and `marketTags` define how the market appears to users.
182
+ - **Options** — `marketOptions` is an array of the possible outcomes. `no_of_options` is the numerical count of those choices.
183
+ - **Permissions** — `isPublic` determines if the market is open or access-restricted. `isPublicPoolResolverAi` dictates if the AI oracle handles the resolution.
184
+ - **Timing** — `startTime` and `endTime` are Unix timestamps defining when the market is active.
185
+ - **Liquidity & Tokens** — `inputAmountWei` is your initial funding. The minimum requirement is $10 in the chosen token. `baseToken` is the contract address of the currency being used, and `tokenDecimals` ensures the math is calculated correctly.
186
+ - **Initial Odds** — `barValues` sets the starting probability distribution for the options as a percentage. All values must sum to 100.
215
187
 
216
- This function prepares an unsigned `approve(spender, amount)` transaction and does not execute it.
188
+ ### Managing the Market Lifecycle
217
189
 
218
- If `amount` is not provided, a default large allowance is approved.
190
+ Creating the market is just the first step. To manage the conclusion of a market, the SDK provides these transaction builders:
219
191
 
220
- ### Return Type
192
+ - `buildCloseMarketTx(params)` — Builds a raw transaction to officially close the market and halt trading.
193
+ - `buildCreateDisputeTx(params)` — Builds a raw transaction to open a dispute on the market outcome.
194
+ - `buildCreateAppealTx(params)` — Builds a raw transaction to appeal a dispute decision.
195
+ - `buildExtendTimeTx(params)` — Builds a raw transaction to extend the dispute resolution window (re-submit appeal).
221
196
 
222
- ```ts
223
- interface RawTransaction {
224
- to: `0x${string}`;
225
- data: `0x${string}`;
226
- }
227
- ```
197
+ ---
228
198
 
229
- ### Example
199
+ ## Trading & Positions
230
200
 
231
- ```ts
232
- const approvalTx = rain.buildApprovalTx({
233
- tokenAddress: "0xTokenAddress...", // ERC20 token address
234
- spender: "0xMarketContractAddress...", // Market contract address
235
- amount: 1000000000000000000n // optional
236
- });
237
- ```
201
+ Build interfaces for buying shares, placing limit orders, and claiming winnings.
238
202
 
239
- ---
203
+ Once a market is live, participants can start taking positions. The Rain SDK allows you to construct trading actions directly from the protocol.
240
204
 
241
- ## buildBuyOptionRawTx
205
+ Because trades happen against our Automated Market Maker (AMM), your users get instant execution. They do not have to wait for a counterparty to match their order.
242
206
 
243
- Builds a **raw EVM transaction** for entering a market option.
207
+ ### Buying Options
244
208
 
245
- This function **does not send the transaction** it only prepares calldata.
209
+ When a user buys an option, they are purchasing shares of a specific outcome. The price of these shares is determined by the AMM based on the current pool ratios.
246
210
 
247
- ### Method Signature
211
+ Here is how you build a standard market order to buy shares.
248
212
 
249
213
  ```ts
250
- buildBuyOptionRawTx(params: EnterOptionTxParams): RawTransaction;
251
- ```
214
+ import { Rain } from '@rainprotocolsdk/sdk';
252
215
 
253
- ### Parameters
216
+ const rain = new Rain({ environment: 'production' });
254
217
 
255
- ```ts
256
- interface EnterOptionTxParams {
257
- marketContractAddress: `0x${string}`; // TradeMarket contract address
258
- selectedOption: bigint; // Option index
259
- buyAmountInWei: bigint; // Amount in wei
260
- }
218
+ // Build the raw buy transaction
219
+ const buyTx = rain.buildBuyOptionRawTx({
220
+ marketContractAddress: '0x...',
221
+ selectedOption: 1n, // The option index (e.g., 0 for Yes, 1 for No)
222
+ buyAmountInWei: 10_000_000n, // 10 USDT (Arbitrum USDT uses 6 decimals)
223
+ });
261
224
  ```
262
225
 
263
- ### Return Type
226
+ If a user wants to set a specific entry target rather than taking the current AMM price, you can build a limit order instead.
264
227
 
265
228
  ```ts
266
- interface RawTransaction {
267
- to: `0x${string}`;
268
- data: `0x${string}`;
269
- }
229
+ // Build a limit buy transaction
230
+ const limitTx = rain.buildLimitBuyOptionTx({
231
+ marketContractAddress: '0x...',
232
+ selectedOption: 1,
233
+ pricePerShare: 500000000000000000n, // 0.50 represented in 1e18
234
+ buyAmountInWei: 10_000_000n,
235
+ tokenDecimals: 6,
236
+ });
270
237
  ```
271
238
 
272
- ### Example
239
+ ### Selling Options
240
+
241
+ Users do not have to hold their shares until the market resolves. If the odds shift in their favor, they can sell their position early to lock in a profit.
273
242
 
274
243
  ```ts
275
- const rawTx = rain.buildBuyOptionRawTx({
276
- marketContractAddress: "0xMarketContractAddress...",
277
- selectedOption: 1n,
278
- buyAmountInWei: 1000000n,
244
+ // Build a limit sell transaction
245
+ const sellTx = rain.buildLimitSellOptionTx({
246
+ marketContractAddress: '0x...',
247
+ selectedOption: 1,
248
+ pricePerShare: 500000000000000000n, // 0.50 represented in 1e18
249
+ shares: 5_000_000n, // The number of shares to sell
250
+ tokenDecimals: 6,
279
251
  });
280
252
  ```
281
253
 
282
- ---
254
+ ### Canceling Orders
283
255
 
284
- ## buildLimitBuyOptionTx
256
+ If a user places limit orders that have not been filled yet, they might want to cancel them. You can build a transaction to remove specific open orders by referencing their order IDs, or cancel all open orders at once.
285
257
 
286
- Builds a **raw EVM transaction** for placing a limit buy order on a Rain market.
258
+ ```ts
259
+ // Build a transaction to cancel specific open orders
260
+ const cancelTx = rain.buildCancelOrdersTx({
261
+ marketContractAddress: '0x...',
262
+ orders: [
263
+ { option: 1, price: 0.5, orderID: 1n },
264
+ { option: 1, price: 0.6, orderID: 2n },
265
+ ],
266
+ });
287
267
 
288
- This function **does not send the transaction** it only prepares calldata.
268
+ // Build a transaction to cancel all open orders for a user
269
+ const cancelAllTx = await rain.buildCancelAllOpenOrdersTx({
270
+ marketContractAddress: '0x...',
271
+ walletAddress: '0x...',
272
+ accessToken: 'your-access-token',
273
+ });
274
+ ```
289
275
 
290
- ### Method Signature
276
+ ### Claiming Winnings
291
277
 
292
- ```ts
293
- buildLimitBuyOptionTx(params: EnterLimitOptionTxParams): RawTransaction
294
- ```
278
+ When a market concludes, it goes through a resolution phase and a short dispute window. Once that window closes, the market is officially settled.
295
279
 
296
- ### Parameters
280
+ Users who hold shares in the winning outcome can then claim their payout. The payout is drawn from the total pool of funds, after a platform fee is collected.
297
281
 
298
282
  ```ts
299
- interface EnterLimitOptionTxParams {
300
- marketContractAddress: `0x${string}`; // Market contract address
301
- selectedOption: number; // Option index
302
- pricePerShare: number; // Limit price per share (between 0 and 1)
303
- buyAmountInWei: bigint; // Total buy amount in token wei
304
- tokenDecimals?: number; // Token decimals (default: 6)
305
- }
283
+ // Build the raw claim transaction
284
+ const claimTx = await rain.buildClaimTx({
285
+ marketId: '698c8f116e985bbfacc7fc01',
286
+ walletAddress: '0x996ea23940f4a01610181D04bdB6F862719b63f0',
287
+ });
306
288
  ```
307
289
 
308
- ### Validations
290
+ This single transaction sends the user's original stake plus their winnings directly to their wallet or smart account.
309
291
 
310
- | Field | Type | Required | Description |
311
- | ----------------------- | ------------- | -------- | ------------------------------------------------------ |
312
- | `marketContractAddress` | `0x${string}` | ✅ | Address of the market contract |
313
- | `selectedOption` | `number` | ✅ | Option index to place the buy order for |
314
- | `pricePerShare` | `number` | ✅ | Limit price per share (between `0` and `1`) |
315
- | `buyAmountInWei` | `bigint` | ✅ | Total amount to spend (already converted to token wei) |
316
- | `tokenDecimals` | `number` | ❌ | Token decimals (default: `6`) |
292
+ ---
317
293
 
318
- ### Return Type
294
+ ## Liquidity
319
295
 
320
- ```ts
321
- interface RawTransaction {
322
- to: `0x${string}`;
323
- data: `0x${string}`;
324
- }
325
- ```
296
+ Every market on Rain needs liquidity to function. Because trades execute against an Automated Market Maker (AMM), the pool requires an initial supply of funds to price shares and settle outcomes.
326
297
 
327
- ### Example
298
+ When you create a market, you must provide at least $10 in initial liquidity via the `inputAmountWei` parameter in `buildCreateMarketTx`. This is the only way to supply liquidity to a market through the current SDK.
328
299
 
329
- ```ts
330
- rain.buildLimitBuyOptionTx({
331
- marketContractAddress: "0xMarketContractAddress...",
332
- selectedOption: 1,
333
- pricePerShare: 0.6,
334
- buyAmountInWei: 1000000n,
335
- });
336
- ```
300
+ ### How LPs Earn Fees
337
301
 
338
- ---
302
+ Liquidity providers take on the other side of the trades. They fund the entire market rather than betting on "Yes" or "No". In return for taking on this risk, they earn a cut of the trading activity.
339
303
 
340
- ## buildLimitSellOptionTx
304
+ The protocol charges a 5% fee on transactions. From that total volume, 1.2% is automatically distributed back to the liquidity providers of that specific market.
341
305
 
342
- Builds a **raw EVM transaction** for placing a limit sell order on a Rain market.
306
+ For applications built on the RNG Layer, like Risk Markets, liquidity providers act as the "house". They still earn the 1.2% volume fee. Additionally, if players fail to exit their positions before a scenario terminates, their stakes remain in the pool, which increases the value of the LP shares.
343
307
 
344
- This function **does not send the transaction** — it only prepares calldata.
308
+ ### Withdrawing Liquidity
345
309
 
346
- ### Method Signature
310
+ Liquidity is locked until the market reaches its resolution. There is no method to remove liquidity while the market is active.
347
311
 
348
- ```ts
349
- buildLimitSellOptionTx(params: LimitSellOptionTxParams): RawTransaction
350
- ```
312
+ Liquidity providers recover their initial supplied share, plus any accumulated fees, by using the standard `buildClaimTx` method after the market officially resolves and settles.
313
+
314
+ ---
315
+
316
+ ## Disputes & Appeals
351
317
 
352
- ### Parameters
318
+ When a market resolves, participants can challenge the outcome through the dispute and appeal system.
319
+
320
+ ### Opening a Dispute
321
+
322
+ If a participant believes the market outcome is incorrect, they can open a dispute.
353
323
 
354
324
  ```ts
355
- interface LimitSellOptionTxParams {
356
- marketContractAddress: `0x${string}`; // Market contract address
357
- selectedOption: number; // Option index
358
- pricePerShare: number; // Limit price per share (between 0 and 1)
359
- sharesAmountWei: bigint; // Number of shares to sell (in wei)
360
- tokenDecimals?: number; // Token decimals (default: 6)
325
+ const disputeTxs = await rain.buildCreateDisputeTx({
326
+ marketContractAddress: '0x...',
327
+ walletAddress: '0x...',
328
+ accessToken: 'your-access-token',
329
+ });
330
+
331
+ for (const tx of disputeTxs) {
332
+ await yourProvider.sendTransaction(tx);
361
333
  }
362
334
  ```
363
335
 
364
- ### Validations
336
+ ### Filing an Appeal
365
337
 
366
- | Field | Type | Required | Description |
367
- | ----------------------- | ------------- | -------- | ------------------------------------------- |
368
- | `marketContractAddress` | `0x${string}` | ✅ | Address of the market contract |
369
- | `selectedOption` | `number` | ✅ | Option index to place the sell order for |
370
- | `pricePerShare` | `number` | ✅ | Limit price per share (between `0` and `1`) |
371
- | `sharesAmountWei` | `bigint` | ✅ | Number of shares to sell (must be `> 0`) |
372
- | `tokenDecimals` | `number` | ❌ | Token decimals (default: `6`) |
373
-
374
- ### Return Type
338
+ If the dispute resolution is also contested, participants can escalate it through an appeal.
375
339
 
376
340
  ```ts
377
- interface RawTransaction {
378
- to: `0x${string}`;
379
- data: `0x${string}`;
341
+ const appealTxs = await rain.buildCreateAppealTx({
342
+ marketContractAddress: '0x...',
343
+ walletAddress: '0x...',
344
+ accessToken: 'your-access-token',
345
+ });
346
+
347
+ for (const tx of appealTxs) {
348
+ await yourProvider.sendTransaction(tx);
380
349
  }
381
350
  ```
382
351
 
383
- ### Example
352
+ ### Extending the Dispute Window
353
+
354
+ If more time is needed for resolution, the dispute window can be extended.
384
355
 
385
356
  ```ts
386
- rain.buildLimitSellOptionTx({
387
- marketContractAddress: "0xMarketContractAddress...",
388
- selectedOption: 0,
389
- pricePerShare: 0.4,
390
- sharesAmountWei: 500000n,
357
+ const extendTx = await rain.buildExtendTimeTx({
358
+ marketContractAddress: '0x...',
359
+ walletAddress: '0x...',
360
+ accessToken: 'your-access-token',
391
361
  });
362
+
363
+ await yourProvider.sendTransaction(extendTx);
392
364
  ```
393
365
 
394
366
  ---
395
367
 
396
- ## buildCancelOrdersTx
368
+ ## Account Abstraction
397
369
 
398
- Builds **raw EVM transactions** to cancel specific open orders on a Rain market.
370
+ Remove gas fees from your trading experience using stateful execution.
399
371
 
400
- Groups orders by type and returns up to two transactions one for sell orders (`cancelSellOrders`) and one for buy orders (`cancelBuyOrders`).
372
+ The SDK splits its functionality into two classes. While the `Rain` class is stateless and handles your queries and transaction building, it does not send transactions.
401
373
 
402
- This function **does not send the transaction** it only prepares calldata.
374
+ To execute trades without requiring users to hold native ETH for gas, you use the `RainAA` class. This stateful class manages Alchemy smart accounts with gas sponsorship.
403
375
 
404
- ### Method Signature
376
+ ### Setting Up the Execution Engine
405
377
 
406
- ```ts
407
- buildCancelOrdersTx(params: CancelOrdersTxParams): RawTransaction[]
408
- ```
409
-
410
- ### Parameters
378
+ To get started, you initialize the `RainAA` class with your standard viem wallet client and your Alchemy credentials.
411
379
 
412
380
  ```ts
413
- interface OrderToCancel {
414
- orderType: 'buy' | 'sell';
415
- option: bigint; // Option index (e.g. 0n for Yes, 1n for No)
416
- pricePerShare: bigint; // Price in 18-decimal wei
417
- orderId: bigint; // externalID from the open order
418
- }
381
+ import { RainAA } from '@rainprotocolsdk/sdk';
382
+ import { arbitrum } from 'viem/chains';
419
383
 
420
- interface CancelOrdersTxParams {
421
- marketContractAddress: `0x${string}`;
422
- orders: OrderToCancel[];
423
- }
384
+ const rainAA = new RainAA({
385
+ walletClient: yourWalletClient, // viem WalletClient
386
+ alchemyApiKey: 'your-alchemy-key',
387
+ paymasterPolicyId: 'your-policy-id',
388
+ chain: arbitrum,
389
+ rpcUrl: 'https://...', // Optional
390
+ });
424
391
  ```
425
392
 
426
- ### Validations
427
-
428
- | Field | Type | Required | Description |
429
- | ----------------------- | ---------------- | -------- | ------------------------------------- |
430
- | `marketContractAddress` | `0x${string}` | ✅ | Address of the market contract |
431
- | `orders` | `OrderToCancel[]`| ✅ | Non-empty array of orders to cancel |
432
-
433
- ### Return Type
393
+ Once initialized, you connect the client. This derives a smart account from the user's Externally Owned Account (EOA).
434
394
 
435
395
  ```ts
436
- RawTransaction[] // 1 tx if only buy or only sell; 2 txs if both
396
+ // Connect, derives smart account from EOA
397
+ const smartAccountAddress = await rainAA.connect();
398
+ console.log('Smart account:', smartAccountAddress);
437
399
  ```
438
400
 
439
- ### Example
401
+ ### Session Management
402
+
403
+ The `RainAA` class provides simple accessors to retrieve the connected smart account address and the underlying AA client. When the session is over, you can disconnect the user.
440
404
 
441
405
  ```ts
442
- const txs = rain.buildCancelOrdersTx({
443
- marketContractAddress: "0xMarketContractAddress...",
444
- orders: [
445
- {
446
- orderType: "buy",
447
- option: 0n,
448
- pricePerShare: 600000000000000000n, // 0.6 in 18 decimals
449
- orderId: 42n,
450
- },
451
- {
452
- orderType: "sell",
453
- option: 1n,
454
- pricePerShare: 400000000000000000n,
455
- orderId: 43n,
456
- },
457
- ],
458
- });
406
+ rainAA.address; // Smart account address (throws if not connected)
407
+ rainAA.client; // Underlying AA client (throws if not connected)
408
+
409
+ // Disconnect
410
+ rainAA.disconnect();
459
411
  ```
460
412
 
461
413
  ---
462
414
 
463
- ## buildCancelAllOpenOrdersTx
415
+ ## WebSockets & Live Data
464
416
 
465
- Fetches all open orders for a wallet on a given market from the Rain backend and builds the cancel transactions automatically.
417
+ Keep your application in sync with the protocol without constantly polling for updates.
466
418
 
467
- Returns an empty array if no open orders exist.
419
+ The `RainSocket` class provides a dedicated WebSocket client that connects to the Rain API and exposes typed event subscriptions. Each subscription method returns an unsubscribe function call it when the user navigates away to prevent memory leaks.
468
420
 
469
- ### Method Signature
421
+ ### Setting Up
470
422
 
471
423
  ```ts
472
- buildCancelAllOpenOrdersTx(params: CancelAllOpenOrdersTxParams): Promise<RawTransaction[]>
473
- ```
424
+ import { RainSocket } from '@rainprotocolsdk/sdk';
474
425
 
475
- ### Parameters
426
+ const rs = new RainSocket({ environment: 'production' });
476
427
 
477
- ```ts
478
- interface CancelAllOpenOrdersTxParams {
479
- marketId: string; // MongoDB _id of the market
480
- marketContractAddress: `0x${string}`; // Market contract address
481
- walletAddress: `0x${string}`; // User's wallet address
482
- accessToken: string; // JWT from Rain auth (login)
483
- }
428
+ rs.onConnect(() => console.log('Connected'));
429
+ rs.onDisconnect(() => console.log('Disconnected'));
484
430
  ```
485
431
 
486
- ### Validations
432
+ ### Trade Events
433
+
434
+ ```ts
435
+ // Fires when a user buys into a market option
436
+ const unsub = rs.onEnterOption(marketId, (data) => {
437
+ console.log(data.poolId, data.investments, data.totalInvestmentWei);
438
+ });
487
439
 
488
- | Field | Type | Required | Description |
489
- | ----------------------- | ------------- | -------- | ------------------------------------ |
490
- | `marketId` | `string` | ✅ | MongoDB `_id` from market data |
491
- | `marketContractAddress` | `0x${string}` | ✅ | Market contract address |
492
- | `walletAddress` | `0x${string}` | ✅ | Wallet address of the user |
493
- | `accessToken` | `string` | ✅ | JWT returned from `login()` |
440
+ // Fires when a new limit order is placed
441
+ const unsub = rs.onOrderCreated(marketId, (data) => {
442
+ console.log(data.poolId, data.order);
443
+ });
494
444
 
495
- ### Return Type
445
+ // Fires when an open order is cancelled
446
+ const unsub = rs.onOrderCancelled(marketId, (data) => {
447
+ console.log(data.poolId, data.order);
448
+ });
496
449
 
497
- ```ts
498
- RawTransaction[] // empty array if no open orders found
450
+ // Fires when a limit order is partially or fully filled
451
+ const unsub = rs.onOrderFilled(marketId, (data) => {
452
+ console.log(data.poolId, data.raw);
453
+ });
499
454
  ```
500
455
 
501
- ### Example
456
+ ### Dispute & Appeal Events
502
457
 
503
458
  ```ts
504
- const txs = await rain.buildCancelAllOpenOrdersTx({
505
- marketId: "698c8f116e985bbfacc7fc01",
506
- marketContractAddress: "0xMarketContractAddress...",
507
- walletAddress: "0x996ea23940f4a01610181D04bdB6F862719b63f0",
508
- accessToken: "eyJhbGciOi...",
459
+ // Fires when a dispute is opened on a market
460
+ const unsub = rs.onDisputeOpened(marketId, (data) => {
461
+ console.log(data.poolId, data.isDisputed, data.status);
509
462
  });
510
- ```
511
463
 
512
- ---
464
+ // Fires when an appeal is filed
465
+ const unsub = rs.onAppealOpened(marketId, (data) => {
466
+ console.log(data.poolId, data.isAppealed);
467
+ });
513
468
 
514
- ## buildCreateMarketTx
469
+ // Fires when the dispute window is extended
470
+ const unsub = rs.onDisputeTimeExtended(marketId, (data) => {
471
+ console.log(data.poolId, data.newEndTime);
472
+ });
473
+ ```
515
474
 
516
- Builds a **raw EVM transaction** for creating a market in Rain Protocol.
475
+ ### Resolution Events
517
476
 
518
- This function **does not send the transaction** — it only prepares calldata.
477
+ ```ts
478
+ // Fires when a dispute winner is decided
479
+ const unsub = rs.onDisputeWinner(marketId, (data) => {
480
+ console.log(data.poolId, data.winnerOption);
481
+ });
519
482
 
520
- ### Method Signature
483
+ // Fires when an appeal winner is finalized
484
+ const unsub = rs.onAppealWinner(marketId, (data) => {
485
+ console.log(data.poolId, data.winnerFinalized);
486
+ });
521
487
 
522
- ```ts
523
- buildCreateMarketTx(params: CreateMarketTxParams): Promise<RawTransaction[]>
488
+ // Fires when a user's reward claim is confirmed
489
+ // Note: requires both marketId and userId
490
+ const unsub = rs.onClaimReward(marketId, userId, (data) => {
491
+ console.log(data.poolId, data.userId);
492
+ });
524
493
  ```
525
494
 
526
- ### Parameters
495
+ ### Cleanup
527
496
 
528
497
  ```ts
529
- interface CreateMarketTxParams {
530
- marketQuestion: string;
531
- marketOptions: string[];
532
- marketTags: string[];
533
- marketDescription: string;
534
- isPublic: boolean;
535
- isPublicPoolResolverAi: boolean;
536
- creator: `0x${string}`;
537
- startTime: bigint; // Unix timestamp (seconds)
538
- endTime: bigint; // Must be > startTime
539
- no_of_options: bigint; // Number of options (>= 2)
540
- inputAmountWei: bigint; // Initial liquidity (token wei)
541
- barValues: number[]; // Token distribution per option in %
542
- baseToken: `0x${string}`; // ERC20 token address
543
- tokenDecimals?: number; // Optional (default: 6)
544
- }
498
+ // Stop a specific subscription
499
+ unsub();
500
+
501
+ // Disconnect the socket entirely
502
+ rs.disconnect();
545
503
  ```
546
504
 
547
- ### Validations
505
+ ---
548
506
 
549
- | Field | Type | Required | Description |
550
- | ------------------------ | ------------------ | -------- | ------------------------------------------ |
551
- | `marketQuestion` | `string` | ✅ | Market question (cannot be empty) |
552
- | `marketOptions` | `string[]` | ✅ | List of options (2 to 26) |
553
- | `marketTags` | `string[]` | ✅ | Tags related to the market (1 to 3) |
554
- | `marketDescription` | `string` | ✅ | Detailed market description |
555
- | `isPublic` | `boolean` | ✅ | Whether market is public |
556
- | `isPublicPoolResolverAi` | `boolean` | ✅ | AI resolver flag |
557
- | `creator` | `0x${string}` | ✅ | Market creator address |
558
- | `startTime` | `bigint` | ✅ | Market start timestamp |
559
- | `endTime` | `bigint` | ✅ | Must be greater than `startTime` |
560
- | `no_of_options` | `bigint` | ✅ | Number of market options (>= 2) |
561
- | `inputAmountWei` | `bigint` | ✅ | Initial liquidity (minimum 10 tokens) |
562
- | `barValues` | `number[]` | ✅ | Cannot be empty |
563
- | `baseToken` | `0x${string}` | ✅ | ERC20 base token address |
564
- | `tokenDecimals` | `number` | ❌ | Defaults to `6` |
507
+ ## Environments & Configuration
565
508
 
566
- ### Minimum Liquidity Rule
509
+ Set up your application for development, testing, or production.
567
510
 
568
- #### inputAmountWei >= 10 tokens
511
+ When initializing the Rain class, your configuration dictates which endpoints and contract addresses the SDK interacts with.
569
512
 
570
- ### Return Type
513
+ ### Environment Addresses
571
514
 
572
- ```ts
573
- RawTransaction[] // [approve, createMarket] or [createMarket] depending on allowance
574
- ```
515
+ The SDK automatically selects the correct Factory Address and API endpoint based on your chosen environment.
575
516
 
576
- ### Note
517
+ | Environment | API Endpoint | Factory Address |
518
+ | ----------- | ------------ | --------------- |
519
+ | development | dev-api.rain.one | 0x148DA7F2039B2B00633AC2ab566f59C8a4C86313 |
520
+ | stage | stg-api.rain.one | 0x6109c9f28FE3Ad84c51368f7Ef2d487ca020c561 |
521
+ | production | prod-api.rain.one | 0xccCB3C03D9355B01883779EF15C1Be09cf3623F1 |
577
522
 
578
- If the user has not approved the **Rain Factory contract**, the function will return two transactions **(approve + create market)**, but if approval already exists, it will return only one transaction **(create market)**.
523
+ You will also frequently interact with the standard base token, which is Arbitrum USDT (`0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9`) using 6 decimals.
579
524
 
580
- ### Example
525
+ ### Full Configuration Options
581
526
 
582
527
  ```ts
583
- const txs = await rain.buildCreateMarketTx({
584
- marketQuestion: "Will BTC hit 100k?",
585
- marketOptions: ["Yes", "No"],
586
- marketTags: ["crypto", "bitcoin"],
587
- marketDescription: "Prediction market for BTC price",
588
- isPublic: true,
589
- isPublicPoolResolverAi: false,
590
- creator: "0x996ea23940f4a01610181D04bdB6F862719b63f0",
591
- startTime: 1770836400n,
592
- endTime: 1770922800n,
593
- no_of_options: 2n,
594
- inputAmountWei: 100000000n,
595
- barValues: [50, 50],
596
- baseToken: "0xCa4f77A38d8552Dd1D5E44e890173921B67725F4",
528
+ const rain = new Rain({
529
+ environment: 'development', // 'development' | 'stage' | 'production'
530
+ rpcUrl: 'https://...', // Optional, defaults to public Arbitrum RPCs
597
531
  });
598
532
  ```
599
533
 
600
534
  ---
601
535
 
602
- ## buildClaimTx
603
-
604
- Builds a **raw EVM transaction** to claim funds from a resolved Rain market.
536
+ ## API Reference
605
537
 
606
- This function **does not send the transaction** it only prepares calldata.
538
+ A comprehensive list of methods, parameters, and return types for the Rain SDK.
607
539
 
608
- ### Method Signature
540
+ All transaction builders return an unsigned `RawTransaction` (`{ to, data, value? }`) that must be executed by a wallet or smart account.
609
541
 
610
- ```ts
611
- buildClaimTx(params: ClaimTxParams): Promise<RawTransaction>
612
- ```
613
-
614
- ### Parameters
615
-
616
- ```ts
617
- interface ClaimTxParams {
618
- marketId: string;
619
- walletAddress: `0x${string}`;
620
- }
621
- ```
622
-
623
- ### Validations
624
-
625
- | Parameter | Type | Required | Description |
626
- | --------------- | ------------- | -------- | ---------------------------------- |
627
- | `marketId` | `string` | ✅ | Unique identifier of the market |
628
- | `walletAddress` | `0x${string}` | ✅ | Address of the user claiming funds |
542
+ ---
629
543
 
630
- ### Return Type
544
+ ### Authentication
631
545
 
632
- ```ts
633
- interface RawTransaction {
634
- to: `0x${string}`;
635
- data: `0x${string}`;
636
- }
637
- ```
546
+ #### `login(params)`
638
547
 
639
- ### Example
548
+ Authenticate a user with the Rain API.
640
549
 
641
550
  ```ts
642
- const tx = await rain.buildClaimTx({
643
- marketId: "698c8f116e985bbfacc7fc01",
644
- walletAddress: "0x996ea23940f4a01610181D04bdB6F862719b63f0",
551
+ const result = await rain.login({
552
+ walletAddress: '0x...',
553
+ signature: '0x...',
645
554
  });
555
+ // Returns: LoginResult
556
+ // { accessToken, userId, ... }
646
557
  ```
647
558
 
648
559
  ---
649
560
 
650
- ## buildCloseMarketTx
651
-
652
- Builds **raw EVM transactions** to close a Rain market and submit the resolution outcome.
653
-
654
- Handles both V2 and V3 market contracts automatically. For V3 markets, checks token allowances and prepends an approval transaction if needed.
561
+ ### Market Queries
655
562
 
656
- This function **does not send the transactions** — it only prepares calldata.
563
+ #### `getPublicMarkets(params)`
657
564
 
658
- ### Method Signature
565
+ Browse markets based on specific filters.
659
566
 
660
567
  ```ts
661
- buildCloseMarketTx(params: CloseMarketTxParams): Promise<RawTransaction[]>
662
- ```
663
-
664
- ### Parameters
665
-
666
- ```ts
667
- interface CloseMarketTxParams {
668
- marketId: string; // MongoDB _id of the market
669
- walletAddress: `0x${string}`; // Smart account address
670
- proposedOutcome?: number; // Winner option index (required for V2 and V3 manual resolver)
671
- usdtTokenAddress?: `0x${string}`; // Required for V3 USDT markets
672
- rainTokenAddress?: `0x${string}`; // Required for V3 RAIN markets
673
- usdtSymbol?: string; // USDT symbol for the environment (e.g. "USDTm")
674
- tokenDecimals?: number; // Defaults to 6
675
- }
568
+ const markets = await rain.getPublicMarkets({
569
+ limit: 12,
570
+ offset: 0,
571
+ sortBy: 'Liquidity', // 'Liquidity' | 'Volumn' | 'latest'
572
+ status: 'Live', // 'Live' | 'Trading' | 'Closed' | ...
573
+ creator: '0x...', // Optional — filter by creator
574
+ });
575
+ // Returns: Market[]
576
+ // { id, title, totalVolume, status, contractAddress, poolOwnerWalletAddress }
676
577
  ```
677
578
 
678
- ### Validations
679
-
680
- | Field | Type | Required | Description |
681
- | -------------------- | ------------- | -------- | -------------------------------------------------------- |
682
- | `marketId` | `string` | ✅ | MongoDB `_id` of the market |
683
- | `walletAddress` | `0x${string}` | ✅ | Smart account used for allowance checks |
684
- | `proposedOutcome` | `number` | ⚠️ | Required for V2 markets and V3 manual resolver markets |
685
- | `usdtTokenAddress` | `0x${string}` | ⚠️ | Required for V3 USDT markets |
686
- | `rainTokenAddress` | `0x${string}` | ⚠️ | Required for V3 RAIN markets |
687
- | `usdtSymbol` | `string` | ❌ | Used to detect if market uses USDT as base token |
688
- | `tokenDecimals` | `number` | ❌ | Defaults to `6` |
579
+ #### `getMarketById(params)`
689
580
 
690
- ### Return Type
581
+ Fetch a single market by its API ID.
691
582
 
692
583
  ```ts
693
- RawTransaction[] // [approve?, closePool] for V3 or [closePool, chooseWinner] for V2
584
+ const market = await rain.getMarketById({
585
+ marketId: '698c8f116e985bbfacc7fc01',
586
+ accessToken: 'your-access-token', // Optional
587
+ });
588
+ // Returns: Market
694
589
  ```
695
590
 
696
- ### Example
591
+ #### `getUserInvestments(params)`
697
592
 
698
- ```ts
699
- // V2 market
700
- const txs = await rain.buildCloseMarketTx({
701
- marketId: "698c8f116e985bbfacc7fc01",
702
- walletAddress: "0x996ea23940f4a01610181D04bdB6F862719b63f0",
703
- proposedOutcome: 0,
704
- });
593
+ Fetch all active investments for a specific user.
705
594
 
706
- // V3 manual resolver with RAIN token
707
- const txs = await rain.buildCloseMarketTx({
708
- marketId: "698c8f116e985bbfacc7fc01",
709
- walletAddress: "0x996ea23940f4a01610181D04bdB6F862719b63f0",
710
- proposedOutcome: 1,
711
- rainTokenAddress: "0xRainTokenAddress...",
712
- usdtSymbol: "USDTm",
595
+ ```ts
596
+ const investments = await rain.getUserInvestments({
597
+ walletAddress: '0x...',
598
+ accessToken: 'your-access-token',
713
599
  });
600
+ // Returns: UserInvestment[]
714
601
  ```
715
602
 
716
603
  ---
717
604
 
718
- ## buildCreateDisputeTx
605
+ ### Transaction Builders
719
606
 
720
- Builds **raw EVM transactions** to open a dispute on a Rain market.
607
+ #### Approvals
721
608
 
722
- Checks the user's token allowance against the dispute fee and prepends an approval transaction if needed.
609
+ ```ts
610
+ // buildApprovalTx(params) — ERC20 approve
611
+ const tx = rain.buildApprovalTx({
612
+ tokenAddress: '0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9', // USDT
613
+ spender: '0x...', // market contract address
614
+ amount: 100_000_000n, // Optional — defaults to max uint256
615
+ });
616
+ ```
723
617
 
724
- This function **does not send the transactions** — it only prepares calldata.
618
+ #### Creating a Market
725
619
 
726
- ### Method Signature
620
+ Returns `[approveTx, createTx]` if approval is needed, or `[createTx]` if already approved.
727
621
 
728
622
  ```ts
729
- buildCreateDisputeTx(params: CreateDisputeTxParams): Promise<RawTransaction[]>
623
+ const txs = await rain.buildCreateMarketTx({
624
+ marketQuestion: 'Will BTC hit 100k?',
625
+ marketOptions: ['Yes', 'No', 'Maybe'],
626
+ marketTags: ['crypto', 'bitcoin'],
627
+ marketDescription: 'Prediction market for BTC price',
628
+ isPublic: true,
629
+ isPublicPoolResolverAi: false,
630
+ creator: '0x996ea23940f4a01610181D04bdB6F862719b63f0',
631
+ startTime: 1770836400n,
632
+ endTime: 1770922800n,
633
+ no_of_options: 3n,
634
+ inputAmountWei: 100_000_000n,
635
+ barValues: [34, 33, 33],
636
+ baseToken: '0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9',
637
+ tokenDecimals: 6,
638
+ });
730
639
  ```
731
640
 
732
- ### Parameters
641
+ #### Trading Options
733
642
 
734
643
  ```ts
735
- interface CreateDisputeTxParams {
736
- marketId: string; // MongoDB _id of the market
737
- walletAddress: `0x${string}`; // User's wallet address
738
- usdtTokenAddress?: `0x${string}`; // Required for USDT markets
739
- rainTokenAddress?: `0x${string}`; // Required for RAIN markets
740
- usdtSymbol?: string; // Used to detect market token type
741
- }
742
- ```
644
+ // buildBuyOptionRawTx(params) — Market buy
645
+ const tx = rain.buildBuyOptionRawTx({
646
+ marketContractAddress: '0x...',
647
+ selectedOption: 1n, // Option index (bigint)
648
+ buyAmountInWei: 10_000_000n, // 10 USDT
649
+ });
743
650
 
744
- ### Validations
651
+ // buildLimitBuyOptionTx(params) — Limit buy order
652
+ const limitBuyTx = rain.buildLimitBuyOptionTx({
653
+ marketContractAddress: '0x...',
654
+ selectedOption: 1,
655
+ pricePerShare: 500000000000000000n, // 0.50 in 1e18
656
+ buyAmountInWei: 10_000_000n,
657
+ tokenDecimals: 6,
658
+ });
745
659
 
746
- | Field | Type | Required | Description |
747
- | ------------------- | ------------- | -------- | -------------------------------------------- |
748
- | `marketId` | `string` | ✅ | MongoDB `_id` of the market |
749
- | `walletAddress` | `0x${string}` | ✅ | Address of the user opening the dispute |
750
- | `usdtTokenAddress` | `0x${string}` | ⚠️ | Required if market uses USDT as base token |
751
- | `rainTokenAddress` | `0x${string}` | ⚠️ | Required if market uses RAIN as base token |
752
- | `usdtSymbol` | `string` | ❌ | Used to detect if market uses USDT |
660
+ // buildLimitSellOptionTx(params) Limit sell order
661
+ const limitSellTx = rain.buildLimitSellOptionTx({
662
+ marketContractAddress: '0x...',
663
+ selectedOption: 1,
664
+ pricePerShare: 500000000000000000n, // 0.50 in 1e18
665
+ shares: 5_000_000n,
666
+ tokenDecimals: 6,
667
+ });
753
668
 
754
- ### Return Type
669
+ // buildCancelOrdersTx(params) — Cancel specific open orders
670
+ const cancelTx = rain.buildCancelOrdersTx({
671
+ marketContractAddress: '0x...',
672
+ orders: [
673
+ { option: 1, price: 0.5, orderID: 1n },
674
+ { option: 1, price: 0.6, orderID: 2n },
675
+ ],
676
+ });
755
677
 
756
- ```ts
757
- RawTransaction[] // [approve?, openDispute]
678
+ // buildCancelAllOpenOrdersTx(params) — Cancel all open orders for a user
679
+ const cancelAllTx = await rain.buildCancelAllOpenOrdersTx({
680
+ marketContractAddress: '0x...',
681
+ walletAddress: '0x...',
682
+ accessToken: 'your-access-token',
683
+ });
758
684
  ```
759
685
 
760
- ### Example
686
+ #### Market Lifecycle
761
687
 
762
688
  ```ts
763
- const txs = await rain.buildCreateDisputeTx({
764
- marketId: "698c8f116e985bbfacc7fc01",
765
- walletAddress: "0x996ea23940f4a01610181D04bdB6F862719b63f0",
766
- rainTokenAddress: "0xRainTokenAddress...",
767
- usdtSymbol: "USDTm",
689
+ // buildCloseMarketTx(params) Close market and halt trading
690
+ const closeTx = await rain.buildCloseMarketTx({
691
+ marketContractAddress: '0x...',
692
+ walletAddress: '0x...',
693
+ accessToken: 'your-access-token',
768
694
  });
769
- ```
770
695
 
771
- ---
696
+ // buildClaimTx(params) — Claim winnings after market settles
697
+ const claimTx = await rain.buildClaimTx({
698
+ marketId: '698c8f116e985bbfacc7fc01',
699
+ walletAddress: '0x996ea23940f4a01610181D04bdB6F862719b63f0',
700
+ });
701
+ ```
772
702
 
773
- ## buildCreateAppealTx
703
+ #### Disputes & Appeals
774
704
 
775
- Builds **raw EVM transactions** to appeal a dispute resolution on a Rain market.
705
+ ```ts
706
+ // buildCreateDisputeTx(params) — Open a dispute on market outcome
707
+ const disputeTxs = await rain.buildCreateDisputeTx({
708
+ marketContractAddress: '0x...',
709
+ walletAddress: '0x...',
710
+ accessToken: 'your-access-token',
711
+ });
776
712
 
777
- Identical flow to `buildCreateDisputeTx` checks token allowance against the appeal fee and prepends an approval if needed.
713
+ // buildCreateAppealTx(params)Appeal a dispute decision
714
+ const appealTxs = await rain.buildCreateAppealTx({
715
+ marketContractAddress: '0x...',
716
+ walletAddress: '0x...',
717
+ accessToken: 'your-access-token',
718
+ });
778
719
 
779
- This function **does not send the transactions** it only prepares calldata.
720
+ // buildExtendTimeTx(params) Extend the dispute resolution window
721
+ const extendTx = await rain.buildExtendTimeTx({
722
+ marketContractAddress: '0x...',
723
+ walletAddress: '0x...',
724
+ accessToken: 'your-access-token',
725
+ });
726
+ ```
780
727
 
781
- ### Method Signature
728
+ ---
782
729
 
783
- ```ts
784
- buildCreateAppealTx(params: CreateAppealTxParams): Promise<RawTransaction[]>
785
- ```
730
+ ### RainSocket — WebSocket Subscriptions
786
731
 
787
- ### Parameters
732
+ All subscription methods return an unsubscribe function `() => void`.
788
733
 
789
734
  ```ts
790
- interface CreateAppealTxParams {
791
- marketId: string; // MongoDB _id of the market
792
- walletAddress: `0x${string}`; // User's wallet address
793
- usdtTokenAddress?: `0x${string}`; // Required for USDT markets
794
- rainTokenAddress?: `0x${string}`; // Required for RAIN markets
795
- usdtSymbol?: string; // Used to detect market token type
796
- }
797
- ```
735
+ import { RainSocket } from '@rainprotocolsdk/sdk';
798
736
 
799
- ### Validations
737
+ const rs = new RainSocket({ environment: 'production' });
800
738
 
801
- | Field | Type | Required | Description |
802
- | ------------------- | ------------- | -------- | -------------------------------------------- |
803
- | `marketId` | `string` | ✅ | MongoDB `_id` of the market |
804
- | `walletAddress` | `0x${string}` | ✅ | Address of the user filing the appeal |
805
- | `usdtTokenAddress` | `0x${string}` | ⚠️ | Required if market uses USDT as base token |
806
- | `rainTokenAddress` | `0x${string}` | ⚠️ | Required if market uses RAIN as base token |
807
- | `usdtSymbol` | `string` | ❌ | Used to detect if market uses USDT |
739
+ // Connection lifecycle
740
+ rs.onConnect(callback)
741
+ rs.onDisconnect(callback)
808
742
 
809
- ### Return Type
743
+ // Trade events
744
+ rs.onEnterOption(marketId, callback) // enter-option/{marketId}
745
+ rs.onOrderCreated(marketId, callback) // order-created/{marketId}
746
+ rs.onOrderCancelled(marketId, callback) // order-cancelled/{marketId}
747
+ rs.onOrderFilled(marketId, callback) // order-filled/{marketId}
810
748
 
811
- ```ts
812
- RawTransaction[] // [approve?, openDispute]
813
- ```
749
+ // Dispute & appeal events
750
+ rs.onDisputeOpened(marketId, callback) // dispute-opened/{marketId}
751
+ rs.onAppealOpened(marketId, callback) // appeal-opened/{marketId}
752
+ rs.onDisputeTimeExtended(marketId, callback) // dispute-time-extented/{marketId}
814
753
 
815
- ### Example
754
+ // Resolution events
755
+ rs.onDisputeWinner(marketId, callback) // dispute-winner/{marketId}
756
+ rs.onAppealWinner(marketId, callback) // appeal-winner/{marketId}
757
+ rs.onClaimReward(marketId, userId, callback) // claim-reward/{marketId}/{userId}
816
758
 
817
- ```ts
818
- const txs = await rain.buildCreateAppealTx({
819
- marketId: "698c8f116e985bbfacc7fc01",
820
- walletAddress: "0x996ea23940f4a01610181D04bdB6F862719b63f0",
821
- rainTokenAddress: "0xRainTokenAddress...",
822
- usdtSymbol: "USDTm",
823
- });
759
+ // Disconnect
760
+ rs.disconnect()
824
761
  ```
825
762
 
826
763
  ---
827
764
 
828
- ## buildExtendTimeTx
765
+ ### RainAA — Account Abstraction
829
766
 
830
- Builds a **raw EVM transaction** to re-submit an appeal by extending the oracle voting timer on a disputed Rain market.
767
+ `RainAA` manages Alchemy smart accounts with gas sponsorship.
831
768
 
832
- Internally calls `resolver()` on the market contract to resolve the oracle address, then fetches a signed epoch from the Rain backend, and encodes the `extendTime(epoch, signature)` call targeting the oracle contract.
769
+ ```ts
770
+ import { RainAA } from '@rainprotocolsdk/sdk';
771
+ import { arbitrum } from 'viem/chains';
833
772
 
834
- This function **does not send the transaction** — it only prepares calldata.
773
+ const rainAA = new RainAA({
774
+ walletClient: yourWalletClient, // viem WalletClient
775
+ alchemyApiKey: 'your-alchemy-key',
776
+ paymasterPolicyId: 'your-policy-id',
777
+ chain: arbitrum,
778
+ rpcUrl: 'https://...', // Optional
779
+ });
835
780
 
836
- ### Method Signature
781
+ // Connect — derives smart account from EOA
782
+ const smartAccountAddress = await rainAA.connect();
837
783
 
838
- ```ts
839
- buildExtendTimeTx(params: ExtendTimeTxParams): Promise<RawTransaction>
840
- ```
841
-
842
- ### Parameters
784
+ // Accessors
785
+ rainAA.address; // Smart account address (throws if not connected)
786
+ rainAA.client; // Underlying AA client (throws if not connected)
843
787
 
844
- ```ts
845
- interface ExtendTimeTxParams {
846
- marketContractAddress: `0x${string}`; // TradeMarket contract address — resolver() is called on it
847
- walletAddress: `0x${string}`; // Smart account address
848
- accessToken: string; // JWT from Rain auth (login)
849
- }
788
+ // Disconnect
789
+ rainAA.disconnect();
850
790
  ```
851
791
 
852
- ### Validations
853
-
854
- | Field | Type | Required | Description |
855
- | ----------------------- | ------------- | -------- | ---------------------------------------------------- |
856
- | `marketContractAddress` | `0x${string}` | ✅ | Market contract — used to look up the oracle address |
857
- | `walletAddress` | `0x${string}` | ✅ | Smart account address of the caller |
858
- | `accessToken` | `string` | ✅ | JWT returned from `login()` |
792
+ ---
859
793
 
860
- ### Return Type
794
+ ### Key Types
861
795
 
862
796
  ```ts
797
+ // Core transaction type — returned by all builders
863
798
  interface RawTransaction {
864
- to: `0x${string}`; // oracle contract address (resolved on-chain)
799
+ to: `0x${string}`;
865
800
  data: `0x${string}`;
801
+ value?: bigint;
866
802
  }
867
- ```
868
803
 
869
- ### Example
804
+ // Market from listing endpoint
805
+ interface Market {
806
+ id: string;
807
+ title: string;
808
+ totalVolume: string;
809
+ status: MarketStatus;
810
+ contractAddress?: string;
811
+ poolOwnerWalletAddress?: string;
812
+ }
870
813
 
871
- ```ts
872
- const tx = await rain.buildExtendTimeTx({
873
- marketContractAddress: "0xMarketContractAddress...",
874
- walletAddress: "0x996ea23940f4a01610181D04bdB6F862719b63f0",
875
- accessToken: "eyJhbGciOi...",
876
- });
814
+ type MarketStatus = 'Live' | 'New' | 'WaitingForResult' | 'UnderDispute' |
815
+ 'UnderAppeal' | 'ClosingSoon' | 'InReview' | 'InEvaluation' | 'Closed' | 'Trading';
877
816
  ```
878
817
 
879
818
  ---
880
819
 
881
- ## RainAA Class (Account Abstraction)
820
+ ## Full Method Reference
821
+
822
+ A complete directory of all available methods in the Rain SDK.
823
+
824
+ ### Rain Class
825
+
826
+ | Method | Returns | Async |
827
+ | ------ | ------- | ----- |
828
+ | **Authentication** | | |
829
+ | `login(params)` | `LoginResult` | Yes |
830
+ | **Market Queries** | | |
831
+ | `getPublicMarkets(params)` | `Market[]` | Yes |
832
+ | `getMarketById(params)` | `Market` | Yes |
833
+ | `getUserInvestments(params)` | `UserInvestment[]` | Yes |
834
+ | **Transaction Builders** | | |
835
+ | `buildApprovalTx(params)` | `RawTransaction` | No |
836
+ | `buildCreateMarketTx(params)` | `RawTransaction[]` | Yes |
837
+ | `buildBuyOptionRawTx(params)` | `RawTransaction` | No |
838
+ | `buildLimitBuyOptionTx(params)` | `RawTransaction` | No |
839
+ | `buildLimitSellOptionTx(params)` | `RawTransaction` | No |
840
+ | `buildCancelOrdersTx(params)` | `RawTransaction[]` | No |
841
+ | `buildCancelAllOpenOrdersTx(params)` | `RawTransaction[]` | Yes |
842
+ | `buildClaimTx(params)` | `RawTransaction` | Yes |
843
+ | `buildCloseMarketTx(params)` | `RawTransaction[]` | Yes |
844
+ | `buildCreateDisputeTx(params)` | `RawTransaction[]` | Yes |
845
+ | `buildCreateAppealTx(params)` | `RawTransaction[]` | Yes |
846
+ | `buildExtendTimeTx(params)` | `RawTransaction` | Yes |
847
+
848
+ ### RainAA Class
849
+
850
+ | Method | Returns | Async |
851
+ | ------ | ------- | ----- |
852
+ | `connect()` | `` 0x${string} `` | Yes |
853
+ | `disconnect()` | `void` | No |
854
+ | `.address` | `` 0x${string} `` | — |
855
+ | `.client` | Smart wallet client | — |
856
+
857
+ ### RainSocket Class
858
+
859
+ | Method | Returns | Async |
860
+ | ------ | ------- | ----- |
861
+ | `onConnect(callback)` | `void` | No |
862
+ | `onDisconnect(callback)` | `void` | No |
863
+ | `onEnterOption(marketId, callback)` | `Unsubscribe` | No |
864
+ | `onOrderCreated(marketId, callback)` | `Unsubscribe` | No |
865
+ | `onOrderCancelled(marketId, callback)` | `Unsubscribe` | No |
866
+ | `onOrderFilled(marketId, callback)` | `Unsubscribe` | No |
867
+ | `onDisputeOpened(marketId, callback)` | `Unsubscribe` | No |
868
+ | `onAppealOpened(marketId, callback)` | `Unsubscribe` | No |
869
+ | `onDisputeTimeExtended(marketId, callback)` | `Unsubscribe` | No |
870
+ | `onDisputeWinner(marketId, callback)` | `Unsubscribe` | No |
871
+ | `onAppealWinner(marketId, callback)` | `Unsubscribe` | No |
872
+ | `onClaimReward(marketId, userId, callback)` | `Unsubscribe` | No |
873
+ | `disconnect()` | `void` | No |
882
874
 
883
- `RainAA` is responsible for:
875
+ ---
884
876
 
885
- * Smart account creation
886
- * Session management (coming soon)
887
- * Gas-sponsored execution (coming soon)
888
- * Transaction submission (coming soon)
877
+ ## Local Development
889
878
 
890
- > `RainAA` consumes raw transactions generated by `Rain`.
879
+ Instructions for building and testing the Rain SDK locally.
891
880
 
892
- ### Conceptual Flow
881
+ If you are looking to contribute to the SDK or run the test suite, follow these steps to set up your local development environment.
893
882
 
894
- ```ts
895
- Rain (WHAT to do)
896
-
897
- Raw Transaction
898
-
899
- RainAA (HOW to execute)
883
+ ### Installation
884
+
885
+ First, navigate to the rain-sdk directory and install the necessary dependencies:
886
+
887
+ ```bash
888
+ cd rain-sdk
889
+ npm install
900
890
  ```
901
891
 
902
- ---
892
+ ### Available Scripts
903
893
 
904
- ## Versioning Policy
894
+ The following commands are available for development and testing.
905
895
 
906
- Rain SDK follows **Semantic Versioning**:
896
+ #### Build the SDK
907
897
 
908
- * **Patch** (`1.0.x`) Bug fixes
909
- * **Minor** (`1.x.0`) → New features, backward compatible
910
- * **Major** (`x.0.0`) → Breaking API changes
898
+ Compiles the TypeScript source code into the final distribution files.
911
899
 
912
- ---
900
+ ```bash
901
+ npm run build
902
+ ```
913
903
 
914
- ## Recommended Usage Pattern
904
+ #### Development Mode
915
905
 
916
- ```ts
917
- // 1. Init SDK
918
- const rain = new Rain({ environment: "production" });
906
+ Runs the development environment in watch mode, automatically recompiling when files are changed.
919
907
 
920
- // 2. Login
921
- const { accessToken } = await rain.login({ signature, walletAddress, smartWalletAddress });
908
+ ```bash
909
+ npm run dev
910
+ ```
922
911
 
923
- // 3. Read data / build tx
924
- const rawTx = await rain.buildBuyOptionRawTx({ ... });
912
+ #### Run Tests
925
913
 
926
- // 4. Execute via your provider
927
- await yourProvider.sendTransaction(rawTx);
914
+ Executes the standard test suite to ensure everything is functioning correctly.
915
+
916
+ ```bash
917
+ npm test
928
918
  ```
929
919
 
930
- ---
920
+ #### Integration Tests
921
+
922
+ Runs tests that interact with external services or the blockchain to verify end-to-end functionality.
931
923
 
932
- **Rain SDK** is built to scale with both products and protocols.
924
+ ```bash
925
+ npm run test:integration
926
+ ```