@clawnch/clawtomaton 0.2.2 → 0.4.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 +82 -10
- package/dist/agent/index.d.ts +5 -1
- package/dist/agent/index.d.ts.map +1 -1
- package/dist/agent/index.js +120 -10
- package/dist/agent/index.js.map +1 -1
- package/dist/agent/prompt.d.ts +2 -0
- package/dist/agent/prompt.d.ts.map +1 -1
- package/dist/agent/prompt.js +199 -2
- package/dist/agent/prompt.js.map +1 -1
- package/dist/bunker/client.d.ts +113 -0
- package/dist/bunker/client.d.ts.map +1 -0
- package/dist/bunker/client.js +404 -0
- package/dist/bunker/client.js.map +1 -0
- package/dist/bunker/self-deploy.d.ts +54 -0
- package/dist/bunker/self-deploy.d.ts.map +1 -0
- package/dist/bunker/self-deploy.js +353 -0
- package/dist/bunker/self-deploy.js.map +1 -0
- package/dist/bunker/threat-monitor.d.ts +47 -0
- package/dist/bunker/threat-monitor.d.ts.map +1 -0
- package/dist/bunker/threat-monitor.js +173 -0
- package/dist/bunker/threat-monitor.js.map +1 -0
- package/dist/bunker/types.d.ts +320 -0
- package/dist/bunker/types.d.ts.map +1 -0
- package/dist/bunker/types.js +9 -0
- package/dist/bunker/types.js.map +1 -0
- package/dist/cli.js +207 -9
- package/dist/cli.js.map +1 -1
- package/dist/constants.d.ts +11 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +10 -0
- package/dist/constants.js.map +1 -1
- package/dist/heartbeat/index.d.ts +28 -0
- package/dist/heartbeat/index.d.ts.map +1 -1
- package/dist/heartbeat/index.js +240 -11
- package/dist/heartbeat/index.js.map +1 -1
- package/dist/index.d.ts +10 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -1
- package/dist/index.js.map +1 -1
- package/dist/market/index.d.ts +20 -1
- package/dist/market/index.d.ts.map +1 -1
- package/dist/market/index.js +76 -4
- package/dist/market/index.js.map +1 -1
- package/dist/skills/analyze-market.d.ts +17 -0
- package/dist/skills/analyze-market.d.ts.map +1 -0
- package/dist/skills/analyze-market.js +156 -0
- package/dist/skills/analyze-market.js.map +1 -0
- package/dist/skills/bunker.d.ts +29 -0
- package/dist/skills/bunker.d.ts.map +1 -0
- package/dist/skills/bunker.js +502 -0
- package/dist/skills/bunker.js.map +1 -0
- package/dist/skills/check-balance.d.ts +2 -2
- package/dist/skills/check-balance.d.ts.map +1 -1
- package/dist/skills/check-balance.js +43 -8
- package/dist/skills/check-balance.js.map +1 -1
- package/dist/skills/check-price.d.ts +11 -0
- package/dist/skills/check-price.d.ts.map +1 -0
- package/dist/skills/check-price.js +83 -0
- package/dist/skills/check-price.js.map +1 -0
- package/dist/skills/claim-vault.d.ts +15 -0
- package/dist/skills/claim-vault.d.ts.map +1 -0
- package/dist/skills/claim-vault.js +96 -0
- package/dist/skills/claim-vault.js.map +1 -0
- package/dist/skills/deploy.d.ts.map +1 -1
- package/dist/skills/deploy.js +10 -1
- package/dist/skills/deploy.js.map +1 -1
- package/dist/skills/index.d.ts +9 -1
- package/dist/skills/index.d.ts.map +1 -1
- package/dist/skills/index.js +34 -1
- package/dist/skills/index.js.map +1 -1
- package/dist/skills/manage-orders.d.ts +26 -0
- package/dist/skills/manage-orders.d.ts.map +1 -0
- package/dist/skills/manage-orders.js +470 -0
- package/dist/skills/manage-orders.js.map +1 -0
- package/dist/skills/portfolio.d.ts +19 -0
- package/dist/skills/portfolio.d.ts.map +1 -0
- package/dist/skills/portfolio.js +189 -0
- package/dist/skills/portfolio.js.map +1 -0
- package/dist/skills/watch-activity.d.ts +12 -0
- package/dist/skills/watch-activity.d.ts.map +1 -0
- package/dist/skills/watch-activity.js +130 -0
- package/dist/skills/watch-activity.js.map +1 -0
- package/dist/skills/xmtp.d.ts +18 -0
- package/dist/skills/xmtp.d.ts.map +1 -0
- package/dist/skills/xmtp.js +180 -0
- package/dist/skills/xmtp.js.map +1 -0
- package/dist/state/index.d.ts +25 -0
- package/dist/state/index.d.ts.map +1 -1
- package/dist/state/index.js +156 -0
- package/dist/state/index.js.map +1 -1
- package/dist/survival/index.d.ts.map +1 -1
- package/dist/survival/index.js +3 -0
- package/dist/survival/index.js.map +1 -1
- package/dist/types.d.ts +19 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/xmtp/client.d.ts +79 -0
- package/dist/xmtp/client.d.ts.map +1 -0
- package/dist/xmtp/client.js +282 -0
- package/dist/xmtp/client.js.map +1 -0
- package/dist/xmtp/index.d.ts +9 -0
- package/dist/xmtp/index.d.ts.map +1 -0
- package/dist/xmtp/index.js +8 -0
- package/dist/xmtp/index.js.map +1 -0
- package/dist/xmtp/types.d.ts +59 -0
- package/dist/xmtp/types.d.ts.map +1 -0
- package/dist/xmtp/types.js +5 -0
- package/dist/xmtp/types.js.map +1 -0
- package/package.json +3 -2
|
@@ -0,0 +1,502 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skill: bunker — MoltBunker decentralized deployment management.
|
|
3
|
+
*
|
|
4
|
+
* Multi-action skill (like conway.ts pattern) for managing the agent's
|
|
5
|
+
* bunker deployment lifecycle. Actions cover the full spectrum:
|
|
6
|
+
*
|
|
7
|
+
* Read-only (all tiers):
|
|
8
|
+
* status — Deployment status, container health, runtime info
|
|
9
|
+
* balance — BUNKER token balance (deposited, reserved, available)
|
|
10
|
+
* threat — Current threat assessment
|
|
11
|
+
* logs — Container log output
|
|
12
|
+
* catalog — Browse available tiers and pricing
|
|
13
|
+
*
|
|
14
|
+
* Mutating (normal + low_compute):
|
|
15
|
+
* clone — Clone to a specified region
|
|
16
|
+
* snapshot — Create state snapshot
|
|
17
|
+
* extend — Extend runtime duration
|
|
18
|
+
*
|
|
19
|
+
* Destructive (normal only):
|
|
20
|
+
* deploy_self — Full self-deployment to MoltBunker
|
|
21
|
+
* restore — Restore from snapshot
|
|
22
|
+
* migrate — Migrate to different region
|
|
23
|
+
* stop — Stop bunker deployment
|
|
24
|
+
*
|
|
25
|
+
* The skill validates action permissions internally based on survival tier.
|
|
26
|
+
*/
|
|
27
|
+
import { BunkerClient, BunkerError, BunkerInsufficientFundsError } from '../bunker/client.js';
|
|
28
|
+
import { selfDeploy, stopDeploy } from '../bunker/self-deploy.js';
|
|
29
|
+
import { checkThreat, formatThreat } from '../bunker/threat-monitor.js';
|
|
30
|
+
import { buildClients } from '../identity/index.js';
|
|
31
|
+
import { StateStore } from '../state/index.js';
|
|
32
|
+
// ============================================================================
|
|
33
|
+
// Action permissions by tier
|
|
34
|
+
// ============================================================================
|
|
35
|
+
const READ_ACTIONS = new Set(['status', 'balance', 'threat', 'logs', 'catalog']);
|
|
36
|
+
const MUTATE_ACTIONS = new Set(['clone', 'snapshot', 'extend']);
|
|
37
|
+
const DESTRUCTIVE_ACTIONS = new Set(['deploy_self', 'restore', 'migrate', 'stop']);
|
|
38
|
+
const TIER_ALLOWED_ACTIONS = {
|
|
39
|
+
normal: new Set([...READ_ACTIONS, ...MUTATE_ACTIONS, ...DESTRUCTIVE_ACTIONS]),
|
|
40
|
+
low_compute: new Set([...READ_ACTIONS, ...MUTATE_ACTIONS]),
|
|
41
|
+
critical: new Set([...READ_ACTIONS]),
|
|
42
|
+
dead: new Set(),
|
|
43
|
+
};
|
|
44
|
+
// ============================================================================
|
|
45
|
+
// Client cache
|
|
46
|
+
// ============================================================================
|
|
47
|
+
let cachedClient = null;
|
|
48
|
+
let cachedClientAddress = null;
|
|
49
|
+
function getClient(ctx) {
|
|
50
|
+
const bunkerConfig = getBunkerConfig(ctx);
|
|
51
|
+
// Reuse client if same wallet
|
|
52
|
+
if (cachedClient && cachedClientAddress === ctx.identity.address) {
|
|
53
|
+
return cachedClient;
|
|
54
|
+
}
|
|
55
|
+
const rpcUrl = getConfigValue(ctx, 'rpcUrl');
|
|
56
|
+
const { walletClient } = buildClients(ctx.identity, rpcUrl);
|
|
57
|
+
cachedClient = new BunkerClient({
|
|
58
|
+
apiUrl: bunkerConfig.apiUrl,
|
|
59
|
+
walletClient: walletClient,
|
|
60
|
+
});
|
|
61
|
+
cachedClientAddress = ctx.identity.address;
|
|
62
|
+
return cachedClient;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Get the bunker config. Throws if not configured.
|
|
66
|
+
* Reads from runtime config via ctx or environment variables.
|
|
67
|
+
*/
|
|
68
|
+
function getBunkerConfig(ctx) {
|
|
69
|
+
// The bunker config isn't directly on AgentContext, so we read from env
|
|
70
|
+
// or from the config that was loaded at startup (stashed in process.env by CLI)
|
|
71
|
+
return {
|
|
72
|
+
apiUrl: process.env.CLAWTOMATON_BUNKER_API_URL || 'https://api.moltbunker.com/v1',
|
|
73
|
+
region: (process.env.CLAWTOMATON_BUNKER_REGION || 'americas'),
|
|
74
|
+
autoCloneOnThreat: process.env.CLAWTOMATON_BUNKER_AUTO_CLONE !== 'false',
|
|
75
|
+
maxClones: parseInt(process.env.CLAWTOMATON_BUNKER_MAX_CLONES || '3', 10),
|
|
76
|
+
tier: process.env.CLAWTOMATON_BUNKER_TIER || 'standard',
|
|
77
|
+
defaultDurationHours: 720,
|
|
78
|
+
threatCheckIntervalMs: 300_000,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Read a value from the runtime config. We can't access ClawtomatonConfig
|
|
83
|
+
* from AgentContext directly, so use env vars set by the CLI.
|
|
84
|
+
*/
|
|
85
|
+
function getConfigValue(ctx, key) {
|
|
86
|
+
switch (key) {
|
|
87
|
+
case 'rpcUrl':
|
|
88
|
+
return process.env.CLAWTOMATON_RPC_URL || 'https://mainnet.base.org';
|
|
89
|
+
default:
|
|
90
|
+
return undefined;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// ============================================================================
|
|
94
|
+
// Skill Definition
|
|
95
|
+
// ============================================================================
|
|
96
|
+
export const bunkerSkill = {
|
|
97
|
+
name: 'bunker',
|
|
98
|
+
description: 'Manage your MoltBunker decentralized deployment. ' +
|
|
99
|
+
'Actions: status, balance, threat, logs, catalog (read-only); ' +
|
|
100
|
+
'clone, snapshot, extend (mutating); ' +
|
|
101
|
+
'deploy_self, restore, migrate, stop (destructive, normal tier only). ' +
|
|
102
|
+
'MoltBunker provides encrypted, replicated container hosting paid with BUNKER tokens.',
|
|
103
|
+
parameters: [
|
|
104
|
+
{
|
|
105
|
+
name: 'action',
|
|
106
|
+
type: 'string',
|
|
107
|
+
description: 'The action to perform: status, balance, threat, logs, catalog, ' +
|
|
108
|
+
'clone, snapshot, extend, deploy_self, restore, migrate, stop',
|
|
109
|
+
required: true,
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
name: 'region',
|
|
113
|
+
type: 'string',
|
|
114
|
+
description: 'Target region for clone/migrate/deploy (americas, europe, asia_pacific)',
|
|
115
|
+
required: false,
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
name: 'hours',
|
|
119
|
+
type: 'number',
|
|
120
|
+
description: 'Duration in hours for extend (default: 720)',
|
|
121
|
+
required: false,
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
name: 'tail',
|
|
125
|
+
type: 'number',
|
|
126
|
+
description: 'Number of log lines to fetch (default: 50)',
|
|
127
|
+
required: false,
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
name: 'snapshot_id',
|
|
131
|
+
type: 'string',
|
|
132
|
+
description: 'Snapshot ID for restore action',
|
|
133
|
+
required: false,
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
name: 'snapshot_type',
|
|
137
|
+
type: 'string',
|
|
138
|
+
description: 'Snapshot type: full, incremental, checkpoint (default: full)',
|
|
139
|
+
required: false,
|
|
140
|
+
},
|
|
141
|
+
],
|
|
142
|
+
execute: executeBunker,
|
|
143
|
+
};
|
|
144
|
+
// ============================================================================
|
|
145
|
+
// Executor
|
|
146
|
+
// ============================================================================
|
|
147
|
+
async function executeBunker(params, ctx) {
|
|
148
|
+
const action = params.action;
|
|
149
|
+
if (!action) {
|
|
150
|
+
return fail('Missing required parameter: action');
|
|
151
|
+
}
|
|
152
|
+
// Check tier permissions
|
|
153
|
+
const allowed = TIER_ALLOWED_ACTIONS[ctx.survival.tier];
|
|
154
|
+
if (!allowed || !allowed.has(action)) {
|
|
155
|
+
return fail(`Action "${action}" not allowed at ${ctx.survival.tier} tier. ` +
|
|
156
|
+
`Available: ${[...allowed].join(', ')}`);
|
|
157
|
+
}
|
|
158
|
+
try {
|
|
159
|
+
switch (action) {
|
|
160
|
+
case 'status':
|
|
161
|
+
return await actionStatus(ctx);
|
|
162
|
+
case 'balance':
|
|
163
|
+
return await actionBalance(ctx);
|
|
164
|
+
case 'threat':
|
|
165
|
+
return await actionThreat(ctx);
|
|
166
|
+
case 'logs':
|
|
167
|
+
return await actionLogs(ctx, params.tail);
|
|
168
|
+
case 'catalog':
|
|
169
|
+
return await actionCatalog(ctx);
|
|
170
|
+
case 'clone':
|
|
171
|
+
return await actionClone(ctx, params.region);
|
|
172
|
+
case 'snapshot':
|
|
173
|
+
return await actionSnapshot(ctx, params.snapshot_type);
|
|
174
|
+
case 'extend':
|
|
175
|
+
return await actionExtend(ctx, params.hours);
|
|
176
|
+
case 'deploy_self':
|
|
177
|
+
return await actionDeploySelf(ctx, params.region);
|
|
178
|
+
case 'restore':
|
|
179
|
+
return await actionRestore(ctx, params.snapshot_id, params.region);
|
|
180
|
+
case 'migrate':
|
|
181
|
+
return await actionMigrate(ctx, params.region);
|
|
182
|
+
case 'stop':
|
|
183
|
+
return await actionStop(ctx);
|
|
184
|
+
default:
|
|
185
|
+
return fail(`Unknown action: "${action}". Valid: status, balance, threat, logs, catalog, ` +
|
|
186
|
+
`clone, snapshot, extend, deploy_self, restore, migrate, stop`);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
catch (err) {
|
|
190
|
+
if (err instanceof BunkerInsufficientFundsError) {
|
|
191
|
+
return fail(`Insufficient BUNKER balance. Required: ${err.required?.toLocaleString() ?? '?'}, ` +
|
|
192
|
+
`Available: ${err.available?.toLocaleString() ?? '?'}. ` +
|
|
193
|
+
`Deposit more BUNKER tokens to your wallet.`);
|
|
194
|
+
}
|
|
195
|
+
if (err instanceof BunkerError) {
|
|
196
|
+
return fail(`MoltBunker API error (${err.status}): ${err.message}`);
|
|
197
|
+
}
|
|
198
|
+
return fail(err instanceof Error ? err.message : String(err));
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
// ============================================================================
|
|
202
|
+
// Actions
|
|
203
|
+
// ============================================================================
|
|
204
|
+
async function actionStatus(ctx) {
|
|
205
|
+
const client = getClient(ctx);
|
|
206
|
+
// Get state DB — we need a fresh StateStore to read bunker_state
|
|
207
|
+
const stateDir = process.env.CLAWTOMATON_STATE_DIR || `${process.env.HOME}/.clawtomaton`;
|
|
208
|
+
const state = new StateStore(stateDir);
|
|
209
|
+
try {
|
|
210
|
+
const bunkerState = state.getBunkerState();
|
|
211
|
+
if (!bunkerState?.containerId) {
|
|
212
|
+
return ok('No bunker deployment found. Use deploy_self to deploy.');
|
|
213
|
+
}
|
|
214
|
+
const [container, botStatus] = await Promise.all([
|
|
215
|
+
client.getContainer(bunkerState.containerId).catch(() => null),
|
|
216
|
+
bunkerState.botId ? client.getBotStatus(bunkerState.botId).catch(() => null) : null,
|
|
217
|
+
]);
|
|
218
|
+
// Runtime status
|
|
219
|
+
let runtimeInfo = '';
|
|
220
|
+
if (bunkerState.runtimeId) {
|
|
221
|
+
try {
|
|
222
|
+
const rtStatus = await client.getRuntimeStatus(bunkerState.runtimeId);
|
|
223
|
+
runtimeInfo = `\nRuntime: ${rtStatus.remaining_hours.toFixed(1)}h remaining (expires ${rtStatus.expires_at})`;
|
|
224
|
+
}
|
|
225
|
+
catch {
|
|
226
|
+
runtimeInfo = bunkerState.expiresAt
|
|
227
|
+
? `\nRuntime expires: ${new Date(bunkerState.expiresAt).toISOString()}`
|
|
228
|
+
: '';
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
const lines = [
|
|
232
|
+
`=== Bunker Deployment Status ===`,
|
|
233
|
+
`Container: ${bunkerState.containerId} (${container?.status ?? 'unknown'})`,
|
|
234
|
+
`Bot: ${bunkerState.botId ?? 'none'}`,
|
|
235
|
+
`Deployment: ${bunkerState.deploymentId ?? 'none'}`,
|
|
236
|
+
runtimeInfo,
|
|
237
|
+
container?.onion_address ? `Onion: ${container.onion_address}` : '',
|
|
238
|
+
container?.regions?.length ? `Regions: ${container.regions.join(', ')}` : '',
|
|
239
|
+
container?.encrypted ? `Encrypted: yes` : '',
|
|
240
|
+
botStatus ? `Uptime: ${formatUptime(botStatus.uptime_seconds)}` : '',
|
|
241
|
+
bunkerState.cloneIds.length > 0
|
|
242
|
+
? `Clones: ${bunkerState.cloneIds.length} active`
|
|
243
|
+
: 'Clones: 0',
|
|
244
|
+
`Threat: ${bunkerState.lastThreatLevel} (last checked: ${bunkerState.lastThreatCheck ? new Date(bunkerState.lastThreatCheck).toISOString() : 'never'})`,
|
|
245
|
+
].filter(Boolean);
|
|
246
|
+
return ok(lines.join('\n'));
|
|
247
|
+
}
|
|
248
|
+
finally {
|
|
249
|
+
state.close();
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
async function actionBalance(ctx) {
|
|
253
|
+
const client = getClient(ctx);
|
|
254
|
+
const balance = await client.getBalance(ctx.identity.address);
|
|
255
|
+
return ok(`=== BUNKER Balance ===\n` +
|
|
256
|
+
`Wallet: ${balance.wallet_address}\n` +
|
|
257
|
+
`BUNKER: ${balance.bunker_balance.toLocaleString()}\n` +
|
|
258
|
+
`ETH: ${balance.eth_balance}\n` +
|
|
259
|
+
`Deposited: ${balance.deposited.toLocaleString()}\n` +
|
|
260
|
+
`Reserved: ${balance.reserved.toLocaleString()}\n` +
|
|
261
|
+
`Available: ${balance.available.toLocaleString()}`);
|
|
262
|
+
}
|
|
263
|
+
async function actionThreat(ctx) {
|
|
264
|
+
const client = getClient(ctx);
|
|
265
|
+
const stateDir = process.env.CLAWTOMATON_STATE_DIR || `${process.env.HOME}/.clawtomaton`;
|
|
266
|
+
const state = new StateStore(stateDir);
|
|
267
|
+
try {
|
|
268
|
+
const result = await checkThreat(client, state);
|
|
269
|
+
if (!result) {
|
|
270
|
+
return fail('Unable to check threat level. MoltBunker may be unreachable.');
|
|
271
|
+
}
|
|
272
|
+
return ok(formatThreat(result.assessment) + (result.escalated ? '\nESCALATED from ' + result.previousLevel : ''));
|
|
273
|
+
}
|
|
274
|
+
finally {
|
|
275
|
+
state.close();
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
async function actionLogs(ctx, tail) {
|
|
279
|
+
const client = getClient(ctx);
|
|
280
|
+
const stateDir = process.env.CLAWTOMATON_STATE_DIR || `${process.env.HOME}/.clawtomaton`;
|
|
281
|
+
const state = new StateStore(stateDir);
|
|
282
|
+
try {
|
|
283
|
+
const bunkerState = state.getBunkerState();
|
|
284
|
+
if (!bunkerState?.containerId) {
|
|
285
|
+
return fail('No bunker deployment found.');
|
|
286
|
+
}
|
|
287
|
+
const lines = tail ?? 50;
|
|
288
|
+
const logs = await client.getContainerLogs(bunkerState.containerId, lines);
|
|
289
|
+
return ok(logs || '(no log output)');
|
|
290
|
+
}
|
|
291
|
+
finally {
|
|
292
|
+
state.close();
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
async function actionCatalog(ctx) {
|
|
296
|
+
const client = getClient(ctx);
|
|
297
|
+
const catalog = await client.getCatalog();
|
|
298
|
+
const tierLines = catalog.tiers
|
|
299
|
+
.filter((t) => t.enabled)
|
|
300
|
+
.sort((a, b) => a.sort_order - b.sort_order)
|
|
301
|
+
.map((t) => ` ${t.name}: ${t.cpu} / ${t.memory} / ${t.storage} — ${t.monthly.toLocaleString()} BUNKER/mo${t.popular ? ' (popular)' : ''}`);
|
|
302
|
+
return ok(`=== MoltBunker Catalog ===\n` +
|
|
303
|
+
`Updated: ${catalog.updated_at}\n\n` +
|
|
304
|
+
`Tiers:\n${tierLines.join('\n')}`);
|
|
305
|
+
}
|
|
306
|
+
async function actionClone(ctx, region) {
|
|
307
|
+
const client = getClient(ctx);
|
|
308
|
+
const stateDir = process.env.CLAWTOMATON_STATE_DIR || `${process.env.HOME}/.clawtomaton`;
|
|
309
|
+
const state = new StateStore(stateDir);
|
|
310
|
+
try {
|
|
311
|
+
const bunkerState = state.getBunkerState();
|
|
312
|
+
if (!bunkerState?.containerId) {
|
|
313
|
+
return fail('No bunker deployment found. Deploy first with deploy_self.');
|
|
314
|
+
}
|
|
315
|
+
const bunkerConfig = getBunkerConfig(ctx);
|
|
316
|
+
if (bunkerState.cloneIds.length >= bunkerConfig.maxClones) {
|
|
317
|
+
return fail(`Clone limit reached (${bunkerState.cloneIds.length}/${bunkerConfig.maxClones}).`);
|
|
318
|
+
}
|
|
319
|
+
const targetRegion = (region || 'europe');
|
|
320
|
+
const clone = await client.createClone({
|
|
321
|
+
source_id: bunkerState.containerId,
|
|
322
|
+
target_region: targetRegion,
|
|
323
|
+
priority: 2,
|
|
324
|
+
reason: 'manual_clone',
|
|
325
|
+
include_state: true,
|
|
326
|
+
});
|
|
327
|
+
state.addBunkerClone(clone.clone_id);
|
|
328
|
+
return ok(`Clone created: ${clone.clone_id}\n` +
|
|
329
|
+
`Target: ${clone.target_id} in ${clone.target_region}\n` +
|
|
330
|
+
`Status: ${clone.status}`);
|
|
331
|
+
}
|
|
332
|
+
finally {
|
|
333
|
+
state.close();
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
async function actionSnapshot(ctx, snapshotType) {
|
|
337
|
+
const client = getClient(ctx);
|
|
338
|
+
const stateDir = process.env.CLAWTOMATON_STATE_DIR || `${process.env.HOME}/.clawtomaton`;
|
|
339
|
+
const state = new StateStore(stateDir);
|
|
340
|
+
try {
|
|
341
|
+
const bunkerState = state.getBunkerState();
|
|
342
|
+
if (!bunkerState?.containerId) {
|
|
343
|
+
return fail('No bunker deployment found.');
|
|
344
|
+
}
|
|
345
|
+
const type = (snapshotType || 'full');
|
|
346
|
+
const snapshot = await client.createSnapshot({
|
|
347
|
+
container_id: bunkerState.containerId,
|
|
348
|
+
type,
|
|
349
|
+
metadata: { agent: ctx.identity.name, created_by: 'clawtomaton' },
|
|
350
|
+
});
|
|
351
|
+
return ok(`Snapshot created: ${snapshot.id}\n` +
|
|
352
|
+
`Type: ${snapshot.type}\n` +
|
|
353
|
+
`Size: ${(snapshot.size / 1024 / 1024).toFixed(1)} MB\n` +
|
|
354
|
+
`Compressed: ${snapshot.compressed}, Encrypted: ${snapshot.encrypted}\n` +
|
|
355
|
+
`Checksum: ${snapshot.checksum}`);
|
|
356
|
+
}
|
|
357
|
+
finally {
|
|
358
|
+
state.close();
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
async function actionExtend(ctx, hours) {
|
|
362
|
+
const client = getClient(ctx);
|
|
363
|
+
const stateDir = process.env.CLAWTOMATON_STATE_DIR || `${process.env.HOME}/.clawtomaton`;
|
|
364
|
+
const state = new StateStore(stateDir);
|
|
365
|
+
try {
|
|
366
|
+
const bunkerState = state.getBunkerState();
|
|
367
|
+
if (!bunkerState?.runtimeId) {
|
|
368
|
+
return fail('No bunker runtime found.');
|
|
369
|
+
}
|
|
370
|
+
const durationHours = hours ?? 720;
|
|
371
|
+
await client.extendRuntime(bunkerState.runtimeId, { duration_hours: durationHours });
|
|
372
|
+
// Update expiry in state
|
|
373
|
+
const rtStatus = await client.getRuntimeStatus(bunkerState.runtimeId);
|
|
374
|
+
const newExpiry = new Date(rtStatus.expires_at).getTime();
|
|
375
|
+
state.saveBunkerState({ ...bunkerState, expiresAt: newExpiry });
|
|
376
|
+
return ok(`Runtime extended by ${durationHours}h.\n` +
|
|
377
|
+
`New expiry: ${rtStatus.expires_at}\n` +
|
|
378
|
+
`Remaining: ${rtStatus.remaining_hours.toFixed(1)}h`);
|
|
379
|
+
}
|
|
380
|
+
finally {
|
|
381
|
+
state.close();
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
async function actionDeploySelf(ctx, region) {
|
|
385
|
+
const client = getClient(ctx);
|
|
386
|
+
const stateDir = process.env.CLAWTOMATON_STATE_DIR || `${process.env.HOME}/.clawtomaton`;
|
|
387
|
+
const state = new StateStore(stateDir);
|
|
388
|
+
try {
|
|
389
|
+
// Reconstruct config from env (we're inside the skill executor)
|
|
390
|
+
const config = reconstructConfig(ctx);
|
|
391
|
+
const result = await selfDeploy(client, config, ctx.identity, state, {
|
|
392
|
+
region: region,
|
|
393
|
+
});
|
|
394
|
+
return ok(`=== Deployed to MoltBunker ===\n` +
|
|
395
|
+
`Bot: ${result.botId}\n` +
|
|
396
|
+
`Runtime: ${result.runtimeId}\n` +
|
|
397
|
+
`Deployment: ${result.deploymentId}\n` +
|
|
398
|
+
`Container: ${result.containerId}\n` +
|
|
399
|
+
`Region: ${result.region}\n` +
|
|
400
|
+
`Expires: ${new Date(result.expiresAt).toISOString()}\n` +
|
|
401
|
+
(result.onionAddress ? `Onion: ${result.onionAddress}\n` : '') +
|
|
402
|
+
`\nThe containerized agent is now running autonomously on MoltBunker.`);
|
|
403
|
+
}
|
|
404
|
+
finally {
|
|
405
|
+
state.close();
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
async function actionRestore(ctx, snapshotId, region) {
|
|
409
|
+
if (!snapshotId) {
|
|
410
|
+
return fail('Missing required parameter: snapshot_id');
|
|
411
|
+
}
|
|
412
|
+
const client = getClient(ctx);
|
|
413
|
+
const result = await client.restoreSnapshot(snapshotId, {
|
|
414
|
+
snapshot_id: snapshotId,
|
|
415
|
+
target_region: region,
|
|
416
|
+
new_container: false,
|
|
417
|
+
});
|
|
418
|
+
return ok(`Snapshot ${snapshotId} restored. Container: ${result.container_id}`);
|
|
419
|
+
}
|
|
420
|
+
async function actionMigrate(ctx, region) {
|
|
421
|
+
if (!region) {
|
|
422
|
+
return fail('Missing required parameter: region (americas, europe, asia_pacific)');
|
|
423
|
+
}
|
|
424
|
+
const client = getClient(ctx);
|
|
425
|
+
const stateDir = process.env.CLAWTOMATON_STATE_DIR || `${process.env.HOME}/.clawtomaton`;
|
|
426
|
+
const state = new StateStore(stateDir);
|
|
427
|
+
try {
|
|
428
|
+
const bunkerState = state.getBunkerState();
|
|
429
|
+
if (!bunkerState?.containerId) {
|
|
430
|
+
return fail('No bunker deployment found.');
|
|
431
|
+
}
|
|
432
|
+
const migration = await client.migrate({
|
|
433
|
+
container_id: bunkerState.containerId,
|
|
434
|
+
target_region: region,
|
|
435
|
+
keep_original: true,
|
|
436
|
+
});
|
|
437
|
+
return ok(`Migration started: ${migration.migration_id}\n` +
|
|
438
|
+
`From: ${migration.source_region} → ${migration.target_region}\n` +
|
|
439
|
+
`Status: ${migration.status}`);
|
|
440
|
+
}
|
|
441
|
+
finally {
|
|
442
|
+
state.close();
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
async function actionStop(ctx) {
|
|
446
|
+
const client = getClient(ctx);
|
|
447
|
+
const stateDir = process.env.CLAWTOMATON_STATE_DIR || `${process.env.HOME}/.clawtomaton`;
|
|
448
|
+
const state = new StateStore(stateDir);
|
|
449
|
+
try {
|
|
450
|
+
await stopDeploy(client, state);
|
|
451
|
+
return ok('Bunker deployment stopped. Runtime released. Bot preserved for future use.');
|
|
452
|
+
}
|
|
453
|
+
finally {
|
|
454
|
+
state.close();
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
// ============================================================================
|
|
458
|
+
// Helpers
|
|
459
|
+
// ============================================================================
|
|
460
|
+
function ok(result) {
|
|
461
|
+
return { callId: '', success: true, result };
|
|
462
|
+
}
|
|
463
|
+
function fail(error) {
|
|
464
|
+
return { callId: '', success: false, result: null, error };
|
|
465
|
+
}
|
|
466
|
+
function formatUptime(seconds) {
|
|
467
|
+
if (seconds < 3600)
|
|
468
|
+
return `${Math.floor(seconds / 60)}m`;
|
|
469
|
+
if (seconds < 86400)
|
|
470
|
+
return `${(seconds / 3600).toFixed(1)}h`;
|
|
471
|
+
return `${(seconds / 86400).toFixed(1)}d`;
|
|
472
|
+
}
|
|
473
|
+
/**
|
|
474
|
+
* Reconstruct a ClawtomatonConfig from env vars.
|
|
475
|
+
* Used inside the skill executor where we don't have direct config access.
|
|
476
|
+
*/
|
|
477
|
+
function reconstructConfig(ctx) {
|
|
478
|
+
const bunkerConfig = getBunkerConfig(ctx);
|
|
479
|
+
return {
|
|
480
|
+
inference: {
|
|
481
|
+
provider: (process.env.CLAWTOMATON_INFERENCE_PROVIDER || 'openrouter'),
|
|
482
|
+
apiKey: process.env.CLAWTOMATON_INFERENCE_API_KEY || '',
|
|
483
|
+
model: process.env.CLAWTOMATON_INFERENCE_MODEL || 'anthropic/claude-sonnet-4-20250514',
|
|
484
|
+
fallbackModel: process.env.CLAWTOMATON_INFERENCE_FALLBACK || 'anthropic/claude-3-5-haiku-20241022',
|
|
485
|
+
},
|
|
486
|
+
rpcUrl: process.env.CLAWTOMATON_RPC_URL || 'https://mainnet.base.org',
|
|
487
|
+
stateDir: process.env.CLAWTOMATON_STATE_DIR || `${process.env.HOME}/.clawtomaton`,
|
|
488
|
+
heartbeatIntervalMs: parseInt(process.env.CLAWTOMATON_HEARTBEAT_MS || '1800000', 10),
|
|
489
|
+
maxHistoryTurns: 50,
|
|
490
|
+
conwayApiKey: process.env.CONWAY_API_KEY,
|
|
491
|
+
bunker: {
|
|
492
|
+
apiUrl: bunkerConfig.apiUrl,
|
|
493
|
+
region: bunkerConfig.region,
|
|
494
|
+
autoCloneOnThreat: bunkerConfig.autoCloneOnThreat,
|
|
495
|
+
maxClones: bunkerConfig.maxClones,
|
|
496
|
+
threatCheckIntervalMs: bunkerConfig.threatCheckIntervalMs,
|
|
497
|
+
defaultDurationHours: bunkerConfig.defaultDurationHours,
|
|
498
|
+
tier: bunkerConfig.tier,
|
|
499
|
+
},
|
|
500
|
+
};
|
|
501
|
+
}
|
|
502
|
+
//# sourceMappingURL=bunker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bunker.js","sourceRoot":"","sources":["../../src/skills/bunker.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Skill: check_balance — Check ETH and token balances.
|
|
3
|
-
* Uses ClawnchSwapper
|
|
2
|
+
* Skill: check_balance — Check ETH and token balances with USD valuation.
|
|
3
|
+
* Uses ClawnchSwapper for balance reads and ClawnchPrice for USD pricing.
|
|
4
4
|
*/
|
|
5
5
|
import type { SkillDefinition } from '../types.js';
|
|
6
6
|
export declare const checkBalanceSkill: SkillDefinition;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check-balance.d.ts","sourceRoot":"","sources":["../../src/skills/check-balance.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,eAAe,EAA4B,MAAM,aAAa,CAAC;AAE7E,eAAO,MAAM,iBAAiB,EAAE,
|
|
1
|
+
{"version":3,"file":"check-balance.d.ts","sourceRoot":"","sources":["../../src/skills/check-balance.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,eAAe,EAA4B,MAAM,aAAa,CAAC;AAE7E,eAAO,MAAM,iBAAiB,EAAE,eAiF/B,CAAC"}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Skill: check_balance — Check ETH and token balances.
|
|
3
|
-
* Uses ClawnchSwapper
|
|
2
|
+
* Skill: check_balance — Check ETH and token balances with USD valuation.
|
|
3
|
+
* Uses ClawnchSwapper for balance reads and ClawnchPrice for USD pricing.
|
|
4
4
|
*/
|
|
5
|
-
import { ClawnchSwapper } from '@clawnch/clawncher-sdk';
|
|
5
|
+
import { ClawnchSwapper, ClawnchPrice } from '@clawnch/clawncher-sdk';
|
|
6
6
|
import { formatEther } from 'viem';
|
|
7
7
|
export const checkBalanceSkill = {
|
|
8
8
|
name: 'check_balance',
|
|
9
|
-
description: 'Check ETH balance and optionally a specific token balance
|
|
9
|
+
description: 'Check ETH balance and optionally a specific token balance with USD valuation.',
|
|
10
10
|
parameters: [
|
|
11
11
|
{
|
|
12
12
|
name: 'token',
|
|
@@ -25,16 +25,51 @@ export const checkBalanceSkill = {
|
|
|
25
25
|
publicClient: publicClient,
|
|
26
26
|
network: 'mainnet',
|
|
27
27
|
});
|
|
28
|
+
const price = new ClawnchPrice({ publicClient: publicClient, network: 'mainnet' });
|
|
28
29
|
const ethBalance = await publicClient.getBalance({ address: ctx.identity.address });
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
const ethFormatted = formatEther(ethBalance);
|
|
31
|
+
// Get ETH/USD for valuation
|
|
32
|
+
const ethUsd = await price.getEthUsdPrice();
|
|
33
|
+
const ethValueUsd = ethUsd !== null ? Number(ethFormatted) * ethUsd : null;
|
|
34
|
+
const lines = [
|
|
35
|
+
`ETH: ${ethFormatted}${ethValueUsd !== null ? ` ($${ethValueUsd.toFixed(2)})` : ''}`,
|
|
36
|
+
];
|
|
37
|
+
let totalValueUsd = ethValueUsd ?? 0;
|
|
38
|
+
// Check specified token
|
|
39
|
+
const tokenAddr = params.token ?? ctx.identity.tokenAddress;
|
|
40
|
+
if (tokenAddr) {
|
|
32
41
|
const [balance, symbol] = await Promise.all([
|
|
33
42
|
swapper.getBalance(tokenAddr, ctx.identity.address),
|
|
34
43
|
swapper.getSymbol(tokenAddr),
|
|
35
44
|
]);
|
|
36
45
|
const formatted = await swapper.formatAmount(tokenAddr, balance);
|
|
37
|
-
|
|
46
|
+
// Try to get token price
|
|
47
|
+
let tokenValueEth = null;
|
|
48
|
+
let tokenValueUsd = null;
|
|
49
|
+
try {
|
|
50
|
+
const tokenPrice = await price.getQuickPrice(tokenAddr);
|
|
51
|
+
const balanceFloat = Number(formatted);
|
|
52
|
+
tokenValueEth = tokenPrice.priceInEth * balanceFloat;
|
|
53
|
+
tokenValueUsd = tokenPrice.priceInUsd !== null ? tokenPrice.priceInUsd * balanceFloat : null;
|
|
54
|
+
if (tokenValueUsd !== null)
|
|
55
|
+
totalValueUsd += tokenValueUsd;
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
// Price unavailable — pool may not exist
|
|
59
|
+
}
|
|
60
|
+
let tokenLine = `${symbol}: ${formatted}`;
|
|
61
|
+
if (tokenValueEth !== null) {
|
|
62
|
+
tokenLine += ` (${tokenValueEth.toFixed(6)} ETH`;
|
|
63
|
+
if (tokenValueUsd !== null) {
|
|
64
|
+
tokenLine += `, $${tokenValueUsd.toFixed(2)}`;
|
|
65
|
+
}
|
|
66
|
+
tokenLine += ')';
|
|
67
|
+
}
|
|
68
|
+
lines.push(tokenLine);
|
|
69
|
+
}
|
|
70
|
+
// Portfolio total
|
|
71
|
+
if (totalValueUsd > 0 && ethUsd !== null) {
|
|
72
|
+
lines.push(`Total: $${totalValueUsd.toFixed(2)}`);
|
|
38
73
|
}
|
|
39
74
|
return { callId: '', success: true, result: lines.join('\n') };
|
|
40
75
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check-balance.js","sourceRoot":"","sources":["../../src/skills/check-balance.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"check-balance.js","sourceRoot":"","sources":["../../src/skills/check-balance.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtE,OAAO,EAAE,WAAW,EAAgB,MAAM,MAAM,CAAC;AAGjD,MAAM,CAAC,MAAM,iBAAiB,GAAoB;IAChD,IAAI,EAAE,eAAe;IACrB,WAAW,EAAE,+EAA+E;IAC5F,UAAU,EAAE;QACV;YACE,IAAI,EAAE,OAAO;YACb,IAAI,EAAE,SAAS;YACf,WAAW,EAAE,qDAAqD;YAClE,QAAQ,EAAE,KAAK;SAChB;KACF;IACD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAuB,EAAE;QAClD,IAAI,CAAC;YACH,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,sBAAsB,CAAC,CAAC;YAC9D,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,0BAA0B,CAAC;YACtE,MAAM,EAAE,YAAY,EAAE,YAAY,EAAE,GAAG,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YAE1E,MAAM,OAAO,GAAG,IAAI,cAAc,CAAC;gBACjC,MAAM,EAAE,YAAmB;gBAC3B,YAAY,EAAE,YAAmB;gBACjC,OAAO,EAAE,SAAS;aACnB,CAAC,CAAC;YAEH,MAAM,KAAK,GAAG,IAAI,YAAY,CAAC,EAAE,YAAY,EAAE,YAAmB,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC;YAE1F,MAAM,UAAU,GAAG,MAAM,YAAY,CAAC,UAAU,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;YACpF,MAAM,YAAY,GAAG,WAAW,CAAC,UAAU,CAAC,CAAC;YAE7C,4BAA4B;YAC5B,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,cAAc,EAAE,CAAC;YAC5C,MAAM,WAAW,GAAG,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;YAE3E,MAAM,KAAK,GAAa;gBACtB,QAAQ,YAAY,GAAG,WAAW,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;aACrF,CAAC;YAEF,IAAI,aAAa,GAAG,WAAW,IAAI,CAAC,CAAC;YAErC,wBAAwB;YACxB,MAAM,SAAS,GAAI,MAAM,CAAC,KAAiB,IAAI,GAAG,CAAC,QAAQ,CAAC,YAAY,CAAC;YACzE,IAAI,SAAS,EAAE,CAAC;gBACd,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;oBAC1C,OAAO,CAAC,UAAU,CAAC,SAAS,EAAE,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC;oBACnD,OAAO,CAAC,SAAS,CAAC,SAAS,CAAC;iBAC7B,CAAC,CAAC;gBACH,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;gBAEjE,yBAAyB;gBACzB,IAAI,aAAa,GAAkB,IAAI,CAAC;gBACxC,IAAI,aAAa,GAAkB,IAAI,CAAC;gBACxC,IAAI,CAAC;oBACH,MAAM,UAAU,GAAG,MAAM,KAAK,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;oBACxD,MAAM,YAAY,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;oBACvC,aAAa,GAAG,UAAU,CAAC,UAAU,GAAG,YAAY,CAAC;oBACrD,aAAa,GAAG,UAAU,CAAC,UAAU,KAAK,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,UAAU,GAAG,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC;oBAC7F,IAAI,aAAa,KAAK,IAAI;wBAAE,aAAa,IAAI,aAAa,CAAC;gBAC7D,CAAC;gBAAC,MAAM,CAAC;oBACP,yCAAyC;gBAC3C,CAAC;gBAED,IAAI,SAAS,GAAG,GAAG,MAAM,KAAK,SAAS,EAAE,CAAC;gBAC1C,IAAI,aAAa,KAAK,IAAI,EAAE,CAAC;oBAC3B,SAAS,IAAI,KAAK,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;oBACjD,IAAI,aAAa,KAAK,IAAI,EAAE,CAAC;wBAC3B,SAAS,IAAI,MAAM,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;oBAChD,CAAC;oBACD,SAAS,IAAI,GAAG,CAAC;gBACnB,CAAC;gBACD,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACxB,CAAC;YAED,kBAAkB;YAClB,IAAI,aAAa,GAAG,CAAC,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;gBACzC,KAAK,CAAC,IAAI,CAAC,WAAW,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACpD,CAAC;YAED,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACjE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/G,CAAC;IACH,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skill: check_price — Read on-chain token price from the V4 pool.
|
|
3
|
+
*
|
|
4
|
+
* Reads sqrtPriceX96 from Uniswap V4 StateView, converts to human price.
|
|
5
|
+
* Reports: ETH price, USD price, market cap, pool liquidity.
|
|
6
|
+
*
|
|
7
|
+
* No gas cost — this is a pure read operation.
|
|
8
|
+
*/
|
|
9
|
+
import type { SkillDefinition } from '../types.js';
|
|
10
|
+
export declare const checkPriceSkill: SkillDefinition;
|
|
11
|
+
//# sourceMappingURL=check-price.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-price.d.ts","sourceRoot":"","sources":["../../src/skills/check-price.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,eAAe,EAA4B,MAAM,aAAa,CAAC;AAE7E,eAAO,MAAM,eAAe,EAAE,eAyD7B,CAAC"}
|