{"id":30046727,"url":"https://github.com/varungulati/react-reward-button","last_synced_at":"2025-09-10T11:38:13.910Z","repository":{"id":305174558,"uuid":"1019427687","full_name":"varungulati/react-reward-button","owner":"varungulati","description":"React Reward Button is a customizable React component that sends Ethereum token rewards on click. It integrates seamlessly with the Reown Wallet Provider, making it ideal for dApps, onboarding flows, or incentivized Web3 actions.","archived":false,"fork":false,"pushed_at":"2025-07-18T16:39:53.000Z","size":1156,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-08-07T08:57:38.215Z","etag":null,"topics":["dapp","ethereum","npm-package","onchain-rewards","react","reown","reward-button","vite","wallet-integration","web3","web3-ui"],"latest_commit_sha":null,"homepage":"https://react-reward-button-demo.fly.dev/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/varungulati.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-07-14T10:02:19.000Z","updated_at":"2025-07-18T16:39:56.000Z","dependencies_parsed_at":"2025-07-18T19:38:31.622Z","dependency_job_id":null,"html_url":"https://github.com/varungulati/react-reward-button","commit_stats":null,"previous_names":["varungulati/react-reward-button"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/varungulati/react-reward-button","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/varungulati%2Freact-reward-button","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/varungulati%2Freact-reward-button/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/varungulati%2Freact-reward-button/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/varungulati%2Freact-reward-button/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/varungulati","download_url":"https://codeload.github.com/varungulati/react-reward-button/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/varungulati%2Freact-reward-button/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274455843,"owners_count":25288557,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-10T02:00:12.551Z","response_time":83,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dapp","ethereum","npm-package","onchain-rewards","react","reown","reward-button","vite","wallet-integration","web3","web3-ui"],"created_at":"2025-08-07T08:53:45.443Z","updated_at":"2025-09-10T11:38:13.887Z","avatar_url":"https://github.com/varungulati.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🎁 React Reward Button\n\nA React component that provides a reward button with Ethereum token rewards. Built with wagmi, AppKit, and ethers.js for seamless Web3 integration.\n\n## Why settle for clicks that do nothing?\n\nReact Reward Button is a drop-in, beautifully styled button powered by shadcn/ui and Reown wallet integration — but with a twist: every click can reward your users with real tokens.\n\n### Unique Selling Points\n\n1. **🎨 Beautiful by Design**  \n   Built on top of shadcn/ui's Button component — fully customizable with variants, sizes, and accessible design patterns out of the box.\n\n2. **🔗 Seamless Wallet Integration with Reown**  \n   Handles wallet connection automatically using the Reown React library. Users connect once and are ready to receive rewards instantly.\n\n3. **🪙 Compatible with Any ERC-20 Token**  \n   Reward users in your own token or any existing ERC-20 token on supported EVM chains (Polygon recommended).\n\n4. **⚡ One Click = Real Value**  \n   Trigger token rewards instantly when users interact with the button — perfect for gamified actions, engagement campaigns, or loyalty flows.\n\n5. **⚙️ Flexible Gas Modes**  \n   Choose how rewards are delivered:\n   - Developer-funded (gasless for user)\n   - Or user-funded (MetaMask/Reown confirmation per claim)\n\n6. **🧩 Plug-and-Play Integration**  \n   Drop it into any React project like a regular button. Add reward props, and you're done — no backend required unless you want one.\n\n## Demo\n\nTry the demo here: [React Reward Button Demo](https://react-reward-button-demo.fly.dev/)\n\n\n## Features\n\n- 🌐 **Web3 Integration**: Built with wagmi and AppKit for modern Web3 functionality\n- 💰 **ERC20 Token Rewards**: Send any ERC20 token as rewards\n- 🔗 **Wallet Connection**: Seamless wallet connection with AppKit\n- ⚙️ **Gas Fee Options**: Choose who pays gas fees (sender or receiver)\n- 🎨 **Customizable UI**: Multiple variants, sizes, and styling options\n- 🔒 **Type Safe**: Full TypeScript support with comprehensive types\n- 📱 **Mobile Friendly**: Works on all devices with responsive design\n- ♿ **Accessible**: Built with accessibility standards in mind\n- 🚀 **Performance**: Optimized for production use\n\n✅ AI-friendly: Works great with ChatGPT/Cursor/GitHub Copilot\n\n## Installation\n\n```bash\nnpm install react-reward-button\n```\n\n### Peer Dependencies\n\nThis library requires the following peer dependencies:\n\n```bash\nnpm install wagmi @tanstack/react-query ethers @reown/appkit @reown/appkit-adapter-wagmi react react-dom\n```\n\n## Setup\n\n### 1. Provider Setup\n\nWrap your app with the necessary providers:\n\n```tsx\nimport { WagmiProvider } from 'wagmi';\nimport { mainnet, polygon, sepolia } from 'wagmi/chains';\nimport { QueryClient, QueryClientProvider } from '@tanstack/react-query';\nimport { createAppKit } from '@reown/appkit/react';\nimport { WagmiAdapter } from '@reown/appkit-adapter-wagmi';\n\nconst queryClient = new QueryClient();\n\n// Get your project ID from https://cloud.reown.com/\nconst projectId = 'YOUR_PROJECT_ID';\n\n// Configure networks\nconst networks = [mainnet, polygon, sepolia];\n\n// Set up the Wagmi adapter\nconst wagmiAdapter = new WagmiAdapter({\n  projectId,\n  networks,\n});\n\n// Create the AppKit instance\ncreateAppKit({\n  adapters: [wagmiAdapter],\n  networks,\n  projectId,\n  metadata: {\n    name: 'My App',\n    description: 'My App Description',\n    url: 'https://myapp.com',\n    icons: ['https://myapp.com/icon.png']\n  }\n});\n\nfunction App() {\n  return (\n    \u003cWagmiProvider config={wagmiAdapter.wagmiConfig}\u003e\n      \u003cQueryClientProvider client={queryClient}\u003e\n        {/* Your app components */}\n      \u003c/QueryClientProvider\u003e\n    \u003c/WagmiProvider\u003e\n  );\n}\n```\n\n### 2. Basic Usage\n\n```tsx\nimport { RewardButton } from 'react-reward-button';\n\nfunction MyComponent() {\n  const handleRewardClaimed = (txHash: string, amount: string) =\u003e {\n    console.log('Reward claimed!', { txHash, amount });\n  };\n\n  const handleRewardFailed = (error: Error) =\u003e {\n    console.error('Reward failed:', error);\n  };\n\n  return (\n    \u003cRewardButton\n      tokenAddress=\"0xA0b86a33E6441357C49c74aA8F4b3f0B7C6d6b2c\" // Example USDC address\n      rewardAmount=\"1000000\" // 1 USDC (6 decimals)\n      senderAddress=\"0x...\" // Your wallet address holding the tokens\n      senderPrivateKey=\"0x...\" // Your private key (keep secure!)\n      onRewardClaimed={handleRewardClaimed}\n      onRewardFailed={handleRewardFailed}\n      tokenSymbol=\"USDC\"\n      showRewardAmount={true}\n    \u003e\n      Claim 1 USDC Reward\n    \u003c/RewardButton\u003e\n  );\n}\n```\n\n## API Reference\n\n### RewardButton Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `tokenAddress` | `string` | `undefined` | The Ethereum address of the reward token contract |\n| `rewardAmount` | `string` | `undefined` | The amount of tokens to reward (in wei or token units) |\n| `recipientAddress` | `string` | `undefined` | The recipient address (falls back to connected wallet) |\n| `senderAddress` | `string` | `undefined` | The sender wallet address that holds the reward tokens |\n| `senderPrivateKey` | `string` | `undefined` | The private key of the sender wallet |\n| `rpcUrl` | `string` | `undefined` | RPC URL for the network |\n| `onReward` | `() =\u003e void \\| Promise\u003cvoid\u003e` | `undefined` | Callback for non-Web3 mode |\n| `onRewardClaimed` | `(txHash: string, amount: string) =\u003e void` | `undefined` | Called when reward is successfully claimed |\n| `onRewardFailed` | `(error: Error) =\u003e void` | `undefined` | Called when reward claim fails |\n| `onRewardStarted` | `() =\u003e void` | `undefined` | Called when reward claim is initiated |\n| `showRewardAmount` | `boolean` | `true` | Whether to show the reward amount on the button |\n| `tokenSymbol` | `string` | `'TOKEN'` | Custom token symbol to display |\n| `requireConnection` | `boolean` | `true` | Whether to require wallet connection |\n| `loadingText` | `string` | `'Claiming Reward...'` | Custom loading text |\n| `userPaysGas` | `boolean` | `false` | Whether user pays gas fees (vs sender) |\n| `isLoading` | `boolean` | `false` | External loading state |\n| `children` | `React.ReactNode` | `'Claim Reward'` | Button content |\n| `variant` | `'default' \\| 'secondary' \\| 'outline' \\| 'ghost' \\| 'destructive'` | `'default'` | Button variant |\n| `size` | `'default' \\| 'sm' \\| 'lg' \\| 'icon'` | `'default'` | Button size |\n| `disabled` | `boolean` | `false` | Whether the button is disabled |\n| `className` | `string` | `undefined` | Additional CSS classes |\n\n## Examples\n\n### Basic ERC20 Token Reward\n\n```tsx\nimport { RewardButton } from 'react-reward-button';\n\nfunction BasicReward() {\n  return (\n    \u003cRewardButton\n      tokenAddress=\"0xA0b86a33E6441357C49c74aA8F4b3f0B7C6d6b2c\"\n      rewardAmount=\"1000000\" // 1 USDC (6 decimals)\n      senderAddress=\"0x742d35Cc6634C0532925a3b8D372C468F8c9d5b7\"\n      senderPrivateKey=\"0x...\" // Keep this secure!\n      tokenSymbol=\"USDC\"\n      onRewardClaimed={(txHash, amount) =\u003e {\n        console.log(`Reward claimed! Amount: ${amount}, TX: ${txHash}`);\n      }}\n    \u003e\n      Claim 1 USDC\n    \u003c/RewardButton\u003e\n  );\n}\n```\n\n### Different Token Examples\n\n```tsx\n// ETH-based reward\n\u003cRewardButton\n  tokenAddress=\"0x...\" // WETH address\n  rewardAmount={ethers.parseEther(\"0.01\")} // 0.01 ETH\n  senderAddress=\"0x...\"\n  senderPrivateKey=\"0x...\"\n  tokenSymbol=\"WETH\"\n\u003e\n  Claim 0.01 WETH\n\u003c/RewardButton\u003e\n\n// Custom ERC20 token\n\u003cRewardButton\n  tokenAddress=\"0x...\" // Your token address\n  rewardAmount=\"100000000000000000000\" // 100 tokens (18 decimals)\n  senderAddress=\"0x...\"\n  senderPrivateKey=\"0x...\"\n  tokenSymbol=\"MYTOKEN\"\n  showRewardAmount={true}\n\u003e\n  Claim Daily Reward\n\u003c/RewardButton\u003e\n```\n\n### Gas Fee Options\n\n```tsx\n// Sender pays gas fees (default)\n\u003cRewardButton\n  tokenAddress=\"0x...\"\n  rewardAmount=\"1000000\"\n  senderAddress=\"0x...\"\n  senderPrivateKey=\"0x...\"\n  userPaysGas={false} // Sender pays gas\n\u003e\n  Free Reward (No Gas Required)\n\u003c/RewardButton\u003e\n\n// User pays gas fees\n\u003cRewardButton\n  tokenAddress=\"0x...\"\n  rewardAmount=\"1000000\"\n  senderAddress=\"0x...\"\n  senderPrivateKey=\"0x...\"\n  userPaysGas={true} // User pays gas\n\u003e\n  Claim Reward (You Pay Gas)\n\u003c/RewardButton\u003e\n```\n\n### Custom Styling\n\n```tsx\n\u003cRewardButton\n  tokenAddress=\"0x...\"\n  rewardAmount=\"1000000\"\n  senderAddress=\"0x...\"\n  senderPrivateKey=\"0x...\"\n  variant=\"outline\"\n  size=\"lg\"\n  className=\"my-custom-styles\"\n  style={{\n    backgroundColor: '#ff6b6b',\n    borderRadius: '12px',\n    padding: '16px 32px'\n  }}\n\u003e\n  🎁 Special Reward\n\u003c/RewardButton\u003e\n```\n\n### Error Handling\n\n```tsx\nimport { useState } from 'react';\nimport { RewardButton } from 'react-reward-button';\n\nfunction RewardWithErrorHandling() {\n  const [error, setError] = useState\u003cstring | null\u003e(null);\n  const [success, setSuccess] = useState(false);\n\n  return (\n    \u003cdiv\u003e\n      \u003cRewardButton\n        tokenAddress=\"0x...\"\n        rewardAmount=\"1000000\"\n        senderAddress=\"0x...\"\n        senderPrivateKey=\"0x...\"\n        onRewardClaimed={(txHash, amount) =\u003e {\n          setSuccess(true);\n          setError(null);\n          console.log('Success!', { txHash, amount });\n        }}\n        onRewardFailed={(error) =\u003e {\n          setError(error.message);\n          setSuccess(false);\n        }}\n        onRewardStarted={() =\u003e {\n          setError(null);\n          setSuccess(false);\n        }}\n      \u003e\n        Claim Reward\n      \u003c/RewardButton\u003e\n      \n      {error \u0026\u0026 \u003cp style={{ color: 'red' }}\u003eError: {error}\u003c/p\u003e}\n      {success \u0026\u0026 \u003cp style={{ color: 'green' }}\u003eReward claimed successfully!\u003c/p\u003e}\n    \u003c/div\u003e\n  );\n}\n```\n\n### Using as Regular Button\n\nIf you don't provide `tokenAddress` and `rewardAmount`, it works as a regular button:\n\n```tsx\nimport { RewardButton } from 'react-reward-button';\n\nfunction RegularButton() {\n  return (\n    \u003cRewardButton\n      onReward={() =\u003e {\n        console.log('Regular button clicked!');\n      }}\n      variant=\"secondary\"\n    \u003e\n      Regular Button\n    \u003c/RewardButton\u003e\n  );\n}\n```\n\n## Configuration\n\n### Environment Variables\n\nFor development, you can use environment variables:\n\n```bash\n# .env\nVITE_REOWN_PROJECT_ID=your_project_id\nVITE_NETWORK=mainnet\nVITE_RPC_URL=https://mainnet.infura.io/v3/your_key\n```\n\n### Network Configuration\n\n```tsx\nimport { mainnet, polygon, sepolia, arbitrum } from 'wagmi/chains';\n\nconst networks = [\n  mainnet,    // Ethereum Mainnet\n  polygon,    // Polygon\n  sepolia,    // Ethereum Sepolia Testnet\n  arbitrum,   // Arbitrum One\n];\n```\n\n## Security Considerations\n\n⚠️ **Important Security Notes:**\n\n1. **Never expose private keys in client-side code** - The `senderPrivateKey` should only be used in secure environments\n2. **Use environment variables** for sensitive data\n3. **Consider using a backend service** for production applications\n4. **Validate all inputs** and amounts before processing\n5. **Test thoroughly** on testnets before mainnet deployment\n\n## Supported Networks\n\n- Ethereum Mainnet\n- Polygon\n- Arbitrum\n- Optimism\n- Sepolia Testnet\n- Polygon Mumbai Testnet\n- Any EVM-compatible network\n\n## Browser Support\n\n- Chrome 90+\n- Firefox 88+\n- Safari 14+\n- Edge 90+\n- Mobile browsers with Web3 wallet support\n\n## Contributing\n\n1. Fork the repository\n2. Create your feature branch (`git checkout -b feature/amazing-feature`)\n3. Commit your changes (`git commit -m 'Add some amazing feature'`)\n4. Push to the branch (`git push origin feature/amazing-feature`)\n5. Open a Pull Request\n\n## License\n\nMIT License - see the [LICENSE](LICENSE) file for details.\n\n## Support\n\n- 🐛 **Issues**: [GitHub Issues](https://github.com/your-username/react-reward-button/issues)\n- 💬 **Discussions**: [GitHub Discussions](https://github.com/your-username/react-reward-button/discussions)\n- 📖 **Documentation**: [Full Documentation](https://github.com/your-username/react-reward-button#readme)\n\n---\n\nMade with ❤️ for the Web3 community","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvarungulati%2Freact-reward-button","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvarungulati%2Freact-reward-button","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvarungulati%2Freact-reward-button/lists"}