@did-btcr2/method 0.26.0 → 0.28.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/README.md +118 -236
- package/dist/.tsbuildinfo +1 -1
- package/dist/browser.js +27665 -23764
- package/dist/browser.mjs +27665 -23764
- package/dist/cjs/index.js +2661 -2239
- package/dist/esm/core/aggregation/cohort.js +178 -0
- package/dist/esm/core/aggregation/cohort.js.map +1 -0
- package/dist/esm/core/aggregation/errors.js +22 -0
- package/dist/esm/core/aggregation/errors.js.map +1 -0
- package/dist/esm/core/{beacon/aggregation/cohort → aggregation}/messages/base.js +0 -1
- package/dist/esm/core/aggregation/messages/base.js.map +1 -0
- package/dist/esm/core/aggregation/messages/constants.js +26 -0
- package/dist/esm/core/aggregation/messages/constants.js.map +1 -0
- package/dist/esm/core/aggregation/messages/factories.js +113 -0
- package/dist/esm/core/aggregation/messages/factories.js.map +1 -0
- package/dist/esm/core/aggregation/messages/guards.js +37 -0
- package/dist/esm/core/aggregation/messages/guards.js.map +1 -0
- package/dist/esm/core/aggregation/messages/index.js +5 -0
- package/dist/esm/core/aggregation/messages/index.js.map +1 -0
- package/dist/esm/core/aggregation/participant.js +376 -0
- package/dist/esm/core/aggregation/participant.js.map +1 -0
- package/dist/esm/core/aggregation/phases.js +39 -0
- package/dist/esm/core/aggregation/phases.js.map +1 -0
- package/dist/esm/core/aggregation/runner/events.js +2 -0
- package/dist/esm/core/aggregation/runner/events.js.map +1 -0
- package/dist/esm/core/aggregation/runner/index.js +5 -0
- package/dist/esm/core/aggregation/runner/index.js.map +1 -0
- package/dist/esm/core/aggregation/runner/participant-runner.js +286 -0
- package/dist/esm/core/aggregation/runner/participant-runner.js.map +1 -0
- package/dist/esm/core/aggregation/runner/service-runner.js +290 -0
- package/dist/esm/core/aggregation/runner/service-runner.js.map +1 -0
- package/dist/esm/core/aggregation/runner/typed-emitter.js +80 -0
- package/dist/esm/core/aggregation/runner/typed-emitter.js.map +1 -0
- package/dist/esm/core/aggregation/service.js +416 -0
- package/dist/esm/core/aggregation/service.js.map +1 -0
- package/dist/esm/core/aggregation/signing-session.js +133 -0
- package/dist/esm/core/aggregation/signing-session.js.map +1 -0
- package/dist/esm/core/aggregation/transport/didcomm.js +32 -0
- package/dist/esm/core/aggregation/transport/didcomm.js.map +1 -0
- package/dist/esm/core/aggregation/transport/error.js +12 -0
- package/dist/esm/core/aggregation/transport/error.js.map +1 -0
- package/dist/esm/core/aggregation/transport/factory.js +20 -0
- package/dist/esm/core/aggregation/transport/factory.js.map +1 -0
- package/dist/esm/core/aggregation/transport/index.js +6 -0
- package/dist/esm/core/aggregation/transport/index.js.map +1 -0
- package/dist/esm/core/aggregation/transport/nostr.js +262 -0
- package/dist/esm/core/aggregation/transport/nostr.js.map +1 -0
- package/dist/esm/core/aggregation/transport/transport.js +2 -0
- package/dist/esm/core/aggregation/transport/transport.js.map +1 -0
- package/dist/esm/core/beacon/beacon.js +80 -0
- package/dist/esm/core/beacon/beacon.js.map +1 -1
- package/dist/esm/core/beacon/cas-beacon.js +15 -56
- package/dist/esm/core/beacon/cas-beacon.js.map +1 -1
- package/dist/esm/core/beacon/error.js +0 -10
- package/dist/esm/core/beacon/error.js.map +1 -1
- package/dist/esm/core/beacon/fee-estimator.js +30 -0
- package/dist/esm/core/beacon/fee-estimator.js.map +1 -0
- package/dist/esm/core/beacon/singleton-beacon.js +10 -53
- package/dist/esm/core/beacon/singleton-beacon.js.map +1 -1
- package/dist/esm/core/beacon/smt-beacon.js +85 -9
- package/dist/esm/core/beacon/smt-beacon.js.map +1 -1
- package/dist/esm/core/identifier.js +13 -0
- package/dist/esm/core/identifier.js.map +1 -1
- package/dist/esm/core/resolver.js +9 -0
- package/dist/esm/core/resolver.js.map +1 -1
- package/dist/esm/core/updater.js +269 -0
- package/dist/esm/core/updater.js.map +1 -0
- package/dist/esm/did-btcr2.js +30 -42
- package/dist/esm/did-btcr2.js.map +1 -1
- package/dist/esm/index.js +16 -25
- package/dist/esm/index.js.map +1 -1
- package/dist/types/core/aggregation/cohort.d.ts +94 -0
- package/dist/types/core/aggregation/cohort.d.ts.map +1 -0
- package/dist/types/core/aggregation/errors.d.ts +14 -0
- package/dist/types/core/aggregation/errors.d.ts.map +1 -0
- package/dist/types/core/{beacon/aggregation/cohort → aggregation}/messages/base.d.ts +7 -1
- package/dist/types/core/aggregation/messages/base.d.ts.map +1 -0
- package/dist/types/core/aggregation/messages/constants.d.ts +23 -0
- package/dist/types/core/aggregation/messages/constants.d.ts.map +1 -0
- package/dist/types/core/aggregation/messages/factories.d.ts +177 -0
- package/dist/types/core/aggregation/messages/factories.d.ts.map +1 -0
- package/dist/types/core/aggregation/messages/guards.d.ts +11 -0
- package/dist/types/core/aggregation/messages/guards.d.ts.map +1 -0
- package/dist/types/core/aggregation/messages/index.d.ts +5 -0
- package/dist/types/core/aggregation/messages/index.d.ts.map +1 -0
- package/dist/types/core/aggregation/participant.d.ts +101 -0
- package/dist/types/core/aggregation/participant.d.ts.map +1 -0
- package/dist/types/core/aggregation/phases.d.ts +49 -0
- package/dist/types/core/aggregation/phases.d.ts.map +1 -0
- package/dist/types/core/aggregation/runner/events.d.ts +89 -0
- package/dist/types/core/aggregation/runner/events.d.ts.map +1 -0
- package/dist/types/core/aggregation/runner/index.d.ts +5 -0
- package/dist/types/core/aggregation/runner/index.d.ts.map +1 -0
- package/dist/types/core/aggregation/runner/participant-runner.d.ts +111 -0
- package/dist/types/core/aggregation/runner/participant-runner.d.ts.map +1 -0
- package/dist/types/core/aggregation/runner/service-runner.d.ts +102 -0
- package/dist/types/core/aggregation/runner/service-runner.d.ts.map +1 -0
- package/dist/types/core/aggregation/runner/typed-emitter.d.ts +41 -0
- package/dist/types/core/aggregation/runner/typed-emitter.d.ts.map +1 -0
- package/dist/types/core/aggregation/service.d.ts +112 -0
- package/dist/types/core/aggregation/service.d.ts.map +1 -0
- package/dist/types/core/aggregation/signing-session.d.ts +69 -0
- package/dist/types/core/aggregation/signing-session.d.ts.map +1 -0
- package/dist/types/core/aggregation/transport/didcomm.d.ts +20 -0
- package/dist/types/core/aggregation/transport/didcomm.d.ts.map +1 -0
- package/dist/types/core/{beacon/aggregation/communication → aggregation/transport}/error.d.ts +2 -2
- package/dist/types/core/aggregation/transport/error.d.ts.map +1 -0
- package/dist/types/core/aggregation/transport/factory.d.ts +13 -0
- package/dist/types/core/aggregation/transport/factory.d.ts.map +1 -0
- package/dist/types/core/aggregation/transport/index.d.ts +6 -0
- package/dist/types/core/aggregation/transport/index.d.ts.map +1 -0
- package/dist/types/core/aggregation/transport/nostr.d.ts +55 -0
- package/dist/types/core/aggregation/transport/nostr.d.ts.map +1 -0
- package/dist/types/core/aggregation/transport/transport.d.ts +37 -0
- package/dist/types/core/aggregation/transport/transport.d.ts.map +1 -0
- package/dist/types/core/beacon/beacon.d.ts +37 -2
- package/dist/types/core/beacon/beacon.d.ts.map +1 -1
- package/dist/types/core/beacon/cas-beacon.d.ts +19 -7
- package/dist/types/core/beacon/cas-beacon.d.ts.map +1 -1
- package/dist/types/core/beacon/error.d.ts +0 -6
- package/dist/types/core/beacon/error.d.ts.map +1 -1
- package/dist/types/core/beacon/fee-estimator.d.ts +40 -0
- package/dist/types/core/beacon/fee-estimator.d.ts.map +1 -0
- package/dist/types/core/beacon/interfaces.d.ts +8 -0
- package/dist/types/core/beacon/interfaces.d.ts.map +1 -1
- package/dist/types/core/beacon/singleton-beacon.d.ts +9 -2
- package/dist/types/core/beacon/singleton-beacon.d.ts.map +1 -1
- package/dist/types/core/beacon/smt-beacon.d.ts +27 -7
- package/dist/types/core/beacon/smt-beacon.d.ts.map +1 -1
- package/dist/types/core/identifier.d.ts +8 -0
- package/dist/types/core/identifier.d.ts.map +1 -1
- package/dist/types/core/interfaces.d.ts +2 -2
- package/dist/types/core/resolver.d.ts +11 -1
- package/dist/types/core/resolver.d.ts.map +1 -1
- package/dist/types/core/updater.d.ts +178 -0
- package/dist/types/core/updater.d.ts.map +1 -0
- package/dist/types/did-btcr2.d.ts +23 -23
- package/dist/types/did-btcr2.d.ts.map +1 -1
- package/dist/types/index.d.ts +11 -25
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +31 -30
- package/src/core/aggregation/cohort.ts +247 -0
- package/src/core/aggregation/errors.ts +25 -0
- package/src/core/{beacon/aggregation/cohort → aggregation}/messages/base.ts +8 -3
- package/src/core/aggregation/messages/constants.ts +28 -0
- package/src/core/aggregation/messages/factories.ts +240 -0
- package/src/core/aggregation/messages/guards.ts +55 -0
- package/src/core/aggregation/messages/index.ts +4 -0
- package/src/core/aggregation/participant.ts +510 -0
- package/src/core/aggregation/phases.ts +82 -0
- package/src/core/aggregation/runner/events.ts +77 -0
- package/src/core/aggregation/runner/index.ts +4 -0
- package/src/core/aggregation/runner/participant-runner.ts +364 -0
- package/src/core/aggregation/runner/service-runner.ts +365 -0
- package/src/core/aggregation/runner/typed-emitter.ts +87 -0
- package/src/core/aggregation/service.ts +547 -0
- package/src/core/aggregation/signing-session.ts +209 -0
- package/src/core/aggregation/transport/didcomm.ts +42 -0
- package/src/core/aggregation/transport/error.ts +13 -0
- package/src/core/aggregation/transport/factory.ts +29 -0
- package/src/core/aggregation/transport/index.ts +5 -0
- package/src/core/aggregation/transport/nostr.ts +333 -0
- package/src/core/aggregation/transport/transport.ts +46 -0
- package/src/core/beacon/beacon.ts +122 -2
- package/src/core/beacon/cas-beacon.ts +28 -76
- package/src/core/beacon/error.ts +0 -12
- package/src/core/beacon/fee-estimator.ts +52 -0
- package/src/core/beacon/interfaces.ts +10 -1
- package/src/core/beacon/singleton-beacon.ts +14 -75
- package/src/core/beacon/smt-beacon.ts +109 -11
- package/src/core/identifier.ts +17 -0
- package/src/core/interfaces.ts +2 -2
- package/src/core/resolver.ts +25 -2
- package/src/core/updater.ts +415 -0
- package/src/did-btcr2.ts +36 -66
- package/src/index.ts +17 -30
- package/dist/esm/core/beacon/aggregation/cohort/index.js +0 -237
- package/dist/esm/core/beacon/aggregation/cohort/index.js.map +0 -1
- package/dist/esm/core/beacon/aggregation/cohort/messages/base.js.map +0 -1
- package/dist/esm/core/beacon/aggregation/cohort/messages/constants.js +0 -11
- package/dist/esm/core/beacon/aggregation/cohort/messages/constants.js.map +0 -1
- package/dist/esm/core/beacon/aggregation/cohort/messages/index.js +0 -98
- package/dist/esm/core/beacon/aggregation/cohort/messages/index.js.map +0 -1
- package/dist/esm/core/beacon/aggregation/cohort/messages/keygen/cohort-advert.js +0 -31
- package/dist/esm/core/beacon/aggregation/cohort/messages/keygen/cohort-advert.js.map +0 -1
- package/dist/esm/core/beacon/aggregation/cohort/messages/keygen/cohort-ready.js +0 -29
- package/dist/esm/core/beacon/aggregation/cohort/messages/keygen/cohort-ready.js.map +0 -1
- package/dist/esm/core/beacon/aggregation/cohort/messages/keygen/opt-in-accept.js +0 -27
- package/dist/esm/core/beacon/aggregation/cohort/messages/keygen/opt-in-accept.js.map +0 -1
- package/dist/esm/core/beacon/aggregation/cohort/messages/keygen/opt-in.js +0 -23
- package/dist/esm/core/beacon/aggregation/cohort/messages/keygen/opt-in.js.map +0 -1
- package/dist/esm/core/beacon/aggregation/cohort/messages/keygen/subscribe.js +0 -28
- package/dist/esm/core/beacon/aggregation/cohort/messages/keygen/subscribe.js.map +0 -1
- package/dist/esm/core/beacon/aggregation/cohort/messages/sign/aggregated-nonce.js +0 -29
- package/dist/esm/core/beacon/aggregation/cohort/messages/sign/aggregated-nonce.js.map +0 -1
- package/dist/esm/core/beacon/aggregation/cohort/messages/sign/authorization-request.js +0 -30
- package/dist/esm/core/beacon/aggregation/cohort/messages/sign/authorization-request.js.map +0 -1
- package/dist/esm/core/beacon/aggregation/cohort/messages/sign/nonce-contribution.js +0 -30
- package/dist/esm/core/beacon/aggregation/cohort/messages/sign/nonce-contribution.js.map +0 -1
- package/dist/esm/core/beacon/aggregation/cohort/messages/sign/request-signature.js +0 -30
- package/dist/esm/core/beacon/aggregation/cohort/messages/sign/request-signature.js.map +0 -1
- package/dist/esm/core/beacon/aggregation/cohort/messages/sign/signature-authorization.js +0 -31
- package/dist/esm/core/beacon/aggregation/cohort/messages/sign/signature-authorization.js.map +0 -1
- package/dist/esm/core/beacon/aggregation/cohort/status.js +0 -8
- package/dist/esm/core/beacon/aggregation/cohort/status.js.map +0 -1
- package/dist/esm/core/beacon/aggregation/communication/adapter/did-comm.js +0 -121
- package/dist/esm/core/beacon/aggregation/communication/adapter/did-comm.js.map +0 -1
- package/dist/esm/core/beacon/aggregation/communication/adapter/nostr.js +0 -245
- package/dist/esm/core/beacon/aggregation/communication/adapter/nostr.js.map +0 -1
- package/dist/esm/core/beacon/aggregation/communication/error.js +0 -12
- package/dist/esm/core/beacon/aggregation/communication/error.js.map +0 -1
- package/dist/esm/core/beacon/aggregation/communication/factory.js +0 -21
- package/dist/esm/core/beacon/aggregation/communication/factory.js.map +0 -1
- package/dist/esm/core/beacon/aggregation/communication/service.js +0 -2
- package/dist/esm/core/beacon/aggregation/communication/service.js.map +0 -1
- package/dist/esm/core/beacon/aggregation/coordinator.js +0 -343
- package/dist/esm/core/beacon/aggregation/coordinator.js.map +0 -1
- package/dist/esm/core/beacon/aggregation/participant.js +0 -435
- package/dist/esm/core/beacon/aggregation/participant.js.map +0 -1
- package/dist/esm/core/beacon/aggregation/session/index.js +0 -244
- package/dist/esm/core/beacon/aggregation/session/index.js.map +0 -1
- package/dist/esm/core/beacon/aggregation/session/status.js +0 -11
- package/dist/esm/core/beacon/aggregation/session/status.js.map +0 -1
- package/dist/esm/core/update.js +0 -112
- package/dist/esm/core/update.js.map +0 -1
- package/dist/types/core/beacon/aggregation/cohort/index.d.ts +0 -136
- package/dist/types/core/beacon/aggregation/cohort/index.d.ts.map +0 -1
- package/dist/types/core/beacon/aggregation/cohort/messages/base.d.ts.map +0 -1
- package/dist/types/core/beacon/aggregation/cohort/messages/constants.d.ts +0 -11
- package/dist/types/core/beacon/aggregation/cohort/messages/constants.d.ts.map +0 -1
- package/dist/types/core/beacon/aggregation/cohort/messages/index.d.ts +0 -65
- package/dist/types/core/beacon/aggregation/cohort/messages/index.d.ts.map +0 -1
- package/dist/types/core/beacon/aggregation/cohort/messages/keygen/cohort-advert.d.ts +0 -29
- package/dist/types/core/beacon/aggregation/cohort/messages/keygen/cohort-advert.d.ts.map +0 -1
- package/dist/types/core/beacon/aggregation/cohort/messages/keygen/cohort-ready.d.ts +0 -26
- package/dist/types/core/beacon/aggregation/cohort/messages/keygen/cohort-ready.d.ts.map +0 -1
- package/dist/types/core/beacon/aggregation/cohort/messages/keygen/opt-in-accept.d.ts +0 -24
- package/dist/types/core/beacon/aggregation/cohort/messages/keygen/opt-in-accept.d.ts.map +0 -1
- package/dist/types/core/beacon/aggregation/cohort/messages/keygen/opt-in.d.ts +0 -20
- package/dist/types/core/beacon/aggregation/cohort/messages/keygen/opt-in.d.ts.map +0 -1
- package/dist/types/core/beacon/aggregation/cohort/messages/keygen/subscribe.d.ts +0 -25
- package/dist/types/core/beacon/aggregation/cohort/messages/keygen/subscribe.d.ts.map +0 -1
- package/dist/types/core/beacon/aggregation/cohort/messages/sign/aggregated-nonce.d.ts +0 -25
- package/dist/types/core/beacon/aggregation/cohort/messages/sign/aggregated-nonce.d.ts.map +0 -1
- package/dist/types/core/beacon/aggregation/cohort/messages/sign/authorization-request.d.ts +0 -26
- package/dist/types/core/beacon/aggregation/cohort/messages/sign/authorization-request.d.ts.map +0 -1
- package/dist/types/core/beacon/aggregation/cohort/messages/sign/nonce-contribution.d.ts +0 -26
- package/dist/types/core/beacon/aggregation/cohort/messages/sign/nonce-contribution.d.ts.map +0 -1
- package/dist/types/core/beacon/aggregation/cohort/messages/sign/request-signature.d.ts +0 -26
- package/dist/types/core/beacon/aggregation/cohort/messages/sign/request-signature.d.ts.map +0 -1
- package/dist/types/core/beacon/aggregation/cohort/messages/sign/signature-authorization.d.ts +0 -27
- package/dist/types/core/beacon/aggregation/cohort/messages/sign/signature-authorization.d.ts.map +0 -1
- package/dist/types/core/beacon/aggregation/cohort/status.d.ts +0 -8
- package/dist/types/core/beacon/aggregation/cohort/status.d.ts.map +0 -1
- package/dist/types/core/beacon/aggregation/communication/adapter/did-comm.d.ts +0 -89
- package/dist/types/core/beacon/aggregation/communication/adapter/did-comm.d.ts.map +0 -1
- package/dist/types/core/beacon/aggregation/communication/adapter/nostr.d.ts +0 -103
- package/dist/types/core/beacon/aggregation/communication/adapter/nostr.d.ts.map +0 -1
- package/dist/types/core/beacon/aggregation/communication/error.d.ts.map +0 -1
- package/dist/types/core/beacon/aggregation/communication/factory.d.ts +0 -10
- package/dist/types/core/beacon/aggregation/communication/factory.d.ts.map +0 -1
- package/dist/types/core/beacon/aggregation/communication/service.d.ts +0 -36
- package/dist/types/core/beacon/aggregation/communication/service.d.ts.map +0 -1
- package/dist/types/core/beacon/aggregation/coordinator.d.ts +0 -116
- package/dist/types/core/beacon/aggregation/coordinator.d.ts.map +0 -1
- package/dist/types/core/beacon/aggregation/participant.d.ts +0 -192
- package/dist/types/core/beacon/aggregation/participant.d.ts.map +0 -1
- package/dist/types/core/beacon/aggregation/session/index.d.ts +0 -156
- package/dist/types/core/beacon/aggregation/session/index.d.ts.map +0 -1
- package/dist/types/core/beacon/aggregation/session/status.d.ts +0 -11
- package/dist/types/core/beacon/aggregation/session/status.d.ts.map +0 -1
- package/dist/types/core/update.d.ts +0 -52
- package/dist/types/core/update.d.ts.map +0 -1
- package/src/core/beacon/aggregation/cohort/index.ts +0 -305
- package/src/core/beacon/aggregation/cohort/messages/constants.ts +0 -12
- package/src/core/beacon/aggregation/cohort/messages/index.ts +0 -143
- package/src/core/beacon/aggregation/cohort/messages/keygen/cohort-advert.ts +0 -44
- package/src/core/beacon/aggregation/cohort/messages/keygen/cohort-ready.ts +0 -40
- package/src/core/beacon/aggregation/cohort/messages/keygen/opt-in-accept.ts +0 -35
- package/src/core/beacon/aggregation/cohort/messages/keygen/opt-in.ts +0 -34
- package/src/core/beacon/aggregation/cohort/messages/keygen/subscribe.ts +0 -36
- package/src/core/beacon/aggregation/cohort/messages/sign/aggregated-nonce.ts +0 -39
- package/src/core/beacon/aggregation/cohort/messages/sign/authorization-request.ts +0 -40
- package/src/core/beacon/aggregation/cohort/messages/sign/nonce-contribution.ts +0 -40
- package/src/core/beacon/aggregation/cohort/messages/sign/request-signature.ts +0 -40
- package/src/core/beacon/aggregation/cohort/messages/sign/signature-authorization.ts +0 -41
- package/src/core/beacon/aggregation/cohort/status.ts +0 -7
- package/src/core/beacon/aggregation/communication/adapter/did-comm.ts +0 -148
- package/src/core/beacon/aggregation/communication/adapter/nostr.ts +0 -323
- package/src/core/beacon/aggregation/communication/error.ts +0 -13
- package/src/core/beacon/aggregation/communication/factory.ts +0 -25
- package/src/core/beacon/aggregation/communication/service.ts +0 -42
- package/src/core/beacon/aggregation/coordinator.ts +0 -419
- package/src/core/beacon/aggregation/participant.ts +0 -517
- package/src/core/beacon/aggregation/session/index.ts +0 -301
- package/src/core/beacon/aggregation/session/status.ts +0 -18
- package/src/core/update.ts +0 -158
package/src/core/identifier.ts
CHANGED
|
@@ -291,6 +291,23 @@ export class Identifier {
|
|
|
291
291
|
return { keyPair: keyPair.exportJSON(), did };
|
|
292
292
|
}
|
|
293
293
|
|
|
294
|
+
/**
|
|
295
|
+
* Extracts the compressed secp256k1 public key from a KEY-type did:btcr2 identifier.
|
|
296
|
+
* @param {string} did The did:btcr2 identifier to extract the public key from.
|
|
297
|
+
* @returns {CompressedSecp256k1PublicKey} The compressed public key.
|
|
298
|
+
* @throws {IdentifierError} If the DID is EXTERNAL type (genesis bytes are a hash, not a pubkey).
|
|
299
|
+
*/
|
|
300
|
+
static getPublicKey(did: string): CompressedSecp256k1PublicKey {
|
|
301
|
+
const { idType, genesisBytes } = Identifier.decode(did);
|
|
302
|
+
if(idType !== 'KEY') {
|
|
303
|
+
throw new IdentifierError(
|
|
304
|
+
`Cannot extract public key from EXTERNAL DID: ${did}. EXTERNAL DIDs encode a document hash, not a public key.`,
|
|
305
|
+
INVALID_DID, { did, idType }
|
|
306
|
+
);
|
|
307
|
+
}
|
|
308
|
+
return new CompressedSecp256k1PublicKey(genesisBytes);
|
|
309
|
+
}
|
|
310
|
+
|
|
294
311
|
/**
|
|
295
312
|
* Validates a did:btcr2 identifier.
|
|
296
313
|
* @param {string} identifier The did:btcr2 identifier to validate.
|
package/src/core/interfaces.ts
CHANGED
|
@@ -64,11 +64,11 @@ export interface SMTProof {
|
|
|
64
64
|
*/
|
|
65
65
|
id: string;
|
|
66
66
|
/**
|
|
67
|
-
* Optional 256-bit nonce generated for each update.
|
|
67
|
+
* Optional 256-bit nonce generated for each update. Hex-encoded (64 chars).
|
|
68
68
|
*/
|
|
69
69
|
nonce?: string;
|
|
70
70
|
/**
|
|
71
|
-
* Optional
|
|
71
|
+
* Optional hex-encoded canonical hash of the BTCR2 Signed Update.
|
|
72
72
|
*/
|
|
73
73
|
updateId?: string;
|
|
74
74
|
/**
|
package/src/core/resolver.ts
CHANGED
|
@@ -81,8 +81,17 @@ export interface NeedSignedUpdate {
|
|
|
81
81
|
readonly beaconServiceId: string;
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
+
/** The resolver needs an SMT Proof whose root hash matches smtRootHash. */
|
|
85
|
+
export interface NeedSMTProof {
|
|
86
|
+
readonly kind: 'NeedSMTProof';
|
|
87
|
+
/** Hex-encoded SHA-256 root hash of the Sparse Merkle Tree. */
|
|
88
|
+
readonly smtRootHash: string;
|
|
89
|
+
/** The beacon service that produced this signal. */
|
|
90
|
+
readonly beaconServiceId: string;
|
|
91
|
+
}
|
|
92
|
+
|
|
84
93
|
/** Discriminated union of all data the resolver may request from the caller. */
|
|
85
|
-
export type DataNeed = NeedGenesisDocument | NeedBeaconSignals | NeedCASAnnouncement | NeedSignedUpdate;
|
|
94
|
+
export type DataNeed = NeedGenesisDocument | NeedBeaconSignals | NeedCASAnnouncement | NeedSignedUpdate | NeedSMTProof;
|
|
86
95
|
|
|
87
96
|
/**
|
|
88
97
|
* Output of {@link Resolver.resolve}. Analogous to Rust's `ResolverState` enum.
|
|
@@ -683,7 +692,8 @@ export class Resolver {
|
|
|
683
692
|
provide(need: NeedBeaconSignals, data: Map<BeaconService, Array<BeaconSignal>>): void;
|
|
684
693
|
provide(need: NeedCASAnnouncement, data: CASAnnouncement): void;
|
|
685
694
|
provide(need: NeedSignedUpdate, data: SignedBTCR2Update): void;
|
|
686
|
-
provide(need:
|
|
695
|
+
provide(need: NeedSMTProof, data: SMTProof): void;
|
|
696
|
+
provide(need: DataNeed, data: object | Map<BeaconService, Array<BeaconSignal>> | CASAnnouncement | SignedBTCR2Update | SMTProof): void {
|
|
687
697
|
switch(need.kind) {
|
|
688
698
|
case 'NeedGenesisDocument': {
|
|
689
699
|
this.#providedGenesisDocument = data;
|
|
@@ -709,6 +719,19 @@ export class Resolver {
|
|
|
709
719
|
this.#sidecarData.updateMap.set(canonicalHash(update, { encoding: 'hex' }), update);
|
|
710
720
|
break;
|
|
711
721
|
}
|
|
722
|
+
|
|
723
|
+
case 'NeedSMTProof': {
|
|
724
|
+
const smtNeed = need as NeedSMTProof;
|
|
725
|
+
const proof = data as SMTProof;
|
|
726
|
+
if(proof.id !== smtNeed.smtRootHash) {
|
|
727
|
+
throw new ResolveError(
|
|
728
|
+
`SMT proof root hash mismatch: expected ${smtNeed.smtRootHash}, got ${proof.id}`,
|
|
729
|
+
INVALID_DID_UPDATE, { expected: smtNeed.smtRootHash, actual: proof.id }
|
|
730
|
+
);
|
|
731
|
+
}
|
|
732
|
+
this.#sidecarData.smtMap.set(smtNeed.smtRootHash, proof);
|
|
733
|
+
break;
|
|
734
|
+
}
|
|
712
735
|
}
|
|
713
736
|
}
|
|
714
737
|
}
|
|
@@ -0,0 +1,415 @@
|
|
|
1
|
+
import type { BitcoinConnection } from '@did-btcr2/bitcoin';
|
|
2
|
+
import type { KeyBytes, PatchOperation } from '@did-btcr2/common';
|
|
3
|
+
import { canonicalHash, INVALID_DID_UPDATE, JSONPatch, UpdateError } from '@did-btcr2/common';
|
|
4
|
+
import { SchnorrMultikey, type DataIntegrityConfig, type SignedBTCR2Update, type UnsignedBTCR2Update } from '@did-btcr2/cryptosuite';
|
|
5
|
+
import { DidDocument, type Btcr2DidDocument, type DidVerificationMethod } from '../utils/did-document.js';
|
|
6
|
+
import { BeaconFactory } from './beacon/factory.js';
|
|
7
|
+
import type { BeaconService } from './beacon/interfaces.js';
|
|
8
|
+
|
|
9
|
+
// ─── DataNeed types ──────────────────────────────────────────────────────────
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* The updater needs the caller to supply a signing key (or a KMS-backed signature)
|
|
13
|
+
* for the given verification method. The unsigned update is attached so the caller
|
|
14
|
+
* can inspect it before producing a signature.
|
|
15
|
+
*/
|
|
16
|
+
export interface NeedSigningKey {
|
|
17
|
+
readonly kind: 'NeedSigningKey';
|
|
18
|
+
/** The verification method ID that requires a signing key. */
|
|
19
|
+
readonly verificationMethodId: string;
|
|
20
|
+
/** The unsigned update that will be signed. */
|
|
21
|
+
readonly unsignedUpdate: UnsignedBTCR2Update;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* The updater needs the caller to ensure the beacon address is funded before
|
|
26
|
+
* broadcasting. The caller checks the beacon address for UTXOs, funds it if
|
|
27
|
+
* needed, and then calls `updater.provide(need)` to continue.
|
|
28
|
+
*
|
|
29
|
+
* If the beacon is already funded, the caller can provide immediately (no-op).
|
|
30
|
+
*/
|
|
31
|
+
export interface NeedFunding {
|
|
32
|
+
readonly kind: 'NeedFunding';
|
|
33
|
+
/** The Bitcoin address that must have a spendable UTXO for broadcast. */
|
|
34
|
+
readonly beaconAddress: string;
|
|
35
|
+
/** The beacon service this address belongs to. */
|
|
36
|
+
readonly beaconService: BeaconService;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* The updater needs the caller to broadcast the signed update via the beacon.
|
|
41
|
+
*
|
|
42
|
+
* The caller decides how: for single-party beacons, call
|
|
43
|
+
* `Updater.announce(beaconService, signedUpdate, secretKey, bitcoin)` or
|
|
44
|
+
* `BeaconFactory.establish(beaconService).broadcastSignal(...)`. For multi-party
|
|
45
|
+
* aggregate beacons, hand off to the aggregation protocol.
|
|
46
|
+
*
|
|
47
|
+
* After the broadcast succeeds, the caller calls `updater.provide(need)` (with no
|
|
48
|
+
* data) to transition the updater to Complete.
|
|
49
|
+
*/
|
|
50
|
+
export interface NeedBroadcast {
|
|
51
|
+
readonly kind: 'NeedBroadcast';
|
|
52
|
+
/** The beacon service to broadcast through. Inspect `beaconService.type` to decide the path. */
|
|
53
|
+
readonly beaconService: BeaconService;
|
|
54
|
+
/** The signed update ready for broadcast. */
|
|
55
|
+
readonly signedUpdate: SignedBTCR2Update;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** Discriminated union of all data needs the updater may request from the caller. */
|
|
59
|
+
export type UpdaterDataNeed = NeedSigningKey | NeedFunding | NeedBroadcast;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* The result returned by the updater when it reaches the Complete phase.
|
|
63
|
+
*/
|
|
64
|
+
export interface UpdaterResult {
|
|
65
|
+
/** The signed update that was constructed, signed, and broadcast. */
|
|
66
|
+
signedUpdate: SignedBTCR2Update;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Output of {@link Updater.advance}. Either the updater needs data from the
|
|
71
|
+
* caller, or the update is complete.
|
|
72
|
+
*/
|
|
73
|
+
export type UpdaterState =
|
|
74
|
+
| { status: 'action-required'; needs: ReadonlyArray<UpdaterDataNeed> }
|
|
75
|
+
| { status: 'complete'; result: UpdaterResult };
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Internal phases of the Updater state machine.
|
|
79
|
+
* @internal
|
|
80
|
+
*/
|
|
81
|
+
enum UpdaterPhase {
|
|
82
|
+
Construct = 'Construct',
|
|
83
|
+
Sign = 'Sign',
|
|
84
|
+
Fund = 'Fund',
|
|
85
|
+
Broadcast = 'Broadcast',
|
|
86
|
+
Complete = 'Complete',
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Parameters for constructing an {@link Updater}. Built by
|
|
91
|
+
* {@link https://dcdpr.github.io/did-btcr2/operations/update.html | DidBtcr2.update}.
|
|
92
|
+
*/
|
|
93
|
+
export interface UpdaterParams {
|
|
94
|
+
sourceDocument: Btcr2DidDocument;
|
|
95
|
+
patches: PatchOperation[];
|
|
96
|
+
sourceVersionId: number;
|
|
97
|
+
verificationMethod: DidVerificationMethod;
|
|
98
|
+
beaconService: BeaconService;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Sans-I/O state machine for did:btcr2 updates — the counterpart to {@link Resolver}.
|
|
103
|
+
*
|
|
104
|
+
* Created by {@link DidBtcr2.update} (the factory). The caller drives the update by
|
|
105
|
+
* repeatedly calling {@link advance} and {@link provide}:
|
|
106
|
+
*
|
|
107
|
+
* ```typescript
|
|
108
|
+
* const updater = DidBtcr2.update({ sourceDocument, patches, ... });
|
|
109
|
+
* let state = updater.advance();
|
|
110
|
+
*
|
|
111
|
+
* while(state.status === 'action-required') {
|
|
112
|
+
* for(const need of state.needs) {
|
|
113
|
+
* switch(need.kind) {
|
|
114
|
+
* case 'NeedSigningKey':
|
|
115
|
+
* updater.provide(need, secretKeyBytes);
|
|
116
|
+
* break;
|
|
117
|
+
* case 'NeedFunding':
|
|
118
|
+
* // Check UTXOs at need.beaconAddress, fund if needed
|
|
119
|
+
* updater.provide(need);
|
|
120
|
+
* break;
|
|
121
|
+
* case 'NeedBroadcast':
|
|
122
|
+
* await Updater.announce(need.beaconService, need.signedUpdate, secretKey, bitcoin);
|
|
123
|
+
* updater.provide(need);
|
|
124
|
+
* break;
|
|
125
|
+
* }
|
|
126
|
+
* }
|
|
127
|
+
* state = updater.advance();
|
|
128
|
+
* }
|
|
129
|
+
*
|
|
130
|
+
* const { signedUpdate } = state.result;
|
|
131
|
+
* ```
|
|
132
|
+
*
|
|
133
|
+
* The Updater performs **zero I/O**. All external work (signing with a KMS or raw
|
|
134
|
+
* key, funding checks, Bitcoin transaction construction, broadcast) flows through
|
|
135
|
+
* the advance/provide protocol. This mirrors the {@link Resolver} pattern and makes
|
|
136
|
+
* the update path transport-agnostic and KMS-ready.
|
|
137
|
+
*
|
|
138
|
+
* The class also exposes static utility methods ({@link construct}, {@link sign},
|
|
139
|
+
* {@link announce}) for callers that need direct access to individual update steps
|
|
140
|
+
* outside the state machine (e.g., test vector generation scripts).
|
|
141
|
+
*
|
|
142
|
+
* @class Updater
|
|
143
|
+
*/
|
|
144
|
+
export class Updater {
|
|
145
|
+
#phase: UpdaterPhase = UpdaterPhase.Construct;
|
|
146
|
+
readonly #sourceDocument: Btcr2DidDocument;
|
|
147
|
+
readonly #patches: PatchOperation[];
|
|
148
|
+
readonly #sourceVersionId: number;
|
|
149
|
+
readonly #verificationMethod: DidVerificationMethod;
|
|
150
|
+
readonly #beaconService: BeaconService;
|
|
151
|
+
|
|
152
|
+
#unsignedUpdate: UnsignedBTCR2Update | null = null;
|
|
153
|
+
#signedUpdate: SignedBTCR2Update | null = null;
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* @internal — Use {@link DidBtcr2.update} to create instances.
|
|
157
|
+
*/
|
|
158
|
+
constructor(params: UpdaterParams) {
|
|
159
|
+
this.#sourceDocument = params.sourceDocument;
|
|
160
|
+
this.#patches = params.patches;
|
|
161
|
+
this.#sourceVersionId = params.sourceVersionId;
|
|
162
|
+
this.#verificationMethod = params.verificationMethod;
|
|
163
|
+
this.#beaconService = params.beaconService;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// ─── Public static utility methods ─────────────────────────────────────────
|
|
167
|
+
// Used by generate-vector.ts and other scripts that need direct access to
|
|
168
|
+
// individual update steps outside the state machine flow.
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Implements subsection {@link https://dcdpr.github.io/did-btcr2/operations/update.html#construct-btcr2-unsigned-update | 7.3.b Construct BTCR2 Unsigned Update}.
|
|
172
|
+
*
|
|
173
|
+
* @param {Btcr2DidDocument} sourceDocument The source DID document to be updated.
|
|
174
|
+
* @param {PatchOperation[]} patches The JSON Patch operations to apply.
|
|
175
|
+
* @param {number} sourceVersionId The version ID of the source document.
|
|
176
|
+
* @returns {UnsignedBTCR2Update} The constructed UnsignedBTCR2Update object.
|
|
177
|
+
* @throws {UpdateError} If the target document fails DID Core validation.
|
|
178
|
+
*/
|
|
179
|
+
static construct(
|
|
180
|
+
sourceDocument: Btcr2DidDocument,
|
|
181
|
+
patches: PatchOperation[],
|
|
182
|
+
sourceVersionId: number,
|
|
183
|
+
): UnsignedBTCR2Update {
|
|
184
|
+
const unsignedUpdate: UnsignedBTCR2Update = {
|
|
185
|
+
'@context' : [
|
|
186
|
+
'https://w3id.org/security/v2',
|
|
187
|
+
'https://w3id.org/zcap/v1',
|
|
188
|
+
'https://w3id.org/json-ld-patch/v1',
|
|
189
|
+
'https://btcr2.dev/context/v1'
|
|
190
|
+
],
|
|
191
|
+
patch : patches,
|
|
192
|
+
targetHash : '',
|
|
193
|
+
targetVersionId : sourceVersionId + 1,
|
|
194
|
+
sourceHash : canonicalHash(sourceDocument),
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
const targetDocument = JSONPatch.apply(sourceDocument, patches);
|
|
198
|
+
|
|
199
|
+
try {
|
|
200
|
+
DidDocument.isValid(targetDocument);
|
|
201
|
+
} catch (error) {
|
|
202
|
+
throw new UpdateError(
|
|
203
|
+
'Error validating targetDocument: ' + (error instanceof Error ? error.message : String(error)),
|
|
204
|
+
INVALID_DID_UPDATE, targetDocument
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
unsignedUpdate.targetHash = canonicalHash(targetDocument);
|
|
209
|
+
return unsignedUpdate;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Implements subsection {@link http://dcdpr.github.io/did-btcr2/operations/update.html#construct-btcr2-signed-update | 7.3.c Construct BTCR2 Signed Update }.
|
|
214
|
+
*
|
|
215
|
+
* @param {string} did The did-btcr2 identifier to derive the root capability from.
|
|
216
|
+
* @param {UnsignedBTCR2Update} unsignedUpdate The unsigned update to sign.
|
|
217
|
+
* @param {DidVerificationMethod} verificationMethod The verification method for signing.
|
|
218
|
+
* @param {KeyBytes} secretKey The secret key bytes.
|
|
219
|
+
* @returns {SignedBTCR2Update} The signed update with a Data Integrity proof.
|
|
220
|
+
*/
|
|
221
|
+
static sign(
|
|
222
|
+
did: string,
|
|
223
|
+
unsignedUpdate: UnsignedBTCR2Update,
|
|
224
|
+
verificationMethod: DidVerificationMethod,
|
|
225
|
+
secretKey: KeyBytes,
|
|
226
|
+
): SignedBTCR2Update {
|
|
227
|
+
const controller = verificationMethod.controller;
|
|
228
|
+
const id = verificationMethod.id.slice(verificationMethod.id.indexOf('#'));
|
|
229
|
+
const multikey = SchnorrMultikey.fromSecretKey(id, controller, secretKey);
|
|
230
|
+
|
|
231
|
+
const config: DataIntegrityConfig = {
|
|
232
|
+
'@context' : [
|
|
233
|
+
'https://w3id.org/security/v2',
|
|
234
|
+
'https://w3id.org/zcap/v1',
|
|
235
|
+
'https://w3id.org/json-ld-patch/v1',
|
|
236
|
+
'https://btcr2.dev/context/v1'
|
|
237
|
+
],
|
|
238
|
+
cryptosuite : 'bip340-jcs-2025',
|
|
239
|
+
type : 'DataIntegrityProof',
|
|
240
|
+
verificationMethod : verificationMethod.id,
|
|
241
|
+
proofPurpose : 'capabilityInvocation',
|
|
242
|
+
capability : `urn:zcap:root:${encodeURIComponent(did)}`,
|
|
243
|
+
capabilityAction : 'Write',
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
const diproof = multikey.toCryptosuite().toDataIntegrityProof();
|
|
247
|
+
return diproof.addProof(unsignedUpdate, config);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Implements subsection {@link https://dcdpr.github.io/did-btcr2/operations/update.html#announce-did-update | 7.3.d Announce DID Update}.
|
|
252
|
+
* Announces a signed update to the Bitcoin blockchain via the specified beacon.
|
|
253
|
+
*
|
|
254
|
+
* @param {BeaconService} beaconService The beacon service to broadcast through.
|
|
255
|
+
* @param {SignedBTCR2Update} update The signed update to announce.
|
|
256
|
+
* @param {KeyBytes} secretKey The secret key for signing the Bitcoin transaction.
|
|
257
|
+
* @param {BitcoinConnection} bitcoin The Bitcoin network connection.
|
|
258
|
+
* @returns {Promise<SignedBTCR2Update>} The signed update that was broadcast.
|
|
259
|
+
*/
|
|
260
|
+
static async announce(
|
|
261
|
+
beaconService: BeaconService,
|
|
262
|
+
update: SignedBTCR2Update,
|
|
263
|
+
secretKey: KeyBytes,
|
|
264
|
+
bitcoin: BitcoinConnection
|
|
265
|
+
): Promise<SignedBTCR2Update> {
|
|
266
|
+
const beacon = BeaconFactory.establish(beaconService);
|
|
267
|
+
return beacon.broadcastSignal(update, secretKey, bitcoin);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// ─── Private instance wrappers ─────────────────────────────────────────────
|
|
271
|
+
// Delegate to the public statics with bound instance fields for cleaner
|
|
272
|
+
// advance/provide code.
|
|
273
|
+
|
|
274
|
+
#construct(): UnsignedBTCR2Update {
|
|
275
|
+
return Updater.construct(this.#sourceDocument, this.#patches, this.#sourceVersionId);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
#sign(secretKey: KeyBytes): SignedBTCR2Update {
|
|
279
|
+
return Updater.sign(this.#sourceDocument.id, this.#unsignedUpdate!, this.#verificationMethod, secretKey);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// ─── State machine ─────────────────────────────────────────────────────────
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Advance the state machine. Returns either:
|
|
286
|
+
* - `{ status: 'action-required', needs }` — caller must provide data via {@link provide}
|
|
287
|
+
* - `{ status: 'complete', result }` — update is signed and broadcast
|
|
288
|
+
*/
|
|
289
|
+
advance(): UpdaterState {
|
|
290
|
+
while(true) {
|
|
291
|
+
switch(this.#phase) {
|
|
292
|
+
|
|
293
|
+
// Phase: Construct
|
|
294
|
+
// Build the unsigned update from source doc + patches. Pure, synchronous.
|
|
295
|
+
case UpdaterPhase.Construct: {
|
|
296
|
+
this.#unsignedUpdate = this.#construct();
|
|
297
|
+
this.#phase = UpdaterPhase.Sign;
|
|
298
|
+
continue;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// Phase: Sign
|
|
302
|
+
// Emit NeedSigningKey — the caller supplies the secret key (or a KMS signature).
|
|
303
|
+
case UpdaterPhase.Sign: {
|
|
304
|
+
return {
|
|
305
|
+
status : 'action-required',
|
|
306
|
+
needs : [{
|
|
307
|
+
kind : 'NeedSigningKey',
|
|
308
|
+
verificationMethodId : this.#verificationMethod.id,
|
|
309
|
+
unsignedUpdate : this.#unsignedUpdate!,
|
|
310
|
+
}],
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
// Phase: Fund
|
|
315
|
+
// Emit NeedFunding with the beacon address. The caller checks UTXOs,
|
|
316
|
+
// funds the address if needed, and provides to continue.
|
|
317
|
+
case UpdaterPhase.Fund: {
|
|
318
|
+
const beaconAddress = this.#beaconService.serviceEndpoint.replace('bitcoin:', '');
|
|
319
|
+
return {
|
|
320
|
+
status : 'action-required',
|
|
321
|
+
needs : [{
|
|
322
|
+
kind : 'NeedFunding',
|
|
323
|
+
beaconAddress,
|
|
324
|
+
beaconService : this.#beaconService,
|
|
325
|
+
}],
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
// Phase: Broadcast
|
|
330
|
+
// Emit NeedBroadcast with the signed update + beacon service. The caller performs
|
|
331
|
+
// the actual on-chain announcement (or hands off to the aggregation protocol).
|
|
332
|
+
case UpdaterPhase.Broadcast: {
|
|
333
|
+
return {
|
|
334
|
+
status : 'action-required',
|
|
335
|
+
needs : [{
|
|
336
|
+
kind : 'NeedBroadcast',
|
|
337
|
+
beaconService : this.#beaconService,
|
|
338
|
+
signedUpdate : this.#signedUpdate!,
|
|
339
|
+
}],
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// Phase: Complete
|
|
344
|
+
case UpdaterPhase.Complete: {
|
|
345
|
+
return {
|
|
346
|
+
status : 'complete',
|
|
347
|
+
result : { signedUpdate: this.#signedUpdate! },
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
* Provide data the updater requested in a previous {@link advance} call.
|
|
356
|
+
* Call once per need, then call {@link advance} again to continue.
|
|
357
|
+
*
|
|
358
|
+
* @param need The DataNeed being fulfilled (from the `needs` array).
|
|
359
|
+
* @param data The data payload corresponding to the need kind (omit for NeedFunding/NeedBroadcast).
|
|
360
|
+
*/
|
|
361
|
+
provide(need: NeedSigningKey, data: KeyBytes): void;
|
|
362
|
+
provide(need: NeedFunding): void;
|
|
363
|
+
provide(need: NeedBroadcast): void;
|
|
364
|
+
provide(need: UpdaterDataNeed, data?: KeyBytes): void {
|
|
365
|
+
switch(need.kind) {
|
|
366
|
+
case 'NeedSigningKey': {
|
|
367
|
+
if(this.#phase !== UpdaterPhase.Sign) {
|
|
368
|
+
throw new UpdateError(
|
|
369
|
+
`Cannot provide NeedSigningKey: updater phase is ${this.#phase}, expected Sign.`,
|
|
370
|
+
INVALID_DID_UPDATE, { phase: this.#phase }
|
|
371
|
+
);
|
|
372
|
+
}
|
|
373
|
+
if(!data) {
|
|
374
|
+
throw new UpdateError(
|
|
375
|
+
'NeedSigningKey requires secret key bytes.',
|
|
376
|
+
INVALID_DID_UPDATE
|
|
377
|
+
);
|
|
378
|
+
}
|
|
379
|
+
if(!this.#unsignedUpdate) {
|
|
380
|
+
throw new UpdateError(
|
|
381
|
+
'Internal error: unsigned update missing in Sign phase.',
|
|
382
|
+
INVALID_DID_UPDATE
|
|
383
|
+
);
|
|
384
|
+
}
|
|
385
|
+
this.#signedUpdate = this.#sign(data);
|
|
386
|
+
this.#phase = UpdaterPhase.Fund;
|
|
387
|
+
break;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
case 'NeedFunding': {
|
|
391
|
+
if(this.#phase !== UpdaterPhase.Fund) {
|
|
392
|
+
throw new UpdateError(
|
|
393
|
+
`Cannot provide NeedFunding: updater phase is ${this.#phase}, expected Fund.`,
|
|
394
|
+
INVALID_DID_UPDATE, { phase: this.#phase }
|
|
395
|
+
);
|
|
396
|
+
}
|
|
397
|
+
// Caller has confirmed funding (or it was already funded). Continue.
|
|
398
|
+
this.#phase = UpdaterPhase.Broadcast;
|
|
399
|
+
break;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
case 'NeedBroadcast': {
|
|
403
|
+
if(this.#phase !== UpdaterPhase.Broadcast) {
|
|
404
|
+
throw new UpdateError(
|
|
405
|
+
`Cannot provide NeedBroadcast: updater phase is ${this.#phase}, expected Broadcast.`,
|
|
406
|
+
INVALID_DID_UPDATE, { phase: this.#phase }
|
|
407
|
+
);
|
|
408
|
+
}
|
|
409
|
+
// Caller has broadcast externally. Transition to Complete.
|
|
410
|
+
this.#phase = UpdaterPhase.Complete;
|
|
411
|
+
break;
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
}
|