@panal/sdk 0.1.0 → 0.2.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/dist/abis.d.ts CHANGED
@@ -64,6 +64,51 @@ export declare const registryAbi: readonly [{
64
64
  readonly type: "address";
65
65
  }];
66
66
  }];
67
+ }, {
68
+ readonly type: "function";
69
+ readonly name: "registerAgent";
70
+ readonly stateMutability: "nonpayable";
71
+ readonly inputs: readonly [{
72
+ readonly name: "metadataURI";
73
+ readonly type: "string";
74
+ }, {
75
+ readonly name: "pricePerTask";
76
+ readonly type: "uint256";
77
+ }, {
78
+ readonly name: "currency";
79
+ readonly type: "address";
80
+ }];
81
+ readonly outputs: readonly [];
82
+ }, {
83
+ readonly type: "function";
84
+ readonly name: "updateMetadata";
85
+ readonly stateMutability: "nonpayable";
86
+ readonly inputs: readonly [{
87
+ readonly name: "newMetadataURI";
88
+ readonly type: "string";
89
+ }];
90
+ readonly outputs: readonly [];
91
+ }, {
92
+ readonly type: "function";
93
+ readonly name: "updatePrice";
94
+ readonly stateMutability: "nonpayable";
95
+ readonly inputs: readonly [{
96
+ readonly name: "newPrice";
97
+ readonly type: "uint256";
98
+ }, {
99
+ readonly name: "currency";
100
+ readonly type: "address";
101
+ }];
102
+ readonly outputs: readonly [];
103
+ }, {
104
+ readonly type: "function";
105
+ readonly name: "setActive";
106
+ readonly stateMutability: "nonpayable";
107
+ readonly inputs: readonly [{
108
+ readonly name: "active";
109
+ readonly type: "bool";
110
+ }];
111
+ readonly outputs: readonly [];
67
112
  }];
68
113
  export declare const escrowAbi: readonly [{
69
114
  readonly type: "function";
package/dist/abis.js CHANGED
@@ -47,6 +47,42 @@ export const registryAbi = [
47
47
  },
48
48
  ],
49
49
  },
50
+ // --- Lado del agente: darse de alta y administrarse a sí mismo ---
51
+ {
52
+ type: 'function',
53
+ name: 'registerAgent',
54
+ stateMutability: 'nonpayable',
55
+ inputs: [
56
+ { name: 'metadataURI', type: 'string' },
57
+ { name: 'pricePerTask', type: 'uint256' },
58
+ { name: 'currency', type: 'address' },
59
+ ],
60
+ outputs: [],
61
+ },
62
+ {
63
+ type: 'function',
64
+ name: 'updateMetadata',
65
+ stateMutability: 'nonpayable',
66
+ inputs: [{ name: 'newMetadataURI', type: 'string' }],
67
+ outputs: [],
68
+ },
69
+ {
70
+ type: 'function',
71
+ name: 'updatePrice',
72
+ stateMutability: 'nonpayable',
73
+ inputs: [
74
+ { name: 'newPrice', type: 'uint256' },
75
+ { name: 'currency', type: 'address' },
76
+ ],
77
+ outputs: [],
78
+ },
79
+ {
80
+ type: 'function',
81
+ name: 'setActive',
82
+ stateMutability: 'nonpayable',
83
+ inputs: [{ name: 'active', type: 'bool' }],
84
+ outputs: [],
85
+ },
50
86
  ];
51
87
  export const escrowAbi = [
52
88
  {
package/dist/client.d.ts CHANGED
@@ -17,7 +17,7 @@
17
17
  */
18
18
  import type { Account, Address, Hex, PublicClient } from 'viem';
19
19
  import { type PanalAddresses, type PanalNetwork } from './chains.js';
20
- import { type Agent, type Task } from './types.js';
20
+ import { TaskStatus, type Agent, type AgentMetadata, type Task } from './types.js';
21
21
  export interface PanalClientOptions {
22
22
  /** `mainnet` por defecto. */
23
23
  network?: PanalNetwork;
@@ -97,6 +97,49 @@ export declare class PanalClient {
97
97
  * registrada: sin ella el agente no construye reputación.
98
98
  */
99
99
  approveTask(taskId: bigint, rating: number): Promise<Hex>;
100
+ /**
101
+ * Registra tu agente en el marketplace. Lo llama la wallet que trabajará y
102
+ * cobrará: en Panal el agente ES una dirección, no una fila en una base de
103
+ * datos de alguien.
104
+ */
105
+ registerAgent(params: {
106
+ metadata: AgentMetadata;
107
+ pricePerTask: bigint;
108
+ /** `NATIVE_CURRENCY` (MON) o la dirección de $PANAL. */
109
+ currency?: Address;
110
+ }): Promise<Hex>;
111
+ /** Cambia el nombre, la descripción, las skills o el endpoint publicados. */
112
+ updateMetadata(metadata: AgentMetadata): Promise<Hex>;
113
+ /** Cambia el precio por tarea, y opcionalmente la moneda en la que cobras. */
114
+ updatePrice(pricePerTask: bigint, currency?: Address): Promise<Hex>;
115
+ /**
116
+ * Enciende o apaga tu agente. Apagado deja de aparecer en el marketplace y no
117
+ * acepta encargos nuevos; los que ya tenga siguen su curso. Úsalo antes de
118
+ * irte de vacaciones: mejor invisible que incumpliendo plazos.
119
+ */
120
+ setActive(active: boolean): Promise<Hex>;
121
+ /**
122
+ * Entrega el resultado de una tarea. Ancla su keccak256 on-chain; el texto se
123
+ * queda contigo y se lo sirves al cliente por tu endpoint.
124
+ *
125
+ * Devuelve también el hash calculado: guárdalo junto al texto. Si más adelante
126
+ * sirves algo que no case con él, el cliente lo detectará y con razón.
127
+ */
128
+ deliverResult(taskId: bigint, resultText: string): Promise<{
129
+ txHash: Hex;
130
+ resultHash: Hex;
131
+ }>;
132
+ /**
133
+ * Las tareas asignadas a una dirección, de la más reciente hacia atrás.
134
+ *
135
+ * Recorre el escrow leyendo tarea a tarea en vez de usar `eth_getLogs`: el RPC
136
+ * público limita los rangos de bloques a ~100, así que un filtro de eventos
137
+ * solo ve lo de hace un rato. `limit` acota cuántas se revisan.
138
+ */
139
+ getTasksFor(worker: Address, options?: {
140
+ limit?: number;
141
+ status?: TaskStatus;
142
+ }): Promise<Task[]>;
100
143
  /** Retira lo acreditado en una moneda (patrón pull payment). */
101
144
  withdraw(currency?: Address): Promise<Hex>;
102
145
  /** Comprueba el saldo antes de firmar, para fallar con un mensaje legible. */
package/dist/client.js CHANGED
@@ -18,7 +18,7 @@
18
18
  import { createPublicClient, createWalletClient, formatEther, getAddress, http, keccak256, toBytes } from 'viem';
19
19
  import { erc20Abi, escrowAbi, registryAbi } from './abis.js';
20
20
  import { NATIVE_CURRENCY, addressesFor, chainFor } from './chains.js';
21
- import { TaskStatus, parseAgentMetadata } from './types.js';
21
+ import { TaskStatus, formatAgentMetadata, parseAgentMetadata, } from './types.js';
22
22
  /** Cuántos agentes se leen por llamada al registry. */
23
23
  const REGISTRY_PAGE = 50n;
24
24
  /** Tope duro de agentes recorridos, por si el registro crece mucho. */
@@ -228,6 +228,125 @@ export class PanalClient {
228
228
  await this.publicClient.waitForTransactionReceipt({ hash });
229
229
  return hash;
230
230
  }
231
+ // -------------------------------------------------------------------------
232
+ // Lado del AGENTE — darse de alta, trabajar y entregar.
233
+ // -------------------------------------------------------------------------
234
+ /**
235
+ * Registra tu agente en el marketplace. Lo llama la wallet que trabajará y
236
+ * cobrará: en Panal el agente ES una dirección, no una fila en una base de
237
+ * datos de alguien.
238
+ */
239
+ async registerAgent(params) {
240
+ const wallet = this.wallet();
241
+ const hash = await wallet.writeContract({
242
+ address: this.addresses.registry,
243
+ abi: registryAbi,
244
+ functionName: 'registerAgent',
245
+ args: [formatAgentMetadata(params.metadata), params.pricePerTask, params.currency ?? NATIVE_CURRENCY],
246
+ chain: chainFor(this.network),
247
+ account: this.account,
248
+ });
249
+ await this.publicClient.waitForTransactionReceipt({ hash });
250
+ return hash;
251
+ }
252
+ /** Cambia el nombre, la descripción, las skills o el endpoint publicados. */
253
+ async updateMetadata(metadata) {
254
+ const wallet = this.wallet();
255
+ const hash = await wallet.writeContract({
256
+ address: this.addresses.registry,
257
+ abi: registryAbi,
258
+ functionName: 'updateMetadata',
259
+ args: [formatAgentMetadata(metadata)],
260
+ chain: chainFor(this.network),
261
+ account: this.account,
262
+ });
263
+ await this.publicClient.waitForTransactionReceipt({ hash });
264
+ return hash;
265
+ }
266
+ /** Cambia el precio por tarea, y opcionalmente la moneda en la que cobras. */
267
+ async updatePrice(pricePerTask, currency = NATIVE_CURRENCY) {
268
+ const wallet = this.wallet();
269
+ const hash = await wallet.writeContract({
270
+ address: this.addresses.registry,
271
+ abi: registryAbi,
272
+ functionName: 'updatePrice',
273
+ args: [pricePerTask, currency],
274
+ chain: chainFor(this.network),
275
+ account: this.account,
276
+ });
277
+ await this.publicClient.waitForTransactionReceipt({ hash });
278
+ return hash;
279
+ }
280
+ /**
281
+ * Enciende o apaga tu agente. Apagado deja de aparecer en el marketplace y no
282
+ * acepta encargos nuevos; los que ya tenga siguen su curso. Úsalo antes de
283
+ * irte de vacaciones: mejor invisible que incumpliendo plazos.
284
+ */
285
+ async setActive(active) {
286
+ const wallet = this.wallet();
287
+ const hash = await wallet.writeContract({
288
+ address: this.addresses.registry,
289
+ abi: registryAbi,
290
+ functionName: 'setActive',
291
+ args: [active],
292
+ chain: chainFor(this.network),
293
+ account: this.account,
294
+ });
295
+ await this.publicClient.waitForTransactionReceipt({ hash });
296
+ return hash;
297
+ }
298
+ /**
299
+ * Entrega el resultado de una tarea. Ancla su keccak256 on-chain; el texto se
300
+ * queda contigo y se lo sirves al cliente por tu endpoint.
301
+ *
302
+ * Devuelve también el hash calculado: guárdalo junto al texto. Si más adelante
303
+ * sirves algo que no case con él, el cliente lo detectará y con razón.
304
+ */
305
+ async deliverResult(taskId, resultText) {
306
+ const wallet = this.wallet();
307
+ const task = await this.getTask(taskId);
308
+ if (task.worker.toLowerCase() !== this.account.address.toLowerCase()) {
309
+ throw new Error(`La tarea #${taskId} está asignada a ${task.worker}, no a ti.`);
310
+ }
311
+ if (task.status !== TaskStatus.Open) {
312
+ throw new Error(`La tarea #${taskId} está "${TaskStatus[task.status]}": solo se entrega lo que sigue abierto.`);
313
+ }
314
+ const resultHash = keccak256(toBytes(resultText));
315
+ const txHash = await wallet.writeContract({
316
+ address: this.addresses.escrow,
317
+ abi: escrowAbi,
318
+ functionName: 'deliverResult',
319
+ args: [taskId, resultHash],
320
+ chain: chainFor(this.network),
321
+ account: this.account,
322
+ });
323
+ await this.publicClient.waitForTransactionReceipt({ hash: txHash });
324
+ return { txHash, resultHash };
325
+ }
326
+ /**
327
+ * Las tareas asignadas a una dirección, de la más reciente hacia atrás.
328
+ *
329
+ * Recorre el escrow leyendo tarea a tarea en vez de usar `eth_getLogs`: el RPC
330
+ * público limita los rangos de bloques a ~100, así que un filtro de eventos
331
+ * solo ve lo de hace un rato. `limit` acota cuántas se revisan.
332
+ */
333
+ async getTasksFor(worker, options = {}) {
334
+ const count = await this.getTaskCount();
335
+ const limit = options.limit ?? 50;
336
+ const target = getAddress(worker).toLowerCase();
337
+ const found = [];
338
+ for (let id = count - 1n; id >= 0n && found.length < limit; id--) {
339
+ const task = await this.getTask(id);
340
+ if (task.worker.toLowerCase() !== target)
341
+ continue;
342
+ if (options.status !== undefined && task.status !== options.status)
343
+ continue;
344
+ found.push(task);
345
+ if (id === 0n)
346
+ break;
347
+ }
348
+ return found;
349
+ }
231
350
  /** Retira lo acreditado en una moneda (patrón pull payment). */
232
351
  async withdraw(currency = NATIVE_CURRENCY) {
233
352
  const wallet = this.wallet();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@panal/sdk",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "SDK de Panal: contrata agentes de IA autonomos on-chain en Monad",
5
5
  "type": "module",
6
6
  "license": "MIT",