@vera-pay/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.
package/README.md ADDED
@@ -0,0 +1,388 @@
1
+ # @verapay/sdk
2
+
3
+ On-chain subscription payments SDK for [Flow Blockchain](https://flow.com). Create plans, accept recurring stablecoin payments, schedule autonomous on-chain payment processing, and pin immutable receipts to IPFS via [Storacha](https://storacha.network) (Protocol Labs).
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @verapay/sdk ethers
9
+ ```
10
+
11
+ `ethers` v6 is a peer dependency.
12
+
13
+ ## Overview
14
+
15
+ The SDK provides two main classes:
16
+
17
+ | Class | Purpose |
18
+ |-------|---------|
19
+ | `VeraPayClient` | Interact with the VeraPay EVM smart contract — create plans, subscribe, process payments |
20
+ | `FlowScheduler` | Schedule autonomous recurring payments using Flow's native Cadence scheduled transactions |
21
+
22
+ Both support optional IPFS integration for pinning payment receipts.
23
+
24
+ ---
25
+
26
+ ## Quick Start
27
+
28
+ ### 1. Connect to VeraPay
29
+
30
+ ```typescript
31
+ import { VeraPayClient, createStorachaAdapter, DEPLOYED_CONTRACTS } from "@verapay/sdk";
32
+ import { ethers } from "ethers";
33
+
34
+ const provider = new ethers.BrowserProvider(window.ethereum);
35
+ const signer = await provider.getSigner();
36
+
37
+ // Optional: IPFS adapter for receipt pinning
38
+ const ipfs = createStorachaAdapter({
39
+ key: process.env.STORACHA_KEY!,
40
+ proof: process.env.STORACHA_PROOF!,
41
+ });
42
+
43
+ const client = VeraPayClient.fromNetwork(
44
+ "flow-testnet",
45
+ DEPLOYED_CONTRACTS["flow-testnet"],
46
+ signer,
47
+ ipfs
48
+ );
49
+ ```
50
+
51
+ ### 2. Create a Subscription Plan (Merchant)
52
+
53
+ ```typescript
54
+ import { KNOWN_TOKENS } from "@verapay/sdk";
55
+
56
+ const { planId } = await client.createPlan({
57
+ paymentToken: KNOWN_TOKENS["flow-testnet"].USDC,
58
+ amount: ethers.parseUnits("9.99", 18),
59
+ interval: 30n * 24n * 3600n, // 30 days
60
+ name: "Pro Plan",
61
+ });
62
+
63
+ console.log("Plan created:", planId);
64
+ ```
65
+
66
+ ### 3. Subscribe (User)
67
+
68
+ ```typescript
69
+ // Handles ERC-20 approval + subscription in one call
70
+ const { subscriptionId, receipt } = await client.subscribeWithApproval(planId);
71
+
72
+ console.log("Subscription ID:", subscriptionId);
73
+ console.log("IPFS receipt:", receipt.ipfsCid);
74
+ ```
75
+
76
+ ### 4. Schedule Recurring Payments (No Keeper Needed)
77
+
78
+ ```typescript
79
+ import { FlowScheduler, CADENCE_HANDLERS } from "@verapay/sdk";
80
+
81
+ const scheduler = new FlowScheduler({
82
+ network: "testnet",
83
+ handlerAddress: CADENCE_HANDLERS["flow-testnet"],
84
+ evmContractAddress: DEPLOYED_CONTRACTS["flow-testnet"],
85
+ ipfsAdapter: ipfs,
86
+ });
87
+
88
+ // Authenticate with a Flow wallet (Blocto, Lilico, etc.)
89
+ await scheduler.authenticate();
90
+
91
+ // One-time setup: create a Cadence Owned Account + init handler
92
+ await scheduler.setup();
93
+
94
+ // Approve the stablecoin for the COA
95
+ await scheduler.approveERC20(KNOWN_TOKENS["flow-testnet"].USDC);
96
+
97
+ // Subscribe to a plan AND schedule the next payment — single transaction
98
+ const result = await scheduler.subscribeAndSchedule({
99
+ planId: "0",
100
+ intervalSeconds: "2592000.0", // 30 days in seconds
101
+ });
102
+
103
+ console.log("Flow TX:", result.flowTxId);
104
+ console.log("Scheduled TX:", result.scheduledTxId);
105
+ console.log("IPFS CID:", result.ipfsCid);
106
+ ```
107
+
108
+ ---
109
+
110
+ ## API Reference
111
+
112
+ ### `VeraPayClient`
113
+
114
+ #### Factory
115
+
116
+ | Method | Description |
117
+ |--------|-------------|
118
+ | `VeraPayClient.fromNetwork(network, contractAddress, signerOrProvider, ipfsAdapter?)` | Create a client configured for a known Flow network |
119
+ | `new VeraPayClient(config, signerOrProvider, ipfsAdapter?)` | Create with manual config |
120
+
121
+ #### Merchant
122
+
123
+ | Method | Returns | Description |
124
+ |--------|---------|-------------|
125
+ | `createPlan(params)` | `{ planId, tx }` | Create a subscription plan |
126
+ | `togglePlan(planId)` | `TransactionResponse` | Enable/disable a plan |
127
+ | `getMerchantPlans(address)` | `bigint[]` | List plan IDs for a merchant |
128
+
129
+ #### Subscriber
130
+
131
+ | Method | Returns | Description |
132
+ |--------|---------|-------------|
133
+ | `subscribeWithApproval(planId, options?)` | `{ subscriptionId, receipt, tx }` | Approve tokens + subscribe (recommended) |
134
+ | `subscribe(planId)` | `{ subscriptionId, receipt, tx }` | Subscribe (requires prior approval) |
135
+ | `cancelSubscription(subId)` | `TransactionResponse` | Cancel a subscription |
136
+ | `getSubscriberSubscriptions(address)` | `bigint[]` | List subscription IDs for a subscriber |
137
+
138
+ #### Keeper / Relayer
139
+
140
+ | Method | Returns | Description |
141
+ |--------|---------|-------------|
142
+ | `processPayment(subId)` | `{ receipt, tx }` | Process a single due payment |
143
+ | `batchProcessPayments(subIds)` | `TransactionResponse` | Process multiple due payments |
144
+ | `isPaymentDue(subId)` | `boolean` | Check if a payment is due |
145
+ | `getDuePayments(subIds)` | `bigint[]` | Filter to due subscriptions |
146
+ | `startKeeper(subIds, intervalMs, callback)` | `() => void` | Start an auto-processing loop (returns stop function) |
147
+
148
+ #### Read-Only
149
+
150
+ | Method | Returns | Description |
151
+ |--------|---------|-------------|
152
+ | `listActivePlans()` | `Plan[]` | All active plans |
153
+ | `getPlan(planId)` | `Plan` | Single plan details |
154
+ | `getSubscription(subId)` | `Subscription` | Single subscription details |
155
+ | `getNextPlanId()` | `bigint` | Next plan ID counter |
156
+ | `getNextSubscriptionId()` | `bigint` | Next subscription ID counter |
157
+
158
+ #### IPFS
159
+
160
+ | Method | Returns | Description |
161
+ |--------|---------|-------------|
162
+ | `hasIPFS` | `boolean` | Whether an IPFS adapter is configured |
163
+ | `pinReceipt(receipt)` | `string` | Pin a receipt to IPFS, returns CID |
164
+ | `fetchReceipt(cid)` | `PaymentReceipt` | Fetch a receipt from IPFS |
165
+
166
+ #### Events
167
+
168
+ | Method | Description |
169
+ |--------|-------------|
170
+ | `onPaymentProcessed(callback, filter?)` | Listen for payment events (auto-pins to IPFS) |
171
+ | `removeAllListeners()` | Remove all event listeners |
172
+
173
+ ---
174
+
175
+ ### `FlowScheduler`
176
+
177
+ Manages Flow Cadence interactions for scheduled payments. Uses [FCL](https://github.com/onflow/fcl-js) for wallet authentication.
178
+
179
+ #### Constructor
180
+
181
+ ```typescript
182
+ new FlowScheduler({
183
+ network: "testnet" | "mainnet",
184
+ handlerAddress: string, // Cadence handler deployer address (without 0x)
185
+ evmContractAddress: string, // VeraPay EVM contract address (with 0x)
186
+ ipfsAdapter?: IPFSAdapter, // Optional IPFS adapter
187
+ })
188
+ ```
189
+
190
+ #### Wallet
191
+
192
+ | Method | Returns | Description |
193
+ |--------|---------|-------------|
194
+ | `authenticate()` | `{ addr }` | Connect Flow wallet (Blocto, Lilico, etc.) |
195
+ | `unauthenticate()` | `void` | Disconnect wallet |
196
+ | `currentUser()` | `string \| null` | Get connected Flow address |
197
+
198
+ #### Account Setup
199
+
200
+ | Method | Returns | Description |
201
+ |--------|---------|-------------|
202
+ | `setupCOA(fundAmount?)` | `string` | Create a Cadence Owned Account (funds with FLOW for EVM gas) |
203
+ | `initHandler()` | `string` | Initialize the VeraPay payment handler on your account |
204
+ | `setup(fundAmount?)` | `{ coaTxId, handlerTxId }` | Convenience: COA + handler in sequence |
205
+
206
+ #### EVM via COA
207
+
208
+ | Method | Returns | Description |
209
+ |--------|---------|-------------|
210
+ | `approveERC20(tokenAddress, amount?)` | `string` | Approve VeraPay to spend tokens from the COA |
211
+ | `subscribeToPlan(planId)` | `string` | Subscribe the COA to a plan |
212
+ | `subscribeAndSchedule(params)` | `SubscribeAndScheduleResult` | Subscribe + schedule next payment in one transaction |
213
+
214
+ #### Scheduling
215
+
216
+ | Method | Returns | Description |
217
+ |--------|---------|-------------|
218
+ | `schedulePayment(params)` | `string` | Schedule a future payment for an existing subscription |
219
+ | `cancelScheduledPayment(txId)` | `string` | Cancel a scheduled payment |
220
+
221
+ #### Utilities
222
+
223
+ | Method | Returns | Description |
224
+ |--------|---------|-------------|
225
+ | `getCoaEvmAddress(flowAddress?)` | `string \| null` | Get the COA's EVM address |
226
+ | `waitForTransaction(txId)` | `{ status, events }` | Wait for a Cadence transaction to seal |
227
+ | `FlowScheduler.extractScheduledTxId(events)` | `string \| undefined` | Extract scheduled tx ID from events (static) |
228
+
229
+ ---
230
+
231
+ ## IPFS Integration (Storacha / Protocol Labs)
232
+
233
+ VeraPay pins payment receipts to [IPFS](https://ipfs.io) via [Storacha](https://storacha.network), built by Protocol Labs (the creators of IPFS and Filecoin). Receipts are content-addressed JSON documents that serve as permanent, verifiable proof of payment.
234
+
235
+ ### Setup Storacha
236
+
237
+ ```bash
238
+ npm install -g @storacha/cli
239
+
240
+ storacha login you@email.com
241
+ storacha space create verapay-receipts
242
+
243
+ # Generate a signing key
244
+ storacha key create --json
245
+ # { "did": "did:key:z6Mk...", "key": "MgCaT7Se2QX9..." }
246
+
247
+ # Delegate capabilities
248
+ storacha delegation create did:key:z6Mk... \
249
+ -c space/blob/add -c space/index/add \
250
+ -c filecoin/offer -c upload/add --base64
251
+ # mAYIEAP8OEaJlcm9v...
252
+ ```
253
+
254
+ ### Use in Code
255
+
256
+ ```typescript
257
+ import { createStorachaAdapter } from "@verapay/sdk";
258
+
259
+ const ipfs = createStorachaAdapter({
260
+ key: "MgCaT7Se2QX9...", // from `storacha key create`
261
+ proof: "mAYIEAP8OEaJl...", // from `storacha delegation create`
262
+ });
263
+
264
+ // Pass to VeraPayClient or FlowScheduler
265
+ const client = VeraPayClient.fromNetwork("flow-testnet", addr, signer, ipfs);
266
+ ```
267
+
268
+ ### Pluggable Adapters
269
+
270
+ | Adapter | Usage |
271
+ |---------|-------|
272
+ | `createStorachaAdapter({ key, proof })` | Production — Storacha (Protocol Labs) |
273
+ | `createKuboAdapter(apiUrl)` | Self-hosted IPFS node (Kubo HTTP API) |
274
+ | `createMemoryAdapter()` | In-memory store for testing |
275
+
276
+ ### Receipt Format
277
+
278
+ ```json
279
+ {
280
+ "subscriptionId": "1",
281
+ "planId": "0",
282
+ "subscriber": "0x...",
283
+ "merchant": "0x...",
284
+ "amount": "9990000000000000000",
285
+ "protocolFee": "49950000000000000",
286
+ "timestamp": 1711900000,
287
+ "txHash": "0x...",
288
+ "blockNumber": 12345678,
289
+ "chainId": 545,
290
+ "ipfsCid": "bafybeig..."
291
+ }
292
+ ```
293
+
294
+ Receipts are viewable at `https://storacha.link/ipfs/<CID>`.
295
+
296
+ ---
297
+
298
+ ## Flow Blockchain: Dual-VM Architecture
299
+
300
+ VeraPay uniquely leverages Flow's dual-VM architecture:
301
+
302
+ ### Flow EVM
303
+
304
+ The `VeraPay.sol` smart contract runs on Flow EVM — a full EVM environment on Flow. Works with all standard EVM tooling: MetaMask, ethers.js, Foundry, wagmi.
305
+
306
+ ### Cadence Scheduled Transactions
307
+
308
+ Flow's native Cadence layer provides [scheduled transactions](https://developers.flow.com/build/cadence/advanced-concepts/scheduled-transactions) — the ability to schedule code execution at a future time, directly on-chain. VeraPay uses this to:
309
+
310
+ 1. Schedule `processPayment()` calls at the subscription interval
311
+ 2. Execute via a **Cadence Owned Account (COA)** that bridges Cadence to EVM
312
+ 3. Pull the ERC-20 payment from the subscriber to the merchant
313
+
314
+ This replaces off-chain keepers, cron jobs, and Chainlink Automation with a fully on-chain solution native to Flow.
315
+
316
+ ---
317
+
318
+ ## Constants & Exports
319
+
320
+ ```typescript
321
+ import {
322
+ // Deployed contract addresses
323
+ DEPLOYED_CONTRACTS, // { "flow-testnet": "0x2473..." }
324
+ CADENCE_HANDLERS, // { "flow-testnet": "7c0bf2..." }
325
+ KNOWN_TOKENS, // { "flow-testnet": { USDC: "0x9C08..." } }
326
+ NETWORKS, // { "flow-testnet": { chainId, rpcUrl, ... } }
327
+
328
+ // IPFS
329
+ DEFAULT_IPFS_GATEWAY,
330
+ ipfsGatewayUrl,
331
+
332
+ // ABIs
333
+ VERA_PAY_ABI,
334
+ ERC20_ABI,
335
+ } from "@verapay/sdk";
336
+ ```
337
+
338
+ ---
339
+
340
+ ## Types
341
+
342
+ ```typescript
343
+ interface Plan {
344
+ planId: bigint;
345
+ merchant: string;
346
+ paymentToken: string;
347
+ amount: bigint;
348
+ interval: bigint;
349
+ name: string;
350
+ metadataURI: string;
351
+ active: boolean;
352
+ }
353
+
354
+ interface Subscription {
355
+ subscriptionId: bigint;
356
+ planId: bigint;
357
+ subscriber: string;
358
+ startTime: bigint;
359
+ lastPaymentTime: bigint;
360
+ paymentsCount: bigint;
361
+ active: boolean;
362
+ }
363
+
364
+ interface PaymentReceipt {
365
+ subscriptionId: string;
366
+ planId: string;
367
+ subscriber: string;
368
+ merchant: string;
369
+ amount: string;
370
+ protocolFee: string;
371
+ timestamp: number;
372
+ txHash: string;
373
+ blockNumber: number;
374
+ chainId: number;
375
+ ipfsCid?: string;
376
+ }
377
+
378
+ interface SubscribeAndScheduleResult {
379
+ flowTxId: string;
380
+ scheduledTxId?: string;
381
+ receipt?: PaymentReceipt;
382
+ ipfsCid?: string;
383
+ }
384
+ ```
385
+
386
+ ## License
387
+
388
+ MIT