@grantex/sdk 0.6.0 → 0.7.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/LICENSE +185 -185
- package/NOTICE +16 -16
- package/README.md +974 -947
- package/dist/authorization-details.d.ts +86 -0
- package/dist/authorization-details.d.ts.map +1 -0
- package/dist/authorization-details.js +209 -0
- package/dist/authorization-details.js.map +1 -0
- package/dist/canonical.d.ts +47 -0
- package/dist/canonical.d.ts.map +1 -0
- package/dist/canonical.js +163 -0
- package/dist/canonical.js.map +1 -0
- package/dist/caps/index.d.ts +19 -0
- package/dist/caps/index.d.ts.map +1 -0
- package/dist/caps/index.js +19 -0
- package/dist/caps/index.js.map +1 -0
- package/dist/caps/limits.d.ts +40 -0
- package/dist/caps/limits.d.ts.map +1 -0
- package/dist/caps/limits.js +109 -0
- package/dist/caps/limits.js.map +1 -0
- package/dist/caps/memory.d.ts +15 -0
- package/dist/caps/memory.d.ts.map +1 -0
- package/dist/caps/memory.js +57 -0
- package/dist/caps/memory.js.map +1 -0
- package/dist/caps/meter.d.ts +107 -0
- package/dist/caps/meter.d.ts.map +1 -0
- package/dist/caps/meter.js +200 -0
- package/dist/caps/meter.js.map +1 -0
- package/dist/caps/postgres.d.ts +64 -0
- package/dist/caps/postgres.d.ts.map +1 -0
- package/dist/caps/postgres.js +221 -0
- package/dist/caps/postgres.js.map +1 -0
- package/dist/caps/redis.d.ts +45 -0
- package/dist/caps/redis.d.ts.map +1 -0
- package/dist/caps/redis.js +173 -0
- package/dist/caps/redis.js.map +1 -0
- package/dist/client.d.ts +12 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +517 -57
- package/dist/client.js.map +1 -1
- package/dist/decisions/action.d.ts +51 -0
- package/dist/decisions/action.d.ts.map +1 -0
- package/dist/decisions/action.js +237 -0
- package/dist/decisions/action.js.map +1 -0
- package/dist/decisions/index.d.ts +11 -0
- package/dist/decisions/index.d.ts.map +1 -0
- package/dist/decisions/index.js +8 -0
- package/dist/decisions/index.js.map +1 -0
- package/dist/decisions/verify.d.ts +103 -0
- package/dist/decisions/verify.d.ts.map +1 -0
- package/dist/decisions/verify.js +277 -0
- package/dist/decisions/verify.js.map +1 -0
- package/dist/denials.d.ts +132 -0
- package/dist/denials.d.ts.map +1 -0
- package/dist/denials.js +129 -0
- package/dist/denials.js.map +1 -0
- package/dist/evidence/build.d.ts +63 -0
- package/dist/evidence/build.d.ts.map +1 -0
- package/dist/evidence/build.js +201 -0
- package/dist/evidence/build.js.map +1 -0
- package/dist/evidence/canonical.d.ts +3 -0
- package/dist/evidence/canonical.d.ts.map +1 -0
- package/dist/evidence/canonical.js +3 -0
- package/dist/evidence/canonical.js.map +1 -0
- package/dist/evidence/checks.d.ts +13 -0
- package/dist/evidence/checks.d.ts.map +1 -0
- package/dist/evidence/checks.js +406 -0
- package/dist/evidence/checks.js.map +1 -0
- package/dist/evidence/document.d.ts +8 -0
- package/dist/evidence/document.d.ts.map +1 -0
- package/dist/evidence/document.js +298 -0
- package/dist/evidence/document.js.map +1 -0
- package/dist/evidence/hashing.d.ts +37 -0
- package/dist/evidence/hashing.d.ts.map +1 -0
- package/dist/evidence/hashing.js +106 -0
- package/dist/evidence/hashing.js.map +1 -0
- package/dist/evidence/index.d.ts +24 -0
- package/dist/evidence/index.d.ts.map +1 -0
- package/dist/evidence/index.js +24 -0
- package/dist/evidence/index.js.map +1 -0
- package/dist/evidence/result.d.ts +88 -0
- package/dist/evidence/result.d.ts.map +1 -0
- package/dist/evidence/result.js +88 -0
- package/dist/evidence/result.js.map +1 -0
- package/dist/evidence/schema-1.0.d.ts +2 -0
- package/dist/evidence/schema-1.0.d.ts.map +1 -0
- package/dist/evidence/schema-1.0.js +1398 -0
- package/dist/evidence/schema-1.0.js.map +1 -0
- package/dist/evidence/schema.d.ts +13 -0
- package/dist/evidence/schema.d.ts.map +1 -0
- package/dist/evidence/schema.js +264 -0
- package/dist/evidence/schema.js.map +1 -0
- package/dist/evidence/signature.d.ts +23 -0
- package/dist/evidence/signature.d.ts.map +1 -0
- package/dist/evidence/signature.js +136 -0
- package/dist/evidence/signature.js.map +1 -0
- package/dist/evidence/trace.d.ts +23 -0
- package/dist/evidence/trace.d.ts.map +1 -0
- package/dist/evidence/trace.js +69 -0
- package/dist/evidence/trace.js.map +1 -0
- package/dist/evidence/verify.d.ts +29 -0
- package/dist/evidence/verify.d.ts.map +1 -0
- package/dist/evidence/verify.js +163 -0
- package/dist/evidence/verify.js.map +1 -0
- package/dist/http.d.ts +12 -1
- package/dist/http.d.ts.map +1 -1
- package/dist/http.js +11 -5
- package/dist/http.js.map +1 -1
- package/dist/index.d.ts +16 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +16 -2
- package/dist/index.js.map +1 -1
- package/dist/manifest.d.ts +178 -9
- package/dist/manifest.d.ts.map +1 -1
- package/dist/manifest.js +379 -16
- package/dist/manifest.js.map +1 -1
- package/dist/purpose.d.ts +29 -0
- package/dist/purpose.d.ts.map +1 -0
- package/dist/purpose.js +60 -0
- package/dist/purpose.js.map +1 -0
- package/dist/resources/agents.js +3 -3
- package/dist/resources/agents.js.map +1 -1
- package/dist/resources/anomalies.d.ts +3 -1
- package/dist/resources/anomalies.d.ts.map +1 -1
- package/dist/resources/anomalies.js +7 -1
- package/dist/resources/anomalies.js.map +1 -1
- package/dist/resources/audit.js +1 -1
- package/dist/resources/audit.js.map +1 -1
- package/dist/resources/budgets.js +2 -2
- package/dist/resources/budgets.js.map +1 -1
- package/dist/resources/credentials.js +1 -1
- package/dist/resources/credentials.js.map +1 -1
- package/dist/resources/decisions.d.ts +69 -0
- package/dist/resources/decisions.d.ts.map +1 -0
- package/dist/resources/decisions.js +115 -0
- package/dist/resources/decisions.js.map +1 -0
- package/dist/resources/domains.js +2 -2
- package/dist/resources/domains.js.map +1 -1
- package/dist/resources/dpdp.js +4 -4
- package/dist/resources/dpdp.js.map +1 -1
- package/dist/resources/grants.js +2 -2
- package/dist/resources/grants.js.map +1 -1
- package/dist/resources/policies.js +3 -3
- package/dist/resources/policies.js.map +1 -1
- package/dist/resources/scim.js +5 -5
- package/dist/resources/scim.js.map +1 -1
- package/dist/resources/tokens.d.ts.map +1 -1
- package/dist/resources/tokens.js +5 -1
- package/dist/resources/tokens.js.map +1 -1
- package/dist/resources/vault.js +2 -2
- package/dist/resources/vault.js.map +1 -1
- package/dist/resources/webauthn.d.ts +6 -1
- package/dist/resources/webauthn.d.ts.map +1 -1
- package/dist/resources/webauthn.js +5 -1
- package/dist/resources/webauthn.js.map +1 -1
- package/dist/resources/webhooks.js +1 -1
- package/dist/resources/webhooks.js.map +1 -1
- package/dist/revocations/feed.d.ts +61 -0
- package/dist/revocations/feed.d.ts.map +1 -0
- package/dist/revocations/feed.js +282 -0
- package/dist/revocations/feed.js.map +1 -0
- package/dist/revocations/index.d.ts +20 -0
- package/dist/revocations/index.d.ts.map +1 -0
- package/dist/revocations/index.js +19 -0
- package/dist/revocations/index.js.map +1 -0
- package/dist/revocations/set.d.ts +59 -0
- package/dist/revocations/set.d.ts.map +1 -0
- package/dist/revocations/set.js +87 -0
- package/dist/revocations/set.js.map +1 -0
- package/dist/scopes.d.ts +26 -0
- package/dist/scopes.d.ts.map +1 -0
- package/dist/scopes.js +37 -0
- package/dist/scopes.js.map +1 -0
- package/dist/types.d.ts +121 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +0 -1
- package/dist/types.js.map +1 -1
- package/dist/verify.d.ts +31 -2
- package/dist/verify.d.ts.map +1 -1
- package/dist/verify.js +236 -29
- package/dist/verify.js.map +1 -1
- package/package.json +92 -84
package/README.md
CHANGED
|
@@ -1,947 +1,974 @@
|
|
|
1
|
-
# @grantex/sdk
|
|
2
|
-
|
|
3
|
-
TypeScript SDK for the [Grantex](https://grantex.dev) delegated authorization protocol — OAuth 2.0 for AI agents.
|
|
4
|
-
|
|
5
|
-
[](https://www.npmjs.com/package/@grantex/sdk)
|
|
6
|
-
[](https://github.com/mishrasanjeev/grantex/blob/main/LICENSE)
|
|
7
|
-
|
|
8
|
-
> **[Homepage](https://grantex.dev)** | **[Docs](https://docs.grantex.dev)** | **[API Reference](https://docs.grantex.dev/api-reference)** | **[Sign Up Free](https://grantex.dev/dashboard/signup)** | **[GitHub](https://github.com/mishrasanjeev/grantex)**
|
|
9
|
-
|
|
10
|
-
## Installation
|
|
11
|
-
|
|
12
|
-
**
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
`
|
|
83
|
-
`
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
);
|
|
111
|
-
|
|
112
|
-
const
|
|
113
|
-
'
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
the
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
`
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
const
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
});
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
});
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
)
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
|
352
|
-
|
|
353
|
-
| `
|
|
354
|
-
| `
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
```
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
|
542
|
-
|
|
543
|
-
| `
|
|
544
|
-
| `
|
|
545
|
-
| `
|
|
546
|
-
| `
|
|
547
|
-
| `
|
|
548
|
-
| `
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
```
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
```
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
console.log(pack.
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
})
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
await grantex.scim.
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
});
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
```
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
```
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
```
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
1
|
+
# @grantex/sdk
|
|
2
|
+
|
|
3
|
+
TypeScript SDK for the [Grantex](https://grantex.dev) delegated authorization protocol — OAuth 2.0 for AI agents.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@grantex/sdk)
|
|
6
|
+
[](https://github.com/mishrasanjeev/grantex/blob/main/LICENSE)
|
|
7
|
+
|
|
8
|
+
> **[Homepage](https://grantex.dev)** | **[Docs](https://docs.grantex.dev)** | **[API Reference](https://docs.grantex.dev/api-reference)** | **[Sign Up Free](https://grantex.dev/dashboard/signup)** | **[GitHub](https://github.com/mishrasanjeev/grantex)**
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
**Version 0.7.0:** adds hosted passkey enrollment sessions and
|
|
13
|
+
account-level irregularity response policy methods. The server must enable the
|
|
14
|
+
corresponding feature flags; this SDK does not register a passkey without an
|
|
15
|
+
authenticated customer handoff. Version 0.6.0 added wallet clients that preserve the
|
|
16
|
+
server's Base USDC `evmPayment` payload and expose `reconcileReservation()` for
|
|
17
|
+
finalized settlement/expiry. Use `@grantex/x402@0.4.0` or later for
|
|
18
|
+
the automatic 402/payment/retry flow. Confirm the published SDK version in
|
|
19
|
+
[Release Status](https://docs.grantex.dev/release-status) before installing.
|
|
20
|
+
See [Base custody setup](https://docs.grantex.dev/guides/base-usdc-custody).
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm install @grantex/sdk@0.7.0
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Quick Start
|
|
27
|
+
|
|
28
|
+
```typescript
|
|
29
|
+
import { Grantex, verifyGrantToken } from '@grantex/sdk';
|
|
30
|
+
|
|
31
|
+
const grantex = new Grantex({ apiKey: 'YOUR_API_KEY' });
|
|
32
|
+
|
|
33
|
+
// 1. Register an agent
|
|
34
|
+
const agent = await grantex.agents.register({
|
|
35
|
+
name: 'Email Assistant',
|
|
36
|
+
description: 'Reads and sends email on behalf of users',
|
|
37
|
+
scopes: ['email:read', 'email:send'],
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// 2. Request authorization
|
|
41
|
+
const { consentUrl } = await grantex.authorize({
|
|
42
|
+
agentId: agent.id,
|
|
43
|
+
userId: 'usr_01J...',
|
|
44
|
+
scopes: ['email:read', 'email:send'],
|
|
45
|
+
});
|
|
46
|
+
// Redirect the user to consentUrl — they approve in plain language
|
|
47
|
+
|
|
48
|
+
// 3. Exchange authorization code for a grant token
|
|
49
|
+
// (your redirect callback receives the `code` after user approves)
|
|
50
|
+
const token = await grantex.tokens.exchange({ code, agentId: agent.id });
|
|
51
|
+
console.log(token.grantToken); // RS256-signed JWT
|
|
52
|
+
console.log(token.scopes); // ['email:read', 'email:send']
|
|
53
|
+
console.log(token.grantId); // 'grnt_01J...'
|
|
54
|
+
|
|
55
|
+
// 4. Verify locally using keys retrieved from the issuer's JWKS
|
|
56
|
+
const grant = await verifyGrantToken(token.grantToken, {
|
|
57
|
+
jwksUri: 'https://api.grantex.dev/.well-known/jwks.json',
|
|
58
|
+
});
|
|
59
|
+
console.log(grant.principalId); // 'usr_01J...'
|
|
60
|
+
|
|
61
|
+
// 5. Revoke when done
|
|
62
|
+
await grantex.tokens.revoke(grant.tokenId);
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Configuration
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
const grantex = new Grantex({
|
|
69
|
+
apiKey: 'gx_....', // or set GRANTEX_API_KEY env var
|
|
70
|
+
baseUrl: 'https://api.grantex.dev', // default
|
|
71
|
+
issuer: 'https://grantex.dev', // optional when token issuer differs from API host
|
|
72
|
+
jwksUri: 'https://api.grantex.dev/.well-known/jwks.json', // optional JWKS override
|
|
73
|
+
timeout: 30000, // request timeout in ms (default: 30s)
|
|
74
|
+
});
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
| Option | Type | Default | Description |
|
|
78
|
+
|--------|------|---------|-------------|
|
|
79
|
+
| `apiKey` | `string` | `process.env.GRANTEX_API_KEY` | API key for authentication |
|
|
80
|
+
| `baseUrl` | `string` | `https://api.grantex.dev` | Base URL of the Grantex API |
|
|
81
|
+
| `issuer` | `string` | derived from `jwksUri` | Expected JWT issuer for local signature verification |
|
|
82
|
+
| `jwksUri` | `string` | `${baseUrl}/.well-known/jwks.json` | URL from which the verifier retrieves signing keys |
|
|
83
|
+
| `timeout` | `number` | `30000` | Request timeout in milliseconds |
|
|
84
|
+
|
|
85
|
+
## OAuth Agent Profile Client
|
|
86
|
+
|
|
87
|
+
`OAuthAgentClient` implements the client role in the prepared
|
|
88
|
+
`draft-mishra-oauth-agent-grants-03` profile. It discovers and validates RFC
|
|
89
|
+
8414 metadata, creates an ES256 DPoP key by default, uses PAR and PKCE S256,
|
|
90
|
+
validates `state` and the RFC 9207 `iss` response parameter, rotates refresh
|
|
91
|
+
tokens, performs same-resource RFC 8693 attenuation, and creates DPoP proofs
|
|
92
|
+
for protected-resource requests.
|
|
93
|
+
|
|
94
|
+
```typescript
|
|
95
|
+
import { OAuthAgentClient } from '@grantex/sdk';
|
|
96
|
+
|
|
97
|
+
const client = await OAuthAgentClient.create({
|
|
98
|
+
issuer: 'https://grantex.dev',
|
|
99
|
+
clientId: 'ag_01J...',
|
|
100
|
+
redirectUri: 'https://agent.example/callback',
|
|
101
|
+
resource: 'https://api.example/resource',
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
const pending = await client.beginAuthorization({
|
|
105
|
+
scopes: ['grantex.resource.read'],
|
|
106
|
+
principalHint: 'principal@example.com',
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
// Redirect the Principal to pending.authorizationUrl. In the callback:
|
|
110
|
+
const tokens = await client.completeAuthorization(callbackUrl);
|
|
111
|
+
|
|
112
|
+
const response = await client.fetch(
|
|
113
|
+
'https://api.example/resource',
|
|
114
|
+
tokens.access_token,
|
|
115
|
+
);
|
|
116
|
+
|
|
117
|
+
const narrower = await client.attenuate(tokens.access_token, [
|
|
118
|
+
'grantex.resource.read',
|
|
119
|
+
]);
|
|
120
|
+
const refreshAttempt = crypto.randomUUID();
|
|
121
|
+
const rotated = await client.refresh(tokens.refresh_token!, {
|
|
122
|
+
idempotencyKey: refreshAttempt,
|
|
123
|
+
});
|
|
124
|
+
await client.revoke(rotated.refresh_token!, 'refresh_token');
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Persist the idempotency key with the old refresh token when lost-response
|
|
128
|
+
recovery must survive a caller restart. Repeating both within 300 seconds uses
|
|
129
|
+
a fresh DPoP proof and returns the exact committed token values with a
|
|
130
|
+
recalculated, non-extended `expires_in`. A
|
|
131
|
+
different key or DPoP identity is treated as refresh-token reuse and revokes
|
|
132
|
+
the token family. When no key is supplied, the client generates and retains one
|
|
133
|
+
for the old refresh token for five minutes in the current process.
|
|
134
|
+
|
|
135
|
+
Persist the generated key securely if an instance must survive process
|
|
136
|
+
restarts. Supply the matching `privateKey` and `publicJwk` to `create`; both are
|
|
137
|
+
required together. `principalHint` is optional account-discovery input and is
|
|
138
|
+
not proof of the Principal's identity; live approval still requires the
|
|
139
|
+
authorization server's passkey authentication. Plain HTTP endpoints are rejected unless
|
|
140
|
+
`allowInsecureLoopback` is enabled for local loopback testing. Revision `-02`
|
|
141
|
+
of the draft family is published as an active individual Internet-Draft;
|
|
142
|
+
revision `-03` is the working candidate implemented here. Neither is an
|
|
143
|
+
IETF-endorsed or independently certified standard.
|
|
144
|
+
|
|
145
|
+
## Agent prepaid wallets (SDK 0.5+)
|
|
146
|
+
|
|
147
|
+
`PrepaidWalletAgentClient` uses an `OAuthAgentClient` and DPoP access token to
|
|
148
|
+
list assigned wallets, reserve payments, and request threshold reloads.
|
|
149
|
+
`PrincipalPrepaidWalletClient` uses a short-lived principal-session token to
|
|
150
|
+
create and fund wallets, assign safe-default policy, manage layered spend
|
|
151
|
+
policies and exact payment approvals, approve reloads, inspect activity, and
|
|
152
|
+
block an assignment, wallet, or all wallets for one agent.
|
|
153
|
+
`DeveloperPrepaidWalletPolicyClient` manages tenant-level policy with the
|
|
154
|
+
developer API key.
|
|
155
|
+
|
|
156
|
+
The access token must include `wallet:spend` and each action scope used in a
|
|
157
|
+
payment (for example `weather:read`). Agent wallet listings intentionally omit
|
|
158
|
+
custody-provider IDs, wallet addresses, principal IDs, and wallet metadata.
|
|
159
|
+
|
|
160
|
+
```typescript
|
|
161
|
+
import {
|
|
162
|
+
PrepaidWalletAgentClient,
|
|
163
|
+
PrincipalPrepaidWalletClient,
|
|
164
|
+
} from '@grantex/sdk';
|
|
165
|
+
|
|
166
|
+
const agentWallets = new PrepaidWalletAgentClient({
|
|
167
|
+
oauthClient,
|
|
168
|
+
accessToken,
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
const principalWallets = new PrincipalPrepaidWalletClient({
|
|
172
|
+
baseUrl: 'https://api.grantex.dev',
|
|
173
|
+
sessionToken,
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
await principalWallets.createSpendPolicy({
|
|
177
|
+
name: 'Shared research budget',
|
|
178
|
+
scopeType: 'group',
|
|
179
|
+
scopeId: 'research-agents',
|
|
180
|
+
effect: 'limit',
|
|
181
|
+
maxAmount: '1000000',
|
|
182
|
+
windowType: 'month',
|
|
183
|
+
onExceed: 'require_approval',
|
|
184
|
+
purposes: ['research'],
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
const authorization = await agentWallets.authorizePayment({
|
|
188
|
+
amount: '1000',
|
|
189
|
+
asset: 'USDC',
|
|
190
|
+
network: 'grantex:prepaid',
|
|
191
|
+
recipient: 'merchant:weather-api',
|
|
192
|
+
resource: 'https://merchant.example/weather',
|
|
193
|
+
scope: 'weather:read',
|
|
194
|
+
merchantId: 'merchant:weather-api',
|
|
195
|
+
purpose: 'research',
|
|
196
|
+
projectId: 'climate-2026',
|
|
197
|
+
costCenter: 'engineering',
|
|
198
|
+
maxTimeoutSeconds: 120,
|
|
199
|
+
idempotencyKey: crypto.randomUUID(),
|
|
200
|
+
});
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
`authorizePayment` returns either a signed reservation or an
|
|
204
|
+
`approval_required` response. After the principal approves that exact request,
|
|
205
|
+
retry with its `approvalRequestId`, the same wallet, idempotency key, and all
|
|
206
|
+
original payment fields. Approval is short-lived and single-use.
|
|
207
|
+
|
|
208
|
+
Amounts are atomic-unit integer strings. Layered policy and exact approval are
|
|
209
|
+
available in `@grantex/sdk` 0.5.0 and later.
|
|
210
|
+
|
|
211
|
+
Self-hosted wallet deployments must also provide correct public resource
|
|
212
|
+
routing, migrations `091` and `092`, durable notification delivery, merchant-side
|
|
213
|
+
idempotency, and any external custody/provider integration. See [Prepaid Wallet
|
|
214
|
+
Production
|
|
215
|
+
Readiness](https://docs.grantex.dev/guides/prepaid-wallet-production);
|
|
216
|
+
installing the SDK alone does not provide those dependencies.
|
|
217
|
+
|
|
218
|
+
## Commerce V1 / OACP
|
|
219
|
+
|
|
220
|
+
The SDK includes a `commerce` resource for the Grantex Commerce V1 control
|
|
221
|
+
plane and OACP live-pilot flow.
|
|
222
|
+
|
|
223
|
+
```typescript
|
|
224
|
+
import { Grantex } from '@grantex/sdk';
|
|
225
|
+
|
|
226
|
+
const grantex = new Grantex({ apiKey: process.env.GRANTEX_API_KEY! });
|
|
227
|
+
|
|
228
|
+
// Public merchant publishing profile
|
|
229
|
+
const profile = await grantex.commerce.getProfile({
|
|
230
|
+
merchantId: 'mch_shopify_mgx0n6_22',
|
|
231
|
+
});
|
|
232
|
+
console.log(profile.merchant?.merchant_id);
|
|
233
|
+
|
|
234
|
+
// Catalog grounding
|
|
235
|
+
const catalog = await grantex.commerce.searchCatalog({
|
|
236
|
+
merchant_id: 'mch_shopify_mgx0n6_22',
|
|
237
|
+
query: 'shirt',
|
|
238
|
+
limit: 5,
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
// Agent cart creation. Commerce write paths require Idempotency-Key.
|
|
242
|
+
const cart = await grantex.commerce.createCart({
|
|
243
|
+
idempotencyKey: crypto.randomUUID(),
|
|
244
|
+
merchant_id: 'mch_shopify_mgx0n6_22',
|
|
245
|
+
currency: 'INR',
|
|
246
|
+
line_items: [
|
|
247
|
+
{ variant_id: String(catalog.items[0]?.['variant_id']), quantity: 1 },
|
|
248
|
+
],
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
// Consent request and Commerce Passport exchange
|
|
252
|
+
const consent = await grantex.commerce.createConsentRequest({
|
|
253
|
+
merchant_id: 'mch_shopify_mgx0n6_22',
|
|
254
|
+
passport_type: 'checkout',
|
|
255
|
+
max_amount: Number(cart.data['total_amount']),
|
|
256
|
+
currency: 'INR',
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
// Redirect the buyer to consent.data['consent_url'], then exchange after
|
|
260
|
+
// the consent request is granted.
|
|
261
|
+
const passport = await grantex.commerce.exchangeConsentForPassport({
|
|
262
|
+
consent_request_id: String(consent.data['consent_request_id']),
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
const payment = await grantex.commerce.createPaymentIntent({
|
|
266
|
+
idempotencyKey: crypto.randomUUID(),
|
|
267
|
+
merchant_id: 'mch_shopify_mgx0n6_22',
|
|
268
|
+
cart_id: String(cart.data['cart_id']),
|
|
269
|
+
passport_jwt: String(passport.data['passport_jwt']),
|
|
270
|
+
amount_minor_units: Number(cart.data['total_amount']),
|
|
271
|
+
currency: 'INR',
|
|
272
|
+
provider_key: 'plural',
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
const checkout = await grantex.commerce.createCheckoutLink(
|
|
276
|
+
String(payment.data['payment_intent_id']),
|
|
277
|
+
{
|
|
278
|
+
idempotencyKey: crypto.randomUUID(),
|
|
279
|
+
passport_jwt: String(passport.data['passport_jwt']),
|
|
280
|
+
success_url: 'https://buyer.example/success',
|
|
281
|
+
cancel_url: 'https://buyer.example/cancel',
|
|
282
|
+
},
|
|
283
|
+
);
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
Plural webhook intake is available at
|
|
287
|
+
`https://api.grantex.dev/v1/webhooks/providers/plural`. Provider webhooks are
|
|
288
|
+
normally called by the provider dashboard, not by application code. The SDK
|
|
289
|
+
also exposes `grantex.commerce.getOpsHealth()` and
|
|
290
|
+
`grantex.commerce.listProviderWebhookEvents()` for operator health checks.
|
|
291
|
+
|
|
292
|
+
## PKCE Support
|
|
293
|
+
|
|
294
|
+
The SDK includes built-in PKCE (Proof Key for Code Exchange) support using the S256 method for secure authorization flows:
|
|
295
|
+
|
|
296
|
+
```typescript
|
|
297
|
+
import { Grantex, generatePkce } from '@grantex/sdk';
|
|
298
|
+
|
|
299
|
+
const grantex = new Grantex({ apiKey: 'YOUR_API_KEY' });
|
|
300
|
+
|
|
301
|
+
// 1. Generate a PKCE challenge
|
|
302
|
+
const pkce = generatePkce();
|
|
303
|
+
// pkce.codeVerifier — random 43-char string (keep secret)
|
|
304
|
+
// pkce.codeChallenge — SHA-256 hash of verifier (send to server)
|
|
305
|
+
// pkce.codeChallengeMethod — 'S256'
|
|
306
|
+
|
|
307
|
+
// 2. Pass the challenge when requesting authorization
|
|
308
|
+
const { consentUrl } = await grantex.authorize({
|
|
309
|
+
agentId: 'ag_01J...',
|
|
310
|
+
userId: 'usr_01J...',
|
|
311
|
+
scopes: ['files:read'],
|
|
312
|
+
codeChallenge: pkce.codeChallenge,
|
|
313
|
+
codeChallengeMethod: pkce.codeChallengeMethod,
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
// 3. Exchange the code with the verifier
|
|
317
|
+
const token = await grantex.tokens.exchange({
|
|
318
|
+
code: 'auth_code_from_redirect',
|
|
319
|
+
agentId: 'ag_01J...',
|
|
320
|
+
codeVerifier: pkce.codeVerifier,
|
|
321
|
+
});
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
---
|
|
325
|
+
|
|
326
|
+
## API Reference
|
|
327
|
+
|
|
328
|
+
### Authorization
|
|
329
|
+
|
|
330
|
+
#### `grantex.authorize(params)`
|
|
331
|
+
|
|
332
|
+
Initiate the delegated authorization flow. Returns a consent URL to redirect the user to.
|
|
333
|
+
|
|
334
|
+
```typescript
|
|
335
|
+
const request = await grantex.authorize({
|
|
336
|
+
agentId: 'ag_01J...',
|
|
337
|
+
userId: 'usr_01J...',
|
|
338
|
+
scopes: ['files:read', 'email:send'],
|
|
339
|
+
audience: 'https://api.example.com', // optional; becomes the JWT aud claim
|
|
340
|
+
expiresIn: '24h', // optional
|
|
341
|
+
redirectUri: 'https://...' // optional
|
|
342
|
+
});
|
|
343
|
+
|
|
344
|
+
console.log(request.consentUrl); // redirect user here
|
|
345
|
+
console.log(request.authRequestId); // track the request
|
|
346
|
+
console.log(request.expiresAt); // ISO 8601 timestamp
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
**Returns**: `AuthorizationRequest`
|
|
350
|
+
|
|
351
|
+
| Field | Type | Description |
|
|
352
|
+
|-------|------|-------------|
|
|
353
|
+
| `authRequestId` | `string` | Unique ID for this authorization request |
|
|
354
|
+
| `consentUrl` | `string` | URL to redirect the user to for consent |
|
|
355
|
+
| `agentId` | `string` | The agent requesting authorization |
|
|
356
|
+
| `principalId` | `string` | The user being asked for consent |
|
|
357
|
+
| `scopes` | `string[]` | Requested scopes |
|
|
358
|
+
| `expiresAt` | `string` | When the request expires (ISO 8601) |
|
|
359
|
+
| `status` | `string` | `'pending'`, `'approved'`, `'denied'`, or `'expired'` |
|
|
360
|
+
|
|
361
|
+
---
|
|
362
|
+
|
|
363
|
+
### Agents
|
|
364
|
+
|
|
365
|
+
#### `grantex.agents.register(params)`
|
|
366
|
+
|
|
367
|
+
Register a new AI agent.
|
|
368
|
+
|
|
369
|
+
```typescript
|
|
370
|
+
const agent = await grantex.agents.register({
|
|
371
|
+
name: 'Code Review Bot',
|
|
372
|
+
description: 'Reviews pull requests and suggests improvements',
|
|
373
|
+
scopes: ['repo:read', 'pr:comment'],
|
|
374
|
+
});
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
#### `grantex.agents.get(agentId)`
|
|
378
|
+
|
|
379
|
+
```typescript
|
|
380
|
+
const agent = await grantex.agents.get('ag_01J...');
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
#### `grantex.agents.list()`
|
|
384
|
+
|
|
385
|
+
```typescript
|
|
386
|
+
const { agents } = await grantex.agents.list();
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
#### `grantex.agents.update(agentId, params)`
|
|
390
|
+
|
|
391
|
+
```typescript
|
|
392
|
+
const agent = await grantex.agents.update('ag_01J...', {
|
|
393
|
+
name: 'Updated Name',
|
|
394
|
+
scopes: ['repo:read', 'pr:comment', 'pr:approve'],
|
|
395
|
+
});
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
#### `grantex.agents.delete(agentId)`
|
|
399
|
+
|
|
400
|
+
```typescript
|
|
401
|
+
await grantex.agents.delete('ag_01J...');
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
---
|
|
405
|
+
|
|
406
|
+
### Grants
|
|
407
|
+
|
|
408
|
+
#### `grantex.grants.get(grantId)`
|
|
409
|
+
|
|
410
|
+
```typescript
|
|
411
|
+
const grant = await grantex.grants.get('grnt_01J...');
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
#### `grantex.grants.list(params?)`
|
|
415
|
+
|
|
416
|
+
```typescript
|
|
417
|
+
const { grants } = await grantex.grants.list({
|
|
418
|
+
agentId: 'ag_01J...', // optional filter
|
|
419
|
+
principalId: 'usr_01J...', // optional filter
|
|
420
|
+
status: 'active', // 'active' | 'revoked' | 'expired'
|
|
421
|
+
page: 1,
|
|
422
|
+
pageSize: 20,
|
|
423
|
+
});
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
#### `grantex.grants.revoke(grantId)`
|
|
427
|
+
|
|
428
|
+
```typescript
|
|
429
|
+
await grantex.grants.revoke('grnt_01J...');
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
#### `grantex.grants.delegate(params)`
|
|
433
|
+
|
|
434
|
+
Create a delegated sub-agent grant (per [SPEC Section 9](https://github.com/mishrasanjeev/grantex/blob/main/SPEC.md)).
|
|
435
|
+
|
|
436
|
+
```typescript
|
|
437
|
+
const delegation = await grantex.grants.delegate({
|
|
438
|
+
parentGrantToken: 'eyJhbG...',
|
|
439
|
+
subAgentId: 'ag_02K...',
|
|
440
|
+
scopes: ['files:read'], // must be subset of parent scopes
|
|
441
|
+
expiresIn: '1h', // optional, cannot exceed parent
|
|
442
|
+
});
|
|
443
|
+
|
|
444
|
+
console.log(delegation.grantToken); // new JWT for the sub-agent
|
|
445
|
+
console.log(delegation.grantId);
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
#### `grantex.grants.verify(token)`
|
|
449
|
+
|
|
450
|
+
Verify a grant token via the API (online verification with real-time revocation check).
|
|
451
|
+
|
|
452
|
+
```typescript
|
|
453
|
+
const verified = await grantex.grants.verify('eyJhbG...');
|
|
454
|
+
console.log(verified.principalId);
|
|
455
|
+
console.log(verified.scopes);
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
Throws `GrantexTokenError` when the token is inactive, revoked, expired, or otherwise unusable.
|
|
459
|
+
|
|
460
|
+
---
|
|
461
|
+
|
|
462
|
+
### Tokens
|
|
463
|
+
|
|
464
|
+
#### `grantex.tokens.exchange(params)`
|
|
465
|
+
|
|
466
|
+
Exchange an authorization code for a grant token. This is the standard way to obtain a grant token after the user approves the consent request.
|
|
467
|
+
|
|
468
|
+
```typescript
|
|
469
|
+
const token = await grantex.tokens.exchange({
|
|
470
|
+
code: 'auth_code_from_redirect', // from your redirect callback
|
|
471
|
+
agentId: 'ag_01J...',
|
|
472
|
+
});
|
|
473
|
+
|
|
474
|
+
console.log(token.grantToken); // RS256-signed JWT — pass this to your agent
|
|
475
|
+
console.log(token.grantId); // grant record ID
|
|
476
|
+
console.log(token.scopes); // granted scopes
|
|
477
|
+
console.log(token.expiresAt); // ISO 8601 expiry
|
|
478
|
+
console.log(token.refreshToken); // for token refresh
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
**Returns**: `ExchangeTokenResponse`
|
|
482
|
+
|
|
483
|
+
| Field | Type | Description |
|
|
484
|
+
|-------|------|-------------|
|
|
485
|
+
| `grantToken` | `string` | Signed RS256 JWT — the agent's bearer credential |
|
|
486
|
+
| `grantId` | `string` | Grant record ID |
|
|
487
|
+
| `scopes` | `string[]` | Scopes the user approved |
|
|
488
|
+
| `expiresAt` | `string` | Underlying grant expiry (ISO 8601) |
|
|
489
|
+
| `refreshToken` | `string` | Refresh token for rotating credentials while the grant remains active |
|
|
490
|
+
|
|
491
|
+
Refresh tokens are single-use and rotate on every accepted refresh. If a response is lost after commit, retry the same previous refresh token and idempotency key. The SDK retains an omitted key for five minutes in the current process; persist an explicit `idempotencyKey` with the old token when recovery must survive restart or failover. Grantex returns the already-rotated pair without extending `expiresAt`; after grant expiry, re-authorize.
|
|
492
|
+
|
|
493
|
+
---
|
|
494
|
+
|
|
495
|
+
#### `grantex.tokens.verify(token)`
|
|
496
|
+
|
|
497
|
+
Online token verification with revocation status.
|
|
498
|
+
|
|
499
|
+
```typescript
|
|
500
|
+
const result = await grantex.tokens.verify('eyJhbG...');
|
|
501
|
+
if (result.valid) {
|
|
502
|
+
console.log(result.scopes); // ['files:read']
|
|
503
|
+
console.log(result.principal); // 'usr_01J...'
|
|
504
|
+
console.log(result.agent); // 'ag_01J...'
|
|
505
|
+
console.log(result.grantId);
|
|
506
|
+
console.log(result.expiresAt);
|
|
507
|
+
}
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
#### `grantex.tokens.revoke(tokenId)`
|
|
511
|
+
|
|
512
|
+
Revoke a token by its JTI. Blocklisted in Redis immediately; all sub-delegated tokens are also invalidated.
|
|
513
|
+
|
|
514
|
+
```typescript
|
|
515
|
+
await grantex.tokens.revoke('tok_01J...');
|
|
516
|
+
```
|
|
517
|
+
|
|
518
|
+
---
|
|
519
|
+
|
|
520
|
+
### Local Token Verification
|
|
521
|
+
|
|
522
|
+
#### `verifyGrantToken(token, options)`
|
|
523
|
+
|
|
524
|
+
Verify a grant token locally with RS256 signing keys retrieved from the published JWKS URL. A bounded process-level resolver cache reuses valid keys for each normalized JWKS URI; initial retrieval and key-rotation refreshes may require network access.
|
|
525
|
+
|
|
526
|
+
```typescript
|
|
527
|
+
import { verifyGrantToken } from '@grantex/sdk';
|
|
528
|
+
|
|
529
|
+
const grant = await verifyGrantToken('eyJhbG...', {
|
|
530
|
+
jwksUri: 'https://api.grantex.dev/.well-known/jwks.json',
|
|
531
|
+
issuer: 'https://grantex.dev', // optional when issuer differs from JWKS host
|
|
532
|
+
requiredScopes: ['files:read'], // optional — rejects if missing
|
|
533
|
+
audience: 'https://myapp.com', // optional — validates aud claim
|
|
534
|
+
});
|
|
535
|
+
```
|
|
536
|
+
|
|
537
|
+
If you call a deployment through a raw Cloud Run URL or another internal host, but the service signs tokens for a canonical public domain, pass `issuer` explicitly. Otherwise issuer validation will reject a valid token because the JWT `iss` claim will not match the transport host.
|
|
538
|
+
|
|
539
|
+
**Returns**: `VerifiedGrant`
|
|
540
|
+
|
|
541
|
+
| Field | Type | Description |
|
|
542
|
+
|-------|------|-------------|
|
|
543
|
+
| `tokenId` | `string` | Unique token ID (JWT `jti` claim) |
|
|
544
|
+
| `grantId` | `string` | Grant record ID |
|
|
545
|
+
| `principalId` | `string` | User who authorized the grant (`sub` claim) |
|
|
546
|
+
| `agentDid` | `string` | Agent's DID (`agt` claim) |
|
|
547
|
+
| `developerId` | `string` | Developer org ID (`dev` claim) |
|
|
548
|
+
| `scopes` | `string[]` | Granted scopes (`scp` claim) |
|
|
549
|
+
| `issuedAt` | `number` | Issued-at timestamp (seconds since epoch) |
|
|
550
|
+
| `expiresAt` | `number` | Expiry timestamp (seconds since epoch) |
|
|
551
|
+
| `parentAgentDid` | `string?` | Parent agent DID (delegation only) |
|
|
552
|
+
| `parentGrantId` | `string?` | Parent grant ID (delegation only) |
|
|
553
|
+
| `delegationDepth` | `number?` | Delegation depth (0 = root) |
|
|
554
|
+
|
|
555
|
+
---
|
|
556
|
+
|
|
557
|
+
### Audit
|
|
558
|
+
|
|
559
|
+
#### `grantex.audit.log(params)`
|
|
560
|
+
|
|
561
|
+
Log an auditable action taken by an agent.
|
|
562
|
+
|
|
563
|
+
```typescript
|
|
564
|
+
const entry = await grantex.audit.log({
|
|
565
|
+
agentId: 'ag_01J...',
|
|
566
|
+
agentDid: 'did:grantex:ag_01J...',
|
|
567
|
+
grantId: 'grnt_01J...',
|
|
568
|
+
principalId: 'usr_01J...',
|
|
569
|
+
action: 'email:send',
|
|
570
|
+
metadata: { to: 'user@example.com', subject: 'Hello' },
|
|
571
|
+
status: 'success', // 'success' | 'failure' | 'blocked'
|
|
572
|
+
});
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
#### `grantex.audit.list(params?)`
|
|
576
|
+
|
|
577
|
+
```typescript
|
|
578
|
+
const { entries } = await grantex.audit.list({
|
|
579
|
+
agentId: 'ag_01J...',
|
|
580
|
+
action: 'email:send',
|
|
581
|
+
since: '2026-01-01T00:00:00Z',
|
|
582
|
+
until: '2026-02-28T23:59:59Z',
|
|
583
|
+
page: 1,
|
|
584
|
+
pageSize: 50,
|
|
585
|
+
});
|
|
586
|
+
```
|
|
587
|
+
|
|
588
|
+
#### `grantex.audit.get(entryId)`
|
|
589
|
+
|
|
590
|
+
```typescript
|
|
591
|
+
const entry = await grantex.audit.get('alog_01J...');
|
|
592
|
+
console.log(entry.hash); // SHA-256 hash for tamper evidence
|
|
593
|
+
console.log(entry.prevHash); // previous entry hash (chain integrity)
|
|
594
|
+
```
|
|
595
|
+
|
|
596
|
+
---
|
|
597
|
+
|
|
598
|
+
### Webhooks
|
|
599
|
+
|
|
600
|
+
#### `grantex.webhooks.create(params)`
|
|
601
|
+
|
|
602
|
+
```typescript
|
|
603
|
+
const webhook = await grantex.webhooks.create({
|
|
604
|
+
url: 'https://myapp.com/webhooks/grantex',
|
|
605
|
+
events: ['grant.created', 'grant.revoked', 'token.issued'],
|
|
606
|
+
});
|
|
607
|
+
console.log(webhook.secret); // HMAC secret for signature verification
|
|
608
|
+
```
|
|
609
|
+
|
|
610
|
+
#### `grantex.webhooks.list()`
|
|
611
|
+
|
|
612
|
+
```typescript
|
|
613
|
+
const { webhooks } = await grantex.webhooks.list();
|
|
614
|
+
```
|
|
615
|
+
|
|
616
|
+
#### `grantex.webhooks.delete(webhookId)`
|
|
617
|
+
|
|
618
|
+
```typescript
|
|
619
|
+
await grantex.webhooks.delete('wh_01J...');
|
|
620
|
+
```
|
|
621
|
+
|
|
622
|
+
#### Webhook Signature Verification
|
|
623
|
+
|
|
624
|
+
```typescript
|
|
625
|
+
import { verifyWebhookSignature } from '@grantex/sdk';
|
|
626
|
+
|
|
627
|
+
// In your webhook handler
|
|
628
|
+
verifyWebhookSignature(requestBody, signatureHeader, webhookSecret);
|
|
629
|
+
```
|
|
630
|
+
|
|
631
|
+
---
|
|
632
|
+
|
|
633
|
+
### Policies
|
|
634
|
+
|
|
635
|
+
Define fine-grained access control rules for agents.
|
|
636
|
+
|
|
637
|
+
#### `grantex.policies.create(params)`
|
|
638
|
+
|
|
639
|
+
```typescript
|
|
640
|
+
const policy = await grantex.policies.create({
|
|
641
|
+
name: 'Block after hours',
|
|
642
|
+
effect: 'deny',
|
|
643
|
+
priority: 10,
|
|
644
|
+
scopes: ['email:send'],
|
|
645
|
+
timeOfDayStart: '18:00',
|
|
646
|
+
timeOfDayEnd: '08:00',
|
|
647
|
+
});
|
|
648
|
+
```
|
|
649
|
+
|
|
650
|
+
#### `grantex.policies.list()`
|
|
651
|
+
|
|
652
|
+
```typescript
|
|
653
|
+
const { policies, total } = await grantex.policies.list();
|
|
654
|
+
```
|
|
655
|
+
|
|
656
|
+
#### `grantex.policies.get(policyId)` / `update(policyId, params)` / `delete(policyId)`
|
|
657
|
+
|
|
658
|
+
```typescript
|
|
659
|
+
const policy = await grantex.policies.get('pol_01J...');
|
|
660
|
+
|
|
661
|
+
await grantex.policies.update('pol_01J...', { effect: 'allow' });
|
|
662
|
+
|
|
663
|
+
await grantex.policies.delete('pol_01J...');
|
|
664
|
+
```
|
|
665
|
+
|
|
666
|
+
---
|
|
667
|
+
|
|
668
|
+
### Compliance
|
|
669
|
+
|
|
670
|
+
#### `grantex.compliance.getSummary(params?)`
|
|
671
|
+
|
|
672
|
+
```typescript
|
|
673
|
+
const summary = await grantex.compliance.getSummary({
|
|
674
|
+
since: '2026-01-01T00:00:00Z',
|
|
675
|
+
until: '2026-02-28T23:59:59Z',
|
|
676
|
+
});
|
|
677
|
+
console.log(summary.agents); // { total, active, suspended, revoked }
|
|
678
|
+
console.log(summary.grants); // { total, active, revoked, expired }
|
|
679
|
+
console.log(summary.auditEntries); // { total, success, failure, blocked }
|
|
680
|
+
```
|
|
681
|
+
|
|
682
|
+
#### `grantex.compliance.exportGrants(params?)`
|
|
683
|
+
|
|
684
|
+
```typescript
|
|
685
|
+
const { grants, total } = await grantex.compliance.exportGrants({
|
|
686
|
+
status: 'active',
|
|
687
|
+
});
|
|
688
|
+
```
|
|
689
|
+
|
|
690
|
+
#### `grantex.compliance.exportAudit(params?)`
|
|
691
|
+
|
|
692
|
+
```typescript
|
|
693
|
+
const { entries, total } = await grantex.compliance.exportAudit({
|
|
694
|
+
since: '2026-01-01T00:00:00Z',
|
|
695
|
+
agentId: 'ag_01J...',
|
|
696
|
+
});
|
|
697
|
+
```
|
|
698
|
+
|
|
699
|
+
#### `grantex.compliance.evidencePack(params?)`
|
|
700
|
+
|
|
701
|
+
Generate a full SOC 2 / GDPR evidence pack with audit chain integrity verification.
|
|
702
|
+
|
|
703
|
+
```typescript
|
|
704
|
+
const pack = await grantex.compliance.evidencePack({
|
|
705
|
+
framework: 'soc2', // 'soc2' | 'gdpr' | 'all'
|
|
706
|
+
since: '2026-01-01T00:00:00Z',
|
|
707
|
+
});
|
|
708
|
+
|
|
709
|
+
console.log(pack.chainIntegrity.valid); // true
|
|
710
|
+
console.log(pack.chainIntegrity.checkedEntries); // 1042
|
|
711
|
+
console.log(pack.summary);
|
|
712
|
+
console.log(pack.grants);
|
|
713
|
+
console.log(pack.auditEntries);
|
|
714
|
+
console.log(pack.policies);
|
|
715
|
+
```
|
|
716
|
+
|
|
717
|
+
---
|
|
718
|
+
|
|
719
|
+
### Anomaly Detection
|
|
720
|
+
|
|
721
|
+
In version 0.7.0, `grantex.anomalies.getResponsePolicy()` and
|
|
722
|
+
`grantex.anomalies.setResponsePolicy('alert_only')` control the account-wide
|
|
723
|
+
response of the legacy detector when the server operator enables
|
|
724
|
+
`IRREGULARITY_RESPONSE_POLICY_ENABLED=true`. Default behavior revokes active
|
|
725
|
+
grants for a high/critical finding's agent. Alert-only retains findings and
|
|
726
|
+
events without that automatic revocation. This setting does not disable other
|
|
727
|
+
security controls.
|
|
728
|
+
|
|
729
|
+
Version 0.7.0 also supports
|
|
730
|
+
`grantex.webauthn.createEnrollmentSession({ principalId, authRequestId? })`.
|
|
731
|
+
Call it only on your server after authenticating the customer. Deliver the
|
|
732
|
+
returned one-use hosted link to that exact customer; never expose the API key
|
|
733
|
+
or log the link. Hosted enrollment requires the server's default-off
|
|
734
|
+
`PASSKEY_ENROLLMENT_ENABLED=true` setting. Live consent has no password or
|
|
735
|
+
sandbox fallback.
|
|
736
|
+
|
|
737
|
+
#### `grantex.anomalies.detect()`
|
|
738
|
+
|
|
739
|
+
Run anomaly detection across all agents.
|
|
740
|
+
|
|
741
|
+
```typescript
|
|
742
|
+
const { anomalies, total } = await grantex.anomalies.detect();
|
|
743
|
+
// anomaly types: 'rate_spike' | 'high_failure_rate' | 'new_principal' | 'off_hours_activity'
|
|
744
|
+
```
|
|
745
|
+
|
|
746
|
+
#### `grantex.anomalies.list(params?)`
|
|
747
|
+
|
|
748
|
+
```typescript
|
|
749
|
+
const { anomalies } = await grantex.anomalies.list({
|
|
750
|
+
unacknowledged: true, // only open anomalies
|
|
751
|
+
});
|
|
752
|
+
```
|
|
753
|
+
|
|
754
|
+
#### `grantex.anomalies.acknowledge(anomalyId)`
|
|
755
|
+
|
|
756
|
+
```typescript
|
|
757
|
+
const anomaly = await grantex.anomalies.acknowledge('anom_01J...');
|
|
758
|
+
```
|
|
759
|
+
|
|
760
|
+
---
|
|
761
|
+
|
|
762
|
+
### Billing
|
|
763
|
+
|
|
764
|
+
#### `grantex.billing.getSubscription()`
|
|
765
|
+
|
|
766
|
+
```typescript
|
|
767
|
+
const sub = await grantex.billing.getSubscription();
|
|
768
|
+
console.log(sub.plan); // 'free' | 'pro' | 'enterprise'
|
|
769
|
+
console.log(sub.status); // 'active' | 'past_due' | 'canceled'
|
|
770
|
+
console.log(sub.currentPeriodEnd); // ISO 8601 or null
|
|
771
|
+
```
|
|
772
|
+
|
|
773
|
+
#### `grantex.billing.createCheckout(params)`
|
|
774
|
+
|
|
775
|
+
```typescript
|
|
776
|
+
const { checkoutUrl } = await grantex.billing.createCheckout({
|
|
777
|
+
plan: 'pro',
|
|
778
|
+
successUrl: 'https://myapp.com/billing/success',
|
|
779
|
+
cancelUrl: 'https://myapp.com/billing/cancel',
|
|
780
|
+
});
|
|
781
|
+
// Redirect user to checkoutUrl
|
|
782
|
+
```
|
|
783
|
+
|
|
784
|
+
#### `grantex.billing.createPortal(params)`
|
|
785
|
+
|
|
786
|
+
```typescript
|
|
787
|
+
const { portalUrl } = await grantex.billing.createPortal({
|
|
788
|
+
returnUrl: 'https://myapp.com/settings',
|
|
789
|
+
});
|
|
790
|
+
```
|
|
791
|
+
|
|
792
|
+
---
|
|
793
|
+
|
|
794
|
+
### SCIM 2.0 Provisioning
|
|
795
|
+
|
|
796
|
+
Sync users from your identity provider.
|
|
797
|
+
|
|
798
|
+
#### Token Management
|
|
799
|
+
|
|
800
|
+
```typescript
|
|
801
|
+
// Create a SCIM bearer token
|
|
802
|
+
const { token, id, label } = await grantex.scim.createToken({
|
|
803
|
+
label: 'Okta SCIM integration',
|
|
804
|
+
});
|
|
805
|
+
// token is returned once — store it securely
|
|
806
|
+
|
|
807
|
+
const { tokens } = await grantex.scim.listTokens();
|
|
808
|
+
|
|
809
|
+
await grantex.scim.revokeToken('scimtok_01J...');
|
|
810
|
+
```
|
|
811
|
+
|
|
812
|
+
#### User Operations
|
|
813
|
+
|
|
814
|
+
```typescript
|
|
815
|
+
// List provisioned users
|
|
816
|
+
const { Resources, totalResults } = await grantex.scim.listUsers({
|
|
817
|
+
startIndex: 1,
|
|
818
|
+
count: 100,
|
|
819
|
+
});
|
|
820
|
+
|
|
821
|
+
// Create a user
|
|
822
|
+
const user = await grantex.scim.createUser({
|
|
823
|
+
userName: 'alice@example.com',
|
|
824
|
+
displayName: 'Alice',
|
|
825
|
+
emails: [{ value: 'alice@example.com', primary: true }],
|
|
826
|
+
});
|
|
827
|
+
|
|
828
|
+
// Get / Replace / Patch / Delete
|
|
829
|
+
const user = await grantex.scim.getUser('scimusr_01J...');
|
|
830
|
+
|
|
831
|
+
await grantex.scim.replaceUser('scimusr_01J...', { userName: 'alice@new.com' });
|
|
832
|
+
|
|
833
|
+
await grantex.scim.updateUser('scimusr_01J...', [
|
|
834
|
+
{ op: 'replace', path: 'active', value: false },
|
|
835
|
+
]);
|
|
836
|
+
|
|
837
|
+
await grantex.scim.deleteUser('scimusr_01J...');
|
|
838
|
+
```
|
|
839
|
+
|
|
840
|
+
---
|
|
841
|
+
|
|
842
|
+
### SSO (OIDC)
|
|
843
|
+
|
|
844
|
+
#### `grantex.sso.createConfig(params)`
|
|
845
|
+
|
|
846
|
+
```typescript
|
|
847
|
+
const config = await grantex.sso.createConfig({
|
|
848
|
+
issuerUrl: 'https://accounts.google.com',
|
|
849
|
+
clientId: 'xxx.apps.googleusercontent.com',
|
|
850
|
+
clientSecret: 'GOCSPX-...',
|
|
851
|
+
redirectUri: 'https://myapp.com/auth/callback',
|
|
852
|
+
});
|
|
853
|
+
```
|
|
854
|
+
|
|
855
|
+
#### `grantex.sso.getConfig()` / `deleteConfig()`
|
|
856
|
+
|
|
857
|
+
```typescript
|
|
858
|
+
const config = await grantex.sso.getConfig();
|
|
859
|
+
await grantex.sso.deleteConfig();
|
|
860
|
+
```
|
|
861
|
+
|
|
862
|
+
#### `grantex.sso.getLoginUrl(org)`
|
|
863
|
+
|
|
864
|
+
```typescript
|
|
865
|
+
const { authorizeUrl } = await grantex.sso.getLoginUrl('dev_01J...');
|
|
866
|
+
// Redirect user to authorizeUrl
|
|
867
|
+
```
|
|
868
|
+
|
|
869
|
+
#### `grantex.sso.handleCallback(code, state)`
|
|
870
|
+
|
|
871
|
+
```typescript
|
|
872
|
+
const { email, name, sub, developerId } = await grantex.sso.handleCallback(code, state);
|
|
873
|
+
```
|
|
874
|
+
|
|
875
|
+
---
|
|
876
|
+
|
|
877
|
+
## Error Handling
|
|
878
|
+
|
|
879
|
+
All errors extend `GrantexError`:
|
|
880
|
+
|
|
881
|
+
```typescript
|
|
882
|
+
import {
|
|
883
|
+
GrantexError, // base class
|
|
884
|
+
GrantexApiError, // API returned an error (has statusCode, body, requestId)
|
|
885
|
+
GrantexAuthError, // 401/403 — invalid or missing API key
|
|
886
|
+
GrantexTokenError, // token verification failed (invalid signature, expired, etc.)
|
|
887
|
+
GrantexNetworkError, // network failure (timeout, DNS, connection refused)
|
|
888
|
+
} from '@grantex/sdk';
|
|
889
|
+
|
|
890
|
+
try {
|
|
891
|
+
await grantex.agents.get('ag_invalid');
|
|
892
|
+
} catch (err) {
|
|
893
|
+
if (err instanceof GrantexAuthError) {
|
|
894
|
+
console.error('Auth failed:', err.statusCode); // 401 or 403
|
|
895
|
+
console.error('Request ID:', err.requestId);
|
|
896
|
+
} else if (err instanceof GrantexApiError) {
|
|
897
|
+
console.error('API error:', err.statusCode, err.body);
|
|
898
|
+
} else if (err instanceof GrantexNetworkError) {
|
|
899
|
+
console.error('Network error:', err.message, err.cause);
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
```
|
|
903
|
+
|
|
904
|
+
---
|
|
905
|
+
|
|
906
|
+
## Requirements
|
|
907
|
+
|
|
908
|
+
- Node.js 18+
|
|
909
|
+
- ESM (`"type": "module"` in your package.json, or use dynamic `import()`)
|
|
910
|
+
|
|
911
|
+
## Links
|
|
912
|
+
|
|
913
|
+
- [GitHub](https://github.com/mishrasanjeev/grantex)
|
|
914
|
+
- [Protocol Specification](https://github.com/mishrasanjeev/grantex/blob/main/SPEC.md)
|
|
915
|
+
- [Python SDK](https://pypi.org/project/grantex/)
|
|
916
|
+
- [API Reference](https://api.grantex.dev/.well-known/jwks.json)
|
|
917
|
+
|
|
918
|
+
## Scope Enforcement (v0.3.1)
|
|
919
|
+
|
|
920
|
+
Enforce tool-level permissions on **any connector** — define your own manifests or use the 53 pre-built ones.
|
|
921
|
+
|
|
922
|
+
```typescript
|
|
923
|
+
import { Grantex, ToolManifest, Permission } from '@grantex/sdk';
|
|
924
|
+
|
|
925
|
+
const grantex = new Grantex({ apiKey: 'gx_...' });
|
|
926
|
+
|
|
927
|
+
// Define a manifest for any connector — no dependency on Grantex to add support
|
|
928
|
+
grantex.loadManifest(new ToolManifest({
|
|
929
|
+
connector: 'my-crm',
|
|
930
|
+
tools: { search: Permission.READ, create_deal: Permission.WRITE, delete_account: Permission.DELETE },
|
|
931
|
+
}));
|
|
932
|
+
|
|
933
|
+
const result = await grantex.enforce({ grantToken: token, connector: 'my-crm', tool: 'delete_account' });
|
|
934
|
+
// result.allowed = false — "write scope does not permit delete operations"
|
|
935
|
+
```
|
|
936
|
+
|
|
937
|
+
**Features:**
|
|
938
|
+
- `enforce()` — verify JWT + check tool permission via manifest, <1ms
|
|
939
|
+
- `wrapTool()` — auto-enforce on LangChain tools
|
|
940
|
+
- `enforceMiddleware()` — Express/Fastify HTTP middleware
|
|
941
|
+
- Define custom manifests for any connector: inline, from JSON, or auto-generated via CLI
|
|
942
|
+
- 53 pre-built manifests included (Salesforce, HubSpot, Jira, Stripe, SAP, S3, and 47 more)
|
|
943
|
+
- Permission hierarchy: `admin > delete > write > read`
|
|
944
|
+
- Permissive mode for migration (`enforceMode: 'permissive'`)
|
|
945
|
+
|
|
946
|
+
[Full Guide](https://docs.grantex.dev/guides/scope-enforcement) | [API Reference](https://docs.grantex.dev/sdks/typescript/enforce)
|
|
947
|
+
|
|
948
|
+
## Grantex Ecosystem
|
|
949
|
+
|
|
950
|
+
| Package | Description |
|
|
951
|
+
|---|---|
|
|
952
|
+
| [`grantex`](https://pypi.org/project/grantex/) | Python SDK |
|
|
953
|
+
| [`@grantex/langchain`](https://www.npmjs.com/package/@grantex/langchain) | LangChain integration |
|
|
954
|
+
| [`@grantex/autogen`](https://www.npmjs.com/package/@grantex/autogen) | AutoGen integration |
|
|
955
|
+
| [`@grantex/vercel-ai`](https://www.npmjs.com/package/@grantex/vercel-ai) | Vercel AI SDK integration |
|
|
956
|
+
| [`grantex-crewai`](https://pypi.org/project/grantex-crewai/) | CrewAI integration |
|
|
957
|
+
| [`grantex-openai-agents`](https://pypi.org/project/grantex-openai-agents/) | OpenAI Agents SDK integration |
|
|
958
|
+
| [`grantex-adk`](https://pypi.org/project/grantex-adk/) | Google ADK integration |
|
|
959
|
+
| [`@grantex/mcp`](https://www.npmjs.com/package/@grantex/mcp) | MCP server for Claude Desktop / Cursor / Windsurf |
|
|
960
|
+
| [`@grantex/cli`](https://www.npmjs.com/package/@grantex/cli) | Command-line tool |
|
|
961
|
+
|
|
962
|
+
## License
|
|
963
|
+
|
|
964
|
+
[Apache 2.0](https://github.com/mishrasanjeev/grantex/blob/main/LICENSE)
|
|
965
|
+
|
|
966
|
+
## Ownership
|
|
967
|
+
|
|
968
|
+
Grantex is owned by Orchestrum Technologies LLP. Inventor and owner: Sanjeev Kumar. Ownership contact: [sanjeev@orchestrum.in](mailto:sanjeev@orchestrum.in) or [mishra.sanjeev@gmail.com](mailto:mishra.sanjeev@gmail.com).
|
|
969
|
+
|
|
970
|
+
## Source Development
|
|
971
|
+
|
|
972
|
+
Use Node.js 24 LTS and `npm ci` to build or test this checkout with Vitest 5.
|
|
973
|
+
Repository validation steps are in [the dependency upgrade guide](https://docs.grantex.dev/guides/dependency-updates).
|
|
974
|
+
Source-tooling requirements are separate from published package runtime support.
|