@ouronet/talos-registry 2.1.0 → 2.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/README.md +2 -2
- package/TOOLTIP-CANON.md +75 -0
- package/dist/data/registry.json +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/tooltip.d.ts +35 -0
- package/dist/tooltip.js +80 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -16,6 +16,6 @@ export type { CallPlan } from "./plan.js";
|
|
|
16
16
|
export { parseCapability, parseCapabilities, capabilityRecipe } from "./caps.js";
|
|
17
17
|
export type { ParsedCapability, CapabilityRecipe } from "./caps.js";
|
|
18
18
|
export { formatForType, formatDecimal, formatInteger, formatString, formatBool } from "./format.js";
|
|
19
|
-
export { tooltipModel, tooltipModels, signatureRows, chainOf, isOffRegistryKey, isNativeKey, isPlaceholder, PLACEHOLDER, CHAIN_PALETTE, CHAIN_LABEL, CONSUMERS, STOA_SIGNATURES, KADENA_SIGNATURES, NATIVE_SIGNATURES } from "./tooltip.js";
|
|
20
|
-
export type { TooltipModel, TooltipSlot, TooltipPreview, Chain, ConsumerIdentity } from "./tooltip.js";
|
|
19
|
+
export { tooltipModel, tooltipModels, signatureRows, chainOf, isOffRegistryKey, isNativeKey, isPlaceholder, PLACEHOLDER, CHAIN_PALETTE, CHAIN_LABEL, CONSUMERS, STOA_SIGNATURES, KADENA_SIGNATURES, NATIVE_SIGNATURES, paramRole, paramsByRole, unfilledFillable } from "./tooltip.js";
|
|
20
|
+
export type { TooltipModel, TooltipSlot, TooltipPreview, Chain, ConsumerIdentity, ParamRole } from "./tooltip.js";
|
|
21
21
|
export type * from "./types.js";
|
package/dist/index.js
CHANGED
|
@@ -15,4 +15,4 @@ export { parseCapability, parseCapabilities, capabilityRecipe } from "./caps.js"
|
|
|
15
15
|
export { formatForType, formatDecimal, formatInteger, formatString, formatBool } from "./format.js";
|
|
16
16
|
// THE TOOLTIP CANON. Shared implementation rather than a shared document -- see TOOLTIP-CANON.md
|
|
17
17
|
// for why each rule exists, and `tooltip.ts` for the rules themselves.
|
|
18
|
-
export { tooltipModel, tooltipModels, signatureRows, chainOf, isOffRegistryKey, isNativeKey, isPlaceholder, PLACEHOLDER, CHAIN_PALETTE, CHAIN_LABEL, CONSUMERS, STOA_SIGNATURES, KADENA_SIGNATURES, NATIVE_SIGNATURES } from "./tooltip.js";
|
|
18
|
+
export { tooltipModel, tooltipModels, signatureRows, chainOf, isOffRegistryKey, isNativeKey, isPlaceholder, PLACEHOLDER, CHAIN_PALETTE, CHAIN_LABEL, CONSUMERS, STOA_SIGNATURES, KADENA_SIGNATURES, NATIVE_SIGNATURES, paramRole, paramsByRole, unfilledFillable } from "./tooltip.js";
|
package/dist/tooltip.d.ts
CHANGED
|
@@ -51,6 +51,14 @@ export interface TooltipSlot {
|
|
|
51
51
|
isPreflightFed: boolean;
|
|
52
52
|
/** false = never prefill into an input that can reach a signed transaction (guards). */
|
|
53
53
|
prefillable: boolean;
|
|
54
|
+
/**
|
|
55
|
+
* The CALLER supplied this value; it is not a ghost.
|
|
56
|
+
*
|
|
57
|
+
* Tracked in the model rather than left to each renderer, because "is this the user's data or
|
|
58
|
+
* an example?" is the question every one of this module's bugs turned on, and two consumers
|
|
59
|
+
* answering it separately is two chances to answer it differently.
|
|
60
|
+
*/
|
|
61
|
+
supplied: boolean;
|
|
54
62
|
/** the registry's own note about this argument, when it has one. */
|
|
55
63
|
note?: string;
|
|
56
64
|
}
|
|
@@ -171,3 +179,30 @@ export declare function signatureRows(m: TooltipModel): {
|
|
|
171
179
|
names: string[];
|
|
172
180
|
types: string[];
|
|
173
181
|
};
|
|
182
|
+
/**
|
|
183
|
+
* What KIND of thing a parameter holds.
|
|
184
|
+
*
|
|
185
|
+
* Pact types cannot answer this -- `patron`, `id`, `ats` and `swpair` are all `string`, and a
|
|
186
|
+
* value of the wrong kind in any of them type-checks, renders plausibly, and makes the preview
|
|
187
|
+
* succeed against the wrong entity. That is the defect class this whole module exists to prevent,
|
|
188
|
+
* and it has now produced four separate bugs.
|
|
189
|
+
*/
|
|
190
|
+
export type ParamRole = "ouronet-account" | "kadena-account" | "token-id" | "dpof-id" | "ats-pool" | "swap-pool" | "other";
|
|
191
|
+
/** The role of a parameter name, or undefined when nothing is known about it. */
|
|
192
|
+
export declare function paramRole(name: string): ParamRole | undefined;
|
|
193
|
+
/** Every name this registry can classify, grouped. Useful for building a consumer's fill map. */
|
|
194
|
+
export declare function paramsByRole(): Record<ParamRole, string[]>;
|
|
195
|
+
/**
|
|
196
|
+
* RULE 7, as a check: which slots the consumer COULD have filled and did not.
|
|
197
|
+
*
|
|
198
|
+
* A slot qualifies when its role is known and the caller supplied no value for it. Those are the
|
|
199
|
+
* ones that silently show somebody else's real id -- `ats = "Auryndex-…"` on a SilverStoa button,
|
|
200
|
+
* an example account whose pool ledger is empty, a reward token rendered as "no live example".
|
|
201
|
+
*
|
|
202
|
+
* Placeholders and preflight-fed slots are NOT reported: the first is honestly unresolved and the
|
|
203
|
+
* second must not be invented. This answers "what did you leave on the table", not "what is
|
|
204
|
+
* missing".
|
|
205
|
+
*
|
|
206
|
+
* A conformant consumer asserts this is empty for every button it renders.
|
|
207
|
+
*/
|
|
208
|
+
export declare function unfilledFillable(m: TooltipModel): TooltipSlot[];
|
package/dist/tooltip.js
CHANGED
|
@@ -185,6 +185,7 @@ function offRegistryModel(key, kind, values, consumer) {
|
|
|
185
185
|
isPreflightFed: false,
|
|
186
186
|
// A guard is never prefillable, on any chain. Same rule, same reason.
|
|
187
187
|
prefillable: type !== "guard",
|
|
188
|
+
supplied: values[name] !== undefined,
|
|
188
189
|
})),
|
|
189
190
|
// No preview, deliberately. Neither chain's `coin` has a reader that prices a call, so there
|
|
190
191
|
// is no cost to show -- and a renderer must SAY that rather than leaving an empty panel,
|
|
@@ -257,6 +258,7 @@ export function tooltipModel(key, values = {}, consumer) {
|
|
|
257
258
|
isPlaceholder,
|
|
258
259
|
isPreflightFed,
|
|
259
260
|
prefillable: u?.zbom !== false,
|
|
261
|
+
supplied: supplied !== undefined,
|
|
260
262
|
note: ep.ghost.notes?.[p.name],
|
|
261
263
|
};
|
|
262
264
|
});
|
|
@@ -325,3 +327,81 @@ export function tooltipModels(keys, values = {}, consumer) {
|
|
|
325
327
|
export function signatureRows(m) {
|
|
326
328
|
return { names: m.slots.map((s) => s.name), types: m.slots.map((s) => s.type) };
|
|
327
329
|
}
|
|
330
|
+
/**
|
|
331
|
+
* DERIVED FROM THE GHOST'S SHAPE, not from a hand-written list of 332 names.
|
|
332
|
+
*
|
|
333
|
+
* Hand-classifying the vocabulary would be the same act that produced the bugs: a human deciding
|
|
334
|
+
* that `ats` looks like a token because both are strings. The registry's ghosts were each resolved
|
|
335
|
+
* for their own parameter and READ FROM MAINNET, so the value's shape is evidence rather than
|
|
336
|
+
* opinion -- an Ouronet account is a glyph string, a pool is `Name-O136CBn22ncY`, a swap pair
|
|
337
|
+
* starts `W|`, a hibernated DPOF starts `H|`.
|
|
338
|
+
*
|
|
339
|
+
* A name whose ghost is the generic `"example"` gets NO role, and that is correct: nothing is
|
|
340
|
+
* known about it, so nothing should be inferred. Those render as visible placeholders.
|
|
341
|
+
*/
|
|
342
|
+
const ROLE_PATTERNS = [
|
|
343
|
+
[/^k:/, "kadena-account"],
|
|
344
|
+
[/^[^\u0000-\u007F]\./, "ouronet-account"],
|
|
345
|
+
[/^W\|/, "swap-pool"],
|
|
346
|
+
[/^H\|/, "dpof-id"],
|
|
347
|
+
[/^[A-Za-z]+-O136CBn22ncY$/, "ats-pool"],
|
|
348
|
+
[/^[A-Z0-9]+-[A-Za-z0-9]{3}-[A-Za-z0-9]+$/, "token-id"],
|
|
349
|
+
];
|
|
350
|
+
let ROLES = null;
|
|
351
|
+
function buildRoles() {
|
|
352
|
+
const out = new Map();
|
|
353
|
+
const reg = registry;
|
|
354
|
+
for (const coll of [reg.entrypoints, reg.previews]) {
|
|
355
|
+
for (const v of Object.values(coll)) {
|
|
356
|
+
const args = v?.ghost?.args ?? {};
|
|
357
|
+
for (const p of v?.params ?? []) {
|
|
358
|
+
if (p.type !== "string" || out.has(p.name))
|
|
359
|
+
continue;
|
|
360
|
+
const g = args[p.name];
|
|
361
|
+
if (typeof g !== "string" || g === "example")
|
|
362
|
+
continue;
|
|
363
|
+
for (const [re, role] of ROLE_PATTERNS)
|
|
364
|
+
if (re.test(g)) {
|
|
365
|
+
out.set(p.name, role);
|
|
366
|
+
break;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
return out;
|
|
372
|
+
}
|
|
373
|
+
/** The role of a parameter name, or undefined when nothing is known about it. */
|
|
374
|
+
export function paramRole(name) {
|
|
375
|
+
if (!ROLES)
|
|
376
|
+
ROLES = buildRoles();
|
|
377
|
+
return ROLES.get(name);
|
|
378
|
+
}
|
|
379
|
+
/** Every name this registry can classify, grouped. Useful for building a consumer's fill map. */
|
|
380
|
+
export function paramsByRole() {
|
|
381
|
+
if (!ROLES)
|
|
382
|
+
ROLES = buildRoles();
|
|
383
|
+
const out = {};
|
|
384
|
+
for (const [n, r] of ROLES)
|
|
385
|
+
(out[r] ??= []).push(n);
|
|
386
|
+
for (const k of Object.keys(out))
|
|
387
|
+
out[k].sort();
|
|
388
|
+
return out;
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* RULE 7, as a check: which slots the consumer COULD have filled and did not.
|
|
392
|
+
*
|
|
393
|
+
* A slot qualifies when its role is known and the caller supplied no value for it. Those are the
|
|
394
|
+
* ones that silently show somebody else's real id -- `ats = "Auryndex-…"` on a SilverStoa button,
|
|
395
|
+
* an example account whose pool ledger is empty, a reward token rendered as "no live example".
|
|
396
|
+
*
|
|
397
|
+
* Placeholders and preflight-fed slots are NOT reported: the first is honestly unresolved and the
|
|
398
|
+
* second must not be invented. This answers "what did you leave on the table", not "what is
|
|
399
|
+
* missing".
|
|
400
|
+
*
|
|
401
|
+
* A conformant consumer asserts this is empty for every button it renders.
|
|
402
|
+
*/
|
|
403
|
+
export function unfilledFillable(m) {
|
|
404
|
+
return m.slots.filter((s) => !s.supplied
|
|
405
|
+
&& !s.isPlaceholder && !s.isPreflightFed
|
|
406
|
+
&& paramRole(s.name) !== undefined);
|
|
407
|
+
}
|
package/package.json
CHANGED