@did-btcr2/common 3.0.0 → 4.0.1
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 +79 -43
- package/dist/cjs/canonicalization.js.map +1 -1
- package/dist/cjs/constants.js +0 -1
- package/dist/cjs/constants.js.map +1 -1
- package/dist/cjs/errors.js +20 -3
- package/dist/cjs/errors.js.map +1 -1
- package/dist/cjs/types.js.map +1 -1
- package/dist/cjs/utils/date.js +92 -1
- package/dist/cjs/utils/date.js.map +1 -1
- package/dist/esm/canonicalization.js +79 -43
- package/dist/esm/canonicalization.js.map +1 -1
- package/dist/esm/constants.js +0 -1
- package/dist/esm/constants.js.map +1 -1
- package/dist/esm/errors.js +20 -3
- package/dist/esm/errors.js.map +1 -1
- package/dist/esm/types.js.map +1 -1
- package/dist/esm/utils/date.js +92 -1
- package/dist/esm/utils/date.js.map +1 -1
- package/dist/types/canonicalization.d.ts +37 -28
- package/dist/types/canonicalization.d.ts.map +1 -1
- package/dist/types/constants.d.ts +0 -1
- package/dist/types/constants.d.ts.map +1 -1
- package/dist/types/errors.d.ts +14 -3
- package/dist/types/errors.d.ts.map +1 -1
- package/dist/types/interfaces.d.ts +0 -271
- package/dist/types/interfaces.d.ts.map +1 -1
- package/dist/types/types.d.ts +3 -3
- package/dist/types/types.d.ts.map +1 -1
- package/dist/types/utils/date.d.ts +21 -1
- package/dist/types/utils/date.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/canonicalization.ts +96 -52
- package/src/constants.ts +0 -1
- package/src/errors.ts +25 -3
- package/src/interfaces.ts +0 -300
- package/src/types.ts +3 -3
- package/src/utils/date.ts +99 -1
package/src/canonicalization.ts
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import { sha256 } from '@noble/hashes/sha2';
|
|
2
|
-
import { bytesToHex } from '@noble/hashes/utils';
|
|
2
|
+
import { bytesToHex, hexToBytes } from '@noble/hashes/utils';
|
|
3
3
|
import { canonicalize as jcsa } from 'json-canonicalize';
|
|
4
4
|
import { base58btc } from 'multiformats/bases/base58';
|
|
5
5
|
import { CanonicalizationError } from './errors.js';
|
|
6
|
-
import { CanonicalizationAlgorithm, CanonicalizationEncoding, HashBytes } from './types.js';
|
|
6
|
+
import { CanonicalizationAlgorithm, CanonicalizationEncoding, HashBytes, HexString } from './types.js';
|
|
7
|
+
|
|
8
|
+
export interface CanonicalizationOptions {
|
|
9
|
+
algorithm?: CanonicalizationAlgorithm;
|
|
10
|
+
encoding?: CanonicalizationEncoding;
|
|
11
|
+
}
|
|
7
12
|
|
|
8
13
|
/**
|
|
9
14
|
* Canonicalization class provides methods for canonicalizing JSON objects
|
|
@@ -13,24 +18,6 @@ import { CanonicalizationAlgorithm, CanonicalizationEncoding, HashBytes } from '
|
|
|
13
18
|
* @type {Canonicalization}
|
|
14
19
|
*/
|
|
15
20
|
export class Canonicalization {
|
|
16
|
-
private readonly _defaultAlgorithm: CanonicalizationAlgorithm;
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Initializes the Canonicalization class with the specified algorithm.
|
|
20
|
-
* @param {CanonicalizationAlgorithm} algorithm The canonicalization algorithm to use ('jcs').
|
|
21
|
-
*/
|
|
22
|
-
constructor(algorithm: CanonicalizationAlgorithm = 'jcs') {
|
|
23
|
-
this._defaultAlgorithm = Canonicalization.normalizeAlgorithm(algorithm);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Gets the canonicalization algorithm.
|
|
28
|
-
* @returns {CanonicalizationAlgorithm} The current canonicalization algorithm.
|
|
29
|
-
*/
|
|
30
|
-
get algorithm(): CanonicalizationAlgorithm {
|
|
31
|
-
return this._defaultAlgorithm;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
21
|
/**
|
|
35
22
|
* Normalizes the canonicalization algorithm.
|
|
36
23
|
* @param {CanonicalizationAlgorithm} algorithm
|
|
@@ -72,22 +59,20 @@ export class Canonicalization {
|
|
|
72
59
|
* @param {Object} [options] Options for processing.
|
|
73
60
|
* @param {CanonicalizationEncoding} [options.encoding='hex'] The encoding format ('hex' or 'base58').
|
|
74
61
|
* @param {CanonicalizationAlgorithm} [options.algorithm] The canonicalization algorithm to use.
|
|
75
|
-
* @returns {
|
|
62
|
+
* @returns {string} The final SHA-256 hash bytes as a hex string.
|
|
76
63
|
*/
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
algorithm
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
const algorithm = Canonicalization.normalizeAlgorithm(options.algorithm ?? this._defaultAlgorithm);
|
|
83
|
-
const encoding = Canonicalization.normalizeEncoding(options.encoding ?? 'hex');
|
|
64
|
+
static process(object: Record<any, any>, options?: CanonicalizationOptions): string {
|
|
65
|
+
// Normalize the algorithm
|
|
66
|
+
const algorithm = Canonicalization.normalizeAlgorithm(options?.algorithm ?? 'jcs');
|
|
67
|
+
// Normalize the encoding
|
|
68
|
+
const encoding = Canonicalization.normalizeEncoding(options?.encoding ?? 'hex');
|
|
84
69
|
|
|
85
70
|
// Step 1: Canonicalize
|
|
86
|
-
const canonicalized =
|
|
71
|
+
const canonicalized = this.canonicalize(object, algorithm);
|
|
87
72
|
// Step 2: Hash
|
|
88
|
-
const hashed = this.
|
|
73
|
+
const hashed = this.toHash(canonicalized);
|
|
89
74
|
// Step 3: Encode
|
|
90
|
-
const encoded = this.encode(hashed, encoding
|
|
75
|
+
const encoded = this.encode(hashed, encoding);
|
|
91
76
|
// Return the encoded string
|
|
92
77
|
return encoded;
|
|
93
78
|
}
|
|
@@ -96,9 +81,9 @@ export class Canonicalization {
|
|
|
96
81
|
* Step 1: Uses this.algorithm to determine the method (JCS).
|
|
97
82
|
* @param {Record<any, any>} object The object to canonicalize.
|
|
98
83
|
* @param {CanonicalizationAlgorithm} [algorithm] The algorithm to use.
|
|
99
|
-
* @returns {
|
|
84
|
+
* @returns {string} The canonicalized object.
|
|
100
85
|
*/
|
|
101
|
-
|
|
86
|
+
static canonicalize(object: Record<any, any>, algorithm: CanonicalizationAlgorithm = 'jcs'): string {
|
|
102
87
|
switch (Canonicalization.normalizeAlgorithm(algorithm)) {
|
|
103
88
|
case 'jcs':
|
|
104
89
|
return this.jcs(object);
|
|
@@ -112,7 +97,7 @@ export class Canonicalization {
|
|
|
112
97
|
* @param {Record<any, any>} object The object to canonicalize.
|
|
113
98
|
* @returns {string} The canonicalized object.
|
|
114
99
|
*/
|
|
115
|
-
jcs(object: Record<any, any>): string {
|
|
100
|
+
static jcs(object: Record<any, any>): string {
|
|
116
101
|
return jcsa(object);
|
|
117
102
|
}
|
|
118
103
|
|
|
@@ -121,7 +106,7 @@ export class Canonicalization {
|
|
|
121
106
|
* @param {string} canonicalized The canonicalized object.
|
|
122
107
|
* @returns {HashBytes} The SHA-256 HashBytes (Uint8Array).
|
|
123
108
|
*/
|
|
124
|
-
|
|
109
|
+
static toHash(canonicalized: string): HashBytes {
|
|
125
110
|
return sha256(canonicalized);
|
|
126
111
|
}
|
|
127
112
|
|
|
@@ -132,33 +117,83 @@ export class Canonicalization {
|
|
|
132
117
|
* @throws {CanonicalizationError} If the encoding format is not supported.
|
|
133
118
|
* @returns {string} The encoded string.
|
|
134
119
|
*/
|
|
135
|
-
|
|
120
|
+
static encode(canonicalizedhash: HashBytes, encoding: CanonicalizationEncoding = 'hex'): string {
|
|
121
|
+
// Normalize encoding
|
|
136
122
|
const normalized = Canonicalization.normalizeEncoding(encoding);
|
|
137
|
-
|
|
123
|
+
|
|
124
|
+
// If encoding is hex, encode to hex
|
|
125
|
+
if (normalized === 'hex') {
|
|
126
|
+
return this.toHex(canonicalizedhash);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// If encoding is base58, encode to base58
|
|
138
130
|
if (normalized === 'base58') {
|
|
139
|
-
|
|
140
|
-
return multibase ? `z${encoded}` : encoded;
|
|
131
|
+
return this.toBase58(canonicalizedhash);
|
|
141
132
|
}
|
|
133
|
+
|
|
134
|
+
// Throw error if encoding is unsupported
|
|
142
135
|
throw new CanonicalizationError(`Unsupported encoding: ${encoding}`, 'ENCODING_ERROR');
|
|
143
136
|
}
|
|
144
137
|
|
|
138
|
+
/**
|
|
139
|
+
* Decodes SHA-256 hashed, canonicalized object as a hex or base58 string.
|
|
140
|
+
* @param {string} canonicalizedhash The canonicalized object to encode.
|
|
141
|
+
* @param {CanonicalizationEncoding} encoding The encoding format ('hex' or 'base58').
|
|
142
|
+
* @throws {CanonicalizationError} If the encoding format is not supported.
|
|
143
|
+
* @returns {string} The encoded string.
|
|
144
|
+
*/
|
|
145
|
+
static decode(canonicalizedhash: string, encoding: CanonicalizationEncoding = 'hex'): HashBytes {
|
|
146
|
+
// Normalize encoding
|
|
147
|
+
const normalized = Canonicalization.normalizeEncoding(encoding);
|
|
148
|
+
|
|
149
|
+
// If encoding is hex, decode from hex
|
|
150
|
+
if (normalized === 'hex') {
|
|
151
|
+
return this.fromHex(canonicalizedhash);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// If encoding is base58, decode from base58
|
|
155
|
+
if (normalized === 'base58') {
|
|
156
|
+
return this.fromBase58(canonicalizedhash);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Throw error if encoding is unsupported
|
|
160
|
+
throw new CanonicalizationError(`Unsupported encoding: ${encoding}`, 'DECODING_ERROR');
|
|
161
|
+
}
|
|
162
|
+
|
|
145
163
|
/**
|
|
146
164
|
* Step 3.1: Encodes HashBytes (Uint8Array) to a hex string.
|
|
147
165
|
* @param {HashBytes} hashBytes The hash as a Uint8Array.
|
|
148
166
|
* @returns {string} The hash as a hex string.
|
|
149
167
|
*/
|
|
150
|
-
|
|
168
|
+
static toHex(hashBytes: HashBytes): string {
|
|
151
169
|
return bytesToHex(hashBytes);
|
|
152
170
|
}
|
|
153
171
|
|
|
172
|
+
/**
|
|
173
|
+
* Decodes a hex string to HashBytes (Uint8Array).
|
|
174
|
+
* @param {HexString} hexString The hash as a hex string.
|
|
175
|
+
* @returns {HashBytes} The hash bytes.
|
|
176
|
+
*/
|
|
177
|
+
static fromHex(hexString: HexString): HashBytes {
|
|
178
|
+
return hexToBytes(hexString);
|
|
179
|
+
}
|
|
180
|
+
|
|
154
181
|
/**
|
|
155
182
|
* Step 3.2: Encodes HashBytes (Uint8Array) to a base58btc string.
|
|
156
183
|
* @param {HashBytes} hashBytes The hash as a Uint8Array.
|
|
157
184
|
* @returns {string} The hash as a hex string.
|
|
158
185
|
*/
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
186
|
+
static toBase58(hashBytes: HashBytes): string {
|
|
187
|
+
return base58btc.encode(hashBytes);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Decodes a base58 string to HashBytes (Uint8Array).
|
|
192
|
+
* @param {string} b58str The hash as a base58 string.
|
|
193
|
+
* @returns {HashBytes} The hash bytes.
|
|
194
|
+
*/
|
|
195
|
+
static fromBase58(b58str: string): HashBytes {
|
|
196
|
+
return base58btc.decode(b58str);
|
|
162
197
|
}
|
|
163
198
|
|
|
164
199
|
/**
|
|
@@ -167,12 +202,16 @@ export class Canonicalization {
|
|
|
167
202
|
* @param {Record<any, any>} object The object to process.
|
|
168
203
|
* @returns {Promise<HashBytes>} The final SHA-256 hash bytes.
|
|
169
204
|
*/
|
|
170
|
-
|
|
205
|
+
static andHash(
|
|
171
206
|
object: Record<any, any>,
|
|
172
|
-
algorithm: CanonicalizationAlgorithm =
|
|
173
|
-
):
|
|
174
|
-
|
|
175
|
-
|
|
207
|
+
algorithm: CanonicalizationAlgorithm = 'jcs'
|
|
208
|
+
): HashBytes {
|
|
209
|
+
// Step 1: Canonicalize
|
|
210
|
+
const canonicalized = this.canonicalize(object, algorithm);
|
|
211
|
+
// Step 2: Hash
|
|
212
|
+
const hashed = this.toHash(canonicalized);
|
|
213
|
+
// Return canonicalized hash bytes
|
|
214
|
+
return hashed;
|
|
176
215
|
}
|
|
177
216
|
|
|
178
217
|
/**
|
|
@@ -181,8 +220,13 @@ export class Canonicalization {
|
|
|
181
220
|
* @param {string} canonicalized The canonicalized object to hash.
|
|
182
221
|
* @returns {string} The SHA-256 hash as a hex string.
|
|
183
222
|
*/
|
|
184
|
-
|
|
185
|
-
|
|
223
|
+
static andHashToHex(canonicalized: string): string {
|
|
224
|
+
// Step 2: Hash
|
|
225
|
+
const hashed = this.toHash(canonicalized);
|
|
226
|
+
// Step 3: Encode (Hex)
|
|
227
|
+
const hexed = this.toHex(hashed);
|
|
228
|
+
// Return the hashed encoded string
|
|
229
|
+
return hexed;
|
|
186
230
|
}
|
|
187
231
|
|
|
188
232
|
/**
|
|
@@ -191,7 +235,7 @@ export class Canonicalization {
|
|
|
191
235
|
* @param {string} canonicalized The canonicalized object to hash.
|
|
192
236
|
* @returns {string} The SHA-256 hash as a base58 string.
|
|
193
237
|
*/
|
|
194
|
-
|
|
195
|
-
return this.encode(this.
|
|
238
|
+
static andHashToBase58(canonicalized: string): string {
|
|
239
|
+
return this.encode(this.toHash(canonicalized), 'base58');
|
|
196
240
|
}
|
|
197
241
|
}
|
package/src/constants.ts
CHANGED
|
@@ -2,7 +2,6 @@ import { sha256 } from '@noble/hashes/sha2';
|
|
|
2
2
|
import { bytesToHex } from '@noble/hashes/utils';
|
|
3
3
|
import { Bytes, HashHex } from './types.js';
|
|
4
4
|
|
|
5
|
-
export const ID_PLACEHOLDER_VALUE = 'did:btcr2:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
|
|
6
5
|
export const OP_RETURN = 0x6a;
|
|
7
6
|
export const OP_PUSH32 = 0x20;
|
|
8
7
|
export const VALID_HRP = ['k', 'x'];
|
package/src/errors.ts
CHANGED
|
@@ -75,8 +75,11 @@ export enum MethodErrorCode {
|
|
|
75
75
|
/** The sidecar data in the DID Update Payload was invalid. */
|
|
76
76
|
INVALID_SIDECAR_DATA = 'INVALID_SIDECAR_DATA',
|
|
77
77
|
|
|
78
|
-
/** The
|
|
79
|
-
|
|
78
|
+
/** The update data required for resolution is missing. */
|
|
79
|
+
MISSING_UPDATE_DATA = 'MISSING_UPDATE_DATA',
|
|
80
|
+
|
|
81
|
+
/** The update is missing or has a malformed field(s). */
|
|
82
|
+
INVALID_UPDATE = 'INVALID_UPDATE',
|
|
80
83
|
|
|
81
84
|
/** The proof is missing or has a malformed domain field. */
|
|
82
85
|
INVALID_DOMAIN_ERROR = 'INVALID_DOMAIN_ERROR'
|
|
@@ -106,7 +109,8 @@ export const {
|
|
|
106
109
|
VERIFICATION_METHOD_ERROR,
|
|
107
110
|
LATE_PUBLISHING_ERROR,
|
|
108
111
|
INVALID_SIDECAR_DATA,
|
|
109
|
-
|
|
112
|
+
MISSING_UPDATE_DATA,
|
|
113
|
+
INVALID_UPDATE,
|
|
110
114
|
INVALID_DOMAIN_ERROR
|
|
111
115
|
} = MethodErrorCode;
|
|
112
116
|
|
|
@@ -166,6 +170,18 @@ export class MethodError extends DidMethodError {
|
|
|
166
170
|
}
|
|
167
171
|
}
|
|
168
172
|
|
|
173
|
+
export class IdentifierError extends DidMethodError {
|
|
174
|
+
constructor(message: string, type: string = 'IdentifierError', data?: Record<string, any>) {
|
|
175
|
+
super(message, { type, name: type, data });
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export class UpdateError extends DidMethodError {
|
|
180
|
+
constructor(message: string, type: string = 'UpdateError', data?: Record<string, any>) {
|
|
181
|
+
super(message, { type, name: type, data });
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
169
185
|
export class ResolveError extends DidMethodError {
|
|
170
186
|
constructor(message: string, type: string = 'ResolveError', data?: Record<string, any>) {
|
|
171
187
|
super(message, { type, name: 'ResolveError', data });
|
|
@@ -190,6 +206,12 @@ export class CryptosuiteError extends DidMethodError {
|
|
|
190
206
|
}
|
|
191
207
|
}
|
|
192
208
|
|
|
209
|
+
export class DataIntegrityProofError extends DidMethodError {
|
|
210
|
+
constructor(message: string, type: string = 'DataIntegrityProofError', data?: Record<string, any>) {
|
|
211
|
+
super(message, { type, name: type, data });
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
193
215
|
export class KeyPairError extends DidMethodError {
|
|
194
216
|
constructor(message: string, type: string = 'KeyPairError', data?: Record<string, any>) {
|
|
195
217
|
super(message, { type, name: type, data });
|
package/src/interfaces.ts
CHANGED
|
@@ -9,303 +9,3 @@ export interface PatchOperation {
|
|
|
9
9
|
value?: unknown; // Required for add, replace, test
|
|
10
10
|
from?: string; // Required for move, copy
|
|
11
11
|
}
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* The unsigned payload object containing instructions for how to update a
|
|
15
|
-
* did:btcr2 DID Document. Once signed, it becomes a
|
|
16
|
-
* {@link DidUpdateInvocation | DID Update Invocation}
|
|
17
|
-
*
|
|
18
|
-
* DID BTCR2
|
|
19
|
-
* {@link https://dcdpr.github.io/did-btcr2/#construct-did-update-payload | 4.3.1 Construct DID Update Payload}.
|
|
20
|
-
*
|
|
21
|
-
* Found in DID BTCR2 Specification {@link https://dcdpr.github.io/did-btcr2/#dereference-root-capability-identifier | Section 9.4.2}
|
|
22
|
-
* @example
|
|
23
|
-
* ```
|
|
24
|
-
* {
|
|
25
|
-
* "@context": [
|
|
26
|
-
* "https://w3id.org/zcap/v1",
|
|
27
|
-
* "https://w3id.org/security/data-integrity/v2",
|
|
28
|
-
* "https://w3id.org/json-ld-patch/v1"
|
|
29
|
-
* ],
|
|
30
|
-
* "patch": [
|
|
31
|
-
* {
|
|
32
|
-
* "op": "add",
|
|
33
|
-
* "path": "/service/4",
|
|
34
|
-
* "value": {
|
|
35
|
-
* "id": "#linked-domain",
|
|
36
|
-
* "type": "LinkedDomains",
|
|
37
|
-
* "serviceEndpoint": "https://contact-me.com"
|
|
38
|
-
* }
|
|
39
|
-
* }
|
|
40
|
-
* ],
|
|
41
|
-
* "proof":{
|
|
42
|
-
* "type": "DataIntegrityProof,
|
|
43
|
-
* "cryptosuite": "schnorr-secp256k1-jcs-2025,
|
|
44
|
-
* "verificationMethod": "did:btcr2:k1qqpuwwde82nennsavvf0lqfnlvx7frrgzs57lchr02q8mz49qzaaxmqphnvcx#initialKey,
|
|
45
|
-
* "invocationTarget": "did:btcr2:k1qqpuwwde82nennsavvf0lqfnlvx7frrgzs57lchr02q8mz49qzaaxmqphnvcx,
|
|
46
|
-
* "capability": "urn:zcap:root:did%3Abtcr2%3Ak1qqpuwwde82nennsavvf0lqfnlvx7frrgzs57lchr02q8mz49qzaaxmqphnvcx,
|
|
47
|
-
* "capabilityAction": "Write,
|
|
48
|
-
* "proofPurpose": "assertionMethod,
|
|
49
|
-
* "proofValue": "z381yXYmxU8NudZ4HXY56DfMN6zfD8syvWcRXzT9xD9uYoQToo8QsXD7ahM3gXTzuay5WJbqTswt2BKaGWYn2hHhVFKJLXaD
|
|
50
|
-
* }
|
|
51
|
-
* }
|
|
52
|
-
* ```
|
|
53
|
-
*/
|
|
54
|
-
export interface DidUpdatePayload {
|
|
55
|
-
/**
|
|
56
|
-
* JSON-LD context URIs for interpreting this payload, including contexts
|
|
57
|
-
* for ZCAP (capabilities), Data Integrity proofs, and JSON-LD patch ops.
|
|
58
|
-
*/
|
|
59
|
-
'@context': string[];
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* A JSON Patch (or JSON-LD Patch) object defining the mutations to apply to
|
|
63
|
-
* the DID Document. Applying this patch to the current DID Document yields
|
|
64
|
-
* the new DID Document (which must remain valid per DID Core spec).
|
|
65
|
-
*/
|
|
66
|
-
patch: JsonPatch;
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* The multihash of the current (source) DID Document, encoded as a multibase
|
|
70
|
-
* base58-btc string. This is a SHA-256 hash of the canonicalized source DID
|
|
71
|
-
* Document, used to ensure the patch is applied to the correct document state.
|
|
72
|
-
*/
|
|
73
|
-
sourceHash: string;
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* The multihash of the updated (target) DID Document, encoded as multibase
|
|
77
|
-
* base58-btc. This is the SHA-256 hash of the canonicalized
|
|
78
|
-
* DID Document after applying the patch, used to verify the update result.
|
|
79
|
-
*/
|
|
80
|
-
targetHash: string;
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* The version number of the DID Document after this update.
|
|
84
|
-
* It is equal to the previous document version + 1.
|
|
85
|
-
*/
|
|
86
|
-
targetVersionId: number;
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* A proof object (Data Integrity proof) that authorizes this update.
|
|
90
|
-
* It is a JSON-LD proof indicating a capability invocation on the DID's
|
|
91
|
-
* root capability, typically signed with the DID's verification key (using
|
|
92
|
-
* Schnorr secp256k1 in did:btcr2).
|
|
93
|
-
*/
|
|
94
|
-
proof?: Proof;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* An extension of {@link DidUpdatePayload | DID Update Payload} containing a
|
|
99
|
-
* Data Integrity proof that authorizes the update. Once signed, the spec calls
|
|
100
|
-
* this an 'invoked DID Update Payload' or 'didUpdateInvocation'.
|
|
101
|
-
*
|
|
102
|
-
* DID BTCR2
|
|
103
|
-
* {@link https://dcdpr.github.io/did-btcr2/#invoke-did-update-payload | 4.3.2 Invoke DID Update Payload}
|
|
104
|
-
* and
|
|
105
|
-
* {@link https://dcdpr.github.io/did-btcr2/#root-didbtcr2-update-capabilities | 9.4 Root did:btcr2 Update Capabilities}.
|
|
106
|
-
*/
|
|
107
|
-
export interface DidUpdateInvocation extends DidUpdatePayload {
|
|
108
|
-
proof: Proof;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* Proof is the Data Integrity proof (ZCAP-LD style) added to a did:btcr2 DID
|
|
113
|
-
* Update Payload.
|
|
114
|
-
*
|
|
115
|
-
* Verifiable Credential Data Integrity
|
|
116
|
-
* {@link https://w3c.github.io/vc-data-integrity/#proofs | 2.1 Proofs}.
|
|
117
|
-
*
|
|
118
|
-
* DID BTCR2
|
|
119
|
-
* {@link https://dcdpr.github.io/did-btcr2/#invoke-did-update-payload | 4.3.2 Invoke DID Update Payload}.
|
|
120
|
-
*/
|
|
121
|
-
export interface Proof extends ProofOptions {
|
|
122
|
-
/**
|
|
123
|
-
* The cryptographic signature value. The exact property name may be defined
|
|
124
|
-
* by the cryptosuite (for instance, `proofValue` for a raw signature) and
|
|
125
|
-
* contains the actual signature bytes in an encoded form.
|
|
126
|
-
*/
|
|
127
|
-
proofValue: string;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* Proof Options used when adding a Data Integrity proof (ZCAP-LD style)
|
|
132
|
-
* to a did:btcr2 DID Update Payload.
|
|
133
|
-
*
|
|
134
|
-
* Verifiable Credential Data Integrity
|
|
135
|
-
* {@link https://w3c.github.io/vc-data-integrity/#proofs | 2.1 Proofs}.
|
|
136
|
-
*
|
|
137
|
-
* DID BTCR2
|
|
138
|
-
* {@link https://dcdpr.github.io/did-btcr2/#invoke-did-update-payload | 4.3.2 Invoke DID Update Payload}.
|
|
139
|
-
*/
|
|
140
|
-
export interface ProofOptions {
|
|
141
|
-
/**
|
|
142
|
-
* The proof type—per the spec’s example, "DataIntegrityProof".
|
|
143
|
-
*/
|
|
144
|
-
type: string;
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
* The cryptographic suite used, e.g. "schnorr-secp256k1-jcs-2025".
|
|
148
|
-
*/
|
|
149
|
-
cryptosuite: string;
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* DID URL of the key invoking the capability, i.e. the DID
|
|
153
|
-
* Document's verificationMethod.id used to sign this update.
|
|
154
|
-
*/
|
|
155
|
-
verificationMethod: string;
|
|
156
|
-
|
|
157
|
-
/**
|
|
158
|
-
* The purpose of the proof, which the spec sets to "capabilityInvocation".
|
|
159
|
-
*/
|
|
160
|
-
proofPurpose: string;
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
* The root capability being invoked. In did:btcr2, this is typically
|
|
164
|
-
* `urn:zcap:root:<urlencoded-did>` (see Section 9.4.1).
|
|
165
|
-
*/
|
|
166
|
-
capability?: string;
|
|
167
|
-
|
|
168
|
-
/**
|
|
169
|
-
* The action performed under the capability—set to "Write" in the spec
|
|
170
|
-
* for DID document updates.
|
|
171
|
-
*/
|
|
172
|
-
capabilityAction?: string;
|
|
173
|
-
|
|
174
|
-
/**
|
|
175
|
-
* (Optional) Some cryptosuites or proofs may include a timestamp, domain,
|
|
176
|
-
* or challenge. Although not explicitly required in the doc's steps, they
|
|
177
|
-
* often appear in Data Integrity proofs and may be included as needed.
|
|
178
|
-
*/
|
|
179
|
-
created?: string;
|
|
180
|
-
domain?: string;
|
|
181
|
-
challenge?: string;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
/**
|
|
185
|
-
* A JSON object that maps did:btcr2 identifiers to the CID of the corresponding
|
|
186
|
-
* DID Update Payload.
|
|
187
|
-
*
|
|
188
|
-
* DID BTCR2
|
|
189
|
-
* {@link https://dcdpr.github.io/did-btcr2/#cidaggregate-beacon | 5.2 CIDAggregate Beacons}.
|
|
190
|
-
*/
|
|
191
|
-
export interface DidUpdateBundle {
|
|
192
|
-
/**
|
|
193
|
-
* The keys are did:btcr2 identifiers as strings. The values are
|
|
194
|
-
* IPFS CIDs (or other CAS IDs) referencing the actual DID Update Payload.
|
|
195
|
-
*/
|
|
196
|
-
[didbtcr2Identifier: string]: string;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
/**
|
|
200
|
-
* A container for out-of-band data the resolver may need. This includes the
|
|
201
|
-
* initial DID document if it isn't stored in IPFS, plus references for each
|
|
202
|
-
* on-chain Beacon signal.
|
|
203
|
-
*
|
|
204
|
-
* DID BTCR2
|
|
205
|
-
* {@link https://dcdpr.github.io/did-btcr2/#sidecar-initial-document-validation | 4.2.1.2.1 Sidecar Initial Document Validation},
|
|
206
|
-
* {@link https://dcdpr.github.io/did-btcr2/#resolve-target-document | 4.2.2 Resolve Target Document},
|
|
207
|
-
* {@link https://dcdpr.github.io/did-btcr2/#traverse-blockchain-history | 4.2.2.2 Traverse Blockchain History},
|
|
208
|
-
* {@link https://dcdpr.github.io/did-btcr2/#find-next-signals | 4.2.2.3 Find Next Signals}.
|
|
209
|
-
*/
|
|
210
|
-
export interface SidecarData {
|
|
211
|
-
/**
|
|
212
|
-
* The initial DID Document for an externally created did:btcr2,
|
|
213
|
-
* if not fetched from IPFS or another CAS.
|
|
214
|
-
*/
|
|
215
|
-
initialDocument?: Record<string, any>; // or a typed DIDDocument from W3C DID Core
|
|
216
|
-
|
|
217
|
-
/**
|
|
218
|
-
* A map from Bitcoin transaction IDs to the sidecar info about that signal.
|
|
219
|
-
* Each signal might provide a single DID Update Payload, or (for aggregator beacons)
|
|
220
|
-
* a bundle or proofs.
|
|
221
|
-
*/
|
|
222
|
-
signalsMetadata: {
|
|
223
|
-
[txid: string]: SignalSidecarData;
|
|
224
|
-
};
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
/**
|
|
228
|
-
* Sidecar data for a specific Beacon Signal. Different Beacon types store different fields.
|
|
229
|
-
* - SingletonBeacon might just store one `updatePayload`.
|
|
230
|
-
* - CIDAggregateBeacon might store `updateBundle` + an `updatePayload`.
|
|
231
|
-
* - SMTAggregateBeacon might store `updatePayload` + a `smtProof`.
|
|
232
|
-
*/
|
|
233
|
-
export interface SignalSidecarData {
|
|
234
|
-
updatePayload?: DidUpdateInvocation; // or DidUpdatePayload if not yet invoked
|
|
235
|
-
updateBundle?: DidUpdateBundle; // for CIDAggregateBeacon
|
|
236
|
-
/**
|
|
237
|
-
* For SMTAggregateBeacon, a Merkle proof that the `updatePayload`
|
|
238
|
-
* is included (or not included) in the aggregator's Sparse Merkle Tree.
|
|
239
|
-
*/
|
|
240
|
-
smtProof?: SmtProof;
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
/**
|
|
244
|
-
* A placeholder for the actual Sparse Merkle Tree inclusion/non-inclusion proof.
|
|
245
|
-
*
|
|
246
|
-
* DID BTCR2
|
|
247
|
-
* {@link https://dcdpr.github.io/did-btcr2/#smtaggregate-beacon | 5.3 SMTAggregate Beacon}.
|
|
248
|
-
*/
|
|
249
|
-
export interface SmtProof {
|
|
250
|
-
// Implementation-specific structure for SMT proofs, e.g.:
|
|
251
|
-
siblingHashes: string[];
|
|
252
|
-
leafIndex?: string;
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
/**
|
|
256
|
-
* The known Beacon types from the spec.
|
|
257
|
-
*/
|
|
258
|
-
export type BeaconType =
|
|
259
|
-
| 'SingletonBeacon'
|
|
260
|
-
| 'CIDAggregateBeacon'
|
|
261
|
-
| 'SMTAggregateBeacon';
|
|
262
|
-
|
|
263
|
-
/**
|
|
264
|
-
* Represents a transaction discovered on the Bitcoin blockchain that
|
|
265
|
-
* spends from a Beacon address, thus announcing DID updates.
|
|
266
|
-
*
|
|
267
|
-
* DID BTCR2
|
|
268
|
-
* {@link https://dcdpr.github.io/did-btcr2/#find-next-signals | 4.2.2.3 Find Next Signals}
|
|
269
|
-
* and
|
|
270
|
-
* {@link https://dcdpr.github.io/did-btcr2/#process-beacon-signals | 4.2.2.4 Process Beacon Signals}.
|
|
271
|
-
*/
|
|
272
|
-
export interface BeaconSignal {
|
|
273
|
-
/**
|
|
274
|
-
* The DID Document's `service` ID of the Beacon that produced this signal, e.g. "#cidAggregateBeacon".
|
|
275
|
-
*/
|
|
276
|
-
beaconId: string;
|
|
277
|
-
|
|
278
|
-
/**
|
|
279
|
-
* The type of Beacon, e.g. "SingletonBeacon".
|
|
280
|
-
*/
|
|
281
|
-
beaconType: BeaconType;
|
|
282
|
-
|
|
283
|
-
/**
|
|
284
|
-
* The Bitcoin transaction that is the actual on-chain Beacon Signal.
|
|
285
|
-
* Typically you'd store a minimal subset or a reference/ID for real usage.
|
|
286
|
-
*/
|
|
287
|
-
tx: any;
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
/**
|
|
291
|
-
* A ZCAP-LD root capability object that authorizes updates for a particular did:btcr2.
|
|
292
|
-
*
|
|
293
|
-
* DID BTCR2
|
|
294
|
-
* {@link https://dcdpr.github.io/did-btcr2/#derive-root-capability-from-didbtcr2-identifier | 9.4.1 Derive Root Capability from did:btcr2 Identifier}.
|
|
295
|
-
*
|
|
296
|
-
* @example Found in DID BTCR2 Specification Section 9.4.1
|
|
297
|
-
* ```
|
|
298
|
-
* {
|
|
299
|
-
* "@context": "https://w3id.org/zcap/v1",
|
|
300
|
-
* "id": "urn:zcap:root:did%3Abtcr2%3Ak1qq...",
|
|
301
|
-
* "controller": "did:btcr2:k1qq...",
|
|
302
|
-
* "invocationTarget": "did:btcr2:k1qq..."
|
|
303
|
-
* }
|
|
304
|
-
* ```
|
|
305
|
-
*/
|
|
306
|
-
export interface DidBtcr2RootCapability {
|
|
307
|
-
'@context': string | string[]; // e.g. "https://w3id.org/zcap/v1"
|
|
308
|
-
id: string; // e.g. "urn:zcap:root:<urlencoded-did>"
|
|
309
|
-
controller: string; // the DID
|
|
310
|
-
invocationTarget: string; // same as DID
|
|
311
|
-
}
|
package/src/types.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { HDKey } from '@scure/bip32';
|
|
|
3
3
|
/* Crypto Types */
|
|
4
4
|
export type Bytes = Uint8Array;
|
|
5
5
|
export type Hex = Bytes | string;
|
|
6
|
+
export type HexString = string;
|
|
6
7
|
export type SignatureHex = Hex;
|
|
7
8
|
export type HashHex = Hex;
|
|
8
9
|
|
|
@@ -25,13 +26,13 @@ export type Point = {
|
|
|
25
26
|
}
|
|
26
27
|
export type PublicKeyObject = {
|
|
27
28
|
point: Point;
|
|
28
|
-
hex:
|
|
29
|
+
hex: HexString;
|
|
29
30
|
multibase: MultibaseObject;
|
|
30
31
|
};
|
|
31
32
|
export type SecretKeyObject = {
|
|
32
33
|
bytes: Array<number>;
|
|
33
34
|
seed?: string;
|
|
34
|
-
hex?:
|
|
35
|
+
hex?: HexString;
|
|
35
36
|
};
|
|
36
37
|
export type SchnorrKeyPair = {
|
|
37
38
|
secretKey: KeyBytes;
|
|
@@ -69,7 +70,6 @@ export enum BitcoinNetworkNames {
|
|
|
69
70
|
export type DecentralizedIdentifier = string;
|
|
70
71
|
export type Did = DecentralizedIdentifier;
|
|
71
72
|
export type BeaconUri = string;
|
|
72
|
-
export type DidPlaceholder = 'did:btcr2:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
|
|
73
73
|
export type CanonicalizedProofConfig = string;
|
|
74
74
|
export type CryptosuiteName = 'bip340-jcs-2025' | 'bip340-rdfc-2025';
|
|
75
75
|
export type JsonPrimitive = string | number | boolean | null;
|