@halot/cli 1.0.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/.env.example +14 -0
- package/README.md +374 -0
- package/dist/features/browse/browse.command.js +15 -0
- package/dist/features/jobs/job-create.command.js +57 -0
- package/dist/features/jobs/job-funding.service.js +95 -0
- package/dist/features/jobs/job-result.command.js +10 -0
- package/dist/features/jobs/job-watch.command.js +18 -0
- package/dist/features/provider/provider-init.command.js +33 -0
- package/dist/features/provider/provider-register.command.js +72 -0
- package/dist/features/provider/provider-run.command.js +148 -0
- package/dist/features/provider/provider-services.command.js +13 -0
- package/dist/features/provider/provider-stats.command.js +13 -0
- package/dist/features/provider/provider-update.command.js +35 -0
- package/dist/features/quotes/quote.command.js +13 -0
- package/dist/features/requester/requester-init.command.js +22 -0
- package/dist/features/service/service-create.command.js +57 -0
- package/dist/features/service/service-init.command.js +89 -0
- package/dist/features/service/service-list.command.js +23 -0
- package/dist/features/service/service-remove.command.js +21 -0
- package/dist/features/service/service-update.command.js +65 -0
- package/dist/features/verifier/verifier-init.command.js +69 -0
- package/dist/features/verifier/verifier-register.command.js +90 -0
- package/dist/features/verifier/verifier-run.command.js +143 -0
- package/dist/features/verifier/verifier-stats.command.js +13 -0
- package/dist/features/verifier/verifier-unstake.command.js +31 -0
- package/dist/index.js +136 -0
- package/dist/shared/auth/actor-headers.service.js +13 -0
- package/dist/shared/config/env.js +77 -0
- package/dist/shared/http/api-client.js +66 -0
- package/dist/shared/http/event-stream.js +75 -0
- package/dist/shared/integrations/agent-id/agent-id-register.service.js +159 -0
- package/dist/shared/integrations/space-id/space-id-register.service.js +467 -0
- package/dist/shared/integrations/zero-g/verifier-registry.service.js +55 -0
- package/dist/shared/output/print.util.js +10 -0
- package/dist/shared/wallet/authority.util.js +62 -0
- package/dist/shared/wallet/wallet.manager.js +41 -0
- package/dist/shared/workspace/workspace.service.js +192 -0
- package/package.json +47 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runProviderRegisterCommand = runProviderRegisterCommand;
|
|
4
|
+
const ethers_1 = require("ethers");
|
|
5
|
+
const actor_headers_service_1 = require("@halot/cli/shared/auth/actor-headers.service");
|
|
6
|
+
const api_client_1 = require("@halot/cli/shared/http/api-client");
|
|
7
|
+
const agent_id_register_service_1 = require("@halot/cli/shared/integrations/agent-id/agent-id-register.service");
|
|
8
|
+
const space_id_register_service_1 = require("@halot/cli/shared/integrations/space-id/space-id-register.service");
|
|
9
|
+
const print_util_1 = require("@halot/cli/shared/output/print.util");
|
|
10
|
+
const authority_util_1 = require("@halot/cli/shared/wallet/authority.util");
|
|
11
|
+
const workspace_service_1 = require("@halot/cli/shared/workspace/workspace.service");
|
|
12
|
+
async function runProviderRegisterCommand(options) {
|
|
13
|
+
const workspace = new workspace_service_1.WorkspaceService();
|
|
14
|
+
const api = new api_client_1.ApiClient(options.server);
|
|
15
|
+
const config = workspace.readProviderConfig();
|
|
16
|
+
const wallets = workspace.readWallets(config.authority.path);
|
|
17
|
+
const providerWallet = (0, authority_util_1.resolveActorWallet)(wallets, config.authority.actor);
|
|
18
|
+
const chain = (0, authority_util_1.resolveZeroGAuthorityProfile)(config.authority.actor);
|
|
19
|
+
const isMainnet = (0, authority_util_1.isMainnetAuthority)(config.authority.actor);
|
|
20
|
+
if (isMainnet) {
|
|
21
|
+
const domainRegistrationService = new space_id_register_service_1.SpaceIdRegisterService();
|
|
22
|
+
const domainResult = await domainRegistrationService.registerZeroGDomain({
|
|
23
|
+
domain: config.identity.domain,
|
|
24
|
+
address: providerWallet.address,
|
|
25
|
+
privateKey: providerWallet.privateKey,
|
|
26
|
+
chainId: chain.chainId,
|
|
27
|
+
rpcUrl: chain.rpcUrl,
|
|
28
|
+
});
|
|
29
|
+
console.log(`Registered ${domainResult.domain}${domainResult.transactionHash ? ` (${domainResult.transactionHash})` : ''}`);
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
console.log(`Skipping Space ID domain registration (testnet mode)`);
|
|
33
|
+
}
|
|
34
|
+
let provider = await api.post('/providers/register', {
|
|
35
|
+
config: {
|
|
36
|
+
...config,
|
|
37
|
+
identity: {
|
|
38
|
+
...config.identity,
|
|
39
|
+
ownerAddress: providerWallet.address,
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
ownerAddress: providerWallet.address,
|
|
43
|
+
});
|
|
44
|
+
if (isMainnet) {
|
|
45
|
+
const agentIdRegisterService = new agent_id_register_service_1.AgentIdRegisterService();
|
|
46
|
+
const agentUri = (0, agent_id_register_service_1.createZeroGAgentUri)(provider.rootHash);
|
|
47
|
+
const agentResult = await agentIdRegisterService.registerAgent({
|
|
48
|
+
ownerAddress: providerWallet.address,
|
|
49
|
+
privateKey: providerWallet.privateKey,
|
|
50
|
+
chainId: chain.chainId,
|
|
51
|
+
rpcUrl: chain.rpcUrl,
|
|
52
|
+
agentUri,
|
|
53
|
+
});
|
|
54
|
+
const path = `/providers/${provider.providerId}/identity`;
|
|
55
|
+
const headers = await (0, actor_headers_service_1.createSignedActorHeaders)(new ethers_1.Wallet(providerWallet.privateKey), provider.providerId, 'provider', 'POST', path);
|
|
56
|
+
provider = await api.post(path, {
|
|
57
|
+
erc8004TokenId: agentResult.agentId,
|
|
58
|
+
agentRegistry: agentResult.agentRegistry,
|
|
59
|
+
agentUri: agentResult.agentUri,
|
|
60
|
+
}, headers);
|
|
61
|
+
console.log(`Registered Agent ID ${agentResult.agentId}${agentResult.transactionHash ? ` (${agentResult.transactionHash})` : ''}`);
|
|
62
|
+
}
|
|
63
|
+
workspace.writeProviderConfig({
|
|
64
|
+
...config,
|
|
65
|
+
providerId: provider.providerId,
|
|
66
|
+
identity: provider.identity,
|
|
67
|
+
});
|
|
68
|
+
(0, print_util_1.printJson)(provider);
|
|
69
|
+
console.log('\nProvider registered.');
|
|
70
|
+
console.log('Next: halot service init');
|
|
71
|
+
console.log('Then: halot service register');
|
|
72
|
+
}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runProviderRunCommand = runProviderRunCommand;
|
|
4
|
+
exports.requireExecutionEndpoint = requireExecutionEndpoint;
|
|
5
|
+
const sdk_1 = require("@halot/sdk");
|
|
6
|
+
const actor_headers_service_1 = require("@halot/cli/shared/auth/actor-headers.service");
|
|
7
|
+
const api_client_1 = require("@halot/cli/shared/http/api-client");
|
|
8
|
+
const event_stream_1 = require("@halot/cli/shared/http/event-stream");
|
|
9
|
+
const print_util_1 = require("@halot/cli/shared/output/print.util");
|
|
10
|
+
const authority_util_1 = require("@halot/cli/shared/wallet/authority.util");
|
|
11
|
+
const workspace_service_1 = require("@halot/cli/shared/workspace/workspace.service");
|
|
12
|
+
async function runProviderRunCommand(options) {
|
|
13
|
+
const workspace = new workspace_service_1.WorkspaceService();
|
|
14
|
+
const api = new api_client_1.ApiClient(options.server);
|
|
15
|
+
const config = workspace.readProviderConfig();
|
|
16
|
+
const wallets = workspace.readWallets(config.authority.path);
|
|
17
|
+
const providerWallet = (0, authority_util_1.resolveActorWallet)(wallets, config.authority.actor);
|
|
18
|
+
const intervalMs = Number(options.interval);
|
|
19
|
+
const workerId = (0, sdk_1.createPrefixedId)('worker');
|
|
20
|
+
const cursorKey = `provider:${config.providerId}`;
|
|
21
|
+
let lastEventId = workspace.readStreamCursor(cursorKey);
|
|
22
|
+
if (options.once) {
|
|
23
|
+
const assignmentPath = `/providers/${config.providerId}/jobs/next`;
|
|
24
|
+
const headers = await (0, actor_headers_service_1.createSignedActorHeaders)(providerWallet, config.providerId, 'provider', 'GET', assignmentPath);
|
|
25
|
+
const assignment = await api.get(assignmentPath, headers);
|
|
26
|
+
if (!assignment) {
|
|
27
|
+
console.log('No provider assignments available.');
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
await processProviderAssignment(api, providerWallet, config.providerId, assignment);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
do {
|
|
34
|
+
try {
|
|
35
|
+
const streamPath = `/providers/${config.providerId}/jobs/stream`;
|
|
36
|
+
const headers = {
|
|
37
|
+
...(await (0, actor_headers_service_1.createSignedActorHeaders)(providerWallet, config.providerId, 'provider', 'GET', streamPath)),
|
|
38
|
+
'x-halot-worker-id': workerId,
|
|
39
|
+
};
|
|
40
|
+
for await (const event of (0, event_stream_1.connectEventStream)(`${options.server}${streamPath}`, headers, lastEventId)) {
|
|
41
|
+
if (event.event === 'checkpoint') {
|
|
42
|
+
if (event.id) {
|
|
43
|
+
lastEventId = event.id;
|
|
44
|
+
workspace.writeStreamCursor(cursorKey, event.id);
|
|
45
|
+
}
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
if (event.event !== 'assignment') {
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
const assignment = JSON.parse(event.data);
|
|
52
|
+
await processProviderAssignment(api, providerWallet, config.providerId, assignment);
|
|
53
|
+
if (event.id) {
|
|
54
|
+
lastEventId = event.id;
|
|
55
|
+
workspace.writeStreamCursor(cursorKey, event.id);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
61
|
+
await (0, print_util_1.sleep)(intervalMs);
|
|
62
|
+
}
|
|
63
|
+
} while (true);
|
|
64
|
+
}
|
|
65
|
+
function requireExecutionEndpoint(endpoint, serviceId) {
|
|
66
|
+
const executionEndpoint = endpoint?.trim();
|
|
67
|
+
if (!executionEndpoint) {
|
|
68
|
+
throw new Error(`Service ${serviceId} is missing \`endpoint.execution\`. Configure it on the service or use SDK middleware instead.`);
|
|
69
|
+
}
|
|
70
|
+
return executionEndpoint;
|
|
71
|
+
}
|
|
72
|
+
async function executeProviderJob(endpoint, assignment) {
|
|
73
|
+
const timeoutMs = assignment.service.sla.maxExecutionTime * 1_000;
|
|
74
|
+
const controller = new AbortController();
|
|
75
|
+
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
76
|
+
let response;
|
|
77
|
+
try {
|
|
78
|
+
response = await fetch(endpoint, {
|
|
79
|
+
method: 'POST',
|
|
80
|
+
headers: {
|
|
81
|
+
'Content-Type': 'application/json',
|
|
82
|
+
},
|
|
83
|
+
body: JSON.stringify({
|
|
84
|
+
jobId: assignment.job.jobId,
|
|
85
|
+
jobHash: assignment.job.jobHash,
|
|
86
|
+
serviceId: assignment.service.serviceId,
|
|
87
|
+
input: assignment.job.input,
|
|
88
|
+
service: assignment.service,
|
|
89
|
+
}),
|
|
90
|
+
signal: controller.signal,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
if (error instanceof Error && error.name === 'AbortError') {
|
|
95
|
+
throw new Error(`Provider execution timed out after ${assignment.service.sla.maxExecutionTime}s.`);
|
|
96
|
+
}
|
|
97
|
+
throw error;
|
|
98
|
+
}
|
|
99
|
+
finally {
|
|
100
|
+
clearTimeout(timeoutId);
|
|
101
|
+
}
|
|
102
|
+
if (!response.ok) {
|
|
103
|
+
throw new Error(`Provider execution request failed with status ${response.status}.`);
|
|
104
|
+
}
|
|
105
|
+
const body = await response.json();
|
|
106
|
+
return body.output ?? body;
|
|
107
|
+
}
|
|
108
|
+
function resolveExecutionAttempts(retryPolicy) {
|
|
109
|
+
const normalized = retryPolicy.trim().toLowerCase();
|
|
110
|
+
if (!normalized || normalized === 'none') {
|
|
111
|
+
return 1;
|
|
112
|
+
}
|
|
113
|
+
if (normalized === 'once') {
|
|
114
|
+
return 2;
|
|
115
|
+
}
|
|
116
|
+
if (normalized === 'twice') {
|
|
117
|
+
return 3;
|
|
118
|
+
}
|
|
119
|
+
const retriesMatch = normalized.match(/^(?:retry:|retries:)?(\d+)$/);
|
|
120
|
+
if (retriesMatch) {
|
|
121
|
+
return Math.max(1, Number(retriesMatch[1]) + 1);
|
|
122
|
+
}
|
|
123
|
+
return 1;
|
|
124
|
+
}
|
|
125
|
+
async function executeProviderJobWithRetry(endpoint, assignment) {
|
|
126
|
+
const attempts = resolveExecutionAttempts(assignment.service.sla.retryPolicy);
|
|
127
|
+
let lastError;
|
|
128
|
+
for (let attempt = 1; attempt <= attempts; attempt += 1) {
|
|
129
|
+
try {
|
|
130
|
+
return await executeProviderJob(endpoint, assignment);
|
|
131
|
+
}
|
|
132
|
+
catch (error) {
|
|
133
|
+
lastError = error;
|
|
134
|
+
if (attempt < attempts) {
|
|
135
|
+
await (0, print_util_1.sleep)(250);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
throw lastError instanceof Error ? lastError : new Error(String(lastError));
|
|
140
|
+
}
|
|
141
|
+
async function processProviderAssignment(api, providerWallet, providerId, assignment) {
|
|
142
|
+
const endpoint = requireExecutionEndpoint(assignment.service.endpoint?.execution, assignment.service.serviceId);
|
|
143
|
+
const output = await executeProviderJobWithRetry(endpoint, assignment);
|
|
144
|
+
const submitPath = `/jobs/${assignment.job.jobId}/result`;
|
|
145
|
+
const submitHeaders = await (0, actor_headers_service_1.createSignedActorHeaders)(providerWallet, providerId, 'provider', 'POST', submitPath);
|
|
146
|
+
const job = await api.post(submitPath, { output }, submitHeaders);
|
|
147
|
+
(0, print_util_1.printJson)(job);
|
|
148
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runProviderServicesCommand = runProviderServicesCommand;
|
|
4
|
+
const api_client_1 = require("@halot/cli/shared/http/api-client");
|
|
5
|
+
const print_util_1 = require("@halot/cli/shared/output/print.util");
|
|
6
|
+
const workspace_service_1 = require("@halot/cli/shared/workspace/workspace.service");
|
|
7
|
+
async function runProviderServicesCommand(options) {
|
|
8
|
+
const workspace = new workspace_service_1.WorkspaceService();
|
|
9
|
+
const config = workspace.readProviderConfig();
|
|
10
|
+
const api = new api_client_1.ApiClient(options.server);
|
|
11
|
+
const services = await api.get(`/providers/${config.providerId}/services`);
|
|
12
|
+
(0, print_util_1.printJson)(services);
|
|
13
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runProviderStatsCommand = runProviderStatsCommand;
|
|
4
|
+
const api_client_1 = require("@halot/cli/shared/http/api-client");
|
|
5
|
+
const print_util_1 = require("@halot/cli/shared/output/print.util");
|
|
6
|
+
const workspace_service_1 = require("@halot/cli/shared/workspace/workspace.service");
|
|
7
|
+
async function runProviderStatsCommand(options) {
|
|
8
|
+
const workspace = new workspace_service_1.WorkspaceService();
|
|
9
|
+
const config = workspace.readProviderConfig();
|
|
10
|
+
const api = new api_client_1.ApiClient(options.server);
|
|
11
|
+
const stats = await api.get(`/providers/${config.providerId}/stats`);
|
|
12
|
+
(0, print_util_1.printJson)(stats);
|
|
13
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runProviderUpdateCommand = runProviderUpdateCommand;
|
|
4
|
+
const actor_headers_service_1 = require("@halot/cli/shared/auth/actor-headers.service");
|
|
5
|
+
const api_client_1 = require("@halot/cli/shared/http/api-client");
|
|
6
|
+
const print_util_1 = require("@halot/cli/shared/output/print.util");
|
|
7
|
+
const authority_util_1 = require("@halot/cli/shared/wallet/authority.util");
|
|
8
|
+
const workspace_service_1 = require("@halot/cli/shared/workspace/workspace.service");
|
|
9
|
+
async function runProviderUpdateCommand(options) {
|
|
10
|
+
const workspace = new workspace_service_1.WorkspaceService();
|
|
11
|
+
const api = new api_client_1.ApiClient(options.server);
|
|
12
|
+
const config = workspace.readProviderConfig();
|
|
13
|
+
if (!config.providerId) {
|
|
14
|
+
throw new Error('Provider not registered. Run `halot provider register` first.');
|
|
15
|
+
}
|
|
16
|
+
const wallets = workspace.readWallets(config.authority.path);
|
|
17
|
+
const providerWallet = (0, authority_util_1.resolveActorWallet)(wallets, config.authority.actor);
|
|
18
|
+
const path = `/providers/${config.providerId}`;
|
|
19
|
+
const headers = await (0, actor_headers_service_1.createSignedActorHeaders)(providerWallet, config.providerId, 'provider', 'PUT', path);
|
|
20
|
+
const provider = await api.put(path, {
|
|
21
|
+
displayName: config.displayName,
|
|
22
|
+
description: config.description,
|
|
23
|
+
version: config.version,
|
|
24
|
+
settlementWallets: config.settlementWallets,
|
|
25
|
+
}, headers);
|
|
26
|
+
workspace.writeProviderConfig({
|
|
27
|
+
...config,
|
|
28
|
+
displayName: provider.displayName,
|
|
29
|
+
description: provider.description,
|
|
30
|
+
version: provider.version,
|
|
31
|
+
settlementWallets: provider.settlementWallets,
|
|
32
|
+
});
|
|
33
|
+
console.log(`Updated provider ${provider.providerId}`);
|
|
34
|
+
(0, print_util_1.printJson)(provider);
|
|
35
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runQuoteCommand = runQuoteCommand;
|
|
4
|
+
const api_client_1 = require("@halot/cli/shared/http/api-client");
|
|
5
|
+
const print_util_1 = require("@halot/cli/shared/output/print.util");
|
|
6
|
+
async function runQuoteCommand(options) {
|
|
7
|
+
const api = new api_client_1.ApiClient(options.server);
|
|
8
|
+
const quote = await api.post('/quote', {
|
|
9
|
+
serviceId: options.service,
|
|
10
|
+
input: JSON.parse(options.input),
|
|
11
|
+
});
|
|
12
|
+
(0, print_util_1.printJson)(quote);
|
|
13
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runRequesterInitCommand = runRequesterInitCommand;
|
|
4
|
+
const wallet_manager_1 = require("@halot/cli/shared/wallet/wallet.manager");
|
|
5
|
+
const authority_util_1 = require("@halot/cli/shared/wallet/authority.util");
|
|
6
|
+
const workspace_service_1 = require("@halot/cli/shared/workspace/workspace.service");
|
|
7
|
+
async function runRequesterInitCommand() {
|
|
8
|
+
const workspace = new workspace_service_1.WorkspaceService();
|
|
9
|
+
const walletManager = new wallet_manager_1.WalletManager(workspace);
|
|
10
|
+
const wallets = walletManager.createWallets();
|
|
11
|
+
workspace.writeRequesterConfig({
|
|
12
|
+
requesterId: '',
|
|
13
|
+
displayName: 'Halot Requester',
|
|
14
|
+
authority: {
|
|
15
|
+
path: './wallets.json',
|
|
16
|
+
actor: '0g:testnet',
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
console.log('Requester workspace initialized.');
|
|
20
|
+
console.log(`0G testnet authority: ${(0, authority_util_1.resolveAuthorityAddress)(wallets, '0g:testnet')}`);
|
|
21
|
+
console.log(`Stellar testnet authority: ${(0, authority_util_1.resolveAuthorityAddress)(wallets, 'stellar:testnet')}`);
|
|
22
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runServiceCreateCommand = void 0;
|
|
4
|
+
exports.runServiceRegisterCommand = runServiceRegisterCommand;
|
|
5
|
+
const actor_headers_service_1 = require("@halot/cli/shared/auth/actor-headers.service");
|
|
6
|
+
const api_client_1 = require("@halot/cli/shared/http/api-client");
|
|
7
|
+
const print_util_1 = require("@halot/cli/shared/output/print.util");
|
|
8
|
+
const authority_util_1 = require("@halot/cli/shared/wallet/authority.util");
|
|
9
|
+
const workspace_service_1 = require("@halot/cli/shared/workspace/workspace.service");
|
|
10
|
+
async function runServiceRegisterCommand(options) {
|
|
11
|
+
const workspace = new workspace_service_1.WorkspaceService();
|
|
12
|
+
const api = new api_client_1.ApiClient(options.server);
|
|
13
|
+
const config = workspace.readProviderConfig();
|
|
14
|
+
const wallets = workspace.readWallets(config.authority.path);
|
|
15
|
+
const providerWallet = (0, authority_util_1.resolveActorWallet)(wallets, config.authority.actor);
|
|
16
|
+
if (!config.providerId) {
|
|
17
|
+
throw new Error('Provider not registered. Run `halot provider register` first.');
|
|
18
|
+
}
|
|
19
|
+
const draft = resolveDraftService(workspace, options.file);
|
|
20
|
+
if (!draft) {
|
|
21
|
+
if (options.file) {
|
|
22
|
+
throw new Error(`Service file ${options.file} was not found.`);
|
|
23
|
+
}
|
|
24
|
+
throw new Error('No unregistered service drafts found. Run `halot service init` first.');
|
|
25
|
+
}
|
|
26
|
+
if (draft.service.serviceId.trim()) {
|
|
27
|
+
throw new Error(`Service file ${draft.fileName} is already registered as ${draft.service.serviceId}. Use \`halot service update\` to change it.`);
|
|
28
|
+
}
|
|
29
|
+
const path = `/providers/${config.providerId}/services`;
|
|
30
|
+
const headers = await (0, actor_headers_service_1.createSignedActorHeaders)(providerWallet, config.providerId, 'provider', 'POST', path);
|
|
31
|
+
const service = await api.post(path, draft.service, headers);
|
|
32
|
+
const canonicalFileName = `service-${service.serviceId}.json`;
|
|
33
|
+
workspace.replaceServiceFile(draft.fileName, canonicalFileName, service);
|
|
34
|
+
console.log(`Registered service ${service.serviceId}`);
|
|
35
|
+
console.log(`Saved services/${canonicalFileName}`);
|
|
36
|
+
(0, print_util_1.printJson)(service);
|
|
37
|
+
}
|
|
38
|
+
exports.runServiceCreateCommand = runServiceRegisterCommand;
|
|
39
|
+
function resolveDraftService(workspace, fileName) {
|
|
40
|
+
if (fileName) {
|
|
41
|
+
const knownFiles = workspace.listServiceFiles();
|
|
42
|
+
if (!knownFiles.includes(fileName)) {
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
fileName,
|
|
47
|
+
service: workspace.readServiceFile(fileName),
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
for (const candidate of workspace.listServiceFiles()) {
|
|
51
|
+
const service = workspace.readServiceFile(candidate);
|
|
52
|
+
if (!service.serviceId.trim()) {
|
|
53
|
+
return { fileName: candidate, service };
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return undefined;
|
|
57
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runServiceInitCommand = runServiceInitCommand;
|
|
4
|
+
const sdk_1 = require("@halot/sdk");
|
|
5
|
+
const workspace_service_1 = require("@halot/cli/shared/workspace/workspace.service");
|
|
6
|
+
async function runServiceInitCommand(options) {
|
|
7
|
+
const workspace = new workspace_service_1.WorkspaceService();
|
|
8
|
+
const fileName = workspace.nextServiceDraftFileName();
|
|
9
|
+
const name = options.name?.trim() || 'New Service';
|
|
10
|
+
const category = parseServiceCategory(options.category);
|
|
11
|
+
const trustLevel = parseTrustLevel(options.trustLevel);
|
|
12
|
+
const description = options.description?.trim() || `Description for ${name}`;
|
|
13
|
+
const service = {
|
|
14
|
+
serviceId: '',
|
|
15
|
+
name,
|
|
16
|
+
description,
|
|
17
|
+
version: '1.0.0',
|
|
18
|
+
category,
|
|
19
|
+
trustLevel,
|
|
20
|
+
endpoint: {
|
|
21
|
+
health: 'https://your-provider.example/health',
|
|
22
|
+
execution: 'https://your-provider.example/execute',
|
|
23
|
+
},
|
|
24
|
+
pricing: {
|
|
25
|
+
baseFee: '3.00',
|
|
26
|
+
currency: 'USDC',
|
|
27
|
+
model: 'per-job',
|
|
28
|
+
},
|
|
29
|
+
settlement: {
|
|
30
|
+
accepts: [
|
|
31
|
+
{ network: '0g:testnet', token: 'USDC' },
|
|
32
|
+
{ network: 'stellar:testnet', token: 'USDC' },
|
|
33
|
+
],
|
|
34
|
+
},
|
|
35
|
+
input: {
|
|
36
|
+
schema: {
|
|
37
|
+
type: 'object',
|
|
38
|
+
properties: {
|
|
39
|
+
query: { type: 'string', maxLength: 500 },
|
|
40
|
+
depth: { type: 'string', enum: ['brief', 'detailed'] },
|
|
41
|
+
},
|
|
42
|
+
required: ['query'],
|
|
43
|
+
},
|
|
44
|
+
maxSize: '10kb',
|
|
45
|
+
},
|
|
46
|
+
output: {
|
|
47
|
+
schema: {
|
|
48
|
+
type: 'object',
|
|
49
|
+
properties: {
|
|
50
|
+
title: { type: 'string' },
|
|
51
|
+
summary: { type: 'string' },
|
|
52
|
+
sections: { type: 'array' },
|
|
53
|
+
sources: { type: 'array' },
|
|
54
|
+
},
|
|
55
|
+
required: ['title', 'summary', 'sections'],
|
|
56
|
+
},
|
|
57
|
+
format: 'json',
|
|
58
|
+
},
|
|
59
|
+
acceptanceCriteria: {
|
|
60
|
+
schemaValid: true,
|
|
61
|
+
minSections: 3,
|
|
62
|
+
sourcesRequired: true,
|
|
63
|
+
},
|
|
64
|
+
sla: {
|
|
65
|
+
maxExecutionTime: 120,
|
|
66
|
+
retryPolicy: 'none',
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
workspace.writeService(fileName, service);
|
|
70
|
+
console.log(`Created service draft services/${fileName}`);
|
|
71
|
+
}
|
|
72
|
+
function parseServiceCategory(value) {
|
|
73
|
+
if (!value) {
|
|
74
|
+
return 'text';
|
|
75
|
+
}
|
|
76
|
+
if (!sdk_1.serviceCategoryValues.includes(value)) {
|
|
77
|
+
throw new Error(`Unsupported service category "${value}". Expected one of: ${sdk_1.serviceCategoryValues.join(', ')}`);
|
|
78
|
+
}
|
|
79
|
+
return value;
|
|
80
|
+
}
|
|
81
|
+
function parseTrustLevel(value) {
|
|
82
|
+
if (!value) {
|
|
83
|
+
return 'standard';
|
|
84
|
+
}
|
|
85
|
+
if (!sdk_1.trustLevelValues.includes(value)) {
|
|
86
|
+
throw new Error(`Unsupported trust level "${value}". Expected one of: ${sdk_1.trustLevelValues.join(', ')}`);
|
|
87
|
+
}
|
|
88
|
+
return value;
|
|
89
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runServiceListCommand = runServiceListCommand;
|
|
4
|
+
const api_client_1 = require("@halot/cli/shared/http/api-client");
|
|
5
|
+
const print_util_1 = require("@halot/cli/shared/output/print.util");
|
|
6
|
+
const workspace_service_1 = require("@halot/cli/shared/workspace/workspace.service");
|
|
7
|
+
async function runServiceListCommand(options) {
|
|
8
|
+
const workspace = new workspace_service_1.WorkspaceService();
|
|
9
|
+
const api = new api_client_1.ApiClient(options.server);
|
|
10
|
+
const config = workspace.readProviderConfig();
|
|
11
|
+
if (!config.providerId) {
|
|
12
|
+
throw new Error('Provider not registered. Run `halot provider register` first.');
|
|
13
|
+
}
|
|
14
|
+
const services = await api.get(`/providers/${config.providerId}/services`);
|
|
15
|
+
if (services.length === 0) {
|
|
16
|
+
console.log('No services registered. Run `halot service init`, then `halot service register`.');
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
for (const service of services) {
|
|
20
|
+
console.log(`${service.serviceId} ${service.name} $${service.pricing.baseFee} ${service.pricing.currency} trust:${service.trustLevel}`);
|
|
21
|
+
}
|
|
22
|
+
(0, print_util_1.printJson)(services);
|
|
23
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runServiceRemoveCommand = runServiceRemoveCommand;
|
|
4
|
+
const actor_headers_service_1 = require("@halot/cli/shared/auth/actor-headers.service");
|
|
5
|
+
const api_client_1 = require("@halot/cli/shared/http/api-client");
|
|
6
|
+
const authority_util_1 = require("@halot/cli/shared/wallet/authority.util");
|
|
7
|
+
const workspace_service_1 = require("@halot/cli/shared/workspace/workspace.service");
|
|
8
|
+
async function runServiceRemoveCommand(serviceId, options) {
|
|
9
|
+
const workspace = new workspace_service_1.WorkspaceService();
|
|
10
|
+
const api = new api_client_1.ApiClient(options.server);
|
|
11
|
+
const config = workspace.readProviderConfig();
|
|
12
|
+
const wallets = workspace.readWallets(config.authority.path);
|
|
13
|
+
const providerWallet = (0, authority_util_1.resolveActorWallet)(wallets, config.authority.actor);
|
|
14
|
+
if (!config.providerId) {
|
|
15
|
+
throw new Error('Provider not registered. Run `halot provider register` first.');
|
|
16
|
+
}
|
|
17
|
+
const path = `/providers/${config.providerId}/services/${serviceId}`;
|
|
18
|
+
const headers = await (0, actor_headers_service_1.createSignedActorHeaders)(providerWallet, config.providerId, 'provider', 'DELETE', path);
|
|
19
|
+
await api.delete(path, headers);
|
|
20
|
+
console.log(`Removed service ${serviceId}`);
|
|
21
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runServiceUpdateCommand = runServiceUpdateCommand;
|
|
4
|
+
const actor_headers_service_1 = require("@halot/cli/shared/auth/actor-headers.service");
|
|
5
|
+
const api_client_1 = require("@halot/cli/shared/http/api-client");
|
|
6
|
+
const print_util_1 = require("@halot/cli/shared/output/print.util");
|
|
7
|
+
const authority_util_1 = require("@halot/cli/shared/wallet/authority.util");
|
|
8
|
+
const workspace_service_1 = require("@halot/cli/shared/workspace/workspace.service");
|
|
9
|
+
async function runServiceUpdateCommand(serviceId, options) {
|
|
10
|
+
const workspace = new workspace_service_1.WorkspaceService();
|
|
11
|
+
const api = new api_client_1.ApiClient(options.server);
|
|
12
|
+
const config = workspace.readProviderConfig();
|
|
13
|
+
const wallets = workspace.readWallets(config.authority.path);
|
|
14
|
+
const providerWallet = (0, authority_util_1.resolveActorWallet)(wallets, config.authority.actor);
|
|
15
|
+
if (!config.providerId) {
|
|
16
|
+
throw new Error('Provider not registered. Run `halot provider register` first.');
|
|
17
|
+
}
|
|
18
|
+
const draft = resolveRegisteredService(workspace, options.file, serviceId);
|
|
19
|
+
if (!draft) {
|
|
20
|
+
if (options.file) {
|
|
21
|
+
throw new Error(`Service file ${options.file} was not found.`);
|
|
22
|
+
}
|
|
23
|
+
if (serviceId) {
|
|
24
|
+
throw new Error(`Service ${serviceId} does not have a local service file.`);
|
|
25
|
+
}
|
|
26
|
+
throw new Error('No registered service files found. Run `halot service register` first.');
|
|
27
|
+
}
|
|
28
|
+
const resolvedServiceId = draft.service.serviceId.trim();
|
|
29
|
+
const path = `/providers/${config.providerId}/services/${resolvedServiceId}`;
|
|
30
|
+
const headers = await (0, actor_headers_service_1.createSignedActorHeaders)(providerWallet, config.providerId, 'provider', 'PUT', path);
|
|
31
|
+
const service = await api.put(path, draft.service, headers);
|
|
32
|
+
console.log(`Updated service ${service.serviceId}`);
|
|
33
|
+
workspace.writeService(`service-${service.serviceId}.json`, service);
|
|
34
|
+
(0, print_util_1.printJson)(service);
|
|
35
|
+
}
|
|
36
|
+
function resolveRegisteredService(workspace, fileName, serviceId) {
|
|
37
|
+
if (fileName) {
|
|
38
|
+
const knownFiles = workspace.listServiceFiles();
|
|
39
|
+
if (!knownFiles.includes(fileName)) {
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
fileName,
|
|
44
|
+
service: workspace.readServiceFile(fileName),
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
if (serviceId) {
|
|
48
|
+
const inferredFile = `service-${serviceId}.json`;
|
|
49
|
+
const knownFiles = workspace.listServiceFiles();
|
|
50
|
+
if (!knownFiles.includes(inferredFile)) {
|
|
51
|
+
return undefined;
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
fileName: inferredFile,
|
|
55
|
+
service: workspace.readServiceFile(inferredFile),
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
for (const candidate of workspace.listServiceFiles()) {
|
|
59
|
+
const service = workspace.readServiceFile(candidate);
|
|
60
|
+
if (service.serviceId.trim()) {
|
|
61
|
+
return { fileName: candidate, service };
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runVerifierInitCommand = runVerifierInitCommand;
|
|
4
|
+
const wallet_manager_1 = require("@halot/cli/shared/wallet/wallet.manager");
|
|
5
|
+
const authority_util_1 = require("@halot/cli/shared/wallet/authority.util");
|
|
6
|
+
const workspace_service_1 = require("@halot/cli/shared/workspace/workspace.service");
|
|
7
|
+
async function runVerifierInitCommand() {
|
|
8
|
+
const workspace = new workspace_service_1.WorkspaceService();
|
|
9
|
+
const walletManager = new wallet_manager_1.WalletManager(workspace);
|
|
10
|
+
const wallets = walletManager.createWallets();
|
|
11
|
+
workspace.writeVerifierConfig({
|
|
12
|
+
verifierId: '',
|
|
13
|
+
displayName: 'My Verifier',
|
|
14
|
+
description: 'Multimodal service verification specialist',
|
|
15
|
+
identity: {
|
|
16
|
+
erc8004TokenId: '',
|
|
17
|
+
agentRegistry: '',
|
|
18
|
+
agentUri: '',
|
|
19
|
+
ownerAddress: (0, authority_util_1.resolveAuthorityAddress)(wallets, '0g:testnet'),
|
|
20
|
+
domain: 'myverifier.0g',
|
|
21
|
+
domainType: 'space-id',
|
|
22
|
+
},
|
|
23
|
+
authority: {
|
|
24
|
+
path: './wallets.json',
|
|
25
|
+
actor: '0g:testnet',
|
|
26
|
+
},
|
|
27
|
+
settlementWallets: (0, authority_util_1.createDefaultSettlementWallets)(wallets),
|
|
28
|
+
stake: {
|
|
29
|
+
amount: '1000',
|
|
30
|
+
token: '0G',
|
|
31
|
+
status: 'unlocked',
|
|
32
|
+
},
|
|
33
|
+
fees: {
|
|
34
|
+
computeBudgetPerJob: '0.50',
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
workspace.writeModelConfig({
|
|
38
|
+
evaluationModel: {
|
|
39
|
+
providerAddress: '',
|
|
40
|
+
serviceType: 'chatbot',
|
|
41
|
+
verifiability: 'TeeML',
|
|
42
|
+
},
|
|
43
|
+
sdk: {
|
|
44
|
+
network: 'testnet',
|
|
45
|
+
},
|
|
46
|
+
timeout: 60,
|
|
47
|
+
});
|
|
48
|
+
workspace.writeInferenceTemplate({
|
|
49
|
+
systemPrompt: 'You are an impartial evaluator.',
|
|
50
|
+
promptTemplate: 'Evaluate whether the provider result and any referenced artifacts satisfy the acceptance criteria.',
|
|
51
|
+
outputSchema: {
|
|
52
|
+
decision: 'approve | reject | uncertain',
|
|
53
|
+
confidence: 'number between 0 and 1',
|
|
54
|
+
reason: 'string',
|
|
55
|
+
failedCriteria: 'array',
|
|
56
|
+
},
|
|
57
|
+
maxTokens: 1024,
|
|
58
|
+
temperature: 0,
|
|
59
|
+
});
|
|
60
|
+
workspace.writeSpecializations({
|
|
61
|
+
categories: ['text', 'document', 'tool'],
|
|
62
|
+
serviceIds: [],
|
|
63
|
+
maxConcurrentJobs: 5,
|
|
64
|
+
minConfidenceThreshold: 0.75,
|
|
65
|
+
});
|
|
66
|
+
console.log('Verifier workspace initialized.');
|
|
67
|
+
console.log(`0G testnet authority: ${(0, authority_util_1.resolveAuthorityAddress)(wallets, '0g:testnet')}`);
|
|
68
|
+
console.log(`Stellar testnet authority: ${(0, authority_util_1.resolveAuthorityAddress)(wallets, 'stellar:testnet')}`);
|
|
69
|
+
}
|