@did-btcr2/method 0.25.3 → 0.27.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 +86 -233
- package/dist/.tsbuildinfo +1 -0
- package/dist/browser.js +129207 -122358
- package/dist/browser.mjs +129235 -122386
- package/dist/cjs/index.js +5332 -43
- 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 +282 -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 +21 -60
- 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/signal-discovery.js +1 -1
- package/dist/esm/core/beacon/signal-discovery.js.map +1 -1
- package/dist/esm/core/beacon/singleton-beacon.js +13 -56
- 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/beacon/utils.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 +50 -35
- package/dist/esm/core/resolver.js.map +1 -1
- package/dist/esm/core/update.js.map +1 -1
- package/dist/esm/did-btcr2.js +1 -1
- package/dist/esm/did-btcr2.js.map +1 -1
- package/dist/esm/index.js +14 -24
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/utils/appendix.js +7 -6
- package/dist/esm/utils/appendix.js.map +1 -1
- package/dist/esm/utils/did-document-builder.js.map +1 -1
- package/dist/esm/utils/did-document.js +2 -2
- package/dist/esm/utils/did-document.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 +107 -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 +41 -6
- package/dist/types/core/beacon/beacon.d.ts.map +1 -1
- package/dist/types/core/beacon/cas-beacon.d.ts +23 -11
- 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/factory.d.ts +2 -2
- package/dist/types/core/beacon/factory.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 +11 -3
- package/dist/types/core/beacon/interfaces.d.ts.map +1 -1
- package/dist/types/core/beacon/signal-discovery.d.ts +3 -3
- package/dist/types/core/beacon/signal-discovery.d.ts.map +1 -1
- package/dist/types/core/beacon/singleton-beacon.d.ts +14 -7
- package/dist/types/core/beacon/singleton-beacon.d.ts.map +1 -1
- package/dist/types/core/beacon/smt-beacon.d.ts +32 -12
- package/dist/types/core/beacon/smt-beacon.d.ts.map +1 -1
- package/dist/types/core/beacon/utils.d.ts +4 -4
- package/dist/types/core/beacon/utils.d.ts.map +1 -1
- package/dist/types/core/identifier.d.ts +10 -2
- package/dist/types/core/identifier.d.ts.map +1 -1
- package/dist/types/core/interfaces.d.ts +4 -4
- package/dist/types/core/interfaces.d.ts.map +1 -1
- package/dist/types/core/resolver.d.ts +19 -9
- package/dist/types/core/resolver.d.ts.map +1 -1
- package/dist/types/core/types.d.ts +6 -5
- package/dist/types/core/types.d.ts.map +1 -1
- package/dist/types/core/update.d.ts +5 -5
- package/dist/types/core/update.d.ts.map +1 -1
- package/dist/types/did-btcr2.d.ts +6 -6
- package/dist/types/did-btcr2.d.ts.map +1 -1
- package/dist/types/index.d.ts +9 -24
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/utils/appendix.d.ts +7 -7
- package/dist/types/utils/appendix.d.ts.map +1 -1
- package/dist/types/utils/did-document-builder.d.ts +3 -2
- package/dist/types/utils/did-document-builder.d.ts.map +1 -1
- package/dist/types/utils/did-document.d.ts +3 -3
- package/dist/types/utils/did-document.d.ts.map +1 -1
- package/package.json +35 -33
- 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 +360 -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 +126 -6
- package/src/core/beacon/cas-beacon.ts +39 -83
- package/src/core/beacon/error.ts +0 -12
- package/src/core/beacon/factory.ts +2 -2
- package/src/core/beacon/fee-estimator.ts +52 -0
- package/src/core/beacon/interfaces.ts +13 -4
- package/src/core/beacon/signal-discovery.ts +5 -4
- package/src/core/beacon/singleton-beacon.ts +21 -81
- package/src/core/beacon/smt-beacon.ts +113 -15
- package/src/core/beacon/utils.ts +6 -4
- package/src/core/identifier.ts +20 -2
- package/src/core/interfaces.ts +4 -4
- package/src/core/resolver.ts +84 -53
- package/src/core/types.ts +6 -5
- package/src/core/update.ts +11 -7
- package/src/did-btcr2.ts +12 -10
- package/src/index.ts +15 -29
- package/src/utils/appendix.ts +14 -16
- package/src/utils/did-document-builder.ts +3 -2
- package/src/utils/did-document.ts +10 -8
- package/dist/cjs/core/beacon/aggregation/cohort/index.js +0 -237
- package/dist/cjs/core/beacon/aggregation/cohort/index.js.map +0 -1
- package/dist/cjs/core/beacon/aggregation/cohort/messages/base.js +0 -26
- package/dist/cjs/core/beacon/aggregation/cohort/messages/base.js.map +0 -1
- package/dist/cjs/core/beacon/aggregation/cohort/messages/constants.js +0 -11
- package/dist/cjs/core/beacon/aggregation/cohort/messages/constants.js.map +0 -1
- package/dist/cjs/core/beacon/aggregation/cohort/messages/index.js +0 -98
- package/dist/cjs/core/beacon/aggregation/cohort/messages/index.js.map +0 -1
- package/dist/cjs/core/beacon/aggregation/cohort/messages/keygen/cohort-advert.js +0 -31
- package/dist/cjs/core/beacon/aggregation/cohort/messages/keygen/cohort-advert.js.map +0 -1
- package/dist/cjs/core/beacon/aggregation/cohort/messages/keygen/cohort-ready.js +0 -29
- package/dist/cjs/core/beacon/aggregation/cohort/messages/keygen/cohort-ready.js.map +0 -1
- package/dist/cjs/core/beacon/aggregation/cohort/messages/keygen/opt-in-accept.js +0 -27
- package/dist/cjs/core/beacon/aggregation/cohort/messages/keygen/opt-in-accept.js.map +0 -1
- package/dist/cjs/core/beacon/aggregation/cohort/messages/keygen/opt-in.js +0 -23
- package/dist/cjs/core/beacon/aggregation/cohort/messages/keygen/opt-in.js.map +0 -1
- package/dist/cjs/core/beacon/aggregation/cohort/messages/keygen/subscribe.js +0 -28
- package/dist/cjs/core/beacon/aggregation/cohort/messages/keygen/subscribe.js.map +0 -1
- package/dist/cjs/core/beacon/aggregation/cohort/messages/sign/aggregated-nonce.js +0 -29
- package/dist/cjs/core/beacon/aggregation/cohort/messages/sign/aggregated-nonce.js.map +0 -1
- package/dist/cjs/core/beacon/aggregation/cohort/messages/sign/authorization-request.js +0 -30
- package/dist/cjs/core/beacon/aggregation/cohort/messages/sign/authorization-request.js.map +0 -1
- package/dist/cjs/core/beacon/aggregation/cohort/messages/sign/nonce-contribution.js +0 -30
- package/dist/cjs/core/beacon/aggregation/cohort/messages/sign/nonce-contribution.js.map +0 -1
- package/dist/cjs/core/beacon/aggregation/cohort/messages/sign/request-signature.js +0 -30
- package/dist/cjs/core/beacon/aggregation/cohort/messages/sign/request-signature.js.map +0 -1
- package/dist/cjs/core/beacon/aggregation/cohort/messages/sign/signature-authorization.js +0 -31
- package/dist/cjs/core/beacon/aggregation/cohort/messages/sign/signature-authorization.js.map +0 -1
- package/dist/cjs/core/beacon/aggregation/cohort/status.js +0 -8
- package/dist/cjs/core/beacon/aggregation/cohort/status.js.map +0 -1
- package/dist/cjs/core/beacon/aggregation/communication/adapter/did-comm.js +0 -121
- package/dist/cjs/core/beacon/aggregation/communication/adapter/did-comm.js.map +0 -1
- package/dist/cjs/core/beacon/aggregation/communication/adapter/nostr.js +0 -246
- package/dist/cjs/core/beacon/aggregation/communication/adapter/nostr.js.map +0 -1
- package/dist/cjs/core/beacon/aggregation/communication/error.js +0 -12
- package/dist/cjs/core/beacon/aggregation/communication/error.js.map +0 -1
- package/dist/cjs/core/beacon/aggregation/communication/factory.js +0 -21
- package/dist/cjs/core/beacon/aggregation/communication/factory.js.map +0 -1
- package/dist/cjs/core/beacon/aggregation/communication/service.js +0 -2
- package/dist/cjs/core/beacon/aggregation/communication/service.js.map +0 -1
- package/dist/cjs/core/beacon/aggregation/coordinator.js +0 -343
- package/dist/cjs/core/beacon/aggregation/coordinator.js.map +0 -1
- package/dist/cjs/core/beacon/aggregation/participant.js +0 -435
- package/dist/cjs/core/beacon/aggregation/participant.js.map +0 -1
- package/dist/cjs/core/beacon/aggregation/session/index.js +0 -244
- package/dist/cjs/core/beacon/aggregation/session/index.js.map +0 -1
- package/dist/cjs/core/beacon/aggregation/session/status.js +0 -11
- package/dist/cjs/core/beacon/aggregation/session/status.js.map +0 -1
- package/dist/cjs/core/beacon/beacon.js +0 -25
- package/dist/cjs/core/beacon/beacon.js.map +0 -1
- package/dist/cjs/core/beacon/cas-beacon.js +0 -152
- package/dist/cjs/core/beacon/cas-beacon.js.map +0 -1
- package/dist/cjs/core/beacon/error.js +0 -37
- package/dist/cjs/core/beacon/error.js.map +0 -1
- package/dist/cjs/core/beacon/factory.js +0 -29
- package/dist/cjs/core/beacon/factory.js.map +0 -1
- package/dist/cjs/core/beacon/interfaces.js +0 -2
- package/dist/cjs/core/beacon/interfaces.js.map +0 -1
- package/dist/cjs/core/beacon/signal-discovery.js +0 -183
- package/dist/cjs/core/beacon/signal-discovery.js.map +0 -1
- package/dist/cjs/core/beacon/singleton-beacon.js +0 -107
- package/dist/cjs/core/beacon/singleton-beacon.js.map +0 -1
- package/dist/cjs/core/beacon/smt-beacon.js +0 -39
- package/dist/cjs/core/beacon/smt-beacon.js.map +0 -1
- package/dist/cjs/core/beacon/utils.js +0 -163
- package/dist/cjs/core/beacon/utils.js.map +0 -1
- package/dist/cjs/core/identifier.js +0 -248
- package/dist/cjs/core/identifier.js.map +0 -1
- package/dist/cjs/core/interfaces.js +0 -2
- package/dist/cjs/core/interfaces.js.map +0 -1
- package/dist/cjs/core/resolver.js +0 -476
- package/dist/cjs/core/resolver.js.map +0 -1
- package/dist/cjs/core/types.js +0 -2
- package/dist/cjs/core/types.js.map +0 -1
- package/dist/cjs/core/update.js +0 -112
- package/dist/cjs/core/update.js.map +0 -1
- package/dist/cjs/did-btcr2.js +0 -193
- package/dist/cjs/did-btcr2.js.map +0 -1
- package/dist/cjs/index.js.map +0 -1
- package/dist/cjs/utils/appendix.js +0 -203
- package/dist/cjs/utils/appendix.js.map +0 -1
- package/dist/cjs/utils/did-document-builder.js +0 -60
- package/dist/cjs/utils/did-document-builder.js.map +0 -1
- package/dist/cjs/utils/did-document.js +0 -424
- package/dist/cjs/utils/did-document.js.map +0 -1
- 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 -246
- 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/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/src/core/beacon/aggregation/cohort/index.ts +0 -304
- 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 -43
- package/src/core/beacon/aggregation/cohort/messages/keygen/cohort-ready.ts +0 -39
- package/src/core/beacon/aggregation/cohort/messages/keygen/opt-in-accept.ts +0 -34
- package/src/core/beacon/aggregation/cohort/messages/keygen/opt-in.ts +0 -33
- package/src/core/beacon/aggregation/cohort/messages/keygen/subscribe.ts +0 -35
- package/src/core/beacon/aggregation/cohort/messages/sign/aggregated-nonce.ts +0 -38
- package/src/core/beacon/aggregation/cohort/messages/sign/authorization-request.ts +0 -39
- package/src/core/beacon/aggregation/cohort/messages/sign/nonce-contribution.ts +0 -39
- package/src/core/beacon/aggregation/cohort/messages/sign/request-signature.ts +0 -39
- package/src/core/beacon/aggregation/cohort/messages/sign/signature-authorization.ts +0 -40
- package/src/core/beacon/aggregation/cohort/status.ts +0 -7
- package/src/core/beacon/aggregation/communication/adapter/did-comm.ts +0 -147
- package/src/core/beacon/aggregation/communication/adapter/nostr.ts +0 -321
- 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 -415
- package/src/core/beacon/aggregation/participant.ts +0 -512
- package/src/core/beacon/aggregation/session/index.ts +0 -300
- package/src/core/beacon/aggregation/session/status.ts +0 -18
|
@@ -1,9 +1,26 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { SignedBTCR2Update } from '@did-btcr2/cryptosuite';
|
|
1
|
+
import type { AddressUtxo, BitcoinConnection } from '@did-btcr2/bitcoin';
|
|
2
|
+
import type { KeyBytes } from '@did-btcr2/common';
|
|
3
|
+
import type { SignedBTCR2Update } from '@did-btcr2/cryptosuite';
|
|
4
|
+
import { SchnorrKeyPair } from '@did-btcr2/keypair';
|
|
5
|
+
import { hexToBytes } from '@noble/hashes/utils';
|
|
6
|
+
import { opcodes, Psbt, script } from 'bitcoinjs-lib';
|
|
4
7
|
import type { BeaconProcessResult } from '../resolver.js';
|
|
5
|
-
import { SidecarData } from '../types.js';
|
|
6
|
-
import {
|
|
8
|
+
import type { SidecarData } from '../types.js';
|
|
9
|
+
import { BeaconError } from './error.js';
|
|
10
|
+
import { StaticFeeEstimator } from './fee-estimator.js';
|
|
11
|
+
import type { FeeEstimator } from './fee-estimator.js';
|
|
12
|
+
import type { BeaconService, BeaconSignal } from './interfaces.js';
|
|
13
|
+
|
|
14
|
+
/** Default fee estimator used when none is supplied. ~5 sat/vB static rate. */
|
|
15
|
+
const DEFAULT_FEE_ESTIMATOR: FeeEstimator = new StaticFeeEstimator(5);
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Options accepted by {@link Beacon.buildSignAndBroadcast}.
|
|
19
|
+
*/
|
|
20
|
+
export interface BroadcastOptions {
|
|
21
|
+
/** Fee estimator for computing the transaction fee. Defaults to {@link DEFAULT_FEE_ESTIMATOR}. */
|
|
22
|
+
feeEstimator?: FeeEstimator;
|
|
23
|
+
}
|
|
7
24
|
|
|
8
25
|
/**
|
|
9
26
|
* Abstract base class for all BTCR2 Beacon types.
|
|
@@ -52,11 +69,114 @@ export abstract class Beacon {
|
|
|
52
69
|
* @param {SignedBTCR2Update} signedUpdate The signed BTCR2 update to broadcast.
|
|
53
70
|
* @param {KeyBytes} secretKey The secret key for signing the Bitcoin transaction.
|
|
54
71
|
* @param {BitcoinConnection} bitcoin The Bitcoin network connection.
|
|
72
|
+
* @param {BroadcastOptions} [options] Optional broadcast configuration (e.g. fee estimator).
|
|
55
73
|
* @returns {Promise<SignedBTCR2Update>} The signed update that was broadcast.
|
|
56
74
|
*/
|
|
57
75
|
abstract broadcastSignal(
|
|
58
76
|
signedUpdate: SignedBTCR2Update,
|
|
59
77
|
secretKey: KeyBytes,
|
|
60
|
-
bitcoin: BitcoinConnection
|
|
78
|
+
bitcoin: BitcoinConnection,
|
|
79
|
+
options?: BroadcastOptions
|
|
61
80
|
): Promise<SignedBTCR2Update>;
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Shared PSBT construction + signing + broadcast helper used by all beacon types.
|
|
84
|
+
*
|
|
85
|
+
* Steps:
|
|
86
|
+
* 1. Parse the beacon's `serviceEndpoint` (stripping `bitcoin:` prefix) into a Bitcoin address.
|
|
87
|
+
* 2. Query the address for unconfirmed/confirmed UTXOs.
|
|
88
|
+
* 3. Select the most recent confirmed UTXO.
|
|
89
|
+
* 4. Fetch the previous transaction hex for `nonWitnessUtxo`.
|
|
90
|
+
* 5. Build a PSBT: input (UTXO) → change output + OP_RETURN(signalBytes).
|
|
91
|
+
* 6. Compute the fee via the supplied (or default) {@link FeeEstimator} against the tx vsize.
|
|
92
|
+
* 7. Sign input 0 with an ECDSA signer derived from `secretKey`.
|
|
93
|
+
* 8. Finalize, extract, and broadcast via the REST transaction endpoint.
|
|
94
|
+
*
|
|
95
|
+
* Fee handling: the PSBT is constructed with a placeholder change amount, signed to measure
|
|
96
|
+
* vsize, then the change is adjusted to pay the actual fee and the input re-signed. This
|
|
97
|
+
* two-pass approach avoids hardcoded fee constants and produces a tx that matches the
|
|
98
|
+
* estimator's rate.
|
|
99
|
+
*
|
|
100
|
+
* @param signalBytes 32-byte payload to embed in OP_RETURN.
|
|
101
|
+
* @param secretKey Secret key used to sign the spending input.
|
|
102
|
+
* @param bitcoin Bitcoin network connection.
|
|
103
|
+
* @param options Broadcast options (fee estimator, etc.).
|
|
104
|
+
* @returns The txid of the broadcast transaction.
|
|
105
|
+
* @throws {BeaconError} if the address is unfunded or no UTXO is available.
|
|
106
|
+
*/
|
|
107
|
+
protected async buildSignAndBroadcast(
|
|
108
|
+
signalBytes: Uint8Array,
|
|
109
|
+
secretKey: KeyBytes,
|
|
110
|
+
bitcoin: BitcoinConnection,
|
|
111
|
+
options?: BroadcastOptions
|
|
112
|
+
): Promise<string> {
|
|
113
|
+
const feeEstimator = options?.feeEstimator ?? DEFAULT_FEE_ESTIMATOR;
|
|
114
|
+
|
|
115
|
+
// Strip the 'bitcoin:' prefix from the service endpoint.
|
|
116
|
+
const bitcoinAddress = this.service.serviceEndpoint.replace('bitcoin:', '');
|
|
117
|
+
|
|
118
|
+
// Fetch UTXOs at the beacon address.
|
|
119
|
+
const utxos = await bitcoin.rest.address.getUtxos(bitcoinAddress);
|
|
120
|
+
if(!utxos.length) {
|
|
121
|
+
throw new BeaconError(
|
|
122
|
+
'No UTXOs found, please fund address!',
|
|
123
|
+
'UNFUNDED_BEACON_ADDRESS', { bitcoinAddress }
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Take the most recently confirmed UTXO.
|
|
128
|
+
const utxo: AddressUtxo | undefined = utxos.sort(
|
|
129
|
+
(a, b) => b.status.block_height - a.status.block_height
|
|
130
|
+
).shift();
|
|
131
|
+
if(!utxo) {
|
|
132
|
+
throw new BeaconError(
|
|
133
|
+
'Beacon bitcoin address unfunded or utxos unconfirmed.',
|
|
134
|
+
'UNFUNDED_BEACON_ADDRESS', { bitcoinAddress }
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Get the previous tx hex for non-witness UTXO reference.
|
|
139
|
+
const prevTx = await bitcoin.rest.transaction.getHex(utxo.txid);
|
|
140
|
+
|
|
141
|
+
// Build the ECDSA signer from the secret key.
|
|
142
|
+
const keyPair = SchnorrKeyPair.fromSecret(secretKey);
|
|
143
|
+
const signer = {
|
|
144
|
+
publicKey : keyPair.publicKey.compressed,
|
|
145
|
+
sign : (hash: Uint8Array) => keyPair.secretKey.sign(hash, { scheme: 'ecdsa' }),
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
// First pass: build with a placeholder fee (0 sats) so we can measure vsize.
|
|
149
|
+
const build = (fee: bigint) =>
|
|
150
|
+
new Psbt({ network: bitcoin.data })
|
|
151
|
+
.addInput({
|
|
152
|
+
hash : utxo.txid,
|
|
153
|
+
index : utxo.vout,
|
|
154
|
+
nonWitnessUtxo : hexToBytes(prevTx),
|
|
155
|
+
})
|
|
156
|
+
.addOutput({ address: bitcoinAddress, value: BigInt(utxo.value) - fee })
|
|
157
|
+
.addOutput({ script: script.compile([opcodes.OP_RETURN, signalBytes]), value: 0n });
|
|
158
|
+
|
|
159
|
+
const probeTx = build(0n)
|
|
160
|
+
.signInput(0, signer)
|
|
161
|
+
.finalizeAllInputs()
|
|
162
|
+
.extractTransaction();
|
|
163
|
+
const vsize = probeTx.virtualSize();
|
|
164
|
+
|
|
165
|
+
// Second pass: use the estimator to compute the real fee.
|
|
166
|
+
const fee = await feeEstimator.estimateFee(vsize);
|
|
167
|
+
if(BigInt(utxo.value) <= fee) {
|
|
168
|
+
throw new BeaconError(
|
|
169
|
+
`UTXO value (${utxo.value}) insufficient to cover fee (${fee}).`,
|
|
170
|
+
'INSUFFICIENT_FUNDS', { bitcoinAddress, utxoValue: utxo.value, fee: fee.toString() }
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const signedTxHex = build(fee)
|
|
175
|
+
.signInput(0, signer)
|
|
176
|
+
.finalizeAllInputs()
|
|
177
|
+
.extractTransaction()
|
|
178
|
+
.toHex();
|
|
179
|
+
|
|
180
|
+
return bitcoin.rest.transaction.send(signedTxHex);
|
|
181
|
+
}
|
|
62
182
|
}
|
|
@@ -1,14 +1,21 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { hexToBytes } from '@noble/hashes/utils';
|
|
6
|
-
import { opcodes, Psbt, script } from 'bitcoinjs-lib';
|
|
1
|
+
import type { BitcoinConnection } from '@did-btcr2/bitcoin';
|
|
2
|
+
import type { KeyBytes } from '@did-btcr2/common';
|
|
3
|
+
import { canonicalHash, canonicalize, decode, encode, hash } from '@did-btcr2/common';
|
|
4
|
+
import type { SignedBTCR2Update } from '@did-btcr2/cryptosuite';
|
|
7
5
|
import type { BeaconProcessResult, DataNeed } from '../resolver.js';
|
|
8
|
-
import { SidecarData } from '../types.js';
|
|
6
|
+
import type { SidecarData } from '../types.js';
|
|
7
|
+
import type { BroadcastOptions } from './beacon.js';
|
|
9
8
|
import { Beacon } from './beacon.js';
|
|
10
|
-
import {
|
|
11
|
-
|
|
9
|
+
import type { BeaconService, BeaconSignal, BlockMetadata, CasPublishFn } from './interfaces.js';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* CAS-specific broadcast options — extends {@link BroadcastOptions} with an optional
|
|
13
|
+
* `casPublish` callback used to publish the CAS Announcement off-chain after the
|
|
14
|
+
* OP_RETURN signal is broadcast.
|
|
15
|
+
*/
|
|
16
|
+
export interface CASBroadcastOptions extends BroadcastOptions {
|
|
17
|
+
casPublish?: CasPublishFn;
|
|
18
|
+
}
|
|
12
19
|
|
|
13
20
|
/**
|
|
14
21
|
* Implements {@link https://dcdpr.github.io/did-btcr2/terminology.html#cas-beacon | CAS Beacon}.
|
|
@@ -38,7 +45,7 @@ export class CASBeacon extends Beacon {
|
|
|
38
45
|
* For each signal, the signalBytes contain the hex-encoded hash of a CAS Announcement.
|
|
39
46
|
* The CAS Announcement maps DIDs to their base64url-encoded update hashes.
|
|
40
47
|
* This method looks up the CAS Announcement from the sidecar, extracts the update
|
|
41
|
-
* hash for the DID being resolved, and retrieves the corresponding signed update.
|
|
48
|
+
* hash for the DID being resolved, and retrieves the corresponding signed update from sidecar.
|
|
42
49
|
*
|
|
43
50
|
* @param {Array<BeaconSignal>} signals The array of Beacon Signals to process.
|
|
44
51
|
* @param {SidecarData} sidecar The sidecar data associated with the CAS Beacon.
|
|
@@ -56,8 +63,8 @@ export class CASBeacon extends Beacon {
|
|
|
56
63
|
const did = this.service.id.split('#')[0];
|
|
57
64
|
|
|
58
65
|
for(const signal of signals) {
|
|
59
|
-
//
|
|
60
|
-
const announcementHash =
|
|
66
|
+
// Signal bytes are hex — matches hex-keyed sidecar maps directly
|
|
67
|
+
const announcementHash = signal.signalBytes;
|
|
61
68
|
|
|
62
69
|
// Look up the CAS Announcement in sidecar casMap
|
|
63
70
|
const casAnnouncement = sidecar.casMap.get(announcementHash);
|
|
@@ -73,13 +80,16 @@ export class CASBeacon extends Beacon {
|
|
|
73
80
|
}
|
|
74
81
|
|
|
75
82
|
// Look up this DID's update hash in the CAS Announcement
|
|
76
|
-
|
|
83
|
+
// Announcement values are base64urlnopad per spec — convert to hex for map lookup
|
|
84
|
+
const updateHashEncoded = casAnnouncement[did];
|
|
77
85
|
|
|
78
86
|
// If no entry for this DID, this announcement doesn't contain an update for us — skip
|
|
79
|
-
if(!
|
|
87
|
+
if(!updateHashEncoded) {
|
|
80
88
|
continue;
|
|
81
89
|
}
|
|
82
90
|
|
|
91
|
+
const updateHash = encode(decode(updateHashEncoded, 'base64urlnopad'), 'hex');
|
|
92
|
+
|
|
83
93
|
// Look up the signed update in sidecar updateMap
|
|
84
94
|
const signedUpdate = sidecar.updateMap.get(updateHash);
|
|
85
95
|
|
|
@@ -102,99 +112,45 @@ export class CASBeacon extends Beacon {
|
|
|
102
112
|
/**
|
|
103
113
|
* Broadcasts a CAS Beacon signal to the Bitcoin network.
|
|
104
114
|
*
|
|
105
|
-
* Creates a CAS Announcement mapping the DID to the update hash,
|
|
106
|
-
*
|
|
107
|
-
*
|
|
115
|
+
* Creates a CAS Announcement mapping the DID to the update hash, broadcasts the hash of the
|
|
116
|
+
* announcement via OP_RETURN, and optionally publishes the announcement off-chain via the
|
|
117
|
+
* supplied `casPublish` callback. UTXO selection, PSBT construction, fee estimation, signing,
|
|
118
|
+
* and broadcast are delegated to {@link Beacon.buildSignAndBroadcast}.
|
|
108
119
|
*
|
|
109
120
|
* @param {SignedBTCR2Update} signedUpdate The signed BTCR2 update to broadcast.
|
|
110
121
|
* @param {KeyBytes} secretKey The secret key for signing the Bitcoin transaction.
|
|
111
122
|
* @param {BitcoinConnection} bitcoin The Bitcoin network connection.
|
|
123
|
+
* @param {CASBroadcastOptions} [options] Optional broadcast configuration, including a
|
|
124
|
+
* `casPublish` callback to publish the announcement off-chain and a `feeEstimator`.
|
|
112
125
|
* @returns {Promise<SignedBTCR2Update>} The signed update that was broadcast.
|
|
113
|
-
* @throws {
|
|
126
|
+
* @throws {BeaconError} if the bitcoin address is invalid, unfunded, or UTXO cannot cover the fee.
|
|
114
127
|
*/
|
|
115
128
|
async broadcastSignal(
|
|
116
129
|
signedUpdate: SignedBTCR2Update,
|
|
117
130
|
secretKey: KeyBytes,
|
|
118
|
-
bitcoin: BitcoinConnection
|
|
131
|
+
bitcoin: BitcoinConnection,
|
|
132
|
+
options?: CASBroadcastOptions
|
|
119
133
|
): Promise<SignedBTCR2Update> {
|
|
120
134
|
// Extract the DID from the beacon service id (strip the #fragment)
|
|
121
135
|
const did = this.service.id.split('#')[0];
|
|
122
136
|
|
|
123
|
-
// Hash the signed update (
|
|
137
|
+
// Hash the signed update (base64urlnopad for the CAS Announcement entry per spec)
|
|
124
138
|
const updateHash = canonicalHash(signedUpdate);
|
|
125
139
|
|
|
126
140
|
// Create the CAS Announcement mapping this DID to its update hash
|
|
127
141
|
const casAnnouncement = { [did]: updateHash };
|
|
128
142
|
|
|
129
|
-
// TODO: Publish CAS Announcement to content-addressed store (e.g., IPFS via Helia)
|
|
130
|
-
|
|
131
143
|
// Canonicalize and hash the CAS Announcement for the OP_RETURN output
|
|
132
144
|
const announcementHash = hash(canonicalize(casAnnouncement));
|
|
133
145
|
|
|
134
|
-
//
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
// Query the Bitcoin network for UTXOs associated with the bitcoinAddress
|
|
138
|
-
const utxos = await bitcoin.rest.address.getUtxos(bitcoinAddress);
|
|
139
|
-
|
|
140
|
-
// If no utxos are found, throw an error indicating the address is unfunded.
|
|
141
|
-
if(!utxos.length) {
|
|
142
|
-
throw new CASBeaconError(
|
|
143
|
-
'No UTXOs found, please fund address!',
|
|
144
|
-
'UNFUNDED_BEACON_ADDRESS', { bitcoinAddress }
|
|
145
|
-
);
|
|
146
|
-
}
|
|
146
|
+
// Delegate UTXO selection, PSBT construction, fee estimation, signing, and broadcast
|
|
147
|
+
await this.buildSignAndBroadcast(announcementHash, secretKey, bitcoin, options);
|
|
147
148
|
|
|
148
|
-
//
|
|
149
|
-
|
|
150
|
-
(
|
|
151
|
-
).shift();
|
|
152
|
-
|
|
153
|
-
// If no utxos are found, throw an error.
|
|
154
|
-
if(!utxo) {
|
|
155
|
-
throw new CASBeaconError(
|
|
156
|
-
'Beacon bitcoin address unfunded or utxos unconfirmed.',
|
|
157
|
-
'UNFUNDED_BEACON_ADDRESS', { bitcoinAddress }
|
|
158
|
-
);
|
|
149
|
+
// Publish CAS Announcement to content-addressed store if callback provided
|
|
150
|
+
if(options?.casPublish) {
|
|
151
|
+
await options.casPublish(casAnnouncement);
|
|
159
152
|
}
|
|
160
153
|
|
|
161
|
-
// Get the previous tx to the utxo being spent
|
|
162
|
-
const prevTx = await bitcoin.rest.transaction.getHex(utxo.txid);
|
|
163
|
-
|
|
164
|
-
// Construct a spend transaction
|
|
165
|
-
const spendTx = new Psbt({ network: bitcoin.data })
|
|
166
|
-
// Spend tx contains the utxo as its input
|
|
167
|
-
.addInput({
|
|
168
|
-
hash : utxo.txid,
|
|
169
|
-
index : utxo.vout,
|
|
170
|
-
nonWitnessUtxo : hexToBytes(prevTx)
|
|
171
|
-
})
|
|
172
|
-
// Add a change output minus a fee of 500 sats
|
|
173
|
-
// TODO: calculate fee based on transaction vsize and current fee rates
|
|
174
|
-
.addOutput({ address: bitcoinAddress, value: BigInt(utxo.value) - BigInt(500) })
|
|
175
|
-
// Add an OP_RETURN output containing the CAS Announcement hash
|
|
176
|
-
.addOutput({ script: script.compile([opcodes.OP_RETURN, announcementHash]), value: 0n });
|
|
177
|
-
|
|
178
|
-
// Construct a key pair and PSBT signer from the secret key
|
|
179
|
-
const keyPair = SchnorrKeyPair.fromSecret(secretKey);
|
|
180
|
-
const signer = {
|
|
181
|
-
publicKey : keyPair.publicKey.compressed,
|
|
182
|
-
sign : (hash: Uint8Array) => keyPair.secretKey.sign(hash, { scheme: 'ecdsa' }),
|
|
183
|
-
};
|
|
184
|
-
|
|
185
|
-
// Sign 0th input, finalize extract to hex in prep for broadcast
|
|
186
|
-
const signedTx = spendTx.signInput(0, signer)
|
|
187
|
-
.finalizeAllInputs()
|
|
188
|
-
.extractTransaction()
|
|
189
|
-
.toHex();
|
|
190
|
-
|
|
191
|
-
// Broadcast spendTx to the Bitcoin network.
|
|
192
|
-
const txid = await bitcoin.rest.transaction.send(signedTx);
|
|
193
|
-
|
|
194
|
-
// Log the txid of the broadcasted transaction
|
|
195
|
-
console.info(`CAS Beacon Signal Broadcasted with txid: ${txid}`);
|
|
196
|
-
|
|
197
|
-
// Return the signed update
|
|
198
154
|
return signedUpdate;
|
|
199
155
|
}
|
|
200
156
|
}
|
package/src/core/beacon/error.ts
CHANGED
|
@@ -6,18 +6,6 @@ export class BeaconError extends MethodError {
|
|
|
6
6
|
}
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
export class BeaconCoordinatorError extends MethodError {
|
|
10
|
-
constructor(message: string, type: string = 'BeaconCoordinatorError', data?: Record<string, any>) {
|
|
11
|
-
super(message, type, data);
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export class BeaconParticipantError extends MethodError {
|
|
16
|
-
constructor(message: string, type: string = 'BeaconParticipantError', data?: Record<string, any>) {
|
|
17
|
-
super(message, type, data);
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
9
|
export class SingletonBeaconError extends MethodError {
|
|
22
10
|
constructor(message: string, type: string = 'SingletonBeaconError', data?: Record<string, any>) {
|
|
23
11
|
super(message, type, data);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { MethodError } from '@did-btcr2/common';
|
|
2
|
-
import { Beacon } from './beacon.js';
|
|
2
|
+
import type { Beacon } from './beacon.js';
|
|
3
3
|
import { CASBeacon } from './cas-beacon.js';
|
|
4
|
-
import { BeaconService } from './interfaces.js';
|
|
4
|
+
import type { BeaconService } from './interfaces.js';
|
|
5
5
|
import { SingletonBeacon } from './singleton-beacon.js';
|
|
6
6
|
import { SMTBeacon } from './smt-beacon.js';
|
|
7
7
|
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Estimates the fee (in satoshis) for a transaction of a given virtual size.
|
|
3
|
+
*
|
|
4
|
+
* Beacons delegate fee calculation to a `FeeEstimator` so that callers can
|
|
5
|
+
* plug in different strategies: static fee rates for tests/regtest, mempool
|
|
6
|
+
* APIs for mainnet, Bitcoin Core `estimatesmartfee` RPC for full-node setups,
|
|
7
|
+
* etc.
|
|
8
|
+
*
|
|
9
|
+
* Implementations return the **total fee in satoshis** for a transaction of
|
|
10
|
+
* the given virtual size (`vsize`). Callers pass the vsize; the estimator
|
|
11
|
+
* decides the fee rate and computes the total.
|
|
12
|
+
*/
|
|
13
|
+
export interface FeeEstimator {
|
|
14
|
+
/**
|
|
15
|
+
* Estimate the total fee in satoshis for a transaction of the given vsize.
|
|
16
|
+
* @param vsize Transaction virtual size in vbytes.
|
|
17
|
+
* @returns Total fee in satoshis.
|
|
18
|
+
*/
|
|
19
|
+
estimateFee(vsize: number): Promise<bigint>;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Fee estimator that returns a fixed fee rate regardless of network conditions.
|
|
24
|
+
*
|
|
25
|
+
* Suitable for:
|
|
26
|
+
* - Tests (deterministic outputs)
|
|
27
|
+
* - Regtest (no real fee market)
|
|
28
|
+
* - Environments where a fee rate is supplied out-of-band
|
|
29
|
+
*
|
|
30
|
+
* For mainnet production use, prefer a dynamic estimator that queries current
|
|
31
|
+
* network conditions (mempool APIs, Bitcoin Core RPC).
|
|
32
|
+
*/
|
|
33
|
+
export class StaticFeeEstimator implements FeeEstimator {
|
|
34
|
+
readonly satsPerVbyte: number;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* @param satsPerVbyte Fee rate in satoshis per virtual byte. Default: 5 sat/vB.
|
|
38
|
+
*/
|
|
39
|
+
constructor(satsPerVbyte: number = 5) {
|
|
40
|
+
if(satsPerVbyte < 0 || !Number.isFinite(satsPerVbyte)) {
|
|
41
|
+
throw new Error(`Invalid satsPerVbyte: ${satsPerVbyte}`);
|
|
42
|
+
}
|
|
43
|
+
this.satsPerVbyte = satsPerVbyte;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
async estimateFee(vsize: number): Promise<bigint> {
|
|
47
|
+
if(vsize < 0 || !Number.isFinite(vsize)) {
|
|
48
|
+
throw new Error(`Invalid vsize: ${vsize}`);
|
|
49
|
+
}
|
|
50
|
+
return BigInt(Math.ceil(vsize * this.satsPerVbyte));
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { RawTransactionRest, RawTransactionV2 } from '@did-btcr2/bitcoin';
|
|
2
|
-
import { UnixTimestamp } from '@did-btcr2/common';
|
|
3
|
-
import { DidServiceEndpoint, DidService } from '@web5/dids';
|
|
1
|
+
import type { RawTransactionRest, RawTransactionV2 } from '@did-btcr2/bitcoin';
|
|
2
|
+
import type { UnixTimestamp } from '@did-btcr2/common';
|
|
3
|
+
import type { DidServiceEndpoint, DidService } from '@web5/dids';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Represents a Beacon Service, which extends a W3C DID Service by setting serviceEndpoint
|
|
@@ -64,4 +64,13 @@ export interface BeaconSignal {
|
|
|
64
64
|
* Metadata about the block containing the Beacon Signal.
|
|
65
65
|
*/
|
|
66
66
|
blockMetadata: BlockMetadata;
|
|
67
|
-
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Callback for publishing a CAS Announcement to a content-addressed store.
|
|
71
|
+
* The method package defines this type; the api layer provides the implementation
|
|
72
|
+
* (e.g., via CasApi.publish backed by IPFS/Helia).
|
|
73
|
+
*
|
|
74
|
+
* @param announcement The CAS Announcement object (DID → update hash mapping).
|
|
75
|
+
*/
|
|
76
|
+
export type CasPublishFn = (announcement: Record<string, string>) => Promise<void>;
|
|
@@ -1,17 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type {
|
|
2
2
|
BitcoinConnection,
|
|
3
3
|
BlockV3,
|
|
4
|
+
RawTransactionV2} from '@did-btcr2/bitcoin';
|
|
5
|
+
import {
|
|
4
6
|
GENESIS_TX_ID,
|
|
5
|
-
RawTransactionV2,
|
|
6
7
|
TXIN_WITNESS_COINBASE
|
|
7
8
|
} from '@did-btcr2/bitcoin';
|
|
8
9
|
import { ResolveError } from '@did-btcr2/common';
|
|
9
|
-
import { BeaconService, BeaconSignal } from './interfaces.js';
|
|
10
|
+
import type { BeaconService, BeaconSignal } from './interfaces.js';
|
|
10
11
|
import { BeaconUtils } from './utils.js';
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
* Static utility class for discovering Beacon Signals on the Bitcoin blockchain.
|
|
14
|
-
* Extracted from
|
|
15
|
+
* Extracted from `Resolver` for single-responsibility and independent testability.
|
|
15
16
|
*
|
|
16
17
|
* @class BeaconSignalDiscovery
|
|
17
18
|
*/
|
|
@@ -1,14 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { hexToBytes } from '@noble/hashes/utils';
|
|
6
|
-
import { opcodes, Psbt, script } from 'bitcoinjs-lib';
|
|
1
|
+
import type { BitcoinConnection } from '@did-btcr2/bitcoin';
|
|
2
|
+
import type { KeyBytes } from '@did-btcr2/common';
|
|
3
|
+
import { canonicalize, hash } from '@did-btcr2/common';
|
|
4
|
+
import type { SignedBTCR2Update } from '@did-btcr2/cryptosuite';
|
|
7
5
|
import type { BeaconProcessResult, DataNeed } from '../resolver.js';
|
|
8
|
-
import { SidecarData } from '../types.js';
|
|
6
|
+
import type { SidecarData } from '../types.js';
|
|
7
|
+
import type { BroadcastOptions } from './beacon.js';
|
|
9
8
|
import { Beacon } from './beacon.js';
|
|
10
|
-
import {
|
|
11
|
-
import { BeaconService, BeaconSignal, BlockMetadata } from './interfaces.js';
|
|
9
|
+
import type { BeaconService, BeaconSignal, BlockMetadata } from './interfaces.js';
|
|
12
10
|
|
|
13
11
|
/**
|
|
14
12
|
* Implements {@link https://dcdpr.github.io/did-btcr2/terminology.html#singleton-beacon | Singleton Beacon}.
|
|
@@ -40,8 +38,8 @@ export class SingletonBeacon extends Beacon {
|
|
|
40
38
|
const needs = new Array<DataNeed>();
|
|
41
39
|
|
|
42
40
|
for(const signal of signals) {
|
|
43
|
-
//
|
|
44
|
-
const updateHash =
|
|
41
|
+
// Signal bytes are hex — matches hex-keyed sidecar maps directly
|
|
42
|
+
const updateHash = signal.signalBytes;
|
|
45
43
|
|
|
46
44
|
// Look up the signed update in sidecar updateMap
|
|
47
45
|
const signedUpdate = sidecar.updateMap.get(updateHash);
|
|
@@ -63,84 +61,26 @@ export class SingletonBeacon extends Beacon {
|
|
|
63
61
|
}
|
|
64
62
|
/**
|
|
65
63
|
* Broadcasts a SingletonBeacon signal to the Bitcoin network.
|
|
64
|
+
*
|
|
65
|
+
* The signal bytes embedded in OP_RETURN are the SHA-256 canonical hash of the signed update.
|
|
66
|
+
* UTXO selection, PSBT construction, fee estimation, signing, and broadcast are delegated to
|
|
67
|
+
* {@link Beacon.buildSignAndBroadcast}.
|
|
68
|
+
*
|
|
66
69
|
* @param {SignedBTCR2Update} signedUpdate The signed BTCR2 update to broadcast.
|
|
67
70
|
* @param {KeyBytes} secretKey The secret key for signing the Bitcoin transaction.
|
|
68
71
|
* @param {BitcoinConnection} bitcoin The Bitcoin network connection.
|
|
72
|
+
* @param {BroadcastOptions} [options] Optional broadcast configuration (e.g. fee estimator).
|
|
69
73
|
* @returns {Promise<SignedBTCR2Update>} The signed update that was broadcast.
|
|
70
|
-
* @throws {
|
|
74
|
+
* @throws {BeaconError} if the bitcoin address is invalid, unfunded, or UTXO cannot cover the fee.
|
|
71
75
|
*/
|
|
72
76
|
async broadcastSignal(
|
|
73
77
|
signedUpdate: SignedBTCR2Update,
|
|
74
78
|
secretKey: KeyBytes,
|
|
75
|
-
bitcoin: BitcoinConnection
|
|
79
|
+
bitcoin: BitcoinConnection,
|
|
80
|
+
options?: BroadcastOptions
|
|
76
81
|
): Promise<SignedBTCR2Update> {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
// Query the Bitcoin network for UTXOs associated with the bitcoinAddress
|
|
81
|
-
const utxos = await bitcoin.rest.address.getUtxos(bitcoinAddress);
|
|
82
|
-
|
|
83
|
-
// If no utxos are found, throw an error indicating the address is unfunded.
|
|
84
|
-
if(!utxos.length) {
|
|
85
|
-
throw new SingletonBeaconError(
|
|
86
|
-
'No UTXOs found, please fund address!',
|
|
87
|
-
'UNFUNDED_BEACON_ADDRESS', { bitcoinAddress }
|
|
88
|
-
);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// Sort utxos by block height and take the most recent one
|
|
92
|
-
const utxo: AddressUtxo | undefined = utxos.sort(
|
|
93
|
-
(a, b) => b.status.block_height - a.status.block_height
|
|
94
|
-
).shift();
|
|
95
|
-
|
|
96
|
-
// If no utxos are found, throw an error.
|
|
97
|
-
if(!utxo) {
|
|
98
|
-
throw new SingletonBeaconError(
|
|
99
|
-
'Beacon bitcoin address unfunded or utxos unconfirmed.',
|
|
100
|
-
'UNFUNDED_BEACON_ADDRESS', { bitcoinAddress }
|
|
101
|
-
);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// Get the previous tx to the utxo being spent
|
|
105
|
-
const prevTx = await bitcoin.rest.transaction.getHex(utxo.txid);
|
|
106
|
-
|
|
107
|
-
// Canonicalize and hash the signed update for OP_RETURN output
|
|
108
|
-
const updateHash = hash(canonicalize(signedUpdate));
|
|
109
|
-
|
|
110
|
-
// Construct a spend transaction
|
|
111
|
-
const spendTx = new Psbt({ network: bitcoin.data })
|
|
112
|
-
// Spend tx contains the utxo as its input
|
|
113
|
-
.addInput({
|
|
114
|
-
hash : utxo.txid,
|
|
115
|
-
index : utxo.vout,
|
|
116
|
-
nonWitnessUtxo : hexToBytes(prevTx)
|
|
117
|
-
})
|
|
118
|
-
// Add a change output minus a fee of 500 sats
|
|
119
|
-
// TODO: calculate fee based on transaction vsize and current fee rates
|
|
120
|
-
.addOutput({ address: bitcoinAddress, value: BigInt(utxo.value) - BigInt(500) })
|
|
121
|
-
// Add an OP_RETURN output containing the update hash
|
|
122
|
-
.addOutput({ script: script.compile([opcodes.OP_RETURN, updateHash]), value: 0n });
|
|
123
|
-
|
|
124
|
-
// Construct a key pair and PSBT signer from the secret key
|
|
125
|
-
const keyPair = SchnorrKeyPair.fromSecret(secretKey);
|
|
126
|
-
const signer = {
|
|
127
|
-
publicKey : keyPair.publicKey.compressed,
|
|
128
|
-
sign : (hash: Uint8Array) => keyPair.secretKey.sign(hash, { scheme: 'ecdsa' }),
|
|
129
|
-
};
|
|
130
|
-
|
|
131
|
-
// Sign 0th input, finalize extract to hex in prep for broadcast
|
|
132
|
-
const signedTx = spendTx.signInput(0, signer)
|
|
133
|
-
.finalizeAllInputs()
|
|
134
|
-
.extractTransaction()
|
|
135
|
-
.toHex();
|
|
136
|
-
|
|
137
|
-
// Broadcast spendTx to the Bitcoin network.
|
|
138
|
-
const txid = await bitcoin.rest.transaction.send(signedTx);
|
|
139
|
-
|
|
140
|
-
// Log the txid of the broadcasted transaction
|
|
141
|
-
console.info(`Singleton Beacon Signal Broadcasted with txid: ${txid}`);
|
|
142
|
-
|
|
143
|
-
// Return the signed update
|
|
82
|
+
const signalBytes = hash(canonicalize(signedUpdate));
|
|
83
|
+
await this.buildSignAndBroadcast(signalBytes, secretKey, bitcoin, options);
|
|
144
84
|
return signedUpdate;
|
|
145
85
|
}
|
|
146
|
-
}
|
|
86
|
+
}
|