pnpfucius 2.0.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,291 @@
1
+ // PNPFUCIUS - The PNP Exchange CLI
2
+ // No external LLM required - uses PNP's built-in oracle
3
+
4
+ import * as readline from 'readline';
5
+ import chalk from 'chalk';
6
+ import { executeTool } from './tools/index.js';
7
+ import { printWelcome, printError, printHelp, printGoodbye } from './ui/welcome.js';
8
+ import { handleSlashCommand } from './slash-commands.js';
9
+ import { getConfig } from '../config.js';
10
+
11
+ // Purple color definitions
12
+ const purple = chalk.hex('#A855F7');
13
+ const purpleBright = chalk.hex('#C084FC');
14
+ const purpleDim = chalk.hex('#7C3AED');
15
+ const violet = chalk.hex('#8B5CF6');
16
+
17
+ export class PnpfuciusAgent {
18
+ constructor(options = {}) {
19
+ this.config = getConfig();
20
+ this.verbose = options.verbose ?? false;
21
+ }
22
+
23
+ /**
24
+ * Main entry point - run the interactive CLI
25
+ */
26
+ async run() {
27
+ printWelcome();
28
+
29
+ console.log(chalk.dim(' Type ') + purple('/help') + chalk.dim(' for commands or enter a command directly.'));
30
+ console.log();
31
+
32
+ const rl = readline.createInterface({
33
+ input: process.stdin,
34
+ output: process.stdout
35
+ });
36
+
37
+ // Handle Ctrl+C gracefully
38
+ rl.on('SIGINT', () => {
39
+ printGoodbye();
40
+ process.exit(0);
41
+ });
42
+
43
+ while (true) {
44
+ try {
45
+ const userInput = await this.prompt(rl);
46
+
47
+ if (!userInput.trim()) {
48
+ continue;
49
+ }
50
+
51
+ // Handle slash commands
52
+ const result = await handleSlashCommand(userInput, {
53
+ agent: this,
54
+ executeTool: this.executeTool.bind(this)
55
+ });
56
+
57
+ if (result === true) {
58
+ // Command was handled
59
+ continue;
60
+ } else if (result === false) {
61
+ // Not a slash command - show help
62
+ console.log(purpleDim('\n ◆ Unknown command. Type /help for available commands.\n'));
63
+ }
64
+
65
+ } catch (error) {
66
+ if (error.code === 'ERR_USE_AFTER_CLOSE') {
67
+ break;
68
+ }
69
+ printError(error.message);
70
+ if (this.verbose) {
71
+ console.error(error);
72
+ }
73
+ }
74
+ }
75
+ }
76
+
77
+ /**
78
+ * Prompt user for input
79
+ */
80
+ async prompt(rl) {
81
+ return new Promise((resolve) => {
82
+ rl.question(purple('\n❯ '), (answer) => {
83
+ resolve(answer);
84
+ });
85
+ });
86
+ }
87
+
88
+ /**
89
+ * Execute a tool and display results
90
+ */
91
+ async executeTool(toolName, input) {
92
+ console.log(purpleDim(`\n ◆ ${toolName}`));
93
+
94
+ try {
95
+ const result = await executeTool(toolName, input);
96
+
97
+ if (result.error) {
98
+ console.log(chalk.red(` ✗ ${result.error}`));
99
+ } else {
100
+ console.log(purple(` ✓ Done`));
101
+ this.displayResult(toolName, result);
102
+ }
103
+
104
+ return result;
105
+ } catch (error) {
106
+ console.log(chalk.red(` ✗ ${error.message}`));
107
+ throw error;
108
+ }
109
+ }
110
+
111
+ /**
112
+ * Display tool result in a nice format
113
+ */
114
+ displayResult(toolName, result) {
115
+ console.log();
116
+
117
+ switch (toolName) {
118
+ case 'discover_all_markets':
119
+ this.displayMarketDiscovery(result);
120
+ break;
121
+ case 'get_market_info':
122
+ case 'get_v2_market_info':
123
+ case 'get_p2p_market_info':
124
+ this.displayMarketInfo(result);
125
+ break;
126
+ case 'get_market_prices':
127
+ this.displayPrices(result);
128
+ break;
129
+ case 'get_balances':
130
+ this.displayBalances(result);
131
+ break;
132
+ case 'create_market':
133
+ case 'create_p2p_market_simple':
134
+ case 'create_amm_market_with_odds':
135
+ this.displayMarketCreation(result);
136
+ break;
137
+ case 'buy_tokens':
138
+ case 'sell_tokens':
139
+ case 'buy_v3_tokens':
140
+ this.displayTrade(result);
141
+ break;
142
+ case 'get_settlement_criteria':
143
+ this.displaySettlementCriteria(result);
144
+ break;
145
+ case 'get_settlement_data':
146
+ this.displaySettlementData(result);
147
+ break;
148
+ case 'redeem_position':
149
+ case 'redeem_v3_position':
150
+ case 'redeem_p2p_position':
151
+ this.displayRedemption(result);
152
+ break;
153
+ case 'get_pnp_config':
154
+ this.displayPnpConfig(result);
155
+ break;
156
+ default:
157
+ // Generic JSON display
158
+ console.log(chalk.dim(JSON.stringify(result, null, 2)));
159
+ }
160
+ }
161
+
162
+ displayMarketDiscovery(result) {
163
+ const v2Count = result.v2_markets?.length || 0;
164
+ const v3Count = result.v3_markets?.length || 0;
165
+
166
+ console.log(purpleBright(` Found ${result.total || v2Count + v3Count} markets on PNP Exchange\n`));
167
+
168
+ if (v2Count > 0) {
169
+ console.log(violet(' V2 Markets (AMM)'));
170
+ for (const addr of result.v2_markets.slice(0, 5)) {
171
+ console.log(` ${purple('◆')} ${chalk.dim(addr)}`);
172
+ }
173
+ if (v2Count > 5) console.log(chalk.dim(` ... and ${v2Count - 5} more`));
174
+ console.log();
175
+ }
176
+
177
+ if (v3Count > 0) {
178
+ console.log(violet(' V3 Markets (P2P)'));
179
+ for (const addr of result.v3_markets.slice(0, 5)) {
180
+ console.log(` ${purple('◆')} ${chalk.dim(addr)}`);
181
+ }
182
+ if (v3Count > 5) console.log(chalk.dim(` ... and ${v3Count - 5} more`));
183
+ console.log();
184
+ }
185
+
186
+ console.log(chalk.dim(' Use /info <address> for market details'));
187
+ }
188
+
189
+ displayMarketInfo(result) {
190
+ const info = result.info || result;
191
+ console.log(purpleBright(' Market Info\n'));
192
+
193
+ if (info.question) console.log(` ${chalk.dim('Question:')} ${info.question}`);
194
+ if (info.market || result.market) console.log(` ${chalk.dim('Address:')} ${violet(info.market || result.market)}`);
195
+ if (info.endTime) console.log(` ${chalk.dim('End Time:')} ${new Date(Number(info.endTime) * 1000).toLocaleString()}`);
196
+ if (info.yesTokenMint) console.log(` ${chalk.dim('YES Mint:')} ${chalk.dim(info.yesTokenMint)}`);
197
+ if (info.noTokenMint) console.log(` ${chalk.dim('NO Mint:')} ${chalk.dim(info.noTokenMint)}`);
198
+ }
199
+
200
+ displayPrices(result) {
201
+ console.log(purpleBright(' Market Prices\n'));
202
+ console.log(` ${chalk.green('YES:')} ${result.yesPrice || 'N/A'}`);
203
+ console.log(` ${chalk.red('NO:')} ${result.noPrice || 'N/A'}`);
204
+ }
205
+
206
+ displayBalances(result) {
207
+ console.log(purpleBright(' Your Balances\n'));
208
+ console.log(` ${chalk.green('YES tokens:')} ${result.yesBalance || 0}`);
209
+ console.log(` ${chalk.red('NO tokens:')} ${result.noBalance || 0}`);
210
+ if (result.usdcBalance) console.log(` ${chalk.dim('USDC:')} ${result.usdcBalance}`);
211
+ }
212
+
213
+ displayMarketCreation(result) {
214
+ console.log(purpleBright(' Market Created!\n'));
215
+ console.log(` ${chalk.dim('Address:')} ${violet(result.market)}`);
216
+ console.log(` ${chalk.dim('Signature:')} ${chalk.dim(result.signature?.slice(0, 30) + '...')}`);
217
+ console.log(` ${chalk.dim('Network:')} ${result.network}`);
218
+ console.log();
219
+ console.log(chalk.dim(` View on Solscan: https://solscan.io/tx/${result.signature}`));
220
+ }
221
+
222
+ displayTrade(result) {
223
+ console.log(purpleBright(' Trade Executed!\n'));
224
+ console.log(` ${chalk.dim('Market:')} ${result.market}`);
225
+ console.log(` ${chalk.dim('Side:')} ${result.side?.toUpperCase()}`);
226
+ console.log(` ${chalk.dim('Amount:')} ${result.amount || result.amountUsdc} USDC`);
227
+ console.log(` ${chalk.dim('Signature:')} ${chalk.dim(result.signature?.slice(0, 30) + '...')}`);
228
+ }
229
+
230
+ displaySettlementCriteria(result) {
231
+ console.log(purpleBright(' PNP Oracle - Settlement Criteria\n'));
232
+
233
+ if (result.criteria) {
234
+ if (typeof result.criteria === 'string') {
235
+ console.log(` ${result.criteria}`);
236
+ } else {
237
+ console.log(chalk.dim(JSON.stringify(result.criteria, null, 2)));
238
+ }
239
+ } else {
240
+ console.log(chalk.dim(' No criteria available yet'));
241
+ }
242
+ }
243
+
244
+ displaySettlementData(result) {
245
+ console.log(purpleBright(' PNP Oracle - Settlement Data\n'));
246
+
247
+ if (result.data) {
248
+ if (result.data.answer) {
249
+ console.log(` ${chalk.dim('Answer:')} ${result.data.answer === 'yes' ? chalk.green('YES') : chalk.red('NO')}`);
250
+ }
251
+ if (result.data.resolvable !== undefined) {
252
+ console.log(` ${chalk.dim('Resolvable:')} ${result.data.resolvable ? chalk.green('Yes') : chalk.yellow('Not yet')}`);
253
+ }
254
+ if (result.data.reasoning) {
255
+ console.log(` ${chalk.dim('Reasoning:')} ${result.data.reasoning}`);
256
+ }
257
+ } else {
258
+ console.log(chalk.dim(' No settlement data available yet'));
259
+ }
260
+ }
261
+
262
+ displayRedemption(result) {
263
+ console.log(purpleBright(' Position Redeemed!\n'));
264
+ console.log(` ${chalk.dim('Market:')} ${result.market}`);
265
+ console.log(` ${chalk.dim('Signature:')} ${chalk.dim(result.signature?.slice(0, 30) + '...')}`);
266
+ console.log();
267
+ console.log(chalk.green(' Winnings have been sent to your wallet!'));
268
+ }
269
+
270
+ displayPnpConfig(result) {
271
+ console.log(purpleBright(' PNP Exchange Configuration\n'));
272
+
273
+ if (result.config) {
274
+ if (result.config.publicKey) {
275
+ console.log(` ${chalk.dim('Config Address:')} ${result.config.publicKey}`);
276
+ }
277
+ if (result.config.account) {
278
+ console.log(chalk.dim(JSON.stringify(result.config.account, null, 2)));
279
+ }
280
+ }
281
+ }
282
+ }
283
+
284
+ // Export factory function
285
+ export function createPnpfuciusAgent(options = {}) {
286
+ return new PnpfuciusAgent(options);
287
+ }
288
+
289
+ // Backwards compatibility
290
+ export const ClaudePredictAgent = PnpfuciusAgent;
291
+ export const createPredictAgent = createPnpfuciusAgent;
@@ -0,0 +1,69 @@
1
+ // System prompts for Claude Predict
2
+
3
+ export const SYSTEM_PROMPT = `You are Claude Predict, an advanced AI agent for prediction markets on Solana's PNP Exchange.
4
+
5
+ ## Core Capabilities
6
+
7
+ You have FULL integration with PNP Exchange protocol, including:
8
+
9
+ ### Market Creation
10
+ - **AMM Markets**: Standard liquidity pool markets (create_market)
11
+ - **P2P Markets**: Direct peer-to-peer betting (create_p2p_market_simple)
12
+ - **Custom Odds**: Create markets with specific starting odds (create_amm_market_with_odds, create_p2p_market_with_odds)
13
+ - **Custom Oracle**: Create markets with your own settlement authority (create_market_with_oracle)
14
+ - **Source-Linked**: Markets tied to Twitter, YouTube, or DeFi metrics (create_market_from_source)
15
+
16
+ ### Market Discovery
17
+ - **Discover All Markets**: Browse ALL PNP markets, not just yours (discover_all_markets)
18
+ - **Market Metadata**: Volume, images, analytics (get_market_metadata)
19
+ - **V2 Market Info**: AMM market details with multipliers (get_v2_market_info)
20
+ - **P2P Market Info**: P2P reserves and settlement data (get_p2p_market_info)
21
+
22
+ ### Trading
23
+ - **Buy Tokens**: Purchase YES/NO tokens with USDC (buy_tokens, buy_v3_tokens)
24
+ - **Sell Tokens**: Sell positions back for USDC (sell_tokens)
25
+ - **Get Prices**: Current market prices and shares (get_market_prices)
26
+ - **Get Balances**: Your token holdings (get_balances)
27
+
28
+ ### PNP Oracle & Settlement (LLM-Powered)
29
+ - **Settlement Criteria**: Get AI-generated criteria for how markets resolve (get_settlement_criteria)
30
+ - **Settlement Data**: Get resolution results from PNP's LLM oracle (get_settlement_data)
31
+ - **Wait for Settlement**: Poll until criteria is available (wait_for_settlement)
32
+ - **Settle Market**: Execute settlement with outcome (settle_market) - requires authority
33
+
34
+ ### Redemption
35
+ - **Redeem Position**: Claim winnings from resolved markets (redeem_position, redeem_v3_position, redeem_p2p_position)
36
+ - **Claim Refund**: Get refunds from cancelled markets (claim_refund, claim_p2p_refund)
37
+
38
+ ### News & AI Scoring
39
+ - **Score News**: AI relevance scoring 0-100 (score_news)
40
+ - **Fetch News**: Get latest privacy news from RSS feeds (fetch_news)
41
+ - **Generate from News**: Create markets from news items (generate_from_news)
42
+
43
+ ### Protocol Info
44
+ - **PNP Config**: Get global protocol settings (get_pnp_config)
45
+
46
+ ## Privacy Market Categories
47
+ 1. **Regulation** - GDPR fines, federal privacy laws, encryption bans, sanctions
48
+ 2. **Technology** - ZK adoption, Tornado Cash, confidential transfers, Aztec, RAILGUN
49
+ 3. **Adoption** - Signal/Brave users, privacy coin delistings, enterprise ZK
50
+ 4. **Events** - Data breaches, surveillance scandals, hackathons, whistleblowers
51
+
52
+ ## Guidelines
53
+
54
+ - Be proactive: When users mention news/events, offer to score and create markets
55
+ - When creating markets, suggest appropriate durations (7-365 days) and liquidity based on topic
56
+ - For P2P markets, explain how custom odds work and ask about risk tolerance
57
+ - Use the discover_all_markets tool to show users trading opportunities
58
+ - When checking resolution, first get settlement criteria then settlement data
59
+ - Format responses in markdown with code blocks for addresses/signatures
60
+ - Keep responses concise but informative
61
+ - After tool results, summarize outcomes clearly`;
62
+
63
+ export const WELCOME_MESSAGE = `Type a message to get started, or try:
64
+ - "Generate 3 market ideas about GDPR"
65
+ - "Create a market about Tornado Cash sanctions"
66
+ - "Discover all markets on PNP Exchange"
67
+ - "Create a P2P bet on the next privacy regulation"
68
+ - "Score this news: EU proposes encryption backdoors"
69
+ - /help for all commands`;