npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@vera-pay/sdk

v0.1.1

Published

VeraPay — on-chain subscription payments SDK for Flow EVM

Readme

@vera-pay/sdk

On-chain subscription payments SDK for Flow Blockchain. Create plans, accept recurring stablecoin payments, schedule autonomous on-chain payment processing, and pin immutable receipts to IPFS via Storacha (Protocol Labs).

Installation

npm install @vera-pay/sdk ethers

ethers v6 is a peer dependency.

Overview

The SDK provides two main classes:

| Class | Purpose | |-------|---------| | VeraPayClient | Interact with the VeraPay EVM smart contract — create plans, subscribe, process payments | | FlowScheduler | Schedule autonomous recurring payments using Flow's native Cadence scheduled transactions |

Both support optional IPFS integration for pinning payment receipts.


Quick Start

1. Connect to VeraPay

import { VeraPayClient, createStorachaAdapter, DEPLOYED_CONTRACTS } from "@vera-pay/sdk";
import { ethers } from "ethers";

const provider = new ethers.BrowserProvider(window.ethereum);
const signer = await provider.getSigner();

// Optional: IPFS adapter for receipt pinning
const ipfs = createStorachaAdapter({
  key: process.env.STORACHA_KEY!,
  proof: process.env.STORACHA_PROOF!,
});

const client = VeraPayClient.fromNetwork(
  "flow-testnet",
  DEPLOYED_CONTRACTS["flow-testnet"],
  signer,
  ipfs
);

2. Create a Subscription Plan (Merchant)

import { KNOWN_TOKENS } from "@vera-pay/sdk";

const { planId } = await client.createPlan({
  paymentToken: KNOWN_TOKENS["flow-testnet"].USDC,
  amount: ethers.parseUnits("9.99", 18),
  interval: 30n * 24n * 3600n, // 30 days
  name: "Pro Plan",
});

console.log("Plan created:", planId);

3. Subscribe (User)

// Handles ERC-20 approval + subscription in one call
const { subscriptionId, receipt } = await client.subscribeWithApproval(planId);

console.log("Subscription ID:", subscriptionId);
console.log("IPFS receipt:", receipt.ipfsCid);

4. Schedule Recurring Payments (No Keeper Needed)

import { FlowScheduler, CADENCE_HANDLERS } from "@vera-pay/sdk";

const scheduler = new FlowScheduler({
  network: "testnet",
  handlerAddress: CADENCE_HANDLERS["flow-testnet"],
  evmContractAddress: DEPLOYED_CONTRACTS["flow-testnet"],
  ipfsAdapter: ipfs,
});

// Authenticate with a Flow wallet (Blocto, Lilico, etc.)
await scheduler.authenticate();

// One-time setup: create a Cadence Owned Account + init handler
await scheduler.setup();

// Approve the stablecoin for the COA
await scheduler.approveERC20(KNOWN_TOKENS["flow-testnet"].USDC);

// Subscribe to a plan AND schedule the next payment — single transaction
const result = await scheduler.subscribeAndSchedule({
  planId: "0",
  intervalSeconds: "2592000.0", // 30 days in seconds
});

console.log("Flow TX:", result.flowTxId);
console.log("Scheduled TX:", result.scheduledTxId);
console.log("IPFS CID:", result.ipfsCid);

API Reference

VeraPayClient

Factory

| Method | Description | |--------|-------------| | VeraPayClient.fromNetwork(network, contractAddress, signerOrProvider, ipfsAdapter?) | Create a client configured for a known Flow network | | new VeraPayClient(config, signerOrProvider, ipfsAdapter?) | Create with manual config |

Merchant

| Method | Returns | Description | |--------|---------|-------------| | createPlan(params) | { planId, tx } | Create a subscription plan | | togglePlan(planId) | TransactionResponse | Enable/disable a plan | | getMerchantPlans(address) | bigint[] | List plan IDs for a merchant |

Subscriber

| Method | Returns | Description | |--------|---------|-------------| | subscribeWithApproval(planId, options?) | { subscriptionId, receipt, tx } | Approve tokens + subscribe (recommended) | | subscribe(planId) | { subscriptionId, receipt, tx } | Subscribe (requires prior approval) | | cancelSubscription(subId) | TransactionResponse | Cancel a subscription | | getSubscriberSubscriptions(address) | bigint[] | List subscription IDs for a subscriber |

Keeper / Relayer

| Method | Returns | Description | |--------|---------|-------------| | processPayment(subId) | { receipt, tx } | Process a single due payment | | batchProcessPayments(subIds) | TransactionResponse | Process multiple due payments | | isPaymentDue(subId) | boolean | Check if a payment is due | | getDuePayments(subIds) | bigint[] | Filter to due subscriptions | | startKeeper(subIds, intervalMs, callback) | () => void | Start an auto-processing loop (returns stop function) |

Read-Only

| Method | Returns | Description | |--------|---------|-------------| | listActivePlans() | Plan[] | All active plans | | getPlan(planId) | Plan | Single plan details | | getSubscription(subId) | Subscription | Single subscription details | | getNextPlanId() | bigint | Next plan ID counter | | getNextSubscriptionId() | bigint | Next subscription ID counter |

IPFS

| Method | Returns | Description | |--------|---------|-------------| | hasIPFS | boolean | Whether an IPFS adapter is configured | | pinReceipt(receipt) | string | Pin a receipt to IPFS, returns CID | | fetchReceipt(cid) | PaymentReceipt | Fetch a receipt from IPFS |

Events

| Method | Description | |--------|-------------| | onPaymentProcessed(callback, filter?) | Listen for payment events (auto-pins to IPFS) | | removeAllListeners() | Remove all event listeners |


FlowScheduler

Manages Flow Cadence interactions for scheduled payments. Uses FCL for wallet authentication.

Constructor

new FlowScheduler({
  network: "testnet" | "mainnet",
  handlerAddress: string,       // Cadence handler deployer address (without 0x)
  evmContractAddress: string,   // VeraPay EVM contract address (with 0x)
  ipfsAdapter?: IPFSAdapter,    // Optional IPFS adapter
})

Wallet

| Method | Returns | Description | |--------|---------|-------------| | authenticate() | { addr } | Connect Flow wallet (Blocto, Lilico, etc.) | | unauthenticate() | void | Disconnect wallet | | currentUser() | string \| null | Get connected Flow address |

Account Setup

| Method | Returns | Description | |--------|---------|-------------| | setupCOA(fundAmount?) | string | Create a Cadence Owned Account (funds with FLOW for EVM gas) | | initHandler() | string | Initialize the VeraPay payment handler on your account | | setup(fundAmount?) | { coaTxId, handlerTxId } | Convenience: COA + handler in sequence |

EVM via COA

| Method | Returns | Description | |--------|---------|-------------| | approveERC20(tokenAddress, amount?) | string | Approve VeraPay to spend tokens from the COA | | subscribeToPlan(planId) | string | Subscribe the COA to a plan | | subscribeAndSchedule(params) | SubscribeAndScheduleResult | Subscribe + schedule next payment in one transaction |

Scheduling

| Method | Returns | Description | |--------|---------|-------------| | schedulePayment(params) | string | Schedule a future payment for an existing subscription | | cancelScheduledPayment(txId) | string | Cancel a scheduled payment |

Utilities

| Method | Returns | Description | |--------|---------|-------------| | getCoaEvmAddress(flowAddress?) | string \| null | Get the COA's EVM address | | waitForTransaction(txId) | { status, events } | Wait for a Cadence transaction to seal | | FlowScheduler.extractScheduledTxId(events) | string \| undefined | Extract scheduled tx ID from events (static) |


IPFS Integration (Storacha / Protocol Labs)

VeraPay pins payment receipts to IPFS via Storacha, built by Protocol Labs (the creators of IPFS and Filecoin). Receipts are content-addressed JSON documents that serve as permanent, verifiable proof of payment.

Setup Storacha

npm install -g @storacha/cli

storacha login [email protected]
storacha space create verapay-receipts

# Generate a signing key
storacha key create --json
# { "did": "did:key:z6Mk...", "key": "MgCaT7Se2QX9..." }

# Delegate capabilities
storacha delegation create did:key:z6Mk... \
  -c space/blob/add -c space/index/add \
  -c filecoin/offer -c upload/add --base64
# mAYIEAP8OEaJlcm9v...

Use in Code

import { createStorachaAdapter } from "@vera-pay/sdk";

const ipfs = createStorachaAdapter({
  key: "MgCaT7Se2QX9...",    // from `storacha key create`
  proof: "mAYIEAP8OEaJl...", // from `storacha delegation create`
});

// Pass to VeraPayClient or FlowScheduler
const client = VeraPayClient.fromNetwork("flow-testnet", addr, signer, ipfs);

Pluggable Adapters

| Adapter | Usage | |---------|-------| | createStorachaAdapter({ key, proof }) | Production — Storacha (Protocol Labs) | | createKuboAdapter(apiUrl) | Self-hosted IPFS node (Kubo HTTP API) | | createMemoryAdapter() | In-memory store for testing |

Receipt Format

{
  "subscriptionId": "1",
  "planId": "0",
  "subscriber": "0x...",
  "merchant": "0x...",
  "amount": "9990000000000000000",
  "protocolFee": "49950000000000000",
  "timestamp": 1711900000,
  "txHash": "0x...",
  "blockNumber": 12345678,
  "chainId": 545,
  "ipfsCid": "bafybeig..."
}

Receipts are viewable at https://storacha.link/ipfs/<CID>.


Flow Blockchain: Dual-VM Architecture

VeraPay uniquely leverages Flow's dual-VM architecture:

Flow EVM

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.

Cadence Scheduled Transactions

Flow's native Cadence layer provides scheduled transactions — the ability to schedule code execution at a future time, directly on-chain. VeraPay uses this to:

  1. Schedule processPayment() calls at the subscription interval
  2. Execute via a Cadence Owned Account (COA) that bridges Cadence to EVM
  3. Pull the ERC-20 payment from the subscriber to the merchant

This replaces off-chain keepers, cron jobs, and Chainlink Automation with a fully on-chain solution native to Flow.


Constants & Exports

import {
  // Deployed contract addresses
  DEPLOYED_CONTRACTS,  // { "flow-testnet": "0x2473..." }
  CADENCE_HANDLERS,    // { "flow-testnet": "7c0bf2..." }
  KNOWN_TOKENS,        // { "flow-testnet": { USDC: "0x9C08..." } }
  NETWORKS,            // { "flow-testnet": { chainId, rpcUrl, ... } }

  // IPFS
  DEFAULT_IPFS_GATEWAY,
  ipfsGatewayUrl,

  // ABIs
  VERA_PAY_ABI,
  ERC20_ABI,
} from "@vera-pay/sdk";

Types

interface Plan {
  planId: bigint;
  merchant: string;
  paymentToken: string;
  amount: bigint;
  interval: bigint;
  name: string;
  metadataURI: string;
  active: boolean;
}

interface Subscription {
  subscriptionId: bigint;
  planId: bigint;
  subscriber: string;
  startTime: bigint;
  lastPaymentTime: bigint;
  paymentsCount: bigint;
  active: boolean;
}

interface PaymentReceipt {
  subscriptionId: string;
  planId: string;
  subscriber: string;
  merchant: string;
  amount: string;
  protocolFee: string;
  timestamp: number;
  txHash: string;
  blockNumber: number;
  chainId: number;
  ipfsCid?: string;
}

interface SubscribeAndScheduleResult {
  flowTxId: string;
  scheduledTxId?: string;
  receipt?: PaymentReceipt;
  ipfsCid?: string;
}

License

MIT