@perkos/scheme-deferred 1.1.0 → 1.1.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.
Files changed (2) hide show
  1. package/README.md +357 -0
  2. package/package.json +3 -2
package/README.md ADDED
@@ -0,0 +1,357 @@
1
+ # @perkos/scheme-deferred
2
+
3
+ EIP-712 voucher-based deferred payment verification utilities for x402 deferred scheme. Provides signature verification, escrow balance checking, and voucher validation for off-chain payment aggregation.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @perkos/scheme-deferred
9
+ ```
10
+
11
+ ## Overview
12
+
13
+ The deferred scheme enables off-chain voucher signing with on-chain batch settlement:
14
+
15
+ 1. **Client deposits** funds into escrow contract
16
+ 2. **Client signs vouchers** (EIP-712) for each payment
17
+ 3. **Facilitator verifies** signatures and escrow balance
18
+ 4. **Seller claims vouchers** via escrow contract
19
+
20
+ ## Usage
21
+
22
+ ### Basic Verification
23
+
24
+ ```typescript
25
+ import { DeferredSchemeVerifier } from '@perkos/scheme-deferred';
26
+ import type { DeferredPayload, PaymentRequirements } from '@perkos/scheme-deferred';
27
+
28
+ const verifier = new DeferredSchemeVerifier({
29
+ network: 'base',
30
+ escrowAddress: '0x...',
31
+ rpcUrl: 'https://mainnet.base.org' // optional
32
+ });
33
+
34
+ const payload: DeferredPayload = {
35
+ voucher: {
36
+ id: '0x...',
37
+ buyer: '0x...',
38
+ seller: '0x...',
39
+ valueAggregate: '5000000',
40
+ asset: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
41
+ timestamp: '1735689600',
42
+ nonce: '1',
43
+ escrow: '0x...',
44
+ chainId: '8453'
45
+ },
46
+ signature: '0x...'
47
+ };
48
+
49
+ const requirements: PaymentRequirements = {
50
+ scheme: 'deferred',
51
+ network: 'base',
52
+ maxAmountRequired: '1000000',
53
+ resource: '/api/service',
54
+ payTo: '0x...',
55
+ maxTimeoutSeconds: 3600,
56
+ asset: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'
57
+ };
58
+
59
+ const result = await verifier.verify(payload, requirements);
60
+
61
+ if (result.isValid) {
62
+ console.log('Valid voucher from:', result.payer);
63
+ } else {
64
+ console.error('Invalid:', result.invalidReason);
65
+ }
66
+ ```
67
+
68
+ ### Create Voucher for Signing
69
+
70
+ ```typescript
71
+ import {
72
+ generateVoucherId,
73
+ createVoucherMessage,
74
+ createEIP712Domain,
75
+ VOUCHER_TYPES
76
+ } from '@perkos/scheme-deferred';
77
+ import { signTypedData } from 'viem/accounts';
78
+
79
+ // Generate unique voucher ID
80
+ const voucherId = generateVoucherId();
81
+
82
+ // Create voucher message
83
+ const message = createVoucherMessage(
84
+ voucherId,
85
+ '0x...buyer', // buyer
86
+ '0x...seller', // seller
87
+ '5000000', // valueAggregate
88
+ '0x...usdc', // asset
89
+ Math.floor(Date.now() / 1000), // timestamp
90
+ '1', // nonce
91
+ '0x...escrow', // escrow
92
+ 8453 // chainId
93
+ );
94
+
95
+ // Create EIP-712 domain
96
+ const domain = createEIP712Domain(
97
+ 8453, // chainId
98
+ '0x...escrow' // escrow contract address
99
+ );
100
+
101
+ // Sign the voucher (client-side)
102
+ const signature = await signTypedData({
103
+ domain,
104
+ types: VOUCHER_TYPES,
105
+ primaryType: 'Voucher',
106
+ message,
107
+ privateKey: '0x...'
108
+ });
109
+ ```
110
+
111
+ ### Check Escrow Balance
112
+
113
+ ```typescript
114
+ const verifier = new DeferredSchemeVerifier({
115
+ network: 'base',
116
+ escrowAddress: '0x...'
117
+ });
118
+
119
+ const balance = await verifier.getEscrowBalance(
120
+ '0x...buyer',
121
+ '0x...seller',
122
+ '0x...asset'
123
+ );
124
+
125
+ console.log('Available balance:', balance.toString());
126
+ ```
127
+
128
+ ### Check Voucher Status
129
+
130
+ ```typescript
131
+ const claimed = await verifier.isVoucherClaimed(
132
+ '0x...voucherId',
133
+ 1n // nonce
134
+ );
135
+
136
+ if (claimed) {
137
+ console.log('Voucher already claimed');
138
+ }
139
+ ```
140
+
141
+ ### Recover Signer from Voucher
142
+
143
+ ```typescript
144
+ const signer = await verifier.recoverSigner(voucher, signature);
145
+
146
+ if (signer && signer.toLowerCase() === voucher.buyer.toLowerCase()) {
147
+ console.log('Valid signature from buyer');
148
+ }
149
+ ```
150
+
151
+ ## API Reference
152
+
153
+ ### DeferredSchemeVerifier
154
+
155
+ ```typescript
156
+ class DeferredSchemeVerifier {
157
+ constructor(config: DeferredSchemeConfig);
158
+
159
+ // Verification
160
+ verify(payload: DeferredPayload, requirements: PaymentRequirements): Promise<VerifyResponse>;
161
+ validateVoucher(voucher: Voucher, requirements: PaymentRequirements): boolean;
162
+ recoverSigner(voucher: Voucher, signature: Hex): Promise<Address | null>;
163
+
164
+ // Escrow operations
165
+ getEscrowBalance(buyer: Address, seller: Address, asset: Address): Promise<bigint>;
166
+ isVoucherClaimed(voucherId: Hex, nonce: bigint): Promise<boolean>;
167
+
168
+ // Getters
169
+ getNetwork(): SupportedNetwork;
170
+ getChainId(): number;
171
+ getEscrowAddress(): Address;
172
+ getEIP712Domain(): EIP712Domain;
173
+ }
174
+ ```
175
+
176
+ ### DeferredSchemeConfig
177
+
178
+ ```typescript
179
+ interface DeferredSchemeConfig {
180
+ network: SupportedNetwork;
181
+ escrowAddress: Address;
182
+ rpcUrl?: string;
183
+ domainName?: string; // default: "X402DeferredEscrow"
184
+ domainVersion?: string; // default: "1"
185
+ }
186
+ ```
187
+
188
+ ### EIP712Domain
189
+
190
+ ```typescript
191
+ interface EIP712Domain {
192
+ name: string;
193
+ version: string;
194
+ chainId: number;
195
+ verifyingContract: Address;
196
+ }
197
+ ```
198
+
199
+ ### SignatureParts
200
+
201
+ ```typescript
202
+ interface SignatureParts {
203
+ v: number;
204
+ r: Hex;
205
+ s: Hex;
206
+ }
207
+ ```
208
+
209
+ ## Utility Functions
210
+
211
+ ### generateVoucherId
212
+
213
+ Generate a random bytes32 voucher ID.
214
+
215
+ ```typescript
216
+ import { generateVoucherId } from '@perkos/scheme-deferred';
217
+
218
+ const voucherId = generateVoucherId();
219
+ // => '0x1234...abcd' (32 bytes hex)
220
+ ```
221
+
222
+ ### createVoucherMessage
223
+
224
+ Create a voucher message object for EIP-712 signing.
225
+
226
+ ```typescript
227
+ import { createVoucherMessage } from '@perkos/scheme-deferred';
228
+
229
+ const message = createVoucherMessage(
230
+ '0x...', // id
231
+ '0x...', // buyer
232
+ '0x...', // seller
233
+ '5000000', // valueAggregate
234
+ '0x...', // asset
235
+ 1735689600, // timestamp
236
+ '1', // nonce
237
+ '0x...', // escrow
238
+ 8453 // chainId
239
+ );
240
+ ```
241
+
242
+ ### createVoucherTuple
243
+
244
+ Convert a Voucher object to a tuple format for contract calls.
245
+
246
+ ```typescript
247
+ import { createVoucherTuple } from '@perkos/scheme-deferred';
248
+
249
+ const tuple = createVoucherTuple(voucher);
250
+ // Use with escrow contract claimVoucher function
251
+ ```
252
+
253
+ ### createEIP712Domain
254
+
255
+ Create an EIP-712 domain for voucher signing.
256
+
257
+ ```typescript
258
+ import { createEIP712Domain } from '@perkos/scheme-deferred';
259
+
260
+ const domain = createEIP712Domain(
261
+ 8453, // chainId
262
+ '0x...', // escrowAddress
263
+ 'CustomName', // optional domain name
264
+ '2' // optional version
265
+ );
266
+ ```
267
+
268
+ ### parseSignature
269
+
270
+ Parse a signature into v, r, s components.
271
+
272
+ ```typescript
273
+ import { parseSignature } from '@perkos/scheme-deferred';
274
+
275
+ const { v, r, s } = parseSignature('0x...');
276
+ ```
277
+
278
+ ## EIP-712 Type Definition
279
+
280
+ The voucher type definition used for EIP-712 signing:
281
+
282
+ ```typescript
283
+ import { VOUCHER_TYPES, VOUCHER_TYPE_DEF } from '@perkos/scheme-deferred';
284
+
285
+ // VOUCHER_TYPE_DEF structure:
286
+ [
287
+ { name: "id", type: "bytes32" },
288
+ { name: "buyer", type: "address" },
289
+ { name: "seller", type: "address" },
290
+ { name: "valueAggregate", type: "uint256" },
291
+ { name: "asset", type: "address" },
292
+ { name: "timestamp", type: "uint64" },
293
+ { name: "nonce", type: "uint256" },
294
+ { name: "escrow", type: "address" },
295
+ { name: "chainId", type: "uint256" }
296
+ ]
297
+ ```
298
+
299
+ ## Escrow Contract ABIs
300
+
301
+ The package exports ABIs for interacting with the deferred escrow contract:
302
+
303
+ ```typescript
304
+ import {
305
+ DEFERRED_ESCROW_ABI,
306
+ DEFERRED_ESCROW_GET_BALANCE_ABI,
307
+ DEFERRED_ESCROW_VOUCHER_CLAIMED_ABI,
308
+ DEFERRED_ESCROW_CLAIM_VOUCHER_ABI,
309
+ ERC20_BALANCE_ABI
310
+ } from '@perkos/scheme-deferred';
311
+ ```
312
+
313
+ ### Available Functions
314
+
315
+ | ABI | Function | Description |
316
+ |-----|----------|-------------|
317
+ | `DEFERRED_ESCROW_GET_BALANCE_ABI` | `getAvailableBalance(buyer, seller, asset)` | Get escrow balance |
318
+ | `DEFERRED_ESCROW_VOUCHER_CLAIMED_ABI` | `voucherClaimed(voucherId, nonce)` | Check if claimed |
319
+ | `DEFERRED_ESCROW_CLAIM_VOUCHER_ABI` | `claimVoucher(voucher, signature)` | Claim voucher |
320
+
321
+ ## Verification Flow
322
+
323
+ The `verify()` method performs these checks in order:
324
+
325
+ 1. **Voucher Validation**: Checks escrow address, chainId, seller, amount, and asset
326
+ 2. **Signature Recovery**: Recovers signer using EIP-712 typed data
327
+ 3. **Signer Verification**: Ensures signer matches voucher buyer
328
+ 4. **Claim Status**: Checks if voucher already claimed on-chain
329
+ 5. **Balance Check**: Verifies sufficient escrow balance
330
+
331
+ ## Re-exported Types
332
+
333
+ ```typescript
334
+ import type {
335
+ DeferredPayload,
336
+ Voucher,
337
+ VerifyResponse,
338
+ PaymentRequirements,
339
+ Address,
340
+ Hex
341
+ } from '@perkos/scheme-deferred';
342
+
343
+ // V2 helper
344
+ import { getPaymentAmount } from '@perkos/scheme-deferred';
345
+ ```
346
+
347
+ ## Related Packages
348
+
349
+ - [@perkos/types-x402](https://www.npmjs.com/package/@perkos/types-x402) - Core x402 types
350
+ - [@perkos/util-chains](https://www.npmjs.com/package/@perkos/util-chains) - Chain utilities
351
+ - [@perkos/scheme-exact](https://www.npmjs.com/package/@perkos/scheme-exact) - Exact payment scheme
352
+ - [@perkos/contracts-escrow](https://www.npmjs.com/package/@perkos/contracts-escrow) - Escrow contract ABI
353
+ - [@perkos/service-x402](https://www.npmjs.com/package/@perkos/service-x402) - x402 service orchestrator
354
+
355
+ ## License
356
+
357
+ MIT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@perkos/scheme-deferred",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "EIP-712 Voucher-based deferred payment verification utilities for x402 deferred scheme",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -13,7 +13,8 @@
13
13
  }
14
14
  },
15
15
  "files": [
16
- "dist"
16
+ "dist",
17
+ "README.md"
17
18
  ],
18
19
  "scripts": {
19
20
  "build": "tsup src/index.ts --format cjs,esm --dts",