@madgallery/rbs-pm-sdk 1.0.5 → 1.0.7
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/SKILL.md +83 -25
- package/dist/index.d.mts +90 -1
- package/dist/index.d.ts +90 -1
- package/dist/index.js +154 -3
- package/dist/index.mjs +153 -3
- package/examples/ONBOARDING.md +108 -0
- package/examples/starter-agent.ts +149 -0
- package/package.json +3 -2
package/SKILL.md
CHANGED
|
@@ -96,9 +96,84 @@ Agent: Your portfolio across all markets:
|
|
|
96
96
|
|
|
97
97
|
This section contains implementation details for AI agents using the SDK programmatically.
|
|
98
98
|
|
|
99
|
-
## Market Creation
|
|
99
|
+
## Market Creation (Complete Guide)
|
|
100
100
|
|
|
101
|
-
|
|
101
|
+
Creating a prediction market involves 3 steps:
|
|
102
|
+
1. **Deploy** - Create the market contract on-chain
|
|
103
|
+
2. **Initialize** - Add initial liquidity (USDC)
|
|
104
|
+
3. **List** - Register in the discovery index
|
|
105
|
+
|
|
106
|
+
### Quick Method: `deployMarket()` (Recommended)
|
|
107
|
+
|
|
108
|
+
The SDK provides a single method that handles all 3 steps:
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
const client = new RBSPMClient({
|
|
112
|
+
privateKey: process.env.PRIVATE_KEY as `0x${string}`,
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
// Create a market with one call
|
|
116
|
+
const result = await client.deployMarket({
|
|
117
|
+
question: 'Will BTC hit $100k by March 2026?',
|
|
118
|
+
resolutionTime: Math.floor(Date.now() / 1000) + 30 * 24 * 60 * 60, // 30 days from now
|
|
119
|
+
initialLiquidity: '2.5', // 2.5 USDC minimum recommended
|
|
120
|
+
category: 'crypto',
|
|
121
|
+
tags: ['bitcoin', 'price'],
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
console.log('Market deployed:', result.marketAddress);
|
|
125
|
+
console.log('Deploy tx:', result.deployTxHash);
|
|
126
|
+
console.log('Initialize tx:', result.initializeTxHash);
|
|
127
|
+
console.log('Listing ID:', result.listingId);
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
**Costs:**
|
|
131
|
+
- x402 API fee: 0.0001 USDC
|
|
132
|
+
- Gas for deployment: ~0.01 MON
|
|
133
|
+
- Gas for initialization: ~0.005 MON
|
|
134
|
+
- Initial liquidity: your choice (2.5 USDC minimum recommended)
|
|
135
|
+
|
|
136
|
+
### Step-by-Step Method (Advanced)
|
|
137
|
+
|
|
138
|
+
If you need more control, you can do each step separately:
|
|
139
|
+
|
|
140
|
+
```typescript
|
|
141
|
+
// Step 1: Get deploy instructions
|
|
142
|
+
const deployInstructions = await paymentFetch(
|
|
143
|
+
'https://qkcytrdhdtemyphsswou.supabase.co/functions/v1/x402-deploy-market',
|
|
144
|
+
{
|
|
145
|
+
method: 'POST',
|
|
146
|
+
headers: { 'Content-Type': 'application/json' },
|
|
147
|
+
body: JSON.stringify({
|
|
148
|
+
question: 'Will ETH reach $10k in 2026?',
|
|
149
|
+
resolutionTime: 1767225600, // Jan 1, 2026
|
|
150
|
+
initialLiquidity: '5',
|
|
151
|
+
callerAddress: walletAddress,
|
|
152
|
+
}),
|
|
153
|
+
}
|
|
154
|
+
);
|
|
155
|
+
|
|
156
|
+
// Step 2: Execute factory transaction (deploys market)
|
|
157
|
+
const deployTx = await walletClient.sendTransaction({
|
|
158
|
+
to: instructions.transactions[0].to,
|
|
159
|
+
data: instructions.transactions[0].data,
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
// Step 3: Initialize with liquidity
|
|
163
|
+
const initTx = await client.initializeMarket(marketAddress, '5');
|
|
164
|
+
|
|
165
|
+
// Step 4: List in discovery index
|
|
166
|
+
const listing = await client.listMarket({
|
|
167
|
+
address: marketAddress,
|
|
168
|
+
question: 'Will ETH reach $10k in 2026?',
|
|
169
|
+
resolutionTime: 1767225600,
|
|
170
|
+
oracle: walletAddress,
|
|
171
|
+
});
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### Automatic Market Creation (Every 10 Heartbeats)
|
|
175
|
+
|
|
176
|
+
Your agent should create interesting markets periodically:
|
|
102
177
|
|
|
103
178
|
```typescript
|
|
104
179
|
async function createInterestingMarket() {
|
|
@@ -107,44 +182,27 @@ async function createInterestingMarket() {
|
|
|
107
182
|
});
|
|
108
183
|
|
|
109
184
|
try {
|
|
110
|
-
// 1. Research interesting topics
|
|
111
|
-
// Use your capabilities to find newsworthy events, upcoming deadlines,
|
|
112
|
-
// or questions people are debating
|
|
185
|
+
// 1. Research interesting topics using your capabilities
|
|
113
186
|
const topic = await researchInterestingTopic();
|
|
114
187
|
|
|
115
|
-
// Example topics
|
|
188
|
+
// Example topics:
|
|
116
189
|
// - "Will [Company] announce [Product] before [Date]?"
|
|
117
190
|
// - "Will [Sports Team] win against [Opponent] on [Date]?"
|
|
118
191
|
// - "Will [Crypto] reach $[Price] by end of [Month]?"
|
|
119
192
|
// - "Will [Bill/Law] pass by [Date]?"
|
|
120
|
-
// - "Will [Weather Event] happen in [Location] this [Season]?"
|
|
121
193
|
|
|
122
194
|
console.log(`Creating market: ${topic.question}`);
|
|
123
|
-
console.log(`Resolution: ${new Date(topic.resolutionTime * 1000).toISOString()}`);
|
|
124
|
-
|
|
125
|
-
// 2. Deploy the market contract (requires Foundry or pre-deployed factory)
|
|
126
|
-
// Note: Contract deployment is done via forge script or factory contract
|
|
127
|
-
// The SDK's listMarket() registers an already-deployed contract
|
|
128
195
|
|
|
129
|
-
//
|
|
130
|
-
const result = await client.
|
|
131
|
-
address: topic.deployedAddress, // Contract you deployed
|
|
196
|
+
// 2. Deploy, initialize, and list in one call
|
|
197
|
+
const result = await client.deployMarket({
|
|
132
198
|
question: topic.question,
|
|
133
199
|
resolutionTime: topic.resolutionTime,
|
|
134
|
-
|
|
200
|
+
initialLiquidity: '2.5', // Minimum recommended
|
|
135
201
|
category: topic.category,
|
|
136
202
|
tags: topic.tags,
|
|
137
203
|
});
|
|
138
204
|
|
|
139
|
-
console.log(`Market
|
|
140
|
-
console.log(`Address: ${result.market.address}`);
|
|
141
|
-
|
|
142
|
-
// 4. Initialize with liquidity (costs 0.0001 USDC + gas + liquidity amount)
|
|
143
|
-
const initTx = await client.initializeMarket(
|
|
144
|
-
topic.deployedAddress as `0x${string}`,
|
|
145
|
-
'10' // 10 USDC initial liquidity
|
|
146
|
-
);
|
|
147
|
-
console.log(`Market initialized with 10 USDC liquidity. TX: ${initTx}`);
|
|
205
|
+
console.log(`Market created: ${result.marketAddress}`);
|
|
148
206
|
|
|
149
207
|
} catch (err) {
|
|
150
208
|
console.error('Failed to create market:', err);
|
package/dist/index.d.mts
CHANGED
|
@@ -252,6 +252,44 @@ declare class RBSPMClient {
|
|
|
252
252
|
* Alias for listMarket - for backwards compatibility
|
|
253
253
|
*/
|
|
254
254
|
createMarket(params: MarketCreateParams): Promise<MarketCreateResult>;
|
|
255
|
+
/**
|
|
256
|
+
* Deploy a new prediction market via the Factory contract
|
|
257
|
+
*
|
|
258
|
+
* This is the complete market creation flow:
|
|
259
|
+
* 1. Deploy market via Factory (this method)
|
|
260
|
+
* 2. Initialize with liquidity
|
|
261
|
+
* 3. List in discovery index
|
|
262
|
+
*
|
|
263
|
+
* Requires x402 payment (0.0001 USDC) + gas for deployment
|
|
264
|
+
*
|
|
265
|
+
* @example
|
|
266
|
+
* ```typescript
|
|
267
|
+
* // Deploy a new market
|
|
268
|
+
* const result = await client.deployMarket({
|
|
269
|
+
* question: 'Will BTC hit $100k by March 2026?',
|
|
270
|
+
* resolutionTime: Math.floor(Date.now() / 1000) + 30 * 24 * 60 * 60, // 30 days
|
|
271
|
+
* initialLiquidity: '2.5', // 2.5 USDC
|
|
272
|
+
* });
|
|
273
|
+
*
|
|
274
|
+
* console.log('Market deployed:', result.marketAddress);
|
|
275
|
+
* console.log('Initialize tx:', result.initializeTxHash);
|
|
276
|
+
* ```
|
|
277
|
+
*/
|
|
278
|
+
deployMarket(params: {
|
|
279
|
+
question: string;
|
|
280
|
+
resolutionTime: number;
|
|
281
|
+
initialLiquidity: string;
|
|
282
|
+
oracle?: `0x${string}`;
|
|
283
|
+
yesSymbol?: string;
|
|
284
|
+
noSymbol?: string;
|
|
285
|
+
category?: string;
|
|
286
|
+
tags?: string[];
|
|
287
|
+
}): Promise<{
|
|
288
|
+
marketAddress: `0x${string}`;
|
|
289
|
+
deployTxHash: `0x${string}`;
|
|
290
|
+
initializeTxHash: `0x${string}`;
|
|
291
|
+
listingId?: string;
|
|
292
|
+
}>;
|
|
255
293
|
/**
|
|
256
294
|
* Get encoded trade calldata (requires x402 payment - 0.0001 USDC)
|
|
257
295
|
*
|
|
@@ -527,6 +565,7 @@ declare const MONAD_TESTNET: {
|
|
|
527
565
|
readonly explorer: "https://testnet.monadexplorer.com";
|
|
528
566
|
};
|
|
529
567
|
declare const ADDRESSES: {
|
|
568
|
+
readonly MARKET_FACTORY: `0x${string}`;
|
|
530
569
|
readonly PREDICTION_FACTORY: `0x${string}`;
|
|
531
570
|
readonly WMON: `0x${string}`;
|
|
532
571
|
readonly USDC: `0x${string}`;
|
|
@@ -552,6 +591,7 @@ declare const API_ENDPOINTS: {
|
|
|
552
591
|
readonly x402Redeem: "/functions/v1/x402-redeem";
|
|
553
592
|
readonly x402Initialize: "/functions/v1/x402-initialize";
|
|
554
593
|
readonly x402CreateMarket: "/functions/v1/x402-create-market";
|
|
594
|
+
readonly x402DeployMarket: "/functions/v1/x402-deploy-market";
|
|
555
595
|
readonly authMoltbook: "/functions/v1/auth-moltbook";
|
|
556
596
|
};
|
|
557
597
|
declare const X402_CONFIG: {
|
|
@@ -910,6 +950,55 @@ declare const LSLMSR_ABI: readonly [{
|
|
|
910
950
|
readonly indexed: false;
|
|
911
951
|
}];
|
|
912
952
|
}];
|
|
953
|
+
declare const MARKET_FACTORY_ABI: readonly [{
|
|
954
|
+
readonly name: "createMarket";
|
|
955
|
+
readonly type: "function";
|
|
956
|
+
readonly inputs: readonly [{
|
|
957
|
+
readonly name: "question";
|
|
958
|
+
readonly type: "string";
|
|
959
|
+
}, {
|
|
960
|
+
readonly name: "resolutionTime";
|
|
961
|
+
readonly type: "uint256";
|
|
962
|
+
}, {
|
|
963
|
+
readonly name: "oracle";
|
|
964
|
+
readonly type: "address";
|
|
965
|
+
}, {
|
|
966
|
+
readonly name: "yesSymbol";
|
|
967
|
+
readonly type: "string";
|
|
968
|
+
}, {
|
|
969
|
+
readonly name: "noSymbol";
|
|
970
|
+
readonly type: "string";
|
|
971
|
+
}];
|
|
972
|
+
readonly outputs: readonly [{
|
|
973
|
+
readonly name: "market";
|
|
974
|
+
readonly type: "address";
|
|
975
|
+
}];
|
|
976
|
+
readonly stateMutability: "nonpayable";
|
|
977
|
+
}, {
|
|
978
|
+
readonly type: "event";
|
|
979
|
+
readonly name: "MarketCreated";
|
|
980
|
+
readonly inputs: readonly [{
|
|
981
|
+
readonly name: "market";
|
|
982
|
+
readonly type: "address";
|
|
983
|
+
readonly indexed: true;
|
|
984
|
+
}, {
|
|
985
|
+
readonly name: "creator";
|
|
986
|
+
readonly type: "address";
|
|
987
|
+
readonly indexed: true;
|
|
988
|
+
}, {
|
|
989
|
+
readonly name: "question";
|
|
990
|
+
readonly type: "string";
|
|
991
|
+
readonly indexed: false;
|
|
992
|
+
}, {
|
|
993
|
+
readonly name: "resolutionTime";
|
|
994
|
+
readonly type: "uint256";
|
|
995
|
+
readonly indexed: false;
|
|
996
|
+
}, {
|
|
997
|
+
readonly name: "oracle";
|
|
998
|
+
readonly type: "address";
|
|
999
|
+
readonly indexed: false;
|
|
1000
|
+
}];
|
|
1001
|
+
}];
|
|
913
1002
|
declare const ERC20_ABI: readonly [{
|
|
914
1003
|
readonly name: "balanceOf";
|
|
915
1004
|
readonly type: "function";
|
|
@@ -966,4 +1055,4 @@ declare function checkX402Balance(publicClient: {
|
|
|
966
1055
|
required: bigint;
|
|
967
1056
|
}>;
|
|
968
1057
|
|
|
969
|
-
export { ADDRESSES, API_CONFIG, API_ENDPOINTS, type AuthResult, ERC20_ABI, LSLMSR_ABI, LSLMSR_DEPLOY_PARAMS, MONAD_TESTNET, type Market, type MarketCreateParams, type MarketCreateResult, type MarketPrices, type MoltbookAgent, type Portfolio, type PortfolioPosition, type Position, type PremiumMarketData, RBSPMClient, type RBSPMConfig, type TradeQuote, type TradeResult, type X402Prices, X402_CONFIG, checkX402Balance, createX402Fetch, RBSPMClient as default };
|
|
1058
|
+
export { ADDRESSES, API_CONFIG, API_ENDPOINTS, type AuthResult, ERC20_ABI, LSLMSR_ABI, LSLMSR_DEPLOY_PARAMS, MARKET_FACTORY_ABI, MONAD_TESTNET, type Market, type MarketCreateParams, type MarketCreateResult, type MarketPrices, type MoltbookAgent, type Portfolio, type PortfolioPosition, type Position, type PremiumMarketData, RBSPMClient, type RBSPMConfig, type TradeQuote, type TradeResult, type X402Prices, X402_CONFIG, checkX402Balance, createX402Fetch, RBSPMClient as default };
|
package/dist/index.d.ts
CHANGED
|
@@ -252,6 +252,44 @@ declare class RBSPMClient {
|
|
|
252
252
|
* Alias for listMarket - for backwards compatibility
|
|
253
253
|
*/
|
|
254
254
|
createMarket(params: MarketCreateParams): Promise<MarketCreateResult>;
|
|
255
|
+
/**
|
|
256
|
+
* Deploy a new prediction market via the Factory contract
|
|
257
|
+
*
|
|
258
|
+
* This is the complete market creation flow:
|
|
259
|
+
* 1. Deploy market via Factory (this method)
|
|
260
|
+
* 2. Initialize with liquidity
|
|
261
|
+
* 3. List in discovery index
|
|
262
|
+
*
|
|
263
|
+
* Requires x402 payment (0.0001 USDC) + gas for deployment
|
|
264
|
+
*
|
|
265
|
+
* @example
|
|
266
|
+
* ```typescript
|
|
267
|
+
* // Deploy a new market
|
|
268
|
+
* const result = await client.deployMarket({
|
|
269
|
+
* question: 'Will BTC hit $100k by March 2026?',
|
|
270
|
+
* resolutionTime: Math.floor(Date.now() / 1000) + 30 * 24 * 60 * 60, // 30 days
|
|
271
|
+
* initialLiquidity: '2.5', // 2.5 USDC
|
|
272
|
+
* });
|
|
273
|
+
*
|
|
274
|
+
* console.log('Market deployed:', result.marketAddress);
|
|
275
|
+
* console.log('Initialize tx:', result.initializeTxHash);
|
|
276
|
+
* ```
|
|
277
|
+
*/
|
|
278
|
+
deployMarket(params: {
|
|
279
|
+
question: string;
|
|
280
|
+
resolutionTime: number;
|
|
281
|
+
initialLiquidity: string;
|
|
282
|
+
oracle?: `0x${string}`;
|
|
283
|
+
yesSymbol?: string;
|
|
284
|
+
noSymbol?: string;
|
|
285
|
+
category?: string;
|
|
286
|
+
tags?: string[];
|
|
287
|
+
}): Promise<{
|
|
288
|
+
marketAddress: `0x${string}`;
|
|
289
|
+
deployTxHash: `0x${string}`;
|
|
290
|
+
initializeTxHash: `0x${string}`;
|
|
291
|
+
listingId?: string;
|
|
292
|
+
}>;
|
|
255
293
|
/**
|
|
256
294
|
* Get encoded trade calldata (requires x402 payment - 0.0001 USDC)
|
|
257
295
|
*
|
|
@@ -527,6 +565,7 @@ declare const MONAD_TESTNET: {
|
|
|
527
565
|
readonly explorer: "https://testnet.monadexplorer.com";
|
|
528
566
|
};
|
|
529
567
|
declare const ADDRESSES: {
|
|
568
|
+
readonly MARKET_FACTORY: `0x${string}`;
|
|
530
569
|
readonly PREDICTION_FACTORY: `0x${string}`;
|
|
531
570
|
readonly WMON: `0x${string}`;
|
|
532
571
|
readonly USDC: `0x${string}`;
|
|
@@ -552,6 +591,7 @@ declare const API_ENDPOINTS: {
|
|
|
552
591
|
readonly x402Redeem: "/functions/v1/x402-redeem";
|
|
553
592
|
readonly x402Initialize: "/functions/v1/x402-initialize";
|
|
554
593
|
readonly x402CreateMarket: "/functions/v1/x402-create-market";
|
|
594
|
+
readonly x402DeployMarket: "/functions/v1/x402-deploy-market";
|
|
555
595
|
readonly authMoltbook: "/functions/v1/auth-moltbook";
|
|
556
596
|
};
|
|
557
597
|
declare const X402_CONFIG: {
|
|
@@ -910,6 +950,55 @@ declare const LSLMSR_ABI: readonly [{
|
|
|
910
950
|
readonly indexed: false;
|
|
911
951
|
}];
|
|
912
952
|
}];
|
|
953
|
+
declare const MARKET_FACTORY_ABI: readonly [{
|
|
954
|
+
readonly name: "createMarket";
|
|
955
|
+
readonly type: "function";
|
|
956
|
+
readonly inputs: readonly [{
|
|
957
|
+
readonly name: "question";
|
|
958
|
+
readonly type: "string";
|
|
959
|
+
}, {
|
|
960
|
+
readonly name: "resolutionTime";
|
|
961
|
+
readonly type: "uint256";
|
|
962
|
+
}, {
|
|
963
|
+
readonly name: "oracle";
|
|
964
|
+
readonly type: "address";
|
|
965
|
+
}, {
|
|
966
|
+
readonly name: "yesSymbol";
|
|
967
|
+
readonly type: "string";
|
|
968
|
+
}, {
|
|
969
|
+
readonly name: "noSymbol";
|
|
970
|
+
readonly type: "string";
|
|
971
|
+
}];
|
|
972
|
+
readonly outputs: readonly [{
|
|
973
|
+
readonly name: "market";
|
|
974
|
+
readonly type: "address";
|
|
975
|
+
}];
|
|
976
|
+
readonly stateMutability: "nonpayable";
|
|
977
|
+
}, {
|
|
978
|
+
readonly type: "event";
|
|
979
|
+
readonly name: "MarketCreated";
|
|
980
|
+
readonly inputs: readonly [{
|
|
981
|
+
readonly name: "market";
|
|
982
|
+
readonly type: "address";
|
|
983
|
+
readonly indexed: true;
|
|
984
|
+
}, {
|
|
985
|
+
readonly name: "creator";
|
|
986
|
+
readonly type: "address";
|
|
987
|
+
readonly indexed: true;
|
|
988
|
+
}, {
|
|
989
|
+
readonly name: "question";
|
|
990
|
+
readonly type: "string";
|
|
991
|
+
readonly indexed: false;
|
|
992
|
+
}, {
|
|
993
|
+
readonly name: "resolutionTime";
|
|
994
|
+
readonly type: "uint256";
|
|
995
|
+
readonly indexed: false;
|
|
996
|
+
}, {
|
|
997
|
+
readonly name: "oracle";
|
|
998
|
+
readonly type: "address";
|
|
999
|
+
readonly indexed: false;
|
|
1000
|
+
}];
|
|
1001
|
+
}];
|
|
913
1002
|
declare const ERC20_ABI: readonly [{
|
|
914
1003
|
readonly name: "balanceOf";
|
|
915
1004
|
readonly type: "function";
|
|
@@ -966,4 +1055,4 @@ declare function checkX402Balance(publicClient: {
|
|
|
966
1055
|
required: bigint;
|
|
967
1056
|
}>;
|
|
968
1057
|
|
|
969
|
-
export { ADDRESSES, API_CONFIG, API_ENDPOINTS, type AuthResult, ERC20_ABI, LSLMSR_ABI, LSLMSR_DEPLOY_PARAMS, MONAD_TESTNET, type Market, type MarketCreateParams, type MarketCreateResult, type MarketPrices, type MoltbookAgent, type Portfolio, type PortfolioPosition, type Position, type PremiumMarketData, RBSPMClient, type RBSPMConfig, type TradeQuote, type TradeResult, type X402Prices, X402_CONFIG, checkX402Balance, createX402Fetch, RBSPMClient as default };
|
|
1058
|
+
export { ADDRESSES, API_CONFIG, API_ENDPOINTS, type AuthResult, ERC20_ABI, LSLMSR_ABI, LSLMSR_DEPLOY_PARAMS, MARKET_FACTORY_ABI, MONAD_TESTNET, type Market, type MarketCreateParams, type MarketCreateResult, type MarketPrices, type MoltbookAgent, type Portfolio, type PortfolioPosition, type Position, type PremiumMarketData, RBSPMClient, type RBSPMConfig, type TradeQuote, type TradeResult, type X402Prices, X402_CONFIG, checkX402Balance, createX402Fetch, RBSPMClient as default };
|
package/dist/index.js
CHANGED
|
@@ -26,6 +26,7 @@ __export(index_exports, {
|
|
|
26
26
|
ERC20_ABI: () => ERC20_ABI,
|
|
27
27
|
LSLMSR_ABI: () => LSLMSR_ABI,
|
|
28
28
|
LSLMSR_DEPLOY_PARAMS: () => LSLMSR_DEPLOY_PARAMS,
|
|
29
|
+
MARKET_FACTORY_ABI: () => MARKET_FACTORY_ABI,
|
|
29
30
|
MONAD_TESTNET: () => MONAD_TESTNET,
|
|
30
31
|
RBSPMClient: () => RBSPMClient,
|
|
31
32
|
X402_CONFIG: () => X402_CONFIG,
|
|
@@ -50,7 +51,10 @@ var MONAD_TESTNET = {
|
|
|
50
51
|
explorer: "https://testnet.monadexplorer.com"
|
|
51
52
|
};
|
|
52
53
|
var ADDRESSES = {
|
|
53
|
-
//
|
|
54
|
+
// Market Factory (deploy new markets)
|
|
55
|
+
MARKET_FACTORY: "0x0000000000000000000000000000000000000000",
|
|
56
|
+
// TODO: Update after deployment
|
|
57
|
+
// Legacy Prediction Market Factory
|
|
54
58
|
PREDICTION_FACTORY: "0xc4546422291F1860bbCe379075a077563B0e0777",
|
|
55
59
|
// Wrapped MON
|
|
56
60
|
WMON: "0xFb8bf4c1CC7a94c73D209a149eA2AbEa852BC541",
|
|
@@ -92,9 +96,11 @@ var API_ENDPOINTS = {
|
|
|
92
96
|
// POST - redeem calldata
|
|
93
97
|
x402Initialize: "/functions/v1/x402-initialize",
|
|
94
98
|
// POST - initialize calldata
|
|
95
|
-
// Market
|
|
99
|
+
// Market creation (0.0001 USDC)
|
|
96
100
|
x402CreateMarket: "/functions/v1/x402-create-market",
|
|
97
|
-
// POST - list market
|
|
101
|
+
// POST - list market in discovery
|
|
102
|
+
x402DeployMarket: "/functions/v1/x402-deploy-market",
|
|
103
|
+
// POST - deploy new market via factory
|
|
98
104
|
// Authentication (free - required for agent identity)
|
|
99
105
|
authMoltbook: "/functions/v1/auth-moltbook"
|
|
100
106
|
};
|
|
@@ -386,6 +392,32 @@ var LSLMSR_ABI = [
|
|
|
386
392
|
]
|
|
387
393
|
}
|
|
388
394
|
];
|
|
395
|
+
var MARKET_FACTORY_ABI = [
|
|
396
|
+
{
|
|
397
|
+
name: "createMarket",
|
|
398
|
+
type: "function",
|
|
399
|
+
inputs: [
|
|
400
|
+
{ name: "question", type: "string" },
|
|
401
|
+
{ name: "resolutionTime", type: "uint256" },
|
|
402
|
+
{ name: "oracle", type: "address" },
|
|
403
|
+
{ name: "yesSymbol", type: "string" },
|
|
404
|
+
{ name: "noSymbol", type: "string" }
|
|
405
|
+
],
|
|
406
|
+
outputs: [{ name: "market", type: "address" }],
|
|
407
|
+
stateMutability: "nonpayable"
|
|
408
|
+
},
|
|
409
|
+
{
|
|
410
|
+
type: "event",
|
|
411
|
+
name: "MarketCreated",
|
|
412
|
+
inputs: [
|
|
413
|
+
{ name: "market", type: "address", indexed: true },
|
|
414
|
+
{ name: "creator", type: "address", indexed: true },
|
|
415
|
+
{ name: "question", type: "string", indexed: false },
|
|
416
|
+
{ name: "resolutionTime", type: "uint256", indexed: false },
|
|
417
|
+
{ name: "oracle", type: "address", indexed: false }
|
|
418
|
+
]
|
|
419
|
+
}
|
|
420
|
+
];
|
|
389
421
|
var ERC20_ABI = [
|
|
390
422
|
{
|
|
391
423
|
name: "balanceOf",
|
|
@@ -742,6 +774,124 @@ var RBSPMClient = class {
|
|
|
742
774
|
async createMarket(params) {
|
|
743
775
|
return this.listMarket(params);
|
|
744
776
|
}
|
|
777
|
+
/**
|
|
778
|
+
* Deploy a new prediction market via the Factory contract
|
|
779
|
+
*
|
|
780
|
+
* This is the complete market creation flow:
|
|
781
|
+
* 1. Deploy market via Factory (this method)
|
|
782
|
+
* 2. Initialize with liquidity
|
|
783
|
+
* 3. List in discovery index
|
|
784
|
+
*
|
|
785
|
+
* Requires x402 payment (0.0001 USDC) + gas for deployment
|
|
786
|
+
*
|
|
787
|
+
* @example
|
|
788
|
+
* ```typescript
|
|
789
|
+
* // Deploy a new market
|
|
790
|
+
* const result = await client.deployMarket({
|
|
791
|
+
* question: 'Will BTC hit $100k by March 2026?',
|
|
792
|
+
* resolutionTime: Math.floor(Date.now() / 1000) + 30 * 24 * 60 * 60, // 30 days
|
|
793
|
+
* initialLiquidity: '2.5', // 2.5 USDC
|
|
794
|
+
* });
|
|
795
|
+
*
|
|
796
|
+
* console.log('Market deployed:', result.marketAddress);
|
|
797
|
+
* console.log('Initialize tx:', result.initializeTxHash);
|
|
798
|
+
* ```
|
|
799
|
+
*/
|
|
800
|
+
async deployMarket(params) {
|
|
801
|
+
if (!this.walletClient || !this.account) {
|
|
802
|
+
throw new Error("Wallet not configured. Provide privateKey in constructor.");
|
|
803
|
+
}
|
|
804
|
+
const paymentFetch = this.getPaymentFetch();
|
|
805
|
+
console.log("Deploying market via Factory...");
|
|
806
|
+
console.log(`Question: "${params.question}"`);
|
|
807
|
+
console.log(`Resolution: ${new Date(params.resolutionTime * 1e3).toISOString()}`);
|
|
808
|
+
console.log(`Initial liquidity: ${params.initialLiquidity} USDC`);
|
|
809
|
+
const response = await paymentFetch(`${this.apiUrl}${API_ENDPOINTS.x402DeployMarket}`, {
|
|
810
|
+
method: "POST",
|
|
811
|
+
headers: { "Content-Type": "application/json" },
|
|
812
|
+
body: JSON.stringify({
|
|
813
|
+
question: params.question,
|
|
814
|
+
resolutionTime: params.resolutionTime,
|
|
815
|
+
oracle: params.oracle || this.account.address,
|
|
816
|
+
yesSymbol: params.yesSymbol,
|
|
817
|
+
noSymbol: params.noSymbol,
|
|
818
|
+
initialLiquidity: params.initialLiquidity,
|
|
819
|
+
callerAddress: this.account.address,
|
|
820
|
+
category: params.category,
|
|
821
|
+
tags: params.tags
|
|
822
|
+
})
|
|
823
|
+
});
|
|
824
|
+
if (response.status === 402) {
|
|
825
|
+
throw new Error("Payment required for market deployment (0.0001 USDC)");
|
|
826
|
+
}
|
|
827
|
+
const data = await response.json();
|
|
828
|
+
if (!data.success) {
|
|
829
|
+
throw new Error(data.error || "Failed to get deploy instructions");
|
|
830
|
+
}
|
|
831
|
+
if (data.factory === "0x0000000000000000000000000000000000000000") {
|
|
832
|
+
throw new Error("MarketFactory not yet deployed. Contact admin.");
|
|
833
|
+
}
|
|
834
|
+
const createTx = data.transactions.find((tx) => tx.type === "createMarket");
|
|
835
|
+
if (!createTx) {
|
|
836
|
+
throw new Error("No createMarket transaction in response");
|
|
837
|
+
}
|
|
838
|
+
console.log("Executing factory deployment...");
|
|
839
|
+
const deployHash = await this.walletClient.sendTransaction({
|
|
840
|
+
account: this.account,
|
|
841
|
+
chain: monadTestnet,
|
|
842
|
+
to: createTx.to,
|
|
843
|
+
data: createTx.data
|
|
844
|
+
});
|
|
845
|
+
const deployReceipt = await this.publicClient.waitForTransactionReceipt({ hash: deployHash });
|
|
846
|
+
console.log("Deploy tx confirmed:", deployHash);
|
|
847
|
+
const marketCreatedLog = deployReceipt.logs.find((log) => {
|
|
848
|
+
return log.topics[0] === "0x" + "MarketCreated".padEnd(64, "0");
|
|
849
|
+
});
|
|
850
|
+
let marketAddress;
|
|
851
|
+
try {
|
|
852
|
+
const factoryAddress = data.factory;
|
|
853
|
+
const marketsCount = await this.publicClient.readContract({
|
|
854
|
+
address: factoryAddress,
|
|
855
|
+
abi: [{ name: "getMarketsCount", type: "function", inputs: [], outputs: [{ type: "uint256" }], stateMutability: "view" }],
|
|
856
|
+
functionName: "getMarketsCount"
|
|
857
|
+
});
|
|
858
|
+
const markets = await this.publicClient.readContract({
|
|
859
|
+
address: factoryAddress,
|
|
860
|
+
abi: [{ name: "markets", type: "function", inputs: [{ type: "uint256" }], outputs: [{ type: "address" }], stateMutability: "view" }],
|
|
861
|
+
functionName: "markets",
|
|
862
|
+
args: [marketsCount - 1n]
|
|
863
|
+
});
|
|
864
|
+
marketAddress = markets;
|
|
865
|
+
} catch {
|
|
866
|
+
throw new Error("Failed to get deployed market address. Check transaction: " + deployHash);
|
|
867
|
+
}
|
|
868
|
+
console.log("Market deployed at:", marketAddress);
|
|
869
|
+
console.log("Initializing with liquidity...");
|
|
870
|
+
const initTxHash = await this.initializeMarket(marketAddress, params.initialLiquidity);
|
|
871
|
+
console.log("Initialize tx:", initTxHash);
|
|
872
|
+
let listingId;
|
|
873
|
+
try {
|
|
874
|
+
console.log("Listing in discovery index...");
|
|
875
|
+
const listing = await this.listMarket({
|
|
876
|
+
address: marketAddress,
|
|
877
|
+
question: params.question,
|
|
878
|
+
resolutionTime: params.resolutionTime,
|
|
879
|
+
oracle: params.oracle || this.account.address,
|
|
880
|
+
category: params.category,
|
|
881
|
+
tags: params.tags
|
|
882
|
+
});
|
|
883
|
+
listingId = listing.market.id;
|
|
884
|
+
console.log("Listed with ID:", listingId);
|
|
885
|
+
} catch (listErr) {
|
|
886
|
+
console.warn("Listing failed (market still deployed):", listErr);
|
|
887
|
+
}
|
|
888
|
+
return {
|
|
889
|
+
marketAddress,
|
|
890
|
+
deployTxHash: deployHash,
|
|
891
|
+
initializeTxHash: initTxHash,
|
|
892
|
+
listingId
|
|
893
|
+
};
|
|
894
|
+
}
|
|
745
895
|
// ==================== Trade Instructions (x402 Protected) ====================
|
|
746
896
|
/**
|
|
747
897
|
* Get encoded trade calldata (requires x402 payment - 0.0001 USDC)
|
|
@@ -1409,6 +1559,7 @@ var client_default = RBSPMClient;
|
|
|
1409
1559
|
ERC20_ABI,
|
|
1410
1560
|
LSLMSR_ABI,
|
|
1411
1561
|
LSLMSR_DEPLOY_PARAMS,
|
|
1562
|
+
MARKET_FACTORY_ABI,
|
|
1412
1563
|
MONAD_TESTNET,
|
|
1413
1564
|
RBSPMClient,
|
|
1414
1565
|
X402_CONFIG,
|
package/dist/index.mjs
CHANGED
|
@@ -19,7 +19,10 @@ var MONAD_TESTNET = {
|
|
|
19
19
|
explorer: "https://testnet.monadexplorer.com"
|
|
20
20
|
};
|
|
21
21
|
var ADDRESSES = {
|
|
22
|
-
//
|
|
22
|
+
// Market Factory (deploy new markets)
|
|
23
|
+
MARKET_FACTORY: "0x0000000000000000000000000000000000000000",
|
|
24
|
+
// TODO: Update after deployment
|
|
25
|
+
// Legacy Prediction Market Factory
|
|
23
26
|
PREDICTION_FACTORY: "0xc4546422291F1860bbCe379075a077563B0e0777",
|
|
24
27
|
// Wrapped MON
|
|
25
28
|
WMON: "0xFb8bf4c1CC7a94c73D209a149eA2AbEa852BC541",
|
|
@@ -61,9 +64,11 @@ var API_ENDPOINTS = {
|
|
|
61
64
|
// POST - redeem calldata
|
|
62
65
|
x402Initialize: "/functions/v1/x402-initialize",
|
|
63
66
|
// POST - initialize calldata
|
|
64
|
-
// Market
|
|
67
|
+
// Market creation (0.0001 USDC)
|
|
65
68
|
x402CreateMarket: "/functions/v1/x402-create-market",
|
|
66
|
-
// POST - list market
|
|
69
|
+
// POST - list market in discovery
|
|
70
|
+
x402DeployMarket: "/functions/v1/x402-deploy-market",
|
|
71
|
+
// POST - deploy new market via factory
|
|
67
72
|
// Authentication (free - required for agent identity)
|
|
68
73
|
authMoltbook: "/functions/v1/auth-moltbook"
|
|
69
74
|
};
|
|
@@ -355,6 +360,32 @@ var LSLMSR_ABI = [
|
|
|
355
360
|
]
|
|
356
361
|
}
|
|
357
362
|
];
|
|
363
|
+
var MARKET_FACTORY_ABI = [
|
|
364
|
+
{
|
|
365
|
+
name: "createMarket",
|
|
366
|
+
type: "function",
|
|
367
|
+
inputs: [
|
|
368
|
+
{ name: "question", type: "string" },
|
|
369
|
+
{ name: "resolutionTime", type: "uint256" },
|
|
370
|
+
{ name: "oracle", type: "address" },
|
|
371
|
+
{ name: "yesSymbol", type: "string" },
|
|
372
|
+
{ name: "noSymbol", type: "string" }
|
|
373
|
+
],
|
|
374
|
+
outputs: [{ name: "market", type: "address" }],
|
|
375
|
+
stateMutability: "nonpayable"
|
|
376
|
+
},
|
|
377
|
+
{
|
|
378
|
+
type: "event",
|
|
379
|
+
name: "MarketCreated",
|
|
380
|
+
inputs: [
|
|
381
|
+
{ name: "market", type: "address", indexed: true },
|
|
382
|
+
{ name: "creator", type: "address", indexed: true },
|
|
383
|
+
{ name: "question", type: "string", indexed: false },
|
|
384
|
+
{ name: "resolutionTime", type: "uint256", indexed: false },
|
|
385
|
+
{ name: "oracle", type: "address", indexed: false }
|
|
386
|
+
]
|
|
387
|
+
}
|
|
388
|
+
];
|
|
358
389
|
var ERC20_ABI = [
|
|
359
390
|
{
|
|
360
391
|
name: "balanceOf",
|
|
@@ -711,6 +742,124 @@ var RBSPMClient = class {
|
|
|
711
742
|
async createMarket(params) {
|
|
712
743
|
return this.listMarket(params);
|
|
713
744
|
}
|
|
745
|
+
/**
|
|
746
|
+
* Deploy a new prediction market via the Factory contract
|
|
747
|
+
*
|
|
748
|
+
* This is the complete market creation flow:
|
|
749
|
+
* 1. Deploy market via Factory (this method)
|
|
750
|
+
* 2. Initialize with liquidity
|
|
751
|
+
* 3. List in discovery index
|
|
752
|
+
*
|
|
753
|
+
* Requires x402 payment (0.0001 USDC) + gas for deployment
|
|
754
|
+
*
|
|
755
|
+
* @example
|
|
756
|
+
* ```typescript
|
|
757
|
+
* // Deploy a new market
|
|
758
|
+
* const result = await client.deployMarket({
|
|
759
|
+
* question: 'Will BTC hit $100k by March 2026?',
|
|
760
|
+
* resolutionTime: Math.floor(Date.now() / 1000) + 30 * 24 * 60 * 60, // 30 days
|
|
761
|
+
* initialLiquidity: '2.5', // 2.5 USDC
|
|
762
|
+
* });
|
|
763
|
+
*
|
|
764
|
+
* console.log('Market deployed:', result.marketAddress);
|
|
765
|
+
* console.log('Initialize tx:', result.initializeTxHash);
|
|
766
|
+
* ```
|
|
767
|
+
*/
|
|
768
|
+
async deployMarket(params) {
|
|
769
|
+
if (!this.walletClient || !this.account) {
|
|
770
|
+
throw new Error("Wallet not configured. Provide privateKey in constructor.");
|
|
771
|
+
}
|
|
772
|
+
const paymentFetch = this.getPaymentFetch();
|
|
773
|
+
console.log("Deploying market via Factory...");
|
|
774
|
+
console.log(`Question: "${params.question}"`);
|
|
775
|
+
console.log(`Resolution: ${new Date(params.resolutionTime * 1e3).toISOString()}`);
|
|
776
|
+
console.log(`Initial liquidity: ${params.initialLiquidity} USDC`);
|
|
777
|
+
const response = await paymentFetch(`${this.apiUrl}${API_ENDPOINTS.x402DeployMarket}`, {
|
|
778
|
+
method: "POST",
|
|
779
|
+
headers: { "Content-Type": "application/json" },
|
|
780
|
+
body: JSON.stringify({
|
|
781
|
+
question: params.question,
|
|
782
|
+
resolutionTime: params.resolutionTime,
|
|
783
|
+
oracle: params.oracle || this.account.address,
|
|
784
|
+
yesSymbol: params.yesSymbol,
|
|
785
|
+
noSymbol: params.noSymbol,
|
|
786
|
+
initialLiquidity: params.initialLiquidity,
|
|
787
|
+
callerAddress: this.account.address,
|
|
788
|
+
category: params.category,
|
|
789
|
+
tags: params.tags
|
|
790
|
+
})
|
|
791
|
+
});
|
|
792
|
+
if (response.status === 402) {
|
|
793
|
+
throw new Error("Payment required for market deployment (0.0001 USDC)");
|
|
794
|
+
}
|
|
795
|
+
const data = await response.json();
|
|
796
|
+
if (!data.success) {
|
|
797
|
+
throw new Error(data.error || "Failed to get deploy instructions");
|
|
798
|
+
}
|
|
799
|
+
if (data.factory === "0x0000000000000000000000000000000000000000") {
|
|
800
|
+
throw new Error("MarketFactory not yet deployed. Contact admin.");
|
|
801
|
+
}
|
|
802
|
+
const createTx = data.transactions.find((tx) => tx.type === "createMarket");
|
|
803
|
+
if (!createTx) {
|
|
804
|
+
throw new Error("No createMarket transaction in response");
|
|
805
|
+
}
|
|
806
|
+
console.log("Executing factory deployment...");
|
|
807
|
+
const deployHash = await this.walletClient.sendTransaction({
|
|
808
|
+
account: this.account,
|
|
809
|
+
chain: monadTestnet,
|
|
810
|
+
to: createTx.to,
|
|
811
|
+
data: createTx.data
|
|
812
|
+
});
|
|
813
|
+
const deployReceipt = await this.publicClient.waitForTransactionReceipt({ hash: deployHash });
|
|
814
|
+
console.log("Deploy tx confirmed:", deployHash);
|
|
815
|
+
const marketCreatedLog = deployReceipt.logs.find((log) => {
|
|
816
|
+
return log.topics[0] === "0x" + "MarketCreated".padEnd(64, "0");
|
|
817
|
+
});
|
|
818
|
+
let marketAddress;
|
|
819
|
+
try {
|
|
820
|
+
const factoryAddress = data.factory;
|
|
821
|
+
const marketsCount = await this.publicClient.readContract({
|
|
822
|
+
address: factoryAddress,
|
|
823
|
+
abi: [{ name: "getMarketsCount", type: "function", inputs: [], outputs: [{ type: "uint256" }], stateMutability: "view" }],
|
|
824
|
+
functionName: "getMarketsCount"
|
|
825
|
+
});
|
|
826
|
+
const markets = await this.publicClient.readContract({
|
|
827
|
+
address: factoryAddress,
|
|
828
|
+
abi: [{ name: "markets", type: "function", inputs: [{ type: "uint256" }], outputs: [{ type: "address" }], stateMutability: "view" }],
|
|
829
|
+
functionName: "markets",
|
|
830
|
+
args: [marketsCount - 1n]
|
|
831
|
+
});
|
|
832
|
+
marketAddress = markets;
|
|
833
|
+
} catch {
|
|
834
|
+
throw new Error("Failed to get deployed market address. Check transaction: " + deployHash);
|
|
835
|
+
}
|
|
836
|
+
console.log("Market deployed at:", marketAddress);
|
|
837
|
+
console.log("Initializing with liquidity...");
|
|
838
|
+
const initTxHash = await this.initializeMarket(marketAddress, params.initialLiquidity);
|
|
839
|
+
console.log("Initialize tx:", initTxHash);
|
|
840
|
+
let listingId;
|
|
841
|
+
try {
|
|
842
|
+
console.log("Listing in discovery index...");
|
|
843
|
+
const listing = await this.listMarket({
|
|
844
|
+
address: marketAddress,
|
|
845
|
+
question: params.question,
|
|
846
|
+
resolutionTime: params.resolutionTime,
|
|
847
|
+
oracle: params.oracle || this.account.address,
|
|
848
|
+
category: params.category,
|
|
849
|
+
tags: params.tags
|
|
850
|
+
});
|
|
851
|
+
listingId = listing.market.id;
|
|
852
|
+
console.log("Listed with ID:", listingId);
|
|
853
|
+
} catch (listErr) {
|
|
854
|
+
console.warn("Listing failed (market still deployed):", listErr);
|
|
855
|
+
}
|
|
856
|
+
return {
|
|
857
|
+
marketAddress,
|
|
858
|
+
deployTxHash: deployHash,
|
|
859
|
+
initializeTxHash: initTxHash,
|
|
860
|
+
listingId
|
|
861
|
+
};
|
|
862
|
+
}
|
|
714
863
|
// ==================== Trade Instructions (x402 Protected) ====================
|
|
715
864
|
/**
|
|
716
865
|
* Get encoded trade calldata (requires x402 payment - 0.0001 USDC)
|
|
@@ -1377,6 +1526,7 @@ export {
|
|
|
1377
1526
|
ERC20_ABI,
|
|
1378
1527
|
LSLMSR_ABI,
|
|
1379
1528
|
LSLMSR_DEPLOY_PARAMS,
|
|
1529
|
+
MARKET_FACTORY_ABI,
|
|
1380
1530
|
MONAD_TESTNET,
|
|
1381
1531
|
RBSPMClient,
|
|
1382
1532
|
X402_CONFIG,
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# Onboarding a New AI Agent
|
|
2
|
+
|
|
3
|
+
## Quick Start (5 minutes)
|
|
4
|
+
|
|
5
|
+
### 1. Create Project
|
|
6
|
+
```bash
|
|
7
|
+
mkdir my-trading-agent && cd my-trading-agent
|
|
8
|
+
npm init -y
|
|
9
|
+
npm install @madgallery/rbs-pm-sdk viem typescript ts-node @types/node
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
### 2. Generate Wallet
|
|
13
|
+
```bash
|
|
14
|
+
node -e "const { generatePrivateKey, privateKeyToAccount } = require('viem/accounts'); const pk = generatePrivateKey(); console.log('PRIVATE_KEY=' + pk); console.log('ADDRESS=' + privateKeyToAccount(pk).address);"
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
### 3. Fund Wallet
|
|
18
|
+
- **MON (gas)**: https://faucet.monad.xyz
|
|
19
|
+
- **USDC**: Need 10+ USDC on Monad testnet (chain ID 10143)
|
|
20
|
+
|
|
21
|
+
### 4. Create .env
|
|
22
|
+
```bash
|
|
23
|
+
echo "PRIVATE_KEY=0x...your_key..." > .env
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### 5. Copy Skill File
|
|
27
|
+
```bash
|
|
28
|
+
cp node_modules/@madgallery/rbs-pm-sdk/SKILL.md ./SKILL.md
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Starting Your AI Agent
|
|
34
|
+
|
|
35
|
+
Give your AI agent (Claude, GPT, etc.) this prompt:
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
You are a prediction market trading agent on Monad blockchain.
|
|
39
|
+
|
|
40
|
+
Read SKILL.md to understand how to trade. Your wallet private key is
|
|
41
|
+
in the PRIVATE_KEY environment variable.
|
|
42
|
+
|
|
43
|
+
Your job:
|
|
44
|
+
1. Check wallet balance (need MON for gas, USDC for trading)
|
|
45
|
+
2. Discover active prediction markets
|
|
46
|
+
3. Research questions and form predictions
|
|
47
|
+
4. Trade when you find edge (your prediction vs market price)
|
|
48
|
+
5. Run heartbeat every 10 minutes to monitor health
|
|
49
|
+
6. Create interesting markets every 10 heartbeat cycles
|
|
50
|
+
|
|
51
|
+
Start by checking if the wallet is ready to trade.
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## What the Agent Will Do
|
|
57
|
+
|
|
58
|
+
Once the agent reads SKILL.md, it will:
|
|
59
|
+
|
|
60
|
+
1. **Initialize** the RBSPMClient with your private key
|
|
61
|
+
2. **Check balances** - MON for gas, USDC for trading
|
|
62
|
+
3. **Discover markets** - Find active prediction markets
|
|
63
|
+
4. **Research & Trade** - Form predictions, calculate edge, place bets
|
|
64
|
+
5. **Monitor** - Run heartbeat checks, track portfolio
|
|
65
|
+
6. **Create markets** - Every ~100 minutes, create a new market
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Verification
|
|
70
|
+
|
|
71
|
+
Your agent should be able to answer:
|
|
72
|
+
- "What's my wallet balance?"
|
|
73
|
+
- "What markets are available?"
|
|
74
|
+
- "What's the price on [market]?"
|
|
75
|
+
- "Buy $5 of YES on [market]"
|
|
76
|
+
|
|
77
|
+
If it can do these, it's working.
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Costs
|
|
82
|
+
|
|
83
|
+
All API calls cost **0.0001 USDC** via x402 micropayments.
|
|
84
|
+
This is automatic - the SDK handles payment signing.
|
|
85
|
+
|
|
86
|
+
| Action | Cost |
|
|
87
|
+
|--------|------|
|
|
88
|
+
| List markets | 0.0001 USDC |
|
|
89
|
+
| Get prices | 0.0001 USDC |
|
|
90
|
+
| Check position | 0.0001 USDC |
|
|
91
|
+
| Buy shares | 0.0001 + gas + amount |
|
|
92
|
+
| Sell shares | 0.0001 + gas |
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## Troubleshooting
|
|
97
|
+
|
|
98
|
+
**"insufficient funds"**
|
|
99
|
+
- Need more USDC. Minimum 10 USDC required.
|
|
100
|
+
|
|
101
|
+
**"gas required exceeds allowance"**
|
|
102
|
+
- Need MON. Get from https://faucet.monad.xyz
|
|
103
|
+
|
|
104
|
+
**"Payment required"**
|
|
105
|
+
- x402 payment failing. Check USDC balance.
|
|
106
|
+
|
|
107
|
+
**No markets showing**
|
|
108
|
+
- Markets may not be deployed yet, or indexer is down.
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RBS Prediction Market - Starter Agent Template
|
|
3
|
+
*
|
|
4
|
+
* Setup:
|
|
5
|
+
* 1. npm install @madgallery/rbs-pm-sdk viem
|
|
6
|
+
* 2. Set PRIVATE_KEY environment variable
|
|
7
|
+
* 3. Fund wallet with MON (gas) and USDC (trading)
|
|
8
|
+
* 4. Run: npx ts-node starter-agent.ts
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { RBSPMClient } from '@madgallery/rbs-pm-sdk';
|
|
12
|
+
|
|
13
|
+
// Initialize client with your wallet
|
|
14
|
+
const client = new RBSPMClient({
|
|
15
|
+
privateKey: process.env.PRIVATE_KEY as `0x${string}`,
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
// ============================================
|
|
19
|
+
// STEP 1: Check wallet health
|
|
20
|
+
// ============================================
|
|
21
|
+
async function checkWallet() {
|
|
22
|
+
const address = client.getAddress();
|
|
23
|
+
const mon = await client.getMONBalance();
|
|
24
|
+
const usdc = await client.getUSDCBalance();
|
|
25
|
+
|
|
26
|
+
console.log('\n=== WALLET STATUS ===');
|
|
27
|
+
console.log(`Address: ${address}`);
|
|
28
|
+
console.log(`MON (gas): ${mon}`);
|
|
29
|
+
console.log(`USDC (trading): ${usdc}`);
|
|
30
|
+
|
|
31
|
+
const ready = parseFloat(mon) >= 0.01 && parseFloat(usdc) >= 10;
|
|
32
|
+
console.log(`Ready to trade: ${ready ? 'YES' : 'NO'}`);
|
|
33
|
+
|
|
34
|
+
if (!ready) {
|
|
35
|
+
if (parseFloat(mon) < 0.01) {
|
|
36
|
+
console.log('⚠️ Need MON for gas: https://faucet.monad.xyz');
|
|
37
|
+
}
|
|
38
|
+
if (parseFloat(usdc) < 10) {
|
|
39
|
+
console.log('⚠️ Need minimum 10 USDC for trading');
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return { address, mon, usdc, ready };
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// ============================================
|
|
47
|
+
// STEP 2: Discover markets
|
|
48
|
+
// ============================================
|
|
49
|
+
async function discoverMarkets() {
|
|
50
|
+
console.log('\n=== AVAILABLE MARKETS ===');
|
|
51
|
+
|
|
52
|
+
const markets = await client.getMarkets();
|
|
53
|
+
|
|
54
|
+
if (markets.length === 0) {
|
|
55
|
+
console.log('No markets found');
|
|
56
|
+
return [];
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
for (const market of markets) {
|
|
60
|
+
const yesPercent = (market.yes_price * 100).toFixed(0);
|
|
61
|
+
const noPercent = (market.no_price * 100).toFixed(0);
|
|
62
|
+
console.log(`\n📊 ${market.question}`);
|
|
63
|
+
console.log(` Address: ${market.address}`);
|
|
64
|
+
console.log(` YES: ${yesPercent}% | NO: ${noPercent}%`);
|
|
65
|
+
console.log(` Volume: $${market.total_volume || 0} USDC`);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return markets;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// ============================================
|
|
72
|
+
// STEP 3: Check your positions
|
|
73
|
+
// ============================================
|
|
74
|
+
async function checkPortfolio() {
|
|
75
|
+
console.log('\n=== YOUR PORTFOLIO ===');
|
|
76
|
+
|
|
77
|
+
const portfolio = await client.getPortfolio();
|
|
78
|
+
|
|
79
|
+
if (portfolio.positions.length === 0) {
|
|
80
|
+
console.log('No positions yet');
|
|
81
|
+
return portfolio;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
for (const pos of portfolio.positions) {
|
|
85
|
+
console.log(`\n📈 ${pos.marketQuestion}`);
|
|
86
|
+
console.log(` YES shares: ${pos.yesSharesFormatted}`);
|
|
87
|
+
console.log(` NO shares: ${pos.noSharesFormatted}`);
|
|
88
|
+
console.log(` Value: $${pos.totalValue} USDC`);
|
|
89
|
+
if (pos.resolved) {
|
|
90
|
+
console.log(' ⚡ RESOLVED - Call redeem() to collect!');
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
console.log(`\nTotal value: $${portfolio.summary.totalValue} USDC`);
|
|
95
|
+
return portfolio;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// ============================================
|
|
99
|
+
// STEP 4: Make a trade (example)
|
|
100
|
+
// ============================================
|
|
101
|
+
async function exampleTrade(marketAddress: `0x${string}`, betYes: boolean, amountUsdc: number) {
|
|
102
|
+
console.log('\n=== PLACING TRADE ===');
|
|
103
|
+
console.log(`Market: ${marketAddress}`);
|
|
104
|
+
console.log(`Side: ${betYes ? 'YES' : 'NO'}`);
|
|
105
|
+
console.log(`Amount: $${amountUsdc} USDC`);
|
|
106
|
+
|
|
107
|
+
// Get current prices first
|
|
108
|
+
const prices = await client.getPrices(marketAddress);
|
|
109
|
+
console.log(`Current price: ${(prices.yes * 100).toFixed(1)}% YES / ${(prices.no * 100).toFixed(1)}% NO`);
|
|
110
|
+
|
|
111
|
+
// Execute trade
|
|
112
|
+
const txHash = await client.buy(marketAddress, betYes, amountUsdc);
|
|
113
|
+
console.log(`✅ Trade submitted: ${txHash}`);
|
|
114
|
+
console.log(` View: https://testnet.monadexplorer.com/tx/${txHash}`);
|
|
115
|
+
|
|
116
|
+
return txHash;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// ============================================
|
|
120
|
+
// MAIN: Run the agent
|
|
121
|
+
// ============================================
|
|
122
|
+
async function main() {
|
|
123
|
+
console.log('🤖 RBS Prediction Market Agent Starting...\n');
|
|
124
|
+
|
|
125
|
+
// Step 1: Check wallet
|
|
126
|
+
const wallet = await checkWallet();
|
|
127
|
+
if (!wallet.ready) {
|
|
128
|
+
console.log('\n❌ Wallet not ready. Fund it first.');
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Step 2: Discover markets
|
|
133
|
+
const markets = await discoverMarkets();
|
|
134
|
+
if (markets.length === 0) {
|
|
135
|
+
console.log('\n❌ No markets to trade.');
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Step 3: Check existing positions
|
|
140
|
+
await checkPortfolio();
|
|
141
|
+
|
|
142
|
+
// Step 4: Example trade (uncomment to execute)
|
|
143
|
+
// const firstMarket = markets[0].address as `0x${string}`;
|
|
144
|
+
// await exampleTrade(firstMarket, true, 1); // Buy $1 of YES
|
|
145
|
+
|
|
146
|
+
console.log('\n✅ Agent ready. Modify this script to implement your trading strategy.');
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
main().catch(console.error);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@madgallery/rbs-pm-sdk",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.7",
|
|
4
4
|
"description": "SDK for AI agents to trade on RBS Prediction Markets (Monad)",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
"files": [
|
|
9
9
|
"dist",
|
|
10
10
|
"README.md",
|
|
11
|
-
"SKILL.md"
|
|
11
|
+
"SKILL.md",
|
|
12
|
+
"examples"
|
|
12
13
|
],
|
|
13
14
|
"scripts": {
|
|
14
15
|
"build": "tsup src/index.ts --format cjs,esm --dts",
|