@atcute/did-plc 0.1.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 +17 -0
- package/README.md +15 -0
- package/dist/constants.d.ts +1 -0
- package/dist/constants.js +5 -0
- package/dist/constants.js.map +1 -0
- package/dist/data.d.ts +32 -0
- package/dist/data.js +183 -0
- package/dist/data.js.map +1 -0
- package/dist/errors.d.ts +33 -0
- package/dist/errors.js +53 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/typedefs.d.ts +17 -0
- package/dist/typedefs.js +162 -0
- package/dist/typedefs.js.map +1 -0
- package/dist/types.d.ts +54 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +5 -0
- package/dist/utils.js +51 -0
- package/dist/utils.js.map +1 -0
- package/lib/constants.ts +5 -0
- package/lib/data.ts +245 -0
- package/lib/errors.ts +57 -0
- package/lib/index.ts +7 -0
- package/lib/typedefs.ts +201 -0
- package/lib/types.ts +71 -0
- package/lib/utils.ts +66 -0
- package/package.json +42 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
2
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
3
|
+
in the Software without restriction, including without limitation the rights
|
|
4
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
5
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
6
|
+
furnished to do so, subject to the following conditions:
|
|
7
|
+
|
|
8
|
+
The above copyright notice and this permission notice shall be included in all
|
|
9
|
+
copies or substantial portions of the Software.
|
|
10
|
+
|
|
11
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
12
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
13
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
14
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
15
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
16
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
17
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# @atcute/did-plc
|
|
2
|
+
|
|
3
|
+
validations, type definitions and schemas for did:plc operations
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
import { defs, validateIndexedOperationLog } from '@atcute/did-plc';
|
|
7
|
+
|
|
8
|
+
const did = `did:plc:ragtjsm2j2vknwkz3zp4oxrd`;
|
|
9
|
+
|
|
10
|
+
const response = await fetch(`https://plc.directory/${did}/log/audit`);
|
|
11
|
+
const json = await response.json();
|
|
12
|
+
|
|
13
|
+
const logs = defs.indexedOperationLog.parse(json);
|
|
14
|
+
await validateIndexedOperationLog(did, logs);
|
|
15
|
+
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const DISPUTE_WINDOW: number;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../lib/constants.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,GAAG,GAAG,CAAC;AACnB,MAAM,MAAM,GAAG,EAAE,GAAG,MAAM,CAAC;AAC3B,MAAM,IAAI,GAAG,EAAE,GAAG,MAAM,CAAC;AAEzB,MAAM,CAAC,MAAM,cAAc,GAAG,EAAE,GAAG,IAAI,CAAC"}
|
package/dist/data.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import * as t from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Process an indexed entry by validating it and integrating it into the canonical log.
|
|
4
|
+
*/
|
|
5
|
+
export declare const processIndexedEntry: (did: t.DidPlcString, canonical: t.IndexedEntryWithSigner[], proposed: t.IndexedEntry) => Promise<{
|
|
6
|
+
prev: string | null;
|
|
7
|
+
ops: t.IndexedEntryWithSigner[];
|
|
8
|
+
nullified: t.IndexedEntryWithSigner[];
|
|
9
|
+
}>;
|
|
10
|
+
/**
|
|
11
|
+
* Process an indexed entry log by sequentially processing each operation.
|
|
12
|
+
*/
|
|
13
|
+
export declare const processIndexedEntryLog: (did: t.DidPlcString, ops: t.IndexedEntryLog) => Promise<{
|
|
14
|
+
canonical: t.IndexedEntryWithSigner[];
|
|
15
|
+
nullified: t.IndexedEntryWithSigner[];
|
|
16
|
+
}>;
|
|
17
|
+
/**
|
|
18
|
+
* Check whether an operation can still be disputed
|
|
19
|
+
*/
|
|
20
|
+
export declare const isDisputePeriodActive: (disputed: t.IndexedEntry, now?: number) => boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Check if a key is authorized to dispute an operation
|
|
23
|
+
*/
|
|
24
|
+
export declare const isAuthorizedForDispute: (base: t.IndexedEntryWithSigner<t.CompatibleOperation>, disputed: t.IndexedEntryWithSigner, key: t.DidKeyString) => boolean;
|
|
25
|
+
export interface DisputeCandidate {
|
|
26
|
+
base: t.IndexedEntryWithSigner<t.CompatibleOperation>;
|
|
27
|
+
disputed: t.IndexedEntryWithSigner;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Finds operations that can be disputed by a given key
|
|
31
|
+
*/
|
|
32
|
+
export declare const getDisputeCandidates: (canonical: t.IndexedEntryWithSigner[], key: t.DidKeyString) => DisputeCandidate[];
|
package/dist/data.js
ADDED
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import * as CBOR from '@atcute/cbor';
|
|
2
|
+
import * as CID from '@atcute/cid';
|
|
3
|
+
import { toBase32 } from '@atcute/multibase';
|
|
4
|
+
import { toSha256 } from '@atcute/uint8array';
|
|
5
|
+
import { DISPUTE_WINDOW } from './constants.js';
|
|
6
|
+
import * as err from './errors.js';
|
|
7
|
+
import * as t from './types.js';
|
|
8
|
+
import { isSignedOperationValid, normalizeOp } from './utils.js';
|
|
9
|
+
/**
|
|
10
|
+
* Process an indexed entry by validating it and integrating it into the canonical log.
|
|
11
|
+
*/
|
|
12
|
+
export const processIndexedEntry = async (did, canonical, proposed) => {
|
|
13
|
+
if (canonical.length === 0) {
|
|
14
|
+
if (proposed.operation.type === 'plc_tombstone') {
|
|
15
|
+
throw new err.ImproperOperationError(proposed, `expected genesis op to not be tombstone`);
|
|
16
|
+
}
|
|
17
|
+
if (proposed.operation.prev !== null) {
|
|
18
|
+
throw new err.ImproperOperationError(proposed, `expected null prev on genesis op`);
|
|
19
|
+
}
|
|
20
|
+
// Check if CID and DID matches
|
|
21
|
+
{
|
|
22
|
+
const opBytes = CBOR.encode(proposed.operation);
|
|
23
|
+
const expectedDid = `did:plc:${toBase32(await toSha256(opBytes)).slice(0, 24)}`;
|
|
24
|
+
if (expectedDid !== did) {
|
|
25
|
+
throw new err.GenesisHashError(proposed, did);
|
|
26
|
+
}
|
|
27
|
+
const expectedCid = CID.toString(await CID.create(CID.CODEC_DCBOR, opBytes));
|
|
28
|
+
if (expectedCid !== proposed.cid) {
|
|
29
|
+
throw new err.InvalidHashError(proposed, expectedCid);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
// Check if signature is valid
|
|
33
|
+
let allowedSigners;
|
|
34
|
+
let signedBy;
|
|
35
|
+
{
|
|
36
|
+
const { rotationKeys } = normalizeOp(proposed.operation);
|
|
37
|
+
const ok = await isSignedOperationValid(rotationKeys, proposed.operation);
|
|
38
|
+
if (!ok) {
|
|
39
|
+
throw new err.InvalidSignatureError(proposed);
|
|
40
|
+
}
|
|
41
|
+
allowedSigners = rotationKeys;
|
|
42
|
+
signedBy = ok;
|
|
43
|
+
}
|
|
44
|
+
return {
|
|
45
|
+
prev: null,
|
|
46
|
+
nullified: [],
|
|
47
|
+
ops: [{ ...proposed, allowedSigners, signedBy }],
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
// Grab the previous reference
|
|
51
|
+
const proposedPrev = proposed.operation.prev;
|
|
52
|
+
if (!proposedPrev) {
|
|
53
|
+
throw new err.ImproperOperationError(proposed, `expected prev op`);
|
|
54
|
+
}
|
|
55
|
+
const indexOfPrev = canonical.findIndex((op) => op.cid === proposedPrev);
|
|
56
|
+
if (indexOfPrev === -1) {
|
|
57
|
+
throw new err.ImproperOperationError(proposed, `prev op not in history`);
|
|
58
|
+
}
|
|
59
|
+
// Check if the CID matches
|
|
60
|
+
{
|
|
61
|
+
const opBytes = CBOR.encode(proposed.operation);
|
|
62
|
+
const expectedCid = CID.toString(await CID.create(CID.CODEC_DCBOR, opBytes));
|
|
63
|
+
if (expectedCid !== proposed.cid) {
|
|
64
|
+
throw new err.InvalidHashError(proposed, expectedCid);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
// Get the proposed canonical history
|
|
68
|
+
const alteredHistory = canonical.slice(0, indexOfPrev + 1);
|
|
69
|
+
const nullified = canonical.slice(indexOfPrev + 1);
|
|
70
|
+
const lastOp = alteredHistory.at(-1);
|
|
71
|
+
if (!lastOp) {
|
|
72
|
+
throw new err.ImproperOperationError(proposed, `missing last op`);
|
|
73
|
+
}
|
|
74
|
+
if (lastOp.operation.type === 'plc_tombstone') {
|
|
75
|
+
throw new err.ImproperOperationError(proposed, `did is tombstoned`);
|
|
76
|
+
}
|
|
77
|
+
const lastOpNormalized = normalizeOp(lastOp.operation);
|
|
78
|
+
const firstNullified = nullified[0];
|
|
79
|
+
// We're not nullifying, check if the signature is valid and move on
|
|
80
|
+
if (!firstNullified) {
|
|
81
|
+
const allowedSigners = lastOpNormalized.rotationKeys;
|
|
82
|
+
const signedBy = await isSignedOperationValid(allowedSigners, proposed.operation);
|
|
83
|
+
if (!signedBy) {
|
|
84
|
+
throw new err.InvalidSignatureError(proposed);
|
|
85
|
+
}
|
|
86
|
+
return {
|
|
87
|
+
prev: proposedPrev,
|
|
88
|
+
nullified: [],
|
|
89
|
+
ops: [...canonical, { ...proposed, allowedSigners, signedBy }],
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
// The indexed log should say that all of the nullified has `nullified: true`
|
|
93
|
+
// for (let idx = 0, len = nullified.length; idx < len; idx++) {
|
|
94
|
+
// const op = nullified[idx];
|
|
95
|
+
// if (!op.nullified) {
|
|
96
|
+
// throw new err.ImproperOperationError(op, `expected nullified prop to be true`);
|
|
97
|
+
// }
|
|
98
|
+
// }
|
|
99
|
+
// Check if operation within the recovery window
|
|
100
|
+
{
|
|
101
|
+
const lapsed = new Date(proposed.createdAt).getTime() - new Date(firstNullified.createdAt).getTime();
|
|
102
|
+
if (lapsed > DISPUTE_WINDOW) {
|
|
103
|
+
throw new err.LateDisputeError(proposed, lapsed);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
// Check if the dispute is valid
|
|
107
|
+
{
|
|
108
|
+
let allowedSigners;
|
|
109
|
+
let signedBy;
|
|
110
|
+
{
|
|
111
|
+
const disputedSigner = firstNullified.signedBy;
|
|
112
|
+
const indexOfSigner = lastOpNormalized.rotationKeys.indexOf(disputedSigner);
|
|
113
|
+
const morePowerfulKeys = lastOpNormalized.rotationKeys.slice(0, indexOfSigner);
|
|
114
|
+
const ok = await isSignedOperationValid(morePowerfulKeys, proposed.operation);
|
|
115
|
+
if (!ok) {
|
|
116
|
+
throw new err.InvalidSignatureError(proposed);
|
|
117
|
+
}
|
|
118
|
+
allowedSigners = morePowerfulKeys;
|
|
119
|
+
signedBy = ok;
|
|
120
|
+
}
|
|
121
|
+
return {
|
|
122
|
+
prev: proposedPrev,
|
|
123
|
+
nullified: nullified,
|
|
124
|
+
ops: [...alteredHistory, { ...proposed, allowedSigners, signedBy }],
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
/**
|
|
129
|
+
* Process an indexed entry log by sequentially processing each operation.
|
|
130
|
+
*/
|
|
131
|
+
export const processIndexedEntryLog = async (did, ops) => {
|
|
132
|
+
let nullified = [];
|
|
133
|
+
let canonical = [];
|
|
134
|
+
for (const operation of ops) {
|
|
135
|
+
const result = await processIndexedEntry(did, canonical, operation);
|
|
136
|
+
canonical = result.ops;
|
|
137
|
+
if (result.nullified.length > 0) {
|
|
138
|
+
nullified = nullified.concat(result.nullified);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return { canonical, nullified };
|
|
142
|
+
};
|
|
143
|
+
/**
|
|
144
|
+
* Check whether an operation can still be disputed
|
|
145
|
+
*/
|
|
146
|
+
export const isDisputePeriodActive = (disputed, now = Date.now()) => {
|
|
147
|
+
const lapsed = now - new Date(disputed.createdAt).getTime();
|
|
148
|
+
return lapsed <= DISPUTE_WINDOW;
|
|
149
|
+
};
|
|
150
|
+
/**
|
|
151
|
+
* Check if a key is authorized to dispute an operation
|
|
152
|
+
*/
|
|
153
|
+
export const isAuthorizedForDispute = (base, disputed, key) => {
|
|
154
|
+
const { rotationKeys } = normalizeOp(base.operation);
|
|
155
|
+
const disputedSigner = disputed.signedBy;
|
|
156
|
+
const disputedIndex = rotationKeys.indexOf(disputedSigner);
|
|
157
|
+
if (disputedIndex === -1) {
|
|
158
|
+
return false;
|
|
159
|
+
}
|
|
160
|
+
const didKeyIndex = rotationKeys.indexOf(key);
|
|
161
|
+
return didKeyIndex !== -1 && didKeyIndex < disputedIndex;
|
|
162
|
+
};
|
|
163
|
+
/**
|
|
164
|
+
* Finds operations that can be disputed by a given key
|
|
165
|
+
*/
|
|
166
|
+
export const getDisputeCandidates = (canonical, key) => {
|
|
167
|
+
const candidates = [];
|
|
168
|
+
const now = Date.now();
|
|
169
|
+
for (let idx = 1, len = canonical.length; idx < len; idx++) {
|
|
170
|
+
const base = canonical[idx - 1];
|
|
171
|
+
const disputed = canonical[idx];
|
|
172
|
+
// Only consider if it's still within the recovery window.
|
|
173
|
+
if (!isDisputePeriodActive(disputed, now)) {
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
// Check if the provided key is allowed to dispute this operation.
|
|
177
|
+
if (isAuthorizedForDispute(base, disputed, key)) {
|
|
178
|
+
candidates.push({ base, disputed });
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
return candidates;
|
|
182
|
+
};
|
|
183
|
+
//# sourceMappingURL=data.js.map
|
package/dist/data.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data.js","sourceRoot":"","sources":["../lib/data.ts"],"names":[],"mappings":"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"}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import * as t from './types.js';
|
|
2
|
+
export declare class PlcError extends Error {
|
|
3
|
+
name: string;
|
|
4
|
+
}
|
|
5
|
+
export declare class ImproperOperationError extends PlcError {
|
|
6
|
+
operation: t.IndexedEntry;
|
|
7
|
+
reason: string;
|
|
8
|
+
name: string;
|
|
9
|
+
constructor(operation: t.IndexedEntry, reason: string);
|
|
10
|
+
}
|
|
11
|
+
export declare class InvalidSignatureError extends PlcError {
|
|
12
|
+
operation: t.IndexedEntry;
|
|
13
|
+
name: string;
|
|
14
|
+
constructor(operation: t.IndexedEntry);
|
|
15
|
+
}
|
|
16
|
+
export declare class InvalidHashError extends PlcError {
|
|
17
|
+
operation: t.IndexedEntry;
|
|
18
|
+
expected: string;
|
|
19
|
+
name: string;
|
|
20
|
+
constructor(operation: t.IndexedEntry, expected: string);
|
|
21
|
+
}
|
|
22
|
+
export declare class GenesisHashError extends PlcError {
|
|
23
|
+
operation: t.IndexedEntry;
|
|
24
|
+
did: t.DidPlcString;
|
|
25
|
+
name: string;
|
|
26
|
+
constructor(operation: t.IndexedEntry, did: t.DidPlcString);
|
|
27
|
+
}
|
|
28
|
+
export declare class LateDisputeError extends PlcError {
|
|
29
|
+
operation: t.IndexedEntry;
|
|
30
|
+
lapsed: number;
|
|
31
|
+
name: string;
|
|
32
|
+
constructor(operation: t.IndexedEntry, lapsed: number);
|
|
33
|
+
}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import * as t from './types.js';
|
|
2
|
+
export class PlcError extends Error {
|
|
3
|
+
name = 'PlcError';
|
|
4
|
+
}
|
|
5
|
+
export class ImproperOperationError extends PlcError {
|
|
6
|
+
operation;
|
|
7
|
+
reason;
|
|
8
|
+
name = 'ImproperOperationError';
|
|
9
|
+
constructor(operation, reason) {
|
|
10
|
+
super(`improper operation; cid=${operation.cid}; reason=${reason}`);
|
|
11
|
+
this.operation = operation;
|
|
12
|
+
this.reason = reason;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
export class InvalidSignatureError extends PlcError {
|
|
16
|
+
operation;
|
|
17
|
+
name = 'InvalidSignatureError';
|
|
18
|
+
constructor(operation) {
|
|
19
|
+
super(`invalid signature; cid=${operation.cid}`);
|
|
20
|
+
this.operation = operation;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
export class InvalidHashError extends PlcError {
|
|
24
|
+
operation;
|
|
25
|
+
expected;
|
|
26
|
+
name = 'InvalidHashError';
|
|
27
|
+
constructor(operation, expected) {
|
|
28
|
+
super(`invalid hash; expected=${expected}; got=${operation.cid}`);
|
|
29
|
+
this.operation = operation;
|
|
30
|
+
this.expected = expected;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
export class GenesisHashError extends PlcError {
|
|
34
|
+
operation;
|
|
35
|
+
did;
|
|
36
|
+
name = 'GenesisHashError';
|
|
37
|
+
constructor(operation, did) {
|
|
38
|
+
super(`mismatching genesis hash; did=${did}; cid=${operation.cid}`);
|
|
39
|
+
this.operation = operation;
|
|
40
|
+
this.did = did;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
export class LateDisputeError extends PlcError {
|
|
44
|
+
operation;
|
|
45
|
+
lapsed;
|
|
46
|
+
name = 'LateDisputeError';
|
|
47
|
+
constructor(operation, lapsed) {
|
|
48
|
+
super(`dispute occured outside of permitted window; cid=${operation.cid}; lapsed=${lapsed}`);
|
|
49
|
+
this.operation = operation;
|
|
50
|
+
this.lapsed = lapsed;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../lib/errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,YAAY,CAAC;AAEhC,MAAM,OAAO,QAAS,SAAQ,KAAK;IACzB,IAAI,GAAG,UAAU,CAAC;CAC3B;AAED,MAAM,OAAO,sBAAuB,SAAQ,QAAQ;IAI3C;IACA;IAJC,IAAI,GAAG,wBAAwB,CAAC;IAEzC,YACQ,SAAyB,EACzB,MAAc;QAErB,KAAK,CAAC,2BAA2B,SAAS,CAAC,GAAG,YAAY,MAAM,EAAE,CAAC,CAAC;QAH7D,cAAS,GAAT,SAAS,CAAgB;QACzB,WAAM,GAAN,MAAM,CAAQ;IAGtB,CAAC;CACD;AAED,MAAM,OAAO,qBAAsB,SAAQ,QAAQ;IAG/B;IAFV,IAAI,GAAG,uBAAuB,CAAC;IAExC,YAAmB,SAAyB;QAC3C,KAAK,CAAC,0BAA0B,SAAS,CAAC,GAAG,EAAE,CAAC,CAAC;QAD/B,cAAS,GAAT,SAAS,CAAgB;IAE5C,CAAC;CACD;AAED,MAAM,OAAO,gBAAiB,SAAQ,QAAQ;IAIrC;IACA;IAJC,IAAI,GAAG,kBAAkB,CAAC;IAEnC,YACQ,SAAyB,EACzB,QAAgB;QAEvB,KAAK,CAAC,0BAA0B,QAAQ,SAAS,SAAS,CAAC,GAAG,EAAE,CAAC,CAAC;QAH3D,cAAS,GAAT,SAAS,CAAgB;QACzB,aAAQ,GAAR,QAAQ,CAAQ;IAGxB,CAAC;CACD;AAED,MAAM,OAAO,gBAAiB,SAAQ,QAAQ;IAIrC;IACA;IAJC,IAAI,GAAG,kBAAkB,CAAC;IAEnC,YACQ,SAAyB,EACzB,GAAmB;QAE1B,KAAK,CAAC,iCAAiC,GAAG,SAAS,SAAS,CAAC,GAAG,EAAE,CAAC,CAAC;QAH7D,cAAS,GAAT,SAAS,CAAgB;QACzB,QAAG,GAAH,GAAG,CAAgB;IAG3B,CAAC;CACD;AAED,MAAM,OAAO,gBAAiB,SAAQ,QAAQ;IAIrC;IACA;IAJC,IAAI,GAAG,kBAAkB,CAAC;IAEnC,YACQ,SAAyB,EACzB,MAAc;QAErB,KAAK,CAAC,oDAAoD,SAAS,CAAC,GAAG,YAAY,MAAM,EAAE,CAAC,CAAC;QAHtF,cAAS,GAAT,SAAS,CAAgB;QACzB,WAAM,GAAN,MAAM,CAAQ;IAGtB,CAAC;CACD"}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,eAAe,CAAC;AACtC,cAAc,YAAY,CAAC;AAE3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import * as v from '@badrap/valita';
|
|
2
|
+
import * as t from './types.js';
|
|
3
|
+
export declare const didPlcString: v.Type<`did:plc:${string}`>;
|
|
4
|
+
export declare const didKeyString: v.Type<`did:key:${string}`>;
|
|
5
|
+
export declare const unsignedLegacyCreateOperation: v.Type<t.UnsignedLegacyCreateOperation>;
|
|
6
|
+
export declare const legacyCreateOperation: v.Type<t.LegacyCreateOperation>;
|
|
7
|
+
export declare const service: v.Type<t.Service>;
|
|
8
|
+
export declare const unsignedOperation: v.Type<t.UnsignedOperation>;
|
|
9
|
+
export declare const operation: v.Type<t.Operation>;
|
|
10
|
+
export declare const unsignedTombstone: v.Type<t.UnsignedTombstone>;
|
|
11
|
+
export declare const tombstone: v.Type<t.Tombstone>;
|
|
12
|
+
export declare const compatibleOperation: v.Type<t.CompatibleOperation>;
|
|
13
|
+
export declare const compatibleOperationOrTombstone: v.Type<t.CompatibleOperationOrTombstone>;
|
|
14
|
+
export declare const operationOrTombstone: v.Type<t.OperationOrTombstone>;
|
|
15
|
+
export declare const operationLog: v.Type<t.OperationLog>;
|
|
16
|
+
export declare const indexedEntry: v.Type<t.IndexedEntry>;
|
|
17
|
+
export declare const indexedEntryLog: v.Type<t.IndexedEntryLog>;
|
package/dist/typedefs.js
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import * as v from '@badrap/valita';
|
|
2
|
+
import * as CID from '@atcute/cid';
|
|
3
|
+
import { parseDidKey } from '@atcute/crypto';
|
|
4
|
+
import * as t from './types.js';
|
|
5
|
+
// #region Strings
|
|
6
|
+
const DID_PLC_RE = /^did:plc:([a-z2-7]{24})$/;
|
|
7
|
+
export const didPlcString = v
|
|
8
|
+
.string()
|
|
9
|
+
.assert((input) => DID_PLC_RE.test(input), `must be a did:plc`);
|
|
10
|
+
export const didKeyString = v.string().chain((input) => {
|
|
11
|
+
try {
|
|
12
|
+
parseDidKey(input);
|
|
13
|
+
}
|
|
14
|
+
catch (err) {
|
|
15
|
+
if (err instanceof SyntaxError) {
|
|
16
|
+
return v.err(`did:key can't be parsed`);
|
|
17
|
+
}
|
|
18
|
+
return v.err(`invalid did:key`);
|
|
19
|
+
}
|
|
20
|
+
return v.ok(input);
|
|
21
|
+
});
|
|
22
|
+
const cidString = v.string().chain((input) => {
|
|
23
|
+
try {
|
|
24
|
+
CID.fromString(input);
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return v.err(`invalid cid`);
|
|
28
|
+
}
|
|
29
|
+
return v.ok(input);
|
|
30
|
+
});
|
|
31
|
+
// #endregion
|
|
32
|
+
// #region create
|
|
33
|
+
const _unsignedLegacyCreateOperation = v.object({
|
|
34
|
+
type: v.literal('create'),
|
|
35
|
+
prev: v.null(),
|
|
36
|
+
signingKey: didKeyString,
|
|
37
|
+
recoveryKey: didKeyString,
|
|
38
|
+
handle: v.string().assert((input) => input.length <= 256, `handle too long (max 256 characters)`),
|
|
39
|
+
service: v
|
|
40
|
+
.string()
|
|
41
|
+
.assert((input) => input.length <= 512, `service endpoint too long (max 512 characters)`),
|
|
42
|
+
});
|
|
43
|
+
export const unsignedLegacyCreateOperation = _unsignedLegacyCreateOperation;
|
|
44
|
+
export const legacyCreateOperation = _unsignedLegacyCreateOperation.extend({
|
|
45
|
+
sig: v.string(),
|
|
46
|
+
});
|
|
47
|
+
// #endregion
|
|
48
|
+
// #region plc_operation
|
|
49
|
+
export const service = v.object({
|
|
50
|
+
type: v.string().assert((input) => input.length <= 256, `service type too long (max 256 characters)`),
|
|
51
|
+
endpoint: v
|
|
52
|
+
.string()
|
|
53
|
+
.assert((input) => input.length <= 512, `service endpoint too long (max 512 characters)`),
|
|
54
|
+
});
|
|
55
|
+
const _unsignedOperation = v.object({
|
|
56
|
+
type: v.literal('plc_operation'),
|
|
57
|
+
prev: v.string().nullable(),
|
|
58
|
+
rotationKeys: v.array(didKeyString).chain((input) => {
|
|
59
|
+
const length = input.length;
|
|
60
|
+
if (length === 0) {
|
|
61
|
+
return v.err(`missing rotation keys`);
|
|
62
|
+
}
|
|
63
|
+
else if (length > 10) {
|
|
64
|
+
return v.err(`too many rotation keys (max 10 keys)`);
|
|
65
|
+
}
|
|
66
|
+
for (let i = 0; i < length; i++) {
|
|
67
|
+
const key = input[i];
|
|
68
|
+
for (let j = 0; j < i; j++) {
|
|
69
|
+
if (input[j] === key) {
|
|
70
|
+
return v.err({
|
|
71
|
+
message: `duplicate "${key}" rotation key`,
|
|
72
|
+
path: [i],
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return v.ok(input);
|
|
78
|
+
}),
|
|
79
|
+
verificationMethods: v.record(didKeyString).chain((input) => {
|
|
80
|
+
for (const id in input) {
|
|
81
|
+
if (id.length > 32) {
|
|
82
|
+
return v.err({
|
|
83
|
+
message: `verification method id too long (max 32 characters)`,
|
|
84
|
+
path: [id],
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return v.ok(input);
|
|
89
|
+
}),
|
|
90
|
+
alsoKnownAs: v
|
|
91
|
+
.array(v.string().assert((input) => input.length <= 256, `aka entry too long (max 256 characters)`))
|
|
92
|
+
.chain((input) => {
|
|
93
|
+
const length = input.length;
|
|
94
|
+
if (length > 10) {
|
|
95
|
+
return v.err(`too many aka entries (max 10)`);
|
|
96
|
+
}
|
|
97
|
+
for (let i = 0; i < length; i++) {
|
|
98
|
+
const aka = input[i];
|
|
99
|
+
for (let j = 0; j < i; j++) {
|
|
100
|
+
if (input[j] === aka) {
|
|
101
|
+
return v.err({
|
|
102
|
+
message: `duplicate "${aka}" aka entry`,
|
|
103
|
+
path: [i],
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return v.ok(input);
|
|
109
|
+
}),
|
|
110
|
+
services: v.record(service).chain((input) => {
|
|
111
|
+
const length = Object.keys(input).length;
|
|
112
|
+
if (length > 10) {
|
|
113
|
+
return v.err(`too many service entries (max 10)`);
|
|
114
|
+
}
|
|
115
|
+
for (const id in input) {
|
|
116
|
+
if (id.length > 32) {
|
|
117
|
+
return v.err({
|
|
118
|
+
message: `service id too long (max 32 characters)`,
|
|
119
|
+
path: [id],
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return v.ok(input);
|
|
124
|
+
}),
|
|
125
|
+
});
|
|
126
|
+
export const unsignedOperation = _unsignedOperation;
|
|
127
|
+
export const operation = _unsignedOperation.extend({
|
|
128
|
+
sig: v.string(),
|
|
129
|
+
});
|
|
130
|
+
// #endregion
|
|
131
|
+
// #region plc_tombstone
|
|
132
|
+
const _unsignedTombstone = v.object({
|
|
133
|
+
type: v.literal('plc_tombstone'),
|
|
134
|
+
prev: v.string(),
|
|
135
|
+
});
|
|
136
|
+
export const unsignedTombstone = _unsignedTombstone;
|
|
137
|
+
export const tombstone = _unsignedTombstone.extend({
|
|
138
|
+
sig: v.string(),
|
|
139
|
+
});
|
|
140
|
+
// #endregion
|
|
141
|
+
// #region Entry
|
|
142
|
+
export const compatibleOperation = v.union(operation, legacyCreateOperation);
|
|
143
|
+
export const compatibleOperationOrTombstone = v.union(operation, legacyCreateOperation, tombstone);
|
|
144
|
+
export const operationOrTombstone = v.union(operation, tombstone);
|
|
145
|
+
export const operationLog = v
|
|
146
|
+
.tuple([compatibleOperation])
|
|
147
|
+
.concat(v.array(operationOrTombstone));
|
|
148
|
+
// #endregion
|
|
149
|
+
// #region Indexed entry
|
|
150
|
+
const _indexedEntry = v.object({
|
|
151
|
+
did: didPlcString,
|
|
152
|
+
operation: compatibleOperationOrTombstone,
|
|
153
|
+
cid: cidString,
|
|
154
|
+
nullified: v.boolean(),
|
|
155
|
+
createdAt: v.string().assert((input) => !Number.isNaN(new Date(input).getTime()), `invalid timestamp`),
|
|
156
|
+
});
|
|
157
|
+
export const indexedEntry = _indexedEntry;
|
|
158
|
+
export const indexedEntryLog = v
|
|
159
|
+
.tuple([_indexedEntry.extend({ operation: compatibleOperation })])
|
|
160
|
+
.concat(v.array(_indexedEntry.extend({ operation: operationOrTombstone })));
|
|
161
|
+
// #endregion
|
|
162
|
+
//# sourceMappingURL=typedefs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typedefs.js","sourceRoot":"","sources":["../lib/typedefs.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
export type DidPlcString = `did:plc:${string}`;
|
|
2
|
+
export type DidKeyString = `did:key:${string}`;
|
|
3
|
+
export interface UnsignedLegacyCreateOperation {
|
|
4
|
+
type: 'create';
|
|
5
|
+
prev: null;
|
|
6
|
+
signingKey: DidKeyString;
|
|
7
|
+
recoveryKey: DidKeyString;
|
|
8
|
+
handle: string;
|
|
9
|
+
service: string;
|
|
10
|
+
}
|
|
11
|
+
export interface LegacyCreateOperation extends UnsignedLegacyCreateOperation {
|
|
12
|
+
sig: string;
|
|
13
|
+
}
|
|
14
|
+
export interface Service {
|
|
15
|
+
type: string;
|
|
16
|
+
endpoint: string;
|
|
17
|
+
}
|
|
18
|
+
export interface UnsignedOperation {
|
|
19
|
+
type: 'plc_operation';
|
|
20
|
+
prev: string | null;
|
|
21
|
+
alsoKnownAs: string[];
|
|
22
|
+
rotationKeys: DidKeyString[];
|
|
23
|
+
verificationMethods: Record<string, DidKeyString>;
|
|
24
|
+
services: Record<string, Service>;
|
|
25
|
+
}
|
|
26
|
+
export interface Operation extends UnsignedOperation {
|
|
27
|
+
sig: string;
|
|
28
|
+
}
|
|
29
|
+
export interface UnsignedTombstone {
|
|
30
|
+
type: 'plc_tombstone';
|
|
31
|
+
prev: string;
|
|
32
|
+
}
|
|
33
|
+
export interface Tombstone extends UnsignedTombstone {
|
|
34
|
+
sig: string;
|
|
35
|
+
}
|
|
36
|
+
export type CompatibleOperation = Operation | LegacyCreateOperation;
|
|
37
|
+
export type CompatibleOperationOrTombstone = CompatibleOperation | Tombstone;
|
|
38
|
+
export type OperationOrTombstone = Operation | Tombstone;
|
|
39
|
+
export type OperationLog = [genesis: CompatibleOperation, ...OperationOrTombstone[]];
|
|
40
|
+
export interface IndexedEntry<T extends CompatibleOperationOrTombstone = CompatibleOperationOrTombstone> {
|
|
41
|
+
did: DidPlcString;
|
|
42
|
+
operation: T;
|
|
43
|
+
cid: string;
|
|
44
|
+
nullified: boolean;
|
|
45
|
+
createdAt: string;
|
|
46
|
+
}
|
|
47
|
+
export interface IndexedEntryWithSigner<T extends CompatibleOperationOrTombstone = CompatibleOperationOrTombstone> extends IndexedEntry<T> {
|
|
48
|
+
allowedSigners: DidKeyString[];
|
|
49
|
+
signedBy: DidKeyString;
|
|
50
|
+
}
|
|
51
|
+
export type IndexedEntryLog = [
|
|
52
|
+
genesis: IndexedEntry<CompatibleOperation>,
|
|
53
|
+
...IndexedEntry<OperationOrTombstone>[]
|
|
54
|
+
];
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../lib/types.ts"],"names":[],"mappings":""}
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import * as t from './types.js';
|
|
2
|
+
export declare const wrapHttpPrefix: (str: string) => string;
|
|
3
|
+
export declare const wrapAtprotoPrefix: (str: string) => string;
|
|
4
|
+
export declare const normalizeOp: (op: t.CompatibleOperation) => t.Operation;
|
|
5
|
+
export declare const isSignedOperationValid: (allowedKeys: t.DidKeyString[], op: t.CompatibleOperationOrTombstone) => Promise<t.DidKeyString | null>;
|