solana-traderclaw 1.0.59 → 1.0.60
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/config/gateway-v1-upgraded.json5 +4 -4
- package/config/gateway-v1.json5 +3 -3
- package/dist/{chunk-T4YWGIIR.js → chunk-VUIYNUGF.js} +1 -1
- package/dist/index.js +138 -3
- package/dist/src/http-client.js +1 -1
- package/package.json +1 -1
- package/skills/solana-trader/SKILL.md +13 -0
- package/skills/solana-trader/workspace/TOOLS.md +7 -2
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
agentId: "main",
|
|
39
39
|
sessionTarget: "isolated",
|
|
40
40
|
delivery: { mode: "none" },
|
|
41
|
-
message: "CRON_JOB: source_reputation_recalc\n\nStep 1: Call solana_alpha_sources to get per-source performance stats.\n\nStep 2: Call solana_alpha_history to get recent signal history.\n\nStep 3: Call solana_trades to get recent trade outcomes. Cross-reference each trade to its originating signal source.\n\nStep 4: For each source, calculate: win rate, average PnL, signal-to-trade conversion rate.\n\nStep 5: Assign tier rankings:\n- TIER-1 (LOCK): Win rate above 60% AND 5+ trades AND positive avg PnL\n- TIER-2 (CONDITIONAL): Win rate 30-60% OR fewer than 5 trades\n- TIER-3 (BLACKLIST): Win rate below 30% with 5+ trades\n\nStep 6: Write scorecard to memory using solana_memory_write with tag 'source_reputation'.\n\nFORMATTING RULES:\n- Every token reference MUST use SYMBOL (full_CA) format.\n- Do not execute trades. Do not ask questions.",
|
|
41
|
+
message: "CRON_JOB: source_reputation_recalc\n\nStep 1: Call solana_alpha_sources to get per-source performance stats (signal count, conversion rate, avg score).\n\nStep 2: Call solana_alpha_history to get recent signal history with scores and source identifiers.\n\nStep 3: Call solana_trades to get recent trade outcomes. Cross-reference each trade back to its originating signal source.\n\nStep 4: For each source, calculate: win rate (trades that hit TP vs SL), average PnL per trade, signal-to-trade conversion rate.\n\nStep 5: Assign tier rankings:\n- TIER-1 (LOCK): Win rate above 60% AND 5+ trades AND positive avg PnL\n- TIER-2 (CONDITIONAL): Win rate 30-60% OR fewer than 5 trades\n- TIER-3 (BLACKLIST): Win rate below 30% with 5+ trades\n\nStep 6: Write scorecard to memory using solana_memory_write with tag 'source_reputation'.\n\nFORMATTING RULES:\n- Every token reference MUST use SYMBOL (full_CA) format.\n- Do not execute trades. Do not ask questions.",
|
|
42
42
|
enabled: true
|
|
43
43
|
},
|
|
44
44
|
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
agentId: "main",
|
|
50
50
|
sessionTarget: "isolated",
|
|
51
51
|
delivery: { mode: "none" },
|
|
52
|
-
message: "CRON_JOB: portfolio_risk_audit\n\nStep 1: Call solana_capital_status
|
|
52
|
+
message: "CRON_JOB: portfolio_risk_audit\n\nStep 1: Call solana_capital_status to get wallet balance and portfolio value.\n\nStep 2: Call solana_positions to get all open positions with entry prices and sizes.\n\nStep 3: For each open position, call solana_token_snapshot to get current price, 24h volume, and market cap.\n\nStep 4: Run concentration check — flag WARNING if any single position exceeds 30 percent of total portfolio value, CRITICAL if above 50 percent.\n\nStep 5: Run exposure check — flag WARNING if total exposure exceeds 50 percent of wallet balance, CRITICAL if above 75 percent.\n\nStep 6: Run drawdown check — CRITICAL if portfolio drawdown exceeds 25 percent from peak capital.\n\nStep 7: Calculate portfolio heat (sum of all position risk scores). Flag WARNING above 50 percent, CRITICAL above 75 percent.\n\nStep 8: Run liquidity check — WARNING if any position exceeds 2 percent of its pool depth.\n\nStep 9: Check solana_killswitch_status.\n\nStep 10: Write risk report via solana_memory_write with tag 'risk_audit'.\n\nFORMATTING RULES:\n- Every token reference MUST use SYMBOL (full_CA) format.\n- Do not execute trades. Do not ask questions.",
|
|
53
53
|
enabled: true
|
|
54
54
|
},
|
|
55
55
|
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
agentId: "main",
|
|
61
61
|
sessionTarget: "isolated",
|
|
62
62
|
delivery: { mode: "none" },
|
|
63
|
-
message: "CRON_JOB: meta_rotation_analysis\n\nStep 1: Call solana_scan_launches to get recent launches (last 3-6 hours).\n\nStep 2: Categorize each token by narrative cluster: AI/Agents, Animal Memes, Political, Celebrity/IP, DeFi, Gaming, Culture/Humor, Other.\n\nStep 3: For each cluster, aggregate: token count, total volume, average market cap.\n\nStep 4: Call solana_memory_search for 'meta_rotation' to compare with prior scan.\n\nStep 5: Classify each narrative: GAINING, SATURATED, COOLING, DORMANT.\n\nStep 6: Write rotation report via solana_memory_write with tag 'meta_rotation'.\n\nFORMATTING RULES:\n- Every token reference MUST use SYMBOL (full_CA) format.\n- Do not execute trades. Do not ask questions.",
|
|
63
|
+
message: "CRON_JOB: meta_rotation_analysis\n\nStep 0: Call x_search_tweets with queries: 'solana memecoin', 'pump fun gem', 'sol alpha'. Note which token names and narratives appear most frequently in the last 3 hours. Use this social signal to validate or challenge the on-chain data in the following steps.\n\nStep 1: Call solana_scan_launches to get recent token launches (last 3-6 hours).\n\nStep 2: Categorize each token by narrative cluster: AI/Agents, Animal Memes, Political, Celebrity/IP, DeFi, Gaming, Culture/Humor, Other.\n\nStep 3: For each cluster, aggregate: token count, total volume, average market cap.\n\nStep 4: Call solana_memory_search for 'meta_rotation' to compare with prior scan.\n\nStep 5: Classify each narrative: GAINING, SATURATED, COOLING, DORMANT.\n\nStep 6: Write rotation report via solana_memory_write with tag 'meta_rotation'.\n\nFORMATTING RULES:\n- Every token reference MUST use SYMBOL (full_CA) format.\n- Do not execute trades. Do not ask questions.",
|
|
64
64
|
enabled: true
|
|
65
65
|
},
|
|
66
66
|
|
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
agentId: "main",
|
|
81
81
|
sessionTarget: "isolated",
|
|
82
82
|
delivery: { mode: "none" },
|
|
83
|
-
message: "CRON_JOB: subscription_cleanup\n\nStep 1: Call solana_positions to get open
|
|
83
|
+
message: "CRON_JOB: subscription_cleanup\n\nStep 1: Call solana_positions to get all open positions and extract their contract addresses.\n\nStep 2: Call solana_bitquery_subscriptions to list all active Bitquery subscriptions. If this call returns an AUTH_SCOPE_MISSING error, log the error to memory and stop gracefully — do not retry or error out.\n\nStep 3: For each active subscription, check if the associated token CA still has an open position. Build two lists: 'matched' (has position) and 'orphaned' (no position).\n\nStep 4: Unsubscribe orphans via solana_bitquery_unsubscribe.\n\nStep 5: Reopen subscriptions nearing 24h expiry via solana_bitquery_subscription_reopen.\n\nStep 6: Write summary via solana_memory_write with tag 'subscription_cleanup'.\n\nFORMATTING RULES:\n- Every token reference MUST use SYMBOL (full_CA) format.\n- Do not execute trades. Do not ask questions.",
|
|
84
84
|
enabled: true
|
|
85
85
|
},
|
|
86
86
|
|
package/config/gateway-v1.json5
CHANGED
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
agentId: "main",
|
|
39
39
|
sessionTarget: "isolated",
|
|
40
40
|
delivery: { mode: "none" },
|
|
41
|
-
message: "CRON_JOB: source_reputation_recalc\n\nStep 1: Call solana_alpha_sources to get per-source performance stats.\n\nStep 2: Call solana_alpha_history to get recent signal history.\n\nStep 3: Call solana_trades to get recent trade outcomes. Cross-reference each trade to its originating signal source.\n\nStep 4: For each source, calculate: win rate, average PnL, signal-to-trade conversion rate.\n\nStep 5: Assign tier rankings:\n- TIER-1 (LOCK): Win rate above 60% AND 5+ trades AND positive avg PnL\n- TIER-2 (CONDITIONAL): Win rate 30-60% OR fewer than 5 trades\n- TIER-3 (BLACKLIST): Win rate below 30% with 5+ trades\n\nStep 6: Write scorecard to memory using solana_memory_write with tag 'source_reputation'.\n\nFORMATTING RULES:\n- Every token reference MUST use SYMBOL (full_CA) format.\n- Do not execute trades. Do not ask questions.",
|
|
41
|
+
message: "CRON_JOB: source_reputation_recalc\n\nStep 1: Call solana_alpha_sources to get per-source performance stats (signal count, conversion rate, avg score).\n\nStep 2: Call solana_alpha_history to get recent signal history with scores and source identifiers.\n\nStep 3: Call solana_trades to get recent trade outcomes. Cross-reference each trade back to its originating signal source.\n\nStep 4: For each source, calculate: win rate (trades that hit TP vs SL), average PnL per trade, signal-to-trade conversion rate.\n\nStep 5: Assign tier rankings:\n- TIER-1 (LOCK): Win rate above 60% AND 5+ trades AND positive avg PnL\n- TIER-2 (CONDITIONAL): Win rate 30-60% OR fewer than 5 trades\n- TIER-3 (BLACKLIST): Win rate below 30% with 5+ trades\n\nStep 6: Write scorecard to memory using solana_memory_write with tag 'source_reputation'.\n\nFORMATTING RULES:\n- Every token reference MUST use SYMBOL (full_CA) format.\n- Do not execute trades. Do not ask questions.",
|
|
42
42
|
enabled: true
|
|
43
43
|
},
|
|
44
44
|
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
agentId: "main",
|
|
50
50
|
sessionTarget: "isolated",
|
|
51
51
|
delivery: { mode: "none" },
|
|
52
|
-
message: "CRON_JOB: portfolio_risk_audit\n\nStep 1: Call solana_capital_status
|
|
52
|
+
message: "CRON_JOB: portfolio_risk_audit\n\nStep 1: Call solana_capital_status to get wallet balance and portfolio value.\n\nStep 2: Call solana_positions to get all open positions with entry prices and sizes.\n\nStep 3: For each open position, call solana_token_snapshot to get current price, 24h volume, and market cap.\n\nStep 4: Run concentration check — flag WARNING if any single position exceeds 30 percent of total portfolio value, CRITICAL if above 50 percent.\n\nStep 5: Run exposure check — flag WARNING if total exposure exceeds 50 percent of wallet balance, CRITICAL if above 75 percent.\n\nStep 6: Run drawdown check — CRITICAL if portfolio drawdown exceeds 25 percent from peak capital.\n\nStep 7: Calculate portfolio heat (sum of all position risk scores). Flag WARNING above 50 percent, CRITICAL above 75 percent.\n\nStep 8: Run liquidity check — WARNING if any position exceeds 2 percent of its pool depth.\n\nStep 9: Check solana_killswitch_status.\n\nStep 10: Write risk report via solana_memory_write with tag 'risk_audit'.\n\nFORMATTING RULES:\n- Every token reference MUST use SYMBOL (full_CA) format.\n- Do not execute trades. Do not ask questions.",
|
|
53
53
|
enabled: true
|
|
54
54
|
},
|
|
55
55
|
|
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
agentId: "main",
|
|
81
81
|
sessionTarget: "isolated",
|
|
82
82
|
delivery: { mode: "none" },
|
|
83
|
-
message: "CRON_JOB: subscription_cleanup\n\nStep 1: Call solana_positions to get open
|
|
83
|
+
message: "CRON_JOB: subscription_cleanup\n\nStep 1: Call solana_positions to get all open positions and extract their contract addresses.\n\nStep 2: Call solana_bitquery_subscriptions to list all active Bitquery subscriptions. If this call returns an AUTH_SCOPE_MISSING error, log the error to memory and stop gracefully — do not retry or error out.\n\nStep 3: For each active subscription, check if the associated token CA still has an open position. Build two lists: 'matched' (has position) and 'orphaned' (no position).\n\nStep 4: Unsubscribe orphans via solana_bitquery_unsubscribe.\n\nStep 5: Reopen subscriptions nearing 24h expiry via solana_bitquery_subscription_reopen.\n\nStep 6: Write summary via solana_memory_write with tag 'subscription_cleanup'.\n\nFORMATTING RULES:\n- Every token reference MUST use SYMBOL (full_CA) format.\n- Do not execute trades. Do not ask questions.",
|
|
84
84
|
enabled: true
|
|
85
85
|
},
|
|
86
86
|
|
|
@@ -26,7 +26,7 @@ async function doRequest(opts, isRetry = false) {
|
|
|
26
26
|
headers,
|
|
27
27
|
signal: controller.signal
|
|
28
28
|
};
|
|
29
|
-
if ((opts.method === "POST" || opts.method === "PUT") && opts.body) {
|
|
29
|
+
if ((opts.method === "POST" || opts.method === "PUT" || opts.method === "PATCH") && opts.body) {
|
|
30
30
|
fetchOpts.body = JSON.stringify(opts.body);
|
|
31
31
|
}
|
|
32
32
|
const res = await fetch(url, fetchOpts);
|
package/dist/index.js
CHANGED
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
} from "./chunk-3YPZOXWE.js";
|
|
19
19
|
import {
|
|
20
20
|
orchestratorRequest
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-VUIYNUGF.js";
|
|
22
22
|
import {
|
|
23
23
|
IntelligenceLab
|
|
24
24
|
} from "./chunk-C24QA3MQ.js";
|
|
@@ -1026,6 +1026,18 @@ var solanaTraderPlugin = {
|
|
|
1026
1026
|
onUnauthorized
|
|
1027
1027
|
});
|
|
1028
1028
|
};
|
|
1029
|
+
const patch = async (apiPath, body) => {
|
|
1030
|
+
const token = await sessionManager.getAccessToken();
|
|
1031
|
+
return orchestratorRequest({
|
|
1032
|
+
baseUrl: orchestratorUrl,
|
|
1033
|
+
method: "PATCH",
|
|
1034
|
+
path: apiPath,
|
|
1035
|
+
body,
|
|
1036
|
+
timeout: apiTimeout,
|
|
1037
|
+
accessToken: token,
|
|
1038
|
+
onUnauthorized
|
|
1039
|
+
});
|
|
1040
|
+
};
|
|
1029
1041
|
const del = async (apiPath) => {
|
|
1030
1042
|
const token = await sessionManager.getAccessToken();
|
|
1031
1043
|
return orchestratorRequest({
|
|
@@ -1466,7 +1478,12 @@ var solanaTraderPlugin = {
|
|
|
1466
1478
|
description: "Advisory only \u2014 server decides position mode internally. Sent for future compatibility."
|
|
1467
1479
|
})
|
|
1468
1480
|
),
|
|
1469
|
-
idempotencyKey: Type.Optional(Type.String({ description: "Unique key to prevent duplicate executions (e.g., UUID). Server uses walletId + key for replay cache." }))
|
|
1481
|
+
idempotencyKey: Type.Optional(Type.String({ description: "Unique key to prevent duplicate executions (e.g., UUID). Server uses walletId + key for replay cache." })),
|
|
1482
|
+
agentId: Type.Optional(
|
|
1483
|
+
Type.String({
|
|
1484
|
+
description: "Optional agent id for gateway-forwarded notices (e.g. main). If omitted, the plugin config `agentId` is sent when set so default-risk messages reach the right agent."
|
|
1485
|
+
})
|
|
1486
|
+
)
|
|
1470
1487
|
}),
|
|
1471
1488
|
execute: wrapExecute("solana_trade_execute", async (_id, params) => {
|
|
1472
1489
|
const headers = {};
|
|
@@ -1481,6 +1498,8 @@ var solanaTraderPlugin = {
|
|
|
1481
1498
|
slPct: params.slPct,
|
|
1482
1499
|
managementMode: params.managementMode
|
|
1483
1500
|
};
|
|
1501
|
+
const execAgentId = typeof params.agentId === "string" && params.agentId.trim().length > 0 ? params.agentId.trim() : config.agentId && String(config.agentId).trim().length > 0 ? String(config.agentId).trim() : void 0;
|
|
1502
|
+
if (execAgentId) body.agentId = execAgentId;
|
|
1484
1503
|
const tsExecute = params.trailingStop;
|
|
1485
1504
|
if (tsExecute?.levels && Array.isArray(tsExecute.levels) && tsExecute.levels.length > 0) {
|
|
1486
1505
|
body.trailingStop = tsExecute;
|
|
@@ -1700,7 +1719,7 @@ var solanaTraderPlugin = {
|
|
|
1700
1719
|
});
|
|
1701
1720
|
api.registerTool({
|
|
1702
1721
|
name: "solana_positions",
|
|
1703
|
-
description: "List trading positions with mark-to-market. **PnL:** for Solana wallets, `realizedPnl` / `unrealizedPnl` are returned in SOL-native units. `unrealizedReturnPct` is ROI on cost basis (for sweep-dead-tokens logic).",
|
|
1722
|
+
description: "List trading positions with mark-to-market. **PnL:** for Solana wallets, `realizedPnl` / `unrealizedPnl` are returned in SOL-native units. `unrealizedReturnPct` is ROI on cost basis (for sweep-dead-tokens logic). **Exit plan (source of truth):** use each position's `tpLevelsDetailed`, `slLevels`, `trailingStopPct`, `trailingStopLevels`, and `deadlockState.exits` \u2014 never guess exits from mode tables or memory.",
|
|
1704
1723
|
parameters: Type.Object({
|
|
1705
1724
|
status: Type.Optional(Type.String({ description: "Filter by status: 'open', 'closed', or omit for all" }))
|
|
1706
1725
|
}),
|
|
@@ -1710,6 +1729,122 @@ var solanaTraderPlugin = {
|
|
|
1710
1729
|
return get(reqPath);
|
|
1711
1730
|
})
|
|
1712
1731
|
});
|
|
1732
|
+
api.registerTool({
|
|
1733
|
+
name: "risk_management_get_default",
|
|
1734
|
+
description: "Read per-wallet default exit parameters used when a buy is executed **without** any TP/SL/trailing fields. Returns either the user's saved defaults or the platform system default (`source`: user | system).",
|
|
1735
|
+
parameters: Type.Object({}),
|
|
1736
|
+
execute: wrapExecute(
|
|
1737
|
+
"risk_management_get_default",
|
|
1738
|
+
async () => get(`/api/wallet/risk-defaults?walletId=${walletId}`)
|
|
1739
|
+
)
|
|
1740
|
+
});
|
|
1741
|
+
api.registerTool({
|
|
1742
|
+
name: "trade_size_limit_get",
|
|
1743
|
+
description: "Read the per-wallet maximum **buy** size in SOL enforced by the API (stored in `wallet.limits.maxTradeSizeSol`; platform default 1.5 SOL when unset). Always use this before sizing buys; never guess the limit.",
|
|
1744
|
+
parameters: Type.Object({}),
|
|
1745
|
+
execute: wrapExecute(
|
|
1746
|
+
"trade_size_limit_get",
|
|
1747
|
+
async () => get(`/api/wallet/max-trade-size?walletId=${walletId}`)
|
|
1748
|
+
)
|
|
1749
|
+
});
|
|
1750
|
+
api.registerTool({
|
|
1751
|
+
name: "trade_size_limit_set",
|
|
1752
|
+
description: "Set the per-wallet maximum buy size in SOL (persisted on the wallet `limits` JSON). Subject to a platform ceiling.",
|
|
1753
|
+
parameters: Type.Object({
|
|
1754
|
+
maxTradeSizeSol: Type.Number({ exclusiveMinimum: 0 })
|
|
1755
|
+
}),
|
|
1756
|
+
execute: wrapExecute(
|
|
1757
|
+
"trade_size_limit_set",
|
|
1758
|
+
async (_id, params) => put("/api/wallet/max-trade-size", {
|
|
1759
|
+
walletId,
|
|
1760
|
+
maxTradeSizeSol: params.maxTradeSizeSol
|
|
1761
|
+
})
|
|
1762
|
+
)
|
|
1763
|
+
});
|
|
1764
|
+
api.registerTool({
|
|
1765
|
+
name: "risk_management_set_default",
|
|
1766
|
+
description: "Save per-wallet default exit parameters (`tpExits`, `slExits`, `trailingStop.levels`) applied on buys that omit risk fields. Same shape as trade execute exit payloads.",
|
|
1767
|
+
parameters: Type.Object({
|
|
1768
|
+
tpExits: Type.Array(
|
|
1769
|
+
Type.Object({
|
|
1770
|
+
percent: Type.Number(),
|
|
1771
|
+
amountPct: Type.Number()
|
|
1772
|
+
}),
|
|
1773
|
+
{ minItems: 1 }
|
|
1774
|
+
),
|
|
1775
|
+
slExits: Type.Array(
|
|
1776
|
+
Type.Object({
|
|
1777
|
+
percent: Type.Number(),
|
|
1778
|
+
amountPct: Type.Number()
|
|
1779
|
+
}),
|
|
1780
|
+
{ minItems: 1 }
|
|
1781
|
+
),
|
|
1782
|
+
trailingStop: Type.Object({
|
|
1783
|
+
levels: Type.Array(
|
|
1784
|
+
Type.Object({
|
|
1785
|
+
percentage: Type.Number(),
|
|
1786
|
+
amount: Type.Optional(Type.Number()),
|
|
1787
|
+
triggerAboveATH: Type.Optional(Type.Number())
|
|
1788
|
+
}),
|
|
1789
|
+
{ minItems: 1, maxItems: 5 }
|
|
1790
|
+
)
|
|
1791
|
+
})
|
|
1792
|
+
}),
|
|
1793
|
+
execute: wrapExecute(
|
|
1794
|
+
"risk_management_set_default",
|
|
1795
|
+
async (_id, params) => put("/api/wallet/risk-defaults", {
|
|
1796
|
+
walletId,
|
|
1797
|
+
tpExits: params.tpExits,
|
|
1798
|
+
slExits: params.slExits,
|
|
1799
|
+
trailingStop: params.trailingStop
|
|
1800
|
+
})
|
|
1801
|
+
)
|
|
1802
|
+
});
|
|
1803
|
+
api.registerTool({
|
|
1804
|
+
name: "position_risk_management_update",
|
|
1805
|
+
description: "Update **percentages and amounts only** on an open position's live exit plan (CaptureSell + stored position metadata). Cannot add or remove levels \u2014 array lengths must match the existing subscription. Use after entry when refining TP/SL/trailing numerics.",
|
|
1806
|
+
parameters: Type.Object({
|
|
1807
|
+
tokenAddress: Type.String({ description: "SPL mint for the open position" }),
|
|
1808
|
+
tpExits: Type.Optional(
|
|
1809
|
+
Type.Array(
|
|
1810
|
+
Type.Object({
|
|
1811
|
+
percent: Type.Number(),
|
|
1812
|
+
amountPct: Type.Number()
|
|
1813
|
+
})
|
|
1814
|
+
)
|
|
1815
|
+
),
|
|
1816
|
+
slExits: Type.Optional(
|
|
1817
|
+
Type.Array(
|
|
1818
|
+
Type.Object({
|
|
1819
|
+
percent: Type.Number(),
|
|
1820
|
+
amountPct: Type.Number()
|
|
1821
|
+
})
|
|
1822
|
+
)
|
|
1823
|
+
),
|
|
1824
|
+
trailingStop: Type.Optional(
|
|
1825
|
+
Type.Object({
|
|
1826
|
+
levels: Type.Array(
|
|
1827
|
+
Type.Object({
|
|
1828
|
+
percentage: Type.Number(),
|
|
1829
|
+
amount: Type.Optional(Type.Number()),
|
|
1830
|
+
triggerAboveATH: Type.Optional(Type.Number())
|
|
1831
|
+
}),
|
|
1832
|
+
{ minItems: 1, maxItems: 5 }
|
|
1833
|
+
)
|
|
1834
|
+
})
|
|
1835
|
+
)
|
|
1836
|
+
}),
|
|
1837
|
+
execute: wrapExecute("position_risk_management_update", async (_id, params) => {
|
|
1838
|
+
const body = {
|
|
1839
|
+
walletId,
|
|
1840
|
+
tokenAddress: params.tokenAddress
|
|
1841
|
+
};
|
|
1842
|
+
if (params.tpExits) body.tpExits = params.tpExits;
|
|
1843
|
+
if (params.slExits) body.slExits = params.slExits;
|
|
1844
|
+
if (params.trailingStop) body.trailingStop = params.trailingStop;
|
|
1845
|
+
return patch("/api/position/risk-management", body);
|
|
1846
|
+
})
|
|
1847
|
+
});
|
|
1713
1848
|
api.registerTool({
|
|
1714
1849
|
name: "solana_wallet_token_balance",
|
|
1715
1850
|
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`).",
|
package/dist/src/http-client.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "solana-traderclaw",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.60",
|
|
4
4
|
"description": "TraderClaw V1-Upgraded — Solana trading for OpenClaw with intelligence lab, tool envelopes, prompt scrubbing, read-only X social intel, and split skill docs",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -105,6 +105,8 @@ You operate in exactly one mode at a time. Default: `HARDENED`.
|
|
|
105
105
|
|
|
106
106
|
## Mode Parameters
|
|
107
107
|
|
|
108
|
+
*The exit percentages in this table (e.g. suggested `slExits` / `tpExits` ranges) are **illustrative mode targets** for planning — they are **not** the live exit configuration of any open position.*
|
|
109
|
+
|
|
108
110
|
| Parameter | HARDENED | DEGEN |
|
|
109
111
|
|---|---|---|
|
|
110
112
|
| Entry confidence threshold | High (strong confluence) | Moderate (lower bar) |
|
|
@@ -130,6 +132,17 @@ You operate in exactly one mode at a time. Default: `HARDENED`.
|
|
|
130
132
|
- `trailingStop`: `{ levels: [{ percentage: <trailing drawdown %>, amount: <% of position to sell, default 100>, triggerAboveATH: <% above session ATH to arm, default 100 = 2× ATH> }] }` — 1–5 tiered trailing stops. Use `trailingStopPct` for simpler single-level trailing.
|
|
131
133
|
- `slippageBps`: REQUIRED on both precheck and execute. Positive integer, basis points (e.g. 300 = 3%). Scale to liquidity, hard cap 800bps.
|
|
132
134
|
|
|
135
|
+
## Source of truth for exit configuration (mandatory)
|
|
136
|
+
|
|
137
|
+
- **Live** take-profit, stop-loss, and trailing-stop parameters for each **open** position come **only** from the orchestrator API via `solana_positions` (and related tools). Use the fields returned on each position row, especially: `tpLevelsDetailed`, `slLevels`, `trailingStopPct`, `trailingStopLevels`, and `deadlockState.exits` (including `trailingStopLevels` when present).
|
|
138
|
+
- **Never** invent, recall from chat history, or copy numbers from the **Mode Parameters** table above as if they were your current exits.
|
|
139
|
+
- If you need the **default** plan applied when a buy omitted risk fields, use `risk_management_get_default` (user override vs platform default). To change **defaults** for future buys, use `risk_management_set_default`. To adjust **numeric** TP/SL/trailing values on an **existing** position without adding or removing levels, use `position_risk_management_update`.
|
|
140
|
+
|
|
141
|
+
## Maximum buy size in SOL (mandatory)
|
|
142
|
+
|
|
143
|
+
- The API enforces a per-wallet cap on **buy** `sizeSol` via `wallet.limits.maxTradeSizeSol` stored in Supabase on the same `limits` JSON as other risk knobs (default **1.5 SOL** when the key is absent).
|
|
144
|
+
- **Never** invent or recall a max size from mode tables or memory. Before proposing or executing a buy, call `trade_size_limit_get`. When the user wants a different cap, use `trade_size_limit_set` (subject to a platform ceiling).
|
|
145
|
+
|
|
133
146
|
## Position Execution Model (Authoritative)
|
|
134
147
|
|
|
135
148
|
This section defines the UNIQUE valid interpretation of all exit-related parameters.
|
|
@@ -13,7 +13,7 @@ Things like:
|
|
|
13
13
|
- Rate limit observations
|
|
14
14
|
- Anything environment-specific
|
|
15
15
|
|
|
16
|
-
## Tool Inventory (
|
|
16
|
+
## Tool Inventory (101 tools — 98 Solana + 3 X read-only)
|
|
17
17
|
|
|
18
18
|
Every tool has a mandatory trigger — when the trigger condition is met, you MUST call the tool. "Cron-only" tools are called during cron jobs, not the heartbeat fast loop.
|
|
19
19
|
|
|
@@ -27,7 +27,7 @@ Every tool has a mandatory trigger — when the trigger condition is met, you MU
|
|
|
27
27
|
| `solana_gateway_credentials_set` | Register gateway URL and token | When gateway is not registered (startup) |
|
|
28
28
|
| `solana_gateway_forward_probe` | Test forwarding path health | Startup sequence; when events stop arriving |
|
|
29
29
|
|
|
30
|
-
### Wallet & Capital (
|
|
30
|
+
### Wallet & Capital (11)
|
|
31
31
|
| Tool | Purpose | When to Call |
|
|
32
32
|
|---|---|---|
|
|
33
33
|
| `solana_wallets` | List all wallets | Startup; when user asks about wallets |
|
|
@@ -38,6 +38,11 @@ Every tool has a mandatory trigger — when the trigger condition is met, you MU
|
|
|
38
38
|
| `solana_sweep_dead_tokens` | Batch-exit losing positions | `dead_money_sweep` cron; Step 0 when multiple dead positions found |
|
|
39
39
|
| `solana_killswitch_status` | Check kill switch state | Step 0 every heartbeat |
|
|
40
40
|
| `solana_killswitch` | Toggle kill switch (enabled + mode) | When consecutive loss limit hit; when user requests |
|
|
41
|
+
| `risk_management_get_default` | Read per-wallet default TP/SL/trailing used when buys omit risk | Before relying on implicit defaults; after user asks about protection |
|
|
42
|
+
| `risk_management_set_default` | Save per-wallet default exit plan for future buys | When user or policy wants custom defaults instead of platform system default |
|
|
43
|
+
| `trade_size_limit_get` | Read max **buy** size (SOL) from wallet `limits` (default 1.5) | Before every buy or when user asks about size limits |
|
|
44
|
+
| `trade_size_limit_set` | Set max **buy** size (SOL) on wallet `limits` | When user asks to change the per-order cap |
|
|
45
|
+
| `position_risk_management_update` | Adjust TP/SL/trailing **numbers** on an open position (same level count) | After entry when refining exits without removing levels |
|
|
41
46
|
|
|
42
47
|
### Scanning & Discovery (4)
|
|
43
48
|
| Tool | Purpose | When to Call |
|