@atproto/did 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/dist/did.js ADDED
@@ -0,0 +1,148 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.didSchema = exports.isDid = exports.checkDid = exports.checkDidMsid = exports.extractDidMethod = exports.checkDidMethod = exports.DID_PREFIX = void 0;
4
+ const zod_1 = require("zod");
5
+ const did_error_js_1 = require("./did-error.js");
6
+ const DID_PREFIX = 'did:';
7
+ exports.DID_PREFIX = DID_PREFIX;
8
+ const DID_PREFIX_LENGTH = DID_PREFIX.length;
9
+ /**
10
+ * DID Method-name check function.
11
+ *
12
+ * Check if the input is a valid DID method name, at the position between
13
+ * `start` (inclusive) and `end` (exclusive).
14
+ */
15
+ function checkDidMethod(input, start = 0, end = input.length) {
16
+ if (!Number.isFinite(end) ||
17
+ !Number.isFinite(start) ||
18
+ end < start ||
19
+ end > input.length) {
20
+ throw new TypeError('Invalid start or end position');
21
+ }
22
+ if (end === start) {
23
+ throw new did_error_js_1.InvalidDidError(input, `Empty method name`);
24
+ }
25
+ let c;
26
+ for (let i = start; i < end; i++) {
27
+ c = input.charCodeAt(i);
28
+ if ((c < 0x61 || c > 0x7a) && // a-z
29
+ (c < 0x30 || c > 0x39) // 0-9
30
+ ) {
31
+ throw new did_error_js_1.InvalidDidError(input, `Invalid character at position ${i} in DID method name`);
32
+ }
33
+ }
34
+ }
35
+ exports.checkDidMethod = checkDidMethod;
36
+ /**
37
+ * This method assumes the input is a valid Did
38
+ */
39
+ function extractDidMethod(did) {
40
+ const msidSep = did.indexOf(':', DID_PREFIX_LENGTH);
41
+ const method = did.slice(DID_PREFIX_LENGTH, msidSep);
42
+ return method;
43
+ }
44
+ exports.extractDidMethod = extractDidMethod;
45
+ /**
46
+ * DID Method-specific identifier check function.
47
+ *
48
+ * Check if the input is a valid DID method-specific identifier, at the position
49
+ * between `start` (inclusive) and `end` (exclusive).
50
+ */
51
+ function checkDidMsid(input, start = 0, end = input.length) {
52
+ if (!Number.isFinite(end) ||
53
+ !Number.isFinite(start) ||
54
+ end < start ||
55
+ end > input.length) {
56
+ throw new TypeError('Invalid start or end position');
57
+ }
58
+ if (end === start) {
59
+ throw new did_error_js_1.InvalidDidError(input, `DID method-specific id must not be empty`);
60
+ }
61
+ let c;
62
+ for (let i = start; i < end; i++) {
63
+ c = input.charCodeAt(i);
64
+ // Check for frequent chars first
65
+ if ((c < 0x61 || c > 0x7a) && // a-z
66
+ (c < 0x41 || c > 0x5a) && // A-Z
67
+ (c < 0x30 || c > 0x39) && // 0-9
68
+ c !== 0x2e && // .
69
+ c !== 0x2d && // -
70
+ c !== 0x5f // _
71
+ ) {
72
+ // Less frequent chars are checked here
73
+ // ":"
74
+ if (c === 0x3a) {
75
+ if (i === end - 1) {
76
+ throw new did_error_js_1.InvalidDidError(input, `DID cannot end with ":"`);
77
+ }
78
+ continue;
79
+ }
80
+ // pct-encoded
81
+ if (c === 0x25) {
82
+ c = input.charCodeAt(++i);
83
+ if ((c < 0x30 || c > 0x39) && (c < 0x41 || c > 0x46)) {
84
+ throw new did_error_js_1.InvalidDidError(input, `Invalid pct-encoded character at position ${i}`);
85
+ }
86
+ c = input.charCodeAt(++i);
87
+ if ((c < 0x30 || c > 0x39) && (c < 0x41 || c > 0x46)) {
88
+ throw new did_error_js_1.InvalidDidError(input, `Invalid pct-encoded character at position ${i}`);
89
+ }
90
+ // There must always be 2 HEXDIG after a "%"
91
+ if (i >= end) {
92
+ throw new did_error_js_1.InvalidDidError(input, `Incomplete pct-encoded character at position ${i - 2}`);
93
+ }
94
+ continue;
95
+ }
96
+ throw new did_error_js_1.InvalidDidError(input, `Disallowed character in DID at position ${i}`);
97
+ }
98
+ }
99
+ }
100
+ exports.checkDidMsid = checkDidMsid;
101
+ function checkDid(input) {
102
+ if (typeof input !== 'string') {
103
+ throw new did_error_js_1.InvalidDidError(typeof input, `DID must be a string`);
104
+ }
105
+ const { length } = input;
106
+ if (length > 2048) {
107
+ throw new did_error_js_1.InvalidDidError(input, `DID is too long (2048 chars max)`);
108
+ }
109
+ if (!input.startsWith(DID_PREFIX)) {
110
+ throw new did_error_js_1.InvalidDidError(input, `DID requires "${DID_PREFIX}" prefix`);
111
+ }
112
+ const idSep = input.indexOf(':', DID_PREFIX_LENGTH);
113
+ if (idSep === -1) {
114
+ throw new did_error_js_1.InvalidDidError(input, `Missing colon after method name`);
115
+ }
116
+ checkDidMethod(input, DID_PREFIX_LENGTH, idSep);
117
+ checkDidMsid(input, idSep + 1, length);
118
+ }
119
+ exports.checkDid = checkDid;
120
+ function isDid(input) {
121
+ try {
122
+ checkDid(input);
123
+ return true;
124
+ }
125
+ catch (err) {
126
+ if (err instanceof did_error_js_1.DidError) {
127
+ return false;
128
+ }
129
+ throw err;
130
+ }
131
+ }
132
+ exports.isDid = isDid;
133
+ exports.didSchema = zod_1.z
134
+ .string()
135
+ .superRefine((value, ctx) => {
136
+ try {
137
+ checkDid(value);
138
+ return true;
139
+ }
140
+ catch (err) {
141
+ ctx.addIssue({
142
+ code: zod_1.z.ZodIssueCode.custom,
143
+ message: err instanceof Error ? err.message : 'Unexpected error',
144
+ });
145
+ return false;
146
+ }
147
+ });
148
+ //# sourceMappingURL=did.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"did.js","sourceRoot":"","sources":["../src/did.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export * from './did-document.js';
2
+ export * from './did-error.js';
3
+ export * from './did.js';
4
+ export * from './methods.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAA;AACjC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,UAAU,CAAA;AACxB,cAAc,cAAc,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./did-document.js"), exports);
18
+ __exportStar(require("./did-error.js"), exports);
19
+ __exportStar(require("./did.js"), exports);
20
+ __exportStar(require("./methods.js"), exports);
21
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,oDAAiC;AACjC,iDAA8B;AAC9B,2CAAwB;AACxB,+CAA4B"}
@@ -0,0 +1,6 @@
1
+ import { Did } from '../did.js';
2
+ declare const DID_PLC_PREFIX = "did:plc:";
3
+ export { DID_PLC_PREFIX };
4
+ export declare function isDidPlc(input: unknown): input is Did<'plc'>;
5
+ export declare function checkDidPlc(input: string): asserts input is Did<'plc'>;
6
+ //# sourceMappingURL=plc.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plc.d.ts","sourceRoot":"","sources":["../../src/methods/plc.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAA;AAE/B,QAAA,MAAM,cAAc,aAAa,CAAA;AAIjC,OAAO,EAAE,cAAc,EAAE,CAAA;AAEzB,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,GAAG,CAAC,KAAK,CAAC,CAQ5D;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,IAAI,GAAG,CAAC,KAAK,CAAC,CAoBtE"}
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.checkDidPlc = exports.isDidPlc = exports.DID_PLC_PREFIX = void 0;
4
+ const did_error_js_1 = require("../did-error.js");
5
+ const DID_PLC_PREFIX = `did:plc:`;
6
+ exports.DID_PLC_PREFIX = DID_PLC_PREFIX;
7
+ const DID_PLC_PREFIX_LENGTH = DID_PLC_PREFIX.length;
8
+ const DID_PLC_LENGTH = 32;
9
+ function isDidPlc(input) {
10
+ if (typeof input !== 'string')
11
+ return false;
12
+ try {
13
+ checkDidPlc(input);
14
+ return true;
15
+ }
16
+ catch {
17
+ return false;
18
+ }
19
+ }
20
+ exports.isDidPlc = isDidPlc;
21
+ function checkDidPlc(input) {
22
+ if (input.length !== DID_PLC_LENGTH) {
23
+ throw new did_error_js_1.InvalidDidError(input, `did:plc must be ${DID_PLC_LENGTH} characters long`);
24
+ }
25
+ if (!input.startsWith(DID_PLC_PREFIX)) {
26
+ throw new did_error_js_1.InvalidDidError(input, `Invalid did:plc prefix`);
27
+ }
28
+ let c;
29
+ for (let i = DID_PLC_PREFIX_LENGTH; i < DID_PLC_LENGTH; i++) {
30
+ c = input.charCodeAt(i);
31
+ // Base32 encoding ([a-z2-7])
32
+ if ((c < 0x61 || c > 0x7a) && (c < 0x32 || c > 0x37)) {
33
+ throw new did_error_js_1.InvalidDidError(input, `Invalid character at position ${i}`);
34
+ }
35
+ }
36
+ }
37
+ exports.checkDidPlc = checkDidPlc;
38
+ //# sourceMappingURL=plc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plc.js","sourceRoot":"","sources":["../../src/methods/plc.ts"],"names":[],"mappings":";;;AAAA,kDAAiD;AAGjD,MAAM,cAAc,GAAG,UAAU,CAAA;AAIxB,wCAAc;AAHvB,MAAM,qBAAqB,GAAG,cAAc,CAAC,MAAM,CAAA;AACnD,MAAM,cAAc,GAAG,EAAE,CAAA;AAIzB,SAAgB,QAAQ,CAAC,KAAc;IACrC,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAA;IAC3C,IAAI,CAAC;QACH,WAAW,CAAC,KAAK,CAAC,CAAA;QAClB,OAAO,IAAI,CAAA;IACb,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC;AARD,4BAQC;AAED,SAAgB,WAAW,CAAC,KAAa;IACvC,IAAI,KAAK,CAAC,MAAM,KAAK,cAAc,EAAE,CAAC;QACpC,MAAM,IAAI,8BAAe,CACvB,KAAK,EACL,mBAAmB,cAAc,kBAAkB,CACpD,CAAA;IACH,CAAC;IAED,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;QACtC,MAAM,IAAI,8BAAe,CAAC,KAAK,EAAE,wBAAwB,CAAC,CAAA;IAC5D,CAAC;IAED,IAAI,CAAS,CAAA;IACb,KAAK,IAAI,CAAC,GAAG,qBAAqB,EAAE,CAAC,GAAG,cAAc,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5D,CAAC,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAA;QACvB,6BAA6B;QAC7B,IAAI,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC;YACrD,MAAM,IAAI,8BAAe,CAAC,KAAK,EAAE,iCAAiC,CAAC,EAAE,CAAC,CAAA;QACxE,CAAC;IACH,CAAC;AACH,CAAC;AApBD,kCAoBC"}
@@ -0,0 +1,16 @@
1
+ import { Did } from '../did.js';
2
+ export declare const DID_WEB_PREFIX = "did:web:";
3
+ /**
4
+ * This function checks if the input is a valid Web DID, as per DID spec.
5
+ * ATPROTO adds additional constraints to allowed DID values for the `did:web`
6
+ * method. Use {@link isAtprotoDidWeb} if that's what you need.
7
+ */
8
+ export declare function isDidWeb(input: unknown): input is Did<'web'>;
9
+ /**
10
+ * @see {@link https://atproto.com/specs/did#blessed-did-methods}
11
+ */
12
+ export declare function isAtprotoDidWeb(input: unknown): input is Did<'web'>;
13
+ export declare function checkDidWeb(input: string): asserts input is Did<'web'>;
14
+ export declare function didWebToUrl(did: string): URL;
15
+ export declare function urlToDidWeb(url: URL): Did<'web'>;
16
+ //# sourceMappingURL=web.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web.d.ts","sourceRoot":"","sources":["../../src/methods/web.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAgB,MAAM,WAAW,CAAA;AAE7C,eAAO,MAAM,cAAc,aAAa,CAAA;AAExC;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,GAAG,CAAC,KAAK,CAAC,CAQ5D;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,GAAG,CAAC,KAAK,CAAC,CAoBnE;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,IAAI,GAAG,CAAC,KAAK,CAAC,CAEtE;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAmB5C;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,CAOhD"}
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.urlToDidWeb = exports.didWebToUrl = exports.checkDidWeb = exports.isAtprotoDidWeb = exports.isDidWeb = exports.DID_WEB_PREFIX = void 0;
4
+ const did_error_js_1 = require("../did-error.js");
5
+ const did_js_1 = require("../did.js");
6
+ exports.DID_WEB_PREFIX = `did:web:`;
7
+ /**
8
+ * This function checks if the input is a valid Web DID, as per DID spec.
9
+ * ATPROTO adds additional constraints to allowed DID values for the `did:web`
10
+ * method. Use {@link isAtprotoDidWeb} if that's what you need.
11
+ */
12
+ function isDidWeb(input) {
13
+ if (typeof input !== 'string')
14
+ return false;
15
+ try {
16
+ didWebToUrl(input);
17
+ return true;
18
+ }
19
+ catch {
20
+ return false;
21
+ }
22
+ }
23
+ exports.isDidWeb = isDidWeb;
24
+ /**
25
+ * @see {@link https://atproto.com/specs/did#blessed-did-methods}
26
+ */
27
+ function isAtprotoDidWeb(input) {
28
+ // Optimization: make cheap checks first
29
+ if (typeof input !== 'string') {
30
+ return false;
31
+ }
32
+ // Path are not allowed
33
+ if (input.includes(':', exports.DID_WEB_PREFIX.length)) {
34
+ return false;
35
+ }
36
+ // Port numbers are not allowed, except for localhost
37
+ if (input.includes('%3A', exports.DID_WEB_PREFIX.length) &&
38
+ !input.startsWith('did:web:localhost%3A')) {
39
+ return false;
40
+ }
41
+ return isDidWeb(input);
42
+ }
43
+ exports.isAtprotoDidWeb = isAtprotoDidWeb;
44
+ function checkDidWeb(input) {
45
+ didWebToUrl(input);
46
+ }
47
+ exports.checkDidWeb = checkDidWeb;
48
+ function didWebToUrl(did) {
49
+ if (!did.startsWith(exports.DID_WEB_PREFIX)) {
50
+ throw new did_error_js_1.InvalidDidError(did, `did:web must start with ${exports.DID_WEB_PREFIX}`);
51
+ }
52
+ if (did.charAt(exports.DID_WEB_PREFIX.length) === ':') {
53
+ throw new did_error_js_1.InvalidDidError(did, 'did:web MSID must not start with a colon');
54
+ }
55
+ // Make sure every char is valid (per DID spec)
56
+ (0, did_js_1.checkDidMsid)(did, exports.DID_WEB_PREFIX.length);
57
+ try {
58
+ const msid = did.slice(exports.DID_WEB_PREFIX.length);
59
+ const parts = msid.split(':').map(decodeURIComponent);
60
+ return new URL(`https://${parts.join('/')}`);
61
+ }
62
+ catch (cause) {
63
+ throw new did_error_js_1.InvalidDidError(did, 'Invalid Web DID', cause);
64
+ }
65
+ }
66
+ exports.didWebToUrl = didWebToUrl;
67
+ function urlToDidWeb(url) {
68
+ const path = url.pathname === '/'
69
+ ? ''
70
+ : url.pathname.slice(1).split('/').map(encodeURIComponent).join(':');
71
+ return `did:web:${encodeURIComponent(url.host)}${path ? `:${path}` : ''}`;
72
+ }
73
+ exports.urlToDidWeb = urlToDidWeb;
74
+ //# sourceMappingURL=web.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/methods/web.ts"],"names":[],"mappings":";;;AAAA,kDAAiD;AACjD,sCAA6C;AAEhC,QAAA,cAAc,GAAG,UAAU,CAAA;AAExC;;;;GAIG;AACH,SAAgB,QAAQ,CAAC,KAAc;IACrC,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAA;IAC3C,IAAI,CAAC;QACH,WAAW,CAAC,KAAK,CAAC,CAAA;QAClB,OAAO,IAAI,CAAA;IACb,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC;AARD,4BAQC;AAED;;GAEG;AACH,SAAgB,eAAe,CAAC,KAAc;IAC5C,wCAAwC;IACxC,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAA;IACd,CAAC;IAED,uBAAuB;IACvB,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE,sBAAc,CAAC,MAAM,CAAC,EAAE,CAAC;QAC/C,OAAO,KAAK,CAAA;IACd,CAAC;IAED,qDAAqD;IACrD,IACE,KAAK,CAAC,QAAQ,CAAC,KAAK,EAAE,sBAAc,CAAC,MAAM,CAAC;QAC5C,CAAC,KAAK,CAAC,UAAU,CAAC,sBAAsB,CAAC,EACzC,CAAC;QACD,OAAO,KAAK,CAAA;IACd,CAAC;IAED,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAA;AACxB,CAAC;AApBD,0CAoBC;AAED,SAAgB,WAAW,CAAC,KAAa;IACvC,WAAW,CAAC,KAAK,CAAC,CAAA;AACpB,CAAC;AAFD,kCAEC;AAED,SAAgB,WAAW,CAAC,GAAW;IACrC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,sBAAc,CAAC,EAAE,CAAC;QACpC,MAAM,IAAI,8BAAe,CAAC,GAAG,EAAE,2BAA2B,sBAAc,EAAE,CAAC,CAAA;IAC7E,CAAC;IAED,IAAI,GAAG,CAAC,MAAM,CAAC,sBAAc,CAAC,MAAM,CAAC,KAAK,GAAG,EAAE,CAAC;QAC9C,MAAM,IAAI,8BAAe,CAAC,GAAG,EAAE,0CAA0C,CAAC,CAAA;IAC5E,CAAC;IAED,+CAA+C;IAC/C,IAAA,qBAAY,EAAC,GAAG,EAAE,sBAAc,CAAC,MAAM,CAAC,CAAA;IAExC,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,sBAAc,CAAC,MAAM,CAAC,CAAA;QAC7C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAA;QACrD,OAAO,IAAI,GAAG,CAAC,WAAW,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IAC9C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,8BAAe,CAAC,GAAG,EAAE,iBAAiB,EAAE,KAAK,CAAC,CAAA;IAC1D,CAAC;AACH,CAAC;AAnBD,kCAmBC;AAED,SAAgB,WAAW,CAAC,GAAQ;IAClC,MAAM,IAAI,GACR,GAAG,CAAC,QAAQ,KAAK,GAAG;QAClB,CAAC,CAAC,EAAE;QACJ,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAExE,OAAO,WAAW,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAA;AAC3E,CAAC;AAPD,kCAOC"}
@@ -0,0 +1,3 @@
1
+ export * from './methods/plc.js';
2
+ export * from './methods/web.js';
3
+ //# sourceMappingURL=methods.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"methods.d.ts","sourceRoot":"","sources":["../src/methods.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAA;AAChC,cAAc,kBAAkB,CAAA"}
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./methods/plc.js"), exports);
18
+ __exportStar(require("./methods/web.js"), exports);
19
+ //# sourceMappingURL=methods.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"methods.js","sourceRoot":"","sources":["../src/methods.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,mDAAgC;AAChC,mDAAgC"}
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "@atproto/did",
3
+ "version": "0.1.0",
4
+ "license": "MIT",
5
+ "description": "DID resolution and verification library",
6
+ "keywords": [
7
+ "atproto",
8
+ "did",
9
+ "validation",
10
+ "types"
11
+ ],
12
+ "homepage": "https://atproto.com",
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "https://github.com/bluesky-social/atproto",
16
+ "directory": "packages/did"
17
+ },
18
+ "type": "commonjs",
19
+ "main": "dist/index.js",
20
+ "types": "dist/index.d.ts",
21
+ "exports": {
22
+ ".": {
23
+ "types": "./dist/index.d.ts",
24
+ "default": "./dist/index.js"
25
+ }
26
+ },
27
+ "dependencies": {
28
+ "zod": "^3.23.8"
29
+ },
30
+ "devDependencies": {
31
+ "typescript": "^5.3.3"
32
+ },
33
+ "scripts": {
34
+ "build": "tsc --build tsconfig.build.json"
35
+ }
36
+ }
@@ -0,0 +1,151 @@
1
+ import { z } from 'zod'
2
+
3
+ import { Did, didSchema } from './did.js'
4
+
5
+ /**
6
+ * RFC3968 compliant URI
7
+ *
8
+ * @see {@link https://www.rfc-editor.org/rfc/rfc3986}
9
+ */
10
+ const rfc3968UriSchema = z.string().refine((data) => {
11
+ try {
12
+ new URL(data)
13
+ return true
14
+ } catch {
15
+ return false
16
+ }
17
+ }, 'RFC3968 compliant URI')
18
+
19
+ const didControllerSchema = z.union([didSchema, z.array(didSchema)])
20
+
21
+ /**
22
+ * @note this schema might be too permissive
23
+ */
24
+ const didRelativeUriSchema = z.union([
25
+ rfc3968UriSchema,
26
+ z.string().regex(/^#[^#]+$/),
27
+ ])
28
+
29
+ const didVerificationMethodSchema = z.object({
30
+ id: didRelativeUriSchema,
31
+ type: z.string().min(1),
32
+ controller: didControllerSchema,
33
+ publicKeyJwk: z.record(z.string(), z.unknown()).optional(),
34
+ publicKeyMultibase: z.string().optional(),
35
+ })
36
+
37
+ /**
38
+ * The value of the id property MUST be a URI conforming to [RFC3986]. A
39
+ * conforming producer MUST NOT produce multiple service entries with the same
40
+ * id. A conforming consumer MUST produce an error if it detects multiple
41
+ * service entries with the same id.
42
+ *
43
+ * @note Normally, only rfc3968UriSchema should be allowed here. However, the
44
+ * did:plc uses relative URI. For this reason, we also allow relative URIs
45
+ * here.
46
+ */
47
+ const didServiceIdSchema = didRelativeUriSchema
48
+
49
+ /**
50
+ * The value of the type property MUST be a string or a set of strings. In order
51
+ * to maximize interoperability, the service type and its associated properties
52
+ * SHOULD be registered in the DID Specification Registries
53
+ * [DID-SPEC-REGISTRIES].
54
+ */
55
+ const didServiceTypeSchema = z.union([z.string(), z.array(z.string())])
56
+
57
+ /**
58
+ * The value of the serviceEndpoint property MUST be a string, a map, or a set
59
+ * composed of one or more strings and/or maps. All string values MUST be valid
60
+ * URIs conforming to [RFC3986] and normalized according to the Normalization
61
+ * and Comparison rules in RFC3986 and to any normalization rules in its
62
+ * applicable URI scheme specification.
63
+ */
64
+ const didServiceEndpointSchema = z.union([
65
+ rfc3968UriSchema,
66
+ z.record(z.string(), rfc3968UriSchema),
67
+ z
68
+ .array(z.union([rfc3968UriSchema, z.record(z.string(), rfc3968UriSchema)]))
69
+ .nonempty(),
70
+ ])
71
+
72
+ /**
73
+ * Each service map MUST contain id, type, and serviceEndpoint properties.
74
+ * @see {@link https://www.w3.org/TR/did-core/#services}
75
+ */
76
+ const didServiceSchema = z.object({
77
+ id: didServiceIdSchema,
78
+ type: didServiceTypeSchema,
79
+ serviceEndpoint: didServiceEndpointSchema,
80
+ })
81
+
82
+ export type DidService = z.infer<typeof didServiceSchema>
83
+
84
+ const didAuthenticationSchema = z.union([
85
+ //
86
+ didRelativeUriSchema,
87
+ didVerificationMethodSchema,
88
+ ])
89
+
90
+ /**
91
+ * @note This schema is incomplete
92
+ * @see {@link https://www.w3.org/TR/did-core/#production-0}
93
+ */
94
+ export const didDocumentSchema = z.object({
95
+ '@context': z.union([
96
+ z.literal('https://www.w3.org/ns/did/v1'),
97
+ z
98
+ .array(z.string().url())
99
+ .nonempty()
100
+ .refine((data) => data[0] === 'https://www.w3.org/ns/did/v1', {
101
+ message: 'First @context must be https://www.w3.org/ns/did/v1',
102
+ }),
103
+ ]),
104
+ id: didSchema,
105
+ controller: didControllerSchema.optional(),
106
+ alsoKnownAs: z.array(rfc3968UriSchema).optional(),
107
+ service: z.array(didServiceSchema).optional(),
108
+ authentication: z.array(didAuthenticationSchema).optional(),
109
+ verificationMethod: z
110
+ .array(z.union([didVerificationMethodSchema, didRelativeUriSchema]))
111
+ .optional(),
112
+ })
113
+
114
+ export type DidDocument<Method extends string = string> = z.infer<
115
+ typeof didDocumentSchema
116
+ > & { id: Did<Method> }
117
+
118
+ // @TODO: add other refinements ?
119
+ export const didDocumentValidator = didDocumentSchema
120
+ .superRefine((data, ctx) => {
121
+ if (data.service) {
122
+ for (let i = 0; i < data.service.length; i++) {
123
+ if (data.service[i].id === data.id) {
124
+ ctx.addIssue({
125
+ code: z.ZodIssueCode.custom,
126
+ message: `Service id must be different from the document id`,
127
+ path: ['service', i, 'id'],
128
+ })
129
+ }
130
+ }
131
+ }
132
+ })
133
+ .superRefine((data, ctx) => {
134
+ if (data.service) {
135
+ const normalizedIds = data.service.map((s) =>
136
+ s.id?.startsWith('#') ? `${data.id}${s.id}` : s.id,
137
+ )
138
+
139
+ for (let i = 0; i < normalizedIds.length; i++) {
140
+ for (let j = i + 1; j < normalizedIds.length; j++) {
141
+ if (normalizedIds[i] === normalizedIds[j]) {
142
+ ctx.addIssue({
143
+ code: z.ZodIssueCode.custom,
144
+ message: `Duplicate service id (${normalizedIds[j]}) found in the document`,
145
+ path: ['service', j, 'id'],
146
+ })
147
+ }
148
+ }
149
+ }
150
+ }
151
+ })
@@ -0,0 +1,49 @@
1
+ export class DidError extends Error {
2
+ constructor(
3
+ public readonly did: string,
4
+ message: string,
5
+ public readonly code: string,
6
+ public readonly status = 400,
7
+ cause?: unknown,
8
+ ) {
9
+ super(message, { cause })
10
+ }
11
+
12
+ /**
13
+ * For compatibility with error handlers in common HTTP frameworks.
14
+ */
15
+ get statusCode() {
16
+ return this.status
17
+ }
18
+
19
+ override toString() {
20
+ return `${this.constructor.name} ${this.code} (${this.did}): ${this.message}`
21
+ }
22
+
23
+ static from(cause: unknown, did: string): DidError {
24
+ if (cause instanceof DidError) {
25
+ return cause
26
+ }
27
+
28
+ const message =
29
+ cause instanceof Error
30
+ ? cause.message
31
+ : typeof cause === 'string'
32
+ ? cause
33
+ : 'An unknown error occurred'
34
+
35
+ const status =
36
+ (typeof cause?.['statusCode'] === 'number'
37
+ ? cause['statusCode']
38
+ : undefined) ??
39
+ (typeof cause?.['status'] === 'number' ? cause['status'] : undefined)
40
+
41
+ return new DidError(did, message, 'did-unknown-error', status, cause)
42
+ }
43
+ }
44
+
45
+ export class InvalidDidError extends DidError {
46
+ constructor(did: string, message: string, cause?: unknown) {
47
+ super(did, message, 'did-invalid', 400, cause)
48
+ }
49
+ }