@originals/sdk 1.4.3 → 1.5.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.d.ts +6 -0
- package/dist/adapters/FeeOracleMock.js +8 -0
- package/dist/adapters/index.d.ts +4 -0
- package/dist/adapters/index.js +4 -0
- package/dist/adapters/providers/OrdHttpProvider.d.ts +56 -0
- package/dist/adapters/providers/OrdHttpProvider.js +110 -0
- package/dist/adapters/providers/OrdMockProvider.d.ts +70 -0
- package/dist/adapters/providers/OrdMockProvider.js +75 -0
- package/dist/adapters/types.d.ts +71 -0
- package/dist/adapters/types.js +1 -0
- package/dist/bitcoin/BitcoinManager.d.ts +15 -0
- package/dist/bitcoin/BitcoinManager.js +262 -0
- package/dist/bitcoin/BroadcastClient.d.ts +30 -0
- package/dist/bitcoin/BroadcastClient.js +35 -0
- package/dist/bitcoin/OrdinalsClient.d.ts +21 -0
- package/dist/bitcoin/OrdinalsClient.js +105 -0
- package/dist/bitcoin/PSBTBuilder.d.ts +24 -0
- package/dist/bitcoin/PSBTBuilder.js +80 -0
- package/dist/bitcoin/fee-calculation.d.ts +14 -0
- package/dist/bitcoin/fee-calculation.js +31 -0
- package/dist/bitcoin/providers/OrdNodeProvider.d.ts +38 -0
- package/dist/bitcoin/providers/OrdNodeProvider.js +67 -0
- package/dist/bitcoin/providers/OrdinalsProvider.d.ts +33 -0
- package/dist/bitcoin/providers/OrdinalsProvider.js +50 -0
- package/dist/bitcoin/providers/types.d.ts +63 -0
- package/dist/bitcoin/providers/types.js +1 -0
- package/dist/bitcoin/transactions/commit.d.ts +89 -0
- package/dist/bitcoin/transactions/commit.js +311 -0
- package/dist/bitcoin/transactions/index.d.ts +7 -0
- package/dist/bitcoin/transactions/index.js +8 -0
- package/dist/bitcoin/transfer.d.ts +9 -0
- package/dist/bitcoin/transfer.js +26 -0
- package/dist/bitcoin/utxo-selection.d.ts +78 -0
- package/dist/bitcoin/utxo-selection.js +237 -0
- package/dist/bitcoin/utxo.d.ts +26 -0
- package/dist/bitcoin/utxo.js +78 -0
- package/dist/contexts/credentials-v1.json +195 -0
- package/dist/contexts/credentials-v2-examples.json +5 -0
- package/dist/contexts/credentials-v2.json +301 -0
- package/dist/contexts/credentials.json +195 -0
- package/dist/contexts/data-integrity-v2.json +81 -0
- package/dist/contexts/dids.json +57 -0
- package/dist/contexts/ed255192020.json +93 -0
- package/dist/contexts/ordinals-plus.json +23 -0
- package/dist/contexts/originals.json +22 -0
- package/dist/core/OriginalsSDK.d.ts +158 -0
- package/dist/core/OriginalsSDK.js +274 -0
- package/dist/crypto/Multikey.d.ts +30 -0
- package/dist/crypto/Multikey.js +149 -0
- package/dist/crypto/Signer.d.ts +21 -0
- package/dist/crypto/Signer.js +196 -0
- package/dist/crypto/noble-init.d.ts +18 -0
- package/dist/crypto/noble-init.js +106 -0
- package/dist/did/BtcoDidResolver.d.ts +57 -0
- package/dist/did/BtcoDidResolver.js +166 -0
- package/dist/did/DIDManager.d.ts +101 -0
- package/dist/did/DIDManager.js +493 -0
- package/dist/did/Ed25519Verifier.d.ts +30 -0
- package/dist/did/Ed25519Verifier.js +59 -0
- package/dist/did/KeyManager.d.ts +17 -0
- package/dist/did/KeyManager.js +207 -0
- package/dist/did/WebVHManager.d.ts +100 -0
- package/dist/did/WebVHManager.js +312 -0
- package/dist/did/createBtcoDidDocument.d.ts +10 -0
- package/dist/did/createBtcoDidDocument.js +42 -0
- package/dist/did/providers/OrdinalsClientProviderAdapter.d.ts +23 -0
- package/dist/did/providers/OrdinalsClientProviderAdapter.js +51 -0
- package/dist/events/EventEmitter.d.ts +115 -0
- package/dist/events/EventEmitter.js +198 -0
- package/dist/events/index.d.ts +7 -0
- package/dist/events/index.js +6 -0
- package/dist/events/types.d.ts +286 -0
- package/dist/events/types.js +9 -0
- package/dist/examples/basic-usage.d.ts +3 -0
- package/dist/examples/basic-usage.js +62 -0
- package/dist/examples/create-module-original.d.ts +32 -0
- package/dist/examples/create-module-original.js +376 -0
- package/dist/examples/full-lifecycle-flow.d.ts +56 -0
- package/dist/examples/full-lifecycle-flow.js +419 -0
- package/dist/examples/run.d.ts +12 -0
- package/dist/examples/run.js +51 -0
- package/dist/index.d.ts +43 -0
- package/dist/index.js +52 -0
- package/dist/kinds/KindRegistry.d.ts +76 -0
- package/dist/kinds/KindRegistry.js +216 -0
- package/dist/kinds/index.d.ts +33 -0
- package/dist/kinds/index.js +36 -0
- package/dist/kinds/types.d.ts +363 -0
- package/dist/kinds/types.js +25 -0
- package/dist/kinds/validators/AgentValidator.d.ts +14 -0
- package/dist/kinds/validators/AgentValidator.js +155 -0
- package/dist/kinds/validators/AppValidator.d.ts +14 -0
- package/dist/kinds/validators/AppValidator.js +135 -0
- package/dist/kinds/validators/DatasetValidator.d.ts +14 -0
- package/dist/kinds/validators/DatasetValidator.js +148 -0
- package/dist/kinds/validators/DocumentValidator.d.ts +14 -0
- package/dist/kinds/validators/DocumentValidator.js +180 -0
- package/dist/kinds/validators/MediaValidator.d.ts +14 -0
- package/dist/kinds/validators/MediaValidator.js +172 -0
- package/dist/kinds/validators/ModuleValidator.d.ts +14 -0
- package/dist/kinds/validators/ModuleValidator.js +140 -0
- package/dist/kinds/validators/base.d.ts +96 -0
- package/dist/kinds/validators/base.js +218 -0
- package/dist/kinds/validators/index.d.ts +10 -0
- package/dist/kinds/validators/index.js +10 -0
- package/dist/lifecycle/BatchOperations.d.ts +147 -0
- package/dist/lifecycle/BatchOperations.js +251 -0
- package/dist/lifecycle/LifecycleManager.d.ts +362 -0
- package/dist/lifecycle/LifecycleManager.js +1692 -0
- package/dist/lifecycle/OriginalsAsset.d.ts +164 -0
- package/dist/lifecycle/OriginalsAsset.js +380 -0
- package/dist/lifecycle/ProvenanceQuery.d.ts +126 -0
- package/dist/lifecycle/ProvenanceQuery.js +220 -0
- package/dist/lifecycle/ResourceVersioning.d.ts +73 -0
- package/dist/lifecycle/ResourceVersioning.js +127 -0
- package/dist/migration/MigrationManager.d.ts +86 -0
- package/dist/migration/MigrationManager.js +412 -0
- package/dist/migration/audit/AuditLogger.d.ts +51 -0
- package/dist/migration/audit/AuditLogger.js +156 -0
- package/dist/migration/checkpoint/CheckpointManager.d.ts +31 -0
- package/dist/migration/checkpoint/CheckpointManager.js +96 -0
- package/dist/migration/checkpoint/CheckpointStorage.d.ts +26 -0
- package/dist/migration/checkpoint/CheckpointStorage.js +89 -0
- package/dist/migration/index.d.ts +22 -0
- package/dist/migration/index.js +27 -0
- package/dist/migration/operations/BaseMigration.d.ts +48 -0
- package/dist/migration/operations/BaseMigration.js +83 -0
- package/dist/migration/operations/PeerToBtcoMigration.d.ts +25 -0
- package/dist/migration/operations/PeerToBtcoMigration.js +67 -0
- package/dist/migration/operations/PeerToWebvhMigration.d.ts +19 -0
- package/dist/migration/operations/PeerToWebvhMigration.js +46 -0
- package/dist/migration/operations/WebvhToBtcoMigration.d.ts +25 -0
- package/dist/migration/operations/WebvhToBtcoMigration.js +67 -0
- package/dist/migration/rollback/RollbackManager.d.ts +29 -0
- package/dist/migration/rollback/RollbackManager.js +146 -0
- package/dist/migration/state/StateMachine.d.ts +25 -0
- package/dist/migration/state/StateMachine.js +76 -0
- package/dist/migration/state/StateTracker.d.ts +36 -0
- package/dist/migration/state/StateTracker.js +123 -0
- package/dist/migration/types.d.ts +306 -0
- package/dist/migration/types.js +33 -0
- package/dist/migration/validation/BitcoinValidator.d.ts +13 -0
- package/dist/migration/validation/BitcoinValidator.js +83 -0
- package/dist/migration/validation/CredentialValidator.d.ts +13 -0
- package/dist/migration/validation/CredentialValidator.js +46 -0
- package/dist/migration/validation/DIDCompatibilityValidator.d.ts +16 -0
- package/dist/migration/validation/DIDCompatibilityValidator.js +127 -0
- package/dist/migration/validation/LifecycleValidator.d.ts +10 -0
- package/dist/migration/validation/LifecycleValidator.js +52 -0
- package/dist/migration/validation/StorageValidator.d.ts +10 -0
- package/dist/migration/validation/StorageValidator.js +65 -0
- package/dist/migration/validation/ValidationPipeline.d.ts +29 -0
- package/dist/migration/validation/ValidationPipeline.js +180 -0
- package/dist/resources/ResourceManager.d.ts +231 -0
- package/dist/resources/ResourceManager.js +573 -0
- package/dist/resources/index.d.ts +11 -0
- package/dist/resources/index.js +10 -0
- package/dist/resources/types.d.ts +93 -0
- package/dist/resources/types.js +80 -0
- package/dist/storage/LocalStorageAdapter.d.ts +11 -0
- package/dist/storage/LocalStorageAdapter.js +53 -0
- package/dist/storage/MemoryStorageAdapter.d.ts +6 -0
- package/dist/storage/MemoryStorageAdapter.js +21 -0
- package/dist/storage/StorageAdapter.d.ts +16 -0
- package/dist/storage/StorageAdapter.js +1 -0
- package/dist/storage/index.d.ts +2 -0
- package/dist/storage/index.js +2 -0
- package/dist/types/bitcoin.d.ts +84 -0
- package/dist/types/bitcoin.js +1 -0
- package/dist/types/common.d.ts +82 -0
- package/dist/types/common.js +1 -0
- package/dist/types/credentials.d.ts +75 -0
- package/dist/types/credentials.js +1 -0
- package/dist/types/did.d.ts +26 -0
- package/dist/types/did.js +1 -0
- package/dist/types/index.d.ts +5 -0
- package/dist/types/index.js +5 -0
- package/dist/types/network.d.ts +78 -0
- package/dist/types/network.js +145 -0
- package/dist/utils/EventLogger.d.ts +71 -0
- package/dist/utils/EventLogger.js +232 -0
- package/dist/utils/Logger.d.ts +106 -0
- package/dist/utils/Logger.js +257 -0
- package/dist/utils/MetricsCollector.d.ts +110 -0
- package/dist/utils/MetricsCollector.js +264 -0
- package/dist/utils/bitcoin-address.d.ts +38 -0
- package/dist/utils/bitcoin-address.js +113 -0
- package/dist/utils/cbor.d.ts +2 -0
- package/dist/utils/cbor.js +9 -0
- package/dist/utils/encoding.d.ts +37 -0
- package/dist/utils/encoding.js +120 -0
- package/dist/utils/hash.d.ts +1 -0
- package/dist/utils/hash.js +5 -0
- package/dist/utils/retry.d.ts +10 -0
- package/dist/utils/retry.js +35 -0
- package/dist/utils/satoshi-validation.d.ts +60 -0
- package/dist/utils/satoshi-validation.js +156 -0
- package/dist/utils/serialization.d.ts +14 -0
- package/dist/utils/serialization.js +76 -0
- package/dist/utils/telemetry.d.ts +17 -0
- package/dist/utils/telemetry.js +24 -0
- package/dist/utils/validation.d.ts +5 -0
- package/dist/utils/validation.js +98 -0
- package/dist/vc/CredentialManager.d.ts +329 -0
- package/dist/vc/CredentialManager.js +615 -0
- package/dist/vc/Issuer.d.ts +27 -0
- package/dist/vc/Issuer.js +70 -0
- package/dist/vc/Verifier.d.ts +16 -0
- package/dist/vc/Verifier.js +50 -0
- package/dist/vc/cryptosuites/bbs.d.ts +44 -0
- package/dist/vc/cryptosuites/bbs.js +213 -0
- package/dist/vc/cryptosuites/bbsSimple.d.ts +9 -0
- package/dist/vc/cryptosuites/bbsSimple.js +12 -0
- package/dist/vc/cryptosuites/eddsa.d.ts +30 -0
- package/dist/vc/cryptosuites/eddsa.js +81 -0
- package/dist/vc/documentLoader.d.ts +16 -0
- package/dist/vc/documentLoader.js +59 -0
- package/dist/vc/proofs/data-integrity.d.ts +21 -0
- package/dist/vc/proofs/data-integrity.js +15 -0
- package/dist/vc/utils/jsonld.d.ts +2 -0
- package/dist/vc/utils/jsonld.js +15 -0
- package/package.json +2 -1
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enhanced Logger for Originals SDK
|
|
3
|
+
*
|
|
4
|
+
* Features:
|
|
5
|
+
* - Multiple log levels (debug, info, warn, error)
|
|
6
|
+
* - Child loggers with hierarchical context
|
|
7
|
+
* - Performance timing with startTimer
|
|
8
|
+
* - Multiple output destinations
|
|
9
|
+
* - Data sanitization for sensitive information
|
|
10
|
+
* - Async-safe operations
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Console log output implementation
|
|
14
|
+
*/
|
|
15
|
+
export class ConsoleLogOutput {
|
|
16
|
+
write(entry) {
|
|
17
|
+
const timestamp = entry.timestamp;
|
|
18
|
+
const level = entry.level.toUpperCase().padEnd(5);
|
|
19
|
+
const context = entry.context;
|
|
20
|
+
const message = entry.message;
|
|
21
|
+
const durationStr = entry.duration !== undefined ? ` (${entry.duration.toFixed(2)}ms)` : '';
|
|
22
|
+
const dataStr = entry.data ? ` ${JSON.stringify(entry.data)}` : '';
|
|
23
|
+
const logMessage = `[${timestamp}] ${level} [${context}] ${message}${durationStr}${dataStr}`;
|
|
24
|
+
switch (entry.level) {
|
|
25
|
+
case 'debug':
|
|
26
|
+
console.debug(logMessage);
|
|
27
|
+
break;
|
|
28
|
+
case 'info':
|
|
29
|
+
console.info(logMessage);
|
|
30
|
+
break;
|
|
31
|
+
case 'warn':
|
|
32
|
+
console.warn(logMessage);
|
|
33
|
+
break;
|
|
34
|
+
case 'error':
|
|
35
|
+
console.error(logMessage);
|
|
36
|
+
break;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* File log output implementation (async)
|
|
42
|
+
*/
|
|
43
|
+
export class FileLogOutput {
|
|
44
|
+
constructor(filePath) {
|
|
45
|
+
this.filePath = filePath;
|
|
46
|
+
this.buffer = [];
|
|
47
|
+
this.flushTimeout = null;
|
|
48
|
+
this.flushInterval = 1000; // Flush every 1 second
|
|
49
|
+
}
|
|
50
|
+
async write(entry) {
|
|
51
|
+
// Format as JSON line
|
|
52
|
+
const line = JSON.stringify(entry) + '\n';
|
|
53
|
+
this.buffer.push(line);
|
|
54
|
+
// Schedule flush
|
|
55
|
+
if (!this.flushTimeout) {
|
|
56
|
+
this.flushTimeout = setTimeout(() => this.flush(), this.flushInterval);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
async flush() {
|
|
60
|
+
if (this.buffer.length === 0) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
const lines = this.buffer.join('');
|
|
64
|
+
this.buffer = [];
|
|
65
|
+
this.flushTimeout = null;
|
|
66
|
+
try {
|
|
67
|
+
// Use Bun's file API for efficient file writing
|
|
68
|
+
const file = Bun.file(this.filePath);
|
|
69
|
+
const exists = await file.exists();
|
|
70
|
+
if (exists) {
|
|
71
|
+
// Append to existing file
|
|
72
|
+
const content = await file.text();
|
|
73
|
+
await Bun.write(this.filePath, content + lines);
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
// Create new file
|
|
77
|
+
await Bun.write(this.filePath, lines);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
catch (err) {
|
|
81
|
+
// Fallback to console on file write error
|
|
82
|
+
console.error('Failed to write log file:', err);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Main Logger class
|
|
88
|
+
*/
|
|
89
|
+
export class Logger {
|
|
90
|
+
constructor(context, config) {
|
|
91
|
+
this.context = context;
|
|
92
|
+
this.outputs = [];
|
|
93
|
+
this.minLevel = config.logging?.level || 'info';
|
|
94
|
+
this.includeTimestamps = config.logging?.includeTimestamps !== false;
|
|
95
|
+
this.includeContext = config.logging?.includeContext !== false;
|
|
96
|
+
this.sanitizeLogs = config.logging?.sanitizeLogs !== false;
|
|
97
|
+
// Set up default outputs
|
|
98
|
+
if (config.logging?.outputs && config.logging.outputs.length > 0) {
|
|
99
|
+
this.outputs = [...config.logging.outputs];
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
// Default to console output
|
|
103
|
+
this.outputs = [new ConsoleLogOutput()];
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Log a debug message
|
|
108
|
+
*/
|
|
109
|
+
debug(message, data) {
|
|
110
|
+
this.log('debug', message, data);
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Log an info message
|
|
114
|
+
*/
|
|
115
|
+
info(message, data) {
|
|
116
|
+
this.log('info', message, data);
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Log a warning message
|
|
120
|
+
*/
|
|
121
|
+
warn(message, data) {
|
|
122
|
+
this.log('warn', message, data);
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Log an error message
|
|
126
|
+
*/
|
|
127
|
+
error(message, error, data) {
|
|
128
|
+
const errorData = error ? {
|
|
129
|
+
...data,
|
|
130
|
+
error: {
|
|
131
|
+
name: error.name,
|
|
132
|
+
message: error.message,
|
|
133
|
+
stack: error.stack
|
|
134
|
+
}
|
|
135
|
+
} : data;
|
|
136
|
+
this.log('error', message, errorData);
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Start a timer for performance tracking
|
|
140
|
+
* Returns a function that stops the timer and logs the duration
|
|
141
|
+
*/
|
|
142
|
+
startTimer(operation) {
|
|
143
|
+
const startTime = performance.now();
|
|
144
|
+
return () => {
|
|
145
|
+
const duration = performance.now() - startTime;
|
|
146
|
+
this.log('debug', `${operation} completed`, undefined, duration);
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Create a child logger with nested context
|
|
151
|
+
*/
|
|
152
|
+
child(childContext) {
|
|
153
|
+
const newLogger = Object.create(Logger.prototype);
|
|
154
|
+
newLogger.context = `${this.context}:${childContext}`;
|
|
155
|
+
newLogger.outputs = this.outputs;
|
|
156
|
+
newLogger.minLevel = this.minLevel;
|
|
157
|
+
newLogger.includeTimestamps = this.includeTimestamps;
|
|
158
|
+
newLogger.includeContext = this.includeContext;
|
|
159
|
+
newLogger.sanitizeLogs = this.sanitizeLogs;
|
|
160
|
+
return newLogger;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Set a single output (replaces existing outputs)
|
|
164
|
+
*/
|
|
165
|
+
setOutput(output) {
|
|
166
|
+
this.outputs = [output];
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Add an output to the existing outputs
|
|
170
|
+
*/
|
|
171
|
+
addOutput(output) {
|
|
172
|
+
this.outputs.push(output);
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Internal log method
|
|
176
|
+
*/
|
|
177
|
+
log(level, message, data, duration) {
|
|
178
|
+
// Check if we should log this level
|
|
179
|
+
if (Logger.LEVEL_PRIORITY[level] < Logger.LEVEL_PRIORITY[this.minLevel]) {
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
// Sanitize data if needed
|
|
183
|
+
const sanitizedData = this.sanitizeLogs ? this.sanitize(data) : data;
|
|
184
|
+
// Create log entry
|
|
185
|
+
const entry = {
|
|
186
|
+
timestamp: this.includeTimestamps ? new Date().toISOString() : '',
|
|
187
|
+
level,
|
|
188
|
+
context: this.includeContext ? this.context : '',
|
|
189
|
+
message,
|
|
190
|
+
data: sanitizedData,
|
|
191
|
+
duration
|
|
192
|
+
};
|
|
193
|
+
// Write to all outputs (fire and forget for async outputs)
|
|
194
|
+
for (const output of this.outputs) {
|
|
195
|
+
try {
|
|
196
|
+
const result = output.write(entry);
|
|
197
|
+
// If result is a promise, don't await it (non-blocking)
|
|
198
|
+
if (result instanceof Promise) {
|
|
199
|
+
result.catch(err => {
|
|
200
|
+
// Silently fail for async outputs to avoid blocking
|
|
201
|
+
if (typeof console !== 'undefined' && console.error) {
|
|
202
|
+
console.error('Log output error:', err);
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
catch (err) {
|
|
208
|
+
// Continue even if one output fails
|
|
209
|
+
if (typeof console !== 'undefined' && console.error) {
|
|
210
|
+
console.error('Log output error:', err);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Sanitize sensitive data from logs
|
|
217
|
+
*/
|
|
218
|
+
sanitize(data) {
|
|
219
|
+
if (!data) {
|
|
220
|
+
return data;
|
|
221
|
+
}
|
|
222
|
+
// Handle arrays
|
|
223
|
+
if (Array.isArray(data)) {
|
|
224
|
+
return data.map(item => this.sanitize(item));
|
|
225
|
+
}
|
|
226
|
+
// Handle objects
|
|
227
|
+
if (typeof data === 'object') {
|
|
228
|
+
const sanitized = {};
|
|
229
|
+
for (const [key, value] of Object.entries(data)) {
|
|
230
|
+
const lowerKey = key.toLowerCase();
|
|
231
|
+
// Sanitize sensitive keys
|
|
232
|
+
if (lowerKey.includes('private') ||
|
|
233
|
+
lowerKey.includes('key') ||
|
|
234
|
+
lowerKey.includes('secret') ||
|
|
235
|
+
lowerKey.includes('password') ||
|
|
236
|
+
lowerKey.includes('token') ||
|
|
237
|
+
lowerKey.includes('credential')) {
|
|
238
|
+
sanitized[key] = '[REDACTED]';
|
|
239
|
+
}
|
|
240
|
+
else {
|
|
241
|
+
// Recursively sanitize nested objects
|
|
242
|
+
sanitized[key] = this.sanitize(value);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
return sanitized;
|
|
246
|
+
}
|
|
247
|
+
// Return primitive values as-is
|
|
248
|
+
return data;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
// Log level priorities
|
|
252
|
+
Logger.LEVEL_PRIORITY = {
|
|
253
|
+
debug: 0,
|
|
254
|
+
info: 1,
|
|
255
|
+
warn: 2,
|
|
256
|
+
error: 3
|
|
257
|
+
};
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Metrics Collector for Originals SDK
|
|
3
|
+
*
|
|
4
|
+
* Features:
|
|
5
|
+
* - Track operation counts and performance
|
|
6
|
+
* - Asset lifecycle metrics (created, migrated, transferred)
|
|
7
|
+
* - Error tracking by error code
|
|
8
|
+
* - Cache statistics (optional)
|
|
9
|
+
* - Export in JSON and Prometheus formats
|
|
10
|
+
* - Memory-efficient storage
|
|
11
|
+
*/
|
|
12
|
+
import type { LayerType } from '../types';
|
|
13
|
+
/**
|
|
14
|
+
* Operation-specific metrics
|
|
15
|
+
*/
|
|
16
|
+
export interface OperationMetrics {
|
|
17
|
+
count: number;
|
|
18
|
+
totalTime: number;
|
|
19
|
+
avgTime: number;
|
|
20
|
+
minTime: number;
|
|
21
|
+
maxTime: number;
|
|
22
|
+
errorCount: number;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Complete metrics snapshot
|
|
26
|
+
*/
|
|
27
|
+
export interface Metrics {
|
|
28
|
+
assetsCreated: number;
|
|
29
|
+
assetsMigrated: Record<string, number>;
|
|
30
|
+
assetsTransferred: number;
|
|
31
|
+
operationTimes: Record<string, OperationMetrics>;
|
|
32
|
+
errors: Record<string, number>;
|
|
33
|
+
cacheStats?: {
|
|
34
|
+
hits: number;
|
|
35
|
+
misses: number;
|
|
36
|
+
hitRate: number;
|
|
37
|
+
};
|
|
38
|
+
startTime: string;
|
|
39
|
+
uptime: number;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* MetricsCollector class
|
|
43
|
+
*/
|
|
44
|
+
export declare class MetricsCollector {
|
|
45
|
+
private assetsCreatedCount;
|
|
46
|
+
private assetsMigratedMap;
|
|
47
|
+
private assetsTransferredCount;
|
|
48
|
+
private operationMetrics;
|
|
49
|
+
private errorCounts;
|
|
50
|
+
private cacheHits;
|
|
51
|
+
private cacheMisses;
|
|
52
|
+
private readonly startTime;
|
|
53
|
+
constructor();
|
|
54
|
+
/**
|
|
55
|
+
* Record an operation with timing and success status
|
|
56
|
+
*/
|
|
57
|
+
recordOperation(operation: string, duration: number, success: boolean): void;
|
|
58
|
+
/**
|
|
59
|
+
* Start tracking an operation, returns completion function
|
|
60
|
+
*/
|
|
61
|
+
startOperation(operation: string): () => void;
|
|
62
|
+
/**
|
|
63
|
+
* Record an asset creation
|
|
64
|
+
*/
|
|
65
|
+
recordAssetCreated(): void;
|
|
66
|
+
/**
|
|
67
|
+
* Record an asset migration between layers
|
|
68
|
+
*/
|
|
69
|
+
recordMigration(from: LayerType, to: LayerType): void;
|
|
70
|
+
/**
|
|
71
|
+
* Record an asset transfer
|
|
72
|
+
*/
|
|
73
|
+
recordTransfer(): void;
|
|
74
|
+
/**
|
|
75
|
+
* Record an error by error code
|
|
76
|
+
*/
|
|
77
|
+
recordError(code: string, operation?: string): void;
|
|
78
|
+
/**
|
|
79
|
+
* Record a cache hit
|
|
80
|
+
*/
|
|
81
|
+
recordCacheHit(): void;
|
|
82
|
+
/**
|
|
83
|
+
* Record a cache miss
|
|
84
|
+
*/
|
|
85
|
+
recordCacheMiss(): void;
|
|
86
|
+
/**
|
|
87
|
+
* Get a snapshot of all metrics
|
|
88
|
+
*/
|
|
89
|
+
getMetrics(): Metrics;
|
|
90
|
+
/**
|
|
91
|
+
* Get metrics for a specific operation
|
|
92
|
+
*/
|
|
93
|
+
getOperationMetrics(operation: string): OperationMetrics | null;
|
|
94
|
+
/**
|
|
95
|
+
* Reset all metrics
|
|
96
|
+
*/
|
|
97
|
+
reset(): void;
|
|
98
|
+
/**
|
|
99
|
+
* Export metrics in the specified format
|
|
100
|
+
*/
|
|
101
|
+
export(format: 'json' | 'prometheus'): string;
|
|
102
|
+
/**
|
|
103
|
+
* Export metrics as JSON
|
|
104
|
+
*/
|
|
105
|
+
private exportJSON;
|
|
106
|
+
/**
|
|
107
|
+
* Export metrics in Prometheus format
|
|
108
|
+
*/
|
|
109
|
+
private exportPrometheus;
|
|
110
|
+
}
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Metrics Collector for Originals SDK
|
|
3
|
+
*
|
|
4
|
+
* Features:
|
|
5
|
+
* - Track operation counts and performance
|
|
6
|
+
* - Asset lifecycle metrics (created, migrated, transferred)
|
|
7
|
+
* - Error tracking by error code
|
|
8
|
+
* - Cache statistics (optional)
|
|
9
|
+
* - Export in JSON and Prometheus formats
|
|
10
|
+
* - Memory-efficient storage
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* MetricsCollector class
|
|
14
|
+
*/
|
|
15
|
+
export class MetricsCollector {
|
|
16
|
+
constructor() {
|
|
17
|
+
this.assetsCreatedCount = 0;
|
|
18
|
+
this.assetsMigratedMap = new Map();
|
|
19
|
+
this.assetsTransferredCount = 0;
|
|
20
|
+
this.operationMetrics = new Map();
|
|
21
|
+
this.errorCounts = new Map();
|
|
22
|
+
this.cacheHits = 0;
|
|
23
|
+
this.cacheMisses = 0;
|
|
24
|
+
this.startTime = new Date().toISOString();
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Record an operation with timing and success status
|
|
28
|
+
*/
|
|
29
|
+
recordOperation(operation, duration, success) {
|
|
30
|
+
if (!this.operationMetrics.has(operation)) {
|
|
31
|
+
this.operationMetrics.set(operation, {
|
|
32
|
+
count: 0,
|
|
33
|
+
totalTime: 0,
|
|
34
|
+
minTime: Infinity,
|
|
35
|
+
maxTime: -Infinity,
|
|
36
|
+
errorCount: 0
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
const metrics = this.operationMetrics.get(operation);
|
|
40
|
+
metrics.count++;
|
|
41
|
+
metrics.totalTime += duration;
|
|
42
|
+
metrics.minTime = Math.min(metrics.minTime, duration);
|
|
43
|
+
metrics.maxTime = Math.max(metrics.maxTime, duration);
|
|
44
|
+
if (!success) {
|
|
45
|
+
metrics.errorCount++;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Start tracking an operation, returns completion function
|
|
50
|
+
*/
|
|
51
|
+
startOperation(operation) {
|
|
52
|
+
const startTime = performance.now();
|
|
53
|
+
return (success = true) => {
|
|
54
|
+
const duration = performance.now() - startTime;
|
|
55
|
+
this.recordOperation(operation, duration, success);
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Record an asset creation
|
|
60
|
+
*/
|
|
61
|
+
recordAssetCreated() {
|
|
62
|
+
this.assetsCreatedCount++;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Record an asset migration between layers
|
|
66
|
+
*/
|
|
67
|
+
recordMigration(from, to) {
|
|
68
|
+
// Create transition key
|
|
69
|
+
const fromShort = from.split(':')[1]; // "peer", "webvh", "btco"
|
|
70
|
+
const toShort = to.split(':')[1];
|
|
71
|
+
const transitionKey = `${fromShort}→${toShort}`;
|
|
72
|
+
const current = this.assetsMigratedMap.get(transitionKey) || 0;
|
|
73
|
+
this.assetsMigratedMap.set(transitionKey, current + 1);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Record an asset transfer
|
|
77
|
+
*/
|
|
78
|
+
recordTransfer() {
|
|
79
|
+
this.assetsTransferredCount++;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Record an error by error code
|
|
83
|
+
*/
|
|
84
|
+
recordError(code, operation) {
|
|
85
|
+
// Track error by code
|
|
86
|
+
const current = this.errorCounts.get(code) || 0;
|
|
87
|
+
this.errorCounts.set(code, current + 1);
|
|
88
|
+
// If operation is provided, increment its error count
|
|
89
|
+
if (operation && this.operationMetrics.has(operation)) {
|
|
90
|
+
this.operationMetrics.get(operation).errorCount++;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Record a cache hit
|
|
95
|
+
*/
|
|
96
|
+
recordCacheHit() {
|
|
97
|
+
this.cacheHits++;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Record a cache miss
|
|
101
|
+
*/
|
|
102
|
+
recordCacheMiss() {
|
|
103
|
+
this.cacheMisses++;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Get a snapshot of all metrics
|
|
107
|
+
*/
|
|
108
|
+
getMetrics() {
|
|
109
|
+
const operationTimes = {};
|
|
110
|
+
for (const [operation, metrics] of this.operationMetrics.entries()) {
|
|
111
|
+
operationTimes[operation] = {
|
|
112
|
+
count: metrics.count,
|
|
113
|
+
totalTime: metrics.totalTime,
|
|
114
|
+
avgTime: metrics.count > 0 ? metrics.totalTime / metrics.count : 0,
|
|
115
|
+
minTime: metrics.minTime === Infinity ? 0 : metrics.minTime,
|
|
116
|
+
maxTime: metrics.maxTime === -Infinity ? 0 : metrics.maxTime,
|
|
117
|
+
errorCount: metrics.errorCount
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
const assetsMigrated = {};
|
|
121
|
+
for (const [key, count] of this.assetsMigratedMap.entries()) {
|
|
122
|
+
assetsMigrated[key] = count;
|
|
123
|
+
}
|
|
124
|
+
const errors = {};
|
|
125
|
+
for (const [code, count] of this.errorCounts.entries()) {
|
|
126
|
+
errors[code] = count;
|
|
127
|
+
}
|
|
128
|
+
const totalCacheRequests = this.cacheHits + this.cacheMisses;
|
|
129
|
+
const cacheStats = totalCacheRequests > 0 ? {
|
|
130
|
+
hits: this.cacheHits,
|
|
131
|
+
misses: this.cacheMisses,
|
|
132
|
+
hitRate: this.cacheHits / totalCacheRequests
|
|
133
|
+
} : undefined;
|
|
134
|
+
return {
|
|
135
|
+
assetsCreated: this.assetsCreatedCount,
|
|
136
|
+
assetsMigrated,
|
|
137
|
+
assetsTransferred: this.assetsTransferredCount,
|
|
138
|
+
operationTimes,
|
|
139
|
+
errors,
|
|
140
|
+
cacheStats,
|
|
141
|
+
startTime: this.startTime,
|
|
142
|
+
uptime: Date.now() - new Date(this.startTime).getTime()
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Get metrics for a specific operation
|
|
147
|
+
*/
|
|
148
|
+
getOperationMetrics(operation) {
|
|
149
|
+
const metrics = this.operationMetrics.get(operation);
|
|
150
|
+
if (!metrics) {
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
return {
|
|
154
|
+
count: metrics.count,
|
|
155
|
+
totalTime: metrics.totalTime,
|
|
156
|
+
avgTime: metrics.count > 0 ? metrics.totalTime / metrics.count : 0,
|
|
157
|
+
minTime: metrics.minTime === Infinity ? 0 : metrics.minTime,
|
|
158
|
+
maxTime: metrics.maxTime === -Infinity ? 0 : metrics.maxTime,
|
|
159
|
+
errorCount: metrics.errorCount
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Reset all metrics
|
|
164
|
+
*/
|
|
165
|
+
reset() {
|
|
166
|
+
this.assetsCreatedCount = 0;
|
|
167
|
+
this.assetsMigratedMap.clear();
|
|
168
|
+
this.assetsTransferredCount = 0;
|
|
169
|
+
this.operationMetrics.clear();
|
|
170
|
+
this.errorCounts.clear();
|
|
171
|
+
this.cacheHits = 0;
|
|
172
|
+
this.cacheMisses = 0;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Export metrics in the specified format
|
|
176
|
+
*/
|
|
177
|
+
export(format) {
|
|
178
|
+
if (format === 'json') {
|
|
179
|
+
return this.exportJSON();
|
|
180
|
+
}
|
|
181
|
+
else if (format === 'prometheus') {
|
|
182
|
+
return this.exportPrometheus();
|
|
183
|
+
}
|
|
184
|
+
throw new Error(`Unsupported export format: ${format}`);
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Export metrics as JSON
|
|
188
|
+
*/
|
|
189
|
+
exportJSON() {
|
|
190
|
+
return JSON.stringify(this.getMetrics(), null, 2);
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Export metrics in Prometheus format
|
|
194
|
+
*/
|
|
195
|
+
exportPrometheus() {
|
|
196
|
+
const lines = [];
|
|
197
|
+
const metrics = this.getMetrics();
|
|
198
|
+
// Asset metrics
|
|
199
|
+
lines.push('# HELP originals_assets_created_total Total number of assets created');
|
|
200
|
+
lines.push('# TYPE originals_assets_created_total counter');
|
|
201
|
+
lines.push(`originals_assets_created_total ${metrics.assetsCreated}`);
|
|
202
|
+
lines.push('');
|
|
203
|
+
lines.push('# HELP originals_assets_transferred_total Total number of assets transferred');
|
|
204
|
+
lines.push('# TYPE originals_assets_transferred_total counter');
|
|
205
|
+
lines.push(`originals_assets_transferred_total ${metrics.assetsTransferred}`);
|
|
206
|
+
lines.push('');
|
|
207
|
+
// Migration metrics
|
|
208
|
+
lines.push('# HELP originals_assets_migrated_total Total number of assets migrated by layer transition');
|
|
209
|
+
lines.push('# TYPE originals_assets_migrated_total counter');
|
|
210
|
+
for (const [transition, count] of Object.entries(metrics.assetsMigrated)) {
|
|
211
|
+
const [from, to] = transition.split('→');
|
|
212
|
+
lines.push(`originals_assets_migrated_total{from="${from}",to="${to}"} ${count}`);
|
|
213
|
+
}
|
|
214
|
+
lines.push('');
|
|
215
|
+
// Operation metrics
|
|
216
|
+
for (const [operation, opMetrics] of Object.entries(metrics.operationTimes)) {
|
|
217
|
+
const safeOpName = operation.replace(/[^a-zA-Z0-9_]/g, '_');
|
|
218
|
+
lines.push(`# HELP originals_operation_${safeOpName}_total Total number of ${operation} operations`);
|
|
219
|
+
lines.push(`# TYPE originals_operation_${safeOpName}_total counter`);
|
|
220
|
+
lines.push(`originals_operation_${safeOpName}_total ${opMetrics.count}`);
|
|
221
|
+
lines.push('');
|
|
222
|
+
lines.push(`# HELP originals_operation_${safeOpName}_duration_milliseconds Duration of ${operation} operations`);
|
|
223
|
+
lines.push(`# TYPE originals_operation_${safeOpName}_duration_milliseconds summary`);
|
|
224
|
+
lines.push(`originals_operation_${safeOpName}_duration_milliseconds{quantile="0.0"} ${opMetrics.minTime}`);
|
|
225
|
+
lines.push(`originals_operation_${safeOpName}_duration_milliseconds{quantile="0.5"} ${opMetrics.avgTime}`);
|
|
226
|
+
lines.push(`originals_operation_${safeOpName}_duration_milliseconds{quantile="1.0"} ${opMetrics.maxTime}`);
|
|
227
|
+
lines.push(`originals_operation_${safeOpName}_duration_milliseconds_sum ${opMetrics.totalTime}`);
|
|
228
|
+
lines.push(`originals_operation_${safeOpName}_duration_milliseconds_count ${opMetrics.count}`);
|
|
229
|
+
lines.push('');
|
|
230
|
+
lines.push(`# HELP originals_operation_${safeOpName}_errors_total Total number of errors in ${operation} operations`);
|
|
231
|
+
lines.push(`# TYPE originals_operation_${safeOpName}_errors_total counter`);
|
|
232
|
+
lines.push(`originals_operation_${safeOpName}_errors_total ${opMetrics.errorCount}`);
|
|
233
|
+
lines.push('');
|
|
234
|
+
}
|
|
235
|
+
// Error metrics
|
|
236
|
+
lines.push('# HELP originals_errors_total Total number of errors by code');
|
|
237
|
+
lines.push('# TYPE originals_errors_total counter');
|
|
238
|
+
for (const [code, count] of Object.entries(metrics.errors)) {
|
|
239
|
+
lines.push(`originals_errors_total{code="${code}"} ${count}`);
|
|
240
|
+
}
|
|
241
|
+
lines.push('');
|
|
242
|
+
// Cache metrics
|
|
243
|
+
if (metrics.cacheStats) {
|
|
244
|
+
lines.push('# HELP originals_cache_hits_total Total number of cache hits');
|
|
245
|
+
lines.push('# TYPE originals_cache_hits_total counter');
|
|
246
|
+
lines.push(`originals_cache_hits_total ${metrics.cacheStats.hits}`);
|
|
247
|
+
lines.push('');
|
|
248
|
+
lines.push('# HELP originals_cache_misses_total Total number of cache misses');
|
|
249
|
+
lines.push('# TYPE originals_cache_misses_total counter');
|
|
250
|
+
lines.push(`originals_cache_misses_total ${metrics.cacheStats.misses}`);
|
|
251
|
+
lines.push('');
|
|
252
|
+
lines.push('# HELP originals_cache_hit_rate Cache hit rate');
|
|
253
|
+
lines.push('# TYPE originals_cache_hit_rate gauge');
|
|
254
|
+
lines.push(`originals_cache_hit_rate ${metrics.cacheStats.hitRate}`);
|
|
255
|
+
lines.push('');
|
|
256
|
+
}
|
|
257
|
+
// System metrics
|
|
258
|
+
lines.push('# HELP originals_uptime_milliseconds SDK uptime in milliseconds');
|
|
259
|
+
lines.push('# TYPE originals_uptime_milliseconds gauge');
|
|
260
|
+
lines.push(`originals_uptime_milliseconds ${metrics.uptime}`);
|
|
261
|
+
lines.push('');
|
|
262
|
+
return lines.join('\n');
|
|
263
|
+
}
|
|
264
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bitcoin network types supported by the validation
|
|
3
|
+
*/
|
|
4
|
+
export type BitcoinNetwork = 'mainnet' | 'regtest' | 'signet';
|
|
5
|
+
/**
|
|
6
|
+
* Validates a Bitcoin address format and checksum for the given network.
|
|
7
|
+
*
|
|
8
|
+
* This function uses bitcoinjs-lib's address.toOutputScript() which performs:
|
|
9
|
+
* - Format validation (bech32, base58check)
|
|
10
|
+
* - Checksum verification
|
|
11
|
+
* - Network prefix validation
|
|
12
|
+
*
|
|
13
|
+
* @param address - The Bitcoin address to validate
|
|
14
|
+
* @param network - The network to validate against ('mainnet', 'regtest', 'signet')
|
|
15
|
+
* @returns true if the address is valid for the network
|
|
16
|
+
* @throws Error with descriptive message if validation fails
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```typescript
|
|
20
|
+
* // Valid mainnet address
|
|
21
|
+
* validateBitcoinAddress('bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq', 'mainnet'); // true
|
|
22
|
+
*
|
|
23
|
+
* // Invalid checksum
|
|
24
|
+
* validateBitcoinAddress('bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdd', 'mainnet'); // throws
|
|
25
|
+
*
|
|
26
|
+
* // Wrong network
|
|
27
|
+
* validateBitcoinAddress('bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq', 'testnet'); // throws
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export declare function validateBitcoinAddress(address: string, network: BitcoinNetwork): boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Validates a Bitcoin address and returns a boolean instead of throwing
|
|
33
|
+
*
|
|
34
|
+
* @param address - The Bitcoin address to validate
|
|
35
|
+
* @param network - The network to validate against
|
|
36
|
+
* @returns true if valid, false otherwise
|
|
37
|
+
*/
|
|
38
|
+
export declare function isValidBitcoinAddress(address: string, network: BitcoinNetwork): boolean;
|