@did-btcr2/method 0.23.0 → 0.25.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 +96 -50
- package/dist/browser.js +36332 -37280
- package/dist/browser.mjs +36331 -37279
- package/dist/cjs/core/beacon/aggregation/communication/adapter/did-comm.js +1 -1
- package/dist/cjs/core/beacon/aggregation/communication/adapter/did-comm.js.map +1 -1
- package/dist/cjs/core/beacon/aggregation/communication/adapter/nostr.js +1 -1
- package/dist/cjs/core/beacon/aggregation/communication/adapter/nostr.js.map +1 -1
- package/dist/cjs/core/beacon/aggregation/coordinator.js +40 -44
- package/dist/cjs/core/beacon/aggregation/coordinator.js.map +1 -1
- package/dist/cjs/core/beacon/aggregation/participant.js +35 -38
- package/dist/cjs/core/beacon/aggregation/participant.js.map +1 -1
- package/dist/cjs/core/beacon/aggregation/session/index.js +3 -4
- package/dist/cjs/core/beacon/aggregation/session/index.js.map +1 -1
- package/dist/cjs/core/beacon/beacon.js.map +1 -1
- package/dist/cjs/core/beacon/cas-beacon.js +119 -7
- package/dist/cjs/core/beacon/cas-beacon.js.map +1 -1
- package/dist/cjs/core/beacon/factory.js +1 -1
- package/dist/cjs/core/beacon/factory.js.map +1 -1
- package/dist/cjs/core/beacon/{singleton.js → singleton-beacon.js} +19 -27
- package/dist/cjs/core/beacon/singleton-beacon.js.map +1 -0
- package/dist/cjs/core/beacon/smt-beacon.js +1 -1
- package/dist/cjs/core/beacon/smt-beacon.js.map +1 -1
- package/dist/cjs/core/identifier.js +1 -1
- package/dist/cjs/core/identifier.js.map +1 -1
- package/dist/{esm/core/resolve.js → cjs/core/resolver.js} +244 -92
- package/dist/cjs/core/resolver.js.map +1 -0
- package/dist/cjs/core/update.js +7 -7
- package/dist/cjs/core/update.js.map +1 -1
- package/dist/cjs/did-btcr2.js +34 -94
- package/dist/cjs/did-btcr2.js.map +1 -1
- package/dist/cjs/index.js +2 -3
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/utils/did-document.js +9 -19
- package/dist/cjs/utils/did-document.js.map +1 -1
- package/dist/esm/core/beacon/aggregation/communication/adapter/did-comm.js +1 -1
- package/dist/esm/core/beacon/aggregation/communication/adapter/did-comm.js.map +1 -1
- package/dist/esm/core/beacon/aggregation/communication/adapter/nostr.js +1 -1
- package/dist/esm/core/beacon/aggregation/communication/adapter/nostr.js.map +1 -1
- package/dist/esm/core/beacon/aggregation/coordinator.js +40 -44
- package/dist/esm/core/beacon/aggregation/coordinator.js.map +1 -1
- package/dist/esm/core/beacon/aggregation/participant.js +35 -38
- package/dist/esm/core/beacon/aggregation/participant.js.map +1 -1
- package/dist/esm/core/beacon/aggregation/session/index.js +3 -4
- package/dist/esm/core/beacon/aggregation/session/index.js.map +1 -1
- package/dist/esm/core/beacon/beacon.js.map +1 -1
- package/dist/esm/core/beacon/cas-beacon.js +119 -7
- package/dist/esm/core/beacon/cas-beacon.js.map +1 -1
- package/dist/esm/core/beacon/factory.js +1 -1
- package/dist/esm/core/beacon/factory.js.map +1 -1
- package/dist/esm/core/beacon/{singleton.js → singleton-beacon.js} +19 -27
- package/dist/esm/core/beacon/singleton-beacon.js.map +1 -0
- package/dist/esm/core/beacon/smt-beacon.js +1 -1
- package/dist/esm/core/beacon/smt-beacon.js.map +1 -1
- package/dist/esm/core/identifier.js +1 -1
- package/dist/esm/core/identifier.js.map +1 -1
- package/dist/{cjs/core/resolve.js → esm/core/resolver.js} +244 -92
- package/dist/esm/core/resolver.js.map +1 -0
- package/dist/esm/core/update.js +7 -7
- package/dist/esm/core/update.js.map +1 -1
- package/dist/esm/did-btcr2.js +34 -94
- package/dist/esm/did-btcr2.js.map +1 -1
- package/dist/esm/index.js +2 -3
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/utils/did-document.js +9 -19
- package/dist/esm/utils/did-document.js.map +1 -1
- package/dist/types/core/beacon/aggregation/cohort/index.d.ts +1 -0
- package/dist/types/core/beacon/aggregation/cohort/messages/base.d.ts +1 -0
- package/dist/types/core/beacon/aggregation/cohort/messages/constants.d.ts +1 -0
- package/dist/types/core/beacon/aggregation/cohort/messages/index.d.ts +1 -0
- package/dist/types/core/beacon/aggregation/cohort/messages/keygen/cohort-advert.d.ts +1 -0
- package/dist/types/core/beacon/aggregation/cohort/messages/keygen/cohort-ready.d.ts +2 -2
- package/dist/types/core/beacon/aggregation/cohort/messages/keygen/cohort-ready.d.ts.map +1 -1
- package/dist/types/core/beacon/aggregation/cohort/messages/keygen/opt-in-accept.d.ts +1 -0
- package/dist/types/core/beacon/aggregation/cohort/messages/keygen/opt-in.d.ts +1 -0
- package/dist/types/core/beacon/aggregation/cohort/messages/keygen/subscribe.d.ts +1 -0
- package/dist/types/core/beacon/aggregation/cohort/messages/sign/aggregated-nonce.d.ts +1 -0
- package/dist/types/core/beacon/aggregation/cohort/messages/sign/authorization-request.d.ts +1 -0
- package/dist/types/core/beacon/aggregation/cohort/messages/sign/nonce-contribution.d.ts +1 -0
- package/dist/types/core/beacon/aggregation/cohort/messages/sign/request-signature.d.ts +1 -0
- package/dist/types/core/beacon/aggregation/cohort/messages/sign/signature-authorization.d.ts +1 -0
- package/dist/types/core/beacon/aggregation/cohort/status.d.ts +1 -0
- package/dist/types/core/beacon/aggregation/communication/adapter/did-comm.d.ts +4 -3
- package/dist/types/core/beacon/aggregation/communication/adapter/did-comm.d.ts.map +1 -1
- package/dist/types/core/beacon/aggregation/communication/adapter/nostr.d.ts +5 -3
- package/dist/types/core/beacon/aggregation/communication/adapter/nostr.d.ts.map +1 -1
- package/dist/types/core/beacon/aggregation/communication/error.d.ts +1 -0
- package/dist/types/core/beacon/aggregation/communication/factory.d.ts +1 -0
- package/dist/types/core/beacon/aggregation/communication/service.d.ts +3 -2
- package/dist/types/core/beacon/aggregation/communication/service.d.ts.map +1 -1
- package/dist/types/core/beacon/aggregation/coordinator.d.ts +1 -0
- package/dist/types/core/beacon/aggregation/coordinator.d.ts.map +1 -1
- package/dist/types/core/beacon/aggregation/participant.d.ts +1 -0
- package/dist/types/core/beacon/aggregation/participant.d.ts.map +1 -1
- package/dist/types/core/beacon/aggregation/session/index.d.ts +1 -0
- package/dist/types/core/beacon/aggregation/session/index.d.ts.map +1 -1
- package/dist/types/core/beacon/aggregation/session/status.d.ts +1 -0
- package/dist/types/core/beacon/beacon.d.ts +10 -4
- package/dist/types/core/beacon/beacon.d.ts.map +1 -1
- package/dist/types/core/beacon/cas-beacon.d.ts +27 -7
- package/dist/types/core/beacon/cas-beacon.d.ts.map +1 -1
- package/dist/types/core/beacon/error.d.ts +1 -0
- package/dist/types/core/beacon/factory.d.ts +1 -0
- package/dist/types/core/beacon/interfaces.d.ts +1 -0
- package/dist/types/core/beacon/signal-discovery.d.ts +1 -0
- package/dist/types/core/beacon/{singleton.d.ts → singleton-beacon.d.ts} +7 -5
- package/dist/types/core/beacon/singleton-beacon.d.ts.map +1 -0
- package/dist/types/core/beacon/smt-beacon.d.ts +5 -3
- package/dist/types/core/beacon/smt-beacon.d.ts.map +1 -1
- package/dist/types/core/beacon/utils.d.ts +1 -0
- package/dist/types/core/identifier.d.ts +1 -0
- package/dist/types/core/interfaces.d.ts +6 -15
- package/dist/types/core/interfaces.d.ts.map +1 -1
- package/dist/types/core/resolver.d.ts +167 -0
- package/dist/types/core/resolver.d.ts.map +1 -0
- package/dist/types/core/types.d.ts +1 -0
- package/dist/types/core/update.d.ts +4 -3
- package/dist/types/core/update.d.ts.map +1 -1
- package/dist/types/did-btcr2.d.ts +17 -16
- package/dist/types/did-btcr2.d.ts.map +1 -1
- package/dist/types/index.d.ts +3 -3
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/utils/appendix.d.ts +1 -0
- package/dist/types/utils/did-document-builder.d.ts +1 -0
- package/dist/types/utils/did-document.d.ts +2 -6
- package/dist/types/utils/did-document.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/core/beacon/aggregation/cohort/messages/keygen/cohort-ready.ts +1 -1
- package/src/core/beacon/aggregation/communication/adapter/did-comm.ts +4 -3
- package/src/core/beacon/aggregation/communication/adapter/nostr.ts +4 -3
- package/src/core/beacon/aggregation/communication/service.ts +2 -2
- package/src/core/beacon/aggregation/coordinator.ts +40 -44
- package/src/core/beacon/aggregation/participant.ts +38 -40
- package/src/core/beacon/aggregation/session/index.ts +3 -4
- package/src/core/beacon/beacon.ts +9 -5
- package/src/core/beacon/cas-beacon.ts +156 -10
- package/src/core/beacon/factory.ts +1 -1
- package/src/core/beacon/{singleton.ts → singleton-beacon.ts} +20 -36
- package/src/core/beacon/smt-beacon.ts +4 -3
- package/src/core/identifier.ts +1 -1
- package/src/core/interfaces.ts +5 -16
- package/src/core/resolver.ts +706 -0
- package/src/core/update.ts +9 -9
- package/src/did-btcr2.ts +37 -130
- package/src/index.ts +2 -3
- package/src/utils/did-document.ts +10 -18
- package/dist/cjs/core/beacon/singleton.js.map +0 -1
- package/dist/cjs/core/resolve.js.map +0 -1
- package/dist/cjs/utils/general.js +0 -195
- package/dist/cjs/utils/general.js.map +0 -1
- package/dist/esm/core/beacon/singleton.js.map +0 -1
- package/dist/esm/core/resolve.js.map +0 -1
- package/dist/esm/utils/general.js +0 -195
- package/dist/esm/utils/general.js.map +0 -1
- package/dist/types/core/beacon/singleton.d.ts.map +0 -1
- package/dist/types/core/resolve.d.ts +0 -92
- package/dist/types/core/resolve.d.ts.map +0 -1
- package/dist/types/utils/general.d.ts +0 -85
- package/dist/types/utils/general.d.ts.map +0 -1
- package/src/core/resolve.ts +0 -474
- package/src/utils/general.ts +0 -204
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { KeyBytes,
|
|
1
|
+
import { KeyBytes, Maybe } from '@did-btcr2/common';
|
|
2
2
|
import { HDKey } from '@scure/bip32';
|
|
3
3
|
import { mnemonicToSeedSync } from '@scure/bip39';
|
|
4
4
|
import * as musig2 from '@scure/btc-signer/musig2';
|
|
@@ -130,7 +130,7 @@ export class BeaconParticipant {
|
|
|
130
130
|
this.protocol = protocol || new NostrAdapter();
|
|
131
131
|
this.protocol.setKeys({ public: pk, secret });
|
|
132
132
|
this.cohortKeyState.set('__UNSET__', this.beaconKeyIndex);
|
|
133
|
-
|
|
133
|
+
console.debug(`BeaconParticipant initialized with DID: ${this.did}, Name: ${this.name}, Key Index: ${this.beaconKeyIndex}`);
|
|
134
134
|
}
|
|
135
135
|
|
|
136
136
|
/**
|
|
@@ -138,7 +138,7 @@ export class BeaconParticipant {
|
|
|
138
138
|
* @returns {void}
|
|
139
139
|
*/
|
|
140
140
|
public start(): void {
|
|
141
|
-
|
|
141
|
+
console.info(`Setting up BeaconParticipant ${this.name} (${this.did}) on ${this.protocol.name} ...`);
|
|
142
142
|
this.protocol.registerMessageHandler(BEACON_COHORT_ADVERT, this._handleCohortAdvert.bind(this));
|
|
143
143
|
this.protocol.registerMessageHandler(BEACON_COHORT_OPT_IN_ACCEPT, this._handleSubscribeAccept.bind(this));
|
|
144
144
|
this.protocol.registerMessageHandler(BEACON_COHORT_READY, this._handleCohortReady.bind(this));
|
|
@@ -171,10 +171,10 @@ export class BeaconParticipant {
|
|
|
171
171
|
this.beaconKeyIndex = this.cohortKeyState.size + 1;
|
|
172
172
|
}
|
|
173
173
|
if(this.cohortKeyState.has(cohortId)) {
|
|
174
|
-
|
|
174
|
+
console.warn(`Cohort key state for cohort ${cohortId} already exists. Updating key index.`);
|
|
175
175
|
}
|
|
176
176
|
this.cohortKeyState.set(cohortId, this.beaconKeyIndex);
|
|
177
|
-
|
|
177
|
+
console.info(`Cohort key state updated. Next beacon key index: ${this.beaconKeyIndex + 1}`);
|
|
178
178
|
}
|
|
179
179
|
|
|
180
180
|
/**
|
|
@@ -196,7 +196,7 @@ export class BeaconParticipant {
|
|
|
196
196
|
}
|
|
197
197
|
|
|
198
198
|
if (this.cohortKeyState.has(cohortId)) {
|
|
199
|
-
|
|
199
|
+
console.warn(`Cohort key state already exists for ${cohortId}. Skipping migration from '__UNSET__'.`);
|
|
200
200
|
this.cohortKeyState.delete(unsetKey);
|
|
201
201
|
return;
|
|
202
202
|
}
|
|
@@ -204,7 +204,7 @@ export class BeaconParticipant {
|
|
|
204
204
|
this.setCohortKey(cohortId);
|
|
205
205
|
this.cohortKeyState.delete(unsetKey);
|
|
206
206
|
|
|
207
|
-
|
|
207
|
+
console.info(`Finalized '__UNSET__' CohortKeyState with ${cohortId} for ${this.did}`);
|
|
208
208
|
}
|
|
209
209
|
|
|
210
210
|
/**
|
|
@@ -226,25 +226,25 @@ export class BeaconParticipant {
|
|
|
226
226
|
* @returns {Promise<void>}
|
|
227
227
|
*/
|
|
228
228
|
public async _handleCohortAdvert(message: Maybe<CohortAdvertMessage>): Promise<void> {
|
|
229
|
-
|
|
229
|
+
console.debug('_handleCohortAdvert', message);
|
|
230
230
|
const cohortAdvertMessage = BeaconCohortAdvertMessage.fromJSON(message);
|
|
231
|
-
|
|
231
|
+
console.info(`Received new cohort announcement from ${cohortAdvertMessage.from}`, cohortAdvertMessage);
|
|
232
232
|
|
|
233
233
|
const cohortId = cohortAdvertMessage.body?.cohortId;
|
|
234
234
|
if (!cohortId) {
|
|
235
|
-
|
|
235
|
+
console.warn('Received malformed cohort advert message: missing cohortId', cohortAdvertMessage);
|
|
236
236
|
return;
|
|
237
237
|
}
|
|
238
238
|
|
|
239
239
|
const network = cohortAdvertMessage.body?.network;
|
|
240
240
|
if (!network) {
|
|
241
|
-
|
|
241
|
+
console.warn('Received malformed cohort advert message: missing network', cohortAdvertMessage);
|
|
242
242
|
return;
|
|
243
243
|
}
|
|
244
244
|
|
|
245
245
|
const minParticipants = cohortAdvertMessage.body?.cohortSize;
|
|
246
246
|
if (!cohortId || !network || !minParticipants) {
|
|
247
|
-
|
|
247
|
+
console.warn('Received malformed cohort advert message: missing minParticipants', cohortAdvertMessage);
|
|
248
248
|
return;
|
|
249
249
|
}
|
|
250
250
|
|
|
@@ -271,30 +271,30 @@ export class BeaconParticipant {
|
|
|
271
271
|
const cohortId = cohortSetMessage.body?.cohortId;
|
|
272
272
|
const cohort = this.cohorts.find(c => c.id === cohortId);
|
|
273
273
|
if (!cohortId || !cohort) {
|
|
274
|
-
|
|
274
|
+
console.warn(`Cohort with ID ${cohortId} not found or not joined by participant ${this.did}.`);
|
|
275
275
|
return;
|
|
276
276
|
}
|
|
277
277
|
this.finalizeUnsetCohortKey(cohortId);
|
|
278
278
|
const participantPkBytes = this.getCohortKey(cohortId).publicKey;
|
|
279
279
|
if(!participantPkBytes) {
|
|
280
|
-
|
|
280
|
+
console.error(`Failed to derive public key for cohort ${cohortId}`);
|
|
281
281
|
return;
|
|
282
282
|
}
|
|
283
283
|
const participantPk = Buffer.from(participantPkBytes).toString('hex');
|
|
284
284
|
const beaconAddress = cohortSetMessage.body?.beaconAddress;
|
|
285
285
|
if(!beaconAddress) {
|
|
286
|
-
|
|
286
|
+
console.error(`Beacon address not provided in cohort set message for ${cohortId}`);
|
|
287
287
|
return;
|
|
288
288
|
}
|
|
289
289
|
const cohortKeys = cohortSetMessage.body?.cohortKeys;
|
|
290
290
|
if(!cohortKeys) {
|
|
291
|
-
|
|
291
|
+
console.error(`Cohort keys not provided in cohort set message for ${cohortId}`);
|
|
292
292
|
return;
|
|
293
293
|
}
|
|
294
294
|
const keys = cohortKeys.map(key => Buffer.from(key).toString('hex'));
|
|
295
295
|
cohort.validateCohort([participantPk], keys, beaconAddress);
|
|
296
|
-
|
|
297
|
-
|
|
296
|
+
console.info(`BeaconParticipant w/ pk ${participantPk} successfully joined cohort ${cohortId} with beacon address ${beaconAddress}.`);
|
|
297
|
+
console.info(`Cohort status: ${cohort.status}`);
|
|
298
298
|
}
|
|
299
299
|
|
|
300
300
|
/**
|
|
@@ -306,17 +306,17 @@ export class BeaconParticipant {
|
|
|
306
306
|
const authRequest = BeaconCohortAuthorizationRequestMessage.fromJSON(message);
|
|
307
307
|
const cohort = this.cohorts.find(c => c.id === authRequest.body?.cohortId);
|
|
308
308
|
if (!cohort) {
|
|
309
|
-
|
|
309
|
+
console.warn(`Authorization request for unknown cohort ${authRequest.body?.cohortId} from ${authRequest.from}`);
|
|
310
310
|
return;
|
|
311
311
|
}
|
|
312
312
|
const id = authRequest.body?.sessionId;
|
|
313
313
|
if (!id) {
|
|
314
|
-
|
|
314
|
+
console.warn(`Authorization request missing session ID from ${authRequest.from}`);
|
|
315
315
|
return;
|
|
316
316
|
}
|
|
317
317
|
const pendingTx = authRequest.body?.pendingTx;
|
|
318
318
|
if (!pendingTx) {
|
|
319
|
-
|
|
319
|
+
console.warn(`Authorization request missing pending transaction from ${authRequest.from}`);
|
|
320
320
|
return;
|
|
321
321
|
}
|
|
322
322
|
const session = new BeaconCohortSigningSession({
|
|
@@ -338,23 +338,23 @@ export class BeaconParticipant {
|
|
|
338
338
|
const aggNonceMessage = BeaconCohortAggregatedNonceMessage.fromJSON(message);
|
|
339
339
|
const sessionId = aggNonceMessage.body?.sessionId;
|
|
340
340
|
if (!sessionId) {
|
|
341
|
-
|
|
341
|
+
console.warn(`Aggregated nonce message missing session ID from ${aggNonceMessage.from}`);
|
|
342
342
|
return;
|
|
343
343
|
}
|
|
344
344
|
const session = this.activeSigningSessions.get(sessionId);
|
|
345
345
|
if (!session) {
|
|
346
|
-
|
|
346
|
+
console.warn(`Aggregated nonce message received for unknown session ${sessionId}`);
|
|
347
347
|
return;
|
|
348
348
|
}
|
|
349
349
|
const aggregatedNonce = aggNonceMessage.body?.aggregatedNonce;
|
|
350
350
|
if (!aggregatedNonce) {
|
|
351
|
-
|
|
351
|
+
console.warn(`Aggregated nonce message missing aggregated nonce from ${aggNonceMessage.from}`);
|
|
352
352
|
return;
|
|
353
353
|
}
|
|
354
354
|
session.aggregatedNonce = aggregatedNonce;
|
|
355
355
|
const participantSk = this.getCohortKey(session.cohort.id).privateKey;
|
|
356
356
|
if(!participantSk) {
|
|
357
|
-
|
|
357
|
+
console.error(`Failed to derive secret key for cohort ${session.cohort.id}`);
|
|
358
358
|
return;
|
|
359
359
|
}
|
|
360
360
|
const partialSig = session.generatePartialSignature(participantSk);
|
|
@@ -368,7 +368,7 @@ export class BeaconParticipant {
|
|
|
368
368
|
*/
|
|
369
369
|
public async subscribeToCoordinator(coordinatorDid: string): Promise<any> {
|
|
370
370
|
if(this.coordinatorDids.includes(coordinatorDid)) {
|
|
371
|
-
|
|
371
|
+
console.info(`Already subscribed to coordinator ${coordinatorDid}`);
|
|
372
372
|
return;
|
|
373
373
|
}
|
|
374
374
|
const subMessage = new BeaconCohortSubscribeMessage({ to: coordinatorDid, from: this.did });
|
|
@@ -382,16 +382,16 @@ export class BeaconParticipant {
|
|
|
382
382
|
* @returns {Promise<void>}
|
|
383
383
|
*/
|
|
384
384
|
public async joinCohort(cohortId: string, coordinatorDid: string): Promise<void> {
|
|
385
|
-
|
|
385
|
+
console.info(`BeaconParticipant ${this.did} joining cohort ${cohortId} with coordinator ${coordinatorDid}`);
|
|
386
386
|
this.finalizeUnsetCohortKey(cohortId);
|
|
387
387
|
const cohort = this.cohorts.find(c => c.id === cohortId);
|
|
388
388
|
if (!cohort) {
|
|
389
|
-
|
|
389
|
+
console.warn(`Cohort with ID ${cohortId} not found.`);
|
|
390
390
|
return;
|
|
391
391
|
}
|
|
392
392
|
const pk = this.getCohortKey(cohortId).publicKey;
|
|
393
393
|
if(!pk) {
|
|
394
|
-
|
|
394
|
+
console.error(`Failed to derive public key for cohort ${cohortId} at index ${this.beaconKeyIndex}`);
|
|
395
395
|
return;
|
|
396
396
|
}
|
|
397
397
|
this.setCohortKey(cohortId);
|
|
@@ -415,11 +415,11 @@ export class BeaconParticipant {
|
|
|
415
415
|
public async requestCohortSignature(cohortId: string, data: string): Promise<boolean> {
|
|
416
416
|
const cohort = this.cohorts.find(c => c.id === cohortId);
|
|
417
417
|
if (!cohort) {
|
|
418
|
-
|
|
418
|
+
console.warn(`Cohort with ID ${cohortId} not found.`);
|
|
419
419
|
return false;
|
|
420
420
|
}
|
|
421
421
|
if(cohort.status !== COHORT_STATUS.COHORT_SET_STATUS) {
|
|
422
|
-
|
|
422
|
+
console.warn(`Cohort ${cohortId} not in a set state. Current status: ${cohort.status}`);
|
|
423
423
|
return false;
|
|
424
424
|
}
|
|
425
425
|
const reqSigMessage = new BeaconCohortRequestSignatureMessage({
|
|
@@ -469,16 +469,14 @@ export class BeaconParticipant {
|
|
|
469
469
|
session: BeaconCohortSigningSession
|
|
470
470
|
): Promise<void> {
|
|
471
471
|
const nonceContributionMessage = BeaconCohortNonceContributionMessage.fromJSON({
|
|
472
|
-
to
|
|
473
|
-
from
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
nonceContribution
|
|
478
|
-
}
|
|
472
|
+
to : cohort.coordinatorDid,
|
|
473
|
+
from : this.did,
|
|
474
|
+
sessionId : session.id,
|
|
475
|
+
cohortId : cohort.id,
|
|
476
|
+
nonceContribution
|
|
479
477
|
});
|
|
480
478
|
await this.protocol.sendMessage(nonceContributionMessage, this.did, cohort.coordinatorDid);
|
|
481
|
-
|
|
479
|
+
console.info(`Nonce contribution sent for session ${session.id} in cohort ${cohort.id} by participant ${this.did}`);
|
|
482
480
|
}
|
|
483
481
|
|
|
484
482
|
/**
|
|
@@ -496,7 +494,7 @@ export class BeaconParticipant {
|
|
|
496
494
|
partialSignature : partialSig,
|
|
497
495
|
});
|
|
498
496
|
await this.protocol.sendMessage(sigAuthMessage, this.did, session.cohort.coordinatorDid);
|
|
499
|
-
|
|
497
|
+
console.info(`Partial signature sent for session ${session.id} in cohort ${session.cohort.id} by participant ${this.did}`);
|
|
500
498
|
}
|
|
501
499
|
|
|
502
500
|
/**
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { Logger } from '@did-btcr2/common';
|
|
2
1
|
import * as musig2 from '@scure/btc-signer/musig2';
|
|
3
2
|
import { Transaction } from 'bitcoinjs-lib';
|
|
4
3
|
import { AggregateBeaconError } from '../../error.js';
|
|
@@ -166,7 +165,7 @@ export class BeaconCohortSigningSession implements SigningSession {
|
|
|
166
165
|
}
|
|
167
166
|
|
|
168
167
|
if (this.nonceContributions.get(from)) {
|
|
169
|
-
|
|
168
|
+
console.warn(`WARNING: Nonce contribution already received from ${from}.`);
|
|
170
169
|
}
|
|
171
170
|
|
|
172
171
|
this.nonceContributions.set(from, nonceContribution);
|
|
@@ -210,7 +209,7 @@ export class BeaconCohortSigningSession implements SigningSession {
|
|
|
210
209
|
}
|
|
211
210
|
|
|
212
211
|
if(this.partialSignatures.get(from)) {
|
|
213
|
-
|
|
212
|
+
console.warn(`WARNING: Partial signature already received from ${from}.`);
|
|
214
213
|
}
|
|
215
214
|
|
|
216
215
|
this.partialSignatures.set(from, partialSignature);
|
|
@@ -236,7 +235,7 @@ export class BeaconCohortSigningSession implements SigningSession {
|
|
|
236
235
|
}
|
|
237
236
|
|
|
238
237
|
const sigSum = [...this.partialSignatures.values()].reduce((sum, sig) => sum + bigEndianToInt(sig), 0n);
|
|
239
|
-
|
|
238
|
+
console.info(`Aggregated Signature computed: ${sigSum}`);
|
|
240
239
|
|
|
241
240
|
this.aggregatedNonce ??= this.generateAggregatedNonce();
|
|
242
241
|
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { KeyBytes } from '@did-btcr2/common';
|
|
2
2
|
import { BitcoinConnection } from '@did-btcr2/bitcoin';
|
|
3
|
-
import { SignedBTCR2Update } from '
|
|
3
|
+
import { SignedBTCR2Update } from '@did-btcr2/cryptosuite';
|
|
4
|
+
import type { BeaconProcessResult } from '../resolver.js';
|
|
4
5
|
import { SidecarData } from '../types.js';
|
|
5
|
-
import { BeaconService, BeaconSignal
|
|
6
|
+
import { BeaconService, BeaconSignal } from './interfaces.js';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* Abstract base class for all BTCR2 Beacon types.
|
|
@@ -32,15 +33,18 @@ export abstract class Beacon {
|
|
|
32
33
|
/**
|
|
33
34
|
* Processes an array of Beacon Signals to extract BTCR2 Signed Updates.
|
|
34
35
|
* Used during the resolve path.
|
|
36
|
+
*
|
|
37
|
+
* Returns successfully resolved updates and any data needs that must be
|
|
38
|
+
* satisfied before remaining signals can be processed.
|
|
39
|
+
*
|
|
35
40
|
* @param {Array<BeaconSignal>} signals The beacon signals discovered on-chain.
|
|
36
41
|
* @param {SidecarData} sidecar The processed sidecar data containing update/CAS/SMT maps.
|
|
37
|
-
* @returns {
|
|
42
|
+
* @returns {BeaconProcessResult} The updates and any data needs.
|
|
38
43
|
*/
|
|
39
44
|
abstract processSignals(
|
|
40
45
|
signals: Array<BeaconSignal>,
|
|
41
46
|
sidecar: SidecarData,
|
|
42
|
-
):
|
|
43
|
-
|
|
47
|
+
): BeaconProcessResult;
|
|
44
48
|
|
|
45
49
|
/**
|
|
46
50
|
* Broadcasts a signed update as a Beacon Signal to the Bitcoin network.
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import { BitcoinConnection } from '@did-btcr2/bitcoin';
|
|
2
|
-
import { KeyBytes } from '@did-btcr2/common';
|
|
1
|
+
import { AddressUtxo, BitcoinConnection } from '@did-btcr2/bitcoin';
|
|
2
|
+
import { canonicalHash, canonicalize, decode, encode, hash, KeyBytes } from '@did-btcr2/common';
|
|
3
3
|
import { SignedBTCR2Update } from '@did-btcr2/cryptosuite';
|
|
4
|
+
import { SchnorrKeyPair } from '@did-btcr2/keypair';
|
|
5
|
+
import { opcodes, Psbt, script } from 'bitcoinjs-lib';
|
|
6
|
+
import type { BeaconProcessResult, DataNeed } from '../resolver.js';
|
|
4
7
|
import { SidecarData } from '../types.js';
|
|
5
8
|
import { Beacon } from './beacon.js';
|
|
6
9
|
import { CASBeaconError } from './error.js';
|
|
@@ -8,6 +11,13 @@ import { BeaconService, BeaconSignal, BlockMetadata } from './interfaces.js';
|
|
|
8
11
|
|
|
9
12
|
/**
|
|
10
13
|
* Implements {@link https://dcdpr.github.io/did-btcr2/terminology.html#cas-beacon | CAS Beacon}.
|
|
14
|
+
*
|
|
15
|
+
* A CAS (Content-Addressed Store) Beacon aggregates updates for multiple DIDs
|
|
16
|
+
* into a single CAS Announcement — a mapping of DIDs to their update hashes.
|
|
17
|
+
* The hash of the CAS Announcement is broadcast on-chain via OP_RETURN.
|
|
18
|
+
* During resolution, the CAS Announcement is retrieved from the sidecar (or CAS)
|
|
19
|
+
* and used to look up the individual signed update for the DID being resolved.
|
|
20
|
+
*
|
|
11
21
|
* @class CASBeacon
|
|
12
22
|
* @type {CASBeacon}
|
|
13
23
|
* @extends {Beacon}
|
|
@@ -23,31 +33,167 @@ export class CASBeacon extends Beacon {
|
|
|
23
33
|
|
|
24
34
|
/**
|
|
25
35
|
* Implements {@link https://dcdpr.github.io/did-btcr2/operations/resolve.html#process-cas-beacon | 7.2.e.1 Process CAS Beacon}.
|
|
36
|
+
*
|
|
37
|
+
* For each signal, the signalBytes contain the hex-encoded hash of a CAS Announcement.
|
|
38
|
+
* The CAS Announcement maps DIDs to their base64url-encoded update hashes.
|
|
39
|
+
* This method looks up the CAS Announcement from the sidecar, extracts the update
|
|
40
|
+
* hash for the DID being resolved, and retrieves the corresponding signed update.
|
|
41
|
+
*
|
|
26
42
|
* @param {Array<BeaconSignal>} signals The array of Beacon Signals to process.
|
|
27
43
|
* @param {SidecarData} sidecar The sidecar data associated with the CAS Beacon.
|
|
28
|
-
* @returns {
|
|
29
|
-
* @throws {CASBeaconError} if
|
|
44
|
+
* @returns {BeaconProcessResult} Successfully resolved updates and any data needs.
|
|
45
|
+
* @throws {CASBeaconError} if hash verification fails (validation errors only).
|
|
30
46
|
*/
|
|
31
47
|
processSignals(
|
|
32
48
|
signals: Array<BeaconSignal>,
|
|
33
49
|
sidecar: SidecarData
|
|
34
|
-
):
|
|
35
|
-
|
|
50
|
+
): BeaconProcessResult {
|
|
51
|
+
const updates = new Array<[SignedBTCR2Update, BlockMetadata]>();
|
|
52
|
+
const needs = new Array<DataNeed>();
|
|
53
|
+
|
|
54
|
+
// Extract the DID from the beacon service id (strip the #fragment)
|
|
55
|
+
const did = this.service.id.split('#')[0];
|
|
56
|
+
|
|
57
|
+
for(const signal of signals) {
|
|
58
|
+
// Decode signal bytes from hex and re-encode to base64url for sidecar lookup
|
|
59
|
+
const announcementHash = encode(decode(signal.signalBytes, 'hex'));
|
|
60
|
+
|
|
61
|
+
// Look up the CAS Announcement in sidecar casMap
|
|
62
|
+
const casAnnouncement = sidecar.casMap.get(announcementHash);
|
|
63
|
+
|
|
64
|
+
if(!casAnnouncement) {
|
|
65
|
+
// CAS Announcement not available — emit a need
|
|
66
|
+
needs.push({
|
|
67
|
+
kind : 'NeedCASAnnouncement',
|
|
68
|
+
announcementHash,
|
|
69
|
+
beaconServiceId : this.service.id
|
|
70
|
+
});
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Look up this DID's update hash in the CAS Announcement
|
|
75
|
+
const updateHash = casAnnouncement[did];
|
|
76
|
+
|
|
77
|
+
// If no entry for this DID, this announcement doesn't contain an update for us — skip
|
|
78
|
+
if(!updateHash) {
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Look up the signed update in sidecar updateMap
|
|
83
|
+
const signedUpdate = sidecar.updateMap.get(updateHash);
|
|
84
|
+
|
|
85
|
+
if(!signedUpdate) {
|
|
86
|
+
// Signed update not available — emit a need
|
|
87
|
+
needs.push({
|
|
88
|
+
kind : 'NeedSignedUpdate',
|
|
89
|
+
updateHash,
|
|
90
|
+
beaconServiceId : this.service.id
|
|
91
|
+
});
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
updates.push([signedUpdate, signal.blockMetadata]);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return { updates, needs };
|
|
36
99
|
}
|
|
37
100
|
|
|
38
101
|
/**
|
|
39
|
-
*
|
|
102
|
+
* Broadcasts a CAS Beacon signal to the Bitcoin network.
|
|
103
|
+
*
|
|
104
|
+
* Creates a CAS Announcement mapping the DID to the update hash, then broadcasts
|
|
105
|
+
* the hash of the announcement via OP_RETURN. The CAS Announcement is distributed
|
|
106
|
+
* to resolvers via sidecar data.
|
|
107
|
+
*
|
|
40
108
|
* @param {SignedBTCR2Update} signedUpdate The signed BTCR2 update to broadcast.
|
|
41
109
|
* @param {KeyBytes} secretKey The secret key for signing the Bitcoin transaction.
|
|
42
110
|
* @param {BitcoinConnection} bitcoin The Bitcoin network connection.
|
|
43
|
-
* @
|
|
44
|
-
* @throws {CASBeaconError} if
|
|
111
|
+
* @returns {Promise<SignedBTCR2Update>} The signed update that was broadcast.
|
|
112
|
+
* @throws {CASBeaconError} if the bitcoin address is invalid or unfunded.
|
|
45
113
|
*/
|
|
46
114
|
async broadcastSignal(
|
|
47
115
|
signedUpdate: SignedBTCR2Update,
|
|
48
116
|
secretKey: KeyBytes,
|
|
49
117
|
bitcoin: BitcoinConnection
|
|
50
118
|
): Promise<SignedBTCR2Update> {
|
|
51
|
-
|
|
119
|
+
// Extract the DID from the beacon service id (strip the #fragment)
|
|
120
|
+
const did = this.service.id.split('#')[0];
|
|
121
|
+
|
|
122
|
+
// Hash the signed update (base64url for the CAS Announcement entry)
|
|
123
|
+
const updateHash = canonicalHash(signedUpdate);
|
|
124
|
+
|
|
125
|
+
// Create the CAS Announcement mapping this DID to its update hash
|
|
126
|
+
const casAnnouncement = { [did]: updateHash };
|
|
127
|
+
|
|
128
|
+
// TODO: Publish CAS Announcement to content-addressed store (e.g., IPFS via Helia)
|
|
129
|
+
|
|
130
|
+
// Canonicalize and hash the CAS Announcement for the OP_RETURN output
|
|
131
|
+
const announcementHash = hash(canonicalize(casAnnouncement));
|
|
132
|
+
|
|
133
|
+
// Convert the serviceEndpoint to a bitcoin address by removing the 'bitcoin:' prefix
|
|
134
|
+
const bitcoinAddress = this.service.serviceEndpoint.replace('bitcoin:', '');
|
|
135
|
+
|
|
136
|
+
// Query the Bitcoin network for UTXOs associated with the bitcoinAddress
|
|
137
|
+
const utxos = await bitcoin.rest.address.getUtxos(bitcoinAddress);
|
|
138
|
+
|
|
139
|
+
// If no utxos are found, throw an error indicating the address is unfunded.
|
|
140
|
+
if(!utxos.length) {
|
|
141
|
+
throw new CASBeaconError(
|
|
142
|
+
'No UTXOs found, please fund address!',
|
|
143
|
+
'UNFUNDED_BEACON_ADDRESS', { bitcoinAddress }
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Sort utxos by block height and take the most recent one
|
|
148
|
+
const utxo: AddressUtxo | undefined = utxos.sort(
|
|
149
|
+
(a, b) => b.status.block_height - a.status.block_height
|
|
150
|
+
).shift();
|
|
151
|
+
|
|
152
|
+
// If no utxos are found, throw an error.
|
|
153
|
+
if(!utxo) {
|
|
154
|
+
throw new CASBeaconError(
|
|
155
|
+
'Beacon bitcoin address unfunded or utxos unconfirmed.',
|
|
156
|
+
'UNFUNDED_BEACON_ADDRESS', { bitcoinAddress }
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Get the previous tx to the utxo being spent
|
|
161
|
+
const prevTx = await bitcoin.rest.transaction.getHex(utxo.txid);
|
|
162
|
+
|
|
163
|
+
// Construct a spend transaction
|
|
164
|
+
const spendTx = new Psbt({ network: bitcoin.data })
|
|
165
|
+
// Spend tx contains the utxo as its input
|
|
166
|
+
.addInput({
|
|
167
|
+
hash : utxo.txid,
|
|
168
|
+
index : utxo.vout,
|
|
169
|
+
nonWitnessUtxo : Buffer.from(prevTx, 'hex')
|
|
170
|
+
})
|
|
171
|
+
// Add a change output minus a fee of 500 sats
|
|
172
|
+
// TODO: calculate fee based on transaction vsize and current fee rates
|
|
173
|
+
.addOutput({ address: bitcoinAddress, value: BigInt(utxo.value) - BigInt(500) })
|
|
174
|
+
// Add an OP_RETURN output containing the CAS Announcement hash
|
|
175
|
+
.addOutput({ script: script.compile([opcodes.OP_RETURN, announcementHash]), value: 0n });
|
|
176
|
+
|
|
177
|
+
// Construct a key pair and PSBT signer from the secret key
|
|
178
|
+
const keyPair = SchnorrKeyPair.fromSecret(secretKey);
|
|
179
|
+
const signer = {
|
|
180
|
+
publicKey : keyPair.publicKey.compressed,
|
|
181
|
+
sign : (hash: Uint8Array) => keyPair.secretKey.sign(hash, { scheme: 'ecdsa' }),
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
// Sign 0th input, finalize extract to hex in prep for broadcast
|
|
185
|
+
const signedTx = spendTx.signInput(0, signer)
|
|
186
|
+
.finalizeAllInputs()
|
|
187
|
+
.extractTransaction()
|
|
188
|
+
.toHex();
|
|
189
|
+
|
|
190
|
+
// Broadcast spendTx to the Bitcoin network.
|
|
191
|
+
const txid = await bitcoin.rest.transaction.send(signedTx);
|
|
192
|
+
|
|
193
|
+
// Log the txid of the broadcasted transaction
|
|
194
|
+
console.info(`CAS Beacon Signal Broadcasted with txid: ${txid}`);
|
|
195
|
+
|
|
196
|
+
// Return the signed update
|
|
197
|
+
return signedUpdate;
|
|
52
198
|
}
|
|
53
199
|
}
|
|
@@ -2,7 +2,7 @@ import { MethodError } from '@did-btcr2/common';
|
|
|
2
2
|
import { Beacon } from './beacon.js';
|
|
3
3
|
import { CASBeacon } from './cas-beacon.js';
|
|
4
4
|
import { BeaconService } from './interfaces.js';
|
|
5
|
-
import { SingletonBeacon } from './singleton.js';
|
|
5
|
+
import { SingletonBeacon } from './singleton-beacon.js';
|
|
6
6
|
import { SMTBeacon } from './smt-beacon.js';
|
|
7
7
|
|
|
8
8
|
/**
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { AddressUtxo, BitcoinConnection } from '@did-btcr2/bitcoin';
|
|
2
|
-
import {
|
|
2
|
+
import { canonicalize, decode, encode, hash, KeyBytes } from '@did-btcr2/common';
|
|
3
3
|
import { SignedBTCR2Update } from '@did-btcr2/cryptosuite';
|
|
4
4
|
import { SchnorrKeyPair } from '@did-btcr2/keypair';
|
|
5
5
|
import { opcodes, Psbt, script } from 'bitcoinjs-lib';
|
|
6
|
-
import {
|
|
6
|
+
import type { BeaconProcessResult, DataNeed } from '../resolver.js';
|
|
7
7
|
import { SidecarData } from '../types.js';
|
|
8
8
|
import { Beacon } from './beacon.js';
|
|
9
9
|
import { SingletonBeaconError } from './error.js';
|
|
@@ -20,7 +20,6 @@ export class SingletonBeacon extends Beacon {
|
|
|
20
20
|
/**
|
|
21
21
|
* Creates an instance of SingletonBeacon.
|
|
22
22
|
* @param {BeaconService} service The BeaconService object representing the funded beacon to announce the update to.
|
|
23
|
-
*
|
|
24
23
|
*/
|
|
25
24
|
constructor(service: BeaconService) {
|
|
26
25
|
super({ ...service, type: 'SingletonBeacon' });
|
|
@@ -28,53 +27,38 @@ export class SingletonBeacon extends Beacon {
|
|
|
28
27
|
|
|
29
28
|
/**
|
|
30
29
|
* Processes an array of Beacon Signals associated with a Singleton Beacon Service.
|
|
31
|
-
* @
|
|
32
|
-
* @
|
|
30
|
+
* @param {Array<BeaconSignal>} signals The beacon signals discovered on-chain.
|
|
31
|
+
* @param {SidecarData} sidecar The processed sidecar data.
|
|
32
|
+
* @returns {BeaconProcessResult} Successfully resolved updates and any data needs.
|
|
33
33
|
*/
|
|
34
|
-
|
|
34
|
+
processSignals(
|
|
35
35
|
signals: Array<BeaconSignal>,
|
|
36
36
|
sidecar: SidecarData
|
|
37
|
-
):
|
|
38
|
-
// Initialize an empty array to hold the BTCR2 signed updates
|
|
37
|
+
): BeaconProcessResult {
|
|
39
38
|
const updates = new Array<[SignedBTCR2Update, BlockMetadata]>();
|
|
39
|
+
const needs = new Array<DataNeed>();
|
|
40
40
|
|
|
41
|
-
// Loop through each signal in signals
|
|
42
41
|
for(const signal of signals) {
|
|
43
|
-
//
|
|
44
|
-
const updateHash = signal.signalBytes;
|
|
42
|
+
// Decode signal bytes from hex and re-encode to base64url for sidecar lookup
|
|
43
|
+
const updateHash = encode(decode(signal.signalBytes, 'hex'));
|
|
45
44
|
|
|
46
|
-
//
|
|
45
|
+
// Look up the signed update in sidecar updateMap
|
|
47
46
|
const signedUpdate = sidecar.updateMap.get(updateHash);
|
|
48
47
|
|
|
49
|
-
// If no btcr2 update is found in sidecar data maps, throw missingUpdateData error.
|
|
50
48
|
if(!signedUpdate) {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
49
|
+
// Data not available — emit a need instead of throwing
|
|
50
|
+
needs.push({
|
|
51
|
+
kind : 'NeedSignedUpdate',
|
|
52
|
+
updateHash,
|
|
53
|
+
beaconServiceId : this.service.id
|
|
54
|
+
});
|
|
55
|
+
continue;
|
|
55
56
|
}
|
|
56
57
|
|
|
57
|
-
// Canonicalize, hash and encode to base58btc the signed update object found in sidecar or CAS
|
|
58
|
-
const encodedUpdate = Canonicalization.process(signedUpdate, { encoding: 'base58btc' });
|
|
59
|
-
|
|
60
|
-
// Encode the signal bytes hex string to base58btc
|
|
61
|
-
const signalBytes = base58btc.encode(Buffer.from(updateHash, 'hex'));
|
|
62
|
-
|
|
63
|
-
// Check for mismatch between found sidecar/cas update hash and onchain beacon signal hash
|
|
64
|
-
if (encodedUpdate !== signalBytes) {
|
|
65
|
-
// If mismatch, throw invalidSidecarData error.
|
|
66
|
-
throw new SingletonBeaconError(
|
|
67
|
-
`Hash mismatch: sidecar update ${encodedUpdate} !== signal bytes ${signalBytes}.`,
|
|
68
|
-
INVALID_SIDECAR_DATA, { encodedUpdate, signalBytes }
|
|
69
|
-
);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// Push signedUpdate to updates array
|
|
73
58
|
updates.push([signedUpdate, signal.blockMetadata]);
|
|
74
59
|
}
|
|
75
60
|
|
|
76
|
-
|
|
77
|
-
return updates;
|
|
61
|
+
return { updates, needs };
|
|
78
62
|
}
|
|
79
63
|
/**
|
|
80
64
|
* Broadcasts a SingletonBeacon signal to the Bitcoin network.
|
|
@@ -120,7 +104,7 @@ export class SingletonBeacon extends Beacon {
|
|
|
120
104
|
const prevTx = await bitcoin.rest.transaction.getHex(utxo.txid);
|
|
121
105
|
|
|
122
106
|
// Canonicalize and hash the signed update for OP_RETURN output
|
|
123
|
-
const updateHash =
|
|
107
|
+
const updateHash = hash(canonicalize(signedUpdate));
|
|
124
108
|
|
|
125
109
|
// Construct a spend transaction
|
|
126
110
|
const spendTx = new Psbt({ network: bitcoin.data })
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { BitcoinConnection } from '@did-btcr2/bitcoin';
|
|
2
2
|
import { KeyBytes } from '@did-btcr2/common';
|
|
3
3
|
import { SignedBTCR2Update } from '@did-btcr2/cryptosuite';
|
|
4
|
+
import type { BeaconProcessResult } from '../resolver.js';
|
|
4
5
|
import { SidecarData } from '../types.js';
|
|
5
6
|
import { Beacon } from './beacon.js';
|
|
6
7
|
import { SMTBeaconError } from './error.js';
|
|
7
|
-
import { BeaconService, BeaconSignal
|
|
8
|
+
import { BeaconService, BeaconSignal } from './interfaces.js';
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* Implements {@link https://dcdpr.github.io/did-btcr2/terminology.html#smt-beacon | SMTBeacon}.
|
|
@@ -25,13 +26,13 @@ export class SMTBeacon extends Beacon {
|
|
|
25
26
|
* Implements {@link https://dcdpr.github.io/did-btcr2/operations/resolve.html#process-smt-beacon | 7.2.e.1 Process SMT Beacon}.
|
|
26
27
|
* @param {Array<BeaconSignal>} signals The array of Beacon Signals to process.
|
|
27
28
|
* @param {SidecarData} sidecar The sidecar data associated with the SMT Beacon.
|
|
28
|
-
* @returns {
|
|
29
|
+
* @returns {BeaconProcessResult} The processed signals.
|
|
29
30
|
* @throws {SMTBeaconError} if processing fails.
|
|
30
31
|
*/
|
|
31
32
|
processSignals(
|
|
32
33
|
signals: Array<BeaconSignal>,
|
|
33
34
|
sidecar: SidecarData
|
|
34
|
-
):
|
|
35
|
+
): BeaconProcessResult {
|
|
35
36
|
throw new SMTBeaconError('Method not implemented.', `METHOD_NOT_IMPLEMENTED`, {signals, sidecar});
|
|
36
37
|
}
|
|
37
38
|
|