UNPKG

react-reward-button

Version:

Drop-in React component that sends Ethereum token rewards and shows confetti animations. Built with wagmi, ethers, and ShadCN UI.

272 lines (265 loc) 8.65 kB
import React from 'react'; import { ClassValue } from 'clsx'; export { ethers } from 'ethers'; interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> { /** * Whether the button should render as a child component (using Slot) * This allows for composition patterns common in shadcn/ui */ asChild?: boolean; /** * Visual variants for the button */ variant?: 'default' | 'secondary' | 'outline' | 'ghost' | 'destructive'; /** * Size variants for the button */ size?: 'default' | 'sm' | 'lg' | 'icon'; /** * Whether the button is in a loading state */ isLoading?: boolean; /** * Custom text to show when loading */ loadingText?: string; /** * Whether the button is in a success state */ isSuccess?: boolean; } declare const Button: React.ForwardRefExoticComponent<ButtonProps & React.RefAttributes<HTMLButtonElement>>; interface TokenInfo { symbol: string; decimals: number; name: string; } interface RewardButtonState { isLoading: boolean; error: string | null; tokenInfo: TokenInfo | null; isSuccess: boolean; } interface RewardButtonProps extends Omit<ButtonProps, 'isLoading'> { /** The Ethereum address of the reward token contract (optional - if not provided, behaves as regular button) */ tokenAddress?: string; /** The amount of tokens to reward (in wei or token units) (optional - if not provided, behaves as regular button) */ rewardAmount?: string; /** * The recipient address for the reward (optional) * Priority: 1. Connected wallet address, 2. This recipientAddress prop * If neither is provided, the reward claim will fail with an error * No fallback address is used for security reasons */ recipientAddress?: string; /** The sender wallet address that holds the reward tokens */ senderAddress?: string; /** The private key of the sender wallet (for signing transactions) */ senderPrivateKey?: string; /** RPC URL for the network (optional - uses default if not provided) */ rpcUrl?: string; /** * Callback function called when the reward button is clicked (for non-Web3 mode) * If tokenAddress and rewardAmount are provided, this is ignored in favor of Web3 functionality */ onReward?: () => void | Promise<void>; /** Callback function called when reward is successfully claimed */ onRewardClaimed?: (txHash: string, amount: string) => void; /** Callback function called when reward claim fails */ onRewardFailed?: (error: Error) => void; /** Callback function called when reward claim is initiated */ onRewardStarted?: () => void; /** Whether to show the reward amount on the button */ showRewardAmount?: boolean; /** Custom token symbol to display (e.g., "USDC", "ETH") */ tokenSymbol?: string; /** Whether to require wallet connection before claiming */ requireConnection?: boolean; /** Custom loading text for reward operations */ loadingText?: string; /** * Whether the user (receiver) pays gas fees instead of sender * - true: Connected wallet pays gas fees (transferFrom pattern) * - false: Sender wallet pays gas fees (transfer pattern - default) */ userPaysGas?: boolean; /** Whether the button is in a loading state */ isLoading?: boolean; /** * Content to display inside the button * @default "Claim Reward" */ children?: React.ReactNode; } declare const RewardButton: React.FC<RewardButtonProps>; /** * Utility function for merging class names using clsx * This is inspired by shadcn/ui's cn() utility */ declare function cn(...inputs: ClassValue[]): string; declare const ERC20_ABI: readonly [{ readonly constant: true; readonly inputs: readonly []; readonly name: "name"; readonly outputs: readonly [{ readonly name: ""; readonly type: "string"; }]; readonly type: "function"; }, { readonly constant: true; readonly inputs: readonly []; readonly name: "symbol"; readonly outputs: readonly [{ readonly name: ""; readonly type: "string"; }]; readonly type: "function"; }, { readonly constant: true; readonly inputs: readonly []; readonly name: "decimals"; readonly outputs: readonly [{ readonly name: ""; readonly type: "uint8"; }]; readonly type: "function"; }, { readonly constant: true; readonly inputs: readonly [{ readonly name: "_owner"; readonly type: "address"; }]; readonly name: "balanceOf"; readonly outputs: readonly [{ readonly name: "balance"; readonly type: "uint256"; }]; readonly type: "function"; }, { readonly constant: false; readonly inputs: readonly [{ readonly name: "_to"; readonly type: "address"; }, { readonly name: "_value"; readonly type: "uint256"; }]; readonly name: "transfer"; readonly outputs: readonly [{ readonly name: ""; readonly type: "bool"; }]; readonly type: "function"; }, { readonly constant: false; readonly inputs: readonly [{ readonly name: "_spender"; readonly type: "address"; }, { readonly name: "_value"; readonly type: "uint256"; }]; readonly name: "approve"; readonly outputs: readonly [{ readonly name: ""; readonly type: "bool"; }]; readonly type: "function"; }, { readonly constant: false; readonly inputs: readonly [{ readonly name: "_from"; readonly type: "address"; }, { readonly name: "_to"; readonly type: "address"; }, { readonly name: "_value"; readonly type: "uint256"; }]; readonly name: "transferFrom"; readonly outputs: readonly [{ readonly name: ""; readonly type: "bool"; }]; readonly type: "function"; }, { readonly constant: true; readonly inputs: readonly [{ readonly name: "_owner"; readonly type: "address"; }, { readonly name: "_spender"; readonly type: "address"; }]; readonly name: "allowance"; readonly outputs: readonly [{ readonly name: ""; readonly type: "uint256"; }]; readonly type: "function"; }, { readonly anonymous: false; readonly inputs: readonly [{ readonly indexed: true; readonly name: "from"; readonly type: "address"; }, { readonly indexed: true; readonly name: "to"; readonly type: "address"; }, { readonly indexed: false; readonly name: "value"; readonly type: "uint256"; }]; readonly name: "Transfer"; readonly type: "event"; }, { readonly anonymous: false; readonly inputs: readonly [{ readonly indexed: true; readonly name: "owner"; readonly type: "address"; }, { readonly indexed: true; readonly name: "spender"; readonly type: "address"; }, { readonly indexed: false; readonly name: "value"; readonly type: "uint256"; }]; readonly name: "Approval"; readonly type: "event"; }]; declare const COMMON_TOKENS: { readonly USDC: "0xA0b86a33E6441b6b07c2fE4c2b4B8B1d8B7a0F4c"; readonly USDT: "0xdAC17F958D2ee523a2206206994597C13D831ec7"; readonly DAI: "0x6B175474E89094C44Da98b954EedeAC495271d0F"; readonly WETH: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"; }; declare const BUTTON_VARIANTS: { readonly default: "reward-button--default"; readonly secondary: "reward-button--secondary"; readonly outline: "reward-button--outline"; readonly ghost: "reward-button--ghost"; readonly destructive: "reward-button--destructive"; }; declare const BUTTON_SIZES: { readonly default: "reward-button--size-default"; readonly sm: "reward-button--size-sm"; readonly lg: "reward-button--size-lg"; readonly icon: "reward-button--size-icon"; }; declare const DEFAULT_BUTTON_TEXT = "Claim Reward"; declare const CSS_CLASSES: { readonly base: "reward-button"; readonly loading: "reward-button--loading"; readonly disabled: "reward-button--disabled"; readonly loadingContent: "reward-button__loading"; readonly spinner: "reward-button__spinner"; }; export { BUTTON_SIZES, BUTTON_VARIANTS, Button, COMMON_TOKENS, CSS_CLASSES, DEFAULT_BUTTON_TEXT, ERC20_ABI, RewardButton, cn, RewardButton as default }; export type { ButtonProps, RewardButtonProps, RewardButtonState, TokenInfo };