rain-sdk-v2 2.1.3 → 2.1.5
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 +148 -0
- package/dist/Rain.d.ts +38 -1
- package/dist/Rain.js +41 -0
- package/dist/api/index.d.ts +1 -0
- package/dist/api/index.js +1 -0
- package/dist/api/leaderboard.d.ts +5 -0
- package/dist/api/leaderboard.js +32 -0
- package/dist/api/types.d.ts +138 -0
- package/dist/index.d.ts +1 -0
- package/dist/markets/getDisputeState.d.ts +24 -0
- package/dist/markets/getDisputeState.js +69 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -661,6 +661,96 @@ const payouts = await rain.getDynamicPayout({
|
|
|
661
661
|
// payouts = [yesPayoutWei, noPayoutWei]
|
|
662
662
|
```
|
|
663
663
|
|
|
664
|
+
### `getResolverBondAmount(params): Promise<bigint>`
|
|
665
|
+
|
|
666
|
+
Get the bond amount (in base-token wei) a resolver must post to propose a resolution for an option.
|
|
667
|
+
|
|
668
|
+
```typescript
|
|
669
|
+
const bond = await rain.getResolverBondAmount({
|
|
670
|
+
marketContractAddress: '0x...',
|
|
671
|
+
option: 1n, // 1-based option index
|
|
672
|
+
});
|
|
673
|
+
```
|
|
674
|
+
|
|
675
|
+
### `getDisputeAppealFee(params): Promise<bigint>`
|
|
676
|
+
|
|
677
|
+
Get the fee (in base-token wei) required to open a dispute or appeal on an option.
|
|
678
|
+
|
|
679
|
+
```typescript
|
|
680
|
+
const fee = await rain.getDisputeAppealFee({
|
|
681
|
+
marketContractAddress: '0x...',
|
|
682
|
+
option: 1n,
|
|
683
|
+
});
|
|
684
|
+
```
|
|
685
|
+
|
|
686
|
+
### `optionResolverBond(params): Promise<bigint>`
|
|
687
|
+
|
|
688
|
+
Get the resolver bond currently posted on an option (0n if no resolution has been proposed).
|
|
689
|
+
|
|
690
|
+
```typescript
|
|
691
|
+
const bond = await rain.optionResolverBond({
|
|
692
|
+
marketContractAddress: '0x...',
|
|
693
|
+
option: 1n,
|
|
694
|
+
});
|
|
695
|
+
```
|
|
696
|
+
|
|
697
|
+
### `optionResolutionProposer(params): Promise<`0x${string}`>`
|
|
698
|
+
|
|
699
|
+
Get the address that proposed the resolution for an option (zero address if none).
|
|
700
|
+
|
|
701
|
+
```typescript
|
|
702
|
+
const proposer = await rain.optionResolutionProposer({
|
|
703
|
+
marketContractAddress: '0x...',
|
|
704
|
+
option: 1n,
|
|
705
|
+
});
|
|
706
|
+
```
|
|
707
|
+
|
|
708
|
+
### `isOptionDisputed(params): Promise<boolean>`
|
|
709
|
+
|
|
710
|
+
Check whether an option's resolution has been disputed.
|
|
711
|
+
|
|
712
|
+
```typescript
|
|
713
|
+
const disputed = await rain.isOptionDisputed({
|
|
714
|
+
marketContractAddress: '0x...',
|
|
715
|
+
option: 1n,
|
|
716
|
+
});
|
|
717
|
+
```
|
|
718
|
+
|
|
719
|
+
### `isOptionAppealed(params): Promise<boolean>`
|
|
720
|
+
|
|
721
|
+
Check whether an option's dispute resolution has been appealed.
|
|
722
|
+
|
|
723
|
+
```typescript
|
|
724
|
+
const appealed = await rain.isOptionAppealed({
|
|
725
|
+
marketContractAddress: '0x...',
|
|
726
|
+
option: 1n,
|
|
727
|
+
});
|
|
728
|
+
```
|
|
729
|
+
|
|
730
|
+
### `optionDispute(params): Promise<OptionDisputeInfo>`
|
|
731
|
+
|
|
732
|
+
Get the dispute details for an option: fee paid, the winner claimed by the disputer, the disputer address, and the dispute resolver.
|
|
733
|
+
|
|
734
|
+
```typescript
|
|
735
|
+
const dispute = await rain.optionDispute({
|
|
736
|
+
marketContractAddress: '0x...',
|
|
737
|
+
option: 1n,
|
|
738
|
+
});
|
|
739
|
+
// { disputeFee: bigint, disputedWinner: bigint, disputer: '0x...', disputeResolver: '0x...' }
|
|
740
|
+
```
|
|
741
|
+
|
|
742
|
+
### `optionAppeal(params): Promise<OptionAppealInfo>`
|
|
743
|
+
|
|
744
|
+
Get the appeal details for an option: fee paid, the winner claimed by the appellant, the disputer address, and the appeal resolver.
|
|
745
|
+
|
|
746
|
+
```typescript
|
|
747
|
+
const appeal = await rain.optionAppeal({
|
|
748
|
+
marketContractAddress: '0x...',
|
|
749
|
+
option: 1n,
|
|
750
|
+
});
|
|
751
|
+
// { disputeFee: bigint, disputedWinner: bigint, disputer: '0x...', appealResolver: '0x...' }
|
|
752
|
+
```
|
|
753
|
+
|
|
664
754
|
### `getUserActiveBuyOrders(params): Promise<bigint>`
|
|
665
755
|
|
|
666
756
|
Get count of user's active buy orders.
|
|
@@ -1237,6 +1327,64 @@ const priceData = await rain.getTokenPrice('0x...'); // token contract address
|
|
|
1237
1327
|
// priceData.data = { price: 0.05 } — USD price per token
|
|
1238
1328
|
```
|
|
1239
1329
|
|
|
1330
|
+
### Leaderboard
|
|
1331
|
+
|
|
1332
|
+
Public endpoints — no access token required. Boards are served from a materialized document rebuilt by a cron (~20 min), so changes appear after the next tick rather than on the next request.
|
|
1333
|
+
|
|
1334
|
+
```typescript
|
|
1335
|
+
// Get a ranked leaderboard — one board per (board, window, category)
|
|
1336
|
+
const board = await rain.getLeaderboard({
|
|
1337
|
+
board: 'profit', // 'profit' (net realized PnL) or 'correct_calls' (sum of 1 − entryPrice over winning positions)
|
|
1338
|
+
window: 'all_time', // 'all_time' (default) or 'monthly' (current UTC calendar month)
|
|
1339
|
+
category: 'Crypto', // optional, case-insensitive; omit for the global board
|
|
1340
|
+
limit: 10, // up to the stored cap of 100 (default 10)
|
|
1341
|
+
});
|
|
1342
|
+
// board.data = { board, window, category, categoryLabel, period, limit, totalRanked, priceBasis, entries, lastUpdatedAt }
|
|
1343
|
+
// Each entry carries all four table columns — profit, correctCalls, winRate, trades —
|
|
1344
|
+
// whichever board is sorting, so switching the sorted column needs no second request.
|
|
1345
|
+
|
|
1346
|
+
// Search traders on a board — the leaderboard's trader search box
|
|
1347
|
+
const found = await rain.searchLeaderboard({
|
|
1348
|
+
q: '0x742d', // wallet address, address fragment (with/without 0x, prefix/middle/tail), or user id
|
|
1349
|
+
board: 'profit', // required — searches the stored board for this (board, window, category)
|
|
1350
|
+
window: 'all_time', // optional, default 'all_time'
|
|
1351
|
+
category: 'Crypto', // optional; omit for the global board
|
|
1352
|
+
limit: 10, // up to 50 (default 10)
|
|
1353
|
+
});
|
|
1354
|
+
// found.data = { board, window, category, period, query, matched, searchedTop, totalRanked, lastUpdatedAt, results }
|
|
1355
|
+
// `results` are the same entry objects getLeaderboard returns, in rank order.
|
|
1356
|
+
// Scoped to the stored board — a trader outside the top N is simply not found.
|
|
1357
|
+
// Empty `results` means "not on this board"; `searchedTop` + `totalRanked` let you
|
|
1358
|
+
// say "not in the top 100" precisely. Queries under 2 characters return empty, not a 400.
|
|
1359
|
+
|
|
1360
|
+
// Get a trader's most recent trades — the rows inside an expanded leaderboard row
|
|
1361
|
+
const recent = await rain.getTraderRecentTrades({
|
|
1362
|
+
userId: '...', // from a leaderboard entry's `userId`
|
|
1363
|
+
limit: 5, // rendered rows (a multi-side trade flattens into more lines), up to 25 (default 5)
|
|
1364
|
+
});
|
|
1365
|
+
// recent.data = { userId, limit, trades }
|
|
1366
|
+
// Each trade: { action ('Buy'|'Sell'), origin, transactionHash, tradedAt, poolId, question,
|
|
1367
|
+
// poolImage, subPoolId, subQuestion, side (1=YES, 2=NO), optionName, shares,
|
|
1368
|
+
// amountUSD, pricePerShare, priceCents, status ('open'|'pending'|'settled'),
|
|
1369
|
+
// pnlScope, pnlUSD }
|
|
1370
|
+
// Directional trades only (origin ∈ {enter, orderFill}), newest first — and unlike the
|
|
1371
|
+
// track-record endpoint, OPEN positions are included (status 'open').
|
|
1372
|
+
// `pnlUSD` is POSITION-level, not per-fill: several trades in the same market report the
|
|
1373
|
+
// same number. Null until settled; `amountUSD`/`pnlUSD` are dollars × 1e6.
|
|
1374
|
+
|
|
1375
|
+
// Get categories that currently have a ranked board (feeds the category filter)
|
|
1376
|
+
const categories = await rain.getLeaderboardCategories();
|
|
1377
|
+
// categories.data = [{ category: 'CRYPTO', label: 'Crypto' }, ...]
|
|
1378
|
+
// Pass `category` back as the `category` param of getLeaderboard.
|
|
1379
|
+
```
|
|
1380
|
+
|
|
1381
|
+
**Notes:**
|
|
1382
|
+
- **Units:** every `*USD` number (including `profit` and `score` on the profit board) is **dollars × 1e6** — divide by 1,000,000 to display. E.g. `profit: 887505347` is **$887.51**.
|
|
1383
|
+
- **Monthly window** buckets on when PnL *settled*, not when the position was opened; `window: 'monthly'` always means the current UTC month (`period` reports it as `YYYY-MM`).
|
|
1384
|
+
- **Only positive scores are ranked.** An unknown `category` returns an empty board, not a 400.
|
|
1385
|
+
- **Top-N only** — there is no rank-of-user lookup. Empty `entries` with `lastUpdatedAt: null` means the cron hasn't built the board yet; empty with a timestamp means nobody qualifies.
|
|
1386
|
+
- The client can highlight the viewer's own row by matching `userId` in `entries`.
|
|
1387
|
+
|
|
1240
1388
|
---
|
|
1241
1389
|
|
|
1242
1390
|
## WebSocket Events (Socket.IO)
|
package/dist/Rain.d.ts
CHANGED
|
@@ -4,8 +4,9 @@ import { ExtendTimeTxParams } from './tx/buildExtendTimeRawTx.js';
|
|
|
4
4
|
import { RainCoreConfig, RainEnvironment } from './types.js';
|
|
5
5
|
import { LoginParams, LoginResult } from './auth/types.js';
|
|
6
6
|
import { SellProceedsResult } from './markets/getSellProceeds.js';
|
|
7
|
+
import { OptionDisputeInfo, OptionAppealInfo } from './markets/getDisputeState.js';
|
|
7
8
|
import { EntrySharesResult } from './markets/getEntryShares.js';
|
|
8
|
-
import type { UserProfileUpdateParams, UserHistoryParams, CreateCommentParams, CommentsListingParams, UpdateCommentParams, CommentCountParams, PublicPoolsParams, PrivatePoolsParams, PoolListingByCreatorParams, VerifyAccessCodeParams, PoolTotalParticipantsParams, SearchPoolParams, RelatedPoolsParams, UpdateStreamingParams, UpdatePoolResolutionTimeParams, FindPoolFallbackParams, SignOraclesExtendTimeParams, TrendingTagsParams, UserTotalInvestmentParams, OptionsTotalVolumeParams, PoolActivityParams, TopHoldersParams, UserInvestedPoolsParams, InvestmentVolumeGraphParams, UserPnlGraphParams, TopWinnersLosersParams, PnlByPoolIdParams, UserPositionsParams, OpenPositionsParams, UserSharePositionsParams, SearchInvestedPoolsParams, PriceDataParams, AddReviewParams, GetUserOrdersParams, OrderBookParams, GetUserOrderByPoolIdParams, OrdersListingByPoolParams, AddUserPointsParams, UserOnboardingParams, PointsGraphParams, GetNotificationsParams, MarkNotificationAsReadParams, CreateDisputeMessageParams, GetPoolDisputeConvoParams, FollowToggleParams, FollowCheckParams, FollowListParams, FollowStatsParams, RainBurnPerPoolParams, ToggleBookmarkParams, GetBookmarksParams, CheckBookmarkParams } from './api/types.js';
|
|
9
|
+
import type { UserProfileUpdateParams, UserHistoryParams, CreateCommentParams, CommentsListingParams, UpdateCommentParams, CommentCountParams, PublicPoolsParams, PrivatePoolsParams, PoolListingByCreatorParams, VerifyAccessCodeParams, PoolTotalParticipantsParams, SearchPoolParams, RelatedPoolsParams, UpdateStreamingParams, UpdatePoolResolutionTimeParams, FindPoolFallbackParams, SignOraclesExtendTimeParams, TrendingTagsParams, UserTotalInvestmentParams, OptionsTotalVolumeParams, PoolActivityParams, TopHoldersParams, UserInvestedPoolsParams, InvestmentVolumeGraphParams, UserPnlGraphParams, TopWinnersLosersParams, PnlByPoolIdParams, UserPositionsParams, OpenPositionsParams, UserSharePositionsParams, SearchInvestedPoolsParams, PriceDataParams, AddReviewParams, GetUserOrdersParams, OrderBookParams, GetUserOrderByPoolIdParams, OrdersListingByPoolParams, AddUserPointsParams, UserOnboardingParams, PointsGraphParams, GetNotificationsParams, MarkNotificationAsReadParams, CreateDisputeMessageParams, GetPoolDisputeConvoParams, FollowToggleParams, FollowCheckParams, FollowListParams, FollowStatsParams, RainBurnPerPoolParams, ToggleBookmarkParams, GetBookmarksParams, CheckBookmarkParams, LeaderboardParams, LeaderboardSearchParams, TraderRecentTradesParams } from './api/types.js';
|
|
9
10
|
export declare class Rain {
|
|
10
11
|
readonly environment: RainEnvironment;
|
|
11
12
|
private readonly marketFactory;
|
|
@@ -58,6 +59,38 @@ export declare class Rain {
|
|
|
58
59
|
getDisputeWindow(params: {
|
|
59
60
|
marketContractAddress: `0x${string}`;
|
|
60
61
|
}): Promise<bigint>;
|
|
62
|
+
getResolverBondAmount(params: {
|
|
63
|
+
marketContractAddress: `0x${string}`;
|
|
64
|
+
option: bigint;
|
|
65
|
+
}): Promise<bigint>;
|
|
66
|
+
getDisputeAppealFee(params: {
|
|
67
|
+
marketContractAddress: `0x${string}`;
|
|
68
|
+
option: bigint;
|
|
69
|
+
}): Promise<bigint>;
|
|
70
|
+
optionResolverBond(params: {
|
|
71
|
+
marketContractAddress: `0x${string}`;
|
|
72
|
+
option: bigint;
|
|
73
|
+
}): Promise<bigint>;
|
|
74
|
+
optionResolutionProposer(params: {
|
|
75
|
+
marketContractAddress: `0x${string}`;
|
|
76
|
+
option: bigint;
|
|
77
|
+
}): Promise<`0x${string}`>;
|
|
78
|
+
isOptionDisputed(params: {
|
|
79
|
+
marketContractAddress: `0x${string}`;
|
|
80
|
+
option: bigint;
|
|
81
|
+
}): Promise<boolean>;
|
|
82
|
+
isOptionAppealed(params: {
|
|
83
|
+
marketContractAddress: `0x${string}`;
|
|
84
|
+
option: bigint;
|
|
85
|
+
}): Promise<boolean>;
|
|
86
|
+
optionDispute(params: {
|
|
87
|
+
marketContractAddress: `0x${string}`;
|
|
88
|
+
option: bigint;
|
|
89
|
+
}): Promise<OptionDisputeInfo>;
|
|
90
|
+
optionAppeal(params: {
|
|
91
|
+
marketContractAddress: `0x${string}`;
|
|
92
|
+
option: bigint;
|
|
93
|
+
}): Promise<OptionAppealInfo>;
|
|
61
94
|
getEntryShares(params: {
|
|
62
95
|
marketContractAddress: `0x${string}`;
|
|
63
96
|
option: bigint;
|
|
@@ -292,4 +325,8 @@ export declare class Rain {
|
|
|
292
325
|
toggleBookmark(params: ToggleBookmarkParams, accessToken: string): Promise<import("./api/types.js").ApiResponse<unknown>>;
|
|
293
326
|
getBookmarks(params: GetBookmarksParams, accessToken: string): Promise<import("./api/types.js").ApiResponse<unknown>>;
|
|
294
327
|
checkBookmark(params: CheckBookmarkParams, accessToken: string): Promise<import("./api/types.js").ApiResponse<unknown>>;
|
|
328
|
+
getLeaderboard(params: LeaderboardParams): Promise<import("./api/types.js").ApiResponse<import("./api/types.js").LeaderboardData>>;
|
|
329
|
+
searchLeaderboard(params: LeaderboardSearchParams): Promise<import("./api/types.js").ApiResponse<import("./api/types.js").LeaderboardSearchData>>;
|
|
330
|
+
getTraderRecentTrades(params: TraderRecentTradesParams): Promise<import("./api/types.js").ApiResponse<import("./api/types.js").TraderRecentTradesData>>;
|
|
331
|
+
getLeaderboardCategories(): Promise<import("./api/types.js").ApiResponse<import("./api/types.js").LeaderboardCategory[]>>;
|
|
295
332
|
}
|
package/dist/Rain.js
CHANGED
|
@@ -24,6 +24,9 @@ import { getSellProceeds } from './markets/getSellProceeds.js';
|
|
|
24
24
|
import { getUserSharesInEscrow } from './markets/getUserSharesInEscrow.js';
|
|
25
25
|
import { getOptionClaimed } from './markets/getOptionClaimed.js';
|
|
26
26
|
import { getDisputeWindow } from './markets/getDisputeWindow.js';
|
|
27
|
+
import { getResolverBondAmount } from './markets/getResolverBondAmount.js';
|
|
28
|
+
import { getDisputeAppealFee } from './markets/getDisputeFee.js';
|
|
29
|
+
import { optionResolverBond, optionResolutionProposer, isOptionDisputed, isOptionAppealed, optionDispute, optionAppeal } from './markets/getDisputeState.js';
|
|
27
30
|
import { getEntryShares } from './markets/getEntryShares.js';
|
|
28
31
|
import { createPublicClient, http, parseAbi } from 'viem';
|
|
29
32
|
import { arbitrum } from 'viem/chains';
|
|
@@ -41,6 +44,7 @@ import * as disputeApi from './api/dispute.js';
|
|
|
41
44
|
import * as followApi from './api/follow.js';
|
|
42
45
|
import * as whitelistedTokensApi from './api/whitelistedTokens.js';
|
|
43
46
|
import * as bookmarksApi from './api/bookmarks.js';
|
|
47
|
+
import * as leaderboardApi from './api/leaderboard.js';
|
|
44
48
|
const erc20AllowanceAbi = parseAbi(['function allowance(address owner, address spender) view returns (uint256)']);
|
|
45
49
|
const factoryViewAbi = parseAbi([
|
|
46
50
|
'function oracleFixedFee() view returns (uint256)',
|
|
@@ -136,6 +140,30 @@ export class Rain {
|
|
|
136
140
|
async getDisputeWindow(params) {
|
|
137
141
|
return getDisputeWindow({ ...params, rpcUrl: this.rpcUrl });
|
|
138
142
|
}
|
|
143
|
+
async getResolverBondAmount(params) {
|
|
144
|
+
return getResolverBondAmount({ ...params, rpcUrl: this.rpcUrl });
|
|
145
|
+
}
|
|
146
|
+
async getDisputeAppealFee(params) {
|
|
147
|
+
return getDisputeAppealFee({ ...params, rpcUrl: this.rpcUrl });
|
|
148
|
+
}
|
|
149
|
+
async optionResolverBond(params) {
|
|
150
|
+
return optionResolverBond({ ...params, rpcUrl: this.rpcUrl });
|
|
151
|
+
}
|
|
152
|
+
async optionResolutionProposer(params) {
|
|
153
|
+
return optionResolutionProposer({ ...params, rpcUrl: this.rpcUrl });
|
|
154
|
+
}
|
|
155
|
+
async isOptionDisputed(params) {
|
|
156
|
+
return isOptionDisputed({ ...params, rpcUrl: this.rpcUrl });
|
|
157
|
+
}
|
|
158
|
+
async isOptionAppealed(params) {
|
|
159
|
+
return isOptionAppealed({ ...params, rpcUrl: this.rpcUrl });
|
|
160
|
+
}
|
|
161
|
+
async optionDispute(params) {
|
|
162
|
+
return optionDispute({ ...params, rpcUrl: this.rpcUrl });
|
|
163
|
+
}
|
|
164
|
+
async optionAppeal(params) {
|
|
165
|
+
return optionAppeal({ ...params, rpcUrl: this.rpcUrl });
|
|
166
|
+
}
|
|
139
167
|
async getEntryShares(params) {
|
|
140
168
|
return getEntryShares({ ...params, rpcUrl: this.rpcUrl });
|
|
141
169
|
}
|
|
@@ -503,4 +531,17 @@ export class Rain {
|
|
|
503
531
|
async checkBookmark(params, accessToken) {
|
|
504
532
|
return bookmarksApi.checkBookmark(params, this.cfg(accessToken));
|
|
505
533
|
}
|
|
534
|
+
// ─── Leaderboard ────────────────────────────────────────────────────────────
|
|
535
|
+
async getLeaderboard(params) {
|
|
536
|
+
return leaderboardApi.getLeaderboard(params, this.cfg());
|
|
537
|
+
}
|
|
538
|
+
async searchLeaderboard(params) {
|
|
539
|
+
return leaderboardApi.searchLeaderboard(params, this.cfg());
|
|
540
|
+
}
|
|
541
|
+
async getTraderRecentTrades(params) {
|
|
542
|
+
return leaderboardApi.getTraderRecentTrades(params, this.cfg());
|
|
543
|
+
}
|
|
544
|
+
async getLeaderboardCategories() {
|
|
545
|
+
return leaderboardApi.getLeaderboardCategories(this.cfg());
|
|
546
|
+
}
|
|
506
547
|
}
|
package/dist/api/index.d.ts
CHANGED
package/dist/api/index.js
CHANGED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { ApiConfig, ApiResponse, LeaderboardParams, LeaderboardData, LeaderboardCategory, LeaderboardSearchParams, LeaderboardSearchData, TraderRecentTradesParams, TraderRecentTradesData } from './types.js';
|
|
2
|
+
export declare function getLeaderboard(params: LeaderboardParams, config: ApiConfig): Promise<ApiResponse<LeaderboardData>>;
|
|
3
|
+
export declare function searchLeaderboard(params: LeaderboardSearchParams, config: ApiConfig): Promise<ApiResponse<LeaderboardSearchData>>;
|
|
4
|
+
export declare function getTraderRecentTrades(params: TraderRecentTradesParams, config: ApiConfig): Promise<ApiResponse<TraderRecentTradesData>>;
|
|
5
|
+
export declare function getLeaderboardCategories(config: ApiConfig): Promise<ApiResponse<LeaderboardCategory[]>>;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { buildHeaders, buildQuery, handleResponse } from './helpers.js';
|
|
2
|
+
export async function getLeaderboard(params, config) {
|
|
3
|
+
const qs = buildQuery({ board: params.board, window: params.window, category: params.category, limit: params.limit });
|
|
4
|
+
const res = await fetch(`${config.apiUrl}/leaderboard${qs}`, {
|
|
5
|
+
method: 'GET',
|
|
6
|
+
headers: buildHeaders(config),
|
|
7
|
+
});
|
|
8
|
+
return handleResponse(res);
|
|
9
|
+
}
|
|
10
|
+
export async function searchLeaderboard(params, config) {
|
|
11
|
+
const qs = buildQuery({ q: params.q, board: params.board, window: params.window, category: params.category, limit: params.limit });
|
|
12
|
+
const res = await fetch(`${config.apiUrl}/leaderboard/search${qs}`, {
|
|
13
|
+
method: 'GET',
|
|
14
|
+
headers: buildHeaders(config),
|
|
15
|
+
});
|
|
16
|
+
return handleResponse(res);
|
|
17
|
+
}
|
|
18
|
+
export async function getTraderRecentTrades(params, config) {
|
|
19
|
+
const qs = buildQuery({ limit: params.limit });
|
|
20
|
+
const res = await fetch(`${config.apiUrl}/leaderboard/traders/${encodeURIComponent(params.userId)}/recent-trades${qs}`, {
|
|
21
|
+
method: 'GET',
|
|
22
|
+
headers: buildHeaders(config),
|
|
23
|
+
});
|
|
24
|
+
return handleResponse(res);
|
|
25
|
+
}
|
|
26
|
+
export async function getLeaderboardCategories(config) {
|
|
27
|
+
const res = await fetch(`${config.apiUrl}/leaderboard/categories`, {
|
|
28
|
+
method: 'GET',
|
|
29
|
+
headers: buildHeaders(config),
|
|
30
|
+
});
|
|
31
|
+
return handleResponse(res);
|
|
32
|
+
}
|
package/dist/api/types.d.ts
CHANGED
|
@@ -322,3 +322,141 @@ export interface GetBookmarksParams {
|
|
|
322
322
|
export interface CheckBookmarkParams {
|
|
323
323
|
poolId: string;
|
|
324
324
|
}
|
|
325
|
+
export type LeaderboardBoard = 'profit' | 'correct_calls';
|
|
326
|
+
export type LeaderboardWindow = 'all_time' | 'monthly';
|
|
327
|
+
export interface LeaderboardParams {
|
|
328
|
+
/** Ranking to serve: net realized PnL, or the weighted correct-calls score. */
|
|
329
|
+
board: LeaderboardBoard;
|
|
330
|
+
/** `all_time` (default) or the current UTC calendar month. */
|
|
331
|
+
window?: LeaderboardWindow;
|
|
332
|
+
/** Market category (case-insensitive). Omit for the global board. Unknown categories return an empty board. */
|
|
333
|
+
category?: string;
|
|
334
|
+
/** Entries to return, up to the stored cap of 100. Default 10. */
|
|
335
|
+
limit?: number;
|
|
336
|
+
}
|
|
337
|
+
export interface LeaderboardEntry {
|
|
338
|
+
rank: number;
|
|
339
|
+
userId: string;
|
|
340
|
+
walletAddress: string | null;
|
|
341
|
+
eoaWalletAddress: string | null;
|
|
342
|
+
/** The ranking key. On `profit`, dollars × 1e6 (divide by 1,000,000 to display); on `correct_calls`, an unscaled weight. */
|
|
343
|
+
score: number;
|
|
344
|
+
positions: number;
|
|
345
|
+
/** Net realized PnL in dollars × 1e6. Present on both boards. */
|
|
346
|
+
profit: number;
|
|
347
|
+
/** Sum of `1 − entryPrice` over winning positions — a weight, not a count. Present on both boards. */
|
|
348
|
+
correctCalls: number;
|
|
349
|
+
/** Resolved directional positions — the denominator of `winRate`. */
|
|
350
|
+
trades: number;
|
|
351
|
+
wins: number;
|
|
352
|
+
/** `wins / trades`, a fraction in [0,1]. */
|
|
353
|
+
winRate: number;
|
|
354
|
+
badge: 'none' | 'blue' | 'gold';
|
|
355
|
+
/** Crowns held on this board and category — the row's crown indicator. */
|
|
356
|
+
categoryCrowns: number;
|
|
357
|
+
/** Newest crowned month in this bucket, `YYYY-MM` (UTC), or null. */
|
|
358
|
+
lastCrownPeriod: string | null;
|
|
359
|
+
/** Crowns held across all boards and categories. */
|
|
360
|
+
crownCount: number;
|
|
361
|
+
marketScore: number;
|
|
362
|
+
costScore: number;
|
|
363
|
+
}
|
|
364
|
+
export interface LeaderboardData {
|
|
365
|
+
board: LeaderboardBoard;
|
|
366
|
+
window: LeaderboardWindow;
|
|
367
|
+
/** Upper-cased matched key, or null for the global board. */
|
|
368
|
+
category: string | null;
|
|
369
|
+
/** Display spelling of the matched category, or null. */
|
|
370
|
+
categoryLabel: string | null;
|
|
371
|
+
/** `YYYY-MM` (UTC) on the monthly window; null on all-time. */
|
|
372
|
+
period: string | null;
|
|
373
|
+
limit: number;
|
|
374
|
+
/** Users ranked in total (before the stored cap). */
|
|
375
|
+
totalRanked: number;
|
|
376
|
+
/** Entry-price basis the correct-calls board was ranked on: `market` or `cost`. */
|
|
377
|
+
priceBasis: 'market' | 'cost';
|
|
378
|
+
entries: LeaderboardEntry[];
|
|
379
|
+
/** When the cron last rebuilt this board; null means never. */
|
|
380
|
+
lastUpdatedAt: string | null;
|
|
381
|
+
}
|
|
382
|
+
export interface LeaderboardCategory {
|
|
383
|
+
/** Upper-cased key — pass this back as `category`. */
|
|
384
|
+
category: string;
|
|
385
|
+
/** First-seen spelling, for display. */
|
|
386
|
+
label: string;
|
|
387
|
+
}
|
|
388
|
+
export interface LeaderboardSearchParams {
|
|
389
|
+
/** Wallet address, address fragment (with or without 0x, prefix/middle/tail), or user id. Case-insensitive substring match. */
|
|
390
|
+
q: string;
|
|
391
|
+
/** Board to search: `profit` or `correct_calls`. */
|
|
392
|
+
board: LeaderboardBoard;
|
|
393
|
+
/** `all_time` (default) or the current UTC calendar month. */
|
|
394
|
+
window?: LeaderboardWindow;
|
|
395
|
+
/** Market category (case-insensitive). Omit for the global board. */
|
|
396
|
+
category?: string;
|
|
397
|
+
/** Results to return, up to 50. Default 10. */
|
|
398
|
+
limit?: number;
|
|
399
|
+
}
|
|
400
|
+
export interface TraderRecentTradesParams {
|
|
401
|
+
/** The trader's user id, as returned in leaderboard entries. */
|
|
402
|
+
userId: string;
|
|
403
|
+
/** Rendered rows to return (a trade carrying more than one side flattens into more than one line), up to 25. Default 5. */
|
|
404
|
+
limit?: number;
|
|
405
|
+
}
|
|
406
|
+
export interface TraderRecentTrade {
|
|
407
|
+
/** Rendered form of `transactionType`: `Buy` or `Sell`. */
|
|
408
|
+
action: 'Buy' | 'Sell';
|
|
409
|
+
transactionType: string;
|
|
410
|
+
origin: 'enter' | 'orderFill';
|
|
411
|
+
transactionHash: string;
|
|
412
|
+
tradedAt: string;
|
|
413
|
+
poolId: string;
|
|
414
|
+
question: string | null;
|
|
415
|
+
poolImage: string | null;
|
|
416
|
+
subPoolId: string | null;
|
|
417
|
+
/** The sub-market — e.g. "Match winner". */
|
|
418
|
+
subQuestion: string | null;
|
|
419
|
+
/** 1 = YES, 2 = NO */
|
|
420
|
+
side: number;
|
|
421
|
+
optionName: string;
|
|
422
|
+
shares: number;
|
|
423
|
+
/** Collateral paid, in dollars × 1e6 (divide by 1,000,000 to display). */
|
|
424
|
+
amountUSD: number;
|
|
425
|
+
/** Collateral paid per share, in (0,1). Null when the recorded ratio is not a price (e.g. a 1:1 AMM entry). */
|
|
426
|
+
pricePerShare: number | null;
|
|
427
|
+
/** `pricePerShare` in cents, for the "9c" label. */
|
|
428
|
+
priceCents: number | null;
|
|
429
|
+
/** `open` = market not resolved; `pending` = won but unclaimed (no PnL yet, never booked as a loss); `settled` = realized. */
|
|
430
|
+
status: 'open' | 'pending' | 'settled';
|
|
431
|
+
/** Always `position` — PnL is per (pool, subPool), not per fill. */
|
|
432
|
+
pnlScope: string;
|
|
433
|
+
/** Realized PnL of the POSITION this trade belongs to, in dollars × 1e6. Null until settled. */
|
|
434
|
+
pnlUSD: number | null;
|
|
435
|
+
/** Resolved-but-unclaimed winnings of the position, in dollars × 1e6. */
|
|
436
|
+
pendingUSD?: number;
|
|
437
|
+
/** Whether the position won, once resolved. */
|
|
438
|
+
won?: boolean;
|
|
439
|
+
}
|
|
440
|
+
export interface TraderRecentTradesData {
|
|
441
|
+
userId: string;
|
|
442
|
+
limit: number;
|
|
443
|
+
/** Most recent directional trades, newest first. */
|
|
444
|
+
trades: TraderRecentTrade[];
|
|
445
|
+
}
|
|
446
|
+
export interface LeaderboardSearchData {
|
|
447
|
+
board: LeaderboardBoard;
|
|
448
|
+
window: LeaderboardWindow;
|
|
449
|
+
category: string | null;
|
|
450
|
+
/** `YYYY-MM` (UTC) on the monthly window; null on all-time. */
|
|
451
|
+
period: string | null;
|
|
452
|
+
query: string;
|
|
453
|
+
/** Board entries the term matched, before `limit`. */
|
|
454
|
+
matched: number;
|
|
455
|
+
/** Board rows searched — the stored depth. With `matched: 0`, lets a client say "not in the top N" rather than "no such trader". */
|
|
456
|
+
searchedTop: number;
|
|
457
|
+
/** Users ranked on this board in total. */
|
|
458
|
+
totalRanked: number;
|
|
459
|
+
lastUpdatedAt: string | null;
|
|
460
|
+
/** Matching board entries — the same objects `getLeaderboard` returns, in rank order. */
|
|
461
|
+
results: LeaderboardEntry[];
|
|
462
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export { signLoginMessage } from './auth/signMessage.js';
|
|
|
8
8
|
export type { ExtendTimeTxParams } from './tx/buildExtendTimeRawTx.js';
|
|
9
9
|
export type { CalculateWinnerTxParams } from './tx/buildCalculateWinnerRawTx.js';
|
|
10
10
|
export type { TokenConfig } from './config/environments.js';
|
|
11
|
+
export type { OptionDisputeInfo, OptionAppealInfo } from './markets/getDisputeState.js';
|
|
11
12
|
export * from './api/index.js';
|
|
12
13
|
export { RainSocket } from './socket/RainSocket.js';
|
|
13
14
|
export type { RainSocketEvent, EnterOptionEventData, ExitOptionEventData, LiquidityEventData, SplitEventData, MergeEventData, RemoveLiquidityEventData, SyncPriceEventData, OrderCreatedEventData, OrderCancelledEventData, OrderFilledEventData, PoolClosedEventData, PoolEventData, WinnerEventData, DisputeOpenedEventData, OracleCreatedEventData, AppealOpenedEventData, DisputeWinnerEventData, AppealWinnerEventData, ClaimRewardEventData, DisputeRefundEventData } from './socket/RainSocket.js';
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export interface OptionDisputeInfo {
|
|
2
|
+
disputeFee: bigint;
|
|
3
|
+
disputedWinner: bigint;
|
|
4
|
+
disputer: `0x${string}`;
|
|
5
|
+
disputeResolver: `0x${string}`;
|
|
6
|
+
}
|
|
7
|
+
export interface OptionAppealInfo {
|
|
8
|
+
disputeFee: bigint;
|
|
9
|
+
disputedWinner: bigint;
|
|
10
|
+
disputer: `0x${string}`;
|
|
11
|
+
appealResolver: `0x${string}`;
|
|
12
|
+
}
|
|
13
|
+
interface OptionReadParams {
|
|
14
|
+
marketContractAddress: `0x${string}`;
|
|
15
|
+
option: bigint;
|
|
16
|
+
rpcUrl: string;
|
|
17
|
+
}
|
|
18
|
+
export declare function optionResolverBond(params: OptionReadParams): Promise<bigint>;
|
|
19
|
+
export declare function optionResolutionProposer(params: OptionReadParams): Promise<`0x${string}`>;
|
|
20
|
+
export declare function isOptionDisputed(params: OptionReadParams): Promise<boolean>;
|
|
21
|
+
export declare function isOptionAppealed(params: OptionReadParams): Promise<boolean>;
|
|
22
|
+
export declare function optionDispute(params: OptionReadParams): Promise<OptionDisputeInfo>;
|
|
23
|
+
export declare function optionAppeal(params: OptionReadParams): Promise<OptionAppealInfo>;
|
|
24
|
+
export {};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { createPublicClient, http } from 'viem';
|
|
2
|
+
import { arbitrum } from 'viem/chains';
|
|
3
|
+
import { MarketsAbi } from '../abi/MarketsAbi.js';
|
|
4
|
+
function client(rpcUrl) {
|
|
5
|
+
return createPublicClient({
|
|
6
|
+
chain: arbitrum,
|
|
7
|
+
transport: http(rpcUrl),
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
export async function optionResolverBond(params) {
|
|
11
|
+
const { marketContractAddress, option, rpcUrl } = params;
|
|
12
|
+
const bond = await client(rpcUrl).readContract({
|
|
13
|
+
address: marketContractAddress,
|
|
14
|
+
abi: MarketsAbi,
|
|
15
|
+
functionName: 'optionResolverBond',
|
|
16
|
+
args: [option],
|
|
17
|
+
});
|
|
18
|
+
return bond;
|
|
19
|
+
}
|
|
20
|
+
export async function optionResolutionProposer(params) {
|
|
21
|
+
const { marketContractAddress, option, rpcUrl } = params;
|
|
22
|
+
const proposer = await client(rpcUrl).readContract({
|
|
23
|
+
address: marketContractAddress,
|
|
24
|
+
abi: MarketsAbi,
|
|
25
|
+
functionName: 'optionResolutionProposer',
|
|
26
|
+
args: [option],
|
|
27
|
+
});
|
|
28
|
+
return proposer;
|
|
29
|
+
}
|
|
30
|
+
export async function isOptionDisputed(params) {
|
|
31
|
+
const { marketContractAddress, option, rpcUrl } = params;
|
|
32
|
+
const disputed = await client(rpcUrl).readContract({
|
|
33
|
+
address: marketContractAddress,
|
|
34
|
+
abi: MarketsAbi,
|
|
35
|
+
functionName: 'isOptionDisputed',
|
|
36
|
+
args: [option],
|
|
37
|
+
});
|
|
38
|
+
return disputed;
|
|
39
|
+
}
|
|
40
|
+
export async function isOptionAppealed(params) {
|
|
41
|
+
const { marketContractAddress, option, rpcUrl } = params;
|
|
42
|
+
const appealed = await client(rpcUrl).readContract({
|
|
43
|
+
address: marketContractAddress,
|
|
44
|
+
abi: MarketsAbi,
|
|
45
|
+
functionName: 'isOptionAppealed',
|
|
46
|
+
args: [option],
|
|
47
|
+
});
|
|
48
|
+
return appealed;
|
|
49
|
+
}
|
|
50
|
+
export async function optionDispute(params) {
|
|
51
|
+
const { marketContractAddress, option, rpcUrl } = params;
|
|
52
|
+
const [disputeFee, disputedWinner, disputer, disputeResolver] = await client(rpcUrl).readContract({
|
|
53
|
+
address: marketContractAddress,
|
|
54
|
+
abi: MarketsAbi,
|
|
55
|
+
functionName: 'optionDispute',
|
|
56
|
+
args: [option],
|
|
57
|
+
});
|
|
58
|
+
return { disputeFee, disputedWinner, disputer, disputeResolver };
|
|
59
|
+
}
|
|
60
|
+
export async function optionAppeal(params) {
|
|
61
|
+
const { marketContractAddress, option, rpcUrl } = params;
|
|
62
|
+
const [disputeFee, disputedWinner, disputer, appealResolver] = await client(rpcUrl).readContract({
|
|
63
|
+
address: marketContractAddress,
|
|
64
|
+
abi: MarketsAbi,
|
|
65
|
+
functionName: 'optionAppeal',
|
|
66
|
+
args: [option],
|
|
67
|
+
});
|
|
68
|
+
return { disputeFee, disputedWinner, disputer, appealResolver };
|
|
69
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rain-sdk-v2",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.5",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Rain SDK V2 — TypeScript SDK for Rain prediction markets on Arbitrum. Market creation, trading, liquidity, order book, split/merge, dispute, and smart account support.",
|
|
6
6
|
"main": "dist/index.js",
|