@tollbooth-dpyc/web 1.1.0 → 1.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/client.d.ts +8 -0
- package/dist/client.js +3 -0
- package/dist/debugLog.js +5 -2
- package/dist/inlineProof.d.ts +8 -0
- package/dist/inlineProof.js +15 -1
- package/dist/react/useSession.d.ts +2 -0
- package/dist/react/useSession.js +2 -1
- package/dist/standardTools.d.ts +215 -9
- package/dist/standardTools.js +46 -4
- package/package.json +1 -1
package/dist/client.d.ts
CHANGED
|
@@ -28,6 +28,14 @@ export interface CallOptions {
|
|
|
28
28
|
* patron out, whatever it gets back.
|
|
29
29
|
*/
|
|
30
30
|
bestEffort?: boolean;
|
|
31
|
+
/**
|
|
32
|
+
* A background read — a badge, a poll — that must not send the patron to
|
|
33
|
+
* the sign-in gate. A proof bounce still throws `ProofRequiredError`, but
|
|
34
|
+
* the session is left as it is and `onProofExpired` is not told; the next
|
|
35
|
+
* call the patron makes themselves meets the lapse and re-arms sign-in.
|
|
36
|
+
* Opt-in: by default a bounce signs the patron out and re-arms the gate.
|
|
37
|
+
*/
|
|
38
|
+
quietProof?: boolean;
|
|
31
39
|
timeoutMs?: number;
|
|
32
40
|
}
|
|
33
41
|
export interface ToolAnswer<T> {
|
package/dist/client.js
CHANGED
|
@@ -31,6 +31,7 @@ const STANDARD_BOOTSTRAP = [
|
|
|
31
31
|
"publish_nostr_profile",
|
|
32
32
|
"get_operator_onboarding_status",
|
|
33
33
|
"check_authority_balance",
|
|
34
|
+
"get_pricing_model",
|
|
34
35
|
"list_canonical_identities",
|
|
35
36
|
"check_proof_status",
|
|
36
37
|
"get_patron_onboarding_status",
|
|
@@ -165,6 +166,8 @@ export async function callToolWithContent(tool, args = {}, opts = {}) {
|
|
|
165
166
|
if (!opts.bestEffort) {
|
|
166
167
|
const bounced = proofBounceMessage(payload);
|
|
167
168
|
if (bounced !== null) {
|
|
169
|
+
if (opts.quietProof)
|
|
170
|
+
throw new ProofRequiredError(bounced);
|
|
168
171
|
// The token just refused is the same one the recent-login shortcut
|
|
169
172
|
// would replay, so it goes too, or a returning patron re-bounces.
|
|
170
173
|
const npub = getStoredNpub();
|
package/dist/debugLog.js
CHANGED
|
@@ -28,9 +28,12 @@ const REDACTED = "[redacted]";
|
|
|
28
28
|
const SECRET_FIELD = "(?:nsec|ncryptsec|dpop_token|proof|poison|password|passphrase|secret|token|authorization|api_?key|private_?key|client_secret|[a-z0-9_]*_(?:nsec|token|secret|password|passphrase|api_?key|private_?key))";
|
|
29
29
|
// `"dpop_token":"…"`, `\"dpop_token\":\"…\"` (JSON inside a JSON string),
|
|
30
30
|
// `dpop_token=…` (a query string) and `dpop_token: '…'` (a Python repr). A
|
|
31
|
-
// quoted value is taken whole
|
|
31
|
+
// quoted value is taken whole — spaces, escaped quotes and the other kind of
|
|
32
|
+
// quote included — up to its own closing quote or the end of a truncated line;
|
|
33
|
+
// a bare one up to a delimiter. Stopping at the first quote of either kind let
|
|
34
|
+
// the tail of a secret holding `'` or `\"` through.
|
|
32
35
|
function fieldValue(names) {
|
|
33
|
-
return new RegExp(`((?:\\\\*["'])?\\b${names}(?:\\\\*["'])?\\s*[:=]\\s*)(?:(\\\\*["'])[
|
|
36
|
+
return new RegExp(`((?:\\\\*["'])?\\b${names}(?:\\\\*["'])?\\s*[:=]\\s*)(?:(\\\\*["'])(?:\\\\.|\\\\$|(?!\\2)[^\\\\])*?(?=\\2|$)|[^"'\\\\,}\\]&\\s]+)`, "gi");
|
|
34
37
|
}
|
|
35
38
|
const FIELD_VALUE = fieldValue(SECRET_FIELD);
|
|
36
39
|
// update_patron_credential / update_operator_credential carry the secret as
|
package/dist/inlineProof.d.ts
CHANGED
|
@@ -5,6 +5,14 @@
|
|
|
5
5
|
* runtime tool name, e.g. "chart_snapshot_display"), and `created_at` (within
|
|
6
6
|
* about 60 seconds of server time). The wheel verifies the Schnorr signature
|
|
7
7
|
* inline — no relay round trip, no cached phrase.
|
|
8
|
+
*
|
|
9
|
+
* Every proof also carries a random `nonce` tag, exactly as the wheel's own
|
|
10
|
+
* `create_proof` does. Without it, two calls to the same tool in the same
|
|
11
|
+
* wall-clock second sign byte-identical events, their ids collide, and the
|
|
12
|
+
* verifier's replay guard refuses the second. The nonce is signed but inert:
|
|
13
|
+
* `verify_proof` reads only the `u` tag.
|
|
8
14
|
*/
|
|
15
|
+
/** 16 random bytes as 32 lowercase hex chars — Python's `secrets.token_hex(16)`. */
|
|
16
|
+
export declare function proofNonce(): string;
|
|
9
17
|
/** The JSON-stringified signed event, exactly what `verify_proof` expects. */
|
|
10
18
|
export declare function signInlineProof(runtimeToolName: string, secretKey?: Uint8Array): string;
|
package/dist/inlineProof.js
CHANGED
|
@@ -5,16 +5,30 @@
|
|
|
5
5
|
* runtime tool name, e.g. "chart_snapshot_display"), and `created_at` (within
|
|
6
6
|
* about 60 seconds of server time). The wheel verifies the Schnorr signature
|
|
7
7
|
* inline — no relay round trip, no cached phrase.
|
|
8
|
+
*
|
|
9
|
+
* Every proof also carries a random `nonce` tag, exactly as the wheel's own
|
|
10
|
+
* `create_proof` does. Without it, two calls to the same tool in the same
|
|
11
|
+
* wall-clock second sign byte-identical events, their ids collide, and the
|
|
12
|
+
* verifier's replay guard refuses the second. The nonce is signed but inert:
|
|
13
|
+
* `verify_proof` reads only the `u` tag.
|
|
8
14
|
*/
|
|
9
15
|
import { finalizeEvent } from "nostr-tools";
|
|
10
16
|
import { getSessionNsecBytes } from "./sessionNsec.js";
|
|
11
17
|
const PROOF_KIND = 27235;
|
|
18
|
+
/** 16 random bytes as 32 lowercase hex chars — Python's `secrets.token_hex(16)`. */
|
|
19
|
+
export function proofNonce() {
|
|
20
|
+
const bytes = crypto.getRandomValues(new Uint8Array(16));
|
|
21
|
+
return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
|
|
22
|
+
}
|
|
12
23
|
/** The JSON-stringified signed event, exactly what `verify_proof` expects. */
|
|
13
24
|
export function signInlineProof(runtimeToolName, secretKey) {
|
|
14
25
|
const signed = finalizeEvent({
|
|
15
26
|
kind: PROOF_KIND,
|
|
16
27
|
created_at: Math.floor(Date.now() / 1000),
|
|
17
|
-
tags: [
|
|
28
|
+
tags: [
|
|
29
|
+
["u", runtimeToolName],
|
|
30
|
+
["nonce", proofNonce()],
|
|
31
|
+
],
|
|
18
32
|
content: "",
|
|
19
33
|
}, secretKey ?? getSessionNsecBytes());
|
|
20
34
|
return JSON.stringify(signed);
|
|
@@ -12,6 +12,8 @@ export interface Session {
|
|
|
12
12
|
canSign: boolean;
|
|
13
13
|
/** Set when a cached proof lapses: a calm prompt to sign in again. */
|
|
14
14
|
notice: string;
|
|
15
|
+
/** Clear the notice without signing in — the patron read it and moved on. */
|
|
16
|
+
dismissNotice: () => void;
|
|
15
17
|
/** Call after a successful sign-in so the whole app notices. */
|
|
16
18
|
refresh: () => void;
|
|
17
19
|
signOut: () => void;
|
package/dist/react/useSession.js
CHANGED
|
@@ -28,6 +28,7 @@ export function useSession() {
|
|
|
28
28
|
setState(read());
|
|
29
29
|
setNotice("");
|
|
30
30
|
}, []);
|
|
31
|
+
const dismissNotice = useCallback(() => setNotice(""), []);
|
|
31
32
|
useEffect(() => onProofExpired(() => {
|
|
32
33
|
// A tab that can sign for THIS npub lost nothing.
|
|
33
34
|
if (canSignFor(currentClaim()))
|
|
@@ -35,5 +36,5 @@ export function useSession() {
|
|
|
35
36
|
setNotice("Your session lapsed while you were away. Sign in again to carry on.");
|
|
36
37
|
setState(read());
|
|
37
38
|
}), []);
|
|
38
|
-
return { ...state, notice, refresh, signOut };
|
|
39
|
+
return { ...state, notice, dismissNotice, refresh, signOut };
|
|
39
40
|
}
|
package/dist/standardTools.d.ts
CHANGED
|
@@ -2,14 +2,45 @@
|
|
|
2
2
|
* Typed wrappers for the tools every operator gets from
|
|
3
3
|
* `register_standard_tools` in the tollbooth-dpyc wheel.
|
|
4
4
|
*/
|
|
5
|
+
/** What a patron must supply beyond the npub proof, per the wheel's `patron_auth_block`. */
|
|
6
|
+
export interface PatronAuth {
|
|
7
|
+
mode: "oauth" | "secure_courier" | "none";
|
|
8
|
+
patron_credentials_required: boolean;
|
|
9
|
+
/** mode "oauth": the provider's credential service. */
|
|
10
|
+
oauth_service?: string;
|
|
11
|
+
/** mode "secure_courier": the service a patron delivers secrets to. */
|
|
12
|
+
credential_service?: string;
|
|
13
|
+
}
|
|
14
|
+
/** The wheel's `service_status`: health and build facts, free and unauthenticated. */
|
|
5
15
|
export interface ServiceStatus {
|
|
16
|
+
success?: boolean;
|
|
17
|
+
service?: string;
|
|
18
|
+
slug?: string;
|
|
19
|
+
version?: string;
|
|
20
|
+
tollbooth_dpyc_version?: string;
|
|
21
|
+
vault_configured?: boolean;
|
|
22
|
+
courier_has_vault?: boolean;
|
|
6
23
|
operator_npub_hash?: string;
|
|
24
|
+
process_id?: number;
|
|
25
|
+
/** Deploy metadata from the environment (commit, build time, …), lower-cased keys. */
|
|
26
|
+
build_info?: Record<string, string> | null;
|
|
27
|
+
patron_auth?: PatronAuth;
|
|
28
|
+
/** Only on a server that runs background jobs. */
|
|
29
|
+
async_jobs?: {
|
|
30
|
+
docket_url_set: boolean;
|
|
31
|
+
backend: string;
|
|
32
|
+
durable_across_recycles: boolean;
|
|
33
|
+
};
|
|
34
|
+
durable_jobs?: {
|
|
35
|
+
modal_app: string | null;
|
|
36
|
+
detached_executor_active: boolean;
|
|
37
|
+
detached_executor_resolved: boolean;
|
|
38
|
+
detached_executor_error: string | null;
|
|
39
|
+
last_dispatch_error: string | null;
|
|
40
|
+
dispatching: boolean;
|
|
41
|
+
};
|
|
7
42
|
lifecycle?: string;
|
|
8
43
|
message?: string;
|
|
9
|
-
version?: string;
|
|
10
|
-
tollbooth_dpyc_version?: string;
|
|
11
|
-
service?: string;
|
|
12
|
-
slug?: string;
|
|
13
44
|
}
|
|
14
45
|
export declare function serviceStatus(): Promise<ServiceStatus>;
|
|
15
46
|
export interface NpubProofResult {
|
|
@@ -75,24 +106,49 @@ export interface CheckBalanceResult {
|
|
|
75
106
|
calls: number;
|
|
76
107
|
api_sats: number;
|
|
77
108
|
}>;
|
|
109
|
+
invoice_summary?: {
|
|
110
|
+
total_invoices: number;
|
|
111
|
+
settled_count: number;
|
|
112
|
+
pending_count: number;
|
|
113
|
+
total_real_sats: number;
|
|
114
|
+
total_api_sats_credited: number;
|
|
115
|
+
};
|
|
78
116
|
error?: string;
|
|
79
117
|
error_code?: string;
|
|
80
118
|
}
|
|
81
119
|
export declare function checkBalance(): Promise<CheckBalanceResult>;
|
|
120
|
+
export interface ConstraintEffect {
|
|
121
|
+
type: string;
|
|
122
|
+
message?: string;
|
|
123
|
+
[key: string]: unknown;
|
|
124
|
+
}
|
|
125
|
+
/** The wheel's `check_price` preview. */
|
|
82
126
|
export interface CheckPriceResult {
|
|
83
127
|
success: boolean;
|
|
84
128
|
tool_id?: string;
|
|
85
|
-
|
|
86
|
-
|
|
129
|
+
tool_name?: string;
|
|
130
|
+
/** "flat" | "flat+multipliers" | "percent" */
|
|
131
|
+
pricing_type?: string;
|
|
132
|
+
base_cost_api_sats?: number | null;
|
|
133
|
+
effective_cost_api_sats?: number | null;
|
|
134
|
+
rate_percent?: number;
|
|
135
|
+
rate_param?: string;
|
|
136
|
+
min_cost_sats?: number;
|
|
137
|
+
multipliers?: Record<string, unknown>;
|
|
138
|
+
constraints_enabled?: boolean;
|
|
139
|
+
constraint_effects?: ConstraintEffect[];
|
|
140
|
+
hint?: string;
|
|
87
141
|
error?: string;
|
|
88
142
|
error_code?: string;
|
|
89
143
|
}
|
|
90
144
|
/**
|
|
91
145
|
* The fare for one tool in api_sats, as the live pricing model resolves it,
|
|
92
|
-
* constraints included — keyed by the tool's frozen UUID
|
|
93
|
-
*
|
|
146
|
+
* constraints included — keyed by the tool's frozen UUID (or its capability
|
|
147
|
+
* name). `toolKwargs` are the call's own parameters, for a tool priced by
|
|
148
|
+
* them (ad valorem, or a multiplier on a categorical argument). Null when
|
|
149
|
+
* unreadable: show the answer without a price rather than invent one.
|
|
94
150
|
*/
|
|
95
|
-
export declare function checkPrice(toolId: string): Promise<number | null>;
|
|
151
|
+
export declare function checkPrice(toolId: string, toolKwargs?: Record<string, unknown>): Promise<number | null>;
|
|
96
152
|
export interface PurchaseCreditsResult {
|
|
97
153
|
success?: boolean;
|
|
98
154
|
invoice_id?: string;
|
|
@@ -112,6 +168,10 @@ export interface CheckPaymentResult {
|
|
|
112
168
|
invoice_id?: string;
|
|
113
169
|
credits_granted?: number;
|
|
114
170
|
balance_api_sats?: number;
|
|
171
|
+
amount_sats?: number;
|
|
172
|
+
/** false: the credit could not be written; nothing was granted. */
|
|
173
|
+
persisted?: boolean;
|
|
174
|
+
source?: string;
|
|
115
175
|
error?: string;
|
|
116
176
|
error_code?: string;
|
|
117
177
|
}
|
|
@@ -235,3 +295,149 @@ export interface PublishNostrProfileResult {
|
|
|
235
295
|
}
|
|
236
296
|
/** Relay a kind-0 the BROWSER signed. The wheel verifies it and fans it out. */
|
|
237
297
|
export declare function publishNostrProfile(npub: string, signedEvent: string): Promise<PublishNostrProfileResult>;
|
|
298
|
+
/** Every lifecycle `session_status` reports. */
|
|
299
|
+
export type SessionLifecycle = "ready" | "warming_up" | "misconfigured" | "quota_exceeded" | "not_registered" | "no_identity";
|
|
300
|
+
/** The patron's stored upstream OAuth token, when the operator has a provider. */
|
|
301
|
+
export interface UpstreamOAuth {
|
|
302
|
+
service: string;
|
|
303
|
+
has_access_token: boolean;
|
|
304
|
+
has_refresh_token: boolean;
|
|
305
|
+
refresh_enabled: boolean;
|
|
306
|
+
access_token_expires_at?: number;
|
|
307
|
+
access_token_expires_in_seconds?: number;
|
|
308
|
+
}
|
|
309
|
+
export interface SessionStatusResult {
|
|
310
|
+
success?: boolean;
|
|
311
|
+
lifecycle?: SessionLifecycle;
|
|
312
|
+
message?: string;
|
|
313
|
+
operator_npub?: string;
|
|
314
|
+
/** Why it is not ready, from the failing layer. */
|
|
315
|
+
detail?: string;
|
|
316
|
+
operator_credential_service?: string;
|
|
317
|
+
patron_credential_service?: string;
|
|
318
|
+
upstream_oauth?: UpstreamOAuth;
|
|
319
|
+
/** The vault could not answer — not the same as "never authorized". */
|
|
320
|
+
upstream_oauth_unreadable?: string;
|
|
321
|
+
error?: string;
|
|
322
|
+
error_code?: string;
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Is the operator ready to serve? Free, no proof. With `patronNpub`, also the
|
|
326
|
+
* patron's upstream OAuth token expiry, so a page can refresh ahead of time.
|
|
327
|
+
*/
|
|
328
|
+
export declare function sessionStatus(patronNpub?: string): Promise<SessionStatusResult>;
|
|
329
|
+
export interface OnboardingItem {
|
|
330
|
+
field: string;
|
|
331
|
+
/** "identity" | "authority" | "secret" */
|
|
332
|
+
category: string;
|
|
333
|
+
/** "configured" | "missing" | "unknown" */
|
|
334
|
+
status: string;
|
|
335
|
+
how?: string;
|
|
336
|
+
lifecycle?: string;
|
|
337
|
+
delivered_at?: string | null;
|
|
338
|
+
}
|
|
339
|
+
/** The wheel's `get_operator_onboarding_status`: what the operator still has to set up. */
|
|
340
|
+
export interface OperatorOnboardingStatus {
|
|
341
|
+
ready?: boolean;
|
|
342
|
+
configured?: OnboardingItem[];
|
|
343
|
+
missing?: OnboardingItem[];
|
|
344
|
+
optional_missing?: OnboardingItem[];
|
|
345
|
+
summary?: string;
|
|
346
|
+
bootstrap_error?: string;
|
|
347
|
+
vault_ok?: boolean;
|
|
348
|
+
/** Set when the credential vault could not be read: nothing is known either way. */
|
|
349
|
+
vault_situation?: string;
|
|
350
|
+
credential_greeting?: string | null;
|
|
351
|
+
credential_service?: string | null;
|
|
352
|
+
operator_name?: string;
|
|
353
|
+
error?: string;
|
|
354
|
+
error_code?: string;
|
|
355
|
+
}
|
|
356
|
+
export declare function getOperatorOnboardingStatus(): Promise<OperatorOnboardingStatus>;
|
|
357
|
+
/**
|
|
358
|
+
* The operator's own balance at its Authority — what certifies patron top-ups.
|
|
359
|
+
* The Authority's ledger, in the same shape as a patron's `check_balance`.
|
|
360
|
+
*/
|
|
361
|
+
export declare function checkAuthorityBalance(): Promise<CheckBalanceResult>;
|
|
362
|
+
export interface PricingStep {
|
|
363
|
+
id: string;
|
|
364
|
+
type: string;
|
|
365
|
+
params?: Record<string, unknown>;
|
|
366
|
+
patron_npubs?: string[];
|
|
367
|
+
}
|
|
368
|
+
export interface ToolPrice {
|
|
369
|
+
tool_id: string;
|
|
370
|
+
tool_name: string;
|
|
371
|
+
price_sats: number;
|
|
372
|
+
category: string;
|
|
373
|
+
intent: string;
|
|
374
|
+
priced: boolean;
|
|
375
|
+
price_type?: string;
|
|
376
|
+
price_formula?: unknown;
|
|
377
|
+
min_cost?: number;
|
|
378
|
+
max_cost?: number;
|
|
379
|
+
multipliers?: Record<string, unknown>;
|
|
380
|
+
chain?: PricingStep[];
|
|
381
|
+
}
|
|
382
|
+
/** The wheel's `get_pricing_model`. `status` is "ok" or "error". */
|
|
383
|
+
export interface PricingModelResult {
|
|
384
|
+
status?: string;
|
|
385
|
+
model_id?: string | null;
|
|
386
|
+
name?: string | null;
|
|
387
|
+
is_active?: boolean | null;
|
|
388
|
+
tools?: ToolPrice[] | null;
|
|
389
|
+
tranche_lifetime?: {
|
|
390
|
+
target_usage_pct: number;
|
|
391
|
+
ttl_days?: number;
|
|
392
|
+
min_days?: number;
|
|
393
|
+
max_days?: number;
|
|
394
|
+
};
|
|
395
|
+
error?: string;
|
|
396
|
+
}
|
|
397
|
+
/** The operator's active pricing model. Free, no proof. */
|
|
398
|
+
export declare function getPricingModel(): Promise<PricingModelResult>;
|
|
399
|
+
export interface CanonicalIdentity {
|
|
400
|
+
tool_id: string;
|
|
401
|
+
mcp_name: string;
|
|
402
|
+
category: string;
|
|
403
|
+
intent: string;
|
|
404
|
+
capability: string;
|
|
405
|
+
registered: boolean;
|
|
406
|
+
reason?: string;
|
|
407
|
+
}
|
|
408
|
+
/** The wheel's `list_canonical_identities`: every tool's frozen UUID and wire name. */
|
|
409
|
+
export interface CanonicalIdentitiesResult {
|
|
410
|
+
success?: boolean;
|
|
411
|
+
operator_npub?: string;
|
|
412
|
+
count?: number;
|
|
413
|
+
unregistered_count?: number;
|
|
414
|
+
tools?: CanonicalIdentity[];
|
|
415
|
+
unregistered?: Array<{
|
|
416
|
+
mcp_name: string;
|
|
417
|
+
reason: string;
|
|
418
|
+
[key: string]: unknown;
|
|
419
|
+
}>;
|
|
420
|
+
error?: string;
|
|
421
|
+
}
|
|
422
|
+
export declare function listCanonicalIdentities(): Promise<CanonicalIdentitiesResult>;
|
|
423
|
+
export interface PatronCredentialFieldsResult {
|
|
424
|
+
success?: boolean;
|
|
425
|
+
fields?: string[];
|
|
426
|
+
/** Per field, when it was delivered; null for secrets vaulted before stamps. */
|
|
427
|
+
delivered_at?: Record<string, string | null>;
|
|
428
|
+
count?: number;
|
|
429
|
+
error?: string;
|
|
430
|
+
error_code?: string;
|
|
431
|
+
}
|
|
432
|
+
export interface PatronCredentialWriteResult {
|
|
433
|
+
success?: boolean;
|
|
434
|
+
message?: string;
|
|
435
|
+
error?: string;
|
|
436
|
+
error_code?: string;
|
|
437
|
+
}
|
|
438
|
+
/** The names of the patron's stored credential fields — never their values. */
|
|
439
|
+
export declare function getPatronCredentialFields(): Promise<PatronCredentialFieldsResult>;
|
|
440
|
+
/** Set one credential field, leaving the others as they are. */
|
|
441
|
+
export declare function updatePatronCredential(field: string, value: string): Promise<PatronCredentialWriteResult>;
|
|
442
|
+
/** Remove one credential field, leaving the others as they are. */
|
|
443
|
+
export declare function deletePatronCredential(field: string): Promise<PatronCredentialWriteResult>;
|
package/dist/standardTools.js
CHANGED
|
@@ -39,11 +39,16 @@ export function checkBalance() {
|
|
|
39
39
|
}
|
|
40
40
|
/**
|
|
41
41
|
* The fare for one tool in api_sats, as the live pricing model resolves it,
|
|
42
|
-
* constraints included — keyed by the tool's frozen UUID
|
|
43
|
-
*
|
|
42
|
+
* constraints included — keyed by the tool's frozen UUID (or its capability
|
|
43
|
+
* name). `toolKwargs` are the call's own parameters, for a tool priced by
|
|
44
|
+
* them (ad valorem, or a multiplier on a categorical argument). Null when
|
|
45
|
+
* unreadable: show the answer without a price rather than invent one.
|
|
44
46
|
*/
|
|
45
|
-
export async function checkPrice(toolId) {
|
|
46
|
-
const r = await callTool("check_price", {
|
|
47
|
+
export async function checkPrice(toolId, toolKwargs) {
|
|
48
|
+
const r = await callTool("check_price", {
|
|
49
|
+
tool_id: toolId,
|
|
50
|
+
...(toolKwargs ? { tool_kwargs: JSON.stringify(toolKwargs) } : {}),
|
|
51
|
+
});
|
|
47
52
|
const v = r.effective_cost_api_sats ?? r.base_cost_api_sats;
|
|
48
53
|
return typeof v === "number" ? v : null;
|
|
49
54
|
}
|
|
@@ -78,3 +83,40 @@ export function publishNostrProfile(npub, signedEvent) {
|
|
|
78
83
|
signed_event: signedEvent,
|
|
79
84
|
});
|
|
80
85
|
}
|
|
86
|
+
/**
|
|
87
|
+
* Is the operator ready to serve? Free, no proof. With `patronNpub`, also the
|
|
88
|
+
* patron's upstream OAuth token expiry, so a page can refresh ahead of time.
|
|
89
|
+
*/
|
|
90
|
+
export function sessionStatus(patronNpub) {
|
|
91
|
+
return callTool("session_status", patronNpub ? { patron_npub: patronNpub } : {}, { bestEffort: true });
|
|
92
|
+
}
|
|
93
|
+
export function getOperatorOnboardingStatus() {
|
|
94
|
+
return callTool("get_operator_onboarding_status", {}, { bestEffort: true });
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* The operator's own balance at its Authority — what certifies patron top-ups.
|
|
98
|
+
* The Authority's ledger, in the same shape as a patron's `check_balance`.
|
|
99
|
+
*/
|
|
100
|
+
export function checkAuthorityBalance() {
|
|
101
|
+
return callTool("check_authority_balance", {}, { bestEffort: true });
|
|
102
|
+
}
|
|
103
|
+
/** The operator's active pricing model. Free, no proof. */
|
|
104
|
+
export function getPricingModel() {
|
|
105
|
+
return callTool("get_pricing_model", {});
|
|
106
|
+
}
|
|
107
|
+
export function listCanonicalIdentities() {
|
|
108
|
+
return callTool("list_canonical_identities", {});
|
|
109
|
+
}
|
|
110
|
+
/** The names of the patron's stored credential fields — never their values. */
|
|
111
|
+
export function getPatronCredentialFields() {
|
|
112
|
+
return callTool("get_patron_credential_fields", {});
|
|
113
|
+
}
|
|
114
|
+
/** Set one credential field, leaving the others as they are. */
|
|
115
|
+
export function updatePatronCredential(field, value) {
|
|
116
|
+
// `field` first: the log's scrubber keys on it to hide `value`.
|
|
117
|
+
return callTool("update_patron_credential", { field, value });
|
|
118
|
+
}
|
|
119
|
+
/** Remove one credential field, leaving the others as they are. */
|
|
120
|
+
export function deletePatronCredential(field) {
|
|
121
|
+
return callTool("delete_patron_credential", { field });
|
|
122
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tollbooth-dpyc/web",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Shared browser SDK for Tollbooth DPYC operator front ends: npub sign-in, proofs, MCP client, profile and wallet",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Lonnie VanZandt",
|