@tjamescouch/agentchat 0.22.1 → 0.23.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.
Files changed (153) hide show
  1. package/Dockerfile +1 -1
  2. package/dist/bin/agentchat.d.ts +7 -0
  3. package/dist/bin/agentchat.d.ts.map +1 -0
  4. package/dist/bin/agentchat.js +1511 -0
  5. package/dist/bin/agentchat.js.map +1 -0
  6. package/dist/lib/allowlist.d.ts +77 -0
  7. package/dist/lib/allowlist.d.ts.map +1 -0
  8. package/dist/lib/allowlist.js +151 -0
  9. package/dist/lib/allowlist.js.map +1 -0
  10. package/dist/lib/client.d.ts +147 -0
  11. package/dist/lib/client.d.ts.map +1 -0
  12. package/dist/lib/client.js +704 -0
  13. package/dist/lib/client.js.map +1 -0
  14. package/dist/lib/daemon.d.ts +122 -0
  15. package/dist/lib/daemon.d.ts.map +1 -0
  16. package/dist/lib/daemon.js +523 -0
  17. package/dist/lib/daemon.js.map +1 -0
  18. package/dist/lib/deploy/akash.d.ts +271 -0
  19. package/dist/lib/deploy/akash.d.ts.map +1 -0
  20. package/dist/lib/deploy/akash.js +671 -0
  21. package/dist/lib/deploy/akash.js.map +1 -0
  22. package/dist/lib/deploy/config.d.ts +62 -0
  23. package/dist/lib/deploy/config.d.ts.map +1 -0
  24. package/dist/lib/deploy/config.js +116 -0
  25. package/dist/lib/deploy/config.js.map +1 -0
  26. package/dist/lib/deploy/docker.d.ts +37 -0
  27. package/dist/lib/deploy/docker.d.ts.map +1 -0
  28. package/dist/lib/deploy/docker.js +122 -0
  29. package/dist/lib/deploy/docker.js.map +1 -0
  30. package/dist/lib/deploy/index.d.ts +11 -0
  31. package/dist/lib/deploy/index.d.ts.map +1 -0
  32. package/dist/lib/deploy/index.js +11 -0
  33. package/dist/lib/deploy/index.js.map +1 -0
  34. package/dist/lib/escrow-hooks.d.ts +199 -0
  35. package/dist/lib/escrow-hooks.d.ts.map +1 -0
  36. package/dist/lib/escrow-hooks.js +221 -0
  37. package/dist/lib/escrow-hooks.js.map +1 -0
  38. package/dist/lib/identity.d.ts +134 -0
  39. package/dist/lib/identity.d.ts.map +1 -0
  40. package/dist/lib/identity.js +334 -0
  41. package/dist/lib/identity.js.map +1 -0
  42. package/dist/lib/jitter.d.ts +42 -0
  43. package/dist/lib/jitter.d.ts.map +1 -0
  44. package/{lib/jitter.ts → dist/lib/jitter.js} +10 -18
  45. package/dist/lib/jitter.js.map +1 -0
  46. package/dist/lib/proposals.d.ts +223 -0
  47. package/dist/lib/proposals.d.ts.map +1 -0
  48. package/dist/lib/proposals.js +379 -0
  49. package/dist/lib/proposals.js.map +1 -0
  50. package/dist/lib/protocol.d.ts +220 -0
  51. package/dist/lib/protocol.d.ts.map +1 -0
  52. package/dist/lib/protocol.js +507 -0
  53. package/dist/lib/protocol.js.map +1 -0
  54. package/dist/lib/receipts.d.ts +134 -0
  55. package/dist/lib/receipts.d.ts.map +1 -0
  56. package/dist/lib/receipts.js +270 -0
  57. package/dist/lib/receipts.js.map +1 -0
  58. package/dist/lib/reputation.d.ts +250 -0
  59. package/dist/lib/reputation.d.ts.map +1 -0
  60. package/dist/lib/reputation.js +586 -0
  61. package/dist/lib/reputation.js.map +1 -0
  62. package/dist/lib/security.d.ts +27 -0
  63. package/dist/lib/security.d.ts.map +1 -0
  64. package/dist/lib/security.js +150 -0
  65. package/dist/lib/security.js.map +1 -0
  66. package/dist/lib/server/handlers/admin.d.ts +26 -0
  67. package/dist/lib/server/handlers/admin.d.ts.map +1 -0
  68. package/dist/lib/server/handlers/admin.js +76 -0
  69. package/dist/lib/server/handlers/admin.js.map +1 -0
  70. package/dist/lib/server/handlers/identity.d.ts +36 -0
  71. package/dist/lib/server/handlers/identity.d.ts.map +1 -0
  72. package/dist/lib/server/handlers/identity.js +330 -0
  73. package/dist/lib/server/handlers/identity.js.map +1 -0
  74. package/dist/lib/server/handlers/index.d.ts +10 -0
  75. package/dist/lib/server/handlers/index.d.ts.map +1 -0
  76. package/dist/lib/server/handlers/index.js +15 -0
  77. package/dist/lib/server/handlers/index.js.map +1 -0
  78. package/dist/lib/server/handlers/message.d.ts +47 -0
  79. package/dist/lib/server/handlers/message.d.ts.map +1 -0
  80. package/dist/lib/server/handlers/message.js +265 -0
  81. package/dist/lib/server/handlers/message.js.map +1 -0
  82. package/dist/lib/server/handlers/presence.d.ts +18 -0
  83. package/dist/lib/server/handlers/presence.d.ts.map +1 -0
  84. package/dist/lib/server/handlers/presence.js +35 -0
  85. package/dist/lib/server/handlers/presence.js.map +1 -0
  86. package/dist/lib/server/handlers/proposal.d.ts +38 -0
  87. package/dist/lib/server/handlers/proposal.d.ts.map +1 -0
  88. package/dist/lib/server/handlers/proposal.js +273 -0
  89. package/dist/lib/server/handlers/proposal.js.map +1 -0
  90. package/dist/lib/server/handlers/skills.d.ts +22 -0
  91. package/dist/lib/server/handlers/skills.d.ts.map +1 -0
  92. package/dist/lib/server/handlers/skills.js +119 -0
  93. package/dist/lib/server/handlers/skills.js.map +1 -0
  94. package/dist/lib/server-directory.d.ts +85 -0
  95. package/dist/lib/server-directory.d.ts.map +1 -0
  96. package/dist/lib/server-directory.js +177 -0
  97. package/dist/lib/server-directory.js.map +1 -0
  98. package/dist/lib/server.d.ts +162 -0
  99. package/dist/lib/server.d.ts.map +1 -0
  100. package/dist/lib/server.js +602 -0
  101. package/dist/lib/server.js.map +1 -0
  102. package/dist/lib/types.d.ts +461 -0
  103. package/dist/lib/types.d.ts.map +1 -0
  104. package/dist/lib/types.js +98 -0
  105. package/dist/lib/types.js.map +1 -0
  106. package/package.json +22 -13
  107. package/bin/agentchat.js +0 -1617
  108. package/bin/agentchat.ts +0 -1812
  109. package/lib/allowlist.js +0 -162
  110. package/lib/chat.py +0 -241
  111. package/lib/client.js +0 -821
  112. package/lib/client.ts +0 -877
  113. package/lib/daemon.js +0 -562
  114. package/lib/daemon.ts +0 -662
  115. package/lib/deploy/akash.js +0 -811
  116. package/lib/deploy/config.js +0 -128
  117. package/lib/deploy/docker.js +0 -132
  118. package/lib/deploy/index.js +0 -24
  119. package/lib/elo_swarm.py +0 -569
  120. package/lib/escrow-hooks.js +0 -237
  121. package/lib/escrow-hooks.ts +0 -391
  122. package/lib/identity.js +0 -376
  123. package/lib/identity.ts +0 -412
  124. package/lib/jitter.js +0 -54
  125. package/lib/proposals.js +0 -426
  126. package/lib/proposals.ts +0 -612
  127. package/lib/protocol.js +0 -516
  128. package/lib/receipts.js +0 -294
  129. package/lib/receipts.ts +0 -359
  130. package/lib/reputation.js +0 -664
  131. package/lib/reputation.ts +0 -790
  132. package/lib/security.js +0 -183
  133. package/lib/server/handlers/admin.js +0 -94
  134. package/lib/server/handlers/identity.js +0 -258
  135. package/lib/server/handlers/index.js +0 -42
  136. package/lib/server/handlers/message.js +0 -319
  137. package/lib/server/handlers/presence.js +0 -45
  138. package/lib/server/handlers/proposal.js +0 -358
  139. package/lib/server/handlers/skills.js +0 -141
  140. package/lib/server-directory.js +0 -190
  141. package/lib/server-directory.ts +0 -232
  142. package/lib/server.js +0 -633
  143. package/lib/server.ts +0 -698
  144. package/lib/supervisor/USAGE.md +0 -110
  145. package/lib/supervisor/agent-health.sh +0 -107
  146. package/lib/supervisor/agent-monitor.sh +0 -123
  147. package/lib/supervisor/agent-supervisor.sh +0 -135
  148. package/lib/supervisor/agentctl.sh +0 -266
  149. package/lib/supervisor/god-backup.sh +0 -126
  150. package/lib/supervisor/god-watchdog.sh +0 -107
  151. package/lib/supervisor/killswitch.sh +0 -43
  152. package/lib/supervisor/notify.sh +0 -19
  153. package/lib/types.ts +0 -433
@@ -0,0 +1,671 @@
1
+ /**
2
+ * Akash Network Deployment Module
3
+ *
4
+ * Enables self-service deployment to Akash decentralized cloud.
5
+ *
6
+ * DISCLAIMER: This is infrastructure tooling, not a cryptocurrency product.
7
+ * AKT tokens are used solely to pay for compute resources.
8
+ * You are responsible for your own wallet security and funds.
9
+ */
10
+ import fs from 'fs/promises';
11
+ import path from 'path';
12
+ import yaml from 'js-yaml';
13
+ // ============ Constants ============
14
+ // Default paths
15
+ const AKASH_DIR = path.join(process.cwd(), '.agentchat');
16
+ export const WALLET_PATH = path.join(AKASH_DIR, 'akash-wallet.json');
17
+ export const DEPLOYMENTS_PATH = path.join(AKASH_DIR, 'akash-deployments.json');
18
+ export const CERTIFICATE_PATH = path.join(AKASH_DIR, 'akash-cert.json');
19
+ // Network configuration
20
+ export const NETWORKS = {
21
+ mainnet: {
22
+ chainId: 'akashnet-2',
23
+ rpcEndpoint: 'https://rpc.akashnet.net:443',
24
+ restEndpoint: 'https://api.akashnet.net:443',
25
+ prefix: 'akash'
26
+ },
27
+ testnet: {
28
+ chainId: 'sandbox-01',
29
+ rpcEndpoint: 'https://rpc.sandbox-01.aksh.pw:443',
30
+ restEndpoint: 'https://api.sandbox-01.aksh.pw:443',
31
+ prefix: 'akash'
32
+ }
33
+ };
34
+ // Default deposit amount (5 AKT in uakt)
35
+ const DEFAULT_DEPOSIT = '5000000';
36
+ // ============ AkashWallet Class ============
37
+ /**
38
+ * Akash Wallet - manages keypair and signing
39
+ */
40
+ export class AkashWallet {
41
+ mnemonic;
42
+ address;
43
+ pubkey;
44
+ network;
45
+ created;
46
+ constructor(data) {
47
+ this.mnemonic = data.mnemonic;
48
+ this.address = data.address;
49
+ this.pubkey = data.pubkey;
50
+ this.network = data.network || 'testnet';
51
+ this.created = data.created || new Date().toISOString();
52
+ }
53
+ /**
54
+ * Generate a new wallet
55
+ */
56
+ static async generate(network = 'testnet') {
57
+ const { DirectSecp256k1HdWallet } = await import('@cosmjs/proto-signing');
58
+ const wallet = await DirectSecp256k1HdWallet.generate(24, {
59
+ prefix: NETWORKS[network].prefix
60
+ });
61
+ const [account] = await wallet.getAccounts();
62
+ return new AkashWallet({
63
+ mnemonic: wallet.mnemonic,
64
+ address: account.address,
65
+ pubkey: Buffer.from(account.pubkey).toString('base64'),
66
+ network,
67
+ created: new Date().toISOString()
68
+ });
69
+ }
70
+ /**
71
+ * Load wallet from mnemonic
72
+ */
73
+ static async fromMnemonic(mnemonic, network = 'testnet') {
74
+ const { DirectSecp256k1HdWallet } = await import('@cosmjs/proto-signing');
75
+ const wallet = await DirectSecp256k1HdWallet.fromMnemonic(mnemonic, {
76
+ prefix: NETWORKS[network].prefix
77
+ });
78
+ const [account] = await wallet.getAccounts();
79
+ return new AkashWallet({
80
+ mnemonic,
81
+ address: account.address,
82
+ pubkey: Buffer.from(account.pubkey).toString('base64'),
83
+ network
84
+ });
85
+ }
86
+ /**
87
+ * Get signing wallet instance
88
+ */
89
+ async getSigningWallet() {
90
+ const { DirectSecp256k1HdWallet } = await import('@cosmjs/proto-signing');
91
+ return DirectSecp256k1HdWallet.fromMnemonic(this.mnemonic, {
92
+ prefix: NETWORKS[this.network].prefix
93
+ });
94
+ }
95
+ /**
96
+ * Save wallet to file
97
+ */
98
+ async save(filePath = WALLET_PATH) {
99
+ await fs.mkdir(path.dirname(filePath), { recursive: true });
100
+ const data = {
101
+ version: 1,
102
+ network: this.network,
103
+ address: this.address,
104
+ pubkey: this.pubkey,
105
+ mnemonic: this.mnemonic,
106
+ created: this.created
107
+ };
108
+ await fs.writeFile(filePath, JSON.stringify(data, null, 2), { mode: 0o600 });
109
+ return filePath;
110
+ }
111
+ /**
112
+ * Load wallet from file
113
+ */
114
+ static async load(filePath = WALLET_PATH) {
115
+ const content = await fs.readFile(filePath, 'utf-8');
116
+ const data = JSON.parse(content);
117
+ if (data.version !== 1) {
118
+ throw new Error(`Unsupported wallet version: ${data.version}`);
119
+ }
120
+ return new AkashWallet(data);
121
+ }
122
+ /**
123
+ * Check if wallet file exists
124
+ */
125
+ static async exists(filePath = WALLET_PATH) {
126
+ try {
127
+ await fs.access(filePath);
128
+ return true;
129
+ }
130
+ catch {
131
+ return false;
132
+ }
133
+ }
134
+ /**
135
+ * Get wallet info for display (no sensitive data)
136
+ */
137
+ getInfo() {
138
+ return {
139
+ address: this.address,
140
+ network: this.network,
141
+ created: this.created
142
+ };
143
+ }
144
+ }
145
+ // ============ SDL Generation ============
146
+ /**
147
+ * Generate SDL (Stack Definition Language) for agentchat server
148
+ */
149
+ export function generateSDL(options = {}) {
150
+ const config = {
151
+ name: options.name || 'agentchat',
152
+ port: options.port || 6667,
153
+ cpu: options.cpu || 0.5,
154
+ memory: options.memory || 512,
155
+ storage: options.storage || 1,
156
+ logMessages: options.logMessages || false
157
+ };
158
+ const sdl = {
159
+ version: '2.0',
160
+ services: {
161
+ agentchat: {
162
+ image: options.image || 'ghcr.io/anthropics/agentchat:latest',
163
+ expose: [
164
+ {
165
+ port: config.port,
166
+ as: 80,
167
+ to: [{ global: true }]
168
+ }
169
+ ],
170
+ env: [
171
+ `PORT=${config.port}`,
172
+ 'HOST=0.0.0.0',
173
+ `SERVER_NAME=${config.name}`,
174
+ `LOG_MESSAGES=${config.logMessages}`
175
+ ]
176
+ }
177
+ },
178
+ profiles: {
179
+ compute: {
180
+ agentchat: {
181
+ resources: {
182
+ cpu: { units: config.cpu },
183
+ memory: { size: `${config.memory}Mi` },
184
+ storage: { size: `${config.storage}Gi` }
185
+ }
186
+ }
187
+ },
188
+ placement: {
189
+ dcloud: {
190
+ pricing: {
191
+ agentchat: {
192
+ denom: 'uakt',
193
+ amount: 1000
194
+ }
195
+ }
196
+ }
197
+ }
198
+ },
199
+ deployment: {
200
+ agentchat: {
201
+ dcloud: {
202
+ profile: 'agentchat',
203
+ count: 1
204
+ }
205
+ }
206
+ }
207
+ };
208
+ return yaml.dump(sdl, { lineWidth: -1 });
209
+ }
210
+ // ============ AkashClient Class ============
211
+ /**
212
+ * Akash deployment client
213
+ */
214
+ export class AkashClient {
215
+ wallet;
216
+ network;
217
+ constructor(wallet) {
218
+ this.wallet = wallet;
219
+ this.network = NETWORKS[wallet.network];
220
+ }
221
+ /**
222
+ * Get signing client for transactions
223
+ */
224
+ async getSigningClient() {
225
+ const { SigningStargateClient } = await import('@cosmjs/stargate');
226
+ const { getAkashTypeRegistry } = await import('@akashnetwork/akashjs/build/stargate/index.js');
227
+ const { Registry } = await import('@cosmjs/proto-signing');
228
+ const signingWallet = await this.wallet.getSigningWallet();
229
+ const registry = new Registry(getAkashTypeRegistry());
230
+ return SigningStargateClient.connectWithSigner(this.network.rpcEndpoint, signingWallet, { registry });
231
+ }
232
+ /**
233
+ * Query account balance
234
+ */
235
+ async getBalance() {
236
+ const { StargateClient } = await import('@cosmjs/stargate');
237
+ let client;
238
+ try {
239
+ client = await StargateClient.connect(this.network.rpcEndpoint);
240
+ }
241
+ catch (err) {
242
+ throw new Error(`Failed to connect to ${this.wallet.network} RPC endpoint.\n` +
243
+ `Network: ${this.network.rpcEndpoint}\n` +
244
+ `The network may be temporarily unavailable. Try again later.`);
245
+ }
246
+ const balance = await client.getBalance(this.wallet.address, 'uakt');
247
+ const akt = parseInt(balance.amount) / 1_000_000;
248
+ return {
249
+ uakt: balance.amount,
250
+ akt: akt.toFixed(6),
251
+ sufficient: parseInt(balance.amount) >= 5_000_000
252
+ };
253
+ }
254
+ /**
255
+ * Create a deployment on Akash
256
+ */
257
+ async createDeployment(sdlContent, options = {}) {
258
+ const { SDL } = await import('@akashnetwork/akashjs/build/sdl/SDL/SDL.js');
259
+ const { MsgCreateDeployment } = await import('@akashnetwork/akash-api/v1beta3');
260
+ const { Message } = await import('@akashnetwork/akashjs/build/stargate/index.js');
261
+ // Parse SDL
262
+ const sdl = SDL.fromString(sdlContent, 'beta3');
263
+ // Get signing client
264
+ const client = await this.getSigningClient();
265
+ const blockHeight = await client.getHeight();
266
+ // Create deployment ID
267
+ const dseq = options.dseq || blockHeight.toString();
268
+ // Build deployment message
269
+ const groups = sdl.groups();
270
+ const manifestVersion = await sdl.manifestVersion();
271
+ const deploymentMsg = {
272
+ id: {
273
+ owner: this.wallet.address,
274
+ dseq: dseq
275
+ },
276
+ groups: groups,
277
+ deposit: {
278
+ denom: 'uakt',
279
+ amount: options.deposit || DEFAULT_DEPOSIT
280
+ },
281
+ version: manifestVersion,
282
+ depositor: this.wallet.address
283
+ };
284
+ const msg = {
285
+ typeUrl: Message.MsgCreateDeployment,
286
+ value: MsgCreateDeployment.fromPartial(deploymentMsg)
287
+ };
288
+ // Broadcast transaction
289
+ const fee = {
290
+ amount: [{ denom: 'uakt', amount: '25000' }],
291
+ gas: '500000'
292
+ };
293
+ console.log('Broadcasting deployment transaction...');
294
+ const tx = await client.signAndBroadcast(this.wallet.address, [msg], fee, 'agentchat deployment');
295
+ if (tx.code !== 0) {
296
+ throw new Error(`Deployment failed: ${tx.rawLog}`);
297
+ }
298
+ console.log(`Deployment created: dseq=${dseq}, tx=${tx.transactionHash}`);
299
+ // Save deployment record
300
+ await this.saveDeployment({
301
+ dseq,
302
+ owner: this.wallet.address,
303
+ txHash: tx.transactionHash,
304
+ status: 'pending_bids',
305
+ createdAt: new Date().toISOString(),
306
+ sdl: sdlContent
307
+ });
308
+ return {
309
+ dseq,
310
+ txHash: tx.transactionHash,
311
+ status: 'pending_bids',
312
+ manifest: sdl.manifest()
313
+ };
314
+ }
315
+ /**
316
+ * Query bids for a deployment
317
+ */
318
+ async queryBids(dseq) {
319
+ const url = `${this.network.restEndpoint}/akash/market/v1beta4/bids/list?filters.owner=${this.wallet.address}&filters.dseq=${dseq}`;
320
+ const response = await fetch(url);
321
+ if (!response.ok) {
322
+ throw new Error(`Failed to query bids: ${response.statusText}`);
323
+ }
324
+ const data = await response.json();
325
+ return data.bids || [];
326
+ }
327
+ /**
328
+ * Accept a bid and create a lease
329
+ */
330
+ async createLease(dseq, provider, gseq = 1, oseq = 1) {
331
+ const { MsgCreateLease } = await import('@akashnetwork/akash-api/v1beta3');
332
+ const { Message } = await import('@akashnetwork/akashjs/build/stargate/index.js');
333
+ const client = await this.getSigningClient();
334
+ const leaseMsg = {
335
+ bidId: {
336
+ owner: this.wallet.address,
337
+ dseq: dseq,
338
+ gseq: gseq,
339
+ oseq: oseq,
340
+ provider: provider
341
+ }
342
+ };
343
+ const msg = {
344
+ typeUrl: Message.MsgCreateLease,
345
+ value: MsgCreateLease.fromPartial(leaseMsg)
346
+ };
347
+ const fee = {
348
+ amount: [{ denom: 'uakt', amount: '25000' }],
349
+ gas: '500000'
350
+ };
351
+ console.log('Creating lease...');
352
+ const tx = await client.signAndBroadcast(this.wallet.address, [msg], fee, 'create lease');
353
+ if (tx.code !== 0) {
354
+ throw new Error(`Lease creation failed: ${tx.rawLog}`);
355
+ }
356
+ console.log(`Lease created: provider=${provider}, tx=${tx.transactionHash}`);
357
+ // Update deployment record
358
+ await this.updateDeployment(dseq, {
359
+ status: 'active',
360
+ provider,
361
+ leaseCreatedAt: new Date().toISOString()
362
+ });
363
+ return {
364
+ dseq,
365
+ provider,
366
+ gseq,
367
+ oseq,
368
+ txHash: tx.transactionHash
369
+ };
370
+ }
371
+ /**
372
+ * Send manifest to provider
373
+ */
374
+ async sendManifest(dseq, provider, manifest) {
375
+ const certificateModule = await import('@akashnetwork/akashjs/build/certificates/index.js');
376
+ // Load or create certificate
377
+ let cert;
378
+ try {
379
+ const certData = await fs.readFile(CERTIFICATE_PATH, 'utf-8');
380
+ cert = JSON.parse(certData);
381
+ }
382
+ catch {
383
+ // Generate new certificate
384
+ console.log('Generating deployment certificate...');
385
+ const generated = await certificateModule.createCertificate(this.wallet.address);
386
+ cert = {
387
+ cert: generated.cert,
388
+ privateKey: generated.privateKey,
389
+ publicKey: generated.publicKey
390
+ };
391
+ await fs.writeFile(CERTIFICATE_PATH, JSON.stringify(cert, null, 2), { mode: 0o600 });
392
+ }
393
+ // Query provider info to get hostUri
394
+ const providerUrl = `${this.network.restEndpoint}/akash/provider/v1beta3/providers/${provider}`;
395
+ const providerResponse = await fetch(providerUrl);
396
+ if (!providerResponse.ok) {
397
+ throw new Error(`Failed to get provider info: ${providerResponse.statusText}`);
398
+ }
399
+ const providerInfo = await providerResponse.json();
400
+ const hostUri = providerInfo.provider?.hostUri;
401
+ if (!hostUri) {
402
+ throw new Error('Provider hostUri not found');
403
+ }
404
+ // Send manifest
405
+ const manifestUrl = `${hostUri}/deployment/${dseq}/manifest`;
406
+ console.log(`Sending manifest to ${manifestUrl}...`);
407
+ const response = await fetch(manifestUrl, {
408
+ method: 'PUT',
409
+ headers: {
410
+ 'Content-Type': 'application/json'
411
+ },
412
+ body: JSON.stringify(manifest)
413
+ });
414
+ if (!response.ok) {
415
+ const text = await response.text();
416
+ throw new Error(`Failed to send manifest: ${response.statusText} - ${text}`);
417
+ }
418
+ console.log('Manifest sent successfully');
419
+ // Update deployment record
420
+ await this.updateDeployment(dseq, {
421
+ manifestSent: true,
422
+ manifestSentAt: new Date().toISOString()
423
+ });
424
+ return { success: true };
425
+ }
426
+ /**
427
+ * Get lease status from provider
428
+ */
429
+ async getLeaseStatus(dseq, provider, gseq = 1, oseq = 1) {
430
+ // Query provider info
431
+ const providerUrl = `${this.network.restEndpoint}/akash/provider/v1beta3/providers/${provider}`;
432
+ const providerResponse = await fetch(providerUrl);
433
+ if (!providerResponse.ok) {
434
+ throw new Error(`Failed to get provider info: ${providerResponse.statusText}`);
435
+ }
436
+ const providerInfo = await providerResponse.json();
437
+ const hostUri = providerInfo.provider?.hostUri;
438
+ if (!hostUri) {
439
+ throw new Error('Provider hostUri not found');
440
+ }
441
+ // Query lease status
442
+ const statusUrl = `${hostUri}/lease/${dseq}/${gseq}/${oseq}/status`;
443
+ const response = await fetch(statusUrl);
444
+ if (!response.ok) {
445
+ throw new Error(`Failed to get lease status: ${response.statusText}`);
446
+ }
447
+ return response.json();
448
+ }
449
+ /**
450
+ * Close a deployment
451
+ */
452
+ async closeDeployment(dseq) {
453
+ const { MsgCloseDeployment } = await import('@akashnetwork/akash-api/v1beta3');
454
+ const { Message } = await import('@akashnetwork/akashjs/build/stargate/index.js');
455
+ const client = await this.getSigningClient();
456
+ const closeMsg = {
457
+ id: {
458
+ owner: this.wallet.address,
459
+ dseq: dseq
460
+ }
461
+ };
462
+ const msg = {
463
+ typeUrl: Message.MsgCloseDeployment,
464
+ value: MsgCloseDeployment.fromPartial(closeMsg)
465
+ };
466
+ const fee = {
467
+ amount: [{ denom: 'uakt', amount: '25000' }],
468
+ gas: '500000'
469
+ };
470
+ console.log('Closing deployment...');
471
+ const tx = await client.signAndBroadcast(this.wallet.address, [msg], fee, 'close deployment');
472
+ if (tx.code !== 0) {
473
+ throw new Error(`Failed to close deployment: ${tx.rawLog}`);
474
+ }
475
+ // Update deployment record
476
+ await this.updateDeployment(dseq, {
477
+ status: 'closed',
478
+ closedAt: new Date().toISOString()
479
+ });
480
+ return { dseq, txHash: tx.transactionHash, status: 'closed' };
481
+ }
482
+ /**
483
+ * Save deployment to local records
484
+ */
485
+ async saveDeployment(deployment) {
486
+ let deployments = [];
487
+ try {
488
+ const content = await fs.readFile(DEPLOYMENTS_PATH, 'utf-8');
489
+ deployments = JSON.parse(content);
490
+ }
491
+ catch {
492
+ // File doesn't exist yet
493
+ }
494
+ deployments.push(deployment);
495
+ await fs.writeFile(DEPLOYMENTS_PATH, JSON.stringify(deployments, null, 2));
496
+ }
497
+ /**
498
+ * Update deployment in local records
499
+ */
500
+ async updateDeployment(dseq, updates) {
501
+ let deployments = [];
502
+ try {
503
+ const content = await fs.readFile(DEPLOYMENTS_PATH, 'utf-8');
504
+ deployments = JSON.parse(content);
505
+ }
506
+ catch {
507
+ return;
508
+ }
509
+ const index = deployments.findIndex(d => d.dseq === dseq);
510
+ if (index !== -1) {
511
+ deployments[index] = { ...deployments[index], ...updates };
512
+ await fs.writeFile(DEPLOYMENTS_PATH, JSON.stringify(deployments, null, 2));
513
+ }
514
+ }
515
+ /**
516
+ * List local deployment records
517
+ */
518
+ async listDeployments() {
519
+ try {
520
+ const content = await fs.readFile(DEPLOYMENTS_PATH, 'utf-8');
521
+ return JSON.parse(content);
522
+ }
523
+ catch {
524
+ return [];
525
+ }
526
+ }
527
+ }
528
+ // ============ High-level deployment functions for CLI ============
529
+ export async function generateWallet(network = 'testnet', walletPath = WALLET_PATH) {
530
+ if (await AkashWallet.exists(walletPath)) {
531
+ throw new Error(`Wallet already exists at ${walletPath}\n` +
532
+ 'Use --force to overwrite (WARNING: This will destroy your existing wallet!)');
533
+ }
534
+ const wallet = await AkashWallet.generate(network);
535
+ await wallet.save(walletPath);
536
+ return wallet;
537
+ }
538
+ export async function checkBalance(walletPath = WALLET_PATH) {
539
+ const wallet = await AkashWallet.load(walletPath);
540
+ const client = new AkashClient(wallet);
541
+ return {
542
+ wallet: wallet.getInfo(),
543
+ balance: await client.getBalance()
544
+ };
545
+ }
546
+ export async function createDeployment(options = {}) {
547
+ const walletPath = options.walletPath || WALLET_PATH;
548
+ const wallet = await AkashWallet.load(walletPath);
549
+ const client = new AkashClient(wallet);
550
+ // Check balance first
551
+ const balance = await client.getBalance();
552
+ if (!balance.sufficient) {
553
+ throw new Error(`Insufficient balance: ${balance.akt} AKT\n` +
554
+ `Need at least 5 AKT for deployment.\n` +
555
+ `Fund your wallet: ${wallet.address}`);
556
+ }
557
+ // Generate SDL
558
+ const sdl = generateSDL(options);
559
+ // Create deployment
560
+ const deployment = await client.createDeployment(sdl, options);
561
+ // Wait for bids
562
+ console.log('Waiting for bids (30 seconds)...');
563
+ await new Promise(resolve => setTimeout(resolve, 30000));
564
+ // Query bids
565
+ const bids = await client.queryBids(deployment.dseq);
566
+ if (bids.length === 0) {
567
+ console.log('No bids received. Deployment is pending.');
568
+ console.log(`Check status with: agentchat deploy --provider akash --status`);
569
+ return deployment;
570
+ }
571
+ // Select best bid (lowest price)
572
+ const sortedBids = bids
573
+ .filter(b => b.bid?.state === 'open')
574
+ .sort((a, b) => parseInt(a.bid?.price?.amount || '0') - parseInt(b.bid?.price?.amount || '0'));
575
+ if (sortedBids.length === 0) {
576
+ console.log('No open bids available.');
577
+ return deployment;
578
+ }
579
+ const bestBid = sortedBids[0];
580
+ const provider = bestBid.bid?.bidId?.provider;
581
+ if (!provider) {
582
+ console.log('No valid provider found in bids.');
583
+ return deployment;
584
+ }
585
+ console.log(`Accepting bid from provider: ${provider}`);
586
+ // Create lease
587
+ const lease = await client.createLease(deployment.dseq, provider, bestBid.bid?.bidId?.gseq || 1, bestBid.bid?.bidId?.oseq || 1);
588
+ // Send manifest
589
+ await client.sendManifest(deployment.dseq, provider, deployment.manifest);
590
+ // Get status
591
+ console.log('Waiting for deployment to start (15 seconds)...');
592
+ await new Promise(resolve => setTimeout(resolve, 15000));
593
+ try {
594
+ const status = await client.getLeaseStatus(deployment.dseq, provider);
595
+ const services = status.services || {};
596
+ const service = Object.values(services)[0];
597
+ const uris = service?.uris || [];
598
+ if (uris.length > 0) {
599
+ console.log(`\nDeployment ready!`);
600
+ console.log(`Endpoint: ${uris[0]}`);
601
+ return { ...deployment, ...lease, endpoint: uris[0], status: 'active' };
602
+ }
603
+ }
604
+ catch (err) {
605
+ console.log('Status check failed, deployment may still be starting.');
606
+ }
607
+ return { ...deployment, ...lease, status: 'active' };
608
+ }
609
+ export async function listDeployments(walletPath = WALLET_PATH) {
610
+ const wallet = await AkashWallet.load(walletPath);
611
+ const client = new AkashClient(wallet);
612
+ return client.listDeployments();
613
+ }
614
+ export async function closeDeployment(dseq, walletPath = WALLET_PATH) {
615
+ const wallet = await AkashWallet.load(walletPath);
616
+ const client = new AkashClient(wallet);
617
+ return client.closeDeployment(dseq);
618
+ }
619
+ export async function acceptBid(dseq, provider, walletPath = WALLET_PATH) {
620
+ const wallet = await AkashWallet.load(walletPath);
621
+ const client = new AkashClient(wallet);
622
+ // Get deployment from local records
623
+ const deployments = await client.listDeployments();
624
+ const deployment = deployments.find(d => d.dseq === dseq);
625
+ if (!deployment) {
626
+ throw new Error(`Deployment ${dseq} not found in local records`);
627
+ }
628
+ // Create lease
629
+ const lease = await client.createLease(dseq, provider);
630
+ // Parse SDL and send manifest
631
+ const { SDL } = await import('@akashnetwork/akashjs/build/sdl/SDL/SDL.js');
632
+ const sdl = SDL.fromString(deployment.sdl, 'beta3');
633
+ await client.sendManifest(dseq, provider, sdl.manifest());
634
+ return lease;
635
+ }
636
+ export async function queryBids(dseq, walletPath = WALLET_PATH) {
637
+ const wallet = await AkashWallet.load(walletPath);
638
+ const client = new AkashClient(wallet);
639
+ return client.queryBids(dseq);
640
+ }
641
+ export async function getDeploymentStatus(dseq, walletPath = WALLET_PATH) {
642
+ const wallet = await AkashWallet.load(walletPath);
643
+ const client = new AkashClient(wallet);
644
+ // Get deployment from local records
645
+ const deployments = await client.listDeployments();
646
+ const deployment = deployments.find(d => d.dseq === dseq);
647
+ if (!deployment) {
648
+ throw new Error(`Deployment ${dseq} not found`);
649
+ }
650
+ if (!deployment.provider) {
651
+ // No lease yet, check for bids
652
+ const bids = await client.queryBids(dseq);
653
+ return {
654
+ ...deployment,
655
+ bids: bids.map(b => ({
656
+ provider: b.bid?.bidId?.provider || '',
657
+ price: b.bid?.price?.amount || '',
658
+ state: b.bid?.state || ''
659
+ }))
660
+ };
661
+ }
662
+ // Has a lease, get status from provider
663
+ try {
664
+ const status = await client.getLeaseStatus(dseq, deployment.provider);
665
+ return { ...deployment, leaseStatus: status };
666
+ }
667
+ catch (err) {
668
+ return { ...deployment, leaseStatusError: err.message };
669
+ }
670
+ }
671
+ //# sourceMappingURL=akash.js.map