signify-ts 0.1.1 → 0.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.
Files changed (115) hide show
  1. package/README.md +96 -47
  2. package/dist/buffer-polyfill.d.ts +1 -0
  3. package/dist/exports.d.ts +40 -0
  4. package/dist/index.d.ts +4 -3
  5. package/dist/keri/app/aiding.d.ts +138 -0
  6. package/dist/keri/app/clienting.d.ts +182 -0
  7. package/dist/keri/app/contacting.d.ts +93 -0
  8. package/dist/keri/app/controller.d.ts +49 -0
  9. package/dist/keri/app/coring.d.ts +121 -0
  10. package/dist/keri/app/credentialing.d.ts +239 -0
  11. package/dist/keri/app/escrowing.d.ts +19 -0
  12. package/dist/keri/app/exchanging.d.ts +60 -0
  13. package/dist/keri/app/grouping.d.ts +44 -0
  14. package/dist/keri/app/habery.d.ts +48 -47
  15. package/dist/keri/app/notifying.d.ts +34 -0
  16. package/dist/keri/core/authing.d.ts +10 -9
  17. package/dist/keri/core/bexter.d.ts +7 -0
  18. package/dist/keri/core/cigar.d.ts +8 -8
  19. package/dist/keri/core/cipher.d.ts +5 -5
  20. package/dist/keri/core/core.d.ts +59 -53
  21. package/dist/keri/core/counter.d.ts +43 -43
  22. package/dist/keri/core/decrypter.d.ts +10 -10
  23. package/dist/keri/core/diger.d.ts +21 -21
  24. package/dist/keri/core/encrypter.d.ts +9 -9
  25. package/dist/keri/core/eventing.d.ts +54 -21
  26. package/dist/keri/core/httping.d.ts +44 -34
  27. package/dist/keri/core/indexer.d.ts +98 -88
  28. package/dist/keri/core/keeping.d.ts +103 -1
  29. package/dist/keri/core/kering.d.ts +5 -5
  30. package/dist/keri/core/manager.d.ts +174 -172
  31. package/dist/keri/core/matter.d.ts +116 -69
  32. package/dist/keri/core/number.d.ts +7 -6
  33. package/dist/keri/core/pather.d.ts +7 -0
  34. package/dist/keri/core/prefixer.d.ts +15 -15
  35. package/dist/keri/core/saider.d.ts +23 -23
  36. package/dist/keri/core/salter.d.ts +23 -23
  37. package/dist/keri/core/seqner.d.ts +15 -0
  38. package/dist/keri/core/serder.d.ts +31 -23
  39. package/dist/keri/core/siger.d.ts +18 -18
  40. package/dist/keri/core/signer.d.ts +34 -34
  41. package/dist/keri/core/tholder.d.ts +29 -14
  42. package/dist/keri/core/utils.d.ts +20 -15
  43. package/dist/keri/core/vdring.d.ts +16 -0
  44. package/dist/keri/core/verfer.d.ts +13 -12
  45. package/dist/keri/end/ending.d.ts +13 -13
  46. package/dist/math.d.ts +1 -0
  47. package/dist/ready.d.ts +1 -0
  48. package/dist/signify-ts.cjs +7835 -0
  49. package/dist/signify-ts.cjs.development.js +6369 -256
  50. package/dist/signify-ts.cjs.development.js.map +1 -1
  51. package/dist/signify-ts.cjs.map +7 -0
  52. package/dist/signify-ts.cjs.production.min.js +1 -1
  53. package/dist/signify-ts.cjs.production.min.js.map +1 -1
  54. package/dist/signify-ts.esm.js +6205 -229
  55. package/dist/signify-ts.esm.js.map +1 -1
  56. package/dist/signify-ts.mjs +7811 -0
  57. package/dist/signify-ts.mjs.map +7 -0
  58. package/package.json +49 -49
  59. package/src/buffer-polyfill.ts +5 -0
  60. package/src/exports.ts +44 -0
  61. package/src/index.ts +4 -5
  62. package/src/keri/app/aiding.ts +493 -0
  63. package/src/keri/app/clienting.ts +492 -0
  64. package/src/keri/app/contacting.ts +188 -0
  65. package/src/keri/app/controller.ts +372 -0
  66. package/src/keri/app/coring.ts +225 -0
  67. package/src/keri/app/credentialing.ts +820 -0
  68. package/src/keri/app/escrowing.ts +34 -0
  69. package/src/keri/app/exchanging.ts +220 -0
  70. package/src/keri/app/grouping.ts +90 -0
  71. package/src/keri/app/habery.ts +118 -85
  72. package/src/keri/app/notifying.ts +69 -0
  73. package/src/keri/core/authing.ts +73 -85
  74. package/src/keri/core/bexter.ts +138 -0
  75. package/src/keri/core/cigar.ts +10 -11
  76. package/src/keri/core/cipher.ts +23 -14
  77. package/src/keri/core/core.ts +223 -81
  78. package/src/keri/core/counter.ts +182 -116
  79. package/src/keri/core/decrypter.ts +48 -34
  80. package/src/keri/core/diger.ts +23 -22
  81. package/src/keri/core/encrypter.ts +37 -27
  82. package/src/keri/core/eventing.ts +468 -106
  83. package/src/keri/core/httping.ts +151 -105
  84. package/src/keri/core/indexer.ts +313 -211
  85. package/src/keri/core/keeping.ts +679 -3
  86. package/src/keri/core/kering.ts +4 -6
  87. package/src/keri/core/manager.ts +660 -499
  88. package/src/keri/core/matter.ts +382 -148
  89. package/src/keri/core/number.ts +56 -11
  90. package/src/keri/core/pather.ts +98 -0
  91. package/src/keri/core/prefixer.ts +122 -101
  92. package/src/keri/core/saider.ts +104 -76
  93. package/src/keri/core/salter.ts +71 -40
  94. package/src/keri/core/seqner.ts +46 -0
  95. package/src/keri/core/serder.ts +102 -38
  96. package/src/keri/core/siger.ts +19 -18
  97. package/src/keri/core/signer.ts +73 -53
  98. package/src/keri/core/tholder.ts +196 -30
  99. package/src/keri/core/utils.ts +121 -50
  100. package/src/keri/core/vdring.ts +94 -0
  101. package/src/keri/core/verfer.ts +22 -9
  102. package/src/keri/end/ending.ts +111 -101
  103. package/src/math.ts +3 -0
  104. package/src/ready.ts +5 -0
  105. package/dist/keri/app/accountant.d.ts +0 -10
  106. package/dist/keri/app/apping.d.ts +0 -1
  107. package/dist/keri/app/client.d.ts +0 -7
  108. package/dist/keri/app/signify.d.ts +0 -6
  109. package/src/keri/app/accountant.ts +0 -35
  110. package/src/keri/app/apping.ts +0 -12
  111. package/src/keri/app/client.ts +0 -30
  112. package/src/keri/app/signify.ts +0 -12
  113. package/src/keri/app/tsconfig.json +0 -100
  114. package/src/keri/core/tsconfig.json +0 -100
  115. package/src/keri/end/tsconfig.json +0 -100
@@ -0,0 +1,372 @@
1
+ import { SaltyCreator } from '../core/manager';
2
+ import { Salter, Tier } from '../core/salter';
3
+ import { MtrDex } from '../core/matter';
4
+ import { Diger } from '../core/diger';
5
+ import { incept, rotate, interact } from '../core/eventing';
6
+ import { Serder } from '../core/serder';
7
+ import { Tholder } from '../core/tholder';
8
+ import { Ilks, b, Serials, Versionage } from '../core/core';
9
+ import { Verfer } from '../core/verfer';
10
+ import { Encrypter } from '../core/encrypter';
11
+ import { Decrypter } from '../core/decrypter';
12
+ import { Cipher } from '../core/cipher';
13
+ import { Seqner } from '../core/seqner';
14
+ import { CesrNumber } from '../core/number';
15
+
16
+ /**
17
+ * Agent is a custodial entity that can be used in conjuntion with a local Client to establish the
18
+ * KERI "signing at the edge" semantic
19
+ */
20
+ export class Agent {
21
+ pre: string;
22
+ anchor: string;
23
+ verfer: Verfer | null;
24
+ state: any | null;
25
+ sn: number | undefined;
26
+ said: string | undefined;
27
+
28
+ constructor(agent: any) {
29
+ this.pre = '';
30
+ this.anchor = '';
31
+ this.verfer = null;
32
+ this.state = null;
33
+ this.sn = 0;
34
+ this.said = '';
35
+ this.parse(agent);
36
+ }
37
+
38
+ private parse(agent: Agent) {
39
+ const [state, verfer] = this.event(agent);
40
+
41
+ this.sn = new CesrNumber({}, undefined, state['s']).num;
42
+ this.said = state['d'];
43
+
44
+ if (state['et'] !== Ilks.dip) {
45
+ throw new Error(`invalid inception event type ${state['et']}`);
46
+ }
47
+
48
+ this.pre = state['i'];
49
+ if (!state['di']) {
50
+ throw new Error('no anchor to controller AID');
51
+ }
52
+
53
+ this.anchor = state['di'];
54
+
55
+ this.verfer = verfer;
56
+ this.state = state;
57
+ }
58
+
59
+ private event(evt: any): [any, Verfer, Diger] {
60
+ if (evt['k'].length !== 1) {
61
+ throw new Error(`agent inception event can only have one key`);
62
+ }
63
+
64
+ const verfer = new Verfer({ qb64: evt['k'][0] });
65
+
66
+ if (evt['n'].length !== 1) {
67
+ throw new Error(`agent inception event can only have one next key`);
68
+ }
69
+
70
+ const diger = new Diger({ qb64: evt['n'][0] });
71
+
72
+ const tholder = new Tholder({ sith: evt['kt'] });
73
+ if (tholder.num !== 1) {
74
+ throw new Error(`invalid threshold ${tholder.num}, must be 1`);
75
+ }
76
+
77
+ const ntholder = new Tholder({ sith: evt['nt'] });
78
+ if (ntholder.num !== 1) {
79
+ throw new Error(
80
+ `invalid next threshold ${ntholder.num}, must be 1`
81
+ );
82
+ }
83
+ return [evt, verfer, diger];
84
+ }
85
+ }
86
+
87
+ /**
88
+ * Controller is responsible for managing signing keys for the client and agent. The client
89
+ * signing key represents the Account for the client on the agent
90
+ */
91
+ export class Controller {
92
+ private bran: string;
93
+ public stem: string;
94
+ public tier: Tier;
95
+ public ridx: number;
96
+ public salter: any;
97
+ public signer: any;
98
+ private nsigner: any;
99
+ public serder: Serder;
100
+ private keys: string[];
101
+ public ndigs: string[];
102
+
103
+ constructor(
104
+ bran: string,
105
+ tier: Tier,
106
+ ridx: number = 0,
107
+ state: any | null = null
108
+ ) {
109
+ this.bran = MtrDex.Salt_128 + 'A' + bran.substring(0, 21); // qb64 salt for seed
110
+ this.stem = 'signify:controller';
111
+ this.tier = tier;
112
+ this.ridx = ridx;
113
+
114
+ this.salter = new Salter({ qb64: this.bran, tier: this.tier });
115
+
116
+ const creator = new SaltyCreator(
117
+ this.salter.qb64,
118
+ this.tier,
119
+ this.stem
120
+ );
121
+
122
+ this.signer = creator
123
+ .create(
124
+ undefined,
125
+ 1,
126
+ MtrDex.Ed25519_Seed,
127
+ true,
128
+ 0,
129
+ this.ridx,
130
+ 0,
131
+ false
132
+ )
133
+ .signers.pop();
134
+ this.nsigner = creator
135
+ .create(
136
+ undefined,
137
+ 1,
138
+ MtrDex.Ed25519_Seed,
139
+ true,
140
+ 0,
141
+ this.ridx + 1,
142
+ 0,
143
+ false
144
+ )
145
+ .signers.pop();
146
+ this.keys = [this.signer.verfer.qb64];
147
+ this.ndigs = [
148
+ new Diger({ code: MtrDex.Blake3_256 }, this.nsigner.verfer.qb64b)
149
+ .qb64,
150
+ ];
151
+
152
+ if (state == null || state['ee']['s'] == 0) {
153
+ this.serder = incept({
154
+ keys: this.keys,
155
+ isith: '1',
156
+ nsith: '1',
157
+ ndigs: this.ndigs,
158
+ code: MtrDex.Blake3_256,
159
+ toad: '0',
160
+ wits: [],
161
+ });
162
+ } else {
163
+ this.serder = new Serder(state['ee']);
164
+ }
165
+ }
166
+
167
+ approveDelegation(_agent: Agent) {
168
+ const seqner = new Seqner({ sn: _agent.sn });
169
+ const anchor = { i: _agent.pre, s: seqner.snh, d: _agent.said };
170
+ const sn = new CesrNumber({}, undefined, this.serder.ked['s']).num + 1;
171
+ this.serder = interact({
172
+ pre: this.serder.pre,
173
+ dig: this.serder.ked['d'],
174
+ sn: sn,
175
+ data: [anchor],
176
+ version: Versionage,
177
+ kind: Serials.JSON,
178
+ });
179
+ return [this.signer.sign(this.serder.raw, 0).qb64];
180
+ }
181
+
182
+ get pre(): string {
183
+ return this.serder.pre;
184
+ }
185
+
186
+ get event() {
187
+ const siger = this.signer.sign(this.serder.raw, 0);
188
+ return [this.serder, siger];
189
+ }
190
+
191
+ get verfers(): [] {
192
+ return this.signer.verfer();
193
+ }
194
+
195
+ derive(state: any) {
196
+ if (state != undefined && state['ee']['s'] === '0') {
197
+ return incept({
198
+ keys: this.keys,
199
+ isith: '1',
200
+ nsith: '1',
201
+ ndigs: this.ndigs,
202
+ code: MtrDex.Blake3_256,
203
+ toad: '0',
204
+ wits: [],
205
+ });
206
+ } else {
207
+ return new Serder({ ked: state.controller['ee'] });
208
+ }
209
+ }
210
+
211
+ rotate(bran: string, aids: Array<any>) {
212
+ const nbran = MtrDex.Salt_128 + 'A' + bran.substring(0, 21); // qb64 salt for seed
213
+ const nsalter = new Salter({ qb64: nbran, tier: this.tier });
214
+ const nsigner = this.salter.signer(undefined, false);
215
+
216
+ const creator = new SaltyCreator(
217
+ this.salter.qb64,
218
+ this.tier,
219
+ this.stem
220
+ );
221
+ const signer = creator
222
+ .create(
223
+ undefined,
224
+ 1,
225
+ MtrDex.Ed25519_Seed,
226
+ true,
227
+ 0,
228
+ this.ridx + 1,
229
+ 0,
230
+ false
231
+ )
232
+ .signers.pop();
233
+
234
+ const ncreator = new SaltyCreator(nsalter.qb64, this.tier, this.stem);
235
+ this.signer = ncreator
236
+ .create(
237
+ undefined,
238
+ 1,
239
+ MtrDex.Ed25519_Seed,
240
+ true,
241
+ 0,
242
+ this.ridx,
243
+ 0,
244
+ false
245
+ )
246
+ .signers.pop();
247
+ this.nsigner = ncreator
248
+ .create(
249
+ undefined,
250
+ 1,
251
+ MtrDex.Ed25519_Seed,
252
+ true,
253
+ 0,
254
+ this.ridx + 1,
255
+ 0,
256
+ false
257
+ )
258
+ .signers.pop();
259
+
260
+ this.keys = [this.signer.verfer.qb64, signer?.verfer.qb64];
261
+ this.ndigs = [new Diger({}, this.nsigner.verfer.qb64b).qb64];
262
+
263
+ const rot = rotate({
264
+ pre: this.pre,
265
+ keys: this.keys,
266
+ dig: this.serder.ked['d'],
267
+ isith: ['1', '0'],
268
+ nsith: '1',
269
+ ndigs: this.ndigs,
270
+ });
271
+
272
+ const sigs = [
273
+ signer?.sign(b(rot.raw), 1, false, 0).qb64,
274
+ this.signer.sign(rot.raw, 0).qb64,
275
+ ];
276
+ const encrypter = new Encrypter({}, b(nsigner.verfer.qb64));
277
+ const decrypter = new Decrypter({}, nsigner.qb64b);
278
+ const sxlt = encrypter.encrypt(b(this.bran)).qb64;
279
+
280
+ const keys: Record<any, any> = {};
281
+
282
+ for (const aid of aids) {
283
+ const pre: string = aid['prefix'] as string;
284
+ if ('salty' in aid) {
285
+ const salty: any = aid['salty'];
286
+ const cipher = new Cipher({ qb64: salty['sxlt'] });
287
+ const dnxt = decrypter.decrypt(null, cipher).qb64;
288
+
289
+ // Now we have the AID salt, use it to verify against the current public keys
290
+ const acreator = new SaltyCreator(
291
+ dnxt,
292
+ salty['tier'],
293
+ salty['stem']
294
+ );
295
+ const signers = acreator.create(
296
+ salty['icodes'],
297
+ undefined,
298
+ MtrDex.Ed25519_Seed,
299
+ salty['transferable'],
300
+ salty['pidx'],
301
+ 0,
302
+ salty['kidx'],
303
+ false
304
+ );
305
+ const _signers = [];
306
+ for (const signer of signers.signers) {
307
+ _signers.push(signer.verfer.qb64);
308
+ }
309
+ const pubs = aid['state']['k'];
310
+
311
+ if (pubs.join(',') != _signers.join(',')) {
312
+ throw new Error('Invalid Salty AID');
313
+ }
314
+
315
+ const asxlt = encrypter.encrypt(b(dnxt)).qb64;
316
+ keys[pre] = {
317
+ sxlt: asxlt,
318
+ };
319
+ } else if ('randy' in aid) {
320
+ const randy = aid['randy'];
321
+ const prxs = randy['prxs'];
322
+ const nxts = randy['nxts'];
323
+
324
+ const nprxs = [];
325
+ const signers = [];
326
+ for (const prx of prxs) {
327
+ const cipher = new Cipher({ qb64: prx });
328
+ const dsigner = decrypter.decrypt(null, cipher, true);
329
+ signers.push(dsigner);
330
+ nprxs.push(encrypter.encrypt(b(dsigner.qb64)).qb64);
331
+ }
332
+ const pubs = aid['state']['k'];
333
+ const _signers = [];
334
+ for (const signer of signers) {
335
+ _signers.push(signer.verfer.qb64);
336
+ }
337
+
338
+ if (pubs.join(',') != _signers.join(',')) {
339
+ throw new Error(
340
+ `unable to rotate, validation of encrypted public keys ${pubs} failed`
341
+ );
342
+ }
343
+
344
+ const nnxts = [];
345
+ for (const nxt of nxts) {
346
+ nnxts.push(this.recrypt(nxt, decrypter, encrypter));
347
+ }
348
+
349
+ keys[pre] = {
350
+ prxs: nprxs,
351
+ nxts: nnxts,
352
+ };
353
+ } else {
354
+ throw new Error('invalid aid type ');
355
+ }
356
+ }
357
+
358
+ const data = {
359
+ rot: rot.ked,
360
+ sigs: sigs,
361
+ sxlt: sxlt,
362
+ keys: keys,
363
+ };
364
+ return data;
365
+ }
366
+
367
+ recrypt(enc: string, decrypter: Decrypter, encrypter: Encrypter) {
368
+ const cipher = new Cipher({ qb64: enc });
369
+ const dnxt = decrypter.decrypt(null, cipher).qb64;
370
+ return encrypter.encrypt(b(dnxt)).qb64;
371
+ }
372
+ }
@@ -0,0 +1,225 @@
1
+ import { SignifyClient } from './clienting';
2
+ import libsodium from 'libsodium-wrappers-sumo';
3
+ import { Salter } from '../core/salter';
4
+ import { Matter, MtrDex } from '../core/matter';
5
+
6
+ export function randomPasscode(): string {
7
+ const raw = libsodium.randombytes_buf(16);
8
+ const salter = new Salter({ raw: raw });
9
+
10
+ return salter.qb64.substring(2);
11
+ }
12
+
13
+ export function randomNonce(): string {
14
+ const seed = libsodium.randombytes_buf(libsodium.crypto_sign_SEEDBYTES);
15
+ const seedqb64 = new Matter({ raw: seed, code: MtrDex.Ed25519_Seed });
16
+ return seedqb64.qb64;
17
+ }
18
+
19
+ export class Oobis {
20
+ public client: SignifyClient;
21
+ /**
22
+ * Oobis
23
+ * @param {SignifyClient} client
24
+ */
25
+ constructor(client: SignifyClient) {
26
+ this.client = client;
27
+ }
28
+
29
+ /**
30
+ * Get the OOBI(s) for a managed indentifier for a given role
31
+ * @param {string} name Name or alias of the identifier
32
+ * @param {string} role Authorized role
33
+ * @returns {Promise<any>} A promise to the OOBI(s)
34
+ */
35
+ async get(name: string, role: string = 'agent'): Promise<any> {
36
+ const path = `/identifiers/${name}/oobis?role=${role}`;
37
+ const method = 'GET';
38
+ const res = await this.client.fetch(path, method, null);
39
+ return await res.json();
40
+ }
41
+
42
+ /**
43
+ * Resolve an OOBI
44
+ * @async
45
+ * @param {string} oobi The OOBI to be resolver
46
+ * @param {string} [alias] Optional name or alias to link the OOBI resolution to a contact
47
+ * @returns {Promise<any>} A promise to the long-running operation
48
+ */
49
+ async resolve(oobi: string, alias?: string): Promise<any> {
50
+ const path = `/oobis`;
51
+ const data: any = {
52
+ url: oobi,
53
+ };
54
+ if (alias !== undefined) {
55
+ data.oobialias = alias;
56
+ }
57
+ const method = 'POST';
58
+ const res = await this.client.fetch(path, method, data);
59
+ return await res.json();
60
+ }
61
+ }
62
+
63
+ export interface Operation<T = unknown> {
64
+ name: string;
65
+ metadata?: {
66
+ depends?: Operation;
67
+ [property: string]: any;
68
+ };
69
+ done?: boolean;
70
+ error?: any;
71
+ response?: T;
72
+ }
73
+
74
+ /**
75
+ * Operations
76
+ * @remarks
77
+ * Operations represent the status and result of long running tasks performed by KERIA agent
78
+ */
79
+ export class Operations {
80
+ public client: SignifyClient;
81
+ /**
82
+ * Operations
83
+ * @param {SignifyClient} client
84
+ */
85
+ constructor(client: SignifyClient) {
86
+ this.client = client;
87
+ }
88
+
89
+ /**
90
+ * Get operation status
91
+ * @async
92
+ * @param {string} name Name of the operation
93
+ * @returns {Promise<Operation>} A promise to the status of the operation
94
+ */
95
+ async get<T = unknown>(name: string): Promise<Operation<T>> {
96
+ const path = `/operations/${name}`;
97
+ const data = null;
98
+ const method = 'GET';
99
+ const res = await this.client.fetch(path, method, data);
100
+ return await res.json();
101
+ }
102
+ /**
103
+ * List operations
104
+ * @async
105
+ * @param {string} type Select operations by type
106
+ * @returns {Promise<Operation[]>} A list of operations
107
+ */
108
+ async list(type?: string): Promise<Operation<any>[]> {
109
+ const params = new URLSearchParams();
110
+ if (type !== undefined) {
111
+ params.append('type', type);
112
+ }
113
+ const path = `/operations?${params.toString()}`;
114
+ const data = null;
115
+ const method = 'GET';
116
+ const res = await this.client.fetch(path, method, data);
117
+ return await res.json();
118
+ }
119
+ /**
120
+ * Delete operation
121
+ * @async
122
+ * @param {string} name Name of the operation
123
+ */
124
+ async delete(name: string): Promise<void> {
125
+ const path = `/operations/${name}`;
126
+ const data = null;
127
+ const method = 'DELETE';
128
+ await this.client.fetch(path, method, data);
129
+ }
130
+ }
131
+
132
+ /**
133
+ * KeyEvents
134
+ */
135
+ export class KeyEvents {
136
+ public client: SignifyClient;
137
+ /**
138
+ * KeyEvents
139
+ * @param {SignifyClient} client
140
+ */
141
+ constructor(client: SignifyClient) {
142
+ this.client = client;
143
+ }
144
+
145
+ /**
146
+ * Retrieve key events for an identifier
147
+ * @async
148
+ * @param {string} pre Identifier prefix
149
+ * @returns {Promise<any>} A promise to the key events
150
+ */
151
+ async get(pre: string): Promise<any> {
152
+ const path = `/events?pre=${pre}`;
153
+ const data = null;
154
+ const method = 'GET';
155
+ const res = await this.client.fetch(path, method, data);
156
+ return await res.json();
157
+ }
158
+ }
159
+
160
+ /**
161
+ * KeyStates
162
+ */
163
+ export class KeyStates {
164
+ public client: SignifyClient;
165
+ /**
166
+ * KeyStates
167
+ * @param {SignifyClient} client
168
+ */
169
+ constructor(client: SignifyClient) {
170
+ this.client = client;
171
+ }
172
+
173
+ /**
174
+ * Retriene the key state for an identifier
175
+ * @async
176
+ * @param {string} pre Identifier prefix
177
+ * @returns {Promise<any>} A promise to the key states
178
+ */
179
+ async get(pre: string): Promise<any> {
180
+ const path = `/states?pre=${pre}`;
181
+ const data = null;
182
+ const method = 'GET';
183
+ const res = await this.client.fetch(path, method, data);
184
+ return await res.json();
185
+ }
186
+
187
+ /**
188
+ * Retrieve the key state for a list of identifiers
189
+ * @async
190
+ * @param {Array<string>} pres List of identifier prefixes
191
+ * @returns {Promise<any>} A promise to the key states
192
+ */
193
+ async list(pres: string[]): Promise<any> {
194
+ const path = `/states?${pres.map((pre) => `pre=${pre}`).join('&')}`;
195
+ const data = null;
196
+ const method = 'GET';
197
+ const res = await this.client.fetch(path, method, data);
198
+ return await res.json();
199
+ }
200
+
201
+ /**
202
+ * Query the key state of an identifier for a given sequence number or anchor
203
+ * @async
204
+ * @param {string} pre Identifier prefix
205
+ * @param {number} [sn] Optional sequence number
206
+ * @param {any} [anchor] Optional anchor
207
+ * @returns {Promise<any>} A promise to the long-running operation
208
+ */
209
+ async query(pre: string, sn?: string, anchor?: any): Promise<any> {
210
+ const path = `/queries`;
211
+ const data: any = {
212
+ pre: pre,
213
+ };
214
+ if (sn !== undefined) {
215
+ data.sn = sn;
216
+ }
217
+ if (anchor !== undefined) {
218
+ data.anchor = anchor;
219
+ }
220
+
221
+ const method = 'POST';
222
+ const res = await this.client.fetch(path, method, data);
223
+ return await res.json();
224
+ }
225
+ }