@rainprotocolsdk/sdk 1.1.1 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,20 @@
1
+ export declare const ALLOWED_ENVIRONMENTS: readonly ["development", "stage", "production"];
2
+ export declare const DEFAULT_RPCS: string[];
3
+ export declare function getRandomRpc(): string;
4
+ export declare const ENV_CONFIG: {
5
+ readonly development: {
6
+ readonly apiUrl: "https://dev-api.rain.one";
7
+ readonly market_factory_address: "0x148DA7F2039B2B00633AC2ab566f59C8a4C86313";
8
+ readonly dispute_initial_timer: number;
9
+ };
10
+ readonly stage: {
11
+ readonly apiUrl: "https://stg-api.rain.one";
12
+ readonly market_factory_address: "0x6109c9f28FE3Ad84c51368f7Ef2d487ca020c561";
13
+ readonly dispute_initial_timer: number;
14
+ };
15
+ readonly production: {
16
+ readonly apiUrl: "https://prod-api.rain.one";
17
+ readonly market_factory_address: "0xccCB3C03D9355B01883779EF15C1Be09cf3623F1";
18
+ readonly dispute_initial_timer: number;
19
+ };
20
+ };
@@ -0,0 +1,27 @@
1
+ export const ALLOWED_ENVIRONMENTS = ["development", "stage", "production"];
2
+ export const DEFAULT_RPCS = [
3
+ "https://arbitrum.meowrpc.com",
4
+ "https://rpc.sentio.xyz/arbitrum-one",
5
+ "https://rpc.owlracle.info/arb/70d38ce1826c4a60bb2a8e05a6c8b20f"
6
+ ];
7
+ export function getRandomRpc() {
8
+ const index = Math.floor(Math.random() * DEFAULT_RPCS.length);
9
+ return DEFAULT_RPCS[index];
10
+ }
11
+ export const ENV_CONFIG = {
12
+ development: {
13
+ apiUrl: "https://dev-api.rain.one",
14
+ market_factory_address: "0x148DA7F2039B2B00633AC2ab566f59C8a4C86313",
15
+ dispute_initial_timer: 1 * 60
16
+ },
17
+ stage: {
18
+ apiUrl: "https://stg-api.rain.one",
19
+ market_factory_address: "0x6109c9f28FE3Ad84c51368f7Ef2d487ca020c561",
20
+ dispute_initial_timer: 1 * 60
21
+ },
22
+ production: {
23
+ apiUrl: "https://prod-api.rain.one",
24
+ market_factory_address: "0xccCB3C03D9355B01883779EF15C1Be09cf3623F1",
25
+ dispute_initial_timer: 120 * 60
26
+ },
27
+ };
@@ -1,3 +1,5 @@
1
1
  export declare const ENTER_OPTION = "enterOption";
2
2
  export declare const PLACE_BUY_ORDER = "placeBuyOrder";
3
3
  export declare const APPROVE_TOKEN = "approve";
4
+ export declare const CREATE_MARKET = "createPool";
5
+ export declare const CLAIM = "claim";
@@ -1,3 +1,5 @@
1
1
  export const ENTER_OPTION = 'enterOption';
2
2
  export const PLACE_BUY_ORDER = 'placeBuyOrder';
3
3
  export const APPROVE_TOKEN = 'approve';
4
+ export const CREATE_MARKET = 'createPool';
5
+ export const CLAIM = "claim";
@@ -1,7 +1,9 @@
1
- import { API_BASE_URL } from '../config/api.js';
2
1
  import { MARKET_SORT_BY, MARKET_STATUS } from './constants.js';
3
2
  export async function getMarkets(params) {
4
3
  const query = new URLSearchParams();
4
+ if (!params?.apiUrl) {
5
+ throw new Error("Environemnt is not set properly, api url is missing");
6
+ }
5
7
  if (params?.limit)
6
8
  query.append('limit', params.limit.toString());
7
9
  if (params?.offset)
@@ -10,7 +12,7 @@ export async function getMarkets(params) {
10
12
  query.append('sortBy', MARKET_SORT_BY[params.sortBy]);
11
13
  if (params?.status)
12
14
  query.append('status', MARKET_STATUS[params.status]);
13
- const res = await fetch(`${API_BASE_URL}/pools/public-pools?${query.toString()}`);
15
+ const res = await fetch(`${params.apiUrl}/pools/public-pools?${query.toString()}`);
14
16
  if (!res.ok) {
15
17
  throw new Error(`Failed to fetch markets: ${res.status}`);
16
18
  }
@@ -5,6 +5,7 @@ export interface GetMarketsParams {
5
5
  offset?: number;
6
6
  sortBy?: MarketSortBy;
7
7
  status?: MarketStatus;
8
+ apiUrl?: string;
8
9
  }
9
10
  export interface Market {
10
11
  id: string;
@@ -0,0 +1,2 @@
1
+ import { ClaimTxParams, RawTransaction } from "../types.js";
2
+ export declare function buildClaimRawTx(params: ClaimTxParams): Promise<RawTransaction>;
@@ -0,0 +1,34 @@
1
+ import { encodeFunctionData } from "viem";
2
+ import { TradePoolAbi } from "../../abi/TradeMarketsAbi.js";
3
+ import { getMarket, getUserOptionShares, isRpcValid } from "./helpers.js";
4
+ import { MARKET_STATUS } from "../../markets/constants.js";
5
+ import { CLAIM } from "../../constants/contractmethods.js";
6
+ export async function buildClaimRawTx(params) {
7
+ const { marketId, walletAddress, apiUrl, rpcUrl } = params;
8
+ if (!apiUrl) {
9
+ throw new Error("Environemnt is not set properly, api url is missing");
10
+ }
11
+ const isRpcWorking = await isRpcValid(rpcUrl);
12
+ if (!rpcUrl || !isRpcWorking) {
13
+ throw new Error("Provided RPC URL is not valid or not working");
14
+ }
15
+ if (!marketId)
16
+ throw new Error("marketContractAddress is required");
17
+ if (!walletAddress)
18
+ throw new Error("walletAddress is required");
19
+ const { data } = await getMarket({ marketId, apiUrl });
20
+ if (data?.status !== MARKET_STATUS.Closed)
21
+ throw new Error("Market is not closed yet. Please wait until the market is closed to claim your funds.");
22
+ const marketContractAddress = data?.contractAddress;
23
+ const options = data?.options || 0;
24
+ const userShares = await getUserOptionShares({ marketContractAddress: marketContractAddress, walletAddress: walletAddress, options: options, rpcUrl: rpcUrl });
25
+ if (userShares?.length <= 0)
26
+ throw new Error("No shares to claim for this market");
27
+ return {
28
+ to: marketContractAddress,
29
+ data: encodeFunctionData({
30
+ abi: TradePoolAbi,
31
+ functionName: CLAIM,
32
+ }),
33
+ };
34
+ }
@@ -0,0 +1,8 @@
1
+ import { Market } from "../../markets/types.js";
2
+ import { GetUserOptionSharesParams } from "../types.js";
3
+ export declare function getMarket(params: {
4
+ marketId: string;
5
+ apiUrl: string;
6
+ }): Promise<Market>;
7
+ export declare function isRpcValid(rpcUrl: string | undefined): Promise<boolean>;
8
+ export declare function getUserOptionShares(params: GetUserOptionSharesParams): Promise<number[]>;
@@ -0,0 +1,37 @@
1
+ import { Contract, JsonRpcProvider } from "ethers";
2
+ import { TradePoolAbi } from "../../abi/TradeMarketsAbi.js";
3
+ export async function getMarket(params) {
4
+ if (!params?.apiUrl) {
5
+ throw new Error("Environemnt is not set properly, api url is missing");
6
+ }
7
+ const res = await fetch(`${params.apiUrl}/pools/pool/${params.marketId}`);
8
+ if (!res.ok) {
9
+ throw new Error(`Failed to fetch markets: ${res.status}`);
10
+ }
11
+ const data = await res.json();
12
+ return data;
13
+ }
14
+ export async function isRpcValid(rpcUrl) {
15
+ if (!rpcUrl)
16
+ return false;
17
+ const provider = new JsonRpcProvider(rpcUrl);
18
+ try {
19
+ await provider.getNetwork();
20
+ return true;
21
+ }
22
+ catch (error) {
23
+ return false;
24
+ }
25
+ }
26
+ export async function getUserOptionShares(params) {
27
+ const { marketContractAddress, options, walletAddress, rpcUrl } = params;
28
+ const provider = new JsonRpcProvider(rpcUrl);
29
+ const userShares = [];
30
+ for (let i = 0; i < options.length; i++) {
31
+ const choiceIndex = options[i].choiceIndex;
32
+ const contract = new Contract(marketContractAddress, TradePoolAbi, provider);
33
+ const userVotes = await contract.userVotes(choiceIndex, walletAddress);
34
+ Number(userVotes) > 0 && userShares.push(Number(userVotes));
35
+ }
36
+ return userShares;
37
+ }
@@ -0,0 +1,2 @@
1
+ import { CreateMarketTxParams, RawTransaction } from "../types.js";
2
+ export declare function buildCreateMarketRawTx(params: CreateMarketTxParams): RawTransaction;
@@ -0,0 +1,36 @@
1
+ import { encodeFunctionData } from "viem";
2
+ import { CreateMarketAbi } from "../../abi/CreateMarketAbi.js";
3
+ import { CREATE_MARKET } from "../../constants/contractmethods.js";
4
+ import { validateCreateMarketParams } from "./createMarketValidation.js";
5
+ import { normalizeBarValues } from "./helpers.js";
6
+ const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
7
+ export function buildCreateMarketRawTx(params) {
8
+ const { isPublic, isPublicPoolResolverAi, creator, startTime, endTime, options, disputeTimer, ipfsUrl, inputAmountWei, barValues, baseToken, factoryContractAddress, } = params;
9
+ if (!factoryContractAddress)
10
+ throw new Error("environment is not set correctly, factory contract address is missing");
11
+ validateCreateMarketParams(params);
12
+ const normalizeBarValue = normalizeBarValues(barValues);
13
+ const createMarketParams = [
14
+ isPublic,
15
+ isPublicPoolResolverAi,
16
+ creator,
17
+ ZERO_ADDRESS,
18
+ startTime,
19
+ endTime,
20
+ options,
21
+ disputeTimer,
22
+ ipfsUrl,
23
+ inputAmountWei,
24
+ normalizeBarValue,
25
+ creator,
26
+ baseToken,
27
+ ];
28
+ return {
29
+ to: factoryContractAddress,
30
+ data: encodeFunctionData({
31
+ abi: CreateMarketAbi,
32
+ functionName: CREATE_MARKET,
33
+ args: [createMarketParams],
34
+ }),
35
+ };
36
+ }
@@ -0,0 +1,2 @@
1
+ import { CreateMarketTxParams } from "../types.js";
2
+ export declare function validateCreateMarketParams(params: CreateMarketTxParams): boolean;
@@ -0,0 +1,34 @@
1
+ export function validateCreateMarketParams(params) {
2
+ const { isPublic, isPublicPoolResolverAi, creator, startTime, endTime, options, ipfsUrl, inputAmountWei, barValues, baseToken, factoryContractAddress, tokenDecimals, } = params;
3
+ // Required field validations
4
+ if (typeof isPublic !== "boolean")
5
+ throw new Error("isPublic is required and must be a boolean");
6
+ if (typeof isPublicPoolResolverAi !== "boolean")
7
+ throw new Error("isPublicPoolResolverAi is required and must be a boolean");
8
+ if (!creator)
9
+ throw new Error("creator address is required");
10
+ if (!startTime)
11
+ throw new Error("startTime is required");
12
+ if (!endTime)
13
+ throw new Error("endTime is required");
14
+ if (!options)
15
+ throw new Error("number of options is required and cannot be empty");
16
+ if (!ipfsUrl || typeof ipfsUrl !== "string")
17
+ throw new Error("ipfsUrl is required");
18
+ if (!inputAmountWei)
19
+ throw new Error("inputAmountWei is required");
20
+ if (!barValues || !Array.isArray(barValues) || barValues.length === 0)
21
+ throw new Error("barValues array is required and cannot be empty");
22
+ if (!baseToken)
23
+ throw new Error("baseToken address is required");
24
+ if (!factoryContractAddress)
25
+ throw new Error("factoryContractAddress is required");
26
+ const decimals = tokenDecimals ?? 6;
27
+ const oneTokenInWei = 10n ** BigInt(decimals);
28
+ if (inputAmountWei < oneTokenInWei * 10n) {
29
+ throw new Error("Market cannot be opened: inputAmountWei must be at least $10");
30
+ }
31
+ if (startTime >= endTime)
32
+ throw new Error("startTime must be earlier than endTime");
33
+ return true;
34
+ }
@@ -0,0 +1 @@
1
+ export declare function normalizeBarValues(values: (number)[]): number[];
@@ -0,0 +1,11 @@
1
+ export function normalizeBarValues(values) {
2
+ const transformedBarValues = [
3
+ ...values.map((value) => Math.floor(value * 100)),
4
+ ];
5
+ const totalRounded = transformedBarValues.reduce((sum, val) => sum + val, 0);
6
+ const difference = 10000 - totalRounded;
7
+ if (difference !== 0) {
8
+ transformedBarValues[transformedBarValues.length - 1] += difference;
9
+ }
10
+ return transformedBarValues;
11
+ }
@@ -20,3 +20,33 @@ export interface EnterLimitOptionTxParams {
20
20
  buyAmountInWei: bigint;
21
21
  tokenDecimals?: number;
22
22
  }
23
+ export interface CreateMarketTxParams {
24
+ isPublic: boolean;
25
+ isPublicPoolResolverAi: boolean;
26
+ creator: `0x${string}`;
27
+ startTime: bigint;
28
+ endTime: bigint;
29
+ options: bigint;
30
+ disputeTimer: number;
31
+ ipfsUrl: string;
32
+ inputAmountWei: bigint;
33
+ barValues: number[];
34
+ baseToken: `0x${string}`;
35
+ tokenDecimals?: number;
36
+ factoryContractAddress?: `0x${string}`;
37
+ }
38
+ export interface ClaimTxParams {
39
+ marketId: string;
40
+ walletAddress: `0x${string}`;
41
+ apiUrl?: string;
42
+ rpcUrl?: string;
43
+ }
44
+ export interface GetUserOptionSharesParams {
45
+ options: [{
46
+ choiceIndex: number;
47
+ optionName: string;
48
+ }];
49
+ walletAddress: `0x${string}`;
50
+ marketContractAddress: `0x${string}`;
51
+ rpcUrl: string;
52
+ }
package/dist/types.d.ts CHANGED
@@ -7,3 +7,8 @@ export interface RainConfig {
7
7
  chain: Chain;
8
8
  rpcUrl?: string;
9
9
  }
10
+ export type RainEnvironment = "development" | "stage" | "production";
11
+ export interface RainCoreConfig {
12
+ environment?: RainEnvironment;
13
+ rpcUrl?: string;
14
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rainprotocolsdk/sdk",
3
- "version": "1.1.1",
3
+ "version": "1.3.0",
4
4
  "type": "module",
5
5
  "description": "Rain SDK",
6
6
  "main": "dist/index.js",
@@ -1 +0,0 @@
1
- export declare const API_BASE_URL = "https://dev-api.rain.one";
@@ -1 +0,0 @@
1
- export const API_BASE_URL = "https://dev-api.rain.one";