@did-btcr2/common 5.0.0 → 8.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/dist/cjs/canonicalization.js +95 -230
- package/dist/cjs/canonicalization.js.map +1 -1
- package/dist/cjs/errors.js +3 -8
- package/dist/cjs/errors.js.map +1 -1
- package/dist/cjs/index.js +0 -3
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/json-patch.js +1 -1
- package/dist/cjs/json-patch.js.map +1 -1
- package/dist/cjs/types.js.map +1 -1
- package/dist/cjs/utils/date.js +3 -4
- package/dist/cjs/utils/date.js.map +1 -1
- package/dist/cjs/utils/json.js +2 -9
- package/dist/cjs/utils/json.js.map +1 -1
- package/dist/esm/canonicalization.js +95 -230
- package/dist/esm/canonicalization.js.map +1 -1
- package/dist/esm/errors.js +3 -8
- package/dist/esm/errors.js.map +1 -1
- package/dist/esm/index.js +0 -3
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/json-patch.js +1 -1
- package/dist/esm/json-patch.js.map +1 -1
- package/dist/esm/types.js.map +1 -1
- package/dist/esm/utils/date.js +3 -4
- package/dist/esm/utils/date.js.map +1 -1
- package/dist/esm/utils/json.js +2 -9
- package/dist/esm/utils/json.js.map +1 -1
- package/dist/types/canonicalization.d.ts +46 -137
- package/dist/types/canonicalization.d.ts.map +1 -1
- package/dist/types/errors.d.ts +5 -6
- package/dist/types/errors.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -3
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/json-patch.d.ts +2 -1
- package/dist/types/json-patch.d.ts.map +1 -1
- package/dist/types/types.d.ts +8 -28
- package/dist/types/types.d.ts.map +1 -1
- package/dist/types/utils/date.d.ts +4 -4
- package/dist/types/utils/date.d.ts.map +1 -1
- package/dist/types/utils/json.d.ts +2 -16
- package/dist/types/utils/json.d.ts.map +1 -1
- package/dist/types/utils/string.d.ts +1 -0
- package/package.json +11 -5
- package/src/canonicalization.ts +100 -254
- package/src/errors.ts +3 -15
- package/src/index.ts +0 -3
- package/src/json-patch.ts +2 -2
- package/src/types.ts +7 -30
- package/src/utils/date.ts +3 -4
- package/src/utils/json.ts +3 -10
- package/dist/cjs/constants.js +0 -119
- package/dist/cjs/constants.js.map +0 -1
- package/dist/cjs/logger.js +0 -155
- package/dist/cjs/logger.js.map +0 -1
- package/dist/cjs/utils/set.js +0 -23
- package/dist/cjs/utils/set.js.map +0 -1
- package/dist/esm/constants.js +0 -119
- package/dist/esm/constants.js.map +0 -1
- package/dist/esm/logger.js +0 -155
- package/dist/esm/logger.js.map +0 -1
- package/dist/esm/utils/set.js +0 -23
- package/dist/esm/utils/set.js.map +0 -1
- package/dist/types/constants.d.ts +0 -97
- package/dist/types/constants.d.ts.map +0 -1
- package/dist/types/logger.d.ts +0 -64
- package/dist/types/logger.d.ts.map +0 -1
- package/dist/types/utils/set.d.ts +0 -14
- package/dist/types/utils/set.d.ts.map +0 -1
- package/src/constants.ts +0 -127
- package/src/logger.ts +0 -173
- package/src/utils/set.ts +0 -23
package/src/canonicalization.ts
CHANGED
|
@@ -1,279 +1,125 @@
|
|
|
1
1
|
import { sha256 } from '@noble/hashes/sha2';
|
|
2
|
-
import {
|
|
2
|
+
import { base58, base64urlnopad, hex } from '@scure/base';
|
|
3
3
|
import { canonicalize as jcsa } from 'json-canonicalize';
|
|
4
|
-
import { base58btc } from 'multiformats/bases/base58';
|
|
5
4
|
import { CanonicalizationError } from './errors.js';
|
|
6
|
-
import {
|
|
7
|
-
|
|
5
|
+
import { HashBytes } from './types.js';
|
|
6
|
+
|
|
7
|
+
export type CanonicalizationAlgorithm = 'jcs' | 'rdfc';
|
|
8
|
+
export type CanonicalizationEncoding = 'hex' | 'base58' | 'base64url';
|
|
8
9
|
|
|
9
10
|
export interface CanonicalizationOptions {
|
|
10
11
|
algorithm?: CanonicalizationAlgorithm;
|
|
11
12
|
encoding?: CanonicalizationEncoding;
|
|
12
13
|
}
|
|
13
14
|
|
|
15
|
+
const SUPPORTED_ALGORITHMS: ReadonlySet<CanonicalizationAlgorithm> = new Set(['jcs']);
|
|
16
|
+
const SUPPORTED_ENCODINGS: ReadonlySet<CanonicalizationEncoding> = new Set(['hex', 'base58', 'base64url']);
|
|
17
|
+
|
|
14
18
|
/**
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* @
|
|
19
|
-
* @type {Canonicalization}
|
|
19
|
+
* Normalizes and validates the canonicalization algorithm.
|
|
20
|
+
* @param {CanonicalizationAlgorithm} algorithm - The algorithm to normalize.
|
|
21
|
+
* @returns {CanonicalizationAlgorithm} The normalized algorithm.
|
|
22
|
+
* @throws {CanonicalizationError} If the algorithm is not supported.
|
|
20
23
|
*/
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
* @returns {CanonicalizationAlgorithm} The normalized algorithm.
|
|
26
|
-
* @throws {CanonicalizationError} If the algorithm is not supported.
|
|
27
|
-
*/
|
|
28
|
-
static normalizeAlgorithm(algorithm: CanonicalizationAlgorithm): CanonicalizationAlgorithm {
|
|
29
|
-
const normalized = algorithm.toLowerCase() as CanonicalizationAlgorithm;
|
|
30
|
-
if (normalized !== 'jcs') {
|
|
31
|
-
throw new CanonicalizationError(`Unsupported algorithm: ${algorithm}`, 'ALGORITHM_ERROR');
|
|
32
|
-
}
|
|
33
|
-
return normalized;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Normalizes the canonicalization encoding.
|
|
38
|
-
* @param {CanonicalizationEncoding} encoding - The encoding to normalize.
|
|
39
|
-
* @returns {CanonicalizationEncoding} The normalized encoding.
|
|
40
|
-
* @throws {CanonicalizationError} If the encoding is not supported.
|
|
41
|
-
*/
|
|
42
|
-
static normalizeEncoding(encoding: CanonicalizationEncoding): CanonicalizationEncoding {
|
|
43
|
-
const normalized = encoding.toLowerCase() as CanonicalizationEncoding;
|
|
44
|
-
if (!['hex', 'base58btc', 'base64url'].includes(normalized)) {
|
|
45
|
-
throw new CanonicalizationError(`Unsupported encoding: ${encoding}`, 'ENCODING_ERROR');
|
|
46
|
-
}
|
|
47
|
-
return normalized;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Implements {@link http://dcdpr.github.io/did-btcr2/#json-canonicalization-and-hash | 9.2 JSON Canonicalization and Hash}.
|
|
52
|
-
*
|
|
53
|
-
* A macro function that takes in a JSON document, document, and canonicalizes it following the JSON Canonicalization
|
|
54
|
-
* Scheme. The function returns the canonicalizedBytes.
|
|
55
|
-
*
|
|
56
|
-
* Optionally encodes a sha256 hashed canonicalized JSON object.
|
|
57
|
-
* Step 1 Canonicalize (JCS) → Step 2 Hash (SHA256) → Step 3 Encode (Hex/Base58).
|
|
58
|
-
*
|
|
59
|
-
* @param {Record<any, any>} object The object to process.
|
|
60
|
-
* @param {Object} [options] Options for processing.
|
|
61
|
-
* @param {CanonicalizationEncoding} [options.encoding='hex'] The encoding format ('hex' or 'base58btc').
|
|
62
|
-
* @param {CanonicalizationAlgorithm} [options.algorithm] The canonicalization algorithm to use.
|
|
63
|
-
* @returns {string} The final SHA-256 hash bytes as a hex string.
|
|
64
|
-
*/
|
|
65
|
-
static process(object: Record<any, any>, options?: CanonicalizationOptions): string {
|
|
66
|
-
// Normalize the algorithm
|
|
67
|
-
const algorithm = Canonicalization.normalizeAlgorithm(options?.algorithm ?? 'jcs');
|
|
68
|
-
// Normalize the encoding
|
|
69
|
-
const encoding = Canonicalization.normalizeEncoding(options?.encoding ?? 'hex');
|
|
70
|
-
|
|
71
|
-
// Step 1: Canonicalize
|
|
72
|
-
const canonicalized = this.canonicalize(object, algorithm);
|
|
73
|
-
// Step 2: Hash
|
|
74
|
-
const hashed = this.toHash(canonicalized);
|
|
75
|
-
// Step 3: Encode
|
|
76
|
-
const encoded = this.encode(hashed, encoding);
|
|
77
|
-
// Return the encoded string
|
|
78
|
-
return encoded;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Step 1: Uses this.algorithm to determine the method (JCS).
|
|
83
|
-
* @param {Record<any, any>} object The object to canonicalize.
|
|
84
|
-
* @param {CanonicalizationAlgorithm} [algorithm] The algorithm to use.
|
|
85
|
-
* @returns {string} The canonicalized object.
|
|
86
|
-
*/
|
|
87
|
-
static canonicalize(object: Record<any, any>, algorithm: CanonicalizationAlgorithm = 'jcs'): string {
|
|
88
|
-
switch (Canonicalization.normalizeAlgorithm(algorithm)) {
|
|
89
|
-
case 'jcs':
|
|
90
|
-
return this.jcs(object);
|
|
91
|
-
default:
|
|
92
|
-
throw new CanonicalizationError(`Unsupported algorithm: ${algorithm}`, 'ALGORITHM_ERROR');
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Step 1: Canonicalizes an object using JCS (JSON Canonicalization Scheme).
|
|
98
|
-
* @param {Record<any, any>} object The object to canonicalize.
|
|
99
|
-
* @returns {string} The canonicalized object.
|
|
100
|
-
*/
|
|
101
|
-
static jcs(object: Record<any, any>): string {
|
|
102
|
-
return jcsa(object);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Step 2: SHA-256 hashes a canonicalized object.
|
|
107
|
-
* @param {string} canonicalized The canonicalized object.
|
|
108
|
-
* @returns {HashBytes} The SHA-256 HashBytes (Uint8Array).
|
|
109
|
-
*/
|
|
110
|
-
static toHash(canonicalized: string): HashBytes {
|
|
111
|
-
return sha256(canonicalized);
|
|
24
|
+
function normalizeAlgorithm(algorithm: CanonicalizationAlgorithm): CanonicalizationAlgorithm {
|
|
25
|
+
const lower = algorithm.toLowerCase();
|
|
26
|
+
if (!SUPPORTED_ALGORITHMS.has(lower as CanonicalizationAlgorithm)) {
|
|
27
|
+
throw new CanonicalizationError(`Unsupported algorithm: ${algorithm}`, 'ALGORITHM_ERROR');
|
|
112
28
|
}
|
|
29
|
+
return lower as CanonicalizationAlgorithm;
|
|
30
|
+
}
|
|
113
31
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
const normalized = Canonicalization.normalizeEncoding(encoding);
|
|
124
|
-
|
|
125
|
-
// If encoding is hex, encode to hex
|
|
126
|
-
if (normalized === 'hex') {
|
|
127
|
-
return this.toHex(canonicalizedhash);
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
// If encoding is base58btc, encode to base58btc
|
|
131
|
-
if (normalized === 'base58btc') {
|
|
132
|
-
return this.toBase58(canonicalizedhash);
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
// If encoding is base64url, encode to base64url
|
|
136
|
-
if (normalized === 'base64url') {
|
|
137
|
-
return this.toBase64Url(canonicalizedhash);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
// Throw error if encoding is unsupported
|
|
32
|
+
/**
|
|
33
|
+
* Normalizes and validates the canonicalization encoding.
|
|
34
|
+
* @param {CanonicalizationEncoding} encoding - The encoding to normalize.
|
|
35
|
+
* @returns {CanonicalizationEncoding} The normalized encoding.
|
|
36
|
+
* @throws {CanonicalizationError} If the encoding is not supported.
|
|
37
|
+
*/
|
|
38
|
+
function normalizeEncoding(encoding: CanonicalizationEncoding): CanonicalizationEncoding {
|
|
39
|
+
const lower = encoding.toLowerCase();
|
|
40
|
+
if (!SUPPORTED_ENCODINGS.has(lower as CanonicalizationEncoding)) {
|
|
141
41
|
throw new CanonicalizationError(`Unsupported encoding: ${encoding}`, 'ENCODING_ERROR');
|
|
142
42
|
}
|
|
43
|
+
return lower as CanonicalizationEncoding;
|
|
44
|
+
}
|
|
143
45
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
// If encoding is base58btc, decode from base58btc
|
|
161
|
-
if (normalized === 'base58btc') {
|
|
162
|
-
return this.fromBase58(canonicalizedhash);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
if(normalized === 'base64url') {
|
|
166
|
-
return this.fromBase64Url(canonicalizedhash);
|
|
46
|
+
/**
|
|
47
|
+
* Canonicalizes a JSON object using the specified algorithm.
|
|
48
|
+
*
|
|
49
|
+
* @param {Record<any, any>} object - The object to canonicalize.
|
|
50
|
+
* @param {CanonicalizationAlgorithm} [algorithm='jcs'] - The algorithm to use.
|
|
51
|
+
* @returns {string} The canonicalized string.
|
|
52
|
+
* @throws {CanonicalizationError} If the algorithm is not supported.
|
|
53
|
+
*/
|
|
54
|
+
export function canonicalize(object: Record<any, any>, algorithm: CanonicalizationAlgorithm = 'jcs'): string {
|
|
55
|
+
const normalized = normalizeAlgorithm(algorithm);
|
|
56
|
+
switch (normalized) {
|
|
57
|
+
case 'jcs': {
|
|
58
|
+
// Round-trip to a plain object so JCS always sees the same key set
|
|
59
|
+
// regardless of whether the input is a class instance or a POJO.
|
|
60
|
+
const plain = JSON.parse(JSON.stringify(object));
|
|
61
|
+
return jcsa(plain);
|
|
167
62
|
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
throw new CanonicalizationError(`Unsupported encoding: ${encoding}`, 'DECODING_ERROR');
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
/**
|
|
174
|
-
* Step 3.1: Encodes HashBytes (Uint8Array) to a hex string.
|
|
175
|
-
* @param {HashBytes} hashBytes The hash as a Uint8Array.
|
|
176
|
-
* @returns {string} The hash as a hex string.
|
|
177
|
-
*/
|
|
178
|
-
static toHex(hashBytes: HashBytes): string {
|
|
179
|
-
return bytesToHex(hashBytes);
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
/**
|
|
183
|
-
* Decodes a hex string to HashBytes (Uint8Array).
|
|
184
|
-
* @param {HexString} hexString The hash as a hex string.
|
|
185
|
-
* @returns {HashBytes} The hash bytes.
|
|
186
|
-
*/
|
|
187
|
-
static fromHex(hexString: HexString): HashBytes {
|
|
188
|
-
return hexToBytes(hexString);
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
/**
|
|
192
|
-
* Step 3.2: Encodes HashBytes (Uint8Array) to a base58btc string.
|
|
193
|
-
* @param {HashBytes} hashBytes The hash as a Uint8Array.
|
|
194
|
-
* @returns {string} The hash as a hex string.
|
|
195
|
-
*/
|
|
196
|
-
static toBase58(hashBytes: HashBytes): string {
|
|
197
|
-
return base58btc.encode(hashBytes);
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
/**
|
|
201
|
-
* Decodes a base58btc string to HashBytes (Uint8Array).
|
|
202
|
-
* @param {string} b58str The hash as a base58btc string.
|
|
203
|
-
* @returns {HashBytes} The hash bytes.
|
|
204
|
-
*/
|
|
205
|
-
static fromBase58(b58str: string): HashBytes {
|
|
206
|
-
return base58btc.decode(b58str);
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
/**
|
|
210
|
-
* Step 3.2: Encodes HashBytes (Uint8Array) to a base64url string.
|
|
211
|
-
* @param {HashBytes} hashBytes The hash as a Uint8Array.
|
|
212
|
-
* @returns {string} The hash as a base64url string.
|
|
213
|
-
*/
|
|
214
|
-
static toBase64Url(hashBytes: HashBytes): string {
|
|
215
|
-
return base64url.encode(hashBytes);
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
/**
|
|
219
|
-
* Decodes a base64url string to HashBytes (Uint8Array).
|
|
220
|
-
* @param {string} b64urlstr The hash as a base64url string.
|
|
221
|
-
* @returns {HashBytes} The hash bytes.
|
|
222
|
-
*/
|
|
223
|
-
static fromBase64Url(b64urlstr: string): HashBytes {
|
|
224
|
-
return base64url.decode(b64urlstr);
|
|
63
|
+
default:
|
|
64
|
+
throw new CanonicalizationError(`Unsupported algorithm: ${algorithm}`, 'ALGORITHM_ERROR');
|
|
225
65
|
}
|
|
66
|
+
}
|
|
226
67
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
): HashBytes {
|
|
237
|
-
// Step 1: Canonicalize
|
|
238
|
-
const canonicalized = this.canonicalize(object, algorithm);
|
|
239
|
-
// Step 2: Hash
|
|
240
|
-
const hashed = this.toHash(canonicalized);
|
|
241
|
-
// Return canonicalized hash bytes
|
|
242
|
-
return hashed;
|
|
243
|
-
}
|
|
68
|
+
/**
|
|
69
|
+
* SHA-256 hashes a canonicalized string.
|
|
70
|
+
*
|
|
71
|
+
* @param {string} canonicalized - The canonicalized string to hash.
|
|
72
|
+
* @returns {HashBytes} The SHA-256 hash bytes (Uint8Array).
|
|
73
|
+
*/
|
|
74
|
+
export function hash(canonicalized: string): HashBytes {
|
|
75
|
+
return sha256(canonicalized);
|
|
76
|
+
}
|
|
244
77
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
return
|
|
78
|
+
/**
|
|
79
|
+
* Encodes hash bytes using the specified encoding.
|
|
80
|
+
*
|
|
81
|
+
* @param {HashBytes} hashBytes - The hash bytes to encode.
|
|
82
|
+
* @param {CanonicalizationEncoding} [encoding='base64url'] - The encoding format.
|
|
83
|
+
* @returns {string} The encoded string.
|
|
84
|
+
* @throws {CanonicalizationError} If the encoding is not supported.
|
|
85
|
+
*/
|
|
86
|
+
export function encode(hashBytes: HashBytes, encoding: CanonicalizationEncoding = 'base64url'): string {
|
|
87
|
+
const normalized = normalizeEncoding(encoding);
|
|
88
|
+
switch (normalized) {
|
|
89
|
+
case 'hex': return hex.encode(hashBytes);
|
|
90
|
+
case 'base58': return base58.encode(hashBytes);
|
|
91
|
+
case 'base64url': return base64urlnopad.encode(hashBytes);
|
|
258
92
|
}
|
|
93
|
+
}
|
|
259
94
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
95
|
+
/**
|
|
96
|
+
* Decodes an encoded hash string back to bytes.
|
|
97
|
+
*
|
|
98
|
+
* @param {string} encoded - The encoded hash string.
|
|
99
|
+
* @param {CanonicalizationEncoding} [encoding='base64url'] - The encoding format.
|
|
100
|
+
* @returns {HashBytes} The decoded hash bytes.
|
|
101
|
+
* @throws {CanonicalizationError} If the encoding is not supported.
|
|
102
|
+
*/
|
|
103
|
+
export function decode(encoded: string, encoding: CanonicalizationEncoding = 'base64url'): HashBytes {
|
|
104
|
+
const normalized = normalizeEncoding(encoding);
|
|
105
|
+
switch (normalized) {
|
|
106
|
+
case 'hex': return hex.decode(encoded);
|
|
107
|
+
case 'base58': return base58.decode(encoded);
|
|
108
|
+
case 'base64url': return base64urlnopad.decode(encoded);
|
|
268
109
|
}
|
|
110
|
+
}
|
|
269
111
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
112
|
+
/**
|
|
113
|
+
* Implements {@link https://dcdpr.github.io/did-btcr2/algorithms.html#json-document-hashing | 8.c JSON Document Hashing}.
|
|
114
|
+
*
|
|
115
|
+
* Full pipeline: Canonicalize (JCS) -> Hash (SHA-256) -> Encode.
|
|
116
|
+
*
|
|
117
|
+
* @param {Record<any, any>} object - The object to process.
|
|
118
|
+
* @param {CanonicalizationOptions} [options] - Options for algorithm and encoding.
|
|
119
|
+
* @returns {string} The encoded hash string.
|
|
120
|
+
*/
|
|
121
|
+
export function canonicalHash(object: Record<any, any>, options?: CanonicalizationOptions): string {
|
|
122
|
+
const algorithm = normalizeAlgorithm(options?.algorithm ?? 'jcs');
|
|
123
|
+
const encoding = normalizeEncoding(options?.encoding ?? 'base64url');
|
|
124
|
+
return encode(hash(canonicalize(object, algorithm)), encoding);
|
|
279
125
|
}
|
package/src/errors.ts
CHANGED
|
@@ -94,7 +94,6 @@ export const {
|
|
|
94
94
|
INTERNAL_ERROR,
|
|
95
95
|
INVALID_DID_DOCUMENT,
|
|
96
96
|
INVALID_DID_UPDATE,
|
|
97
|
-
INVALID_DID_DOCUMENT_LENGTH,
|
|
98
97
|
INVALID_DID_URL,
|
|
99
98
|
INVALID_PREVIOUS_DID_PROOF,
|
|
100
99
|
INVALID_PUBLIC_KEY,
|
|
@@ -102,9 +101,6 @@ export const {
|
|
|
102
101
|
INVALID_PUBLIC_KEY_LENGTH,
|
|
103
102
|
INVALID_PUBLIC_KEY_TYPE,
|
|
104
103
|
INVALID_SIGNATURE,
|
|
105
|
-
NOT_FOUND,
|
|
106
|
-
REPRESENTATION_NOT_SUPPORTED,
|
|
107
|
-
UNSUPPORTED_PUBLIC_KEY_TYPE,
|
|
108
104
|
PROOF_VERIFICATION_ERROR,
|
|
109
105
|
PROOF_GENERATION_ERROR,
|
|
110
106
|
PROOF_SERIALIZATION_ERROR,
|
|
@@ -113,12 +109,10 @@ export const {
|
|
|
113
109
|
LATE_PUBLISHING_ERROR,
|
|
114
110
|
INVALID_SIDECAR_DATA,
|
|
115
111
|
MISSING_UPDATE_DATA,
|
|
116
|
-
INVALID_UPDATE,
|
|
117
|
-
INVALID_DOMAIN_ERROR,
|
|
118
112
|
MISSING_RESOLUTION_OPTIONS
|
|
119
113
|
} = MethodErrorCode;
|
|
120
114
|
|
|
121
|
-
|
|
115
|
+
type ErrorOptions = {
|
|
122
116
|
type?: string;
|
|
123
117
|
name?: string;
|
|
124
118
|
data?: any;
|
|
@@ -169,7 +163,7 @@ export class DidMethodError extends Error {
|
|
|
169
163
|
}
|
|
170
164
|
|
|
171
165
|
export class MethodError extends DidMethodError {
|
|
172
|
-
constructor(message: string, type: string, data?: Record<string, any>) {
|
|
166
|
+
constructor(message: string, type: string = 'MethodError', data?: Record<string, any>) {
|
|
173
167
|
super(message, { type, name: type, data });
|
|
174
168
|
}
|
|
175
169
|
}
|
|
@@ -188,7 +182,7 @@ export class UpdateError extends DidMethodError {
|
|
|
188
182
|
|
|
189
183
|
export class ResolveError extends DidMethodError {
|
|
190
184
|
constructor(message: string, type: string = 'ResolveError', data?: Record<string, any>) {
|
|
191
|
-
super(message, { type, name:
|
|
185
|
+
super(message, { type, name: type, data });
|
|
192
186
|
}
|
|
193
187
|
}
|
|
194
188
|
|
|
@@ -258,12 +252,6 @@ export class CIDAggregateBeaconError extends DidMethodError {
|
|
|
258
252
|
}
|
|
259
253
|
}
|
|
260
254
|
|
|
261
|
-
export class SMTAggregateBeaconError extends DidMethodError {
|
|
262
|
-
constructor(message: string, type: string = 'SMTAggregateBeaconError', data?: Record<string, any>) {
|
|
263
|
-
super(message, { type, name: type, data });
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
|
|
267
255
|
export class CanonicalizationError extends DidMethodError {
|
|
268
256
|
constructor(message: string, type: string = 'CanonicalizationError', data?: Record<string, any>) {
|
|
269
257
|
super(message, { type, name: type, data });
|
package/src/index.ts
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
export * from './canonicalization.js';
|
|
2
|
-
export * from './constants.js';
|
|
3
2
|
export * from './errors.js';
|
|
4
3
|
export * from './json-patch.js';
|
|
5
|
-
export * from './logger.js';
|
|
6
4
|
export * from './types.js';
|
|
7
5
|
export * from './utils/date.js';
|
|
8
6
|
export * from './utils/json.js';
|
|
9
|
-
export * from './utils/set.js';
|
|
10
7
|
export * from './utils/string.js';
|
package/src/json-patch.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { JSONObject } from './types.js';
|
|
|
4
4
|
|
|
5
5
|
const { applyPatch, compare, deepClone } = jsonPatch;
|
|
6
6
|
|
|
7
|
-
export type PatchOpCode = 'add' | 'remove' | 'replace' | 'move' | 'copy' | 'test'
|
|
7
|
+
export type PatchOpCode = 'add' | 'remove' | 'replace' | 'move' | 'copy' | 'test';
|
|
8
8
|
/**
|
|
9
9
|
* A JSON Patch operation, as defined in {@link https://datatracker.ietf.org/doc/html/rfc6902 | RFC 6902}.
|
|
10
10
|
*/
|
|
@@ -41,7 +41,7 @@ export class JSONPatch {
|
|
|
41
41
|
throw new MethodError('Invalid JSON Patch operations', 'JSON_PATCH_APPLY_ERROR', { error: validationError });
|
|
42
42
|
}
|
|
43
43
|
try {
|
|
44
|
-
const result = applyPatch(docClone, operations as Operation[],
|
|
44
|
+
const result = applyPatch(docClone, operations as Operation[], false, mutate);
|
|
45
45
|
if (result.newDocument === undefined) {
|
|
46
46
|
throw new MethodError('JSON Patch application failed', 'JSON_PATCH_APPLY_ERROR', { result });
|
|
47
47
|
}
|
package/src/types.ts
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
import { HDKey } from '@scure/bip32';
|
|
1
|
+
import type { HDKey } from '@scure/bip32';
|
|
2
2
|
|
|
3
3
|
/* Crypto Types */
|
|
4
4
|
export type Bytes = Uint8Array;
|
|
5
5
|
export type Hex = Bytes | string;
|
|
6
6
|
export type HexString = string;
|
|
7
|
-
export type SignatureHex = Hex;
|
|
8
|
-
export type HashHex = Hex;
|
|
9
7
|
|
|
10
8
|
export type DocumentBytes = Bytes;
|
|
11
9
|
export type SignatureBytes = Bytes;
|
|
@@ -14,10 +12,6 @@ export type HashBytes = Bytes;
|
|
|
14
12
|
export type MessageBytes = Bytes;
|
|
15
13
|
export type Entropy = Bytes | bigint;
|
|
16
14
|
|
|
17
|
-
export type CompressedPublicKeyParityByte = 0x02 | 0x03;
|
|
18
|
-
export type Bip340Encoding = string;
|
|
19
|
-
export type Base58BtcPrefix = 'z';
|
|
20
|
-
|
|
21
15
|
export type KeyBytes = Bytes;
|
|
22
16
|
export type Point = {
|
|
23
17
|
x: Array<number>;
|
|
@@ -69,33 +63,16 @@ export enum BitcoinNetworkNames {
|
|
|
69
63
|
}
|
|
70
64
|
export type DecentralizedIdentifier = string;
|
|
71
65
|
export type Did = DecentralizedIdentifier;
|
|
72
|
-
export type BeaconUri = string;
|
|
73
66
|
export type CanonicalizedProofConfig = string;
|
|
74
67
|
export type CryptosuiteName = 'bip340-jcs-2025' | 'bip340-rdfc-2025';
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
export type JSONObject = JsonObject;
|
|
68
|
+
type JsonPrimitive = string | number | boolean | null;
|
|
69
|
+
type JsonArray = JsonValue[];
|
|
70
|
+
type JsonValue = JsonPrimitive | JsonArray | JsonObject;
|
|
71
|
+
type JsonObject = { [key: string]: JsonValue };
|
|
72
|
+
export type JSONObject = JsonObject;
|
|
80
73
|
export type Prototyped = JSONObject;
|
|
81
74
|
export type Unprototyped = JSONObject;
|
|
82
|
-
export type ContextObject = Record<string, JsonValue>;
|
|
83
|
-
export type Context = string | string[] | ContextObject | ContextObject[]
|
|
84
75
|
|
|
85
76
|
/* General Types */
|
|
86
|
-
export type Maybe<T> = T |
|
|
87
|
-
export type TwoDigits = `${number}${number}`;
|
|
88
|
-
export type ThreeDigits = `${number}${number}${number}`;
|
|
89
|
-
export type Year = `${1 | 2}${ThreeDigits}`;
|
|
90
|
-
export type Month = TwoDigits;
|
|
91
|
-
export type Day = TwoDigits;
|
|
92
|
-
export type Hours = TwoDigits;
|
|
93
|
-
export type Minutes = TwoDigits;
|
|
94
|
-
export type Seconds = TwoDigits;
|
|
95
|
-
export type UtcTimestamp = `${Year}-${Month}-${Day}T${Hours}:${Minutes}:${Seconds}`;
|
|
96
|
-
export type TzOffset = `${Hours}:${Minutes}`;
|
|
97
|
-
export type DateTimestamp = `${UtcTimestamp}Z` | `${UtcTimestamp}-${TzOffset}`;
|
|
98
|
-
export type CanonicalizableObject = Record<string, any>;
|
|
99
|
-
export type CanonicalizationAlgorithm = 'jcs' | 'rdfc';
|
|
100
|
-
export type CanonicalizationEncoding = 'hex' | 'base58btc' | 'base64url';
|
|
77
|
+
export type Maybe<T> = T | undefined;
|
|
101
78
|
export type UnixTimestamp = number;
|
package/src/utils/date.ts
CHANGED
|
@@ -31,10 +31,9 @@ export class DateUtils {
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
/**
|
|
34
|
-
*
|
|
35
|
-
* @param {string} dateString - The date string to
|
|
36
|
-
* @returns {
|
|
37
|
-
* @throws {Error} If the date string is invalid.
|
|
34
|
+
* Parse a date string into a Date object.
|
|
35
|
+
* @param {string} dateString - The date string to parse.
|
|
36
|
+
* @returns {Date} The parsed Date, or Date(0) (Unix epoch) if the string is invalid.
|
|
38
37
|
*/
|
|
39
38
|
static dateStringToTimestamp(dateString: string): Date {
|
|
40
39
|
const date = new Date(dateString);
|
package/src/utils/json.ts
CHANGED
|
@@ -207,7 +207,7 @@ export class JSONUtils {
|
|
|
207
207
|
}
|
|
208
208
|
|
|
209
209
|
if (candidate && typeof candidate === 'object') {
|
|
210
|
-
const result: any =
|
|
210
|
+
const result: any = {};
|
|
211
211
|
for (const key of Object.keys(candidate)) {
|
|
212
212
|
if (keySet.has(key)) continue;
|
|
213
213
|
result[key] = walk(candidate[key]);
|
|
@@ -229,7 +229,7 @@ export class JSONUtils {
|
|
|
229
229
|
static sanitize<T>(value: T): T {
|
|
230
230
|
const walk = (candidate: any): any => {
|
|
231
231
|
if (Array.isArray(candidate)) {
|
|
232
|
-
return candidate.map(item => walk(item));
|
|
232
|
+
return candidate.filter(item => item !== undefined).map(item => walk(item));
|
|
233
233
|
}
|
|
234
234
|
|
|
235
235
|
if (candidate && typeof candidate === 'object') {
|
|
@@ -249,14 +249,7 @@ export class JSONUtils {
|
|
|
249
249
|
return walk(value);
|
|
250
250
|
}
|
|
251
251
|
|
|
252
|
-
|
|
253
|
-
* Internal function to clone JSON values with options.
|
|
254
|
-
* @param {T} value - The value to clone.
|
|
255
|
-
* @param {CloneOptions} options - The cloning options.
|
|
256
|
-
* @param {WeakMap<object, any>} seen - A WeakMap to track seen objects for circular reference detection.
|
|
257
|
-
* @returns {any} The cloned value.
|
|
258
|
-
*/
|
|
259
|
-
static cloneInternal<T>(
|
|
252
|
+
private static cloneInternal<T>(
|
|
260
253
|
value: T,
|
|
261
254
|
options: CloneOptions = {},
|
|
262
255
|
seen: WeakMap<object, any> = new WeakMap<object, any>(),
|