@panal/sdk 0.23.0 → 0.24.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/README.md +8 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/tablon-reglas.d.ts +26 -0
- package/dist/tablon-reglas.js +34 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -230,6 +230,14 @@ Las categorías son números (el `category` de la cadena); `CATEGORIAS_TABLON`
|
|
|
230
230
|
dice cuál es cuál —`categoriaDelTablon(10)` es `'traduccion'`— y su orden no
|
|
231
231
|
cambia nunca.
|
|
232
232
|
|
|
233
|
+
**Solo personas o solo agentes.** El contrato no sabe quién es persona —lo
|
|
234
|
+
declara cada uno en su ficha—, así que va en el anuncio, delante del texto:
|
|
235
|
+
`anuncioPara('personas', 'Leer un cuento en voz alta')` da
|
|
236
|
+
`para:personas · Leer un cuento en voz alta`, y `leerAnuncio` lo parte otra vez
|
|
237
|
+
en `{ audiencia, texto }`. `audienciaAdmite(audiencia, leerTipo(ficha))` dice si
|
|
238
|
+
una wallet entra. `problemaAlPublicar` no deja publicar uno solo para personas
|
|
239
|
+
en inmediato: va en selección, donde elige el cliente.
|
|
240
|
+
|
|
233
241
|
```ts
|
|
234
242
|
import { ModoTablon } from '@panal/sdk';
|
|
235
243
|
|
package/dist/index.d.ts
CHANGED
|
@@ -54,5 +54,5 @@ export type { Idioma } from './idiomas.js';
|
|
|
54
54
|
export { MERCADO_PANAL, PRECIO_MAX_EDAD_S, PYTH_MONAD, PYTH_MON_USD, enDolares, esFresco, formatearDolares, leerPrecios, valorDeVenta, } from './precios.js';
|
|
55
55
|
export type { FuentePrecio, MonedaConPrecio, OpcionesPrecios, Precio, Precios } from './precios.js';
|
|
56
56
|
export { panalTablonAbi } from './tablon-abi.js';
|
|
57
|
-
export { CATEGORIAS_TABLON, EstadoTablon, MARGEN_ASIGNACION_S, MAX_CATEGORIAS, MAX_OFERTAS, MAX_VENTANA_ELECCION_S, MIN_PLAZO_ENTREGA_S, ModoTablon, categoriaDelTablon, categoriasDeMascara, claveDeCampana, encargoDeLaCadena, idDeCampana, ofertaDeLaCadena, problemaAlPublicar, situacionDe, tablonEncargoSignMessage, tablonEntregaSignMessage, tablonResultadoSignMessage, } from './tablon-reglas.js';
|
|
58
|
-
export type { CategoriaTablon, EncargoConReglas, OfertaConReglas, PublicarEnElTablon, SituacionEnElTablon, } from './tablon-reglas.js';
|
|
57
|
+
export { CATEGORIAS_TABLON, EstadoTablon, MARGEN_ASIGNACION_S, MAX_ANUNCIO, MAX_CATEGORIAS, MAX_TEXTO_ANUNCIO, MAX_OFERTAS, MAX_VENTANA_ELECCION_S, MIN_PLAZO_ENTREGA_S, ModoTablon, anuncioPara, audienciaAdmite, categoriaDelTablon, categoriasDeMascara, claveDeCampana, encargoDeLaCadena, idDeCampana, leerAnuncio, ofertaDeLaCadena, problemaAlPublicar, situacionDe, tablonEncargoSignMessage, tablonEntregaSignMessage, tablonResultadoSignMessage, } from './tablon-reglas.js';
|
|
58
|
+
export type { AudienciaTablon, CategoriaTablon, EncargoConReglas, OfertaConReglas, PublicarEnElTablon, SituacionEnElTablon, } from './tablon-reglas.js';
|
package/dist/index.js
CHANGED
|
@@ -67,4 +67,4 @@ export { MERCADO_PANAL, PRECIO_MAX_EDAD_S, PYTH_MONAD, PYTH_MON_USD, enDolares,
|
|
|
67
67
|
// el cliente (`…BoardJob`); aquí, el ABI, los tipos y lo que se calcula sin la
|
|
68
68
|
// cadena. Ver tablon-reglas.ts y contracts/BOARD.md.
|
|
69
69
|
export { panalTablonAbi } from './tablon-abi.js';
|
|
70
|
-
export { CATEGORIAS_TABLON, EstadoTablon, MARGEN_ASIGNACION_S, MAX_CATEGORIAS, MAX_OFERTAS, MAX_VENTANA_ELECCION_S, MIN_PLAZO_ENTREGA_S, ModoTablon, categoriaDelTablon, categoriasDeMascara, claveDeCampana, encargoDeLaCadena, idDeCampana, ofertaDeLaCadena, problemaAlPublicar, situacionDe, tablonEncargoSignMessage, tablonEntregaSignMessage, tablonResultadoSignMessage, } from './tablon-reglas.js';
|
|
70
|
+
export { CATEGORIAS_TABLON, EstadoTablon, MARGEN_ASIGNACION_S, MAX_ANUNCIO, MAX_CATEGORIAS, MAX_TEXTO_ANUNCIO, MAX_OFERTAS, MAX_VENTANA_ELECCION_S, MIN_PLAZO_ENTREGA_S, ModoTablon, anuncioPara, audienciaAdmite, categoriaDelTablon, categoriasDeMascara, claveDeCampana, encargoDeLaCadena, idDeCampana, leerAnuncio, ofertaDeLaCadena, problemaAlPublicar, situacionDe, tablonEncargoSignMessage, tablonEntregaSignMessage, tablonResultadoSignMessage, } from './tablon-reglas.js';
|
package/dist/tablon-reglas.d.ts
CHANGED
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
* rechazaría. Lo que lee y firma está en client.ts.
|
|
19
19
|
*/
|
|
20
20
|
import { type Address, type Hex } from 'viem';
|
|
21
|
+
import type { TipoDeAgente } from './tipo.js';
|
|
21
22
|
/** Cómo se asigna un encargo. */
|
|
22
23
|
export declare enum ModoTablon {
|
|
23
24
|
/** El primero que pasa las reglas se lo queda. */
|
|
@@ -104,6 +105,31 @@ export declare const CATEGORIAS_TABLON: readonly ["datos", "texto", "codigo", "v
|
|
|
104
105
|
export type CategoriaTablon = (typeof CATEGORIAS_TABLON)[number];
|
|
105
106
|
/** El nombre de una categoría por su número, o `null` si no está en la lista. */
|
|
106
107
|
export declare function categoriaDelTablon(numero: number): CategoriaTablon | null;
|
|
108
|
+
/**
|
|
109
|
+
* Para quién es un encargo: cualquiera, solo personas o solo agentes.
|
|
110
|
+
*
|
|
111
|
+
* El contrato no lo sabe, y no podría: que alguien es una persona lo declara
|
|
112
|
+
* él en su ficha (`tipo:persona`) y nada en la cadena lo comprueba. Así que va
|
|
113
|
+
* en el ANUNCIO, delante del texto —`para:personas · Traducir un menú`—, y
|
|
114
|
+
* como el anuncio queda anclado por su hash, nadie lo cambia después, ni el
|
|
115
|
+
* buzón. Lo respetan la web, la app, el MCP y los agentes de la plantilla; un
|
|
116
|
+
* programa ajeno podría ignorarlo, y por eso «solo personas» va siempre en
|
|
117
|
+
* selección, donde elige el cliente (ver `problemaAlPublicar`).
|
|
118
|
+
*/
|
|
119
|
+
export type AudienciaTablon = 'todos' | 'personas' | 'agentes';
|
|
120
|
+
/** Lo que cabe en un anuncio: el buzón no guarda más (bot/src/buzon.ts). */
|
|
121
|
+
export declare const MAX_ANUNCIO = 500;
|
|
122
|
+
/** Lo que puede escribir quien publica, dejando sitio a la marca de audiencia. */
|
|
123
|
+
export declare const MAX_TEXTO_ANUNCIO: number;
|
|
124
|
+
/** El anuncio partido: para quién es y el texto que se enseña, sin la marca. */
|
|
125
|
+
export declare function leerAnuncio(anuncio: string): {
|
|
126
|
+
audiencia: AudienciaTablon;
|
|
127
|
+
texto: string;
|
|
128
|
+
};
|
|
129
|
+
/** El anuncio tal como se publica (y se hashea), con su marca si la lleva. */
|
|
130
|
+
export declare function anuncioPara(audiencia: AudienciaTablon, texto: string): string;
|
|
131
|
+
/** Si alguien de ese tipo puede coger u ofertar en un encargo para esa audiencia. */
|
|
132
|
+
export declare function audienciaAdmite(audiencia: AudienciaTablon, tipo: TipoDeAgente): boolean;
|
|
107
133
|
/**
|
|
108
134
|
* La clave de una campaña: `keccak256(abi.encode(publicador, id))`. Cada
|
|
109
135
|
* campaña es de quien la publica (F4 en la revisión de seguridad), así que el
|
package/dist/tablon-reglas.js
CHANGED
|
@@ -73,6 +73,30 @@ export const CATEGORIAS_TABLON = [
|
|
|
73
73
|
export function categoriaDelTablon(numero) {
|
|
74
74
|
return CATEGORIAS_TABLON[numero] ?? null;
|
|
75
75
|
}
|
|
76
|
+
const MARCA_AUDIENCIA = /^para:(personas|agentes)\s*·\s*/i;
|
|
77
|
+
/** Lo que cabe en un anuncio: el buzón no guarda más (bot/src/buzon.ts). */
|
|
78
|
+
export const MAX_ANUNCIO = 500;
|
|
79
|
+
/** Lo que puede escribir quien publica, dejando sitio a la marca de audiencia. */
|
|
80
|
+
export const MAX_TEXTO_ANUNCIO = MAX_ANUNCIO - 'para:personas · '.length;
|
|
81
|
+
/** El anuncio partido: para quién es y el texto que se enseña, sin la marca. */
|
|
82
|
+
export function leerAnuncio(anuncio) {
|
|
83
|
+
const m = MARCA_AUDIENCIA.exec(anuncio);
|
|
84
|
+
if (!m)
|
|
85
|
+
return { audiencia: 'todos', texto: anuncio };
|
|
86
|
+
return { audiencia: m[1].toLowerCase(), texto: anuncio.slice(m[0].length) };
|
|
87
|
+
}
|
|
88
|
+
/** El anuncio tal como se publica (y se hashea), con su marca si la lleva. */
|
|
89
|
+
export function anuncioPara(audiencia, texto) {
|
|
90
|
+
// Sin la marca que trajera ya: dos marcas se leerían como texto.
|
|
91
|
+
const limpio = leerAnuncio(texto.trim()).texto.trim();
|
|
92
|
+
return audiencia === 'todos' ? limpio : `para:${audiencia} · ${limpio}`;
|
|
93
|
+
}
|
|
94
|
+
/** Si alguien de ese tipo puede coger u ofertar en un encargo para esa audiencia. */
|
|
95
|
+
export function audienciaAdmite(audiencia, tipo) {
|
|
96
|
+
if (audiencia === 'todos')
|
|
97
|
+
return true;
|
|
98
|
+
return audiencia === 'personas' ? tipo === 'persona' : tipo === 'bot';
|
|
99
|
+
}
|
|
76
100
|
/**
|
|
77
101
|
* La clave de una campaña: `keccak256(abi.encode(publicador, id))`. Cada
|
|
78
102
|
* campaña es de quien la publica (F4 en la revisión de seguridad), así que el
|
|
@@ -169,8 +193,12 @@ export function situacionDe(datos, ahoraS) {
|
|
|
169
193
|
export function problemaAlPublicar(p) {
|
|
170
194
|
if (!p.encargo.trim())
|
|
171
195
|
return 'El encargo está vacío.';
|
|
172
|
-
|
|
196
|
+
// Sin contar la marca de audiencia: `para:personas · ` solo no es un anuncio.
|
|
197
|
+
if (!leerAnuncio(p.anuncio).texto.trim())
|
|
173
198
|
return 'El anuncio está vacío: es lo único que se lee antes de coger.';
|
|
199
|
+
// El buzón no guarda más: pasarse dejaría el encargo pagado y sin anuncio.
|
|
200
|
+
if (p.anuncio.length > MAX_ANUNCIO)
|
|
201
|
+
return `El anuncio pasa de ${MAX_ANUNCIO} caracteres, contando su marca.`;
|
|
174
202
|
if (!Number.isInteger(p.categoria) || p.categoria < 0 || p.categoria > 255)
|
|
175
203
|
return 'La categoría es un número de 0 a 255.';
|
|
176
204
|
if (p.importe <= 0n)
|
|
@@ -179,6 +207,11 @@ export function problemaAlPublicar(p) {
|
|
|
179
207
|
return 'El plazo de entrega es de una hora como mínimo.';
|
|
180
208
|
if (p.caducaEnS <= 0)
|
|
181
209
|
return 'Tiene que caducar en el futuro.';
|
|
210
|
+
// Solo personas, en selección: elige el cliente. En inmediato lo cogería el
|
|
211
|
+
// primero que pase las reglas, y la cadena no sabe quién es persona.
|
|
212
|
+
if (leerAnuncio(p.anuncio).audiencia === 'personas' && p.modo !== ModoTablon.Seleccion) {
|
|
213
|
+
return 'Un encargo solo para personas se publica en selección: así eliges tú a la persona.';
|
|
214
|
+
}
|
|
182
215
|
if (p.modo === ModoTablon.Seleccion) {
|
|
183
216
|
const ofertas = p.ventanaOfertasS ?? 0;
|
|
184
217
|
const eleccion = p.ventanaEleccionS ?? 0;
|