@did-btcr2/method 0.18.1 → 0.19.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.
Files changed (262) hide show
  1. package/dist/browser.js +5217 -6057
  2. package/dist/browser.mjs +5217 -6057
  3. package/dist/cjs/core/beacon/aggregation/cohort/index.js +3 -3
  4. package/dist/cjs/core/beacon/aggregation/cohort/index.js.map +1 -1
  5. package/dist/cjs/core/beacon/aggregation/cohort/messages/base.js +1 -9
  6. package/dist/cjs/core/beacon/aggregation/cohort/messages/base.js.map +1 -1
  7. package/dist/cjs/core/beacon/aggregation/cohort/messages/keygen/cohort-advert.js +2 -1
  8. package/dist/cjs/core/beacon/aggregation/cohort/messages/keygen/cohort-advert.js.map +1 -1
  9. package/dist/cjs/core/beacon/aggregation/cohort/messages/keygen/cohort-ready.js +2 -1
  10. package/dist/cjs/core/beacon/aggregation/cohort/messages/keygen/cohort-ready.js.map +1 -1
  11. package/dist/cjs/core/beacon/aggregation/cohort/messages/keygen/opt-in-accept.js +2 -1
  12. package/dist/cjs/core/beacon/aggregation/cohort/messages/keygen/opt-in-accept.js.map +1 -1
  13. package/dist/cjs/core/beacon/aggregation/cohort/messages/keygen/opt-in.js +2 -1
  14. package/dist/cjs/core/beacon/aggregation/cohort/messages/keygen/opt-in.js.map +1 -1
  15. package/dist/cjs/core/beacon/aggregation/cohort/messages/keygen/subscribe.js +2 -1
  16. package/dist/cjs/core/beacon/aggregation/cohort/messages/keygen/subscribe.js.map +1 -1
  17. package/dist/cjs/core/beacon/aggregation/cohort/messages/sign/aggregated-nonce.js +2 -1
  18. package/dist/cjs/core/beacon/aggregation/cohort/messages/sign/aggregated-nonce.js.map +1 -1
  19. package/dist/cjs/core/beacon/aggregation/cohort/messages/sign/authorization-request.js +2 -1
  20. package/dist/cjs/core/beacon/aggregation/cohort/messages/sign/authorization-request.js.map +1 -1
  21. package/dist/cjs/core/beacon/aggregation/cohort/messages/sign/nonce-contribution.js +2 -1
  22. package/dist/cjs/core/beacon/aggregation/cohort/messages/sign/nonce-contribution.js.map +1 -1
  23. package/dist/cjs/core/beacon/aggregation/cohort/messages/sign/request-signature.js +2 -1
  24. package/dist/cjs/core/beacon/aggregation/cohort/messages/sign/request-signature.js.map +1 -1
  25. package/dist/cjs/core/beacon/aggregation/cohort/messages/sign/signature-authorization.js +2 -1
  26. package/dist/cjs/core/beacon/aggregation/cohort/messages/sign/signature-authorization.js.map +1 -1
  27. package/dist/cjs/core/beacon/aggregation/communication/adapter/nostr.js +36 -18
  28. package/dist/cjs/core/beacon/aggregation/communication/adapter/nostr.js.map +1 -1
  29. package/dist/cjs/core/beacon/aggregation/coordinator.js +14 -14
  30. package/dist/cjs/core/beacon/aggregation/coordinator.js.map +1 -1
  31. package/dist/cjs/core/beacon/aggregation/participant.js +4 -3
  32. package/dist/cjs/core/beacon/aggregation/participant.js.map +1 -1
  33. package/dist/cjs/core/beacon/aggregation/session/index.js +1 -1
  34. package/dist/cjs/core/beacon/aggregation/session/index.js.map +1 -1
  35. package/dist/cjs/core/beacon/cas-beacon.js +55 -0
  36. package/dist/cjs/core/beacon/cas-beacon.js.map +1 -0
  37. package/dist/cjs/core/beacon/factory.js +11 -10
  38. package/dist/cjs/core/beacon/factory.js.map +1 -1
  39. package/dist/cjs/core/beacon/interfaces.js +32 -0
  40. package/dist/cjs/core/beacon/interfaces.js.map +1 -0
  41. package/dist/cjs/core/beacon/singleton.js +59 -135
  42. package/dist/cjs/core/beacon/singleton.js.map +1 -1
  43. package/dist/cjs/core/beacon/smt-beacon.js +56 -0
  44. package/dist/cjs/core/beacon/smt-beacon.js.map +1 -0
  45. package/dist/cjs/core/beacon/utils.js +67 -105
  46. package/dist/cjs/core/beacon/utils.js.map +1 -1
  47. package/dist/cjs/core/identifier.js +18 -21
  48. package/dist/cjs/core/identifier.js.map +1 -1
  49. package/dist/cjs/core/interfaces.js +2 -0
  50. package/dist/cjs/core/interfaces.js.map +1 -0
  51. package/dist/cjs/core/resolve.js +511 -0
  52. package/dist/cjs/core/resolve.js.map +1 -0
  53. package/dist/cjs/{utils → core}/types.js.map +1 -1
  54. package/dist/cjs/core/{crud/update.js → update.js} +62 -52
  55. package/dist/cjs/core/update.js.map +1 -0
  56. package/dist/cjs/did-btcr2.js +109 -75
  57. package/dist/cjs/did-btcr2.js.map +1 -1
  58. package/dist/cjs/index.js +14 -15
  59. package/dist/cjs/index.js.map +1 -1
  60. package/dist/cjs/utils/appendix.js +10 -18
  61. package/dist/cjs/utils/appendix.js.map +1 -1
  62. package/dist/cjs/utils/did-document.js +51 -58
  63. package/dist/cjs/utils/did-document.js.map +1 -1
  64. package/dist/cjs/utils/general.js +1 -1
  65. package/dist/cjs/utils/general.js.map +1 -1
  66. package/dist/esm/core/beacon/aggregation/cohort/index.js +3 -3
  67. package/dist/esm/core/beacon/aggregation/cohort/index.js.map +1 -1
  68. package/dist/esm/core/beacon/aggregation/cohort/messages/base.js +1 -9
  69. package/dist/esm/core/beacon/aggregation/cohort/messages/base.js.map +1 -1
  70. package/dist/esm/core/beacon/aggregation/cohort/messages/keygen/cohort-advert.js +2 -1
  71. package/dist/esm/core/beacon/aggregation/cohort/messages/keygen/cohort-advert.js.map +1 -1
  72. package/dist/esm/core/beacon/aggregation/cohort/messages/keygen/cohort-ready.js +2 -1
  73. package/dist/esm/core/beacon/aggregation/cohort/messages/keygen/cohort-ready.js.map +1 -1
  74. package/dist/esm/core/beacon/aggregation/cohort/messages/keygen/opt-in-accept.js +2 -1
  75. package/dist/esm/core/beacon/aggregation/cohort/messages/keygen/opt-in-accept.js.map +1 -1
  76. package/dist/esm/core/beacon/aggregation/cohort/messages/keygen/opt-in.js +2 -1
  77. package/dist/esm/core/beacon/aggregation/cohort/messages/keygen/opt-in.js.map +1 -1
  78. package/dist/esm/core/beacon/aggregation/cohort/messages/keygen/subscribe.js +2 -1
  79. package/dist/esm/core/beacon/aggregation/cohort/messages/keygen/subscribe.js.map +1 -1
  80. package/dist/esm/core/beacon/aggregation/cohort/messages/sign/aggregated-nonce.js +2 -1
  81. package/dist/esm/core/beacon/aggregation/cohort/messages/sign/aggregated-nonce.js.map +1 -1
  82. package/dist/esm/core/beacon/aggregation/cohort/messages/sign/authorization-request.js +2 -1
  83. package/dist/esm/core/beacon/aggregation/cohort/messages/sign/authorization-request.js.map +1 -1
  84. package/dist/esm/core/beacon/aggregation/cohort/messages/sign/nonce-contribution.js +2 -1
  85. package/dist/esm/core/beacon/aggregation/cohort/messages/sign/nonce-contribution.js.map +1 -1
  86. package/dist/esm/core/beacon/aggregation/cohort/messages/sign/request-signature.js +2 -1
  87. package/dist/esm/core/beacon/aggregation/cohort/messages/sign/request-signature.js.map +1 -1
  88. package/dist/esm/core/beacon/aggregation/cohort/messages/sign/signature-authorization.js +2 -1
  89. package/dist/esm/core/beacon/aggregation/cohort/messages/sign/signature-authorization.js.map +1 -1
  90. package/dist/esm/core/beacon/aggregation/communication/adapter/nostr.js +36 -18
  91. package/dist/esm/core/beacon/aggregation/communication/adapter/nostr.js.map +1 -1
  92. package/dist/esm/core/beacon/aggregation/coordinator.js +14 -14
  93. package/dist/esm/core/beacon/aggregation/coordinator.js.map +1 -1
  94. package/dist/esm/core/beacon/aggregation/participant.js +4 -3
  95. package/dist/esm/core/beacon/aggregation/participant.js.map +1 -1
  96. package/dist/esm/core/beacon/aggregation/session/index.js +1 -1
  97. package/dist/esm/core/beacon/aggregation/session/index.js.map +1 -1
  98. package/dist/esm/core/beacon/cas-beacon.js +55 -0
  99. package/dist/esm/core/beacon/cas-beacon.js.map +1 -0
  100. package/dist/esm/core/beacon/factory.js +11 -10
  101. package/dist/esm/core/beacon/factory.js.map +1 -1
  102. package/dist/esm/core/beacon/interfaces.js +32 -0
  103. package/dist/esm/core/beacon/interfaces.js.map +1 -0
  104. package/dist/esm/core/beacon/singleton.js +59 -135
  105. package/dist/esm/core/beacon/singleton.js.map +1 -1
  106. package/dist/esm/core/beacon/smt-beacon.js +56 -0
  107. package/dist/esm/core/beacon/smt-beacon.js.map +1 -0
  108. package/dist/esm/core/beacon/utils.js +67 -105
  109. package/dist/esm/core/beacon/utils.js.map +1 -1
  110. package/dist/esm/core/identifier.js +18 -21
  111. package/dist/esm/core/identifier.js.map +1 -1
  112. package/dist/esm/core/interfaces.js +2 -0
  113. package/dist/esm/core/interfaces.js.map +1 -0
  114. package/dist/esm/core/resolve.js +511 -0
  115. package/dist/esm/core/resolve.js.map +1 -0
  116. package/dist/esm/{utils → core}/types.js.map +1 -1
  117. package/dist/esm/core/{crud/update.js → update.js} +62 -52
  118. package/dist/esm/core/update.js.map +1 -0
  119. package/dist/esm/did-btcr2.js +109 -75
  120. package/dist/esm/did-btcr2.js.map +1 -1
  121. package/dist/esm/index.js +14 -15
  122. package/dist/esm/index.js.map +1 -1
  123. package/dist/esm/utils/appendix.js +10 -18
  124. package/dist/esm/utils/appendix.js.map +1 -1
  125. package/dist/esm/utils/did-document.js +51 -58
  126. package/dist/esm/utils/did-document.js.map +1 -1
  127. package/dist/esm/utils/general.js +1 -1
  128. package/dist/esm/utils/general.js.map +1 -1
  129. package/dist/types/core/beacon/aggregation/cohort/index.d.ts +1 -1
  130. package/dist/types/core/beacon/aggregation/cohort/messages/base.d.ts +0 -7
  131. package/dist/types/core/beacon/aggregation/cohort/messages/base.d.ts.map +1 -1
  132. package/dist/types/core/beacon/aggregation/cohort/messages/keygen/cohort-advert.d.ts.map +1 -1
  133. package/dist/types/core/beacon/aggregation/cohort/messages/keygen/cohort-ready.d.ts.map +1 -1
  134. package/dist/types/core/beacon/aggregation/cohort/messages/keygen/opt-in-accept.d.ts.map +1 -1
  135. package/dist/types/core/beacon/aggregation/cohort/messages/keygen/opt-in.d.ts.map +1 -1
  136. package/dist/types/core/beacon/aggregation/cohort/messages/keygen/subscribe.d.ts.map +1 -1
  137. package/dist/types/core/beacon/aggregation/cohort/messages/sign/aggregated-nonce.d.ts.map +1 -1
  138. package/dist/types/core/beacon/aggregation/cohort/messages/sign/authorization-request.d.ts.map +1 -1
  139. package/dist/types/core/beacon/aggregation/cohort/messages/sign/nonce-contribution.d.ts.map +1 -1
  140. package/dist/types/core/beacon/aggregation/cohort/messages/sign/request-signature.d.ts.map +1 -1
  141. package/dist/types/core/beacon/aggregation/cohort/messages/sign/signature-authorization.d.ts.map +1 -1
  142. package/dist/types/core/beacon/aggregation/communication/adapter/nostr.d.ts +13 -5
  143. package/dist/types/core/beacon/aggregation/communication/adapter/nostr.d.ts.map +1 -1
  144. package/dist/types/core/beacon/aggregation/coordinator.d.ts +17 -29
  145. package/dist/types/core/beacon/aggregation/coordinator.d.ts.map +1 -1
  146. package/dist/types/core/beacon/aggregation/participant.d.ts.map +1 -1
  147. package/dist/types/core/beacon/cas-beacon.d.ts +47 -0
  148. package/dist/types/core/beacon/cas-beacon.d.ts.map +1 -0
  149. package/dist/types/core/beacon/factory.d.ts +5 -4
  150. package/dist/types/core/beacon/factory.d.ts.map +1 -1
  151. package/dist/types/core/beacon/interfaces.d.ts +98 -0
  152. package/dist/types/core/beacon/interfaces.d.ts.map +1 -0
  153. package/dist/types/core/beacon/singleton.d.ts +22 -65
  154. package/dist/types/core/beacon/singleton.d.ts.map +1 -1
  155. package/dist/types/core/beacon/smt-beacon.d.ts +48 -0
  156. package/dist/types/core/beacon/smt-beacon.d.ts.map +1 -0
  157. package/dist/types/core/beacon/utils.d.ts +19 -97
  158. package/dist/types/core/beacon/utils.d.ts.map +1 -1
  159. package/dist/types/core/identifier.d.ts.map +1 -1
  160. package/dist/types/core/interfaces.d.ts +94 -0
  161. package/dist/types/core/interfaces.d.ts.map +1 -0
  162. package/dist/types/core/resolve.d.ts +105 -0
  163. package/dist/types/core/resolve.d.ts.map +1 -0
  164. package/dist/types/core/types.d.ts +71 -0
  165. package/dist/types/core/types.d.ts.map +1 -0
  166. package/dist/types/core/{crud/update.d.ts → update.d.ts} +21 -20
  167. package/dist/types/core/update.d.ts.map +1 -0
  168. package/dist/types/did-btcr2.d.ts +45 -57
  169. package/dist/types/did-btcr2.d.ts.map +1 -1
  170. package/dist/types/index.d.ts +14 -15
  171. package/dist/types/index.d.ts.map +1 -1
  172. package/dist/types/utils/appendix.d.ts +5 -10
  173. package/dist/types/utils/appendix.d.ts.map +1 -1
  174. package/dist/types/utils/did-document-builder.d.ts +1 -1
  175. package/dist/types/utils/did-document-builder.d.ts.map +1 -1
  176. package/dist/types/utils/did-document.d.ts +31 -29
  177. package/dist/types/utils/did-document.d.ts.map +1 -1
  178. package/package.json +6 -6
  179. package/src/core/beacon/aggregation/cohort/index.ts +3 -3
  180. package/src/core/beacon/aggregation/cohort/messages/base.ts +1 -12
  181. package/src/core/beacon/aggregation/cohort/messages/keygen/cohort-advert.ts +2 -2
  182. package/src/core/beacon/aggregation/cohort/messages/keygen/cohort-ready.ts +2 -2
  183. package/src/core/beacon/aggregation/cohort/messages/keygen/opt-in-accept.ts +2 -2
  184. package/src/core/beacon/aggregation/cohort/messages/keygen/opt-in.ts +2 -2
  185. package/src/core/beacon/aggregation/cohort/messages/keygen/subscribe.ts +2 -2
  186. package/src/core/beacon/aggregation/cohort/messages/sign/aggregated-nonce.ts +2 -2
  187. package/src/core/beacon/aggregation/cohort/messages/sign/authorization-request.ts +2 -2
  188. package/src/core/beacon/aggregation/cohort/messages/sign/nonce-contribution.ts +2 -2
  189. package/src/core/beacon/aggregation/cohort/messages/sign/request-signature.ts +2 -2
  190. package/src/core/beacon/aggregation/cohort/messages/sign/signature-authorization.ts +2 -2
  191. package/src/core/beacon/aggregation/communication/adapter/nostr.ts +43 -21
  192. package/src/core/beacon/aggregation/coordinator.ts +41 -29
  193. package/src/core/beacon/aggregation/participant.ts +4 -3
  194. package/src/core/beacon/aggregation/session/index.ts +1 -1
  195. package/src/core/beacon/cas-beacon.ts +67 -0
  196. package/src/core/beacon/factory.ts +13 -15
  197. package/src/core/beacon/interfaces.ts +124 -0
  198. package/src/core/beacon/singleton.ts +75 -145
  199. package/src/core/beacon/smt-beacon.ts +70 -0
  200. package/src/core/beacon/utils.ts +80 -170
  201. package/src/core/identifier.ts +21 -24
  202. package/src/core/interfaces.ts +101 -0
  203. package/src/core/resolve.ts +707 -0
  204. package/src/core/types.ts +78 -0
  205. package/src/core/{crud/update.ts → update.ts} +75 -68
  206. package/src/did-btcr2.ts +152 -92
  207. package/src/index.ts +14 -24
  208. package/src/utils/appendix.ts +18 -22
  209. package/src/utils/did-document-builder.ts +1 -1
  210. package/src/utils/did-document.ts +67 -71
  211. package/src/utils/general.ts +1 -1
  212. package/dist/cjs/core/beacon/cid-aggregate.js +0 -116
  213. package/dist/cjs/core/beacon/cid-aggregate.js.map +0 -1
  214. package/dist/cjs/core/beacon/smt-aggregate.js +0 -126
  215. package/dist/cjs/core/beacon/smt-aggregate.js.map +0 -1
  216. package/dist/cjs/core/crud/deactivate.js +0 -14
  217. package/dist/cjs/core/crud/deactivate.js.map +0 -1
  218. package/dist/cjs/core/crud/read.js +0 -679
  219. package/dist/cjs/core/crud/read.js.map +0 -1
  220. package/dist/cjs/core/crud/update.js.map +0 -1
  221. package/dist/cjs/interfaces/beacon.js +0 -41
  222. package/dist/cjs/interfaces/beacon.js.map +0 -1
  223. package/dist/cjs/interfaces/crud.js +0 -2
  224. package/dist/cjs/interfaces/crud.js.map +0 -1
  225. package/dist/esm/core/beacon/cid-aggregate.js +0 -116
  226. package/dist/esm/core/beacon/cid-aggregate.js.map +0 -1
  227. package/dist/esm/core/beacon/smt-aggregate.js +0 -126
  228. package/dist/esm/core/beacon/smt-aggregate.js.map +0 -1
  229. package/dist/esm/core/crud/deactivate.js +0 -14
  230. package/dist/esm/core/crud/deactivate.js.map +0 -1
  231. package/dist/esm/core/crud/read.js +0 -679
  232. package/dist/esm/core/crud/read.js.map +0 -1
  233. package/dist/esm/core/crud/update.js.map +0 -1
  234. package/dist/esm/interfaces/beacon.js +0 -41
  235. package/dist/esm/interfaces/beacon.js.map +0 -1
  236. package/dist/esm/interfaces/crud.js +0 -2
  237. package/dist/esm/interfaces/crud.js.map +0 -1
  238. package/dist/types/core/beacon/cid-aggregate.d.ts +0 -102
  239. package/dist/types/core/beacon/cid-aggregate.d.ts.map +0 -1
  240. package/dist/types/core/beacon/smt-aggregate.d.ts +0 -111
  241. package/dist/types/core/beacon/smt-aggregate.d.ts.map +0 -1
  242. package/dist/types/core/crud/deactivate.d.ts +0 -13
  243. package/dist/types/core/crud/deactivate.d.ts.map +0 -1
  244. package/dist/types/core/crud/read.d.ts +0 -334
  245. package/dist/types/core/crud/read.d.ts.map +0 -1
  246. package/dist/types/core/crud/update.d.ts.map +0 -1
  247. package/dist/types/interfaces/beacon.d.ts +0 -116
  248. package/dist/types/interfaces/beacon.d.ts.map +0 -1
  249. package/dist/types/interfaces/crud.d.ts +0 -32
  250. package/dist/types/interfaces/crud.d.ts.map +0 -1
  251. package/dist/types/utils/types.d.ts +0 -38
  252. package/dist/types/utils/types.d.ts.map +0 -1
  253. package/src/canonicalize.d.ts +0 -6
  254. package/src/core/beacon/cid-aggregate.ts +0 -153
  255. package/src/core/beacon/smt-aggregate.ts +0 -135
  256. package/src/core/crud/deactivate.ts +0 -13
  257. package/src/core/crud/read.ts +0 -948
  258. package/src/interfaces/beacon.ts +0 -137
  259. package/src/interfaces/crud.ts +0 -33
  260. package/src/utils/types.ts +0 -41
  261. /package/dist/cjs/{utils → core}/types.js +0 -0
  262. /package/dist/esm/{utils → core}/types.js +0 -0
@@ -1,183 +1,114 @@
1
- import { AddressUtxo, BitcoinNetworkConnection, RawTransactionRest, RawTransactionV2, TxOut, Vout } from '@did-btcr2/bitcoin';
2
- import { DidUpdatePayload, INVALID_SIDECAR_DATA, LATE_PUBLISHING_ERROR, SingletonBeaconError } from '@did-btcr2/common';
1
+ import { AddressUtxo, BitcoinNetworkConnection } from '@did-btcr2/bitcoin';
2
+ import { HexString, INVALID_SIDECAR_DATA, MethodError, MISSING_UPDATE_DATA, SingletonBeaconError } from '@did-btcr2/common';
3
+ import { BTCR2SignedUpdate } from '@did-btcr2/cryptosuite';
3
4
  import { CompressedSecp256k1PublicKey } from '@did-btcr2/keypair';
4
5
  import { Kms, Signer } from '@did-btcr2/kms';
5
6
  import { opcodes, Psbt, script } from 'bitcoinjs-lib';
6
7
  import { base58btc } from 'multiformats/bases/base58';
7
- import { Beacon, BeaconService, BeaconSignal } from '../../interfaces/beacon.js';
8
- import { BeaconSidecarData, Metadata, SignalsMetadata, SingletonSidecar } from '../../utils/types.js';
9
- import { Appendix } from '../../utils/appendix.js';
8
+ import { canonicalization } from '../../did-btcr2.js';
10
9
  import { Identifier } from '../identifier.js';
11
-
12
- const bitcoin = new BitcoinNetworkConnection();
10
+ import { SidecarData } from '../types.js';
11
+ import { AggregateBeacon, BeaconService, BeaconSignal, BlockMetadata } from './interfaces.js';
13
12
 
14
13
  /**
15
- * Implements {@link https://dcdpr.github.io/did-btcr2/#singleton-beacon | 5.1 Singleton Beacon}.
16
- *
17
- * A Singleton Beacon enables a single entity to independently post a DID Update Payload in a Beacon Signal. Its is a
18
- * Beacon that can be used to publish a single DID Update Payload targeting a single DID document. The serviceEndpoint
19
- * for this Beacon Type is a Bitcoin address represented as a URI following the BIP21 scheme. It is recommended that
20
- * this Bitcoin address be under the sole control of the DID controller. How the Bitcoin address and the cryptographic
21
- * material that controls it are generated is left to the implementation.
14
+ * Implements {@link https://dcdpr.github.io/did-btcr2/terminology.html#singleton-beacon | Singleton Beacon}.
22
15
  *
23
16
  * @class SingletonBeacon
24
17
  * @type {SingletonBeacon}
25
- * @extends {Beacon}
18
+ * @extends {AggregateBeacon}
26
19
  */
27
- export class SingletonBeacon extends Beacon {
20
+ export class SingletonBeacon extends AggregateBeacon {
28
21
 
29
22
  /**
30
23
  * Creates an instance of SingletonBeacon.
31
24
  * @param {BeaconService} service The Beacon service.
32
- * @param {?BeaconSidecarData} [sidecar] Optional sidecar data.
25
+ * @param {?BeaconSidecarData} sidecar The SingletonBeacon sidecar data.
33
26
  */
34
- constructor(service: BeaconService, sidecar?: BeaconSidecarData<SingletonSidecar>) {
35
- super({ ...service, type: 'SingletonBeacon' }, sidecar);
36
- }
37
-
38
- /**
39
- * Get the Beacon service.
40
- * @readonly
41
- * @type {BeaconService} The Beacon service.
42
- */
43
- get service(): BeaconService {
44
- return {
45
- type : this.type,
46
- id : this.id,
47
- serviceEndpoint : this.serviceEndpoint
48
- };
27
+ constructor(
28
+ service: BeaconService,
29
+ signals: Array<BeaconSignal>,
30
+ sidecar: SidecarData,
31
+ bitcoin?: BitcoinNetworkConnection
32
+ ) {
33
+ super({ ...service, type: 'SingletonBeacon' }, signals, sidecar, bitcoin);
49
34
  }
50
35
 
51
36
  /**
52
- * Implements {@link https://dcdpr.github.io/did-btcr2/#establish-singleton-beacon | 5.1.1 Establish Singleton Beacon}.
53
- *
54
- * Static, convenience method for establishing a Beacon object.
55
- *
56
- * A Singleton Beacon is a Beacon that can be used to publish a single DID Update Payload targeting a single DID
57
- * document. The serviceEndpoint for this Beacon Type is a Bitcoin address represented as a URI following the BIP21
58
- * scheme. It is RECOMMENDED that this Bitcoin address be under the sole control of the DID controller. How the
59
- * Bitcoin address and the cryptographic material that controls it are generated is left to the implementation.
60
- * The Establish Singleton Beacon algorithm takes in a Bitcoin address and a serviceId and returns a Singleton Beacon service.
61
- * It returns a SignletonBeacon object with the given id, type, and serviceEndpoint.
62
- *
37
+ * Static, convenience method for establishing a CASBeacon object.
63
38
  * @param {string} service The Beacon service.
64
- * @param {BeaconSidecarData<SingletonSidecar>} sidecar The sidecar data.
39
+ * @param {SidecarData} sidecar The sidecar data.
65
40
  * @returns {SingletonBeacon} The Singleton Beacon.
66
41
  */
67
- public static establish(service: BeaconService, sidecar: BeaconSidecarData<SingletonSidecar>): SingletonBeacon {
68
- return new SingletonBeacon(service, sidecar);
42
+ static establish(service: BeaconService, signals: Array<BeaconSignal>, sidecar: SidecarData): SingletonBeacon {
43
+ return new SingletonBeacon(service, signals, sidecar);
69
44
  }
70
45
 
71
46
  /**
72
- * TODO: Figure out if this is necessary or not.
73
- * @param {string} didUpdatePayload The DID Update Payload to generate the signal for.
47
+ * Generates a Beacon Signal for a Singleton Beacon Service.
48
+ * @param {HexString} updateHash The update hash to be included in the Beacon Signal.
74
49
  * @returns {BeaconSignal} The generated signal.
75
50
  * @throws {MethodError} if the signal is invalid.
76
51
  */
77
- public generateSignal(didUpdatePayload: string): BeaconSignal {
78
- throw new Error('Method not implemented.' + didUpdatePayload);
52
+ generateSignal(updateHash: HexString): BeaconSignal {
53
+ throw new MethodError('Method not implemented.', `METHOD_NOT_IMPLEMENTED`, {updateHash});
79
54
  }
80
55
 
81
56
  /**
82
- * TODO: Finish implementation per spec
83
- *
84
- * Implements {@link https://dcdpr.github.io/did-btcr2/#process-singleton-beacon-signal | 5.1.3 Process Singleton Beacon Signal}.
85
- * See {@link Beacon.processSignal | Abstract Beacon Interface Method processSignal} for more details.
86
- *
87
- * The Process Singleton Beacon Signal algorithm is called by the Process Beacon Signals algorithm as part of the Read
88
- * operation. It takes a Bitcoin transaction representing a Beacon Signal and optional signalSidecarData containing
89
- * any sidecar data provided to the resolver for the Beacon Signal identified by the Bitcoin transaction identifier.
90
- * It returns the DID Update payload announced by the Beacon Signal or throws an error.
91
- *
92
- * @param {RawTransactionV2} signal Bitcoin transaction representing a Beacon Signal.
93
- * @param {SignalsMetadata} signalsMetadata: SignalsMetadata Optional sidecar data for the Beacon Signal.
94
- * @returns {Promise<DidUpdatePayload | undefined>} The DID Update payload announced by the Beacon Signal.
95
- * @throws {DidError} if the signalTx is invalid or the signalSidecarData is invalid.
57
+ * Processes an array of Beacon Signals associated with a Singleton Beacon Service.
58
+ * @returns {Promise<BTCR2SignedUpdate | undefined>} The DID Update payload announced by the Beacon Signal.
59
+ * @throws {SingletonBeaconError} if the signalTx is invalid or the signalSidecarData is invalid.
96
60
  */
97
- public async processSignal(signal: RawTransactionV2 | RawTransactionRest, signalsMetadata: SignalsMetadata): Promise<DidUpdatePayload | undefined> {
98
- // 1. Initialize a txOut variable to the 0th transaction output of the tx.
99
- const output = signal.vout.filter((vout) => ((vout as Vout)['scriptpubkey_asm'] as string || (vout as TxOut)['scriptPubKey'].asm as string).includes('OP_RETURN'))?.[0];
100
- if(!output) {
101
- throw new SingletonBeaconError('No OP_RETURN output found in transaction outputs.', 'NO_OP_RETURN', { signal });
102
- }
103
- const outputMap = new Map(Object.entries(output));
61
+ async processSignals(): Promise<Array<[BTCR2SignedUpdate, BlockMetadata]>> {
62
+ // Initialize an empty array to hold the BTCR2 signed updates
63
+ const updates = new Array<[BTCR2SignedUpdate, BlockMetadata]>();
104
64
 
105
- // 2. Set didUpdatePayload to null.
106
- let didUpdatePayload: DidUpdatePayload | undefined = undefined;
65
+ // Loop through each signal in this.signals
66
+ for(const signal of this.signals || []) {
67
+ // Grab the beacon signal bytes hash from the signal
68
+ const updateHash = signal.signalBytes;
107
69
 
108
- // 3. Check txout is of the format [OP_RETURN, OP_PUSH32, <32bytes>], if not, then return didUpdatePayload.
109
- // The Bitcoin transaction is not a Beacon Signal.
110
- const UPDATE_PAYLOAD_HASH = (outputMap.get('scriptpubkey_asm') ?? outputMap.get('scriptPubKey').asm).split(' ').last() as string;
111
- if(!UPDATE_PAYLOAD_HASH) {
112
- return undefined;
113
- }
114
- // 4. Set hashBytes to the 32 bytes in the txout.
115
- const hashBytes = JSON.canonicalization.encode(Buffer.fromHex(UPDATE_PAYLOAD_HASH), 'base58');
116
-
117
- // Convert signalsMetadata to a Map for easier access
118
- const signalsMetadataMap = new Map<string, Metadata>(Object.entries(signalsMetadata));
70
+ // Use the updateHash as the sidecar data lookup key to retrieve the btcr2 update
71
+ const signedUpdate = this.sidecar.updateMap.get(updateHash);
119
72
 
120
- // 5. If signalsMetadata:
121
- if (signalsMetadata) {
122
- // 5.1 Set didUpdatePayload to signalsMetadata.updatePayload
123
- didUpdatePayload = signalsMetadataMap.get(signal.txid)?.didUpdate;
124
-
125
- if(!didUpdatePayload) {
126
- throw new SingletonBeaconError('Update Payload not found in signal metadata.', 'PROCESS_SIGNAL_ERROR');
73
+ // If no btcr2 update is found in sidecar data maps, throw missingUpdateData error.
74
+ if(!signedUpdate) {
75
+ throw new SingletonBeaconError(
76
+ `BTCR2 Signed Update not found for update hash ${updateHash}.`,
77
+ MISSING_UPDATE_DATA, signal
78
+ );
127
79
  }
128
80
 
129
- // 5.2 Set updateHashBytes to the result of passing didUpdatePayload to the JSON Canonicalization and Hash algorithm.
130
- const updateHashBytes = await JSON.canonicalization.process(didUpdatePayload, 'base58');
81
+ // Canonicalize, hash and encode to base58 the signed update object found in sidecar or CAS
82
+ const encodedUpdate = canonicalization.process(signedUpdate, { encoding: 'base58' });
83
+
84
+ // Encode the signal bytes hex string to base58
85
+ const signalBytes = base58btc.encode(Buffer.from(updateHash, 'hex'));
131
86
 
132
- // 5.3 If updateHashBytes does not equal hashBytes, MUST throw an invalidSidecarData error.
133
- if (updateHashBytes !== hashBytes) {
87
+ // Check for mismatch between found sidecar/cas update hash and onchain beacon signal hash
88
+ if (encodedUpdate !== signalBytes) {
89
+ // If mismatch, throw invalidSidecarData error.
134
90
  throw new SingletonBeaconError(
135
- `Hash mismatch: updateHashBytes ${updateHashBytes} !== hashBytes ${hashBytes}.`,
136
- INVALID_SIDECAR_DATA,
137
- { UPDATE_PAYLOAD_HASH, didUpdatePayload }
91
+ `Hash mismatch: sidecar update ${encodedUpdate} !== signal bytes ${signalBytes}.`,
92
+ INVALID_SIDECAR_DATA, { encodedUpdate, signalBytes }
138
93
  );
139
94
  }
140
- // 7. Return didUpdatePayload.
141
- return didUpdatePayload;
142
- }
143
95
 
144
- // 6. Else:
145
- // 6.1 Set didUpdatePayload to the result of passing hashBytes into the Fetch Content from Addressable Storage algorithm.
146
- const didUpdatePayloadString = await Appendix.fetchFromCas(base58btc.decode(hashBytes));
147
- if(!didUpdatePayloadString || !JSON.parse(didUpdatePayloadString)) {
148
- throw new SingletonBeaconError('Update payload not found in addressable storage.', INVALID_SIDECAR_DATA);
96
+ // Push signedUpdate to updates array
97
+ updates.push([signedUpdate, signal.blockMetadata]);
149
98
  }
150
- didUpdatePayload = JSON.parse(didUpdatePayloadString) as DidUpdatePayload;
151
99
 
152
- // 6.2 If didUpdatePayload is null, MUST raise a latePublishingError. MAY identify Beacon Signal to resolver and request additional Sidecar data be provided.
153
- if (!didUpdatePayload) {
154
- throw new SingletonBeaconError('Update payload hash does not match transaction hash.', LATE_PUBLISHING_ERROR);
155
- }
156
-
157
- // 7. Return didUpdatePayload.
158
- return didUpdatePayload;
100
+ // Return the array of signed updates
101
+ return updates;
159
102
  }
160
103
 
161
-
162
104
  /**
163
- * Implements {@link https://dcdpr.github.io/did-btcr2/#broadcast-singleton-beacon-signal | 5.1.2 Broadcast Singleton Beacon Signal}.
164
- *
165
- * The Broadcast Singleton Beacon Signal algorithm is called by the Announce DID Update algorithm as part of the
166
- * Update operation, if the Beacon being used is of the type SingletonBeacon. It takes as input a Beacon service and a
167
- * secured didUpdatePayload. The algorithm constructs a Bitcoin transaction that spends from the Beacon address
168
- * identified in the service and contains a transaction output of the format [OP_RETURN, OP_PUSH32, <hashBytes>],
169
- * where hashBytes is the SHA256 hash of the canonical didUpdatePayload. The Bitcoin transaction is then signed and
170
- * broadcast to the Bitcoin network, thereby publicly announcing a DID update in a Beacon Signal. It returns a
171
- * signalMetadata object mapping the Bitcoin transaction identifier of the Beacon Signal to the necessary data needed
172
- * to verify the signal announces a specific DID Update Payload.
173
- *
105
+ * Broadcasts a SingletonBeacon signal.
174
106
  * TODO: Design and implement a way to construct, sign and send via RPC
175
107
  *
176
- * @param {DidUpdatePayload} didUpdatePayload The verificationMethod object to be used for signing.
177
108
  * @returns {SignedRawTx} Successful output of a bitcoin transaction.
178
109
  * @throws {SingletonBeaconError} if the bitcoin address is invalid or unfunded.
179
110
  */
180
- public async broadcastSignal(didUpdatePayload: DidUpdatePayload): Promise<SignalsMetadata> {
111
+ async broadcastSignal(updateHash: HexString): Promise<HexString> {
181
112
  // 1. Initialize an addressURI variable to beacon.serviceEndpoint.
182
113
  // 2. Set bitcoinAddress to the decoding of addressURI following BIP21.
183
114
  const bitcoinAddress = this.service.serviceEndpoint.replace('bitcoin:', '');
@@ -185,9 +116,8 @@ export class SingletonBeacon extends Beacon {
185
116
  // 3. Ensure bitcoinAddress is funded, if not, fund this address.
186
117
  // let inputs: Array<CreateRawTxInputs> = [];
187
118
 
188
- const utxos = await bitcoin.network.rest.address.getUtxos(bitcoinAddress);
119
+ const utxos = await this.bitcoin.network.rest.address.getUtxos(bitcoinAddress);
189
120
  if(!utxos.length) {
190
- // TODO: Discuss what to do here because sending to a beacon address does not allow you to spend from it immediately.
191
121
  throw new SingletonBeaconError('No UTXOs found, please fund address!', 'UNFUNDED_BEACON_ADDRESS', { bitcoinAddress });
192
122
  }
193
123
 
@@ -195,28 +125,31 @@ export class SingletonBeacon extends Beacon {
195
125
  if(!utxo) {
196
126
  throw new SingletonBeaconError(
197
127
  'Beacon bitcoin address unfunded or utxos unconfirmed.',
198
- 'UNFUNDED_BEACON_ADDRESS', { bitcoinAddress });
128
+ 'UNFUNDED_BEACON_ADDRESS', { bitcoinAddress }
129
+ );
199
130
  }
200
131
 
201
- // 4. Set hashBytes to the result of passing didUpdatePayload to the JSON Canonicalization and Hash algorithm.
202
- const hashBytes = Buffer.fromHex(await JSON.canonicalization.process(didUpdatePayload));
203
- if (hashBytes.length !== 32) throw new SingletonBeaconError('Hash must be 32 bytes');
132
+ // 4. Set hashBytes to the result of passing signedUpdate to the JSON Canonicalization and Hash algorithm.
133
+ const udpateHashBytes = Buffer.from(updateHash, 'hex');
134
+ if (udpateHashBytes.length !== 32) {
135
+ throw new SingletonBeaconError('Hash must be 32 bytes');
136
+ }
204
137
 
205
138
  // 5. Initialize spendTx to a Bitcoin transaction that spends a transaction controlled by the bitcoinAddress and
206
139
  // contains at least one transaction output. This output MUST have the following format
207
140
  // [OP_RETURN, OP_PUSH32, hashBytes]
208
141
  const {txid, vout} = utxo;
209
- const prevTx = await bitcoin.network.rest.transaction.getHex(txid);
142
+ const prevTx = await this.bitcoin.network.rest.transaction.getHex(txid);
210
143
  const input = {
211
144
  hash : txid,
212
145
  index : vout,
213
- nonWitnessUtxo : Buffer.fromHex(prevTx)
146
+ nonWitnessUtxo : Buffer.from(prevTx, 'hex')
214
147
  };
215
148
  // TODO: Figure out a good way to estimate fees
216
- const spendTx = new Psbt({ network: bitcoin.network.data })
149
+ const spendTx = new Psbt({ network: this.bitcoin.network.data })
217
150
  .addInput(input)
218
151
  .addOutput({ address: bitcoinAddress, value: BigInt(utxo.value) - BigInt(500) })
219
- .addOutput({ script: script.compile([opcodes.OP_RETURN, hashBytes]), value: 0n });
152
+ .addOutput({ script: script.compile([opcodes.OP_RETURN, udpateHashBytes]), value: 0n });
220
153
 
221
154
  // 6. Retrieve the cryptographic material, e.g private key or signing capability, associated with the bitcoinAddress
222
155
  // or service. How this is done is left to the implementer.
@@ -227,7 +160,7 @@ export class SingletonBeacon extends Beacon {
227
160
  throw new Error('Key pair not found.');
228
161
  }
229
162
 
230
- const signer = new Signer({ keyPair, network: bitcoin.network.name });
163
+ const signer = new Signer({ keyPair, network: this.bitcoin.network.name });
231
164
 
232
165
  // 7. Sign the spendTx.
233
166
  const signedTx = spendTx.signInput(0, signer)
@@ -239,15 +172,12 @@ export class SingletonBeacon extends Beacon {
239
172
  }
240
173
 
241
174
  // 8. Broadcast spendTx to the Bitcoin network.
242
- const spentTx = await bitcoin.network.rest.transaction.send(signedTx);
175
+ const spentTx = await this.bitcoin.network.rest.transaction.send(signedTx);
243
176
  if(!spentTx) {
244
177
  throw new SingletonBeaconError('Failed to send raw transaction.', 'SEND_FAILED', { spentTx });
245
178
  }
246
179
 
247
- // 9. Set signalId to the Bitcoin transaction identifier of spendTx.
248
- // 10. Initialize signalMetadata to an empty object.
249
- // 11. Set signalMetadata.updatePayload to didUpdatePayload.
250
- // 12. Return the object {<signalId>: { updatePayload: DidUpdatePayload; proofs?: any; }}.
251
- return { [spentTx]: { didUpdate: didUpdatePayload } };
180
+ // Return the signed update and the spend tx id.
181
+ return spentTx;
252
182
  }
253
183
  }
@@ -0,0 +1,70 @@
1
+ import { BitcoinNetworkConnection } from '@did-btcr2/bitcoin';
2
+ import { HexString, MethodError } from '@did-btcr2/common';
3
+ import { BTCR2SignedUpdate } from '@did-btcr2/cryptosuite';
4
+ import { SidecarData } from '../types.js';
5
+ import { AggregateBeacon, BeaconService, BeaconSignal, BlockMetadata } from './interfaces.js';
6
+
7
+ /**
8
+ * TODO: Finish implementation
9
+ * Implements {@link https://dcdpr.github.io/did-btcr2/terminology.html#smt-beacon | SMTBeacon}.
10
+ * @class SMTBeacon
11
+ * @type {SMTBeacon}
12
+ * @extends {AggregateBeacon}
13
+ */
14
+ export class SMTBeacon extends AggregateBeacon {
15
+ /**
16
+ * Creates an instance of SingletonBeacon.
17
+ * @param {BeaconService} service The Beacon service.
18
+ * @param {Array<BeaconSignal>} signals The SingletonBeacon sidecar data.
19
+ * @param {SidecarData} sidecar The sidecar data.
20
+ */
21
+ constructor(
22
+ service: BeaconService,
23
+ signals: Array<BeaconSignal>,
24
+ sidecar: SidecarData,
25
+ bitcoin?: BitcoinNetworkConnection
26
+ ) {
27
+ super({ ...service, type: 'SMTBeacon' }, signals, sidecar, bitcoin);
28
+ }
29
+
30
+ /**
31
+ * Static, convenience method for establishing a SMTBeacon object.
32
+ * @param {string} service The Beacon service.
33
+ * @param {SidecarData} sidecar The sidecar data.
34
+ * @returns {SingletonBeacon} The Singleton Beacon.
35
+ */
36
+ static establish(service: BeaconService, signals: Array<BeaconSignal>, sidecar: SidecarData): SMTBeacon {
37
+ return new SMTBeacon(service, signals, sidecar);
38
+ }
39
+
40
+ /**
41
+ * TODO: Figure out if this is necessary or not.
42
+ * @param {HexString} updateHash The hash of the BTCR2 update to generate the signal for.
43
+ * @returns {BeaconSignal} The generated signal.
44
+ * @throws {MethodError} if the signal is invalid.
45
+ */
46
+ generateSignal(updateHash: HexString): BeaconSignal {
47
+ throw new MethodError('Method not implemented.', `METHOD_NOT_IMPLEMENTED`, {updateHash});
48
+ }
49
+
50
+ /**
51
+ * Process SMTBeacon signals.
52
+ * @returns {Promise<Array<BTCR2SignedUpdate>>} The processed signed update or undefined.
53
+ * @throws {MethodError} if the signal processing fails.
54
+ */
55
+ async processSignals(): Promise<Array<[BTCR2SignedUpdate, BlockMetadata]>> {
56
+ throw new MethodError('Method not implemented.', `METHOD_NOT_IMPLEMENTED`);
57
+ }
58
+
59
+
60
+ /**
61
+ * Broadcast a SMTBeacon signal.
62
+ * @param {HexString} updateHash The hash of the BTCR2 update to broadcast.
63
+ * @returns {Promise<SignalsMetadata>} The result of the broadcast.
64
+ * @throws {MethodError} if the broadcast fails.
65
+ */
66
+ async broadcastSignal(updateHash: HexString): Promise<HexString> {
67
+ throw new MethodError('Method not implemented.', `METHOD_NOT_IMPLEMENTED`, {updateHash});
68
+ }
69
+
70
+ }