@originals/sdk 1.4.5 ā 1.6.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/dist/adapters/FeeOracleMock.js +2 -2
- package/dist/bitcoin/OrdinalsClient.d.ts +1 -1
- package/dist/bitcoin/OrdinalsClient.js +10 -8
- package/dist/bitcoin/PSBTBuilder.js +1 -1
- package/dist/bitcoin/utxo-selection.js +2 -2
- package/dist/cel/ExternalReferenceManager.d.ts +57 -0
- package/dist/cel/ExternalReferenceManager.js +73 -0
- package/dist/cel/OriginalsCel.d.ts +245 -0
- package/dist/cel/OriginalsCel.js +349 -0
- package/dist/cel/algorithms/createEventLog.d.ts +32 -0
- package/dist/cel/algorithms/createEventLog.js +56 -0
- package/dist/cel/algorithms/deactivateEventLog.d.ts +35 -0
- package/dist/cel/algorithms/deactivateEventLog.js +91 -0
- package/dist/cel/algorithms/index.d.ts +10 -0
- package/dist/cel/algorithms/index.js +10 -0
- package/dist/cel/algorithms/updateEventLog.d.ts +34 -0
- package/dist/cel/algorithms/updateEventLog.js +82 -0
- package/dist/cel/algorithms/verifyEventLog.d.ts +45 -0
- package/dist/cel/algorithms/verifyEventLog.js +255 -0
- package/dist/cel/algorithms/witnessEvent.d.ts +29 -0
- package/dist/cel/algorithms/witnessEvent.js +75 -0
- package/dist/cel/cli/create.d.ts +36 -0
- package/dist/cel/cli/create.js +282 -0
- package/dist/cel/cli/index.d.ts +11 -0
- package/dist/cel/cli/index.js +351 -0
- package/dist/cel/cli/inspect.d.ts +30 -0
- package/dist/cel/cli/inspect.js +475 -0
- package/dist/cel/cli/migrate.d.ts +41 -0
- package/dist/cel/cli/migrate.js +405 -0
- package/dist/cel/cli/verify.d.ts +31 -0
- package/dist/cel/cli/verify.js +205 -0
- package/dist/cel/hash.d.ts +46 -0
- package/dist/cel/hash.js +66 -0
- package/dist/cel/index.d.ts +15 -0
- package/dist/cel/index.js +15 -0
- package/dist/cel/layers/BtcoCelManager.d.ts +121 -0
- package/dist/cel/layers/BtcoCelManager.js +329 -0
- package/dist/cel/layers/PeerCelManager.d.ts +151 -0
- package/dist/cel/layers/PeerCelManager.js +299 -0
- package/dist/cel/layers/WebVHCelManager.d.ts +122 -0
- package/dist/cel/layers/WebVHCelManager.js +291 -0
- package/dist/cel/layers/index.d.ts +13 -0
- package/dist/cel/layers/index.js +16 -0
- package/dist/cel/serialization/cbor.d.ts +42 -0
- package/dist/cel/serialization/cbor.js +163 -0
- package/dist/cel/serialization/index.d.ts +9 -0
- package/dist/cel/serialization/index.js +9 -0
- package/dist/cel/serialization/json.d.ts +41 -0
- package/dist/cel/serialization/json.js +180 -0
- package/dist/cel/types.d.ts +149 -0
- package/dist/cel/types.js +7 -0
- package/dist/cel/witnesses/BitcoinWitness.d.ts +83 -0
- package/dist/cel/witnesses/BitcoinWitness.js +116 -0
- package/dist/cel/witnesses/HttpWitness.d.ts +79 -0
- package/dist/cel/witnesses/HttpWitness.js +163 -0
- package/dist/cel/witnesses/WitnessService.d.ts +49 -0
- package/dist/cel/witnesses/WitnessService.js +10 -0
- package/dist/cel/witnesses/index.d.ts +10 -0
- package/dist/cel/witnesses/index.js +7 -0
- package/dist/core/OriginalsSDK.js +5 -1
- package/dist/crypto/Signer.js +14 -6
- package/dist/crypto/noble-init.js +20 -1
- package/dist/did/BtcoDidResolver.d.ts +2 -2
- package/dist/did/BtcoDidResolver.js +12 -8
- package/dist/did/DIDManager.js +6 -4
- package/dist/did/KeyManager.d.ts +1 -1
- package/dist/did/KeyManager.js +7 -4
- package/dist/did/WebVHManager.js +1 -1
- package/dist/did/createBtcoDidDocument.js +2 -1
- package/dist/events/types.d.ts +4 -1
- package/dist/examples/create-module-original.js +1 -1
- package/dist/examples/full-lifecycle-flow.js +2 -2
- package/dist/index.d.ts +13 -0
- package/dist/index.js +12 -0
- package/dist/kinds/KindRegistry.js +59 -29
- package/dist/lifecycle/BatchOperations.d.ts +5 -3
- package/dist/lifecycle/BatchOperations.js +11 -5
- package/dist/lifecycle/LifecycleManager.d.ts +1 -1
- package/dist/lifecycle/LifecycleManager.js +42 -33
- package/dist/lifecycle/OriginalsAsset.js +2 -2
- package/dist/migration/MigrationManager.js +67 -3
- package/dist/storage/LocalStorageAdapter.js +4 -1
- package/dist/storage/MemoryStorageAdapter.js +7 -7
- package/dist/types/network.js +6 -3
- package/dist/utils/Logger.d.ts +6 -6
- package/dist/utils/Logger.js +5 -3
- package/dist/utils/MetricsCollector.js +1 -1
- package/dist/utils/bitcoin-address.js +4 -2
- package/dist/utils/cbor.js +16 -3
- package/dist/utils/encoding.d.ts +4 -4
- package/dist/utils/encoding.js +7 -6
- package/dist/utils/hash.js +6 -1
- package/dist/utils/serialization.d.ts +2 -2
- package/dist/utils/serialization.js +7 -5
- package/dist/utils/telemetry.js +6 -2
- package/dist/utils/validation.js +8 -4
- package/dist/vc/CredentialManager.d.ts +8 -8
- package/dist/vc/CredentialManager.js +46 -33
- package/dist/vc/Issuer.d.ts +2 -2
- package/dist/vc/Issuer.js +5 -1
- package/dist/vc/Verifier.d.ts +2 -2
- package/dist/vc/Verifier.js +12 -6
- package/dist/vc/documentLoader.d.ts +5 -3
- package/dist/vc/documentLoader.js +5 -4
- package/package.json +4 -1
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HttpWitness - HTTP-based witness service for CEL event logs
|
|
3
|
+
*
|
|
4
|
+
* Implements the WitnessService interface for HTTP-based witness endpoints.
|
|
5
|
+
* Used primarily for the did:webvh layer to obtain third-party attestations
|
|
6
|
+
* from remote witness services.
|
|
7
|
+
*
|
|
8
|
+
* @see https://w3c-ccg.github.io/cel-spec/
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Error thrown when the HTTP witness service is unavailable or returns an error
|
|
12
|
+
*/
|
|
13
|
+
export class HttpWitnessError extends Error {
|
|
14
|
+
constructor(message, witnessUrl, statusCode, responseBody) {
|
|
15
|
+
super(message);
|
|
16
|
+
this.name = 'HttpWitnessError';
|
|
17
|
+
this.witnessUrl = witnessUrl;
|
|
18
|
+
this.statusCode = statusCode;
|
|
19
|
+
this.responseBody = responseBody;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* HTTP-based witness service implementation
|
|
24
|
+
*
|
|
25
|
+
* Posts digestMultibase to a witness endpoint and parses the WitnessProof response.
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```typescript
|
|
29
|
+
* const witness = new HttpWitness('https://witness.example.com/api/attest');
|
|
30
|
+
* const proof = await witness.witness('uEiD...');
|
|
31
|
+
* console.log(proof.witnessedAt); // ISO timestamp of attestation
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export class HttpWitness {
|
|
35
|
+
/**
|
|
36
|
+
* Creates a new HttpWitness instance
|
|
37
|
+
*
|
|
38
|
+
* @param witnessUrl - The URL of the witness endpoint to POST to
|
|
39
|
+
* @param options - Optional configuration options
|
|
40
|
+
*/
|
|
41
|
+
constructor(witnessUrl, options = {}) {
|
|
42
|
+
if (!witnessUrl || typeof witnessUrl !== 'string') {
|
|
43
|
+
throw new Error('witnessUrl must be a non-empty string');
|
|
44
|
+
}
|
|
45
|
+
// Validate URL format
|
|
46
|
+
try {
|
|
47
|
+
new URL(witnessUrl);
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
throw new Error(`Invalid witness URL: ${witnessUrl}`);
|
|
51
|
+
}
|
|
52
|
+
this.witnessUrl = witnessUrl;
|
|
53
|
+
this.timeout = options.timeout ?? 30000;
|
|
54
|
+
this.headers = {
|
|
55
|
+
'Content-Type': 'application/json',
|
|
56
|
+
'Accept': 'application/json',
|
|
57
|
+
...options.headers,
|
|
58
|
+
};
|
|
59
|
+
this.fetchFn = options.fetch ?? globalThis.fetch;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Witnesses a digest by posting to the HTTP endpoint
|
|
63
|
+
*
|
|
64
|
+
* @param digestMultibase - The Multibase-encoded digest to witness
|
|
65
|
+
* @returns A WitnessProof containing the attestation and witnessedAt timestamp
|
|
66
|
+
* @throws HttpWitnessError if the witness service is unavailable or returns an error
|
|
67
|
+
*/
|
|
68
|
+
async witness(digestMultibase) {
|
|
69
|
+
if (!digestMultibase || typeof digestMultibase !== 'string') {
|
|
70
|
+
throw new Error('digestMultibase must be a non-empty string');
|
|
71
|
+
}
|
|
72
|
+
// Create abort controller for timeout
|
|
73
|
+
const controller = new AbortController();
|
|
74
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
75
|
+
try {
|
|
76
|
+
const response = await this.fetchFn(this.witnessUrl, {
|
|
77
|
+
method: 'POST',
|
|
78
|
+
headers: this.headers,
|
|
79
|
+
body: JSON.stringify({ digest: digestMultibase }),
|
|
80
|
+
signal: controller.signal,
|
|
81
|
+
});
|
|
82
|
+
clearTimeout(timeoutId);
|
|
83
|
+
// Handle non-OK responses
|
|
84
|
+
if (!response.ok) {
|
|
85
|
+
let responseBody;
|
|
86
|
+
try {
|
|
87
|
+
responseBody = await response.text();
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
// Ignore body read errors
|
|
91
|
+
}
|
|
92
|
+
throw new HttpWitnessError(`Witness service returned ${response.status} ${response.statusText}`, this.witnessUrl, response.status, responseBody);
|
|
93
|
+
}
|
|
94
|
+
// Parse response
|
|
95
|
+
let data;
|
|
96
|
+
try {
|
|
97
|
+
data = await response.json();
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
throw new HttpWitnessError('Witness service returned invalid JSON response', this.witnessUrl, response.status);
|
|
101
|
+
}
|
|
102
|
+
// Validate WitnessProof structure
|
|
103
|
+
const proof = this.validateWitnessProof(data);
|
|
104
|
+
return proof;
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
clearTimeout(timeoutId);
|
|
108
|
+
// Re-throw HttpWitnessError as-is
|
|
109
|
+
if (error instanceof HttpWitnessError) {
|
|
110
|
+
throw error;
|
|
111
|
+
}
|
|
112
|
+
// Handle abort/timeout
|
|
113
|
+
if (error instanceof Error && error.name === 'AbortError') {
|
|
114
|
+
throw new HttpWitnessError(`Witness service request timed out after ${this.timeout}ms`, this.witnessUrl);
|
|
115
|
+
}
|
|
116
|
+
// Handle network errors
|
|
117
|
+
if (error instanceof TypeError) {
|
|
118
|
+
throw new HttpWitnessError(`Witness service unavailable: ${error.message}`, this.witnessUrl);
|
|
119
|
+
}
|
|
120
|
+
// Re-throw other errors
|
|
121
|
+
throw new HttpWitnessError(`Witness request failed: ${error instanceof Error ? error.message : String(error)}`, this.witnessUrl);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Validates that the response data is a valid WitnessProof
|
|
126
|
+
*
|
|
127
|
+
* @param data - The parsed JSON response
|
|
128
|
+
* @returns A validated WitnessProof
|
|
129
|
+
* @throws HttpWitnessError if the response is not a valid WitnessProof
|
|
130
|
+
*/
|
|
131
|
+
validateWitnessProof(data) {
|
|
132
|
+
if (!data || typeof data !== 'object') {
|
|
133
|
+
throw new HttpWitnessError('Witness service returned invalid proof: expected object', this.witnessUrl);
|
|
134
|
+
}
|
|
135
|
+
const proof = data;
|
|
136
|
+
// Check required DataIntegrityProof fields
|
|
137
|
+
const requiredFields = ['type', 'cryptosuite', 'created', 'verificationMethod', 'proofPurpose', 'proofValue'];
|
|
138
|
+
for (const field of requiredFields) {
|
|
139
|
+
if (typeof proof[field] !== 'string') {
|
|
140
|
+
throw new HttpWitnessError(`Witness service returned invalid proof: missing or invalid '${field}' field`, this.witnessUrl);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
// Check WitnessProof-specific field
|
|
144
|
+
if (typeof proof.witnessedAt !== 'string') {
|
|
145
|
+
throw new HttpWitnessError("Witness service returned invalid proof: missing or invalid 'witnessedAt' field", this.witnessUrl);
|
|
146
|
+
}
|
|
147
|
+
return {
|
|
148
|
+
type: proof.type,
|
|
149
|
+
cryptosuite: proof.cryptosuite,
|
|
150
|
+
created: proof.created,
|
|
151
|
+
verificationMethod: proof.verificationMethod,
|
|
152
|
+
proofPurpose: proof.proofPurpose,
|
|
153
|
+
proofValue: proof.proofValue,
|
|
154
|
+
witnessedAt: proof.witnessedAt,
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Gets the witness URL this instance is configured to use
|
|
159
|
+
*/
|
|
160
|
+
get url() {
|
|
161
|
+
return this.witnessUrl;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WitnessService Interface
|
|
3
|
+
*
|
|
4
|
+
* Defines a pluggable interface for witness services that attest to the
|
|
5
|
+
* existence of events at a point in time. Witnesses add trust anchors
|
|
6
|
+
* to event logs by providing third-party attestations.
|
|
7
|
+
*
|
|
8
|
+
* @see https://w3c-ccg.github.io/cel-spec/
|
|
9
|
+
*/
|
|
10
|
+
import type { WitnessProof } from '../types';
|
|
11
|
+
/**
|
|
12
|
+
* Interface for witness services that can attest to event digests.
|
|
13
|
+
*
|
|
14
|
+
* Implementations might include:
|
|
15
|
+
* - HTTP-based witness services (for did:webvh layer)
|
|
16
|
+
* - Bitcoin timestamping services (for did:btco layer)
|
|
17
|
+
* - Notary services
|
|
18
|
+
* - Blockchain-based attestation services
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```typescript
|
|
22
|
+
* class MyHttpWitness implements WitnessService {
|
|
23
|
+
* constructor(private witnessUrl: string) {}
|
|
24
|
+
*
|
|
25
|
+
* async witness(digestMultibase: string): Promise<WitnessProof> {
|
|
26
|
+
* const response = await fetch(this.witnessUrl, {
|
|
27
|
+
* method: 'POST',
|
|
28
|
+
* body: JSON.stringify({ digest: digestMultibase })
|
|
29
|
+
* });
|
|
30
|
+
* return response.json();
|
|
31
|
+
* }
|
|
32
|
+
* }
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export interface WitnessService {
|
|
36
|
+
/**
|
|
37
|
+
* Witnesses a digest and returns a proof of attestation.
|
|
38
|
+
*
|
|
39
|
+
* The witness should:
|
|
40
|
+
* 1. Record the digest at the current point in time
|
|
41
|
+
* 2. Generate a cryptographic proof of the attestation
|
|
42
|
+
* 3. Include a witnessedAt timestamp in the proof
|
|
43
|
+
*
|
|
44
|
+
* @param digestMultibase - The Multibase-encoded digest to witness (from computeDigestMultibase)
|
|
45
|
+
* @returns A WitnessProof containing the attestation and witnessedAt timestamp
|
|
46
|
+
* @throws Error if the witness service is unavailable or fails
|
|
47
|
+
*/
|
|
48
|
+
witness(digestMultibase: string): Promise<WitnessProof>;
|
|
49
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WitnessService Interface
|
|
3
|
+
*
|
|
4
|
+
* Defines a pluggable interface for witness services that attest to the
|
|
5
|
+
* existence of events at a point in time. Witnesses add trust anchors
|
|
6
|
+
* to event logs by providing third-party attestations.
|
|
7
|
+
*
|
|
8
|
+
* @see https://w3c-ccg.github.io/cel-spec/
|
|
9
|
+
*/
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CEL Witness Services
|
|
3
|
+
*
|
|
4
|
+
* Pluggable witness interfaces and implementations for third-party attestations.
|
|
5
|
+
*/
|
|
6
|
+
export type { WitnessService } from './WitnessService';
|
|
7
|
+
export { HttpWitness, HttpWitnessError } from './HttpWitness';
|
|
8
|
+
export type { HttpWitnessOptions } from './HttpWitness';
|
|
9
|
+
export { BitcoinWitness, BitcoinWitnessError } from './BitcoinWitness';
|
|
10
|
+
export type { BitcoinWitnessOptions, BitcoinWitnessProof } from './BitcoinWitness';
|
|
@@ -49,6 +49,7 @@ export class OriginalsSDK {
|
|
|
49
49
|
this.eventLogger.configureEventLogging(this.config.logging.eventLogging);
|
|
50
50
|
}
|
|
51
51
|
// Subscribe to lifecycle events
|
|
52
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
|
|
52
53
|
this.eventLogger.subscribeToEvents(this.lifecycle.eventEmitter);
|
|
53
54
|
}
|
|
54
55
|
/**
|
|
@@ -179,6 +180,7 @@ export class OriginalsSDK {
|
|
|
179
180
|
});
|
|
180
181
|
return {
|
|
181
182
|
did: result.did,
|
|
183
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
182
184
|
doc: result.doc,
|
|
183
185
|
log: result.log,
|
|
184
186
|
meta: result.meta
|
|
@@ -197,10 +199,12 @@ export class OriginalsSDK {
|
|
|
197
199
|
switch (options.type) {
|
|
198
200
|
case 'did':
|
|
199
201
|
return OriginalsSDK.updateDIDOriginal(options);
|
|
200
|
-
default:
|
|
202
|
+
default: {
|
|
201
203
|
// TypeScript exhaustiveness check
|
|
202
204
|
const _exhaustive = options;
|
|
205
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
|
|
203
206
|
throw new Error(`Unsupported Original type: ${_exhaustive.type}`);
|
|
207
|
+
}
|
|
204
208
|
}
|
|
205
209
|
}
|
|
206
210
|
/**
|
package/dist/crypto/Signer.js
CHANGED
|
@@ -25,7 +25,9 @@ export class ES256KSigner extends Signer {
|
|
|
25
25
|
}
|
|
26
26
|
const privateKey = decoded.key;
|
|
27
27
|
const hash = sha256(data);
|
|
28
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
|
28
29
|
const sigAny = await secp256k1.signAsync(hash, privateKey);
|
|
30
|
+
/* eslint-disable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call */
|
|
29
31
|
const sigBytes = sigAny instanceof Uint8Array
|
|
30
32
|
? sigAny
|
|
31
33
|
: typeof sigAny?.toCompactRawBytes === 'function'
|
|
@@ -33,6 +35,7 @@ export class ES256KSigner extends Signer {
|
|
|
33
35
|
: typeof sigAny?.toRawBytes === 'function'
|
|
34
36
|
? sigAny.toRawBytes()
|
|
35
37
|
: new Uint8Array(sigAny);
|
|
38
|
+
/* eslint-enable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call */
|
|
36
39
|
return Buffer.from(sigBytes);
|
|
37
40
|
}
|
|
38
41
|
async verify(data, signature, publicKeyMultibase) {
|
|
@@ -52,7 +55,7 @@ export class ES256KSigner extends Signer {
|
|
|
52
55
|
const publicKey = decoded.key;
|
|
53
56
|
const hash = sha256(data);
|
|
54
57
|
try {
|
|
55
|
-
return secp256k1.verify(signature, hash, publicKey);
|
|
58
|
+
return await Promise.resolve(secp256k1.verify(signature, hash, publicKey));
|
|
56
59
|
}
|
|
57
60
|
catch {
|
|
58
61
|
return false;
|
|
@@ -75,6 +78,7 @@ export class Ed25519Signer extends Signer {
|
|
|
75
78
|
throw new Error('Invalid key type for Ed25519');
|
|
76
79
|
}
|
|
77
80
|
const privateKey = decoded.key;
|
|
81
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
|
78
82
|
const signature = await ed25519.signAsync(data, privateKey);
|
|
79
83
|
return Buffer.from(signature);
|
|
80
84
|
}
|
|
@@ -94,6 +98,7 @@ export class Ed25519Signer extends Signer {
|
|
|
94
98
|
}
|
|
95
99
|
const publicKey = decoded.key;
|
|
96
100
|
try {
|
|
101
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
|
97
102
|
return await ed25519.verifyAsync(signature, data, publicKey);
|
|
98
103
|
}
|
|
99
104
|
catch {
|
|
@@ -118,7 +123,9 @@ export class ES256Signer extends Signer {
|
|
|
118
123
|
}
|
|
119
124
|
const privateKey = decoded.key;
|
|
120
125
|
const hash = sha256(data);
|
|
126
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-assignment
|
|
121
127
|
const sigAny = p256.sign(hash, privateKey);
|
|
128
|
+
/* eslint-disable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call */
|
|
122
129
|
const sigBytes = sigAny instanceof Uint8Array
|
|
123
130
|
? sigAny
|
|
124
131
|
: typeof sigAny?.toCompactRawBytes === 'function'
|
|
@@ -126,7 +133,8 @@ export class ES256Signer extends Signer {
|
|
|
126
133
|
: typeof sigAny?.toRawBytes === 'function'
|
|
127
134
|
? sigAny.toRawBytes()
|
|
128
135
|
: new Uint8Array(sigAny);
|
|
129
|
-
|
|
136
|
+
/* eslint-enable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call */
|
|
137
|
+
return await Promise.resolve(Buffer.from(sigBytes));
|
|
130
138
|
}
|
|
131
139
|
async verify(data, signature, publicKeyMultibase) {
|
|
132
140
|
if (!publicKeyMultibase || publicKeyMultibase[0] !== 'z') {
|
|
@@ -145,7 +153,7 @@ export class ES256Signer extends Signer {
|
|
|
145
153
|
const publicKey = decoded.key;
|
|
146
154
|
const hash = sha256(data);
|
|
147
155
|
try {
|
|
148
|
-
return p256.verify(signature, hash, publicKey);
|
|
156
|
+
return await Promise.resolve(p256.verify(signature, hash, publicKey));
|
|
149
157
|
}
|
|
150
158
|
catch {
|
|
151
159
|
return false;
|
|
@@ -168,8 +176,8 @@ export class Bls12381G2Signer extends Signer {
|
|
|
168
176
|
throw new Error('Invalid key type for Bls12381G2');
|
|
169
177
|
}
|
|
170
178
|
const sk = decoded.key;
|
|
171
|
-
const sig =
|
|
172
|
-
return Buffer.from(sig);
|
|
179
|
+
const sig = bls.sign(data, sk);
|
|
180
|
+
return await Promise.resolve(Buffer.from(sig));
|
|
173
181
|
}
|
|
174
182
|
async verify(data, signature, publicKeyMultibase) {
|
|
175
183
|
if (!publicKeyMultibase || publicKeyMultibase[0] !== 'z') {
|
|
@@ -187,7 +195,7 @@ export class Bls12381G2Signer extends Signer {
|
|
|
187
195
|
}
|
|
188
196
|
const pk = decoded.key;
|
|
189
197
|
try {
|
|
190
|
-
return await bls.verify(signature, data, pk);
|
|
198
|
+
return await Promise.resolve(bls.verify(signature, data, pk));
|
|
191
199
|
}
|
|
192
200
|
catch {
|
|
193
201
|
return false;
|
|
@@ -22,8 +22,14 @@ const hmacSha256Impl = (key, ...msgs) => hmac(sha256, key, concatBytes(...msgs))
|
|
|
22
22
|
/**
|
|
23
23
|
* Safely set a property on an object, handling readonly properties
|
|
24
24
|
*/
|
|
25
|
-
|
|
25
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
26
|
+
function safeSetProperty(
|
|
27
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
28
|
+
obj, prop,
|
|
29
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
30
|
+
value, options) {
|
|
26
31
|
try {
|
|
32
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
|
|
27
33
|
obj[prop] = value;
|
|
28
34
|
return true;
|
|
29
35
|
}
|
|
@@ -31,6 +37,7 @@ function safeSetProperty(obj, prop, value, options) {
|
|
|
31
37
|
// Property might be readonly, try defineProperty
|
|
32
38
|
try {
|
|
33
39
|
Object.defineProperty(obj, prop, {
|
|
40
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
34
41
|
value,
|
|
35
42
|
writable: options?.writable ?? true,
|
|
36
43
|
configurable: options?.configurable ?? true,
|
|
@@ -47,10 +54,13 @@ function safeSetProperty(obj, prop, value, options) {
|
|
|
47
54
|
* Initialize @noble/secp256k1 with hmacSha256Sync utility
|
|
48
55
|
*/
|
|
49
56
|
function initSecp256k1() {
|
|
57
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-explicit-any
|
|
50
58
|
const sAny = secp256k1;
|
|
59
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
51
60
|
if (!sAny?.utils) {
|
|
52
61
|
// Try to create utils object if it doesn't exist
|
|
53
62
|
try {
|
|
63
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
54
64
|
sAny.utils = {};
|
|
55
65
|
}
|
|
56
66
|
catch {
|
|
@@ -63,7 +73,9 @@ function initSecp256k1() {
|
|
|
63
73
|
}
|
|
64
74
|
}
|
|
65
75
|
// Set hmacSha256Sync if not already set
|
|
76
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
66
77
|
if (typeof sAny.utils.hmacSha256Sync !== 'function') {
|
|
78
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
67
79
|
safeSetProperty(sAny.utils, 'hmacSha256Sync', hmacSha256Impl);
|
|
68
80
|
}
|
|
69
81
|
}
|
|
@@ -72,14 +84,19 @@ function initSecp256k1() {
|
|
|
72
84
|
* Handles both etc.sha512Sync (v2.x) and utils.sha512Sync (backward compat)
|
|
73
85
|
*/
|
|
74
86
|
function initEd25519() {
|
|
87
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-explicit-any
|
|
75
88
|
const eAny = ed25519;
|
|
76
89
|
// Set etc.sha512Sync for @noble/ed25519 v2.x (required)
|
|
90
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
77
91
|
if (eAny?.etc && typeof eAny.etc.sha512Sync !== 'function') {
|
|
92
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
78
93
|
safeSetProperty(eAny.etc, 'sha512Sync', sha512Impl);
|
|
79
94
|
}
|
|
80
95
|
// Set utils.sha512Sync for backward compatibility
|
|
96
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
81
97
|
if (!eAny?.utils) {
|
|
82
98
|
try {
|
|
99
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
83
100
|
eAny.utils = {};
|
|
84
101
|
}
|
|
85
102
|
catch {
|
|
@@ -90,7 +107,9 @@ function initEd25519() {
|
|
|
90
107
|
});
|
|
91
108
|
}
|
|
92
109
|
}
|
|
110
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
93
111
|
if (typeof eAny.utils.sha512Sync !== 'function') {
|
|
112
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
94
113
|
safeSetProperty(eAny.utils, 'sha512Sync', sha512Impl);
|
|
95
114
|
}
|
|
96
115
|
}
|
|
@@ -2,7 +2,7 @@ import type { DIDDocument } from '../types/did';
|
|
|
2
2
|
export interface BtcoInscriptionData {
|
|
3
3
|
inscriptionId: string;
|
|
4
4
|
content: string;
|
|
5
|
-
metadata:
|
|
5
|
+
metadata: Record<string, unknown> | null;
|
|
6
6
|
contentUrl?: string;
|
|
7
7
|
contentType?: string;
|
|
8
8
|
isValidDid?: boolean;
|
|
@@ -39,7 +39,7 @@ export interface ResourceProviderLike {
|
|
|
39
39
|
content_type: string;
|
|
40
40
|
content_url: string;
|
|
41
41
|
}>;
|
|
42
|
-
getMetadata(inscriptionId: string): Promise<
|
|
42
|
+
getMetadata(inscriptionId: string): Promise<Record<string, unknown> | null>;
|
|
43
43
|
}
|
|
44
44
|
export interface BtcoDidResolutionOptions {
|
|
45
45
|
provider?: ResourceProviderLike;
|
|
@@ -39,7 +39,8 @@ export class BtcoDidResolver {
|
|
|
39
39
|
inscriptionIds = satInfo?.inscription_ids || [];
|
|
40
40
|
}
|
|
41
41
|
catch (e) {
|
|
42
|
-
|
|
42
|
+
const message = e instanceof Error ? e.message : String(e);
|
|
43
|
+
return this.createErrorResult('notFound', `Failed to retrieve inscriptions for satoshi ${satNumber}: ${message}`);
|
|
43
44
|
}
|
|
44
45
|
if (inscriptionIds.length === 0) {
|
|
45
46
|
return this.createErrorResult('notFound', `No inscriptions found on satoshi ${satNumber}`);
|
|
@@ -82,7 +83,8 @@ export class BtcoDidResolver {
|
|
|
82
83
|
}
|
|
83
84
|
}
|
|
84
85
|
catch (err) {
|
|
85
|
-
|
|
86
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
87
|
+
inscriptionData.error = `Failed to fetch content: ${message}`;
|
|
86
88
|
inscriptionDataList.push(inscriptionData);
|
|
87
89
|
continue;
|
|
88
90
|
}
|
|
@@ -110,7 +112,8 @@ export class BtcoDidResolver {
|
|
|
110
112
|
}
|
|
111
113
|
}
|
|
112
114
|
catch (err) {
|
|
113
|
-
|
|
115
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
116
|
+
inscriptionData.error = `Failed to process inscription: ${message}`;
|
|
114
117
|
}
|
|
115
118
|
inscriptionDataList.push(inscriptionData);
|
|
116
119
|
}
|
|
@@ -142,17 +145,18 @@ export class BtcoDidResolver {
|
|
|
142
145
|
isValidDidDocument(doc) {
|
|
143
146
|
if (!doc || typeof doc !== 'object')
|
|
144
147
|
return false;
|
|
145
|
-
|
|
148
|
+
const d = doc;
|
|
149
|
+
if (!d.id || typeof d.id !== 'string')
|
|
146
150
|
return false;
|
|
147
|
-
if (!
|
|
151
|
+
if (!d['@context'])
|
|
148
152
|
return false;
|
|
149
|
-
const contexts = Array.isArray(
|
|
153
|
+
const contexts = Array.isArray(d['@context']) ? d['@context'] : [d['@context']];
|
|
150
154
|
if (!contexts.includes('https://www.w3.org/ns/did/v1') && !contexts.includes('https://w3id.org/did/v1')) {
|
|
151
155
|
return false;
|
|
152
156
|
}
|
|
153
|
-
if (
|
|
157
|
+
if (d.verificationMethod && !Array.isArray(d.verificationMethod))
|
|
154
158
|
return false;
|
|
155
|
-
if (
|
|
159
|
+
if (d.authentication && !Array.isArray(d.authentication))
|
|
156
160
|
return false;
|
|
157
161
|
return true;
|
|
158
162
|
}
|
package/dist/did/DIDManager.js
CHANGED
|
@@ -28,7 +28,9 @@ export class DIDManager {
|
|
|
28
28
|
}
|
|
29
29
|
], undefined, undefined);
|
|
30
30
|
// Resolve to DID Document using the same library
|
|
31
|
-
const
|
|
31
|
+
const rawResolved = await didPeerMod.resolve(did);
|
|
32
|
+
// Type the resolved document properly
|
|
33
|
+
const resolved = rawResolved;
|
|
32
34
|
// Ensure controller is set on VM entries for compatibility
|
|
33
35
|
if (resolved && Array.isArray(resolved.verificationMethod)) {
|
|
34
36
|
resolved.verificationMethod = resolved.verificationMethod.map((vm) => ({
|
|
@@ -88,7 +90,7 @@ export class DIDManager {
|
|
|
88
90
|
...didDoc,
|
|
89
91
|
id: `did:webvh:${normalized}:${slug}`
|
|
90
92
|
};
|
|
91
|
-
return migrated;
|
|
93
|
+
return await Promise.resolve(migrated);
|
|
92
94
|
}
|
|
93
95
|
async migrateToDIDBTCO(didDoc, satoshi) {
|
|
94
96
|
// Validate satoshi parameter
|
|
@@ -115,7 +117,7 @@ export class DIDManager {
|
|
|
115
117
|
network = this.config.network || 'mainnet';
|
|
116
118
|
}
|
|
117
119
|
// Try to carry over the first multikey VM if present
|
|
118
|
-
const firstVm =
|
|
120
|
+
const firstVm = didDoc.verificationMethod?.[0];
|
|
119
121
|
let publicKey;
|
|
120
122
|
let keyType;
|
|
121
123
|
try {
|
|
@@ -147,7 +149,7 @@ export class DIDManager {
|
|
|
147
149
|
if (didDoc.service && didDoc.service.length > 0) {
|
|
148
150
|
btcoDoc.service = didDoc.service;
|
|
149
151
|
}
|
|
150
|
-
return btcoDoc;
|
|
152
|
+
return await Promise.resolve(btcoDoc);
|
|
151
153
|
}
|
|
152
154
|
async resolveDID(did) {
|
|
153
155
|
try {
|
package/dist/did/KeyManager.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { DIDDocument, KeyPair, KeyType, KeyRecoveryCredential } from '../types';
|
|
|
3
3
|
export declare class KeyManager {
|
|
4
4
|
constructor();
|
|
5
5
|
generateKeyPair(type: KeyType): Promise<KeyPair>;
|
|
6
|
-
rotateKeys(didDoc: DIDDocument, newKeyPair: KeyPair):
|
|
6
|
+
rotateKeys(didDoc: DIDDocument, newKeyPair: KeyPair): DIDDocument;
|
|
7
7
|
recoverFromCompromise(didDoc: DIDDocument): Promise<{
|
|
8
8
|
didDocument: DIDDocument;
|
|
9
9
|
recoveryCredential: KeyRecoveryCredential;
|
package/dist/did/KeyManager.js
CHANGED
|
@@ -11,7 +11,8 @@ function toMultikeyType(type) {
|
|
|
11
11
|
return 'Ed25519';
|
|
12
12
|
if (type === 'ES256')
|
|
13
13
|
return 'P256';
|
|
14
|
-
|
|
14
|
+
const _exhaustiveCheck = type;
|
|
15
|
+
throw new Error(`Unsupported key type: ${String(_exhaustiveCheck)}`);
|
|
15
16
|
}
|
|
16
17
|
function fromMultikeyType(type) {
|
|
17
18
|
if (type === 'Secp256k1')
|
|
@@ -38,7 +39,8 @@ export class KeyManager {
|
|
|
38
39
|
}
|
|
39
40
|
if (type === 'Ed25519') {
|
|
40
41
|
const privateKeyBytes = ed25519.utils.randomPrivateKey();
|
|
41
|
-
const
|
|
42
|
+
const ed25519Module = ed25519;
|
|
43
|
+
const publicKeyBytes = await ed25519Module.getPublicKeyAsync(privateKeyBytes);
|
|
42
44
|
return {
|
|
43
45
|
privateKey: multikey.encodePrivateKey(privateKeyBytes, 'Ed25519'),
|
|
44
46
|
publicKey: multikey.encodePublicKey(publicKeyBytes, 'Ed25519')
|
|
@@ -52,9 +54,10 @@ export class KeyManager {
|
|
|
52
54
|
publicKey: multikey.encodePublicKey(publicKeyBytes, 'P256')
|
|
53
55
|
};
|
|
54
56
|
}
|
|
55
|
-
|
|
57
|
+
const _exhaustiveCheck = type;
|
|
58
|
+
throw new Error(`Unsupported key type: ${String(_exhaustiveCheck)}`);
|
|
56
59
|
}
|
|
57
|
-
|
|
60
|
+
rotateKeys(didDoc, newKeyPair) {
|
|
58
61
|
const multikeyContext = 'https://w3id.org/security/multikey/v1';
|
|
59
62
|
const securityContext = 'https://w3id.org/security/v1';
|
|
60
63
|
// Ensure required contexts are present
|
package/dist/did/WebVHManager.js
CHANGED
|
@@ -7,7 +7,8 @@ function getDidPrefix(network) {
|
|
|
7
7
|
return 'did:btco:sig';
|
|
8
8
|
if (network === 'regtest')
|
|
9
9
|
return 'did:btco:reg';
|
|
10
|
-
|
|
10
|
+
const _exhaustiveCheck = network;
|
|
11
|
+
throw new Error(`Unsupported Bitcoin network: ${String(_exhaustiveCheck)}`);
|
|
11
12
|
}
|
|
12
13
|
function buildVerificationMethod(did, params) {
|
|
13
14
|
const fragment = '#0';
|
package/dist/events/types.d.ts
CHANGED
|
@@ -220,7 +220,10 @@ export interface MigrationCompletedEvent extends BaseEvent {
|
|
|
220
220
|
export interface MigrationFailedEvent extends BaseEvent {
|
|
221
221
|
type: 'migration:failed';
|
|
222
222
|
migrationId: string;
|
|
223
|
-
error:
|
|
223
|
+
error: Error | {
|
|
224
|
+
message: string;
|
|
225
|
+
code?: string;
|
|
226
|
+
};
|
|
224
227
|
}
|
|
225
228
|
/**
|
|
226
229
|
* Emitted when migration is rolled back
|
|
@@ -322,7 +322,7 @@ async function estimateModuleCosts() {
|
|
|
322
322
|
}
|
|
323
323
|
console.log('');
|
|
324
324
|
// Validate migration before attempting
|
|
325
|
-
const validation =
|
|
325
|
+
const validation = sdk.lifecycle.validateMigration(moduleAsset, 'did:btco');
|
|
326
326
|
console.log('Migration validation:');
|
|
327
327
|
console.log(` Valid: ${validation.valid}`);
|
|
328
328
|
console.log(` Checks:`);
|
|
@@ -139,11 +139,11 @@ async function validateAndEstimate(sdk, asset) {
|
|
|
139
139
|
console.log('\nš STEP 3: Validating Migration & Estimating Costs\n');
|
|
140
140
|
// Validate migration to did:webvh
|
|
141
141
|
console.log('Validating migration to did:webvh:');
|
|
142
|
-
const webvhValidation =
|
|
142
|
+
const webvhValidation = sdk.lifecycle.validateMigration(asset, 'did:webvh');
|
|
143
143
|
printValidation(webvhValidation);
|
|
144
144
|
// Validate migration to did:btco
|
|
145
145
|
console.log('\nValidating migration to did:btco:');
|
|
146
|
-
const btcoValidation =
|
|
146
|
+
const btcoValidation = sdk.lifecycle.validateMigration(asset, 'did:btco');
|
|
147
147
|
printValidation(btcoValidation);
|
|
148
148
|
// Estimate costs for Bitcoin inscription
|
|
149
149
|
console.log('\nCost estimates for Bitcoin inscription:');
|