@did-btcr2/method 0.13.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/LICENSE +373 -0
- package/README.md +7 -0
- package/dist/browser.js +2364 -0
- package/dist/browser.js.map +7 -0
- package/dist/browser.mjs +2364 -0
- package/dist/browser.mjs.map +7 -0
- package/dist/cjs/bitcoin/constants.js +20 -0
- package/dist/cjs/bitcoin/constants.js.map +1 -0
- package/dist/cjs/bitcoin/errors.js +11 -0
- package/dist/cjs/bitcoin/errors.js.map +1 -0
- package/dist/cjs/bitcoin/index.js +95 -0
- package/dist/cjs/bitcoin/index.js.map +1 -0
- package/dist/cjs/bitcoin/interface.js +2 -0
- package/dist/cjs/bitcoin/interface.js.map +1 -0
- package/dist/cjs/bitcoin/network.js +17 -0
- package/dist/cjs/bitcoin/network.js.map +1 -0
- package/dist/cjs/bitcoin/rest-client.js +289 -0
- package/dist/cjs/bitcoin/rest-client.js.map +1 -0
- package/dist/cjs/bitcoin/rpc-client.js +722 -0
- package/dist/cjs/bitcoin/rpc-client.js.map +1 -0
- package/dist/cjs/bitcoin/taproot.js +219 -0
- package/dist/cjs/bitcoin/taproot.js.map +1 -0
- package/dist/cjs/btcr2/beacon/aggregation/coordinator.js +120 -0
- package/dist/cjs/btcr2/beacon/aggregation/coordinator.js.map +1 -0
- package/dist/cjs/btcr2/beacon/aggregation/messages/advert.js +24 -0
- package/dist/cjs/btcr2/beacon/aggregation/messages/advert.js.map +1 -0
- package/dist/cjs/btcr2/beacon/aggregation/messages/base.js +37 -0
- package/dist/cjs/btcr2/beacon/aggregation/messages/base.js.map +1 -0
- package/dist/cjs/btcr2/beacon/aggregation/messages/cohort-set.js +25 -0
- package/dist/cjs/btcr2/beacon/aggregation/messages/cohort-set.js.map +1 -0
- package/dist/cjs/btcr2/beacon/aggregation/messages/keygen.js +8 -0
- package/dist/cjs/btcr2/beacon/aggregation/messages/keygen.js.map +1 -0
- package/dist/cjs/btcr2/beacon/aggregation/messages/opt-in.js +23 -0
- package/dist/cjs/btcr2/beacon/aggregation/messages/opt-in.js.map +1 -0
- package/dist/cjs/btcr2/beacon/aggregation/messages/sign.js +7 -0
- package/dist/cjs/btcr2/beacon/aggregation/messages/sign.js.map +1 -0
- package/dist/cjs/btcr2/beacon/aggregation/models/cohort/index.js +92 -0
- package/dist/cjs/btcr2/beacon/aggregation/models/cohort/index.js.map +1 -0
- package/dist/cjs/btcr2/beacon/aggregation/models/cohort/status.js +8 -0
- package/dist/cjs/btcr2/beacon/aggregation/models/cohort/status.js.map +1 -0
- package/dist/cjs/btcr2/beacon/aggregation/participant.js +2 -0
- package/dist/cjs/btcr2/beacon/aggregation/participant.js.map +1 -0
- package/dist/cjs/btcr2/beacon/aggregation/protocol/nostr.js +57 -0
- package/dist/cjs/btcr2/beacon/aggregation/protocol/nostr.js.map +1 -0
- package/dist/cjs/btcr2/beacon/aggregation/protocol/service.js +2 -0
- package/dist/cjs/btcr2/beacon/aggregation/protocol/service.js.map +1 -0
- package/dist/cjs/btcr2/beacon/cid-aggregate.js +116 -0
- package/dist/cjs/btcr2/beacon/cid-aggregate.js.map +1 -0
- package/dist/cjs/btcr2/beacon/factory.js +30 -0
- package/dist/cjs/btcr2/beacon/factory.js.map +1 -0
- package/dist/cjs/btcr2/beacon/singleton.js +220 -0
- package/dist/cjs/btcr2/beacon/singleton.js.map +1 -0
- package/dist/cjs/btcr2/beacon/smt-aggregate.js +126 -0
- package/dist/cjs/btcr2/beacon/smt-aggregate.js.map +1 -0
- package/dist/cjs/btcr2/crud/create.js +102 -0
- package/dist/cjs/btcr2/crud/create.js.map +1 -0
- package/dist/cjs/btcr2/crud/deactivate.js +14 -0
- package/dist/cjs/btcr2/crud/deactivate.js.map +1 -0
- package/dist/cjs/btcr2/crud/read.js +686 -0
- package/dist/cjs/btcr2/crud/read.js.map +1 -0
- package/dist/cjs/btcr2/crud/update.js +195 -0
- package/dist/cjs/btcr2/crud/update.js.map +1 -0
- package/dist/cjs/btcr2/key-manager/index.js +290 -0
- package/dist/cjs/btcr2/key-manager/index.js.map +1 -0
- package/dist/cjs/btcr2/key-manager/interface.js +2 -0
- package/dist/cjs/btcr2/key-manager/interface.js.map +1 -0
- package/dist/cjs/did-btcr2.js +222 -0
- package/dist/cjs/did-btcr2.js.map +1 -0
- package/dist/cjs/index.js +27 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/interfaces/beacon.js +41 -0
- package/dist/cjs/interfaces/beacon.js.map +1 -0
- package/dist/cjs/interfaces/crud.js +2 -0
- package/dist/cjs/interfaces/crud.js.map +1 -0
- package/dist/cjs/interfaces/ibeacon.js +2 -0
- package/dist/cjs/interfaces/ibeacon.js.map +1 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/types/bitcoin.js +62 -0
- package/dist/cjs/types/bitcoin.js.map +1 -0
- package/dist/cjs/types/crud.js +2 -0
- package/dist/cjs/types/crud.js.map +1 -0
- package/dist/cjs/utils/appendix.js +221 -0
- package/dist/cjs/utils/appendix.js.map +1 -0
- package/dist/cjs/utils/beacons.js +206 -0
- package/dist/cjs/utils/beacons.js.map +1 -0
- package/dist/cjs/utils/did-document-builder.js +61 -0
- package/dist/cjs/utils/did-document-builder.js.map +1 -0
- package/dist/cjs/utils/did-document.js +380 -0
- package/dist/cjs/utils/did-document.js.map +1 -0
- package/dist/cjs/utils/general.js +195 -0
- package/dist/cjs/utils/general.js.map +1 -0
- package/dist/cjs/utils/identifier.js +238 -0
- package/dist/cjs/utils/identifier.js.map +1 -0
- package/dist/esm/bitcoin/constants.js +20 -0
- package/dist/esm/bitcoin/constants.js.map +1 -0
- package/dist/esm/bitcoin/errors.js +11 -0
- package/dist/esm/bitcoin/errors.js.map +1 -0
- package/dist/esm/bitcoin/index.js +95 -0
- package/dist/esm/bitcoin/index.js.map +1 -0
- package/dist/esm/bitcoin/interface.js +2 -0
- package/dist/esm/bitcoin/interface.js.map +1 -0
- package/dist/esm/bitcoin/network.js +17 -0
- package/dist/esm/bitcoin/network.js.map +1 -0
- package/dist/esm/bitcoin/rest-client.js +289 -0
- package/dist/esm/bitcoin/rest-client.js.map +1 -0
- package/dist/esm/bitcoin/rpc-client.js +722 -0
- package/dist/esm/bitcoin/rpc-client.js.map +1 -0
- package/dist/esm/bitcoin/taproot.js +219 -0
- package/dist/esm/bitcoin/taproot.js.map +1 -0
- package/dist/esm/btcr2/beacon/aggregation/coordinator.js +120 -0
- package/dist/esm/btcr2/beacon/aggregation/coordinator.js.map +1 -0
- package/dist/esm/btcr2/beacon/aggregation/messages/advert.js +24 -0
- package/dist/esm/btcr2/beacon/aggregation/messages/advert.js.map +1 -0
- package/dist/esm/btcr2/beacon/aggregation/messages/base.js +37 -0
- package/dist/esm/btcr2/beacon/aggregation/messages/base.js.map +1 -0
- package/dist/esm/btcr2/beacon/aggregation/messages/cohort-set.js +25 -0
- package/dist/esm/btcr2/beacon/aggregation/messages/cohort-set.js.map +1 -0
- package/dist/esm/btcr2/beacon/aggregation/messages/keygen.js +8 -0
- package/dist/esm/btcr2/beacon/aggregation/messages/keygen.js.map +1 -0
- package/dist/esm/btcr2/beacon/aggregation/messages/opt-in.js +23 -0
- package/dist/esm/btcr2/beacon/aggregation/messages/opt-in.js.map +1 -0
- package/dist/esm/btcr2/beacon/aggregation/messages/sign.js +7 -0
- package/dist/esm/btcr2/beacon/aggregation/messages/sign.js.map +1 -0
- package/dist/esm/btcr2/beacon/aggregation/models/cohort/index.js +92 -0
- package/dist/esm/btcr2/beacon/aggregation/models/cohort/index.js.map +1 -0
- package/dist/esm/btcr2/beacon/aggregation/models/cohort/status.js +8 -0
- package/dist/esm/btcr2/beacon/aggregation/models/cohort/status.js.map +1 -0
- package/dist/esm/btcr2/beacon/aggregation/participant.js +2 -0
- package/dist/esm/btcr2/beacon/aggregation/participant.js.map +1 -0
- package/dist/esm/btcr2/beacon/aggregation/protocol/nostr.js +57 -0
- package/dist/esm/btcr2/beacon/aggregation/protocol/nostr.js.map +1 -0
- package/dist/esm/btcr2/beacon/aggregation/protocol/service.js +2 -0
- package/dist/esm/btcr2/beacon/aggregation/protocol/service.js.map +1 -0
- package/dist/esm/btcr2/beacon/cid-aggregate.js +116 -0
- package/dist/esm/btcr2/beacon/cid-aggregate.js.map +1 -0
- package/dist/esm/btcr2/beacon/factory.js +30 -0
- package/dist/esm/btcr2/beacon/factory.js.map +1 -0
- package/dist/esm/btcr2/beacon/singleton.js +220 -0
- package/dist/esm/btcr2/beacon/singleton.js.map +1 -0
- package/dist/esm/btcr2/beacon/smt-aggregate.js +126 -0
- package/dist/esm/btcr2/beacon/smt-aggregate.js.map +1 -0
- package/dist/esm/btcr2/crud/create.js +102 -0
- package/dist/esm/btcr2/crud/create.js.map +1 -0
- package/dist/esm/btcr2/crud/deactivate.js +14 -0
- package/dist/esm/btcr2/crud/deactivate.js.map +1 -0
- package/dist/esm/btcr2/crud/read.js +686 -0
- package/dist/esm/btcr2/crud/read.js.map +1 -0
- package/dist/esm/btcr2/crud/update.js +195 -0
- package/dist/esm/btcr2/crud/update.js.map +1 -0
- package/dist/esm/btcr2/key-manager/index.js +290 -0
- package/dist/esm/btcr2/key-manager/index.js.map +1 -0
- package/dist/esm/btcr2/key-manager/interface.js +2 -0
- package/dist/esm/btcr2/key-manager/interface.js.map +1 -0
- package/dist/esm/did-btcr2.js +222 -0
- package/dist/esm/did-btcr2.js.map +1 -0
- package/dist/esm/index.js +27 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/interfaces/beacon.js +41 -0
- package/dist/esm/interfaces/beacon.js.map +1 -0
- package/dist/esm/interfaces/crud.js +2 -0
- package/dist/esm/interfaces/crud.js.map +1 -0
- package/dist/esm/interfaces/ibeacon.js +2 -0
- package/dist/esm/interfaces/ibeacon.js.map +1 -0
- package/dist/esm/types/bitcoin.js +62 -0
- package/dist/esm/types/bitcoin.js.map +1 -0
- package/dist/esm/types/crud.js +2 -0
- package/dist/esm/types/crud.js.map +1 -0
- package/dist/esm/utils/appendix.js +221 -0
- package/dist/esm/utils/appendix.js.map +1 -0
- package/dist/esm/utils/beacons.js +206 -0
- package/dist/esm/utils/beacons.js.map +1 -0
- package/dist/esm/utils/did-document-builder.js +61 -0
- package/dist/esm/utils/did-document-builder.js.map +1 -0
- package/dist/esm/utils/did-document.js +380 -0
- package/dist/esm/utils/did-document.js.map +1 -0
- package/dist/esm/utils/general.js +195 -0
- package/dist/esm/utils/general.js.map +1 -0
- package/dist/esm/utils/identifier.js +238 -0
- package/dist/esm/utils/identifier.js.map +1 -0
- package/dist/types/bitcoin/constants.d.ts +19 -0
- package/dist/types/bitcoin/constants.d.ts.map +1 -0
- package/dist/types/bitcoin/errors.d.ts +5 -0
- package/dist/types/bitcoin/errors.d.ts.map +1 -0
- package/dist/types/bitcoin/index.d.ts +75 -0
- package/dist/types/bitcoin/index.d.ts.map +1 -0
- package/dist/types/bitcoin/interface.d.ts +86 -0
- package/dist/types/bitcoin/interface.d.ts.map +1 -0
- package/dist/types/bitcoin/network.d.ts +2 -0
- package/dist/types/bitcoin/network.d.ts.map +1 -0
- package/dist/types/bitcoin/rest-client.d.ts +268 -0
- package/dist/types/bitcoin/rest-client.d.ts.map +1 -0
- package/dist/types/bitcoin/rpc-client.d.ts +506 -0
- package/dist/types/bitcoin/rpc-client.d.ts.map +1 -0
- package/dist/types/bitcoin/taproot.d.ts +34 -0
- package/dist/types/bitcoin/taproot.d.ts.map +1 -0
- package/dist/types/btcr2/beacon/aggregation/coordinator.d.ts +74 -0
- package/dist/types/btcr2/beacon/aggregation/coordinator.d.ts.map +1 -0
- package/dist/types/btcr2/beacon/aggregation/messages/advert.d.ts +22 -0
- package/dist/types/btcr2/beacon/aggregation/messages/advert.d.ts.map +1 -0
- package/dist/types/btcr2/beacon/aggregation/messages/base.d.ts +36 -0
- package/dist/types/btcr2/beacon/aggregation/messages/base.d.ts.map +1 -0
- package/dist/types/btcr2/beacon/aggregation/messages/cohort-set.d.ts +23 -0
- package/dist/types/btcr2/beacon/aggregation/messages/cohort-set.d.ts.map +1 -0
- package/dist/types/btcr2/beacon/aggregation/messages/keygen.d.ts +6 -0
- package/dist/types/btcr2/beacon/aggregation/messages/keygen.d.ts.map +1 -0
- package/dist/types/btcr2/beacon/aggregation/messages/opt-in.d.ts +22 -0
- package/dist/types/btcr2/beacon/aggregation/messages/opt-in.d.ts.map +1 -0
- package/dist/types/btcr2/beacon/aggregation/messages/sign.d.ts +5 -0
- package/dist/types/btcr2/beacon/aggregation/messages/sign.d.ts.map +1 -0
- package/dist/types/btcr2/beacon/aggregation/models/cohort/index.d.ts +77 -0
- package/dist/types/btcr2/beacon/aggregation/models/cohort/index.d.ts.map +1 -0
- package/dist/types/btcr2/beacon/aggregation/models/cohort/status.d.ts +7 -0
- package/dist/types/btcr2/beacon/aggregation/models/cohort/status.d.ts.map +1 -0
- package/dist/types/btcr2/beacon/aggregation/participant.d.ts +1 -0
- package/dist/types/btcr2/beacon/aggregation/participant.d.ts.map +1 -0
- package/dist/types/btcr2/beacon/aggregation/protocol/nostr.d.ts +36 -0
- package/dist/types/btcr2/beacon/aggregation/protocol/nostr.d.ts.map +1 -0
- package/dist/types/btcr2/beacon/aggregation/protocol/service.d.ts +6 -0
- package/dist/types/btcr2/beacon/aggregation/protocol/service.d.ts.map +1 -0
- package/dist/types/btcr2/beacon/cid-aggregate.d.ts +103 -0
- package/dist/types/btcr2/beacon/cid-aggregate.d.ts.map +1 -0
- package/dist/types/btcr2/beacon/factory.d.ts +17 -0
- package/dist/types/btcr2/beacon/factory.d.ts.map +1 -0
- package/dist/types/btcr2/beacon/singleton.d.ts +93 -0
- package/dist/types/btcr2/beacon/singleton.d.ts.map +1 -0
- package/dist/types/btcr2/beacon/smt-aggregate.d.ts +112 -0
- package/dist/types/btcr2/beacon/smt-aggregate.d.ts.map +1 -0
- package/dist/types/btcr2/crud/create.d.ts +92 -0
- package/dist/types/btcr2/crud/create.d.ts.map +1 -0
- package/dist/types/btcr2/crud/deactivate.d.ts +13 -0
- package/dist/types/btcr2/crud/deactivate.d.ts.map +1 -0
- package/dist/types/btcr2/crud/read.d.ts +341 -0
- package/dist/types/btcr2/crud/read.d.ts.map +1 -0
- package/dist/types/btcr2/crud/update.d.ts +83 -0
- package/dist/types/btcr2/crud/update.d.ts.map +1 -0
- package/dist/types/btcr2/key-manager/index.d.ts +145 -0
- package/dist/types/btcr2/key-manager/index.d.ts.map +1 -0
- package/dist/types/btcr2/key-manager/interface.d.ts +113 -0
- package/dist/types/btcr2/key-manager/interface.d.ts.map +1 -0
- package/dist/types/did-btcr2.d.ts +117 -0
- package/dist/types/did-btcr2.d.ts.map +1 -0
- package/dist/types/index.d.ts +26 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/interfaces/beacon.d.ts +57 -0
- package/dist/types/interfaces/beacon.d.ts.map +1 -0
- package/dist/types/interfaces/crud.d.ts +35 -0
- package/dist/types/interfaces/crud.d.ts.map +1 -0
- package/dist/types/interfaces/ibeacon.d.ts +66 -0
- package/dist/types/interfaces/ibeacon.d.ts.map +1 -0
- package/dist/types/types/bitcoin.d.ts +827 -0
- package/dist/types/types/bitcoin.d.ts.map +1 -0
- package/dist/types/types/crud.d.ts +38 -0
- package/dist/types/types/crud.d.ts.map +1 -0
- package/dist/types/utils/appendix.d.ts +118 -0
- package/dist/types/utils/appendix.d.ts.map +1 -0
- package/dist/types/utils/beacons.d.ts +156 -0
- package/dist/types/utils/beacons.d.ts.map +1 -0
- package/dist/types/utils/did-document-builder.d.ts +13 -0
- package/dist/types/utils/did-document-builder.d.ts.map +1 -0
- package/dist/types/utils/did-document.d.ts +211 -0
- package/dist/types/utils/did-document.d.ts.map +1 -0
- package/dist/types/utils/general.d.ts +85 -0
- package/dist/types/utils/general.d.ts.map +1 -0
- package/dist/types/utils/identifier.d.ts +59 -0
- package/dist/types/utils/identifier.d.ts.map +1 -0
- package/package.json +137 -0
- package/src/bitcoin/constants.ts +19 -0
- package/src/bitcoin/errors.ts +10 -0
- package/src/bitcoin/index.ts +154 -0
- package/src/bitcoin/interface.ts +160 -0
- package/src/bitcoin/network.ts +17 -0
- package/src/bitcoin/rest-client.ts +415 -0
- package/src/bitcoin/rpc-client.ts +888 -0
- package/src/bitcoin/taproot.ts +237 -0
- package/src/btcr2/beacon/aggregation/coordinator.ts +135 -0
- package/src/btcr2/beacon/aggregation/messages/advert.ts +36 -0
- package/src/btcr2/beacon/aggregation/messages/base.ts +59 -0
- package/src/btcr2/beacon/aggregation/messages/cohort-set.ts +37 -0
- package/src/btcr2/beacon/aggregation/messages/keygen.ts +8 -0
- package/src/btcr2/beacon/aggregation/messages/opt-in.ts +35 -0
- package/src/btcr2/beacon/aggregation/messages/sign.ts +7 -0
- package/src/btcr2/beacon/aggregation/models/cohort/index.ts +112 -0
- package/src/btcr2/beacon/aggregation/models/cohort/status.ts +7 -0
- package/src/btcr2/beacon/aggregation/participant.ts +0 -0
- package/src/btcr2/beacon/aggregation/protocol/nostr.ts +81 -0
- package/src/btcr2/beacon/aggregation/protocol/service.ts +6 -0
- package/src/btcr2/beacon/cid-aggregate.ts +154 -0
- package/src/btcr2/beacon/factory.ts +36 -0
- package/src/btcr2/beacon/singleton.ts +257 -0
- package/src/btcr2/beacon/smt-aggregate.ts +136 -0
- package/src/btcr2/crud/create.ts +160 -0
- package/src/btcr2/crud/deactivate.ts +13 -0
- package/src/btcr2/crud/read.ts +946 -0
- package/src/btcr2/crud/update.ts +277 -0
- package/src/btcr2/key-manager/index.ts +364 -0
- package/src/btcr2/key-manager/interface.ts +129 -0
- package/src/canonicalize.d.ts +6 -0
- package/src/did-btcr2.ts +288 -0
- package/src/index.ts +34 -0
- package/src/interfaces/beacon.ts +68 -0
- package/src/interfaces/crud.ts +36 -0
- package/src/interfaces/ibeacon.ts +76 -0
- package/src/types/bitcoin.ts +1028 -0
- package/src/types/crud.ts +41 -0
- package/src/utils/appendix.ts +257 -0
- package/src/utils/beacons.ts +276 -0
- package/src/utils/did-document-builder.ts +73 -0
- package/src/utils/did-document.ts +474 -0
- package/src/utils/general.ts +204 -0
- package/src/utils/identifier.ts +276 -0
|
@@ -0,0 +1,474 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BTCR2_DID_DOCUMENT_CONTEXT,
|
|
3
|
+
Btcr2IdentifierTypes,
|
|
4
|
+
DidDocumentError,
|
|
5
|
+
ID_PLACEHOLDER_VALUE,
|
|
6
|
+
INVALID_DID_DOCUMENT,
|
|
7
|
+
JSONObject,
|
|
8
|
+
Logger
|
|
9
|
+
} from '@did-btcr2/common';
|
|
10
|
+
import { DidService, DidVerificationMethod, DidDocument as IDidDocument } from '@web5/dids';
|
|
11
|
+
import { BeaconService } from '../interfaces/ibeacon.js';
|
|
12
|
+
import { Btc1Appendix } from './appendix.js';
|
|
13
|
+
import { BeaconUtils } from './beacons.js';
|
|
14
|
+
import { Btc1Identifier } from './identifier.js';
|
|
15
|
+
|
|
16
|
+
export const BECH32M_CHARS = '';
|
|
17
|
+
export const BTC1_DID_REGEX = /did:btcr2:(x1[qpzry9x8gf2tvdw0s3jn54khce6mua7l]*)/g;
|
|
18
|
+
|
|
19
|
+
export type ExternalData = {
|
|
20
|
+
id: string,
|
|
21
|
+
verificationMethod: Array<Btc1VerificationMethod>,
|
|
22
|
+
authentication?: Array<string | Btc1VerificationMethod>,
|
|
23
|
+
assertionMethod?: Array<string | Btc1VerificationMethod>,
|
|
24
|
+
capabilityInvocation?: Array<string | Btc1VerificationMethod>,
|
|
25
|
+
capabilityDelegation?: Array<string | Btc1VerificationMethod>,
|
|
26
|
+
service: Array<BeaconService>
|
|
27
|
+
}
|
|
28
|
+
export type VerificationRelationships = {
|
|
29
|
+
authentication?: Array<string | Btc1VerificationMethod>;
|
|
30
|
+
assertionMethod?: Array<string | Btc1VerificationMethod>;
|
|
31
|
+
capabilityInvocation?: Array<string | Btc1VerificationMethod>;
|
|
32
|
+
capabilityDelegation?: Array<string | Btc1VerificationMethod>;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface IBtc1VerificationMethod extends DidVerificationMethod {
|
|
36
|
+
id: string;
|
|
37
|
+
type: string;
|
|
38
|
+
controller: string;
|
|
39
|
+
publicKeyMultibase: string;
|
|
40
|
+
secretKeyMultibase?: string | undefined;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* DID BTCR2 Verification Method extends the DidVerificationMethod class adding helper methods and properties
|
|
45
|
+
* @class Btc1VerificationMethod
|
|
46
|
+
* @type {Btc1VerificationMethod}
|
|
47
|
+
*
|
|
48
|
+
*/
|
|
49
|
+
export class Btc1VerificationMethod implements IBtc1VerificationMethod {
|
|
50
|
+
id: string;
|
|
51
|
+
type: string;
|
|
52
|
+
controller: string;
|
|
53
|
+
publicKeyMultibase: string;
|
|
54
|
+
secretKeyMultibase?: string | undefined;
|
|
55
|
+
|
|
56
|
+
constructor({ id, type, controller, publicKeyMultibase, secretKeyMultibase }: IBtc1VerificationMethod) {
|
|
57
|
+
this.id = id;
|
|
58
|
+
this.type = type;
|
|
59
|
+
this.controller = controller;
|
|
60
|
+
this.publicKeyMultibase = publicKeyMultibase;
|
|
61
|
+
this.secretKeyMultibase = secretKeyMultibase;
|
|
62
|
+
if(!secretKeyMultibase){
|
|
63
|
+
delete this.secretKeyMultibase;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// TODO: Add helper methods and properties
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* BTCR2 DID Document Interface
|
|
71
|
+
* @interface IBtc1DidDocument
|
|
72
|
+
* @type {IBtc1DidDocument}
|
|
73
|
+
* @extends {IDidDocument}
|
|
74
|
+
* @property {string} id - The identifier of the DID Document.
|
|
75
|
+
* @property {Array<string>} [controller] - The controller of the DID Document.
|
|
76
|
+
* @property {Array<string | JSONObject>} ['@context'] - The context of the DID Document.
|
|
77
|
+
* @property {Array<DidVerificationMethod>} verificationMethod - The verification methods of the DID Document.
|
|
78
|
+
* @property {Array<string | Btc1VerificationMethod>} [authentication] - The authentication methods of the DID Document.
|
|
79
|
+
* @property {Array<string | Btc1VerificationMethod>} [assertionMethod] - The assertion methods of the DID Document.
|
|
80
|
+
* @property {Array<string | Btc1VerificationMethod>} [capabilityInvocation] - The capability invocation methods of the DID Document.
|
|
81
|
+
* @property {Array<string | Btc1VerificationMethod>} [capabilityDelegation] - The capability delegation methods of the DID Document.
|
|
82
|
+
* @property {Array<BeaconService>} service - The services of the DID Document.
|
|
83
|
+
*/
|
|
84
|
+
export interface IBtc1DidDocument extends IDidDocument {
|
|
85
|
+
id: string;
|
|
86
|
+
controller?: Array<string>;
|
|
87
|
+
'@context'?: Array<string | JSONObject>;
|
|
88
|
+
verificationMethod: Array<Btc1VerificationMethod>;
|
|
89
|
+
authentication?: Array<string | Btc1VerificationMethod>;
|
|
90
|
+
assertionMethod?: Array<string | Btc1VerificationMethod>;
|
|
91
|
+
capabilityInvocation?: Array<string | Btc1VerificationMethod>;
|
|
92
|
+
capabilityDelegation?: Array<string | Btc1VerificationMethod>;
|
|
93
|
+
service: Array<BeaconService>;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* BTCR2 DID Document extends the DidDocument class adding helper methods and properties
|
|
98
|
+
* @class Btc1DidDocument
|
|
99
|
+
* @type {Btc1DidDocument}
|
|
100
|
+
* @implements {IBtc1DidDocument}
|
|
101
|
+
* @property {string} id - The identifier of the DID Document.
|
|
102
|
+
* @property {Array<string>} [controller] - The controller of the DID Document.
|
|
103
|
+
* @property {Array<string | JSONObject>} ['@context'] - The context of the DID Document.
|
|
104
|
+
* @property {Array<DidVerificationMethod>} verificationMethod - The verification methods of the DID Document.
|
|
105
|
+
* @property {Array<string | Btc1VerificationMethod>} [authentication] - The authentication methods of the DID Document.
|
|
106
|
+
* @property {Array<string | Btc1VerificationMethod>} [assertionMethod] - The assertion methods of the DID Document.
|
|
107
|
+
* @property {Array<string | Btc1VerificationMethod>} [capabilityInvocation] - The capability invocation methods of the DID Document.
|
|
108
|
+
* @property {Array<string | Btc1VerificationMethod>} [capabilityDelegation] - The capability delegation methods of the DID Document.
|
|
109
|
+
* @property {Array<BeaconService>} service - The services of the DID Document.
|
|
110
|
+
*/
|
|
111
|
+
export class Btc1DidDocument implements IBtc1DidDocument {
|
|
112
|
+
id: string;
|
|
113
|
+
controller?: Array<string>;
|
|
114
|
+
'@context'?: Array<string | JSONObject> = BTCR2_DID_DOCUMENT_CONTEXT;
|
|
115
|
+
verificationMethod: Array<Btc1VerificationMethod>;
|
|
116
|
+
authentication?: Array<string | Btc1VerificationMethod>;
|
|
117
|
+
assertionMethod?: Array<string | Btc1VerificationMethod>;
|
|
118
|
+
capabilityInvocation?: Array<string | Btc1VerificationMethod>;
|
|
119
|
+
capabilityDelegation?: Array<string | Btc1VerificationMethod>;
|
|
120
|
+
service: Array<BeaconService>;
|
|
121
|
+
|
|
122
|
+
constructor(document: IBtc1DidDocument) {
|
|
123
|
+
// Set the ID and ID type
|
|
124
|
+
const idType = document.id.includes('k1')
|
|
125
|
+
? Btcr2IdentifierTypes.KEY
|
|
126
|
+
: Btcr2IdentifierTypes.EXTERNAL;
|
|
127
|
+
|
|
128
|
+
// Validate ID and parts for non-intermediate
|
|
129
|
+
const isIntermediate = document.id === ID_PLACEHOLDER_VALUE;
|
|
130
|
+
// Deconstruct the document parts for validation
|
|
131
|
+
const { id, controller, verificationMethod: vm, service } = document;
|
|
132
|
+
if (!isIntermediate) {
|
|
133
|
+
if (!Btc1DidDocument.isValidId(id)) {
|
|
134
|
+
throw new DidDocumentError(`Invalid id: ${id}`, INVALID_DID_DOCUMENT, document);
|
|
135
|
+
}
|
|
136
|
+
if(!Btc1DidDocument.isValidController(controller ?? [id])) {
|
|
137
|
+
throw new DidDocumentError(`Invalid controller: ${controller}`, INVALID_DID_DOCUMENT, document);
|
|
138
|
+
}
|
|
139
|
+
if (!Btc1DidDocument.isValidVerificationMethods(vm)) {
|
|
140
|
+
throw new DidDocumentError('Invalid verificationMethod: ' + vm, INVALID_DID_DOCUMENT, document);
|
|
141
|
+
}
|
|
142
|
+
if (!Btc1DidDocument.isValidServices(service)) {
|
|
143
|
+
throw new DidDocumentError('Invalid service: ' + service, INVALID_DID_DOCUMENT, document);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Set core properties
|
|
148
|
+
this.id = document.id;
|
|
149
|
+
this.verificationMethod = document.verificationMethod;
|
|
150
|
+
this.service = document.service;
|
|
151
|
+
this['@context'] = document['@context'] || BTCR2_DID_DOCUMENT_CONTEXT;
|
|
152
|
+
this.controller = document.controller || [this.id];
|
|
153
|
+
|
|
154
|
+
// Relationships logic based on idType
|
|
155
|
+
if (idType === Btcr2IdentifierTypes.KEY) {
|
|
156
|
+
// auto-generate #initialKey if missing
|
|
157
|
+
const keyRef = `${this.id}#initialKey`;
|
|
158
|
+
this.authentication = document.authentication || [keyRef];
|
|
159
|
+
this.assertionMethod = document.assertionMethod || [keyRef];
|
|
160
|
+
this.capabilityInvocation = document.capabilityInvocation || [keyRef];
|
|
161
|
+
this.capabilityDelegation = document.capabilityDelegation || [keyRef];
|
|
162
|
+
} else {
|
|
163
|
+
// EXTERNAL: use provided arrays, must be defined
|
|
164
|
+
this.authentication = document.authentication;
|
|
165
|
+
this.assertionMethod = document.assertionMethod;
|
|
166
|
+
this.capabilityInvocation = document.capabilityInvocation;
|
|
167
|
+
this.capabilityDelegation = document.capabilityDelegation;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Sanitize the DID Document
|
|
171
|
+
Btc1DidDocument.sanitize(this);
|
|
172
|
+
// If the DID Document is not an intermediateDocument, validate it
|
|
173
|
+
if (!isIntermediate) {
|
|
174
|
+
Btc1DidDocument.validate(this);
|
|
175
|
+
} else {
|
|
176
|
+
this.validateIntermediate();
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Convert the Btc1DidDocument to a JSON object.
|
|
182
|
+
* @returns {JSONObject} The JSON representation of the Btc1DidDocument.
|
|
183
|
+
*/
|
|
184
|
+
public json(): JSONObject {
|
|
185
|
+
return {
|
|
186
|
+
id : this.id,
|
|
187
|
+
controller : this.controller,
|
|
188
|
+
'@context' : this['@context'],
|
|
189
|
+
verificationMethod : this.verificationMethod,
|
|
190
|
+
authentication : this.authentication,
|
|
191
|
+
assertionMethod : this.assertionMethod,
|
|
192
|
+
capabilityInvocation : this.capabilityInvocation,
|
|
193
|
+
capabilityDelegation : this.capabilityDelegation,
|
|
194
|
+
service : this.service
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Create a minimal Btc1DidDocument from "k1" btcr2 identifier.
|
|
200
|
+
* @param {string} publicKeyMultibase The public key in multibase format.
|
|
201
|
+
* @param {Array<BeaconService>} service The beacon services to be included in the document.
|
|
202
|
+
* @returns {Btc1DidDocument} A new Btc1DidDocument with the placeholder ID.
|
|
203
|
+
*/
|
|
204
|
+
public static fromKeyIdentifier(
|
|
205
|
+
id: string,
|
|
206
|
+
publicKeyMultibase: string,
|
|
207
|
+
service: Array<BeaconService>
|
|
208
|
+
): Btc1DidDocument {
|
|
209
|
+
// Ensure the ID is in the correct format
|
|
210
|
+
id = id.includes('#') ? id : `${id}#initialKey`;
|
|
211
|
+
// Create the verification method and the Btc1DidDocument
|
|
212
|
+
const document = {
|
|
213
|
+
id,
|
|
214
|
+
verificationMethod : [
|
|
215
|
+
new Btc1VerificationMethod({
|
|
216
|
+
id,
|
|
217
|
+
type : 'Multikey',
|
|
218
|
+
controller : id,
|
|
219
|
+
publicKeyMultibase
|
|
220
|
+
})
|
|
221
|
+
],
|
|
222
|
+
service
|
|
223
|
+
} as IBtc1DidDocument;
|
|
224
|
+
return new Btc1DidDocument(document);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Create a Btc1DidDocument from "x1" btcr2 identifier.
|
|
229
|
+
* @param {ExternalData} data The verification methods of the DID Document.
|
|
230
|
+
* @returns {Btc1DidDocument} A new Btc1DidDocument.
|
|
231
|
+
*/
|
|
232
|
+
public static fromExternalIdentifier(data: ExternalData): Btc1DidDocument {
|
|
233
|
+
return new Btc1DidDocument(data as IBtc1DidDocument);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Sanitize the DID Document by removing undefined values
|
|
239
|
+
* @returns {Btc1DidDocument} The sanitized DID Document
|
|
240
|
+
*/
|
|
241
|
+
public static sanitize(doc: Btc1DidDocument): Btc1DidDocument {
|
|
242
|
+
for (const key of Object.keys(doc)) {
|
|
243
|
+
if (doc[key as keyof Btc1DidDocument] === undefined) {
|
|
244
|
+
delete doc[key as keyof Btc1DidDocument];
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
return doc;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Validates a Btc1DidDocument by breaking it into modular validation methods.
|
|
252
|
+
* @param {Btc1DidDocument} didDocument The DID document to validate.
|
|
253
|
+
* @returns {boolean} True if the DID document is valid.
|
|
254
|
+
* @throws {DidDocumentError} If any validation check fails.
|
|
255
|
+
*/
|
|
256
|
+
public static isValid(didDocument: Btc1DidDocument): boolean {
|
|
257
|
+
if (!this.isValidContext(didDocument?.['@context'])) {
|
|
258
|
+
throw new DidDocumentError('Invalid "@context"', INVALID_DID_DOCUMENT, didDocument);
|
|
259
|
+
}
|
|
260
|
+
if (!this.isValidId(didDocument?.id)) {
|
|
261
|
+
throw new DidDocumentError('Invalid "id"', INVALID_DID_DOCUMENT, didDocument);
|
|
262
|
+
}
|
|
263
|
+
if (!this.isValidVerificationMethods(didDocument?.verificationMethod)) {
|
|
264
|
+
throw new DidDocumentError('Invalid "verificationMethod"', INVALID_DID_DOCUMENT, didDocument);
|
|
265
|
+
}
|
|
266
|
+
if (!this.isValidServices(didDocument?.service)) {
|
|
267
|
+
throw new DidDocumentError('Invalid "service"', INVALID_DID_DOCUMENT, didDocument);
|
|
268
|
+
}
|
|
269
|
+
if (!this.isValidVerificationRelationships(didDocument)) {
|
|
270
|
+
throw new DidDocumentError('Invalid verification relationships', INVALID_DID_DOCUMENT, didDocument);
|
|
271
|
+
}
|
|
272
|
+
return true;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Validates that "@context" exists and includes correct values.
|
|
277
|
+
* @private
|
|
278
|
+
* @param {Btc1DidDocument['@context']} context The context to validate.
|
|
279
|
+
* @returns {boolean} True if the context is valid.
|
|
280
|
+
*/
|
|
281
|
+
private static isValidContext(context: Btc1DidDocument['@context']): boolean {
|
|
282
|
+
if(!context) return false;
|
|
283
|
+
if(!Array.isArray(context)) return false;
|
|
284
|
+
if(!context.every(ctx => typeof ctx === 'string' && BTCR2_DID_DOCUMENT_CONTEXT.includes(ctx))) return false;
|
|
285
|
+
return true;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Validates that the DID Document has a valid id.
|
|
290
|
+
* @private
|
|
291
|
+
* @param {string} id The id to validate.
|
|
292
|
+
* @returns {boolean} True if the id is valid.
|
|
293
|
+
*/
|
|
294
|
+
private static isValidId(id: string): boolean {
|
|
295
|
+
try {
|
|
296
|
+
Btc1Identifier.decode(id);
|
|
297
|
+
return true;
|
|
298
|
+
} catch (error: any) {
|
|
299
|
+
Logger.error('Invalid DID Document ID', error);
|
|
300
|
+
return false;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* Validates that the controller exists and is correctly formatted.
|
|
306
|
+
* @param {Array<string>} controller The controller to validate.
|
|
307
|
+
* @returns {boolean} True if the controller is valid.
|
|
308
|
+
*/
|
|
309
|
+
private static isValidController(controller: Array<string>): boolean {
|
|
310
|
+
if(!controller) return false;
|
|
311
|
+
if(!Array.isArray(controller)) return false;
|
|
312
|
+
if(!controller.every(c => typeof c === 'string')) return false;
|
|
313
|
+
return true;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Validates that verification methods exist and are correctly formatted.
|
|
318
|
+
* @private
|
|
319
|
+
* @param {DidVerificationMethod[]} verificationMethod The verification methods to validate.
|
|
320
|
+
* @returns {boolean} True if the verification methods are valid.
|
|
321
|
+
*/
|
|
322
|
+
private static isValidVerificationMethods(verificationMethod: DidVerificationMethod[]): boolean {
|
|
323
|
+
return Array.isArray(verificationMethod) && verificationMethod.every(Btc1Appendix.isDidVerificationMethod);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* Validates that the DID Document has valid services.
|
|
328
|
+
* @private
|
|
329
|
+
* @param {DidService[]} service The services to validate.
|
|
330
|
+
* @returns {boolean} True if the services are valid.
|
|
331
|
+
*/
|
|
332
|
+
private static isValidServices(service: DidService[]): boolean {
|
|
333
|
+
return Array.isArray(service) && service.every(BeaconUtils.isBeaconService);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* Validates verification relationships (authentication, assertionMethod, capabilityInvocation, capabilityDelegation).
|
|
338
|
+
* @private
|
|
339
|
+
* @param {Btc1DidDocument} didDocument The DID Document to validate.
|
|
340
|
+
* @returns {boolean} True if the verification relationships are valid.
|
|
341
|
+
*/
|
|
342
|
+
public static isValidVerificationRelationships(didDocument: Btc1DidDocument): boolean {
|
|
343
|
+
// Define the available verification relationships
|
|
344
|
+
const possibleVerificationRelationships: (keyof Btc1DidDocument)[] = [
|
|
345
|
+
'authentication',
|
|
346
|
+
'assertionMethod',
|
|
347
|
+
'capabilityInvocation',
|
|
348
|
+
'capabilityDelegation'
|
|
349
|
+
];
|
|
350
|
+
|
|
351
|
+
// Get the DID Document keys
|
|
352
|
+
const verificationRelationships = Object.keys(didDocument) as Array<keyof Btc1DidDocument>;
|
|
353
|
+
|
|
354
|
+
// Filter the DID Document keys to only those that are in the available verification relationships
|
|
355
|
+
const availableVerificationRelationships = possibleVerificationRelationships.filter(
|
|
356
|
+
key => verificationRelationships.includes(key as keyof Btc1DidDocument)
|
|
357
|
+
) as (keyof Btc1DidDocument)[];
|
|
358
|
+
|
|
359
|
+
// Check if all available verification relationships are valid
|
|
360
|
+
return availableVerificationRelationships.every((key) =>
|
|
361
|
+
// Check if the key exists in the DID Document
|
|
362
|
+
didDocument[key] &&
|
|
363
|
+
// Check if the key is an array
|
|
364
|
+
Array.isArray(didDocument[key]) &&
|
|
365
|
+
// Check that every value in the array is a string or DidVerificationMethod
|
|
366
|
+
didDocument[key].every(
|
|
367
|
+
entry => typeof entry === 'string' || Btc1Appendix.isDidVerificationMethod(entry)
|
|
368
|
+
));
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
/**
|
|
372
|
+
* Validate the DID Document
|
|
373
|
+
* @returns {Btc1DidDocument} Validated DID Document.
|
|
374
|
+
* @throws {DidDocumentError} If the DID Document is invalid.
|
|
375
|
+
*/
|
|
376
|
+
public static validate(didDocument: Btc1DidDocument | IntermediateDidDocument): Btc1DidDocument {
|
|
377
|
+
// Validate the DID Document
|
|
378
|
+
if (didDocument.id === ID_PLACEHOLDER_VALUE) {
|
|
379
|
+
(didDocument as IntermediateDidDocument).validateIntermediate();
|
|
380
|
+
} else {
|
|
381
|
+
Btc1DidDocument.isValid(didDocument);
|
|
382
|
+
}
|
|
383
|
+
// Return the DID Document
|
|
384
|
+
return didDocument;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
/**
|
|
388
|
+
* Validate the IntermediateDidDocument.
|
|
389
|
+
* @returns {boolean} True if the IntermediateDidDocument is valid.
|
|
390
|
+
*/
|
|
391
|
+
public validateIntermediate(): void {
|
|
392
|
+
// Validate the id
|
|
393
|
+
if(this.id !== ID_PLACEHOLDER_VALUE) {
|
|
394
|
+
throw new DidDocumentError('Invalid IntermediateDidDocument ID', INVALID_DID_DOCUMENT, this);
|
|
395
|
+
}
|
|
396
|
+
// Validate the controller
|
|
397
|
+
if(!this.controller?.every(c => c === ID_PLACEHOLDER_VALUE)) {
|
|
398
|
+
throw new DidDocumentError('Invalid IntermediateDidDocument controller', INVALID_DID_DOCUMENT, this);
|
|
399
|
+
}
|
|
400
|
+
// Validate the verificationMethod
|
|
401
|
+
if(!this.verificationMethod.every(vm => vm.id.includes(ID_PLACEHOLDER_VALUE) && vm.controller === ID_PLACEHOLDER_VALUE)) {
|
|
402
|
+
throw new DidDocumentError('Invalid IntermediateDidDocument verificationMethod', INVALID_DID_DOCUMENT, this);
|
|
403
|
+
}
|
|
404
|
+
// Validate the service
|
|
405
|
+
if(!this.service.every(svc => svc.id.includes(ID_PLACEHOLDER_VALUE))) {
|
|
406
|
+
throw new DidDocumentError('Invalid IntermediateDidDocument service', INVALID_DID_DOCUMENT, this);
|
|
407
|
+
}
|
|
408
|
+
if(!Btc1DidDocument.isValidVerificationRelationships(this)) {
|
|
409
|
+
// Return true if all validations pass
|
|
410
|
+
throw new DidDocumentError('Invalid IntermediateDidDocument assertionMethod', INVALID_DID_DOCUMENT, this);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
/**
|
|
415
|
+
* Convert the Btc1DidDocument to an IntermediateDidDocument.
|
|
416
|
+
* @returns {IntermediateDidDocument} The IntermediateDidDocument representation of the Btc1DidDocument.
|
|
417
|
+
*/
|
|
418
|
+
public toIntermediate(): IntermediateDidDocument {
|
|
419
|
+
if(this.id.includes('k1')) {
|
|
420
|
+
throw new DidDocumentError('Cannot convert a key identifier to an intermediate document', INVALID_DID_DOCUMENT, this);
|
|
421
|
+
}
|
|
422
|
+
return new IntermediateDidDocument(this);
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
/**
|
|
427
|
+
* IntermediateDidDocument extends the Btc1DidDocument class for creating and managing intermediate DID documents.
|
|
428
|
+
* This class is used to create a minimal DID document with a placeholder ID.
|
|
429
|
+
* It is used in the process of creating a new DID document.
|
|
430
|
+
* @class IntermediateDidDocument
|
|
431
|
+
* @extends {Btc1DidDocument}
|
|
432
|
+
*/
|
|
433
|
+
export class IntermediateDidDocument extends Btc1DidDocument {
|
|
434
|
+
constructor(document: IBtc1DidDocument) {
|
|
435
|
+
const intermediateDocument = JSON.cloneReplace(document, BTC1_DID_REGEX, ID_PLACEHOLDER_VALUE) as IBtc1DidDocument;
|
|
436
|
+
super(intermediateDocument);
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
/**
|
|
440
|
+
* Create a minimal IntermediateDidDocument with a placeholder ID.
|
|
441
|
+
* @param {Array<Btc1VerificationMethod>} verificationMethod The public key in multibase format.
|
|
442
|
+
* @param {VerificationRelationships} relationships The public key in multibase format.
|
|
443
|
+
* @param {Array<BeaconService>} service The service to be included in the document.
|
|
444
|
+
* @returns {IntermediateDidDocument} A new IntermediateDidDocument with the placeholder ID.
|
|
445
|
+
*/
|
|
446
|
+
public static create(
|
|
447
|
+
verificationMethod: Array<Btc1VerificationMethod>,
|
|
448
|
+
relationships: VerificationRelationships,
|
|
449
|
+
service: Array<BeaconService>
|
|
450
|
+
): IntermediateDidDocument {
|
|
451
|
+
const id = ID_PLACEHOLDER_VALUE;
|
|
452
|
+
return new IntermediateDidDocument({ id, ...relationships, verificationMethod, service, });
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
/**
|
|
456
|
+
* Convert the IntermediateDidDocument to a Btc1DidDocument by replacing the placeholder value with the provided DID.
|
|
457
|
+
* @param did The DID to replace the placeholder value in the document.
|
|
458
|
+
* @returns {Btc1DidDocument} A new Btc1DidDocument with the placeholder value replaced by the provided DID.
|
|
459
|
+
*/
|
|
460
|
+
public toBtc1DidDocument(did: string): Btc1DidDocument {
|
|
461
|
+
const stringThis = JSON.stringify(this).replaceAll(ID_PLACEHOLDER_VALUE, did);
|
|
462
|
+
const parseThis = JSON.parse(stringThis) as IBtc1DidDocument;
|
|
463
|
+
return new Btc1DidDocument(parseThis);
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
/**
|
|
467
|
+
* Create a Btc1DidDocument from a JSON object.
|
|
468
|
+
* @param {JSONObject} object The JSON object to convert.
|
|
469
|
+
* @returns {Btc1DidDocument} The created Btc1DidDocument.
|
|
470
|
+
*/
|
|
471
|
+
public static from(object: JSONObject): Btc1DidDocument {
|
|
472
|
+
return new IntermediateDidDocument(object as IBtc1DidDocument).toBtc1DidDocument(object.id as string);
|
|
473
|
+
}
|
|
474
|
+
}
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import { KeyBytes, BIP340_PUBLIC_KEY_MULTIBASE_PREFIX, HdWallet } from '@did-btcr2/common';
|
|
2
|
+
import { sha256 } from '@noble/hashes/sha2';
|
|
3
|
+
import { CURVE, getPublicKey, utils } from '@noble/secp256k1';
|
|
4
|
+
import { HDKey } from '@scure/bip32';
|
|
5
|
+
import { generateMnemonic, mnemonicToSeed } from '@scure/bip39';
|
|
6
|
+
import { wordlist } from '@scure/bip39/wordlists/english';
|
|
7
|
+
import { base58btc } from 'multiformats/bases/base58';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Static class of general utility functions for the did-btcr2 spec implementation
|
|
11
|
+
* @class GeneralUtils
|
|
12
|
+
* @type {GeneralUtils}
|
|
13
|
+
*/
|
|
14
|
+
export class GeneralUtils {
|
|
15
|
+
/**
|
|
16
|
+
* Helper function to encode a secp256k1 key in SchnorrSecp256k1 Multikey Format
|
|
17
|
+
* @param {KeyBytes} xOnlyKeyBytes
|
|
18
|
+
* @returns {PublicKeyMultibase}
|
|
19
|
+
*/
|
|
20
|
+
public static encode(xOnlyKeyBytes: KeyBytes): string {
|
|
21
|
+
if (xOnlyKeyBytes.length !== 32) {
|
|
22
|
+
throw new Error('x-only public key must be 32 bytes');
|
|
23
|
+
}
|
|
24
|
+
const prefix = Array.from(BIP340_PUBLIC_KEY_MULTIBASE_PREFIX);
|
|
25
|
+
const x = Array.from(xOnlyKeyBytes);
|
|
26
|
+
// Set the prefix and the public key bytes
|
|
27
|
+
const multikeyBytes = new Uint8Array([...prefix, ...x]);
|
|
28
|
+
// Encode the public key as a multibase base58btc string
|
|
29
|
+
return base58btc.encode(multikeyBytes);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Converts a bigint to a buffer
|
|
34
|
+
* @param {bigint} value The bigint to convert
|
|
35
|
+
* @returns {Buffer} The buffer representation of the bigint
|
|
36
|
+
*/
|
|
37
|
+
static bigintToBuffer(value: bigint): Buffer {
|
|
38
|
+
const hex = value.toString(16).padStart(64, '0');
|
|
39
|
+
return Buffer.fromHex(hex);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Generates a new mnemonic phrase and HD wallet
|
|
44
|
+
* @returns {HdWallet} Promise resolving to a new hdwallet object w/ mnemonic and hdkey
|
|
45
|
+
* @throws {Error} if the public key bytes cannot be derived
|
|
46
|
+
*/
|
|
47
|
+
static async generateHdWallet(): Promise<HdWallet> {
|
|
48
|
+
// Generate random mnemonic phrase.
|
|
49
|
+
const mnemonic = generateMnemonic(wordlist, 128);
|
|
50
|
+
// Generate seed from random mnemonic phrase.
|
|
51
|
+
const seed = await mnemonicToSeed(mnemonic);
|
|
52
|
+
// Generate HDKey from seed.
|
|
53
|
+
const hdkey = HDKey.fromMasterSeed(seed);
|
|
54
|
+
// Ensure HDKey returns valid
|
|
55
|
+
if (!hdkey) {
|
|
56
|
+
throw new Error('Failed to derive hd wallet');
|
|
57
|
+
}
|
|
58
|
+
return { mnemonic, hdkey };
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
static generateCompressedSecp256k1KeyPair(){
|
|
62
|
+
const privateKey = utils.randomPrivateKey();
|
|
63
|
+
if(!utils.isValidPrivateKey(privateKey)) {
|
|
64
|
+
throw new Error('Invalid private key');
|
|
65
|
+
}
|
|
66
|
+
return { privateKey, publicKey: getPublicKey(privateKey, true) };
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Recovers an HDKey from a mnemonic phrase
|
|
71
|
+
* @param {string} mnemonic The mnemonic phrase to recover the HDKey from
|
|
72
|
+
* @param {Uint8Array} seed Optional seed to recover the HDKey from
|
|
73
|
+
* @returns {HDKey} Promise resolving to the recovered HDKey
|
|
74
|
+
* @throws Error if the HDKey cannot be recovered
|
|
75
|
+
*/
|
|
76
|
+
static async recoverHdWallet(mnemonic: string, seed?: Uint8Array): Promise<HDKey> {
|
|
77
|
+
seed ??= await mnemonicToSeed(mnemonic);
|
|
78
|
+
// Generate HDKey from seed.
|
|
79
|
+
const hdkey = HDKey.fromMasterSeed(seed);
|
|
80
|
+
// Ensure HDKey returns valid
|
|
81
|
+
if (!hdkey) {
|
|
82
|
+
throw new Error('Failed to recover hdkey');
|
|
83
|
+
}
|
|
84
|
+
// Return the HDKey
|
|
85
|
+
return hdkey;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Recovers a secp256k1 privateKey from its original entropy
|
|
90
|
+
* @param {Uint8Array} xorEntropy The original entropy to recover the privateKey from
|
|
91
|
+
* @param {Uint8Array} salt The salt used to tweak the privateKey
|
|
92
|
+
* @returns {Uint8Array} The recovered privateKey
|
|
93
|
+
* @throws {Error} if the privateKey cannot be recovered
|
|
94
|
+
*/
|
|
95
|
+
static recoverTweakedRawPrivateKey(xorEntropy: Uint8Array, salt: Uint8Array): Uint8Array {
|
|
96
|
+
// If entropy is not 32 bytes, hash it to get a deterministic 32-byte private key
|
|
97
|
+
if (xorEntropy.length !== 32) {
|
|
98
|
+
xorEntropy = sha256(xorEntropy);
|
|
99
|
+
}
|
|
100
|
+
const entropy = this.XNOR(xorEntropy, salt);
|
|
101
|
+
// Convert entropy to hex
|
|
102
|
+
const hexEntropy = Buffer.from(entropy).toString('hex');
|
|
103
|
+
// Convert hexEntropy to BigInt
|
|
104
|
+
const privateKey = BigInt(`0x${hexEntropy}`);
|
|
105
|
+
// Ensure private key is in valid secp256k1 range1
|
|
106
|
+
if (privateKey < BigInt(1) || privateKey >= CURVE.n) {
|
|
107
|
+
throw new Error('Invalid private key derived from entropy');
|
|
108
|
+
}
|
|
109
|
+
// The valid 32-byte private key
|
|
110
|
+
return entropy;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Recovers a secp256k1 privateKey from its original entropy
|
|
115
|
+
* @param {Uint8Array} entropy The entropy to recover the privateKey from
|
|
116
|
+
* @returns {Uint8Array} The recovered privateKey
|
|
117
|
+
* @throws {Error} if the privateKey cannot be recovered
|
|
118
|
+
*/
|
|
119
|
+
static recoverRawPrivateKey(entropy: Uint8Array): Uint8Array {
|
|
120
|
+
// If entropy is not 32 bytes, hash it to get a deterministic 32-byte private key
|
|
121
|
+
if (entropy.length !== 32) {
|
|
122
|
+
entropy = sha256(entropy);
|
|
123
|
+
}
|
|
124
|
+
// Convert entropy to hex
|
|
125
|
+
const hexEntropy = Buffer.from(entropy).toString('hex');
|
|
126
|
+
// Convert hexEntropy to BigInt
|
|
127
|
+
const privateKey = BigInt(`0x${hexEntropy}`);
|
|
128
|
+
// Ensure private key is in valid secp256k1 range1
|
|
129
|
+
if (privateKey < BigInt(1) || privateKey >= CURVE.n) {
|
|
130
|
+
throw new Error('Invalid private key derived from entropy');
|
|
131
|
+
}
|
|
132
|
+
// The valid 32-byte private key
|
|
133
|
+
return entropy;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Tweak the entropy with a salt using XOR
|
|
138
|
+
* @param {Uint8Array} entropy The entropy to tweak
|
|
139
|
+
* @param {Uint8Array} salt The salt to tweak the entropy with
|
|
140
|
+
* @returns {Uint8Array} The tweaked entropy
|
|
141
|
+
*/
|
|
142
|
+
static XOR(entropy: Uint8Array, salt: Uint8Array): Uint8Array {
|
|
143
|
+
const tweaked = new Uint8Array(entropy.length);
|
|
144
|
+
for (let i = 0; i < entropy.length; i++) {
|
|
145
|
+
tweaked[i] = entropy[i] ^ salt[i % salt.length]; // XOR with repeating salt
|
|
146
|
+
}
|
|
147
|
+
return tweaked;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Untweak the entropy with a salt using XNOR
|
|
152
|
+
*
|
|
153
|
+
* @param {Uint8Array} tweakedEntropy The tweaked entropy to untweak
|
|
154
|
+
* @param {Uint8Array} salt The salt to untweak the entropy with
|
|
155
|
+
* @returns {Uint8Array} The original entropy
|
|
156
|
+
*/
|
|
157
|
+
static XNOR(tweakedEntropy: Uint8Array, salt: Uint8Array): Uint8Array {
|
|
158
|
+
const originalEntropy = new Uint8Array(tweakedEntropy.length);
|
|
159
|
+
for (let i = 0; i < tweakedEntropy.length; i++) {
|
|
160
|
+
originalEntropy[i] = tweakedEntropy[i] ^ salt[i % salt.length]; // XOR with salt again
|
|
161
|
+
}
|
|
162
|
+
return originalEntropy;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Recovers an HDKey from a mnemonic phrase
|
|
167
|
+
* @param {string} mnemonic The mnemonic phrase to recover the HDKey from
|
|
168
|
+
* @param {string} path The path to derive the child key from
|
|
169
|
+
* @returns {Uint8Array} Promise resolving to the recovered private key bytes
|
|
170
|
+
* @throws {Error} if the HDKey cannot be recovered
|
|
171
|
+
*/
|
|
172
|
+
static async recoverHdChildFromMnemonic(mnemonic: string, path: string): Promise<Uint8Array> {
|
|
173
|
+
// Generate HDKey from seed.
|
|
174
|
+
const hdkey = await this.recoverHdWallet(mnemonic);
|
|
175
|
+
// Ensure HDKey returns valid
|
|
176
|
+
if (!hdkey) {
|
|
177
|
+
throw new Error('Failed to recover hdkey');
|
|
178
|
+
}
|
|
179
|
+
// Return the privateKey of the derived childKey
|
|
180
|
+
const childPrivKeyBytes = hdkey.derive(path).privateKey;
|
|
181
|
+
if (!childPrivKeyBytes) {
|
|
182
|
+
throw new Error('Failed to recover child private key');
|
|
183
|
+
}
|
|
184
|
+
return childPrivKeyBytes;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Derives a child key from an HDKey
|
|
189
|
+
* @param {HDKey} hdkey The HDKey to derive the child key from
|
|
190
|
+
* @param {string} path The path to derive the child key from
|
|
191
|
+
* @returns {HDKey} A Promise resolving to the child key
|
|
192
|
+
* @throws {Error} Error if the child key cannot be derived
|
|
193
|
+
*/
|
|
194
|
+
static deriveChildKey(hdkey: HDKey, path: string): HDKey {
|
|
195
|
+
// Derive child key from HDKey.
|
|
196
|
+
const childKey = hdkey.derive(path);
|
|
197
|
+
// Ensure child key returns valid
|
|
198
|
+
if (!childKey) {
|
|
199
|
+
throw new Error(`Failed to derive child key`);
|
|
200
|
+
}
|
|
201
|
+
// Return the child key
|
|
202
|
+
return childKey;
|
|
203
|
+
}
|
|
204
|
+
}
|