@dxos/keys 0.7.4 → 0.7.5-labs.071a3e2
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/lib/browser/index.mjs +174 -45
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +170 -42
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +173 -45
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/dxn.d.ts +49 -0
- package/dist/types/src/dxn.d.ts.map +1 -1
- package/dist/types/src/identity-did.d.ts +16 -0
- package/dist/types/src/identity-did.d.ts.map +1 -0
- package/dist/types/src/identity-did.test.d.ts +2 -0
- package/dist/types/src/identity-did.test.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +1 -0
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/random-bytes.d.ts +1 -1
- package/dist/types/src/random-bytes.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -0
- package/package.json +4 -4
- package/src/dxn.ts +109 -5
- package/src/identity-did.test.ts +17 -0
- package/src/identity-did.ts +49 -0
- package/src/index.ts +1 -0
package/dist/types/src/dxn.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { inspect, InspectOptionsStylized } from 'node:util';
|
|
2
2
|
import { inspectCustom } from '@dxos/debug';
|
|
3
|
+
import type { SpaceId } from './space-id';
|
|
3
4
|
/**
|
|
4
5
|
* DXN unambiguously names a resource like an ECHO object, schema definition, plugin, etc.
|
|
5
6
|
* Each DXN starts with a dx prefix, followed by a resource kind.
|
|
@@ -23,19 +24,47 @@ export declare class DXN {
|
|
|
23
24
|
* Kind constants.
|
|
24
25
|
*/
|
|
25
26
|
static kind: Readonly<{
|
|
27
|
+
/**
|
|
28
|
+
* dxn:type:<type name>[:<version>]
|
|
29
|
+
*/
|
|
26
30
|
TYPE: "type";
|
|
31
|
+
/**
|
|
32
|
+
* dxn:echo:<space id>:<echo id>
|
|
33
|
+
* dxn:echo:@:<echo id>
|
|
34
|
+
*/
|
|
27
35
|
ECHO: "echo";
|
|
36
|
+
/**
|
|
37
|
+
* The subspace tag enables us to partition queues by usage within the context of a space.
|
|
38
|
+
* dxn:queue:<subspace_tag>:<space_id>:<queue_id>[:object_id]
|
|
39
|
+
* dxn:queue:data:BA25QRC2FEWCSAMRP4RZL65LWJ7352CKE:01J00J9B45YHYSGZQTQMSKMGJ6
|
|
40
|
+
* dxn:queue:trace:BA25QRC2FEWCSAMRP4RZL65LWJ7352CKE:01J00J9B45YHYSGZQTQMSKMGJ6
|
|
41
|
+
*/
|
|
42
|
+
QUEUE: "queue";
|
|
28
43
|
}>;
|
|
29
44
|
static equals(a: DXN, b: DXN): boolean;
|
|
30
45
|
static isDXNString(dxn: string): boolean;
|
|
31
46
|
static parse(dxn: string): DXN;
|
|
47
|
+
static tryParse(dxn: string): DXN | undefined;
|
|
48
|
+
/**
|
|
49
|
+
* @example `dxn:type:example.com/type/Contact`
|
|
50
|
+
*/
|
|
32
51
|
static fromTypename(type: string): DXN;
|
|
52
|
+
/**
|
|
53
|
+
* @example `dxn:type:example.com/type/Contact:0.1.0`
|
|
54
|
+
*/
|
|
55
|
+
static fromTypenameAndVersion(type: string, version: string): DXN;
|
|
56
|
+
/**
|
|
57
|
+
* @example `dxn:echo:@:01J00J9B45YHYSGZQTQMSKMGJ6`
|
|
58
|
+
*/
|
|
33
59
|
static fromLocalObjectId(id: string): DXN;
|
|
34
60
|
constructor(kind: string, parts: string[]);
|
|
35
61
|
get kind(): string;
|
|
36
62
|
get parts(): string[];
|
|
37
63
|
toTypename(): string;
|
|
38
64
|
hasTypenameOf(typename: string): boolean;
|
|
65
|
+
asTypeDXN(): DXN.TypeDXN | undefined;
|
|
66
|
+
asEchoDXN(): DXN.EchoDXN | undefined;
|
|
67
|
+
asQueueDXN(): DXN.QueueDXN | undefined;
|
|
39
68
|
isLocalObjectId(): boolean;
|
|
40
69
|
toString(): string;
|
|
41
70
|
/**
|
|
@@ -43,8 +72,28 @@ export declare class DXN {
|
|
|
43
72
|
*/
|
|
44
73
|
[inspectCustom](depth: number, options: InspectOptionsStylized, inspectFn: typeof inspect): string;
|
|
45
74
|
}
|
|
75
|
+
export declare namespace DXN {
|
|
76
|
+
type TypeDXN = {
|
|
77
|
+
type: string;
|
|
78
|
+
version?: string;
|
|
79
|
+
};
|
|
80
|
+
type EchoDXN = {
|
|
81
|
+
spaceId?: SpaceId;
|
|
82
|
+
echoId: string;
|
|
83
|
+
};
|
|
84
|
+
type QueueDXN = {
|
|
85
|
+
subspaceTag: string;
|
|
86
|
+
spaceId: SpaceId;
|
|
87
|
+
queueId: string;
|
|
88
|
+
objectId?: string;
|
|
89
|
+
};
|
|
90
|
+
}
|
|
46
91
|
/**
|
|
47
92
|
* Tags for ECHO DXNs that should resolve the object ID in the local space.
|
|
48
93
|
*/
|
|
49
94
|
export declare const LOCAL_SPACE_TAG = "@";
|
|
95
|
+
export declare const QueueSubspaceTags: Readonly<{
|
|
96
|
+
DATA: "data";
|
|
97
|
+
TRACE: "trace";
|
|
98
|
+
}>;
|
|
50
99
|
//# sourceMappingURL=dxn.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dxn.d.ts","sourceRoot":"","sources":["../../../src/dxn.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AAEjE,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG5C;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,GAAG;;IACd;;OAEG;IACH,MAAM,CAAC,IAAI;;;
|
|
1
|
+
{"version":3,"file":"dxn.d.ts","sourceRoot":"","sources":["../../../src/dxn.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AAEjE,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG5C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,GAAG;;IACd;;OAEG;IACH,MAAM,CAAC,IAAI;QACT;;WAEG;;QAEH;;;WAGG;;QAEH;;;;;WAKG;;OAEF;IAEH,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG;IAI5B,MAAM,CAAC,WAAW,CAAC,GAAG,EAAE,MAAM;IAI9B,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG;IAkB9B,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,MAAM;IAQ3B;;OAEG;IACH,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM;IAIhC;;OAEG;IAEH,MAAM,CAAC,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;IAI3D;;OAEG;IACH,MAAM,CAAC,iBAAiB,CAAC,EAAE,EAAE,MAAM;gBAOvB,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE;IAsBzC,IAAI,IAAI,WAEP;IAED,IAAI,KAAK,aAER;IAED,UAAU;IAKV,aAAa,CAAC,QAAQ,EAAE,MAAM;IAI9B,SAAS,IAAI,GAAG,CAAC,OAAO,GAAG,SAAS;IAYpC,SAAS,IAAI,GAAG,CAAC,OAAO,GAAG,SAAS;IAYpC,UAAU,IAAI,GAAG,CAAC,QAAQ,GAAG,SAAS;IAkBtC,eAAe;IAIf,QAAQ;IAIR;;OAEG;IACH,CAAC,aAAa,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,sBAAsB,EAAE,SAAS,EAAE,OAAO,OAAO;CAS1F;AAED,MAAM,CAAC,OAAO,WAAW,GAAG,CAAC;IAC3B,KAAY,OAAO,GAAG;QACpB,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;IAEF,KAAY,OAAO,GAAG;QACpB,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IAEF,KAAY,QAAQ,GAAG;QACrB,WAAW,EAAE,MAAM,CAAC;QACpB,OAAO,EAAE,OAAO,CAAC;QACjB,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAED;;GAEG;AACH,eAAO,MAAM,eAAe,MAAM,CAAC;AAEnC,eAAO,MAAM,iBAAiB;;;EAG5B,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A unique identifier for a space.
|
|
3
|
+
* Space keys are generated by creating a keypair, and then taking the first 20 bytes of the SHA-256 hash of the public key and encoding them to multibase RFC4648 base-32 format (prefixed with B, see Multibase Table).
|
|
4
|
+
* @example did:halo:BA25QRC2FEWCSAMRP4RZL65LWJ7352CKE
|
|
5
|
+
*/
|
|
6
|
+
export type IdentityDid = string & {
|
|
7
|
+
__IdentityDid: true;
|
|
8
|
+
};
|
|
9
|
+
export declare const IdentityDid: Readonly<{
|
|
10
|
+
byteLength: 20;
|
|
11
|
+
encode: (value: Uint8Array) => IdentityDid;
|
|
12
|
+
decode: (value: IdentityDid) => Uint8Array;
|
|
13
|
+
isValid: (value: string) => value is IdentityDid;
|
|
14
|
+
random: () => IdentityDid;
|
|
15
|
+
}>;
|
|
16
|
+
//# sourceMappingURL=identity-did.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity-did.d.ts","sourceRoot":"","sources":["../../../src/identity-did.ts"],"names":[],"mappings":"AAWA;;;;GAIG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG;IAAE,aAAa,EAAE,IAAI,CAAA;CAAE,CAAC;AAE3D,eAAO,MAAM,WAAW;;oBAEN,UAAU,KAAG,WAAW;oBAMxB,WAAW,KAAG,UAAU;qBAKvB,MAAM,KAAG,KAAK,IAAI,WAAW;kBAKlC,WAAW;EAGvB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity-did.test.d.ts","sourceRoot":"","sources":["../../../src/identity-did.test.ts"],"names":[],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAIA,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,OAAO,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAIA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,OAAO,CAAC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const randomBytes: (length: number) => Uint8Array
|
|
1
|
+
export declare const randomBytes: (length: number) => Uint8Array<ArrayBuffer>;
|
|
2
2
|
//# sourceMappingURL=random-bytes.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"random-bytes.d.ts","sourceRoot":"","sources":["../../../src/random-bytes.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,WAAW,WAAY,MAAM,
|
|
1
|
+
{"version":3,"file":"random-bytes.d.ts","sourceRoot":"","sources":["../../../src/random-bytes.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,WAAW,WAAY,MAAM,4BAQzC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":"5.7.3"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/keys",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.5-labs.071a3e2",
|
|
4
4
|
"description": "Key utils and definitions.",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -26,9 +26,9 @@
|
|
|
26
26
|
"src"
|
|
27
27
|
],
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@dxos/
|
|
30
|
-
"@dxos/
|
|
31
|
-
"@dxos/node-std": "0.7.
|
|
29
|
+
"@dxos/debug": "0.7.5-labs.071a3e2",
|
|
30
|
+
"@dxos/invariant": "0.7.5-labs.071a3e2",
|
|
31
|
+
"@dxos/node-std": "0.7.5-labs.071a3e2"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"base32-decode": "^1.0.0",
|
package/src/dxn.ts
CHANGED
|
@@ -7,6 +7,8 @@ import type { inspect, InspectOptionsStylized } from 'node:util';
|
|
|
7
7
|
import { inspectCustom } from '@dxos/debug';
|
|
8
8
|
import { invariant } from '@dxos/invariant';
|
|
9
9
|
|
|
10
|
+
import type { SpaceId } from './space-id';
|
|
11
|
+
|
|
10
12
|
/**
|
|
11
13
|
* DXN unambiguously names a resource like an ECHO object, schema definition, plugin, etc.
|
|
12
14
|
* Each DXN starts with a dx prefix, followed by a resource kind.
|
|
@@ -29,8 +31,22 @@ export class DXN {
|
|
|
29
31
|
* Kind constants.
|
|
30
32
|
*/
|
|
31
33
|
static kind = Object.freeze({
|
|
34
|
+
/**
|
|
35
|
+
* dxn:type:<type name>[:<version>]
|
|
36
|
+
*/
|
|
32
37
|
TYPE: 'type',
|
|
38
|
+
/**
|
|
39
|
+
* dxn:echo:<space id>:<echo id>
|
|
40
|
+
* dxn:echo:@:<echo id>
|
|
41
|
+
*/
|
|
33
42
|
ECHO: 'echo',
|
|
43
|
+
/**
|
|
44
|
+
* The subspace tag enables us to partition queues by usage within the context of a space.
|
|
45
|
+
* dxn:queue:<subspace_tag>:<space_id>:<queue_id>[:object_id]
|
|
46
|
+
* dxn:queue:data:BA25QRC2FEWCSAMRP4RZL65LWJ7352CKE:01J00J9B45YHYSGZQTQMSKMGJ6
|
|
47
|
+
* dxn:queue:trace:BA25QRC2FEWCSAMRP4RZL65LWJ7352CKE:01J00J9B45YHYSGZQTQMSKMGJ6
|
|
48
|
+
*/
|
|
49
|
+
QUEUE: 'queue',
|
|
34
50
|
});
|
|
35
51
|
|
|
36
52
|
static equals(a: DXN, b: DXN) {
|
|
@@ -43,26 +59,48 @@ export class DXN {
|
|
|
43
59
|
|
|
44
60
|
static parse(dxn: string): DXN {
|
|
45
61
|
if (typeof dxn !== 'string') {
|
|
46
|
-
throw new Error(
|
|
62
|
+
throw new Error(`Invalid DXN: ${dxn}`);
|
|
47
63
|
}
|
|
48
64
|
const [prefix, kind, ...parts] = dxn.split(':');
|
|
49
65
|
if (!(prefix === 'dxn')) {
|
|
50
|
-
throw new Error(
|
|
66
|
+
throw new Error(`Invalid DXN: ${dxn}`);
|
|
51
67
|
}
|
|
52
68
|
if (!(typeof kind === 'string' && kind.length > 0)) {
|
|
53
|
-
throw new Error(
|
|
69
|
+
throw new Error(`Invalid DXN: ${dxn}`);
|
|
54
70
|
}
|
|
55
71
|
if (!(parts.length > 0)) {
|
|
56
|
-
throw new Error(
|
|
72
|
+
throw new Error(`Invalid DXN: ${dxn}`);
|
|
57
73
|
}
|
|
58
74
|
|
|
59
75
|
return new DXN(kind, parts);
|
|
60
76
|
}
|
|
61
77
|
|
|
78
|
+
static tryParse(dxn: string) {
|
|
79
|
+
try {
|
|
80
|
+
return DXN.parse(dxn);
|
|
81
|
+
} catch (error) {
|
|
82
|
+
return undefined;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* @example `dxn:type:example.com/type/Contact`
|
|
88
|
+
*/
|
|
62
89
|
static fromTypename(type: string) {
|
|
63
90
|
return new DXN(DXN.kind.TYPE, [type]);
|
|
64
91
|
}
|
|
65
92
|
|
|
93
|
+
/**
|
|
94
|
+
* @example `dxn:type:example.com/type/Contact:0.1.0`
|
|
95
|
+
*/
|
|
96
|
+
// TODO(dmaretskyi): Consider using @ as the version separator.
|
|
97
|
+
static fromTypenameAndVersion(type: string, version: string) {
|
|
98
|
+
return new DXN(DXN.kind.TYPE, [type, version]);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* @example `dxn:echo:@:01J00J9B45YHYSGZQTQMSKMGJ6`
|
|
103
|
+
*/
|
|
66
104
|
static fromLocalObjectId(id: string) {
|
|
67
105
|
return new DXN(DXN.kind.ECHO, [LOCAL_SPACE_TAG, id]);
|
|
68
106
|
}
|
|
@@ -77,7 +115,7 @@ export class DXN {
|
|
|
77
115
|
// Per-type validation.
|
|
78
116
|
switch (kind) {
|
|
79
117
|
case DXN.kind.TYPE:
|
|
80
|
-
if (parts.length
|
|
118
|
+
if (parts.length > 2) {
|
|
81
119
|
throw new Error('Invalid "type" DXN');
|
|
82
120
|
}
|
|
83
121
|
break;
|
|
@@ -109,6 +147,48 @@ export class DXN {
|
|
|
109
147
|
return this.#kind === DXN.kind.TYPE && this.#parts.length === 1 && this.#parts[0] === typename;
|
|
110
148
|
}
|
|
111
149
|
|
|
150
|
+
asTypeDXN(): DXN.TypeDXN | undefined {
|
|
151
|
+
if (this.kind !== DXN.kind.TYPE) {
|
|
152
|
+
return undefined;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const [type, version] = this.#parts;
|
|
156
|
+
return {
|
|
157
|
+
type,
|
|
158
|
+
version: version as string | undefined,
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
asEchoDXN(): DXN.EchoDXN | undefined {
|
|
163
|
+
if (this.kind !== DXN.kind.ECHO) {
|
|
164
|
+
return undefined;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const [spaceId, echoId] = this.#parts;
|
|
168
|
+
return {
|
|
169
|
+
spaceId: spaceId === LOCAL_SPACE_TAG ? undefined : (spaceId as SpaceId | undefined),
|
|
170
|
+
echoId,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
asQueueDXN(): DXN.QueueDXN | undefined {
|
|
175
|
+
if (this.kind !== DXN.kind.QUEUE) {
|
|
176
|
+
return undefined;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const [subspaceTag, spaceId, queueId, objectId] = this.#parts;
|
|
180
|
+
if (typeof queueId !== 'string') {
|
|
181
|
+
return undefined;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
return {
|
|
185
|
+
subspaceTag,
|
|
186
|
+
spaceId: spaceId as SpaceId,
|
|
187
|
+
queueId,
|
|
188
|
+
objectId: objectId as string | undefined,
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
|
|
112
192
|
isLocalObjectId() {
|
|
113
193
|
return this.#kind === DXN.kind.ECHO && this.#parts[0] === LOCAL_SPACE_TAG && this.#parts.length === 2;
|
|
114
194
|
}
|
|
@@ -131,7 +211,31 @@ export class DXN {
|
|
|
131
211
|
}
|
|
132
212
|
}
|
|
133
213
|
|
|
214
|
+
export declare namespace DXN {
|
|
215
|
+
export type TypeDXN = {
|
|
216
|
+
type: string;
|
|
217
|
+
version?: string;
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
export type EchoDXN = {
|
|
221
|
+
spaceId?: SpaceId;
|
|
222
|
+
echoId: string; // TODO(dmaretskyi): ObjectId.
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
export type QueueDXN = {
|
|
226
|
+
subspaceTag: string;
|
|
227
|
+
spaceId: SpaceId;
|
|
228
|
+
queueId: string; // TODO(dmaretskyi): ObjectId.
|
|
229
|
+
objectId?: string; // TODO(dmaretskyi): ObjectId.
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
|
|
134
233
|
/**
|
|
135
234
|
* Tags for ECHO DXNs that should resolve the object ID in the local space.
|
|
136
235
|
*/
|
|
137
236
|
export const LOCAL_SPACE_TAG = '@';
|
|
237
|
+
|
|
238
|
+
export const QueueSubspaceTags = Object.freeze({
|
|
239
|
+
DATA: 'data',
|
|
240
|
+
TRACE: 'trace',
|
|
241
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2024 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { expect, test } from 'vitest';
|
|
6
|
+
|
|
7
|
+
import { IdentityDid } from './identity-did';
|
|
8
|
+
|
|
9
|
+
test('identity-did', () => {
|
|
10
|
+
const id = IdentityDid.random();
|
|
11
|
+
|
|
12
|
+
expect(id.length).toBe(42);
|
|
13
|
+
expect(IdentityDid.isValid(id)).toBe(true);
|
|
14
|
+
const decoded = IdentityDid.decode(id);
|
|
15
|
+
expect(decoded.length).toBe(IdentityDid.byteLength);
|
|
16
|
+
expect(IdentityDid.encode(decoded)).toBe(id);
|
|
17
|
+
});
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2024 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import base32Decode from 'base32-decode';
|
|
6
|
+
import base32Encode from 'base32-encode';
|
|
7
|
+
|
|
8
|
+
import { invariant } from '@dxos/invariant';
|
|
9
|
+
|
|
10
|
+
import { randomBytes } from './random-bytes';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* A unique identifier for a space.
|
|
14
|
+
* Space keys are generated by creating a keypair, and then taking the first 20 bytes of the SHA-256 hash of the public key and encoding them to multibase RFC4648 base-32 format (prefixed with B, see Multibase Table).
|
|
15
|
+
* @example did:halo:BA25QRC2FEWCSAMRP4RZL65LWJ7352CKE
|
|
16
|
+
*/
|
|
17
|
+
export type IdentityDid = string & { __IdentityDid: true };
|
|
18
|
+
|
|
19
|
+
export const IdentityDid = Object.freeze({
|
|
20
|
+
byteLength: 20,
|
|
21
|
+
encode: (value: Uint8Array): IdentityDid => {
|
|
22
|
+
invariant(value instanceof Uint8Array, 'Invalid type');
|
|
23
|
+
invariant(value.length === IdentityDid.byteLength, 'Invalid length');
|
|
24
|
+
|
|
25
|
+
return (DID_PREFIX + MULTIBASE_PREFIX + base32Encode(value, 'RFC4648')) as IdentityDid;
|
|
26
|
+
},
|
|
27
|
+
decode: (value: IdentityDid): Uint8Array => {
|
|
28
|
+
invariant(value.startsWith(DID_PREFIX + MULTIBASE_PREFIX), 'Invalid multibase32 encoding');
|
|
29
|
+
|
|
30
|
+
return new Uint8Array(base32Decode(value.slice(10), 'RFC4648'));
|
|
31
|
+
},
|
|
32
|
+
isValid: (value: string): value is IdentityDid => {
|
|
33
|
+
return (
|
|
34
|
+
typeof value === 'string' && value.startsWith(DID_PREFIX + MULTIBASE_PREFIX) && value.length === ENCODED_LENGTH
|
|
35
|
+
);
|
|
36
|
+
},
|
|
37
|
+
random: (): IdentityDid => {
|
|
38
|
+
return IdentityDid.encode(randomBytes(IdentityDid.byteLength));
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Denotes RFC4648 base-32 format.
|
|
44
|
+
*/
|
|
45
|
+
const MULTIBASE_PREFIX = 'B';
|
|
46
|
+
|
|
47
|
+
const DID_PREFIX = 'did:halo:';
|
|
48
|
+
|
|
49
|
+
const ENCODED_LENGTH = 42;
|