pepay-streams-sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/README.md +405 -0
  2. package/dist/api/index.d.mts +321 -0
  3. package/dist/api/index.d.ts +321 -0
  4. package/dist/api/index.js +312 -0
  5. package/dist/api/index.js.map +1 -0
  6. package/dist/api/index.mjs +306 -0
  7. package/dist/api/index.mjs.map +1 -0
  8. package/dist/automation/index.d.mts +140 -0
  9. package/dist/automation/index.d.ts +140 -0
  10. package/dist/automation/index.js +331 -0
  11. package/dist/automation/index.js.map +1 -0
  12. package/dist/automation/index.mjs +326 -0
  13. package/dist/automation/index.mjs.map +1 -0
  14. package/dist/campaigns/index.d.mts +286 -0
  15. package/dist/campaigns/index.d.ts +286 -0
  16. package/dist/campaigns/index.js +652 -0
  17. package/dist/campaigns/index.js.map +1 -0
  18. package/dist/campaigns/index.mjs +645 -0
  19. package/dist/campaigns/index.mjs.map +1 -0
  20. package/dist/claims/index.d.mts +190 -0
  21. package/dist/claims/index.d.ts +190 -0
  22. package/dist/claims/index.js +414 -0
  23. package/dist/claims/index.js.map +1 -0
  24. package/dist/claims/index.mjs +409 -0
  25. package/dist/claims/index.mjs.map +1 -0
  26. package/dist/index-BTG0TRJt.d.mts +555 -0
  27. package/dist/index-BTG0TRJt.d.ts +555 -0
  28. package/dist/index.d.mts +170 -0
  29. package/dist/index.d.ts +170 -0
  30. package/dist/index.js +2926 -0
  31. package/dist/index.js.map +1 -0
  32. package/dist/index.mjs +2888 -0
  33. package/dist/index.mjs.map +1 -0
  34. package/dist/marketplace/index.d.mts +225 -0
  35. package/dist/marketplace/index.d.ts +225 -0
  36. package/dist/marketplace/index.js +529 -0
  37. package/dist/marketplace/index.js.map +1 -0
  38. package/dist/marketplace/index.mjs +524 -0
  39. package/dist/marketplace/index.mjs.map +1 -0
  40. package/dist/react/index.d.mts +185 -0
  41. package/dist/react/index.d.ts +185 -0
  42. package/dist/react/index.js +340 -0
  43. package/dist/react/index.js.map +1 -0
  44. package/dist/react/index.mjs +333 -0
  45. package/dist/react/index.mjs.map +1 -0
  46. package/dist/staking/index.d.mts +158 -0
  47. package/dist/staking/index.d.ts +158 -0
  48. package/dist/staking/index.js +359 -0
  49. package/dist/staking/index.js.map +1 -0
  50. package/dist/staking/index.mjs +354 -0
  51. package/dist/staking/index.mjs.map +1 -0
  52. package/package.json +106 -0
  53. package/src/api/index.ts +577 -0
  54. package/src/automation/index.ts +436 -0
  55. package/src/campaigns/index.ts +835 -0
  56. package/src/claims/index.ts +530 -0
  57. package/src/client.ts +518 -0
  58. package/src/index.ts +101 -0
  59. package/src/marketplace/index.ts +730 -0
  60. package/src/react/index.ts +498 -0
  61. package/src/staking/index.ts +449 -0
  62. package/src/types/index.ts +631 -0
@@ -0,0 +1,436 @@
1
+ /**
2
+ * Automation Module
3
+ *
4
+ * Provides methods for keeper automation:
5
+ * - Enable/disable auto-withdraw for vesting campaigns
6
+ * - Enable/disable auto-release for locks
7
+ * - Query automation status
8
+ */
9
+ import {
10
+ type PublicClient,
11
+ type WalletClient,
12
+ type Address,
13
+ type Hash,
14
+ } from 'viem';
15
+ import { DIAMOND_ABI } from '@pepay-streams/abi/diamond';
16
+ import type {
17
+ EnableAutoWithdrawParams,
18
+ EnableAutoReleaseParams,
19
+ AutomationStatus,
20
+ TransactionResult,
21
+ } from '../types';
22
+
23
+ /**
24
+ * Automation module for keeper-powered operations
25
+ */
26
+ export class AutomationModule {
27
+ constructor(
28
+ private readonly publicClient: PublicClient,
29
+ private readonly walletClient: WalletClient | undefined,
30
+ private readonly diamondAddress: Address
31
+ ) {}
32
+
33
+ // ============================================================================
34
+ // Auto-Withdraw (for Vesting campaigns)
35
+ // ============================================================================
36
+
37
+ /**
38
+ * Enable auto-withdraw for a vesting campaign
39
+ *
40
+ * Keepers will automatically claim vested tokens on behalf of recipients.
41
+ *
42
+ * @example
43
+ * ```typescript
44
+ * const result = await sdk.automation.enableAutoWithdraw({
45
+ * campaignId: 1n,
46
+ * frequency: 7 * 24 * 60 * 60, // Weekly
47
+ * tipAmount: parseEther('0.1'), // 0.1 ETH for keeper
48
+ * });
49
+ * ```
50
+ */
51
+ async enableAutoWithdraw(
52
+ params: EnableAutoWithdrawParams
53
+ ): Promise<TransactionResult> {
54
+ const wallet = this.requireWallet();
55
+
56
+ const hash = await wallet.writeContract({
57
+ chain: wallet.chain,
58
+ account: wallet.account!,
59
+ address: this.diamondAddress,
60
+ abi: DIAMOND_ABI,
61
+ functionName: 'enableAutoWithdraw',
62
+ args: [params.campaignId, BigInt(params.frequency)],
63
+ value: params.tipAmount ?? 0n,
64
+ });
65
+
66
+ return this.createTransactionResult(hash);
67
+ }
68
+
69
+ /**
70
+ * Disable auto-withdraw for a campaign
71
+ *
72
+ * Returns remaining tip balance to caller.
73
+ */
74
+ async disableAutoWithdraw(campaignId: bigint): Promise<TransactionResult> {
75
+ const wallet = this.requireWallet();
76
+
77
+ const hash = await wallet.writeContract({
78
+ chain: wallet.chain,
79
+ account: wallet.account!,
80
+ address: this.diamondAddress,
81
+ abi: DIAMOND_ABI,
82
+ functionName: 'disableAutoWithdraw',
83
+ args: [campaignId],
84
+ });
85
+
86
+ return this.createTransactionResult(hash);
87
+ }
88
+
89
+ // ============================================================================
90
+ // Auto-Release (for Lock campaigns)
91
+ // ============================================================================
92
+
93
+ /**
94
+ * Enable auto-release for a lock campaign
95
+ *
96
+ * Keepers will automatically release tokens when unlock time passes.
97
+ *
98
+ * @example
99
+ * ```typescript
100
+ * const result = await sdk.automation.enableAutoRelease({
101
+ * campaignId: 5n,
102
+ * frequency: 3600, // Check every hour
103
+ * tipAmount: parseEther('0.05'), // 0.05 ETH for keeper
104
+ * });
105
+ * ```
106
+ */
107
+ async enableAutoRelease(
108
+ params: EnableAutoReleaseParams & { frequency?: number }
109
+ ): Promise<TransactionResult> {
110
+ const wallet = this.requireWallet();
111
+
112
+ // Default frequency of 1 hour if not specified
113
+ const frequency = params.frequency ?? 3600;
114
+
115
+ const hash = await wallet.writeContract({
116
+ chain: wallet.chain,
117
+ account: wallet.account!,
118
+ address: this.diamondAddress,
119
+ abi: DIAMOND_ABI,
120
+ functionName: 'enableAutoReleaseLock',
121
+ args: [params.campaignId, BigInt(frequency)],
122
+ value: params.tipAmount ?? 0n,
123
+ });
124
+
125
+ return this.createTransactionResult(hash);
126
+ }
127
+
128
+ /**
129
+ * Disable auto-release for a lock campaign
130
+ */
131
+ async disableAutoRelease(campaignId: bigint): Promise<TransactionResult> {
132
+ const wallet = this.requireWallet();
133
+
134
+ const hash = await wallet.writeContract({
135
+ chain: wallet.chain,
136
+ account: wallet.account!,
137
+ address: this.diamondAddress,
138
+ abi: DIAMOND_ABI,
139
+ functionName: 'disableAutoReleaseLock',
140
+ args: [campaignId],
141
+ });
142
+
143
+ return this.createTransactionResult(hash);
144
+ }
145
+
146
+ // ============================================================================
147
+ // Automation Status Queries
148
+ // ============================================================================
149
+
150
+ /**
151
+ * Get auto-withdraw status for a campaign
152
+ *
153
+ * @example
154
+ * ```typescript
155
+ * const status = await sdk.automation.getAutoWithdrawStatus(campaignId);
156
+ * console.log('Enabled:', status.enabled);
157
+ * console.log('Next run:', new Date(status.nextRun * 1000));
158
+ * console.log('Tip balance:', formatEther(status.tipBalance));
159
+ * ```
160
+ */
161
+ async getAutoWithdrawStatus(campaignId: bigint): Promise<AutomationStatus> {
162
+ const [config, pendingCount, cursor] = await Promise.all([
163
+ this.publicClient.readContract({
164
+ address: this.diamondAddress,
165
+ abi: DIAMOND_ABI,
166
+ functionName: 'automationConfig',
167
+ args: [campaignId],
168
+ }) as Promise<[boolean, bigint, bigint]>,
169
+ this.publicClient.readContract({
170
+ address: this.diamondAddress,
171
+ abi: DIAMOND_ABI,
172
+ functionName: 'recipientsPending',
173
+ args: [campaignId],
174
+ }) as Promise<bigint>,
175
+ this.publicClient.readContract({
176
+ address: this.diamondAddress,
177
+ abi: DIAMOND_ABI,
178
+ functionName: 'regCursor',
179
+ args: [campaignId],
180
+ }) as Promise<bigint>,
181
+ ]);
182
+
183
+ const [enabled, frequency, lastRun] = config;
184
+ const nextRun = Number(lastRun) + Number(frequency);
185
+
186
+ return {
187
+ enabled,
188
+ lastRun: Number(lastRun),
189
+ nextRun,
190
+ frequency: Number(frequency),
191
+ tipBalance: 0n, // Tip balance is managed internally
192
+ recipientsProcessed: Number(cursor),
193
+ totalRecipients: Number(pendingCount) + Number(cursor),
194
+ };
195
+ }
196
+
197
+ /**
198
+ * Get auto-release status for a lock campaign
199
+ */
200
+ async getAutoReleaseStatus(campaignId: bigint): Promise<{
201
+ enabled: boolean;
202
+ frequency: number;
203
+ lastRun: number;
204
+ nextRun: number;
205
+ }> {
206
+ const config = await this.publicClient.readContract({
207
+ address: this.diamondAddress,
208
+ abi: DIAMOND_ABI,
209
+ functionName: 'automationLockConfig',
210
+ args: [campaignId],
211
+ }) as [boolean, bigint, bigint];
212
+
213
+ const [enabled, frequency, lastRun] = config;
214
+ const nextRun = Number(lastRun) + Number(frequency);
215
+
216
+ return {
217
+ enabled,
218
+ frequency: Number(frequency),
219
+ lastRun: Number(lastRun),
220
+ nextRun,
221
+ };
222
+ }
223
+
224
+ /**
225
+ * Preview automation for specific recipients
226
+ */
227
+ async previewAutomation(
228
+ campaignId: bigint,
229
+ recipients: Address[]
230
+ ): Promise<{
231
+ pendingCount: bigint;
232
+ nextFeeWei: bigint;
233
+ escrowWei: bigint;
234
+ }> {
235
+ const result = await this.publicClient.readContract({
236
+ address: this.diamondAddress,
237
+ abi: DIAMOND_ABI,
238
+ functionName: 'automationPreviewFor',
239
+ args: [campaignId, recipients],
240
+ }) as [bigint, bigint, bigint];
241
+
242
+ return {
243
+ pendingCount: result[0],
244
+ nextFeeWei: result[1],
245
+ escrowWei: result[2],
246
+ };
247
+ }
248
+
249
+ /**
250
+ * Get automation run statistics
251
+ */
252
+ async getAutomationStats(
253
+ campaignId: bigint,
254
+ lockMode = false
255
+ ): Promise<{
256
+ runsObserved: number;
257
+ avgRecipientsPerRun: number;
258
+ lastRecipientsProcessed: number;
259
+ maxRecipientsPerRun: number;
260
+ }> {
261
+ const result = await this.publicClient.readContract({
262
+ address: this.diamondAddress,
263
+ abi: DIAMOND_ABI,
264
+ functionName: 'automationRunStats',
265
+ args: [campaignId, lockMode],
266
+ }) as {
267
+ runsObserved: bigint;
268
+ avgRecipientsPerRun: bigint;
269
+ lastRecipientsProcessed: bigint;
270
+ maxRecipientsPerRun: bigint;
271
+ };
272
+
273
+ return {
274
+ runsObserved: Number(result.runsObserved),
275
+ avgRecipientsPerRun: Number(result.avgRecipientsPerRun),
276
+ lastRecipientsProcessed: Number(result.lastRecipientsProcessed),
277
+ maxRecipientsPerRun: Number(result.maxRecipientsPerRun),
278
+ };
279
+ }
280
+
281
+ /**
282
+ * Check if auto-withdraw is currently runnable
283
+ *
284
+ * Returns true if cooldown has passed and there are pending recipients.
285
+ */
286
+ async isAutoWithdrawRunnable(campaignId: bigint): Promise<boolean> {
287
+ const status = await this.getAutoWithdrawStatus(campaignId);
288
+ const now = Math.floor(Date.now() / 1000);
289
+
290
+ return (
291
+ status.enabled &&
292
+ now >= status.nextRun &&
293
+ status.recipientsProcessed < status.totalRecipients
294
+ );
295
+ }
296
+
297
+ /**
298
+ * Check if auto-release is currently runnable
299
+ */
300
+ async isAutoReleaseRunnable(campaignId: bigint): Promise<boolean> {
301
+ const status = await this.getAutoReleaseStatus(campaignId);
302
+ const now = Math.floor(Date.now() / 1000);
303
+
304
+ return status.enabled && now >= status.nextRun;
305
+ }
306
+
307
+ // ============================================================================
308
+ // Keeper Functions (for automation operators)
309
+ // ============================================================================
310
+
311
+ /**
312
+ * Execute auto-withdraw for specific recipients (keeper only)
313
+ *
314
+ * @example
315
+ * ```typescript
316
+ * // Get recipients from registry or external source
317
+ * const recipients = ['0x...', '0x...', '0x...'];
318
+ * await sdk.automation.executeAutoWithdraw(campaignId, recipients);
319
+ * ```
320
+ */
321
+ async executeAutoWithdraw(
322
+ campaignId: bigint,
323
+ recipients: Address[]
324
+ ): Promise<TransactionResult> {
325
+ const wallet = this.requireWallet();
326
+
327
+ const hash = await wallet.writeContract({
328
+ chain: wallet.chain,
329
+ account: wallet.account!,
330
+ address: this.diamondAddress,
331
+ abi: DIAMOND_ABI,
332
+ functionName: 'autoWithdraw',
333
+ args: [campaignId, recipients],
334
+ });
335
+
336
+ return this.createTransactionResult(hash);
337
+ }
338
+
339
+ /**
340
+ * Execute auto-withdraw using registry cursor (keeper only)
341
+ *
342
+ * Processes up to batchSize recipients from the registry.
343
+ */
344
+ async executeAutoWithdrawNext(
345
+ campaignId: bigint,
346
+ batchSize = 50
347
+ ): Promise<TransactionResult> {
348
+ const wallet = this.requireWallet();
349
+
350
+ const hash = await wallet.writeContract({
351
+ chain: wallet.chain,
352
+ account: wallet.account!,
353
+ address: this.diamondAddress,
354
+ abi: DIAMOND_ABI,
355
+ functionName: 'autoWithdrawNext',
356
+ args: [campaignId, BigInt(batchSize)],
357
+ });
358
+
359
+ return this.createTransactionResult(hash);
360
+ }
361
+
362
+ /**
363
+ * Execute auto-release for specific recipients (keeper only)
364
+ */
365
+ async executeAutoRelease(
366
+ campaignId: bigint,
367
+ recipients: Address[]
368
+ ): Promise<TransactionResult> {
369
+ const wallet = this.requireWallet();
370
+
371
+ const hash = await wallet.writeContract({
372
+ chain: wallet.chain,
373
+ account: wallet.account!,
374
+ address: this.diamondAddress,
375
+ abi: DIAMOND_ABI,
376
+ functionName: 'autoReleaseLock',
377
+ args: [campaignId, recipients],
378
+ });
379
+
380
+ return this.createTransactionResult(hash);
381
+ }
382
+
383
+ /**
384
+ * Execute auto-release using registry cursor (keeper only)
385
+ */
386
+ async executeAutoReleaseNext(
387
+ campaignId: bigint,
388
+ batchSize = 50
389
+ ): Promise<TransactionResult> {
390
+ const wallet = this.requireWallet();
391
+
392
+ const hash = await wallet.writeContract({
393
+ chain: wallet.chain,
394
+ account: wallet.account!,
395
+ address: this.diamondAddress,
396
+ abi: DIAMOND_ABI,
397
+ functionName: 'autoReleaseLockNext',
398
+ args: [campaignId, BigInt(batchSize)],
399
+ });
400
+
401
+ return this.createTransactionResult(hash);
402
+ }
403
+
404
+ // ============================================================================
405
+ // Helpers
406
+ // ============================================================================
407
+
408
+ private requireWallet(): WalletClient {
409
+ if (!this.walletClient) {
410
+ throw new Error(
411
+ 'Wallet client required for write operations. Initialize SDK with a signer.'
412
+ );
413
+ }
414
+ return this.walletClient;
415
+ }
416
+
417
+ private createTransactionResult(hash: Hash): TransactionResult {
418
+ return {
419
+ hash,
420
+ wait: async () => {
421
+ const receipt = await this.publicClient.waitForTransactionReceipt({
422
+ hash,
423
+ });
424
+ return {
425
+ blockNumber: receipt.blockNumber,
426
+ transactionHash: receipt.transactionHash,
427
+ gasUsed: receipt.gasUsed,
428
+ status: receipt.status,
429
+ logs: receipt.logs,
430
+ };
431
+ },
432
+ };
433
+ }
434
+ }
435
+
436
+ export default AutomationModule;