@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 ADDED
@@ -0,0 +1,422 @@
1
+ # @t402-internal/streaming-payments
2
+
3
+ Streaming payments with payment channels for T402 Protocol.
4
+
5
+ ## Overview
6
+
7
+ This package provides per-second settlement using payment channel technology. It enables continuous value transfer with off-chain state updates and on-chain settlement, similar to Lightning Network concepts adapted for stablecoin HTTP payments.
8
+
9
+ ## Installation
10
+
11
+ ```bash
12
+ pnpm add @t402-internal/streaming-payments
13
+ ```
14
+
15
+ ## Quick Start
16
+
17
+ ```typescript
18
+ import {
19
+ ChannelOpener,
20
+ ChannelStateMachine,
21
+ FlowController,
22
+ CheckpointManager,
23
+ FinalSettlementManager,
24
+ } from '@t402-internal/streaming-payments';
25
+
26
+ // Create a payment channel
27
+ const opener = new ChannelOpener();
28
+ const { channel, stateMachine, fundingRequired } = opener.create({
29
+ chain: 'eip155:8453',
30
+ asset: '0xUSDT',
31
+ payerAddress: '0xPayer',
32
+ payeeAddress: '0xPayee',
33
+ depositAmount: '1000000000', // 1000 USDT
34
+ ratePerSecond: '1000', // 0.001 USDT per second
35
+ });
36
+
37
+ // Fund the channel
38
+ opener.processFunding(stateMachine, '0xTxHash', '1000000000');
39
+ opener.confirmFunding(stateMachine, { /* confirmation */ });
40
+
41
+ // Start streaming
42
+ const flow = new FlowController(channel.id, channel.ratePerSecond);
43
+ flow.start();
44
+
45
+ // Get current streamed amount
46
+ const currentAmount = flow.getCurrentAmount();
47
+
48
+ // Pause/resume
49
+ flow.pause();
50
+ flow.resume();
51
+
52
+ // Stop and get final amount
53
+ const { finalAmount } = flow.stop();
54
+ ```
55
+
56
+ ## Modules
57
+
58
+ ### Channels
59
+
60
+ Payment channel lifecycle management with state machine.
61
+
62
+ ```typescript
63
+ import {
64
+ ChannelOpener,
65
+ ChannelCloser,
66
+ ChannelStateMachine,
67
+ ChannelRecovery,
68
+ isChannelActive,
69
+ isChannelTerminal,
70
+ } from '@t402-internal/streaming-payments/channels';
71
+
72
+ // Open channel
73
+ const opener = new ChannelOpener({
74
+ fundingTimeout: 3600000, // 1 hour
75
+ confirmations: 3,
76
+ });
77
+
78
+ const result = opener.create({
79
+ chain: 'eip155:8453',
80
+ asset: '0xUSDT',
81
+ payerAddress: '0xPayer',
82
+ payeeAddress: '0xPayee',
83
+ depositAmount: '1000000000',
84
+ ratePerSecond: '1000',
85
+ });
86
+
87
+ // Process state transitions
88
+ const stateMachine = result.stateMachine;
89
+ stateMachine.process({ type: 'FUND', txHash: '0x...', amount: '1000000000' });
90
+ stateMachine.process({ type: 'CONFIRM_FUNDING' });
91
+
92
+ // Close channel
93
+ const closer = new ChannelCloser({
94
+ challengePeriod: 86400, // 24 hours
95
+ });
96
+
97
+ closer.initiateClose(stateMachine, '0xPayer', '0xSignature');
98
+ closer.finalize(stateMachine);
99
+
100
+ // Recovery
101
+ const recovery = new ChannelRecovery();
102
+ const recoveryResult = recovery.recoverFromCheckpoints(channel, checkpoints);
103
+ ```
104
+
105
+ ### Channel States
106
+
107
+ | State | Description |
108
+ |-------|-------------|
109
+ | `created` | Channel created, awaiting funding |
110
+ | `funding` | Funding transaction submitted |
111
+ | `open` | Channel active and streaming |
112
+ | `paused` | Temporarily paused |
113
+ | `closing` | Close initiated, in challenge period |
114
+ | `disputing` | Dispute in progress |
115
+ | `closed` | Fully settled |
116
+ | `expired` | Timed out |
117
+
118
+ ### Streaming
119
+
120
+ Continuous flow control with metering and billing.
121
+
122
+ ```typescript
123
+ import {
124
+ FlowController,
125
+ createFixedRateFlow,
126
+ createTieredRateFlow,
127
+ RateController,
128
+ MeteringManager,
129
+ BillingManager,
130
+ } from '@t402-internal/streaming-payments/streaming';
131
+
132
+ // Fixed rate streaming
133
+ const flow = createFixedRateFlow('ch_123', '1000');
134
+ flow.start();
135
+
136
+ // Get current amount
137
+ console.log(flow.getCurrentAmount());
138
+
139
+ // Tiered rate streaming
140
+ const tieredFlow = createTieredRateFlow(
141
+ 'ch_123',
142
+ '1000', // Base rate
143
+ [
144
+ { threshold: '1000000', rate: '800' }, // Discount after 1M
145
+ { threshold: '5000000', rate: '600' }, // Further discount after 5M
146
+ ],
147
+ );
148
+
149
+ // Rate adjustment
150
+ const rateController = new RateController({
151
+ type: 'fixed',
152
+ baseRate: '1000',
153
+ minRate: '500',
154
+ maxRate: '2000',
155
+ });
156
+
157
+ rateController.adjustRate({
158
+ sessionId: 'ss_123',
159
+ newRate: '1200',
160
+ reason: 'Peak demand',
161
+ });
162
+
163
+ // Metering
164
+ const metering = new MeteringManager('ss_123');
165
+ metering.record(60, '60000', '1000'); // 60 seconds at 1000/s
166
+
167
+ const metrics = metering.getMetrics();
168
+ console.log(metrics.totalAmount);
169
+ console.log(metrics.averageRate);
170
+
171
+ // Billing
172
+ const billing = new BillingManager(
173
+ 'ch_123',
174
+ '0xPayer',
175
+ '0xPayee',
176
+ { period: 'hour', minimumCharge: '100000' },
177
+ );
178
+
179
+ const invoice = billing.generateInvoice(
180
+ metering.getRecords(),
181
+ startTime,
182
+ endTime,
183
+ );
184
+ ```
185
+
186
+ ### Streaming Events
187
+
188
+ ```typescript
189
+ flow.onEvent(event => {
190
+ switch (event.type) {
191
+ case 'started':
192
+ console.log('Stream started at rate:', event.rate);
193
+ break;
194
+ case 'paused':
195
+ console.log('Stream paused, total:', event.totalStreamed);
196
+ break;
197
+ case 'checkpoint':
198
+ console.log('Checkpoint created:', event.checkpointId);
199
+ break;
200
+ case 'completed':
201
+ console.log('Stream completed:', event.totalAmount);
202
+ break;
203
+ }
204
+ });
205
+ ```
206
+
207
+ ### Settlement
208
+
209
+ Checkpoint-based settlement with dispute resolution.
210
+
211
+ ```typescript
212
+ import {
213
+ CheckpointManager,
214
+ FinalSettlementManager,
215
+ DisputeManager,
216
+ signCheckpoint,
217
+ createCheckpointEvidence,
218
+ } from '@t402-internal/streaming-payments/settlement';
219
+
220
+ // Checkpoint management
221
+ const checkpointMgr = new CheckpointManager(settlementConfig, {
222
+ autoCheckpoint: true,
223
+ intervalSeconds: 3600,
224
+ });
225
+
226
+ const checkpoint = checkpointMgr.create({
227
+ channelId: 'ch_123',
228
+ sequence: 0,
229
+ payerBalance: '900000000',
230
+ payeeBalance: '100000000',
231
+ totalStreamed: '100000000',
232
+ payerSignature: '0xsig',
233
+ });
234
+
235
+ // Validate checkpoint chain
236
+ const validation = checkpointMgr.verifyCheckpointChain(checkpoints);
237
+
238
+ // Final settlement
239
+ const settlementMgr = new FinalSettlementManager(
240
+ checkpointMgr,
241
+ settlementConfig,
242
+ );
243
+
244
+ // Initiate settlement
245
+ settlementMgr.initiate({
246
+ channelId: 'ch_123',
247
+ initiator: '0xPayer',
248
+ finalCheckpoint: checkpoint,
249
+ reason: 'unilateral',
250
+ signature: '0xsig',
251
+ });
252
+
253
+ // Mutual close (instant, no challenge period)
254
+ settlementMgr.processMutual(
255
+ 'ch_123',
256
+ payerSignature,
257
+ payeeSignature,
258
+ finalCheckpoint,
259
+ );
260
+
261
+ // Finalize after challenge period
262
+ const { canFinalize, timeRemaining } = settlementMgr.canFinalize('ch_123');
263
+ if (canFinalize) {
264
+ settlementMgr.finalize('ch_123');
265
+ }
266
+
267
+ // Dispute handling
268
+ const disputeMgr = new DisputeManager(checkpointMgr, settlementConfig);
269
+
270
+ // Raise dispute
271
+ disputeMgr.raise({
272
+ channelId: 'ch_123',
273
+ initiator: '0xPayee',
274
+ respondent: '0xPayer',
275
+ reason: 'stale_state',
276
+ description: 'Payer submitted old checkpoint',
277
+ claimedPayerBalance: '800000000',
278
+ claimedPayeeBalance: '200000000',
279
+ claimedCheckpoint: newerCheckpoint,
280
+ evidence: [
281
+ createCheckpointEvidence(newerCheckpoint, 'Newer signed checkpoint'),
282
+ ],
283
+ });
284
+
285
+ // Respond to dispute
286
+ disputeMgr.respond({
287
+ disputeId: 'dsp_123',
288
+ responder: '0xPayer',
289
+ evidence: [...],
290
+ signature: '0xsig',
291
+ });
292
+
293
+ // Resolve dispute
294
+ disputeMgr.resolve(
295
+ 'dsp_123',
296
+ '0xPayee', // Winner
297
+ '800000000', // Final payer balance
298
+ '200000000', // Final payee balance
299
+ 'Challenger had newer checkpoint',
300
+ );
301
+ ```
302
+
303
+ ## Settlement Flow
304
+
305
+ ```
306
+ 1. Channel Open
307
+ - Payer deposits funds
308
+ - Channel enters 'open' state
309
+
310
+ 2. Streaming
311
+ - Continuous per-second billing
312
+ - Periodic checkpoints
313
+ - Off-chain state updates
314
+
315
+ 3. Close Initiation
316
+ - Either party can initiate
317
+ - Submit final checkpoint
318
+
319
+ 4. Challenge Period (24h default)
320
+ - Counter-party can dispute
321
+ - Submit newer checkpoint to win
322
+
323
+ 5. Finalization
324
+ - After challenge period
325
+ - On-chain settlement
326
+ - Funds distributed
327
+ ```
328
+
329
+ ## API Reference
330
+
331
+ ### ChannelOpener
332
+
333
+ - `create(request)` - Create new channel
334
+ - `processFunding(stateMachine, txHash, amount)` - Process funding tx
335
+ - `confirmFunding(stateMachine, confirmation)` - Confirm funding
336
+
337
+ ### ChannelStateMachine
338
+
339
+ - `getChannel()` - Get current channel state
340
+ - `getState()` - Get channel state enum
341
+ - `process(event)` - Process state transition
342
+ - `canTransition(state)` - Check if transition allowed
343
+ - `updateBalance(payer, payee)` - Update balances
344
+ - `addCheckpoint(checkpoint)` - Add checkpoint
345
+ - `onStateChange(state, callback)` - Subscribe to changes
346
+
347
+ ### FlowController
348
+
349
+ - `start()` - Start streaming
350
+ - `pause()` - Pause streaming
351
+ - `resume()` - Resume streaming
352
+ - `stop()` - Stop and get final amount
353
+ - `cancel(reason)` - Cancel streaming
354
+ - `getCurrentAmount()` - Get current streamed amount
355
+ - `getCurrentRate()` - Get effective rate
356
+ - `createCheckpoint()` - Create manual checkpoint
357
+ - `onEvent(callback)` - Subscribe to events
358
+
359
+ ### CheckpointManager
360
+
361
+ - `create(request)` - Create checkpoint
362
+ - `getLatest(channelId)` - Get latest checkpoint
363
+ - `validate(checkpoint)` - Validate checkpoint
364
+ - `verifyCheckpointChain(checkpoints)` - Verify integrity
365
+ - `needsCheckpoint(channelId, balance)` - Check if needed
366
+
367
+ ### FinalSettlementManager
368
+
369
+ - `initiate(request)` - Start settlement
370
+ - `processMutual(...)` - Mutual (instant) close
371
+ - `canFinalize(channelId)` - Check if can finalize
372
+ - `finalize(channelId)` - Complete settlement
373
+
374
+ ### DisputeManager
375
+
376
+ - `raise(request)` - Raise dispute
377
+ - `respond(response)` - Respond to dispute
378
+ - `resolve(...)` - Resolve dispute
379
+ - `addEvidence(...)` - Add evidence
380
+ - `evaluateEvidence(disputeId)` - Evaluate evidence
381
+
382
+ ## Dispute Reasons
383
+
384
+ | Reason | Description |
385
+ |--------|-------------|
386
+ | `invalid_checkpoint` | Checkpoint signature/data invalid |
387
+ | `stale_state` | Challenger has newer valid state |
388
+ | `balance_mismatch` | Balance doesn't match expected |
389
+ | `unauthorized_close` | Unauthorized party initiated close |
390
+ | `fraud` | Fraudulent activity detected |
391
+
392
+ ## Configuration
393
+
394
+ ### Settlement Config
395
+
396
+ ```typescript
397
+ const settlementConfig = {
398
+ challengePeriod: 86400, // 24 hours
399
+ disputeResponsePeriod: 43200, // 12 hours
400
+ disputeResolutionPeriod: 172800, // 48 hours
401
+ minCheckpointInterval: 60, // 60 seconds
402
+ maxCheckpointsStored: 100,
403
+ settlementFee: '0',
404
+ disputeBond: '0',
405
+ };
406
+ ```
407
+
408
+ ### Billing Config
409
+
410
+ ```typescript
411
+ const billingConfig = {
412
+ period: 'realtime', // 'second' | 'minute' | 'hour' | 'day'
413
+ minimumCharge: '0',
414
+ roundingMode: 'floor', // 'ceil' | 'round'
415
+ gracePeriod: 0,
416
+ invoiceInterval: 86400, // Generate invoice daily
417
+ };
418
+ ```
419
+
420
+ ## License
421
+
422
+ Internal use only - T402 Protocol