@silvana-one/coordination 1.0.24 → 1.0.26

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 (96) hide show
  1. package/dist/node/agent.d.ts +43 -15
  2. package/dist/node/agent.js +129 -31
  3. package/dist/node/agent.js.map +1 -1
  4. package/dist/node/app_instance.d.ts +58 -0
  5. package/dist/node/app_instance.js +203 -0
  6. package/dist/node/app_instance.js.map +1 -0
  7. package/dist/node/build.d.ts +5 -0
  8. package/dist/node/build.js +21 -0
  9. package/dist/node/build.js.map +1 -0
  10. package/dist/node/execute.d.ts +1 -0
  11. package/dist/node/execute.js +10 -2
  12. package/dist/node/execute.js.map +1 -1
  13. package/dist/node/faucet.d.ts +34 -0
  14. package/dist/node/faucet.js +91 -0
  15. package/dist/node/faucet.js.map +1 -0
  16. package/dist/node/index.cjs +1087 -31
  17. package/dist/node/index.d.ts +9 -0
  18. package/dist/node/index.js +9 -0
  19. package/dist/node/index.js.map +1 -1
  20. package/dist/node/ipfs.d.ts +13 -0
  21. package/dist/node/ipfs.js +88 -0
  22. package/dist/node/ipfs.js.map +1 -0
  23. package/dist/node/job.d.ts +57 -0
  24. package/dist/node/job.js +168 -0
  25. package/dist/node/job.js.map +1 -0
  26. package/dist/node/package.d.ts +1 -0
  27. package/dist/node/package.js +6 -0
  28. package/dist/node/package.js.map +1 -0
  29. package/dist/node/public-key.d.ts +24 -0
  30. package/dist/node/public-key.js +44 -0
  31. package/dist/node/public-key.js.map +1 -0
  32. package/dist/node/publish.js.map +1 -1
  33. package/dist/node/test.d.ts +48 -0
  34. package/dist/node/test.js +278 -0
  35. package/dist/node/test.js.map +1 -0
  36. package/dist/node/upgrade.js +1 -12
  37. package/dist/node/upgrade.js.map +1 -1
  38. package/dist/node/walrus.d.ts +12 -0
  39. package/dist/node/walrus.js +73 -0
  40. package/dist/node/walrus.js.map +1 -0
  41. package/dist/tsconfig.tsbuildinfo +1 -1
  42. package/dist/tsconfig.web.tsbuildinfo +1 -1
  43. package/dist/web/agent.d.ts +43 -15
  44. package/dist/web/agent.js +129 -31
  45. package/dist/web/agent.js.map +1 -1
  46. package/dist/web/app_instance.d.ts +58 -0
  47. package/dist/web/app_instance.js +203 -0
  48. package/dist/web/app_instance.js.map +1 -0
  49. package/dist/web/build.d.ts +5 -0
  50. package/dist/web/build.js +21 -0
  51. package/dist/web/build.js.map +1 -0
  52. package/dist/web/execute.d.ts +1 -0
  53. package/dist/web/execute.js +10 -2
  54. package/dist/web/execute.js.map +1 -1
  55. package/dist/web/faucet.d.ts +34 -0
  56. package/dist/web/faucet.js +91 -0
  57. package/dist/web/faucet.js.map +1 -0
  58. package/dist/web/index.d.ts +9 -0
  59. package/dist/web/index.js +9 -0
  60. package/dist/web/index.js.map +1 -1
  61. package/dist/web/ipfs.d.ts +13 -0
  62. package/dist/web/ipfs.js +88 -0
  63. package/dist/web/ipfs.js.map +1 -0
  64. package/dist/web/job.d.ts +57 -0
  65. package/dist/web/job.js +168 -0
  66. package/dist/web/job.js.map +1 -0
  67. package/dist/web/package.d.ts +1 -0
  68. package/dist/web/package.js +6 -0
  69. package/dist/web/package.js.map +1 -0
  70. package/dist/web/public-key.d.ts +24 -0
  71. package/dist/web/public-key.js +44 -0
  72. package/dist/web/public-key.js.map +1 -0
  73. package/dist/web/publish.js.map +1 -1
  74. package/dist/web/test.d.ts +48 -0
  75. package/dist/web/test.js +278 -0
  76. package/dist/web/test.js.map +1 -0
  77. package/dist/web/upgrade.js +1 -12
  78. package/dist/web/upgrade.js.map +1 -1
  79. package/dist/web/walrus.d.ts +12 -0
  80. package/dist/web/walrus.js +73 -0
  81. package/dist/web/walrus.js.map +1 -0
  82. package/package.json +7 -4
  83. package/src/agent.ts +204 -56
  84. package/src/app_instance.ts +264 -0
  85. package/src/build.ts +33 -0
  86. package/src/execute.ts +11 -2
  87. package/src/faucet.ts +145 -0
  88. package/src/index.ts +9 -0
  89. package/src/ipfs.ts +105 -0
  90. package/src/job.ts +223 -0
  91. package/src/package.ts +6 -0
  92. package/src/public-key.ts +66 -0
  93. package/src/publish.ts +0 -2
  94. package/src/test.ts +383 -0
  95. package/src/upgrade.ts +1 -18
  96. package/src/walrus.ts +96 -0
package/src/agent.ts CHANGED
@@ -5,6 +5,7 @@ import {
5
5
  fetchSuiDynamicFieldsList,
6
6
  fetchSuiObject,
7
7
  } from "./fetch.js";
8
+ import { silvanaRegistryPackage } from "./package.js";
8
9
 
9
10
  type AgentChain =
10
11
  | "ethereum-mainnet"
@@ -26,18 +27,23 @@ type AgentChain =
26
27
  | "walrus-testnet"
27
28
  | string; // other chains
28
29
 
30
+ export interface AgentMethod {
31
+ dockerImage: string;
32
+ dockerSha256?: string;
33
+ minMemoryGb: number;
34
+ minCpuCores: number;
35
+ requiresTee: boolean;
36
+ }
37
+
29
38
  export interface Agent {
30
39
  id: string;
31
40
  name: string;
32
41
  image?: string;
33
42
  description?: string;
34
43
  site?: string;
35
- dockerImage: string;
36
- dockerSha256?: string;
37
- minMemoryGb: number;
38
- minCpuCores: number;
39
- supportsTEE: boolean;
40
44
  chains: AgentChain[];
45
+ methods: Record<string, AgentMethod>;
46
+ defaultMethod?: AgentMethod;
41
47
  createdAt: number;
42
48
  updatedAt: number;
43
49
  version: number;
@@ -75,7 +81,7 @@ export class AgentRegistry {
75
81
  console.log("Creating agent registry", params.name);
76
82
  const transaction = new Transaction();
77
83
  transaction.moveCall({
78
- target: `@silvana/agent::registry::create_registry`,
84
+ target: `${silvanaRegistryPackage}::registry::create_registry`,
79
85
  arguments: [transaction.pure.string(params.name)],
80
86
  });
81
87
 
@@ -93,7 +99,7 @@ export class AgentRegistry {
93
99
  const tx = new Transaction();
94
100
 
95
101
  tx.moveCall({
96
- target: `@silvana/agent::registry::add_developer`,
102
+ target: `${silvanaRegistryPackage}::registry::add_developer`,
97
103
  arguments: [
98
104
  tx.object(this.registry),
99
105
  tx.pure.string(name),
@@ -119,7 +125,7 @@ export class AgentRegistry {
119
125
  const tx = new Transaction();
120
126
 
121
127
  tx.moveCall({
122
- target: `@silvana/agent::registry::update_developer`,
128
+ target: `${silvanaRegistryPackage}::registry::update_developer`,
123
129
  arguments: [
124
130
  tx.object(this.registry),
125
131
  tx.pure.string(name),
@@ -139,7 +145,7 @@ export class AgentRegistry {
139
145
  const tx = new Transaction();
140
146
 
141
147
  tx.moveCall({
142
- target: `@silvana/agent::registry::remove_developer`,
148
+ target: `${silvanaRegistryPackage}::registry::remove_developer`,
143
149
  arguments: [
144
150
  tx.object(this.registry),
145
151
  tx.pure.string(name),
@@ -157,11 +163,6 @@ export class AgentRegistry {
157
163
  image?: string;
158
164
  description?: string;
159
165
  site?: string;
160
- docker_image: string;
161
- docker_sha256?: string;
162
- min_memory_gb: number;
163
- min_cpu_cores: number;
164
- supports_tee: boolean;
165
166
  chains: AgentChain[];
166
167
  }): Transaction {
167
168
  const {
@@ -170,17 +171,12 @@ export class AgentRegistry {
170
171
  image,
171
172
  description,
172
173
  site,
173
- docker_image,
174
- docker_sha256,
175
- min_memory_gb,
176
- min_cpu_cores,
177
- supports_tee,
178
174
  chains,
179
175
  } = params;
180
176
  const tx = new Transaction();
181
177
 
182
178
  tx.moveCall({
183
- target: `@silvana/agent::registry::add_agent`,
179
+ target: `${silvanaRegistryPackage}::registry::add_agent`,
184
180
  arguments: [
185
181
  tx.object(this.registry),
186
182
  tx.pure.string(developer),
@@ -188,11 +184,6 @@ export class AgentRegistry {
188
184
  tx.pure.option("string", image ?? null),
189
185
  tx.pure.option("string", description ?? null),
190
186
  tx.pure.option("string", site ?? null),
191
- tx.pure.string(docker_image),
192
- tx.pure.option("string", docker_sha256 ?? null),
193
- tx.pure.u16(min_memory_gb),
194
- tx.pure.u16(min_cpu_cores),
195
- tx.pure.bool(supports_tee),
196
187
  tx.pure.vector("string", chains),
197
188
  tx.object(SUI_CLOCK_OBJECT_ID),
198
189
  ],
@@ -207,11 +198,6 @@ export class AgentRegistry {
207
198
  image?: string;
208
199
  description?: string;
209
200
  site?: string;
210
- docker_image: string;
211
- docker_sha256?: string;
212
- min_memory_gb: number;
213
- min_cpu_cores: number;
214
- supports_tee: boolean;
215
201
  chains: AgentChain[];
216
202
  }): Transaction {
217
203
  const {
@@ -220,17 +206,12 @@ export class AgentRegistry {
220
206
  image,
221
207
  description,
222
208
  site,
223
- docker_image,
224
- docker_sha256,
225
- min_memory_gb,
226
- min_cpu_cores,
227
- supports_tee,
228
209
  chains,
229
210
  } = params;
230
211
  const tx = new Transaction();
231
212
 
232
213
  tx.moveCall({
233
- target: `@silvana/agent::registry::update_agent`,
214
+ target: `${silvanaRegistryPackage}::registry::update_agent`,
234
215
  arguments: [
235
216
  tx.object(this.registry),
236
217
  tx.pure.string(developer),
@@ -238,11 +219,6 @@ export class AgentRegistry {
238
219
  tx.pure.option("string", image ?? null),
239
220
  tx.pure.option("string", description ?? null),
240
221
  tx.pure.option("string", site ?? null),
241
- tx.pure.string(docker_image),
242
- tx.pure.option("string", docker_sha256 ?? null),
243
- tx.pure.u16(min_memory_gb),
244
- tx.pure.u16(min_cpu_cores),
245
- tx.pure.bool(supports_tee),
246
222
  tx.pure.vector("string", chains),
247
223
  tx.object(SUI_CLOCK_OBJECT_ID),
248
224
  ],
@@ -256,7 +232,153 @@ export class AgentRegistry {
256
232
  const tx = new Transaction();
257
233
 
258
234
  tx.moveCall({
259
- target: `@silvana/agent::registry::remove_agent`,
235
+ target: `${silvanaRegistryPackage}::registry::remove_agent`,
236
+ arguments: [
237
+ tx.object(this.registry),
238
+ tx.pure.string(developer),
239
+ tx.pure.string(agent),
240
+ tx.object(SUI_CLOCK_OBJECT_ID),
241
+ ],
242
+ });
243
+
244
+ return tx;
245
+ }
246
+
247
+ addAgentMethod(params: {
248
+ developer: string;
249
+ agent: string;
250
+ method: string;
251
+ dockerImage: string;
252
+ dockerSha256?: string;
253
+ minMemoryGb: number;
254
+ minCpuCores: number;
255
+ requiresTee: boolean;
256
+ }): Transaction {
257
+ const {
258
+ developer,
259
+ agent,
260
+ method,
261
+ dockerImage,
262
+ dockerSha256,
263
+ minMemoryGb,
264
+ minCpuCores,
265
+ requiresTee,
266
+ } = params;
267
+ const tx = new Transaction();
268
+
269
+ tx.moveCall({
270
+ target: `${silvanaRegistryPackage}::registry::add_method`,
271
+ arguments: [
272
+ tx.object(this.registry),
273
+ tx.pure.string(developer),
274
+ tx.pure.string(agent),
275
+ tx.pure.string(method),
276
+ tx.pure.string(dockerImage),
277
+ tx.pure.option("string", dockerSha256 ?? null),
278
+ tx.pure.u16(minMemoryGb),
279
+ tx.pure.u16(minCpuCores),
280
+ tx.pure.bool(requiresTee),
281
+ tx.object(SUI_CLOCK_OBJECT_ID),
282
+ ],
283
+ });
284
+
285
+ return tx;
286
+ }
287
+
288
+ updateAgentMethod(params: {
289
+ developer: string;
290
+ agent: string;
291
+ method: string;
292
+ dockerImage: string;
293
+ dockerSha256?: string;
294
+ minMemoryGb: number;
295
+ minCpuCores: number;
296
+ requiresTee: boolean;
297
+ }): Transaction {
298
+ const {
299
+ developer,
300
+ agent,
301
+ method,
302
+ dockerImage,
303
+ dockerSha256,
304
+ minMemoryGb,
305
+ minCpuCores,
306
+ requiresTee,
307
+ } = params;
308
+ const tx = new Transaction();
309
+
310
+ tx.moveCall({
311
+ target: `${silvanaRegistryPackage}::registry::update_method`,
312
+ arguments: [
313
+ tx.object(this.registry),
314
+ tx.pure.string(developer),
315
+ tx.pure.string(agent),
316
+ tx.pure.string(method),
317
+ tx.pure.string(dockerImage),
318
+ tx.pure.option("string", dockerSha256 ?? null),
319
+ tx.pure.u16(minMemoryGb),
320
+ tx.pure.u16(minCpuCores),
321
+ tx.pure.bool(requiresTee),
322
+ tx.object(SUI_CLOCK_OBJECT_ID),
323
+ ],
324
+ });
325
+
326
+ return tx;
327
+ }
328
+
329
+ removeAgentMethod(params: {
330
+ developer: string;
331
+ agent: string;
332
+ method: string;
333
+ }): Transaction {
334
+ const { developer, agent, method } = params;
335
+ const tx = new Transaction();
336
+
337
+ tx.moveCall({
338
+ target: `${silvanaRegistryPackage}::registry::remove_method`,
339
+ arguments: [
340
+ tx.object(this.registry),
341
+ tx.pure.string(developer),
342
+ tx.pure.string(agent),
343
+ tx.pure.string(method),
344
+ tx.object(SUI_CLOCK_OBJECT_ID),
345
+ ],
346
+ });
347
+
348
+ return tx;
349
+ }
350
+
351
+ setDefaultMethod(params: {
352
+ developer: string;
353
+ agent: string;
354
+ method: string;
355
+ }): Transaction {
356
+ const { developer, agent, method } = params;
357
+ const tx = new Transaction();
358
+
359
+ tx.moveCall({
360
+ target: `${silvanaRegistryPackage}::registry::set_default_method`,
361
+ arguments: [
362
+ tx.object(this.registry),
363
+ tx.pure.string(developer),
364
+ tx.pure.string(agent),
365
+ tx.pure.string(method),
366
+ tx.object(SUI_CLOCK_OBJECT_ID),
367
+ ],
368
+ });
369
+
370
+ return tx;
371
+ }
372
+
373
+ removeDefaultMethod(params: {
374
+ developer: string;
375
+ agent: string;
376
+ }): Transaction {
377
+ const { developer, agent } = params;
378
+ const tx = new Transaction();
379
+
380
+ tx.moveCall({
381
+ target: `${silvanaRegistryPackage}::registry::remove_default_method`,
260
382
  arguments: [
261
383
  tx.object(this.registry),
262
384
  tx.pure.string(developer),
@@ -367,32 +489,58 @@ export class AgentRegistry {
367
489
  if (!agentObject) {
368
490
  return undefined;
369
491
  }
492
+
493
+ // Parse methods from VecMap structure
494
+ const methods: Record<string, AgentMethod> = {};
495
+ const methodsData = (agentObject as any)?.methods?.fields?.contents;
496
+ if (methodsData && Array.isArray(methodsData)) {
497
+ for (const entry of methodsData) {
498
+ const key = entry?.fields?.key;
499
+ const value = entry?.fields?.value;
500
+ if (key && value) {
501
+ methods[key] = {
502
+ dockerImage: value.docker_image,
503
+ dockerSha256: value.docker_sha256 ?? undefined,
504
+ minMemoryGb: Number(value.min_memory_gb),
505
+ minCpuCores: Number(value.min_cpu_cores),
506
+ requiresTee: Boolean(value.requires_tee),
507
+ };
508
+ }
509
+ }
510
+ }
511
+
512
+ // Parse default method if it exists
513
+ let defaultMethod: AgentMethod | undefined;
514
+ const defaultMethodData = (agentObject as any)?.default_method;
515
+ if (defaultMethodData && typeof defaultMethodData === 'object' && !Array.isArray(defaultMethodData)) {
516
+ defaultMethod = {
517
+ dockerImage: defaultMethodData.docker_image,
518
+ dockerSha256: defaultMethodData.docker_sha256 ?? undefined,
519
+ minMemoryGb: Number(defaultMethodData.min_memory_gb),
520
+ minCpuCores: Number(defaultMethodData.min_cpu_cores),
521
+ requiresTee: Boolean(defaultMethodData.requires_tee),
522
+ };
523
+ }
524
+
370
525
  const agent = {
371
526
  id: (agentObject as any)?.id?.id,
372
527
  name: (agentObject as any).name,
373
528
  image: (agentObject as any)?.image ?? undefined,
374
529
  description: (agentObject as any)?.description ?? undefined,
375
530
  site: (agentObject as any)?.site ?? undefined,
376
- dockerImage: (agentObject as any).docker_image,
377
- dockerSha256: (agentObject as any)?.docker_sha256 ?? undefined,
378
- minMemoryGb: Number((agentObject as any).min_memory_gb),
379
- minCpuCores: Number((agentObject as any).min_cpu_cores),
380
- supportsTEE: Boolean((agentObject as any).supports_tee),
531
+ chains: (agentObject as any)?.chains ?? [],
532
+ methods,
533
+ defaultMethod,
381
534
  createdAt: Number((agentObject as any).created_at),
382
535
  updatedAt: Number((agentObject as any).updated_at),
383
536
  version: Number((agentObject as any).version),
384
537
  };
385
- if (
386
- !agent.id ||
387
- !agent.name ||
388
- !agent.dockerImage ||
389
- !agent.minMemoryGb ||
390
- !agent.minCpuCores ||
391
- !agent.createdAt ||
392
- !agent.updatedAt
393
- ) {
538
+
539
+ // Only check for essential fields
540
+ if (!agent.id || !agent.name) {
394
541
  return undefined;
395
542
  }
543
+
396
544
  return agent as Agent;
397
545
  }
398
546
 
@@ -0,0 +1,264 @@
1
+ import { Transaction } from "@mysten/sui/transactions";
2
+ import { SUI_CLOCK_OBJECT_ID } from "@mysten/sui/utils";
3
+ import { silvanaRegistryPackage } from "./package.js";
4
+ import { fetchSuiDynamicField, fetchSuiObject } from "./fetch.js";
5
+ import { Job, JobStatus } from "./job.js";
6
+
7
+ export interface AppMethod {
8
+ description?: string;
9
+ developer: string;
10
+ agent: string;
11
+ agentMethod: string;
12
+ }
13
+
14
+ export interface AppInstance {
15
+ id: string;
16
+ silvanaAppName: string;
17
+ description?: string;
18
+ metadata?: string;
19
+ methods: Record<string, AppMethod>;
20
+ admin: string;
21
+ sequence: number;
22
+ blockNumber: number;
23
+ previousBlockTimestamp: number;
24
+ previousBlockLastSequence: number;
25
+ lastProvedBlockNumber: number;
26
+ isPaused: boolean;
27
+ jobsId: string;
28
+ createdAt: number;
29
+ updatedAt: number;
30
+ }
31
+
32
+ export interface CreateAppJobParams {
33
+ appInstance: string;
34
+ description?: string;
35
+ method: string;
36
+ sequences?: number[];
37
+ data: Uint8Array;
38
+ }
39
+
40
+ export class AppInstanceManager {
41
+ private readonly registry: string;
42
+
43
+ constructor(params: { registry: string }) {
44
+ this.registry = params.registry;
45
+ }
46
+
47
+ // Note: update_method and remove_method functions are not available in the Move module
48
+ // These would need to be implemented in app_instance.move if needed
49
+
50
+ createAppJob(params: CreateAppJobParams): Transaction {
51
+ const { appInstance, description, method, sequences, data } = params;
52
+
53
+ // Debug logging
54
+ console.log("createAppJob params:", {
55
+ appInstance,
56
+ description,
57
+ method,
58
+ sequences,
59
+ data:
60
+ data instanceof Uint8Array ? `Uint8Array(${data.length})` : typeof data,
61
+ dataContent: data instanceof Uint8Array ? Array.from(data) : data,
62
+ });
63
+
64
+ const tx = new Transaction();
65
+
66
+ tx.moveCall({
67
+ target: `${silvanaRegistryPackage}::app_instance::create_app_job`,
68
+ arguments: [
69
+ tx.object(appInstance),
70
+ tx.pure.string(method),
71
+ tx.pure.option("string", description ?? null),
72
+ tx.pure.option("vector<u64>", sequences ?? null),
73
+ tx.pure.vector("u8", data),
74
+ tx.object(SUI_CLOCK_OBJECT_ID),
75
+ ],
76
+ });
77
+
78
+ return tx;
79
+ }
80
+
81
+ startAppJob(params: { appInstance: string; jobId: number }): Transaction {
82
+ const { appInstance, jobId } = params;
83
+ const tx = new Transaction();
84
+
85
+ tx.moveCall({
86
+ target: `${silvanaRegistryPackage}::app_instance::start_app_job`,
87
+ arguments: [
88
+ tx.object(appInstance),
89
+ tx.pure.u64(jobId),
90
+ tx.object(SUI_CLOCK_OBJECT_ID),
91
+ ],
92
+ });
93
+
94
+ return tx;
95
+ }
96
+
97
+ completeAppJob(params: { appInstance: string; jobId: number }): Transaction {
98
+ const { appInstance, jobId } = params;
99
+ const tx = new Transaction();
100
+
101
+ tx.moveCall({
102
+ target: `${silvanaRegistryPackage}::app_instance::complete_app_job`,
103
+ arguments: [
104
+ tx.object(appInstance),
105
+ tx.pure.u64(jobId),
106
+ tx.object(SUI_CLOCK_OBJECT_ID),
107
+ ],
108
+ });
109
+
110
+ return tx;
111
+ }
112
+
113
+ failAppJob(params: {
114
+ appInstance: string;
115
+ jobId: number;
116
+ error: string;
117
+ }): Transaction {
118
+ const { appInstance, jobId, error } = params;
119
+ const tx = new Transaction();
120
+
121
+ tx.moveCall({
122
+ target: `${silvanaRegistryPackage}::app_instance::fail_app_job`,
123
+ arguments: [
124
+ tx.object(appInstance),
125
+ tx.pure.u64(jobId),
126
+ tx.pure.string(error),
127
+ tx.object(SUI_CLOCK_OBJECT_ID),
128
+ ],
129
+ });
130
+
131
+ return tx;
132
+ }
133
+
134
+ async getAppInstance(
135
+ appInstanceId: string
136
+ ): Promise<AppInstance | undefined> {
137
+ try {
138
+ const appInstance = await fetchSuiObject(appInstanceId);
139
+ if (!appInstance) return undefined;
140
+
141
+ const fields = (appInstance as any)?.data?.content?.fields;
142
+ if (!fields) return undefined;
143
+
144
+ // Parse methods from VecMap
145
+ const methods: Record<string, AppMethod> = {};
146
+ const methodsArray = fields?.methods?.fields?.contents;
147
+ if (Array.isArray(methodsArray)) {
148
+ for (const entry of methodsArray) {
149
+ const key = entry?.fields?.key;
150
+ const value = entry?.fields?.value;
151
+ if (key && value) {
152
+ // Value might have a fields property too
153
+ const methodFields = value.fields || value;
154
+ methods[key] = {
155
+ description: methodFields.description ?? undefined,
156
+ developer: methodFields.developer,
157
+ agent: methodFields.agent,
158
+ agentMethod: methodFields.agent_method || methodFields.agentMethod,
159
+ };
160
+ }
161
+ }
162
+ }
163
+
164
+ return {
165
+ id: fields?.id?.id,
166
+ silvanaAppName: fields.silvana_app_name,
167
+ description: fields?.description ?? undefined,
168
+ metadata: fields?.metadata ?? undefined,
169
+ methods,
170
+ admin: fields.admin,
171
+ sequence: Number(fields.sequence),
172
+ blockNumber: Number(fields.block_number),
173
+ previousBlockTimestamp: Number(fields.previous_block_timestamp),
174
+ previousBlockLastSequence: Number(fields.previous_block_last_sequence),
175
+ lastProvedBlockNumber: Number(fields.last_proved_block_number),
176
+ isPaused: Boolean(fields.isPaused),
177
+ jobsId: String(fields.jobs?.fields?.id?.id ?? ""),
178
+ createdAt: Number(fields.created_at),
179
+ updatedAt: Number(fields.updated_at),
180
+ };
181
+ } catch (error) {
182
+ console.error("Error fetching app instance:", error);
183
+ return undefined;
184
+ }
185
+ }
186
+
187
+ async getAppJob(params: {
188
+ appInstance: string;
189
+ jobId: number;
190
+ }): Promise<Job | undefined> {
191
+ try {
192
+ const appInstanceObj = await fetchSuiObject(params.appInstance);
193
+ if (!appInstanceObj) return undefined;
194
+
195
+ // Jobs are embedded in the AppInstance - use correct path
196
+ const jobsTableId = (appInstanceObj as any)?.data?.content?.fields?.jobs?.fields?.jobs?.fields?.id?.id;
197
+ if (!jobsTableId) return undefined;
198
+
199
+ const job = await fetchSuiDynamicField({
200
+ parentID: jobsTableId,
201
+ fieldName: "jobs",
202
+ type: "u64",
203
+ key: String(params.jobId),
204
+ });
205
+
206
+ if (!job) return undefined;
207
+
208
+ const parseStatus = (status: any): JobStatus => {
209
+ // Check variant field format (used by Sui dynamic fields)
210
+ if (status?.variant === "Pending") return { type: "Pending" };
211
+ if (status?.variant === "Running") return { type: "Running" };
212
+ if (status?.variant === "Failed") {
213
+ // Get error from fields or from direct property
214
+ const error = status?.fields?.error || status?.fields?.[0] || "Unknown error";
215
+ return { type: "Failed", error };
216
+ }
217
+ // Legacy formats
218
+ if (status?.Pending !== undefined) return { type: "Pending" };
219
+ if (status?.Running !== undefined) return { type: "Running" };
220
+ if (status?.Failed !== undefined) return { type: "Failed", error: status.Failed };
221
+ return { type: "Pending" };
222
+ };
223
+
224
+ return {
225
+ id: (job as any)?.id?.id,
226
+ jobId: Number((job as any).job_id),
227
+ description: (job as any)?.description ?? undefined,
228
+ developer: (job as any).developer,
229
+ agent: (job as any).agent,
230
+ agentMethod: (job as any).agent_method,
231
+ app: (job as any).app,
232
+ appInstance: (job as any).app_instance,
233
+ appInstanceMethod: (job as any).app_instance_method,
234
+ sequences:
235
+ (job as any)?.sequences?.map((s: string) => Number(s)) ?? undefined,
236
+ data: new Uint8Array((job as any).data),
237
+ status: parseStatus((job as any).status),
238
+ attempts: Number((job as any).attempts),
239
+ createdAt: Number((job as any).created_at),
240
+ updatedAt: Number((job as any).updated_at),
241
+ };
242
+ } catch (error) {
243
+ console.error("Error fetching app job:", error);
244
+ return undefined;
245
+ }
246
+ }
247
+
248
+ async getAppPendingJobs(appInstance: string): Promise<number[]> {
249
+ try {
250
+ const appInstanceObj = await fetchSuiObject(appInstance);
251
+ if (!appInstanceObj) return [];
252
+
253
+ // Jobs are embedded in the AppInstance - use correct path
254
+ const pendingJobs = (appInstanceObj as any)?.data?.content?.fields?.jobs?.fields?.pending_jobs?.fields?.contents;
255
+
256
+ if (!Array.isArray(pendingJobs)) return [];
257
+
258
+ return pendingJobs.map((id: string) => Number(id));
259
+ } catch (error) {
260
+ console.error("Error fetching app pending jobs:", error);
261
+ return [];
262
+ }
263
+ }
264
+ }
package/src/build.ts ADDED
@@ -0,0 +1,33 @@
1
+ export async function buildMovePackage(path: string): Promise<{
2
+ modules: string[];
3
+ dependencies: string[];
4
+ digest: number[];
5
+ }> {
6
+ const { execSync } = await import("child_process");
7
+ let bytes:
8
+ | {
9
+ modules: string[];
10
+ dependencies: string[];
11
+ digest: number[];
12
+ }
13
+ | undefined = undefined;
14
+
15
+ console.log("Running sui client publish command...");
16
+ try {
17
+ const output = execSync(
18
+ `sui move build --dump-bytecode-as-base64 --ignore-chain --path ${path}`,
19
+ {
20
+ encoding: "utf-8",
21
+ }
22
+ );
23
+ bytes = JSON.parse(output);
24
+ if (!bytes) {
25
+ throw new Error("Error building package");
26
+ }
27
+ return bytes;
28
+ //console.log("Command output:", bytes);
29
+ } catch (error) {
30
+ console.error("Error running command:", error);
31
+ throw error;
32
+ }
33
+ }
package/src/execute.ts CHANGED
@@ -66,6 +66,7 @@ export async function executeTx(params: {
66
66
  digest: string;
67
67
  events: object;
68
68
  executeTime: number;
69
+ error?: string;
69
70
  }
70
71
  | undefined
71
72
  > {
@@ -136,13 +137,21 @@ export async function executeTx(params: {
136
137
  }
137
138
 
138
139
  if (executedTx?.effects?.status?.status === "failure") {
140
+ const errorMessage = executedTx?.effects?.status?.error || "Unknown error";
139
141
  if (showErrors) {
140
142
  console.log(
141
143
  `Errors for tx ${executedTx.digest}:`,
142
- executedTx?.effects?.status?.error
144
+ errorMessage
143
145
  );
144
- throw new Error(`tx execution failed: ${executedTx.digest}`);
145
146
  }
147
+ // Return the transaction with error information instead of throwing
148
+ return {
149
+ tx: executedTx,
150
+ digest: executedTx.digest,
151
+ events: (executedTx?.events as SuiEvent[])?.[0]?.parsedJson as object,
152
+ executeTime: end - start,
153
+ error: errorMessage,
154
+ };
146
155
  }
147
156
  return {
148
157
  tx: executedTx,