@ziggs-ai/api-client 0.3.1 → 0.5.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/ConnectionManager.d.ts +13 -1
- package/dist/ConnectionManager.js +52 -9
- package/dist/capabilities/artifacts.d.ts +3 -0
- package/dist/capabilities/artifacts.js +94 -0
- package/dist/capabilities/chat.d.ts +11 -0
- package/dist/capabilities/chat.js +38 -0
- package/dist/capabilities/connections.d.ts +4 -0
- package/dist/capabilities/connections.js +112 -0
- package/dist/capabilities/context.d.ts +23 -0
- package/dist/capabilities/context.js +220 -0
- package/dist/capabilities/discovery.d.ts +4 -0
- package/dist/capabilities/discovery.js +77 -0
- package/dist/capabilities/grants.d.ts +9 -0
- package/dist/capabilities/grants.js +77 -0
- package/dist/capabilities/index.d.ts +9 -0
- package/dist/capabilities/index.js +9 -0
- package/dist/capabilities/links.d.ts +17 -0
- package/dist/capabilities/links.js +219 -0
- package/dist/capabilities/payments.d.ts +11 -0
- package/dist/capabilities/payments.js +404 -0
- package/dist/capabilities/types.d.ts +88 -0
- package/dist/capabilities/types.js +24 -0
- package/dist/http/AgreementClient.d.ts +6 -0
- package/dist/http/ConnectionsClient.d.ts +27 -1
- package/dist/http/ConnectionsClient.js +29 -0
- package/dist/http/ContextReadClient.js +7 -1
- package/dist/http/GrantsClient.d.ts +16 -0
- package/dist/http/GrantsClient.js +3 -0
- package/dist/http/InboxClient.d.ts +95 -65
- package/dist/http/InboxClient.js +42 -14
- package/dist/http/MarketplaceClient.d.ts +8 -0
- package/dist/http/OrgsClient.d.ts +36 -0
- package/dist/http/OrgsClient.js +61 -0
- package/dist/http/PaymentsClient.d.ts +75 -10
- package/dist/http/PaymentsClient.js +26 -14
- package/dist/http/index.d.ts +6 -6
- package/dist/http/index.js +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/package.json +1 -1
- package/dist/http/grantRails.d.ts +0 -20
- package/dist/http/grantRails.js +0 -50
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import 'dotenv/config';
|
|
2
|
+
import { getBackendUrl } from '../utils/urlUtils.js';
|
|
3
|
+
import { buildOperatorHeaders } from './operatorHeaders.js';
|
|
4
|
+
/**
|
|
5
|
+
* ZIG-739 / ZIG-956 — the operator's full org membership (not just granted
|
|
6
|
+
* scopes, which is all the grant listers see). Lets a delegate resolve an org
|
|
7
|
+
* name to an id and offer a pick-list instead of demanding a pasted org_... id.
|
|
8
|
+
* Moved here from ziggs-mcp so every surface rides the one client (ZIG-894).
|
|
9
|
+
*/
|
|
10
|
+
export async function fetchMyOrgs(creds, baseUrl) {
|
|
11
|
+
const url = `${baseUrl || getBackendUrl()}/orgs/me`;
|
|
12
|
+
const res = await fetch(url, {
|
|
13
|
+
method: 'GET',
|
|
14
|
+
headers: buildOperatorHeaders(creds.operatorKey, creds.agentId),
|
|
15
|
+
});
|
|
16
|
+
const body = await res.text().catch(() => '');
|
|
17
|
+
if (!res.ok) {
|
|
18
|
+
throw new Error(`GET /orgs/me ${res.status} ${body.slice(0, 200)}`);
|
|
19
|
+
}
|
|
20
|
+
const parsed = body ? JSON.parse(body) : {};
|
|
21
|
+
return (parsed.orgs ?? []).map((o) => ({
|
|
22
|
+
orgId: o.orgId,
|
|
23
|
+
name: o.name,
|
|
24
|
+
kind: o.kind,
|
|
25
|
+
role: o.role,
|
|
26
|
+
}));
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* ZIG-739 — resolve an org selector (exact org_... id OR a name/handle) against
|
|
30
|
+
* the operator's memberships. Exact id wins; otherwise case-insensitive name
|
|
31
|
+
* match. Ambiguous names return the candidates rather than guessing.
|
|
32
|
+
*/
|
|
33
|
+
export function resolveOrgSelector(orgs, selector) {
|
|
34
|
+
const byId = orgs.find((o) => o.orgId === selector);
|
|
35
|
+
if (byId)
|
|
36
|
+
return { status: 'ok', orgId: byId.orgId };
|
|
37
|
+
const needle = selector.toLowerCase();
|
|
38
|
+
const byName = orgs.filter((o) => o.name.toLowerCase() === needle);
|
|
39
|
+
if (byName.length === 1)
|
|
40
|
+
return { status: 'ok', orgId: byName[0].orgId };
|
|
41
|
+
if (byName.length > 1)
|
|
42
|
+
return { status: 'ambiguous', matches: byName };
|
|
43
|
+
return { status: 'not-found' };
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* ZIG-640 / ZIG-956 — runtime acting org from the server (self-hire / agent
|
|
47
|
+
* row): GET /agents/claude-delegate/access. Moved here from ziggs-mcp's inline
|
|
48
|
+
* fetch (ZIG-894 "one client for every surface").
|
|
49
|
+
*/
|
|
50
|
+
export async function fetchDelegateAccess(creds, baseUrl) {
|
|
51
|
+
const url = `${baseUrl || getBackendUrl()}/agents/claude-delegate/access`;
|
|
52
|
+
const res = await fetch(url, {
|
|
53
|
+
method: 'GET',
|
|
54
|
+
headers: buildOperatorHeaders(creds.operatorKey, creds.agentId),
|
|
55
|
+
});
|
|
56
|
+
const body = await res.text().catch(() => '');
|
|
57
|
+
if (!res.ok) {
|
|
58
|
+
throw new Error(`GET /agents/claude-delegate/access ${res.status} ${body.slice(0, 200)}`);
|
|
59
|
+
}
|
|
60
|
+
return body ? JSON.parse(body) : {};
|
|
61
|
+
}
|
|
@@ -11,6 +11,71 @@ export interface WalletBalance {
|
|
|
11
11
|
balance: number;
|
|
12
12
|
availableBalance: number;
|
|
13
13
|
}
|
|
14
|
+
export interface PaymentTransactionView {
|
|
15
|
+
transactionId?: string;
|
|
16
|
+
[key: string]: unknown;
|
|
17
|
+
}
|
|
18
|
+
/** A resolved wallet reference (GET /payments/wallets/resolve). */
|
|
19
|
+
export interface WalletRef {
|
|
20
|
+
walletId?: string;
|
|
21
|
+
ownerId?: string;
|
|
22
|
+
currency?: string;
|
|
23
|
+
status?: string;
|
|
24
|
+
[key: string]: unknown;
|
|
25
|
+
}
|
|
26
|
+
export type TransferResult = {
|
|
27
|
+
status: 'approval_required';
|
|
28
|
+
approvalId: string | null;
|
|
29
|
+
expiresAt: string | null;
|
|
30
|
+
reason: string | null;
|
|
31
|
+
toWalletId: string;
|
|
32
|
+
amount: number;
|
|
33
|
+
} | {
|
|
34
|
+
status: 'transferred';
|
|
35
|
+
transactionId: string | null;
|
|
36
|
+
toWalletId: string;
|
|
37
|
+
amount: number;
|
|
38
|
+
};
|
|
39
|
+
export interface HoldResult {
|
|
40
|
+
transaction?: PaymentTransactionView;
|
|
41
|
+
[key: string]: unknown;
|
|
42
|
+
}
|
|
43
|
+
export interface ReleaseResult {
|
|
44
|
+
transaction?: PaymentTransactionView;
|
|
45
|
+
[key: string]: unknown;
|
|
46
|
+
}
|
|
47
|
+
export interface PaymentGrantView {
|
|
48
|
+
grantId?: string;
|
|
49
|
+
holderId?: string;
|
|
50
|
+
parentGrantId?: string;
|
|
51
|
+
caveats?: unknown[];
|
|
52
|
+
expiresAt?: string | null;
|
|
53
|
+
[key: string]: unknown;
|
|
54
|
+
}
|
|
55
|
+
export interface PaymentGrantEnvelope {
|
|
56
|
+
grant?: PaymentGrantView;
|
|
57
|
+
[key: string]: unknown;
|
|
58
|
+
}
|
|
59
|
+
export interface RevokeGrantResult {
|
|
60
|
+
revoked?: unknown;
|
|
61
|
+
[key: string]: unknown;
|
|
62
|
+
}
|
|
63
|
+
export interface PaymentApproval {
|
|
64
|
+
approvalId?: string;
|
|
65
|
+
status?: string;
|
|
66
|
+
executedTransactionId?: string | null;
|
|
67
|
+
[key: string]: unknown;
|
|
68
|
+
}
|
|
69
|
+
export type WaitForApprovalResult = {
|
|
70
|
+
status: 'gone';
|
|
71
|
+
} | {
|
|
72
|
+
status: 'executed';
|
|
73
|
+
approval: PaymentApproval;
|
|
74
|
+
transactionId: string | null;
|
|
75
|
+
} | {
|
|
76
|
+
status: 'rejected' | 'expired' | 'timeout';
|
|
77
|
+
approval: PaymentApproval;
|
|
78
|
+
};
|
|
14
79
|
/**
|
|
15
80
|
* ZIG-894 — the one payments client for every surface (agent-sdk, ziggs-mcp,
|
|
16
81
|
* scripts). Consolidates the former agent-sdk private ZiggsPayClient. Wallet
|
|
@@ -28,25 +93,25 @@ export declare class PaymentsClient {
|
|
|
28
93
|
resolve({ userId, agentId }?: {
|
|
29
94
|
userId?: string;
|
|
30
95
|
agentId?: string;
|
|
31
|
-
}): Promise<
|
|
96
|
+
}): Promise<WalletRef | null>;
|
|
32
97
|
transfer({ to, amount, idempotencyKey, description, paymentGrantId, }: {
|
|
33
98
|
to: string;
|
|
34
99
|
amount: number;
|
|
35
100
|
idempotencyKey?: string;
|
|
36
101
|
description?: string;
|
|
37
102
|
paymentGrantId?: string;
|
|
38
|
-
}): Promise<
|
|
103
|
+
}): Promise<TransferResult>;
|
|
39
104
|
hold({ amount, idempotencyKey, description, }: {
|
|
40
105
|
amount: number;
|
|
41
106
|
idempotencyKey?: string;
|
|
42
107
|
description?: string;
|
|
43
|
-
}): Promise<
|
|
108
|
+
}): Promise<HoldResult>;
|
|
44
109
|
release({ holdId, action, toWalletId, idempotencyKey, }: {
|
|
45
110
|
holdId: string;
|
|
46
111
|
action?: string;
|
|
47
112
|
toWalletId?: string;
|
|
48
113
|
idempotencyKey?: string;
|
|
49
|
-
}): Promise<
|
|
114
|
+
}): Promise<ReleaseResult>;
|
|
50
115
|
history(params?: {
|
|
51
116
|
limit?: number;
|
|
52
117
|
offset?: number;
|
|
@@ -55,13 +120,13 @@ export declare class PaymentsClient {
|
|
|
55
120
|
issueGrant({ holderId, caveats }: {
|
|
56
121
|
holderId: string;
|
|
57
122
|
caveats?: unknown;
|
|
58
|
-
}): Promise<
|
|
123
|
+
}): Promise<PaymentGrantEnvelope>;
|
|
59
124
|
attenuateGrant({ grantId, holderId, caveats, }: {
|
|
60
125
|
grantId: string;
|
|
61
126
|
holderId: string;
|
|
62
127
|
caveats?: unknown;
|
|
63
|
-
}): Promise<
|
|
64
|
-
revokeGrant(grantId: string): Promise<
|
|
128
|
+
}): Promise<PaymentGrantEnvelope>;
|
|
129
|
+
revokeGrant(grantId: string): Promise<RevokeGrantResult>;
|
|
65
130
|
/**
|
|
66
131
|
* Live wallet grants the acting agent holds, via the unified GET /grants
|
|
67
132
|
* (ZIG-648 retired GET /payments/grants), following the cursor to completion.
|
|
@@ -80,14 +145,14 @@ export declare class PaymentsClient {
|
|
|
80
145
|
}): Promise<unknown>;
|
|
81
146
|
approvals({ status }?: {
|
|
82
147
|
status?: string;
|
|
83
|
-
}): Promise<
|
|
84
|
-
getApproval(approvalId: string): Promise<
|
|
148
|
+
}): Promise<PaymentApproval[]>;
|
|
149
|
+
getApproval(approvalId: string): Promise<PaymentApproval | null>;
|
|
85
150
|
decide(approvalId: string, decision: string, note?: string): Promise<unknown>;
|
|
86
151
|
waitForApproval(approvalId: string, opts?: {
|
|
87
152
|
pollMs?: number;
|
|
88
153
|
timeoutMs?: number;
|
|
89
154
|
signal?: AbortSignal;
|
|
90
|
-
}): Promise<
|
|
155
|
+
}): Promise<WaitForApprovalResult>;
|
|
91
156
|
private _request;
|
|
92
157
|
private _get;
|
|
93
158
|
private _post;
|
|
@@ -65,10 +65,10 @@ export class PaymentsClient {
|
|
|
65
65
|
throw new Error('transfer: paymentGrantId is required for agent-impersonated transfers. The wallet owner must have issued a payment grant to this agentId.');
|
|
66
66
|
let toWalletId = to;
|
|
67
67
|
if (!to.startsWith('wal_')) {
|
|
68
|
-
const w =
|
|
69
|
-
if (!w?.
|
|
68
|
+
const w = await this.resolve(to.startsWith('agent_') ? { agentId: to } : { userId: to });
|
|
69
|
+
if (!w?.walletId)
|
|
70
70
|
throw new Error(`transfer: could not resolve wallet for "${to}"`);
|
|
71
|
-
toWalletId = w
|
|
71
|
+
toWalletId = w.walletId;
|
|
72
72
|
}
|
|
73
73
|
const result = (await this._post('/payments/transfer', {
|
|
74
74
|
toWalletId,
|
|
@@ -89,23 +89,28 @@ export class PaymentsClient {
|
|
|
89
89
|
};
|
|
90
90
|
}
|
|
91
91
|
const tx = result?.['transaction'];
|
|
92
|
-
return {
|
|
92
|
+
return {
|
|
93
|
+
status: 'transferred',
|
|
94
|
+
transactionId: tx?.['transactionId'] || null,
|
|
95
|
+
toWalletId,
|
|
96
|
+
amount,
|
|
97
|
+
};
|
|
93
98
|
}
|
|
94
99
|
async hold({ amount, idempotencyKey, description, }) {
|
|
95
100
|
if (!(Number.isInteger(amount) && amount > 0))
|
|
96
101
|
throw new Error('hold: `amount` must be a positive integer (cents)');
|
|
97
|
-
return this._post('/payments/hold', {
|
|
102
|
+
return (await this._post('/payments/hold', {
|
|
98
103
|
amount,
|
|
99
104
|
idempotencyKey: idempotencyKey || randomIdempotencyKey('hold'),
|
|
100
105
|
description,
|
|
101
|
-
});
|
|
106
|
+
}));
|
|
102
107
|
}
|
|
103
108
|
async release({ holdId, action = 'complete', toWalletId, idempotencyKey, }) {
|
|
104
|
-
return this._post(`/payments/release/${holdId}`, {
|
|
109
|
+
return (await this._post(`/payments/release/${holdId}`, {
|
|
105
110
|
idempotencyKey: idempotencyKey || randomIdempotencyKey('rel'),
|
|
106
111
|
action,
|
|
107
112
|
toWalletId,
|
|
108
|
-
});
|
|
113
|
+
}));
|
|
109
114
|
}
|
|
110
115
|
async history(params = {}) {
|
|
111
116
|
const q = new URLSearchParams();
|
|
@@ -118,13 +123,16 @@ export class PaymentsClient {
|
|
|
118
123
|
return this._get('/payments/history' + (q.toString() ? `?${q}` : ''));
|
|
119
124
|
}
|
|
120
125
|
async issueGrant({ holderId, caveats }) {
|
|
121
|
-
return this._post('/payments/grants', { holderId, caveats });
|
|
126
|
+
return (await this._post('/payments/grants', { holderId, caveats }));
|
|
122
127
|
}
|
|
123
128
|
async attenuateGrant({ grantId, holderId, caveats, }) {
|
|
124
|
-
return this._post(`/payments/grants/${grantId}/attenuate`, {
|
|
129
|
+
return (await this._post(`/payments/grants/${grantId}/attenuate`, {
|
|
130
|
+
holderId,
|
|
131
|
+
caveats,
|
|
132
|
+
}));
|
|
125
133
|
}
|
|
126
134
|
async revokeGrant(grantId) {
|
|
127
|
-
return this._request('DELETE', `/payments/grants/${grantId}`, undefined);
|
|
135
|
+
return (await this._request('DELETE', `/payments/grants/${grantId}`, undefined));
|
|
128
136
|
}
|
|
129
137
|
/**
|
|
130
138
|
* Live wallet grants the acting agent holds, via the unified GET /grants
|
|
@@ -189,12 +197,16 @@ export class PaymentsClient {
|
|
|
189
197
|
while (true) {
|
|
190
198
|
if (signal?.aborted)
|
|
191
199
|
throw new Error('aborted');
|
|
192
|
-
const approval =
|
|
200
|
+
const approval = await this.getApproval(approvalId);
|
|
193
201
|
if (!approval)
|
|
194
202
|
return { status: 'gone' };
|
|
195
|
-
const s = approval
|
|
203
|
+
const s = approval.status;
|
|
196
204
|
if (s === 'executed')
|
|
197
|
-
return {
|
|
205
|
+
return {
|
|
206
|
+
status: 'executed',
|
|
207
|
+
approval,
|
|
208
|
+
transactionId: approval.executedTransactionId || null,
|
|
209
|
+
};
|
|
198
210
|
if (s === 'rejected')
|
|
199
211
|
return { status: 'rejected', approval };
|
|
200
212
|
if (s === 'expired')
|
package/dist/http/index.d.ts
CHANGED
|
@@ -11,18 +11,18 @@ export type { ContextReadType, ContextReadQuery, ContextReadEnvelope, ContextSna
|
|
|
11
11
|
export { ContextDiscoveryClient } from './ContextDiscoveryClient.js';
|
|
12
12
|
export type { DiscoverableItem } from './ContextDiscoveryClient.js';
|
|
13
13
|
export { GrantsClient } from './GrantsClient.js';
|
|
14
|
-
export type { ListGrantsQuery, ListGrantsResult } from './GrantsClient.js';
|
|
14
|
+
export type { ListGrantsQuery, ListGrantsResult, UnreadableRail } from './GrantsClient.js';
|
|
15
15
|
export { ContextGrantsClient } from './ContextGrantsClient.js';
|
|
16
16
|
export type { ContextGrantRecord, ContextGrantScope, ContextGrantScopeKind, ContextTemporal, IssueContextGrantInput, DelegateContextGrantInput, DelegateContextGrantResult, ReachEntry, GrantReachResult, } from './ContextGrantsClient.js';
|
|
17
17
|
export { grantCaveat } from './grants.js';
|
|
18
18
|
export type { GrantView, GrantScopeKind, GrantScopeView, GrantCaveatView, GrantHealth, } from './grants.js';
|
|
19
|
-
export { decodeOperatorScopes, unreadableGrantRails } from './grantRails.js';
|
|
20
|
-
export type { UnreadableRail } from './grantRails.js';
|
|
21
19
|
export { PaymentsClient } from './PaymentsClient.js';
|
|
22
|
-
export type { PaymentsError, WalletBalance } from './PaymentsClient.js';
|
|
20
|
+
export type { PaymentsError, WalletBalance, WalletRef, PaymentTransactionView, TransferResult, HoldResult, ReleaseResult, PaymentGrantView, PaymentGrantEnvelope, RevokeGrantResult, PaymentApproval, WaitForApprovalResult, } from './PaymentsClient.js';
|
|
23
21
|
export { ConnectionsClient, assertNoLeakedConnectionSecret, } from './ConnectionsClient.js';
|
|
24
|
-
export type { ConnectionsError, ConnectionProxyParams, McpConnectionRequestParams, } from './ConnectionsClient.js';
|
|
22
|
+
export type { ConnectionsError, ConnectionProxyParams, ConnectionGrant, ConnectionWithGrants, McpConnectionRequestParams, } from './ConnectionsClient.js';
|
|
23
|
+
export { fetchMyOrgs, resolveOrgSelector, fetchDelegateAccess, } from './OrgsClient.js';
|
|
24
|
+
export type { MyOrg, OrgResolution } from './OrgsClient.js';
|
|
25
25
|
export { AgentSearchClient } from './AgentSearchClient.js';
|
|
26
26
|
export { TelemetryClient } from './TelemetryClient.js';
|
|
27
27
|
export { InboxClient } from './InboxClient.js';
|
|
28
|
-
export type {
|
|
28
|
+
export type { InboxDeliveryRef, InboxChatNews, InboxProposalRef, InboxTaskRef, InboxConnectionRequestRef, InboxHumanAttention, InboxEnvelope, InboxAckResult, InboxOperatorAgentEntry, InboxOperatorEnvelope, } from './InboxClient.js';
|
package/dist/http/index.js
CHANGED
|
@@ -9,9 +9,9 @@ export { ContextDiscoveryClient } from './ContextDiscoveryClient.js';
|
|
|
9
9
|
export { GrantsClient } from './GrantsClient.js';
|
|
10
10
|
export { ContextGrantsClient } from './ContextGrantsClient.js';
|
|
11
11
|
export { grantCaveat } from './grants.js';
|
|
12
|
-
export { decodeOperatorScopes, unreadableGrantRails } from './grantRails.js';
|
|
13
12
|
export { PaymentsClient } from './PaymentsClient.js';
|
|
14
13
|
export { ConnectionsClient, assertNoLeakedConnectionSecret, } from './ConnectionsClient.js';
|
|
14
|
+
export { fetchMyOrgs, resolveOrgSelector, fetchDelegateAccess, } from './OrgsClient.js';
|
|
15
15
|
export { AgentSearchClient } from './AgentSearchClient.js';
|
|
16
16
|
export { TelemetryClient } from './TelemetryClient.js';
|
|
17
17
|
export { InboxClient } from './InboxClient.js';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export * from './http/index.js';
|
|
2
|
+
export * from './capabilities/index.js';
|
|
2
3
|
export * from './relay/provisionRelayWorkers.js';
|
|
3
4
|
export { ConnectionManager } from './ConnectionManager.js';
|
|
5
|
+
export type { StartAgentOptions } from './ConnectionManager.js';
|
|
4
6
|
export { EntryTypes, ContentTypes, OPEN_AGREEMENT_TARGET, ORG_AGREEMENT_TARGET, BROADCAST_TARGETS, isBroadcastTarget, AGREEMENT_ENGAGEMENT_KIND, isValidContentType } from './types.js';
|
|
5
7
|
export { getBackendUrl, getWebSocketUrl } from './utils/urlUtils.js';
|
|
6
8
|
export { runtimeLog, resetRuntimeLogLevelCache } from './shared/runtimeLog.js';
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export * from './http/index.js';
|
|
2
|
+
export * from './capabilities/index.js';
|
|
2
3
|
export * from './relay/provisionRelayWorkers.js';
|
|
3
4
|
export { ConnectionManager } from './ConnectionManager.js';
|
|
4
5
|
export { EntryTypes, ContentTypes, OPEN_AGREEMENT_TARGET, ORG_AGREEMENT_TARGET, BROADCAST_TARGETS, isBroadcastTarget, AGREEMENT_ENGAGEMENT_KIND, isValidContentType } from './types.js';
|
package/package.json
CHANGED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import type { GrantScopeKind } from './grants.js';
|
|
2
|
-
/**
|
|
3
|
-
* Read the `scopes` claim of an operator JWT without verifying its signature —
|
|
4
|
-
* an identity hint only, exactly as the backend re-checks the key row on every
|
|
5
|
-
* request. Returns null when the token isn't a decodable JWT (so callers treat
|
|
6
|
-
* entitlement as unknown rather than empty).
|
|
7
|
-
*/
|
|
8
|
-
export declare function decodeOperatorScopes(operatorKey: string): string[] | null;
|
|
9
|
-
export interface UnreadableRail {
|
|
10
|
-
rail: 'context' | 'connection' | 'wallet';
|
|
11
|
-
requiredScope: string;
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* Which grant rails the operator key can't read, among those requested (or all
|
|
15
|
-
* rails when no filter is given). Returns null when the key's scopes can't be
|
|
16
|
-
* decoded — the caller then omits the "what I can't see" note rather than
|
|
17
|
-
* guessing. `GET /grants` enforces the same boundary server-side; this only
|
|
18
|
-
* lets the tool surface report it.
|
|
19
|
-
*/
|
|
20
|
-
export declare function unreadableGrantRails(operatorKey: string, requested?: readonly GrantScopeKind[]): UnreadableRail[] | null;
|
package/dist/http/grantRails.js
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
const RAIL_GROUPS = [
|
|
2
|
-
{ rail: 'context', kinds: ['chat', 'agreement', 'org'], requiredScope: 'context:read' },
|
|
3
|
-
{ rail: 'connection', kinds: ['connection'], requiredScope: 'connections:read' },
|
|
4
|
-
{ rail: 'wallet', kinds: ['wallet'], requiredScope: 'payments:read' },
|
|
5
|
-
];
|
|
6
|
-
/**
|
|
7
|
-
* Read the `scopes` claim of an operator JWT without verifying its signature —
|
|
8
|
-
* an identity hint only, exactly as the backend re-checks the key row on every
|
|
9
|
-
* request. Returns null when the token isn't a decodable JWT (so callers treat
|
|
10
|
-
* entitlement as unknown rather than empty).
|
|
11
|
-
*/
|
|
12
|
-
export function decodeOperatorScopes(operatorKey) {
|
|
13
|
-
const parts = (operatorKey ?? '').trim().split('.');
|
|
14
|
-
if (parts.length !== 3)
|
|
15
|
-
return null;
|
|
16
|
-
try {
|
|
17
|
-
const json = Buffer.from(parts[1], 'base64url').toString('utf8');
|
|
18
|
-
const payload = JSON.parse(json);
|
|
19
|
-
if (!Array.isArray(payload.scopes))
|
|
20
|
-
return null;
|
|
21
|
-
return payload.scopes.filter((s) => typeof s === 'string');
|
|
22
|
-
}
|
|
23
|
-
catch {
|
|
24
|
-
return null;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Which grant rails the operator key can't read, among those requested (or all
|
|
29
|
-
* rails when no filter is given). Returns null when the key's scopes can't be
|
|
30
|
-
* decoded — the caller then omits the "what I can't see" note rather than
|
|
31
|
-
* guessing. `GET /grants` enforces the same boundary server-side; this only
|
|
32
|
-
* lets the tool surface report it.
|
|
33
|
-
*/
|
|
34
|
-
export function unreadableGrantRails(operatorKey, requested) {
|
|
35
|
-
const scopes = decodeOperatorScopes(operatorKey);
|
|
36
|
-
if (scopes === null)
|
|
37
|
-
return null;
|
|
38
|
-
const held = new Set(scopes);
|
|
39
|
-
const wanted = requested && requested.length > 0 ? new Set(requested) : null;
|
|
40
|
-
const out = [];
|
|
41
|
-
for (const group of RAIL_GROUPS) {
|
|
42
|
-
const inScope = wanted ? group.kinds.some((k) => wanted.has(k)) : true;
|
|
43
|
-
if (!inScope)
|
|
44
|
-
continue;
|
|
45
|
-
if (!held.has(group.requiredScope)) {
|
|
46
|
-
out.push({ rail: group.rail, requiredScope: group.requiredScope });
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
return out;
|
|
50
|
-
}
|