@lightninglabs/wavelength-core 0.1.1-rc3 → 0.1.1

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.
@@ -17,8 +17,15 @@ export declare class ActivityStream {
17
17
  });
18
18
  start(): void;
19
19
  stop(): void;
20
+ /**
21
+ * Returns the preimage seen for a payment hash, or undefined. It is the only
22
+ * route to a settled send's proof of payment; see #preimages.
23
+ */
24
+ preimageFor(paymentHash: string): string | undefined;
25
+ /** Every preimage seen so far, for merging into a refreshed snapshot. */
26
+ preimages(): ReadonlyMap<string, string>;
20
27
  /** Forwarded 'activity' client events; debounced into one onActivity call. */
21
- noteActivity(entry: Pick<Entry, 'cursor'>): void;
28
+ noteActivity(entry: Pick<Entry, 'cursor'> & Partial<Entry>): void;
22
29
  /** Forwarded 'activityStream' client events: the stream was lost; reopen. */
23
30
  noteStreamLost(): void;
24
31
  }
@@ -1 +1 @@
1
- {"version":3,"file":"activity.d.ts","sourceRoot":"","sources":["../../src/engine/activity.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAQ3C;;;;;;GAMG;AACH,qBAAa,cAAc;;gBAmBb,IAAI,EAAE;QAChB,MAAM,EAAE,IAAI,CAAC,gBAAgB,EAAE,eAAe,GAAG,cAAc,CAAC,CAAC;QACjE,UAAU,EAAE,MAAM,IAAI,CAAC;QACvB,WAAW,EAAE,MAAM,IAAI,CAAC;QACxB,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;KAChC;IAID,KAAK,IAAI,IAAI;IAYb,IAAI,IAAI,IAAI;IAaZ,8EAA8E;IAC9E,YAAY,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,IAAI;IAWhD,6EAA6E;IAC7E,cAAc,IAAI,IAAI;CAoEvB"}
1
+ {"version":3,"file":"activity.d.ts","sourceRoot":"","sources":["../../src/engine/activity.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAQ3C;;;;;;GAMG;AACH,qBAAa,cAAc;;gBAmCb,IAAI,EAAE;QAChB,MAAM,EAAE,IAAI,CAAC,gBAAgB,EAAE,eAAe,GAAG,cAAc,CAAC,CAAC;QACjE,UAAU,EAAE,MAAM,IAAI,CAAC;QACvB,WAAW,EAAE,MAAM,IAAI,CAAC;QACxB,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;KAChC;IAID,KAAK,IAAI,IAAI;IAYb,IAAI,IAAI,IAAI;IAcZ;;;OAGG;IACH,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAIpD,yEAAyE;IACzE,SAAS,IAAI,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC;IAIxC,8EAA8E;IAC9E,YAAY,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,IAAI;IAkBjE,6EAA6E;IAC7E,cAAc,IAAI,IAAI;CAoEvB"}
@@ -9,6 +9,22 @@ import { ACTIVITY_DEBOUNCE_MS, STREAM_BACKOFF_CAP_MS, STREAM_BACKOFF_MS, STREAM_
9
9
  export class ActivityStream {
10
10
  #running = false;
11
11
  #cursor = 0;
12
+ /**
13
+ * Preimages seen on the stream, keyed by payment hash.
14
+ *
15
+ * The daemon reveals a send's preimage exactly once, on the entry it pushes
16
+ * when the swap settles, and omits it from the list snapshot that every
17
+ * later refresh reads. Without remembering it here the field is unreachable
18
+ * through any public API: the stream event is consumed for its cursor and
19
+ * the body discarded, and the refresh that follows overwrites the entry with
20
+ * a copy that has none.
21
+ *
22
+ * That matters because a preimage is proof of payment, and the only way a
23
+ * caller can demonstrate to a third party that an invoice was actually
24
+ * settled. Holding them in memory is enough: they are re-delivered on the
25
+ * includeExisting replay when a stream reopens.
26
+ */
27
+ #preimages = new Map();
12
28
  #backoff = STREAM_BACKOFF_MS;
13
29
  #failures = 0;
14
30
  #lifecycleGeneration = 0;
@@ -41,10 +57,22 @@ export class ActivityStream {
41
57
  this.#running = false;
42
58
  this.#lifecycleGeneration += 1;
43
59
  this.#cursor = 0;
60
+ this.#preimages.clear();
44
61
  clearTimeout(this.#retryTimer);
45
62
  clearTimeout(this.#debounce);
46
63
  this.#opts.client.stopActivity();
47
64
  }
65
+ /**
66
+ * Returns the preimage seen for a payment hash, or undefined. It is the only
67
+ * route to a settled send's proof of payment; see #preimages.
68
+ */
69
+ preimageFor(paymentHash) {
70
+ return this.#preimages.get(paymentHash);
71
+ }
72
+ /** Every preimage seen so far, for merging into a refreshed snapshot. */
73
+ preimages() {
74
+ return this.#preimages;
75
+ }
48
76
  /** Forwarded 'activity' client events; debounced into one onActivity call. */
49
77
  noteActivity(entry) {
50
78
  if (!this.#running) {
@@ -53,6 +81,12 @@ export class ActivityStream {
53
81
  if (Number.isSafeInteger(entry.cursor) && entry.cursor > this.#cursor) {
54
82
  this.#cursor = entry.cursor;
55
83
  }
84
+ // Capture the proof before the body is dropped. This is the only moment
85
+ // it exists anywhere the SDK can see.
86
+ const progress = entry.progress;
87
+ if (progress?.paymentHash && progress.preimage) {
88
+ this.#preimages.set(progress.paymentHash, progress.preimage);
89
+ }
56
90
  clearTimeout(this.#debounce);
57
91
  this.#debounce = setTimeout(() => this.#opts.onActivity(), ACTIVITY_DEBOUNCE_MS);
58
92
  }
@@ -1,16 +1,26 @@
1
1
  import type { WavelengthClient } from '../client.ts';
2
2
  import type { RuntimeConfig } from '../config.ts';
3
+ import { type WavelengthPerformanceListener } from '../performance.ts';
3
4
  import { type ExitBatchEvent, type ExitBatchOptions, type ExitBatchResult } from '../exit.ts';
4
5
  import type { CreateWalletRequest, DepositRequest, ExitRequest, ExitStatusRequest, ExitSummaryRequest, GetExitPlanRequest, ListRequest, OpenWalletFromPasskeyRequest, ReceiveRequest, RestoreWalletRequest, SendRequest, SweepWalletRequest, UnlockWalletRequest } from '../requests.ts';
5
- import type { CreateWalletResult, DepositResult, ExitResult, ExitStatusResult, ExitSummaryResult, GetExitPlanResult, ListResult, OpenWalletFromPasskeyResult, PrepareSendResult, ReceiveResult, SendResult, SweepWalletResult, UnlockWalletResult } from '../results.ts';
6
+ import type { CreateWalletResult, DepositResult, Entry, ExitResult, ExitStatusResult, ExitSummaryResult, GetExitPlanResult, ListResult, OpenWalletFromPasskeyResult, PrepareSendResult, ReceiveResult, SendResult, SweepWalletResult, UnlockWalletResult } from '../results.ts';
6
7
  import { type WalletInfo } from '../state.ts';
7
8
  import type { WalletSnapshot } from './snapshot.ts';
9
+ /** The instrumentation options every arm of {@link WalletEngineOptions} shares. */
10
+ type WalletEnginePerformanceOptions = {
11
+ /**
12
+ * Receives structured timing samples for runtime readiness, wallet
13
+ * create/open RPCs, post-operation info adoption, and sync polling. Omit it
14
+ * to keep performance instrumentation disabled.
15
+ */
16
+ onPerformance?: WavelengthPerformanceListener;
17
+ };
8
18
  /**
9
19
  * Options for {@link createWalletEngine}. A discriminated union: the type
10
20
  * requires config when autoStart is true, so autoStart cannot be set without
11
21
  * a config to start from.
12
22
  */
13
- export type WalletEngineOptions = {
23
+ export type WalletEngineOptions = WalletEnginePerformanceOptions & ({
14
24
  /** The transport client the engine drives. */
15
25
  client: WavelengthClient;
16
26
  /** Default runtime config used by autoStart and by start() with no argument. */
@@ -24,7 +34,7 @@ export type WalletEngineOptions = {
24
34
  config?: RuntimeConfig;
25
35
  /** Start the runtime automatically once it is ready. Requires config; omit or set false when config is unset. */
26
36
  autoStart?: false;
27
- };
37
+ });
28
38
  /**
29
39
  * Removes a key from every arm of a union type. TypeScript's built-in Omit
30
40
  * does not distribute over unions (it flattens to the union of all keys
@@ -117,4 +127,18 @@ export interface WalletEngine {
117
127
  }
118
128
  /** Creates a {@link WalletEngine} over any transport client. */
119
129
  export declare function createWalletEngine(options: WalletEngineOptions): WalletEngine;
130
+ /**
131
+ * Puts back the preimages the list snapshot drops.
132
+ *
133
+ * The daemon reveals a send's preimage once, on the stream entry it pushes at
134
+ * settle, and never again: every list read returns the entry with the field
135
+ * empty. So a refresh would otherwise erase proof of payment that the SDK had
136
+ * already seen, and a caller who blinked would have no way to get it back.
137
+ *
138
+ * Entries that already carry a preimage, or for which none was ever seen, are
139
+ * returned untouched, so this allocates nothing in the ordinary case and never
140
+ * invents a value it was not given.
141
+ */
142
+ export declare function restorePreimages(entries: readonly Entry[], preimages: ReadonlyMap<string, string>): Entry[];
143
+ export {};
120
144
  //# sourceMappingURL=engine.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/engine/engine.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/engine/engine.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import { toError } from "../errors.js";
2
+ import { performanceNow, reportPerformance, } from "../performance.js";
2
3
  import { exitBatch as runExitBatch, } from "../exit.js";
3
4
  import { WalletState } from "../state.js";
4
5
  import { ActivityStream } from "./activity.js";
@@ -16,6 +17,7 @@ class WavelengthEngine {
16
17
  client;
17
18
  #store = new SnapshotStore();
18
19
  #config;
20
+ #onPerformance;
19
21
  #disposed = false;
20
22
  // Counts stops the host asked for, so a start that rejects afterwards can
21
23
  // tell an intentional shutdown from a runtime that died underneath it.
@@ -30,12 +32,15 @@ class WavelengthEngine {
30
32
  #reconciler;
31
33
  #syncPoller;
32
34
  #restorePoller;
35
+ #syncStartedAt;
36
+ #syncTicks = 0;
33
37
  // The pending restore promise, settled exactly once at usability (resolve)
34
38
  // or wallet-down failure (reject).
35
39
  #restore;
36
40
  constructor(options) {
37
41
  this.client = options.client;
38
42
  this.#config = options.config;
43
+ this.#onPerformance = options.onPerformance;
39
44
  this.#stream = new ActivityStream({
40
45
  client: this.client,
41
46
  onActivity: () => this.#reconciler.trigger(),
@@ -57,7 +62,10 @@ class WavelengthEngine {
57
62
  this.#syncPoller = new Poller({
58
63
  intervalMs: SYNC_POLL_MS,
59
64
  failureLimit: SYNC_POLL_FAILURE_LIMIT,
60
- tick: () => this.refresh(),
65
+ tick: () => {
66
+ this.#syncTicks += 1;
67
+ return this.refresh();
68
+ },
61
69
  onExhausted: (err) => {
62
70
  // A poller tick already in flight when the poller stops can resolve
63
71
  // after the phase has left 'syncing', so only dispatch while the
@@ -73,7 +81,17 @@ class WavelengthEngine {
73
81
  immediate: true,
74
82
  tick: () => this.#restoreTick(),
75
83
  });
84
+ const readyStartedAt = this.#onPerformance
85
+ ? performanceNow()
86
+ : undefined;
76
87
  this.client.ready().then(() => {
88
+ if (readyStartedAt !== undefined) {
89
+ reportPerformance(this.#onPerformance, {
90
+ stage: 'runtime',
91
+ phase: 'clientReady',
92
+ durationMs: performanceNow() - readyStartedAt,
93
+ });
94
+ }
77
95
  if (this.#disposed) {
78
96
  return;
79
97
  }
@@ -84,6 +102,14 @@ class WavelengthEngine {
84
102
  void this.start().catch(() => undefined);
85
103
  }
86
104
  }, (err) => {
105
+ if (readyStartedAt !== undefined) {
106
+ reportPerformance(this.#onPerformance, {
107
+ stage: 'runtime',
108
+ phase: 'clientReady',
109
+ durationMs: performanceNow() - readyStartedAt,
110
+ detail: { outcome: 'error' },
111
+ });
112
+ }
87
113
  if (!this.#disposed) {
88
114
  this.#dispatch({ type: 'runtimeFailed' }, { error: toError(err) });
89
115
  }
@@ -184,10 +210,12 @@ class WavelengthEngine {
184
210
  }
185
211
  async createWallet(req) {
186
212
  this.#assertNotDisposed();
187
- const result = await this.client.createWallet(req);
188
- await this.#adoptInfo();
189
- this.#kickRefresh();
190
- return result;
213
+ return this.#measureWallet('createTotal', async () => {
214
+ const result = await this.#measureWallet('createRpc', () => this.client.createWallet(req));
215
+ await this.#adoptInfo('create');
216
+ this.#kickRefresh();
217
+ return result;
218
+ });
191
219
  }
192
220
  restoreWallet(req) {
193
221
  // A restore with server-assisted recovery blocks createWallet for the
@@ -281,17 +309,21 @@ class WavelengthEngine {
281
309
  }
282
310
  async unlockWallet(req) {
283
311
  this.#assertNotDisposed();
284
- const result = await this.client.unlockWallet(req);
285
- await this.#adoptInfo();
286
- this.#kickRefresh();
287
- return result;
312
+ return this.#measureWallet('unlockTotal', async () => {
313
+ const result = await this.#measureWallet('unlockRpc', () => this.client.unlockWallet(req));
314
+ await this.#adoptInfo('unlock');
315
+ this.#kickRefresh();
316
+ return result;
317
+ });
288
318
  }
289
319
  async openWalletFromPasskey(req) {
290
320
  this.#assertNotDisposed();
291
- const result = await this.client.openWalletFromPasskey(req);
292
- await this.#adoptInfo();
293
- this.#kickRefresh();
294
- return result;
321
+ return this.#measureWallet('passkeyOpenTotal', async () => {
322
+ const result = await this.#measureWallet('passkeyOpenRpc', () => this.client.openWalletFromPasskey(req));
323
+ await this.#adoptInfo('passkeyOpen');
324
+ this.#kickRefresh();
325
+ return result;
326
+ });
295
327
  }
296
328
  async deposit(req = {}) {
297
329
  this.#assertNotDisposed();
@@ -366,7 +398,17 @@ class WavelengthEngine {
366
398
  list(req) {
367
399
  this.#assertNotDisposed();
368
400
  // Listing reads state, so nothing to refresh.
369
- return this.client.list(req);
401
+ return this.client.list(req).then((result) => {
402
+ if (!result.activity)
403
+ return result;
404
+ return {
405
+ ...result,
406
+ activity: {
407
+ ...result.activity,
408
+ entries: restorePreimages(result.activity.entries, this.#stream.preimages()),
409
+ },
410
+ };
411
+ });
370
412
  }
371
413
  clearLogs() {
372
414
  this.#store.update({ logs: [] });
@@ -424,10 +466,24 @@ class WavelengthEngine {
424
466
  this.#reconciler.cancel();
425
467
  }
426
468
  if (phase === 'syncing') {
469
+ if (this.#syncStartedAt === undefined && this.#onPerformance) {
470
+ this.#syncStartedAt = performanceNow();
471
+ this.#syncTicks = 0;
472
+ }
427
473
  this.#syncPoller.start();
428
474
  }
429
475
  else {
430
476
  this.#syncPoller.stop();
477
+ if (this.#syncStartedAt !== undefined) {
478
+ reportPerformance(this.#onPerformance, {
479
+ stage: 'wallet',
480
+ phase: 'sync',
481
+ durationMs: performanceNow() - this.#syncStartedAt,
482
+ detail: { ticks: this.#syncTicks, outcome: phase },
483
+ });
484
+ this.#syncStartedAt = undefined;
485
+ this.#syncTicks = 0;
486
+ }
431
487
  }
432
488
  if (phase === 'restoring') {
433
489
  this.#restorePoller.start();
@@ -454,7 +510,7 @@ class WavelengthEngine {
454
510
  if (snap.phase === 'stopping' || snap.phase === 'stopped') {
455
511
  return snap.balance;
456
512
  }
457
- const entries = rows.activity?.entries || [];
513
+ const entries = restorePreimages(rows.activity?.entries || [], this.#stream.preimages());
458
514
  const nextInfo = stabilize(snap.info, info);
459
515
  const nextBalance = stabilize(snap.balance, balance);
460
516
  const nextActivity = stabilize(snap.activity, entries);
@@ -468,24 +524,52 @@ class WavelengthEngine {
468
524
  // every attempt fails the daemon is presumed gone: escalate via
469
525
  // walletAdoptionFailed rather than silently leaving the wallet stuck
470
526
  // without info.
471
- async #adoptInfo() {
527
+ async #adoptInfo(operation) {
528
+ const startedAt = this.#onPerformance ? performanceNow() : undefined;
529
+ let attempts = 0;
530
+ let retryWaitMs = 0;
531
+ let adopted = false;
472
532
  for (let attempt = 0; attempt < ADOPT_INFO_RETRIES; attempt++) {
473
533
  if (this.#disposed) {
474
- return null;
534
+ break;
475
535
  }
536
+ attempts += 1;
476
537
  try {
477
538
  const info = await this.client.getInfo();
478
539
  this.#dispatch({ type: 'infoReceived', info }, { info });
540
+ adopted = true;
541
+ if (startedAt !== undefined) {
542
+ reportPerformance(this.#onPerformance, {
543
+ stage: 'wallet',
544
+ phase: 'adoptInfo',
545
+ durationMs: performanceNow() - startedAt,
546
+ detail: { operation, attempts, retryWaitMs, outcome: 'success' },
547
+ });
548
+ }
479
549
  return info;
480
550
  }
481
551
  catch {
482
552
  if (attempt < ADOPT_INFO_RETRIES - 1) {
553
+ retryWaitMs += ADOPT_INFO_RETRY_MS;
483
554
  await new Promise((resolve) => {
484
555
  setTimeout(resolve, ADOPT_INFO_RETRY_MS);
485
556
  });
486
557
  }
487
558
  }
488
559
  }
560
+ if (startedAt !== undefined && !adopted) {
561
+ reportPerformance(this.#onPerformance, {
562
+ stage: 'wallet',
563
+ phase: 'adoptInfo',
564
+ durationMs: performanceNow() - startedAt,
565
+ detail: {
566
+ operation,
567
+ attempts,
568
+ retryWaitMs,
569
+ outcome: this.#disposed ? 'disposed' : 'exhausted',
570
+ },
571
+ });
572
+ }
489
573
  if (!this.#disposed) {
490
574
  this.#dispatch({ type: 'walletAdoptionFailed' }, {
491
575
  error: new Error('the wallet was created but the daemon stopped responding'),
@@ -493,6 +577,28 @@ class WavelengthEngine {
493
577
  }
494
578
  return null;
495
579
  }
580
+ async #measureWallet(phase, task) {
581
+ if (!this.#onPerformance) {
582
+ return task();
583
+ }
584
+ const startedAt = performanceNow();
585
+ let outcome = 'success';
586
+ try {
587
+ return await task();
588
+ }
589
+ catch (err) {
590
+ outcome = 'error';
591
+ throw err;
592
+ }
593
+ finally {
594
+ reportPerformance(this.#onPerformance, {
595
+ stage: 'wallet',
596
+ phase,
597
+ durationMs: performanceNow() - startedAt,
598
+ detail: { outcome },
599
+ });
600
+ }
601
+ }
496
602
  // Serialized background refresh with a consecutive-failure budget. Below
497
603
  // the limit failures stay engine-internal; at the limit the phase escalates
498
604
  // so a dead daemon cannot hide behind a healthy-looking ready wallet.
@@ -582,3 +688,31 @@ class WavelengthEngine {
582
688
  this.#rejectRestore(new Error('the runtime stopped during the restore'));
583
689
  }
584
690
  }
691
+ /**
692
+ * Puts back the preimages the list snapshot drops.
693
+ *
694
+ * The daemon reveals a send's preimage once, on the stream entry it pushes at
695
+ * settle, and never again: every list read returns the entry with the field
696
+ * empty. So a refresh would otherwise erase proof of payment that the SDK had
697
+ * already seen, and a caller who blinked would have no way to get it back.
698
+ *
699
+ * Entries that already carry a preimage, or for which none was ever seen, are
700
+ * returned untouched, so this allocates nothing in the ordinary case and never
701
+ * invents a value it was not given.
702
+ */
703
+ export function restorePreimages(entries, preimages) {
704
+ if (preimages.size === 0) {
705
+ return entries;
706
+ }
707
+ return entries.map((entry) => {
708
+ const progress = entry.progress;
709
+ if (!progress?.paymentHash || progress.preimage) {
710
+ return entry;
711
+ }
712
+ const preimage = preimages.get(progress.paymentHash);
713
+ if (preimage === undefined) {
714
+ return entry;
715
+ }
716
+ return { ...entry, progress: { ...progress, preimage } };
717
+ });
718
+ }
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export type { ActivityStreamPayload, ActivityStreamState, WavelengthEvent, WavelengthEventType, WavelengthListener, WavelengthLogLevel, WavelengthLogPayload, } from './events.ts';
2
+ export type { WavelengthPerformanceEvent, WavelengthPerformanceListener, } from './performance.ts';
2
3
  export { DEBUG_LEVELS, networkDefaults, validateRuntimeConfig, } from './config.ts';
3
4
  export type { DebugLevel, Network, PresetNetwork, RuntimeConfig, } from './config.ts';
4
5
  export { WalletState, normalizeInfo, phaseFromInfo, walletStateFromProto } from './state.ts';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * A structured timing sample emitted by an opt-in Wavelength performance
3
+ * reporter. Stage identifies the broad subsystem and phase identifies the
4
+ * measured boundary within it.
5
+ */
6
+ export type WavelengthPerformanceEvent = {
7
+ /** Broad subsystem being measured, such as runtime, wallet, or passkey. */
8
+ stage: 'runtime' | 'wallet' | 'passkey';
9
+ /** Stable name of the measured operation within the stage. */
10
+ phase: string;
11
+ /** Elapsed wall-clock time in milliseconds. */
12
+ durationMs: number;
13
+ /** Extra low-cardinality context for interpreting the sample. */
14
+ detail?: Record<string, string | number | boolean>;
15
+ };
16
+ /** Receives opt-in structured Wavelength performance samples. */
17
+ export type WavelengthPerformanceListener = (event: WavelengthPerformanceEvent) => void;
18
+ /** Returns a monotonic timestamp when available. */
19
+ export declare function performanceNow(): number;
20
+ /**
21
+ * Delivers a timing sample without allowing diagnostics to break wallet
22
+ * behavior when a host reporter throws.
23
+ */
24
+ export declare function reportPerformance(listener: WavelengthPerformanceListener | undefined, event: WavelengthPerformanceEvent): void;
25
+ //# sourceMappingURL=performance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"performance.d.ts","sourceRoot":"","sources":["../src/performance.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,MAAM,0BAA0B,GAAG;IACvC,2EAA2E;IAC3E,KAAK,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;IACxC,8DAA8D;IAC9D,KAAK,EAAE,MAAM,CAAC;IACd,+CAA+C;IAC/C,UAAU,EAAE,MAAM,CAAC;IACnB,iEAAiE;IACjE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;CACpD,CAAC;AAEF,iEAAiE;AACjE,MAAM,MAAM,6BAA6B,GAAG,CAC1C,KAAK,EAAE,0BAA0B,KAC9B,IAAI,CAAC;AAEV,oDAAoD;AACpD,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,6BAA6B,GAAG,SAAS,EACnD,KAAK,EAAE,0BAA0B,GAChC,IAAI,CAUN"}
@@ -0,0 +1,19 @@
1
+ /** Returns a monotonic timestamp when available. */
2
+ export function performanceNow() {
3
+ return globalThis.performance?.now?.() ?? Date.now();
4
+ }
5
+ /**
6
+ * Delivers a timing sample without allowing diagnostics to break wallet
7
+ * behavior when a host reporter throws.
8
+ */
9
+ export function reportPerformance(listener, event) {
10
+ if (!listener) {
11
+ return;
12
+ }
13
+ try {
14
+ listener(event);
15
+ }
16
+ catch {
17
+ // Performance reporting is diagnostic and must never break wallet work.
18
+ }
19
+ }
package/dist/version.d.ts CHANGED
@@ -14,5 +14,5 @@
14
14
  * scripts/runtime-version.mjs, so keep the declaration in this exact
15
15
  * single-quoted literal form.
16
16
  */
17
- export declare const RUNTIME_MANIFEST_VERSION = "v0.1.1-rc3";
17
+ export declare const RUNTIME_MANIFEST_VERSION = "v0.1.1";
18
18
  //# sourceMappingURL=version.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,wBAAwB,eAAe,CAAC"}
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,wBAAwB,WAAW,CAAC"}
package/dist/version.js CHANGED
@@ -14,4 +14,4 @@
14
14
  * scripts/runtime-version.mjs, so keep the declaration in this exact
15
15
  * single-quoted literal form.
16
16
  */
17
- export const RUNTIME_MANIFEST_VERSION = 'v0.1.1-rc3';
17
+ export const RUNTIME_MANIFEST_VERSION = 'v0.1.1';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lightninglabs/wavelength-core",
3
- "version": "0.1.1-rc3",
3
+ "version": "0.1.1",
4
4
  "private": false,
5
5
  "description": "Transport- and framework-agnostic contract for the Wavelength self-custodial Lightning wallet SDK.",
6
6
  "license": "MIT",