@t402/streaming-payments 1.0.0-beta.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.
- package/README.md +422 -0
- package/dist/channels/index.d.ts +1560 -0
- package/dist/channels/index.js +1135 -0
- package/dist/channels/index.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +3482 -0
- package/dist/index.js.map +1 -0
- package/dist/settlement/index.d.ts +867 -0
- package/dist/settlement/index.js +1030 -0
- package/dist/settlement/index.js.map +1 -0
- package/dist/streaming/index.d.ts +1004 -0
- package/dist/streaming/index.js +1321 -0
- package/dist/streaming/index.js.map +1 -0
- package/package.json +60 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/channels/types.ts","../src/channels/state.ts","../src/channels/opening.ts","../src/channels/closing.ts","../src/channels/recovery.ts","../src/streaming/types.ts","../src/streaming/flow.ts","../src/streaming/rate.ts","../src/streaming/metering.ts","../src/streaming/billing.ts","../src/settlement/types.ts","../src/settlement/checkpoint.ts","../src/settlement/final.ts","../src/settlement/dispute.ts"],"sourcesContent":["import { z } from 'zod';\n\n/**\n * Chain identifier (CAIP-2)\n */\nexport type ChainId = string;\n\n/**\n * Asset identifier (contract address or native)\n */\nexport type AssetId = string;\n\n/**\n * Channel state\n */\nexport const ChannelState = z.enum([\n 'created', // Channel created but not funded\n 'funding', // Waiting for funding transaction\n 'open', // Channel is active and streaming\n 'paused', // Channel temporarily paused\n 'closing', // Channel close initiated\n 'disputing', // Dispute in progress\n 'closed', // Channel fully closed\n 'expired', // Channel expired without proper close\n]);\nexport type ChannelState = z.infer<typeof ChannelState>;\n\n/**\n * Channel configuration\n */\nexport const ChannelConfig = z.object({\n // Funding requirements\n minDeposit: z.string().default('1000000'), // Minimum deposit (in smallest units)\n maxDeposit: z.string().optional(),\n\n // Timing\n challengePeriod: z.number().default(86400), // Dispute window in seconds (24h default)\n expirationTime: z.number().optional(), // Optional expiration timestamp\n\n // Checkpointing\n checkpointInterval: z.number().default(3600), // Checkpoint every hour\n minCheckpointAmount: z.string().default('100000'), // Min amount change to checkpoint\n\n // Fees\n channelFee: z.string().default('0'), // One-time channel opening fee\n settlementFee: z.string().default('0'), // Fee for final settlement\n});\nexport type ChannelConfig = z.infer<typeof ChannelConfig>;\n\n/**\n * Channel participant\n */\nexport const ChannelParticipant = z.object({\n address: z.string(),\n role: z.enum(['payer', 'payee']),\n publicKey: z.string().optional(), // For off-chain signature verification\n});\nexport type ChannelParticipant = z.infer<typeof ChannelParticipant>;\n\n/**\n * Channel balance\n */\nexport const ChannelBalance = z.object({\n payer: z.string(), // Payer's remaining balance\n payee: z.string(), // Payee's accrued balance\n total: z.string(), // Total channel capacity\n locked: z.string().default('0'), // Amount locked in disputes\n});\nexport type ChannelBalance = z.infer<typeof ChannelBalance>;\n\n/**\n * Payment channel checkpoint\n */\nexport const ChannelCheckpoint = z.object({\n channelId: z.string(),\n sequence: z.number(), // Monotonically increasing sequence number\n timestamp: z.number(),\n balance: ChannelBalance,\n amountStreamed: z.string(), // Total amount streamed so far\n payerSignature: z.string(),\n payeeSignature: z.string().optional(), // Payee signature for mutual checkpoints\n stateRoot: z.string().optional(), // Merkle root of channel state\n});\nexport type ChannelCheckpoint = z.infer<typeof ChannelCheckpoint>;\n\n/**\n * Streaming payment channel\n */\nexport const StreamingChannel = z.object({\n id: z.string(),\n state: ChannelState,\n chain: z.string(), // CAIP-2 chain ID\n asset: z.string(), // Token contract address\n\n // Participants\n payer: ChannelParticipant,\n payee: ChannelParticipant,\n\n // Financial state\n balance: ChannelBalance,\n\n // Streaming parameters\n ratePerSecond: z.string(), // Amount per second\n startTime: z.number().optional(), // When streaming started\n pausedAt: z.number().optional(), // When paused (if paused)\n\n // Configuration\n config: ChannelConfig,\n\n // On-chain references\n contractAddress: z.string().optional(), // Payment channel contract\n fundingTxHash: z.string().optional(),\n closingTxHash: z.string().optional(),\n\n // Checkpointing\n checkpoints: z.array(ChannelCheckpoint),\n latestCheckpoint: ChannelCheckpoint.optional(),\n\n // Timestamps\n createdAt: z.number(),\n updatedAt: z.number(),\n closedAt: z.number().optional(),\n});\nexport type StreamingChannel = z.infer<typeof StreamingChannel>;\n\n/**\n * Channel creation request\n */\nexport const ChannelCreateRequest = z.object({\n chain: z.string(),\n asset: z.string(),\n payerAddress: z.string(),\n payeeAddress: z.string(),\n depositAmount: z.string(),\n ratePerSecond: z.string(),\n config: ChannelConfig.optional(),\n});\nexport type ChannelCreateRequest = z.infer<typeof ChannelCreateRequest>;\n\n/**\n * Channel funding transaction\n */\nexport const FundingTransaction = z.object({\n channelId: z.string(),\n txHash: z.string(),\n amount: z.string(),\n sender: z.string(),\n blockNumber: z.number().optional(),\n timestamp: z.number(),\n confirmed: z.boolean(),\n});\nexport type FundingTransaction = z.infer<typeof FundingTransaction>;\n\n/**\n * Channel close request\n */\nexport const ChannelCloseRequest = z.object({\n channelId: z.string(),\n initiator: z.string(), // Address of closer\n reason: z.enum(['mutual', 'unilateral', 'timeout', 'dispute']),\n finalCheckpoint: ChannelCheckpoint.optional(),\n signature: z.string(),\n});\nexport type ChannelCloseRequest = z.infer<typeof ChannelCloseRequest>;\n\n/**\n * Channel dispute\n */\nexport const ChannelDispute = z.object({\n channelId: z.string(),\n disputeId: z.string(),\n initiator: z.string(),\n reason: z.string(),\n claimedBalance: ChannelBalance,\n evidence: z.array(z.object({\n type: z.enum(['checkpoint', 'signature', 'transaction']),\n data: z.string(),\n timestamp: z.number(),\n })),\n status: z.enum(['pending', 'resolved', 'rejected']),\n resolution: z.object({\n winner: z.string().optional(),\n finalBalance: ChannelBalance.optional(),\n timestamp: z.number().optional(),\n }).optional(),\n createdAt: z.number(),\n expiresAt: z.number(),\n});\nexport type ChannelDispute = z.infer<typeof ChannelDispute>;\n\n/**\n * Channel state transition\n */\nexport const StateTransition = z.object({\n from: ChannelState,\n to: ChannelState,\n trigger: z.string(),\n timestamp: z.number(),\n metadata: z.record(z.unknown()).optional(),\n});\nexport type StateTransition = z.infer<typeof StateTransition>;\n\n/**\n * Recovery data for channel state restoration\n */\nexport const RecoveryData = z.object({\n channelId: z.string(),\n checkpoints: z.array(ChannelCheckpoint),\n transactions: z.array(FundingTransaction),\n disputes: z.array(ChannelDispute),\n stateHistory: z.array(StateTransition),\n recoveredAt: z.number(),\n});\nexport type RecoveryData = z.infer<typeof RecoveryData>;\n","import {\n StreamingChannel,\n ChannelState,\n StateTransition,\n ChannelCheckpoint,\n} from './types.js';\n\n/**\n * Valid state transitions for payment channels\n */\nconst STATE_TRANSITIONS: Record<ChannelState, ChannelState[]> = {\n created: ['funding', 'closed'],\n funding: ['open', 'closed', 'expired'],\n open: ['paused', 'closing', 'disputing'],\n paused: ['open', 'closing', 'disputing'],\n closing: ['closed', 'disputing'],\n disputing: ['closing', 'closed'],\n closed: [],\n expired: [],\n};\n\n/**\n * State machine event\n */\nexport type StateEvent =\n | { type: 'FUND'; txHash: string; amount: string }\n | { type: 'CONFIRM_FUNDING' }\n | { type: 'START_STREAMING' }\n | { type: 'PAUSE' }\n | { type: 'RESUME' }\n | { type: 'INITIATE_CLOSE'; initiator: string }\n | { type: 'MUTUAL_CLOSE'; signature: string }\n | { type: 'DISPUTE'; reason: string }\n | { type: 'RESOLVE_DISPUTE'; winner: string }\n | { type: 'FINALIZE' }\n | { type: 'TIMEOUT' };\n\n/**\n * Channel state machine\n */\nexport class ChannelStateMachine {\n private channel: StreamingChannel;\n private transitions: StateTransition[] = [];\n private listeners: Map<string, Set<(channel: StreamingChannel) => void>> = new Map();\n\n constructor(channel: StreamingChannel) {\n this.channel = { ...channel };\n }\n\n /**\n * Get current channel state\n */\n getChannel(): StreamingChannel {\n return { ...this.channel };\n }\n\n /**\n * Get current state\n */\n getState(): ChannelState {\n return this.channel.state;\n }\n\n /**\n * Get state history\n */\n getTransitions(): StateTransition[] {\n return [...this.transitions];\n }\n\n /**\n * Check if a transition is valid\n */\n canTransition(to: ChannelState): boolean {\n const allowedTransitions = STATE_TRANSITIONS[this.channel.state];\n return allowedTransitions.includes(to);\n }\n\n /**\n * Get allowed transitions from current state\n */\n getAllowedTransitions(): ChannelState[] {\n return STATE_TRANSITIONS[this.channel.state];\n }\n\n /**\n * Process a state event\n */\n process(event: StateEvent): { success: boolean; error?: string } {\n const currentState = this.channel.state;\n let nextState: ChannelState | null = null;\n let metadata: Record<string, unknown> = {};\n\n switch (event.type) {\n case 'FUND':\n if (currentState !== 'created') {\n return { success: false, error: 'Channel must be in created state to fund' };\n }\n nextState = 'funding';\n metadata = { txHash: event.txHash, amount: event.amount };\n this.channel.fundingTxHash = event.txHash;\n break;\n\n case 'CONFIRM_FUNDING':\n if (currentState !== 'funding') {\n return { success: false, error: 'Channel must be in funding state' };\n }\n nextState = 'open';\n this.channel.startTime = Date.now();\n break;\n\n case 'START_STREAMING':\n if (currentState !== 'open' && currentState !== 'paused') {\n return { success: false, error: 'Channel must be open or paused to stream' };\n }\n if (currentState === 'paused') {\n nextState = 'open';\n this.channel.pausedAt = undefined;\n }\n break;\n\n case 'PAUSE':\n if (currentState !== 'open') {\n return { success: false, error: 'Channel must be open to pause' };\n }\n nextState = 'paused';\n this.channel.pausedAt = Date.now();\n break;\n\n case 'RESUME':\n if (currentState !== 'paused') {\n return { success: false, error: 'Channel must be paused to resume' };\n }\n nextState = 'open';\n this.channel.pausedAt = undefined;\n break;\n\n case 'INITIATE_CLOSE':\n if (currentState !== 'open' && currentState !== 'paused') {\n return { success: false, error: 'Channel must be open or paused to close' };\n }\n nextState = 'closing';\n metadata = { initiator: event.initiator };\n break;\n\n case 'MUTUAL_CLOSE':\n if (currentState !== 'closing') {\n return { success: false, error: 'Channel must be in closing state' };\n }\n nextState = 'closed';\n this.channel.closedAt = Date.now();\n metadata = { signature: event.signature };\n break;\n\n case 'DISPUTE':\n if (!['open', 'paused', 'closing'].includes(currentState)) {\n return { success: false, error: 'Cannot dispute in current state' };\n }\n nextState = 'disputing';\n metadata = { reason: event.reason };\n break;\n\n case 'RESOLVE_DISPUTE':\n if (currentState !== 'disputing') {\n return { success: false, error: 'No dispute to resolve' };\n }\n nextState = 'closing';\n metadata = { winner: event.winner };\n break;\n\n case 'FINALIZE':\n if (currentState !== 'closing') {\n return { success: false, error: 'Channel must be in closing state' };\n }\n nextState = 'closed';\n this.channel.closedAt = Date.now();\n break;\n\n case 'TIMEOUT':\n if (currentState === 'funding') {\n nextState = 'expired';\n } else if (currentState === 'disputing') {\n // Timeout during dispute - use last valid checkpoint\n nextState = 'closed';\n this.channel.closedAt = Date.now();\n } else {\n return { success: false, error: 'Timeout not applicable in current state' };\n }\n break;\n\n default:\n return { success: false, error: 'Unknown event type' };\n }\n\n if (nextState && nextState !== currentState) {\n if (!this.canTransition(nextState)) {\n return { success: false, error: `Invalid transition from ${currentState} to ${nextState}` };\n }\n\n const transition: StateTransition = {\n from: currentState,\n to: nextState,\n trigger: event.type,\n timestamp: Date.now(),\n metadata,\n };\n\n this.channel.state = nextState;\n this.channel.updatedAt = Date.now();\n this.transitions.push(transition);\n\n this.notifyListeners(nextState);\n }\n\n return { success: true };\n }\n\n /**\n * Update channel balance\n */\n updateBalance(payerBalance: string, payeeBalance: string): void {\n this.channel.balance = {\n ...this.channel.balance,\n payer: payerBalance,\n payee: payeeBalance,\n };\n this.channel.updatedAt = Date.now();\n }\n\n /**\n * Add checkpoint\n */\n addCheckpoint(checkpoint: ChannelCheckpoint): void {\n this.channel.checkpoints.push(checkpoint);\n this.channel.latestCheckpoint = checkpoint;\n this.channel.updatedAt = Date.now();\n }\n\n /**\n * Get current streamed amount\n */\n getCurrentStreamedAmount(): string {\n if (!this.channel.startTime) return '0';\n if (this.channel.state !== 'open' && this.channel.state !== 'paused') {\n return this.channel.balance.payee;\n }\n\n const now = this.channel.pausedAt ?? Date.now();\n const elapsed = Math.floor((now - this.channel.startTime) / 1000);\n const streamed = BigInt(this.channel.ratePerSecond) * BigInt(elapsed);\n const maxStreamed = BigInt(this.channel.balance.total);\n\n return (streamed > maxStreamed ? maxStreamed : streamed).toString();\n }\n\n /**\n * Calculate remaining balance\n */\n getRemainingBalance(): string {\n const total = BigInt(this.channel.balance.total);\n const streamed = BigInt(this.getCurrentStreamedAmount());\n return (total - streamed).toString();\n }\n\n /**\n * Check if channel needs checkpoint\n */\n needsCheckpoint(): boolean {\n const config = this.channel.config;\n const lastCheckpoint = this.channel.latestCheckpoint;\n\n if (!lastCheckpoint) return true;\n\n // Check time interval\n const timeSinceCheckpoint = Date.now() - lastCheckpoint.timestamp;\n if (timeSinceCheckpoint >= config.checkpointInterval * 1000) return true;\n\n // Check amount change\n const currentStreamed = BigInt(this.getCurrentStreamedAmount());\n const lastStreamed = BigInt(lastCheckpoint.amountStreamed);\n const amountChange = currentStreamed - lastStreamed;\n\n if (amountChange >= BigInt(config.minCheckpointAmount)) return true;\n\n return false;\n }\n\n /**\n * Subscribe to state changes\n */\n onStateChange(state: ChannelState | '*', callback: (channel: StreamingChannel) => void): () => void {\n const key = state;\n if (!this.listeners.has(key)) {\n this.listeners.set(key, new Set());\n }\n this.listeners.get(key)!.add(callback);\n\n return () => {\n this.listeners.get(key)?.delete(callback);\n };\n }\n\n private notifyListeners(newState: ChannelState): void {\n // Notify specific state listeners\n this.listeners.get(newState)?.forEach(cb => cb(this.channel));\n // Notify wildcard listeners\n this.listeners.get('*')?.forEach(cb => cb(this.channel));\n }\n}\n\n/**\n * Check if channel is active (can stream)\n */\nexport function isChannelActive(channel: StreamingChannel): boolean {\n return channel.state === 'open';\n}\n\n/**\n * Check if channel is terminal (cannot transition further)\n */\nexport function isChannelTerminal(channel: StreamingChannel): boolean {\n return channel.state === 'closed' || channel.state === 'expired';\n}\n\n/**\n * Calculate channel utilization\n */\nexport function getChannelUtilization(channel: StreamingChannel): number {\n const total = parseFloat(channel.balance.total);\n if (total === 0) return 0;\n\n const payee = parseFloat(channel.balance.payee);\n return (payee / total) * 100;\n}\n","import {\n StreamingChannel,\n ChannelCreateRequest,\n ChannelConfig,\n ChannelParticipant,\n ChannelBalance,\n FundingTransaction,\n} from './types.js';\nimport { ChannelStateMachine } from './state.js';\n\n/**\n * Channel opening configuration\n */\nexport interface ChannelOpeningConfig {\n fundingTimeout?: number; // Timeout for funding in ms (default 1 hour)\n confirmations?: number; // Required confirmations for funding tx\n contractAddress?: string; // Payment channel contract address\n}\n\n/**\n * Channel opening result\n */\nexport interface ChannelOpeningResult {\n channel: StreamingChannel;\n stateMachine: ChannelStateMachine;\n fundingRequired: {\n amount: string;\n to: string;\n data?: string;\n };\n}\n\n/**\n * Channel opener - handles channel creation and funding\n */\nexport class ChannelOpener {\n private config: Required<ChannelOpeningConfig>;\n\n constructor(config: ChannelOpeningConfig = {}) {\n this.config = {\n fundingTimeout: config.fundingTimeout ?? 3600000, // 1 hour\n confirmations: config.confirmations ?? 1,\n contractAddress: config.contractAddress ?? '',\n };\n }\n\n /**\n * Create a new channel\n */\n create(request: ChannelCreateRequest): ChannelOpeningResult {\n // Validate request\n this.validateCreateRequest(request);\n\n const channelConfig = request.config ?? ChannelConfig.parse({});\n const now = Date.now();\n const channelId = this.generateChannelId(request, now);\n\n const payer: ChannelParticipant = {\n address: request.payerAddress,\n role: 'payer',\n };\n\n const payee: ChannelParticipant = {\n address: request.payeeAddress,\n role: 'payee',\n };\n\n const balance: ChannelBalance = {\n payer: request.depositAmount,\n payee: '0',\n total: request.depositAmount,\n locked: '0',\n };\n\n const channel: StreamingChannel = {\n id: channelId,\n state: 'created',\n chain: request.chain,\n asset: request.asset,\n payer,\n payee,\n balance,\n ratePerSecond: request.ratePerSecond,\n config: channelConfig,\n contractAddress: this.config.contractAddress || undefined,\n checkpoints: [],\n createdAt: now,\n updatedAt: now,\n };\n\n const stateMachine = new ChannelStateMachine(channel);\n\n // Calculate funding requirements\n const fundingRequired = this.calculateFundingRequirements(channel);\n\n return {\n channel: stateMachine.getChannel(),\n stateMachine,\n fundingRequired,\n };\n }\n\n /**\n * Process funding transaction\n */\n processFunding(\n stateMachine: ChannelStateMachine,\n txHash: string,\n amount: string,\n ): { success: boolean; error?: string } {\n const channel = stateMachine.getChannel();\n\n // Validate funding amount\n if (BigInt(amount) < BigInt(channel.config.minDeposit)) {\n return { success: false, error: 'Funding amount below minimum deposit' };\n }\n\n if (channel.config.maxDeposit && BigInt(amount) > BigInt(channel.config.maxDeposit)) {\n return { success: false, error: 'Funding amount exceeds maximum deposit' };\n }\n\n // Process state transition\n const result = stateMachine.process({\n type: 'FUND',\n txHash,\n amount,\n });\n\n if (!result.success) {\n return result;\n }\n\n // Update balance with actual funded amount\n stateMachine.updateBalance(amount, '0');\n\n return { success: true };\n }\n\n /**\n * Confirm funding (after required confirmations)\n */\n confirmFunding(\n stateMachine: ChannelStateMachine,\n _confirmation: FundingTransaction,\n ): { success: boolean; error?: string } {\n return stateMachine.process({ type: 'CONFIRM_FUNDING' });\n }\n\n /**\n * Handle funding timeout\n */\n handleTimeout(\n stateMachine: ChannelStateMachine,\n ): { success: boolean; expired: boolean } {\n const channel = stateMachine.getChannel();\n\n if (channel.state !== 'funding') {\n return { success: false, expired: false };\n }\n\n const elapsed = Date.now() - channel.createdAt;\n if (elapsed < this.config.fundingTimeout) {\n return { success: false, expired: false };\n }\n\n const result = stateMachine.process({ type: 'TIMEOUT' });\n return { success: result.success, expired: result.success };\n }\n\n /**\n * Validate channel create request\n */\n private validateCreateRequest(request: ChannelCreateRequest): void {\n // Parse and validate with zod\n ChannelCreateRequest.parse(request);\n\n // Additional validations\n if (request.payerAddress === request.payeeAddress) {\n throw new Error('Payer and payee must be different addresses');\n }\n\n if (BigInt(request.depositAmount) <= 0n) {\n throw new Error('Deposit amount must be positive');\n }\n\n if (BigInt(request.ratePerSecond) <= 0n) {\n throw new Error('Rate per second must be positive');\n }\n\n // Check if rate is sustainable\n const depositBigInt = BigInt(request.depositAmount);\n const rateBigInt = BigInt(request.ratePerSecond);\n const minDuration = depositBigInt / rateBigInt;\n\n if (minDuration < 60n) {\n throw new Error('Channel would be exhausted in less than 60 seconds');\n }\n }\n\n /**\n * Generate unique channel ID\n */\n private generateChannelId(request: ChannelCreateRequest, timestamp: number): string {\n const data = `${request.chain}:${request.asset}:${request.payerAddress}:${request.payeeAddress}:${timestamp}`;\n // Simple hash for ID generation\n let hash = 0;\n for (let i = 0; i < data.length; i++) {\n const char = data.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash = hash & hash;\n }\n return `ch_${Math.abs(hash).toString(16).padStart(16, '0')}`;\n }\n\n /**\n * Calculate funding requirements for channel\n */\n private calculateFundingRequirements(channel: StreamingChannel): {\n amount: string;\n to: string;\n data?: string;\n } {\n const totalRequired = BigInt(channel.balance.total) + BigInt(channel.config.channelFee);\n\n return {\n amount: totalRequired.toString(),\n to: channel.contractAddress ?? channel.payee.address,\n data: this.encodeFundingData(channel),\n };\n }\n\n /**\n * Encode funding transaction data\n */\n private encodeFundingData(channel: StreamingChannel): string {\n // In production, this would encode the actual contract call\n // For now, return a placeholder representing the channel initialization\n const methodId = '0x' + 'initChannel'.split('').map(c => c.charCodeAt(0).toString(16)).join('').slice(0, 8);\n return `${methodId}${channel.id.replace('ch_', '').padStart(64, '0')}`;\n }\n}\n\n/**\n * Estimate channel duration based on rate\n */\nexport function estimateChannelDuration(\n depositAmount: string,\n ratePerSecond: string,\n): { seconds: number; formatted: string } {\n const deposit = BigInt(depositAmount);\n const rate = BigInt(ratePerSecond);\n\n if (rate === 0n) {\n return { seconds: Infinity, formatted: 'infinite' };\n }\n\n const seconds = Number(deposit / rate);\n\n // Format duration\n if (seconds < 60) {\n return { seconds, formatted: `${seconds} seconds` };\n } else if (seconds < 3600) {\n const minutes = Math.floor(seconds / 60);\n return { seconds, formatted: `${minutes} minutes` };\n } else if (seconds < 86400) {\n const hours = Math.floor(seconds / 3600);\n return { seconds, formatted: `${hours} hours` };\n } else {\n const days = Math.floor(seconds / 86400);\n return { seconds, formatted: `${days} days` };\n }\n}\n\n/**\n * Calculate required deposit for desired duration\n */\nexport function calculateRequiredDeposit(\n ratePerSecond: string,\n durationSeconds: number,\n): string {\n const rate = BigInt(ratePerSecond);\n const duration = BigInt(durationSeconds);\n return (rate * duration).toString();\n}\n","import {\n StreamingChannel,\n ChannelCheckpoint,\n ChannelCloseRequest,\n ChannelBalance,\n} from './types.js';\nimport { ChannelStateMachine } from './state.js';\n\n/**\n * Channel closing configuration\n */\nexport interface ChannelClosingConfig {\n challengePeriod?: number; // Default challenge period in seconds\n gracePeriod?: number; // Grace period for mutual close\n autoFinalize?: boolean; // Auto-finalize after challenge period\n}\n\n/**\n * Close initiation result\n */\nexport interface CloseInitiationResult {\n success: boolean;\n error?: string;\n challengeDeadline?: number;\n finalCheckpoint?: ChannelCheckpoint;\n settlementAmount?: {\n payer: string;\n payee: string;\n };\n}\n\n/**\n * Channel final settlement result\n */\nexport interface ChannelSettlementResult {\n success: boolean;\n error?: string;\n finalBalance: ChannelBalance;\n settlementTxHash?: string;\n gasCost?: string;\n}\n\n/**\n * Channel closer - handles channel closing and settlement\n */\nexport class ChannelCloser {\n private config: Required<ChannelClosingConfig>;\n\n constructor(config: ChannelClosingConfig = {}) {\n this.config = {\n challengePeriod: config.challengePeriod ?? 86400, // 24 hours\n gracePeriod: config.gracePeriod ?? 3600, // 1 hour\n autoFinalize: config.autoFinalize ?? true,\n };\n }\n\n /**\n * Initiate channel close\n */\n initiateClose(\n stateMachine: ChannelStateMachine,\n initiator: string,\n signature: string,\n ): CloseInitiationResult {\n const channel = stateMachine.getChannel();\n\n // Verify initiator is a participant\n if (initiator !== channel.payer.address && initiator !== channel.payee.address) {\n return { success: false, error: 'Initiator must be a channel participant' };\n }\n\n // Calculate final balances\n const currentStreamed = stateMachine.getCurrentStreamedAmount();\n const finalBalance = this.calculateFinalBalance(channel, currentStreamed);\n\n // Create final checkpoint\n const finalCheckpoint = this.createFinalCheckpoint(channel, finalBalance, signature);\n\n // Process state transition\n const result = stateMachine.process({\n type: 'INITIATE_CLOSE',\n initiator,\n });\n\n if (!result.success) {\n return { success: false, error: result.error };\n }\n\n // Add final checkpoint\n stateMachine.addCheckpoint(finalCheckpoint);\n\n const challengeDeadline = Date.now() + this.config.challengePeriod * 1000;\n\n return {\n success: true,\n challengeDeadline,\n finalCheckpoint,\n settlementAmount: {\n payer: finalBalance.payer,\n payee: finalBalance.payee,\n },\n };\n }\n\n /**\n * Complete mutual close (both parties agree)\n */\n mutualClose(\n stateMachine: ChannelStateMachine,\n payerSignature: string,\n payeeSignature: string,\n ): CloseInitiationResult {\n const channel = stateMachine.getChannel();\n\n // Calculate final balances\n const currentStreamed = stateMachine.getCurrentStreamedAmount();\n const finalBalance = this.calculateFinalBalance(channel, currentStreamed);\n\n // Create mutually signed checkpoint\n const finalCheckpoint: ChannelCheckpoint = {\n channelId: channel.id,\n sequence: channel.checkpoints.length,\n timestamp: Date.now(),\n balance: finalBalance,\n amountStreamed: currentStreamed,\n payerSignature,\n payeeSignature,\n };\n\n // For mutual close, skip challenge period\n let result = stateMachine.process({\n type: 'INITIATE_CLOSE',\n initiator: channel.payer.address,\n });\n\n if (!result.success) {\n return { success: false, error: result.error };\n }\n\n result = stateMachine.process({\n type: 'MUTUAL_CLOSE',\n signature: `${payerSignature}:${payeeSignature}`,\n });\n\n if (!result.success) {\n return { success: false, error: result.error };\n }\n\n stateMachine.addCheckpoint(finalCheckpoint);\n\n return {\n success: true,\n finalCheckpoint,\n settlementAmount: {\n payer: finalBalance.payer,\n payee: finalBalance.payee,\n },\n };\n }\n\n /**\n * Finalize channel after challenge period\n */\n finalize(\n stateMachine: ChannelStateMachine,\n ): ChannelSettlementResult {\n const channel = stateMachine.getChannel();\n\n if (channel.state !== 'closing') {\n return {\n success: false,\n error: 'Channel must be in closing state',\n finalBalance: channel.balance,\n };\n }\n\n // Check if challenge period has passed\n const latestCheckpoint = channel.latestCheckpoint;\n if (latestCheckpoint) {\n const elapsed = Date.now() - latestCheckpoint.timestamp;\n if (elapsed < this.config.challengePeriod * 1000) {\n return {\n success: false,\n error: 'Challenge period not yet elapsed',\n finalBalance: channel.balance,\n };\n }\n }\n\n // Process finalization\n const result = stateMachine.process({ type: 'FINALIZE' });\n\n if (!result.success) {\n return {\n success: false,\n error: result.error,\n finalBalance: channel.balance,\n };\n }\n\n const finalChannel = stateMachine.getChannel();\n\n return {\n success: true,\n finalBalance: finalChannel.balance,\n };\n }\n\n /**\n * Validate close request\n */\n validateCloseRequest(\n channel: StreamingChannel,\n request: ChannelCloseRequest,\n ): { valid: boolean; errors: string[] } {\n const errors: string[] = [];\n\n // Validate channel ID\n if (request.channelId !== channel.id) {\n errors.push('Channel ID mismatch');\n }\n\n // Validate initiator\n if (request.initiator !== channel.payer.address &&\n request.initiator !== channel.payee.address) {\n errors.push('Initiator is not a channel participant');\n }\n\n // Validate channel state\n if (channel.state !== 'open' && channel.state !== 'paused') {\n errors.push(`Cannot close channel in ${channel.state} state`);\n }\n\n // Validate checkpoint if provided\n if (request.finalCheckpoint) {\n const cpErrors = this.validateCheckpoint(channel, request.finalCheckpoint);\n errors.push(...cpErrors);\n }\n\n return { valid: errors.length === 0, errors };\n }\n\n /**\n * Get settlement amounts for on-chain execution\n */\n getSettlementAmounts(\n channel: StreamingChannel,\n ): { payer: string; payee: string; fee: string } {\n const finalBalance = channel.latestCheckpoint?.balance ?? channel.balance;\n const fee = channel.config.settlementFee;\n\n // Deduct fee from payer's remaining balance\n const payerAmount = BigInt(finalBalance.payer) - BigInt(fee);\n\n return {\n payer: payerAmount > 0n ? payerAmount.toString() : '0',\n payee: finalBalance.payee,\n fee,\n };\n }\n\n /**\n * Calculate time until channel can be finalized\n */\n getTimeUntilFinalization(channel: StreamingChannel): number {\n if (channel.state !== 'closing') {\n return -1;\n }\n\n const latestCheckpoint = channel.latestCheckpoint;\n if (!latestCheckpoint) {\n return 0;\n }\n\n const elapsed = Date.now() - latestCheckpoint.timestamp;\n const remaining = this.config.challengePeriod * 1000 - elapsed;\n\n return Math.max(0, remaining);\n }\n\n /**\n * Check if channel close can be challenged\n */\n canChallenge(channel: StreamingChannel): boolean {\n if (channel.state !== 'closing') {\n return false;\n }\n\n return this.getTimeUntilFinalization(channel) > 0;\n }\n\n private calculateFinalBalance(\n channel: StreamingChannel,\n amountStreamed: string,\n ): ChannelBalance {\n const total = BigInt(channel.balance.total);\n const streamed = BigInt(amountStreamed);\n const remaining = total - streamed;\n\n return {\n payer: remaining.toString(),\n payee: streamed.toString(),\n total: total.toString(),\n locked: '0',\n };\n }\n\n private createFinalCheckpoint(\n channel: StreamingChannel,\n balance: ChannelBalance,\n signature: string,\n ): ChannelCheckpoint {\n return {\n channelId: channel.id,\n sequence: channel.checkpoints.length,\n timestamp: Date.now(),\n balance,\n amountStreamed: balance.payee,\n payerSignature: signature,\n };\n }\n\n private validateCheckpoint(\n channel: StreamingChannel,\n checkpoint: ChannelCheckpoint,\n ): string[] {\n const errors: string[] = [];\n\n // Validate sequence number\n const expectedSequence = channel.checkpoints.length;\n if (checkpoint.sequence !== expectedSequence) {\n errors.push(`Invalid sequence: expected ${expectedSequence}, got ${checkpoint.sequence}`);\n }\n\n // Validate balance consistency\n const totalBalance = BigInt(checkpoint.balance.payer) + BigInt(checkpoint.balance.payee);\n if (totalBalance !== BigInt(channel.balance.total)) {\n errors.push('Balance inconsistency: payer + payee does not equal total');\n }\n\n // Validate timestamp\n if (checkpoint.timestamp > Date.now()) {\n errors.push('Checkpoint timestamp is in the future');\n }\n\n return errors;\n }\n}\n\n/**\n * Build on-chain close transaction data\n */\nexport function buildCloseTransactionData(\n channel: StreamingChannel,\n checkpoint: ChannelCheckpoint,\n): { to: string; data: string; value: string } {\n // In production, this would encode the actual contract call\n const methodId = '0x' + 'closeChannel'.split('').map(c => c.charCodeAt(0).toString(16)).join('').slice(0, 8);\n\n const data = [\n methodId,\n channel.id.replace('ch_', '').padStart(64, '0'),\n checkpoint.sequence.toString(16).padStart(64, '0'),\n checkpoint.payerSignature.replace('0x', '').padStart(128, '0'),\n ].join('');\n\n return {\n to: channel.contractAddress ?? channel.payee.address,\n data,\n value: '0',\n };\n}\n","import {\n StreamingChannel,\n ChannelCheckpoint,\n RecoveryData,\n FundingTransaction,\n ChannelDispute,\n StateTransition,\n ChannelState,\n} from './types.js';\nimport { ChannelStateMachine } from './state.js';\n\n/**\n * Recovery configuration\n */\nexport interface RecoveryConfig {\n maxCheckpointsToKeep?: number;\n verifySignatures?: boolean;\n onChainFallback?: boolean;\n}\n\n/**\n * Recovery result\n */\nexport interface RecoveryResult {\n success: boolean;\n error?: string;\n channel?: StreamingChannel;\n stateMachine?: ChannelStateMachine;\n recoveredFromCheckpoint?: ChannelCheckpoint;\n dataLoss?: boolean;\n}\n\n/**\n * Channel storage interface for recovery\n */\nexport interface IChannelStorage {\n getChannel(channelId: string): Promise<StreamingChannel | null>;\n getCheckpoints(channelId: string): Promise<ChannelCheckpoint[]>;\n getTransactions(channelId: string): Promise<FundingTransaction[]>;\n getDisputes(channelId: string): Promise<ChannelDispute[]>;\n getStateHistory(channelId: string): Promise<StateTransition[]>;\n}\n\n/**\n * Channel recovery manager\n */\nexport class ChannelRecovery {\n private config: Required<RecoveryConfig>;\n private storage?: IChannelStorage;\n\n constructor(config: RecoveryConfig = {}, storage?: IChannelStorage) {\n this.config = {\n maxCheckpointsToKeep: config.maxCheckpointsToKeep ?? 100,\n verifySignatures: config.verifySignatures ?? true,\n onChainFallback: config.onChainFallback ?? true,\n };\n this.storage = storage;\n }\n\n /**\n * Recover channel from checkpoints\n */\n recoverFromCheckpoints(\n baseChannel: StreamingChannel,\n checkpoints: ChannelCheckpoint[],\n ): RecoveryResult {\n if (checkpoints.length === 0) {\n return {\n success: true,\n channel: baseChannel,\n stateMachine: new ChannelStateMachine(baseChannel),\n dataLoss: false,\n };\n }\n\n // Sort checkpoints by sequence\n const sortedCheckpoints = [...checkpoints].sort((a, b) => a.sequence - b.sequence);\n\n // Find the latest valid checkpoint\n let latestValid: ChannelCheckpoint | undefined;\n\n for (let i = sortedCheckpoints.length - 1; i >= 0; i--) {\n const checkpoint = sortedCheckpoints[i];\n\n if (this.isCheckpointValid(baseChannel, checkpoint)) {\n latestValid = checkpoint;\n break;\n }\n }\n\n if (!latestValid) {\n return {\n success: false,\n error: 'No valid checkpoints found',\n dataLoss: true,\n };\n }\n\n // Reconstruct channel state from checkpoint\n const recoveredChannel = this.reconstructFromCheckpoint(baseChannel, latestValid, sortedCheckpoints);\n\n return {\n success: true,\n channel: recoveredChannel,\n stateMachine: new ChannelStateMachine(recoveredChannel),\n recoveredFromCheckpoint: latestValid,\n dataLoss: sortedCheckpoints[sortedCheckpoints.length - 1].sequence > latestValid.sequence,\n };\n }\n\n /**\n * Full recovery from storage\n */\n async recoverFromStorage(channelId: string): Promise<RecoveryResult> {\n if (!this.storage) {\n return {\n success: false,\n error: 'No storage provider configured',\n };\n }\n\n try {\n // Fetch all recovery data\n const [channel, checkpoints, transactions, disputes] = await Promise.all([\n this.storage.getChannel(channelId),\n this.storage.getCheckpoints(channelId),\n this.storage.getTransactions(channelId),\n this.storage.getDisputes(channelId),\n ]);\n\n if (!channel) {\n return {\n success: false,\n error: 'Channel not found in storage',\n };\n }\n\n // Use checkpoint recovery\n const result = this.recoverFromCheckpoints(channel, checkpoints);\n\n if (!result.success) {\n // Try on-chain fallback if enabled\n if (this.config.onChainFallback) {\n return this.recoverFromOnChain(channel, transactions, disputes);\n }\n return result;\n }\n\n return result;\n } catch (error) {\n return {\n success: false,\n error: `Storage recovery failed: ${error instanceof Error ? error.message : 'Unknown error'}`,\n };\n }\n }\n\n /**\n * Export recovery data for backup\n */\n exportRecoveryData(\n channel: StreamingChannel,\n stateMachine: ChannelStateMachine,\n ): RecoveryData {\n return {\n channelId: channel.id,\n checkpoints: channel.checkpoints,\n transactions: [], // Would be populated from transaction history\n disputes: [], // Would be populated from dispute history\n stateHistory: stateMachine.getTransitions(),\n recoveredAt: Date.now(),\n };\n }\n\n /**\n * Import recovery data\n */\n importRecoveryData(data: RecoveryData): RecoveryResult {\n // Validate recovery data\n if (!data.channelId || !data.checkpoints) {\n return {\n success: false,\n error: 'Invalid recovery data format',\n };\n }\n\n // Find the base channel state from first checkpoint or reconstruct\n if (data.checkpoints.length === 0) {\n return {\n success: false,\n error: 'No checkpoints in recovery data',\n };\n }\n\n // Create minimal base channel\n const baseChannel = this.createBaseChannelFromRecoveryData(data);\n\n return this.recoverFromCheckpoints(baseChannel, data.checkpoints);\n }\n\n /**\n * Verify checkpoint integrity\n */\n verifyCheckpointChain(checkpoints: ChannelCheckpoint[]): {\n valid: boolean;\n errors: string[];\n } {\n const errors: string[] = [];\n\n if (checkpoints.length === 0) {\n return { valid: true, errors: [] };\n }\n\n const sorted = [...checkpoints].sort((a, b) => a.sequence - b.sequence);\n\n for (let i = 0; i < sorted.length; i++) {\n const current = sorted[i];\n\n // Check sequence\n if (current.sequence !== i) {\n errors.push(`Sequence gap: expected ${i}, got ${current.sequence}`);\n }\n\n // Check timestamp ordering\n if (i > 0 && current.timestamp < sorted[i - 1].timestamp) {\n errors.push(`Timestamp ordering violation at sequence ${current.sequence}`);\n }\n\n // Check amount monotonicity (streamed amount should only increase)\n if (i > 0) {\n const prevStreamed = BigInt(sorted[i - 1].amountStreamed);\n const currStreamed = BigInt(current.amountStreamed);\n if (currStreamed < prevStreamed) {\n errors.push(`Amount decreased at sequence ${current.sequence}`);\n }\n }\n }\n\n return { valid: errors.length === 0, errors };\n }\n\n /**\n * Prune old checkpoints keeping only recent ones\n */\n pruneCheckpoints(checkpoints: ChannelCheckpoint[]): ChannelCheckpoint[] {\n if (checkpoints.length <= this.config.maxCheckpointsToKeep) {\n return checkpoints;\n }\n\n // Keep first checkpoint (genesis), last N-1 checkpoints\n const sorted = [...checkpoints].sort((a, b) => a.sequence - b.sequence);\n const genesis = sorted[0];\n const recent = sorted.slice(-(this.config.maxCheckpointsToKeep - 1));\n\n return [genesis, ...recent];\n }\n\n private isCheckpointValid(\n channel: StreamingChannel,\n checkpoint: ChannelCheckpoint,\n ): boolean {\n // Validate channel ID\n if (checkpoint.channelId !== channel.id) {\n return false;\n }\n\n // Validate balance totals\n const total = BigInt(checkpoint.balance.payer) + BigInt(checkpoint.balance.payee);\n if (total !== BigInt(channel.balance.total)) {\n return false;\n }\n\n // Validate signature presence\n if (!checkpoint.payerSignature) {\n return false;\n }\n\n // In production, would verify cryptographic signatures\n if (this.config.verifySignatures) {\n // Signature verification would happen here\n }\n\n return true;\n }\n\n private reconstructFromCheckpoint(\n baseChannel: StreamingChannel,\n checkpoint: ChannelCheckpoint,\n allCheckpoints: ChannelCheckpoint[],\n ): StreamingChannel {\n // Filter checkpoints up to and including the recovery point\n const validCheckpoints = allCheckpoints.filter(cp => cp.sequence <= checkpoint.sequence);\n\n // Determine state based on checkpoint\n let state: ChannelState = 'open';\n if (checkpoint.payeeSignature) {\n // Mutual checkpoint might indicate closing\n state = 'open';\n }\n\n return {\n ...baseChannel,\n state,\n balance: checkpoint.balance,\n checkpoints: validCheckpoints,\n latestCheckpoint: checkpoint,\n updatedAt: checkpoint.timestamp,\n };\n }\n\n private recoverFromOnChain(\n channel: StreamingChannel,\n transactions: FundingTransaction[],\n disputes: ChannelDispute[],\n ): RecoveryResult {\n // Reconstruct state from on-chain data\n const confirmedTxs = transactions.filter(tx => tx.confirmed);\n\n if (confirmedTxs.length === 0) {\n return {\n success: false,\n error: 'No confirmed transactions found',\n dataLoss: true,\n };\n }\n\n // Calculate total funded amount\n const totalFunded = confirmedTxs.reduce(\n (sum, tx) => sum + BigInt(tx.amount),\n 0n,\n );\n\n // Check for active disputes\n const activeDispute = disputes.find(d => d.status === 'pending');\n\n let state: ChannelState = 'open';\n if (activeDispute) {\n state = 'disputing';\n }\n\n const recoveredChannel: StreamingChannel = {\n ...channel,\n state,\n balance: {\n ...channel.balance,\n total: totalFunded.toString(),\n payer: totalFunded.toString(),\n payee: '0',\n },\n fundingTxHash: confirmedTxs[0].txHash,\n checkpoints: [],\n updatedAt: Date.now(),\n };\n\n return {\n success: true,\n channel: recoveredChannel,\n stateMachine: new ChannelStateMachine(recoveredChannel),\n dataLoss: true,\n };\n }\n\n private createBaseChannelFromRecoveryData(data: RecoveryData): StreamingChannel {\n const firstCheckpoint = data.checkpoints[0];\n\n return {\n id: data.channelId,\n state: 'open',\n chain: '',\n asset: '',\n payer: { address: '', role: 'payer' },\n payee: { address: '', role: 'payee' },\n balance: firstCheckpoint.balance,\n ratePerSecond: '0',\n config: {\n minDeposit: '0',\n challengePeriod: 86400,\n checkpointInterval: 3600,\n minCheckpointAmount: '0',\n channelFee: '0',\n settlementFee: '0',\n },\n checkpoints: [],\n createdAt: firstCheckpoint.timestamp,\n updatedAt: firstCheckpoint.timestamp,\n };\n }\n}\n\n/**\n * Create a state snapshot for backup\n */\nexport function createStateSnapshot(\n _channel: StreamingChannel,\n stateMachine: ChannelStateMachine,\n): string {\n const snapshot = {\n version: 1,\n channel: stateMachine.getChannel(),\n transitions: stateMachine.getTransitions(),\n timestamp: Date.now(),\n };\n\n return JSON.stringify(snapshot);\n}\n\n/**\n * Restore from state snapshot\n */\nexport function restoreFromSnapshot(\n snapshotJson: string,\n): RecoveryResult {\n try {\n const snapshot = JSON.parse(snapshotJson);\n\n if (snapshot.version !== 1) {\n return {\n success: false,\n error: 'Unsupported snapshot version',\n };\n }\n\n const channel = snapshot.channel as StreamingChannel;\n const stateMachine = new ChannelStateMachine(channel);\n\n return {\n success: true,\n channel,\n stateMachine,\n dataLoss: false,\n };\n } catch (error) {\n return {\n success: false,\n error: `Failed to parse snapshot: ${error instanceof Error ? error.message : 'Unknown error'}`,\n };\n }\n}\n","import { z } from 'zod';\n\n/**\n * Stream state\n */\nexport const StreamState = z.enum([\n 'idle', // Stream not started\n 'active', // Streaming in progress\n 'paused', // Temporarily paused\n 'completed', // Stream completed (exhausted)\n 'cancelled', // Stream cancelled\n]);\nexport type StreamState = z.infer<typeof StreamState>;\n\n/**\n * Rate type\n */\nexport const RateType = z.enum([\n 'fixed', // Fixed rate per second\n 'variable', // Rate can change\n 'tiered', // Different rates based on usage\n 'dynamic', // Demand-based pricing\n]);\nexport type RateType = z.infer<typeof RateType>;\n\n/**\n * Stream rate configuration\n */\nexport const StreamRate = z.object({\n type: RateType,\n baseRate: z.string(), // Base rate per second\n minRate: z.string().optional(), // Minimum rate\n maxRate: z.string().optional(), // Maximum rate\n // For tiered rates\n tiers: z.array(z.object({\n threshold: z.string(), // Usage threshold\n rate: z.string(), // Rate after threshold\n })).optional(),\n // For dynamic rates\n adjustmentInterval: z.number().optional(), // How often to adjust (seconds)\n adjustmentFactor: z.number().optional(), // Max adjustment per interval\n});\nexport type StreamRate = z.infer<typeof StreamRate>;\n\n/**\n * Usage metrics\n */\nexport const UsageMetrics = z.object({\n totalSeconds: z.number(),\n totalAmount: z.string(),\n averageRate: z.string(),\n peakRate: z.string(),\n startTime: z.number(),\n endTime: z.number().optional(),\n // Breakdown by period\n hourly: z.array(z.object({\n hour: z.number(),\n amount: z.string(),\n seconds: z.number(),\n })).optional(),\n});\nexport type UsageMetrics = z.infer<typeof UsageMetrics>;\n\n/**\n * Metering record\n */\nexport const MeteringRecord = z.object({\n timestamp: z.number(),\n duration: z.number(), // Seconds since last record\n amount: z.string(), // Amount for this period\n rate: z.string(), // Rate applied\n cumulative: z.string(), // Cumulative total\n metadata: z.record(z.unknown()).optional(),\n});\nexport type MeteringRecord = z.infer<typeof MeteringRecord>;\n\n/**\n * Billing period\n */\nexport const BillingPeriod = z.enum([\n 'realtime', // Continuous real-time billing\n 'second', // Per-second\n 'minute', // Per-minute\n 'hour', // Per-hour\n 'day', // Per-day\n]);\nexport type BillingPeriod = z.infer<typeof BillingPeriod>;\n\n/**\n * Billing configuration\n */\nexport const BillingConfig = z.object({\n period: BillingPeriod,\n minimumCharge: z.string().default('0'),\n roundingMode: z.enum(['floor', 'ceil', 'round']).default('floor'),\n gracePeriod: z.number().default(0), // Seconds of free usage\n invoiceInterval: z.number().optional(), // Generate invoice every N seconds\n});\nexport type BillingConfig = z.infer<typeof BillingConfig>;\n\n/**\n * Invoice item\n */\nexport const InvoiceItem = z.object({\n description: z.string(),\n quantity: z.number(), // Duration in billing periods\n rate: z.string(),\n amount: z.string(),\n startTime: z.number(),\n endTime: z.number(),\n});\nexport type InvoiceItem = z.infer<typeof InvoiceItem>;\n\n/**\n * Invoice\n */\nexport const Invoice = z.object({\n id: z.string(),\n channelId: z.string(),\n payer: z.string(),\n payee: z.string(),\n items: z.array(InvoiceItem),\n subtotal: z.string(),\n fees: z.string(),\n total: z.string(),\n currency: z.string(),\n status: z.enum(['pending', 'paid', 'settled', 'disputed']),\n createdAt: z.number(),\n dueAt: z.number().optional(),\n paidAt: z.number().optional(),\n});\nexport type Invoice = z.infer<typeof Invoice>;\n\n/**\n * Stream session\n */\nexport const StreamSession = z.object({\n id: z.string(),\n channelId: z.string(),\n state: StreamState,\n rate: StreamRate,\n startedAt: z.number().optional(),\n pausedAt: z.number().optional(),\n endedAt: z.number().optional(),\n totalDuration: z.number(), // Total streaming seconds\n totalAmount: z.string(), // Total amount streamed\n meteringRecords: z.array(MeteringRecord),\n billingConfig: BillingConfig,\n invoices: z.array(z.string()), // Invoice IDs\n});\nexport type StreamSession = z.infer<typeof StreamSession>;\n\n/**\n * Rate adjustment request\n */\nexport const RateAdjustmentRequest = z.object({\n sessionId: z.string(),\n newRate: z.string(),\n reason: z.string(),\n effectiveFrom: z.number().optional(), // Timestamp, default now\n signature: z.string().optional(), // For mutual rate changes\n});\nexport type RateAdjustmentRequest = z.infer<typeof RateAdjustmentRequest>;\n\n/**\n * Stream event\n */\nexport const StreamEvent = z.discriminatedUnion('type', [\n z.object({\n type: z.literal('started'),\n sessionId: z.string(),\n timestamp: z.number(),\n rate: z.string(),\n }),\n z.object({\n type: z.literal('paused'),\n sessionId: z.string(),\n timestamp: z.number(),\n totalStreamed: z.string(),\n }),\n z.object({\n type: z.literal('resumed'),\n sessionId: z.string(),\n timestamp: z.number(),\n }),\n z.object({\n type: z.literal('rate_changed'),\n sessionId: z.string(),\n timestamp: z.number(),\n oldRate: z.string(),\n newRate: z.string(),\n }),\n z.object({\n type: z.literal('checkpoint'),\n sessionId: z.string(),\n timestamp: z.number(),\n amount: z.string(),\n checkpointId: z.string(),\n }),\n z.object({\n type: z.literal('completed'),\n sessionId: z.string(),\n timestamp: z.number(),\n totalAmount: z.string(),\n totalDuration: z.number(),\n }),\n z.object({\n type: z.literal('cancelled'),\n sessionId: z.string(),\n timestamp: z.number(),\n reason: z.string(),\n }),\n]);\nexport type StreamEvent = z.infer<typeof StreamEvent>;\n","import {\n StreamSession,\n StreamState,\n StreamRate,\n StreamEvent,\n BillingConfig,\n MeteringRecord,\n} from './types.js';\n\n/**\n * Flow controller configuration\n */\nexport interface FlowConfig {\n updateInterval?: number; // How often to update state (ms)\n bufferTime?: number; // Buffer time before exhaustion (seconds)\n autoCheckpoint?: boolean; // Auto-create checkpoints\n checkpointInterval?: number; // Checkpoint interval (seconds)\n}\n\n/**\n * Flow controller for managing streaming sessions\n */\nexport class FlowController {\n private session: StreamSession;\n private config: Required<FlowConfig>;\n private updateTimer?: ReturnType<typeof setInterval>;\n private checkpointTimer?: ReturnType<typeof setInterval>;\n private eventListeners: Set<(event: StreamEvent) => void> = new Set();\n private lastUpdateTime: number = 0;\n\n constructor(\n channelId: string,\n rate: StreamRate,\n billingConfig: BillingConfig,\n config: FlowConfig = {},\n ) {\n this.config = {\n updateInterval: config.updateInterval ?? 1000,\n bufferTime: config.bufferTime ?? 60,\n autoCheckpoint: config.autoCheckpoint ?? true,\n checkpointInterval: config.checkpointInterval ?? 3600,\n };\n\n this.session = {\n id: this.generateSessionId(),\n channelId,\n state: 'idle',\n rate,\n totalDuration: 0,\n totalAmount: '0',\n meteringRecords: [],\n billingConfig,\n invoices: [],\n };\n }\n\n /**\n * Get current session state\n */\n getSession(): StreamSession {\n return { ...this.session };\n }\n\n /**\n * Get current state\n */\n getState(): StreamState {\n return this.session.state;\n }\n\n /**\n * Start streaming\n */\n start(): { success: boolean; error?: string } {\n if (this.session.state !== 'idle' && this.session.state !== 'paused') {\n return { success: false, error: 'Stream must be idle or paused to start' };\n }\n\n const now = Date.now();\n\n if (this.session.state === 'idle') {\n this.session.startedAt = now;\n } else {\n // Resuming from pause - add pause duration to account for gap\n const pauseDuration = now - (this.session.pausedAt ?? now);\n this.session.pausedAt = undefined;\n\n // Log the pause duration in metering\n this.addMeteringRecord({\n timestamp: now,\n duration: 0,\n amount: '0',\n rate: '0',\n cumulative: this.session.totalAmount,\n metadata: { event: 'resume', pauseDuration },\n });\n }\n\n this.session.state = 'active';\n this.lastUpdateTime = now;\n\n // Start update timer\n this.startUpdateTimer();\n\n // Start checkpoint timer if enabled\n if (this.config.autoCheckpoint) {\n this.startCheckpointTimer();\n }\n\n this.emitEvent({\n type: 'started',\n sessionId: this.session.id,\n timestamp: now,\n rate: this.session.rate.baseRate,\n });\n\n return { success: true };\n }\n\n /**\n * Pause streaming\n */\n pause(): { success: boolean; error?: string } {\n if (this.session.state !== 'active') {\n return { success: false, error: 'Stream must be active to pause' };\n }\n\n const now = Date.now();\n\n // Update totals before pausing\n this.updateTotals(now);\n\n this.session.state = 'paused';\n this.session.pausedAt = now;\n\n // Stop timers\n this.stopTimers();\n\n this.emitEvent({\n type: 'paused',\n sessionId: this.session.id,\n timestamp: now,\n totalStreamed: this.session.totalAmount,\n });\n\n return { success: true };\n }\n\n /**\n * Resume streaming (alias for start when paused)\n */\n resume(): { success: boolean; error?: string } {\n if (this.session.state !== 'paused') {\n return { success: false, error: 'Stream must be paused to resume' };\n }\n\n const result = this.start();\n\n if (result.success) {\n this.emitEvent({\n type: 'resumed',\n sessionId: this.session.id,\n timestamp: Date.now(),\n });\n }\n\n return result;\n }\n\n /**\n * Stop streaming (complete)\n */\n stop(): { success: boolean; error?: string; finalAmount: string } {\n const now = Date.now();\n\n if (this.session.state === 'active') {\n this.updateTotals(now);\n }\n\n this.stopTimers();\n\n this.session.state = 'completed';\n this.session.endedAt = now;\n\n this.emitEvent({\n type: 'completed',\n sessionId: this.session.id,\n timestamp: now,\n totalAmount: this.session.totalAmount,\n totalDuration: this.session.totalDuration,\n });\n\n return {\n success: true,\n finalAmount: this.session.totalAmount,\n };\n }\n\n /**\n * Cancel streaming\n */\n cancel(reason: string): { success: boolean; error?: string } {\n const now = Date.now();\n\n if (this.session.state === 'active') {\n this.updateTotals(now);\n }\n\n this.stopTimers();\n\n this.session.state = 'cancelled';\n this.session.endedAt = now;\n\n this.emitEvent({\n type: 'cancelled',\n sessionId: this.session.id,\n timestamp: now,\n reason,\n });\n\n return { success: true };\n }\n\n /**\n * Get current streamed amount\n */\n getCurrentAmount(): string {\n if (this.session.state !== 'active') {\n return this.session.totalAmount;\n }\n\n const now = Date.now();\n const elapsed = Math.floor((now - this.lastUpdateTime) / 1000);\n const additionalAmount = this.calculateAmount(elapsed, this.session.rate);\n\n return (BigInt(this.session.totalAmount) + BigInt(additionalAmount)).toString();\n }\n\n /**\n * Get current rate\n */\n getCurrentRate(): string {\n return this.getEffectiveRate(this.session.rate, this.session.totalAmount);\n }\n\n /**\n * Get time until exhaustion (returns -1 if infinite)\n */\n getTimeUntilExhaustion(channelCapacity: string): number {\n if (this.session.state !== 'active') {\n return -1;\n }\n\n const remaining = BigInt(channelCapacity) - BigInt(this.getCurrentAmount());\n if (remaining <= 0n) {\n return 0;\n }\n\n const rate = BigInt(this.getCurrentRate());\n if (rate <= 0n) {\n return -1;\n }\n\n return Number(remaining / rate);\n }\n\n /**\n * Check if stream is near exhaustion\n */\n isNearExhaustion(channelCapacity: string): boolean {\n const remaining = this.getTimeUntilExhaustion(channelCapacity);\n return remaining >= 0 && remaining <= this.config.bufferTime;\n }\n\n /**\n * Create manual checkpoint\n */\n createCheckpoint(): { id: string; amount: string; timestamp: number } {\n const now = Date.now();\n const amount = this.getCurrentAmount();\n const checkpointId = `cp_${this.session.id}_${now}`;\n\n this.emitEvent({\n type: 'checkpoint',\n sessionId: this.session.id,\n timestamp: now,\n amount,\n checkpointId,\n });\n\n return { id: checkpointId, amount, timestamp: now };\n }\n\n /**\n * Subscribe to stream events\n */\n onEvent(callback: (event: StreamEvent) => void): () => void {\n this.eventListeners.add(callback);\n return () => this.eventListeners.delete(callback);\n }\n\n /**\n * Clean up resources\n */\n destroy(): void {\n this.stopTimers();\n this.eventListeners.clear();\n }\n\n private startUpdateTimer(): void {\n this.updateTimer = setInterval(() => {\n if (this.session.state === 'active') {\n this.updateTotals(Date.now());\n }\n }, this.config.updateInterval);\n }\n\n private startCheckpointTimer(): void {\n this.checkpointTimer = setInterval(() => {\n if (this.session.state === 'active') {\n this.createCheckpoint();\n }\n }, this.config.checkpointInterval * 1000);\n }\n\n private stopTimers(): void {\n if (this.updateTimer) {\n clearInterval(this.updateTimer);\n this.updateTimer = undefined;\n }\n if (this.checkpointTimer) {\n clearInterval(this.checkpointTimer);\n this.checkpointTimer = undefined;\n }\n }\n\n private updateTotals(now: number): void {\n const elapsed = Math.floor((now - this.lastUpdateTime) / 1000);\n if (elapsed <= 0) return;\n\n const amount = this.calculateAmount(elapsed, this.session.rate);\n const newTotal = BigInt(this.session.totalAmount) + BigInt(amount);\n\n this.session.totalDuration += elapsed;\n this.session.totalAmount = newTotal.toString();\n this.lastUpdateTime = now;\n\n // Add metering record\n this.addMeteringRecord({\n timestamp: now,\n duration: elapsed,\n amount,\n rate: this.getCurrentRate(),\n cumulative: this.session.totalAmount,\n });\n }\n\n private calculateAmount(seconds: number, rate: StreamRate): string {\n const effectiveRate = this.getEffectiveRate(rate, this.session.totalAmount);\n return (BigInt(effectiveRate) * BigInt(seconds)).toString();\n }\n\n private getEffectiveRate(rate: StreamRate, totalAmount: string): string {\n if (rate.type === 'fixed') {\n return rate.baseRate;\n }\n\n if (rate.type === 'tiered' && rate.tiers) {\n // Find applicable tier\n const amount = BigInt(totalAmount);\n let applicableRate = rate.baseRate;\n\n for (const tier of rate.tiers) {\n if (amount >= BigInt(tier.threshold)) {\n applicableRate = tier.rate;\n }\n }\n\n return applicableRate;\n }\n\n // For variable and dynamic, return base rate\n // Real implementation would have more sophisticated logic\n return rate.baseRate;\n }\n\n private addMeteringRecord(record: MeteringRecord): void {\n this.session.meteringRecords.push(record);\n\n // Keep only last 1000 records to prevent memory bloat\n if (this.session.meteringRecords.length > 1000) {\n this.session.meteringRecords = this.session.meteringRecords.slice(-1000);\n }\n }\n\n private emitEvent(event: StreamEvent): void {\n this.eventListeners.forEach(callback => {\n try {\n callback(event);\n } catch {\n // Ignore listener errors\n }\n });\n }\n\n private generateSessionId(): string {\n return `ss_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;\n }\n}\n\n/**\n * Create a simple fixed-rate flow controller\n */\nexport function createFixedRateFlow(\n channelId: string,\n ratePerSecond: string,\n config?: FlowConfig,\n): FlowController {\n const rate: StreamRate = {\n type: 'fixed',\n baseRate: ratePerSecond,\n };\n\n const billingConfig = {\n period: 'realtime' as const,\n minimumCharge: '0',\n roundingMode: 'floor' as const,\n gracePeriod: 0,\n };\n\n return new FlowController(channelId, rate, billingConfig, config);\n}\n\n/**\n * Create a tiered rate flow controller\n */\nexport function createTieredRateFlow(\n channelId: string,\n baseRate: string,\n tiers: Array<{ threshold: string; rate: string }>,\n config?: FlowConfig,\n): FlowController {\n const rate: StreamRate = {\n type: 'tiered',\n baseRate,\n tiers,\n };\n\n const billingConfig = {\n period: 'realtime' as const,\n minimumCharge: '0',\n roundingMode: 'floor' as const,\n gracePeriod: 0,\n };\n\n return new FlowController(channelId, rate, billingConfig, config);\n}\n","import {\n StreamRate,\n RateAdjustmentRequest,\n} from './types.js';\n\n/**\n * Rate controller configuration\n */\nexport interface RateControllerConfig {\n maxChangePercent?: number; // Max rate change per adjustment (percentage)\n minChangeInterval?: number; // Minimum time between changes (seconds)\n smoothingFactor?: number; // For dynamic rates (0-1)\n}\n\n/**\n * Rate history entry\n */\nexport interface RateHistoryEntry {\n timestamp: number;\n rate: string;\n reason: string;\n previousRate: string;\n}\n\n/**\n * Rate controller for managing and adjusting streaming rates\n */\nexport class RateController {\n private currentRate: StreamRate;\n private config: Required<RateControllerConfig>;\n private history: RateHistoryEntry[] = [];\n private lastChangeTime: number = 0;\n\n constructor(\n initialRate: StreamRate,\n config: RateControllerConfig = {},\n ) {\n this.currentRate = { ...initialRate };\n this.config = {\n maxChangePercent: config.maxChangePercent ?? 50,\n minChangeInterval: config.minChangeInterval ?? 60,\n smoothingFactor: config.smoothingFactor ?? 0.3,\n };\n }\n\n /**\n * Get current rate configuration\n */\n getRate(): StreamRate {\n return { ...this.currentRate };\n }\n\n /**\n * Get current effective rate\n */\n getEffectiveRate(totalUsage?: string): string {\n if (this.currentRate.type === 'fixed') {\n return this.currentRate.baseRate;\n }\n\n if (this.currentRate.type === 'tiered' && this.currentRate.tiers && totalUsage) {\n return this.calculateTieredRate(totalUsage);\n }\n\n return this.currentRate.baseRate;\n }\n\n /**\n * Request rate adjustment\n */\n adjustRate(request: RateAdjustmentRequest): {\n success: boolean;\n error?: string;\n newRate?: string;\n adjustedAmount?: string;\n } {\n const now = Date.now();\n\n // Check minimum interval\n const timeSinceLastChange = (now - this.lastChangeTime) / 1000;\n if (timeSinceLastChange < this.config.minChangeInterval) {\n return {\n success: false,\n error: `Rate can only be changed every ${this.config.minChangeInterval} seconds`,\n };\n }\n\n // Validate new rate\n const newRateBigInt = BigInt(request.newRate);\n if (newRateBigInt <= 0n) {\n return { success: false, error: 'Rate must be positive' };\n }\n\n // Check rate bounds\n if (this.currentRate.minRate && newRateBigInt < BigInt(this.currentRate.minRate)) {\n return {\n success: false,\n error: `Rate cannot be below minimum: ${this.currentRate.minRate}`,\n };\n }\n\n if (this.currentRate.maxRate && newRateBigInt > BigInt(this.currentRate.maxRate)) {\n return {\n success: false,\n error: `Rate cannot exceed maximum: ${this.currentRate.maxRate}`,\n };\n }\n\n // Check max change percentage\n const currentRateBigInt = BigInt(this.currentRate.baseRate);\n const changePercent = this.calculateChangePercent(currentRateBigInt, newRateBigInt);\n\n let adjustedRate = request.newRate;\n\n if (changePercent > this.config.maxChangePercent) {\n // Apply max change limit\n adjustedRate = this.applyMaxChange(\n currentRateBigInt,\n newRateBigInt,\n this.config.maxChangePercent,\n );\n }\n\n // Record history\n this.history.push({\n timestamp: now,\n rate: adjustedRate,\n reason: request.reason,\n previousRate: this.currentRate.baseRate,\n });\n\n // Update rate\n this.currentRate.baseRate = adjustedRate;\n this.lastChangeTime = now;\n\n return {\n success: true,\n newRate: adjustedRate,\n adjustedAmount: adjustedRate !== request.newRate ? adjustedRate : undefined,\n };\n }\n\n /**\n * Set rate bounds\n */\n setBounds(minRate?: string, maxRate?: string): void {\n if (minRate !== undefined) {\n this.currentRate.minRate = minRate;\n }\n if (maxRate !== undefined) {\n this.currentRate.maxRate = maxRate;\n }\n }\n\n /**\n * Add or update a tier\n */\n addTier(threshold: string, rate: string): void {\n if (this.currentRate.type !== 'tiered') {\n this.currentRate.type = 'tiered';\n this.currentRate.tiers = [];\n }\n\n const tiers = this.currentRate.tiers ?? [];\n const existingIndex = tiers.findIndex(t => t.threshold === threshold);\n\n if (existingIndex >= 0) {\n tiers[existingIndex].rate = rate;\n } else {\n tiers.push({ threshold, rate });\n // Sort by threshold\n tiers.sort((a, b) => {\n return BigInt(a.threshold) < BigInt(b.threshold) ? -1 : 1;\n });\n }\n\n this.currentRate.tiers = tiers;\n }\n\n /**\n * Remove a tier\n */\n removeTier(threshold: string): boolean {\n if (!this.currentRate.tiers) return false;\n\n const initialLength = this.currentRate.tiers.length;\n this.currentRate.tiers = this.currentRate.tiers.filter(\n t => t.threshold !== threshold,\n );\n\n return this.currentRate.tiers.length < initialLength;\n }\n\n /**\n * Get rate history\n */\n getHistory(): RateHistoryEntry[] {\n return [...this.history];\n }\n\n /**\n * Calculate average rate over time period\n */\n getAverageRate(startTime: number, endTime: number): string {\n const relevantHistory = this.history.filter(\n h => h.timestamp >= startTime && h.timestamp <= endTime,\n );\n\n if (relevantHistory.length === 0) {\n return this.currentRate.baseRate;\n }\n\n // Weight-average by time\n let totalWeight = 0n;\n let weightedSum = 0n;\n let prevTime = startTime;\n\n for (const entry of relevantHistory) {\n const duration = BigInt(entry.timestamp - prevTime);\n weightedSum += BigInt(entry.previousRate) * duration;\n totalWeight += duration;\n prevTime = entry.timestamp;\n }\n\n // Add final period\n const finalDuration = BigInt(endTime - prevTime);\n weightedSum += BigInt(this.currentRate.baseRate) * finalDuration;\n totalWeight += finalDuration;\n\n if (totalWeight === 0n) {\n return this.currentRate.baseRate;\n }\n\n return (weightedSum / totalWeight).toString();\n }\n\n /**\n * Calculate rate for dynamic pricing based on demand\n */\n calculateDynamicRate(\n demand: number, // 0-1 representing demand level\n _baseRate?: string,\n ): string {\n const base = BigInt(this.currentRate.baseRate);\n const min = this.currentRate.minRate ? BigInt(this.currentRate.minRate) : base / 2n;\n const max = this.currentRate.maxRate ? BigInt(this.currentRate.maxRate) : base * 2n;\n\n // Linear interpolation based on demand\n const range = max - min;\n const adjustment = BigInt(Math.floor(Number(range) * demand));\n\n return (min + adjustment).toString();\n }\n\n /**\n * Apply exponential smoothing for rate changes\n */\n smoothRate(targetRate: string): string {\n const current = BigInt(this.currentRate.baseRate);\n const target = BigInt(targetRate);\n const alpha = this.config.smoothingFactor;\n\n // Exponential smoothing: new = alpha * target + (1 - alpha) * current\n const smoothed = BigInt(Math.floor(\n alpha * Number(target) + (1 - alpha) * Number(current),\n ));\n\n return smoothed.toString();\n }\n\n private calculateTieredRate(totalUsage: string): string {\n const usage = BigInt(totalUsage);\n const tiers = this.currentRate.tiers ?? [];\n\n // Find the highest applicable tier\n let applicableRate = this.currentRate.baseRate;\n\n for (const tier of tiers) {\n if (usage >= BigInt(tier.threshold)) {\n applicableRate = tier.rate;\n }\n }\n\n return applicableRate;\n }\n\n private calculateChangePercent(from: bigint, to: bigint): number {\n if (from === 0n) return 100;\n const diff = to > from ? to - from : from - to;\n return Number((diff * 100n) / from);\n }\n\n private applyMaxChange(from: bigint, to: bigint, maxPercent: number): string {\n const maxChange = (from * BigInt(maxPercent)) / 100n;\n\n if (to > from) {\n return (from + maxChange).toString();\n } else {\n return (from - maxChange).toString();\n }\n }\n}\n\n/**\n * Rate limiter for preventing abuse\n */\nexport class RateLimiter {\n private requests: Map<string, number[]> = new Map();\n private maxRequests: number;\n private windowMs: number;\n\n constructor(maxRequests: number = 10, windowMs: number = 60000) {\n this.maxRequests = maxRequests;\n this.windowMs = windowMs;\n }\n\n /**\n * Check if request is allowed\n */\n isAllowed(key: string): boolean {\n const now = Date.now();\n const windowStart = now - this.windowMs;\n\n // Get requests for this key\n let requests = this.requests.get(key) ?? [];\n\n // Filter to only requests in current window\n requests = requests.filter(t => t > windowStart);\n\n if (requests.length >= this.maxRequests) {\n return false;\n }\n\n // Add current request\n requests.push(now);\n this.requests.set(key, requests);\n\n return true;\n }\n\n /**\n * Get remaining requests in window\n */\n getRemainingRequests(key: string): number {\n const now = Date.now();\n const windowStart = now - this.windowMs;\n\n const requests = (this.requests.get(key) ?? []).filter(t => t > windowStart);\n return Math.max(0, this.maxRequests - requests.length);\n }\n\n /**\n * Reset limits for a key\n */\n reset(key: string): void {\n this.requests.delete(key);\n }\n\n /**\n * Clear all limits\n */\n clear(): void {\n this.requests.clear();\n }\n}\n\n/**\n * Calculate optimal rate based on channel parameters\n */\nexport function calculateOptimalRate(\n channelCapacity: string,\n desiredDurationSeconds: number,\n bufferPercent: number = 10,\n): string {\n const capacity = BigInt(channelCapacity);\n const duration = BigInt(desiredDurationSeconds);\n\n if (duration === 0n) {\n return '0';\n }\n\n // Apply buffer (reduce effective capacity)\n const effectiveCapacity = (capacity * BigInt(100 - bufferPercent)) / 100n;\n\n return (effectiveCapacity / duration).toString();\n}\n\n/**\n * Convert rate between time units\n */\nexport function convertRate(\n rate: string,\n fromUnit: 'second' | 'minute' | 'hour' | 'day',\n toUnit: 'second' | 'minute' | 'hour' | 'day',\n): string {\n const unitToSeconds: Record<string, number> = {\n second: 1,\n minute: 60,\n hour: 3600,\n day: 86400,\n };\n\n const fromSeconds = unitToSeconds[fromUnit];\n const toSeconds = unitToSeconds[toUnit];\n\n const rateBigInt = BigInt(rate);\n const perSecond = rateBigInt / BigInt(fromSeconds);\n\n return (perSecond * BigInt(toSeconds)).toString();\n}\n","import {\n MeteringRecord,\n UsageMetrics,\n} from './types.js';\n\n/**\n * Metering configuration\n */\nexport interface MeteringConfig {\n recordInterval?: number; // Record every N seconds\n aggregationInterval?: number; // Aggregate records every N seconds\n maxRecords?: number; // Maximum records to keep\n precision?: number; // Decimal precision for amounts\n}\n\n/**\n * Aggregated usage data\n */\nexport interface AggregatedUsage {\n period: string; // ISO timestamp of period start\n totalAmount: string;\n totalDuration: number;\n averageRate: string;\n recordCount: number;\n}\n\n/**\n * Metering manager for tracking usage\n */\nexport class MeteringManager {\n private records: MeteringRecord[] = [];\n private config: Required<MeteringConfig>;\n private sessionId: string;\n private startTime: number;\n\n constructor(sessionId: string, config: MeteringConfig = {}) {\n this.sessionId = sessionId;\n this.startTime = Date.now();\n this.config = {\n recordInterval: config.recordInterval ?? 1,\n aggregationInterval: config.aggregationInterval ?? 3600,\n maxRecords: config.maxRecords ?? 10000,\n precision: config.precision ?? 18,\n };\n }\n\n /**\n * Record usage\n */\n record(\n duration: number,\n amount: string,\n rate: string,\n metadata?: Record<string, unknown>,\n ): MeteringRecord {\n const cumulative = this.calculateCumulative(amount);\n\n const record: MeteringRecord = {\n timestamp: Date.now(),\n duration,\n amount,\n rate,\n cumulative,\n metadata,\n };\n\n this.records.push(record);\n\n // Prune old records if needed\n if (this.records.length > this.config.maxRecords) {\n this.pruneRecords();\n }\n\n return record;\n }\n\n /**\n * Get all records\n */\n getRecords(): MeteringRecord[] {\n return [...this.records];\n }\n\n /**\n * Get records in time range\n */\n getRecordsInRange(startTime: number, endTime: number): MeteringRecord[] {\n return this.records.filter(\n r => r.timestamp >= startTime && r.timestamp <= endTime,\n );\n }\n\n /**\n * Calculate usage metrics\n */\n getMetrics(): UsageMetrics {\n if (this.records.length === 0) {\n return {\n totalSeconds: 0,\n totalAmount: '0',\n averageRate: '0',\n peakRate: '0',\n startTime: this.startTime,\n };\n }\n\n const totalSeconds = this.records.reduce((sum, r) => sum + r.duration, 0);\n const totalAmount = this.records[this.records.length - 1].cumulative;\n const rates = this.records.map(r => BigInt(r.rate));\n const peakRate = rates.length > 0 ? rates.reduce((max, r) => r > max ? r : max, 0n) : 0n;\n\n const averageRate = totalSeconds > 0\n ? (BigInt(totalAmount) / BigInt(totalSeconds)).toString()\n : '0';\n\n return {\n totalSeconds,\n totalAmount,\n averageRate,\n peakRate: peakRate.toString(),\n startTime: this.startTime,\n endTime: this.records[this.records.length - 1].timestamp,\n hourly: this.getHourlyBreakdown(),\n };\n }\n\n /**\n * Get aggregated usage by period\n */\n aggregate(intervalSeconds: number = 3600): AggregatedUsage[] {\n if (this.records.length === 0) return [];\n\n const aggregated: AggregatedUsage[] = [];\n const intervalMs = intervalSeconds * 1000;\n\n // Group records by interval\n const groups = new Map<number, MeteringRecord[]>();\n\n for (const record of this.records) {\n const periodStart = Math.floor(record.timestamp / intervalMs) * intervalMs;\n const existing = groups.get(periodStart) ?? [];\n existing.push(record);\n groups.set(periodStart, existing);\n }\n\n // Calculate aggregates for each group\n for (const [periodStart, records] of groups) {\n const totalAmount = records.reduce(\n (sum, r) => sum + BigInt(r.amount),\n 0n,\n );\n const totalDuration = records.reduce((sum, r) => sum + r.duration, 0);\n const averageRate = totalDuration > 0\n ? (totalAmount / BigInt(totalDuration)).toString()\n : '0';\n\n aggregated.push({\n period: new Date(periodStart).toISOString(),\n totalAmount: totalAmount.toString(),\n totalDuration,\n averageRate,\n recordCount: records.length,\n });\n }\n\n return aggregated.sort((a, b) => a.period.localeCompare(b.period));\n }\n\n /**\n * Get cumulative amount at a point in time\n */\n getCumulativeAt(timestamp: number): string {\n // Find the last record before or at the timestamp\n for (let i = this.records.length - 1; i >= 0; i--) {\n if (this.records[i].timestamp <= timestamp) {\n return this.records[i].cumulative;\n }\n }\n return '0';\n }\n\n /**\n * Calculate usage for billing period\n */\n getUsageForBillingPeriod(\n startTime: number,\n endTime: number,\n ): { amount: string; duration: number; records: number } {\n const periodRecords = this.getRecordsInRange(startTime, endTime);\n\n const amount = periodRecords.reduce(\n (sum, r) => sum + BigInt(r.amount),\n 0n,\n );\n const duration = periodRecords.reduce((sum, r) => sum + r.duration, 0);\n\n return {\n amount: amount.toString(),\n duration,\n records: periodRecords.length,\n };\n }\n\n /**\n * Export records for backup/audit\n */\n export(): string {\n return JSON.stringify({\n sessionId: this.sessionId,\n startTime: this.startTime,\n records: this.records,\n exportedAt: Date.now(),\n });\n }\n\n /**\n * Import records from backup\n */\n import(data: string): { success: boolean; recordsImported: number } {\n try {\n const parsed = JSON.parse(data);\n\n if (parsed.sessionId !== this.sessionId) {\n return { success: false, recordsImported: 0 };\n }\n\n const importedRecords = parsed.records as MeteringRecord[];\n let importedCount = 0;\n\n for (const record of importedRecords) {\n // Only import records we don't have\n const exists = this.records.some(r => r.timestamp === record.timestamp);\n if (!exists) {\n this.records.push(record);\n importedCount++;\n }\n }\n\n // Re-sort by timestamp\n this.records.sort((a, b) => a.timestamp - b.timestamp);\n\n return { success: true, recordsImported: importedCount };\n } catch {\n return { success: false, recordsImported: 0 };\n }\n }\n\n /**\n * Clear all records\n */\n clear(): void {\n this.records = [];\n }\n\n private calculateCumulative(newAmount: string): string {\n if (this.records.length === 0) {\n return newAmount;\n }\n\n const lastCumulative = BigInt(this.records[this.records.length - 1].cumulative);\n return (lastCumulative + BigInt(newAmount)).toString();\n }\n\n private pruneRecords(): void {\n // Keep first record (for reference), and last N records\n const keepCount = this.config.maxRecords;\n if (this.records.length <= keepCount) return;\n\n const first = this.records[0];\n const recent = this.records.slice(-(keepCount - 1));\n\n this.records = [first, ...recent];\n }\n\n private getHourlyBreakdown(): UsageMetrics['hourly'] {\n const hourlyMap = new Map<number, { amount: bigint; seconds: number }>();\n\n for (const record of this.records) {\n const hour = new Date(record.timestamp).getUTCHours();\n const existing = hourlyMap.get(hour) ?? { amount: 0n, seconds: 0 };\n existing.amount += BigInt(record.amount);\n existing.seconds += record.duration;\n hourlyMap.set(hour, existing);\n }\n\n return Array.from(hourlyMap.entries()).map(([hour, data]) => ({\n hour,\n amount: data.amount.toString(),\n seconds: data.seconds,\n }));\n }\n}\n\n/**\n * Calculate pro-rated usage for partial periods\n */\nexport function calculateProRatedUsage(\n fullPeriodAmount: string,\n fullPeriodSeconds: number,\n actualSeconds: number,\n): string {\n if (fullPeriodSeconds === 0) return '0';\n\n const amount = BigInt(fullPeriodAmount);\n return ((amount * BigInt(actualSeconds)) / BigInt(fullPeriodSeconds)).toString();\n}\n\n/**\n * Estimate usage based on historical data\n */\nexport function estimateUsage(\n metrics: UsageMetrics,\n futureSeconds: number,\n): string {\n if (metrics.totalSeconds === 0) return '0';\n\n const avgRate = BigInt(metrics.averageRate);\n return (avgRate * BigInt(futureSeconds)).toString();\n}\n\n/**\n * Compare usage across periods\n */\nexport function compareUsage(\n current: UsageMetrics,\n previous: UsageMetrics,\n): {\n amountChange: string;\n amountChangePercent: number;\n rateChange: string;\n rateChangePercent: number;\n} {\n const currentAmount = BigInt(current.totalAmount);\n const previousAmount = BigInt(previous.totalAmount);\n const amountChange = currentAmount - previousAmount;\n const amountChangePercent = previousAmount > 0n\n ? Number((amountChange * 100n) / previousAmount)\n : 0;\n\n const currentRate = BigInt(current.averageRate);\n const previousRate = BigInt(previous.averageRate);\n const rateChange = currentRate - previousRate;\n const rateChangePercent = previousRate > 0n\n ? Number((rateChange * 100n) / previousRate)\n : 0;\n\n return {\n amountChange: amountChange.toString(),\n amountChangePercent,\n rateChange: rateChange.toString(),\n rateChangePercent,\n };\n}\n","import {\n BillingConfig,\n BillingPeriod,\n Invoice,\n InvoiceItem,\n MeteringRecord,\n} from './types.js';\n\n/**\n * Billing manager configuration\n */\nexport interface BillingManagerConfig {\n autoInvoice?: boolean;\n invoiceInterval?: number; // Generate invoice every N seconds\n currency?: string;\n taxRate?: number; // 0-1\n}\n\n/**\n * Billing manager for generating invoices from metering data\n */\nexport class BillingManager {\n private config: Required<BillingManagerConfig>;\n private billingConfig: BillingConfig;\n private invoices: Invoice[] = [];\n private channelId: string;\n private payer: string;\n private payee: string;\n private lastInvoiceTime: number;\n\n constructor(\n channelId: string,\n payer: string,\n payee: string,\n billingConfig: BillingConfig,\n config: BillingManagerConfig = {},\n ) {\n this.channelId = channelId;\n this.payer = payer;\n this.payee = payee;\n this.billingConfig = billingConfig;\n this.lastInvoiceTime = Date.now();\n\n this.config = {\n autoInvoice: config.autoInvoice ?? false,\n invoiceInterval: config.invoiceInterval ?? 86400,\n currency: config.currency ?? 'USDT',\n taxRate: config.taxRate ?? 0,\n };\n }\n\n /**\n * Generate invoice from metering records\n */\n generateInvoice(\n records: MeteringRecord[],\n startTime: number,\n endTime: number,\n ): Invoice {\n const items = this.createInvoiceItems(records, startTime, endTime);\n const subtotal = this.calculateSubtotal(items);\n const fees = this.calculateFees(subtotal);\n const total = (BigInt(subtotal) + BigInt(fees)).toString();\n\n const invoice: Invoice = {\n id: this.generateInvoiceId(),\n channelId: this.channelId,\n payer: this.payer,\n payee: this.payee,\n items,\n subtotal,\n fees,\n total,\n currency: this.config.currency,\n status: 'pending',\n createdAt: Date.now(),\n dueAt: Date.now() + 86400000, // Due in 24 hours\n };\n\n this.invoices.push(invoice);\n this.lastInvoiceTime = endTime;\n\n return invoice;\n }\n\n /**\n * Get all invoices\n */\n getInvoices(): Invoice[] {\n return [...this.invoices];\n }\n\n /**\n * Get invoice by ID\n */\n getInvoice(id: string): Invoice | undefined {\n return this.invoices.find(inv => inv.id === id);\n }\n\n /**\n * Mark invoice as paid\n */\n markPaid(invoiceId: string): boolean {\n const invoice = this.invoices.find(inv => inv.id === invoiceId);\n if (!invoice || invoice.status !== 'pending') {\n return false;\n }\n\n invoice.status = 'paid';\n invoice.paidAt = Date.now();\n return true;\n }\n\n /**\n * Mark invoice as settled\n */\n markSettled(invoiceId: string): boolean {\n const invoice = this.invoices.find(inv => inv.id === invoiceId);\n if (!invoice) return false;\n\n invoice.status = 'settled';\n return true;\n }\n\n /**\n * Get pending amount\n */\n getPendingAmount(): string {\n return this.invoices\n .filter(inv => inv.status === 'pending')\n .reduce((sum, inv) => sum + BigInt(inv.total), 0n)\n .toString();\n }\n\n /**\n * Get total billed amount\n */\n getTotalBilled(): string {\n return this.invoices\n .reduce((sum, inv) => sum + BigInt(inv.total), 0n)\n .toString();\n }\n\n /**\n * Check if new invoice is due\n */\n isInvoiceDue(currentTime: number): boolean {\n const elapsed = currentTime - this.lastInvoiceTime;\n return elapsed >= this.config.invoiceInterval * 1000;\n }\n\n /**\n * Calculate amount for billing period\n */\n calculatePeriodAmount(\n rate: string,\n durationSeconds: number,\n ): string {\n const periodSeconds = this.getPeriodSeconds(this.billingConfig.period);\n const periods = durationSeconds / periodSeconds;\n\n const amount = BigInt(rate) * BigInt(Math.floor(periods * periodSeconds));\n\n // Apply rounding\n return this.applyRounding(amount.toString());\n }\n\n /**\n * Apply minimum charge\n */\n applyMinimumCharge(amount: string): string {\n const minCharge = BigInt(this.billingConfig.minimumCharge);\n const actualAmount = BigInt(amount);\n\n return (actualAmount < minCharge ? minCharge : actualAmount).toString();\n }\n\n /**\n * Calculate grace period savings\n */\n calculateGracePeriodSavings(\n rate: string,\n totalDuration: number,\n ): string {\n const gracePeriod = this.billingConfig.gracePeriod;\n if (gracePeriod <= 0 || totalDuration <= gracePeriod) {\n return '0';\n }\n\n // Savings is the amount that would have been charged during grace period\n return (BigInt(rate) * BigInt(Math.min(gracePeriod, totalDuration))).toString();\n }\n\n /**\n * Get billing summary\n */\n getSummary(): {\n totalInvoices: number;\n totalBilled: string;\n totalPaid: string;\n totalPending: string;\n averageInvoice: string;\n } {\n const totalBilled = this.getTotalBilled();\n const totalPaid = this.invoices\n .filter(inv => inv.status === 'paid' || inv.status === 'settled')\n .reduce((sum, inv) => sum + BigInt(inv.total), 0n)\n .toString();\n const totalPending = this.getPendingAmount();\n const averageInvoice = this.invoices.length > 0\n ? (BigInt(totalBilled) / BigInt(this.invoices.length)).toString()\n : '0';\n\n return {\n totalInvoices: this.invoices.length,\n totalBilled,\n totalPaid,\n totalPending,\n averageInvoice,\n };\n }\n\n /**\n * Export billing data\n */\n export(): string {\n return JSON.stringify({\n channelId: this.channelId,\n invoices: this.invoices,\n exportedAt: Date.now(),\n });\n }\n\n private createInvoiceItems(\n records: MeteringRecord[],\n startTime: number,\n endTime: number,\n ): InvoiceItem[] {\n if (records.length === 0) {\n return [];\n }\n\n // Group records by rate for separate line items\n const rateGroups = new Map<string, MeteringRecord[]>();\n\n for (const record of records) {\n const existing = rateGroups.get(record.rate) ?? [];\n existing.push(record);\n rateGroups.set(record.rate, existing);\n }\n\n const items: InvoiceItem[] = [];\n\n for (const [rate, groupRecords] of rateGroups) {\n const totalDuration = groupRecords.reduce((sum, r) => sum + r.duration, 0);\n const totalAmount = groupRecords.reduce(\n (sum, r) => sum + BigInt(r.amount),\n 0n,\n );\n\n const periodName = this.getPeriodName(this.billingConfig.period);\n const quantity = this.calculateQuantity(totalDuration);\n\n items.push({\n description: `Streaming usage at ${rate} per ${periodName}`,\n quantity,\n rate,\n amount: totalAmount.toString(),\n startTime,\n endTime,\n });\n }\n\n return items;\n }\n\n private calculateSubtotal(items: InvoiceItem[]): string {\n return items\n .reduce((sum, item) => sum + BigInt(item.amount), 0n)\n .toString();\n }\n\n private calculateFees(subtotal: string): string {\n const amount = BigInt(subtotal);\n const taxRate = this.config.taxRate;\n\n if (taxRate <= 0) return '0';\n\n // Calculate tax/fees\n return BigInt(Math.floor(Number(amount) * taxRate)).toString();\n }\n\n private applyRounding(amount: string): string {\n const value = BigInt(amount);\n const mode = this.billingConfig.roundingMode;\n\n // For bigint, rounding is mainly about precision truncation\n // In real implementation, this would handle decimal places\n switch (mode) {\n case 'floor':\n return value.toString();\n case 'ceil':\n return value.toString();\n case 'round':\n return value.toString();\n default:\n return value.toString();\n }\n }\n\n private getPeriodSeconds(period: BillingPeriod): number {\n switch (period) {\n case 'realtime':\n case 'second':\n return 1;\n case 'minute':\n return 60;\n case 'hour':\n return 3600;\n case 'day':\n return 86400;\n }\n }\n\n private getPeriodName(period: BillingPeriod): string {\n switch (period) {\n case 'realtime':\n case 'second':\n return 'second';\n case 'minute':\n return 'minute';\n case 'hour':\n return 'hour';\n case 'day':\n return 'day';\n }\n }\n\n private calculateQuantity(totalSeconds: number): number {\n const periodSeconds = this.getPeriodSeconds(this.billingConfig.period);\n return totalSeconds / periodSeconds;\n }\n\n private generateInvoiceId(): string {\n return `inv_${this.channelId.slice(-8)}_${Date.now().toString(36)}`;\n }\n}\n\n/**\n * Format currency amount for display\n */\nexport function formatCurrencyAmount(\n amount: string,\n decimals: number = 6,\n symbol: string = 'USDT',\n): string {\n const value = BigInt(amount);\n const divisor = BigInt(10 ** decimals);\n const wholePart = value / divisor;\n const fractionalPart = value % divisor;\n\n const fractionalStr = fractionalPart.toString().padStart(decimals, '0');\n const trimmedFractional = fractionalStr.replace(/0+$/, '') || '0';\n\n return `${wholePart}.${trimmedFractional} ${symbol}`;\n}\n\n/**\n * Parse currency amount from display format\n */\nexport function parseCurrencyAmount(\n display: string,\n decimals: number = 6,\n): string {\n // Remove currency symbol and whitespace\n const cleaned = display.replace(/[^\\d.]/g, '');\n const [whole, fractional = ''] = cleaned.split('.');\n\n const paddedFractional = fractional.slice(0, decimals).padEnd(decimals, '0');\n const combined = whole + paddedFractional;\n\n return BigInt(combined).toString();\n}\n\n/**\n * Calculate estimated bill for future period\n */\nexport function estimateFutureBill(\n currentRate: string,\n durationSeconds: number,\n minimumCharge: string = '0',\n): string {\n const estimated = BigInt(currentRate) * BigInt(durationSeconds);\n const minimum = BigInt(minimumCharge);\n\n return (estimated < minimum ? minimum : estimated).toString();\n}\n","import { z } from 'zod';\n\n/**\n * Settlement state\n */\nexport const SettlementState = z.enum([\n 'pending', // Settlement not yet initiated\n 'in_progress', // Settlement process started\n 'challenging', // In challenge period\n 'disputed', // Dispute raised\n 'finalizing', // Finalizing on-chain\n 'completed', // Successfully settled\n 'failed', // Settlement failed\n]);\nexport type SettlementState = z.infer<typeof SettlementState>;\n\n/**\n * Checkpoint type\n */\nexport const CheckpointType = z.enum([\n 'periodic', // Regular interval checkpoint\n 'manual', // Manually triggered\n 'balance', // Triggered by balance threshold\n 'pre_close', // Before channel close\n 'dispute', // Checkpoint for dispute\n]);\nexport type CheckpointType = z.infer<typeof CheckpointType>;\n\n/**\n * Settlement checkpoint - extends channel checkpoint with settlement data\n */\nexport const SettlementCheckpoint = z.object({\n id: z.string(),\n channelId: z.string(),\n sequence: z.number(),\n type: CheckpointType,\n\n // Balances\n payerBalance: z.string(),\n payeeBalance: z.string(),\n totalStreamed: z.string(),\n\n // Signatures\n payerSignature: z.string(),\n payeeSignature: z.string().optional(),\n\n // Verification\n stateHash: z.string(),\n merkleRoot: z.string().optional(),\n\n // Timing\n createdAt: z.number(),\n expiresAt: z.number().optional(),\n\n // On-chain reference\n txHash: z.string().optional(),\n blockNumber: z.number().optional(),\n});\nexport type SettlementCheckpoint = z.infer<typeof SettlementCheckpoint>;\n\n/**\n * Settlement request\n */\nexport const SettlementRequest = z.object({\n channelId: z.string(),\n initiator: z.string(),\n finalCheckpoint: SettlementCheckpoint,\n reason: z.enum(['mutual', 'unilateral', 'timeout', 'dispute_resolution']),\n signature: z.string(),\n metadata: z.record(z.unknown()).optional(),\n});\nexport type SettlementRequest = z.infer<typeof SettlementRequest>;\n\n/**\n * Settlement result\n */\nexport const SettlementResult = z.object({\n success: z.boolean(),\n settlementId: z.string().optional(),\n error: z.string().optional(),\n finalBalances: z.object({\n payer: z.string(),\n payee: z.string(),\n }).optional(),\n txHash: z.string().optional(),\n timestamp: z.number(),\n});\nexport type SettlementResult = z.infer<typeof SettlementResult>;\n\n/**\n * Dispute reason\n */\nexport const DisputeReason = z.enum([\n 'invalid_checkpoint', // Checkpoint signature or data invalid\n 'stale_state', // Challenger has newer valid state\n 'balance_mismatch', // Balance doesn't match expected\n 'unauthorized_close', // Unauthorized party initiated close\n 'fraud', // Fraudulent activity detected\n 'other', // Other reason\n]);\nexport type DisputeReason = z.infer<typeof DisputeReason>;\n\n/**\n * Dispute evidence\n */\nexport const DisputeEvidence = z.object({\n type: z.enum(['checkpoint', 'signature', 'transaction', 'state_proof']),\n data: z.string(),\n description: z.string(),\n timestamp: z.number(),\n verified: z.boolean().default(false),\n});\nexport type DisputeEvidence = z.infer<typeof DisputeEvidence>;\n\n/**\n * Dispute record\n */\nexport const Dispute = z.object({\n id: z.string(),\n channelId: z.string(),\n initiator: z.string(),\n respondent: z.string(),\n reason: DisputeReason,\n description: z.string(),\n\n // Claimed state\n claimedPayerBalance: z.string(),\n claimedPayeeBalance: z.string(),\n claimedCheckpoint: SettlementCheckpoint.optional(),\n\n // Evidence\n evidence: z.array(DisputeEvidence),\n responseEvidence: z.array(DisputeEvidence).optional(),\n\n // Resolution\n status: z.enum(['pending', 'under_review', 'resolved', 'rejected', 'timeout']),\n resolution: z.object({\n winner: z.string().optional(),\n finalPayerBalance: z.string(),\n finalPayeeBalance: z.string(),\n reason: z.string(),\n timestamp: z.number(),\n }).optional(),\n\n // Timing\n createdAt: z.number(),\n responseDeadline: z.number(),\n resolutionDeadline: z.number(),\n});\nexport type Dispute = z.infer<typeof Dispute>;\n\n/**\n * Settlement configuration\n */\nexport const SettlementConfig = z.object({\n challengePeriod: z.number().default(86400), // 24 hours\n disputeResponsePeriod: z.number().default(43200), // 12 hours\n disputeResolutionPeriod: z.number().default(172800), // 48 hours\n minCheckpointInterval: z.number().default(60), // 60 seconds\n maxCheckpointsStored: z.number().default(100),\n settlementFee: z.string().default('0'),\n disputeBond: z.string().default('0'), // Bond required to raise dispute\n});\nexport type SettlementConfig = z.infer<typeof SettlementConfig>;\n\n/**\n * On-chain settlement data\n */\nexport const OnChainSettlement = z.object({\n channelId: z.string(),\n settlementId: z.string(),\n txHash: z.string(),\n blockNumber: z.number(),\n payerReceived: z.string(),\n payeeReceived: z.string(),\n fee: z.string(),\n timestamp: z.number(),\n finalized: z.boolean(),\n});\nexport type OnChainSettlement = z.infer<typeof OnChainSettlement>;\n","import {\n SettlementCheckpoint,\n CheckpointType,\n SettlementConfig,\n} from './types.js';\n\n/**\n * Checkpoint manager configuration\n */\nexport interface CheckpointManagerConfig {\n autoCheckpoint?: boolean;\n intervalSeconds?: number;\n balanceThreshold?: string;\n onCheckpoint?: (checkpoint: SettlementCheckpoint) => void;\n}\n\n/**\n * Checkpoint creation request\n */\nexport interface CheckpointRequest {\n channelId: string;\n sequence: number;\n payerBalance: string;\n payeeBalance: string;\n totalStreamed: string;\n type?: CheckpointType;\n payerSignature: string;\n payeeSignature?: string;\n}\n\n/**\n * Checkpoint manager for creating and validating checkpoints\n */\nexport class CheckpointManager {\n private checkpoints: Map<string, SettlementCheckpoint[]> = new Map();\n private config: Required<CheckpointManagerConfig>;\n private settlementConfig: SettlementConfig;\n private lastCheckpointTime: Map<string, number> = new Map();\n\n constructor(\n settlementConfig: SettlementConfig,\n config: CheckpointManagerConfig = {},\n ) {\n this.settlementConfig = settlementConfig;\n this.config = {\n autoCheckpoint: config.autoCheckpoint ?? false,\n intervalSeconds: config.intervalSeconds ?? 3600,\n balanceThreshold: config.balanceThreshold ?? '1000000',\n onCheckpoint: config.onCheckpoint ?? (() => {}),\n };\n }\n\n /**\n * Create a new checkpoint\n */\n create(request: CheckpointRequest): SettlementCheckpoint {\n const now = Date.now();\n const channelCheckpoints = this.checkpoints.get(request.channelId) ?? [];\n\n // Validate sequence\n const expectedSequence = channelCheckpoints.length;\n if (request.sequence !== expectedSequence) {\n throw new Error(`Invalid sequence: expected ${expectedSequence}, got ${request.sequence}`);\n }\n\n // Validate interval\n const lastTime = this.lastCheckpointTime.get(request.channelId) ?? 0;\n const elapsed = (now - lastTime) / 1000;\n if (elapsed < this.settlementConfig.minCheckpointInterval && channelCheckpoints.length > 0) {\n throw new Error(`Checkpoint interval too short: ${elapsed}s < ${this.settlementConfig.minCheckpointInterval}s`);\n }\n\n // Generate state hash\n const stateHash = this.generateStateHash(request);\n\n const checkpoint: SettlementCheckpoint = {\n id: this.generateCheckpointId(request.channelId, request.sequence),\n channelId: request.channelId,\n sequence: request.sequence,\n type: request.type ?? 'manual',\n payerBalance: request.payerBalance,\n payeeBalance: request.payeeBalance,\n totalStreamed: request.totalStreamed,\n payerSignature: request.payerSignature,\n payeeSignature: request.payeeSignature,\n stateHash,\n createdAt: now,\n };\n\n // Store checkpoint\n channelCheckpoints.push(checkpoint);\n this.checkpoints.set(request.channelId, channelCheckpoints);\n this.lastCheckpointTime.set(request.channelId, now);\n\n // Prune old checkpoints if needed\n this.pruneCheckpoints(request.channelId);\n\n // Notify callback\n this.config.onCheckpoint(checkpoint);\n\n return checkpoint;\n }\n\n /**\n * Get latest checkpoint for channel\n */\n getLatest(channelId: string): SettlementCheckpoint | undefined {\n const checkpoints = this.checkpoints.get(channelId);\n if (!checkpoints || checkpoints.length === 0) return undefined;\n return checkpoints[checkpoints.length - 1];\n }\n\n /**\n * Get checkpoint by sequence\n */\n getBySequence(channelId: string, sequence: number): SettlementCheckpoint | undefined {\n const checkpoints = this.checkpoints.get(channelId);\n if (!checkpoints) return undefined;\n return checkpoints.find(cp => cp.sequence === sequence);\n }\n\n /**\n * Get all checkpoints for channel\n */\n getAll(channelId: string): SettlementCheckpoint[] {\n return [...(this.checkpoints.get(channelId) ?? [])];\n }\n\n /**\n * Validate checkpoint\n */\n validate(checkpoint: SettlementCheckpoint): {\n valid: boolean;\n errors: string[];\n } {\n const errors: string[] = [];\n\n // Validate balance consistency\n const payerBalance = BigInt(checkpoint.payerBalance);\n const payeeBalance = BigInt(checkpoint.payeeBalance);\n const totalStreamed = BigInt(checkpoint.totalStreamed);\n\n if (payerBalance < 0n) {\n errors.push('Payer balance cannot be negative');\n }\n\n if (payeeBalance < 0n) {\n errors.push('Payee balance cannot be negative');\n }\n\n if (totalStreamed < 0n) {\n errors.push('Total streamed cannot be negative');\n }\n\n // Validate total streamed equals payee balance (for standard streaming)\n if (payeeBalance !== totalStreamed) {\n errors.push('Total streamed should equal payee balance');\n }\n\n // Validate signature presence\n if (!checkpoint.payerSignature) {\n errors.push('Payer signature is required');\n }\n\n // Validate state hash\n const expectedHash = this.generateStateHash({\n channelId: checkpoint.channelId,\n sequence: checkpoint.sequence,\n payerBalance: checkpoint.payerBalance,\n payeeBalance: checkpoint.payeeBalance,\n totalStreamed: checkpoint.totalStreamed,\n payerSignature: checkpoint.payerSignature,\n });\n\n if (checkpoint.stateHash !== expectedHash) {\n errors.push('State hash mismatch');\n }\n\n // Validate timestamp\n if (checkpoint.createdAt > Date.now()) {\n errors.push('Checkpoint timestamp is in the future');\n }\n\n return { valid: errors.length === 0, errors };\n }\n\n /**\n * Compare two checkpoints\n */\n compare(a: SettlementCheckpoint, b: SettlementCheckpoint): {\n isNewer: boolean;\n balanceDifference: { payer: string; payee: string };\n } {\n const isNewer = a.sequence > b.sequence ||\n (a.sequence === b.sequence && a.createdAt > b.createdAt);\n\n const payerDiff = BigInt(a.payerBalance) - BigInt(b.payerBalance);\n const payeeDiff = BigInt(a.payeeBalance) - BigInt(b.payeeBalance);\n\n return {\n isNewer,\n balanceDifference: {\n payer: payerDiff.toString(),\n payee: payeeDiff.toString(),\n },\n };\n }\n\n /**\n * Check if checkpoint is needed\n */\n needsCheckpoint(\n channelId: string,\n currentPayeeBalance: string,\n ): { needed: boolean; reason: string } {\n const lastCheckpoint = this.getLatest(channelId);\n const now = Date.now();\n\n // No checkpoint exists\n if (!lastCheckpoint) {\n return { needed: true, reason: 'No existing checkpoint' };\n }\n\n // Time-based check\n const elapsed = (now - lastCheckpoint.createdAt) / 1000;\n if (elapsed >= this.config.intervalSeconds) {\n return { needed: true, reason: 'Interval elapsed' };\n }\n\n // Balance threshold check\n const balanceChange = BigInt(currentPayeeBalance) - BigInt(lastCheckpoint.payeeBalance);\n if (balanceChange >= BigInt(this.config.balanceThreshold)) {\n return { needed: true, reason: 'Balance threshold exceeded' };\n }\n\n return { needed: false, reason: '' };\n }\n\n /**\n * Build merkle root from checkpoint history\n */\n buildMerkleRoot(channelId: string): string {\n const checkpoints = this.checkpoints.get(channelId);\n if (!checkpoints || checkpoints.length === 0) {\n return '0x' + '0'.repeat(64);\n }\n\n // Simple merkle root - hash all state hashes together\n const hashes = checkpoints.map(cp => cp.stateHash);\n return this.hashArray(hashes);\n }\n\n /**\n * Verify checkpoint is in merkle tree\n */\n verifyMerkleProof(\n checkpoint: SettlementCheckpoint,\n merkleRoot: string,\n _proof: string[],\n ): boolean {\n const channelRoot = this.buildMerkleRoot(checkpoint.channelId);\n return channelRoot === merkleRoot;\n }\n\n /**\n * Export checkpoints for backup\n */\n export(channelId: string): string {\n const checkpoints = this.checkpoints.get(channelId) ?? [];\n return JSON.stringify({\n channelId,\n checkpoints,\n exportedAt: Date.now(),\n });\n }\n\n /**\n * Import checkpoints from backup\n */\n import(data: string): { success: boolean; imported: number } {\n try {\n const parsed = JSON.parse(data);\n const { channelId, checkpoints } = parsed;\n\n // Validate and import\n let imported = 0;\n const existing = this.checkpoints.get(channelId) ?? [];\n\n for (const cp of checkpoints as SettlementCheckpoint[]) {\n const validation = this.validate(cp);\n if (validation.valid) {\n const exists = existing.some(e => e.sequence === cp.sequence);\n if (!exists) {\n existing.push(cp);\n imported++;\n }\n }\n }\n\n // Sort by sequence\n existing.sort((a, b) => a.sequence - b.sequence);\n this.checkpoints.set(channelId, existing);\n\n return { success: true, imported };\n } catch {\n return { success: false, imported: 0 };\n }\n }\n\n /**\n * Clear checkpoints for channel\n */\n clear(channelId: string): void {\n this.checkpoints.delete(channelId);\n this.lastCheckpointTime.delete(channelId);\n }\n\n private generateCheckpointId(channelId: string, sequence: number): string {\n return `cp_${channelId.slice(-8)}_${sequence}_${Date.now().toString(36)}`;\n }\n\n private generateStateHash(request: CheckpointRequest): string {\n const data = [\n request.channelId,\n request.sequence.toString(),\n request.payerBalance,\n request.payeeBalance,\n request.totalStreamed,\n ].join(':');\n\n // Simple hash implementation\n let hash = 0;\n for (let i = 0; i < data.length; i++) {\n const char = data.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash = hash & hash;\n }\n return '0x' + Math.abs(hash).toString(16).padStart(64, '0');\n }\n\n private hashArray(hashes: string[]): string {\n const combined = hashes.join('');\n let hash = 0;\n for (let i = 0; i < combined.length; i++) {\n const char = combined.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash = hash & hash;\n }\n return '0x' + Math.abs(hash).toString(16).padStart(64, '0');\n }\n\n private pruneCheckpoints(channelId: string): void {\n const checkpoints = this.checkpoints.get(channelId);\n if (!checkpoints) return;\n\n const maxStored = this.settlementConfig.maxCheckpointsStored;\n if (checkpoints.length <= maxStored) return;\n\n // Keep first, last N-1 checkpoints\n const first = checkpoints[0];\n const recent = checkpoints.slice(-(maxStored - 1));\n\n this.checkpoints.set(channelId, [first, ...recent]);\n }\n}\n\n/**\n * Sign checkpoint data\n */\nexport function signCheckpoint(\n checkpoint: SettlementCheckpoint,\n _privateKey: string,\n): string {\n // In production, would use actual cryptographic signing\n const dataToSign = [\n checkpoint.channelId,\n checkpoint.sequence.toString(),\n checkpoint.payerBalance,\n checkpoint.payeeBalance,\n checkpoint.totalStreamed,\n checkpoint.createdAt.toString(),\n ].join(':');\n\n // Mock signature\n let hash = 0;\n for (let i = 0; i < dataToSign.length; i++) {\n const char = dataToSign.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash = hash & hash;\n }\n return '0x' + Math.abs(hash).toString(16).padStart(128, '0');\n}\n\n/**\n * Verify checkpoint signature\n */\nexport function verifyCheckpointSignature(\n _checkpoint: SettlementCheckpoint,\n signature: string,\n _publicKey: string,\n): boolean {\n // In production, would use actual signature verification\n // For now, just check signature format\n return signature.startsWith('0x') && signature.length === 130;\n}\n","import {\n SettlementState,\n SettlementCheckpoint,\n SettlementRequest,\n SettlementResult,\n SettlementConfig,\n OnChainSettlement,\n} from './types.js';\nimport { CheckpointManager } from './checkpoint.js';\n\n/**\n * Final settlement manager configuration\n */\nexport interface FinalSettlementConfig {\n autoFinalize?: boolean;\n retryAttempts?: number;\n retryDelayMs?: number;\n}\n\n/**\n * Settlement status\n */\nexport interface SettlementStatus {\n state: SettlementState;\n channelId: string;\n initiator: string;\n checkpoint: SettlementCheckpoint;\n challengeDeadline: number;\n finalizedAt?: number;\n txHash?: string;\n error?: string;\n}\n\n/**\n * Final settlement manager\n */\nexport class FinalSettlementManager {\n private settlements: Map<string, SettlementStatus> = new Map();\n private checkpointManager: CheckpointManager;\n private settlementConfig: SettlementConfig;\n private onChainSettlements: Map<string, OnChainSettlement> = new Map();\n\n constructor(\n checkpointManager: CheckpointManager,\n settlementConfig: SettlementConfig,\n _config: FinalSettlementConfig = {},\n ) {\n this.checkpointManager = checkpointManager;\n this.settlementConfig = settlementConfig;\n }\n\n /**\n * Initiate settlement\n */\n initiate(request: SettlementRequest): SettlementResult {\n const now = Date.now();\n\n // Validate request\n const validation = this.validateRequest(request);\n if (!validation.valid) {\n return {\n success: false,\n error: validation.errors.join(', '),\n timestamp: now,\n };\n }\n\n // Check if settlement already exists\n const existing = this.settlements.get(request.channelId);\n if (existing && existing.state !== 'completed' && existing.state !== 'failed') {\n return {\n success: false,\n error: 'Settlement already in progress',\n timestamp: now,\n };\n }\n\n // Create settlement status\n const settlementId = this.generateSettlementId(request.channelId);\n const challengeDeadline = now + this.settlementConfig.challengePeriod * 1000;\n\n const status: SettlementStatus = {\n state: 'pending',\n channelId: request.channelId,\n initiator: request.initiator,\n checkpoint: request.finalCheckpoint,\n challengeDeadline,\n };\n\n this.settlements.set(request.channelId, status);\n\n // Transition to in_progress\n this.transitionState(request.channelId, 'in_progress');\n\n return {\n success: true,\n settlementId,\n finalBalances: {\n payer: request.finalCheckpoint.payerBalance,\n payee: request.finalCheckpoint.payeeBalance,\n },\n timestamp: now,\n };\n }\n\n /**\n * Process mutual settlement (both parties agree)\n */\n processMutual(\n channelId: string,\n payerSignature: string,\n payeeSignature: string,\n finalCheckpoint: SettlementCheckpoint,\n ): SettlementResult {\n const now = Date.now();\n\n // Validate signatures\n if (!payerSignature || !payeeSignature) {\n return {\n success: false,\n error: 'Both signatures required for mutual settlement',\n timestamp: now,\n };\n }\n\n // Update checkpoint with both signatures\n const mutualCheckpoint: SettlementCheckpoint = {\n ...finalCheckpoint,\n payerSignature,\n payeeSignature,\n };\n\n // Create settlement\n const status: SettlementStatus = {\n state: 'finalizing',\n channelId,\n initiator: 'mutual',\n checkpoint: mutualCheckpoint,\n challengeDeadline: now, // No challenge period for mutual\n };\n\n this.settlements.set(channelId, status);\n\n // Skip challenge period and finalize immediately\n return this.finalize(channelId);\n }\n\n /**\n * Check if challenge period has elapsed\n */\n canFinalize(channelId: string): { canFinalize: boolean; timeRemaining: number } {\n const status = this.settlements.get(channelId);\n if (!status) {\n return { canFinalize: false, timeRemaining: -1 };\n }\n\n if (status.state === 'completed' || status.state === 'failed') {\n return { canFinalize: false, timeRemaining: 0 };\n }\n\n if (status.state === 'disputed') {\n return { canFinalize: false, timeRemaining: -1 };\n }\n\n const now = Date.now();\n const timeRemaining = Math.max(0, status.challengeDeadline - now);\n\n return {\n canFinalize: timeRemaining === 0,\n timeRemaining,\n };\n }\n\n /**\n * Finalize settlement after challenge period\n */\n finalize(channelId: string): SettlementResult {\n const now = Date.now();\n const status = this.settlements.get(channelId);\n\n if (!status) {\n return {\n success: false,\n error: 'No settlement found',\n timestamp: now,\n };\n }\n\n // Check if can finalize\n const { canFinalize: canFinalizeNow, timeRemaining } = this.canFinalize(channelId);\n if (!canFinalizeNow && status.state !== 'finalizing') {\n return {\n success: false,\n error: `Cannot finalize: ${timeRemaining}ms remaining in challenge period`,\n timestamp: now,\n };\n }\n\n // Transition to finalizing\n this.transitionState(channelId, 'finalizing');\n\n // Simulate on-chain settlement\n const settlementId = this.generateSettlementId(channelId);\n const mockTxHash = this.generateMockTxHash(channelId);\n\n const onChainSettlement: OnChainSettlement = {\n channelId,\n settlementId,\n txHash: mockTxHash,\n blockNumber: Math.floor(Date.now() / 1000),\n payerReceived: status.checkpoint.payerBalance,\n payeeReceived: status.checkpoint.payeeBalance,\n fee: this.settlementConfig.settlementFee,\n timestamp: now,\n finalized: true,\n };\n\n this.onChainSettlements.set(channelId, onChainSettlement);\n\n // Transition to completed\n this.transitionState(channelId, 'completed');\n status.finalizedAt = now;\n status.txHash = mockTxHash;\n\n return {\n success: true,\n settlementId,\n finalBalances: {\n payer: status.checkpoint.payerBalance,\n payee: status.checkpoint.payeeBalance,\n },\n txHash: mockTxHash,\n timestamp: now,\n };\n }\n\n /**\n * Get settlement status\n */\n getStatus(channelId: string): SettlementStatus | undefined {\n return this.settlements.get(channelId);\n }\n\n /**\n * Get on-chain settlement\n */\n getOnChainSettlement(channelId: string): OnChainSettlement | undefined {\n return this.onChainSettlements.get(channelId);\n }\n\n /**\n * Cancel pending settlement (before challenge period ends)\n */\n cancel(\n channelId: string,\n canceller: string,\n reason: string,\n ): { success: boolean; error?: string } {\n const status = this.settlements.get(channelId);\n\n if (!status) {\n return { success: false, error: 'No settlement found' };\n }\n\n if (status.state !== 'pending' && status.state !== 'in_progress' && status.state !== 'challenging') {\n return { success: false, error: 'Cannot cancel settlement in current state' };\n }\n\n // Only initiator can cancel\n if (status.initiator !== canceller && status.initiator !== 'mutual') {\n return { success: false, error: 'Only initiator can cancel' };\n }\n\n this.transitionState(channelId, 'failed');\n status.error = `Cancelled: ${reason}`;\n\n return { success: true };\n }\n\n /**\n * Calculate settlement amounts\n */\n calculateSettlementAmounts(\n checkpoint: SettlementCheckpoint,\n ): {\n payerReceives: string;\n payeeReceives: string;\n fee: string;\n total: string;\n } {\n const payerBalance = BigInt(checkpoint.payerBalance);\n const payeeBalance = BigInt(checkpoint.payeeBalance);\n const fee = BigInt(this.settlementConfig.settlementFee);\n\n // Deduct fee from payer's balance\n const payerReceives = payerBalance > fee ? payerBalance - fee : 0n;\n const payeeReceives = payeeBalance;\n const total = payerReceives + payeeReceives + fee;\n\n return {\n payerReceives: payerReceives.toString(),\n payeeReceives: payeeReceives.toString(),\n fee: fee.toString(),\n total: total.toString(),\n };\n }\n\n /**\n * Build settlement transaction data\n */\n buildSettlementTransaction(\n channelId: string,\n ): { to: string; data: string; value: string } | null {\n const status = this.settlements.get(channelId);\n if (!status) return null;\n\n const amounts = this.calculateSettlementAmounts(status.checkpoint);\n\n // In production, this would encode actual contract call\n const methodId = '0x' + 'settle'.split('').map(c => c.charCodeAt(0).toString(16)).join('').slice(0, 8);\n\n const data = [\n methodId,\n channelId.replace(/^ch_/, '').padStart(64, '0'),\n amounts.payerReceives.padStart(64, '0'),\n amounts.payeeReceives.padStart(64, '0'),\n status.checkpoint.payerSignature.replace('0x', '').padStart(128, '0'),\n ].join('');\n\n return {\n to: '0x' + '0'.repeat(40), // Contract address placeholder\n data,\n value: '0',\n };\n }\n\n private validateRequest(request: SettlementRequest): {\n valid: boolean;\n errors: string[];\n } {\n const errors: string[] = [];\n\n // Validate checkpoint\n const cpValidation = this.checkpointManager.validate(request.finalCheckpoint);\n if (!cpValidation.valid) {\n errors.push(...cpValidation.errors);\n }\n\n // Validate signature\n if (!request.signature) {\n errors.push('Settlement signature is required');\n }\n\n // Validate reason\n const validReasons = ['mutual', 'unilateral', 'timeout', 'dispute_resolution'];\n if (!validReasons.includes(request.reason)) {\n errors.push('Invalid settlement reason');\n }\n\n return { valid: errors.length === 0, errors };\n }\n\n private transitionState(channelId: string, newState: SettlementState): void {\n const status = this.settlements.get(channelId);\n if (status) {\n status.state = newState;\n }\n }\n\n private generateSettlementId(channelId: string): string {\n return `stl_${channelId.slice(-8)}_${Date.now().toString(36)}`;\n }\n\n private generateMockTxHash(channelId: string): string {\n const data = channelId + Date.now().toString();\n let hash = 0;\n for (let i = 0; i < data.length; i++) {\n const char = data.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash = hash & hash;\n }\n return '0x' + Math.abs(hash).toString(16).padStart(64, '0');\n }\n}\n\n/**\n * Estimate settlement gas cost\n */\nexport function estimateSettlementGas(\n hasDispute: boolean,\n checkpointCount: number,\n): string {\n const baseGas = 100000n;\n const disputeGas = hasDispute ? 50000n : 0n;\n const checkpointGas = BigInt(checkpointCount) * 5000n;\n\n return (baseGas + disputeGas + checkpointGas).toString();\n}\n\n/**\n * Verify settlement transaction on-chain\n */\nexport function verifySettlementOnChain(\n settlement: OnChainSettlement,\n): { verified: boolean; error?: string } {\n // In production, would verify against actual blockchain data\n if (!settlement.txHash || !settlement.txHash.startsWith('0x')) {\n return { verified: false, error: 'Invalid transaction hash' };\n }\n\n if (!settlement.finalized) {\n return { verified: false, error: 'Settlement not finalized' };\n }\n\n return { verified: true };\n}\n","import {\n Dispute,\n DisputeReason,\n DisputeEvidence,\n SettlementCheckpoint,\n SettlementConfig,\n} from './types.js';\nimport { CheckpointManager } from './checkpoint.js';\n\n/**\n * Dispute manager configuration\n */\nexport interface DisputeManagerConfig {\n requireBond?: boolean;\n autoResolve?: boolean;\n notifyParties?: (dispute: Dispute, event: string) => void;\n}\n\n/**\n * Dispute creation request\n */\nexport interface DisputeRequest {\n channelId: string;\n initiator: string;\n respondent: string;\n reason: DisputeReason;\n description: string;\n claimedPayerBalance: string;\n claimedPayeeBalance: string;\n claimedCheckpoint?: SettlementCheckpoint;\n evidence: DisputeEvidence[];\n bond?: string;\n}\n\n/**\n * Dispute response\n */\nexport interface DisputeResponse {\n disputeId: string;\n responder: string;\n counterClaim?: {\n payerBalance: string;\n payeeBalance: string;\n };\n evidence: DisputeEvidence[];\n signature: string;\n}\n\n/**\n * Dispute manager for handling payment disputes\n */\nexport class DisputeManager {\n private disputes: Map<string, Dispute> = new Map();\n private config: Required<DisputeManagerConfig>;\n private settlementConfig: SettlementConfig;\n private checkpointManager: CheckpointManager;\n\n constructor(\n checkpointManager: CheckpointManager,\n settlementConfig: SettlementConfig,\n config: DisputeManagerConfig = {},\n ) {\n this.checkpointManager = checkpointManager;\n this.settlementConfig = settlementConfig;\n this.config = {\n requireBond: config.requireBond ?? true,\n autoResolve: config.autoResolve ?? false,\n notifyParties: config.notifyParties ?? (() => {}),\n };\n }\n\n /**\n * Raise a dispute\n */\n raise(request: DisputeRequest): {\n success: boolean;\n dispute?: Dispute;\n error?: string;\n } {\n const now = Date.now();\n\n // Validate request\n const validation = this.validateRequest(request);\n if (!validation.valid) {\n return { success: false, error: validation.errors.join(', ') };\n }\n\n // Check for existing dispute\n const existingDispute = this.getByChannel(request.channelId);\n if (existingDispute && existingDispute.status === 'pending') {\n return { success: false, error: 'Dispute already pending for this channel' };\n }\n\n // Check bond requirement\n if (this.config.requireBond && this.settlementConfig.disputeBond !== '0') {\n if (!request.bond || BigInt(request.bond) < BigInt(this.settlementConfig.disputeBond)) {\n return {\n success: false,\n error: `Dispute bond of ${this.settlementConfig.disputeBond} required`,\n };\n }\n }\n\n const disputeId = this.generateDisputeId(request.channelId);\n const responseDeadline = now + this.settlementConfig.disputeResponsePeriod * 1000;\n const resolutionDeadline = now + this.settlementConfig.disputeResolutionPeriod * 1000;\n\n const dispute: Dispute = {\n id: disputeId,\n channelId: request.channelId,\n initiator: request.initiator,\n respondent: request.respondent,\n reason: request.reason,\n description: request.description,\n claimedPayerBalance: request.claimedPayerBalance,\n claimedPayeeBalance: request.claimedPayeeBalance,\n claimedCheckpoint: request.claimedCheckpoint,\n evidence: request.evidence,\n status: 'pending',\n createdAt: now,\n responseDeadline,\n resolutionDeadline,\n };\n\n this.disputes.set(disputeId, dispute);\n\n // Notify parties\n this.config.notifyParties(dispute, 'raised');\n\n return { success: true, dispute };\n }\n\n /**\n * Respond to a dispute\n */\n respond(response: DisputeResponse): {\n success: boolean;\n error?: string;\n } {\n const dispute = this.disputes.get(response.disputeId);\n\n if (!dispute) {\n return { success: false, error: 'Dispute not found' };\n }\n\n if (dispute.status !== 'pending') {\n return { success: false, error: 'Dispute is not pending' };\n }\n\n if (response.responder !== dispute.respondent) {\n return { success: false, error: 'Only the respondent can respond' };\n }\n\n const now = Date.now();\n if (now > dispute.responseDeadline) {\n return { success: false, error: 'Response deadline has passed' };\n }\n\n // Add response evidence\n dispute.responseEvidence = response.evidence;\n dispute.status = 'under_review';\n\n // Notify parties\n this.config.notifyParties(dispute, 'responded');\n\n return { success: true };\n }\n\n /**\n * Resolve a dispute\n */\n resolve(\n disputeId: string,\n winner: string,\n finalPayerBalance: string,\n finalPayeeBalance: string,\n reason: string,\n ): {\n success: boolean;\n error?: string;\n } {\n const dispute = this.disputes.get(disputeId);\n\n if (!dispute) {\n return { success: false, error: 'Dispute not found' };\n }\n\n if (dispute.status === 'resolved' || dispute.status === 'rejected') {\n return { success: false, error: 'Dispute already resolved' };\n }\n\n const now = Date.now();\n\n dispute.resolution = {\n winner,\n finalPayerBalance,\n finalPayeeBalance,\n reason,\n timestamp: now,\n };\n dispute.status = 'resolved';\n\n // Notify parties\n this.config.notifyParties(dispute, 'resolved');\n\n return { success: true };\n }\n\n /**\n * Reject a dispute\n */\n reject(\n disputeId: string,\n reason: string,\n ): { success: boolean; error?: string } {\n const dispute = this.disputes.get(disputeId);\n\n if (!dispute) {\n return { success: false, error: 'Dispute not found' };\n }\n\n if (dispute.status === 'resolved' || dispute.status === 'rejected') {\n return { success: false, error: 'Dispute already resolved' };\n }\n\n dispute.status = 'rejected';\n dispute.resolution = {\n finalPayerBalance: dispute.claimedPayerBalance,\n finalPayeeBalance: dispute.claimedPayeeBalance,\n reason: `Rejected: ${reason}`,\n timestamp: Date.now(),\n };\n\n // Notify parties\n this.config.notifyParties(dispute, 'rejected');\n\n return { success: true };\n }\n\n /**\n * Handle timeout (no response)\n */\n handleTimeout(disputeId: string): {\n success: boolean;\n resolution?: Dispute['resolution'];\n } {\n const dispute = this.disputes.get(disputeId);\n\n if (!dispute) {\n return { success: false };\n }\n\n const now = Date.now();\n\n // Check response deadline\n if (dispute.status === 'pending' && now > dispute.responseDeadline) {\n // Respondent didn't respond - initiator wins by default\n return this.resolve(\n disputeId,\n dispute.initiator,\n dispute.claimedPayerBalance,\n dispute.claimedPayeeBalance,\n 'Timeout: No response from respondent',\n ).success ? { success: true, resolution: dispute.resolution } : { success: false };\n }\n\n // Check resolution deadline\n if (dispute.status === 'under_review' && now > dispute.resolutionDeadline) {\n // Resolution timeout - need arbitration or default resolution\n dispute.status = 'timeout';\n return { success: true };\n }\n\n return { success: false };\n }\n\n /**\n * Get dispute by ID\n */\n get(disputeId: string): Dispute | undefined {\n return this.disputes.get(disputeId);\n }\n\n /**\n * Get dispute by channel ID\n */\n getByChannel(channelId: string): Dispute | undefined {\n for (const dispute of this.disputes.values()) {\n if (dispute.channelId === channelId &&\n dispute.status !== 'resolved' &&\n dispute.status !== 'rejected') {\n return dispute;\n }\n }\n return undefined;\n }\n\n /**\n * Get all disputes\n */\n getAll(): Dispute[] {\n return Array.from(this.disputes.values());\n }\n\n /**\n * Get disputes by status\n */\n getByStatus(status: Dispute['status']): Dispute[] {\n return Array.from(this.disputes.values()).filter(d => d.status === status);\n }\n\n /**\n * Add evidence to existing dispute\n */\n addEvidence(\n disputeId: string,\n party: string,\n evidence: DisputeEvidence,\n ): { success: boolean; error?: string } {\n const dispute = this.disputes.get(disputeId);\n\n if (!dispute) {\n return { success: false, error: 'Dispute not found' };\n }\n\n if (dispute.status !== 'pending' && dispute.status !== 'under_review') {\n return { success: false, error: 'Cannot add evidence to resolved dispute' };\n }\n\n if (party !== dispute.initiator && party !== dispute.respondent) {\n return { success: false, error: 'Only parties can add evidence' };\n }\n\n if (party === dispute.initiator) {\n dispute.evidence.push(evidence);\n } else {\n dispute.responseEvidence = dispute.responseEvidence ?? [];\n dispute.responseEvidence.push(evidence);\n }\n\n return { success: true };\n }\n\n /**\n * Evaluate dispute based on evidence\n */\n evaluateEvidence(disputeId: string): {\n initiatorScore: number;\n respondentScore: number;\n recommendation: string;\n } {\n const dispute = this.disputes.get(disputeId);\n\n if (!dispute) {\n return { initiatorScore: 0, respondentScore: 0, recommendation: 'Dispute not found' };\n }\n\n let initiatorScore = 0;\n let respondentScore = 0;\n\n // Score initiator evidence\n for (const evidence of dispute.evidence) {\n if (evidence.verified) {\n initiatorScore += this.getEvidenceWeight(evidence.type);\n } else {\n initiatorScore += this.getEvidenceWeight(evidence.type) * 0.5;\n }\n }\n\n // Score respondent evidence\n for (const evidence of dispute.responseEvidence ?? []) {\n if (evidence.verified) {\n respondentScore += this.getEvidenceWeight(evidence.type);\n } else {\n respondentScore += this.getEvidenceWeight(evidence.type) * 0.5;\n }\n }\n\n // Check if initiator has newer checkpoint\n if (dispute.claimedCheckpoint) {\n const latestCheckpoint = this.checkpointManager.getLatest(dispute.channelId);\n if (latestCheckpoint) {\n const comparison = this.checkpointManager.compare(\n dispute.claimedCheckpoint,\n latestCheckpoint,\n );\n if (comparison.isNewer) {\n initiatorScore += 10;\n } else {\n respondentScore += 10;\n }\n }\n }\n\n let recommendation: string;\n if (initiatorScore > respondentScore * 1.5) {\n recommendation = 'Initiator has stronger evidence';\n } else if (respondentScore > initiatorScore * 1.5) {\n recommendation = 'Respondent has stronger evidence';\n } else {\n recommendation = 'Evidence is inconclusive - may need arbitration';\n }\n\n return { initiatorScore, respondentScore, recommendation };\n }\n\n private validateRequest(request: DisputeRequest): {\n valid: boolean;\n errors: string[];\n } {\n const errors: string[] = [];\n\n if (!request.channelId) {\n errors.push('Channel ID is required');\n }\n\n if (!request.initiator) {\n errors.push('Initiator address is required');\n }\n\n if (!request.respondent) {\n errors.push('Respondent address is required');\n }\n\n if (request.initiator === request.respondent) {\n errors.push('Initiator and respondent must be different');\n }\n\n if (!request.reason) {\n errors.push('Dispute reason is required');\n }\n\n if (!request.description || request.description.length < 10) {\n errors.push('Description must be at least 10 characters');\n }\n\n if (request.evidence.length === 0) {\n errors.push('At least one piece of evidence is required');\n }\n\n // Validate balance claims\n if (BigInt(request.claimedPayerBalance) < 0n) {\n errors.push('Claimed payer balance cannot be negative');\n }\n\n if (BigInt(request.claimedPayeeBalance) < 0n) {\n errors.push('Claimed payee balance cannot be negative');\n }\n\n return { valid: errors.length === 0, errors };\n }\n\n private getEvidenceWeight(type: DisputeEvidence['type']): number {\n const weights: Record<DisputeEvidence['type'], number> = {\n checkpoint: 10,\n signature: 8,\n transaction: 9,\n state_proof: 10,\n };\n return weights[type] ?? 5;\n }\n\n private generateDisputeId(channelId: string): string {\n return `dsp_${channelId.slice(-8)}_${Date.now().toString(36)}`;\n }\n}\n\n/**\n * Create evidence from checkpoint\n */\nexport function createCheckpointEvidence(\n checkpoint: SettlementCheckpoint,\n description: string,\n): DisputeEvidence {\n return {\n type: 'checkpoint',\n data: JSON.stringify(checkpoint),\n description,\n timestamp: Date.now(),\n verified: false,\n };\n}\n\n/**\n * Create evidence from signature\n */\nexport function createSignatureEvidence(\n signature: string,\n signedData: string,\n description: string,\n): DisputeEvidence {\n return {\n type: 'signature',\n data: JSON.stringify({ signature, signedData }),\n description,\n timestamp: Date.now(),\n verified: false,\n };\n}\n\n/**\n * Create evidence from transaction\n */\nexport function createTransactionEvidence(\n txHash: string,\n description: string,\n): DisputeEvidence {\n return {\n type: 'transaction',\n data: txHash,\n description,\n timestamp: Date.now(),\n verified: false,\n };\n}\n"],"mappings":"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","names":["z","z"]}
|