@did-btcr2/method 0.15.0 → 0.17.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/browser.js +314 -312
- package/dist/browser.mjs +314 -312
- package/dist/cjs/core/beacon/aggregation/protocol/nostr.js +4 -4
- package/dist/cjs/core/beacon/aggregation/protocol/nostr.js.map +1 -1
- package/dist/cjs/core/beacon/cid-aggregate.js +2 -2
- package/dist/cjs/core/beacon/singleton.js +2 -2
- package/dist/cjs/core/beacon/singleton.js.map +1 -1
- package/dist/cjs/core/crud/deactivate.js +4 -4
- package/dist/cjs/core/crud/deactivate.js.map +1 -1
- package/dist/cjs/core/crud/read.js +20 -20
- package/dist/cjs/core/crud/read.js.map +1 -1
- package/dist/cjs/core/crud/update.js +2 -2
- package/dist/cjs/core/crud/update.js.map +1 -1
- package/dist/cjs/core/key-manager/index.js +5 -5
- package/dist/cjs/core/key-manager/index.js.map +1 -1
- package/dist/cjs/did-btcr2.js +8 -20
- package/dist/cjs/did-btcr2.js.map +1 -1
- package/dist/cjs/index.js +0 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/utils/appendix.js +4 -4
- package/dist/cjs/utils/appendix.js.map +1 -1
- package/dist/cjs/utils/did-document-builder.js +1 -1
- package/dist/cjs/utils/did-document-builder.js.map +1 -1
- package/dist/cjs/utils/did-document.js +62 -14
- package/dist/cjs/utils/did-document.js.map +1 -1
- package/dist/cjs/utils/identifier.js +5 -5
- package/dist/cjs/utils/identifier.js.map +1 -1
- package/dist/esm/core/beacon/aggregation/protocol/nostr.js +4 -4
- package/dist/esm/core/beacon/aggregation/protocol/nostr.js.map +1 -1
- package/dist/esm/core/beacon/cid-aggregate.js +2 -2
- package/dist/esm/core/beacon/singleton.js +2 -2
- package/dist/esm/core/beacon/singleton.js.map +1 -1
- package/dist/esm/core/crud/deactivate.js +4 -4
- package/dist/esm/core/crud/deactivate.js.map +1 -1
- package/dist/esm/core/crud/read.js +20 -20
- package/dist/esm/core/crud/read.js.map +1 -1
- package/dist/esm/core/crud/update.js +2 -2
- package/dist/esm/core/crud/update.js.map +1 -1
- package/dist/esm/core/key-manager/index.js +5 -5
- package/dist/esm/core/key-manager/index.js.map +1 -1
- package/dist/esm/did-btcr2.js +8 -20
- package/dist/esm/did-btcr2.js.map +1 -1
- package/dist/esm/index.js +0 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/utils/appendix.js +4 -4
- package/dist/esm/utils/appendix.js.map +1 -1
- package/dist/esm/utils/did-document-builder.js +1 -1
- package/dist/esm/utils/did-document-builder.js.map +1 -1
- package/dist/esm/utils/did-document.js +62 -14
- package/dist/esm/utils/did-document.js.map +1 -1
- package/dist/esm/utils/identifier.js +5 -5
- package/dist/esm/utils/identifier.js.map +1 -1
- package/dist/types/core/beacon/aggregation/protocol/nostr.d.ts +1 -1
- package/dist/types/core/beacon/cid-aggregate.d.ts +2 -2
- package/dist/types/core/crud/deactivate.d.ts +4 -4
- package/dist/types/core/crud/deactivate.d.ts.map +1 -1
- package/dist/types/core/crud/read.d.ts +4 -4
- package/dist/types/core/crud/read.d.ts.map +1 -1
- package/dist/types/core/crud/update.d.ts +10 -0
- package/dist/types/core/crud/update.d.ts.map +1 -1
- package/dist/types/core/key-manager/index.d.ts +6 -6
- package/dist/types/core/key-manager/index.d.ts.map +1 -1
- package/dist/types/core/key-manager/interface.d.ts +3 -3
- package/dist/types/core/key-manager/interface.d.ts.map +1 -1
- package/dist/types/did-btcr2.d.ts +15 -5
- package/dist/types/did-btcr2.d.ts.map +1 -1
- package/dist/types/index.d.ts +0 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/interfaces/crud.d.ts +1 -4
- package/dist/types/interfaces/crud.d.ts.map +1 -1
- package/dist/types/types/crud.d.ts +5 -5
- package/dist/types/types/crud.d.ts.map +1 -1
- package/dist/types/utils/appendix.d.ts +7 -7
- package/dist/types/utils/appendix.d.ts.map +1 -1
- package/dist/types/utils/did-document-builder.d.ts +1 -1
- package/dist/types/utils/did-document-builder.d.ts.map +1 -1
- package/dist/types/utils/did-document.d.ts +26 -11
- package/dist/types/utils/did-document.d.ts.map +1 -1
- package/dist/types/utils/identifier.d.ts +2 -2
- package/dist/types/utils/identifier.d.ts.map +1 -1
- package/package.json +7 -6
- package/src/core/beacon/aggregation/protocol/nostr.ts +4 -4
- package/src/core/beacon/cid-aggregate.ts +2 -2
- package/src/core/beacon/singleton.ts +2 -2
- package/src/core/crud/deactivate.ts +4 -4
- package/src/core/crud/read.ts +21 -21
- package/src/core/crud/update.ts +14 -2
- package/src/core/key-manager/index.ts +7 -7
- package/src/core/key-manager/interface.ts +3 -3
- package/src/did-btcr2.ts +24 -25
- package/src/index.ts +0 -1
- package/src/interfaces/crud.ts +1 -4
- package/src/types/crud.ts +5 -5
- package/src/utils/appendix.ts +9 -9
- package/src/utils/did-document-builder.ts +1 -1
- package/src/utils/did-document.ts +73 -17
- package/src/utils/identifier.ts +5 -5
- package/dist/cjs/core/crud/create.js +0 -102
- package/dist/cjs/core/crud/create.js.map +0 -1
- package/dist/esm/core/crud/create.js +0 -102
- package/dist/esm/core/crud/create.js.map +0 -1
- package/dist/types/core/crud/create.d.ts +0 -92
- package/dist/types/core/crud/create.d.ts.map +0 -1
- package/src/core/crud/create.ts +0 -160
package/src/core/crud/read.ts
CHANGED
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
UnixTimestamp
|
|
25
25
|
} from '@did-btcr2/common';
|
|
26
26
|
import { Cryptosuite, DataIntegrityProof, SchnorrMultikey } from '@did-btcr2/cryptosuite';
|
|
27
|
-
import {
|
|
27
|
+
import { CompressedSecp256k1PublicKey } from '@did-btcr2/keypair';
|
|
28
28
|
import { bytesToHex } from '@noble/hashes/utils';
|
|
29
29
|
import { DidBtcr2 } from '../../did-btcr2.js';
|
|
30
30
|
import { DidResolutionOptions } from '../../interfaces/crud.js';
|
|
@@ -136,8 +136,8 @@ export class Resolve {
|
|
|
136
136
|
// Deconstruct the components
|
|
137
137
|
const { network, genesisBytes } = identifierComponents;
|
|
138
138
|
|
|
139
|
-
// Construct a new
|
|
140
|
-
const { compressed: publicKey, multibase: publicKeyMultibase } = new
|
|
139
|
+
// Construct a new CompressedSecp256k1PublicKey and deconstruct the publicKey and publicKeyMultibase
|
|
140
|
+
const { compressed: publicKey, multibase: publicKeyMultibase } = new CompressedSecp256k1PublicKey(genesisBytes);
|
|
141
141
|
|
|
142
142
|
// Generate the service field for the DID Document
|
|
143
143
|
const service = BeaconUtils.generateBeaconServices({
|
|
@@ -154,7 +154,7 @@ export class Resolve {
|
|
|
154
154
|
id : `${identifier}#initialKey`,
|
|
155
155
|
type : 'Multikey',
|
|
156
156
|
controller : identifier,
|
|
157
|
-
publicKeyMultibase : publicKeyMultibase.
|
|
157
|
+
publicKeyMultibase : publicKeyMultibase.encoded
|
|
158
158
|
}],
|
|
159
159
|
service
|
|
160
160
|
});
|
|
@@ -353,7 +353,7 @@ export class Resolve {
|
|
|
353
353
|
|
|
354
354
|
// 10. Set targetDocument to the result of calling the Traverse Bitcoin Blockchain History algorithm
|
|
355
355
|
// passing in contemporaryDIDDocument, contemporaryBlockheight, currentVersionId, targetVersionId,
|
|
356
|
-
// targetTime, didDocumentHistory,
|
|
356
|
+
// targetTime, didDocumentHistory, updateHashHistory, signalsMetadata, and network.
|
|
357
357
|
const targetDocument = this.traverseBlockchainHistory({
|
|
358
358
|
contemporaryDidDocument : initialDocument,
|
|
359
359
|
contemporaryBlockHeight : 0,
|
|
@@ -361,7 +361,7 @@ export class Resolve {
|
|
|
361
361
|
targetVersionId,
|
|
362
362
|
targetTime,
|
|
363
363
|
didDocumentHistory : new Array(),
|
|
364
|
-
|
|
364
|
+
updateHashHistory : new Array(),
|
|
365
365
|
signalsMetadata,
|
|
366
366
|
network
|
|
367
367
|
});
|
|
@@ -396,7 +396,7 @@ export class Resolve {
|
|
|
396
396
|
* @param {UnixTimestamp} params.targetTime The timestamp used to target specific historical states of a DID document.
|
|
397
397
|
* Only Beacon Signals included in the Bitcoin blockchain before the targetTime are processed.
|
|
398
398
|
* @param {boolean} params.didDocumentHistory An array of DID documents ordered ascensing by version (1...N).
|
|
399
|
-
* @param {boolean} params.
|
|
399
|
+
* @param {boolean} params.updateHashHistory An array of SHA256 hashes of BTCR2 Updates ordered by version that are
|
|
400
400
|
* applied to the DID document in order to construct the contemporaryDIDDocument.
|
|
401
401
|
* @param {SignalsMetadata} params.signalsMetadata See {@link SignalsMetadata} for details.
|
|
402
402
|
* @param {string} params.network The bitcoin network to connect to (mainnet, signet, testnet, regtest).
|
|
@@ -409,7 +409,7 @@ export class Resolve {
|
|
|
409
409
|
targetVersionId,
|
|
410
410
|
targetTime,
|
|
411
411
|
didDocumentHistory,
|
|
412
|
-
|
|
412
|
+
updateHashHistory,
|
|
413
413
|
signalsMetadata,
|
|
414
414
|
network
|
|
415
415
|
}: {
|
|
@@ -419,7 +419,7 @@ export class Resolve {
|
|
|
419
419
|
targetVersionId?: number;
|
|
420
420
|
targetTime: number;
|
|
421
421
|
didDocumentHistory: DidDocument[];
|
|
422
|
-
|
|
422
|
+
updateHashHistory: string[];
|
|
423
423
|
signalsMetadata: SignalsMetadata;
|
|
424
424
|
network: string;
|
|
425
425
|
}): Promise<DidDocument> {
|
|
@@ -463,8 +463,8 @@ export class Resolve {
|
|
|
463
463
|
// 10.1. If update.targetVersionId is less than or equal to currentVersionId, run Algorithm Confirm Duplicate
|
|
464
464
|
// Update passing in update, documentHistory, and contemporaryHash.
|
|
465
465
|
if (updateTargetVersionId <= currentVersionId) {
|
|
466
|
-
|
|
467
|
-
await this.confirmDuplicateUpdate({ update, updateHashHistory:
|
|
466
|
+
updateHashHistory.push(contemporaryHash);
|
|
467
|
+
await this.confirmDuplicateUpdate({ update, updateHashHistory: updateHashHistory });
|
|
468
468
|
|
|
469
469
|
// 10.2. If update.targetVersionId equals currentVersionId + 1:
|
|
470
470
|
} else if (updateTargetVersionId === currentVersionId + 1) {
|
|
@@ -498,8 +498,8 @@ export class Resolve {
|
|
|
498
498
|
// 10.2.7 Set updateHash to the result of passing unsecuredUpdate into the JSON Canonicalization and Hash algorithm.
|
|
499
499
|
const updateHash = await JSON.canonicalization.process(update, 'base58');
|
|
500
500
|
|
|
501
|
-
// 10.2.8. Push updateHash onto
|
|
502
|
-
|
|
501
|
+
// 10.2.8. Push updateHash onto updateHashHistory.
|
|
502
|
+
updateHashHistory.push(updateHash as string);
|
|
503
503
|
|
|
504
504
|
// 10.2.9. Set contemporaryHash to result of passing contemporaryDIDDocument into the JSON Canonicalization and Hash algorithm.
|
|
505
505
|
contemporaryHash = await JSON.canonicalization.process(contemporaryDidDocument, 'base58');
|
|
@@ -796,19 +796,19 @@ export class Resolve {
|
|
|
796
796
|
// Establish a Beacon instance using the service and sidecar
|
|
797
797
|
const beacon = BeaconFactory.establish(service, sidecar);
|
|
798
798
|
|
|
799
|
-
// 2.5 Set
|
|
800
|
-
const
|
|
799
|
+
// 2.5 Set didUpdate to null.
|
|
800
|
+
const didUpdate = await beacon.processSignal(signalTx, signalsMetadata) ?? null;
|
|
801
801
|
|
|
802
802
|
// If the updates is null, throw an error
|
|
803
|
-
if (!
|
|
804
|
-
throw new MethodError('No
|
|
803
|
+
if (!didUpdate) {
|
|
804
|
+
throw new MethodError('No didUpdate for beacon', 'PROCESS_BEACON_SIGNALS_ERROR', { tx, signalsMetadata });
|
|
805
805
|
}
|
|
806
806
|
|
|
807
|
-
// 2.9 If
|
|
808
|
-
updates.push(
|
|
807
|
+
// 2.9 If didUpdate is not null, push didUpdate to updates.
|
|
808
|
+
updates.push(didUpdate);
|
|
809
809
|
|
|
810
810
|
// 3. Return updates.
|
|
811
|
-
return
|
|
811
|
+
return didUpdate;
|
|
812
812
|
}
|
|
813
813
|
|
|
814
814
|
/**
|
|
@@ -824,7 +824,7 @@ export class Resolve {
|
|
|
824
824
|
* @param {DidUpdatePayload} params.update The DID Update Payload to confirm.
|
|
825
825
|
* @param {Array<string>} params.updateHashHistory The history of hashes for previously applied updates.
|
|
826
826
|
* @returns {Promise<void>} A promise that resolves if the update is a duplicate, otherwise throws an error.
|
|
827
|
-
* @throws {
|
|
827
|
+
* @throws {ResolveError} if the update hash does not match the historical hash.
|
|
828
828
|
*/
|
|
829
829
|
public static async confirmDuplicateUpdate({ update, updateHashHistory }: {
|
|
830
830
|
update: DidUpdatePayload;
|
package/src/core/crud/update.ts
CHANGED
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
ProofOptions
|
|
13
13
|
} from '@did-btcr2/common';
|
|
14
14
|
import { SchnorrMultikey } from '@did-btcr2/cryptosuite';
|
|
15
|
-
import { SchnorrKeyPair,
|
|
15
|
+
import { SchnorrKeyPair, Secp256k1SecretKey } from '@did-btcr2/keypair';
|
|
16
16
|
import type { DidService } from '@web5/dids';
|
|
17
17
|
import { BeaconService } from '../../interfaces/ibeacon.js';
|
|
18
18
|
import { SignalsMetadata } from '../../types/crud.js';
|
|
@@ -21,6 +21,18 @@ import { DidDocument, DidVerificationMethod } from '../../utils/did-document.js'
|
|
|
21
21
|
import { BeaconFactory } from '../beacon/factory.js';
|
|
22
22
|
import { KeyManager } from '../key-manager/index.js';
|
|
23
23
|
|
|
24
|
+
export interface ConstructUpdateParams {
|
|
25
|
+
identifier: string;
|
|
26
|
+
sourceDocument: DidDocument;
|
|
27
|
+
sourceVersionId: number;
|
|
28
|
+
patch: PatchOperation[];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface UpdateParams extends ConstructUpdateParams {
|
|
32
|
+
verificationMethodId: string;
|
|
33
|
+
beaconIds: string[];
|
|
34
|
+
}
|
|
35
|
+
|
|
24
36
|
export type InvokePayloadParams = {
|
|
25
37
|
identifier: string;
|
|
26
38
|
didUpdatePayload: DidUpdatePayload;
|
|
@@ -158,7 +170,7 @@ export class Update {
|
|
|
158
170
|
id,
|
|
159
171
|
controller,
|
|
160
172
|
keys : new SchnorrKeyPair({
|
|
161
|
-
secretKey :
|
|
173
|
+
secretKey : Secp256k1SecretKey.decode(secretKeyMultibase)
|
|
162
174
|
})
|
|
163
175
|
});
|
|
164
176
|
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
SignatureBytes
|
|
11
11
|
} from '@did-btcr2/common';
|
|
12
12
|
import { SchnorrMultikey } from '@did-btcr2/cryptosuite';
|
|
13
|
-
import {
|
|
13
|
+
import { CompressedSecp256k1PublicKey, SchnorrKeyPair } from '@did-btcr2/keypair';
|
|
14
14
|
import { sha256 } from '@noble/hashes/sha2';
|
|
15
15
|
import { KeyValueStore, MemoryStore } from '@web5/common';
|
|
16
16
|
import { KeyIdentifier } from '@web5/crypto';
|
|
@@ -104,11 +104,11 @@ export class KeyManager implements IKeyManager, CryptoSigner, BitcoinSigner {
|
|
|
104
104
|
}
|
|
105
105
|
|
|
106
106
|
/**
|
|
107
|
-
* Gets the key pair from the key store and returns a
|
|
107
|
+
* Gets the key pair from the key store and returns a CompressedSecp256k1PublicKey.
|
|
108
108
|
* @param {KeyIdentifier} keyUri The URI of the key to get the public key for.
|
|
109
|
-
* @returns {Promise<
|
|
109
|
+
* @returns {Promise<CompressedSecp256k1PublicKey>} The public key associated with the key URI.
|
|
110
110
|
*/
|
|
111
|
-
public async getPublicKey(keyUri?: KeyIdentifier): Promise<
|
|
111
|
+
public async getPublicKey(keyUri?: KeyIdentifier): Promise<CompressedSecp256k1PublicKey> {
|
|
112
112
|
// Use the active key URI if not provided
|
|
113
113
|
const key = await this.getKey(keyUri);
|
|
114
114
|
|
|
@@ -264,13 +264,13 @@ export class KeyManager implements IKeyManager, CryptoSigner, BitcoinSigner {
|
|
|
264
264
|
|
|
265
265
|
/**
|
|
266
266
|
* Computes a multibase-compliant URI from a key.
|
|
267
|
-
* @param key A SchnorrKeyPair,
|
|
267
|
+
* @param key A SchnorrKeyPair, CompressedSecp256k1PublicKey, or multibase string
|
|
268
268
|
* @returns {string} A multibase URI (e.g. 'urn:mb:zQ3s...')
|
|
269
269
|
*/
|
|
270
|
-
public static toMultibaseUri(data: SchnorrKeyPair |
|
|
270
|
+
public static toMultibaseUri(data: SchnorrKeyPair | CompressedSecp256k1PublicKey | Multibase<'zQ3s'>): string {
|
|
271
271
|
const multibase = data instanceof SchnorrKeyPair
|
|
272
272
|
? data.publicKey.multibase
|
|
273
|
-
: data instanceof
|
|
273
|
+
: data instanceof CompressedSecp256k1PublicKey
|
|
274
274
|
? data.multibase
|
|
275
275
|
: data;
|
|
276
276
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { HashBytes, Hex, SignatureBytes } from '@did-btcr2/common';
|
|
2
2
|
import { Multikey, SchnorrMultikey } from '@did-btcr2/cryptosuite';
|
|
3
|
-
import { SchnorrKeyPair,
|
|
3
|
+
import { SchnorrKeyPair, CompressedSecp256k1PublicKey } from '@did-btcr2/keypair';
|
|
4
4
|
import { KeyValueStore } from '@web5/common';
|
|
5
5
|
|
|
6
6
|
export type KeyManagerOptions = {
|
|
@@ -77,9 +77,9 @@ export interface IKeyManager {
|
|
|
77
77
|
/**
|
|
78
78
|
* Gets the public key of a key pair.
|
|
79
79
|
* @param {KeyIdentifier} keyUri The URI of the key to get the public key for.
|
|
80
|
-
* @returns {Promise<
|
|
80
|
+
* @returns {Promise<CompressedSecp256k1PublicKey>} The public key of the key pair.
|
|
81
81
|
*/
|
|
82
|
-
getPublicKey(keyUri: KeyIdentifier): Promise<
|
|
82
|
+
getPublicKey(keyUri: KeyIdentifier): Promise<CompressedSecp256k1PublicKey>;
|
|
83
83
|
|
|
84
84
|
/**
|
|
85
85
|
* Imports a key pair into the key store.
|
package/src/did-btcr2.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
IdentifierTypes,
|
|
4
|
-
INVALID_DID,
|
|
2
|
+
DocumentBytes,
|
|
5
3
|
INVALID_DID_DOCUMENT,
|
|
4
|
+
KeyBytes,
|
|
6
5
|
METHOD_NOT_SUPPORTED,
|
|
6
|
+
MethodError,
|
|
7
7
|
PatchOperation,
|
|
8
8
|
W3C_DID_RESOLUTION_V1
|
|
9
9
|
} from '@did-btcr2/common';
|
|
@@ -17,7 +17,6 @@ import {
|
|
|
17
17
|
} from '@web5/dids';
|
|
18
18
|
import { initEccLib } from 'bitcoinjs-lib';
|
|
19
19
|
import * as tinysecp from 'tiny-secp256k1';
|
|
20
|
-
import { Create, CreateParams, CreateResponse } from './core/crud/create.js';
|
|
21
20
|
import { Resolve } from './core/crud/read.js';
|
|
22
21
|
import { Update } from './core/crud/update.js';
|
|
23
22
|
import { DidResolutionOptions } from './interfaces/crud.js';
|
|
@@ -25,6 +24,15 @@ import { Appendix } from './utils/appendix.js';
|
|
|
25
24
|
import { DidDocument, DidVerificationMethod } from './utils/did-document.js';
|
|
26
25
|
import { Identifier } from './utils/identifier.js';
|
|
27
26
|
|
|
27
|
+
export type Btcr2Identifier = string;
|
|
28
|
+
|
|
29
|
+
export interface DidCreateOptions {
|
|
30
|
+
/** DID BTCR2 Version Number */
|
|
31
|
+
version?: number;
|
|
32
|
+
/** Bitcoin Network */
|
|
33
|
+
network?: string;
|
|
34
|
+
}
|
|
35
|
+
|
|
28
36
|
/** Initialize tiny secp256k1 */
|
|
29
37
|
initEccLib(tinysecp);
|
|
30
38
|
|
|
@@ -37,7 +45,7 @@ initEccLib(tinysecp);
|
|
|
37
45
|
*
|
|
38
46
|
* @class DidBtcr2
|
|
39
47
|
* @type {DidBtcr2}
|
|
40
|
-
*
|
|
48
|
+
* @implements {DidMethod}
|
|
41
49
|
*/
|
|
42
50
|
export class DidBtcr2 implements DidMethod {
|
|
43
51
|
/** @type {string} Name of the DID method, as defined in the DID BTCR2 specification */
|
|
@@ -61,30 +69,21 @@ export class DidBtcr2 implements DidMethod {
|
|
|
61
69
|
* @returns {Promise<CreateResponse>} Promise resolving to a CreateResponse object.
|
|
62
70
|
* @throws {DidBtcr2Error} if any of the checks fail
|
|
63
71
|
*/
|
|
64
|
-
public static async create(params:
|
|
72
|
+
public static async create(params: {
|
|
73
|
+
idType: 'KEY' | 'EXTERNAL';
|
|
74
|
+
genesisBytes: KeyBytes | DocumentBytes;
|
|
75
|
+
options?: DidCreateOptions;
|
|
76
|
+
}): Promise<Btcr2Identifier> {
|
|
65
77
|
// Deconstruct the idType and options from the params
|
|
66
78
|
const { idType, options = {} } = params;
|
|
67
79
|
|
|
68
|
-
//
|
|
69
|
-
|
|
70
|
-
// Deconstruct the pubKeyBytes from the params
|
|
71
|
-
const { pubKeyBytes } = params;
|
|
80
|
+
// Deconstruct the version and network from the options, setting defaults if not given
|
|
81
|
+
const { version = 1, network = 'bitcoin' } = options;
|
|
72
82
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// If idType is external, call Create.external
|
|
78
|
-
if(idType === IdentifierTypes.EXTERNAL) {
|
|
79
|
-
// Deconstruct the intermediateDocument from the params
|
|
80
|
-
const { intermediateDocument } = params;
|
|
81
|
-
|
|
82
|
-
// Return call to Create.external
|
|
83
|
-
return await Create.external({ intermediateDocument, options });
|
|
84
|
-
}
|
|
83
|
+
// Set the genesisBytes from the params
|
|
84
|
+
const genesisBytes = params.genesisBytes;
|
|
85
85
|
|
|
86
|
-
|
|
87
|
-
throw new MethodError('Invalid idType: expected "KEY" or "EXTERNAL"', INVALID_DID, params);
|
|
86
|
+
return Identifier.encode({ idType, genesisBytes, version, network });
|
|
88
87
|
}
|
|
89
88
|
|
|
90
89
|
/**
|
|
@@ -176,7 +175,7 @@ export class DidBtcr2 implements DidMethod {
|
|
|
176
175
|
* @param {string} params.identifier The btcr2 identifier to be updated.
|
|
177
176
|
* @param {DidDocument} params.sourceDocument The DID document being updated.
|
|
178
177
|
* @param {string} params.sourceVersionId The versionId of the source document.
|
|
179
|
-
* @param {
|
|
178
|
+
* @param {PatchOperation} params.documentPatch The JSON patch to be applied to the source document.
|
|
180
179
|
* @param {string} params.verificationMethodId The verificationMethod ID to sign the update
|
|
181
180
|
* @param {string[]} params.beaconIds The beacon IDs to announce the update
|
|
182
181
|
* @returns {Promise<void>} Promise resolving to void
|
package/src/index.ts
CHANGED
|
@@ -3,7 +3,6 @@ export * from './core/beacon/factory.js';
|
|
|
3
3
|
export * from './core/beacon/singleton.js';
|
|
4
4
|
export * from './core/beacon/smt-aggregate.js';
|
|
5
5
|
|
|
6
|
-
export * from './core/crud/create.js';
|
|
7
6
|
export * from './core/crud/deactivate.js';
|
|
8
7
|
export * from './core/crud/read.js';
|
|
9
8
|
export * from './core/crud/update.js';
|
package/src/interfaces/crud.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { BitcoinCoreRpcClient } from '@did-btcr2/bitcoin';
|
|
2
1
|
import { UnixTimestamp } from '@did-btcr2/common';
|
|
3
2
|
import { DidResolutionOptions as IDidResolutionOptions } from '@web5/dids';
|
|
4
3
|
import { SidecarData } from '../types/crud.js';
|
|
@@ -8,7 +7,6 @@ import { DidDocument } from '../utils/did-document.js';
|
|
|
8
7
|
* Options for resolving a DID Document
|
|
9
8
|
* @param {?number} versionId The versionId for resolving the DID Document
|
|
10
9
|
* @param {?UnixTimestamp} versionTime The versionTime for resolving the DID Document
|
|
11
|
-
* @param {?BitcoinCoreRpcClient} rpc BitcoinCoreRpcClient client connection
|
|
12
10
|
* @param {?SidecarData} sidecarData The sidecar data for resolving the DID Document
|
|
13
11
|
*/
|
|
14
12
|
export interface DidResolutionOptions extends IDidResolutionOptions {
|
|
@@ -16,9 +14,8 @@ export interface DidResolutionOptions extends IDidResolutionOptions {
|
|
|
16
14
|
versionTime?: UnixTimestamp;
|
|
17
15
|
sidecarData?: SidecarData;
|
|
18
16
|
network?: string;
|
|
19
|
-
rpc?: BitcoinCoreRpcClient;
|
|
20
17
|
}
|
|
21
|
-
export interface
|
|
18
|
+
export interface RootCapability {
|
|
22
19
|
'@context': string;
|
|
23
20
|
id: string;
|
|
24
21
|
controller: string;
|
package/src/types/crud.ts
CHANGED
|
@@ -8,23 +8,23 @@ export type FindNextSignals = {
|
|
|
8
8
|
beacons: BeaconService[]
|
|
9
9
|
};
|
|
10
10
|
export type Metadata = {
|
|
11
|
-
|
|
11
|
+
didUpdate: DidUpdatePayload;
|
|
12
12
|
proofs?: string;
|
|
13
13
|
};
|
|
14
14
|
export type SignalSidecarData = Metadata;
|
|
15
|
-
export interface
|
|
15
|
+
export interface Sidecar {
|
|
16
16
|
did: string;
|
|
17
17
|
}
|
|
18
18
|
export type SignalsMetadata = { [signalId: string]: Metadata; };
|
|
19
|
-
export interface SingletonSidecar extends
|
|
19
|
+
export interface SingletonSidecar extends Sidecar {
|
|
20
20
|
signalsMetadata: SignalsMetadata;
|
|
21
21
|
}
|
|
22
|
-
export interface CIDAggregateSidecar extends
|
|
22
|
+
export interface CIDAggregateSidecar extends Sidecar {
|
|
23
23
|
initialDocument: DidDocument;
|
|
24
24
|
signalsMetadata: SignalsMetadata;
|
|
25
25
|
cidUpdates: Array<string>;
|
|
26
26
|
}
|
|
27
|
-
export interface SMTAggregateSidecar extends
|
|
27
|
+
export interface SMTAggregateSidecar extends Sidecar {
|
|
28
28
|
initialDocument: DidDocument;
|
|
29
29
|
signalsMetadata: SignalsMetadata;
|
|
30
30
|
smtProof: ProofBytes;
|
package/src/utils/appendix.ts
CHANGED
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
import { createHelia } from 'helia';
|
|
11
11
|
import { CID } from 'multiformats';
|
|
12
12
|
import { create as createDigest } from 'multiformats/hashes/digest';
|
|
13
|
-
import {
|
|
13
|
+
import { RootCapability } from '../interfaces/crud.js';
|
|
14
14
|
import { DidVerificationMethod } from './did-document.js';
|
|
15
15
|
|
|
16
16
|
export interface DidComponents {
|
|
@@ -97,7 +97,7 @@ export class Appendix {
|
|
|
97
97
|
|
|
98
98
|
|
|
99
99
|
/**
|
|
100
|
-
* Implements {@link https://dcdpr.github.io/did-btcr2/#derive-root-capability-from-
|
|
100
|
+
* Implements {@link https://dcdpr.github.io/did-btcr2/#derive-root-capability-from-didbtcr2-identifier | 9.4.1 Derive Root Capability from did:btcr2 Identifier }.
|
|
101
101
|
*
|
|
102
102
|
* The Derive Root Capability algorithm deterministically generates a ZCAP-LD root capability from a given did:btcr2
|
|
103
103
|
* identifier. Each root capability is unique to the identifier. This root capability is defined and understood by the
|
|
@@ -105,7 +105,7 @@ export class Appendix {
|
|
|
105
105
|
* document. It takes in a did:btcr2 identifier and returns a rootCapability object. It returns the root capability.
|
|
106
106
|
*
|
|
107
107
|
* @param {string} identifier The did-btcr2 identifier to derive the root capability from
|
|
108
|
-
* @returns {
|
|
108
|
+
* @returns {RootCapability} The root capability object
|
|
109
109
|
* @example Root capability for updating the DID document for
|
|
110
110
|
* did:btcr2:k1q0rnnwf657vuu8trztlczvlmphjgc6q598h79cm6sp7c4fgqh0fkc0vzd9u
|
|
111
111
|
* ```
|
|
@@ -117,9 +117,9 @@ export class Appendix {
|
|
|
117
117
|
* }
|
|
118
118
|
* ```
|
|
119
119
|
*/
|
|
120
|
-
public static deriveRootCapability(identifier: string):
|
|
120
|
+
public static deriveRootCapability(identifier: string): RootCapability {
|
|
121
121
|
// 1. Define rootCapability as an empty object.
|
|
122
|
-
const rootCapability = {} as
|
|
122
|
+
const rootCapability = {} as RootCapability;
|
|
123
123
|
|
|
124
124
|
// 2. Set rootCapability.@context to ‘https://w3id.org/zcap/v1’.
|
|
125
125
|
rootCapability['@context'] = W3C_ZCAP_V1;
|
|
@@ -148,7 +148,7 @@ export class Appendix {
|
|
|
148
148
|
* capability object.
|
|
149
149
|
*
|
|
150
150
|
* @param {string} capabilityId The root capability identifier to dereference.
|
|
151
|
-
* @returns {
|
|
151
|
+
* @returns {RootCapability} The root capability object.
|
|
152
152
|
* @example a didUpdatePayload with an invoked ZCAP-LD capability containing a patch defining how the DID document
|
|
153
153
|
* for did:btcr2:k1q0rnnwf657vuu8trztlczvlmphjgc6q598h79cm6sp7c4fgqh0fkc0vzd9u SHOULD be mutated.
|
|
154
154
|
* ```
|
|
@@ -174,16 +174,16 @@ export class Appendix {
|
|
|
174
174
|
* "cryptosuite": "schnorr-secp256k1-jcs-2025",
|
|
175
175
|
* "verificationMethod": "did:btcr2:k1q0rnnwf657vuu8trztlczvlmphjgc6q598h79cm6sp7c4fgqh0fkc0vzd9u#initialKey",
|
|
176
176
|
* "invocationTarget": "did:btcr2:k1q0rnnwf657vuu8trztlczvlmphjgc6q598h79cm6sp7c4fgqh0fkc0vzd9u",
|
|
177
|
-
* "capability": "urn:zcap:root:did%
|
|
177
|
+
* "capability": "urn:zcap:root:did%3Abtcr2%3Ak1q0rnnwf657vuu8trztlczvlmphjgc6q598h79cm6sp7c4fgqh0fkc0vzd9u",
|
|
178
178
|
* "capabilityAction": "Write",
|
|
179
179
|
* "proofPurpose": "assertionMethod",
|
|
180
180
|
* "proofValue": "z381yXYmxU8NudZ4HXY56DfMN6zfD8syvWcRXzT9xD9uYoQToo8QsXD7ahM3gXTzuay5WJbqTswt2BKaGWYn2hHhVFKJLXaDz"
|
|
181
181
|
* }
|
|
182
182
|
* }
|
|
183
183
|
*/
|
|
184
|
-
public static derefernceRootCapabilityIdentifier(capabilityId: string):
|
|
184
|
+
public static derefernceRootCapabilityIdentifier(capabilityId: string): RootCapability {
|
|
185
185
|
// 1. Set rootCapability to an empty object.
|
|
186
|
-
const rootCapability = {} as
|
|
186
|
+
const rootCapability = {} as RootCapability;
|
|
187
187
|
|
|
188
188
|
// 2. Set components to the result of capabilityId.split(":").
|
|
189
189
|
const [urn, zcap, root, did] = capabilityId.split(':') ?? [];
|
|
@@ -2,7 +2,7 @@ import { DidDocumentError, INVALID_DID_DOCUMENT } from '@did-btcr2/common';
|
|
|
2
2
|
import { BeaconService } from '../interfaces/ibeacon.js';
|
|
3
3
|
import { DidDocument, DidVerificationMethod } from './did-document.js';
|
|
4
4
|
|
|
5
|
-
export class
|
|
5
|
+
export class DidDocumentBuilder {
|
|
6
6
|
private document: Partial<DidDocument> = {};
|
|
7
7
|
|
|
8
8
|
constructor(initialDocument: Partial<DidDocument>) {
|
|
@@ -1,20 +1,23 @@
|
|
|
1
|
+
import { getNetwork } from '@did-btcr2/bitcoin';
|
|
1
2
|
import {
|
|
2
3
|
BTCR2_DID_DOCUMENT_CONTEXT,
|
|
3
|
-
IdentifierTypes,
|
|
4
4
|
DidDocumentError,
|
|
5
5
|
ID_PLACEHOLDER_VALUE,
|
|
6
|
+
IdentifierTypes,
|
|
6
7
|
INVALID_DID_DOCUMENT,
|
|
7
8
|
JSONObject,
|
|
9
|
+
KeyBytes,
|
|
8
10
|
Logger
|
|
9
11
|
} from '@did-btcr2/common';
|
|
10
|
-
import {
|
|
12
|
+
import { CompressedSecp256k1PublicKey } from '@did-btcr2/keypair';
|
|
13
|
+
import { DidService, DidDocument as IIDidDocument, DidVerificationMethod as IIDidVerificationMethod } from '@web5/dids';
|
|
11
14
|
import { BeaconService } from '../interfaces/ibeacon.js';
|
|
12
15
|
import { Appendix } from './appendix.js';
|
|
13
16
|
import { BeaconUtils } from './beacons.js';
|
|
14
17
|
import { Identifier } from './identifier.js';
|
|
15
18
|
|
|
16
19
|
export const BECH32M_CHARS = '';
|
|
17
|
-
export const
|
|
20
|
+
export const DID_REGEX = /did:btcr2:(x1[qpzry9x8gf2tvdw0s3jn54khce6mua7l]*)/g;
|
|
18
21
|
|
|
19
22
|
export type ExternalData = {
|
|
20
23
|
id: string,
|
|
@@ -120,6 +123,7 @@ export class DidDocument implements IDidDocument {
|
|
|
120
123
|
service: Array<BeaconService>;
|
|
121
124
|
|
|
122
125
|
constructor(document: IDidDocument) {
|
|
126
|
+
console.log('Constructing DidDocument with document:', document);
|
|
123
127
|
// Set the ID and ID type
|
|
124
128
|
const idType = document.id.includes('k1')
|
|
125
129
|
? IdentifierTypes.KEY
|
|
@@ -388,7 +392,7 @@ export class DidDocument implements IDidDocument {
|
|
|
388
392
|
* Validate the IntermediateDidDocument.
|
|
389
393
|
* @returns {boolean} True if the IntermediateDidDocument is valid.
|
|
390
394
|
*/
|
|
391
|
-
public validateIntermediate():
|
|
395
|
+
public validateIntermediate(): boolean {
|
|
392
396
|
// Validate the id
|
|
393
397
|
if(this.id !== ID_PLACEHOLDER_VALUE) {
|
|
394
398
|
throw new DidDocumentError('Invalid IntermediateDidDocument ID', INVALID_DID_DOCUMENT, this);
|
|
@@ -409,6 +413,8 @@ export class DidDocument implements IDidDocument {
|
|
|
409
413
|
// Return true if all validations pass
|
|
410
414
|
throw new DidDocumentError('Invalid IntermediateDidDocument assertionMethod', INVALID_DID_DOCUMENT, this);
|
|
411
415
|
}
|
|
416
|
+
|
|
417
|
+
return true;
|
|
412
418
|
}
|
|
413
419
|
|
|
414
420
|
/**
|
|
@@ -431,9 +437,30 @@ export class DidDocument implements IDidDocument {
|
|
|
431
437
|
* @extends {DidDocument}
|
|
432
438
|
*/
|
|
433
439
|
export class IntermediateDidDocument extends DidDocument {
|
|
434
|
-
constructor(document:
|
|
435
|
-
|
|
436
|
-
|
|
440
|
+
constructor(document: JSONObject) {
|
|
441
|
+
super(document as IDidDocument);
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
/**
|
|
445
|
+
* Convert the IntermediateDidDocument to a DidDocument by replacing the placeholder value with the provided DID.
|
|
446
|
+
* @param did The DID to replace the placeholder value in the document.
|
|
447
|
+
* @returns {DidDocument} A new DidDocument with the placeholder value replaced by the provided DID.
|
|
448
|
+
*/
|
|
449
|
+
public toDidDocument(did: string): DidDocument {
|
|
450
|
+
const stringThis = JSON.stringify(this).replaceAll(ID_PLACEHOLDER_VALUE, did);
|
|
451
|
+
const parseThis = JSON.parse(stringThis) as IDidDocument;
|
|
452
|
+
return new DidDocument(parseThis);
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
|
|
456
|
+
/**
|
|
457
|
+
* Create an IntermediateDidDocument from a DidDocument by replacing the DID with a placeholder value.
|
|
458
|
+
* @param {DidDocument} didDocument The DidDocument to convert.
|
|
459
|
+
* @returns {IntermediateDidDocument} The IntermediateDidDocument representation of the DidDocument.
|
|
460
|
+
*/
|
|
461
|
+
public static fromDidDocument(didDocument: DidDocument): IntermediateDidDocument {
|
|
462
|
+
const intermediateDocument = JSON.cloneReplace(didDocument, DID_REGEX, ID_PLACEHOLDER_VALUE) as IDidDocument;
|
|
463
|
+
return new IntermediateDidDocument(intermediateDocument);
|
|
437
464
|
}
|
|
438
465
|
|
|
439
466
|
/**
|
|
@@ -453,22 +480,51 @@ export class IntermediateDidDocument extends DidDocument {
|
|
|
453
480
|
}
|
|
454
481
|
|
|
455
482
|
/**
|
|
456
|
-
*
|
|
457
|
-
* @param
|
|
458
|
-
* @returns {
|
|
483
|
+
* Create a minimal IntermediateDidDocument from a public key.
|
|
484
|
+
* @param {KeyBytes} publicKey The public key in bytes format.
|
|
485
|
+
* @returns {IntermediateDidDocument} A new IntermediateDidDocument with the placeholder ID.
|
|
459
486
|
*/
|
|
460
|
-
public
|
|
461
|
-
const
|
|
462
|
-
const
|
|
463
|
-
|
|
487
|
+
public static fromPublicKey(publicKey: KeyBytes, network: string): IntermediateDidDocument {
|
|
488
|
+
const pk = new CompressedSecp256k1PublicKey(publicKey);
|
|
489
|
+
const id = ID_PLACEHOLDER_VALUE;
|
|
490
|
+
const service = BeaconUtils.generateBeaconService({
|
|
491
|
+
id : `${id}#key-0`,
|
|
492
|
+
publicKey : pk.compressed,
|
|
493
|
+
network : getNetwork(network),
|
|
494
|
+
addressType : 'p2pkh',
|
|
495
|
+
type : 'SingletonBeacon',
|
|
496
|
+
});
|
|
497
|
+
|
|
498
|
+
const relationships = {
|
|
499
|
+
authentication : [`${id}#key-0`],
|
|
500
|
+
assertionMethod : [`${id}#key-0`],
|
|
501
|
+
capabilityInvocation : [`${id}#key-0`],
|
|
502
|
+
capabilityDelegation : [`${id}#key-0`]
|
|
503
|
+
};
|
|
504
|
+
const verificationMethod = [
|
|
505
|
+
{
|
|
506
|
+
id : `${id}#key-0`,
|
|
507
|
+
type : 'Multikey',
|
|
508
|
+
controller : id,
|
|
509
|
+
publicKeyMultibase : pk.multibase.encoded,
|
|
510
|
+
}
|
|
511
|
+
];
|
|
512
|
+
|
|
513
|
+
return IntermediateDidDocument.create(verificationMethod, relationships, [service]);
|
|
464
514
|
}
|
|
465
515
|
|
|
466
516
|
/**
|
|
467
|
-
*
|
|
517
|
+
* Taken an object, convert it to an IntermediateDocuemnt and then to a DidDocument.
|
|
468
518
|
* @param {JSONObject} object The JSON object to convert.
|
|
469
519
|
* @returns {DidDocument} The created DidDocument.
|
|
470
520
|
*/
|
|
471
|
-
public static
|
|
472
|
-
return new IntermediateDidDocument(object as IDidDocument)
|
|
521
|
+
public static fromJSON(object: JSONObject): IntermediateDidDocument {
|
|
522
|
+
return new IntermediateDidDocument(object as IDidDocument);
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
export class Document {
|
|
527
|
+
public static isValid(didDocument: DidDocument | IntermediateDidDocument): boolean {
|
|
528
|
+
return new DidDocument(didDocument).validateIntermediate();
|
|
473
529
|
}
|
|
474
530
|
}
|
package/src/utils/identifier.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BitcoinNetworkNames, MethodError, IdentifierTypes, Bytes, INVALID_DID, METHOD_NOT_SUPPORTED } from '@did-btcr2/common';
|
|
2
|
-
import {
|
|
2
|
+
import { CompressedSecp256k1PublicKey, SchnorrKeyPair } from '@did-btcr2/keypair';
|
|
3
3
|
import { bech32m } from '@scure/base';
|
|
4
4
|
import { DidComponents } from './appendix.js';
|
|
5
5
|
|
|
@@ -16,7 +16,7 @@ import { DidComponents } from './appendix.js';
|
|
|
16
16
|
*/
|
|
17
17
|
export class Identifier {
|
|
18
18
|
/**
|
|
19
|
-
* Implements {@link https://dcdpr.github.io/did-btcr2/#
|
|
19
|
+
* Implements {@link https://dcdpr.github.io/did-btcr2/#didbtcr2-identifier-encoding | 3.2 did:btcr2 Identifier Encoding}.
|
|
20
20
|
*
|
|
21
21
|
* A did:btcr2 DID consists of a did:btcr2 prefix, followed by an id-bech32 value, which is a Bech32m encoding of:
|
|
22
22
|
* - the specification version;
|
|
@@ -61,7 +61,7 @@ export class Identifier {
|
|
|
61
61
|
// 5. If idType is “key” and genesisBytes is not a valid compressed secp256k1 public key, raise invalidDid error.
|
|
62
62
|
if (idType === 'KEY') {
|
|
63
63
|
try {
|
|
64
|
-
new
|
|
64
|
+
new CompressedSecp256k1PublicKey(genesisBytes);
|
|
65
65
|
} catch {
|
|
66
66
|
throw new MethodError(
|
|
67
67
|
'Expected "genesisBytes" to be a valid compressed secp256k1 public key',
|
|
@@ -125,7 +125,7 @@ export class Identifier {
|
|
|
125
125
|
}
|
|
126
126
|
|
|
127
127
|
/**
|
|
128
|
-
* Implements {@link https://dcdpr.github.io/did-btcr2/#
|
|
128
|
+
* Implements {@link https://dcdpr.github.io/did-btcr2/#didbtcr2-identifier-decoding | 3.3 did:btcr2 Identifier Decoding}.
|
|
129
129
|
* @param {string} identifier The BTCR2 DID to be parsed
|
|
130
130
|
* @returns {DidComponents} The parsed identifier components. See {@link DidComponents} for details.
|
|
131
131
|
* @throws {DidError} if an error occurs while parsing the identifier
|
|
@@ -248,7 +248,7 @@ export class Identifier {
|
|
|
248
248
|
// 19. If idType is “key” and genesisBytes is not a valid compressed secp256k1 public key, raise invalidDid error.
|
|
249
249
|
if (idType === 'KEY') {
|
|
250
250
|
try {
|
|
251
|
-
new
|
|
251
|
+
new CompressedSecp256k1PublicKey(genesisBytes);
|
|
252
252
|
} catch {
|
|
253
253
|
throw new MethodError(`Invalid genesisBytes: ${genesisBytes}`, INVALID_DID, { identifier });
|
|
254
254
|
}
|