@did-btcr2/method 0.13.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (310) hide show
  1. package/LICENSE +373 -0
  2. package/README.md +7 -0
  3. package/dist/browser.js +2364 -0
  4. package/dist/browser.js.map +7 -0
  5. package/dist/browser.mjs +2364 -0
  6. package/dist/browser.mjs.map +7 -0
  7. package/dist/cjs/bitcoin/constants.js +20 -0
  8. package/dist/cjs/bitcoin/constants.js.map +1 -0
  9. package/dist/cjs/bitcoin/errors.js +11 -0
  10. package/dist/cjs/bitcoin/errors.js.map +1 -0
  11. package/dist/cjs/bitcoin/index.js +95 -0
  12. package/dist/cjs/bitcoin/index.js.map +1 -0
  13. package/dist/cjs/bitcoin/interface.js +2 -0
  14. package/dist/cjs/bitcoin/interface.js.map +1 -0
  15. package/dist/cjs/bitcoin/network.js +17 -0
  16. package/dist/cjs/bitcoin/network.js.map +1 -0
  17. package/dist/cjs/bitcoin/rest-client.js +289 -0
  18. package/dist/cjs/bitcoin/rest-client.js.map +1 -0
  19. package/dist/cjs/bitcoin/rpc-client.js +722 -0
  20. package/dist/cjs/bitcoin/rpc-client.js.map +1 -0
  21. package/dist/cjs/bitcoin/taproot.js +219 -0
  22. package/dist/cjs/bitcoin/taproot.js.map +1 -0
  23. package/dist/cjs/btcr2/beacon/aggregation/coordinator.js +120 -0
  24. package/dist/cjs/btcr2/beacon/aggregation/coordinator.js.map +1 -0
  25. package/dist/cjs/btcr2/beacon/aggregation/messages/advert.js +24 -0
  26. package/dist/cjs/btcr2/beacon/aggregation/messages/advert.js.map +1 -0
  27. package/dist/cjs/btcr2/beacon/aggregation/messages/base.js +37 -0
  28. package/dist/cjs/btcr2/beacon/aggregation/messages/base.js.map +1 -0
  29. package/dist/cjs/btcr2/beacon/aggregation/messages/cohort-set.js +25 -0
  30. package/dist/cjs/btcr2/beacon/aggregation/messages/cohort-set.js.map +1 -0
  31. package/dist/cjs/btcr2/beacon/aggregation/messages/keygen.js +8 -0
  32. package/dist/cjs/btcr2/beacon/aggregation/messages/keygen.js.map +1 -0
  33. package/dist/cjs/btcr2/beacon/aggregation/messages/opt-in.js +23 -0
  34. package/dist/cjs/btcr2/beacon/aggregation/messages/opt-in.js.map +1 -0
  35. package/dist/cjs/btcr2/beacon/aggregation/messages/sign.js +7 -0
  36. package/dist/cjs/btcr2/beacon/aggregation/messages/sign.js.map +1 -0
  37. package/dist/cjs/btcr2/beacon/aggregation/models/cohort/index.js +92 -0
  38. package/dist/cjs/btcr2/beacon/aggregation/models/cohort/index.js.map +1 -0
  39. package/dist/cjs/btcr2/beacon/aggregation/models/cohort/status.js +8 -0
  40. package/dist/cjs/btcr2/beacon/aggregation/models/cohort/status.js.map +1 -0
  41. package/dist/cjs/btcr2/beacon/aggregation/participant.js +2 -0
  42. package/dist/cjs/btcr2/beacon/aggregation/participant.js.map +1 -0
  43. package/dist/cjs/btcr2/beacon/aggregation/protocol/nostr.js +57 -0
  44. package/dist/cjs/btcr2/beacon/aggregation/protocol/nostr.js.map +1 -0
  45. package/dist/cjs/btcr2/beacon/aggregation/protocol/service.js +2 -0
  46. package/dist/cjs/btcr2/beacon/aggregation/protocol/service.js.map +1 -0
  47. package/dist/cjs/btcr2/beacon/cid-aggregate.js +116 -0
  48. package/dist/cjs/btcr2/beacon/cid-aggregate.js.map +1 -0
  49. package/dist/cjs/btcr2/beacon/factory.js +30 -0
  50. package/dist/cjs/btcr2/beacon/factory.js.map +1 -0
  51. package/dist/cjs/btcr2/beacon/singleton.js +220 -0
  52. package/dist/cjs/btcr2/beacon/singleton.js.map +1 -0
  53. package/dist/cjs/btcr2/beacon/smt-aggregate.js +126 -0
  54. package/dist/cjs/btcr2/beacon/smt-aggregate.js.map +1 -0
  55. package/dist/cjs/btcr2/crud/create.js +102 -0
  56. package/dist/cjs/btcr2/crud/create.js.map +1 -0
  57. package/dist/cjs/btcr2/crud/deactivate.js +14 -0
  58. package/dist/cjs/btcr2/crud/deactivate.js.map +1 -0
  59. package/dist/cjs/btcr2/crud/read.js +686 -0
  60. package/dist/cjs/btcr2/crud/read.js.map +1 -0
  61. package/dist/cjs/btcr2/crud/update.js +195 -0
  62. package/dist/cjs/btcr2/crud/update.js.map +1 -0
  63. package/dist/cjs/btcr2/key-manager/index.js +290 -0
  64. package/dist/cjs/btcr2/key-manager/index.js.map +1 -0
  65. package/dist/cjs/btcr2/key-manager/interface.js +2 -0
  66. package/dist/cjs/btcr2/key-manager/interface.js.map +1 -0
  67. package/dist/cjs/did-btcr2.js +222 -0
  68. package/dist/cjs/did-btcr2.js.map +1 -0
  69. package/dist/cjs/index.js +27 -0
  70. package/dist/cjs/index.js.map +1 -0
  71. package/dist/cjs/interfaces/beacon.js +41 -0
  72. package/dist/cjs/interfaces/beacon.js.map +1 -0
  73. package/dist/cjs/interfaces/crud.js +2 -0
  74. package/dist/cjs/interfaces/crud.js.map +1 -0
  75. package/dist/cjs/interfaces/ibeacon.js +2 -0
  76. package/dist/cjs/interfaces/ibeacon.js.map +1 -0
  77. package/dist/cjs/package.json +1 -0
  78. package/dist/cjs/types/bitcoin.js +62 -0
  79. package/dist/cjs/types/bitcoin.js.map +1 -0
  80. package/dist/cjs/types/crud.js +2 -0
  81. package/dist/cjs/types/crud.js.map +1 -0
  82. package/dist/cjs/utils/appendix.js +221 -0
  83. package/dist/cjs/utils/appendix.js.map +1 -0
  84. package/dist/cjs/utils/beacons.js +206 -0
  85. package/dist/cjs/utils/beacons.js.map +1 -0
  86. package/dist/cjs/utils/did-document-builder.js +61 -0
  87. package/dist/cjs/utils/did-document-builder.js.map +1 -0
  88. package/dist/cjs/utils/did-document.js +380 -0
  89. package/dist/cjs/utils/did-document.js.map +1 -0
  90. package/dist/cjs/utils/general.js +195 -0
  91. package/dist/cjs/utils/general.js.map +1 -0
  92. package/dist/cjs/utils/identifier.js +238 -0
  93. package/dist/cjs/utils/identifier.js.map +1 -0
  94. package/dist/esm/bitcoin/constants.js +20 -0
  95. package/dist/esm/bitcoin/constants.js.map +1 -0
  96. package/dist/esm/bitcoin/errors.js +11 -0
  97. package/dist/esm/bitcoin/errors.js.map +1 -0
  98. package/dist/esm/bitcoin/index.js +95 -0
  99. package/dist/esm/bitcoin/index.js.map +1 -0
  100. package/dist/esm/bitcoin/interface.js +2 -0
  101. package/dist/esm/bitcoin/interface.js.map +1 -0
  102. package/dist/esm/bitcoin/network.js +17 -0
  103. package/dist/esm/bitcoin/network.js.map +1 -0
  104. package/dist/esm/bitcoin/rest-client.js +289 -0
  105. package/dist/esm/bitcoin/rest-client.js.map +1 -0
  106. package/dist/esm/bitcoin/rpc-client.js +722 -0
  107. package/dist/esm/bitcoin/rpc-client.js.map +1 -0
  108. package/dist/esm/bitcoin/taproot.js +219 -0
  109. package/dist/esm/bitcoin/taproot.js.map +1 -0
  110. package/dist/esm/btcr2/beacon/aggregation/coordinator.js +120 -0
  111. package/dist/esm/btcr2/beacon/aggregation/coordinator.js.map +1 -0
  112. package/dist/esm/btcr2/beacon/aggregation/messages/advert.js +24 -0
  113. package/dist/esm/btcr2/beacon/aggregation/messages/advert.js.map +1 -0
  114. package/dist/esm/btcr2/beacon/aggregation/messages/base.js +37 -0
  115. package/dist/esm/btcr2/beacon/aggregation/messages/base.js.map +1 -0
  116. package/dist/esm/btcr2/beacon/aggregation/messages/cohort-set.js +25 -0
  117. package/dist/esm/btcr2/beacon/aggregation/messages/cohort-set.js.map +1 -0
  118. package/dist/esm/btcr2/beacon/aggregation/messages/keygen.js +8 -0
  119. package/dist/esm/btcr2/beacon/aggregation/messages/keygen.js.map +1 -0
  120. package/dist/esm/btcr2/beacon/aggregation/messages/opt-in.js +23 -0
  121. package/dist/esm/btcr2/beacon/aggregation/messages/opt-in.js.map +1 -0
  122. package/dist/esm/btcr2/beacon/aggregation/messages/sign.js +7 -0
  123. package/dist/esm/btcr2/beacon/aggregation/messages/sign.js.map +1 -0
  124. package/dist/esm/btcr2/beacon/aggregation/models/cohort/index.js +92 -0
  125. package/dist/esm/btcr2/beacon/aggregation/models/cohort/index.js.map +1 -0
  126. package/dist/esm/btcr2/beacon/aggregation/models/cohort/status.js +8 -0
  127. package/dist/esm/btcr2/beacon/aggregation/models/cohort/status.js.map +1 -0
  128. package/dist/esm/btcr2/beacon/aggregation/participant.js +2 -0
  129. package/dist/esm/btcr2/beacon/aggregation/participant.js.map +1 -0
  130. package/dist/esm/btcr2/beacon/aggregation/protocol/nostr.js +57 -0
  131. package/dist/esm/btcr2/beacon/aggregation/protocol/nostr.js.map +1 -0
  132. package/dist/esm/btcr2/beacon/aggregation/protocol/service.js +2 -0
  133. package/dist/esm/btcr2/beacon/aggregation/protocol/service.js.map +1 -0
  134. package/dist/esm/btcr2/beacon/cid-aggregate.js +116 -0
  135. package/dist/esm/btcr2/beacon/cid-aggregate.js.map +1 -0
  136. package/dist/esm/btcr2/beacon/factory.js +30 -0
  137. package/dist/esm/btcr2/beacon/factory.js.map +1 -0
  138. package/dist/esm/btcr2/beacon/singleton.js +220 -0
  139. package/dist/esm/btcr2/beacon/singleton.js.map +1 -0
  140. package/dist/esm/btcr2/beacon/smt-aggregate.js +126 -0
  141. package/dist/esm/btcr2/beacon/smt-aggregate.js.map +1 -0
  142. package/dist/esm/btcr2/crud/create.js +102 -0
  143. package/dist/esm/btcr2/crud/create.js.map +1 -0
  144. package/dist/esm/btcr2/crud/deactivate.js +14 -0
  145. package/dist/esm/btcr2/crud/deactivate.js.map +1 -0
  146. package/dist/esm/btcr2/crud/read.js +686 -0
  147. package/dist/esm/btcr2/crud/read.js.map +1 -0
  148. package/dist/esm/btcr2/crud/update.js +195 -0
  149. package/dist/esm/btcr2/crud/update.js.map +1 -0
  150. package/dist/esm/btcr2/key-manager/index.js +290 -0
  151. package/dist/esm/btcr2/key-manager/index.js.map +1 -0
  152. package/dist/esm/btcr2/key-manager/interface.js +2 -0
  153. package/dist/esm/btcr2/key-manager/interface.js.map +1 -0
  154. package/dist/esm/did-btcr2.js +222 -0
  155. package/dist/esm/did-btcr2.js.map +1 -0
  156. package/dist/esm/index.js +27 -0
  157. package/dist/esm/index.js.map +1 -0
  158. package/dist/esm/interfaces/beacon.js +41 -0
  159. package/dist/esm/interfaces/beacon.js.map +1 -0
  160. package/dist/esm/interfaces/crud.js +2 -0
  161. package/dist/esm/interfaces/crud.js.map +1 -0
  162. package/dist/esm/interfaces/ibeacon.js +2 -0
  163. package/dist/esm/interfaces/ibeacon.js.map +1 -0
  164. package/dist/esm/types/bitcoin.js +62 -0
  165. package/dist/esm/types/bitcoin.js.map +1 -0
  166. package/dist/esm/types/crud.js +2 -0
  167. package/dist/esm/types/crud.js.map +1 -0
  168. package/dist/esm/utils/appendix.js +221 -0
  169. package/dist/esm/utils/appendix.js.map +1 -0
  170. package/dist/esm/utils/beacons.js +206 -0
  171. package/dist/esm/utils/beacons.js.map +1 -0
  172. package/dist/esm/utils/did-document-builder.js +61 -0
  173. package/dist/esm/utils/did-document-builder.js.map +1 -0
  174. package/dist/esm/utils/did-document.js +380 -0
  175. package/dist/esm/utils/did-document.js.map +1 -0
  176. package/dist/esm/utils/general.js +195 -0
  177. package/dist/esm/utils/general.js.map +1 -0
  178. package/dist/esm/utils/identifier.js +238 -0
  179. package/dist/esm/utils/identifier.js.map +1 -0
  180. package/dist/types/bitcoin/constants.d.ts +19 -0
  181. package/dist/types/bitcoin/constants.d.ts.map +1 -0
  182. package/dist/types/bitcoin/errors.d.ts +5 -0
  183. package/dist/types/bitcoin/errors.d.ts.map +1 -0
  184. package/dist/types/bitcoin/index.d.ts +75 -0
  185. package/dist/types/bitcoin/index.d.ts.map +1 -0
  186. package/dist/types/bitcoin/interface.d.ts +86 -0
  187. package/dist/types/bitcoin/interface.d.ts.map +1 -0
  188. package/dist/types/bitcoin/network.d.ts +2 -0
  189. package/dist/types/bitcoin/network.d.ts.map +1 -0
  190. package/dist/types/bitcoin/rest-client.d.ts +268 -0
  191. package/dist/types/bitcoin/rest-client.d.ts.map +1 -0
  192. package/dist/types/bitcoin/rpc-client.d.ts +506 -0
  193. package/dist/types/bitcoin/rpc-client.d.ts.map +1 -0
  194. package/dist/types/bitcoin/taproot.d.ts +34 -0
  195. package/dist/types/bitcoin/taproot.d.ts.map +1 -0
  196. package/dist/types/btcr2/beacon/aggregation/coordinator.d.ts +74 -0
  197. package/dist/types/btcr2/beacon/aggregation/coordinator.d.ts.map +1 -0
  198. package/dist/types/btcr2/beacon/aggregation/messages/advert.d.ts +22 -0
  199. package/dist/types/btcr2/beacon/aggregation/messages/advert.d.ts.map +1 -0
  200. package/dist/types/btcr2/beacon/aggregation/messages/base.d.ts +36 -0
  201. package/dist/types/btcr2/beacon/aggregation/messages/base.d.ts.map +1 -0
  202. package/dist/types/btcr2/beacon/aggregation/messages/cohort-set.d.ts +23 -0
  203. package/dist/types/btcr2/beacon/aggregation/messages/cohort-set.d.ts.map +1 -0
  204. package/dist/types/btcr2/beacon/aggregation/messages/keygen.d.ts +6 -0
  205. package/dist/types/btcr2/beacon/aggregation/messages/keygen.d.ts.map +1 -0
  206. package/dist/types/btcr2/beacon/aggregation/messages/opt-in.d.ts +22 -0
  207. package/dist/types/btcr2/beacon/aggregation/messages/opt-in.d.ts.map +1 -0
  208. package/dist/types/btcr2/beacon/aggregation/messages/sign.d.ts +5 -0
  209. package/dist/types/btcr2/beacon/aggregation/messages/sign.d.ts.map +1 -0
  210. package/dist/types/btcr2/beacon/aggregation/models/cohort/index.d.ts +77 -0
  211. package/dist/types/btcr2/beacon/aggregation/models/cohort/index.d.ts.map +1 -0
  212. package/dist/types/btcr2/beacon/aggregation/models/cohort/status.d.ts +7 -0
  213. package/dist/types/btcr2/beacon/aggregation/models/cohort/status.d.ts.map +1 -0
  214. package/dist/types/btcr2/beacon/aggregation/participant.d.ts +1 -0
  215. package/dist/types/btcr2/beacon/aggregation/participant.d.ts.map +1 -0
  216. package/dist/types/btcr2/beacon/aggregation/protocol/nostr.d.ts +36 -0
  217. package/dist/types/btcr2/beacon/aggregation/protocol/nostr.d.ts.map +1 -0
  218. package/dist/types/btcr2/beacon/aggregation/protocol/service.d.ts +6 -0
  219. package/dist/types/btcr2/beacon/aggregation/protocol/service.d.ts.map +1 -0
  220. package/dist/types/btcr2/beacon/cid-aggregate.d.ts +103 -0
  221. package/dist/types/btcr2/beacon/cid-aggregate.d.ts.map +1 -0
  222. package/dist/types/btcr2/beacon/factory.d.ts +17 -0
  223. package/dist/types/btcr2/beacon/factory.d.ts.map +1 -0
  224. package/dist/types/btcr2/beacon/singleton.d.ts +93 -0
  225. package/dist/types/btcr2/beacon/singleton.d.ts.map +1 -0
  226. package/dist/types/btcr2/beacon/smt-aggregate.d.ts +112 -0
  227. package/dist/types/btcr2/beacon/smt-aggregate.d.ts.map +1 -0
  228. package/dist/types/btcr2/crud/create.d.ts +92 -0
  229. package/dist/types/btcr2/crud/create.d.ts.map +1 -0
  230. package/dist/types/btcr2/crud/deactivate.d.ts +13 -0
  231. package/dist/types/btcr2/crud/deactivate.d.ts.map +1 -0
  232. package/dist/types/btcr2/crud/read.d.ts +341 -0
  233. package/dist/types/btcr2/crud/read.d.ts.map +1 -0
  234. package/dist/types/btcr2/crud/update.d.ts +83 -0
  235. package/dist/types/btcr2/crud/update.d.ts.map +1 -0
  236. package/dist/types/btcr2/key-manager/index.d.ts +145 -0
  237. package/dist/types/btcr2/key-manager/index.d.ts.map +1 -0
  238. package/dist/types/btcr2/key-manager/interface.d.ts +113 -0
  239. package/dist/types/btcr2/key-manager/interface.d.ts.map +1 -0
  240. package/dist/types/did-btcr2.d.ts +117 -0
  241. package/dist/types/did-btcr2.d.ts.map +1 -0
  242. package/dist/types/index.d.ts +26 -0
  243. package/dist/types/index.d.ts.map +1 -0
  244. package/dist/types/interfaces/beacon.d.ts +57 -0
  245. package/dist/types/interfaces/beacon.d.ts.map +1 -0
  246. package/dist/types/interfaces/crud.d.ts +35 -0
  247. package/dist/types/interfaces/crud.d.ts.map +1 -0
  248. package/dist/types/interfaces/ibeacon.d.ts +66 -0
  249. package/dist/types/interfaces/ibeacon.d.ts.map +1 -0
  250. package/dist/types/types/bitcoin.d.ts +827 -0
  251. package/dist/types/types/bitcoin.d.ts.map +1 -0
  252. package/dist/types/types/crud.d.ts +38 -0
  253. package/dist/types/types/crud.d.ts.map +1 -0
  254. package/dist/types/utils/appendix.d.ts +118 -0
  255. package/dist/types/utils/appendix.d.ts.map +1 -0
  256. package/dist/types/utils/beacons.d.ts +156 -0
  257. package/dist/types/utils/beacons.d.ts.map +1 -0
  258. package/dist/types/utils/did-document-builder.d.ts +13 -0
  259. package/dist/types/utils/did-document-builder.d.ts.map +1 -0
  260. package/dist/types/utils/did-document.d.ts +211 -0
  261. package/dist/types/utils/did-document.d.ts.map +1 -0
  262. package/dist/types/utils/general.d.ts +85 -0
  263. package/dist/types/utils/general.d.ts.map +1 -0
  264. package/dist/types/utils/identifier.d.ts +59 -0
  265. package/dist/types/utils/identifier.d.ts.map +1 -0
  266. package/package.json +137 -0
  267. package/src/bitcoin/constants.ts +19 -0
  268. package/src/bitcoin/errors.ts +10 -0
  269. package/src/bitcoin/index.ts +154 -0
  270. package/src/bitcoin/interface.ts +160 -0
  271. package/src/bitcoin/network.ts +17 -0
  272. package/src/bitcoin/rest-client.ts +415 -0
  273. package/src/bitcoin/rpc-client.ts +888 -0
  274. package/src/bitcoin/taproot.ts +237 -0
  275. package/src/btcr2/beacon/aggregation/coordinator.ts +135 -0
  276. package/src/btcr2/beacon/aggregation/messages/advert.ts +36 -0
  277. package/src/btcr2/beacon/aggregation/messages/base.ts +59 -0
  278. package/src/btcr2/beacon/aggregation/messages/cohort-set.ts +37 -0
  279. package/src/btcr2/beacon/aggregation/messages/keygen.ts +8 -0
  280. package/src/btcr2/beacon/aggregation/messages/opt-in.ts +35 -0
  281. package/src/btcr2/beacon/aggregation/messages/sign.ts +7 -0
  282. package/src/btcr2/beacon/aggregation/models/cohort/index.ts +112 -0
  283. package/src/btcr2/beacon/aggregation/models/cohort/status.ts +7 -0
  284. package/src/btcr2/beacon/aggregation/participant.ts +0 -0
  285. package/src/btcr2/beacon/aggregation/protocol/nostr.ts +81 -0
  286. package/src/btcr2/beacon/aggregation/protocol/service.ts +6 -0
  287. package/src/btcr2/beacon/cid-aggregate.ts +154 -0
  288. package/src/btcr2/beacon/factory.ts +36 -0
  289. package/src/btcr2/beacon/singleton.ts +257 -0
  290. package/src/btcr2/beacon/smt-aggregate.ts +136 -0
  291. package/src/btcr2/crud/create.ts +160 -0
  292. package/src/btcr2/crud/deactivate.ts +13 -0
  293. package/src/btcr2/crud/read.ts +946 -0
  294. package/src/btcr2/crud/update.ts +277 -0
  295. package/src/btcr2/key-manager/index.ts +364 -0
  296. package/src/btcr2/key-manager/interface.ts +129 -0
  297. package/src/canonicalize.d.ts +6 -0
  298. package/src/did-btcr2.ts +288 -0
  299. package/src/index.ts +34 -0
  300. package/src/interfaces/beacon.ts +68 -0
  301. package/src/interfaces/crud.ts +36 -0
  302. package/src/interfaces/ibeacon.ts +76 -0
  303. package/src/types/bitcoin.ts +1028 -0
  304. package/src/types/crud.ts +41 -0
  305. package/src/utils/appendix.ts +257 -0
  306. package/src/utils/beacons.ts +276 -0
  307. package/src/utils/did-document-builder.ts +73 -0
  308. package/src/utils/did-document.ts +474 -0
  309. package/src/utils/general.ts +204 -0
  310. package/src/utils/identifier.ts +276 -0
@@ -0,0 +1,277 @@
1
+ import {
2
+ BTCR2_DID_UPDATE_PAYLOAD_CONTEXT,
3
+ Btcr2Error,
4
+ DidUpdateInvocation,
5
+ DidUpdatePayload,
6
+ INVALID_DID_DOCUMENT,
7
+ INVALID_DID_UPDATE,
8
+ INVALID_PUBLIC_KEY_TYPE,
9
+ Logger,
10
+ NOT_FOUND,
11
+ PatchOperation,
12
+ ProofOptions
13
+ } from '@did-btcr2/common';
14
+ import { SchnorrMultikey } from '@did-btcr2/cryptosuite';
15
+ import { SchnorrKeyPair, SecretKey } from '@did-btcr2/keypair';
16
+ import type { DidService } from '@web5/dids';
17
+ import { BeaconService } from '../../interfaces/ibeacon.js';
18
+ import { SignalsMetadata } from '../../types/crud.js';
19
+ import { Btc1Appendix } from '../../utils/appendix.js';
20
+ import { Btc1DidDocument, Btc1VerificationMethod } from '../../utils/did-document.js';
21
+ import { BeaconFactory } from '../beacon/factory.js';
22
+ import { Btc1KeyManager } from '../key-manager/index.js';
23
+
24
+ export type InvokePayloadParams = {
25
+ identifier: string;
26
+ didUpdatePayload: DidUpdatePayload;
27
+ verificationMethod: Btc1VerificationMethod;
28
+ }
29
+
30
+ /**
31
+ * Implements {@link https://dcdpr.github.io/did-btcr2/#update | 4.3 Update}.
32
+ *
33
+ * An update to a did:btcr2 document is an invoked capability using the ZCAP-LD
34
+ * data format, signed by a verificationMethod that has the authority to make
35
+ * the update as specified in the previous DID document. Capability invocations
36
+ * for updates MUST be authorized using Data Integrity following the
37
+ * bip340-jcs-2025 cryptosuite with a proofPurpose of capabilityInvocation.
38
+ *
39
+ * @class Btc1Update
40
+ * @type {Btc1Update}
41
+ */
42
+ export class Btc1Update {
43
+ /**
44
+ * Implements {@link https://dcdpr.github.io/did-btcr2/#construct-did-update-payload | 4.3.1 Construct DID Update Payload}.
45
+ *
46
+ * The Construct DID Update Payload algorithm applies the documentPatch to the sourceDocument and verifies the
47
+ * resulting targetDocument is a conformant DID document. It takes in a btc1Identifier, sourceDocument,
48
+ * sourceVersionId, and documentPatch objects. It returns an unsigned DID Update Payload.
49
+ *
50
+ * @param {ConstructPayloadParams} params See {@link ConstructPayloadParams} for more details.
51
+ * @param {string} params.identifier The did-btcr2 identifier to use for verification.
52
+ * @param {Btc1DidDocument} params.sourceDocument The source document to be updated.
53
+ * @param {string} params.sourceVersionId The versionId of the source document.
54
+ * @param {DidDocumentPatch} params.patch The JSON patch to be applied to the source document.
55
+ * @returns {Promise<DidUpdatePayload>} The constructed DidUpdatePayload object.
56
+ * @throws {Btcr2Error} InvalidDid if sourceDocument.id does not match identifier.
57
+ */
58
+ public static async construct({
59
+ identifier,
60
+ sourceDocument,
61
+ sourceVersionId,
62
+ patch,
63
+ }: {
64
+ identifier: string;
65
+ sourceDocument: Btc1DidDocument;
66
+ sourceVersionId: number;
67
+ patch: PatchOperation[];
68
+ }): Promise<DidUpdatePayload> {
69
+
70
+ // 1. Check that sourceDocument.id equals identifier else MUST raise invalidDIDUpdate error.
71
+ if (sourceDocument.id !== identifier) {
72
+ throw new Btcr2Error(
73
+ INVALID_DID_UPDATE,
74
+ 'Source document id does not match identifier',
75
+ { sourceDocument, identifier}
76
+ );
77
+ }
78
+
79
+ // 2. Initialize didUpdatePayload to an empty object.
80
+ const didUpdatePayload: DidUpdatePayload = {
81
+ // 3. Set didUpdatePayload.@context to the following list
82
+ '@context' : BTCR2_DID_UPDATE_PAYLOAD_CONTEXT,
83
+ // 4. Set didUpdatePayload.patch to documentPatch.
84
+ patch,
85
+ targetHash : '',
86
+ targetVersionId : 0,
87
+ sourceHash : '',
88
+ };
89
+ // TODO: Need to add btcr2 context. ["https://w3id.org/zcap/v1", "https://w3id.org/security/data-integrity/v2", "https://w3id.org/json-ld-patch/v1"]
90
+
91
+ // 5. Set targetDocument to the result of applying the documentPatch to the sourceDocument, following the JSON Patch
92
+ // specification.
93
+ const targetDocument = JSON.patch.apply(sourceDocument, patch) as Btc1DidDocument;
94
+
95
+ // 6. Validate targetDocument is a conformant DID document, else MUST raise invalidDIDUpdate error.
96
+ Btc1DidDocument.validate(targetDocument);
97
+
98
+ // 7. Set sourceHashBytes to the result of passing sourceDocument into the JSON Canonicalization and Hash algorithm.
99
+ // 8. Set didUpdatePayload.sourceHash to the base58-btc Multibase encoding of sourceHashBytes.
100
+ didUpdatePayload.sourceHash = (await JSON.canonicalization.process(sourceDocument, 'base58')).slice(1);
101
+ // TODO: Question - is base58btc the correct encoding scheme?
102
+
103
+ // 9. Set targetHashBytes to the result of passing targetDocument into the JSON Canonicalization and Hash algorithm.
104
+ // 10. Set didUpdatePayload.targetHash to the base58-btc Multibase encoding of targetHashBytes.
105
+ didUpdatePayload.targetHash = (await JSON.canonicalization.process(targetDocument, 'base58')).slice(1);
106
+
107
+ // 11. Set didUpdatePayload.targetVersionId to sourceVersionId + 1.
108
+ didUpdatePayload.targetVersionId = sourceVersionId + 1;
109
+
110
+ // 12. Return updatePayload.
111
+ return didUpdatePayload;
112
+ }
113
+
114
+ /**
115
+ * {@link https://dcdpr.github.io/did-btcr2/#invoke-did-update-payload | 4.3.2 Invoke DID Update Payload}.
116
+ *
117
+ * The Invoke DID Update Payload algorithm takes in a btc1Identifier, an unsigned didUpdatePayload, and a
118
+ * verificationMethod. It retrieves the privateKeyBytes for the verificationMethod and adds a capability invocation in
119
+ * the form of a Data Integrity proof following the Authorization Capabilities (ZCAP-LD) and VC Data Integrity
120
+ * specifications. It returns the invoked DID Update Payload.
121
+ *
122
+ * @param {InvokePayloadParams} params Required params for calling the invokePayload method
123
+ * @param {string} params.identifier The did-btcr2 identifier to derive the root capability from
124
+ * @param {DidUpdatePayload} params.didUpdatePayload The updatePayload object to be signed
125
+ * @param {DidVerificationMethod} params.verificationMethod The verificationMethod object to be used for signing
126
+ * @returns {DidUpdateInvocation} Did update payload secured with a proof => DidUpdateInvocation
127
+ * @throws {Btcr2Error} if the privateKeyBytes are invalid
128
+ */
129
+ public static async invoke({
130
+ identifier,
131
+ didUpdatePayload,
132
+ verificationMethod
133
+ }: {
134
+ identifier: string;
135
+ didUpdatePayload: DidUpdatePayload;
136
+ verificationMethod: Btc1VerificationMethod;
137
+ }): Promise<DidUpdateInvocation> {
138
+ // Deconstruct the verificationMethod
139
+ const { id: fullId, controller, publicKeyMultibase, secretKeyMultibase } = verificationMethod;
140
+
141
+ // Validate the verificationMethod
142
+ if(!publicKeyMultibase) {
143
+ throw new Btcr2Error(
144
+ 'Invalid publicKeyMultibase: cannot be undefined',
145
+ INVALID_PUBLIC_KEY_TYPE, verificationMethod
146
+ );
147
+ }
148
+
149
+ // 1. Set privateKeyBytes to the result of retrieving the private key bytes
150
+ // associated with the verificationMethod value.
151
+ const id = fullId.slice(fullId.indexOf('#'));
152
+ const multikey = !secretKeyMultibase
153
+ // 1.1 Compute the keyUri and check if the key is in the keystore
154
+ ? await Btc1KeyManager.getKeyPair(fullId)
155
+ // 1.2 If not, use the secretKeyMultibase from the verificationMethod
156
+ : SchnorrMultikey
157
+ .initialize({
158
+ id,
159
+ controller,
160
+ keys : new SchnorrKeyPair({
161
+ secretKey : SecretKey.decode(secretKeyMultibase)
162
+ })
163
+ });
164
+
165
+ // 1.3 If the privateKey is not found, throw an error
166
+ if (!multikey) {
167
+ throw new Btcr2Error(
168
+ 'No privateKey found in kms or vm',
169
+ NOT_FOUND, verificationMethod
170
+ );
171
+ }
172
+
173
+ // 2. Set rootCapability to the result of passing btc1Identifier into the Derive Root Capability from did:btcr2
174
+ // Identifier algorithm.
175
+ const rootCapability = Btc1Appendix.deriveRootCapability(identifier);
176
+ const cryptosuite = 'bip340-jcs-2025';
177
+ // 3. Initialize proofOptions to an empty object.
178
+ // 4. Set proofOptions.type to DataIntegrityProof.
179
+ // 5. Set proofOptions.cryptosuite to schnorr-secp256k1-jcs-2025.
180
+ // 6. Set proofOptions.verificationMethod to verificationMethod.id.
181
+ // 7. Set proofOptions.proofPurpose to capabilityInvocation.
182
+ // 8. Set proofOptions.capability to rootCapability.id.
183
+ // 9. Set proofOptions.capabilityAction to Write.
184
+ // TODO: Wonder if we actually need this. Arent we always writing?
185
+ const options: ProofOptions = {
186
+ cryptosuite,
187
+ type : 'DataIntegrityProof',
188
+ verificationMethod : fullId,
189
+ proofPurpose : 'capabilityInvocation',
190
+ capability : rootCapability.id,
191
+ capabilityAction : 'Write',
192
+ };
193
+
194
+ // 10. Set cryptosuite to the result of executing the Cryptosuite Instantiation algorithm from the BIP340 Data
195
+ // Integrity specification passing in proofOptions.
196
+ const diproof = multikey.toCryptosuite(cryptosuite).toDataIntegrityProof();
197
+
198
+ // TODO: 11. need to set up the proof instantiation such that it can resolve / dereference the root capability. This is deterministic from the DID.
199
+
200
+ // 12. Set didUpdateInvocation to the result of executing the Add Proof algorithm from VC Data Integrity passing
201
+ // didUpdatePayload as the input document, cryptosuite, and the set of proofOptions.
202
+ // 13. Return didUpdateInvocation.
203
+ return await diproof.addProof({ document: didUpdatePayload, options });
204
+ }
205
+
206
+ /**
207
+ * Implements {@link https://dcdpr.github.io/did-btcr2/#announce-did-update | 4.3.3 Announce DID Update}.
208
+ *
209
+ * The Announce DID Update algorithm retrieves beaconServices from the sourceDocument and calls the Broadcast DID
210
+ * Update algorithm corresponding to the type of the Beacon. It takes in a btc1Identifier, sourceDocument, an array of
211
+ * beaconIds, and a didUpdateInvocation. It returns an array of signalsMetadata, containing the necessary
212
+ * data to validate the Beacon Signal against the didUpdateInvocation.
213
+ *
214
+ * @param {AnnounceUpdatePayloadParams} params Required params for calling the announcePayload method
215
+ * @param {Btc1DidDocument} params.sourceDocument The did-btcr2 did document to derive the root capability from
216
+ * @param {string[]} params.beaconIds The didUpdatePayload object to be signed
217
+ * @param {DidUpdateInvocation} params.didUpdatePayload The verificationMethod object to be used for signing
218
+ * @returns {SignalsMetadata} The signalsMetadata object containing data to validate the Beacon Signal
219
+ * @throws {Btcr2Error} if the beaconService type is invalid
220
+ */
221
+ public static async announce({
222
+ sourceDocument,
223
+ beaconIds,
224
+ didUpdateInvocation
225
+ }: {
226
+ sourceDocument: Btc1DidDocument;
227
+ beaconIds: string[];
228
+ didUpdateInvocation: DidUpdateInvocation;
229
+ }): Promise<SignalsMetadata> {
230
+ // 1. Set beaconServices to an empty array.
231
+ const beaconServices: BeaconService[] = [];
232
+
233
+ // 2. signalMetadata to an empty array.
234
+ let signalsMetadata;
235
+
236
+ // 3. For beaconId in beaconIds:
237
+ for (const beaconId of beaconIds) {
238
+ // 3.1 Find the beacon services in the sourceDocument
239
+ const beaconService = sourceDocument.service.find((s: DidService) => s.id === beaconId);
240
+
241
+ // 3.2 If no beaconService MUST throw beaconNotFound error.
242
+ if (!beaconService) {
243
+ throw new Btcr2Error('Not found: sourceDocument does not contain beaconId', INVALID_DID_DOCUMENT, { beaconId });
244
+ }
245
+
246
+ // 3.3 Push beaconService to beaconServices.
247
+ beaconServices.push(beaconService);
248
+ }
249
+
250
+ // 4. For beaconService in beaconServices:
251
+ for (const beaconService of beaconServices) {
252
+ // 4.1 Set signalMetadata to null.
253
+ // 4.2 If beaconService.type == SingletonBeacon:
254
+ // 4.2.1 Set signalMetadata to the result of passing beaconService and didUpdateInvocation to the Broadcast
255
+ // Singleton Beacon Signal algorithm.
256
+ // 4.3 Else If beaconService.type == CIDAggregateBeacon:
257
+ // 4.3.1 Set signalMetadata to the result of passing btc1Identifier, beaconService and didUpdateInvocation to
258
+ // the Broadcast CIDAggregate Beacon Signal algorithm.
259
+ // 4.4 Else If beaconService.type == SMTAggregateBeacon:
260
+ // 4.4.1 Set signalMetadata to the result of passing btc1Identifier, beaconService and didUpdateInvocation to
261
+ // the Broadcast SMTAggregate Beacon Signal algorithm.
262
+ // 4.5 Else:
263
+ // 4.5.1 MUST throw invalidBeacon error.
264
+ const beacon = BeaconFactory.establish(beaconService);
265
+ signalsMetadata = await beacon.broadcastSignal(didUpdateInvocation);
266
+ }
267
+ if(!signalsMetadata) {
268
+ throw new Btcr2Error(
269
+ 'Invalid beacon: no signalsMetadata found',
270
+ INVALID_DID_DOCUMENT, { beaconServices }
271
+ );
272
+ }
273
+ Logger.debug('signalsMetadata', signalsMetadata);
274
+ // Return the signalsMetadata
275
+ return signalsMetadata;
276
+ }
277
+ }
@@ -0,0 +1,364 @@
1
+ import {
2
+ Btcr2KeyManagerError,
3
+ HashBytes,
4
+ Hex,
5
+ SchnorrKeyPairObject,
6
+ Logger,
7
+ MULTIBASE_URI_PREFIX,
8
+ KeyBytes,
9
+ SignatureBytes
10
+ } from '@did-btcr2/common';
11
+ import { SchnorrMultikey } from '@did-btcr2/cryptosuite';
12
+ import { SchnorrKeyPair, PublicKey } from '@did-btcr2/keypair';
13
+ import { sha256 } from '@noble/hashes/sha2';
14
+ import { KeyValueStore, MemoryStore } from '@web5/common';
15
+ import { KeyIdentifier } from '@web5/crypto';
16
+ import { Did } from '@web5/dids';
17
+ import { Multibase } from 'multiformats';
18
+ import { AvailableNetworks } from '../../bitcoin/index.js';
19
+ import { BitcoinSigner, Btc1KeyManagerOptions, CryptoSigner, KeyManager, KeyManagerParams } from './interface.js';
20
+
21
+ export interface Btc1Signer {
22
+ multikey: SchnorrMultikey;
23
+ network: keyof AvailableNetworks;
24
+ };
25
+
26
+ /**
27
+ * Class for managing cryptographic keys for the B DID method.
28
+ * @class Btc1KeyManager
29
+ * @type {Btc1KeyManager}
30
+ */
31
+ export class Btc1KeyManager implements KeyManager, CryptoSigner, BitcoinSigner {
32
+ /**
33
+ * Singleton instance of the Btc1KeyManager.
34
+ * @private
35
+ * @type {Btc1KeyManager}
36
+ */
37
+ static #instance?: Btc1KeyManager;
38
+
39
+ /**
40
+ * The `activeKeyUri` property is a string that represents the URI of the currently active key.
41
+ * It is used to identify the key that will be used for signing and verifying operations.
42
+ * This property is optional and can be set to a specific key URI when initializing the
43
+ * `Btc1KeyManager` instance. If not set, the key manager will use the default key URI.
44
+ * @type {KeyIdentifier}
45
+ */
46
+ public activeKeyUri?: KeyIdentifier;
47
+
48
+ /**
49
+ * The `_store` private variable in `Btc1KeyManager` is a `KeyValueStore` instance used for
50
+ * storing and managing cryptographic keys. It allows the `Btc1KeyManager` class to save,
51
+ * retrieve, and handle keys efficiently within the local Key Management System (KMS) context.
52
+ * This variable can be configured to use different storage backends, like in-memory storage or
53
+ * persistent storage, providing flexibility in key management according to the application's
54
+ * requirements.
55
+ * @private
56
+ * @readonly
57
+ * @type {KeyValueStore<KeyIdentifier, SchnorrKeyPair>} The key store for managing cryptographic keys.
58
+ */
59
+ private readonly _store: KeyValueStore<KeyIdentifier, SchnorrMultikey>;
60
+
61
+ /**
62
+ * Creates an instance of Btc1KeyManager.
63
+ * @param {?KeyManagerParams} params The parameters to initialize the key manager.
64
+ * @param {KeyValueStore<KeyIdentifier, SchnorrMultikey>} params.store An optional property to specify a custom
65
+ * `KeyValueStore` instance for key management. If not provided, {@link Btc1KeyManager} uses a default `MemoryStore`
66
+ * instance. This store is responsible for managing cryptographic keys, allowing them to be retrieved, stored, and
67
+ * managed during cryptographic operations.
68
+ * @param {KeyIdentifier} params.keyUri An optional property to specify the active key URI for the key manager.
69
+ */
70
+ constructor({ store, keyUri, keys }: KeyManagerParams = {}) {
71
+ // Set the default key store to a MemoryStore instance
72
+ this._store = store ?? new MemoryStore<KeyIdentifier, SchnorrMultikey>();
73
+
74
+ // Import the keys into the key store
75
+ if (keyUri && keys) {
76
+ void this.importKey(keys, keyUri).then(() => {
77
+ this.activeKeyUri = keyUri;
78
+ });
79
+ }
80
+ }
81
+
82
+ /**
83
+ * Gets the singleton instance of the Btc1KeyManager.
84
+ * @returns {Btc1KeyManager} The singleton instance of the Btc1KeyManager.
85
+ */
86
+ public static get instance(): Btc1KeyManager {
87
+ // Check if the Btc1KeyManager instance is initialized
88
+ if (!Btc1KeyManager.#instance) {
89
+ throw new Btcr2KeyManagerError('Btc1KeyManager not initialized. Call initialize() first.', 'KEY_MANAGER_NOT_INITIALIZED');
90
+ }
91
+ // Return the singleton instance
92
+ const instance = Btc1KeyManager.#instance;
93
+ return instance;
94
+ }
95
+
96
+ /**
97
+ * Signs a transaction using the key associated with the key URI.
98
+ * @param {Hex} txHex The transaction hex to sign.
99
+ * @param {KeyIdentifier} keyUri The URI of the key to sign the transaction with.
100
+ * @returns {Promise<Hex>} A promise resolving to the signed transaction hex.
101
+ */
102
+ signTransaction(txHex: Hex, keyUri?: KeyIdentifier): Promise<Hex> {
103
+ throw new Error('Method not implemented.' + txHex + keyUri);
104
+ }
105
+
106
+ /**
107
+ * Gets the key pair from the key store and returns a PublicKey.
108
+ * @param {KeyIdentifier} keyUri The URI of the key to get the public key for.
109
+ * @returns {Promise<PublicKey>} The public key associated with the key URI.
110
+ */
111
+ public async getPublicKey(keyUri?: KeyIdentifier): Promise<PublicKey> {
112
+ // Use the active key URI if not provided
113
+ const key = await this.getKey(keyUri);
114
+
115
+ // Check if the key exists and has a public key
116
+ if (!key?.publicKey) {
117
+ throw new Btcr2KeyManagerError(`Key not found for URI: ${keyUri}`, 'KEY_NOT_FOUND');
118
+ }
119
+
120
+ // Return the public key
121
+ return key.publicKey;
122
+ }
123
+
124
+ /**
125
+ * Signs the given data using the key associated with the key URI.
126
+ * @param {Hex} data The data to sign.
127
+ * @param {?KeyIdentifier} keyUri The URI of the key to sign the data with.
128
+ * @returns {Promise<SignatureBytes>} A promise resolving to the signature of the data.
129
+ */
130
+ public async sign(data: Hex, keyUri?: KeyIdentifier): Promise<SignatureBytes> {
131
+ // Get the key from the store
132
+ const key = await this.getKey(keyUri);
133
+
134
+ // Check if the key exists
135
+ if (!key) {
136
+ throw new Btcr2KeyManagerError(`Key URI ${keyUri} not found`, 'KEY_NOT_FOUND');
137
+ }
138
+
139
+ // Check if the key can sign
140
+ if(!key.signer) {
141
+ throw new Btcr2KeyManagerError(`Key URI ${keyUri} is not a signer`, 'KEY_NOT_SIGNER');
142
+ }
143
+
144
+ // Sign the data using the key and return the signature
145
+ return key.sign(data);
146
+ }
147
+
148
+ /**
149
+ * Verifies a signature using the key associated with the key URI.
150
+ * @param {KeyIdentifier} keyUri The URI of the key to verify the signature with.
151
+ * @param {SignatureBytes} signature The signature to verify.
152
+ * @param {Hex} data The data to verify the signature with.
153
+ * @returns {Promise<boolean>} A promise resolving to a boolean indicating the verification result.
154
+ */
155
+ public async verify(signature: SignatureBytes, data: Hex, keyUri?: KeyIdentifier): Promise<boolean> {
156
+ // Get the key from the store
157
+ const key = await this.getKey(keyUri);
158
+
159
+ // Check if the key exists
160
+ if (!key) {
161
+ throw new Btcr2KeyManagerError(`Key not found for URI: ${keyUri}`, 'KEY_NOT_FOUND');
162
+ }
163
+
164
+ // Verify the signature using the multikey
165
+ return key.verify(signature, data);
166
+ }
167
+
168
+ /**
169
+ * Gets the key pair from the key store.
170
+ * @param {KeyIdentifier} keyUri The URI of the key to get.
171
+ * @returns {Promise<SchnorrKeyPair>} The key pair associated with the key URI.
172
+ * @throws {Btcr2KeyManagerError} If the key is not found in the key store.
173
+ */
174
+ private async getKey(keyUri?: KeyIdentifier): Promise<SchnorrMultikey | undefined> {
175
+ // Use the active key URI if not provided
176
+ const uri = keyUri ?? this.activeKeyUri;
177
+
178
+ // Throw an error if no key URI is provided or active
179
+ if (!uri) {
180
+ throw new Btcr2KeyManagerError('No active key uri set.', 'ACTIVE_KEY_URI_NOT_SET');
181
+ }
182
+
183
+ // Get the key pair from the key store
184
+ return await this._store.get(uri);
185
+ }
186
+
187
+ /**
188
+ * Exports the full multikeypair from the key store.
189
+ * @returns {Promise<SchnorrKeyPair>} The key pair associated with the key URI.
190
+ * @throws {Btcr2KeyManagerError} If the key is not found in the key store.
191
+ */
192
+ public async exportKey(keyUri?: KeyIdentifier): Promise<SchnorrMultikey | undefined> {
193
+ // Get the key from the key store and return it
194
+ return await this.getKey(keyUri);
195
+ }
196
+
197
+ /**
198
+ * Imports a keypair to the store.
199
+ * @param {SchnorrKeyPair} keys The keypair to import.
200
+ * @param {KeyIdentifier} keyUri The URI of the key to import.
201
+ * @param {Btc1KeyManagerOptions} options Relevant import options.
202
+ * @param {boolean} options.active A flag to set the key as active (optional, default: false).
203
+ * @returns {Promise<KeyIdentifier>} A promise that resolves to the key identifier of the imported key.
204
+ */
205
+ public async importKey(keys: SchnorrKeyPair, keyUri: string, options: Btc1KeyManagerOptions = {}): Promise<KeyIdentifier> {
206
+ const parts = Did.parse(keyUri);
207
+ if(!parts) {
208
+ throw new Btcr2KeyManagerError(
209
+ 'Invalid key URI: must be valid, parsable BTCR2 identifier',
210
+ 'INVALID_KEY_URI',
211
+ { keyUri, parts }
212
+ );
213
+ }
214
+
215
+ if(!parts.id) {
216
+ throw new Btcr2KeyManagerError(
217
+ 'Invalid key URI: missing id part',
218
+ 'INVALID_KEY_URI',
219
+ { keyUri, parts }
220
+ );
221
+ }
222
+
223
+ if(!parts.fragment) {
224
+ throw new Btcr2KeyManagerError(
225
+ 'Invalid key URI: missing fragment part',
226
+ 'INVALID_KEY_URI',
227
+ { keyUri, parts }
228
+ );
229
+ }
230
+ // Instantiate a new SchnorrMultikey with the provided keys
231
+ const multikey = new SchnorrMultikey({ controller: parts.uri, id: `#${parts.fragment}`, keys });
232
+
233
+ // Store the keypair in the key store
234
+ await this._store.set(keyUri, multikey);
235
+
236
+ // Set the key as active if required
237
+ if (options.active) {
238
+ this.activeKeyUri = keyUri;
239
+ }
240
+
241
+ // Return the key URI
242
+ return keyUri;
243
+ }
244
+
245
+ /**
246
+ * Computes the hash of the given data.
247
+ * @param {Uint8Array} data The data to hash.
248
+ * @returns {HashBytes} The hash of the data.
249
+ */
250
+ public digest(data: Uint8Array): HashBytes {
251
+ return sha256(data);
252
+ }
253
+
254
+ /**
255
+ * Computes the key URI of a given keypair.
256
+ * @param {string} id The fragment identifier (e.g. 'key-1').
257
+ * @param {string} [controller] The DID controller (e.g. 'did:btcr2:xyz').
258
+ * @returns {KeyIdentifier} A full DID fragment URI (e.g. 'did:btcr2:xyz#key-1')
259
+ */
260
+ public static computeKeyUri(id: string, controller: string): KeyIdentifier {
261
+ // Concat the id to the controller and return
262
+ return `${controller}${id.startsWith('#') ? id : `#${id}`}`;
263
+ }
264
+
265
+ /**
266
+ * Computes a multibase-compliant URI from a key.
267
+ * @param key A SchnorrKeyPair, PublicKey, or multibase string
268
+ * @returns {string} A multibase URI (e.g. 'urn:mb:zQ3s...')
269
+ */
270
+ public static toMultibaseUri(data: SchnorrKeyPair | PublicKey | Multibase<'zQ3s'>): string {
271
+ const multibase = data instanceof SchnorrKeyPair
272
+ ? data.publicKey.multibase
273
+ : data instanceof PublicKey
274
+ ? data.multibase
275
+ : data;
276
+
277
+ return `${MULTIBASE_URI_PREFIX}${multibase}`;
278
+ }
279
+
280
+ /**
281
+ * Initializes a singleton Btc1KeyManager instance.
282
+ * @param {SchnorrKeyPair} keys The keypair used to initialize the key manager.
283
+ * @returns {void}
284
+ */
285
+ public static async initialize(keys: SchnorrKeyPair | SchnorrKeyPairObject, keyUri: string): Promise<Btc1KeyManager> {
286
+ if(!(keys instanceof SchnorrKeyPair)) {
287
+ keys = SchnorrKeyPair.fromJSON(keys);
288
+ }
289
+
290
+ // Check if the Btc1KeyManager instance is already initialized
291
+ if (Btc1KeyManager.#instance) {
292
+ Logger.warn('Btc1KeyManager global instance is already initialized.');
293
+ return Btc1KeyManager.#instance;
294
+ }
295
+
296
+ // Check if the keypair is provided
297
+ if(!keys) {
298
+ // Log a warning message if not provided
299
+ Logger.warn('keys not provided, generating ...');
300
+ }
301
+
302
+ // Generate a new keypair if not provided
303
+ keys ??= SchnorrKeyPair.generate();
304
+
305
+ // Initialize the singleton key manager with the keypair
306
+ Btc1KeyManager.#instance = new Btc1KeyManager({ keys });
307
+
308
+ // Import the keypair into the key store
309
+ await Btc1KeyManager.#instance.importKey(keys, keyUri, { active: true });
310
+
311
+ // Set the active key URI
312
+ Btc1KeyManager.#instance.activeKeyUri = keyUri;
313
+
314
+ // Log the active key URI
315
+ Logger.info(`KeyManager initialized with Active Key URI: ${Btc1KeyManager.#instance.activeKeyUri}`);
316
+
317
+ // Return the singleton instance
318
+ return Btc1KeyManager.#instance;
319
+ }
320
+
321
+ /**
322
+ * Retrieves a keypair from the key store using the provided key URI.
323
+ * @public
324
+ * @param {KeyIdentifier} keyUri The URI of the keypair to retrieve.
325
+ * @returns {Promise<SchnorrKeyPair | undefined>} The retrieved keypair, or undefined if not found.
326
+ */
327
+ public static async getKeyPair(keyUri?: KeyIdentifier): Promise<SchnorrMultikey | undefined> {
328
+ // Use the active key URI if not provided
329
+ keyUri ??= Btc1KeyManager.#instance?.activeKeyUri;
330
+ // Instantiate a new Btc1KeyManager with the default key store
331
+ return await Btc1KeyManager.#instance?.getKey(keyUri);
332
+ }
333
+
334
+ public async getKeySigner(keyUri: KeyIdentifier, network: keyof AvailableNetworks): Promise<Signer> {
335
+ const multikey = await this.getKey(keyUri);
336
+ if(!multikey) {
337
+ throw new Btcr2KeyManagerError(`Key not found for URI: ${keyUri}`, 'KEY_NOT_FOUND');
338
+ }
339
+ return new Signer({ multikey, network });
340
+ }
341
+ }
342
+
343
+ export class Signer {
344
+ public multikey: SchnorrMultikey;
345
+ public network: keyof AvailableNetworks;
346
+
347
+ constructor(params: Btc1Signer) {
348
+ this.multikey = params.multikey;
349
+ this.network = params.network;
350
+ }
351
+
352
+ get publicKey(): KeyBytes {
353
+ // Return the public key from the multikey
354
+ return this.multikey.publicKey.compressed;
355
+ }
356
+
357
+ public sign(hash: Hex): SignatureBytes {
358
+ return this.multikey.sign(hash, { scheme: 'ecdsa' });
359
+ };
360
+
361
+ public signSchnorr(hash: Hex): SignatureBytes {
362
+ return this.multikey.sign(hash);
363
+ }
364
+ }