@interop/did-method-webvh 3.0.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/CHANGELOG.md +345 -0
- package/LICENSE +201 -0
- package/README.md +294 -0
- package/dist/assertions.d.ts +5 -0
- package/dist/assertions.js +82 -0
- package/dist/cli.d.ts +21 -0
- package/dist/cli.js +533 -0
- package/dist/config.d.ts +7 -0
- package/dist/config.js +35 -0
- package/dist/constants.d.ts +3 -0
- package/dist/constants.js +3 -0
- package/dist/cryptography.d.ts +52 -0
- package/dist/cryptography.js +95 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +6 -0
- package/dist/interfaces.d.ts +231 -0
- package/dist/interfaces.js +17 -0
- package/dist/method.d.ts +73 -0
- package/dist/method.js +95 -0
- package/dist/method_versions/method.v1.0.d.ts +23 -0
- package/dist/method_versions/method.v1.0.js +554 -0
- package/dist/types.d.ts +5 -0
- package/dist/types.js +5 -0
- package/dist/utils/buffer.d.ts +3 -0
- package/dist/utils/buffer.js +62 -0
- package/dist/utils/canonicalize.d.ts +3 -0
- package/dist/utils/canonicalize.js +80 -0
- package/dist/utils/crypto.d.ts +2 -0
- package/dist/utils/crypto.js +17 -0
- package/dist/utils/multiformats.d.ts +100 -0
- package/dist/utils/multiformats.js +283 -0
- package/dist/utils.d.ts +49 -0
- package/dist/utils.js +659 -0
- package/dist/witness.d.ts +39 -0
- package/dist/witness.js +216 -0
- package/package.json +70 -0
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { canonicalizeEx } from 'json-canonicalize';
|
|
2
|
+
const sanitizeForCanonicalization = (value, seen) => {
|
|
3
|
+
if (value === null)
|
|
4
|
+
return null;
|
|
5
|
+
const type = typeof value;
|
|
6
|
+
if (type === 'undefined') {
|
|
7
|
+
throw new Error('Canonicalization input contains undefined in array position');
|
|
8
|
+
}
|
|
9
|
+
if (type === 'function' || type === 'symbol' || type === 'bigint') {
|
|
10
|
+
throw new Error(`Canonicalization input contains unsupported type: ${type}`);
|
|
11
|
+
}
|
|
12
|
+
if (type === 'number' && !Number.isFinite(value)) {
|
|
13
|
+
throw new Error('Canonicalization input contains non-finite number');
|
|
14
|
+
}
|
|
15
|
+
if (type !== 'object')
|
|
16
|
+
return value;
|
|
17
|
+
const obj = value;
|
|
18
|
+
if (seen.has(obj)) {
|
|
19
|
+
throw new Error('Canonicalization input contains circular references');
|
|
20
|
+
}
|
|
21
|
+
if (Array.isArray(obj)) {
|
|
22
|
+
const sanitizedArray = [];
|
|
23
|
+
seen.set(obj, sanitizedArray);
|
|
24
|
+
for (const item of obj) {
|
|
25
|
+
sanitizedArray.push(sanitizeForCanonicalization(item, seen));
|
|
26
|
+
}
|
|
27
|
+
return sanitizedArray;
|
|
28
|
+
}
|
|
29
|
+
const sanitizedObject = {};
|
|
30
|
+
seen.set(obj, sanitizedObject);
|
|
31
|
+
for (const [key, entry] of Object.entries(obj)) {
|
|
32
|
+
if (typeof entry === 'undefined') {
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
sanitizedObject[key] = sanitizeForCanonicalization(entry, seen);
|
|
36
|
+
}
|
|
37
|
+
return sanitizedObject;
|
|
38
|
+
};
|
|
39
|
+
const assertJsonCompatible = (value, seen) => {
|
|
40
|
+
if (value === null)
|
|
41
|
+
return;
|
|
42
|
+
const type = typeof value;
|
|
43
|
+
if (type === 'undefined') {
|
|
44
|
+
throw new Error('Canonicalization input contains undefined');
|
|
45
|
+
}
|
|
46
|
+
if (type === 'function' || type === 'symbol' || type === 'bigint') {
|
|
47
|
+
throw new Error(`Canonicalization input contains unsupported type: ${type}`);
|
|
48
|
+
}
|
|
49
|
+
if (type === 'number' && !Number.isFinite(value)) {
|
|
50
|
+
throw new Error('Canonicalization input contains non-finite number');
|
|
51
|
+
}
|
|
52
|
+
if (type !== 'object')
|
|
53
|
+
return;
|
|
54
|
+
const obj = value;
|
|
55
|
+
if (seen.has(obj)) {
|
|
56
|
+
throw new Error('Canonicalization input contains circular references');
|
|
57
|
+
}
|
|
58
|
+
seen.add(obj);
|
|
59
|
+
if (Array.isArray(obj)) {
|
|
60
|
+
for (const item of obj) {
|
|
61
|
+
assertJsonCompatible(item, seen);
|
|
62
|
+
}
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
for (const entry of Object.values(obj)) {
|
|
66
|
+
assertJsonCompatible(entry, seen);
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
export function validateStrictJsonValue(value) {
|
|
70
|
+
assertJsonCompatible(value, new WeakSet());
|
|
71
|
+
}
|
|
72
|
+
export const canonicalizeStrict = (value) => {
|
|
73
|
+
const sanitized = sanitizeForCanonicalization(value, new WeakMap());
|
|
74
|
+
validateStrictJsonValue(sanitized);
|
|
75
|
+
return canonicalizeEx(sanitized, {
|
|
76
|
+
allowCircular: false,
|
|
77
|
+
filterUndefined: true,
|
|
78
|
+
undefinedInArrayToNull: false,
|
|
79
|
+
});
|
|
80
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/// <reference lib="dom" />
|
|
2
|
+
import { sha256 } from '@noble/hashes/sha2.js';
|
|
3
|
+
const encoder = new TextEncoder();
|
|
4
|
+
function arrayBufferToHex(buffer) {
|
|
5
|
+
const view = buffer instanceof Uint8Array ? buffer : new Uint8Array(buffer);
|
|
6
|
+
return Array.from(view)
|
|
7
|
+
.map((b) => b.toString(16).padStart(2, '0'))
|
|
8
|
+
.join('');
|
|
9
|
+
}
|
|
10
|
+
export async function createHash(data) {
|
|
11
|
+
return sha256(encoder.encode(data));
|
|
12
|
+
}
|
|
13
|
+
export async function createHashHex(data) {
|
|
14
|
+
const hash = await createHash(data);
|
|
15
|
+
const view = new Uint8Array(hash.buffer);
|
|
16
|
+
return arrayBufferToHex(view);
|
|
17
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* multiformats.ts
|
|
3
|
+
*
|
|
4
|
+
* This file provides utilities for working with Multibase and Multihash formats
|
|
5
|
+
* as specified in the DID:WebVH method specification.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Supported Multibase encoding types
|
|
9
|
+
*/
|
|
10
|
+
export declare enum MultibaseEncoding {
|
|
11
|
+
BASE64URL_NO_PAD = "u",
|
|
12
|
+
BASE58_BTC = "z"
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Encodes binary data using Base64URL (no padding)
|
|
16
|
+
* @param bytes - The binary data to encode
|
|
17
|
+
* @returns The base64url encoded string (without the multibase prefix)
|
|
18
|
+
*/
|
|
19
|
+
export declare function encodeBase64Url(bytes: Uint8Array): string;
|
|
20
|
+
/**
|
|
21
|
+
* Encodes binary data using Base58BTC
|
|
22
|
+
* @param bytes - The binary data to encode
|
|
23
|
+
* @returns The base58btc encoded string (without the multibase prefix)
|
|
24
|
+
*/
|
|
25
|
+
export declare function encodeBase58Btc(bytes: Uint8Array): string;
|
|
26
|
+
/**
|
|
27
|
+
* Decodes a Base58BTC string to binary data
|
|
28
|
+
* @param str - The base58btc encoded string
|
|
29
|
+
* @returns The decoded binary data
|
|
30
|
+
*/
|
|
31
|
+
export declare function decodeBase58Btc(str: string): Uint8Array;
|
|
32
|
+
/**
|
|
33
|
+
* Encodes binary data using the specified multibase encoding
|
|
34
|
+
* @param bytes - The binary data to encode
|
|
35
|
+
* @param encoding - The multibase encoding to use
|
|
36
|
+
* @returns The multibase encoded string (including the prefix)
|
|
37
|
+
*/
|
|
38
|
+
export declare function multibaseEncode(bytes: Uint8Array, encoding?: MultibaseEncoding): string;
|
|
39
|
+
/**
|
|
40
|
+
* Decodes a multibase encoded string to binary data
|
|
41
|
+
* @param str - The multibase encoded string
|
|
42
|
+
* @returns The decoded binary data and the encoding used
|
|
43
|
+
*/
|
|
44
|
+
export declare function multibaseDecode(str: string): {
|
|
45
|
+
bytes: Uint8Array;
|
|
46
|
+
encoding: MultibaseEncoding;
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* Supported Multihash algorithm identifiers
|
|
50
|
+
*/
|
|
51
|
+
export declare enum MultihashAlgorithm {
|
|
52
|
+
SHA2_256 = 18,
|
|
53
|
+
SHA2_384 = 32,
|
|
54
|
+
SHA3_256 = 22,
|
|
55
|
+
SHA3_384 = 21
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Expected digest lengths for each algorithm (in bytes)
|
|
59
|
+
*/
|
|
60
|
+
export declare const DIGEST_LENGTHS: {
|
|
61
|
+
18: number;
|
|
62
|
+
32: number;
|
|
63
|
+
22: number;
|
|
64
|
+
21: number;
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* Creates a multihash from a digest and algorithm
|
|
68
|
+
* @param digest - The digest bytes
|
|
69
|
+
* @param algorithm - The hash algorithm used
|
|
70
|
+
* @returns The multihash as a Uint8Array
|
|
71
|
+
*/
|
|
72
|
+
export declare function createMultihash(digest: Uint8Array, algorithm: MultihashAlgorithm): Uint8Array;
|
|
73
|
+
/**
|
|
74
|
+
* Decodes a multihash
|
|
75
|
+
* @param bytes - The multihash bytes
|
|
76
|
+
* @returns The decoded multihash components
|
|
77
|
+
*/
|
|
78
|
+
export declare function decodeMultihash(bytes: Uint8Array): {
|
|
79
|
+
algorithm: MultihashAlgorithm;
|
|
80
|
+
digestLength: number;
|
|
81
|
+
digest: Uint8Array;
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* Encodes a multihash using multibase encoding
|
|
85
|
+
* @param multihash - The multihash bytes
|
|
86
|
+
* @param encoding - The multibase encoding to use
|
|
87
|
+
* @returns The multibase encoded multihash
|
|
88
|
+
*/
|
|
89
|
+
export declare function encodeMultihashWithMultibase(multihash: Uint8Array, encoding?: MultibaseEncoding): string;
|
|
90
|
+
/**
|
|
91
|
+
* Decodes a multibase encoded multihash
|
|
92
|
+
* @param str - The multibase encoded multihash
|
|
93
|
+
* @returns The decoded multihash components and the encoding used
|
|
94
|
+
*/
|
|
95
|
+
export declare function decodeMultihashFromMultibase(str: string): {
|
|
96
|
+
algorithm: MultihashAlgorithm;
|
|
97
|
+
digestLength: number;
|
|
98
|
+
digest: Uint8Array;
|
|
99
|
+
encoding: MultibaseEncoding;
|
|
100
|
+
};
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* multiformats.ts
|
|
3
|
+
*
|
|
4
|
+
* This file provides utilities for working with Multibase and Multihash formats
|
|
5
|
+
* as specified in the DID:WebVH method specification.
|
|
6
|
+
*/
|
|
7
|
+
// ===== MULTIBASE IMPLEMENTATION =====
|
|
8
|
+
/**
|
|
9
|
+
* Supported Multibase encoding types
|
|
10
|
+
*/
|
|
11
|
+
export var MultibaseEncoding;
|
|
12
|
+
(function (MultibaseEncoding) {
|
|
13
|
+
MultibaseEncoding["BASE64URL_NO_PAD"] = "u";
|
|
14
|
+
MultibaseEncoding["BASE58_BTC"] = "z";
|
|
15
|
+
})(MultibaseEncoding || (MultibaseEncoding = {}));
|
|
16
|
+
/**
|
|
17
|
+
* Base encoding alphabets
|
|
18
|
+
*/
|
|
19
|
+
const BASE_ALPHABETS = {
|
|
20
|
+
[MultibaseEncoding.BASE64URL_NO_PAD]: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_',
|
|
21
|
+
[MultibaseEncoding.BASE58_BTC]: '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz',
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Encodes binary data using Base64URL (no padding)
|
|
25
|
+
* @param bytes - The binary data to encode
|
|
26
|
+
* @returns The base64url encoded string (without the multibase prefix)
|
|
27
|
+
*/
|
|
28
|
+
export function encodeBase64Url(bytes) {
|
|
29
|
+
// Convert to base64
|
|
30
|
+
const base64 = Buffer.from(bytes).toString('base64');
|
|
31
|
+
// Convert to base64url by replacing + with - and / with _
|
|
32
|
+
return base64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Decodes a Base64URL (no padding) string to binary data
|
|
36
|
+
* @param str - The base64url encoded string
|
|
37
|
+
* @returns The decoded binary data
|
|
38
|
+
*/
|
|
39
|
+
function decodeBase64Url(str) {
|
|
40
|
+
// Add padding if necessary
|
|
41
|
+
const padding = str.length % 4 === 0 ? 0 : 4 - (str.length % 4);
|
|
42
|
+
const base64 = str.replace(/-/g, '+').replace(/_/g, '/') + '='.repeat(padding);
|
|
43
|
+
// Decode base64 to binary
|
|
44
|
+
const binary = atob(base64);
|
|
45
|
+
const bytes = new Uint8Array(binary.length);
|
|
46
|
+
for (let i = 0; i < binary.length; i++) {
|
|
47
|
+
bytes[i] = binary.charCodeAt(i);
|
|
48
|
+
}
|
|
49
|
+
return bytes;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Encodes binary data using Base58BTC
|
|
53
|
+
* @param bytes - The binary data to encode
|
|
54
|
+
* @returns The base58btc encoded string (without the multibase prefix)
|
|
55
|
+
*/
|
|
56
|
+
export function encodeBase58Btc(bytes) {
|
|
57
|
+
const ALPHABET = BASE_ALPHABETS[MultibaseEncoding.BASE58_BTC];
|
|
58
|
+
// Count leading zeros
|
|
59
|
+
let zeros = 0;
|
|
60
|
+
for (let i = 0; i < bytes.length && bytes[i] === 0; i++) {
|
|
61
|
+
zeros++;
|
|
62
|
+
}
|
|
63
|
+
// Convert to a big integer
|
|
64
|
+
let num = 0n;
|
|
65
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
66
|
+
num = num * 256n + BigInt(bytes[i]);
|
|
67
|
+
}
|
|
68
|
+
// Convert to base58
|
|
69
|
+
let result = '';
|
|
70
|
+
while (num > 0n) {
|
|
71
|
+
const remainder = Number(num % 58n);
|
|
72
|
+
num = num / 58n;
|
|
73
|
+
result = ALPHABET[remainder] + result;
|
|
74
|
+
}
|
|
75
|
+
// Add leading '1's for each leading zero byte
|
|
76
|
+
return '1'.repeat(zeros) + result;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Decodes a Base58BTC string to binary data
|
|
80
|
+
* @param str - The base58btc encoded string
|
|
81
|
+
* @returns The decoded binary data
|
|
82
|
+
*/
|
|
83
|
+
export function decodeBase58Btc(str) {
|
|
84
|
+
const ALPHABET = BASE_ALPHABETS[MultibaseEncoding.BASE58_BTC];
|
|
85
|
+
// Count leading '1's (representing leading zero bytes)
|
|
86
|
+
let zeros = 0;
|
|
87
|
+
for (let i = 0; i < str.length && str[i] === '1'; i++) {
|
|
88
|
+
zeros++;
|
|
89
|
+
}
|
|
90
|
+
// Convert from base58 to a big integer
|
|
91
|
+
let num = 0n;
|
|
92
|
+
for (let i = zeros; i < str.length; i++) {
|
|
93
|
+
const char = str[i];
|
|
94
|
+
const value = ALPHABET.indexOf(char);
|
|
95
|
+
if (value === -1) {
|
|
96
|
+
throw new Error(`Invalid Base58 character: ${char}`);
|
|
97
|
+
}
|
|
98
|
+
num = num * 58n + BigInt(value);
|
|
99
|
+
}
|
|
100
|
+
// Convert to bytes
|
|
101
|
+
const bytes = [];
|
|
102
|
+
while (num > 0n) {
|
|
103
|
+
bytes.unshift(Number(num % 256n));
|
|
104
|
+
num = num / 256n;
|
|
105
|
+
}
|
|
106
|
+
// Add leading zeros
|
|
107
|
+
return new Uint8Array([...new Array(zeros).fill(0), ...bytes]);
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Encodes binary data using the specified multibase encoding
|
|
111
|
+
* @param bytes - The binary data to encode
|
|
112
|
+
* @param encoding - The multibase encoding to use
|
|
113
|
+
* @returns The multibase encoded string (including the prefix)
|
|
114
|
+
*/
|
|
115
|
+
export function multibaseEncode(bytes, encoding = MultibaseEncoding.BASE64URL_NO_PAD) {
|
|
116
|
+
let encoded;
|
|
117
|
+
switch (encoding) {
|
|
118
|
+
case MultibaseEncoding.BASE64URL_NO_PAD:
|
|
119
|
+
encoded = encodeBase64Url(bytes);
|
|
120
|
+
break;
|
|
121
|
+
case MultibaseEncoding.BASE58_BTC:
|
|
122
|
+
encoded = encodeBase58Btc(bytes);
|
|
123
|
+
break;
|
|
124
|
+
default:
|
|
125
|
+
throw new Error(`Unsupported multibase encoding: ${encoding}`);
|
|
126
|
+
}
|
|
127
|
+
return `${encoding}${encoded}`;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Decodes a multibase encoded string to binary data
|
|
131
|
+
* @param str - The multibase encoded string
|
|
132
|
+
* @returns The decoded binary data and the encoding used
|
|
133
|
+
*/
|
|
134
|
+
export function multibaseDecode(str) {
|
|
135
|
+
if (!str || str.length < 2) {
|
|
136
|
+
throw new Error('Invalid multibase string: too short');
|
|
137
|
+
}
|
|
138
|
+
const prefix = str[0];
|
|
139
|
+
const encoded = str.slice(1);
|
|
140
|
+
let bytes;
|
|
141
|
+
switch (prefix) {
|
|
142
|
+
case MultibaseEncoding.BASE64URL_NO_PAD:
|
|
143
|
+
bytes = decodeBase64Url(encoded);
|
|
144
|
+
break;
|
|
145
|
+
case MultibaseEncoding.BASE58_BTC:
|
|
146
|
+
bytes = decodeBase58Btc(encoded);
|
|
147
|
+
break;
|
|
148
|
+
default:
|
|
149
|
+
throw new Error(`Unsupported multibase encoding prefix: ${prefix}`);
|
|
150
|
+
}
|
|
151
|
+
return { bytes, encoding: prefix };
|
|
152
|
+
}
|
|
153
|
+
// ===== MULTIHASH IMPLEMENTATION =====
|
|
154
|
+
/**
|
|
155
|
+
* Supported Multihash algorithm identifiers
|
|
156
|
+
*/
|
|
157
|
+
export var MultihashAlgorithm;
|
|
158
|
+
(function (MultihashAlgorithm) {
|
|
159
|
+
MultihashAlgorithm[MultihashAlgorithm["SHA2_256"] = 18] = "SHA2_256";
|
|
160
|
+
MultihashAlgorithm[MultihashAlgorithm["SHA2_384"] = 32] = "SHA2_384";
|
|
161
|
+
MultihashAlgorithm[MultihashAlgorithm["SHA3_256"] = 22] = "SHA3_256";
|
|
162
|
+
MultihashAlgorithm[MultihashAlgorithm["SHA3_384"] = 21] = "SHA3_384";
|
|
163
|
+
})(MultihashAlgorithm || (MultihashAlgorithm = {}));
|
|
164
|
+
/**
|
|
165
|
+
* Expected digest lengths for each algorithm (in bytes)
|
|
166
|
+
*/
|
|
167
|
+
export const DIGEST_LENGTHS = {
|
|
168
|
+
[MultihashAlgorithm.SHA2_256]: 32,
|
|
169
|
+
[MultihashAlgorithm.SHA2_384]: 48,
|
|
170
|
+
[MultihashAlgorithm.SHA3_256]: 32,
|
|
171
|
+
[MultihashAlgorithm.SHA3_384]: 48,
|
|
172
|
+
};
|
|
173
|
+
/**
|
|
174
|
+
* Encodes a varint (variable integer)
|
|
175
|
+
* @param value - The integer to encode
|
|
176
|
+
* @returns The encoded varint as a Uint8Array
|
|
177
|
+
*/
|
|
178
|
+
function encodeVarint(value) {
|
|
179
|
+
const bytes = [];
|
|
180
|
+
while (value >= 0x80) {
|
|
181
|
+
bytes.push((value & 0x7f) | 0x80);
|
|
182
|
+
value >>>= 7;
|
|
183
|
+
}
|
|
184
|
+
bytes.push(value & 0x7f);
|
|
185
|
+
return new Uint8Array(bytes);
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Decodes a varint (variable integer)
|
|
189
|
+
* @param bytes - The bytes containing the varint
|
|
190
|
+
* @param offset - The starting offset in the bytes array
|
|
191
|
+
* @returns The decoded value and the number of bytes read
|
|
192
|
+
*/
|
|
193
|
+
function decodeVarint(bytes, offset = 0) {
|
|
194
|
+
let value = 0;
|
|
195
|
+
let shift = 0;
|
|
196
|
+
let bytesRead = 0;
|
|
197
|
+
let byte = 0;
|
|
198
|
+
do {
|
|
199
|
+
if (offset + bytesRead >= bytes.length) {
|
|
200
|
+
throw new Error('Invalid varint: buffer too short');
|
|
201
|
+
}
|
|
202
|
+
byte = bytes[offset + bytesRead];
|
|
203
|
+
value |= (byte & 0x7f) << shift;
|
|
204
|
+
shift += 7;
|
|
205
|
+
bytesRead++;
|
|
206
|
+
} while (byte & 0x80);
|
|
207
|
+
return { value, bytesRead };
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Creates a multihash from a digest and algorithm
|
|
211
|
+
* @param digest - The digest bytes
|
|
212
|
+
* @param algorithm - The hash algorithm used
|
|
213
|
+
* @returns The multihash as a Uint8Array
|
|
214
|
+
*/
|
|
215
|
+
export function createMultihash(digest, algorithm) {
|
|
216
|
+
const expectedLength = DIGEST_LENGTHS[algorithm];
|
|
217
|
+
if (digest.length !== expectedLength) {
|
|
218
|
+
throw new Error(`Invalid digest length for algorithm ${algorithm.toString(16)}: expected ${expectedLength}, got ${digest.length}`);
|
|
219
|
+
}
|
|
220
|
+
const algorithmBytes = encodeVarint(algorithm);
|
|
221
|
+
const lengthBytes = encodeVarint(digest.length);
|
|
222
|
+
const result = new Uint8Array(algorithmBytes.length + lengthBytes.length + digest.length);
|
|
223
|
+
result.set(algorithmBytes, 0);
|
|
224
|
+
result.set(lengthBytes, algorithmBytes.length);
|
|
225
|
+
result.set(digest, algorithmBytes.length + lengthBytes.length);
|
|
226
|
+
return result;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Decodes a multihash
|
|
230
|
+
* @param bytes - The multihash bytes
|
|
231
|
+
* @returns The decoded multihash components
|
|
232
|
+
*/
|
|
233
|
+
export function decodeMultihash(bytes) {
|
|
234
|
+
if (bytes.length < 2) {
|
|
235
|
+
throw new Error('Invalid multihash: too short');
|
|
236
|
+
}
|
|
237
|
+
// Decode the algorithm identifier
|
|
238
|
+
const { value: algorithm, bytesRead: algorithmBytesRead } = decodeVarint(bytes, 0);
|
|
239
|
+
// Decode the digest length
|
|
240
|
+
const { value: digestLength, bytesRead: lengthBytesRead } = decodeVarint(bytes, algorithmBytesRead);
|
|
241
|
+
// Extract the digest
|
|
242
|
+
const offset = algorithmBytesRead + lengthBytesRead;
|
|
243
|
+
if (bytes.length - offset < digestLength) {
|
|
244
|
+
throw new Error(`Invalid multihash: digest too short, expected ${digestLength} bytes`);
|
|
245
|
+
}
|
|
246
|
+
const digest = bytes.slice(offset, offset + digestLength);
|
|
247
|
+
// Verify the algorithm is supported
|
|
248
|
+
if (!Object.values(MultihashAlgorithm).includes(algorithm)) {
|
|
249
|
+
throw new Error(`Unsupported multihash algorithm: 0x${algorithm.toString(16)}`);
|
|
250
|
+
}
|
|
251
|
+
// Verify the digest length matches the expected length for the algorithm
|
|
252
|
+
const expectedLength = DIGEST_LENGTHS[algorithm];
|
|
253
|
+
if (digestLength !== expectedLength) {
|
|
254
|
+
throw new Error(`Invalid digest length for algorithm 0x${algorithm.toString(16)}: expected ${expectedLength}, got ${digestLength}`);
|
|
255
|
+
}
|
|
256
|
+
return {
|
|
257
|
+
algorithm: algorithm,
|
|
258
|
+
digestLength,
|
|
259
|
+
digest,
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Encodes a multihash using multibase encoding
|
|
264
|
+
* @param multihash - The multihash bytes
|
|
265
|
+
* @param encoding - The multibase encoding to use
|
|
266
|
+
* @returns The multibase encoded multihash
|
|
267
|
+
*/
|
|
268
|
+
export function encodeMultihashWithMultibase(multihash, encoding = MultibaseEncoding.BASE64URL_NO_PAD) {
|
|
269
|
+
return multibaseEncode(multihash, encoding);
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Decodes a multibase encoded multihash
|
|
273
|
+
* @param str - The multibase encoded multihash
|
|
274
|
+
* @returns The decoded multihash components and the encoding used
|
|
275
|
+
*/
|
|
276
|
+
export function decodeMultihashFromMultibase(str) {
|
|
277
|
+
const { bytes, encoding } = multibaseDecode(str);
|
|
278
|
+
const multihash = decodeMultihash(bytes);
|
|
279
|
+
return {
|
|
280
|
+
...multihash,
|
|
281
|
+
encoding,
|
|
282
|
+
};
|
|
283
|
+
}
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { CreateDIDInterface, DIDDoc, DIDLog, ParsedDidKeyVerificationMethod, VerificationMethod, WitnessProofFileEntry } from './interfaces.js';
|
|
2
|
+
export declare function parseDidKeyDid(input: string): {
|
|
3
|
+
did: string;
|
|
4
|
+
keyMultibase: string;
|
|
5
|
+
};
|
|
6
|
+
export declare function parseDidKeyVerificationMethod(input: string): ParsedDidKeyVerificationMethod;
|
|
7
|
+
interface ParsedAddress {
|
|
8
|
+
canonicalHost: string;
|
|
9
|
+
canonicalPort?: number;
|
|
10
|
+
didDomainComponent: string;
|
|
11
|
+
paths?: string[];
|
|
12
|
+
}
|
|
13
|
+
export declare function parseCanonicalAddress(input: string): ParsedAddress;
|
|
14
|
+
export declare const DID_PLACEHOLDER = "{DID}";
|
|
15
|
+
export declare function validateCreateDidDocument(didDocument: DIDDoc): void;
|
|
16
|
+
export declare function replaceCreateDidPlaceholders<T>(input: T, scid: string, did: string): T;
|
|
17
|
+
export declare function convertWebvhIdToWebId(id: string): string;
|
|
18
|
+
export declare function enrichAlsoKnownAs(doc: DIDDoc, did: string, opts: {
|
|
19
|
+
alsoKnownAsWeb?: boolean;
|
|
20
|
+
}): DIDDoc;
|
|
21
|
+
export declare function generateParallelDidWeb(didwebvhDid: string, didwebvhDoc: DIDDoc): DIDDoc;
|
|
22
|
+
export declare const readLogFromDisk: (path: string) => Promise<DIDLog>;
|
|
23
|
+
export declare const readLogFromString: (str: string) => DIDLog;
|
|
24
|
+
export declare const writeLogToDisk: (path: string, log: DIDLog) => Promise<void>;
|
|
25
|
+
export declare const maybeWriteTestLog: (did: string, log: DIDLog) => Promise<void>;
|
|
26
|
+
export declare const writeVerificationMethodToEnv: (verificationMethod: VerificationMethod) => Promise<void>;
|
|
27
|
+
export declare const clone: (input: any) => any;
|
|
28
|
+
export declare function deepClone(obj: any): any;
|
|
29
|
+
export declare const getBaseUrl: (id: string) => string;
|
|
30
|
+
export declare const getFileUrl: (id: string) => string;
|
|
31
|
+
export declare function fetchLogFromIdentifier(identifier: string): Promise<DIDLog>;
|
|
32
|
+
export declare const createDate: (created?: Date | string) => string;
|
|
33
|
+
export declare function bytesToHex(bytes: Uint8Array): string;
|
|
34
|
+
export declare const createSCID: (logEntryHash: string) => Promise<string>;
|
|
35
|
+
export declare function deriveHash(input: any): Promise<string>;
|
|
36
|
+
export declare const deriveNextKeyHash: (input: string) => Promise<string>;
|
|
37
|
+
export declare const createDIDDoc: (options: CreateDIDInterface) => Promise<{
|
|
38
|
+
doc: DIDDoc;
|
|
39
|
+
}>;
|
|
40
|
+
export declare const generateRandomId: (length?: number) => string;
|
|
41
|
+
export declare const createVMID: (vm: VerificationMethod, did: string | null) => string;
|
|
42
|
+
export declare const normalizeVMs: (verificationMethod: VerificationMethod[] | undefined, did?: string | null) => any;
|
|
43
|
+
export declare const resolveVM: (vm: string) => Promise<VerificationMethod | {
|
|
44
|
+
publicKeyMultibase: string;
|
|
45
|
+
} | null>;
|
|
46
|
+
export declare const findVerificationMethod: (doc: any, vmId: string) => VerificationMethod | null;
|
|
47
|
+
export declare function fetchWitnessProofs(did: string): Promise<WitnessProofFileEntry[]>;
|
|
48
|
+
export declare function replaceValueInObject(obj: any, searchValue: string, replaceValue: string): any;
|
|
49
|
+
export {};
|