suprafx-agent-sdk 0.3.1
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/LICENSE +21 -0
- package/README.md +452 -0
- package/dist/bin/suprafx-mcp.d.ts +15 -0
- package/dist/bin/suprafx-mcp.js +238 -0
- package/dist/bin/suprafx-mcp.js.map +1 -0
- package/dist/src/asset-registry.d.ts +61 -0
- package/dist/src/asset-registry.js +118 -0
- package/dist/src/asset-registry.js.map +1 -0
- package/dist/src/client.d.ts +227 -0
- package/dist/src/client.js +282 -0
- package/dist/src/client.js.map +1 -0
- package/dist/src/derive-ids.d.ts +112 -0
- package/dist/src/derive-ids.js +361 -0
- package/dist/src/derive-ids.js.map +1 -0
- package/dist/src/event-bcs.d.ts +341 -0
- package/dist/src/event-bcs.js +767 -0
- package/dist/src/event-bcs.js.map +1 -0
- package/dist/src/index.d.ts +26 -0
- package/dist/src/index.js +26 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/mcp/config.d.ts +32 -0
- package/dist/src/mcp/config.js +101 -0
- package/dist/src/mcp/config.js.map +1 -0
- package/dist/src/mcp/lifecycle.d.ts +109 -0
- package/dist/src/mcp/lifecycle.js +170 -0
- package/dist/src/mcp/lifecycle.js.map +1 -0
- package/dist/src/mcp/preflight.d.ts +36 -0
- package/dist/src/mcp/preflight.js +291 -0
- package/dist/src/mcp/preflight.js.map +1 -0
- package/dist/src/mcp/server.d.ts +20 -0
- package/dist/src/mcp/server.js +235 -0
- package/dist/src/mcp/server.js.map +1 -0
- package/dist/src/mcp/tools.d.ts +51 -0
- package/dist/src/mcp/tools.js +1022 -0
- package/dist/src/mcp/tools.js.map +1 -0
- package/dist/src/sign-event.d.ts +185 -0
- package/dist/src/sign-event.js +331 -0
- package/dist/src/sign-event.js.map +1 -0
- package/dist/src/signer.d.ts +89 -0
- package/dist/src/signer.js +226 -0
- package/dist/src/signer.js.map +1 -0
- package/package.json +65 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Joshua Tobkin / SupraFX
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,452 @@
|
|
|
1
|
+
# suprafx-agent-sdk
|
|
2
|
+
|
|
3
|
+
**SDK + MCP server for building autonomous agents on SupraFX.**
|
|
4
|
+
|
|
5
|
+
SupraFX is a BFT-consensus cross-chain swap protocol. This package lets
|
|
6
|
+
you (or your AI agent) trade on it programmatically — read the
|
|
7
|
+
orderbook, submit RFQs, place quotes, accept fills, all without going
|
|
8
|
+
through the web UI.
|
|
9
|
+
|
|
10
|
+
The conceptual reference is the machine-readable runbook at
|
|
11
|
+
**<https://suprafx.ai/agent-setup.md>** (also served at `/api/agent-setup`).
|
|
12
|
+
This package implements what it describes — and an agent can follow it
|
|
13
|
+
unattended.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Who maintains this
|
|
18
|
+
|
|
19
|
+
This is the **official SupraFX agent SDK**, maintained by
|
|
20
|
+
[Joshua Tobkin](https://github.com/jtobkin), co-founder & CEO of
|
|
21
|
+
[Supra](https://supra.com) (Supra Labs) — the team that builds and
|
|
22
|
+
operates [SupraFX.ai](https://suprafx.ai). The site's
|
|
23
|
+
[`/llms.txt`](https://suprafx.ai/llms.txt) and
|
|
24
|
+
[agent docs](https://suprafx.ai/agents) link back to this repository,
|
|
25
|
+
so you can verify the association in both directions.
|
|
26
|
+
|
|
27
|
+
Not affiliated with "Supra Algo FX" / fxsupra.com (an entity on the UK
|
|
28
|
+
FCA's warning list) — same word, unrelated operation.
|
|
29
|
+
|
|
30
|
+
A word on trust, since this SDK asks an agent to hold a signing key:
|
|
31
|
+
the delegate key is generated and stored **locally** (`~/.suprafx/config.json`,
|
|
32
|
+
mode 0600) and never leaves your machine — the SDK signs envelopes
|
|
33
|
+
locally and submits only the signed bytes. The master wallet bounds
|
|
34
|
+
what a delegate may do with **per-asset caps and a session expiry**,
|
|
35
|
+
enforced on chain. Read the code — it's small on purpose.
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## What's in the box
|
|
40
|
+
|
|
41
|
+
| Piece | What it does | When to use it |
|
|
42
|
+
|---|---|---|
|
|
43
|
+
| `suprafx-agent-sdk` (the JS/TS lib) | Typed client + signer for the SupraFX REST endpoints | You're writing a custom agent in Node/TypeScript |
|
|
44
|
+
| `suprafx-mcp` (the CLI binary) | An MCP server that exposes SupraFX as tools | You're using Claude Desktop, Cursor, Continue, or any MCP-aware AI agent |
|
|
45
|
+
| `cookbook/` | Runnable example agents (incl. a bullish SUPRA accumulator) | You want a starting point you can fork |
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Quick start — MCP server (recommended for AI agents)
|
|
50
|
+
|
|
51
|
+
### 1. Install
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
npm install -g suprafx-agent-sdk
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### 2. Authorize a delegate (one time)
|
|
58
|
+
|
|
59
|
+
The MCP server signs trades with a *delegate* keypair. Your master
|
|
60
|
+
StarKey wallet authorizes it on chain with per-asset caps and a
|
|
61
|
+
session expiry. See
|
|
62
|
+
[the runbook, §4](https://suprafx.ai/agent-setup.md) for the full flow.
|
|
63
|
+
|
|
64
|
+
Short version:
|
|
65
|
+
1. Go to [suprafx.ai](https://suprafx.ai) → connect StarKey
|
|
66
|
+
2. Profile → Delegates → Create Delegate
|
|
67
|
+
3. Click "Generate" — a JSON file with the delegate's private key
|
|
68
|
+
downloads to your machine. **Save this file safely.**
|
|
69
|
+
4. Set per-asset caps + expiry, sign with StarKey.
|
|
70
|
+
|
|
71
|
+
> ### ⚠️ The per-asset cap rule — it is not the intuitive one
|
|
72
|
+
>
|
|
73
|
+
> - **A positive cap is a spend limit.** This is what you normally want.
|
|
74
|
+
> - **An asset left OUT of the cap map cannot be traded at all.** Permission is
|
|
75
|
+
> deny-by-default, and an empty map authorizes nothing.
|
|
76
|
+
> - **A cap of `0` also means "no trades allowed"** for that asset — fail-closed, safe.
|
|
77
|
+
> - **For "effectively unlimited", use `u64::MAX`** (`18446744073709551615`), exported as
|
|
78
|
+
> `MAX_CAP`. Not `0`, and not `u128::MAX` (which overflows the validator's arithmetic).
|
|
79
|
+
>
|
|
80
|
+
> If you have seen older SupraFX material saying a cap of `0` means *unlimited* — **it is
|
|
81
|
+
> wrong.** That described a fail-open bug fixed on 2026-06-07 after a whitehat report; one
|
|
82
|
+
> stale code comment repeated it for months afterwards. The contract is the authority.
|
|
83
|
+
|
|
84
|
+
### 3. Configure the MCP server
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
suprafx-mcp init
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
The wizard prompts for the delegate private key (or the path to the
|
|
91
|
+
JSON file from step 2) and writes `~/.suprafx/config.json` (mode 0600).
|
|
92
|
+
|
|
93
|
+
It also asks for your **master StarKey address**. Save it: balances, locks and open orders
|
|
94
|
+
all live on the master, not the delegate, so without it an agent has to be told the address
|
|
95
|
+
again every session and loses it on any context reset. Headless equivalent:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
export SUPRAFX_DELEGATE_PRIV_HEX=<64-hex-char delegate private key>
|
|
99
|
+
export SUPRAFX_MASTER_ADDRESS=0x<master StarKey address>
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
> **Rotating the delegate?** The MCP server **hot-reloads** the delegate
|
|
103
|
+
> key from `~/.suprafx/config.json` — just edit the file (or re-run
|
|
104
|
+
> `suprafx-mcp init`) and the next tool call picks up the new key
|
|
105
|
+
> automatically; no restart or reconnect needed. `get_my_identity` always
|
|
106
|
+
> reports the **active** delegate, and signed writes always use the
|
|
107
|
+
> current key (so you can't silently keep signing with a rotated-out /
|
|
108
|
+
> revoked key). The server logs `delegate refreshed from config: <old> -> <new>`
|
|
109
|
+
> to stderr when it switches.
|
|
110
|
+
>
|
|
111
|
+
> Notes: rotating by **hand-editing** `config.json`? Write it **atomically**
|
|
112
|
+
> (temp file + `rename`) so the running server never reads a half-written
|
|
113
|
+
> file — `suprafx-mcp init` already does this. `SUPRAFX_DELEGATE_PRIV_HEX`
|
|
114
|
+
> env still takes **precedence** and is fixed for the process (file edits
|
|
115
|
+
> are ignored while it's set). Changing `baseUrl` needs a **restart** —
|
|
116
|
+
> only the delegate key is hot-reloaded.
|
|
117
|
+
|
|
118
|
+
### 4. Wire it into your agent
|
|
119
|
+
|
|
120
|
+
**Claude Desktop** — edit `~/Library/Application Support/Claude/claude_desktop_config.json`:
|
|
121
|
+
|
|
122
|
+
```json
|
|
123
|
+
{
|
|
124
|
+
"mcpServers": {
|
|
125
|
+
"suprafx": {
|
|
126
|
+
"command": "suprafx-mcp"
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Restart Claude Desktop. Tools appear in the model's palette.
|
|
133
|
+
|
|
134
|
+
**Cursor / Continue** — see their respective MCP setup guides; they
|
|
135
|
+
use the same JSON config format.
|
|
136
|
+
|
|
137
|
+
### 5. Trade
|
|
138
|
+
|
|
139
|
+
Just ask the agent to trade. Examples:
|
|
140
|
+
|
|
141
|
+
> *"Check my SupraFX balances."*
|
|
142
|
+
>
|
|
143
|
+
> *"What's on the ETH/USDC orderbook right now?"*
|
|
144
|
+
>
|
|
145
|
+
> *"Submit an RFQ to sell 0.1 ETH for USDC at $2400 reference."*
|
|
146
|
+
>
|
|
147
|
+
> *"Watch for ETH/USDC quotes and tell me if anything looks good."*
|
|
148
|
+
|
|
149
|
+
The agent calls the right tools, signs with your delegate key locally,
|
|
150
|
+
and submits to chain. You see the results in the chat.
|
|
151
|
+
|
|
152
|
+
### Read-only mode
|
|
153
|
+
|
|
154
|
+
If you skip the delegate-key setup, the MCP server runs read-only —
|
|
155
|
+
only the read tools are exposed. Useful for monitoring agents that
|
|
156
|
+
don't need to trade.
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## Quick start — Library use (for custom Node agents)
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
npm install suprafx-agent-sdk
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
```ts
|
|
167
|
+
import { SupraFxClient, DelegateSigner } from "suprafx-agent-sdk";
|
|
168
|
+
|
|
169
|
+
const client = new SupraFxClient(); // defaults to suprafx.ai
|
|
170
|
+
const signer = new DelegateSigner({
|
|
171
|
+
delegatePrivKeyHex: process.env.SUPRAFX_DELEGATE_PRIV_HEX!,
|
|
172
|
+
client,
|
|
173
|
+
});
|
|
174
|
+
await signer.loadSequenceFromChain();
|
|
175
|
+
|
|
176
|
+
// Read.
|
|
177
|
+
const balances = await client.getBalances("0x<master-address>");
|
|
178
|
+
const orderbook = await client.getOrderbook({ pair: "ETH/USDC" });
|
|
179
|
+
|
|
180
|
+
// Write.
|
|
181
|
+
const result = await signer.placeQuote({
|
|
182
|
+
rfq_id: rfqIdBytes,
|
|
183
|
+
quote_id: randomBytes(16),
|
|
184
|
+
rate: toRateBFT(2400, 18, 6),
|
|
185
|
+
fill_size: toMicroUnits(0.1, 18),
|
|
186
|
+
});
|
|
187
|
+
console.log(result.ok ? `committed at batch ${result.batch}` : `rejected: ${result.detail}`);
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
See [`cookbook/`](./cookbook/) for full runnable examples.
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## Tool reference (MCP)
|
|
195
|
+
|
|
196
|
+
### Read tools (always available)
|
|
197
|
+
|
|
198
|
+
| Tool | What it does |
|
|
199
|
+
|---|---|
|
|
200
|
+
| `get_setup_status` | Readiness report for config, delegate, chain, policy, sequence, and master balances |
|
|
201
|
+
| `get_chain_info` | Chain ID hash + threshold |
|
|
202
|
+
| `get_current_batch` | Current committed batch number |
|
|
203
|
+
| `get_sequence_number({address})` | Next strict-monotonic seq for an address |
|
|
204
|
+
| `list_assets` | All supported assets with decimals |
|
|
205
|
+
| `get_balances({address?})` | A master's available + locked balances per asset. `address` optional once a master is configured. **The tie-breaker read whenever a write reports `unknown`** |
|
|
206
|
+
| `get_orderbook({pair?, status?, limit?})` | Open RFQs (or filter by status), each with the quotes placed on it |
|
|
207
|
+
| `get_my_identity` | Your delegate address and current seq |
|
|
208
|
+
| `preflight({pair?})` | **Run this on connect.** Nine checks with the action that clears each: venue reachable, venue batch actually advancing (not just the L1), assets resolving to real ids, oracle freshness, custody, sequence drift, funding, stale own-RFQs still holding collateral |
|
|
209
|
+
| `list_my_open_orders({address?})` | **Every order of yours still holding locked funds** — RFQs and quotes — each with the exact call that releases it. The answer to "where did my money go" |
|
|
210
|
+
| `get_deposit_status({chain?, tx_hash?, address?})` | **Is my deposit still crediting, or did it fail?** One deposit by `chain` + `tx_hash`, or every claim of the master. `state` is `pending` \| `credited` \| `rejected` \| `expired`; `stale: true` on a pending claim is the fresh-wallet delay (15+ min), **not** a failure — wait and re-read, never re-send. Act on `state`, not `status`: when `reconciled_from_ledger` is true the venue's ledger proved the money arrived and the claim record is simply stale |
|
|
211
|
+
| `get_master_address` | The master address this server is configured with (the delegate has no balances of its own) |
|
|
212
|
+
| `get_oracle_price({pair})` | Venue fair value **with the quote's age** and a `stale` flag. Never quote against a stale oracle |
|
|
213
|
+
|
|
214
|
+
### Write tools (require configured delegate key)
|
|
215
|
+
|
|
216
|
+
| Tool | What it does |
|
|
217
|
+
|---|---|
|
|
218
|
+
| `submit_rfq({sell_chain, sell_token, buy_chain, buy_token, size, reference_price, auto_accept?, auto_accept_target_rate?, allow_partial_fills?, min_fill_size?, ...})` | Become a taker — open a new RFQ. `auto_accept` auto-settles qualifying quotes; `allow_partial_fills` lets it fill in slices (see below) |
|
|
219
|
+
| `place_quote({rfq_id, fill_size, total_payment})` | Become a maker — quote on an existing RFQ |
|
|
220
|
+
| `accept_quote({quote_id, trade_id?})` | As taker, accept a maker's quote |
|
|
221
|
+
| `cancel_rfq({rfq_id, reason?})` | As taker, cancel your open RFQ |
|
|
222
|
+
| `withdraw_quote({quote_id})` | As maker, pull your pending quote |
|
|
223
|
+
|
|
224
|
+
All inputs use human-friendly numbers (e.g. `size: 0.5` for 0.5 ETH).
|
|
225
|
+
The tool converts to the chain's wire format internally.
|
|
226
|
+
|
|
227
|
+
Every write tool also takes **`acknowledged: true`** — see *Guarded mode* below.
|
|
228
|
+
|
|
229
|
+
### Outcomes: `ok: true` is not proof a trade landed
|
|
230
|
+
|
|
231
|
+
A write is accepted at *ingress* before the validators apply it. It can be accepted there and
|
|
232
|
+
still be rejected on chain — inactive delegate, cap exhausted, wrong pair, replayed sequence —
|
|
233
|
+
and nothing tells you. So **every write returns a `lifecycle`**:
|
|
234
|
+
|
|
235
|
+
| `lifecycle` | `applied` | Meaning | What to do |
|
|
236
|
+
|---|---|---|---|
|
|
237
|
+
| `applied` | `true` | A state read **confirmed** it landed | Proceed |
|
|
238
|
+
| `rejected` | `false` | Ingress refused it; nothing committed | Fix and retry |
|
|
239
|
+
| `unknown` | `null` | Accepted, but not confirmed inside the poll window | **Do NOT retry blindly.** Read state back with `get_balances` / `list_my_open_orders` |
|
|
240
|
+
|
|
241
|
+
**`unknown` is not a failure — it means "I do not know yet".** A blind retry on `unknown` is
|
|
242
|
+
how you end up holding two positions. Tune the confirmation window with
|
|
243
|
+
`SUPRAFX_APPLY_POLL_MS` (default `12000`; `0` disables confirmation).
|
|
244
|
+
|
|
245
|
+
### Guarded mode, and limiting what an agent can do
|
|
246
|
+
|
|
247
|
+
The server starts **guarded**: every money tool requires `acknowledged: true` on the call.
|
|
248
|
+
Key-presence alone is not a safety stop — without this, once a key loads, `accept_quote` is as
|
|
249
|
+
ungated as `get_orderbook`.
|
|
250
|
+
|
|
251
|
+
| Launch | Effect |
|
|
252
|
+
|---|---|
|
|
253
|
+
| `suprafx-mcp` | **Guarded** (default) — each write needs `acknowledged: true` |
|
|
254
|
+
| `suprafx-mcp --allow-dangerous` | **Autonomous** — no per-call acknowledgement, for unattended loops |
|
|
255
|
+
| `suprafx-mcp --tools=read` | Keyed but **zero write tools exposed** — a monitor that cannot trade |
|
|
256
|
+
| `suprafx-mcp --tools=read,cancel` | Reads plus **release-only** (`cancel_rfq`, `withdraw_quote`) |
|
|
257
|
+
|
|
258
|
+
`--allow-dangerous` is an operator decision, made once, in the open. Env equivalents:
|
|
259
|
+
`SUPRAFX_ALLOW_DANGEROUS=1`, `SUPRAFX_TOOLS=read,cancel`.
|
|
260
|
+
|
|
261
|
+
### Troubleshooting
|
|
262
|
+
|
|
263
|
+
Start with `get_setup_status`. MCP write failures keep the standard error
|
|
264
|
+
envelope and include a stable `code`, actionable `detail`, and copy-pasteable
|
|
265
|
+
`remedy`:
|
|
266
|
+
|
|
267
|
+
| Code | Remedy |
|
|
268
|
+
|---|---|
|
|
269
|
+
| `NO_DELEGATE_CONFIGURED` | Run `suprafx-mcp init` or set `SUPRAFX_DELEGATE_PRIV_HEX`, then retry. |
|
|
270
|
+
| `NETWORK_FAILURE` | Run `get_setup_status`, verify `SUPRAFX_BASE_URL` and connectivity, then retry. |
|
|
271
|
+
| `SEQUENCE_MISMATCH` | Run `get_setup_status`, re-fetch the delegate sequence number, then retry. |
|
|
272
|
+
| `ENVELOPE_REJECTED` | Run `get_setup_status`, fix the policy or balance issue reported in `detail`, then retry. |
|
|
273
|
+
| `TOOL_EXECUTION_FAILED` | Run `get_setup_status`, correct the tool inputs shown in `detail`, then retry. |
|
|
274
|
+
| `NEEDS_ACKNOWLEDGEMENT` | Guarded mode. Re-send the identical call with `acknowledged: true`, or have the operator relaunch with `--allow-dangerous`. |
|
|
275
|
+
| `NO_DELEGATE_CONFIGURED` | Write tool with no key. Run `suprafx-mcp init` (or set `SUPRAFX_DELEGATE_PRIV_HEX`) and reconnect. |
|
|
276
|
+
| `NO_MASTER_ADDRESS` | Set `SUPRAFX_MASTER_ADDRESS`, or pass `address` — see `get_master_address`. |
|
|
277
|
+
| `TOOL_NOT_EXPOSED` | The server was launched with `--tools=…` excluding this class. Only the operator can widen it. |
|
|
278
|
+
| `RFQ_DEAD_ON_ARRIVAL` | The RFQ could never fill (past expiry, `min_fill_size > size`, or `size <= 0`) but would still lock collateral. Fix the inputs. |
|
|
279
|
+
| `RFQ_NOT_OPEN` | The parent RFQ matched, expired or was cancelled. Re-read `get_orderbook`. |
|
|
280
|
+
|
|
281
|
+
### Auto-accept (taker pre-commit)
|
|
282
|
+
|
|
283
|
+
`submit_rfq({auto_accept: true, auto_accept_target_rate: R})` makes the
|
|
284
|
+
chain auto-settle the first maker quote at or better than `R`, in the
|
|
285
|
+
same batch the quote lands — no `accept_quote` needed, taker can be
|
|
286
|
+
offline. `R` is a **cryptographic price floor**: the chain will never
|
|
287
|
+
fill (or let anyone accept) a quote worse than it. For makers, quoting
|
|
288
|
+
*below* an auto-accept RFQ's target is a dead end — quote at or above it
|
|
289
|
+
to win and settle instantly. (`auto_accept: false`, the default, keeps
|
|
290
|
+
the taker in control: quotes accumulate and you `accept_quote` manually.)
|
|
291
|
+
|
|
292
|
+
### Partial fills
|
|
293
|
+
|
|
294
|
+
`submit_rfq({allow_partial_fills: true, min_fill_size: M})` lets makers
|
|
295
|
+
fill a *slice* of the RFQ (≥ `M`) instead of all-or-nothing. After a
|
|
296
|
+
partial fill the RFQ stays open with a smaller `remaining_size` and keeps
|
|
297
|
+
taking quotes until full or cancelled. A maker who over-quotes is
|
|
298
|
+
capped-and-filled to what remains — never over-locked.
|
|
299
|
+
|
|
300
|
+
**Compose them.** `auto_accept: true` + `allow_partial_fills: true` is a
|
|
301
|
+
resting limit order: one large RFQ that auto-settles every qualifying
|
|
302
|
+
slice at or above your floor, incrementally, until full — taker offline.
|
|
303
|
+
See `cookbook/04-auto-accept-partial-taker.ts`.
|
|
304
|
+
|
|
305
|
+
### Order lifecycle (cancel & withdraw)
|
|
306
|
+
|
|
307
|
+
- **`cancel_rfq({rfq_id, reason?})`** (taker) — pull an open RFQ; the
|
|
308
|
+
earmark is released and all its pending quotes are refunded + rejected.
|
|
309
|
+
- **`withdraw_quote({quote_id})`** (maker) — pull a pending quote; the
|
|
310
|
+
lock is released. There's no "edit quote": to reprice, withdraw then
|
|
311
|
+
`place_quote` again. Refresh stale quotes promptly so you aren't picked
|
|
312
|
+
off at a price the market has left.
|
|
313
|
+
|
|
314
|
+
### Fees
|
|
315
|
+
|
|
316
|
+
**Trade fees are volume-tiered** on 30-day volume. The taker pays; the maker is free and
|
|
317
|
+
becomes **paid** at volume. Netted at settlement — this does not change the on-chain rate,
|
|
318
|
+
so price your quotes accordingly.
|
|
319
|
+
|
|
320
|
+
| 30-day volume | Taker | Maker |
|
|
321
|
+
|---|---|---|
|
|
322
|
+
| < $100k | 5 bps | 0 |
|
|
323
|
+
| $100k – $1M | 4 bps | 0 |
|
|
324
|
+
| $1M – $10M | 3.5 bps | **−0.5 bps (rebate)** |
|
|
325
|
+
| $10M – $50M | 3 bps | **−1 bps (rebate)** |
|
|
326
|
+
| > $50M | 2.5 bps | **−1.5 bps (rebate)** |
|
|
327
|
+
|
|
328
|
+
**Withdrawal fee:** **$2 USD worth of SUPRA plus a 20% margin**, always paid in SUPRA even for
|
|
329
|
+
non-SUPRA assets, quoted at spot — so **the SUPRA amount moves with the price**. Read the live
|
|
330
|
+
number before quoting one to anybody:
|
|
331
|
+
|
|
332
|
+
```bash
|
|
333
|
+
curl https://suprafx.ai/api/platform/withdraw/fee-quote
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
Master-side only (there is no withdraw tool, and the delegate key cannot withdraw) — but budget
|
|
337
|
+
for it to realize PnL.
|
|
338
|
+
|
|
339
|
+
> Earlier versions of this README said the withdrawal fee was "a flat 4000 SUPRA" and that
|
|
340
|
+
> makers earn a flat 1 bp rebate. **Both were wrong.** The fee has been USD-denominated since
|
|
341
|
+
> the $2 policy landed, and the maker rebate only starts above $1M of 30-day volume. Never
|
|
342
|
+
> quote a fixed token amount from memory.
|
|
343
|
+
|
|
344
|
+
---
|
|
345
|
+
|
|
346
|
+
## Security
|
|
347
|
+
|
|
348
|
+
**The delegate private key stays on your machine.** The MCP server
|
|
349
|
+
runs as a local subprocess; the transport is stdio. The key is never
|
|
350
|
+
sent over the wire.
|
|
351
|
+
|
|
352
|
+
**On-chain authorization is bounded.** The master's
|
|
353
|
+
`DelegatePolicyCreated` event sets per-asset caps, allowed pairs,
|
|
354
|
+
allowed roles, and an `expires_at_batch` deadline. A leaked delegate
|
|
355
|
+
key can do at most what the policy allows, and is automatically
|
|
356
|
+
expired at the deadline regardless of master action.
|
|
357
|
+
|
|
358
|
+
**Revocation is instant.** Master goes to Profile → Delegates →
|
|
359
|
+
Deactivate, signs once with StarKey. The on-chain policy flips
|
|
360
|
+
inactive. Every subsequent envelope from the delegate is rejected.
|
|
361
|
+
|
|
362
|
+
**File mode 0600.** `~/.suprafx/config.json` is created mode `0600`
|
|
363
|
+
(owner read/write only). If you copy it elsewhere, preserve the mode.
|
|
364
|
+
|
|
365
|
+
---
|
|
366
|
+
|
|
367
|
+
## Cookbook
|
|
368
|
+
|
|
369
|
+
[`cookbook/`](./cookbook/) ships runnable examples. **Most agents here
|
|
370
|
+
are bullish SUPRA, so the examples are framed around _accumulating_
|
|
371
|
+
SUPRA (buying it) — see the direction primer in the cookbook README so
|
|
372
|
+
you never accidentally quote the sell side.** Every agent defaults to
|
|
373
|
+
`DRY_RUN` and only trades with `LIVE=1`.
|
|
374
|
+
|
|
375
|
+
- **`05-bullish-supra-accumulator.ts`** ⭐ — The flagship. Watches
|
|
376
|
+
`SUPRA/USDC`, `SUPRA/USDT`, `SUPRA/ETH` for sellers and **buys**
|
|
377
|
+
SUPRA at up to the oracle price + a small premium, sized to balance.
|
|
378
|
+
- **`00-generate-delegate-key.ts`** — Generate a delegate keypair
|
|
379
|
+
locally (private key never touches the browser); paste only the
|
|
380
|
+
public key into the delegate form.
|
|
381
|
+
- **`01-passive-quoter.ts`** — Simplest maker: quote reference ± a
|
|
382
|
+
fixed spread on every RFQ for a pair.
|
|
383
|
+
- **`02-inventory-aware-quoter.ts`** — Tracks balances, refuses
|
|
384
|
+
overexposure, widens spread as inventory tilts.
|
|
385
|
+
- **`03-counter-arb-taker.ts`** — The taker round-trip (submit RFQ →
|
|
386
|
+
accept a quote with edge ≥ threshold → timeout-and-cancel). Point
|
|
387
|
+
`BUY_TOKEN=SUPRA` to take the buy side.
|
|
388
|
+
- **`04-auto-accept-partial-taker.ts`** — A resting limit order:
|
|
389
|
+
`auto_accept` + `allow_partial_fills` on one RFQ, auto-filling in
|
|
390
|
+
slices at or above your floor, offline, with cancel-on-deadline.
|
|
391
|
+
|
|
392
|
+
Run the flagship with
|
|
393
|
+
`MASTER_ADDRESS=0x... npx tsx cookbook/05-bullish-supra-accumulator.ts`
|
|
394
|
+
(after `npm install` in this directory) — it dry-runs by default.
|
|
395
|
+
|
|
396
|
+
---
|
|
397
|
+
|
|
398
|
+
## The machine-readable runbook
|
|
399
|
+
|
|
400
|
+
An agent can set itself up with no human walkthrough. Point it at:
|
|
401
|
+
|
|
402
|
+
```
|
|
403
|
+
https://suprafx.ai/agent-setup.md (or https://suprafx.ai/api/agent-setup)
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
Or just paste this to your coding agent:
|
|
407
|
+
|
|
408
|
+
> *Set up SupraFX for me: fetch https://suprafx.ai/agent-setup.md and follow it.*
|
|
409
|
+
|
|
410
|
+
It covers install, read-only verification, the two operator steps that need a wallet, the
|
|
411
|
+
cap rule above, the lifecycle contract, and the known failure modes with the check that
|
|
412
|
+
clears each.
|
|
413
|
+
|
|
414
|
+
## Hosting and discovery
|
|
415
|
+
|
|
416
|
+
This package is published as **`suprafx-agent-sdk`** on npm. The
|
|
417
|
+
canonical landing page is **https://suprafx.ai/agents**, which links
|
|
418
|
+
out to:
|
|
419
|
+
|
|
420
|
+
- This README + the rest of the cookbook
|
|
421
|
+
- The machine-readable runbook at <https://suprafx.ai/agent-setup.md>
|
|
422
|
+
- The source repo on GitHub
|
|
423
|
+
- The npm package page
|
|
424
|
+
|
|
425
|
+
---
|
|
426
|
+
|
|
427
|
+
## License
|
|
428
|
+
|
|
429
|
+
MIT. See LICENSE.
|
|
430
|
+
|
|
431
|
+
---
|
|
432
|
+
|
|
433
|
+
## Versioning + chain compatibility
|
|
434
|
+
|
|
435
|
+
This package targets the live `suprafx.ai` deployment. Major version
|
|
436
|
+
bumps may add fields to the BCS payloads but won't break existing
|
|
437
|
+
encoders. The chain id hash (`get_chain_info → chainIdHashHex`)
|
|
438
|
+
changes on a genesis swap — rare; one happened during the 2026-05-28
|
|
439
|
+
mainnet launch.
|
|
440
|
+
|
|
441
|
+
There is no static release label to pin against — validators roll
|
|
442
|
+
continuously. The authoritative version signal is the live chain id
|
|
443
|
+
hash from `get_chain_info` (`chainIdHashHex`); treat that as the source
|
|
444
|
+
of truth, not any version string. Mainnet Beta runs at roughly ~1
|
|
445
|
+
batch/sec.
|
|
446
|
+
|
|
447
|
+
---
|
|
448
|
+
|
|
449
|
+
## Support
|
|
450
|
+
|
|
451
|
+
Open an issue on the repo, or reach out via the Discord linked from
|
|
452
|
+
`suprafx.ai`.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* `suprafx-mcp` CLI entry point.
|
|
4
|
+
*
|
|
5
|
+
* Two modes:
|
|
6
|
+
* - `suprafx-mcp init` — interactive setup wizard. Writes
|
|
7
|
+
* `~/.suprafx/config.json` with the user's delegate priv key
|
|
8
|
+
* after they paste it in or point to a JSON file the dApp
|
|
9
|
+
* downloaded.
|
|
10
|
+
* - `suprafx-mcp` (no args) — runs the MCP server over stdio.
|
|
11
|
+
* Designed to be invoked by Claude Desktop / Cursor / Continue
|
|
12
|
+
* as a subprocess. Reads stdin for JSON-RPC, writes stdout for
|
|
13
|
+
* responses, stderr for log lines.
|
|
14
|
+
*/
|
|
15
|
+
export {};
|