@rainprotocolsdk/sdk 2.1.2 → 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 +613 -619
- 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/package.json +3 -2
package/README.md
CHANGED
|
@@ -1,932 +1,926 @@
|
|
|
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
|
-
|
|
83
|
+
**2. Fetch Markets**
|
|
109
84
|
|
|
110
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
});
|
|
208
|
-
```
|
|
209
172
|
|
|
210
|
-
|
|
173
|
+
// Execute sequentially
|
|
174
|
+
for (const tx of txs) {
|
|
175
|
+
await yourProvider.sendTransaction(tx);
|
|
176
|
+
}
|
|
177
|
+
```
|
|
211
178
|
|
|
212
|
-
|
|
179
|
+
### Breaking Down the Parameters
|
|
213
180
|
|
|
214
|
-
|
|
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
|
-
|
|
188
|
+
### Managing the Market Lifecycle
|
|
217
189
|
|
|
218
|
-
|
|
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
|
-
|
|
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
|
-
|
|
223
|
-
interface RawTransaction {
|
|
224
|
-
to: `0x${string}`;
|
|
225
|
-
data: `0x${string}`;
|
|
226
|
-
}
|
|
227
|
-
```
|
|
197
|
+
---
|
|
228
198
|
|
|
229
|
-
|
|
199
|
+
## Trading & Positions
|
|
230
200
|
|
|
231
|
-
|
|
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
|
-
|
|
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
|
-
|
|
207
|
+
### Buying Options
|
|
244
208
|
|
|
245
|
-
|
|
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
|
-
|
|
211
|
+
Here is how you build a standard market order to buy shares.
|
|
248
212
|
|
|
249
213
|
```ts
|
|
250
|
-
|
|
251
|
-
```
|
|
214
|
+
import { Rain } from '@rainprotocolsdk/sdk';
|
|
252
215
|
|
|
253
|
-
|
|
216
|
+
const rain = new Rain({ environment: 'production' });
|
|
254
217
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
marketContractAddress:
|
|
258
|
-
selectedOption:
|
|
259
|
-
buyAmountInWei:
|
|
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
|
-
|
|
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
|
-
|
|
267
|
-
|
|
268
|
-
|
|
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
|
-
###
|
|
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
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
###
|
|
276
|
+
### Claiming Winnings
|
|
291
277
|
|
|
292
|
-
|
|
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
|
-
|
|
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
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
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
|
-
|
|
290
|
+
This single transaction sends the user's original stake plus their winnings directly to their wallet or smart account.
|
|
309
291
|
|
|
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`) |
|
|
292
|
+
---
|
|
317
293
|
|
|
318
|
-
|
|
294
|
+
## Liquidity
|
|
319
295
|
|
|
320
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
308
|
+
### Withdrawing Liquidity
|
|
345
309
|
|
|
346
|
-
|
|
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
|
-
|
|
349
|
-
|
|
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
|
-
|
|
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
|
-
|
|
356
|
-
marketContractAddress:
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
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
|
-
###
|
|
336
|
+
### Filing an Appeal
|
|
365
337
|
|
|
366
|
-
|
|
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
|
-
|
|
378
|
-
|
|
379
|
-
|
|
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
|
-
###
|
|
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.
|
|
387
|
-
marketContractAddress:
|
|
388
|
-
|
|
389
|
-
|
|
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
|
-
##
|
|
368
|
+
## Account Abstraction
|
|
397
369
|
|
|
398
|
-
|
|
370
|
+
Remove gas fees from your trading experience using stateful execution.
|
|
399
371
|
|
|
400
|
-
|
|
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
|
-
|
|
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
|
-
###
|
|
376
|
+
### Setting Up the Execution Engine
|
|
405
377
|
|
|
406
|
-
|
|
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
|
-
|
|
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
|
-
}
|
|
381
|
+
import { RainAA } from '@rainprotocolsdk/sdk';
|
|
382
|
+
import { arbitrum } from 'viem/chains';
|
|
419
383
|
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
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
|
-
|
|
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
|
-
|
|
396
|
+
// Connect, derives smart account from EOA
|
|
397
|
+
const smartAccountAddress = await rainAA.connect();
|
|
398
|
+
console.log('Smart account:', smartAccountAddress);
|
|
437
399
|
```
|
|
438
400
|
|
|
439
|
-
###
|
|
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
|
-
|
|
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
|
-
});
|
|
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
|
-
##
|
|
415
|
+
## WebSockets & Live Data
|
|
464
416
|
|
|
465
|
-
|
|
417
|
+
Keep your application in sync with the protocol without constantly polling for updates.
|
|
466
418
|
|
|
467
|
-
|
|
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
|
-
###
|
|
421
|
+
### Setting Up
|
|
470
422
|
|
|
471
423
|
```ts
|
|
472
|
-
|
|
473
|
-
```
|
|
424
|
+
import { RainSocket } from '@rainprotocolsdk/sdk';
|
|
474
425
|
|
|
475
|
-
|
|
426
|
+
const rs = new RainSocket({ environment: 'production' });
|
|
476
427
|
|
|
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
|
-
}
|
|
428
|
+
rs.onConnect(() => console.log('Connected'));
|
|
429
|
+
rs.onDisconnect(() => console.log('Disconnected'));
|
|
484
430
|
```
|
|
485
431
|
|
|
486
|
-
###
|
|
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
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
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
|
-
|
|
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
|
-
|
|
498
|
-
|
|
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
|
-
###
|
|
456
|
+
### Dispute & Appeal Events
|
|
502
457
|
|
|
503
458
|
```ts
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
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
|
-
|
|
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
|
-
|
|
475
|
+
### Resolution Events
|
|
517
476
|
|
|
518
|
-
|
|
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
|
-
|
|
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
|
-
|
|
523
|
-
|
|
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
|
-
###
|
|
495
|
+
### Cleanup
|
|
527
496
|
|
|
528
497
|
```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
|
-
}
|
|
498
|
+
// Stop a specific subscription
|
|
499
|
+
unsub();
|
|
500
|
+
|
|
501
|
+
// Disconnect the socket entirely
|
|
502
|
+
rs.disconnect();
|
|
545
503
|
```
|
|
546
504
|
|
|
547
|
-
|
|
505
|
+
---
|
|
548
506
|
|
|
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` |
|
|
507
|
+
## Environments & Configuration
|
|
565
508
|
|
|
566
|
-
|
|
509
|
+
Set up your application for development, testing, or production.
|
|
567
510
|
|
|
568
|
-
|
|
511
|
+
When initializing the Rain class, your configuration dictates which endpoints and contract addresses the SDK interacts with.
|
|
569
512
|
|
|
570
|
-
###
|
|
513
|
+
### Environment Addresses
|
|
571
514
|
|
|
572
|
-
|
|
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
|
-
|
|
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
|
-
|
|
523
|
+
You will also frequently interact with the standard base token, which is Arbitrum USDT (`0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9`) using 6 decimals.
|
|
579
524
|
|
|
580
|
-
###
|
|
525
|
+
### Full Configuration Options
|
|
581
526
|
|
|
582
527
|
```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",
|
|
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
|
-
##
|
|
603
|
-
|
|
604
|
-
Builds a **raw EVM transaction** to claim funds from a resolved Rain market.
|
|
536
|
+
## API Reference
|
|
605
537
|
|
|
606
|
-
|
|
538
|
+
A comprehensive list of methods, parameters, and return types for the Rain SDK.
|
|
607
539
|
|
|
608
|
-
|
|
540
|
+
All transaction builders return an unsigned `RawTransaction` (`{ to, data, value? }`) that must be executed by a wallet or smart account.
|
|
609
541
|
|
|
610
|
-
|
|
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
|
-
###
|
|
544
|
+
### Authentication
|
|
631
545
|
|
|
632
|
-
|
|
633
|
-
interface RawTransaction {
|
|
634
|
-
to: `0x${string}`;
|
|
635
|
-
data: `0x${string}`;
|
|
636
|
-
}
|
|
637
|
-
```
|
|
546
|
+
#### `login(params)`
|
|
638
547
|
|
|
639
|
-
|
|
548
|
+
Authenticate a user with the Rain API.
|
|
640
549
|
|
|
641
550
|
```ts
|
|
642
|
-
const
|
|
643
|
-
|
|
644
|
-
|
|
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
|
-
|
|
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
|
-
|
|
563
|
+
#### `getPublicMarkets(params)`
|
|
657
564
|
|
|
658
|
-
|
|
565
|
+
Browse markets based on specific filters.
|
|
659
566
|
|
|
660
567
|
```ts
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
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
|
-
|
|
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
|
-
|
|
581
|
+
Fetch a single market by its API ID.
|
|
691
582
|
|
|
692
583
|
```ts
|
|
693
|
-
|
|
584
|
+
const market = await rain.getMarketById({
|
|
585
|
+
marketId: '698c8f116e985bbfacc7fc01',
|
|
586
|
+
accessToken: 'your-access-token', // Optional
|
|
587
|
+
});
|
|
588
|
+
// Returns: Market
|
|
694
589
|
```
|
|
695
590
|
|
|
696
|
-
|
|
591
|
+
#### `getUserInvestments(params)`
|
|
697
592
|
|
|
698
|
-
|
|
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
|
-
|
|
707
|
-
const
|
|
708
|
-
|
|
709
|
-
|
|
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
|
-
|
|
605
|
+
### Transaction Builders
|
|
719
606
|
|
|
720
|
-
|
|
607
|
+
#### Approvals
|
|
721
608
|
|
|
722
|
-
|
|
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
|
-
|
|
618
|
+
#### Creating a Market
|
|
725
619
|
|
|
726
|
-
|
|
620
|
+
Returns `[approveTx, createTx]` if approval is needed, or `[createTx]` if already approved.
|
|
727
621
|
|
|
728
622
|
```ts
|
|
729
|
-
|
|
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
|
-
|
|
641
|
+
#### Trading Options
|
|
733
642
|
|
|
734
643
|
```ts
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
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
|
-
|
|
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
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
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
|
-
|
|
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
|
-
|
|
757
|
-
|
|
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
|
-
|
|
686
|
+
#### Market Lifecycle
|
|
761
687
|
|
|
762
688
|
```ts
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
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
|
-
|
|
703
|
+
#### Disputes & Appeals
|
|
774
704
|
|
|
775
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
728
|
+
---
|
|
782
729
|
|
|
783
|
-
|
|
784
|
-
buildCreateAppealTx(params: CreateAppealTxParams): Promise<RawTransaction[]>
|
|
785
|
-
```
|
|
730
|
+
### RainSocket — WebSocket Subscriptions
|
|
786
731
|
|
|
787
|
-
|
|
732
|
+
All subscription methods return an unsubscribe function `() => void`.
|
|
788
733
|
|
|
789
734
|
```ts
|
|
790
|
-
|
|
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
|
-
|
|
737
|
+
const rs = new RainSocket({ environment: 'production' });
|
|
800
738
|
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
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
|
-
|
|
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
|
-
|
|
812
|
-
|
|
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
|
-
|
|
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
|
-
|
|
818
|
-
|
|
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
|
-
|
|
765
|
+
### RainAA — Account Abstraction
|
|
829
766
|
|
|
830
|
-
|
|
767
|
+
`RainAA` manages Alchemy smart accounts with gas sponsorship.
|
|
831
768
|
|
|
832
|
-
|
|
769
|
+
```ts
|
|
770
|
+
import { RainAA } from '@rainprotocolsdk/sdk';
|
|
771
|
+
import { arbitrum } from 'viem/chains';
|
|
833
772
|
|
|
834
|
-
|
|
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
|
-
|
|
781
|
+
// Connect — derives smart account from EOA
|
|
782
|
+
const smartAccountAddress = await rainAA.connect();
|
|
837
783
|
|
|
838
|
-
|
|
839
|
-
|
|
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
|
-
|
|
845
|
-
|
|
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
|
-
|
|
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
|
-
###
|
|
794
|
+
### Key Types
|
|
861
795
|
|
|
862
796
|
```ts
|
|
797
|
+
// Core transaction type — returned by all builders
|
|
863
798
|
interface RawTransaction {
|
|
864
|
-
to: `0x${string}`;
|
|
799
|
+
to: `0x${string}`;
|
|
865
800
|
data: `0x${string}`;
|
|
801
|
+
value?: bigint;
|
|
866
802
|
}
|
|
867
|
-
```
|
|
868
803
|
|
|
869
|
-
|
|
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
|
-
|
|
872
|
-
|
|
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
|
-
##
|
|
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
|
-
|
|
875
|
+
---
|
|
884
876
|
|
|
885
|
-
|
|
886
|
-
* Session management (coming soon)
|
|
887
|
-
* Gas-sponsored execution (coming soon)
|
|
888
|
-
* Transaction submission (coming soon)
|
|
877
|
+
## Local Development
|
|
889
878
|
|
|
890
|
-
|
|
879
|
+
Instructions for building and testing the Rain SDK locally.
|
|
891
880
|
|
|
892
|
-
|
|
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
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
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
|
-
|
|
894
|
+
The following commands are available for development and testing.
|
|
905
895
|
|
|
906
|
-
|
|
896
|
+
#### Build the SDK
|
|
907
897
|
|
|
908
|
-
|
|
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
|
-
|
|
904
|
+
#### Development Mode
|
|
915
905
|
|
|
916
|
-
|
|
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
|
-
|
|
921
|
-
|
|
908
|
+
```bash
|
|
909
|
+
npm run dev
|
|
910
|
+
```
|
|
922
911
|
|
|
923
|
-
|
|
924
|
-
const rawTx = await rain.buildBuyOptionRawTx({ ... });
|
|
912
|
+
#### Run Tests
|
|
925
913
|
|
|
926
|
-
|
|
927
|
-
|
|
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
|
-
|
|
924
|
+
```bash
|
|
925
|
+
npm run test:integration
|
|
926
|
+
```
|