@arcblock/did 1.29.18 → 1.29.20
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/esm/entity.d.mts +28 -0
- package/esm/entity.mjs +39 -0
- package/esm/index.d.mts +9 -1
- package/esm/index.mjs +10 -2
- package/esm/method.d.mts +30 -0
- package/esm/method.mjs +32 -0
- package/esm/name-registry.d.mts +31 -0
- package/esm/name-registry.mjs +37 -0
- package/esm/name-resolver.d.mts +41 -0
- package/esm/name-resolver.mjs +97 -0
- package/esm/name.d.mts +62 -0
- package/esm/name.mjs +73 -0
- package/esm/parse.d.mts +50 -0
- package/esm/parse.mjs +88 -0
- package/esm/short-form.d.mts +30 -0
- package/esm/short-form.mjs +46 -0
- package/esm/util.mjs +1 -1
- package/esm/validate.d.mts +23 -0
- package/esm/validate.mjs +36 -0
- package/lib/entity.cjs +40 -0
- package/lib/entity.d.cts +28 -0
- package/lib/index.cjs +31 -1
- package/lib/index.d.cts +9 -1
- package/lib/method.cjs +39 -0
- package/lib/method.d.cts +30 -0
- package/lib/name-registry.cjs +38 -0
- package/lib/name-registry.d.cts +31 -0
- package/lib/name-resolver.cjs +97 -0
- package/lib/name-resolver.d.cts +41 -0
- package/lib/name.cjs +77 -0
- package/lib/name.d.cts +62 -0
- package/lib/parse.cjs +91 -0
- package/lib/parse.d.cts +50 -0
- package/lib/short-form.cjs +47 -0
- package/lib/short-form.d.cts +30 -0
- package/lib/util.cjs +1 -1
- package/lib/validate.cjs +36 -0
- package/lib/validate.d.cts +23 -0
- package/package.json +3 -3
package/lib/name.d.cts
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
//#region src/name.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* DID Name Hierarchy Parser
|
|
4
|
+
*
|
|
5
|
+
* DNS-style right-to-left name resolution for did:name identifiers.
|
|
6
|
+
* Supports global names, delegated sub-names, and .local domains.
|
|
7
|
+
*/
|
|
8
|
+
/** Parsed name hierarchy */
|
|
9
|
+
interface NameHierarchy {
|
|
10
|
+
/** Name segments split by '.' */
|
|
11
|
+
segments: string[];
|
|
12
|
+
/** Top-level domain (rightmost segment) */
|
|
13
|
+
tld: string;
|
|
14
|
+
/** Whether this is a .local name */
|
|
15
|
+
isLocal: boolean;
|
|
16
|
+
/** Whether this is a global name (single segment, not .local) */
|
|
17
|
+
isGlobal: boolean;
|
|
18
|
+
/** Number of segments */
|
|
19
|
+
depth: number;
|
|
20
|
+
}
|
|
21
|
+
/** Resolve route types */
|
|
22
|
+
type ResolveRoute = {
|
|
23
|
+
type: 'global';
|
|
24
|
+
name: string;
|
|
25
|
+
} | {
|
|
26
|
+
type: 'local';
|
|
27
|
+
name: string;
|
|
28
|
+
} | {
|
|
29
|
+
type: 'delegated';
|
|
30
|
+
tld: string;
|
|
31
|
+
subName: string;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Parse a name identifier into its hierarchy components.
|
|
35
|
+
*
|
|
36
|
+
* @param name - The name to parse (e.g. 'robertmao', 'bob.myorg', 'anything.local')
|
|
37
|
+
* @returns Parsed hierarchy
|
|
38
|
+
* @throws If name is invalid
|
|
39
|
+
*/
|
|
40
|
+
declare function parseNameHierarchy(name: unknown): NameHierarchy;
|
|
41
|
+
/**
|
|
42
|
+
* Determine the resolve route for a name.
|
|
43
|
+
*
|
|
44
|
+
* - Single segment (e.g. 'robertmao') → global route
|
|
45
|
+
* - Ends with '.local' → local route
|
|
46
|
+
* - Multi-segment (e.g. 'bob.myorg') → delegated route
|
|
47
|
+
*
|
|
48
|
+
* @param name - The name to route
|
|
49
|
+
* @returns The resolve route
|
|
50
|
+
* @throws If name is invalid
|
|
51
|
+
*/
|
|
52
|
+
declare function getResolveRoute(name: string): ResolveRoute;
|
|
53
|
+
/**
|
|
54
|
+
* Check if a name is a .local name.
|
|
55
|
+
*/
|
|
56
|
+
declare function isLocalName(name: string): boolean;
|
|
57
|
+
/**
|
|
58
|
+
* Check if a name is a global name (single segment, not .local).
|
|
59
|
+
*/
|
|
60
|
+
declare function isGlobalName(name: string): boolean;
|
|
61
|
+
//#endregion
|
|
62
|
+
export { NameHierarchy, ResolveRoute, getResolveRoute, isGlobalName, isLocalName, parseNameHierarchy };
|
package/lib/parse.cjs
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
const require_method = require('./method.cjs');
|
|
2
|
+
|
|
3
|
+
//#region src/parse.ts
|
|
4
|
+
/**
|
|
5
|
+
* Universal DID Parser
|
|
6
|
+
*
|
|
7
|
+
* Parses, formats, and extracts components from DID strings.
|
|
8
|
+
* Supports all registered methods (abt, afs, aos, spaces, name).
|
|
9
|
+
*/
|
|
10
|
+
/** DID format regex: did:{method}:{identifier} where method is [a-z0-9]+ */
|
|
11
|
+
const DID_REGEX = /^did:([a-z0-9]+):(.+)$/;
|
|
12
|
+
/**
|
|
13
|
+
* Parse a full DID string into its components.
|
|
14
|
+
*
|
|
15
|
+
* @param did - Full DID string (e.g. 'did:abt:z1abc...')
|
|
16
|
+
* @returns Parsed DID object
|
|
17
|
+
* @throws If the input is not a valid DID string
|
|
18
|
+
*/
|
|
19
|
+
function parse(did) {
|
|
20
|
+
if (typeof did !== "string") throw new Error("DID must be a string");
|
|
21
|
+
if (!did) throw new Error("DID string cannot be empty");
|
|
22
|
+
const match = did.match(DID_REGEX);
|
|
23
|
+
if (!match) throw new Error("Invalid DID format");
|
|
24
|
+
const [, method, identifier] = match;
|
|
25
|
+
if (!method) throw new Error("Invalid DID format");
|
|
26
|
+
if (!identifier) throw new Error("Invalid DID format");
|
|
27
|
+
if (!require_method.isKnownMethod(method)) throw new Error(`Unknown DID method: ${method}`);
|
|
28
|
+
return {
|
|
29
|
+
method,
|
|
30
|
+
identifier,
|
|
31
|
+
full: did
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Format an identifier and method into a full DID string.
|
|
36
|
+
*
|
|
37
|
+
* Handles idempotency: if the identifier already has a `did:{method}:` prefix
|
|
38
|
+
* matching the target method, returns it as-is.
|
|
39
|
+
*
|
|
40
|
+
* @param identifier - The identifier (address or name)
|
|
41
|
+
* @param method - The DID method (default: 'abt')
|
|
42
|
+
* @returns Full DID string
|
|
43
|
+
* @throws If the method is unknown or identifier is empty
|
|
44
|
+
*/
|
|
45
|
+
function formatDid(identifier, method = require_method.DEFAULT_METHOD) {
|
|
46
|
+
if (!identifier) throw new Error("Identifier cannot be empty");
|
|
47
|
+
if (!require_method.isKnownMethod(method)) throw new Error(`Unknown DID method: ${method}`);
|
|
48
|
+
const prefix = `did:${method}:`;
|
|
49
|
+
if (identifier.startsWith(prefix)) return identifier;
|
|
50
|
+
if (identifier.startsWith("did:")) {
|
|
51
|
+
const match = identifier.match(DID_REGEX);
|
|
52
|
+
if (match) {
|
|
53
|
+
if (match[1] === method) return identifier;
|
|
54
|
+
return `did:${method}:${match[2]}`;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return `did:${method}:${identifier}`;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Extract the method from a DID string.
|
|
61
|
+
*
|
|
62
|
+
* @param did - A DID string or bare address
|
|
63
|
+
* @returns The method string, or null if no prefix found
|
|
64
|
+
*/
|
|
65
|
+
function extractMethod(did) {
|
|
66
|
+
if (typeof did !== "string" || !did) return null;
|
|
67
|
+
const match = did.match(DID_REGEX);
|
|
68
|
+
if (!match) return null;
|
|
69
|
+
const method = match[1];
|
|
70
|
+
if (require_method.isKnownMethod(method)) return method;
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Extract the identifier from a DID string, stripping the `did:{method}:` prefix.
|
|
75
|
+
* If the input has no prefix, returns it as-is.
|
|
76
|
+
*
|
|
77
|
+
* @param did - A DID string or bare address
|
|
78
|
+
* @returns The identifier portion
|
|
79
|
+
*/
|
|
80
|
+
function extractIdentifier(did) {
|
|
81
|
+
if (typeof did !== "string" || !did) return "";
|
|
82
|
+
const match = did.match(/^did:[a-z0-9]+:(.+)$/);
|
|
83
|
+
if (match) return match[1];
|
|
84
|
+
return did;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
//#endregion
|
|
88
|
+
exports.extractIdentifier = extractIdentifier;
|
|
89
|
+
exports.extractMethod = extractMethod;
|
|
90
|
+
exports.formatDid = formatDid;
|
|
91
|
+
exports.parse = parse;
|
package/lib/parse.d.cts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { DIDMethod } from "./method.cjs";
|
|
2
|
+
|
|
3
|
+
//#region src/parse.d.ts
|
|
4
|
+
|
|
5
|
+
/** Parsed DID structure */
|
|
6
|
+
interface ParsedDID {
|
|
7
|
+
/** The method component (e.g. 'abt', 'afs', 'name') */
|
|
8
|
+
method: DIDMethod;
|
|
9
|
+
/** The identifier component (everything after did:{method}:) */
|
|
10
|
+
identifier: string;
|
|
11
|
+
/** The full DID string */
|
|
12
|
+
full: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Parse a full DID string into its components.
|
|
16
|
+
*
|
|
17
|
+
* @param did - Full DID string (e.g. 'did:abt:z1abc...')
|
|
18
|
+
* @returns Parsed DID object
|
|
19
|
+
* @throws If the input is not a valid DID string
|
|
20
|
+
*/
|
|
21
|
+
declare function parse(did: unknown): ParsedDID;
|
|
22
|
+
/**
|
|
23
|
+
* Format an identifier and method into a full DID string.
|
|
24
|
+
*
|
|
25
|
+
* Handles idempotency: if the identifier already has a `did:{method}:` prefix
|
|
26
|
+
* matching the target method, returns it as-is.
|
|
27
|
+
*
|
|
28
|
+
* @param identifier - The identifier (address or name)
|
|
29
|
+
* @param method - The DID method (default: 'abt')
|
|
30
|
+
* @returns Full DID string
|
|
31
|
+
* @throws If the method is unknown or identifier is empty
|
|
32
|
+
*/
|
|
33
|
+
declare function formatDid(identifier: string, method?: DIDMethod): string;
|
|
34
|
+
/**
|
|
35
|
+
* Extract the method from a DID string.
|
|
36
|
+
*
|
|
37
|
+
* @param did - A DID string or bare address
|
|
38
|
+
* @returns The method string, or null if no prefix found
|
|
39
|
+
*/
|
|
40
|
+
declare function extractMethod(did: unknown): DIDMethod | null;
|
|
41
|
+
/**
|
|
42
|
+
* Extract the identifier from a DID string, stripping the `did:{method}:` prefix.
|
|
43
|
+
* If the input has no prefix, returns it as-is.
|
|
44
|
+
*
|
|
45
|
+
* @param did - A DID string or bare address
|
|
46
|
+
* @returns The identifier portion
|
|
47
|
+
*/
|
|
48
|
+
declare function extractIdentifier(did: unknown): string;
|
|
49
|
+
//#endregion
|
|
50
|
+
export { ParsedDID, extractIdentifier, extractMethod, formatDid, parse };
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
const require_parse = require('./parse.cjs');
|
|
2
|
+
const require_index = require('./index.cjs');
|
|
3
|
+
|
|
4
|
+
//#region src/short-form.ts
|
|
5
|
+
/**
|
|
6
|
+
* Short-form DID Resolution
|
|
7
|
+
*
|
|
8
|
+
* Deterministic expansion of short-form identifiers to full DIDs.
|
|
9
|
+
* Based on base58 checksum validation (not heuristic guessing).
|
|
10
|
+
*
|
|
11
|
+
* Rules:
|
|
12
|
+
* - Already a full DID (starts with "did:") → return as-is
|
|
13
|
+
* - Valid cryptographic address (passes isValid checksum) → did:abt:{address}
|
|
14
|
+
* - Everything else → did:name:{input}
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Expand a short-form identifier to a full DID.
|
|
18
|
+
*
|
|
19
|
+
* @param input - Short-form identifier (address, name, or full DID)
|
|
20
|
+
* @returns Full DID string
|
|
21
|
+
* @throws If input is not a non-empty string
|
|
22
|
+
*/
|
|
23
|
+
function expandShortForm(input) {
|
|
24
|
+
if (typeof input !== "string") throw new Error("Input must be a string");
|
|
25
|
+
if (!input) throw new Error("Input cannot be empty");
|
|
26
|
+
if (input.startsWith("did:")) return input;
|
|
27
|
+
if (require_index.isValid(input)) return require_parse.formatDid(input, "abt");
|
|
28
|
+
return require_parse.formatDid(input, "name");
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Convert a full DID to its short form (strip the did:{method}: prefix).
|
|
32
|
+
*
|
|
33
|
+
* @param did - Full DID string
|
|
34
|
+
* @returns Short-form identifier
|
|
35
|
+
* @throws If input is not a non-empty string
|
|
36
|
+
*/
|
|
37
|
+
function toShortForm(did) {
|
|
38
|
+
if (typeof did !== "string") throw new Error("Input must be a string");
|
|
39
|
+
if (!did) throw new Error("Input cannot be empty");
|
|
40
|
+
const match = did.match(/^did:[a-z0-9]+:(.+)$/);
|
|
41
|
+
if (match) return match[1];
|
|
42
|
+
return did;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
//#endregion
|
|
46
|
+
exports.expandShortForm = expandShortForm;
|
|
47
|
+
exports.toShortForm = toShortForm;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
//#region src/short-form.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Short-form DID Resolution
|
|
4
|
+
*
|
|
5
|
+
* Deterministic expansion of short-form identifiers to full DIDs.
|
|
6
|
+
* Based on base58 checksum validation (not heuristic guessing).
|
|
7
|
+
*
|
|
8
|
+
* Rules:
|
|
9
|
+
* - Already a full DID (starts with "did:") → return as-is
|
|
10
|
+
* - Valid cryptographic address (passes isValid checksum) → did:abt:{address}
|
|
11
|
+
* - Everything else → did:name:{input}
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Expand a short-form identifier to a full DID.
|
|
15
|
+
*
|
|
16
|
+
* @param input - Short-form identifier (address, name, or full DID)
|
|
17
|
+
* @returns Full DID string
|
|
18
|
+
* @throws If input is not a non-empty string
|
|
19
|
+
*/
|
|
20
|
+
declare function expandShortForm(input: unknown): string;
|
|
21
|
+
/**
|
|
22
|
+
* Convert a full DID to its short form (strip the did:{method}: prefix).
|
|
23
|
+
*
|
|
24
|
+
* @param did - Full DID string
|
|
25
|
+
* @returns Short-form identifier
|
|
26
|
+
* @throws If input is not a non-empty string
|
|
27
|
+
*/
|
|
28
|
+
declare function toShortForm(did: unknown): string;
|
|
29
|
+
//#endregion
|
|
30
|
+
export { expandShortForm, toShortForm };
|
package/lib/util.cjs
CHANGED
|
@@ -14,7 +14,7 @@ const DID_PREFIX = "did:abt:";
|
|
|
14
14
|
const toBytes = (did) => {
|
|
15
15
|
try {
|
|
16
16
|
if ((0, _ocap_util.isHexStrict)(did)) return Buffer.from((0, _ocap_util.stripHexPrefix)(did), "hex");
|
|
17
|
-
let bytes = (0, _ocap_util.fromBase58)(did.replace(
|
|
17
|
+
let bytes = (0, _ocap_util.fromBase58)(did.replace(/^did:[a-z0-9]+:/, ""));
|
|
18
18
|
while (bytes.length < 26) bytes = Buffer.concat([Uint8Array.from([0]), Uint8Array.from(bytes)]);
|
|
19
19
|
return bytes;
|
|
20
20
|
} catch (err) {
|
package/lib/validate.cjs
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
const require_method = require('./method.cjs');
|
|
2
|
+
const require_index = require('./index.cjs');
|
|
3
|
+
|
|
4
|
+
//#region src/validate.ts
|
|
5
|
+
/**
|
|
6
|
+
* DID Validation Functions
|
|
7
|
+
*
|
|
8
|
+
* isValid and isFromPublicKey remain in index.ts (too many dependencies to move).
|
|
9
|
+
* This file provides isKnownDid which covers all methods including did:name.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Check if a DID string is a known valid DID.
|
|
13
|
+
*
|
|
14
|
+
* Unlike `isValid` (which only validates cryptographic addresses),
|
|
15
|
+
* `isKnownDid` covers all known methods:
|
|
16
|
+
* - Crypto methods (abt/afs/aos/spaces): delegates to `isValid` for checksum validation
|
|
17
|
+
* - Alias methods (name): checks for non-empty identifier
|
|
18
|
+
* - Unknown methods: returns false
|
|
19
|
+
* - Bare cryptographic addresses: delegates to `isValid`
|
|
20
|
+
*
|
|
21
|
+
* @param did - DID string to validate
|
|
22
|
+
* @returns true if the DID is valid for its method
|
|
23
|
+
*/
|
|
24
|
+
function isKnownDid(did) {
|
|
25
|
+
if (typeof did !== "string" || !did) return false;
|
|
26
|
+
const match = did.match(/^did:([a-z0-9]+):(.*)$/);
|
|
27
|
+
if (!match) return require_index.isValid(did);
|
|
28
|
+
const [, method, identifier] = match;
|
|
29
|
+
if (!identifier) return false;
|
|
30
|
+
if (require_method.isCryptoMethod(method)) return require_index.isValid(did);
|
|
31
|
+
if (require_method.isAliasMethod(method)) return true;
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
//#endregion
|
|
36
|
+
exports.isKnownDid = isKnownDid;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
//#region src/validate.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* DID Validation Functions
|
|
4
|
+
*
|
|
5
|
+
* isValid and isFromPublicKey remain in index.ts (too many dependencies to move).
|
|
6
|
+
* This file provides isKnownDid which covers all methods including did:name.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Check if a DID string is a known valid DID.
|
|
10
|
+
*
|
|
11
|
+
* Unlike `isValid` (which only validates cryptographic addresses),
|
|
12
|
+
* `isKnownDid` covers all known methods:
|
|
13
|
+
* - Crypto methods (abt/afs/aos/spaces): delegates to `isValid` for checksum validation
|
|
14
|
+
* - Alias methods (name): checks for non-empty identifier
|
|
15
|
+
* - Unknown methods: returns false
|
|
16
|
+
* - Bare cryptographic addresses: delegates to `isValid`
|
|
17
|
+
*
|
|
18
|
+
* @param did - DID string to validate
|
|
19
|
+
* @returns true if the DID is valid for its method
|
|
20
|
+
*/
|
|
21
|
+
declare function isKnownDid(did: unknown): boolean;
|
|
22
|
+
//#endregion
|
|
23
|
+
export { isKnownDid };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arcblock/did",
|
|
3
|
-
"version": "1.29.
|
|
3
|
+
"version": "1.29.20",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Javascript lib to work with ArcBlock DID",
|
|
6
6
|
"keywords": [
|
|
@@ -69,8 +69,8 @@
|
|
|
69
69
|
"url": "https://github.com/ArcBlock/blockchain/issues"
|
|
70
70
|
},
|
|
71
71
|
"dependencies": {
|
|
72
|
-
"@ocap/mcrypto": "1.29.
|
|
73
|
-
"@ocap/util": "1.29.
|
|
72
|
+
"@ocap/mcrypto": "1.29.20",
|
|
73
|
+
"@ocap/util": "1.29.20",
|
|
74
74
|
"bn.js": "5.2.3",
|
|
75
75
|
"debug": "^4.4.3",
|
|
76
76
|
"lodash": "^4.17.23"
|