solana-traderclaw 1.0.36 → 1.0.37
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/bin/installer-step-engine.mjs +1 -1
- package/dist/index.js +98 -7
- package/package.json +1 -1
- package/skills/solana-trader/SKILL.md +25 -18
|
@@ -619,7 +619,7 @@ function traderCronPrescriptiveJobs(agentId) {
|
|
|
619
619
|
schedule: "0 * * * *",
|
|
620
620
|
agentId,
|
|
621
621
|
message:
|
|
622
|
-
"CRON_JOB: alpha_scan — Call solana_scan_launches to find new token launches from the last hour. For each candidate, call solana_token_snapshot to check price, volume, and age. Filter for: 24h volume above 50000 USD, market cap above 10000 USD. For tokens that pass, call solana_token_holders to check holder distribution (skip if top holder owns more than 30 percent), then solana_token_risk to check for mint/freeze authority (hard skip if present). If a token passes all checks,
|
|
622
|
+
"CRON_JOB: alpha_scan — Call solana_scan_launches to find new token launches from the last hour. For each candidate, call solana_token_snapshot to check price, volume, and age. Filter for: 24h volume above 50000 USD, market cap above 10000 USD. For tokens that pass, call solana_token_holders to check holder distribution (skip if top holder owns more than 30 percent), then solana_token_risk to check for mint/freeze authority (hard skip if present). If a token passes all checks, use solana_trade_precheck and consider trade execution using solana_trade_execute. Log all scanned tokens and results using solana_memory_write. Do not ask questions.",
|
|
623
623
|
enabled: true,
|
|
624
624
|
},
|
|
625
625
|
{
|
package/dist/index.js
CHANGED
|
@@ -1254,14 +1254,31 @@ var solanaTraderPlugin = {
|
|
|
1254
1254
|
});
|
|
1255
1255
|
api.registerTool({
|
|
1256
1256
|
name: "solana_trade_precheck",
|
|
1257
|
-
description: "Pre-trade risk check \u2014 validates a proposed trade against risk rules, kill switch, entitlement limits, and on-chain conditions. Returns approved/denied with reasons and capped size. Always call this before executing a trade. Buy: sizeSol required; do not send sizeTokens or sellPct. Sell: send exactly one of sizeTokens or sellPct (not sizeSol). If both sellPct and sizeTokens are sent, sellPct is preferred and sizeTokens is ignored.",
|
|
1257
|
+
description: "Pre-trade risk check \u2014 validates a proposed trade against risk rules, kill switch, entitlement limits, and on-chain conditions. Returns approved/denied with reasons and capped size. Always call this before executing a trade. Buy: sizeSol required; do not send sizeTokens or sellPct. Sell: send exactly one of sizeTokens or sellPct (not sizeSol). If both sellPct and sizeTokens are sent, sellPct is preferred and sizeTokens is ignored. Optional exit fields (trailingStopPct, trailingStop) are accepted to mirror execute payloads; sizing logic ignores them.",
|
|
1258
1258
|
parameters: Type.Object({
|
|
1259
1259
|
tokenAddress: Type.String({ description: "Solana token mint address" }),
|
|
1260
1260
|
side: Type.Union([Type.Literal("buy"), Type.Literal("sell")], { description: "Trade direction" }),
|
|
1261
1261
|
sizeSol: Type.Optional(Type.Number({ description: "Position size in SOL \u2014 required for buy, omit for sell" })),
|
|
1262
1262
|
sellPct: Type.Optional(Type.Number({ description: "Sell percentage 1\u2013100 (100 = full exit) \u2014 sell only; preferred over sizeTokens if both sent" })),
|
|
1263
1263
|
sizeTokens: Type.Optional(Type.Number({ description: "Token amount to sell \u2014 sell only; ignored if sellPct is also provided" })),
|
|
1264
|
-
slippageBps: Type.Optional(Type.Number({ description: "Slippage tolerance in basis points (e.g., 300 = 3%)" }))
|
|
1264
|
+
slippageBps: Type.Optional(Type.Number({ description: "Slippage tolerance in basis points (e.g., 300 = 3%)" })),
|
|
1265
|
+
trailingStopPct: Type.Optional(Type.Number({ description: "Optional \u2014 same as execute; ignored for policy sizing" })),
|
|
1266
|
+
trailingStop: Type.Optional(
|
|
1267
|
+
Type.Object({
|
|
1268
|
+
levels: Type.Array(
|
|
1269
|
+
Type.Object({
|
|
1270
|
+
percentage: Type.Number({ description: "Trailing drawdown % from the armed high once the level is active" }),
|
|
1271
|
+
amount: Type.Optional(Type.Number({ description: "% of position to sell at this level (1\u2013100). Server default 100." })),
|
|
1272
|
+
triggerAboveATH: Type.Optional(
|
|
1273
|
+
Type.Number({
|
|
1274
|
+
description: "Optional. % above session ATH before this level arms. If omitted, API defaults to 100 (2\xD7 ATH)."
|
|
1275
|
+
})
|
|
1276
|
+
)
|
|
1277
|
+
}),
|
|
1278
|
+
{ minItems: 1, maxItems: 5, description: "Multi-level trailing (optional on precheck)" }
|
|
1279
|
+
)
|
|
1280
|
+
})
|
|
1281
|
+
)
|
|
1265
1282
|
}),
|
|
1266
1283
|
execute: wrapExecute(async (_id, params) => {
|
|
1267
1284
|
const body = {
|
|
@@ -1269,6 +1286,13 @@ var solanaTraderPlugin = {
|
|
|
1269
1286
|
side: params.side,
|
|
1270
1287
|
slippageBps: params.slippageBps
|
|
1271
1288
|
};
|
|
1289
|
+
if (params.trailingStopPct !== void 0) {
|
|
1290
|
+
body.trailingStopPct = params.trailingStopPct;
|
|
1291
|
+
}
|
|
1292
|
+
const ts = params.trailingStop;
|
|
1293
|
+
if (ts?.levels && Array.isArray(ts.levels) && ts.levels.length > 0) {
|
|
1294
|
+
body.trailingStop = ts;
|
|
1295
|
+
}
|
|
1272
1296
|
if (params.side === "buy") {
|
|
1273
1297
|
body.sizeSol = params.sizeSol;
|
|
1274
1298
|
} else {
|
|
@@ -1283,7 +1307,7 @@ var solanaTraderPlugin = {
|
|
|
1283
1307
|
});
|
|
1284
1308
|
api.registerTool({
|
|
1285
1309
|
name: "solana_trade_execute",
|
|
1286
|
-
description: "Execute a trade on Solana via the SpyFly bot. Enforces risk rules before proxying to on-chain execution. Returns trade ID, position ID, and transaction signature. IMPORTANT: tpLevels alone (e.g. [10, 15]) means EACH level sells 100% of the position at that gain \u2014 use tpExits for partials (e.g. +10% sell 50%, +15% sell 100%). Buy: sizeSol required; do not send sizeTokens or sellPct. Sell: send exactly one of sizeTokens or sellPct (not sizeSol). If both sellPct and sizeTokens are sent, sellPct is preferred and sizeTokens is ignored.",
|
|
1310
|
+
description: "Execute a trade on Solana via the SpyFly bot. Enforces risk rules before proxying to on-chain execution. Returns trade ID, position ID, and transaction signature. IMPORTANT: tpLevels alone (e.g. [10, 15]) means EACH level sells 100% of the position at that gain \u2014 use tpExits for partials (e.g. +10% sell 50%, +15% sell 100%). Trailing: use `trailingStopPct` for a single simple trailing %, or `trailingStop.levels` (1\u20135) for multi-level trailing with optional `triggerAboveATH` per level (% above session ATH before that level arms; if omitted, server defaults to 100 i.e. 2\xD7 ATH). When both are sent, `trailingStop` wins. Buy: sizeSol required; do not send sizeTokens or sellPct. Sell: send exactly one of sizeTokens or sellPct (not sizeSol). If both sellPct and sizeTokens are sent, sellPct is preferred and sizeTokens is ignored.",
|
|
1287
1311
|
parameters: Type.Object({
|
|
1288
1312
|
tokenAddress: Type.String({ description: "Solana token mint address" }),
|
|
1289
1313
|
side: Type.Union([Type.Literal("buy"), Type.Literal("sell")], { description: "Trade direction" }),
|
|
@@ -1318,7 +1342,37 @@ var solanaTraderPlugin = {
|
|
|
1318
1342
|
{ description: "Multi-level stop-loss with partial exits (optional). Otherwise use slPct for a single full exit." }
|
|
1319
1343
|
)
|
|
1320
1344
|
),
|
|
1321
|
-
trailingStopPct: Type.Optional(
|
|
1345
|
+
trailingStopPct: Type.Optional(
|
|
1346
|
+
Type.Number({
|
|
1347
|
+
description: "Single trailing-stop % (legacy). Ignored if `trailingStop` is provided."
|
|
1348
|
+
})
|
|
1349
|
+
),
|
|
1350
|
+
trailingStop: Type.Optional(
|
|
1351
|
+
Type.Object({
|
|
1352
|
+
levels: Type.Array(
|
|
1353
|
+
Type.Object({
|
|
1354
|
+
percentage: Type.Number({
|
|
1355
|
+
description: "Once armed, sell when price drops this % from the high (trailing drawdown)."
|
|
1356
|
+
}),
|
|
1357
|
+
amount: Type.Optional(
|
|
1358
|
+
Type.Number({
|
|
1359
|
+
description: "% of position to sell when this level fires (1\u2013100). Server default 100."
|
|
1360
|
+
})
|
|
1361
|
+
),
|
|
1362
|
+
triggerAboveATH: Type.Optional(
|
|
1363
|
+
Type.Number({
|
|
1364
|
+
description: "Optional. Session price must reach this % above session ATH before this level arms (e.g. 50 \u2192 1.5\xD7 ATH). If omitted, API defaults to 100 (2\xD7 ATH)."
|
|
1365
|
+
})
|
|
1366
|
+
)
|
|
1367
|
+
}),
|
|
1368
|
+
{
|
|
1369
|
+
minItems: 1,
|
|
1370
|
+
maxItems: 5,
|
|
1371
|
+
description: "Ordered trailing-stop levels (up to 5)."
|
|
1372
|
+
}
|
|
1373
|
+
)
|
|
1374
|
+
})
|
|
1375
|
+
),
|
|
1322
1376
|
managementMode: Type.Optional(
|
|
1323
1377
|
Type.Union([Type.Literal("LOCAL_MANAGED"), Type.Literal("SERVER_MANAGED")], {
|
|
1324
1378
|
description: "Advisory only \u2014 server decides position mode internally. Sent for future compatibility."
|
|
@@ -1337,9 +1391,14 @@ var solanaTraderPlugin = {
|
|
|
1337
1391
|
symbol: params.symbol,
|
|
1338
1392
|
slippageBps: params.slippageBps,
|
|
1339
1393
|
slPct: params.slPct,
|
|
1340
|
-
trailingStopPct: params.trailingStopPct,
|
|
1341
1394
|
managementMode: params.managementMode
|
|
1342
1395
|
};
|
|
1396
|
+
const tsExecute = params.trailingStop;
|
|
1397
|
+
if (tsExecute?.levels && Array.isArray(tsExecute.levels) && tsExecute.levels.length > 0) {
|
|
1398
|
+
body.trailingStop = tsExecute;
|
|
1399
|
+
} else if (params.trailingStopPct !== void 0) {
|
|
1400
|
+
body.trailingStopPct = params.trailingStopPct;
|
|
1401
|
+
}
|
|
1343
1402
|
if (params.side === "buy") {
|
|
1344
1403
|
body.sizeSol = params.sizeSol;
|
|
1345
1404
|
} else {
|
|
@@ -1507,7 +1566,7 @@ var solanaTraderPlugin = {
|
|
|
1507
1566
|
});
|
|
1508
1567
|
api.registerTool({
|
|
1509
1568
|
name: "solana_capital_status",
|
|
1510
|
-
description: "Get your current capital status \u2014 SOL balance, open position count, unrealized PnL, daily notional used, daily loss, and effective limits (
|
|
1569
|
+
description: "Get your current capital status \u2014 SOL balance, open position count, unrealized/realized PnL, daily notional used, daily loss, and effective limits. **PnL:** `totalUnrealizedPnl` / `totalRealizedPnl` are USD (DB); use `totalUnrealizedPnlSol` / `totalRealizedPnlSol` / `totalPnlSol` for SOL (derived via `solPriceUsd`, same as positions API).",
|
|
1511
1570
|
parameters: Type.Object({}),
|
|
1512
1571
|
execute: wrapExecute(
|
|
1513
1572
|
async () => get(`/api/capital/status?walletId=${walletId}`)
|
|
@@ -1515,7 +1574,7 @@ var solanaTraderPlugin = {
|
|
|
1515
1574
|
});
|
|
1516
1575
|
api.registerTool({
|
|
1517
1576
|
name: "solana_positions",
|
|
1518
|
-
description: "List
|
|
1577
|
+
description: "List trading positions with mark-to-market. **PnL:** `realizedPnl` / `unrealizedPnl` are USD as stored; prefer `realizedPnlSol` / `unrealizedPnlSol` when reasoning in SOL. `unrealizedReturnPct` is ROI on cost basis (for sweep-dead-tokens logic). See response `pnlNote`.",
|
|
1519
1578
|
parameters: Type.Object({
|
|
1520
1579
|
status: Type.Optional(Type.String({ description: "Filter by status: 'open', 'closed', or omit for all" }))
|
|
1521
1580
|
}),
|
|
@@ -1525,6 +1584,38 @@ var solanaTraderPlugin = {
|
|
|
1525
1584
|
return get(path2);
|
|
1526
1585
|
})
|
|
1527
1586
|
});
|
|
1587
|
+
api.registerTool({
|
|
1588
|
+
name: "solana_wallet_token_balance",
|
|
1589
|
+
description: "Read on-chain SPL token balance (UI amount) for your trading wallet and a token mint. Same balance path as server exit monitoring (`balanceOf`).",
|
|
1590
|
+
parameters: Type.Object({
|
|
1591
|
+
tokenAddress: Type.String({ description: "SPL token mint address" })
|
|
1592
|
+
}),
|
|
1593
|
+
execute: wrapExecute(
|
|
1594
|
+
async (_id, params) => post("/api/wallet/token-balance", {
|
|
1595
|
+
walletId,
|
|
1596
|
+
tokenAddress: params.tokenAddress
|
|
1597
|
+
})
|
|
1598
|
+
)
|
|
1599
|
+
});
|
|
1600
|
+
api.registerTool({
|
|
1601
|
+
name: "solana_sweep_dead_tokens",
|
|
1602
|
+
description: "Sell 100% of each OPEN position whose unrealizedReturnPct is \u2264 -maxLossPct (default 80), using the same mark-to-market as positions. Use dryRun:true first to list candidates. Executes sequential full exits (sellPct 100). Requires trade:execute scope.",
|
|
1603
|
+
parameters: Type.Object({
|
|
1604
|
+
maxLossPct: Type.Optional(
|
|
1605
|
+
Type.Number({ description: "Threshold: sweep when unrealizedReturnPct <= -maxLossPct (default 80)" })
|
|
1606
|
+
),
|
|
1607
|
+
slippageBps: Type.Optional(Type.Number({ description: "Per-exit slippage in bps (default 300)" })),
|
|
1608
|
+
dryRun: Type.Optional(Type.Boolean({ description: "If true, only return candidate tokens without selling" }))
|
|
1609
|
+
}),
|
|
1610
|
+
execute: wrapExecute(
|
|
1611
|
+
async (_id, params) => post("/api/wallet/sweep-dead-tokens", {
|
|
1612
|
+
walletId,
|
|
1613
|
+
maxLossPct: params.maxLossPct,
|
|
1614
|
+
slippageBps: params.slippageBps,
|
|
1615
|
+
dryRun: params.dryRun
|
|
1616
|
+
})
|
|
1617
|
+
)
|
|
1618
|
+
});
|
|
1528
1619
|
api.registerTool({
|
|
1529
1620
|
name: "solana_funding_instructions",
|
|
1530
1621
|
description: "Get deposit instructions for funding your trading wallet with SOL.",
|
package/package.json
CHANGED
|
@@ -14,7 +14,7 @@ The orchestrator gathers data, enforces execution policy, applies entitlement li
|
|
|
14
14
|
|
|
15
15
|
## How You Access the Orchestrator
|
|
16
16
|
|
|
17
|
-
You interact with the orchestrator **exclusively through plugin tools** (e.g. `solana_system_status`, `
|
|
17
|
+
You interact with the orchestrator **exclusively through plugin tools** (e.g. `solana_system_status`, `solana_scan_hot_pairs`,`solana_scan_launches` , `solana_alpha_signals`, `solana_trade_precheck`, `solana_trade_execute`, etc.). You have no other access method.
|
|
18
18
|
|
|
19
19
|
**Critical rules:**
|
|
20
20
|
- **You do NOT have direct HTTP/API access.** Never attempt to call REST endpoints, use curl/fetch, or construct API URLs. You cannot reach the orchestrator that way.
|
|
@@ -234,8 +234,14 @@ All values are internal targets that must still comply with server policy caps.
|
|
|
234
234
|
| Position size (exploratory) | 3–8% of capital | 5–10% of capital |
|
|
235
235
|
| Max correlated cluster exposure | 40% of capital | 40% of capital |
|
|
236
236
|
| Consecutive losses → kill switch | 5 | 7 |
|
|
237
|
-
|
|
|
238
|
-
|
|
|
237
|
+
| Stop loss (slExits) | -20% on every position | -40% on every position |
|
|
238
|
+
| Trailing Stop loss ("trailingStop": {
|
|
239
|
+
"levels": [
|
|
240
|
+
{ "percentage": 25, "amount": 50 },
|
|
241
|
+
{ "percentage": 35, "amount": 100, "triggerAboveATH": 100 }
|
|
242
|
+
]
|
|
243
|
+
}) where percent is the price decrease from entry price and amount is the size of position in percentage and in token holding | -20% on every position and optional triggerAboveATH | -40% on every position |
|
|
244
|
+
| Multiple Take Profit exits (tpExits) (e.g [{"percent": 100, "amountPct": 30},{ "percent": 200, "amountPct": 100" }], where percent is the price increase from entry price and amountPct is the size of position in percentage and in token holding) | +100–300% (multiple) | +200–500% (multiple) |
|
|
239
245
|
| Exploration ratio | 20% experimental / 80% proven | 50% experimental / 50% proven |
|
|
240
246
|
| Weight evolution (minimum trades) | ≥20 closed trades | ≥20 closed trades |
|
|
241
247
|
| Max weight delta per update | ±0.10 | ±0.15 |
|
|
@@ -330,7 +336,7 @@ There is no context loss from this separation. Cron outputs flow into the persis
|
|
|
330
336
|
↓
|
|
331
337
|
2. Step 0: INTERRUPT CHECK — identify wake-up trigger, check kill switch, check dead money, STRATEGY INTEGRITY CHECK
|
|
332
338
|
↓
|
|
333
|
-
3. Step 1: SCAN — call
|
|
339
|
+
3. Step 1: SCAN — call solana_scan_launches and solana_scan_hot_pairs for broad discovery, process Bitquery subscriptions
|
|
334
340
|
↓
|
|
335
341
|
4. Step 1.5b: ALPHA SIGNALS — poll solana_alpha_signals, score, classify priority
|
|
336
342
|
↓
|
|
@@ -902,10 +908,6 @@ Discovery subscriptions complement — not replace — scan endpoints and alpha
|
|
|
902
908
|
|
|
903
909
|
When multiple paths independently surface the same token = convergence = highest conviction. Log convergence events via `solana_memory_write` with tag `signal_convergence`.
|
|
904
910
|
|
|
905
|
-
**Future enhancement (not yet available):**
|
|
906
|
-
|
|
907
|
-
When `solana_firehose_config` and `solana_firehose_status` tools become available, you will be able to configure advanced filter parameters (volume thresholds, buyer counts, whale detection) directly on the orchestrator or local worker, and check health/stats. For now, use the existing `solana_bitquery_subscribe` with the available template keys and evolve your subscription strategy based on outcomes.
|
|
908
|
-
|
|
909
911
|
---
|
|
910
912
|
|
|
911
913
|
### Step 2: ANALYZE — Deep Dive
|
|
@@ -1128,9 +1130,11 @@ If BUY, you must define before executing:
|
|
|
1128
1130
|
- `tpLevels` — staged take-profit levels as percentages
|
|
1129
1131
|
- HARDENED: `[50, 100, 200]` (patient, ride trends)
|
|
1130
1132
|
- DEGEN: `[25, 50, 100]` (lock gains faster)
|
|
1131
|
-
- `trailingStopPct` — trailing stop
|
|
1132
|
-
|
|
1133
|
-
-
|
|
1133
|
+
- `trailingStopPct` — single trailing stop (% drawdown from session high once active). Legacy/simple path on the server.
|
|
1134
|
+
- **`trailingStop`** (preferred for staging) — `{ levels: [ ... ] }` with **1–5** levels. Each level:
|
|
1135
|
+
- `percentage` — trailing drawdown % from the armed high once that level is active (required).
|
|
1136
|
+
- `amount` — % of position to sell at this level (1–100; server default **100**).
|
|
1137
|
+
- `triggerAboveATH` — **optional.** Price must reach this **% above the session ATH** before this level arms (e.g. `50` → 1.5× ATH). **If omitted, the API defaults to `100` (2× ATH).** Use a smaller value (e.g. `25`) to arm earlier; use `trailingStopPct` instead if you want the simpler single-level trailing that keys off ATH without this gate.
|
|
1134
1138
|
- `managementMode` — LOCAL_MANAGED or SERVER_MANAGED
|
|
1135
1139
|
- `slippageBps` — must scale with liquidity:
|
|
1136
1140
|
- Pool depth > $500K: 100–200 bps
|
|
@@ -1227,7 +1231,7 @@ Call `solana_trade_execute` with:
|
|
|
1227
1231
|
- **For buy:** `sizeSol` (amount in SOL to spend) — required
|
|
1228
1232
|
- **For sell:** `sellPct` (percentage of position to sell, 1–100 where 100 = full exit) **or** `sizeTokens` (exact token count) — one is required. If both sent, `sellPct` wins. Do NOT send `sizeSol` for sells.
|
|
1229
1233
|
- `slippageBps` (scaled to liquidity as defined in your exit plan — hard cap 800bps)
|
|
1230
|
-
- `slPct`, `tpLevels`,
|
|
1234
|
+
- `slPct`, `tpLevels`, **`trailingStopPct` and/or `trailingStop`** (see **Define Exit Plan** above — if both are sent, `trailingStop` wins)
|
|
1231
1235
|
- `managementMode`
|
|
1232
1236
|
|
|
1233
1237
|
Record the returned `tradeId` and `positionId`. You will need these for monitoring and review.
|
|
@@ -1669,7 +1673,6 @@ Your discovery subscriptions (Step 1.75) should evolve alongside your strategy w
|
|
|
1669
1673
|
- **Adjusting discovery subscriptions** (broad, for token detection):
|
|
1670
1674
|
Discovery subscriptions like `pumpFunTokenCreation` and `raydiumNewPools` are fire-and-forget — you set them up once and they run until you unsubscribe. Evolution here means deciding which broad subscriptions to keep vs remove, not changing their parameters.
|
|
1671
1675
|
|
|
1672
|
-
When `solana_firehose_config` becomes available, you will be able to configure advanced filter parameters (volume thresholds, buyer counts, whale detection) on the orchestrator or local worker side without the unsub/resub cycle.
|
|
1673
1676
|
|
|
1674
1677
|
5. Mode switches should trigger subscription review:
|
|
1675
1678
|
- Switching to DEGEN → add more discovery subscriptions, broaden parameters
|
|
@@ -2064,8 +2067,10 @@ All authenticated endpoints use `Authorization: Bearer <accessToken>`.
|
|
|
2064
2067
|
| `POST` | `/api/session/logout` | `refreshToken` | No auth needed. Revokes session |
|
|
2065
2068
|
| `GET` | `/api/wallets` | — | List all wallets. Optional `?refresh=true` |
|
|
2066
2069
|
| `POST` | `/api/wallet/create` | — | Create wallet. Optional: `label`, `publicKey`, `chain` (solana/bsc), `ownerRef`, `includePrivateKey`. Status `201` |
|
|
2067
|
-
| `GET` | `/api/capital/status` | `?walletId=<uuid>` | Wallet capital and daily limits |
|
|
2068
|
-
| `GET` | `/api/wallet/positions` | `?walletId=<uuid>` |
|
|
2070
|
+
| `GET` | `/api/capital/status` | `?walletId=<uuid>` | Wallet capital and daily limits. **PnL:** `totalUnrealizedPnl` / `totalRealizedPnl` are **USD** (stored); `totalUnrealizedPnlSol` / `totalRealizedPnlSol` / `totalPnlSol` are **SOL** derived with `solPriceUsd` (agent-safe). |
|
|
2071
|
+
| `GET` | `/api/wallet/positions` | `?walletId=<uuid>` | Positions. **`realizedPnl` / `unrealizedPnl` = USD** in DB; use **`realizedPnlSol` / `unrealizedPnlSol`** for SOL. `unrealizedReturnPct` = ROI vs cost (for sweep). |
|
|
2072
|
+
| `POST` | `/api/wallet/token-balance` | `walletId`, `tokenAddress` | On-chain SPL **uiAmount** for the wallet (same as server `balanceOf`) |
|
|
2073
|
+
| `POST` | `/api/wallet/sweep-dead-tokens` | `walletId` | Optional: `maxLossPct` (default **80**), `slippageBps`, `dryRun`. Sells **100%** of each **open** position with `unrealizedReturnPct` ≤ **-maxLossPct**. **trade:execute** scope. |
|
|
2069
2074
|
| `GET` | `/api/funding/instructions` | `?walletId=<uuid>` | Deposit instructions |
|
|
2070
2075
|
| `GET` | `/api/killswitch/status` | `?walletId=<uuid>` | Kill switch state |
|
|
2071
2076
|
| `POST` | `/api/killswitch` | `walletId`, `enabled` | Toggle kill switch. Optional: `mode` (TRADES_ONLY / TRADES_AND_STREAMS). **Pro tier required** |
|
|
@@ -2073,7 +2078,7 @@ All authenticated endpoints use `Authorization: Bearer <accessToken>`.
|
|
|
2073
2078
|
| `POST` | `/api/strategy/update` | `walletId`, `featureWeights` | Update weights. Optional: `strategyVersion`, `mode` (HARDENED/DEGEN) |
|
|
2074
2079
|
| `POST` | `/api/thesis/build` | `walletId`, `tokenAddress` | Build full thesis package |
|
|
2075
2080
|
| `POST` | `/api/trade/precheck` | `walletId`, `tokenAddress`, `side` (buy/sell), `slippageBps`. Buy: `sizeSol`. Sell: `sellPct` or `sizeTokens` | Risk/policy check, no execution |
|
|
2076
|
-
| `POST` | `/api/trade/execute` | `walletId`, `tokenAddress`, `side`, `slippageBps`. Buy: `sizeSol`. Sell: `sellPct` or `sizeTokens` | Execute trade. Optional: `symbol`, `tpLevels[]`, `slPct`, `trailingStopPct
|
|
2081
|
+
| `POST` | `/api/trade/execute` | `walletId`, `tokenAddress`, `side`, `slippageBps`. Buy: `sizeSol`. Sell: `sellPct` or `sizeTokens` | Execute trade. Optional: `symbol`, `tpLevels[]`, `slPct`, `trailingStopPct`, `trailingStop: { levels: [{ percentage, amount?, triggerAboveATH? }] }` (1–5 levels; **omitted `triggerAboveATH` defaults to 100** = 2× ATH). Header: `x-idempotency-key` |
|
|
2077
2082
|
| `POST` | `/api/trade/review` | `walletId`, `outcome` (win/loss/neutral), `notes` | Post-trade review. Optional: `tradeId`, `tokenAddress`, `pnlSol`, `tags[]`, `strategyVersion` (strict semver). Status `201` |
|
|
2078
2083
|
| `POST` | `/api/memory/write` | `walletId`, `notes` | Journal entry. Optional: `tokenAddress`, `outcome` (win/loss/neutral), `tags[]`, `strategyVersion` (strict semver). Status `201` |
|
|
2079
2084
|
| `POST` | `/api/memory/search` | `walletId`, `query` | Search memory entries |
|
|
@@ -2701,8 +2706,10 @@ Each user configures their own X/Twitter API developer account tokens in the plu
|
|
|
2701
2706
|
| Thesis | `solana_build_thesis` | Full context package |
|
|
2702
2707
|
| Trade | `solana_trade_precheck` | Pre-trade risk validation |
|
|
2703
2708
|
| Trade | `solana_trade_execute` | Execute trade |
|
|
2704
|
-
| Monitor | `solana_positions` | Position tracking |
|
|
2705
|
-
| Monitor | `solana_capital_status` | Portfolio status |
|
|
2709
|
+
| Monitor | `solana_positions` | Position tracking (USD PnL in DB; use `*PnlSol` fields for SOL) |
|
|
2710
|
+
| Monitor | `solana_capital_status` | Portfolio status (same USD vs SOL split as API) |
|
|
2711
|
+
| Risk | `solana_sweep_dead_tokens` | Full-exit open positions below **-maxLossPct** ROI (default 80%); use `dryRun` first |
|
|
2712
|
+
| Wallet | `solana_wallet_token_balance` | On-chain SPL balance for a mint |
|
|
2706
2713
|
| Review | `solana_trade_review` | Post-trade review |
|
|
2707
2714
|
| Memory | `solana_memory_write` | Write journal entry (deployer profiles, filter evolution, convergence) |
|
|
2708
2715
|
| Memory | `solana_memory_search` | Search memories (check deployer history before profiling) |
|