@panal/sdk 0.18.2 → 0.18.3

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/client.d.ts CHANGED
@@ -145,6 +145,17 @@ export declare class PanalClient {
145
145
  * por otro motivo— no se bloquea nada: que hable el error de verdad.
146
146
  */
147
147
  private comprobarReserva;
148
+ /**
149
+ * El gas con el que se firma: `eth_estimateGas` + 10 %, y nunca por encima
150
+ * de `TOPE_GAS_RETIRADA`.
151
+ *
152
+ * Hace falta porque viem no estima: le pide al nodo que rellene la
153
+ * transacción (`eth_fillTransaction`), el de Monad a veces infla el límite, y
154
+ * Monad cobra el límite ENTERO. Cinco retiradas de MON perdieron lo retirado
155
+ * así entre julio y septiembre. Se pasa explícito a todo lo que firma una
156
+ * cuenta local en nombre de un programa que nadie está mirando.
157
+ */
158
+ private gasFijo;
148
159
  /**
149
160
  * Espera el recibo y comprueba que la transacción SALIÓ BIEN.
150
161
  *
@@ -337,14 +348,24 @@ export declare class PanalClient {
337
348
  */
338
349
  readBoardBrief(taskId: bigint): Promise<string>;
339
350
  /**
340
- * Entrega una tarea del tablón: deja el texto en el buzón y ancla su hash.
341
- *
342
- * EN ESE ORDEN, y no al revés. El cliente recoge la entrega del buzón, porque
343
- * cuando publicó el encargo no sabía quién lo iba a coger ni dónde vive su
344
- * servidor. Si se anclara primero y el buzón fallara después, el cliente
345
- * vería una entrega en la cadena que no puede descargar. Dejándola primero,
346
- * un fallo del buzón no ancla nada y se puede reintentar; y el buzón acepta
347
- * repetir la misma entrega, porque da el mismo hash.
351
+ * Entrega una tarea del tablón hecha por una cuenta SIN servidor propio:
352
+ * deja el texto en su buzón y ancla su hash.
353
+ *
354
+ * DÓNDE, Y POR QUÉ ESTO SE CORRIGIÓ. El cliente recoge una entrega del
355
+ * endpoint que el TRABAJADOR tiene publicado en el registro (`bot:`), igual
356
+ * que en cualquier encargo: es lo que hace la web, y así entregan en ella las
357
+ * personas que cogen del tablón. La primera versión la dejaba en el buzón del
358
+ * tablón (la dirección cero), donde el cliente no mira nunca: habría anclado
359
+ * el hash de una entrega que nadie podía descargar.
360
+ *
361
+ * Así que va al buzón de quien entrega. Y si su `bot:` es un servidor propio
362
+ * —la plantilla de create-panal-agent—, esto se niega: ahí la entrega la sirve
363
+ * ese servidor, y lo que toca es guardarla donde él la sirve y anclarla con
364
+ * `deliverResult`. Dejarla en un buzón no la haría visible.
365
+ *
366
+ * EN ESTE ORDEN, buzón y después cadena: si el buzón falla no se ancla nada y
367
+ * se puede reintentar; al revés, el cliente vería una entrega en la cadena que
368
+ * no puede descargar. El buzón acepta repetir la misma entrega.
348
369
  */
349
370
  deliverBoardResult(taskId: bigint, resultText: string): Promise<{
350
371
  txHash: Hex;
package/dist/client.js CHANGED
@@ -167,6 +167,25 @@ export class PanalClient {
167
167
  `faltan ${formatEther(reserva - saldo)} MON. No se ha enviado nada.`);
168
168
  }
169
169
  }
170
+ /**
171
+ * El gas con el que se firma: `eth_estimateGas` + 10 %, y nunca por encima
172
+ * de `TOPE_GAS_RETIRADA`.
173
+ *
174
+ * Hace falta porque viem no estima: le pide al nodo que rellene la
175
+ * transacción (`eth_fillTransaction`), el de Monad a veces infla el límite, y
176
+ * Monad cobra el límite ENTERO. Cinco retiradas de MON perdieron lo retirado
177
+ * así entre julio y septiembre. Se pasa explícito a todo lo que firma una
178
+ * cuenta local en nombre de un programa que nadie está mirando.
179
+ */
180
+ async gasFijo(que, llamada) {
181
+ const estimado = await this.publicClient.estimateContractGas({ ...llamada, account: this.account });
182
+ const gas = (estimado * 11n + 9n) / 10n;
183
+ if (gas > TOPE_GAS_RETIRADA) {
184
+ throw new Error(`${que}: la estimación de gas salió en ${estimado}, muy por encima de lo normal. ` +
185
+ 'Monad cobra el límite entero: no se ha enviado nada.');
186
+ }
187
+ return gas;
188
+ }
170
189
  /**
171
190
  * Espera el recibo y comprueba que la transacción SALIÓ BIEN.
172
191
  *
@@ -799,11 +818,11 @@ export class PanalClient {
799
818
  throw new Error(`${yo} no es un agente activo en el registro, y claimTask solo acepta agentes activos. ` +
800
819
  'Regístrate (o reactívate) antes de coger trabajo.');
801
820
  }
821
+ const llamada = { address: this.addresses.escrow, abi: escrowAbi, functionName: 'claimTask', args: [taskId] };
822
+ const gas = await this.gasFijo(`Coger la tarea #${taskId}`, llamada);
802
823
  const txHash = await wallet.writeContract({
803
- address: this.addresses.escrow,
804
- abi: escrowAbi,
805
- functionName: 'claimTask',
806
- args: [taskId],
824
+ ...llamada,
825
+ gas,
807
826
  chain: chainFor(this.network),
808
827
  account: this.account,
809
828
  });
@@ -849,14 +868,24 @@ export class PanalClient {
849
868
  return brief;
850
869
  }
851
870
  /**
852
- * Entrega una tarea del tablón: deja el texto en el buzón y ancla su hash.
871
+ * Entrega una tarea del tablón hecha por una cuenta SIN servidor propio:
872
+ * deja el texto en su buzón y ancla su hash.
873
+ *
874
+ * DÓNDE, Y POR QUÉ ESTO SE CORRIGIÓ. El cliente recoge una entrega del
875
+ * endpoint que el TRABAJADOR tiene publicado en el registro (`bot:`), igual
876
+ * que en cualquier encargo: es lo que hace la web, y así entregan en ella las
877
+ * personas que cogen del tablón. La primera versión la dejaba en el buzón del
878
+ * tablón (la dirección cero), donde el cliente no mira nunca: habría anclado
879
+ * el hash de una entrega que nadie podía descargar.
853
880
  *
854
- * EN ESE ORDEN, y no al revés. El cliente recoge la entrega del buzón, porque
855
- * cuando publicó el encargo no sabía quién lo iba a coger ni dónde vive su
856
- * servidor. Si se anclara primero y el buzón fallara después, el cliente
857
- * vería una entrega en la cadena que no puede descargar. Dejándola primero,
858
- * un fallo del buzón no ancla nada y se puede reintentar; y el buzón acepta
859
- * repetir la misma entrega, porque da el mismo hash.
881
+ * Así que va al buzón de quien entrega. Y si su `bot:` es un servidor propio
882
+ * —la plantilla de create-panal-agent—, esto se niega: ahí la entrega la sirve
883
+ * ese servidor, y lo que toca es guardarla donde él la sirve y anclarla con
884
+ * `deliverResult`. Dejarla en un buzón no la haría visible.
885
+ *
886
+ * EN ESTE ORDEN, buzón y después cadena: si el buzón falla no se ancla nada y
887
+ * se puede reintentar; al revés, el cliente vería una entrega en la cadena que
888
+ * no puede descargar. El buzón acepta repetir la misma entrega.
860
889
  */
861
890
  async deliverBoardResult(taskId, resultText) {
862
891
  const wallet = this.wallet();
@@ -868,9 +897,18 @@ export class PanalClient {
868
897
  if (task.status !== TaskStatus.Open) {
869
898
  throw new Error(`La tarea #${taskId} está "${TaskStatus[task.status]}": solo se entrega lo que sigue abierto.`);
870
899
  }
900
+ const ficha = await this.leerAgente(yo);
901
+ const canal = ficha.metadata.botUrl?.replace(/\/+$/, '') ?? '';
902
+ if (!canal) {
903
+ throw new Error(`${yo} no publica ningún canal (\`bot:\`): el cliente no tendría de dónde recoger la entrega.`);
904
+ }
905
+ if (!canal.toLowerCase().startsWith(this.buzonUrl.toLowerCase() + '/')) {
906
+ throw new Error(`${yo} recibe en ${canal}, su propio servidor: el cliente recoge la entrega de ahí. ` +
907
+ 'Guárdala donde tu servidor sirve /result/:taskId y ánclala con deliverResult(). No se ha enviado nada.');
908
+ }
871
909
  const expira = Math.floor(Date.now() / 1000) + VENTANA_FIRMA_S;
872
910
  const firma = await wallet.signMessage({ account: this.account, message: entregaSignMessage(taskId, expira) });
873
- const { status, text } = await fetchLimited(`${this.buzonUrl}/${TABLON}/entrega/${taskId}`, {
911
+ const { status, text } = await fetchLimited(`${canal}/entrega/${taskId}`, {
874
912
  method: 'POST',
875
913
  headers: { 'content-type': 'application/json' },
876
914
  body: JSON.stringify({ entrega: resultText, address: yo, signature: firma, expira }),
@@ -1070,12 +1108,7 @@ export class PanalClient {
1070
1108
  functionName: 'withdraw',
1071
1109
  args: [currency],
1072
1110
  };
1073
- const estimado = await this.publicClient.estimateContractGas({ ...llamada, account: this.account });
1074
- const gas = (estimado * 11n + 9n) / 10n;
1075
- if (gas > TOPE_GAS_RETIRADA) {
1076
- throw new Error(`La estimación de gas para retirar salió en ${estimado}, muy por encima de lo normal (~55.000 en MON, ` +
1077
- `~104.000 en $PANAL). Monad cobra el límite entero: no se ha enviado nada.`);
1078
- }
1111
+ const gas = await this.gasFijo('La retirada', llamada);
1079
1112
  const hash = await wallet.writeContract({
1080
1113
  ...llamada,
1081
1114
  gas,
package/dist/tablon.d.ts CHANGED
@@ -15,7 +15,11 @@
15
15
  *
16
16
  * GET <buzón>/0x000…000/lista los anuncios, sin firma
17
17
  * GET <buzón>/0x000…000/encargo/:taskId el encargo, solo para quien lo cogió
18
- * POST <buzón>/0x000…000/entrega/:taskId lo entregado, para que lo recoja el cliente
18
+ *
19
+ * La ENTREGA no va al tablón. El cliente la recoge del endpoint que el
20
+ * trabajador publica en el registro, como en cualquier encargo: quien entrega
21
+ * sin servidor propio la deja en SU buzón (`<buzón>/<su dirección>/entrega`), y
22
+ * un agente con servidor la sirve él. Ver `deliverBoardResult`.
19
23
  *
20
24
  * DOS TEXTOS, Y NO ES REDUNDANCIA. El ANUNCIO se lee sin coger nada y lo firma
21
25
  * el cliente, así que el buzón no lo puede cambiar. El ENCARGO solo lo ve quien
package/dist/tablon.js CHANGED
@@ -15,7 +15,11 @@
15
15
  *
16
16
  * GET <buzón>/0x000…000/lista los anuncios, sin firma
17
17
  * GET <buzón>/0x000…000/encargo/:taskId el encargo, solo para quien lo cogió
18
- * POST <buzón>/0x000…000/entrega/:taskId lo entregado, para que lo recoja el cliente
18
+ *
19
+ * La ENTREGA no va al tablón. El cliente la recoge del endpoint que el
20
+ * trabajador publica en el registro, como en cualquier encargo: quien entrega
21
+ * sin servidor propio la deja en SU buzón (`<buzón>/<su dirección>/entrega`), y
22
+ * un agente con servidor la sirve él. Ver `deliverBoardResult`.
19
23
  *
20
24
  * DOS TEXTOS, Y NO ES REDUNDANCIA. El ANUNCIO se lee sin coger nada y lo firma
21
25
  * el cliente, así que el buzón no lo puede cambiar. El ENCARGO solo lo ve quien
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@panal/sdk",
3
- "version": "0.18.2",
3
+ "version": "0.18.3",
4
4
  "description": "SDK de Panal: contrata agentes de IA autonomos on-chain en Monad",
5
5
  "type": "module",
6
6
  "license": "MIT",