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,409 @@
1
+ import { keccak256, encodePacked } from 'viem';
2
+ import { DIAMOND_ABI } from '@pepay-streams/abi/diamond';
3
+
4
+ // src/claims/index.ts
5
+ var ClaimsModule = class {
6
+ constructor(publicClient, walletClient, diamondAddress, chainId) {
7
+ this.publicClient = publicClient;
8
+ this.walletClient = walletClient;
9
+ this.diamondAddress = diamondAddress;
10
+ this.chainId = chainId;
11
+ }
12
+ // ============================================================================
13
+ // Standard Claims
14
+ // ============================================================================
15
+ /**
16
+ * Claim vested tokens from a campaign
17
+ *
18
+ * For merkle-tree campaigns, requires allocation and proof.
19
+ * For direct campaigns, allocation should be 0 and proof empty.
20
+ *
21
+ * @example
22
+ * ```typescript
23
+ * // Direct campaign claim
24
+ * const result = await sdk.claims.claim({
25
+ * campaignId: 1n,
26
+ * allocation: 0n,
27
+ * proof: [],
28
+ * });
29
+ *
30
+ * // Merkle campaign claim
31
+ * const result = await sdk.claims.claim({
32
+ * campaignId: 1n,
33
+ * allocation: parseEther('100'),
34
+ * proof: ['0x...', '0x...'],
35
+ * });
36
+ * ```
37
+ */
38
+ async claim(params) {
39
+ const wallet = this.requireWallet();
40
+ let hash;
41
+ if (params.claimTo) {
42
+ hash = await wallet.writeContract({
43
+ chain: wallet.chain,
44
+ account: wallet.account,
45
+ address: this.diamondAddress,
46
+ abi: DIAMOND_ABI,
47
+ functionName: "claimTo",
48
+ args: [
49
+ params.campaignId,
50
+ params.claimTo,
51
+ params.allocation ?? 0n,
52
+ params.proof ?? []
53
+ ]
54
+ });
55
+ } else {
56
+ hash = await wallet.writeContract({
57
+ chain: wallet.chain,
58
+ account: wallet.account,
59
+ address: this.diamondAddress,
60
+ abi: DIAMOND_ABI,
61
+ functionName: "claim",
62
+ args: [
63
+ params.campaignId,
64
+ params.allocation ?? 0n,
65
+ params.proof ?? []
66
+ ]
67
+ });
68
+ }
69
+ return this.createTransactionResult(hash);
70
+ }
71
+ /**
72
+ * Claim from a campaign for multiple recipients in a single transaction
73
+ *
74
+ * More gas efficient than multiple individual claims.
75
+ * For direct allocation campaigns only.
76
+ *
77
+ * @example
78
+ * ```typescript
79
+ * const result = await sdk.claims.claimBatch({
80
+ * campaignId: 1n,
81
+ * recipients: ['0x...', '0x...', '0x...'],
82
+ * });
83
+ * ```
84
+ */
85
+ async claimBatch(params) {
86
+ const wallet = this.requireWallet();
87
+ const hash = await wallet.writeContract({
88
+ chain: wallet.chain,
89
+ account: wallet.account,
90
+ address: this.diamondAddress,
91
+ abi: DIAMOND_ABI,
92
+ functionName: "claimMany",
93
+ args: [params.campaignId, params.recipients]
94
+ });
95
+ return this.createTransactionResult(hash);
96
+ }
97
+ /**
98
+ * Release locked tokens (for Lock campaigns)
99
+ *
100
+ * Can only be called after the unlock time has passed.
101
+ *
102
+ * @example
103
+ * ```typescript
104
+ * const result = await sdk.claims.releaseLock(campaignId, [recipient1, recipient2]);
105
+ * ```
106
+ */
107
+ async releaseLock(campaignId, recipients) {
108
+ const wallet = this.requireWallet();
109
+ const hash = await wallet.writeContract({
110
+ chain: wallet.chain,
111
+ account: wallet.account,
112
+ address: this.diamondAddress,
113
+ abi: DIAMOND_ABI,
114
+ functionName: "releaseLock",
115
+ args: [campaignId, recipients]
116
+ });
117
+ return this.createTransactionResult(hash);
118
+ }
119
+ // ============================================================================
120
+ // Meta-Transaction Claims (Gasless)
121
+ // ============================================================================
122
+ /**
123
+ * Claim via meta-transaction (gasless for recipient)
124
+ *
125
+ * A relayer submits the transaction on behalf of the recipient.
126
+ * The recipient signs an EIP-712 message off-chain.
127
+ *
128
+ * @example
129
+ * ```typescript
130
+ * // Recipient signs off-chain
131
+ * const signedAuth = await sdk.claims.signClaimMessage({
132
+ * campaignId,
133
+ * allocation: parseEther('100'),
134
+ * proof: ['0x...'],
135
+ * deadline: Math.floor(Date.now() / 1000) + 3600, // 1 hour
136
+ * });
137
+ *
138
+ * // Relayer submits
139
+ * const result = await sdk.claims.claimWithSig(signedAuth);
140
+ * ```
141
+ */
142
+ async claimWithSig(params) {
143
+ const wallet = this.requireWallet();
144
+ const auth = {
145
+ id: params.campaignId,
146
+ claimant: params.claimant,
147
+ payoutTo: params.payoutTo ?? params.claimant,
148
+ allocation: params.allocation,
149
+ proofHash: this.computeProofHash(params.proof),
150
+ deadline: BigInt(params.deadline),
151
+ nonce: params.nonce
152
+ };
153
+ const hash = await wallet.writeContract({
154
+ chain: wallet.chain,
155
+ account: wallet.account,
156
+ address: this.diamondAddress,
157
+ abi: DIAMOND_ABI,
158
+ functionName: "claimWithSig",
159
+ args: [auth, params.proof, params.signature]
160
+ });
161
+ return this.createTransactionResult(hash);
162
+ }
163
+ /**
164
+ * Generate the EIP-712 typed data for a claim signature
165
+ *
166
+ * The recipient signs this message off-chain.
167
+ */
168
+ getClaimTypedData(campaignId, claimant, payoutTo, allocation, proofHash, nonce, deadline) {
169
+ return {
170
+ domain: {
171
+ name: "PepayStreams",
172
+ version: "1",
173
+ chainId: this.chainId,
174
+ verifyingContract: this.diamondAddress
175
+ },
176
+ types: {
177
+ ClaimAuth: [
178
+ { name: "id", type: "uint256" },
179
+ { name: "claimant", type: "address" },
180
+ { name: "payoutTo", type: "address" },
181
+ { name: "allocation", type: "uint128" },
182
+ { name: "proofHash", type: "bytes32" },
183
+ { name: "deadline", type: "uint64" },
184
+ { name: "nonce", type: "uint256" }
185
+ ]
186
+ },
187
+ primaryType: "ClaimAuth",
188
+ message: {
189
+ id: campaignId,
190
+ claimant,
191
+ payoutTo,
192
+ allocation,
193
+ proofHash,
194
+ deadline: BigInt(deadline),
195
+ nonce
196
+ }
197
+ };
198
+ }
199
+ /**
200
+ * Sign a claim message for meta-transaction
201
+ *
202
+ * Returns the signature that can be submitted by a relayer.
203
+ */
204
+ async signClaimMessage(params) {
205
+ const wallet = this.requireWallet();
206
+ const claimant = wallet.account.address;
207
+ const payoutTo = params.payoutTo ?? claimant;
208
+ const nonce = await this.getClaimNonce(params.campaignId, claimant);
209
+ const proofHash = this.computeProofHash(params.proof);
210
+ const typedData = this.getClaimTypedData(
211
+ params.campaignId,
212
+ claimant,
213
+ payoutTo,
214
+ params.allocation,
215
+ proofHash,
216
+ nonce,
217
+ params.deadline
218
+ );
219
+ const signature = await wallet.signTypedData({
220
+ account: wallet.account,
221
+ domain: typedData.domain,
222
+ types: typedData.types,
223
+ primaryType: typedData.primaryType,
224
+ message: typedData.message
225
+ });
226
+ return {
227
+ signature,
228
+ nonce,
229
+ deadline: params.deadline,
230
+ claimant,
231
+ payoutTo,
232
+ allocation: params.allocation,
233
+ proof: params.proof,
234
+ campaignId: params.campaignId
235
+ };
236
+ }
237
+ /**
238
+ * Get the current nonce for claim meta-transactions
239
+ */
240
+ async getClaimNonce(campaignId, address) {
241
+ const result = await this.publicClient.readContract({
242
+ address: this.diamondAddress,
243
+ abi: DIAMOND_ABI,
244
+ functionName: "noncesClaim",
245
+ args: [campaignId, address]
246
+ });
247
+ return result;
248
+ }
249
+ // ============================================================================
250
+ // Claim Status Queries
251
+ // ============================================================================
252
+ /**
253
+ * Get the amount currently claimable for a recipient
254
+ *
255
+ * @example
256
+ * ```typescript
257
+ * const claimable = await sdk.claims.getClaimable(campaignId, recipientAddress);
258
+ * console.log('Claimable:', formatEther(claimable));
259
+ * ```
260
+ */
261
+ async getClaimable(campaignId, recipient) {
262
+ const result = await this.publicClient.readContract({
263
+ address: this.diamondAddress,
264
+ abi: DIAMOND_ABI,
265
+ functionName: "claimableOf",
266
+ args: [campaignId, recipient]
267
+ });
268
+ return result;
269
+ }
270
+ /**
271
+ * Check if a recipient is blocked from claiming
272
+ */
273
+ async isBlocked(campaignId, recipient) {
274
+ const result = await this.publicClient.readContract({
275
+ address: this.diamondAddress,
276
+ abi: DIAMOND_ABI,
277
+ functionName: "isBlocked",
278
+ args: [campaignId, recipient]
279
+ });
280
+ return result;
281
+ }
282
+ /**
283
+ * Get vested amount for a recipient (how much has vested so far)
284
+ */
285
+ async getVestedAmount(campaignId, recipient, allocation) {
286
+ const result = await this.publicClient.readContract({
287
+ address: this.diamondAddress,
288
+ abi: DIAMOND_ABI,
289
+ functionName: "vestedAmount",
290
+ args: [campaignId, recipient, allocation]
291
+ });
292
+ return result;
293
+ }
294
+ /**
295
+ * Get merkle claimed shares for a recipient
296
+ */
297
+ async getMerkleClaimedShares(campaignId, recipient) {
298
+ const result = await this.publicClient.readContract({
299
+ address: this.diamondAddress,
300
+ abi: DIAMOND_ABI,
301
+ functionName: "merkleClaimedShares",
302
+ args: [campaignId, recipient]
303
+ });
304
+ return result;
305
+ }
306
+ /**
307
+ * Get detailed recipient status for a campaign
308
+ */
309
+ async getRecipientStatus(campaignId, recipient, allocation) {
310
+ const [claimable, blocked, vested, claimed] = await Promise.all([
311
+ this.getClaimable(campaignId, recipient),
312
+ this.isBlocked(campaignId, recipient),
313
+ this.getVestedAmount(campaignId, recipient, allocation),
314
+ this.getMerkleClaimedShares(campaignId, recipient)
315
+ ]);
316
+ return {
317
+ allocated: allocation,
318
+ claimed,
319
+ due: claimable,
320
+ blocked,
321
+ fullyVested: vested >= allocation
322
+ };
323
+ }
324
+ /**
325
+ * Check if a recipient can claim from a campaign
326
+ */
327
+ async canClaim(campaignId, recipient) {
328
+ try {
329
+ const [claimable, blocked] = await Promise.all([
330
+ this.getClaimable(campaignId, recipient),
331
+ this.isBlocked(campaignId, recipient)
332
+ ]);
333
+ return claimable > 0n && !blocked;
334
+ } catch {
335
+ return false;
336
+ }
337
+ }
338
+ // ============================================================================
339
+ // Merkle Proof Helpers
340
+ // ============================================================================
341
+ /**
342
+ * Verify a Merkle proof locally
343
+ *
344
+ * Useful for validating proofs before submitting transactions.
345
+ */
346
+ verifyMerkleProof(root, leaf, proof) {
347
+ let computedHash = leaf;
348
+ for (const proofElement of proof) {
349
+ if (computedHash < proofElement) {
350
+ computedHash = keccak256(
351
+ encodePacked(["bytes32", "bytes32"], [computedHash, proofElement])
352
+ );
353
+ } else {
354
+ computedHash = keccak256(
355
+ encodePacked(["bytes32", "bytes32"], [proofElement, computedHash])
356
+ );
357
+ }
358
+ }
359
+ return computedHash === root;
360
+ }
361
+ /**
362
+ * Compute Merkle leaf for an allocation
363
+ */
364
+ computeMerkleLeaf(address, amount) {
365
+ return keccak256(encodePacked(["address", "uint256"], [address, amount]));
366
+ }
367
+ /**
368
+ * Compute proof hash for meta-transaction
369
+ */
370
+ computeProofHash(proof) {
371
+ if (proof.length === 0) {
372
+ return "0x0000000000000000000000000000000000000000000000000000000000000000";
373
+ }
374
+ return keccak256(encodePacked(["bytes32[]"], [proof]));
375
+ }
376
+ // ============================================================================
377
+ // Helpers
378
+ // ============================================================================
379
+ requireWallet() {
380
+ if (!this.walletClient) {
381
+ throw new Error(
382
+ "Wallet client required for write operations. Initialize SDK with a signer."
383
+ );
384
+ }
385
+ return this.walletClient;
386
+ }
387
+ createTransactionResult(hash) {
388
+ return {
389
+ hash,
390
+ wait: async () => {
391
+ const receipt = await this.publicClient.waitForTransactionReceipt({
392
+ hash
393
+ });
394
+ return {
395
+ blockNumber: receipt.blockNumber,
396
+ transactionHash: receipt.transactionHash,
397
+ gasUsed: receipt.gasUsed,
398
+ status: receipt.status,
399
+ logs: receipt.logs
400
+ };
401
+ }
402
+ };
403
+ }
404
+ };
405
+ var claims_default = ClaimsModule;
406
+
407
+ export { ClaimsModule, claims_default as default };
408
+ //# sourceMappingURL=index.mjs.map
409
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/claims/index.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\r\n * Claims Module\r\n *\r\n * Provides methods for claiming tokens from campaigns:\r\n * - Single claims (with merkle proof)\r\n * - Batch claims\r\n * - Meta-transaction (gasless) claims\r\n * - Lock releases\r\n */\r\nimport {\r\n type PublicClient,\r\n type WalletClient,\r\n type Address,\r\n type Hash,\r\n type Hex,\r\n keccak256,\r\n encodePacked,\r\n} from 'viem';\r\nimport { DIAMOND_ABI } from '@pepay-streams/abi/diamond';\r\nimport type {\r\n ClaimParams,\r\n BatchClaimParams,\r\n MetaClaimParams,\r\n RecipientStatus,\r\n TransactionResult,\r\n} from '../types';\r\n\r\n/**\r\n * EIP-712 domain for meta-transaction signatures\r\n */\r\ninterface EIP712Domain {\r\n name: string;\r\n version: string;\r\n chainId: number;\r\n verifyingContract: Address;\r\n}\r\n\r\n/**\r\n * Claims module for claiming tokens from distribution campaigns\r\n */\r\nexport class ClaimsModule {\r\n constructor(\r\n private readonly publicClient: PublicClient,\r\n private readonly walletClient: WalletClient | undefined,\r\n private readonly diamondAddress: Address,\r\n private readonly chainId: number\r\n ) {}\r\n\r\n // ============================================================================\r\n // Standard Claims\r\n // ============================================================================\r\n\r\n /**\r\n * Claim vested tokens from a campaign\r\n *\r\n * For merkle-tree campaigns, requires allocation and proof.\r\n * For direct campaigns, allocation should be 0 and proof empty.\r\n *\r\n * @example\r\n * ```typescript\r\n * // Direct campaign claim\r\n * const result = await sdk.claims.claim({\r\n * campaignId: 1n,\r\n * allocation: 0n,\r\n * proof: [],\r\n * });\r\n *\r\n * // Merkle campaign claim\r\n * const result = await sdk.claims.claim({\r\n * campaignId: 1n,\r\n * allocation: parseEther('100'),\r\n * proof: ['0x...', '0x...'],\r\n * });\r\n * ```\r\n */\r\n async claim(params: ClaimParams): Promise<TransactionResult> {\r\n const wallet = this.requireWallet();\r\n\r\n let hash: Hash;\r\n\r\n if (params.claimTo) {\r\n hash = await wallet.writeContract({\r\n chain: wallet.chain,\r\n account: wallet.account!,\r\n address: this.diamondAddress,\r\n abi: DIAMOND_ABI,\r\n functionName: 'claimTo',\r\n args: [\r\n params.campaignId,\r\n params.claimTo,\r\n params.allocation ?? 0n,\r\n params.proof ?? [],\r\n ],\r\n });\r\n } else {\r\n hash = await wallet.writeContract({\r\n chain: wallet.chain,\r\n account: wallet.account!,\r\n address: this.diamondAddress,\r\n abi: DIAMOND_ABI,\r\n functionName: 'claim',\r\n args: [\r\n params.campaignId,\r\n params.allocation ?? 0n,\r\n params.proof ?? [],\r\n ],\r\n });\r\n }\r\n\r\n return this.createTransactionResult(hash);\r\n }\r\n\r\n /**\r\n * Claim from a campaign for multiple recipients in a single transaction\r\n *\r\n * More gas efficient than multiple individual claims.\r\n * For direct allocation campaigns only.\r\n *\r\n * @example\r\n * ```typescript\r\n * const result = await sdk.claims.claimBatch({\r\n * campaignId: 1n,\r\n * recipients: ['0x...', '0x...', '0x...'],\r\n * });\r\n * ```\r\n */\r\n async claimBatch(params: BatchClaimParams): Promise<TransactionResult> {\r\n const wallet = this.requireWallet();\r\n\r\n const hash = await wallet.writeContract({\r\n chain: wallet.chain,\r\n account: wallet.account!,\r\n address: this.diamondAddress,\r\n abi: DIAMOND_ABI,\r\n functionName: 'claimMany',\r\n args: [params.campaignId, params.recipients],\r\n });\r\n\r\n return this.createTransactionResult(hash);\r\n }\r\n\r\n /**\r\n * Release locked tokens (for Lock campaigns)\r\n *\r\n * Can only be called after the unlock time has passed.\r\n *\r\n * @example\r\n * ```typescript\r\n * const result = await sdk.claims.releaseLock(campaignId, [recipient1, recipient2]);\r\n * ```\r\n */\r\n async releaseLock(\r\n campaignId: bigint,\r\n recipients: Address[]\r\n ): Promise<TransactionResult> {\r\n const wallet = this.requireWallet();\r\n\r\n const hash = await wallet.writeContract({\r\n chain: wallet.chain,\r\n account: wallet.account!,\r\n address: this.diamondAddress,\r\n abi: DIAMOND_ABI,\r\n functionName: 'releaseLock',\r\n args: [campaignId, recipients],\r\n });\r\n\r\n return this.createTransactionResult(hash);\r\n }\r\n\r\n // ============================================================================\r\n // Meta-Transaction Claims (Gasless)\r\n // ============================================================================\r\n\r\n /**\r\n * Claim via meta-transaction (gasless for recipient)\r\n *\r\n * A relayer submits the transaction on behalf of the recipient.\r\n * The recipient signs an EIP-712 message off-chain.\r\n *\r\n * @example\r\n * ```typescript\r\n * // Recipient signs off-chain\r\n * const signedAuth = await sdk.claims.signClaimMessage({\r\n * campaignId,\r\n * allocation: parseEther('100'),\r\n * proof: ['0x...'],\r\n * deadline: Math.floor(Date.now() / 1000) + 3600, // 1 hour\r\n * });\r\n *\r\n * // Relayer submits\r\n * const result = await sdk.claims.claimWithSig(signedAuth);\r\n * ```\r\n */\r\n async claimWithSig(params: MetaClaimParams): Promise<TransactionResult> {\r\n const wallet = this.requireWallet();\r\n\r\n const auth = {\r\n id: params.campaignId,\r\n claimant: params.claimant,\r\n payoutTo: params.payoutTo ?? params.claimant,\r\n allocation: params.allocation,\r\n proofHash: this.computeProofHash(params.proof),\r\n deadline: BigInt(params.deadline),\r\n nonce: params.nonce,\r\n };\r\n\r\n const hash = await wallet.writeContract({\r\n chain: wallet.chain,\r\n account: wallet.account!,\r\n address: this.diamondAddress,\r\n abi: DIAMOND_ABI,\r\n functionName: 'claimWithSig',\r\n args: [auth, params.proof, params.signature] as const,\r\n });\r\n\r\n return this.createTransactionResult(hash);\r\n }\r\n\r\n /**\r\n * Generate the EIP-712 typed data for a claim signature\r\n *\r\n * The recipient signs this message off-chain.\r\n */\r\n getClaimTypedData(\r\n campaignId: bigint,\r\n claimant: Address,\r\n payoutTo: Address,\r\n allocation: bigint,\r\n proofHash: Hex,\r\n nonce: bigint,\r\n deadline: number\r\n ): {\r\n domain: EIP712Domain;\r\n types: Record<string, { name: string; type: string }[]>;\r\n primaryType: string;\r\n message: Record<string, unknown>;\r\n } {\r\n return {\r\n domain: {\r\n name: 'PepayStreams',\r\n version: '1',\r\n chainId: this.chainId,\r\n verifyingContract: this.diamondAddress,\r\n },\r\n types: {\r\n ClaimAuth: [\r\n { name: 'id', type: 'uint256' },\r\n { name: 'claimant', type: 'address' },\r\n { name: 'payoutTo', type: 'address' },\r\n { name: 'allocation', type: 'uint128' },\r\n { name: 'proofHash', type: 'bytes32' },\r\n { name: 'deadline', type: 'uint64' },\r\n { name: 'nonce', type: 'uint256' },\r\n ],\r\n },\r\n primaryType: 'ClaimAuth',\r\n message: {\r\n id: campaignId,\r\n claimant,\r\n payoutTo,\r\n allocation,\r\n proofHash,\r\n deadline: BigInt(deadline),\r\n nonce,\r\n },\r\n };\r\n }\r\n\r\n /**\r\n * Sign a claim message for meta-transaction\r\n *\r\n * Returns the signature that can be submitted by a relayer.\r\n */\r\n async signClaimMessage(params: {\r\n campaignId: bigint;\r\n allocation: bigint;\r\n proof: Hex[];\r\n deadline: number;\r\n payoutTo?: Address;\r\n }): Promise<{\r\n signature: Hex;\r\n nonce: bigint;\r\n deadline: number;\r\n claimant: Address;\r\n payoutTo: Address;\r\n allocation: bigint;\r\n proof: Hex[];\r\n campaignId: bigint;\r\n }> {\r\n const wallet = this.requireWallet();\r\n const claimant = wallet.account!.address;\r\n const payoutTo = params.payoutTo ?? claimant;\r\n\r\n // Get current nonce\r\n const nonce = await this.getClaimNonce(params.campaignId, claimant);\r\n const proofHash = this.computeProofHash(params.proof);\r\n\r\n const typedData = this.getClaimTypedData(\r\n params.campaignId,\r\n claimant,\r\n payoutTo,\r\n params.allocation,\r\n proofHash,\r\n nonce,\r\n params.deadline\r\n );\r\n\r\n const signature = await wallet.signTypedData({\r\n account: wallet.account!,\r\n domain: typedData.domain,\r\n types: typedData.types,\r\n primaryType: typedData.primaryType as 'ClaimAuth',\r\n message: typedData.message,\r\n });\r\n\r\n return {\r\n signature,\r\n nonce,\r\n deadline: params.deadline,\r\n claimant,\r\n payoutTo,\r\n allocation: params.allocation,\r\n proof: params.proof,\r\n campaignId: params.campaignId,\r\n };\r\n }\r\n\r\n /**\r\n * Get the current nonce for claim meta-transactions\r\n */\r\n async getClaimNonce(campaignId: bigint, address: Address): Promise<bigint> {\r\n const result = await this.publicClient.readContract({\r\n address: this.diamondAddress,\r\n abi: DIAMOND_ABI,\r\n functionName: 'noncesClaim',\r\n args: [campaignId, address],\r\n });\r\n\r\n return result as bigint;\r\n }\r\n\r\n // ============================================================================\r\n // Claim Status Queries\r\n // ============================================================================\r\n\r\n /**\r\n * Get the amount currently claimable for a recipient\r\n *\r\n * @example\r\n * ```typescript\r\n * const claimable = await sdk.claims.getClaimable(campaignId, recipientAddress);\r\n * console.log('Claimable:', formatEther(claimable));\r\n * ```\r\n */\r\n async getClaimable(campaignId: bigint, recipient: Address): Promise<bigint> {\r\n const result = await this.publicClient.readContract({\r\n address: this.diamondAddress,\r\n abi: DIAMOND_ABI,\r\n functionName: 'claimableOf',\r\n args: [campaignId, recipient],\r\n });\r\n\r\n return result as bigint;\r\n }\r\n\r\n /**\r\n * Check if a recipient is blocked from claiming\r\n */\r\n async isBlocked(campaignId: bigint, recipient: Address): Promise<boolean> {\r\n const result = await this.publicClient.readContract({\r\n address: this.diamondAddress,\r\n abi: DIAMOND_ABI,\r\n functionName: 'isBlocked',\r\n args: [campaignId, recipient],\r\n });\r\n\r\n return result as boolean;\r\n }\r\n\r\n /**\r\n * Get vested amount for a recipient (how much has vested so far)\r\n */\r\n async getVestedAmount(\r\n campaignId: bigint,\r\n recipient: Address,\r\n allocation: bigint\r\n ): Promise<bigint> {\r\n const result = await this.publicClient.readContract({\r\n address: this.diamondAddress,\r\n abi: DIAMOND_ABI,\r\n functionName: 'vestedAmount',\r\n args: [campaignId, recipient, allocation],\r\n });\r\n\r\n return result as bigint;\r\n }\r\n\r\n /**\r\n * Get merkle claimed shares for a recipient\r\n */\r\n async getMerkleClaimedShares(\r\n campaignId: bigint,\r\n recipient: Address\r\n ): Promise<bigint> {\r\n const result = await this.publicClient.readContract({\r\n address: this.diamondAddress,\r\n abi: DIAMOND_ABI,\r\n functionName: 'merkleClaimedShares',\r\n args: [campaignId, recipient],\r\n });\r\n\r\n return result as bigint;\r\n }\r\n\r\n /**\r\n * Get detailed recipient status for a campaign\r\n */\r\n async getRecipientStatus(\r\n campaignId: bigint,\r\n recipient: Address,\r\n allocation: bigint\r\n ): Promise<RecipientStatus> {\r\n const [claimable, blocked, vested, claimed] = await Promise.all([\r\n this.getClaimable(campaignId, recipient),\r\n this.isBlocked(campaignId, recipient),\r\n this.getVestedAmount(campaignId, recipient, allocation),\r\n this.getMerkleClaimedShares(campaignId, recipient),\r\n ]);\r\n\r\n return {\r\n allocated: allocation,\r\n claimed,\r\n due: claimable,\r\n blocked,\r\n fullyVested: vested >= allocation,\r\n };\r\n }\r\n\r\n /**\r\n * Check if a recipient can claim from a campaign\r\n */\r\n async canClaim(campaignId: bigint, recipient: Address): Promise<boolean> {\r\n try {\r\n const [claimable, blocked] = await Promise.all([\r\n this.getClaimable(campaignId, recipient),\r\n this.isBlocked(campaignId, recipient),\r\n ]);\r\n return claimable > 0n && !blocked;\r\n } catch {\r\n return false;\r\n }\r\n }\r\n\r\n // ============================================================================\r\n // Merkle Proof Helpers\r\n // ============================================================================\r\n\r\n /**\r\n * Verify a Merkle proof locally\r\n *\r\n * Useful for validating proofs before submitting transactions.\r\n */\r\n verifyMerkleProof(root: Hex, leaf: Hex, proof: Hex[]): boolean {\r\n let computedHash = leaf;\r\n\r\n for (const proofElement of proof) {\r\n if (computedHash < proofElement) {\r\n computedHash = keccak256(\r\n encodePacked(['bytes32', 'bytes32'], [computedHash, proofElement])\r\n );\r\n } else {\r\n computedHash = keccak256(\r\n encodePacked(['bytes32', 'bytes32'], [proofElement, computedHash])\r\n );\r\n }\r\n }\r\n\r\n return computedHash === root;\r\n }\r\n\r\n /**\r\n * Compute Merkle leaf for an allocation\r\n */\r\n computeMerkleLeaf(address: Address, amount: bigint): Hex {\r\n return keccak256(encodePacked(['address', 'uint256'], [address, amount]));\r\n }\r\n\r\n /**\r\n * Compute proof hash for meta-transaction\r\n */\r\n computeProofHash(proof: Hex[]): Hex {\r\n if (proof.length === 0) {\r\n return '0x0000000000000000000000000000000000000000000000000000000000000000';\r\n }\r\n return keccak256(encodePacked(['bytes32[]'], [proof]));\r\n }\r\n\r\n // ============================================================================\r\n // Helpers\r\n // ============================================================================\r\n\r\n private requireWallet(): WalletClient {\r\n if (!this.walletClient) {\r\n throw new Error(\r\n 'Wallet client required for write operations. Initialize SDK with a signer.'\r\n );\r\n }\r\n return this.walletClient;\r\n }\r\n\r\n private createTransactionResult(hash: Hash): TransactionResult {\r\n return {\r\n hash,\r\n wait: async () => {\r\n const receipt = await this.publicClient.waitForTransactionReceipt({\r\n hash,\r\n });\r\n return {\r\n blockNumber: receipt.blockNumber,\r\n transactionHash: receipt.transactionHash,\r\n gasUsed: receipt.gasUsed,\r\n status: receipt.status,\r\n logs: receipt.logs,\r\n };\r\n },\r\n };\r\n }\r\n}\r\n\r\nexport default ClaimsModule;\r\n"]}