@rainprotocolsdk/sdk 2.1.2 → 2.3.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 +633 -613
- package/dist/Rain.d.ts +2 -1
- package/dist/Rain.js +8 -0
- package/dist/config/environments.d.ts +6 -0
- package/dist/config/environments.js +6 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/socket/RainSocket.d.ts +59 -0
- package/dist/socket/RainSocket.js +193 -0
- package/dist/socket/types.d.ts +65 -0
- package/dist/socket/types.js +1 -0
- package/dist/tx/AddLiquidity/buildAddLiquidityRawTx.d.ts +8 -0
- package/dist/tx/AddLiquidity/buildAddLiquidityRawTx.js +51 -0
- package/dist/tx/types.d.ts +6 -0
- package/package.json +13 -6
package/README.md
CHANGED
|
@@ -1,932 +1,952 @@
|
|
|
1
|
-
# Rain SDK
|
|
1
|
+
# Rain Builders — SDK Guide
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Build complete prediction markets, trading applications, and custom integrations powered by Rain's automated protocol.
|
|
4
4
|
|
|
5
|
-
Rain SDK
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
17
|
-
npm install @rainprotocolsdk/sdk
|
|
18
|
-
```
|
|
15
|
+
---
|
|
19
16
|
|
|
20
|
-
|
|
17
|
+
## What You Can Build
|
|
21
18
|
|
|
22
|
-
|
|
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
|
-
|
|
26
|
+
---
|
|
29
27
|
|
|
30
|
-
|
|
31
|
-
import { Rain } from "@rainprotocolsdk/sdk";
|
|
28
|
+
## SDK Architecture: The Two Pillars
|
|
32
29
|
|
|
33
|
-
|
|
34
|
-
```
|
|
30
|
+
The SDK is split into two independent classes. This structure separates the logical transaction building from the actual execution.
|
|
35
31
|
|
|
36
|
-
|
|
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
|
-
|
|
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
|
-
|
|
44
|
+
### The `Rain` Class (Stateless)
|
|
48
45
|
|
|
49
|
-
|
|
46
|
+
`Rain` operates without state. It fetches data and builds unsigned transactions. It does not require a connected wallet.
|
|
50
47
|
|
|
51
|
-
|
|
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
|
-
###
|
|
50
|
+
### The `RainAA` Class (Stateful Execution)
|
|
54
51
|
|
|
55
|
-
|
|
56
|
-
login(params: LoginParams): Promise<LoginResult>
|
|
57
|
-
```
|
|
52
|
+
`RainAA` maintains state. It handles the mechanics of account abstraction.
|
|
58
53
|
|
|
59
|
-
|
|
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
|
-
|
|
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
|
-
|
|
58
|
+
## Quick Start
|
|
71
59
|
|
|
72
|
-
|
|
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
|
-
###
|
|
62
|
+
### Installation
|
|
80
63
|
|
|
81
|
-
|
|
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
|
-
|
|
88
|
-
|
|
89
|
-
|
|
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
|
-
|
|
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
|
-
|
|
75
|
+
**1. Initialize (stateless — no wallet needed)**
|
|
101
76
|
|
|
102
|
-
|
|
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
|
-
|
|
80
|
+
const rain = new Rain({ environment: 'development' });
|
|
106
81
|
```
|
|
107
82
|
|
|
108
|
-
|
|
109
|
-
|
|
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
|
-
```
|
|
83
|
+
**2. Fetch Markets**
|
|
118
84
|
|
|
119
|
-
|
|
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
|
|
133
|
-
|
|
134
|
-
Fetches a single market by its ID from the Rain backend.
|
|
91
|
+
**3. Build a Buy Transaction**
|
|
135
92
|
|
|
136
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
146
|
-
marketId: string; // MongoDB _id of the market
|
|
147
|
-
}
|
|
108
|
+
await yourProvider.sendTransaction(rawTx);
|
|
148
109
|
```
|
|
149
110
|
|
|
150
|
-
|
|
111
|
+
---
|
|
151
112
|
|
|
152
|
-
|
|
153
|
-
| ---------- | -------- | -------- | ---------------------- |
|
|
154
|
-
| `marketId` | `string` | ✅ | Unique market `_id` |
|
|
113
|
+
## Authentication
|
|
155
114
|
|
|
156
|
-
|
|
115
|
+
Before accessing protected endpoints, users must authenticate with the Rain API.
|
|
157
116
|
|
|
158
117
|
```ts
|
|
159
|
-
const
|
|
160
|
-
|
|
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
|
-
##
|
|
129
|
+
## Creating a Market
|
|
167
130
|
|
|
168
|
-
|
|
131
|
+
Launch your own prediction markets on any verifiable event.
|
|
169
132
|
|
|
170
|
-
|
|
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
|
-
|
|
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
|
-
###
|
|
137
|
+
### Public vs. Private Markets
|
|
177
138
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
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.
|
|
140
|
+
|
|
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.
|
|
187
143
|
|
|
188
|
-
###
|
|
144
|
+
### Building the Transaction
|
|
189
145
|
|
|
190
|
-
|
|
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 |
|
|
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.
|
|
197
147
|
|
|
198
|
-
|
|
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
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
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
|
});
|
|
172
|
+
|
|
173
|
+
// Execute sequentially
|
|
174
|
+
for (const tx of txs) {
|
|
175
|
+
await yourProvider.sendTransaction(tx);
|
|
176
|
+
}
|
|
208
177
|
```
|
|
209
178
|
|
|
179
|
+
### Breaking Down the Parameters
|
|
180
|
+
|
|
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.
|
|
187
|
+
|
|
188
|
+
### Managing the Market Lifecycle
|
|
189
|
+
|
|
190
|
+
Creating the market is just the first step. To manage the conclusion of a market, the SDK provides these transaction builders:
|
|
191
|
+
|
|
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).
|
|
196
|
+
|
|
210
197
|
---
|
|
211
198
|
|
|
212
|
-
##
|
|
199
|
+
## Trading & Positions
|
|
213
200
|
|
|
214
|
-
|
|
201
|
+
Build interfaces for buying shares, placing limit orders, and claiming winnings.
|
|
215
202
|
|
|
216
|
-
|
|
203
|
+
Once a market is live, participants can start taking positions. The Rain SDK allows you to construct trading actions directly from the protocol.
|
|
217
204
|
|
|
218
|
-
|
|
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.
|
|
219
206
|
|
|
220
|
-
###
|
|
207
|
+
### Buying Options
|
|
221
208
|
|
|
222
|
-
|
|
223
|
-
interface RawTransaction {
|
|
224
|
-
to: `0x${string}`;
|
|
225
|
-
data: `0x${string}`;
|
|
226
|
-
}
|
|
227
|
-
```
|
|
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.
|
|
228
210
|
|
|
229
|
-
|
|
211
|
+
Here is how you build a standard market order to buy shares.
|
|
230
212
|
|
|
231
213
|
```ts
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
214
|
+
import { Rain } from '@rainprotocolsdk/sdk';
|
|
215
|
+
|
|
216
|
+
const rain = new Rain({ environment: 'production' });
|
|
217
|
+
|
|
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)
|
|
236
223
|
});
|
|
237
224
|
```
|
|
238
225
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
## buildBuyOptionRawTx
|
|
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.
|
|
242
227
|
|
|
243
|
-
|
|
228
|
+
```ts
|
|
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
|
+
});
|
|
237
|
+
```
|
|
244
238
|
|
|
245
|
-
|
|
239
|
+
### Selling Options
|
|
246
240
|
|
|
247
|
-
|
|
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.
|
|
248
242
|
|
|
249
243
|
```ts
|
|
250
|
-
|
|
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,
|
|
251
|
+
});
|
|
251
252
|
```
|
|
252
253
|
|
|
253
|
-
###
|
|
254
|
+
### Canceling Orders
|
|
255
|
+
|
|
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.
|
|
254
257
|
|
|
255
258
|
```ts
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
}
|
|
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
|
+
});
|
|
267
|
+
|
|
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
|
+
});
|
|
261
274
|
```
|
|
262
275
|
|
|
263
|
-
###
|
|
276
|
+
### Claiming Winnings
|
|
264
277
|
|
|
265
|
-
|
|
266
|
-
interface RawTransaction {
|
|
267
|
-
to: `0x${string}`;
|
|
268
|
-
data: `0x${string}`;
|
|
269
|
-
}
|
|
270
|
-
```
|
|
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.
|
|
271
279
|
|
|
272
|
-
|
|
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.
|
|
273
281
|
|
|
274
282
|
```ts
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
283
|
+
// Build the raw claim transaction
|
|
284
|
+
const claimTx = await rain.buildClaimTx({
|
|
285
|
+
marketId: '698c8f116e985bbfacc7fc01',
|
|
286
|
+
walletAddress: '0x996ea23940f4a01610181D04bdB6F862719b63f0',
|
|
279
287
|
});
|
|
280
288
|
```
|
|
281
289
|
|
|
290
|
+
This single transaction sends the user's original stake plus their winnings directly to their wallet or smart account.
|
|
291
|
+
|
|
282
292
|
---
|
|
283
293
|
|
|
284
|
-
##
|
|
294
|
+
## Liquidity
|
|
285
295
|
|
|
286
|
-
|
|
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.
|
|
287
297
|
|
|
288
|
-
|
|
298
|
+
### Adding Liquidity
|
|
289
299
|
|
|
290
|
-
|
|
300
|
+
Use `buildAddLiquidityTx` to let users supply funds to an existing market. The SDK reads the market's base token on-chain and only requests the approval needed — either USDT or RAIN, depending on the market.
|
|
291
301
|
|
|
292
302
|
```ts
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
303
|
+
const txs = await rain.buildAddLiquidityTx({
|
|
304
|
+
marketContractAddress: '0x...',
|
|
305
|
+
walletAddress: '0x...',
|
|
306
|
+
amount: 100, // human-readable amount — decimals auto-detected (6 for USDT, 18 for RAIN)
|
|
307
|
+
});
|
|
297
308
|
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
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)
|
|
309
|
+
// Execute sequentially
|
|
310
|
+
for (const tx of txs) {
|
|
311
|
+
await yourProvider.sendTransaction(tx);
|
|
305
312
|
}
|
|
306
313
|
```
|
|
307
314
|
|
|
308
|
-
|
|
315
|
+
Returns `[approveTx, enterLiquidityTx]` if the allowance is insufficient, or `[enterLiquidityTx]` if already approved.
|
|
309
316
|
|
|
310
|
-
|
|
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`) |
|
|
317
|
+
### How LPs Earn Fees
|
|
317
318
|
|
|
318
|
-
|
|
319
|
+
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.
|
|
319
320
|
|
|
320
|
-
|
|
321
|
-
interface RawTransaction {
|
|
322
|
-
to: `0x${string}`;
|
|
323
|
-
data: `0x${string}`;
|
|
324
|
-
}
|
|
325
|
-
```
|
|
321
|
+
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.
|
|
326
322
|
|
|
327
|
-
|
|
323
|
+
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.
|
|
328
324
|
|
|
329
|
-
|
|
330
|
-
rain.buildLimitBuyOptionTx({
|
|
331
|
-
marketContractAddress: "0xMarketContractAddress...",
|
|
332
|
-
selectedOption: 1,
|
|
333
|
-
pricePerShare: 0.6,
|
|
334
|
-
buyAmountInWei: 1000000n,
|
|
335
|
-
});
|
|
336
|
-
```
|
|
325
|
+
### Withdrawing Liquidity
|
|
337
326
|
|
|
338
|
-
|
|
327
|
+
Liquidity is locked until the market reaches its resolution. There is no method to remove liquidity while the market is active.
|
|
339
328
|
|
|
340
|
-
|
|
329
|
+
Liquidity providers recover their initial supplied share, plus any accumulated fees, by using the standard `buildClaimTx` method after the market officially resolves and settles.
|
|
341
330
|
|
|
342
|
-
|
|
331
|
+
---
|
|
343
332
|
|
|
344
|
-
|
|
333
|
+
## Disputes & Appeals
|
|
345
334
|
|
|
346
|
-
|
|
335
|
+
When a market resolves, participants can challenge the outcome through the dispute and appeal system.
|
|
347
336
|
|
|
348
|
-
|
|
349
|
-
buildLimitSellOptionTx(params: LimitSellOptionTxParams): RawTransaction
|
|
350
|
-
```
|
|
337
|
+
### Opening a Dispute
|
|
351
338
|
|
|
352
|
-
|
|
339
|
+
If a participant believes the market outcome is incorrect, they can open a dispute.
|
|
353
340
|
|
|
354
341
|
```ts
|
|
355
|
-
|
|
356
|
-
marketContractAddress:
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
342
|
+
const disputeTxs = await rain.buildCreateDisputeTx({
|
|
343
|
+
marketContractAddress: '0x...',
|
|
344
|
+
walletAddress: '0x...',
|
|
345
|
+
accessToken: 'your-access-token',
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
for (const tx of disputeTxs) {
|
|
349
|
+
await yourProvider.sendTransaction(tx);
|
|
361
350
|
}
|
|
362
351
|
```
|
|
363
352
|
|
|
364
|
-
###
|
|
365
|
-
|
|
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`) |
|
|
353
|
+
### Filing an Appeal
|
|
373
354
|
|
|
374
|
-
|
|
355
|
+
If the dispute resolution is also contested, participants can escalate it through an appeal.
|
|
375
356
|
|
|
376
357
|
```ts
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
358
|
+
const appealTxs = await rain.buildCreateAppealTx({
|
|
359
|
+
marketContractAddress: '0x...',
|
|
360
|
+
walletAddress: '0x...',
|
|
361
|
+
accessToken: 'your-access-token',
|
|
362
|
+
});
|
|
363
|
+
|
|
364
|
+
for (const tx of appealTxs) {
|
|
365
|
+
await yourProvider.sendTransaction(tx);
|
|
380
366
|
}
|
|
381
367
|
```
|
|
382
368
|
|
|
383
|
-
###
|
|
369
|
+
### Extending the Dispute Window
|
|
370
|
+
|
|
371
|
+
If more time is needed for resolution, the dispute window can be extended.
|
|
384
372
|
|
|
385
373
|
```ts
|
|
386
|
-
rain.
|
|
387
|
-
marketContractAddress:
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
sharesAmountWei: 500000n,
|
|
374
|
+
const extendTx = await rain.buildExtendTimeTx({
|
|
375
|
+
marketContractAddress: '0x...',
|
|
376
|
+
walletAddress: '0x...',
|
|
377
|
+
accessToken: 'your-access-token',
|
|
391
378
|
});
|
|
379
|
+
|
|
380
|
+
await yourProvider.sendTransaction(extendTx);
|
|
392
381
|
```
|
|
393
382
|
|
|
394
383
|
---
|
|
395
384
|
|
|
396
|
-
##
|
|
385
|
+
## Account Abstraction
|
|
397
386
|
|
|
398
|
-
|
|
387
|
+
Remove gas fees from your trading experience using stateful execution.
|
|
399
388
|
|
|
400
|
-
|
|
389
|
+
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
390
|
|
|
402
|
-
|
|
391
|
+
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
392
|
|
|
404
|
-
###
|
|
393
|
+
### Setting Up the Execution Engine
|
|
405
394
|
|
|
406
|
-
|
|
407
|
-
buildCancelOrdersTx(params: CancelOrdersTxParams): RawTransaction[]
|
|
408
|
-
```
|
|
409
|
-
|
|
410
|
-
### Parameters
|
|
395
|
+
To get started, you initialize the `RainAA` class with your standard viem wallet client and your Alchemy credentials.
|
|
411
396
|
|
|
412
397
|
```ts
|
|
413
|
-
|
|
414
|
-
|
|
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
|
-
}
|
|
398
|
+
import { RainAA } from '@rainprotocolsdk/sdk';
|
|
399
|
+
import { arbitrum } from 'viem/chains';
|
|
419
400
|
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
401
|
+
const rainAA = new RainAA({
|
|
402
|
+
walletClient: yourWalletClient, // viem WalletClient
|
|
403
|
+
alchemyApiKey: 'your-alchemy-key',
|
|
404
|
+
paymasterPolicyId: 'your-policy-id',
|
|
405
|
+
chain: arbitrum,
|
|
406
|
+
rpcUrl: 'https://...', // Optional
|
|
407
|
+
});
|
|
424
408
|
```
|
|
425
409
|
|
|
426
|
-
|
|
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
|
|
410
|
+
Once initialized, you connect the client. This derives a smart account from the user's Externally Owned Account (EOA).
|
|
434
411
|
|
|
435
412
|
```ts
|
|
436
|
-
|
|
413
|
+
// Connect, derives smart account from EOA
|
|
414
|
+
const smartAccountAddress = await rainAA.connect();
|
|
415
|
+
console.log('Smart account:', smartAccountAddress);
|
|
437
416
|
```
|
|
438
417
|
|
|
439
|
-
###
|
|
418
|
+
### Session Management
|
|
419
|
+
|
|
420
|
+
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
421
|
|
|
441
422
|
```ts
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
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
|
-
});
|
|
423
|
+
rainAA.address; // Smart account address (throws if not connected)
|
|
424
|
+
rainAA.client; // Underlying AA client (throws if not connected)
|
|
425
|
+
|
|
426
|
+
// Disconnect
|
|
427
|
+
rainAA.disconnect();
|
|
459
428
|
```
|
|
460
429
|
|
|
461
430
|
---
|
|
462
431
|
|
|
463
|
-
##
|
|
432
|
+
## WebSockets & Live Data
|
|
464
433
|
|
|
465
|
-
|
|
434
|
+
Keep your application in sync with the protocol without constantly polling for updates.
|
|
466
435
|
|
|
467
|
-
|
|
436
|
+
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
437
|
|
|
469
|
-
###
|
|
438
|
+
### Setting Up
|
|
470
439
|
|
|
471
440
|
```ts
|
|
472
|
-
|
|
473
|
-
```
|
|
441
|
+
import { RainSocket } from '@rainprotocolsdk/sdk';
|
|
474
442
|
|
|
475
|
-
|
|
443
|
+
const rs = new RainSocket({ environment: 'production' });
|
|
476
444
|
|
|
477
|
-
|
|
478
|
-
|
|
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
|
-
}
|
|
445
|
+
rs.onConnect(() => console.log('Connected'));
|
|
446
|
+
rs.onDisconnect(() => console.log('Disconnected'));
|
|
484
447
|
```
|
|
485
448
|
|
|
486
|
-
###
|
|
449
|
+
### Trade Events
|
|
450
|
+
|
|
451
|
+
```ts
|
|
452
|
+
// Fires when a user buys into a market option
|
|
453
|
+
const unsub = rs.onEnterOption(marketId, (data) => {
|
|
454
|
+
console.log(data.poolId, data.investments, data.totalInvestmentWei);
|
|
455
|
+
});
|
|
487
456
|
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
| `walletAddress` | `0x${string}` | ✅ | Wallet address of the user |
|
|
493
|
-
| `accessToken` | `string` | ✅ | JWT returned from `login()` |
|
|
457
|
+
// Fires when a new limit order is placed
|
|
458
|
+
const unsub = rs.onOrderCreated(marketId, (data) => {
|
|
459
|
+
console.log(data.poolId, data.order);
|
|
460
|
+
});
|
|
494
461
|
|
|
495
|
-
|
|
462
|
+
// Fires when an open order is cancelled
|
|
463
|
+
const unsub = rs.onOrderCancelled(marketId, (data) => {
|
|
464
|
+
console.log(data.poolId, data.order);
|
|
465
|
+
});
|
|
496
466
|
|
|
497
|
-
|
|
498
|
-
|
|
467
|
+
// Fires when a limit order is partially or fully filled
|
|
468
|
+
const unsub = rs.onOrderFilled(marketId, (data) => {
|
|
469
|
+
console.log(data.poolId, data.raw);
|
|
470
|
+
});
|
|
499
471
|
```
|
|
500
472
|
|
|
501
|
-
###
|
|
473
|
+
### Dispute & Appeal Events
|
|
502
474
|
|
|
503
475
|
```ts
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
walletAddress: "0x996ea23940f4a01610181D04bdB6F862719b63f0",
|
|
508
|
-
accessToken: "eyJhbGciOi...",
|
|
476
|
+
// Fires when a dispute is opened on a market
|
|
477
|
+
const unsub = rs.onDisputeOpened(marketId, (data) => {
|
|
478
|
+
console.log(data.poolId, data.isDisputed, data.status);
|
|
509
479
|
});
|
|
510
|
-
```
|
|
511
480
|
|
|
512
|
-
|
|
481
|
+
// Fires when an appeal is filed
|
|
482
|
+
const unsub = rs.onAppealOpened(marketId, (data) => {
|
|
483
|
+
console.log(data.poolId, data.isAppealed);
|
|
484
|
+
});
|
|
513
485
|
|
|
514
|
-
|
|
486
|
+
// Fires when the dispute window is extended
|
|
487
|
+
const unsub = rs.onDisputeTimeExtended(marketId, (data) => {
|
|
488
|
+
console.log(data.poolId, data.newEndTime);
|
|
489
|
+
});
|
|
490
|
+
```
|
|
515
491
|
|
|
516
|
-
|
|
492
|
+
### Resolution Events
|
|
517
493
|
|
|
518
|
-
|
|
494
|
+
```ts
|
|
495
|
+
// Fires when a dispute winner is decided
|
|
496
|
+
const unsub = rs.onDisputeWinner(marketId, (data) => {
|
|
497
|
+
console.log(data.poolId, data.winnerOption);
|
|
498
|
+
});
|
|
519
499
|
|
|
520
|
-
|
|
500
|
+
// Fires when an appeal winner is finalized
|
|
501
|
+
const unsub = rs.onAppealWinner(marketId, (data) => {
|
|
502
|
+
console.log(data.poolId, data.winnerFinalized);
|
|
503
|
+
});
|
|
521
504
|
|
|
522
|
-
|
|
523
|
-
|
|
505
|
+
// Fires when a user's reward claim is confirmed
|
|
506
|
+
// Note: requires both marketId and userId
|
|
507
|
+
const unsub = rs.onClaimReward(marketId, userId, (data) => {
|
|
508
|
+
console.log(data.poolId, data.userId);
|
|
509
|
+
});
|
|
524
510
|
```
|
|
525
511
|
|
|
526
|
-
###
|
|
512
|
+
### Cleanup
|
|
527
513
|
|
|
528
514
|
```ts
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
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
|
-
}
|
|
515
|
+
// Stop a specific subscription
|
|
516
|
+
unsub();
|
|
517
|
+
|
|
518
|
+
// Disconnect the socket entirely
|
|
519
|
+
rs.disconnect();
|
|
545
520
|
```
|
|
546
521
|
|
|
547
|
-
|
|
522
|
+
---
|
|
548
523
|
|
|
549
|
-
|
|
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` |
|
|
524
|
+
## Environments & Configuration
|
|
565
525
|
|
|
566
|
-
|
|
526
|
+
Set up your application for development, testing, or production.
|
|
567
527
|
|
|
568
|
-
|
|
528
|
+
When initializing the Rain class, your configuration dictates which endpoints and contract addresses the SDK interacts with.
|
|
569
529
|
|
|
570
|
-
###
|
|
530
|
+
### Environment Addresses
|
|
571
531
|
|
|
572
|
-
|
|
573
|
-
RawTransaction[] // [approve, createMarket] or [createMarket] depending on allowance
|
|
574
|
-
```
|
|
532
|
+
The SDK automatically selects the correct Factory Address and API endpoint based on your chosen environment.
|
|
575
533
|
|
|
576
|
-
|
|
534
|
+
| Environment | API Endpoint | Factory Address |
|
|
535
|
+
| ----------- | ------------ | --------------- |
|
|
536
|
+
| development | dev-api.rain.one | 0x148DA7F2039B2B00633AC2ab566f59C8a4C86313 |
|
|
537
|
+
| stage | stg-api.rain.one | 0x6109c9f28FE3Ad84c51368f7Ef2d487ca020c561 |
|
|
538
|
+
| production | prod-api.rain.one | 0xccCB3C03D9355B01883779EF15C1Be09cf3623F1 |
|
|
577
539
|
|
|
578
|
-
|
|
540
|
+
You will also frequently interact with the standard base token, which is Arbitrum USDT (`0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9`) using 6 decimals.
|
|
579
541
|
|
|
580
|
-
###
|
|
542
|
+
### Full Configuration Options
|
|
581
543
|
|
|
582
544
|
```ts
|
|
583
|
-
const
|
|
584
|
-
|
|
585
|
-
|
|
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",
|
|
545
|
+
const rain = new Rain({
|
|
546
|
+
environment: 'development', // 'development' | 'stage' | 'production'
|
|
547
|
+
rpcUrl: 'https://...', // Optional, defaults to public Arbitrum RPCs
|
|
597
548
|
});
|
|
598
549
|
```
|
|
599
550
|
|
|
600
551
|
---
|
|
601
552
|
|
|
602
|
-
##
|
|
553
|
+
## API Reference
|
|
603
554
|
|
|
604
|
-
|
|
555
|
+
A comprehensive list of methods, parameters, and return types for the Rain SDK.
|
|
605
556
|
|
|
606
|
-
|
|
557
|
+
All transaction builders return an unsigned `RawTransaction` (`{ to, data, value? }`) that must be executed by a wallet or smart account.
|
|
607
558
|
|
|
608
|
-
|
|
559
|
+
---
|
|
609
560
|
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
561
|
+
### Authentication
|
|
562
|
+
|
|
563
|
+
#### `login(params)`
|
|
613
564
|
|
|
614
|
-
|
|
565
|
+
Authenticate a user with the Rain API.
|
|
615
566
|
|
|
616
567
|
```ts
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
}
|
|
568
|
+
const result = await rain.login({
|
|
569
|
+
walletAddress: '0x...',
|
|
570
|
+
signature: '0x...',
|
|
571
|
+
});
|
|
572
|
+
// Returns: LoginResult
|
|
573
|
+
// { accessToken, userId, ... }
|
|
621
574
|
```
|
|
622
575
|
|
|
623
|
-
|
|
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 |
|
|
576
|
+
---
|
|
629
577
|
|
|
630
|
-
###
|
|
578
|
+
### Market Queries
|
|
631
579
|
|
|
632
|
-
|
|
633
|
-
interface RawTransaction {
|
|
634
|
-
to: `0x${string}`;
|
|
635
|
-
data: `0x${string}`;
|
|
636
|
-
}
|
|
637
|
-
```
|
|
580
|
+
#### `getPublicMarkets(params)`
|
|
638
581
|
|
|
639
|
-
|
|
582
|
+
Browse markets based on specific filters.
|
|
640
583
|
|
|
641
584
|
```ts
|
|
642
|
-
const
|
|
643
|
-
|
|
644
|
-
|
|
585
|
+
const markets = await rain.getPublicMarkets({
|
|
586
|
+
limit: 12,
|
|
587
|
+
offset: 0,
|
|
588
|
+
sortBy: 'Liquidity', // 'Liquidity' | 'Volumn' | 'latest'
|
|
589
|
+
status: 'Live', // 'Live' | 'Trading' | 'Closed' | ...
|
|
590
|
+
creator: '0x...', // Optional — filter by creator
|
|
645
591
|
});
|
|
592
|
+
// Returns: Market[]
|
|
593
|
+
// { id, title, totalVolume, status, contractAddress, poolOwnerWalletAddress }
|
|
646
594
|
```
|
|
647
595
|
|
|
648
|
-
|
|
649
|
-
|
|
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.
|
|
596
|
+
#### `getMarketById(params)`
|
|
655
597
|
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
### Method Signature
|
|
598
|
+
Fetch a single market by its API ID.
|
|
659
599
|
|
|
660
600
|
```ts
|
|
661
|
-
|
|
601
|
+
const market = await rain.getMarketById({
|
|
602
|
+
marketId: '698c8f116e985bbfacc7fc01',
|
|
603
|
+
accessToken: 'your-access-token', // Optional
|
|
604
|
+
});
|
|
605
|
+
// Returns: Market
|
|
662
606
|
```
|
|
663
607
|
|
|
664
|
-
|
|
608
|
+
#### `getUserInvestments(params)`
|
|
609
|
+
|
|
610
|
+
Fetch all active investments for a specific user.
|
|
665
611
|
|
|
666
612
|
```ts
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
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
|
-
}
|
|
613
|
+
const investments = await rain.getUserInvestments({
|
|
614
|
+
walletAddress: '0x...',
|
|
615
|
+
accessToken: 'your-access-token',
|
|
616
|
+
});
|
|
617
|
+
// Returns: UserInvestment[]
|
|
676
618
|
```
|
|
677
619
|
|
|
678
|
-
|
|
620
|
+
---
|
|
679
621
|
|
|
680
|
-
|
|
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` |
|
|
622
|
+
### Transaction Builders
|
|
689
623
|
|
|
690
|
-
|
|
624
|
+
#### Approvals
|
|
691
625
|
|
|
692
626
|
```ts
|
|
693
|
-
|
|
627
|
+
// buildApprovalTx(params) — ERC20 approve
|
|
628
|
+
const tx = rain.buildApprovalTx({
|
|
629
|
+
tokenAddress: '0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9', // USDT
|
|
630
|
+
spender: '0x...', // market contract address
|
|
631
|
+
amount: 100_000_000n, // Optional — defaults to max uint256
|
|
632
|
+
});
|
|
694
633
|
```
|
|
695
634
|
|
|
696
|
-
|
|
635
|
+
#### Creating a Market
|
|
697
636
|
|
|
698
|
-
|
|
699
|
-
// V2 market
|
|
700
|
-
const txs = await rain.buildCloseMarketTx({
|
|
701
|
-
marketId: "698c8f116e985bbfacc7fc01",
|
|
702
|
-
walletAddress: "0x996ea23940f4a01610181D04bdB6F862719b63f0",
|
|
703
|
-
proposedOutcome: 0,
|
|
704
|
-
});
|
|
637
|
+
Returns `[approveTx, createTx]` if approval is needed, or `[createTx]` if already approved.
|
|
705
638
|
|
|
706
|
-
|
|
707
|
-
const txs = await rain.
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
639
|
+
```ts
|
|
640
|
+
const txs = await rain.buildCreateMarketTx({
|
|
641
|
+
marketQuestion: 'Will BTC hit 100k?',
|
|
642
|
+
marketOptions: ['Yes', 'No', 'Maybe'],
|
|
643
|
+
marketTags: ['crypto', 'bitcoin'],
|
|
644
|
+
marketDescription: 'Prediction market for BTC price',
|
|
645
|
+
isPublic: true,
|
|
646
|
+
isPublicPoolResolverAi: false,
|
|
647
|
+
creator: '0x996ea23940f4a01610181D04bdB6F862719b63f0',
|
|
648
|
+
startTime: 1770836400n,
|
|
649
|
+
endTime: 1770922800n,
|
|
650
|
+
no_of_options: 3n,
|
|
651
|
+
inputAmountWei: 100_000_000n,
|
|
652
|
+
barValues: [34, 33, 33],
|
|
653
|
+
baseToken: '0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9',
|
|
654
|
+
tokenDecimals: 6,
|
|
713
655
|
});
|
|
714
656
|
```
|
|
715
657
|
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
## buildCreateDisputeTx
|
|
658
|
+
#### Trading Options
|
|
719
659
|
|
|
720
|
-
|
|
660
|
+
```ts
|
|
661
|
+
// buildBuyOptionRawTx(params) — Market buy
|
|
662
|
+
const tx = rain.buildBuyOptionRawTx({
|
|
663
|
+
marketContractAddress: '0x...',
|
|
664
|
+
selectedOption: 1n, // Option index (bigint)
|
|
665
|
+
buyAmountInWei: 10_000_000n, // 10 USDT
|
|
666
|
+
});
|
|
721
667
|
|
|
722
|
-
|
|
668
|
+
// buildLimitBuyOptionTx(params) — Limit buy order
|
|
669
|
+
const limitBuyTx = rain.buildLimitBuyOptionTx({
|
|
670
|
+
marketContractAddress: '0x...',
|
|
671
|
+
selectedOption: 1,
|
|
672
|
+
pricePerShare: 500000000000000000n, // 0.50 in 1e18
|
|
673
|
+
buyAmountInWei: 10_000_000n,
|
|
674
|
+
tokenDecimals: 6,
|
|
675
|
+
});
|
|
723
676
|
|
|
724
|
-
|
|
677
|
+
// buildLimitSellOptionTx(params) — Limit sell order
|
|
678
|
+
const limitSellTx = rain.buildLimitSellOptionTx({
|
|
679
|
+
marketContractAddress: '0x...',
|
|
680
|
+
selectedOption: 1,
|
|
681
|
+
pricePerShare: 500000000000000000n, // 0.50 in 1e18
|
|
682
|
+
shares: 5_000_000n,
|
|
683
|
+
tokenDecimals: 6,
|
|
684
|
+
});
|
|
725
685
|
|
|
726
|
-
|
|
686
|
+
// buildCancelOrdersTx(params) — Cancel specific open orders
|
|
687
|
+
const cancelTx = rain.buildCancelOrdersTx({
|
|
688
|
+
marketContractAddress: '0x...',
|
|
689
|
+
orders: [
|
|
690
|
+
{ option: 1, price: 0.5, orderID: 1n },
|
|
691
|
+
{ option: 1, price: 0.6, orderID: 2n },
|
|
692
|
+
],
|
|
693
|
+
});
|
|
727
694
|
|
|
728
|
-
|
|
729
|
-
|
|
695
|
+
// buildCancelAllOpenOrdersTx(params) — Cancel all open orders for a user
|
|
696
|
+
const cancelAllTx = await rain.buildCancelAllOpenOrdersTx({
|
|
697
|
+
marketContractAddress: '0x...',
|
|
698
|
+
walletAddress: '0x...',
|
|
699
|
+
accessToken: 'your-access-token',
|
|
700
|
+
});
|
|
730
701
|
```
|
|
731
702
|
|
|
732
|
-
|
|
703
|
+
#### Market Lifecycle
|
|
733
704
|
|
|
734
705
|
```ts
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
}
|
|
742
|
-
```
|
|
706
|
+
// buildCloseMarketTx(params) — Close market and halt trading
|
|
707
|
+
const closeTx = await rain.buildCloseMarketTx({
|
|
708
|
+
marketContractAddress: '0x...',
|
|
709
|
+
walletAddress: '0x...',
|
|
710
|
+
accessToken: 'your-access-token',
|
|
711
|
+
});
|
|
743
712
|
|
|
744
|
-
|
|
713
|
+
// buildAddLiquidityTx(params) — Add liquidity to a market
|
|
714
|
+
const addLiqTxs = await rain.buildAddLiquidityTx({
|
|
715
|
+
marketContractAddress: '0x...',
|
|
716
|
+
walletAddress: '0x...',
|
|
717
|
+
amount: 100, // human-readable — reads baseToken() on-chain, uses 6 decimals for USDT or 18 for RAIN
|
|
718
|
+
});
|
|
719
|
+
// Returns [approveTx, enterLiquidityTx] or [enterLiquidityTx] if already approved.
|
|
745
720
|
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
| `usdtSymbol` | `string` | ❌ | Used to detect if market uses USDT |
|
|
721
|
+
// buildClaimTx(params) — Claim winnings after market settles
|
|
722
|
+
const claimTx = await rain.buildClaimTx({
|
|
723
|
+
marketId: '698c8f116e985bbfacc7fc01',
|
|
724
|
+
walletAddress: '0x996ea23940f4a01610181D04bdB6F862719b63f0',
|
|
725
|
+
});
|
|
726
|
+
```
|
|
753
727
|
|
|
754
|
-
|
|
728
|
+
#### Disputes & Appeals
|
|
755
729
|
|
|
756
730
|
```ts
|
|
757
|
-
|
|
758
|
-
|
|
731
|
+
// buildCreateDisputeTx(params) — Open a dispute on market outcome
|
|
732
|
+
const disputeTxs = await rain.buildCreateDisputeTx({
|
|
733
|
+
marketContractAddress: '0x...',
|
|
734
|
+
walletAddress: '0x...',
|
|
735
|
+
accessToken: 'your-access-token',
|
|
736
|
+
});
|
|
759
737
|
|
|
760
|
-
|
|
738
|
+
// buildCreateAppealTx(params) — Appeal a dispute decision
|
|
739
|
+
const appealTxs = await rain.buildCreateAppealTx({
|
|
740
|
+
marketContractAddress: '0x...',
|
|
741
|
+
walletAddress: '0x...',
|
|
742
|
+
accessToken: 'your-access-token',
|
|
743
|
+
});
|
|
761
744
|
|
|
762
|
-
|
|
763
|
-
const
|
|
764
|
-
|
|
765
|
-
walletAddress:
|
|
766
|
-
|
|
767
|
-
usdtSymbol: "USDTm",
|
|
745
|
+
// buildExtendTimeTx(params) — Extend the dispute resolution window
|
|
746
|
+
const extendTx = await rain.buildExtendTimeTx({
|
|
747
|
+
marketContractAddress: '0x...',
|
|
748
|
+
walletAddress: '0x...',
|
|
749
|
+
accessToken: 'your-access-token',
|
|
768
750
|
});
|
|
769
751
|
```
|
|
770
752
|
|
|
771
753
|
---
|
|
772
754
|
|
|
773
|
-
|
|
755
|
+
### RainSocket — WebSocket Subscriptions
|
|
774
756
|
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
Identical flow to `buildCreateDisputeTx` — checks token allowance against the appeal fee and prepends an approval if needed.
|
|
778
|
-
|
|
779
|
-
This function **does not send the transactions** — it only prepares calldata.
|
|
780
|
-
|
|
781
|
-
### Method Signature
|
|
757
|
+
All subscription methods return an unsubscribe function `() => void`.
|
|
782
758
|
|
|
783
759
|
```ts
|
|
784
|
-
|
|
785
|
-
```
|
|
760
|
+
import { RainSocket } from '@rainprotocolsdk/sdk';
|
|
786
761
|
|
|
787
|
-
|
|
762
|
+
const rs = new RainSocket({ environment: 'production' });
|
|
788
763
|
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
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
|
-
```
|
|
764
|
+
// Connection lifecycle
|
|
765
|
+
rs.onConnect(callback)
|
|
766
|
+
rs.onDisconnect(callback)
|
|
798
767
|
|
|
799
|
-
|
|
768
|
+
// Trade events
|
|
769
|
+
rs.onEnterOption(marketId, callback) // enter-option/{marketId}
|
|
770
|
+
rs.onOrderCreated(marketId, callback) // order-created/{marketId}
|
|
771
|
+
rs.onOrderCancelled(marketId, callback) // order-cancelled/{marketId}
|
|
772
|
+
rs.onOrderFilled(marketId, callback) // order-filled/{marketId}
|
|
800
773
|
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
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 |
|
|
774
|
+
// Dispute & appeal events
|
|
775
|
+
rs.onDisputeOpened(marketId, callback) // dispute-opened/{marketId}
|
|
776
|
+
rs.onAppealOpened(marketId, callback) // appeal-opened/{marketId}
|
|
777
|
+
rs.onDisputeTimeExtended(marketId, callback) // dispute-time-extented/{marketId}
|
|
808
778
|
|
|
809
|
-
|
|
779
|
+
// Resolution events
|
|
780
|
+
rs.onDisputeWinner(marketId, callback) // dispute-winner/{marketId}
|
|
781
|
+
rs.onAppealWinner(marketId, callback) // appeal-winner/{marketId}
|
|
782
|
+
rs.onClaimReward(marketId, userId, callback) // claim-reward/{marketId}/{userId}
|
|
810
783
|
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
```
|
|
814
|
-
|
|
815
|
-
### Example
|
|
816
|
-
|
|
817
|
-
```ts
|
|
818
|
-
const txs = await rain.buildCreateAppealTx({
|
|
819
|
-
marketId: "698c8f116e985bbfacc7fc01",
|
|
820
|
-
walletAddress: "0x996ea23940f4a01610181D04bdB6F862719b63f0",
|
|
821
|
-
rainTokenAddress: "0xRainTokenAddress...",
|
|
822
|
-
usdtSymbol: "USDTm",
|
|
823
|
-
});
|
|
784
|
+
// Disconnect
|
|
785
|
+
rs.disconnect()
|
|
824
786
|
```
|
|
825
787
|
|
|
826
788
|
---
|
|
827
789
|
|
|
828
|
-
|
|
790
|
+
### RainAA — Account Abstraction
|
|
829
791
|
|
|
830
|
-
|
|
792
|
+
`RainAA` manages Alchemy smart accounts with gas sponsorship.
|
|
831
793
|
|
|
832
|
-
|
|
794
|
+
```ts
|
|
795
|
+
import { RainAA } from '@rainprotocolsdk/sdk';
|
|
796
|
+
import { arbitrum } from 'viem/chains';
|
|
833
797
|
|
|
834
|
-
|
|
798
|
+
const rainAA = new RainAA({
|
|
799
|
+
walletClient: yourWalletClient, // viem WalletClient
|
|
800
|
+
alchemyApiKey: 'your-alchemy-key',
|
|
801
|
+
paymasterPolicyId: 'your-policy-id',
|
|
802
|
+
chain: arbitrum,
|
|
803
|
+
rpcUrl: 'https://...', // Optional
|
|
804
|
+
});
|
|
835
805
|
|
|
836
|
-
|
|
806
|
+
// Connect — derives smart account from EOA
|
|
807
|
+
const smartAccountAddress = await rainAA.connect();
|
|
837
808
|
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
809
|
+
// Accessors
|
|
810
|
+
rainAA.address; // Smart account address (throws if not connected)
|
|
811
|
+
rainAA.client; // Underlying AA client (throws if not connected)
|
|
841
812
|
|
|
842
|
-
|
|
843
|
-
|
|
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
|
-
}
|
|
813
|
+
// Disconnect
|
|
814
|
+
rainAA.disconnect();
|
|
850
815
|
```
|
|
851
816
|
|
|
852
|
-
|
|
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()` |
|
|
817
|
+
---
|
|
859
818
|
|
|
860
|
-
###
|
|
819
|
+
### Key Types
|
|
861
820
|
|
|
862
821
|
```ts
|
|
822
|
+
// Core transaction type — returned by all builders
|
|
863
823
|
interface RawTransaction {
|
|
864
|
-
to: `0x${string}`;
|
|
824
|
+
to: `0x${string}`;
|
|
865
825
|
data: `0x${string}`;
|
|
826
|
+
value?: bigint;
|
|
866
827
|
}
|
|
867
|
-
```
|
|
868
828
|
|
|
869
|
-
|
|
829
|
+
// Market from listing endpoint
|
|
830
|
+
interface Market {
|
|
831
|
+
id: string;
|
|
832
|
+
title: string;
|
|
833
|
+
totalVolume: string;
|
|
834
|
+
status: MarketStatus;
|
|
835
|
+
contractAddress?: string;
|
|
836
|
+
poolOwnerWalletAddress?: string;
|
|
837
|
+
}
|
|
870
838
|
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
marketContractAddress: "0xMarketContractAddress...",
|
|
874
|
-
walletAddress: "0x996ea23940f4a01610181D04bdB6F862719b63f0",
|
|
875
|
-
accessToken: "eyJhbGciOi...",
|
|
876
|
-
});
|
|
839
|
+
type MarketStatus = 'Live' | 'New' | 'WaitingForResult' | 'UnderDispute' |
|
|
840
|
+
'UnderAppeal' | 'ClosingSoon' | 'InReview' | 'InEvaluation' | 'Closed' | 'Trading';
|
|
877
841
|
```
|
|
878
842
|
|
|
879
843
|
---
|
|
880
844
|
|
|
881
|
-
##
|
|
845
|
+
## Full Method Reference
|
|
846
|
+
|
|
847
|
+
A complete directory of all available methods in the Rain SDK.
|
|
848
|
+
|
|
849
|
+
### Rain Class
|
|
850
|
+
|
|
851
|
+
| Method | Returns | Async |
|
|
852
|
+
| ------ | ------- | ----- |
|
|
853
|
+
| **Authentication** | | |
|
|
854
|
+
| `login(params)` | `LoginResult` | Yes |
|
|
855
|
+
| **Market Queries** | | |
|
|
856
|
+
| `getPublicMarkets(params)` | `Market[]` | Yes |
|
|
857
|
+
| `getMarketById(params)` | `Market` | Yes |
|
|
858
|
+
| `getUserInvestments(params)` | `UserInvestment[]` | Yes |
|
|
859
|
+
| **Transaction Builders** | | |
|
|
860
|
+
| `buildApprovalTx(params)` | `RawTransaction` | No |
|
|
861
|
+
| `buildCreateMarketTx(params)` | `RawTransaction[]` | Yes |
|
|
862
|
+
| `buildBuyOptionRawTx(params)` | `RawTransaction` | No |
|
|
863
|
+
| `buildLimitBuyOptionTx(params)` | `RawTransaction` | No |
|
|
864
|
+
| `buildLimitSellOptionTx(params)` | `RawTransaction` | No |
|
|
865
|
+
| `buildCancelOrdersTx(params)` | `RawTransaction[]` | No |
|
|
866
|
+
| `buildCancelAllOpenOrdersTx(params)` | `RawTransaction[]` | Yes |
|
|
867
|
+
| `buildAddLiquidityTx(params)` | `RawTransaction[]` | Yes |
|
|
868
|
+
| `buildClaimTx(params)` | `RawTransaction` | Yes |
|
|
869
|
+
| `buildCloseMarketTx(params)` | `RawTransaction[]` | Yes |
|
|
870
|
+
| `buildCreateDisputeTx(params)` | `RawTransaction[]` | Yes |
|
|
871
|
+
| `buildCreateAppealTx(params)` | `RawTransaction[]` | Yes |
|
|
872
|
+
| `buildExtendTimeTx(params)` | `RawTransaction` | Yes |
|
|
873
|
+
|
|
874
|
+
### RainAA Class
|
|
875
|
+
|
|
876
|
+
| Method | Returns | Async |
|
|
877
|
+
| ------ | ------- | ----- |
|
|
878
|
+
| `connect()` | `` 0x${string} `` | Yes |
|
|
879
|
+
| `disconnect()` | `void` | No |
|
|
880
|
+
| `.address` | `` 0x${string} `` | — |
|
|
881
|
+
| `.client` | Smart wallet client | — |
|
|
882
|
+
|
|
883
|
+
### RainSocket Class
|
|
884
|
+
|
|
885
|
+
| Method | Returns | Async |
|
|
886
|
+
| ------ | ------- | ----- |
|
|
887
|
+
| `onConnect(callback)` | `void` | No |
|
|
888
|
+
| `onDisconnect(callback)` | `void` | No |
|
|
889
|
+
| `onEnterOption(marketId, callback)` | `Unsubscribe` | No |
|
|
890
|
+
| `onOrderCreated(marketId, callback)` | `Unsubscribe` | No |
|
|
891
|
+
| `onOrderCancelled(marketId, callback)` | `Unsubscribe` | No |
|
|
892
|
+
| `onOrderFilled(marketId, callback)` | `Unsubscribe` | No |
|
|
893
|
+
| `onDisputeOpened(marketId, callback)` | `Unsubscribe` | No |
|
|
894
|
+
| `onAppealOpened(marketId, callback)` | `Unsubscribe` | No |
|
|
895
|
+
| `onDisputeTimeExtended(marketId, callback)` | `Unsubscribe` | No |
|
|
896
|
+
| `onDisputeWinner(marketId, callback)` | `Unsubscribe` | No |
|
|
897
|
+
| `onAppealWinner(marketId, callback)` | `Unsubscribe` | No |
|
|
898
|
+
| `onClaimReward(marketId, userId, callback)` | `Unsubscribe` | No |
|
|
899
|
+
| `disconnect()` | `void` | No |
|
|
882
900
|
|
|
883
|
-
|
|
901
|
+
---
|
|
884
902
|
|
|
885
|
-
|
|
886
|
-
* Session management (coming soon)
|
|
887
|
-
* Gas-sponsored execution (coming soon)
|
|
888
|
-
* Transaction submission (coming soon)
|
|
903
|
+
## Local Development
|
|
889
904
|
|
|
890
|
-
|
|
905
|
+
Instructions for building and testing the Rain SDK locally.
|
|
891
906
|
|
|
892
|
-
|
|
907
|
+
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
908
|
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
909
|
+
### Installation
|
|
910
|
+
|
|
911
|
+
First, navigate to the rain-sdk directory and install the necessary dependencies:
|
|
912
|
+
|
|
913
|
+
```bash
|
|
914
|
+
cd rain-sdk
|
|
915
|
+
npm install
|
|
900
916
|
```
|
|
901
917
|
|
|
902
|
-
|
|
918
|
+
### Available Scripts
|
|
903
919
|
|
|
904
|
-
|
|
920
|
+
The following commands are available for development and testing.
|
|
905
921
|
|
|
906
|
-
|
|
922
|
+
#### Build the SDK
|
|
907
923
|
|
|
908
|
-
|
|
909
|
-
* **Minor** (`1.x.0`) → New features, backward compatible
|
|
910
|
-
* **Major** (`x.0.0`) → Breaking API changes
|
|
924
|
+
Compiles the TypeScript source code into the final distribution files.
|
|
911
925
|
|
|
912
|
-
|
|
926
|
+
```bash
|
|
927
|
+
npm run build
|
|
928
|
+
```
|
|
913
929
|
|
|
914
|
-
|
|
930
|
+
#### Development Mode
|
|
915
931
|
|
|
916
|
-
|
|
917
|
-
// 1. Init SDK
|
|
918
|
-
const rain = new Rain({ environment: "production" });
|
|
932
|
+
Runs the development environment in watch mode, automatically recompiling when files are changed.
|
|
919
933
|
|
|
920
|
-
|
|
921
|
-
|
|
934
|
+
```bash
|
|
935
|
+
npm run dev
|
|
936
|
+
```
|
|
922
937
|
|
|
923
|
-
|
|
924
|
-
const rawTx = await rain.buildBuyOptionRawTx({ ... });
|
|
938
|
+
#### Run Tests
|
|
925
939
|
|
|
926
|
-
|
|
927
|
-
|
|
940
|
+
Executes the standard test suite to ensure everything is functioning correctly.
|
|
941
|
+
|
|
942
|
+
```bash
|
|
943
|
+
npm test
|
|
928
944
|
```
|
|
929
945
|
|
|
930
|
-
|
|
946
|
+
#### Integration Tests
|
|
947
|
+
|
|
948
|
+
Runs tests that interact with external services or the blockchain to verify end-to-end functionality.
|
|
931
949
|
|
|
932
|
-
|
|
950
|
+
```bash
|
|
951
|
+
npm run test:integration
|
|
952
|
+
```
|