@originals/sdk 1.4.2 → 1.4.3
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/package.json +4 -1
- package/.eslintrc.json +0 -33
- package/src/adapters/FeeOracleMock.ts +0 -9
- package/src/adapters/index.ts +0 -5
- package/src/adapters/providers/OrdHttpProvider.ts +0 -126
- package/src/adapters/providers/OrdMockProvider.ts +0 -101
- package/src/adapters/types.ts +0 -66
- package/src/bitcoin/BitcoinManager.ts +0 -330
- package/src/bitcoin/BroadcastClient.ts +0 -54
- package/src/bitcoin/OrdinalsClient.ts +0 -119
- package/src/bitcoin/PSBTBuilder.ts +0 -106
- package/src/bitcoin/fee-calculation.ts +0 -38
- package/src/bitcoin/providers/OrdNodeProvider.ts +0 -92
- package/src/bitcoin/providers/OrdinalsProvider.ts +0 -56
- package/src/bitcoin/providers/types.ts +0 -59
- package/src/bitcoin/transactions/commit.ts +0 -465
- package/src/bitcoin/transactions/index.ts +0 -13
- package/src/bitcoin/transfer.ts +0 -43
- package/src/bitcoin/utxo-selection.ts +0 -322
- package/src/bitcoin/utxo.ts +0 -113
- package/src/contexts/credentials-v1.json +0 -237
- package/src/contexts/credentials-v2-examples.json +0 -5
- package/src/contexts/credentials-v2.json +0 -340
- package/src/contexts/credentials.json +0 -237
- package/src/contexts/data-integrity-v2.json +0 -81
- package/src/contexts/dids.json +0 -58
- package/src/contexts/ed255192020.json +0 -93
- package/src/contexts/ordinals-plus.json +0 -23
- package/src/contexts/originals.json +0 -22
- package/src/core/OriginalsSDK.ts +0 -416
- package/src/crypto/Multikey.ts +0 -194
- package/src/crypto/Signer.ts +0 -254
- package/src/crypto/noble-init.ts +0 -121
- package/src/did/BtcoDidResolver.ts +0 -227
- package/src/did/DIDManager.ts +0 -694
- package/src/did/Ed25519Verifier.ts +0 -68
- package/src/did/KeyManager.ts +0 -236
- package/src/did/WebVHManager.ts +0 -498
- package/src/did/createBtcoDidDocument.ts +0 -59
- package/src/did/providers/OrdinalsClientProviderAdapter.ts +0 -68
- package/src/events/EventEmitter.ts +0 -222
- package/src/events/index.ts +0 -19
- package/src/events/types.ts +0 -331
- package/src/examples/basic-usage.ts +0 -78
- package/src/examples/create-module-original.ts +0 -435
- package/src/examples/full-lifecycle-flow.ts +0 -514
- package/src/examples/run.ts +0 -60
- package/src/index.ts +0 -150
- package/src/kinds/KindRegistry.ts +0 -290
- package/src/kinds/index.ts +0 -74
- package/src/kinds/types.ts +0 -470
- package/src/kinds/validators/AgentValidator.ts +0 -257
- package/src/kinds/validators/AppValidator.ts +0 -211
- package/src/kinds/validators/DatasetValidator.ts +0 -242
- package/src/kinds/validators/DocumentValidator.ts +0 -311
- package/src/kinds/validators/MediaValidator.ts +0 -269
- package/src/kinds/validators/ModuleValidator.ts +0 -225
- package/src/kinds/validators/base.ts +0 -276
- package/src/kinds/validators/index.ts +0 -12
- package/src/lifecycle/BatchOperations.ts +0 -373
- package/src/lifecycle/LifecycleManager.ts +0 -2126
- package/src/lifecycle/OriginalsAsset.ts +0 -524
- package/src/lifecycle/ProvenanceQuery.ts +0 -280
- package/src/lifecycle/ResourceVersioning.ts +0 -163
- package/src/migration/MigrationManager.ts +0 -527
- package/src/migration/audit/AuditLogger.ts +0 -176
- package/src/migration/checkpoint/CheckpointManager.ts +0 -112
- package/src/migration/checkpoint/CheckpointStorage.ts +0 -101
- package/src/migration/index.ts +0 -33
- package/src/migration/operations/BaseMigration.ts +0 -126
- package/src/migration/operations/PeerToBtcoMigration.ts +0 -105
- package/src/migration/operations/PeerToWebvhMigration.ts +0 -62
- package/src/migration/operations/WebvhToBtcoMigration.ts +0 -105
- package/src/migration/rollback/RollbackManager.ts +0 -170
- package/src/migration/state/StateMachine.ts +0 -92
- package/src/migration/state/StateTracker.ts +0 -156
- package/src/migration/types.ts +0 -344
- package/src/migration/validation/BitcoinValidator.ts +0 -107
- package/src/migration/validation/CredentialValidator.ts +0 -62
- package/src/migration/validation/DIDCompatibilityValidator.ts +0 -151
- package/src/migration/validation/LifecycleValidator.ts +0 -64
- package/src/migration/validation/StorageValidator.ts +0 -79
- package/src/migration/validation/ValidationPipeline.ts +0 -213
- package/src/resources/ResourceManager.ts +0 -655
- package/src/resources/index.ts +0 -21
- package/src/resources/types.ts +0 -202
- package/src/storage/LocalStorageAdapter.ts +0 -61
- package/src/storage/MemoryStorageAdapter.ts +0 -29
- package/src/storage/StorageAdapter.ts +0 -25
- package/src/storage/index.ts +0 -3
- package/src/types/bitcoin.ts +0 -98
- package/src/types/common.ts +0 -92
- package/src/types/credentials.ts +0 -88
- package/src/types/did.ts +0 -31
- package/src/types/external-shims.d.ts +0 -53
- package/src/types/index.ts +0 -7
- package/src/types/network.ts +0 -175
- package/src/utils/EventLogger.ts +0 -298
- package/src/utils/Logger.ts +0 -322
- package/src/utils/MetricsCollector.ts +0 -358
- package/src/utils/bitcoin-address.ts +0 -130
- package/src/utils/cbor.ts +0 -12
- package/src/utils/encoding.ts +0 -127
- package/src/utils/hash.ts +0 -6
- package/src/utils/retry.ts +0 -46
- package/src/utils/satoshi-validation.ts +0 -196
- package/src/utils/serialization.ts +0 -96
- package/src/utils/telemetry.ts +0 -40
- package/src/utils/validation.ts +0 -119
- package/src/vc/CredentialManager.ts +0 -918
- package/src/vc/Issuer.ts +0 -100
- package/src/vc/Verifier.ts +0 -47
- package/src/vc/cryptosuites/bbs.ts +0 -253
- package/src/vc/cryptosuites/bbsSimple.ts +0 -21
- package/src/vc/cryptosuites/eddsa.ts +0 -99
- package/src/vc/documentLoader.ts +0 -67
- package/src/vc/proofs/data-integrity.ts +0 -33
- package/src/vc/utils/jsonld.ts +0 -18
- package/tests/__mocks__/bbs-signatures.js +0 -17
- package/tests/__mocks__/mf-base58.js +0 -24
- package/tests/fixtures/did-documents.ts +0 -247
- package/tests/index.test.ts +0 -21
- package/tests/integration/BatchOperations.test.ts +0 -531
- package/tests/integration/CompleteLifecycle.e2e.test.ts +0 -735
- package/tests/integration/CredentialManager.test.ts +0 -42
- package/tests/integration/DIDManager.test.ts +0 -41
- package/tests/integration/DidPeerToWebVhFlow.test.ts +0 -351
- package/tests/integration/Events.test.ts +0 -435
- package/tests/integration/Lifecycle.transfer.btco.integration.test.ts +0 -25
- package/tests/integration/LifecycleManager.test.ts +0 -21
- package/tests/integration/MultikeyFlow.test.ts +0 -52
- package/tests/integration/TelemetryIntegration.test.ts +0 -395
- package/tests/integration/WebVhPublish.test.ts +0 -48
- package/tests/integration/createTypedOriginal.test.ts +0 -379
- package/tests/integration/migration/peer-to-webvh.test.ts +0 -172
- package/tests/manual/test-commit-creation.ts +0 -323
- package/tests/mocks/MockKeyStore.ts +0 -38
- package/tests/mocks/adapters/MemoryStorageAdapter.ts +0 -24
- package/tests/mocks/adapters/MockFeeOracle.ts +0 -11
- package/tests/mocks/adapters/MockOrdinalsProvider.ts +0 -76
- package/tests/mocks/adapters/OrdMockProvider.test.ts +0 -176
- package/tests/mocks/adapters/index.ts +0 -6
- package/tests/performance/BatchOperations.perf.test.ts +0 -403
- package/tests/performance/logging.perf.test.ts +0 -336
- package/tests/sdk.test.ts +0 -43
- package/tests/security/bitcoin-penetration-tests.test.ts +0 -622
- package/tests/setup.bun.ts +0 -69
- package/tests/setup.jest.ts +0 -23
- package/tests/stress/batch-operations-stress.test.ts +0 -571
- package/tests/unit/adapters/FeeOracleMock.test.ts +0 -40
- package/tests/unit/bitcoin/BitcoinManager.test.ts +0 -293
- package/tests/unit/bitcoin/BroadcastClient.test.ts +0 -52
- package/tests/unit/bitcoin/OrdNodeProvider.test.ts +0 -53
- package/tests/unit/bitcoin/OrdinalsClient.test.ts +0 -381
- package/tests/unit/bitcoin/OrdinalsClientProvider.test.ts +0 -102
- package/tests/unit/bitcoin/PSBTBuilder.test.ts +0 -84
- package/tests/unit/bitcoin/fee-calculation.test.ts +0 -261
- package/tests/unit/bitcoin/transactions/commit.test.ts +0 -649
- package/tests/unit/bitcoin/transfer.test.ts +0 -31
- package/tests/unit/bitcoin/utxo-selection-new.test.ts +0 -502
- package/tests/unit/bitcoin/utxo.more.test.ts +0 -39
- package/tests/unit/bitcoin/utxo.selection.test.ts +0 -38
- package/tests/unit/core/OriginalsSDK.test.ts +0 -152
- package/tests/unit/crypto/Multikey.test.ts +0 -206
- package/tests/unit/crypto/Signer.test.ts +0 -408
- package/tests/unit/did/BtcoDidResolver.test.ts +0 -611
- package/tests/unit/did/DIDManager.more.test.ts +0 -43
- package/tests/unit/did/DIDManager.test.ts +0 -185
- package/tests/unit/did/Ed25519Verifier.test.ts +0 -160
- package/tests/unit/did/KeyManager.test.ts +0 -452
- package/tests/unit/did/OrdinalsClientProviderAdapter.test.ts +0 -45
- package/tests/unit/did/WebVHManager.test.ts +0 -435
- package/tests/unit/did/createBtcoDidDocument.test.ts +0 -67
- package/tests/unit/did/providers/OrdinalsClientProviderAdapter.test.ts +0 -159
- package/tests/unit/events/EventEmitter.test.ts +0 -407
- package/tests/unit/kinds/KindRegistry.test.ts +0 -329
- package/tests/unit/kinds/types.test.ts +0 -409
- package/tests/unit/kinds/validators.test.ts +0 -651
- package/tests/unit/lifecycle/BatchOperations.test.ts +0 -527
- package/tests/unit/lifecycle/LifecycleManager.cleanapi.test.ts +0 -441
- package/tests/unit/lifecycle/LifecycleManager.keymanagement.test.ts +0 -312
- package/tests/unit/lifecycle/LifecycleManager.prov.test.ts +0 -18
- package/tests/unit/lifecycle/LifecycleManager.test.ts +0 -213
- package/tests/unit/lifecycle/LifecycleManager.transfer.unit.test.ts +0 -30
- package/tests/unit/lifecycle/OriginalsAsset.test.ts +0 -176
- package/tests/unit/lifecycle/ProvenanceQuery.test.ts +0 -577
- package/tests/unit/lifecycle/ResourceVersioning.test.ts +0 -651
- package/tests/unit/resources/ResourceManager.test.ts +0 -740
- package/tests/unit/storage/MemoryStorageAdapter.test.ts +0 -93
- package/tests/unit/types/network.test.ts +0 -255
- package/tests/unit/utils/EventIntegration.test.ts +0 -384
- package/tests/unit/utils/Logger.test.ts +0 -473
- package/tests/unit/utils/MetricsCollector.test.ts +0 -358
- package/tests/unit/utils/bitcoin-address.test.ts +0 -250
- package/tests/unit/utils/cbor.test.ts +0 -35
- package/tests/unit/utils/encoding.test.ts +0 -318
- package/tests/unit/utils/hash.test.ts +0 -12
- package/tests/unit/utils/retry.test.ts +0 -100
- package/tests/unit/utils/satoshi-validation.test.ts +0 -354
- package/tests/unit/utils/serialization.test.ts +0 -124
- package/tests/unit/utils/telemetry.test.ts +0 -52
- package/tests/unit/utils/validation.test.ts +0 -141
- package/tests/unit/vc/CredentialManager.helpers.test.ts +0 -527
- package/tests/unit/vc/CredentialManager.test.ts +0 -487
- package/tests/unit/vc/Issuer.test.ts +0 -107
- package/tests/unit/vc/Verifier.test.ts +0 -525
- package/tests/unit/vc/bbs.test.ts +0 -282
- package/tests/unit/vc/cryptosuites/eddsa.test.ts +0 -398
- package/tests/unit/vc/documentLoader.test.ts +0 -121
- package/tests/unit/vc/proofs/data-integrity.test.ts +0 -24
- package/tsconfig.json +0 -31
- package/tsconfig.test.json +0 -15
package/src/did/DIDManager.ts
DELETED
|
@@ -1,694 +0,0 @@
|
|
|
1
|
-
import { DIDDocument, OriginalsConfig, AssetResource, VerificationMethod, KeyPair, ExternalSigner, ExternalVerifier } from '../types';
|
|
2
|
-
import { getNetworkDomain, DEFAULT_WEBVH_NETWORK, getBitcoinNetworkForWebVH } from '../types/network';
|
|
3
|
-
import { BtcoDidResolver } from './BtcoDidResolver';
|
|
4
|
-
import { OrdinalsClient } from '../bitcoin/OrdinalsClient';
|
|
5
|
-
import { createBtcoDidDocument } from './createBtcoDidDocument';
|
|
6
|
-
import { OrdinalsClientProviderAdapter } from './providers/OrdinalsClientProviderAdapter';
|
|
7
|
-
import { multikey } from '../crypto/Multikey';
|
|
8
|
-
import { KeyManager } from './KeyManager';
|
|
9
|
-
import { Ed25519Signer } from '../crypto/Signer';
|
|
10
|
-
import { validateSatoshiNumber, MAX_SATOSHI_SUPPLY } from '../utils/satoshi-validation';
|
|
11
|
-
import * as fs from 'fs';
|
|
12
|
-
import * as path from 'path';
|
|
13
|
-
|
|
14
|
-
export class DIDManager {
|
|
15
|
-
constructor(private config: OriginalsConfig) {}
|
|
16
|
-
|
|
17
|
-
async createDIDPeer(resources: AssetResource[], returnKeyPair?: false): Promise<DIDDocument>;
|
|
18
|
-
async createDIDPeer(resources: AssetResource[], returnKeyPair: true): Promise<{ didDocument: DIDDocument; keyPair: { privateKey: string; publicKey: string } }>;
|
|
19
|
-
async createDIDPeer(resources: AssetResource[], returnKeyPair?: boolean): Promise<DIDDocument | { didDocument: DIDDocument; keyPair: { privateKey: string; publicKey: string } }> {
|
|
20
|
-
// Generate a multikey keypair according to configured defaultKeyType
|
|
21
|
-
const keyManager = new KeyManager();
|
|
22
|
-
const desiredType = this.config.defaultKeyType || 'ES256K';
|
|
23
|
-
const keyPair = await keyManager.generateKeyPair(desiredType);
|
|
24
|
-
|
|
25
|
-
// Use @aviarytech/did-peer to create a did:peer (variant 4 long-form for full VM+context)
|
|
26
|
-
const didPeerMod: any = await import('@aviarytech/did-peer');
|
|
27
|
-
const did: string = await didPeerMod.createNumAlgo4(
|
|
28
|
-
[
|
|
29
|
-
{
|
|
30
|
-
// type validated by the library; controller/id not required
|
|
31
|
-
type: 'Multikey',
|
|
32
|
-
publicKeyMultibase: keyPair.publicKey
|
|
33
|
-
}
|
|
34
|
-
],
|
|
35
|
-
undefined,
|
|
36
|
-
undefined
|
|
37
|
-
);
|
|
38
|
-
|
|
39
|
-
// Resolve to DID Document using the same library
|
|
40
|
-
const resolved: any = await didPeerMod.resolve(did);
|
|
41
|
-
// Ensure controller is set on VM entries for compatibility
|
|
42
|
-
if (resolved && Array.isArray(resolved.verificationMethod)) {
|
|
43
|
-
resolved.verificationMethod = resolved.verificationMethod.map((vm: any) => ({
|
|
44
|
-
controller: did,
|
|
45
|
-
...vm
|
|
46
|
-
}));
|
|
47
|
-
}
|
|
48
|
-
// Ensure relationships exist and reference a VM
|
|
49
|
-
const vmIds: string[] = Array.isArray(resolved?.verificationMethod)
|
|
50
|
-
? resolved.verificationMethod.map((vm: any) => vm.id).filter(Boolean)
|
|
51
|
-
: [];
|
|
52
|
-
if (!resolved.authentication || resolved.authentication.length === 0) {
|
|
53
|
-
if (vmIds.length > 0) resolved.authentication = [vmIds[0]];
|
|
54
|
-
}
|
|
55
|
-
if (!resolved.assertionMethod || resolved.assertionMethod.length === 0) {
|
|
56
|
-
resolved.assertionMethod = resolved.authentication || (vmIds.length > 0 ? [vmIds[0]] : []);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
if (returnKeyPair) {
|
|
60
|
-
return { didDocument: resolved as DIDDocument, keyPair };
|
|
61
|
-
}
|
|
62
|
-
return resolved as DIDDocument;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
async migrateToDIDWebVH(didDoc: DIDDocument, domain?: string): Promise<DIDDocument> {
|
|
66
|
-
// Use provided domain or get default from configured network
|
|
67
|
-
const network = this.config.webvhNetwork || DEFAULT_WEBVH_NETWORK;
|
|
68
|
-
const targetDomain = domain || getNetworkDomain(network);
|
|
69
|
-
|
|
70
|
-
// Flexible domain validation - allow development domains with ports
|
|
71
|
-
const normalized = String(targetDomain || '').trim().toLowerCase();
|
|
72
|
-
|
|
73
|
-
// Split domain and port if present
|
|
74
|
-
const [domainPart, portPart] = normalized.split(':');
|
|
75
|
-
|
|
76
|
-
// Validate port if present
|
|
77
|
-
if (portPart && (!/^\d+$/.test(portPart) || parseInt(portPart) < 1 || parseInt(portPart) > 65535)) {
|
|
78
|
-
throw new Error(`Invalid domain: ${domain} - invalid port`);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// Allow localhost and IP addresses for development
|
|
82
|
-
const isLocalhost = domainPart === 'localhost';
|
|
83
|
-
const isIP = /^(\d{1,3}\.){3}\d{1,3}$/.test(domainPart);
|
|
84
|
-
|
|
85
|
-
if (!isLocalhost && !isIP) {
|
|
86
|
-
// For non-localhost domains, require proper domain format
|
|
87
|
-
const label = '[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?';
|
|
88
|
-
const domainRegex = new RegExp(`^(?=.{1,253}$)(?:${label})(?:\\.(?:${label}))+?$`, 'i');
|
|
89
|
-
if (!domainRegex.test(domainPart)) {
|
|
90
|
-
throw new Error('Invalid domain');
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
// Stable slug derived from original peer DID suffix (or last segment)
|
|
95
|
-
const parts = (didDoc.id || '').split(':');
|
|
96
|
-
const method = parts.slice(0, 2).join(':');
|
|
97
|
-
const originalSuffix = method === 'did:peer' ? parts.slice(2).join(':') : parts[parts.length - 1];
|
|
98
|
-
const slug = (originalSuffix || '')
|
|
99
|
-
.toString()
|
|
100
|
-
.trim()
|
|
101
|
-
.replace(/[^a-zA-Z0-9._-]/g, '-')
|
|
102
|
-
.toLowerCase();
|
|
103
|
-
|
|
104
|
-
const migrated: DIDDocument = {
|
|
105
|
-
...didDoc,
|
|
106
|
-
id: `did:webvh:${normalized}:${slug}`
|
|
107
|
-
};
|
|
108
|
-
return migrated;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
async migrateToDIDBTCO(didDoc: DIDDocument, satoshi: string): Promise<DIDDocument> {
|
|
112
|
-
// Validate satoshi parameter
|
|
113
|
-
const validation = validateSatoshiNumber(satoshi);
|
|
114
|
-
if (!validation.valid) {
|
|
115
|
-
throw new Error(`Invalid satoshi identifier: ${validation.error}`);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
// Additional range validation for positive values within Bitcoin supply
|
|
119
|
-
const satoshiNum = Number(satoshi);
|
|
120
|
-
if (satoshiNum < 0) {
|
|
121
|
-
throw new Error('Satoshi identifier must be positive (>= 0)');
|
|
122
|
-
}
|
|
123
|
-
if (satoshiNum > MAX_SATOSHI_SUPPLY) {
|
|
124
|
-
throw new Error(`Satoshi identifier must be within Bitcoin's total supply (0 to ${MAX_SATOSHI_SUPPLY.toLocaleString()})`);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
// Determine Bitcoin network from WebVH network configuration if available
|
|
128
|
-
// This ensures consistent environment mapping: magby→regtest, cleffa→signet, pichu→mainnet
|
|
129
|
-
let network: 'mainnet' | 'regtest' | 'signet';
|
|
130
|
-
if (this.config.webvhNetwork) {
|
|
131
|
-
network = getBitcoinNetworkForWebVH(this.config.webvhNetwork);
|
|
132
|
-
} else {
|
|
133
|
-
// Fall back to explicit network config
|
|
134
|
-
network = this.config.network || 'mainnet';
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
// Try to carry over the first multikey VM if present
|
|
138
|
-
const firstVm = (didDoc.verificationMethod && didDoc.verificationMethod[0]) as VerificationMethod | undefined;
|
|
139
|
-
let publicKey: Uint8Array | undefined;
|
|
140
|
-
let keyType: Parameters<typeof createBtcoDidDocument>[2]['keyType'] | undefined;
|
|
141
|
-
try {
|
|
142
|
-
if (firstVm && firstVm.publicKeyMultibase) {
|
|
143
|
-
const decoded = multikey.decodePublicKey(firstVm.publicKeyMultibase);
|
|
144
|
-
publicKey = decoded.key;
|
|
145
|
-
keyType = decoded.type;
|
|
146
|
-
}
|
|
147
|
-
} catch (err) {
|
|
148
|
-
// Unable to decode public key from verification method; will proceed without key material
|
|
149
|
-
if (this.config.enableLogging) {
|
|
150
|
-
console.warn('Failed to decode verification method public key:', err);
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
// If no key material is available, generate a minimal btco DID doc without keys
|
|
155
|
-
let btcoDoc: DIDDocument;
|
|
156
|
-
if (publicKey && keyType) {
|
|
157
|
-
btcoDoc = createBtcoDidDocument(satoshi, network as any, { publicKey, keyType });
|
|
158
|
-
} else {
|
|
159
|
-
const prefix = network === 'mainnet' ? 'did:btco:' : network === 'regtest' ? 'did:btco:reg:' : 'did:btco:sig:';
|
|
160
|
-
btcoDoc = {
|
|
161
|
-
'@context': ['https://www.w3.org/ns/did/v1'],
|
|
162
|
-
id: prefix + String(satoshi)
|
|
163
|
-
};
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
// Carry over service endpoints if present
|
|
167
|
-
if (didDoc.service && didDoc.service.length > 0) {
|
|
168
|
-
btcoDoc.service = didDoc.service;
|
|
169
|
-
}
|
|
170
|
-
return btcoDoc;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
async resolveDID(did: string): Promise<DIDDocument | null> {
|
|
174
|
-
try {
|
|
175
|
-
if (did.startsWith('did:peer:')) {
|
|
176
|
-
try {
|
|
177
|
-
const mod: any = await import('@aviarytech/did-peer');
|
|
178
|
-
const doc = await mod.resolve(did);
|
|
179
|
-
return doc as DIDDocument;
|
|
180
|
-
} catch (err) {
|
|
181
|
-
// Failed to resolve did:peer; returning minimal document
|
|
182
|
-
if (this.config.enableLogging) {
|
|
183
|
-
console.warn('Failed to resolve did:peer:', err);
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
return { '@context': ['https://www.w3.org/ns/did/v1'], id: did };
|
|
187
|
-
}
|
|
188
|
-
if (did.startsWith('did:btco:') || did.startsWith('did:btco:test:') || did.startsWith('did:btco:sig:')) {
|
|
189
|
-
const rpcUrl = this.config.bitcoinRpcUrl || 'http://localhost:3000';
|
|
190
|
-
const network = this.config.network || 'mainnet';
|
|
191
|
-
const client = new OrdinalsClient(rpcUrl, network);
|
|
192
|
-
const adapter = new OrdinalsClientProviderAdapter(client, rpcUrl);
|
|
193
|
-
const resolver = new BtcoDidResolver({ provider: adapter });
|
|
194
|
-
const result = await resolver.resolve(did);
|
|
195
|
-
return result.didDocument || null;
|
|
196
|
-
}
|
|
197
|
-
if (did.startsWith('did:webvh:')) {
|
|
198
|
-
try {
|
|
199
|
-
const mod: any = await import('didwebvh-ts');
|
|
200
|
-
if (mod && typeof mod.resolveDID === 'function') {
|
|
201
|
-
const result = await mod.resolveDID(did);
|
|
202
|
-
if (result && result.doc) return result.doc as DIDDocument;
|
|
203
|
-
}
|
|
204
|
-
} catch (err) {
|
|
205
|
-
// Failed to resolve did:webvh; returning minimal document
|
|
206
|
-
if (this.config.enableLogging) {
|
|
207
|
-
console.warn('Failed to resolve did:webvh:', err);
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
return { '@context': ['https://www.w3.org/ns/did/v1'], id: did };
|
|
211
|
-
}
|
|
212
|
-
return { '@context': ['https://www.w3.org/ns/did/v1'], id: did };
|
|
213
|
-
} catch (err) {
|
|
214
|
-
// DID resolution failed
|
|
215
|
-
if (this.config.enableLogging) {
|
|
216
|
-
console.error('Failed to resolve DID:', err);
|
|
217
|
-
}
|
|
218
|
-
return null;
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
validateDIDDocument(didDoc: DIDDocument): boolean {
|
|
223
|
-
return !!didDoc.id && Array.isArray(didDoc['@context']);
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
private getLayerFromDID(did: string): 'did:peer' | 'did:webvh' | 'did:btco' {
|
|
227
|
-
if (did.startsWith('did:peer:')) return 'did:peer';
|
|
228
|
-
if (did.startsWith('did:webvh:')) return 'did:webvh';
|
|
229
|
-
if (did.startsWith('did:btco:')) return 'did:btco';
|
|
230
|
-
throw new Error('Unsupported DID method');
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
createBtcoDidDocument(
|
|
234
|
-
satNumber: number | string,
|
|
235
|
-
network: 'mainnet' | 'regtest' | 'signet',
|
|
236
|
-
options: Parameters<typeof createBtcoDidDocument>[2]
|
|
237
|
-
): DIDDocument {
|
|
238
|
-
return createBtcoDidDocument(satNumber, network, options as any);
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
// ========================================================================
|
|
242
|
-
// DID:WebVH Methods
|
|
243
|
-
// ========================================================================
|
|
244
|
-
|
|
245
|
-
/**
|
|
246
|
-
* Creates a new did:webvh DID with proper cryptographic signing
|
|
247
|
-
* @param options - Creation options including domain and optional key pair or external signer
|
|
248
|
-
* @returns The created DID, document, log, and key pair (if generated)
|
|
249
|
-
*/
|
|
250
|
-
async createDIDWebVH(options: CreateWebVHOptions): Promise<CreateWebVHResult> {
|
|
251
|
-
const {
|
|
252
|
-
domain: providedDomain,
|
|
253
|
-
keyPair: providedKeyPair,
|
|
254
|
-
paths = [],
|
|
255
|
-
portable = false,
|
|
256
|
-
outputDir,
|
|
257
|
-
externalSigner,
|
|
258
|
-
externalVerifier,
|
|
259
|
-
verificationMethods: providedVerificationMethods,
|
|
260
|
-
updateKeys: providedUpdateKeys
|
|
261
|
-
} = options;
|
|
262
|
-
|
|
263
|
-
// Use provided domain or get default from configured network
|
|
264
|
-
const network = this.config.webvhNetwork || DEFAULT_WEBVH_NETWORK;
|
|
265
|
-
const domain = providedDomain || getNetworkDomain(network);
|
|
266
|
-
|
|
267
|
-
// Dynamically import didwebvh-ts to avoid module resolution issues
|
|
268
|
-
const mod = await import('didwebvh-ts') as unknown as {
|
|
269
|
-
createDID: (options: Record<string, unknown>) => Promise<{
|
|
270
|
-
did: string;
|
|
271
|
-
doc: Record<string, unknown>;
|
|
272
|
-
log: DIDLog;
|
|
273
|
-
}>;
|
|
274
|
-
prepareDataForSigning: (
|
|
275
|
-
document: Record<string, unknown>,
|
|
276
|
-
proof: Record<string, unknown>
|
|
277
|
-
) => Promise<Uint8Array>;
|
|
278
|
-
};
|
|
279
|
-
const { createDID, prepareDataForSigning } = mod;
|
|
280
|
-
|
|
281
|
-
// Runtime validation of imported module
|
|
282
|
-
if (typeof createDID !== 'function' || typeof prepareDataForSigning !== 'function') {
|
|
283
|
-
throw new Error('Failed to load didwebvh-ts: invalid module exports');
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
let signer: Signer | ExternalSigner;
|
|
287
|
-
let verifier: Verifier | ExternalVerifier;
|
|
288
|
-
let keyPair: KeyPair | undefined;
|
|
289
|
-
let verificationMethods: WebVHVerificationMethod[];
|
|
290
|
-
let updateKeys: string[];
|
|
291
|
-
|
|
292
|
-
// Use external signer if provided (e.g., Turnkey integration)
|
|
293
|
-
if (externalSigner) {
|
|
294
|
-
if (!providedVerificationMethods || providedVerificationMethods.length === 0) {
|
|
295
|
-
throw new Error('verificationMethods are required when using externalSigner');
|
|
296
|
-
}
|
|
297
|
-
if (!providedUpdateKeys || providedUpdateKeys.length === 0) {
|
|
298
|
-
throw new Error('updateKeys are required when using externalSigner');
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
signer = externalSigner;
|
|
302
|
-
verifier = externalVerifier || externalSigner as any; // Use signer as verifier if not provided
|
|
303
|
-
verificationMethods = providedVerificationMethods;
|
|
304
|
-
updateKeys = providedUpdateKeys;
|
|
305
|
-
keyPair = undefined; // No key pair when using external signer
|
|
306
|
-
} else {
|
|
307
|
-
// Generate or use provided key pair (Ed25519 for did:webvh)
|
|
308
|
-
const keyManager = new KeyManager();
|
|
309
|
-
keyPair = providedKeyPair || await keyManager.generateKeyPair('Ed25519');
|
|
310
|
-
|
|
311
|
-
// Create verification methods
|
|
312
|
-
verificationMethods = [
|
|
313
|
-
{
|
|
314
|
-
type: 'Multikey',
|
|
315
|
-
publicKeyMultibase: keyPair.publicKey,
|
|
316
|
-
}
|
|
317
|
-
];
|
|
318
|
-
|
|
319
|
-
// Create signer using our adapter
|
|
320
|
-
const internalSigner = new OriginalsWebVHSigner(
|
|
321
|
-
keyPair.privateKey,
|
|
322
|
-
verificationMethods[0],
|
|
323
|
-
prepareDataForSigning,
|
|
324
|
-
{ verificationMethod: verificationMethods[0] }
|
|
325
|
-
);
|
|
326
|
-
|
|
327
|
-
signer = internalSigner;
|
|
328
|
-
verifier = internalSigner; // Use the same signer as verifier
|
|
329
|
-
updateKeys = [`did:key:${keyPair.publicKey}`]; // Use did:key format for authorization
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
// Create the DID using didwebvh-ts
|
|
333
|
-
const result = await createDID({
|
|
334
|
-
domain,
|
|
335
|
-
signer,
|
|
336
|
-
verifier,
|
|
337
|
-
updateKeys,
|
|
338
|
-
verificationMethods,
|
|
339
|
-
context: [
|
|
340
|
-
'https://www.w3.org/ns/did/v1',
|
|
341
|
-
'https://w3id.org/security/multikey/v1'
|
|
342
|
-
],
|
|
343
|
-
paths,
|
|
344
|
-
portable,
|
|
345
|
-
authentication: ['#key-0'],
|
|
346
|
-
assertionMethod: ['#key-0'],
|
|
347
|
-
});
|
|
348
|
-
|
|
349
|
-
// Validate the returned DID document
|
|
350
|
-
if (!this.validateDIDDocument(result.doc as unknown as DIDDocument)) {
|
|
351
|
-
throw new Error('Invalid DID document returned from createDID');
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
// Save the log to did.jsonl if output directory is provided
|
|
355
|
-
let logPath: string | undefined;
|
|
356
|
-
if (outputDir) {
|
|
357
|
-
logPath = await this.saveDIDLog(result.did, result.log, outputDir);
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
return {
|
|
361
|
-
did: result.did,
|
|
362
|
-
didDocument: result.doc as unknown as DIDDocument,
|
|
363
|
-
log: result.log,
|
|
364
|
-
keyPair: keyPair || { publicKey: '', privateKey: '' }, // Return empty keypair if using external signer
|
|
365
|
-
logPath,
|
|
366
|
-
};
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
/**
|
|
370
|
-
* Updates a DID:WebVH document
|
|
371
|
-
* @param options - Update options
|
|
372
|
-
* @returns Updated DID document and log
|
|
373
|
-
*/
|
|
374
|
-
async updateDIDWebVH(options: {
|
|
375
|
-
did: string;
|
|
376
|
-
currentLog: DIDLog;
|
|
377
|
-
updates: Partial<DIDDocument>;
|
|
378
|
-
signer: ExternalSigner | { privateKey: string; publicKey: string };
|
|
379
|
-
verifier?: ExternalVerifier;
|
|
380
|
-
outputDir?: string;
|
|
381
|
-
}): Promise<{ didDocument: DIDDocument; log: DIDLog; logPath?: string }> {
|
|
382
|
-
const { did, currentLog, updates, signer: providedSigner, verifier: providedVerifier, outputDir } = options;
|
|
383
|
-
|
|
384
|
-
// Dynamically import didwebvh-ts
|
|
385
|
-
const mod = await import('didwebvh-ts') as unknown as {
|
|
386
|
-
updateDID: (options: Record<string, unknown>) => Promise<{
|
|
387
|
-
doc: Record<string, unknown>;
|
|
388
|
-
log: DIDLog;
|
|
389
|
-
}>;
|
|
390
|
-
prepareDataForSigning: (
|
|
391
|
-
document: Record<string, unknown>,
|
|
392
|
-
proof: Record<string, unknown>
|
|
393
|
-
) => Promise<Uint8Array>;
|
|
394
|
-
};
|
|
395
|
-
const { updateDID, prepareDataForSigning } = mod;
|
|
396
|
-
|
|
397
|
-
if (typeof updateDID !== 'function') {
|
|
398
|
-
throw new Error('Failed to load didwebvh-ts: invalid module exports');
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
let signer: Signer | ExternalSigner;
|
|
402
|
-
let verifier: Verifier | ExternalVerifier | undefined;
|
|
403
|
-
|
|
404
|
-
// Check if using external signer or internal keypair
|
|
405
|
-
if ('sign' in providedSigner && 'getVerificationMethodId' in providedSigner) {
|
|
406
|
-
// External signer
|
|
407
|
-
signer = providedSigner as ExternalSigner;
|
|
408
|
-
verifier = providedVerifier;
|
|
409
|
-
} else {
|
|
410
|
-
// Internal signer with keypair
|
|
411
|
-
const keyPair = providedSigner as { privateKey: string; publicKey: string };
|
|
412
|
-
const verificationMethod: WebVHVerificationMethod = {
|
|
413
|
-
type: 'Multikey',
|
|
414
|
-
publicKeyMultibase: keyPair.publicKey,
|
|
415
|
-
};
|
|
416
|
-
|
|
417
|
-
const internalSigner = new OriginalsWebVHSigner(
|
|
418
|
-
keyPair.privateKey,
|
|
419
|
-
verificationMethod,
|
|
420
|
-
prepareDataForSigning,
|
|
421
|
-
{ verificationMethod }
|
|
422
|
-
);
|
|
423
|
-
|
|
424
|
-
signer = internalSigner;
|
|
425
|
-
verifier = internalSigner;
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
// Get the current document from the log
|
|
429
|
-
const currentEntry = currentLog[currentLog.length - 1];
|
|
430
|
-
const currentDoc = currentEntry.state as unknown as DIDDocument;
|
|
431
|
-
|
|
432
|
-
// Merge updates with current document
|
|
433
|
-
const updatedDoc = {
|
|
434
|
-
...currentDoc,
|
|
435
|
-
...updates,
|
|
436
|
-
id: did, // Ensure ID doesn't change
|
|
437
|
-
};
|
|
438
|
-
|
|
439
|
-
// Update the DID using didwebvh-ts
|
|
440
|
-
const result = await updateDID({
|
|
441
|
-
log: currentLog,
|
|
442
|
-
doc: updatedDoc,
|
|
443
|
-
signer,
|
|
444
|
-
verifier,
|
|
445
|
-
});
|
|
446
|
-
|
|
447
|
-
// Validate the returned DID document
|
|
448
|
-
if (!this.validateDIDDocument(result.doc as unknown as DIDDocument)) {
|
|
449
|
-
throw new Error('Invalid DID document returned from updateDID');
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
// Save the updated log if output directory is provided
|
|
453
|
-
let logPath: string | undefined;
|
|
454
|
-
if (outputDir) {
|
|
455
|
-
logPath = await this.saveDIDLog(did, result.log, outputDir);
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
return {
|
|
459
|
-
didDocument: result.doc as unknown as DIDDocument,
|
|
460
|
-
log: result.log,
|
|
461
|
-
logPath,
|
|
462
|
-
};
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
/**
|
|
466
|
-
* Saves the DID log to the appropriate did.jsonl path
|
|
467
|
-
* @param did - The DID identifier
|
|
468
|
-
* @param log - The DID log to save
|
|
469
|
-
* @param baseDir - Base directory for saving (e.g., public/.well-known)
|
|
470
|
-
* @returns The full path where the log was saved
|
|
471
|
-
*/
|
|
472
|
-
async saveDIDLog(did: string, log: DIDLog, baseDir: string): Promise<string> {
|
|
473
|
-
// Parse the DID to extract domain and path components
|
|
474
|
-
// Format: did:webvh:domain[:port]:path1:path2...
|
|
475
|
-
const didParts = did.split(':');
|
|
476
|
-
if (didParts.length < 3 || didParts[0] !== 'did' || didParts[1] !== 'webvh') {
|
|
477
|
-
throw new Error('Invalid did:webvh format');
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
// Extract path parts (everything after domain)
|
|
481
|
-
const pathParts = didParts.slice(3);
|
|
482
|
-
|
|
483
|
-
// Validate all path segments to prevent directory traversal
|
|
484
|
-
for (const segment of pathParts) {
|
|
485
|
-
if (!this.isValidPathSegment(segment)) {
|
|
486
|
-
throw new Error(`Invalid path segment in DID: "${segment}". Path segments cannot contain '.', '..', path separators, or be absolute paths.`);
|
|
487
|
-
}
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
// Extract and sanitize domain for filesystem safety
|
|
491
|
-
const rawDomain = decodeURIComponent(didParts[2]);
|
|
492
|
-
// Normalize: lowercase and replace any characters not in [a-z0-9._-] with '_'
|
|
493
|
-
const safeDomain = rawDomain
|
|
494
|
-
.toLowerCase()
|
|
495
|
-
.replace(/[^a-z0-9._-]/g, '_');
|
|
496
|
-
|
|
497
|
-
// Validate the sanitized domain (reject '..' and other dangerous patterns)
|
|
498
|
-
if (!this.isValidPathSegment(safeDomain)) {
|
|
499
|
-
throw new Error(`Invalid domain segment in DID: "${rawDomain}"`);
|
|
500
|
-
}
|
|
501
|
-
|
|
502
|
-
// Construct the file path with domain isolation
|
|
503
|
-
// For did:webvh:example.com:user:alice -> baseDir/did/example.com/user/alice/did.jsonl
|
|
504
|
-
// For did:webvh:example.com:alice -> baseDir/did/example.com/alice/did.jsonl
|
|
505
|
-
const segments = [safeDomain, ...pathParts];
|
|
506
|
-
const didPath = path.join(baseDir, 'did', ...segments, 'did.jsonl');
|
|
507
|
-
|
|
508
|
-
// Verify the resolved path is still within baseDir (defense in depth)
|
|
509
|
-
const resolvedBaseDir = path.resolve(baseDir);
|
|
510
|
-
const resolvedPath = path.resolve(didPath);
|
|
511
|
-
const relativePath = path.relative(resolvedBaseDir, resolvedPath);
|
|
512
|
-
if (relativePath.startsWith('..') || path.isAbsolute(relativePath)) {
|
|
513
|
-
throw new Error('Invalid DID path: resolved path is outside base directory');
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
// Create directories if they don't exist
|
|
517
|
-
const dirPath = path.dirname(didPath);
|
|
518
|
-
await fs.promises.mkdir(dirPath, { recursive: true });
|
|
519
|
-
|
|
520
|
-
// Convert log to JSONL format (one JSON object per line)
|
|
521
|
-
const jsonlContent = log.map((entry: DIDLogEntry) => JSON.stringify(entry)).join('\n');
|
|
522
|
-
|
|
523
|
-
// Write the log file
|
|
524
|
-
await fs.promises.writeFile(didPath, jsonlContent, 'utf8');
|
|
525
|
-
|
|
526
|
-
return didPath;
|
|
527
|
-
}
|
|
528
|
-
|
|
529
|
-
/**
|
|
530
|
-
* Loads a DID log from a did.jsonl file
|
|
531
|
-
* @param logPath - Path to the did.jsonl file
|
|
532
|
-
* @returns The loaded DID log
|
|
533
|
-
*/
|
|
534
|
-
async loadDIDLog(logPath: string): Promise<DIDLog> {
|
|
535
|
-
const content = await fs.promises.readFile(logPath, 'utf8');
|
|
536
|
-
const lines = content.trim().split('\n');
|
|
537
|
-
return lines.map(line => JSON.parse(line));
|
|
538
|
-
}
|
|
539
|
-
|
|
540
|
-
/**
|
|
541
|
-
* Validates a path segment to prevent directory traversal attacks
|
|
542
|
-
* @param segment - Path segment to validate
|
|
543
|
-
* @returns true if valid, false otherwise
|
|
544
|
-
*/
|
|
545
|
-
private isValidPathSegment(segment: string): boolean {
|
|
546
|
-
// Reject empty segments, dots, or segments with path separators
|
|
547
|
-
if (!segment || segment === '.' || segment === '..') {
|
|
548
|
-
return false;
|
|
549
|
-
}
|
|
550
|
-
|
|
551
|
-
// Reject segments containing path separators or other dangerous characters
|
|
552
|
-
if (segment.includes('/') || segment.includes('\\') || segment.includes('\0')) {
|
|
553
|
-
return false;
|
|
554
|
-
}
|
|
555
|
-
|
|
556
|
-
// Reject absolute paths (starting with / or drive letter on Windows)
|
|
557
|
-
if (path.isAbsolute(segment)) {
|
|
558
|
-
return false;
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
return true;
|
|
562
|
-
}
|
|
563
|
-
}
|
|
564
|
-
|
|
565
|
-
// Type definitions for didwebvh-ts (to avoid module resolution issues)
|
|
566
|
-
interface WebVHVerificationMethod {
|
|
567
|
-
id?: string;
|
|
568
|
-
type: string;
|
|
569
|
-
controller?: string;
|
|
570
|
-
publicKeyMultibase: string;
|
|
571
|
-
secretKeyMultibase?: string;
|
|
572
|
-
purpose?: 'authentication' | 'assertionMethod' | 'keyAgreement' | 'capabilityInvocation' | 'capabilityDelegation';
|
|
573
|
-
}
|
|
574
|
-
|
|
575
|
-
interface SigningInput {
|
|
576
|
-
document: Record<string, unknown>;
|
|
577
|
-
proof: Record<string, unknown>;
|
|
578
|
-
}
|
|
579
|
-
|
|
580
|
-
interface SigningOutput {
|
|
581
|
-
proofValue: string;
|
|
582
|
-
}
|
|
583
|
-
|
|
584
|
-
interface SignerOptions {
|
|
585
|
-
verificationMethod?: WebVHVerificationMethod | null;
|
|
586
|
-
useStaticId?: boolean;
|
|
587
|
-
}
|
|
588
|
-
|
|
589
|
-
interface Signer {
|
|
590
|
-
sign(input: SigningInput): Promise<SigningOutput>;
|
|
591
|
-
getVerificationMethodId(): string;
|
|
592
|
-
}
|
|
593
|
-
|
|
594
|
-
interface Verifier {
|
|
595
|
-
verify(signature: Uint8Array, message: Uint8Array, publicKey: Uint8Array): Promise<boolean>;
|
|
596
|
-
}
|
|
597
|
-
|
|
598
|
-
interface DIDLogEntry {
|
|
599
|
-
versionId: string;
|
|
600
|
-
versionTime: string;
|
|
601
|
-
parameters: Record<string, unknown>;
|
|
602
|
-
state: Record<string, unknown>;
|
|
603
|
-
proof?: Record<string, unknown>[];
|
|
604
|
-
}
|
|
605
|
-
|
|
606
|
-
type DIDLog = DIDLogEntry[];
|
|
607
|
-
|
|
608
|
-
export interface CreateWebVHOptions {
|
|
609
|
-
domain?: string; // Optional - defaults to configured webvhNetwork domain
|
|
610
|
-
keyPair?: KeyPair;
|
|
611
|
-
paths?: string[];
|
|
612
|
-
portable?: boolean;
|
|
613
|
-
outputDir?: string;
|
|
614
|
-
externalSigner?: ExternalSigner;
|
|
615
|
-
externalVerifier?: ExternalVerifier;
|
|
616
|
-
verificationMethods?: WebVHVerificationMethod[];
|
|
617
|
-
updateKeys?: string[];
|
|
618
|
-
}
|
|
619
|
-
|
|
620
|
-
export interface CreateWebVHResult {
|
|
621
|
-
did: string;
|
|
622
|
-
didDocument: DIDDocument;
|
|
623
|
-
log: DIDLog;
|
|
624
|
-
keyPair: KeyPair;
|
|
625
|
-
logPath?: string;
|
|
626
|
-
}
|
|
627
|
-
|
|
628
|
-
/**
|
|
629
|
-
* Adapter to use Originals SDK signers with didwebvh-ts
|
|
630
|
-
*/
|
|
631
|
-
class OriginalsWebVHSigner implements Signer, Verifier {
|
|
632
|
-
private privateKeyMultibase: string;
|
|
633
|
-
private signer: Ed25519Signer;
|
|
634
|
-
protected verificationMethod?: WebVHVerificationMethod | null;
|
|
635
|
-
protected useStaticId: boolean;
|
|
636
|
-
private prepareDataForSigning: (document: Record<string, unknown>, proof: Record<string, unknown>) => Promise<Uint8Array>;
|
|
637
|
-
|
|
638
|
-
constructor(
|
|
639
|
-
privateKeyMultibase: string,
|
|
640
|
-
verificationMethod: WebVHVerificationMethod,
|
|
641
|
-
prepareDataForSigning: (document: Record<string, unknown>, proof: Record<string, unknown>) => Promise<Uint8Array>,
|
|
642
|
-
options: SignerOptions = {}
|
|
643
|
-
) {
|
|
644
|
-
this.privateKeyMultibase = privateKeyMultibase;
|
|
645
|
-
this.verificationMethod = options.verificationMethod || verificationMethod;
|
|
646
|
-
this.useStaticId = options.useStaticId || false;
|
|
647
|
-
this.signer = new Ed25519Signer();
|
|
648
|
-
this.prepareDataForSigning = prepareDataForSigning;
|
|
649
|
-
}
|
|
650
|
-
|
|
651
|
-
async sign(input: SigningInput): Promise<SigningOutput> {
|
|
652
|
-
// Prepare the data for signing using didwebvh-ts's canonical approach
|
|
653
|
-
const dataToSign = await this.prepareDataForSigning(input.document, input.proof);
|
|
654
|
-
|
|
655
|
-
// Sign using our Ed25519 signer
|
|
656
|
-
const signature: Buffer = await this.signer.sign(
|
|
657
|
-
Buffer.from(dataToSign),
|
|
658
|
-
this.privateKeyMultibase
|
|
659
|
-
);
|
|
660
|
-
|
|
661
|
-
// Encode signature as multibase
|
|
662
|
-
const proofValue = multikey.encodeMultibase(signature);
|
|
663
|
-
|
|
664
|
-
return { proofValue };
|
|
665
|
-
}
|
|
666
|
-
|
|
667
|
-
async verify(signature: Uint8Array, message: Uint8Array, publicKey: Uint8Array): Promise<boolean> {
|
|
668
|
-
// Decode the public key to multibase format
|
|
669
|
-
const publicKeyMultibase = multikey.encodePublicKey(publicKey, 'Ed25519');
|
|
670
|
-
|
|
671
|
-
// Verify using our Ed25519 signer
|
|
672
|
-
const messageBuffer: Buffer = Buffer.from(message);
|
|
673
|
-
const signatureBuffer: Buffer = Buffer.from(signature);
|
|
674
|
-
|
|
675
|
-
return this.signer.verify(
|
|
676
|
-
messageBuffer,
|
|
677
|
-
signatureBuffer,
|
|
678
|
-
publicKeyMultibase
|
|
679
|
-
);
|
|
680
|
-
}
|
|
681
|
-
|
|
682
|
-
getVerificationMethodId(): string {
|
|
683
|
-
// didwebvh-ts requires verification method to be a did:key: identifier
|
|
684
|
-
// Extract the multibase key from the verification method
|
|
685
|
-
const publicKeyMultibase = this.verificationMethod?.publicKeyMultibase;
|
|
686
|
-
if (!publicKeyMultibase) {
|
|
687
|
-
throw new Error('Verification method must have publicKeyMultibase');
|
|
688
|
-
}
|
|
689
|
-
// Return as did:key format which didwebvh-ts expects
|
|
690
|
-
return `did:key:${publicKeyMultibase}`;
|
|
691
|
-
}
|
|
692
|
-
}
|
|
693
|
-
|
|
694
|
-
|