probable-trader 1.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.
- package/README.md +118 -0
- package/bin/probable-trader.js +64 -0
- package/lib/setup.js +125 -0
- package/package.json +30 -0
- package/requirements.txt +6 -0
- package/schemas/action-output.schema.json +50 -0
- package/schemas/config.schema.json +49 -0
- package/schemas/order-intent.schema.json +47 -0
- package/scripts/lib/__init__.py +1 -0
- package/scripts/lib/client_wrapper.py +241 -0
- package/scripts/lib/config.py +150 -0
- package/scripts/lib/db.py +176 -0
- package/scripts/lib/onboard.py +177 -0
- package/scripts/lib/report.py +105 -0
- package/scripts/lib/safety.py +76 -0
- package/scripts/lib/ws_client.py +109 -0
- package/scripts/prob.py +474 -0
package/README.md
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# Probable Markets Trading Skill
|
|
2
|
+
|
|
3
|
+
An OpenClaw Skill that wraps the [Probable Markets](https://probable.markets) prediction market on BNB Chain (BSC). Enables agents to onboard wallets, discover markets, view orderbooks, place/cancel orders, track positions, and generate audit reports.
|
|
4
|
+
|
|
5
|
+
Built on top of `opinion_clob_sdk` — the official Probable Markets / Opinion Labs Python SDK.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **One-command onboarding** — auto-generates API key via L1 EIP-712 auth
|
|
10
|
+
- **Full trading lifecycle** — place/cancel limit & market orders, split/merge/redeem
|
|
11
|
+
- **Safety by default** — dry-run mode, `--confirm` required for all transactions, secret masking
|
|
12
|
+
- **Audit logging** — every action logged to local SQLite
|
|
13
|
+
- **Real-time streaming** — WebSocket orderbook & execution report subscriptions
|
|
14
|
+
- **Agent-native** — all output as structured JSON (ActionResult envelope)
|
|
15
|
+
|
|
16
|
+
## Quick Start
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
# 1. Install dependencies
|
|
20
|
+
pip install opinion_clob_sdk websockets httpx
|
|
21
|
+
|
|
22
|
+
# 2. Set your private key
|
|
23
|
+
export PROB_PRIVATE_KEY="0xYOUR_PRIVATE_KEY"
|
|
24
|
+
export PROB_RPC_URL="https://bsc-dataseed.binance.org"
|
|
25
|
+
|
|
26
|
+
# 3. Register on probable.markets (connect wallet), then set proxy wallet
|
|
27
|
+
export PROB_MULTI_SIG_ADDR="0xYOUR_PROXY_WALLET"
|
|
28
|
+
|
|
29
|
+
# 4. Auto-generate API key
|
|
30
|
+
python3 scripts/prob.py onboard --confirm --json
|
|
31
|
+
|
|
32
|
+
# 5. Enable trading approvals (on-chain)
|
|
33
|
+
python3 scripts/prob.py setup --confirm --json
|
|
34
|
+
|
|
35
|
+
# 6. Start trading
|
|
36
|
+
python3 scripts/prob.py market list --status activated --json
|
|
37
|
+
python3 scripts/prob.py book <token_id> --json
|
|
38
|
+
python3 scripts/prob.py order place --market-id <M> --token-id <T> --side BUY --price 0.55 --amount 100 --confirm --json
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## CLI Commands
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
prob.py config {show,init} # Configuration management
|
|
45
|
+
prob.py doctor # Health check
|
|
46
|
+
prob.py onboard [--confirm] # Generate API key (L1 auth)
|
|
47
|
+
prob.py setup [--confirm] # Enable trading (on-chain approvals)
|
|
48
|
+
|
|
49
|
+
prob.py market {list,get,search} # Market discovery
|
|
50
|
+
prob.py book <token_id> # Orderbook snapshot
|
|
51
|
+
prob.py price <token_id> # Latest price
|
|
52
|
+
prob.py history <token_id> # Price history
|
|
53
|
+
prob.py fee-rates <token_id> # Fee rates
|
|
54
|
+
|
|
55
|
+
prob.py order {place,get,list,cancel,cancel-all} # Order management
|
|
56
|
+
prob.py positions [--market-id M] # My positions
|
|
57
|
+
prob.py trades [--market-id M] # My trades
|
|
58
|
+
prob.py balance # My balances
|
|
59
|
+
|
|
60
|
+
prob.py split --market-id M --amount A [--confirm] # Split collateral
|
|
61
|
+
prob.py merge --market-id M --amount A [--confirm] # Merge tokens
|
|
62
|
+
prob.py redeem --market-id M [--confirm] # Redeem resolved
|
|
63
|
+
|
|
64
|
+
prob.py ws book <token_id> [--duration N] # Stream orderbook
|
|
65
|
+
prob.py ws user [--duration N] # Stream execution reports
|
|
66
|
+
prob.py report daily [--format json|markdown|both] # Trading report
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Global flags: `--json` (JSON output), `--confirm` (execute), `--dry-run` (preview)
|
|
70
|
+
|
|
71
|
+
## Project Structure
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
marketskill/
|
|
75
|
+
├── SKILL.md # OpenClaw skill definition
|
|
76
|
+
├── scripts/
|
|
77
|
+
│ ├── prob.py # CLI entry point
|
|
78
|
+
│ └── lib/
|
|
79
|
+
│ ├── config.py # Env var + config file loading
|
|
80
|
+
│ ├── client_wrapper.py # Wraps opinion_clob_sdk.Client
|
|
81
|
+
│ ├── onboard.py # L1 auth + API key generation
|
|
82
|
+
│ ├── safety.py # Dry-run, confirmation, secret masking
|
|
83
|
+
│ ├── db.py # SQLite audit log + cache
|
|
84
|
+
│ ├── ws_client.py # WebSocket client
|
|
85
|
+
│ └── report.py # Daily report generator
|
|
86
|
+
├── schemas/ # JSON schemas (config, order intent, output)
|
|
87
|
+
├── references/ # API, WebSocket, and onboarding docs
|
|
88
|
+
└── examples/ # Example interactions
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Safety Model
|
|
92
|
+
|
|
93
|
+
| Feature | Behavior |
|
|
94
|
+
|---------|----------|
|
|
95
|
+
| Default mode | Dry-run — shows what would happen without executing |
|
|
96
|
+
| Transactions | Require `--confirm` flag (orders, cancel, split, merge, redeem, setup) |
|
|
97
|
+
| Secrets | Private keys and API secrets masked in all output |
|
|
98
|
+
| Audit | Every action logged to `.probable/probable.db` (SQLite) |
|
|
99
|
+
| Output | Standardized JSON envelope with `success`, `error`, `request_id`, `timestamp` |
|
|
100
|
+
|
|
101
|
+
## Key Contracts (BSC Mainnet)
|
|
102
|
+
|
|
103
|
+
| Contract | Address |
|
|
104
|
+
|----------|---------|
|
|
105
|
+
| ConditionalTokens | `0xAD1a38cEc043e70E83a3eC30443dB285ED10D774` |
|
|
106
|
+
| MultiSend | `0x998739BFdAAdde7C933B942a68053933098f9EDa` |
|
|
107
|
+
| FeeManager | `0xC9063Dc52dEEfb518E5b6634A6b8D624bc5d7c36` |
|
|
108
|
+
|
|
109
|
+
## Requirements
|
|
110
|
+
|
|
111
|
+
- Python 3.10+
|
|
112
|
+
- `opinion_clob_sdk` (v0.4.3+)
|
|
113
|
+
- `websockets`, `httpx`
|
|
114
|
+
- BNB Chain wallet with BNB (gas) and USDT (trading)
|
|
115
|
+
|
|
116
|
+
## License
|
|
117
|
+
|
|
118
|
+
MIT
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
const { spawn } = require("child_process");
|
|
5
|
+
const path = require("path");
|
|
6
|
+
const { ensureEnvironment, checkPython, installDeps } = require("../lib/setup");
|
|
7
|
+
|
|
8
|
+
const PROB_PY = path.resolve(__dirname, "..", "scripts", "prob.py");
|
|
9
|
+
|
|
10
|
+
// Handle "setup-python" — force (re)install deps
|
|
11
|
+
if (process.argv[2] === "setup-python") {
|
|
12
|
+
try {
|
|
13
|
+
const pythonBin = checkPython();
|
|
14
|
+
console.log("Python found: " + pythonBin);
|
|
15
|
+
// Remove marker to force reinstall
|
|
16
|
+
const fs = require("fs");
|
|
17
|
+
const marker = path.resolve(__dirname, "..", ".probable", ".deps-installed");
|
|
18
|
+
if (fs.existsSync(marker)) {
|
|
19
|
+
fs.unlinkSync(marker);
|
|
20
|
+
}
|
|
21
|
+
installDeps(pythonBin);
|
|
22
|
+
console.log("Setup complete.");
|
|
23
|
+
} catch (err) {
|
|
24
|
+
console.error("Error:", err.message);
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
process.exit(0);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// For --help / -h / no args, only need python check (skip pip install)
|
|
31
|
+
const userArgs = process.argv.slice(2);
|
|
32
|
+
const helpOnly =
|
|
33
|
+
userArgs.length === 0 ||
|
|
34
|
+
userArgs.includes("--help") ||
|
|
35
|
+
userArgs.includes("-h");
|
|
36
|
+
|
|
37
|
+
let pythonBin;
|
|
38
|
+
try {
|
|
39
|
+
if (helpOnly) {
|
|
40
|
+
pythonBin = checkPython();
|
|
41
|
+
} else {
|
|
42
|
+
pythonBin = ensureEnvironment();
|
|
43
|
+
}
|
|
44
|
+
} catch (err) {
|
|
45
|
+
console.error("Error:", err.message);
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Forward all args after "probable-trader" to prob.py
|
|
50
|
+
const args = [PROB_PY, ...process.argv.slice(2)];
|
|
51
|
+
|
|
52
|
+
const child = spawn(pythonBin, args, {
|
|
53
|
+
stdio: "inherit",
|
|
54
|
+
cwd: path.resolve(__dirname, ".."),
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
child.on("error", (err) => {
|
|
58
|
+
console.error("Failed to start Python:", err.message);
|
|
59
|
+
process.exit(1);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
child.on("close", (code) => {
|
|
63
|
+
process.exit(code ?? 1);
|
|
64
|
+
});
|
package/lib/setup.js
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const { execFileSync } = require("child_process");
|
|
4
|
+
const fs = require("fs");
|
|
5
|
+
const path = require("path");
|
|
6
|
+
|
|
7
|
+
const PKG_ROOT = path.resolve(__dirname, "..");
|
|
8
|
+
const MARKER_DIR = path.join(PKG_ROOT, ".probable");
|
|
9
|
+
const MARKER_FILE = path.join(MARKER_DIR, ".deps-installed");
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Find a working python3 binary and verify version >= 3.10.
|
|
13
|
+
* Returns the binary name (e.g. "python3") or throws.
|
|
14
|
+
*/
|
|
15
|
+
function checkPython() {
|
|
16
|
+
const candidates = ["python3", "python"];
|
|
17
|
+
for (const bin of candidates) {
|
|
18
|
+
try {
|
|
19
|
+
const raw = execFileSync(bin, ["--version"], {
|
|
20
|
+
encoding: "utf-8",
|
|
21
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
22
|
+
}).trim();
|
|
23
|
+
const match = raw.match(/Python\s+(\d+)\.(\d+)/);
|
|
24
|
+
if (match) {
|
|
25
|
+
const major = parseInt(match[1], 10);
|
|
26
|
+
const minor = parseInt(match[2], 10);
|
|
27
|
+
if (major === 3 && minor >= 10) {
|
|
28
|
+
return bin;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
} catch {
|
|
32
|
+
// binary not found, try next
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
throw new Error(
|
|
36
|
+
"Python 3.10+ is required but not found.\n" +
|
|
37
|
+
"Install it from https://www.python.org/downloads/ and ensure it is on your PATH."
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Try to run a pip install command. Returns true on success.
|
|
43
|
+
*/
|
|
44
|
+
function tryPipInstall(args) {
|
|
45
|
+
try {
|
|
46
|
+
execFileSync(args[0], args.slice(1), {
|
|
47
|
+
stdio: "inherit",
|
|
48
|
+
});
|
|
49
|
+
return true;
|
|
50
|
+
} catch {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Check if `uv` is available.
|
|
57
|
+
*/
|
|
58
|
+
function hasUv() {
|
|
59
|
+
try {
|
|
60
|
+
execFileSync("uv", ["--version"], { stdio: ["pipe", "pipe", "pipe"] });
|
|
61
|
+
return true;
|
|
62
|
+
} catch {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Install Python dependencies from requirements.txt (only once).
|
|
69
|
+
* Tries multiple strategies: uv pip, pip, pip --user, pip --break-system-packages.
|
|
70
|
+
*/
|
|
71
|
+
function installDeps(pythonBin) {
|
|
72
|
+
if (fs.existsSync(MARKER_FILE)) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const reqFile = path.join(PKG_ROOT, "requirements.txt");
|
|
77
|
+
if (!fs.existsSync(reqFile)) {
|
|
78
|
+
throw new Error("requirements.txt not found at " + reqFile);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
console.error("[probable-trader] Installing Python dependencies (first run)...");
|
|
82
|
+
|
|
83
|
+
const strategies = [
|
|
84
|
+
// 1. uv pip install (fast, respects PEP 668)
|
|
85
|
+
...(hasUv() ? [["uv", "pip", "install", "-r", reqFile]] : []),
|
|
86
|
+
// 2. Standard pip
|
|
87
|
+
[pythonBin, "-m", "pip", "install", "-r", reqFile],
|
|
88
|
+
// 3. pip --user (avoids system site-packages)
|
|
89
|
+
[pythonBin, "-m", "pip", "install", "--user", "-r", reqFile],
|
|
90
|
+
// 4. pip --break-system-packages (PEP 668 override, last resort)
|
|
91
|
+
[pythonBin, "-m", "pip", "install", "--break-system-packages", "-r", reqFile],
|
|
92
|
+
];
|
|
93
|
+
|
|
94
|
+
for (const args of strategies) {
|
|
95
|
+
console.error("[probable-trader] Trying: " + args.join(" "));
|
|
96
|
+
if (tryPipInstall(args)) {
|
|
97
|
+
// Write marker
|
|
98
|
+
if (!fs.existsSync(MARKER_DIR)) {
|
|
99
|
+
fs.mkdirSync(MARKER_DIR, { recursive: true });
|
|
100
|
+
}
|
|
101
|
+
fs.writeFileSync(MARKER_FILE, new Date().toISOString() + "\n");
|
|
102
|
+
console.error("[probable-trader] Python dependencies installed successfully.");
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
throw new Error(
|
|
108
|
+
"Failed to install Python dependencies.\n" +
|
|
109
|
+
"Try running manually:\n" +
|
|
110
|
+
" " + pythonBin + " -m pip install -r " + reqFile + "\n" +
|
|
111
|
+
"Or use a virtual environment:\n" +
|
|
112
|
+
" " + pythonBin + " -m venv .venv && source .venv/bin/activate && pip install -r " + reqFile
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Ensure Python environment is ready. Returns the python binary name.
|
|
118
|
+
*/
|
|
119
|
+
function ensureEnvironment() {
|
|
120
|
+
const pythonBin = checkPython();
|
|
121
|
+
installDeps(pythonBin);
|
|
122
|
+
return pythonBin;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
module.exports = { checkPython, installDeps, ensureEnvironment };
|
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "probable-trader",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "CLI for trading prediction markets on Probable Markets (BSC)",
|
|
5
|
+
"bin": {
|
|
6
|
+
"probable-trader": "bin/probable-trader.js"
|
|
7
|
+
},
|
|
8
|
+
"files": [
|
|
9
|
+
"bin/",
|
|
10
|
+
"lib/",
|
|
11
|
+
"scripts/**/*.py",
|
|
12
|
+
"schemas/",
|
|
13
|
+
"requirements.txt"
|
|
14
|
+
],
|
|
15
|
+
"keywords": [
|
|
16
|
+
"prediction-market",
|
|
17
|
+
"bsc",
|
|
18
|
+
"trading",
|
|
19
|
+
"cli",
|
|
20
|
+
"probable-markets"
|
|
21
|
+
],
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "https://github.com/duolaAmengweb3/probable-trader-skill"
|
|
26
|
+
},
|
|
27
|
+
"engines": {
|
|
28
|
+
"node": ">=16"
|
|
29
|
+
}
|
|
30
|
+
}
|
package/requirements.txt
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"title": "Action Output",
|
|
4
|
+
"description": "Standardized output envelope for all Probable Markets CLI actions",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"properties": {
|
|
7
|
+
"success": {
|
|
8
|
+
"type": "boolean",
|
|
9
|
+
"description": "Whether the action completed successfully"
|
|
10
|
+
},
|
|
11
|
+
"action": {
|
|
12
|
+
"type": "string",
|
|
13
|
+
"description": "Action name (e.g. 'place_order', 'get_markets', 'doctor')"
|
|
14
|
+
},
|
|
15
|
+
"data": {
|
|
16
|
+
"description": "Action-specific response data (null on error)"
|
|
17
|
+
},
|
|
18
|
+
"error": {
|
|
19
|
+
"type": ["string", "null"],
|
|
20
|
+
"description": "Error message if success=false"
|
|
21
|
+
},
|
|
22
|
+
"dry_run": {
|
|
23
|
+
"type": "boolean",
|
|
24
|
+
"description": "True if action was simulated (not executed)",
|
|
25
|
+
"default": false
|
|
26
|
+
},
|
|
27
|
+
"request_id": {
|
|
28
|
+
"type": "string",
|
|
29
|
+
"description": "Unique request ID for audit correlation",
|
|
30
|
+
"pattern": "^[0-9a-f]{12}$"
|
|
31
|
+
},
|
|
32
|
+
"timestamp": {
|
|
33
|
+
"type": "string",
|
|
34
|
+
"format": "date-time",
|
|
35
|
+
"description": "UTC ISO-8601 timestamp"
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
"required": ["success", "action", "request_id", "timestamp"],
|
|
39
|
+
"examples": [
|
|
40
|
+
{
|
|
41
|
+
"success": true,
|
|
42
|
+
"action": "get_markets",
|
|
43
|
+
"data": [{"id": 1, "title": "Will BTC hit 100k?"}],
|
|
44
|
+
"error": null,
|
|
45
|
+
"dry_run": false,
|
|
46
|
+
"request_id": "a1b2c3d4e5f6",
|
|
47
|
+
"timestamp": "2026-03-04T12:00:00+00:00"
|
|
48
|
+
}
|
|
49
|
+
]
|
|
50
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"title": "Probable Markets Skill Configuration",
|
|
4
|
+
"description": "Configuration schema for the probable-trader skill",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"properties": {
|
|
7
|
+
"host": {
|
|
8
|
+
"type": "string",
|
|
9
|
+
"description": "Probable Markets API host URL",
|
|
10
|
+
"default": "https://api.probable.markets"
|
|
11
|
+
},
|
|
12
|
+
"chain_id": {
|
|
13
|
+
"type": "integer",
|
|
14
|
+
"description": "BSC chain ID",
|
|
15
|
+
"default": 56,
|
|
16
|
+
"enum": [56]
|
|
17
|
+
},
|
|
18
|
+
"rpc_url": {
|
|
19
|
+
"type": "string",
|
|
20
|
+
"description": "BSC RPC endpoint URL (e.g. https://bsc-dataseed.binance.org)"
|
|
21
|
+
},
|
|
22
|
+
"api_key": {
|
|
23
|
+
"type": "string",
|
|
24
|
+
"description": "Probable Markets API key (from onboarding)"
|
|
25
|
+
},
|
|
26
|
+
"private_key": {
|
|
27
|
+
"type": "string",
|
|
28
|
+
"description": "EOA private key for signing (hex, with or without 0x prefix)",
|
|
29
|
+
"pattern": "^(0x)?[0-9a-fA-F]{64}$"
|
|
30
|
+
},
|
|
31
|
+
"multi_sig_addr": {
|
|
32
|
+
"type": "string",
|
|
33
|
+
"description": "Gnosis Safe proxy wallet address",
|
|
34
|
+
"pattern": "^0x[0-9a-fA-F]{40}$"
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
"required": [],
|
|
38
|
+
"additionalProperties": false,
|
|
39
|
+
"examples": [
|
|
40
|
+
{
|
|
41
|
+
"host": "https://api.probable.markets",
|
|
42
|
+
"chain_id": 56,
|
|
43
|
+
"rpc_url": "https://bsc-dataseed.binance.org",
|
|
44
|
+
"api_key": "your-api-key",
|
|
45
|
+
"private_key": "0x...",
|
|
46
|
+
"multi_sig_addr": "0x..."
|
|
47
|
+
}
|
|
48
|
+
]
|
|
49
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"title": "Order Intent",
|
|
4
|
+
"description": "Input schema for placing an order on Probable Markets",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"properties": {
|
|
7
|
+
"market_id": {
|
|
8
|
+
"type": "integer",
|
|
9
|
+
"description": "Market/Topic ID"
|
|
10
|
+
},
|
|
11
|
+
"token_id": {
|
|
12
|
+
"type": "string",
|
|
13
|
+
"description": "CTF ERC1155 token ID for the outcome to trade"
|
|
14
|
+
},
|
|
15
|
+
"side": {
|
|
16
|
+
"type": "string",
|
|
17
|
+
"enum": ["BUY", "SELL"],
|
|
18
|
+
"description": "Order side"
|
|
19
|
+
},
|
|
20
|
+
"price": {
|
|
21
|
+
"type": "string",
|
|
22
|
+
"description": "Price per token (0.001 to 0.999)",
|
|
23
|
+
"pattern": "^0\\.[0-9]{1,3}$"
|
|
24
|
+
},
|
|
25
|
+
"amount": {
|
|
26
|
+
"type": "string",
|
|
27
|
+
"description": "Amount in quote token (for BUY) or base token (for SELL), in token units"
|
|
28
|
+
},
|
|
29
|
+
"order_type": {
|
|
30
|
+
"type": "string",
|
|
31
|
+
"enum": ["limit", "market"],
|
|
32
|
+
"default": "limit",
|
|
33
|
+
"description": "Order type: limit (GTC) or market (IOC)"
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"required": ["market_id", "token_id", "side", "price", "amount"],
|
|
37
|
+
"examples": [
|
|
38
|
+
{
|
|
39
|
+
"market_id": 42,
|
|
40
|
+
"token_id": "12345678901234567890",
|
|
41
|
+
"side": "BUY",
|
|
42
|
+
"price": "0.55",
|
|
43
|
+
"amount": "100",
|
|
44
|
+
"order_type": "limit"
|
|
45
|
+
}
|
|
46
|
+
]
|
|
47
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Probable Markets Skill library
|