@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.
Files changed (222) hide show
  1. package/dist/adapters/FeeOracleMock.d.ts +6 -0
  2. package/dist/adapters/FeeOracleMock.js +8 -0
  3. package/dist/adapters/index.d.ts +4 -0
  4. package/dist/adapters/index.js +4 -0
  5. package/dist/adapters/providers/OrdHttpProvider.d.ts +56 -0
  6. package/dist/adapters/providers/OrdHttpProvider.js +110 -0
  7. package/dist/adapters/providers/OrdMockProvider.d.ts +70 -0
  8. package/dist/adapters/providers/OrdMockProvider.js +75 -0
  9. package/dist/adapters/types.d.ts +71 -0
  10. package/dist/adapters/types.js +1 -0
  11. package/dist/bitcoin/BitcoinManager.d.ts +15 -0
  12. package/dist/bitcoin/BitcoinManager.js +262 -0
  13. package/dist/bitcoin/BroadcastClient.d.ts +30 -0
  14. package/dist/bitcoin/BroadcastClient.js +35 -0
  15. package/dist/bitcoin/OrdinalsClient.d.ts +21 -0
  16. package/dist/bitcoin/OrdinalsClient.js +105 -0
  17. package/dist/bitcoin/PSBTBuilder.d.ts +24 -0
  18. package/dist/bitcoin/PSBTBuilder.js +80 -0
  19. package/dist/bitcoin/fee-calculation.d.ts +14 -0
  20. package/dist/bitcoin/fee-calculation.js +31 -0
  21. package/dist/bitcoin/providers/OrdNodeProvider.d.ts +38 -0
  22. package/dist/bitcoin/providers/OrdNodeProvider.js +67 -0
  23. package/dist/bitcoin/providers/OrdinalsProvider.d.ts +33 -0
  24. package/dist/bitcoin/providers/OrdinalsProvider.js +50 -0
  25. package/dist/bitcoin/providers/types.d.ts +63 -0
  26. package/dist/bitcoin/providers/types.js +1 -0
  27. package/dist/bitcoin/transactions/commit.d.ts +89 -0
  28. package/dist/bitcoin/transactions/commit.js +311 -0
  29. package/dist/bitcoin/transactions/index.d.ts +7 -0
  30. package/dist/bitcoin/transactions/index.js +8 -0
  31. package/dist/bitcoin/transfer.d.ts +9 -0
  32. package/dist/bitcoin/transfer.js +26 -0
  33. package/dist/bitcoin/utxo-selection.d.ts +78 -0
  34. package/dist/bitcoin/utxo-selection.js +237 -0
  35. package/dist/bitcoin/utxo.d.ts +26 -0
  36. package/dist/bitcoin/utxo.js +78 -0
  37. package/dist/contexts/credentials-v1.json +195 -0
  38. package/dist/contexts/credentials-v2-examples.json +5 -0
  39. package/dist/contexts/credentials-v2.json +301 -0
  40. package/dist/contexts/credentials.json +195 -0
  41. package/dist/contexts/data-integrity-v2.json +81 -0
  42. package/dist/contexts/dids.json +57 -0
  43. package/dist/contexts/ed255192020.json +93 -0
  44. package/dist/contexts/ordinals-plus.json +23 -0
  45. package/dist/contexts/originals.json +22 -0
  46. package/dist/core/OriginalsSDK.d.ts +158 -0
  47. package/dist/core/OriginalsSDK.js +274 -0
  48. package/dist/crypto/Multikey.d.ts +30 -0
  49. package/dist/crypto/Multikey.js +149 -0
  50. package/dist/crypto/Signer.d.ts +21 -0
  51. package/dist/crypto/Signer.js +196 -0
  52. package/dist/crypto/noble-init.d.ts +18 -0
  53. package/dist/crypto/noble-init.js +106 -0
  54. package/dist/did/BtcoDidResolver.d.ts +57 -0
  55. package/dist/did/BtcoDidResolver.js +166 -0
  56. package/dist/did/DIDManager.d.ts +101 -0
  57. package/dist/did/DIDManager.js +493 -0
  58. package/dist/did/Ed25519Verifier.d.ts +30 -0
  59. package/dist/did/Ed25519Verifier.js +59 -0
  60. package/dist/did/KeyManager.d.ts +17 -0
  61. package/dist/did/KeyManager.js +207 -0
  62. package/dist/did/WebVHManager.d.ts +100 -0
  63. package/dist/did/WebVHManager.js +312 -0
  64. package/dist/did/createBtcoDidDocument.d.ts +10 -0
  65. package/dist/did/createBtcoDidDocument.js +42 -0
  66. package/dist/did/providers/OrdinalsClientProviderAdapter.d.ts +23 -0
  67. package/dist/did/providers/OrdinalsClientProviderAdapter.js +51 -0
  68. package/dist/events/EventEmitter.d.ts +115 -0
  69. package/dist/events/EventEmitter.js +198 -0
  70. package/dist/events/index.d.ts +7 -0
  71. package/dist/events/index.js +6 -0
  72. package/dist/events/types.d.ts +286 -0
  73. package/dist/events/types.js +9 -0
  74. package/dist/examples/basic-usage.d.ts +3 -0
  75. package/dist/examples/basic-usage.js +62 -0
  76. package/dist/examples/create-module-original.d.ts +32 -0
  77. package/dist/examples/create-module-original.js +376 -0
  78. package/dist/examples/full-lifecycle-flow.d.ts +56 -0
  79. package/dist/examples/full-lifecycle-flow.js +419 -0
  80. package/dist/examples/run.d.ts +12 -0
  81. package/dist/examples/run.js +51 -0
  82. package/dist/index.d.ts +43 -0
  83. package/dist/index.js +52 -0
  84. package/dist/kinds/KindRegistry.d.ts +76 -0
  85. package/dist/kinds/KindRegistry.js +216 -0
  86. package/dist/kinds/index.d.ts +33 -0
  87. package/dist/kinds/index.js +36 -0
  88. package/dist/kinds/types.d.ts +363 -0
  89. package/dist/kinds/types.js +25 -0
  90. package/dist/kinds/validators/AgentValidator.d.ts +14 -0
  91. package/dist/kinds/validators/AgentValidator.js +155 -0
  92. package/dist/kinds/validators/AppValidator.d.ts +14 -0
  93. package/dist/kinds/validators/AppValidator.js +135 -0
  94. package/dist/kinds/validators/DatasetValidator.d.ts +14 -0
  95. package/dist/kinds/validators/DatasetValidator.js +148 -0
  96. package/dist/kinds/validators/DocumentValidator.d.ts +14 -0
  97. package/dist/kinds/validators/DocumentValidator.js +180 -0
  98. package/dist/kinds/validators/MediaValidator.d.ts +14 -0
  99. package/dist/kinds/validators/MediaValidator.js +172 -0
  100. package/dist/kinds/validators/ModuleValidator.d.ts +14 -0
  101. package/dist/kinds/validators/ModuleValidator.js +140 -0
  102. package/dist/kinds/validators/base.d.ts +96 -0
  103. package/dist/kinds/validators/base.js +218 -0
  104. package/dist/kinds/validators/index.d.ts +10 -0
  105. package/dist/kinds/validators/index.js +10 -0
  106. package/dist/lifecycle/BatchOperations.d.ts +147 -0
  107. package/dist/lifecycle/BatchOperations.js +251 -0
  108. package/dist/lifecycle/LifecycleManager.d.ts +362 -0
  109. package/dist/lifecycle/LifecycleManager.js +1692 -0
  110. package/dist/lifecycle/OriginalsAsset.d.ts +164 -0
  111. package/dist/lifecycle/OriginalsAsset.js +380 -0
  112. package/dist/lifecycle/ProvenanceQuery.d.ts +126 -0
  113. package/dist/lifecycle/ProvenanceQuery.js +220 -0
  114. package/dist/lifecycle/ResourceVersioning.d.ts +73 -0
  115. package/dist/lifecycle/ResourceVersioning.js +127 -0
  116. package/dist/migration/MigrationManager.d.ts +86 -0
  117. package/dist/migration/MigrationManager.js +412 -0
  118. package/dist/migration/audit/AuditLogger.d.ts +51 -0
  119. package/dist/migration/audit/AuditLogger.js +156 -0
  120. package/dist/migration/checkpoint/CheckpointManager.d.ts +31 -0
  121. package/dist/migration/checkpoint/CheckpointManager.js +96 -0
  122. package/dist/migration/checkpoint/CheckpointStorage.d.ts +26 -0
  123. package/dist/migration/checkpoint/CheckpointStorage.js +89 -0
  124. package/dist/migration/index.d.ts +22 -0
  125. package/dist/migration/index.js +27 -0
  126. package/dist/migration/operations/BaseMigration.d.ts +48 -0
  127. package/dist/migration/operations/BaseMigration.js +83 -0
  128. package/dist/migration/operations/PeerToBtcoMigration.d.ts +25 -0
  129. package/dist/migration/operations/PeerToBtcoMigration.js +67 -0
  130. package/dist/migration/operations/PeerToWebvhMigration.d.ts +19 -0
  131. package/dist/migration/operations/PeerToWebvhMigration.js +46 -0
  132. package/dist/migration/operations/WebvhToBtcoMigration.d.ts +25 -0
  133. package/dist/migration/operations/WebvhToBtcoMigration.js +67 -0
  134. package/dist/migration/rollback/RollbackManager.d.ts +29 -0
  135. package/dist/migration/rollback/RollbackManager.js +146 -0
  136. package/dist/migration/state/StateMachine.d.ts +25 -0
  137. package/dist/migration/state/StateMachine.js +76 -0
  138. package/dist/migration/state/StateTracker.d.ts +36 -0
  139. package/dist/migration/state/StateTracker.js +123 -0
  140. package/dist/migration/types.d.ts +306 -0
  141. package/dist/migration/types.js +33 -0
  142. package/dist/migration/validation/BitcoinValidator.d.ts +13 -0
  143. package/dist/migration/validation/BitcoinValidator.js +83 -0
  144. package/dist/migration/validation/CredentialValidator.d.ts +13 -0
  145. package/dist/migration/validation/CredentialValidator.js +46 -0
  146. package/dist/migration/validation/DIDCompatibilityValidator.d.ts +16 -0
  147. package/dist/migration/validation/DIDCompatibilityValidator.js +127 -0
  148. package/dist/migration/validation/LifecycleValidator.d.ts +10 -0
  149. package/dist/migration/validation/LifecycleValidator.js +52 -0
  150. package/dist/migration/validation/StorageValidator.d.ts +10 -0
  151. package/dist/migration/validation/StorageValidator.js +65 -0
  152. package/dist/migration/validation/ValidationPipeline.d.ts +29 -0
  153. package/dist/migration/validation/ValidationPipeline.js +180 -0
  154. package/dist/resources/ResourceManager.d.ts +231 -0
  155. package/dist/resources/ResourceManager.js +573 -0
  156. package/dist/resources/index.d.ts +11 -0
  157. package/dist/resources/index.js +10 -0
  158. package/dist/resources/types.d.ts +93 -0
  159. package/dist/resources/types.js +80 -0
  160. package/dist/storage/LocalStorageAdapter.d.ts +11 -0
  161. package/dist/storage/LocalStorageAdapter.js +53 -0
  162. package/dist/storage/MemoryStorageAdapter.d.ts +6 -0
  163. package/dist/storage/MemoryStorageAdapter.js +21 -0
  164. package/dist/storage/StorageAdapter.d.ts +16 -0
  165. package/dist/storage/StorageAdapter.js +1 -0
  166. package/dist/storage/index.d.ts +2 -0
  167. package/dist/storage/index.js +2 -0
  168. package/dist/types/bitcoin.d.ts +84 -0
  169. package/dist/types/bitcoin.js +1 -0
  170. package/dist/types/common.d.ts +82 -0
  171. package/dist/types/common.js +1 -0
  172. package/dist/types/credentials.d.ts +75 -0
  173. package/dist/types/credentials.js +1 -0
  174. package/dist/types/did.d.ts +26 -0
  175. package/dist/types/did.js +1 -0
  176. package/dist/types/index.d.ts +5 -0
  177. package/dist/types/index.js +5 -0
  178. package/dist/types/network.d.ts +78 -0
  179. package/dist/types/network.js +145 -0
  180. package/dist/utils/EventLogger.d.ts +71 -0
  181. package/dist/utils/EventLogger.js +232 -0
  182. package/dist/utils/Logger.d.ts +106 -0
  183. package/dist/utils/Logger.js +257 -0
  184. package/dist/utils/MetricsCollector.d.ts +110 -0
  185. package/dist/utils/MetricsCollector.js +264 -0
  186. package/dist/utils/bitcoin-address.d.ts +38 -0
  187. package/dist/utils/bitcoin-address.js +113 -0
  188. package/dist/utils/cbor.d.ts +2 -0
  189. package/dist/utils/cbor.js +9 -0
  190. package/dist/utils/encoding.d.ts +37 -0
  191. package/dist/utils/encoding.js +120 -0
  192. package/dist/utils/hash.d.ts +1 -0
  193. package/dist/utils/hash.js +5 -0
  194. package/dist/utils/retry.d.ts +10 -0
  195. package/dist/utils/retry.js +35 -0
  196. package/dist/utils/satoshi-validation.d.ts +60 -0
  197. package/dist/utils/satoshi-validation.js +156 -0
  198. package/dist/utils/serialization.d.ts +14 -0
  199. package/dist/utils/serialization.js +76 -0
  200. package/dist/utils/telemetry.d.ts +17 -0
  201. package/dist/utils/telemetry.js +24 -0
  202. package/dist/utils/validation.d.ts +5 -0
  203. package/dist/utils/validation.js +98 -0
  204. package/dist/vc/CredentialManager.d.ts +329 -0
  205. package/dist/vc/CredentialManager.js +615 -0
  206. package/dist/vc/Issuer.d.ts +27 -0
  207. package/dist/vc/Issuer.js +70 -0
  208. package/dist/vc/Verifier.d.ts +16 -0
  209. package/dist/vc/Verifier.js +50 -0
  210. package/dist/vc/cryptosuites/bbs.d.ts +44 -0
  211. package/dist/vc/cryptosuites/bbs.js +213 -0
  212. package/dist/vc/cryptosuites/bbsSimple.d.ts +9 -0
  213. package/dist/vc/cryptosuites/bbsSimple.js +12 -0
  214. package/dist/vc/cryptosuites/eddsa.d.ts +30 -0
  215. package/dist/vc/cryptosuites/eddsa.js +81 -0
  216. package/dist/vc/documentLoader.d.ts +16 -0
  217. package/dist/vc/documentLoader.js +59 -0
  218. package/dist/vc/proofs/data-integrity.d.ts +21 -0
  219. package/dist/vc/proofs/data-integrity.js +15 -0
  220. package/dist/vc/utils/jsonld.d.ts +2 -0
  221. package/dist/vc/utils/jsonld.js +15 -0
  222. 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;