React Component — @cron/react

Drop-in subscribe button for any React app.

Install

bash
npm install @cron/react @cron/sdk wagmi viem @rainbow-me/rainbowkit

Setup

CronButton uses wagmi for wallet interaction. Wrap your app with wagmi and RainbowKit providers before rendering the button.

tsx
// app/providers.tsx
"use client";

import { WagmiProvider } from "wagmi";
import { RainbowKitProvider } from "@rainbow-me/rainbowkit";
import { QueryClientProvider, QueryClient } from "@tanstack/react-query";
import { getDefaultConfig } from "@rainbow-me/rainbowkit";
import { base, baseSepolia } from "wagmi/chains";

const config = getDefaultConfig({
  appName: "Your App",
  projectId: process.env.NEXT_PUBLIC_WC_PROJECT_ID!,
  chains: [base, baseSepolia],
  ssr: true,
});

const queryClient = new QueryClient();

export function Providers({ children }: { children: React.ReactNode }) {
  return (
    <WagmiProvider config={config}>
      <QueryClientProvider client={queryClient}>
        <RainbowKitProvider>{children}</RainbowKitProvider>
      </QueryClientProvider>
    </WagmiProvider>
  );
}

Basic usage

tsx
import { CronButton } from "@cron/react";

export function PricingCard({ planId }: { planId: bigint }) {
  return (
    <div>
      <h2>Pro Plan — $9.99/mo</h2>
      <CronButton
        planId={planId}
        chain="base"
        onSuccess={(result) => {
          console.log("Subscribed!", result.subscription.subscriber);
          grantAccess(result.subscription.subscriber);
        }}
        onCancel={() => {
          revokeAccess();
        }}
      />
    </div>
  );
}

Props

PropTypeRequiredDescription
planIdbigintYesOn-chain plan ID to subscribe to
chainstringYes"base", "baseSepolia", "arbitrum", "arbitrumSepolia"
mintNFTbooleanNoMint a CronNFT identity token. Default: false
theme"dark" | "light"NoButton color theme. Default: "dark"
onSuccessfunctionNoCalled after successful subscription
onCancelfunctionNoCalled if user cancels the flow
onErrorfunctionNoCalled on error with an Error object

Flow states

The button manages its own state machine:

  1. idle — shows “Subscribe”
  2. connecting — wallet connection in progress
  3. approving — token approval transaction pending
  4. subscribing — subscribe transaction pending
  5. subscribed — success state, onSuccess called
  6. error — shows error message, onError called

[*] Custom UI

To build a fully custom subscription UI, use the SDK directly (cron.subscriptions.subscribe()) instead of CronButton. The button is a convenience wrapper.

onSuccess payload

typescript
interface SubscribeResult {
  txHash: string;
  subscription: {
    planId: bigint;
    subscriber: string;    // wallet address
    startedAt: number;     // unix timestamp
    nftTokenId?: bigint;   // if mintNFT was true
  };
}