pandora-cli-skills 1.0.3 → 1.1.3
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_FOR_SHARING.md +67 -0
- package/SKILL.md +43 -0
- package/cli/lib/analyze_provider.cjs +76 -0
- package/cli/lib/arbitrage_service.cjs +473 -0
- package/cli/lib/autopilot_service.cjs +255 -0
- package/cli/lib/autopilot_state_store.cjs +107 -0
- package/cli/lib/export_service.cjs +127 -0
- package/cli/lib/history_service.cjs +381 -0
- package/cli/lib/indexer_client.cjs +133 -0
- package/cli/lib/leaderboard_service.cjs +138 -0
- package/cli/lib/polymarket_adapter.cjs +141 -0
- package/cli/lib/suggest_service.cjs +65 -0
- package/cli/lib/webhook_service.cjs +158 -0
- package/cli/pandora.cjs +1943 -244
- package/package.json +4 -2
- package/references/contracts.md +23 -15
package/README_FOR_SHARING.md
CHANGED
|
@@ -78,6 +78,16 @@ Prerequisite: Node.js `>=18`.
|
|
|
78
78
|
- `pandora portfolio --wallet <0x...> [--chain-id <id>] [--limit <n>] [--include-events|--no-events]`
|
|
79
79
|
- `pandora watch --wallet <0x...> --iterations 10 --interval-ms 5000`
|
|
80
80
|
- `pandora watch --market-address <0x...> --side yes --amount-usdc 10 --iterations 5 --alert-yes-above 65 --fail-on-alert`
|
|
81
|
+
- Phase 4 intelligence and automation:
|
|
82
|
+
- `pandora history --wallet <0x...> --limit 50`
|
|
83
|
+
- `pandora export --wallet <0x...> --format csv --year 2026 --out ./trades-2026.csv`
|
|
84
|
+
- `pandora arbitrage --venues pandora,polymarket --min-spread-pct 3`
|
|
85
|
+
- `pandora autopilot run|once ...`
|
|
86
|
+
- `pandora webhook test ...`
|
|
87
|
+
- `pandora leaderboard --metric profit|volume|win-rate`
|
|
88
|
+
- `pandora analyze --market-address <0x...> --provider <name>`
|
|
89
|
+
- `pandora suggest --wallet <0x...> --risk low|medium|high --budget <amount>`
|
|
90
|
+
- ABI-gated placeholders: `pandora resolve`, `pandora lp`
|
|
81
91
|
|
|
82
92
|
## Read-only examples
|
|
83
93
|
- `pandora markets list --limit 20 --order-by createdAt --order-direction desc`
|
|
@@ -91,6 +101,14 @@ Prerequisite: Node.js `>=18`.
|
|
|
91
101
|
- `pandora trade --dry-run --market-address <0x...> --side no --amount-usdc 25 --max-amount-usdc 30 --min-probability-pct 20`
|
|
92
102
|
- `pandora portfolio --wallet <0x...> --chain-id 1`
|
|
93
103
|
- `pandora watch --wallet <0x...> --iterations 3 --interval-ms 1000 --alert-net-liquidity-below -100`
|
|
104
|
+
- `pandora history --wallet <0x...> --limit 50`
|
|
105
|
+
- `pandora export --wallet <0x...> --format csv --out ./trades.csv`
|
|
106
|
+
- `pandora arbitrage --venues pandora,polymarket --min-spread-pct 2`
|
|
107
|
+
- `pandora autopilot once --market-address <0x...> --side no --amount-usdc 10 --trigger-yes-below 15 --paper`
|
|
108
|
+
- `pandora webhook test --webhook-url https://example.com/hook`
|
|
109
|
+
- `pandora leaderboard --metric volume --limit 20`
|
|
110
|
+
- `pandora analyze --market-address <0x...> --provider mock`
|
|
111
|
+
- `pandora suggest --wallet <0x...> --risk medium --budget 50 --include-venues pandora`
|
|
94
112
|
- `pandora polls list --status 1 --category 3`
|
|
95
113
|
- `pandora events list --type all --wallet <0x...> --limit 25`
|
|
96
114
|
- `pandora positions list --wallet <0x...> --limit 50`
|
|
@@ -139,6 +157,45 @@ Prerequisite: Node.js `>=18`.
|
|
|
139
157
|
- `watch` polls on an interval and is intended for terminal monitoring, not background daemonization.
|
|
140
158
|
- `--fail-on-alert` exits non-zero when any configured threshold is hit.
|
|
141
159
|
|
|
160
|
+
## Phase 4 JSON contracts
|
|
161
|
+
- `history`:
|
|
162
|
+
- envelope is `ok=true`, `command="history"`, with `data.schemaVersion`, `data.summary`, and per-trade `data.items[]`.
|
|
163
|
+
- P&L fields are analytics-grade approximations with row diagnostics where precision is limited.
|
|
164
|
+
- `export`:
|
|
165
|
+
- envelope is `ok=true`, `command="export"`, with `data.format`, `data.columns`, `data.count`, optional `data.outPath`, and materialized `data.content`.
|
|
166
|
+
- `arbitrage`:
|
|
167
|
+
- envelope is `ok=true`, `command="arbitrage"`, with `data.parameters`, `data.sources`, and `data.opportunities[]`.
|
|
168
|
+
- source failures are emitted in diagnostics instead of hard crashes.
|
|
169
|
+
- `autopilot`:
|
|
170
|
+
- envelope is `ok=true`, `command="autopilot"`, with `data.strategyHash`, `data.stateFile`, `data.snapshots[]`, and `data.actions[]`.
|
|
171
|
+
- paper mode is default; live mode requires explicit caps (`--max-amount-usdc`, `--max-open-exposure-usdc`, `--max-trades-per-day`).
|
|
172
|
+
- `webhook test`:
|
|
173
|
+
- envelope is `ok=true`, `command="webhook.test"`, with per-target delivery and retry metadata.
|
|
174
|
+
- `leaderboard`:
|
|
175
|
+
- envelope is `ok=true`, `command="leaderboard"`, with ranked rows for selected metric.
|
|
176
|
+
- inconsistent indexer aggregates are sanitized (win-rate capped to 0-100%) and exposed in diagnostics.
|
|
177
|
+
- `analyze`:
|
|
178
|
+
- envelope is `ok=true`, `command="analyze"`, with provider/model metadata, market context, and `{ fairYesPct, confidence, rationale }`.
|
|
179
|
+
- provider-agnostic interface; missing provider returns `ANALYZE_PROVIDER_NOT_CONFIGURED`.
|
|
180
|
+
- `suggest`:
|
|
181
|
+
- envelope is `ok=true`, `command="suggest"`, with ranked suggestions, sizing, and risk notes.
|
|
182
|
+
|
|
183
|
+
## ABI-gated commands
|
|
184
|
+
- `resolve` and `lp` are intentionally gated and return `ABI_READY_REQUIRED` until verified ABI signatures/events and integration tests are committed.
|
|
185
|
+
|
|
186
|
+
## Pandora Mainnet Reference
|
|
187
|
+
- PredictionOracle (Factory): `0x259308E7d8557e4Ba192De1aB8Cf7e0E21896442`
|
|
188
|
+
- PredictionPoll (Implementation): `0xC49c177736107fD8351ed6564136B9ADbE5B1eC3`
|
|
189
|
+
- MarketFactory: `0xaB120F1FD31FB1EC39893B75d80a3822b1Cd8d0c`
|
|
190
|
+
- OutcomeToken (Implementation): `0x15AF9A6cE764a7D2b6913e09494350893436Ab3d`
|
|
191
|
+
- PredictionAMM (Implementation): `0x7D45D4835001347B31B722Fb830fc1D9336F09f4`
|
|
192
|
+
- PredictionPariMutuel (Implementation): `0x5CaF2D85f17A8f3b57918d54c8B138Cacac014BD`
|
|
193
|
+
- Initial collateral (USDC): `0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48`
|
|
194
|
+
- Platform treasury: `0x8789F22a0456FEddaf9074FF4cEE55E4122095f0`
|
|
195
|
+
- Protocol fee rate: `20000` (`2%`)
|
|
196
|
+
- Indexer URL: `https://pandoraindexer.up.railway.app/`
|
|
197
|
+
- Full deployment notes: `references/contracts.md`
|
|
198
|
+
|
|
142
199
|
## Release and verified install
|
|
143
200
|
- CI workflow: `.github/workflows/ci.yml` runs on Linux/macOS/Windows and covers install, lint/typecheck, full tests, and `npm pack --dry-run`.
|
|
144
201
|
- Release workflow: `.github/workflows/release.yml` runs on pushed `v*` tags, runs tests, builds `npm pack`, generates `checksums.sha256`, and uploads both workflow artifacts + GitHub Release assets.
|
|
@@ -161,6 +218,16 @@ Prerequisite: Node.js `>=18`.
|
|
|
161
218
|
- `pandora trade`
|
|
162
219
|
- `pandora portfolio`
|
|
163
220
|
- `pandora watch`
|
|
221
|
+
- `pandora history`
|
|
222
|
+
- `pandora export`
|
|
223
|
+
- `pandora arbitrage`
|
|
224
|
+
- `pandora autopilot`
|
|
225
|
+
- `pandora webhook test`
|
|
226
|
+
- `pandora leaderboard`
|
|
227
|
+
- `pandora analyze`
|
|
228
|
+
- `pandora suggest`
|
|
229
|
+
- `pandora resolve` (ABI-gated)
|
|
230
|
+
- `pandora lp` (ABI-gated)
|
|
164
231
|
- `pandora polls list|get`
|
|
165
232
|
- `pandora events list|get`
|
|
166
233
|
- `pandora positions list`
|
package/SKILL.md
CHANGED
|
@@ -40,6 +40,16 @@ npm link
|
|
|
40
40
|
- Phase 3 analytics command: `pandora portfolio`
|
|
41
41
|
- Phase 3 monitoring command: `pandora watch`
|
|
42
42
|
- Phase 3 watch alerts: `--alert-yes-*`, `--alert-net-liquidity-*`, `--fail-on-alert`
|
|
43
|
+
- Phase 4 commands:
|
|
44
|
+
- `pandora history`
|
|
45
|
+
- `pandora export`
|
|
46
|
+
- `pandora arbitrage`
|
|
47
|
+
- `pandora autopilot run|once`
|
|
48
|
+
- `pandora webhook test`
|
|
49
|
+
- `pandora leaderboard`
|
|
50
|
+
- `pandora analyze`
|
|
51
|
+
- `pandora suggest`
|
|
52
|
+
- ABI-gated placeholders: `pandora resolve`, `pandora lp`
|
|
43
53
|
- Doctor checks:
|
|
44
54
|
- env presence + format validation
|
|
45
55
|
- RPC reachability and chain id match
|
|
@@ -83,6 +93,14 @@ pandora --output json quote --market-address <0x...> --side yes --amount-usdc 10
|
|
|
83
93
|
pandora --output json trade --dry-run --market-address <0x...> --side no --amount-usdc 10 --max-amount-usdc 20
|
|
84
94
|
pandora --output json portfolio --wallet <0x...> --chain-id 1
|
|
85
95
|
pandora --output json watch --wallet <0x...> --iterations 3 --interval-ms 1000 --alert-net-liquidity-above 1000 --fail-on-alert
|
|
96
|
+
pandora --output json history --wallet <0x...> --limit 50
|
|
97
|
+
pandora --output json export --wallet <0x...> --format csv --out ./trades.csv
|
|
98
|
+
pandora --output json arbitrage --venues pandora,polymarket --min-spread-pct 3
|
|
99
|
+
pandora --output json autopilot once --market-address <0x...> --side no --amount-usdc 10 --trigger-yes-below 15 --paper
|
|
100
|
+
pandora --output json webhook test --webhook-url https://example.com/hook
|
|
101
|
+
pandora --output json leaderboard --metric profit --limit 20
|
|
102
|
+
pandora --output json analyze --market-address <0x...> --provider mock
|
|
103
|
+
pandora --output json suggest --wallet <0x...> --risk medium --budget 50 --include-venues pandora
|
|
86
104
|
```
|
|
87
105
|
|
|
88
106
|
## Phase 1 JSON contracts
|
|
@@ -129,6 +147,31 @@ pandora --output json watch --wallet <0x...> --iterations 3 --interval-ms 1000 -
|
|
|
129
147
|
- `watch` is polling-based and terminal-oriented, not a long-running background service manager.
|
|
130
148
|
- `--fail-on-alert` exits non-zero when any configured threshold triggers.
|
|
131
149
|
|
|
150
|
+
## Phase 4 contracts
|
|
151
|
+
- `history`: analytics-grade trade journal with per-trade approximate P&L and diagnostics.
|
|
152
|
+
- `export`: deterministic CSV/JSON materialization from history rows.
|
|
153
|
+
- `arbitrage`: duplicate/correlated market spread detection across Pandora + Polymarket.
|
|
154
|
+
- `autopilot`: paper-first trigger loop with persisted local state and idempotency.
|
|
155
|
+
- `webhook test`: channel validation for generic, Telegram, and Discord payload delivery.
|
|
156
|
+
- `leaderboard`: ranked user aggregates by profit/volume/win-rate.
|
|
157
|
+
- invalid indexer aggregates are sanitized (win-rate capped to 0-100%) and emitted in diagnostics.
|
|
158
|
+
- `analyze`: provider-agnostic market analysis interface (fails with structured error when provider is not configured).
|
|
159
|
+
- `suggest`: risk/budget-ranked opportunities seeded from arbitrage output and wallet history.
|
|
160
|
+
- `resolve` and `lp`: intentionally return `ABI_READY_REQUIRED` until ABI readiness sign-off.
|
|
161
|
+
|
|
162
|
+
## Pandora mainnet deployment reference
|
|
163
|
+
- PredictionOracle (Factory): `0x259308E7d8557e4Ba192De1aB8Cf7e0E21896442`
|
|
164
|
+
- PredictionPoll (Implementation): `0xC49c177736107fD8351ed6564136B9ADbE5B1eC3`
|
|
165
|
+
- MarketFactory: `0xaB120F1FD31FB1EC39893B75d80a3822b1Cd8d0c`
|
|
166
|
+
- OutcomeToken (Implementation): `0x15AF9A6cE764a7D2b6913e09494350893436Ab3d`
|
|
167
|
+
- PredictionAMM (Implementation): `0x7D45D4835001347B31B722Fb830fc1D9336F09f4`
|
|
168
|
+
- PredictionPariMutuel (Implementation): `0x5CaF2D85f17A8f3b57918d54c8B138Cacac014BD`
|
|
169
|
+
- Initial collateral (USDC): `0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48`
|
|
170
|
+
- Platform treasury: `0x8789F22a0456FEddaf9074FF4cEE55E4122095f0`
|
|
171
|
+
- Protocol fee rate: `20000` (`2%`)
|
|
172
|
+
- Indexer URL: `https://pandoraindexer.up.railway.app/`
|
|
173
|
+
- Source of truth doc: `references/contracts.md`
|
|
174
|
+
|
|
132
175
|
## Release verification
|
|
133
176
|
- CI coverage includes Linux, macOS, and Windows.
|
|
134
177
|
- Release artifacts are signed keylessly with cosign in the release workflow.
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
const ANALYZE_SCHEMA_VERSION = '1.0.0';
|
|
2
|
+
|
|
3
|
+
class AnalyzeProviderError extends Error {
|
|
4
|
+
constructor(code, message, details) {
|
|
5
|
+
super(message);
|
|
6
|
+
this.name = 'AnalyzeProviderError';
|
|
7
|
+
this.code = code;
|
|
8
|
+
this.details = details;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function getProviderName(options = {}) {
|
|
13
|
+
const explicit = options.provider ? String(options.provider).trim().toLowerCase() : '';
|
|
14
|
+
const envProvider = process.env.PANDORA_ANALYZE_PROVIDER ? String(process.env.PANDORA_ANALYZE_PROVIDER).trim().toLowerCase() : '';
|
|
15
|
+
return explicit || envProvider || 'none';
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
async function evaluateWithMock(context) {
|
|
19
|
+
const raw = process.env.PANDORA_ANALYZE_MOCK_RESPONSE;
|
|
20
|
+
if (raw) {
|
|
21
|
+
try {
|
|
22
|
+
const parsed = JSON.parse(raw);
|
|
23
|
+
return {
|
|
24
|
+
fairYesPct: parsed.fairYesPct,
|
|
25
|
+
confidence: parsed.confidence,
|
|
26
|
+
rationale: parsed.rationale || 'Mocked analyze response.',
|
|
27
|
+
caveats: Array.isArray(parsed.caveats) ? parsed.caveats : [],
|
|
28
|
+
};
|
|
29
|
+
} catch {
|
|
30
|
+
// Ignore malformed mock payload and fall through to deterministic default.
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const marketYes = Number(context && context.market && context.market.yesPct);
|
|
35
|
+
const fair = Number.isFinite(marketYes) ? Math.max(1, Math.min(99, marketYes * 0.9)) : 50;
|
|
36
|
+
return {
|
|
37
|
+
fairYesPct: fair,
|
|
38
|
+
confidence: 0.42,
|
|
39
|
+
rationale: 'Mock provider generated a conservative fair-value estimate for local/testing workflows.',
|
|
40
|
+
caveats: ['Mock analysis provider is enabled; no external model call was executed.'],
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
async function evaluateMarket(context, options = {}) {
|
|
45
|
+
const provider = getProviderName(options);
|
|
46
|
+
if (provider === 'none') {
|
|
47
|
+
throw new AnalyzeProviderError(
|
|
48
|
+
'ANALYZE_PROVIDER_NOT_CONFIGURED',
|
|
49
|
+
'No analyze provider configured. Set --provider or PANDORA_ANALYZE_PROVIDER.',
|
|
50
|
+
{
|
|
51
|
+
supportedProviders: ['mock'],
|
|
52
|
+
},
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (provider === 'mock') {
|
|
57
|
+
const result = await evaluateWithMock(context);
|
|
58
|
+
return {
|
|
59
|
+
schemaVersion: ANALYZE_SCHEMA_VERSION,
|
|
60
|
+
provider,
|
|
61
|
+
model: options.model || 'mock-v1',
|
|
62
|
+
result,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
throw new AnalyzeProviderError('ANALYZE_PROVIDER_UNSUPPORTED', `Unsupported analyze provider: ${provider}`, {
|
|
67
|
+
supportedProviders: ['mock'],
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
module.exports = {
|
|
72
|
+
ANALYZE_SCHEMA_VERSION,
|
|
73
|
+
AnalyzeProviderError,
|
|
74
|
+
getProviderName,
|
|
75
|
+
evaluateMarket,
|
|
76
|
+
};
|