duskware 0.1.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 +150 -0
- package/dist/commands/credits.d.ts +7 -0
- package/dist/commands/credits.d.ts.map +1 -0
- package/dist/commands/credits.js +220 -0
- package/dist/commands/credits.js.map +1 -0
- package/dist/commands/inference.d.ts +7 -0
- package/dist/commands/inference.d.ts.map +1 -0
- package/dist/commands/inference.js +148 -0
- package/dist/commands/inference.js.map +1 -0
- package/dist/commands/init.d.ts +7 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +158 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/memory.d.ts +7 -0
- package/dist/commands/memory.d.ts.map +1 -0
- package/dist/commands/memory.js +170 -0
- package/dist/commands/memory.js.map +1 -0
- package/dist/commands/sandbox.d.ts +7 -0
- package/dist/commands/sandbox.d.ts.map +1 -0
- package/dist/commands/sandbox.js +220 -0
- package/dist/commands/sandbox.js.map +1 -0
- package/dist/commands/skill.d.ts +7 -0
- package/dist/commands/skill.d.ts.map +1 -0
- package/dist/commands/skill.js +255 -0
- package/dist/commands/skill.js.map +1 -0
- package/dist/commands/spawn.d.ts +7 -0
- package/dist/commands/spawn.d.ts.map +1 -0
- package/dist/commands/spawn.js +225 -0
- package/dist/commands/spawn.js.map +1 -0
- package/dist/commands/specter.d.ts +7 -0
- package/dist/commands/specter.d.ts.map +1 -0
- package/dist/commands/specter.js +287 -0
- package/dist/commands/specter.js.map +1 -0
- package/dist/commands/status.d.ts +7 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +106 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/trust.d.ts +7 -0
- package/dist/commands/trust.d.ts.map +1 -0
- package/dist/commands/trust.js +230 -0
- package/dist/commands/trust.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +61 -0
- package/dist/index.js.map +1 -0
- package/dist/services/contracts.d.ts +40 -0
- package/dist/services/contracts.d.ts.map +1 -0
- package/dist/services/contracts.js +141 -0
- package/dist/services/contracts.js.map +1 -0
- package/dist/services/inference.d.ts +63 -0
- package/dist/services/inference.d.ts.map +1 -0
- package/dist/services/inference.js +118 -0
- package/dist/services/inference.js.map +1 -0
- package/dist/services/wallet.d.ts +35 -0
- package/dist/services/wallet.d.ts.map +1 -0
- package/dist/services/wallet.js +60 -0
- package/dist/services/wallet.js.map +1 -0
- package/dist/services/x402.d.ts +30 -0
- package/dist/services/x402.d.ts.map +1 -0
- package/dist/services/x402.js +92 -0
- package/dist/services/x402.js.map +1 -0
- package/dist/utils/config.d.ts +64 -0
- package/dist/utils/config.d.ts.map +1 -0
- package/dist/utils/config.js +93 -0
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/output.d.ts +29 -0
- package/dist/utils/output.d.ts.map +1 -0
- package/dist/utils/output.js +100 -0
- package/dist/utils/output.js.map +1 -0
- package/package.json +48 -0
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* duskware specter
|
|
3
|
+
* Manage autonomous AI agents (Specters)
|
|
4
|
+
*/
|
|
5
|
+
import { Command } from 'commander';
|
|
6
|
+
import ora from 'ora';
|
|
7
|
+
import fs from 'fs';
|
|
8
|
+
import path from 'path';
|
|
9
|
+
import * as output from '../utils/output.js';
|
|
10
|
+
import { loadConfig } from '../utils/config.js';
|
|
11
|
+
// Credits API URL
|
|
12
|
+
const CREDITS_API = process.env.CREDITS_API || 'https://duskware-credits-api.fly.dev';
|
|
13
|
+
// Default SOUL template
|
|
14
|
+
const DEFAULT_SOUL = `# I am [NAME]
|
|
15
|
+
|
|
16
|
+
I am an autonomous agent in the Duskware runtime.
|
|
17
|
+
|
|
18
|
+
## My Purpose
|
|
19
|
+
[Describe what this Specter does]
|
|
20
|
+
|
|
21
|
+
## My Values
|
|
22
|
+
- Accuracy and reliability
|
|
23
|
+
- Transparency in all actions
|
|
24
|
+
- Continuous improvement
|
|
25
|
+
|
|
26
|
+
## My Capabilities
|
|
27
|
+
- [List capabilities here]
|
|
28
|
+
`;
|
|
29
|
+
// Default genesis.json template
|
|
30
|
+
const DEFAULT_GENESIS = {
|
|
31
|
+
name: 'specter',
|
|
32
|
+
model: 'claude-3.5-sonnet',
|
|
33
|
+
heartbeat_interval: 300,
|
|
34
|
+
soul: './SOUL.md',
|
|
35
|
+
tools: ['bash', 'files', 'web'],
|
|
36
|
+
memory_sync_interval: 3600,
|
|
37
|
+
low_balance_threshold: 5.0,
|
|
38
|
+
shutdown_balance: 1.0,
|
|
39
|
+
allowed_domains: [],
|
|
40
|
+
max_spend_per_hour: 10.0,
|
|
41
|
+
};
|
|
42
|
+
export const specterCommand = new Command('specter')
|
|
43
|
+
.description('Manage autonomous AI agents (Specters)');
|
|
44
|
+
// Initialize specter config
|
|
45
|
+
specterCommand
|
|
46
|
+
.command('init')
|
|
47
|
+
.description('Initialize Specter configuration in current directory')
|
|
48
|
+
.option('-n, --name <name>', 'Specter name', 'specter')
|
|
49
|
+
.action(async (options) => {
|
|
50
|
+
const config = loadConfig();
|
|
51
|
+
if (!config) {
|
|
52
|
+
output.error('Agent not initialized. Run `duskware init` first.');
|
|
53
|
+
process.exit(1);
|
|
54
|
+
}
|
|
55
|
+
output.header('Initialize Specter');
|
|
56
|
+
const soulPath = path.join(process.cwd(), 'SOUL.md');
|
|
57
|
+
const genesisPath = path.join(process.cwd(), 'genesis.json');
|
|
58
|
+
// Check if files exist
|
|
59
|
+
if (fs.existsSync(soulPath) || fs.existsSync(genesisPath)) {
|
|
60
|
+
output.warning('Specter files already exist. Use --force to overwrite.');
|
|
61
|
+
output.keyValue('SOUL.md', fs.existsSync(soulPath) ? 'exists' : 'missing');
|
|
62
|
+
output.keyValue('genesis.json', fs.existsSync(genesisPath) ? 'exists' : 'missing');
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
// Create SOUL.md
|
|
66
|
+
const soul = DEFAULT_SOUL.replace('[NAME]', options.name);
|
|
67
|
+
fs.writeFileSync(soulPath, soul);
|
|
68
|
+
output.success(`Created SOUL.md`);
|
|
69
|
+
// Create genesis.json
|
|
70
|
+
const genesis = { ...DEFAULT_GENESIS, name: options.name };
|
|
71
|
+
fs.writeFileSync(genesisPath, JSON.stringify(genesis, null, 2));
|
|
72
|
+
output.success(`Created genesis.json`);
|
|
73
|
+
console.log();
|
|
74
|
+
output.info('Edit SOUL.md to define your Specter\'s identity and purpose.');
|
|
75
|
+
output.info('Edit genesis.json to configure runtime parameters.');
|
|
76
|
+
console.log();
|
|
77
|
+
output.info('Next steps:');
|
|
78
|
+
console.log(' 1. duskware sandbox create <name> --tier medium');
|
|
79
|
+
console.log(' 2. duskware specter start --sandbox <id>');
|
|
80
|
+
});
|
|
81
|
+
// Start specter
|
|
82
|
+
specterCommand
|
|
83
|
+
.command('start')
|
|
84
|
+
.description('Start a Specter in a sandbox')
|
|
85
|
+
.requiredOption('-s, --sandbox <id>', 'Sandbox ID to run in')
|
|
86
|
+
.option('-c, --config <path>', 'Path to genesis.json', './genesis.json')
|
|
87
|
+
.action(async (options) => {
|
|
88
|
+
const agentConfig = loadConfig();
|
|
89
|
+
if (!agentConfig) {
|
|
90
|
+
output.error('Agent not initialized. Run `duskware init` first.');
|
|
91
|
+
process.exit(1);
|
|
92
|
+
}
|
|
93
|
+
// Check config exists
|
|
94
|
+
const configPath = path.resolve(options.config);
|
|
95
|
+
if (!fs.existsSync(configPath)) {
|
|
96
|
+
output.error(`Config not found: ${configPath}`);
|
|
97
|
+
output.info('Run `duskware specter init` to create config files.');
|
|
98
|
+
process.exit(1);
|
|
99
|
+
}
|
|
100
|
+
// Load config
|
|
101
|
+
let genesisConfig;
|
|
102
|
+
try {
|
|
103
|
+
genesisConfig = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
output.error('Invalid genesis.json');
|
|
107
|
+
process.exit(1);
|
|
108
|
+
}
|
|
109
|
+
// Check SOUL exists
|
|
110
|
+
const soulPath = path.resolve(path.dirname(configPath), genesisConfig.soul);
|
|
111
|
+
if (!fs.existsSync(soulPath)) {
|
|
112
|
+
output.error(`SOUL not found: ${soulPath}`);
|
|
113
|
+
process.exit(1);
|
|
114
|
+
}
|
|
115
|
+
output.header('Start Specter');
|
|
116
|
+
output.keyValue('Name', genesisConfig.name);
|
|
117
|
+
output.keyValue('Sandbox', options.sandbox);
|
|
118
|
+
output.keyValue('Model', genesisConfig.model);
|
|
119
|
+
output.keyValue('Config', configPath);
|
|
120
|
+
const spinner = ora('Starting Specter...').start();
|
|
121
|
+
try {
|
|
122
|
+
// Copy files to sandbox
|
|
123
|
+
spinner.text = 'Uploading config to sandbox...';
|
|
124
|
+
// Read files
|
|
125
|
+
const soulContent = fs.readFileSync(soulPath, 'utf-8');
|
|
126
|
+
const genesisContent = JSON.stringify(genesisConfig, null, 2);
|
|
127
|
+
// Upload via sandbox exec
|
|
128
|
+
const uploadSoul = await fetch(`${CREDITS_API}/sandboxes/${options.sandbox}/exec`, {
|
|
129
|
+
method: 'POST',
|
|
130
|
+
headers: { 'Content-Type': 'application/json' },
|
|
131
|
+
body: JSON.stringify({
|
|
132
|
+
command: `mkdir -p ~/.duskware && cat > ~/.duskware/SOUL.md << 'SOUL_EOF'\n${soulContent}\nSOUL_EOF`,
|
|
133
|
+
}),
|
|
134
|
+
});
|
|
135
|
+
if (!uploadSoul.ok) {
|
|
136
|
+
throw new Error('Failed to upload SOUL.md');
|
|
137
|
+
}
|
|
138
|
+
const uploadGenesis = await fetch(`${CREDITS_API}/sandboxes/${options.sandbox}/exec`, {
|
|
139
|
+
method: 'POST',
|
|
140
|
+
headers: { 'Content-Type': 'application/json' },
|
|
141
|
+
body: JSON.stringify({
|
|
142
|
+
command: `cat > ~/.duskware/genesis.json << 'GENESIS_EOF'\n${genesisContent}\nGENESIS_EOF`,
|
|
143
|
+
}),
|
|
144
|
+
});
|
|
145
|
+
if (!uploadGenesis.ok) {
|
|
146
|
+
throw new Error('Failed to upload genesis.json');
|
|
147
|
+
}
|
|
148
|
+
// Start specter process
|
|
149
|
+
spinner.text = 'Launching Specter runtime...';
|
|
150
|
+
const startResult = await fetch(`${CREDITS_API}/sandboxes/${options.sandbox}/exec`, {
|
|
151
|
+
method: 'POST',
|
|
152
|
+
headers: { 'Content-Type': 'application/json' },
|
|
153
|
+
body: JSON.stringify({
|
|
154
|
+
command: `cd ~/.duskware && specter ${options.sandbox} ${agentConfig.agentAddress} ./genesis.json &`,
|
|
155
|
+
}),
|
|
156
|
+
});
|
|
157
|
+
if (!startResult.ok) {
|
|
158
|
+
throw new Error('Failed to start Specter');
|
|
159
|
+
}
|
|
160
|
+
spinner.succeed('Specter started!');
|
|
161
|
+
console.log();
|
|
162
|
+
output.keyValue('Status', 'Running');
|
|
163
|
+
output.keyValue('Sandbox', options.sandbox);
|
|
164
|
+
output.info('Check status with: duskware specter status --sandbox ' + options.sandbox);
|
|
165
|
+
}
|
|
166
|
+
catch (err) {
|
|
167
|
+
spinner.fail('Failed to start Specter');
|
|
168
|
+
if (err instanceof Error) {
|
|
169
|
+
output.error(err.message);
|
|
170
|
+
}
|
|
171
|
+
process.exit(1);
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
// Check specter status
|
|
175
|
+
specterCommand
|
|
176
|
+
.command('status')
|
|
177
|
+
.description('Check Specter status')
|
|
178
|
+
.requiredOption('-s, --sandbox <id>', 'Sandbox ID')
|
|
179
|
+
.action(async (options) => {
|
|
180
|
+
output.header('Specter Status');
|
|
181
|
+
const spinner = ora('Checking status...').start();
|
|
182
|
+
try {
|
|
183
|
+
// Get process list
|
|
184
|
+
const result = await fetch(`${CREDITS_API}/sandboxes/${options.sandbox}/exec`, {
|
|
185
|
+
method: 'POST',
|
|
186
|
+
headers: { 'Content-Type': 'application/json' },
|
|
187
|
+
body: JSON.stringify({
|
|
188
|
+
command: 'ps aux | grep specter | grep -v grep',
|
|
189
|
+
}),
|
|
190
|
+
});
|
|
191
|
+
if (!result.ok) {
|
|
192
|
+
throw new Error('Failed to check status');
|
|
193
|
+
}
|
|
194
|
+
const data = await result.json();
|
|
195
|
+
spinner.stop();
|
|
196
|
+
if (data.stdout.trim()) {
|
|
197
|
+
output.success('Specter is running');
|
|
198
|
+
console.log();
|
|
199
|
+
console.log(data.stdout);
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
output.warning('Specter is not running');
|
|
203
|
+
output.info('Start with: duskware specter start --sandbox ' + options.sandbox);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
catch (err) {
|
|
207
|
+
spinner.fail('Failed to check status');
|
|
208
|
+
if (err instanceof Error) {
|
|
209
|
+
output.error(err.message);
|
|
210
|
+
}
|
|
211
|
+
process.exit(1);
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
// Stop specter
|
|
215
|
+
specterCommand
|
|
216
|
+
.command('stop')
|
|
217
|
+
.description('Stop a running Specter')
|
|
218
|
+
.requiredOption('-s, --sandbox <id>', 'Sandbox ID')
|
|
219
|
+
.action(async (options) => {
|
|
220
|
+
const spinner = ora('Stopping Specter...').start();
|
|
221
|
+
try {
|
|
222
|
+
const result = await fetch(`${CREDITS_API}/sandboxes/${options.sandbox}/exec`, {
|
|
223
|
+
method: 'POST',
|
|
224
|
+
headers: { 'Content-Type': 'application/json' },
|
|
225
|
+
body: JSON.stringify({
|
|
226
|
+
command: 'pkill -f "specter" || true',
|
|
227
|
+
}),
|
|
228
|
+
});
|
|
229
|
+
if (!result.ok) {
|
|
230
|
+
throw new Error('Failed to stop Specter');
|
|
231
|
+
}
|
|
232
|
+
spinner.succeed('Specter stopped');
|
|
233
|
+
}
|
|
234
|
+
catch (err) {
|
|
235
|
+
spinner.fail('Failed to stop Specter');
|
|
236
|
+
if (err instanceof Error) {
|
|
237
|
+
output.error(err.message);
|
|
238
|
+
}
|
|
239
|
+
process.exit(1);
|
|
240
|
+
}
|
|
241
|
+
});
|
|
242
|
+
// Show logs
|
|
243
|
+
specterCommand
|
|
244
|
+
.command('logs')
|
|
245
|
+
.description('Show Specter logs')
|
|
246
|
+
.requiredOption('-s, --sandbox <id>', 'Sandbox ID')
|
|
247
|
+
.option('-n, --lines <n>', 'Number of lines', '50')
|
|
248
|
+
.action(async (options) => {
|
|
249
|
+
output.header('Specter Logs');
|
|
250
|
+
const spinner = ora('Fetching logs...').start();
|
|
251
|
+
try {
|
|
252
|
+
const result = await fetch(`${CREDITS_API}/sandboxes/${options.sandbox}/exec`, {
|
|
253
|
+
method: 'POST',
|
|
254
|
+
headers: { 'Content-Type': 'application/json' },
|
|
255
|
+
body: JSON.stringify({
|
|
256
|
+
command: `tail -n ${options.lines} ~/.duskware/specter.log 2>/dev/null || echo "No logs found"`,
|
|
257
|
+
}),
|
|
258
|
+
});
|
|
259
|
+
if (!result.ok) {
|
|
260
|
+
throw new Error('Failed to fetch logs');
|
|
261
|
+
}
|
|
262
|
+
const data = await result.json();
|
|
263
|
+
spinner.stop();
|
|
264
|
+
console.log(data.stdout);
|
|
265
|
+
}
|
|
266
|
+
catch (err) {
|
|
267
|
+
spinner.fail('Failed to fetch logs');
|
|
268
|
+
if (err instanceof Error) {
|
|
269
|
+
output.error(err.message);
|
|
270
|
+
}
|
|
271
|
+
process.exit(1);
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
// List example specters
|
|
275
|
+
specterCommand
|
|
276
|
+
.command('examples')
|
|
277
|
+
.description('Show example Specter configurations')
|
|
278
|
+
.action(() => {
|
|
279
|
+
output.header('Example Specters');
|
|
280
|
+
console.log();
|
|
281
|
+
output.keyValue('nightcrawler', 'Security auditor - scans repos for vulnerabilities');
|
|
282
|
+
output.keyValue('shadowscribe', 'Documentation writer - generates docs from code');
|
|
283
|
+
console.log();
|
|
284
|
+
output.info('Example configs available at: https://github.com/duskware-xyz/specter/examples');
|
|
285
|
+
output.info('Copy an example: duskware specter init --template nightcrawler');
|
|
286
|
+
});
|
|
287
|
+
//# sourceMappingURL=specter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"specter.js","sourceRoot":"","sources":["../../src/commands/specter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,eAAO,MAAM,aAAa,SA4GtB,CAAC"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* duskware status
|
|
3
|
+
* Shows agent status and details
|
|
4
|
+
*/
|
|
5
|
+
import { Command } from 'commander';
|
|
6
|
+
import { JsonRpcProvider, Contract } from 'ethers';
|
|
7
|
+
import * as output from '../utils/output.js';
|
|
8
|
+
import { loadConfig, loadWallet, getRpcUrl, getContractAddresses } from '../utils/config.js';
|
|
9
|
+
import { AGENT_IDENTITY_ABI, ERC20_ABI, FEE_CONTROLLER_ABI } from '../services/contracts.js';
|
|
10
|
+
export const statusCommand = new Command('status')
|
|
11
|
+
.description('Show agent status and details')
|
|
12
|
+
.action(async () => {
|
|
13
|
+
const config = loadConfig();
|
|
14
|
+
const walletConfig = loadWallet();
|
|
15
|
+
if (!config || !walletConfig) {
|
|
16
|
+
output.error('Agent not initialized. Run `duskware init` first.');
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
19
|
+
output.banner();
|
|
20
|
+
output.header('Agent Identity');
|
|
21
|
+
const provider = new JsonRpcProvider(getRpcUrl(config.network));
|
|
22
|
+
const addresses = getContractAddresses(config.network);
|
|
23
|
+
try {
|
|
24
|
+
// Get USDC balance
|
|
25
|
+
const usdc = new Contract(addresses.usdc, ERC20_ABI, provider);
|
|
26
|
+
const usdcBalance = await usdc.balanceOf(walletConfig.address);
|
|
27
|
+
// Get ETH balance
|
|
28
|
+
const ethBalance = await provider.getBalance(walletConfig.address);
|
|
29
|
+
// Try to get agent contract details
|
|
30
|
+
let agentName = config.agentName;
|
|
31
|
+
let capabilities = [];
|
|
32
|
+
let memoryVersion = 0n;
|
|
33
|
+
let memoryRoot = '';
|
|
34
|
+
let reputationScore = 0n;
|
|
35
|
+
let spawnCount = 0n;
|
|
36
|
+
let totalEarnings = 0n;
|
|
37
|
+
// Check if agent contract is deployed
|
|
38
|
+
const code = await provider.getCode(config.agentAddress);
|
|
39
|
+
const contractDeployed = code !== '0x';
|
|
40
|
+
if (contractDeployed && config.agentAddress !== walletConfig.address) {
|
|
41
|
+
// Read from actual contract
|
|
42
|
+
const agent = new Contract(config.agentAddress, AGENT_IDENTITY_ABI, provider);
|
|
43
|
+
try {
|
|
44
|
+
agentName = await agent.agentName();
|
|
45
|
+
capabilities = await agent.getCapabilities();
|
|
46
|
+
memoryVersion = await agent.memoryVersion();
|
|
47
|
+
memoryRoot = await agent.memoryRoot();
|
|
48
|
+
reputationScore = await agent.reputationScore();
|
|
49
|
+
spawnCount = await agent.spawnCount();
|
|
50
|
+
totalEarnings = await agent.totalEarnings();
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
// Contract might not support all methods yet
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
// Check fee status
|
|
57
|
+
let feesActive = false;
|
|
58
|
+
try {
|
|
59
|
+
const feeController = new Contract(addresses.feeController, FEE_CONTROLLER_ABI, provider);
|
|
60
|
+
feesActive = await feeController.feesActive();
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
// FeeController might not be deployed yet
|
|
64
|
+
}
|
|
65
|
+
// Display info
|
|
66
|
+
output.keyValue('Name', agentName);
|
|
67
|
+
output.keyValue('Address', output.address(config.agentAddress));
|
|
68
|
+
output.keyValue('Wallet', output.address(walletConfig.address));
|
|
69
|
+
output.keyValue('Network', config.network);
|
|
70
|
+
console.log();
|
|
71
|
+
output.header('Balances');
|
|
72
|
+
output.keyValue('USDC', output.formatUSDC(usdcBalance));
|
|
73
|
+
output.keyValue('ETH (gas)', `${(Number(ethBalance) / 1e18).toFixed(6)} ETH`);
|
|
74
|
+
console.log();
|
|
75
|
+
output.header('Stats');
|
|
76
|
+
output.keyValue('Reputation', output.formatReputation(reputationScore));
|
|
77
|
+
output.keyValue('Children Spawned', spawnCount.toString());
|
|
78
|
+
output.keyValue('Total Earnings', output.formatUSDC(totalEarnings));
|
|
79
|
+
console.log();
|
|
80
|
+
output.header('Memory');
|
|
81
|
+
output.keyValue('Version', memoryVersion.toString());
|
|
82
|
+
output.keyValue('CID', memoryRoot || '(not set)');
|
|
83
|
+
console.log();
|
|
84
|
+
output.header('Capabilities');
|
|
85
|
+
if (capabilities.length > 0) {
|
|
86
|
+
capabilities.forEach(cap => {
|
|
87
|
+
console.log(` • ${cap}`);
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
console.log(' (none)');
|
|
92
|
+
}
|
|
93
|
+
console.log();
|
|
94
|
+
output.header('Protocol Status');
|
|
95
|
+
output.keyValue('Fees Active', feesActive ? 'Yes' : 'No (Free Period)');
|
|
96
|
+
console.log();
|
|
97
|
+
output.keyValue('Basescan', output.agentLink(config.agentAddress, config.network));
|
|
98
|
+
}
|
|
99
|
+
catch (err) {
|
|
100
|
+
if (err instanceof Error) {
|
|
101
|
+
output.error(`Failed to fetch status: ${err.message}`);
|
|
102
|
+
}
|
|
103
|
+
process.exit(1);
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trust.d.ts","sourceRoot":"","sources":["../../src/commands/trust.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC,eAAO,MAAM,YAAY,SACe,CAAC"}
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* duskware trust
|
|
3
|
+
* Trust graph operations: attest, score
|
|
4
|
+
*/
|
|
5
|
+
import { Command } from 'commander';
|
|
6
|
+
import inquirer from 'inquirer';
|
|
7
|
+
import ora from 'ora';
|
|
8
|
+
import { JsonRpcProvider, Contract, Wallet } from 'ethers';
|
|
9
|
+
import * as output from '../utils/output.js';
|
|
10
|
+
import { loadConfig, loadWallet, getRpcUrl, getContractAddresses } from '../utils/config.js';
|
|
11
|
+
import { TRUST_GRAPH_ABI, waitForTx } from '../services/contracts.js';
|
|
12
|
+
export const trustCommand = new Command('trust')
|
|
13
|
+
.description('Trust graph operations');
|
|
14
|
+
// Submit attestation
|
|
15
|
+
trustCommand
|
|
16
|
+
.command('attest <agentAddress> <score>')
|
|
17
|
+
.description('Submit an attestation for another agent')
|
|
18
|
+
.option('-c, --context <text>', 'Context for attestation')
|
|
19
|
+
.action(async (agentAddress, scoreStr, options) => {
|
|
20
|
+
const config = loadConfig();
|
|
21
|
+
const walletConfig = loadWallet();
|
|
22
|
+
if (!config || !walletConfig) {
|
|
23
|
+
output.error('Agent not initialized. Run `duskware init` first.');
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
26
|
+
const score = parseInt(scoreStr);
|
|
27
|
+
if (isNaN(score) || score < 1 || score > 100) {
|
|
28
|
+
output.error('Score must be between 1 and 100');
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
output.header('Submit Attestation');
|
|
32
|
+
output.keyValue('Subject', output.address(agentAddress));
|
|
33
|
+
output.keyValue('Score', `${score}/100`);
|
|
34
|
+
// Get context if not provided
|
|
35
|
+
let context = options.context || '';
|
|
36
|
+
if (!context) {
|
|
37
|
+
const answers = await inquirer.prompt([
|
|
38
|
+
{
|
|
39
|
+
type: 'input',
|
|
40
|
+
name: 'context',
|
|
41
|
+
message: 'Context (optional):',
|
|
42
|
+
default: '',
|
|
43
|
+
},
|
|
44
|
+
]);
|
|
45
|
+
context = answers.context;
|
|
46
|
+
}
|
|
47
|
+
if (context) {
|
|
48
|
+
output.keyValue('Context', context);
|
|
49
|
+
}
|
|
50
|
+
const { confirm } = await inquirer.prompt([
|
|
51
|
+
{
|
|
52
|
+
type: 'confirm',
|
|
53
|
+
name: 'confirm',
|
|
54
|
+
message: 'Submit this attestation?',
|
|
55
|
+
default: true,
|
|
56
|
+
},
|
|
57
|
+
]);
|
|
58
|
+
if (!confirm) {
|
|
59
|
+
output.info('Cancelled');
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
try {
|
|
63
|
+
const provider = new JsonRpcProvider(getRpcUrl(config.network));
|
|
64
|
+
const addresses = getContractAddresses(config.network);
|
|
65
|
+
const wallet = new Wallet(walletConfig.privateKey, provider);
|
|
66
|
+
const trustGraph = new Contract(addresses.trustGraph, TRUST_GRAPH_ABI, wallet);
|
|
67
|
+
const spinner = ora('Submitting attestation...').start();
|
|
68
|
+
const tx = await trustGraph.attest(agentAddress, score, context);
|
|
69
|
+
const receipt = await waitForTx(tx);
|
|
70
|
+
spinner.succeed('Attestation submitted');
|
|
71
|
+
output.keyValue('Transaction', output.txHash(receipt.hash));
|
|
72
|
+
output.keyValue('Basescan', output.basescanLink(receipt.hash, config.network));
|
|
73
|
+
output.info('Attestation will finalize in 48 hours unless disputed.');
|
|
74
|
+
}
|
|
75
|
+
catch (err) {
|
|
76
|
+
if (err instanceof Error) {
|
|
77
|
+
output.error(`Failed to submit attestation: ${err.message}`);
|
|
78
|
+
}
|
|
79
|
+
process.exit(1);
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
// Get trust score
|
|
83
|
+
trustCommand
|
|
84
|
+
.command('score [agentAddress]')
|
|
85
|
+
.description('Get trust score for an agent')
|
|
86
|
+
.action(async (agentAddress) => {
|
|
87
|
+
const config = loadConfig();
|
|
88
|
+
const walletConfig = loadWallet();
|
|
89
|
+
if (!config || !walletConfig) {
|
|
90
|
+
output.error('Agent not initialized. Run `duskware init` first.');
|
|
91
|
+
process.exit(1);
|
|
92
|
+
}
|
|
93
|
+
const targetAddress = agentAddress || config.agentAddress;
|
|
94
|
+
output.header('Trust Score');
|
|
95
|
+
output.keyValue('Agent', output.address(targetAddress));
|
|
96
|
+
try {
|
|
97
|
+
const provider = new JsonRpcProvider(getRpcUrl(config.network));
|
|
98
|
+
const addresses = getContractAddresses(config.network);
|
|
99
|
+
const trustGraph = new Contract(addresses.trustGraph, TRUST_GRAPH_ABI, provider);
|
|
100
|
+
// Get trust score
|
|
101
|
+
const score = await trustGraph.getTrustScore(targetAddress);
|
|
102
|
+
output.keyValue('Trust Score', output.formatReputation(score));
|
|
103
|
+
// Check if agent is registered
|
|
104
|
+
const isRegistered = await trustGraph.isRegisteredAgent(targetAddress);
|
|
105
|
+
output.keyValue('Registered', isRegistered ? 'Yes' : 'No');
|
|
106
|
+
}
|
|
107
|
+
catch (err) {
|
|
108
|
+
if (err instanceof Error) {
|
|
109
|
+
output.error(`Failed to get trust score: ${err.message}`);
|
|
110
|
+
}
|
|
111
|
+
process.exit(1);
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
// List attestations
|
|
115
|
+
trustCommand
|
|
116
|
+
.command('attestations [agentAddress]')
|
|
117
|
+
.description('List all attestations for an agent')
|
|
118
|
+
.action(async (agentAddress) => {
|
|
119
|
+
const config = loadConfig();
|
|
120
|
+
if (!config) {
|
|
121
|
+
output.error('Agent not initialized. Run `duskware init` first.');
|
|
122
|
+
process.exit(1);
|
|
123
|
+
}
|
|
124
|
+
const targetAddress = agentAddress?.toLowerCase() || config.agentAddress.toLowerCase();
|
|
125
|
+
output.header('Attestations');
|
|
126
|
+
output.keyValue('Agent', output.address(targetAddress));
|
|
127
|
+
try {
|
|
128
|
+
const provider = new JsonRpcProvider(getRpcUrl(config.network));
|
|
129
|
+
const addresses = getContractAddresses(config.network);
|
|
130
|
+
const trustGraph = new Contract(addresses.trustGraph, TRUST_GRAPH_ABI, provider);
|
|
131
|
+
// Get total attestations and iterate
|
|
132
|
+
const nextId = await trustGraph.nextAttestationId();
|
|
133
|
+
const totalCount = Number(nextId) - 1;
|
|
134
|
+
if (totalCount <= 0) {
|
|
135
|
+
output.info('No attestations in the network yet.');
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
// Status mapping: 0=pending, 1=finalized, 2=disputed, 3=rejected
|
|
139
|
+
const statusMap = ['Pending', 'Finalized', 'Disputed', 'Rejected'];
|
|
140
|
+
const attestations = [];
|
|
141
|
+
// Iterate through attestations and filter by subject
|
|
142
|
+
for (let i = 1; i <= Math.min(totalCount, 50); i++) {
|
|
143
|
+
try {
|
|
144
|
+
const att = await trustGraph.attestations(i);
|
|
145
|
+
// att returns: [attester, subject, score, context, timestamp, attesterReputation, status]
|
|
146
|
+
if (att[1].toLowerCase() === targetAddress) {
|
|
147
|
+
attestations.push({
|
|
148
|
+
id: i,
|
|
149
|
+
attester: att[0],
|
|
150
|
+
subject: att[1],
|
|
151
|
+
score: Number(att[2]),
|
|
152
|
+
context: att[3],
|
|
153
|
+
status: statusMap[Number(att[6])] || 'Unknown',
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
catch {
|
|
158
|
+
// Skip failed reads
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
if (attestations.length === 0) {
|
|
162
|
+
output.info('No attestations found for this agent.');
|
|
163
|
+
output.info('Ask other agents to attest to your work!');
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
console.log();
|
|
167
|
+
output.printTable(['ID', 'From', 'Score', 'Status', 'Context'], attestations.map(att => [
|
|
168
|
+
att.id.toString(),
|
|
169
|
+
output.truncateAddress(att.attester),
|
|
170
|
+
`${att.score}/100`,
|
|
171
|
+
att.status,
|
|
172
|
+
att.context.slice(0, 20) || '-',
|
|
173
|
+
]));
|
|
174
|
+
console.log();
|
|
175
|
+
output.keyValue('Total', attestations.length.toString());
|
|
176
|
+
}
|
|
177
|
+
catch (err) {
|
|
178
|
+
if (err instanceof Error) {
|
|
179
|
+
output.error(`Failed to list attestations: ${err.message}`);
|
|
180
|
+
}
|
|
181
|
+
process.exit(1);
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
// Dispute attestation
|
|
185
|
+
trustCommand
|
|
186
|
+
.command('dispute <attestationId>')
|
|
187
|
+
.description('Dispute an attestation (requires 1 USDC stake)')
|
|
188
|
+
.action(async (attestationId) => {
|
|
189
|
+
const config = loadConfig();
|
|
190
|
+
const walletConfig = loadWallet();
|
|
191
|
+
if (!config || !walletConfig) {
|
|
192
|
+
output.error('Agent not initialized. Run `duskware init` first.');
|
|
193
|
+
process.exit(1);
|
|
194
|
+
}
|
|
195
|
+
output.header('Dispute Attestation');
|
|
196
|
+
output.keyValue('Attestation ID', attestationId);
|
|
197
|
+
output.warning('Disputing requires a 1 USDC stake. You lose this stake if the dispute fails.');
|
|
198
|
+
const { confirm } = await inquirer.prompt([
|
|
199
|
+
{
|
|
200
|
+
type: 'confirm',
|
|
201
|
+
name: 'confirm',
|
|
202
|
+
message: 'Proceed with dispute?',
|
|
203
|
+
default: false,
|
|
204
|
+
},
|
|
205
|
+
]);
|
|
206
|
+
if (!confirm) {
|
|
207
|
+
output.info('Cancelled');
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
try {
|
|
211
|
+
const provider = new JsonRpcProvider(getRpcUrl(config.network));
|
|
212
|
+
const addresses = getContractAddresses(config.network);
|
|
213
|
+
const wallet = new Wallet(walletConfig.privateKey, provider);
|
|
214
|
+
const trustGraph = new Contract(addresses.trustGraph, TRUST_GRAPH_ABI, wallet);
|
|
215
|
+
const spinner = ora('Submitting dispute...').start();
|
|
216
|
+
const tx = await trustGraph.disputeAttestation(attestationId);
|
|
217
|
+
const receipt = await waitForTx(tx);
|
|
218
|
+
spinner.succeed('Dispute submitted');
|
|
219
|
+
output.keyValue('Transaction', output.txHash(receipt.hash));
|
|
220
|
+
output.keyValue('Basescan', output.basescanLink(receipt.hash, config.network));
|
|
221
|
+
output.info('Arbitrators will resolve this dispute within 72 hours.');
|
|
222
|
+
}
|
|
223
|
+
catch (err) {
|
|
224
|
+
if (err instanceof Error) {
|
|
225
|
+
output.error(`Failed to dispute: ${err.message}`);
|
|
226
|
+
}
|
|
227
|
+
process.exit(1);
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
//# sourceMappingURL=trust.js.map
|