Time-locked stablecoin birthday gifts on Arc. Send USDC or EURC that unlock on someone's birthday — each gift mints a unique on-chain SVG NFT card to the recipient.
- Create — Connect wallet, pick a recipient, token, amount, birthday date and a message
- NFT minted — An ERC-721 gift card with fully on-chain SVG art is sent to the recipient immediately
- Locked — Funds sit in the vault contract until the birthday timestamp passes
- Claim — Recipient claims on their birthday, tokens transfer in one tx, card marks as Claimed
- On-chain SVG NFT gift cards — no IPFS, no off-chain dependencies
- Multi-token: USDC and EURC
- 5 visual card themes (Birthday, Ocean, Sunset, Midnight, Garden)
- Annual recurring gifts with renewal notifications
- Cancel + refund before claim
- Sub-second finality on Arc (~0.48s)
- ~$0.01 gas per transaction (USDC-denominated)
| Language | Solidity 0.8.24 |
| Framework | Foundry |
| Libraries | OpenZeppelin v5 |
| Framework | Next.js 14 (App Router) |
| Chain / Wallet | wagmi v2 + viem + RainbowKit v2 |
| Animations | Framer Motion |
| Styling | Tailwind CSS |
- Node.js 18+
- Foundry
- A WalletConnect project ID
1. Install dependencies
cd contracts
forge install OpenZeppelin/openzeppelin-contracts2. Configure environment
cp .env.example .envFill in:
ARC_TESTNET_RPC_URL=https://rpc.testnet.arc.network
PRIVATE_KEY=0xYOUR_PRIVATE_KEY
3. Run tests
forge test -v4. Deploy to Arc Testnet
forge script script/Deploy.s.sol \
--rpc-url arc_testnet \
--broadcast \
--verifyCopy the BirthdayCard and BirthdayDrop addresses from the output.
1. Install dependencies
cd frontend
npm install2. Configure environment
cp .env.local.example .env.localFill in:
NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID=your_project_id
NEXT_PUBLIC_BIRTHDAY_DROP_ADDRESS=0xYOUR_DROP_ADDRESS
NEXT_PUBLIC_BIRTHDAY_CARD_ADDRESS=0xYOUR_CARD_ADDRESS
3. Run dev server
npm run devOpen http://localhost:3000.
| Chain ID | 5042002 |
| RPC | https://rpc.testnet.arc.network |
| Explorer | https://testnet.arcscan.app |
| Faucet | https://faucet.circle.com |
| USDC | 0x3600000000000000000000000000000000000000 |
| EURC | 0x89B50855Aa3bE2F677cD6303Cec089B5F319D72a |
| Gas token | USDC (18 decimals native, 6 decimals ERC-20) |
contracts/src/
├── BirthdayCard.sol ERC-721 NFT with fully on-chain SVG. 5 themes.
│ Minted to recipient on gift creation.
│ Marked claimed/cancelled by BirthdayDrop.
│
└── BirthdayDrop.sol Gift vault. Holds tokens until birthday.
createGift() — locks tokens, mints NFT
claimGift() — transfers tokens after birthday
cancelGift() — refunds sender, cancels NFT
birthday-drop/
├── contracts/
│ ├── src/
│ │ ├── BirthdayCard.sol
│ │ └── BirthdayDrop.sol
│ ├── test/
│ │ └── BirthdayDrop.t.sol
│ ├── script/
│ │ └── Deploy.s.sol
│ └── foundry.toml
│
└── frontend/
├── app/
│ ├── page.tsx Landing page
│ ├── create/page.tsx Gift creation form + live NFT preview
│ └── dashboard/page.tsx Sent / received gifts dashboard
├── components/
│ ├── Header.tsx
│ ├── LogoMark.tsx
│ ├── GiftCardPreview.tsx
│ ├── GiftItem.tsx
│ ├── CountdownTimer.tsx
│ ├── TokenSelector.tsx
│ └── ThemeSelector.tsx
└── lib/
├── wagmi.ts Arc chain config + RainbowKit
├── contracts.ts Addresses, token list, themes
├── abi.ts Contract ABIs
└── utils.ts Formatting helpers
MIT