@fiber-pay/runtime 0.1.0-rc.3 → 0.1.0-rc.5

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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @fiber-pay/runtime
2
2
 
3
- Runtime monitor + job orchestration for Fiber (`fnn v0.6.1`).
3
+ Runtime monitor + job orchestration for Fiber (`fnn v0.7.1`).
4
4
 
5
5
  ## Quick start
6
6
 
@@ -104,8 +104,8 @@ curl -fsS "$PROXY_A/jobs/$PAYMENT_JOB_ID/events" | jq
104
104
  ## One-command regression (recommended)
105
105
 
106
106
  ```bash
107
- pnpm e2e:runtime-jobs
108
- JOB_TIMEOUT_SEC=420 CHANNEL_CLEANUP_TIMEOUT_SEC=120 pnpm e2e:runtime-jobs -- --json
107
+ pnpm e2e
108
+ CHANNEL_READY_TIMEOUT_SEC=420 CHANNEL_CLOSE_TIMEOUT_SEC=180 pnpm e2e
109
109
  ```
110
110
 
111
111
  ## Handy job commands
@@ -126,10 +126,10 @@ fiber-pay logs --source runtime --follow
126
126
 
127
127
  When started from `fiber-pay node start` or `fiber-pay runtime start`, runtime/fnn logs are persisted to:
128
128
 
129
- - `<data-dir>/logs/fnn.stdout.log`
130
- - `<data-dir>/logs/fnn.stderr.log`
131
- - `<data-dir>/logs/runtime.alerts.jsonl`
129
+ - `<data-dir>/logs/<YYYY-MM-DD>/fnn.stdout.log`
130
+ - `<data-dir>/logs/<YYYY-MM-DD>/fnn.stderr.log`
131
+ - `<data-dir>/logs/<YYYY-MM-DD>/runtime.alerts.jsonl`
132
132
 
133
- `<data-dir>/runtime.meta.json` stores these paths so agents can read files directly during troubleshooting.
133
+ `<data-dir>/runtime.meta.json` is written at startup and stores the log file paths for that startup day, along with `logsBaseDir`, so agents can read those files directly during troubleshooting. Because logs rotate daily at UTC midnight while `runtime.meta.json` is not rewritten, its stored per-file paths can become stale; for other days' logs, use `logsBaseDir` together with the appropriate `<YYYY-MM-DD>` directory (or the `fiber-pay logs --date/--list-dates` options).
134
134
 
135
135
  You can view these files directly via CLI without `cat` using `fiber-pay logs` (alias: `fiber-pay log`).
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { ChannelId, Channel, PaymentHash, PeerInfo, OpenChannelParams, ShutdownChannelParams, AcceptChannelParams, AbandonChannelParams, UpdateChannelParams, OpenChannelResult, AcceptChannelResult, NewInvoiceParams, CancelInvoiceParams, SettleInvoiceParams, GetInvoiceResult, SendPaymentParams, FiberRpcClient } from '@fiber-pay/sdk';
1
+ import { ChannelId, Channel, PaymentHash, PeerInfo, OpenChannelParams, ShutdownChannelParams, AcceptChannelParams, AbandonChannelParams, UpdateChannelParams, OpenChannelResult, AcceptChannelResult, NewInvoiceParams, CancelInvoiceParams, SettleInvoiceParams, GetInvoiceResult, SendPaymentParams, FiberRpcClient, PaymentStatus, HexString } from '@fiber-pay/sdk';
2
2
  import { EventEmitter } from 'node:events';
3
3
 
4
4
  type AlertPriority = 'critical' | 'high' | 'medium' | 'low';
@@ -88,7 +88,10 @@ interface ChannelJobAlertData {
88
88
  idempotencyKey: string;
89
89
  retryCount: number;
90
90
  action?: string;
91
+ peerId?: string;
92
+ temporaryChannelId?: `0x${string}`;
91
93
  channelId?: `0x${string}`;
94
+ fundingAmount?: string;
92
95
  error?: string;
93
96
  }
94
97
  interface AlertBackend {
@@ -97,6 +100,12 @@ interface AlertBackend {
97
100
  stop?(): Promise<void>;
98
101
  }
99
102
 
103
+ interface FormatRuntimeAlertOptions {
104
+ color?: 'auto' | 'always' | 'never';
105
+ prefix?: string;
106
+ }
107
+ declare function formatRuntimeAlert(alert: Alert, options?: FormatRuntimeAlertOptions): string;
108
+
100
109
  type JobType = 'payment' | 'invoice' | 'channel';
101
110
  type JobState = 'queued' | 'executing' | 'inflight' | 'waiting_retry' | 'invoice_created' | 'invoice_active' | 'invoice_received' | 'invoice_settled' | 'invoice_expired' | 'invoice_cancelled' | 'channel_opening' | 'channel_accepting' | 'channel_abandoning' | 'channel_updating' | 'channel_awaiting_ready' | 'channel_ready' | 'channel_closing' | 'channel_closed' | 'succeeded' | 'failed' | 'cancelled';
102
111
  declare const TERMINAL_JOB_STATES: Set<JobState>;
@@ -222,7 +231,12 @@ interface FileAlertConfig {
222
231
  type: 'file';
223
232
  path: string;
224
233
  }
225
- type AlertBackendConfig = StdoutAlertConfig | WebhookAlertConfig | WebsocketAlertConfig | FileAlertConfig;
234
+ interface DailyFileAlertConfig {
235
+ type: 'daily-file';
236
+ baseLogsDir: string;
237
+ filename?: string;
238
+ }
239
+ type AlertBackendConfig = StdoutAlertConfig | WebhookAlertConfig | WebsocketAlertConfig | FileAlertConfig | DailyFileAlertConfig;
226
240
  interface RuntimeConfig {
227
241
  fiberRpcUrl: string;
228
242
  channelPollIntervalMs: number;
@@ -299,6 +313,9 @@ declare class FiberMonitorService extends EventEmitter {
299
313
  private extractPaymentHash;
300
314
  private extractInvoiceHash;
301
315
  private extractChannelId;
316
+ private extractChannelPeerId;
317
+ private extractTemporaryChannelId;
318
+ private extractChannelFundingAmount;
302
319
  private normalizeHash;
303
320
  }
304
321
 
@@ -309,6 +326,108 @@ interface RuntimeBootstrap {
309
326
  }
310
327
  declare function startRuntimeService(configInput?: RuntimeConfigInput): Promise<RuntimeBootstrap>;
311
328
 
329
+ /**
330
+ * Classify an RPC / job failure into a structured error.
331
+ *
332
+ * `failedError` is the raw `failed_error` string from Fiber's `get_payment` response.
333
+ * `error` is any caught JS exception.
334
+ */
335
+ declare function classifyRpcError(error: unknown, failedError?: string): ClassifiedError;
336
+
337
+ declare class SqliteJobStore {
338
+ private readonly db;
339
+ constructor(dbPath: string);
340
+ private runMigrations;
341
+ createJob<P, R>(job: Omit<Job<P, R>, 'id' | 'createdAt' | 'updatedAt'>): Job<P, R>;
342
+ updateJob<P, R>(id: string, updates: Partial<Job<P, R>>): Job<P, R>;
343
+ getJob<P = unknown, R = unknown>(id: string): Job<P, R> | undefined;
344
+ getJobByIdempotencyKey<P = unknown, R = unknown>(key: string): Job<P, R> | undefined;
345
+ listJobs<P = unknown, R = unknown>(filter?: JobFilter): Job<P, R>[];
346
+ deleteJob(id: string): void;
347
+ /** Return jobs that are ready to be retried right now. */
348
+ getRetryableJobs<P = unknown, R = unknown>(now?: number): Job<P, R>[];
349
+ /** Return jobs in non-terminal states (for recovery after daemon restart). */
350
+ getInProgressJobs<P = unknown, R = unknown>(): Job<P, R>[];
351
+ addJobEvent(jobId: string, eventType: JobEventType, fromState?: JobState, toState?: JobState, data?: Record<string, unknown>): JobEvent;
352
+ listJobEvents(jobId: string): JobEvent[];
353
+ close(): void;
354
+ private rowToJob;
355
+ }
356
+
357
+ interface JobManagerEvents {
358
+ 'job:created': [job: RuntimeJob];
359
+ 'job:state_changed': [job: RuntimeJob, from: JobState];
360
+ 'job:succeeded': [job: RuntimeJob];
361
+ 'job:failed': [job: RuntimeJob];
362
+ 'job:cancelled': [job: RuntimeJob];
363
+ }
364
+ interface JobManagerConfig {
365
+ schedulerIntervalMs?: number;
366
+ maxConcurrentJobs?: number;
367
+ retryPolicy?: RetryPolicy;
368
+ }
369
+ declare class JobManager extends EventEmitter<JobManagerEvents> {
370
+ private readonly rpc;
371
+ private readonly store;
372
+ private readonly retryPolicy;
373
+ private readonly schedulerIntervalMs;
374
+ private readonly maxConcurrentJobs;
375
+ private running;
376
+ private schedulerTimer;
377
+ private readonly active;
378
+ constructor(rpc: FiberRpcClient, store: SqliteJobStore, config?: JobManagerConfig);
379
+ ensurePayment(params: PaymentJobParams, options?: {
380
+ idempotencyKey?: string;
381
+ maxRetries?: number;
382
+ }): Promise<PaymentJob>;
383
+ manageInvoice(params: InvoiceJobParams, options?: {
384
+ idempotencyKey?: string;
385
+ maxRetries?: number;
386
+ reuseTerminal?: boolean;
387
+ }): Promise<InvoiceJob>;
388
+ manageChannel(params: ChannelJobParams, options?: {
389
+ idempotencyKey?: string;
390
+ maxRetries?: number;
391
+ reuseTerminal?: boolean;
392
+ }): Promise<ChannelJob>;
393
+ getJob(id: string): RuntimeJob | undefined;
394
+ listJobs(filter?: JobFilter): RuntimeJob[];
395
+ cancelJob(id: string): void;
396
+ start(): void;
397
+ stop(): Promise<void>;
398
+ private createOrReuseJob;
399
+ private tick;
400
+ private schedule;
401
+ private recover;
402
+ private execute;
403
+ private buildEventData;
404
+ }
405
+
406
+ declare const defaultPaymentRetryPolicy: RetryPolicy;
407
+ /**
408
+ * Decide whether a job should be retried given its error and current retry count.
409
+ */
410
+ declare function shouldRetry(error: ClassifiedError, retryCount: number, policy: RetryPolicy): boolean;
411
+ /**
412
+ * Compute the next retry delay using exponential backoff with random jitter.
413
+ * retryCount is the number of retries already attempted (0-based before this retry).
414
+ */
415
+ declare function computeRetryDelay(retryCount: number, policy: RetryPolicy): number;
416
+
417
+ type MachineEvent = 'send_issued' | 'payment_inflight' | 'payment_success' | 'payment_failed_retryable' | 'payment_failed_permanent' | 'invoice_created' | 'invoice_received' | 'invoice_settled' | 'invoice_expired' | 'invoice_cancelled' | 'channel_opening' | 'channel_accepting' | 'channel_abandoning' | 'channel_updating' | 'channel_closing' | 'channel_ready' | 'channel_closed' | 'channel_failed' | 'retry_delay_elapsed' | 'cancel';
418
+ interface Transition {
419
+ from: JobState | JobState[];
420
+ event: MachineEvent;
421
+ to: JobState;
422
+ }
423
+ declare class JobStateMachine {
424
+ private readonly table;
425
+ constructor(transitions: Transition[]);
426
+ transition(current: JobState, event: MachineEvent): JobState | null;
427
+ isTerminal(state: JobState): boolean;
428
+ }
429
+ declare const paymentStateMachine: JobStateMachine;
430
+
312
431
  interface RpcMonitorProxyConfig {
313
432
  listen: string;
314
433
  targetUrl: string;
@@ -412,112 +531,142 @@ declare class MemoryStore implements Store {
412
531
  listAlerts(filters?: AlertFilter): Alert[];
413
532
  }
414
533
 
415
- declare class SqliteJobStore {
416
- private readonly db;
417
- constructor(dbPath: string);
418
- private runMigrations;
419
- createJob<P, R>(job: Omit<Job<P, R>, 'id' | 'createdAt' | 'updatedAt'>): Job<P, R>;
420
- updateJob<P, R>(id: string, updates: Partial<Job<P, R>>): Job<P, R>;
421
- getJob<P = unknown, R = unknown>(id: string): Job<P, R> | undefined;
422
- getJobByIdempotencyKey<P = unknown, R = unknown>(key: string): Job<P, R> | undefined;
423
- listJobs<P = unknown, R = unknown>(filter?: JobFilter): Job<P, R>[];
424
- deleteJob(id: string): void;
425
- /** Return jobs that are ready to be retried right now. */
426
- getRetryableJobs<P = unknown, R = unknown>(now?: number): Job<P, R>[];
427
- /** Return jobs in non-terminal states (for recovery after daemon restart). */
428
- getInProgressJobs<P = unknown, R = unknown>(): Job<P, R>[];
429
- addJobEvent(jobId: string, eventType: JobEventType, fromState?: JobState, toState?: JobState, data?: Record<string, unknown>): JobEvent;
430
- listJobEvents(jobId: string): JobEvent[];
431
- close(): void;
432
- private rowToJob;
433
- }
434
-
435
- interface JobManagerEvents {
436
- 'job:created': [job: RuntimeJob];
437
- 'job:state_changed': [job: RuntimeJob, from: JobState];
438
- 'job:succeeded': [job: RuntimeJob];
439
- 'job:failed': [job: RuntimeJob];
440
- 'job:cancelled': [job: RuntimeJob];
441
- }
442
- interface JobManagerConfig {
443
- schedulerIntervalMs?: number;
444
- maxConcurrentJobs?: number;
445
- retryPolicy?: RetryPolicy;
446
- }
447
- declare class JobManager extends EventEmitter<JobManagerEvents> {
448
- private readonly rpc;
449
- private readonly store;
450
- private readonly retryPolicy;
451
- private readonly schedulerIntervalMs;
452
- private readonly maxConcurrentJobs;
453
- private running;
454
- private schedulerTimer;
455
- private readonly active;
456
- constructor(rpc: FiberRpcClient, store: SqliteJobStore, config?: JobManagerConfig);
457
- ensurePayment(params: PaymentJobParams, options?: {
458
- idempotencyKey?: string;
459
- maxRetries?: number;
460
- }): Promise<PaymentJob>;
461
- manageInvoice(params: InvoiceJobParams, options?: {
462
- idempotencyKey?: string;
463
- maxRetries?: number;
464
- reuseTerminal?: boolean;
465
- }): Promise<InvoiceJob>;
466
- manageChannel(params: ChannelJobParams, options?: {
467
- idempotencyKey?: string;
468
- maxRetries?: number;
469
- reuseTerminal?: boolean;
470
- }): Promise<ChannelJob>;
471
- getJob(id: string): RuntimeJob | undefined;
472
- listJobs(filter?: JobFilter): RuntimeJob[];
473
- cancelJob(id: string): void;
474
- start(): void;
475
- stop(): Promise<void>;
476
- private createOrReuseJob;
477
- private tick;
478
- private schedule;
479
- private recover;
480
- private execute;
481
- private buildEventData;
482
- }
483
-
484
- type MachineEvent = 'send_issued' | 'payment_inflight' | 'payment_success' | 'payment_failed_retryable' | 'payment_failed_permanent' | 'invoice_created' | 'invoice_received' | 'invoice_settled' | 'invoice_expired' | 'invoice_cancelled' | 'channel_opening' | 'channel_accepting' | 'channel_abandoning' | 'channel_updating' | 'channel_closing' | 'channel_ready' | 'channel_closed' | 'channel_failed' | 'retry_delay_elapsed' | 'cancel';
485
- interface Transition {
486
- from: JobState | JobState[];
487
- event: MachineEvent;
488
- to: JobState;
489
- }
490
- declare class JobStateMachine {
491
- private readonly table;
492
- constructor(transitions: Transition[]);
493
- transition(current: JobState, event: MachineEvent): JobState | null;
494
- isTerminal(state: JobState): boolean;
495
- }
496
- declare const paymentStateMachine: JobStateMachine;
497
-
498
534
  /**
499
- * Classify an RPC / job failure into a structured error.
535
+ * Payment Proof & Tracking System
536
+ * Records, stores, and verifies payment evidence for audit trail and reconciliation
500
537
  *
501
- * `failedError` is the raw `failed_error` string from Fiber's `get_payment` response.
502
- * `error` is any caught JS exception.
538
+ * IMPORTANT LIMITATION:
539
+ * Fiber Network RPC currently does NOT return the payment preimage to the sender
540
+ * after a successful payment. In standard Lightning protocol, the preimage serves
541
+ * as cryptographic proof of payment (SHA256(preimage) === payment_hash).
542
+ *
543
+ * Until Fiber exposes the preimage in send_payment/get_payment responses:
544
+ * - Payment proofs are based on RPC status (Success/Failed) rather than preimage
545
+ * - For invoices YOU create (as receiver), preimage IS available
546
+ * - This limitation affects sender-side proof verification only
547
+ *
548
+ * Tracking issue: Preimage not exposed in Fiber RPC send_payment result
503
549
  */
504
- declare function classifyRpcError(error: unknown, failedError?: string): ClassifiedError;
505
550
 
506
- declare const defaultPaymentRetryPolicy: RetryPolicy;
507
- /**
508
- * Decide whether a job should be retried given its error and current retry count.
509
- */
510
- declare function shouldRetry(error: ClassifiedError, retryCount: number, policy: RetryPolicy): boolean;
511
551
  /**
512
- * Compute the next retry delay using exponential backoff with random jitter.
513
- * retryCount is the number of retries already attempted (0-based before this retry).
552
+ * Complete payment proof record
514
553
  */
515
- declare function computeRetryDelay(retryCount: number, policy: RetryPolicy): number;
516
-
517
- interface FormatRuntimeAlertOptions {
518
- color?: 'auto' | 'always' | 'never';
519
- prefix?: string;
554
+ interface PaymentProof {
555
+ /** Unique identifier (payment hash) */
556
+ id: string;
557
+ /** Status at time of recording */
558
+ status: PaymentStatus;
559
+ /** Original invoice string */
560
+ invoice: string;
561
+ /** Invoice details extracted */
562
+ invoiceDetails: {
563
+ paymentHash: string;
564
+ amountCkb: number;
565
+ description?: string;
566
+ };
567
+ /** Payment execution details */
568
+ execution: {
569
+ amountCkb: number;
570
+ feeCkb: number;
571
+ actualTimestamp: number;
572
+ requestTimestamp: number;
573
+ };
574
+ /** Proof of payment */
575
+ proof: {
576
+ preimage?: HexString;
577
+ peerAddress?: string;
578
+ channelUsed?: string;
579
+ routePath?: string[];
580
+ };
581
+ /** Verification status */
582
+ verified: boolean;
583
+ verifiedAt?: number;
584
+ verificationMethod?: 'preimage_hash' | 'rpc_status' | 'manual';
585
+ /** Metadata for audit trail */
586
+ metadata: {
587
+ createdAt: number;
588
+ updatedAt: number;
589
+ notes?: string;
590
+ };
591
+ }
592
+ interface PaymentProofSummary {
593
+ totalProofs: number;
594
+ verifiedCount: number;
595
+ pendingCount: number;
596
+ failedCount: number;
597
+ totalAmountCkb: number;
598
+ totalFeesCkb: number;
599
+ timeRange: {
600
+ earliest?: number;
601
+ latest?: number;
602
+ };
603
+ }
604
+ declare class PaymentProofManager {
605
+ private proofs;
606
+ private proofFilePath;
607
+ private maxStoredProofs;
608
+ constructor(dataDir: string);
609
+ /**
610
+ * Load proofs from disk
611
+ */
612
+ load(): Promise<void>;
613
+ /**
614
+ * Save proofs to disk
615
+ */
616
+ save(): Promise<void>;
617
+ /**
618
+ * Record a payment proof after successful execution
619
+ */
620
+ recordPaymentProof(paymentHash: string, invoice: string, invoiceDetails: {
621
+ paymentHash: string;
622
+ amountCkb: number;
623
+ description?: string;
624
+ }, execution: {
625
+ amountCkb: number;
626
+ feeCkb: number;
627
+ actualTimestamp: number;
628
+ requestTimestamp: number;
629
+ }, status: PaymentStatus, proof?: {
630
+ preimage?: HexString;
631
+ peerAddress?: string;
632
+ channelUsed?: string;
633
+ routePath?: string[];
634
+ }): PaymentProof;
635
+ /**
636
+ * Get proof by payment hash
637
+ */
638
+ getProof(paymentHash: string): PaymentProof | undefined;
639
+ /**
640
+ * Verify a proof's authenticity
641
+ */
642
+ verifyProof(proof: PaymentProof): {
643
+ valid: boolean;
644
+ reason: string;
645
+ };
646
+ /**
647
+ * Get payment timeline between two timestamps
648
+ */
649
+ getPaymentChain(startTime: number, endTime: number): PaymentProof[];
650
+ /**
651
+ * Get summary statistics
652
+ */
653
+ getSummary(): PaymentProofSummary;
654
+ /**
655
+ * Export proofs as audit report
656
+ */
657
+ exportAuditReport(startTime?: number, endTime?: number): string;
658
+ /**
659
+ * Verify preimage hash (SHA256 of preimage = payment_hash)
660
+ */
661
+ private verifyPreimageHash;
662
+ /**
663
+ * Remove oldest proofs to keep storage bounded
664
+ */
665
+ private pruneOldestProofs;
666
+ /**
667
+ * Ensure directory exists
668
+ */
669
+ private ensureDirectory;
520
670
  }
521
- declare function formatRuntimeAlert(alert: Alert, options?: FormatRuntimeAlertOptions): string;
522
671
 
523
- export { type Alert, type AlertBackend, type AlertBackendConfig, type AlertFilter, type AlertInput, type AlertPriority, type AlertType, type ChannelBalanceChangedData, type ChannelJob, type ChannelJobAction, type ChannelJobAlertData, type ChannelJobParams, type ChannelJobResult, type ChannelStateChangedData, type ClassifiedError, type ErrorCategory, FiberMonitorService, type FileAlertConfig, type InvoiceJob, type InvoiceJobAction, type InvoiceJobAlertData, type InvoiceJobParams, type InvoiceJobResult, type Job, type JobEvent, type JobEventType, type JobFilter, JobManager, type JobState, type JobType, MemoryStore, type PaymentJob, type PaymentJobAlertData, type PaymentJobParams, type PaymentJobResult, type PeerEventData, type PendingTlcChangedData, type RetryPolicy, type RpcHealthData, RpcMonitorProxy, type RuntimeConfig, type RuntimeConfigInput, type RuntimeJob, SqliteJobStore, type StdoutAlertConfig, TERMINAL_JOB_STATES, type TrackedInvoiceState, type TrackedPaymentState, type WebhookAlertConfig, type WebsocketAlertConfig, alertPriorityOrder, alertTypeValues, classifyRpcError, computeRetryDelay, createRuntimeConfig, defaultPaymentRetryPolicy, defaultRuntimeConfig, formatRuntimeAlert, isAlertPriority, isAlertType, parseListenAddress, paymentStateMachine, shouldRetry, startRuntimeService };
672
+ export { type Alert, type AlertBackend, type AlertBackendConfig, type AlertFilter, type AlertInput, type AlertPriority, type AlertType, type ChannelBalanceChangedData, type ChannelJob, type ChannelJobAction, type ChannelJobAlertData, type ChannelJobParams, type ChannelJobResult, type ChannelStateChangedData, type ClassifiedError, type DailyFileAlertConfig, type ErrorCategory, FiberMonitorService, type FileAlertConfig, type InvoiceJob, type InvoiceJobAction, type InvoiceJobAlertData, type InvoiceJobParams, type InvoiceJobResult, type Job, type JobEvent, type JobEventType, type JobFilter, JobManager, type JobState, type JobType, MemoryStore, type PaymentJob, type PaymentJobAlertData, type PaymentJobParams, type PaymentJobResult, type PaymentProof, PaymentProofManager, type PaymentProofSummary, type PeerEventData, type PendingTlcChangedData, type RetryPolicy, type RpcHealthData, RpcMonitorProxy, type RuntimeConfig, type RuntimeConfigInput, type RuntimeJob, SqliteJobStore, type StdoutAlertConfig, TERMINAL_JOB_STATES, type TrackedInvoiceState, type TrackedPaymentState, type WebhookAlertConfig, type WebsocketAlertConfig, alertPriorityOrder, alertTypeValues, classifyRpcError, computeRetryDelay, createRuntimeConfig, defaultPaymentRetryPolicy, defaultRuntimeConfig, formatRuntimeAlert, isAlertPriority, isAlertType, parseListenAddress, paymentStateMachine, shouldRetry, startRuntimeService };