signify-ts 0.1.0 → 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.
- package/README.md +101 -5
- package/dist/buffer-polyfill.d.ts +1 -0
- package/dist/exports.d.ts +40 -0
- package/dist/index.d.ts +4 -1
- package/dist/keri/app/aiding.d.ts +138 -0
- package/dist/keri/app/clienting.d.ts +182 -0
- package/dist/keri/app/contacting.d.ts +93 -0
- package/dist/keri/app/controller.d.ts +49 -0
- package/dist/keri/app/coring.d.ts +121 -0
- package/dist/keri/app/credentialing.d.ts +239 -0
- package/dist/keri/app/escrowing.d.ts +19 -0
- package/dist/keri/app/exchanging.d.ts +60 -0
- package/dist/keri/app/grouping.d.ts +44 -0
- package/dist/keri/app/habery.d.ts +48 -0
- package/dist/keri/app/notifying.d.ts +34 -0
- package/dist/keri/core/authing.d.ts +10 -0
- package/dist/keri/core/bexter.d.ts +7 -0
- package/dist/keri/core/cigar.d.ts +8 -8
- package/dist/keri/core/cipher.d.ts +5 -5
- package/dist/keri/core/core.d.ts +59 -68
- package/dist/keri/core/counter.d.ts +43 -0
- package/dist/keri/core/decrypter.d.ts +10 -10
- package/dist/keri/core/diger.d.ts +21 -21
- package/dist/keri/core/encrypter.d.ts +9 -9
- package/dist/keri/core/eventing.d.ts +54 -0
- package/dist/keri/core/httping.d.ts +44 -0
- package/dist/keri/core/indexer.d.ts +98 -88
- package/dist/keri/core/keeping.d.ts +103 -1
- package/dist/keri/core/kering.d.ts +5 -5
- package/dist/keri/core/manager.d.ts +174 -151
- package/dist/keri/core/matter.d.ts +116 -47
- package/dist/keri/core/number.d.ts +7 -0
- package/dist/keri/core/pather.d.ts +7 -0
- package/dist/keri/core/prefixer.d.ts +15 -0
- package/dist/keri/core/saider.d.ts +23 -0
- package/dist/keri/core/salter.d.ts +23 -0
- package/dist/keri/core/seqner.d.ts +15 -0
- package/dist/keri/core/serder.d.ts +31 -0
- package/dist/keri/core/siger.d.ts +18 -18
- package/dist/keri/core/signer.d.ts +34 -34
- package/dist/keri/core/tholder.d.ts +29 -0
- package/dist/keri/core/utils.d.ts +20 -14
- package/dist/keri/core/vdring.d.ts +16 -0
- package/dist/keri/core/verfer.d.ts +13 -0
- package/dist/keri/end/ending.d.ts +13 -0
- package/dist/math.d.ts +1 -0
- package/dist/ready.d.ts +1 -0
- package/dist/signify-ts.cjs +7835 -0
- package/dist/signify-ts.cjs.development.js +9493 -5
- package/dist/signify-ts.cjs.development.js.map +1 -1
- package/dist/signify-ts.cjs.map +7 -0
- package/dist/signify-ts.cjs.production.min.js +1 -1
- package/dist/signify-ts.cjs.production.min.js.map +1 -1
- package/dist/signify-ts.esm.js +9341 -5
- package/dist/signify-ts.esm.js.map +1 -1
- package/dist/signify-ts.mjs +7811 -0
- package/dist/signify-ts.mjs.map +7 -0
- package/package.json +51 -49
- package/src/buffer-polyfill.ts +5 -0
- package/src/exports.ts +44 -0
- package/src/index.ts +4 -6
- package/src/keri/app/aiding.ts +493 -0
- package/src/keri/app/clienting.ts +492 -0
- package/src/keri/app/contacting.ts +188 -0
- package/src/keri/app/controller.ts +372 -0
- package/src/keri/app/coring.ts +225 -0
- package/src/keri/app/credentialing.ts +820 -0
- package/src/keri/app/escrowing.ts +34 -0
- package/src/keri/app/exchanging.ts +220 -0
- package/src/keri/app/grouping.ts +90 -0
- package/src/keri/app/habery.ts +185 -0
- package/src/keri/app/notifying.ts +69 -0
- package/src/keri/core/authing.ts +117 -0
- package/src/keri/core/bexter.ts +138 -0
- package/src/keri/core/cigar.ts +11 -12
- package/src/keri/core/cipher.ts +23 -14
- package/src/keri/core/core.ts +249 -97
- package/src/keri/core/counter.ts +273 -0
- package/src/keri/core/decrypter.ts +48 -34
- package/src/keri/core/diger.ts +25 -24
- package/src/keri/core/encrypter.ts +37 -27
- package/src/keri/core/eventing.ts +581 -0
- package/src/keri/core/httping.ts +209 -0
- package/src/keri/core/indexer.ts +314 -211
- package/src/keri/core/keeping.ts +679 -4
- package/src/keri/core/kering.ts +4 -6
- package/src/keri/core/manager.ts +759 -450
- package/src/keri/core/matter.ts +404 -135
- package/src/keri/core/number.ts +66 -0
- package/src/keri/core/pather.ts +98 -0
- package/src/keri/core/prefixer.ts +233 -0
- package/src/keri/core/saider.ts +186 -0
- package/src/keri/core/salter.ts +76 -41
- package/src/keri/core/seqner.ts +46 -0
- package/src/keri/core/serder.ts +163 -0
- package/src/keri/core/siger.ts +19 -18
- package/src/keri/core/signer.ts +74 -53
- package/src/keri/core/tholder.ts +218 -0
- package/src/keri/core/utils.ts +120 -45
- package/src/keri/core/vdring.ts +94 -0
- package/src/keri/core/verfer.ts +25 -11
- package/src/keri/end/ending.ts +170 -0
- package/src/math.ts +3 -0
- package/src/ready.ts +5 -0
- package/src/keri/core/tsconfig.json +0 -100
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { SignifyClient } from './clienting';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Escrows
|
|
5
|
+
*/
|
|
6
|
+
export class Escrows {
|
|
7
|
+
client: SignifyClient;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Escrows
|
|
11
|
+
* @param {SignifyClient} client
|
|
12
|
+
*/
|
|
13
|
+
constructor(client: SignifyClient) {
|
|
14
|
+
this.client = client;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* List replay messages
|
|
19
|
+
* @async
|
|
20
|
+
* @param {string} [route] Optional route in the replay message
|
|
21
|
+
* @returns {Promise<any>} A promise to the list of replay messages
|
|
22
|
+
*/
|
|
23
|
+
async listReply(route?: string): Promise<any> {
|
|
24
|
+
const params = new URLSearchParams();
|
|
25
|
+
if (route !== undefined) {
|
|
26
|
+
params.append('route', route);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const path = `/escrows/rpy` + '?' + params.toString();
|
|
30
|
+
const method = 'GET';
|
|
31
|
+
const res = await this.client.fetch(path, method, null);
|
|
32
|
+
return await res.json();
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import { SignifyClient } from './clienting';
|
|
2
|
+
import { b, d, Dict, Ident, Ilks, Serials, versify } from '../core/core';
|
|
3
|
+
import { Serder } from '../core/serder';
|
|
4
|
+
import { nowUTC } from '../core/utils';
|
|
5
|
+
import { Pather } from '../core/pather';
|
|
6
|
+
import { Counter, CtrDex } from '../core/counter';
|
|
7
|
+
import { Saider } from '../core/saider';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Exchanges
|
|
11
|
+
*/
|
|
12
|
+
export class Exchanges {
|
|
13
|
+
client: SignifyClient;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Exchanges
|
|
17
|
+
* @param {SignifyClient} client
|
|
18
|
+
*/
|
|
19
|
+
constructor(client: SignifyClient) {
|
|
20
|
+
this.client = client;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Create exn message
|
|
25
|
+
* @async
|
|
26
|
+
* @returns {Promise<any>} A promise to the list of replay messages
|
|
27
|
+
* @param sender
|
|
28
|
+
* @param route
|
|
29
|
+
* @param payload
|
|
30
|
+
* @param embeds
|
|
31
|
+
* @param recipient
|
|
32
|
+
* @param datetime
|
|
33
|
+
* @param dig
|
|
34
|
+
*/
|
|
35
|
+
async createExchangeMessage(
|
|
36
|
+
sender: Dict<any>,
|
|
37
|
+
route: string,
|
|
38
|
+
payload: Dict<any>,
|
|
39
|
+
embeds: Dict<any>,
|
|
40
|
+
recipient?: string,
|
|
41
|
+
datetime?: string,
|
|
42
|
+
dig?: string
|
|
43
|
+
): Promise<[Serder, string[], string]> {
|
|
44
|
+
const keeper = this.client.manager!.get(sender);
|
|
45
|
+
const [exn, end] = exchange(
|
|
46
|
+
route,
|
|
47
|
+
payload,
|
|
48
|
+
sender['prefix'],
|
|
49
|
+
recipient,
|
|
50
|
+
datetime,
|
|
51
|
+
dig,
|
|
52
|
+
undefined,
|
|
53
|
+
embeds
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
const sigs = await keeper.sign(b(exn.raw));
|
|
57
|
+
return [exn, sigs, d(end)];
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Send exn messages to list of recipients
|
|
62
|
+
* @async
|
|
63
|
+
* @returns {Promise<any>} A promise to the list of replay messages
|
|
64
|
+
* @param name
|
|
65
|
+
* @param topic
|
|
66
|
+
* @param sender
|
|
67
|
+
* @param route
|
|
68
|
+
* @param payload
|
|
69
|
+
* @param embeds
|
|
70
|
+
* @param recipients
|
|
71
|
+
*/
|
|
72
|
+
async send(
|
|
73
|
+
name: string,
|
|
74
|
+
topic: string,
|
|
75
|
+
sender: Dict<any>,
|
|
76
|
+
route: string,
|
|
77
|
+
payload: Dict<any>,
|
|
78
|
+
embeds: Dict<any>,
|
|
79
|
+
recipients: string[]
|
|
80
|
+
): Promise<any> {
|
|
81
|
+
const [exn, sigs, atc] = await this.createExchangeMessage(
|
|
82
|
+
sender,
|
|
83
|
+
route,
|
|
84
|
+
payload,
|
|
85
|
+
embeds
|
|
86
|
+
);
|
|
87
|
+
return await this.sendFromEvents(
|
|
88
|
+
name,
|
|
89
|
+
topic,
|
|
90
|
+
exn,
|
|
91
|
+
sigs,
|
|
92
|
+
atc,
|
|
93
|
+
recipients
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Send exn messaget to list of recipients
|
|
99
|
+
* @async
|
|
100
|
+
* @returns {Promise<any>} A promise to the list of replay messages
|
|
101
|
+
* @param name
|
|
102
|
+
* @param topic
|
|
103
|
+
* @param exn
|
|
104
|
+
* @param sigs
|
|
105
|
+
* @param atc
|
|
106
|
+
* @param recipients
|
|
107
|
+
*/
|
|
108
|
+
async sendFromEvents(
|
|
109
|
+
name: string,
|
|
110
|
+
topic: string,
|
|
111
|
+
exn: Serder,
|
|
112
|
+
sigs: string[],
|
|
113
|
+
atc: string,
|
|
114
|
+
recipients: string[]
|
|
115
|
+
): Promise<any> {
|
|
116
|
+
const path = `/identifiers/${name}/exchanges`;
|
|
117
|
+
const method = 'POST';
|
|
118
|
+
const data: any = {
|
|
119
|
+
tpc: topic,
|
|
120
|
+
exn: exn.ked,
|
|
121
|
+
sigs: sigs,
|
|
122
|
+
atc: atc,
|
|
123
|
+
rec: recipients,
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
const res = await this.client.fetch(path, method, data);
|
|
127
|
+
return await res.json();
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Get exn message by said
|
|
132
|
+
* @async
|
|
133
|
+
* @returns A promise to the exn message
|
|
134
|
+
* @param said The said of the exn message
|
|
135
|
+
*/
|
|
136
|
+
async get(said: string): Promise<any> {
|
|
137
|
+
const path = `/exchanges/${said}`;
|
|
138
|
+
const method = 'GET';
|
|
139
|
+
const res = await this.client.fetch(path, method, null);
|
|
140
|
+
return await res.json();
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export function exchange(
|
|
145
|
+
route: string,
|
|
146
|
+
payload: Dict<any>,
|
|
147
|
+
sender: string,
|
|
148
|
+
recipient?: string,
|
|
149
|
+
date?: string,
|
|
150
|
+
dig?: string,
|
|
151
|
+
modifiers?: Dict<any>,
|
|
152
|
+
embeds?: Dict<any>
|
|
153
|
+
): [Serder, Uint8Array] {
|
|
154
|
+
const vs = versify(Ident.KERI, undefined, Serials.JSON, 0);
|
|
155
|
+
const ilk = Ilks.exn;
|
|
156
|
+
const dt =
|
|
157
|
+
date !== undefined
|
|
158
|
+
? date
|
|
159
|
+
: nowUTC().toISOString().replace('Z', '000+00:00');
|
|
160
|
+
const p = dig !== undefined ? dig : '';
|
|
161
|
+
const q = modifiers !== undefined ? modifiers : {};
|
|
162
|
+
const ems = embeds != undefined ? embeds : {};
|
|
163
|
+
|
|
164
|
+
let e = {} as Dict<any>;
|
|
165
|
+
let end = '';
|
|
166
|
+
Object.entries(ems).forEach(([key, value]) => {
|
|
167
|
+
const serder = value[0];
|
|
168
|
+
const atc = value[1];
|
|
169
|
+
e[key] = serder.ked;
|
|
170
|
+
|
|
171
|
+
if (atc == undefined) {
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
let pathed = '';
|
|
175
|
+
const pather = new Pather({}, undefined, ['e', key]);
|
|
176
|
+
pathed += pather.qb64;
|
|
177
|
+
pathed += atc;
|
|
178
|
+
|
|
179
|
+
const counter = new Counter({
|
|
180
|
+
code: CtrDex.PathedMaterialQuadlets,
|
|
181
|
+
count: Math.floor(pathed.length / 4),
|
|
182
|
+
});
|
|
183
|
+
end += counter.qb64;
|
|
184
|
+
end += pathed;
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
if (Object.keys(e).length > 0) {
|
|
188
|
+
e['d'] = '';
|
|
189
|
+
[, e] = Saider.saidify(e);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
const attrs = {} as Dict<any>;
|
|
193
|
+
|
|
194
|
+
if (recipient !== undefined) {
|
|
195
|
+
attrs['i'] = recipient;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
const a = {
|
|
199
|
+
...attrs,
|
|
200
|
+
...payload,
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
const _ked = {
|
|
204
|
+
v: vs,
|
|
205
|
+
t: ilk,
|
|
206
|
+
d: '',
|
|
207
|
+
i: sender,
|
|
208
|
+
p: p,
|
|
209
|
+
dt: dt,
|
|
210
|
+
r: route,
|
|
211
|
+
q: q,
|
|
212
|
+
a: a,
|
|
213
|
+
e: e,
|
|
214
|
+
};
|
|
215
|
+
const [, ked] = Saider.saidify(_ked);
|
|
216
|
+
|
|
217
|
+
const exn = new Serder(ked);
|
|
218
|
+
|
|
219
|
+
return [exn, b(end)];
|
|
220
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { SignifyClient } from './clienting';
|
|
2
|
+
import { Dict } from '../core/core';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Groups
|
|
6
|
+
*/
|
|
7
|
+
export class Groups {
|
|
8
|
+
client: SignifyClient;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Groups
|
|
12
|
+
* @param {SignifyClient} client
|
|
13
|
+
*/
|
|
14
|
+
constructor(client: SignifyClient) {
|
|
15
|
+
this.client = client;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Get group request messages
|
|
20
|
+
* @async
|
|
21
|
+
* @param {string} [said] SAID of exn message to load
|
|
22
|
+
* @returns {Promise<any>} A promise to the list of replay messages
|
|
23
|
+
*/
|
|
24
|
+
async getRequest(said: string): Promise<any> {
|
|
25
|
+
const path = `/multisig/request/` + said;
|
|
26
|
+
const method = 'GET';
|
|
27
|
+
const res = await this.client.fetch(path, method, null);
|
|
28
|
+
return await res.json();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Send multisig exn request messages to other group members
|
|
33
|
+
* @async
|
|
34
|
+
* @param {string} [name] human readable name of group AID
|
|
35
|
+
* @param {Dict<any>} [exn] exn message to send to other members
|
|
36
|
+
* @param {string[]} [sigs] signature of the participant over the exn
|
|
37
|
+
* @param {string} [atc] additional attachments from embedded events in exn
|
|
38
|
+
* @returns {Promise<any>} A promise to the list of replay messages
|
|
39
|
+
*/
|
|
40
|
+
async sendRequest(
|
|
41
|
+
name: string,
|
|
42
|
+
exn: Dict<any>,
|
|
43
|
+
sigs: string[],
|
|
44
|
+
atc: string
|
|
45
|
+
): Promise<any> {
|
|
46
|
+
const path = `/identifiers/${name}/multisig/request`;
|
|
47
|
+
const method = 'POST';
|
|
48
|
+
const data = {
|
|
49
|
+
exn: exn,
|
|
50
|
+
sigs: sigs,
|
|
51
|
+
atc: atc,
|
|
52
|
+
};
|
|
53
|
+
const res = await this.client.fetch(path, method, data);
|
|
54
|
+
return await res.json();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Join multisig group using rotation event.
|
|
59
|
+
* This can be used by participants being asked to contribute keys to a rotation event to join an existing group.
|
|
60
|
+
* @async
|
|
61
|
+
* @param {string} [name] human readable name of group AID
|
|
62
|
+
* @param {any} [rot] rotation event
|
|
63
|
+
* @param {any} [sigs] signatures
|
|
64
|
+
* @param {string} [gid] prefix
|
|
65
|
+
* @param {string[]} [smids] array of particpants
|
|
66
|
+
* @param {string[]} [rmids] array of particpants
|
|
67
|
+
* @returns {Promise<any>} A promise to the list of replay messages
|
|
68
|
+
*/
|
|
69
|
+
async join(
|
|
70
|
+
name: string,
|
|
71
|
+
rot: any,
|
|
72
|
+
sigs: any, //string[],
|
|
73
|
+
gid: string,
|
|
74
|
+
smids: string[],
|
|
75
|
+
rmids: string[]
|
|
76
|
+
): Promise<any> {
|
|
77
|
+
const path = `/identifiers/${name}/multisig/join`;
|
|
78
|
+
const method = 'POST';
|
|
79
|
+
const data = {
|
|
80
|
+
tpc: 'multisig',
|
|
81
|
+
rot: rot.ked,
|
|
82
|
+
sigs: sigs,
|
|
83
|
+
gid: gid,
|
|
84
|
+
smids: smids,
|
|
85
|
+
rmids: rmids,
|
|
86
|
+
};
|
|
87
|
+
const res = await this.client.fetch(path, method, data);
|
|
88
|
+
return await res.json();
|
|
89
|
+
}
|
|
90
|
+
}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { Algos, Manager } from '../core/manager';
|
|
2
|
+
import { MtrDex } from '../core/matter';
|
|
3
|
+
import { Salter } from '../core/salter';
|
|
4
|
+
import { Verfer } from '../core/verfer';
|
|
5
|
+
import { Diger } from '../core/diger';
|
|
6
|
+
import { incept } from '../core/eventing';
|
|
7
|
+
import { Serder } from '../core/serder';
|
|
8
|
+
|
|
9
|
+
export class TraitCodex {
|
|
10
|
+
EstOnly: string = 'EO'; // Only allow establishment events
|
|
11
|
+
DoNotDelegate: string = 'DND'; // Dot not allow delegated identifiers
|
|
12
|
+
NoBackers: string = 'NB'; // Do not allow backers
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const TraitDex = new TraitCodex();
|
|
16
|
+
|
|
17
|
+
export interface HaberyArgs {
|
|
18
|
+
name: string;
|
|
19
|
+
passcode?: string;
|
|
20
|
+
seed?: string | undefined;
|
|
21
|
+
aeid?: string | undefined;
|
|
22
|
+
pidx?: number | undefined;
|
|
23
|
+
salt?: string | undefined;
|
|
24
|
+
tier?: string | undefined;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface MakeHabArgs {
|
|
28
|
+
code?: string;
|
|
29
|
+
transferable?: boolean;
|
|
30
|
+
isith?: string;
|
|
31
|
+
icount?: number;
|
|
32
|
+
nsith?: string;
|
|
33
|
+
ncount?: number;
|
|
34
|
+
toad?: string | number;
|
|
35
|
+
wits?: Array<string>;
|
|
36
|
+
delpre?: string;
|
|
37
|
+
estOnly?: boolean;
|
|
38
|
+
DnD?: boolean;
|
|
39
|
+
data?: any;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export class Hab {
|
|
43
|
+
public name: string;
|
|
44
|
+
public serder: Serder;
|
|
45
|
+
|
|
46
|
+
constructor(name: string, icp: Serder) {
|
|
47
|
+
this.name = name;
|
|
48
|
+
this.serder = icp;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
get pre(): string {
|
|
52
|
+
return this.serder.ked['i'];
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export class Habery {
|
|
57
|
+
private readonly _name: string;
|
|
58
|
+
private readonly _mgr: Manager;
|
|
59
|
+
private readonly _habs: Map<string, Hab> = new Map<string, Hab>();
|
|
60
|
+
|
|
61
|
+
constructor({ name, passcode, seed, aeid, pidx, salt }: HaberyArgs) {
|
|
62
|
+
this._name = name;
|
|
63
|
+
if (passcode != undefined && seed == undefined) {
|
|
64
|
+
if (passcode.length < 21) {
|
|
65
|
+
throw new Error('Bran (passcode seed material) too short.');
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const bran = MtrDex.Salt_128 + 'A' + passcode.substring(0, 21); // qb64 salt for seed
|
|
69
|
+
const signer = new Salter({ qb64: bran }).signer(
|
|
70
|
+
MtrDex.Ed25519_Seed,
|
|
71
|
+
false
|
|
72
|
+
);
|
|
73
|
+
seed = signer.qb64;
|
|
74
|
+
if (aeid == undefined) {
|
|
75
|
+
aeid = signer.verfer.qb64; // lest it remove encryption
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
let algo;
|
|
79
|
+
const salter =
|
|
80
|
+
salt != undefined ? new Salter({ qb64: salt }) : undefined;
|
|
81
|
+
if (salt != undefined) {
|
|
82
|
+
algo = Algos.salty;
|
|
83
|
+
} else {
|
|
84
|
+
algo = Algos.randy;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
this._mgr = new Manager({
|
|
88
|
+
seed: seed,
|
|
89
|
+
aeid: aeid,
|
|
90
|
+
pidx: pidx,
|
|
91
|
+
algo: algo,
|
|
92
|
+
salter: salter,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
get mgr(): Manager {
|
|
97
|
+
return this._mgr;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
get habs(): Array<Hab> {
|
|
101
|
+
return Array.from(this._habs.values());
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
habByName(name: string): Hab | undefined {
|
|
105
|
+
return this._habs.get(name);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
makeHab(
|
|
109
|
+
name: string,
|
|
110
|
+
{
|
|
111
|
+
code = MtrDex.Blake3_256,
|
|
112
|
+
transferable = true,
|
|
113
|
+
isith = undefined,
|
|
114
|
+
icount = 1,
|
|
115
|
+
nsith = undefined,
|
|
116
|
+
ncount = undefined,
|
|
117
|
+
toad = undefined,
|
|
118
|
+
wits = undefined,
|
|
119
|
+
delpre = undefined,
|
|
120
|
+
estOnly = false,
|
|
121
|
+
DnD = false,
|
|
122
|
+
data = undefined,
|
|
123
|
+
}: MakeHabArgs
|
|
124
|
+
): Hab {
|
|
125
|
+
if (nsith == undefined) {
|
|
126
|
+
nsith = isith;
|
|
127
|
+
}
|
|
128
|
+
if (ncount == undefined) {
|
|
129
|
+
ncount = icount;
|
|
130
|
+
}
|
|
131
|
+
if (!transferable) {
|
|
132
|
+
ncount = 0;
|
|
133
|
+
nsith = '0';
|
|
134
|
+
code = MtrDex.Ed25519N;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const [verfers, digers] = this._mgr.incept({
|
|
138
|
+
icount: icount,
|
|
139
|
+
ncount: ncount,
|
|
140
|
+
stem: this.name,
|
|
141
|
+
transferable: transferable,
|
|
142
|
+
temp: false,
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
icount = verfers.length;
|
|
146
|
+
ncount = digers != undefined ? digers.length : 0;
|
|
147
|
+
if (isith == undefined) {
|
|
148
|
+
isith = `${Math.max(1, Math.ceil(icount / 2)).toString(16)}`;
|
|
149
|
+
}
|
|
150
|
+
if (nsith == undefined) {
|
|
151
|
+
nsith = `${Math.max(1, Math.ceil(ncount / 2)).toString(16)}`;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const cnfg = new Array<string>();
|
|
155
|
+
if (estOnly) {
|
|
156
|
+
cnfg.push(TraitDex.EstOnly);
|
|
157
|
+
}
|
|
158
|
+
if (DnD) {
|
|
159
|
+
cnfg.push(TraitDex.DoNotDelegate);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const keys = Array.from(verfers, (verfer: Verfer) => verfer.qb64);
|
|
163
|
+
const ndigs = Array.from(digers, (diger: Diger) => diger.qb64);
|
|
164
|
+
|
|
165
|
+
const icp = incept({
|
|
166
|
+
keys,
|
|
167
|
+
isith,
|
|
168
|
+
ndigs,
|
|
169
|
+
nsith,
|
|
170
|
+
toad,
|
|
171
|
+
wits,
|
|
172
|
+
cnfg,
|
|
173
|
+
data,
|
|
174
|
+
code,
|
|
175
|
+
delpre,
|
|
176
|
+
});
|
|
177
|
+
const hab = new Hab(name, icp);
|
|
178
|
+
this._habs.set(name, hab);
|
|
179
|
+
return hab;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
get name(): string {
|
|
183
|
+
return this._name;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { SignifyClient } from './clienting';
|
|
2
|
+
import { parseRangeHeaders } from '../core/httping';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Notifications
|
|
6
|
+
*/
|
|
7
|
+
export class Notifications {
|
|
8
|
+
client: SignifyClient;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Notifications
|
|
12
|
+
* @param {SignifyClient} client
|
|
13
|
+
*/
|
|
14
|
+
constructor(client: SignifyClient) {
|
|
15
|
+
this.client = client;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* List notifications
|
|
20
|
+
* @async
|
|
21
|
+
* @param {number} [start=0] Start index of list of notifications, defaults to 0
|
|
22
|
+
* @param {number} [end=24] End index of list of notifications, defaults to 24
|
|
23
|
+
* @returns {Promise<any>} A promise to the list of notifications
|
|
24
|
+
*/
|
|
25
|
+
async list(start: number = 0, end: number = 24): Promise<any> {
|
|
26
|
+
const extraHeaders = new Headers();
|
|
27
|
+
extraHeaders.append('Range', `notes=${start}-${end}`);
|
|
28
|
+
|
|
29
|
+
const path = `/notifications`;
|
|
30
|
+
const method = 'GET';
|
|
31
|
+
const res = await this.client.fetch(path, method, null, extraHeaders);
|
|
32
|
+
|
|
33
|
+
const cr = res.headers.get('content-range');
|
|
34
|
+
const range = parseRangeHeaders(cr, 'notes');
|
|
35
|
+
const notes = await res.json();
|
|
36
|
+
|
|
37
|
+
return {
|
|
38
|
+
start: range.start,
|
|
39
|
+
end: range.end,
|
|
40
|
+
total: range.total,
|
|
41
|
+
notes: notes,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Mark a notification as read
|
|
47
|
+
* @async
|
|
48
|
+
* @param {string} said SAID of the notification
|
|
49
|
+
* @returns {Promise<string>} A promise to the result of the marking
|
|
50
|
+
*/
|
|
51
|
+
async mark(said: string): Promise<string> {
|
|
52
|
+
const path = `/notifications/` + said;
|
|
53
|
+
const method = 'PUT';
|
|
54
|
+
const res = await this.client.fetch(path, method, null);
|
|
55
|
+
return await res.text();
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Delete a notification
|
|
60
|
+
* @async
|
|
61
|
+
* @param {string} said SAID of the notification
|
|
62
|
+
* @returns {Promise<any>} A promise to the result of the deletion
|
|
63
|
+
*/
|
|
64
|
+
async delete(said: string): Promise<void> {
|
|
65
|
+
const path = `/notifications/` + said;
|
|
66
|
+
const method = 'DELETE';
|
|
67
|
+
await this.client.fetch(path, method, null);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { Signer } from './signer';
|
|
2
|
+
import { Verfer } from './verfer';
|
|
3
|
+
import { desiginput, normalize, siginput } from './httping';
|
|
4
|
+
import { Signage, signature, designature } from '../end/ending';
|
|
5
|
+
import { Cigar } from './cigar';
|
|
6
|
+
import { Siger } from './siger';
|
|
7
|
+
export class Authenticater {
|
|
8
|
+
static DefaultFields = [
|
|
9
|
+
'@method',
|
|
10
|
+
'@path',
|
|
11
|
+
'signify-resource',
|
|
12
|
+
'signify-timestamp',
|
|
13
|
+
];
|
|
14
|
+
private _verfer: Verfer;
|
|
15
|
+
private readonly _csig: Signer;
|
|
16
|
+
|
|
17
|
+
constructor(csig: Signer, verfer: Verfer) {
|
|
18
|
+
this._csig = csig;
|
|
19
|
+
this._verfer = verfer;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
verify(headers: Headers, method: string, path: string): boolean {
|
|
23
|
+
const siginput = headers.get('Signature-Input');
|
|
24
|
+
if (siginput == null) {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
const signature = headers.get('Signature');
|
|
28
|
+
if (signature == null) {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
let inputs = desiginput(siginput);
|
|
32
|
+
inputs = inputs.filter((input) => input.name == 'signify');
|
|
33
|
+
if (inputs.length == 0) {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
inputs.forEach((input) => {
|
|
37
|
+
const items = new Array<string>();
|
|
38
|
+
input.fields!.forEach((field: string) => {
|
|
39
|
+
if (field.startsWith('@')) {
|
|
40
|
+
if (field == '@method') {
|
|
41
|
+
items.push(`"${field}": ${method}`);
|
|
42
|
+
} else if (field == '@path') {
|
|
43
|
+
items.push(`"${field}": ${path}`);
|
|
44
|
+
}
|
|
45
|
+
} else {
|
|
46
|
+
if (headers.has(field)) {
|
|
47
|
+
const value = normalize(headers.get(field) as string);
|
|
48
|
+
items.push(`"${field}": ${value}`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
const values = new Array<string>();
|
|
53
|
+
values.push(`(${input.fields!.join(' ')})`);
|
|
54
|
+
values.push(`created=${input.created}`);
|
|
55
|
+
if (input.expires != undefined) {
|
|
56
|
+
values.push(`expires=${input.expires}`);
|
|
57
|
+
}
|
|
58
|
+
if (input.nonce != undefined) {
|
|
59
|
+
values.push(`nonce=${input.nonce}`);
|
|
60
|
+
}
|
|
61
|
+
if (input.keyid != undefined) {
|
|
62
|
+
values.push(`keyid=${input.keyid}`);
|
|
63
|
+
}
|
|
64
|
+
if (input.context != undefined) {
|
|
65
|
+
values.push(`context=${input.context}`);
|
|
66
|
+
}
|
|
67
|
+
if (input.alg != undefined) {
|
|
68
|
+
values.push(`alg=${input.alg}`);
|
|
69
|
+
}
|
|
70
|
+
const params = values.join(';');
|
|
71
|
+
items.push(`"@signature-params: ${params}"`);
|
|
72
|
+
const ser = items.join('\n');
|
|
73
|
+
const signage = designature(signature!);
|
|
74
|
+
const cig = signage[0].markers.get(input.name);
|
|
75
|
+
if (!this._verfer.verify(cig.raw, ser)) {
|
|
76
|
+
throw new Error(`Signature for ${input.keyid} invalid.`);
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
sign(
|
|
84
|
+
headers: Headers,
|
|
85
|
+
method: string,
|
|
86
|
+
path: string,
|
|
87
|
+
fields?: Array<string>
|
|
88
|
+
): Headers {
|
|
89
|
+
if (fields == undefined) {
|
|
90
|
+
fields = Authenticater.DefaultFields;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const [header, sig] = siginput(this._csig, {
|
|
94
|
+
name: 'signify',
|
|
95
|
+
method,
|
|
96
|
+
path,
|
|
97
|
+
headers,
|
|
98
|
+
fields,
|
|
99
|
+
alg: 'ed25519',
|
|
100
|
+
keyid: this._csig.verfer.qb64,
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
header.forEach((value, key) => {
|
|
104
|
+
headers.append(key, value);
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
const markers = new Map<string, Siger | Cigar>();
|
|
108
|
+
markers.set('signify', sig);
|
|
109
|
+
const signage = new Signage(markers, false);
|
|
110
|
+
const signed = signature([signage]);
|
|
111
|
+
signed.forEach((value, key) => {
|
|
112
|
+
headers.append(key, value);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
return headers;
|
|
116
|
+
}
|
|
117
|
+
}
|