diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000..9f6498a --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,31 @@ +# Use the latest 2.1 version of CircleCI pipeline process engine. +# See: https://circleci.com/docs/configuration-reference +version: 2.1 +# +# Define a job to be invoked later in a workflow. +# See: https://circleci.com/docs/jobs-steps/#jobs-overview & https://circleci.com/docs/configuration-reference/#jobs +jobs: + say-hello: + # Specify the execution environment. You can specify an image from Docker Hub or use one of our convenience images from CircleCI's Developer Hub. + # See: https://circleci.com/docs/executor-intro/ & https://circleci.com/docs/configuration-reference/#executor-job + docker: + # Specify the version you desire here + # See: https://circleci.com/developer/images/image/cimg/base + - image: cimg/base:current + + # Add steps to the job + # See: https://circleci.com/docs/jobs-steps/#steps-overview & https://circleci.com/docs/configuration-reference/#steps + steps: + # Checkout the code as the first step. + - checkout + - run: + name: "Say hello" + command: "echo Hello, World!" + +# Orchestrate jobs using workflows +# See: https://circleci.com/docs/workflows/ & https://circleci.com/docs/configuration-reference/#workflows +workflows: + say-hello-workflow: # This is the name of the workflow, feel free to change it to better match your workflow. + # Inside the workflow, you define the jobs you want to run. + jobs: + - say-hello diff --git a/.env.example b/.env.example index 549c3f7..7bd4da4 100644 --- a/.env.example +++ b/.env.example @@ -1,4 +1,5 @@ # Retrieve your API Key and Policy ID from the smart wallets dashboard default configuration or create new keys: https://dashboard.alchemy.com/services/smart-wallets/configuration NEXT_PUBLIC_ALCHEMY_API_KEY=YOUR_APP_API_KEY # Get your app API key: https://dashboard.alchemy.com/apps NEXT_PUBLIC_ALCHEMY_POLICY_ID=YOUR_SPONSORSHIP_POLICY_ID # Get your gas sponsorship policy ID: https://dashboard.alchemy.com/services/gas-manager/configuration +NEXT_PUBLIC_CHAIN_ID=421614 # Arbitrum Sepolia as default # NOTE: make sure to set up a smart wallet configuration for your app to enable login \ No newline at end of file diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..3d40a6a --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +* @alchemyplatform/wallet-services diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..80995d3 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,38 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Desktop (please complete the following information):** + - OS: [e.g. iOS] + - Browser [e.g. Chrome, Safari] + - Version [e.g. 22] + +**Smartphone (please complete the following information):** + - Device: [e.g. iPhone 6] + - OS: [e.g. iOS8.1] + - Browser [e.g. stock browser, safari] + - Version [e.g. 22] + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/custom.md b/.github/ISSUE_TEMPLATE/custom.md new file mode 100644 index 0000000..48d5f81 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/custom.md @@ -0,0 +1,10 @@ +--- +name: Custom issue template +about: Describe this issue template's purpose here. +title: '' +labels: '' +assignees: '' + +--- + + diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..72cc8d0 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: '' +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. e.g., I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..79e54d6 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,27 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file + +version: 2 +updates: + - package-ecosystem: "npm" + directory: "/" + schedule: + interval: "weekly" + - package-ecosystem: "npm" + directory: "/accept-a-payment/" + schedule: + interval: "weekly" + - package-ecosystem: "npm" + directory: "/accept-a-payment/client/" + schedule: + interval: "weekly" + - package-ecosystem: "npm" + directory: "/accept-a-payment/server/" + schedule: + interval: "weekly" + - package-ecosystem: "npm" + directory: "/alchemy-demo/" + schedule: + interval: "weekly" diff --git a/.github/workflows/Vercel Preview Deployment.yml b/.github/workflows/Vercel Preview Deployment.yml new file mode 100644 index 0000000..ca7ca97 --- /dev/null +++ b/.github/workflows/Vercel Preview Deployment.yml @@ -0,0 +1,22 @@ +name: Playwright Tests + +on: + repository_dispatch: + types: + - 'vercel.deployment.success' +permissions: + contents: read +jobs: + run-e2es: + if: github.event_name == 'repository_dispatch' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ github.event.client_payload.git.sha }} + - name: Install dependencies + run: npm ci && npx playwright install --with-deps + - name: Run tests + run: npx playwright test + env: + BASE_URL: ${{ github.event.client_payload.url }} diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/accounts-ui-kit.iml b/.idea/accounts-ui-kit.iml new file mode 100644 index 0000000..d6ebd48 --- /dev/null +++ b/.idea/accounts-ui-kit.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/caches/deviceStreaming.xml b/.idea/caches/deviceStreaming.xml new file mode 100644 index 0000000..4accbfe --- /dev/null +++ b/.idea/caches/deviceStreaming.xml @@ -0,0 +1,1971 @@ + + + + + + \ No newline at end of file diff --git a/.idea/markdown.xml b/.idea/markdown.xml new file mode 100644 index 0000000..c61ea33 --- /dev/null +++ b/.idea/markdown.xml @@ -0,0 +1,8 @@ + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..862d09b --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..518f2e3 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 0000000..0726e93 --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + { + "lastFilter": { + "state": "OPEN", + "assignee": "Dargon789" + } +} + { + "selectedUrlAndAccountId": { + "url": "https://github.com/Dargon789/accounts-ui-kit.git", + "accountId": "901c3c88-76ca-48f1-af81-8988657f5914" + } +} + { + "associatedIndex": 6 +} + + + + { + "keyToString": { + "ModuleVcsDetector.initialDetectionPerformed": "true", + "RunOnceActivity.ShowReadmeOnStart": "true", + "RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252": "true", + "RunOnceActivity.cidr.known.project.marker": "true", + "RunOnceActivity.git.unshallow": "true", + "RunOnceActivity.readMode.enableVisualFormatting": "true", + "cf.first.check.clang-format": "false", + "cidr.known.project.marker": "true", + "git-widget-placeholder": "main", + "ignore.virus.scanning.warn.message": "true", + "kotlin-language-version-configured": "true", + "last_opened_file_path": "C:/Users/Legion/accounts-ui-kit" + } +} + + + + 1773969373195 + + + + + + + \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..e11c735 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "githubPullRequests.ignoredPullRequestBranches": [ + "main" + ] +} \ No newline at end of file diff --git a/README.md b/README.md index 388e47f..dc68a45 100644 --- a/README.md +++ b/README.md @@ -7,9 +7,346 @@ Use this template to get started with **embedded smart wallets** using [Alchemy - Email, passkey & social login using pre‑built UI components - Flexible, secure, and cheap smart accounts - Gasless transactions powered by ERC-4337 Account Abstraction -- One‑click NFT mint on Base Sepolia (no ETH required) +- One‑click NFT mint (no ETH required) - Server‑side rendering ready – session persisted with cookies - TailwindCSS + shadcn/ui components, React Query, TypeScript +# Smart Wallets + +> Build zero-friction user onboarding and transactions end-to-end with one SDK. + +smart wallets overview + + + Send your first transaction using the SDK or API. + + +## Everything You Need for Onchain Applications + + + + Email, social, biometric, or EOA login. + + + Remove gas fees for users. + + + Multiple transactions in 1 click on EVM & Solana. + + + Pre-built UI components or fully whitelabel. + + + +## Frameworks + + + + Pre-built React components and hooks. + + + Native mobile wallet experiences. + + + Framework-agnostic implementation. + + + Server-side wallet management. + + + +## Common Starting Places + + + + Build an onchain app from scratch with wallets and transactions. + + + Upgrade to smart wallets using EIP-7702 or direct wagmi integration. + + + Add wallet and transaction functionality to existing web2 applications. + + + Server-side applications with signing and sending on your backend. + + + +## Resources + + + + Troubleshoot issues or get in touch. + + + End-to-end guides for common features. + + + Save costs as you scale. + + + +# Choose Your Starting Point + +> Overview of our product offerings + + + + Low-level JSON-RPC for reading & writing blockchain data. + + + + Structured, indexed data for balances, NFTs, prices, and more. + + + + Account abstraction infrastructure for smart wallets. + + + + Launch dedicated rollups with full control over your L2. + + + + + Build faster with production-ready APIs, smart wallets and rollup infrastructure across 70+ chains. Create your free Alchemy API key and + get started today. + + +*** + +## 1. Node API + +The [Node API](/docs/reference/node-api-overview) gives you low-level access to standard JSON-RPC methods for interacting with blockchains. + +Use it for sending transactions, querying blocks and logs, and accessing state. It supports multiple chains; see the [Chain APIs Overview](/docs/reference/chain-apis-overview) page for the full list. + + + + Read & write interface for all blockchains supported by us. + + + + Subscribe to pending transactions, log events, new blocks, and more. + + + + Get insights into transaction processing and onchain activity. + + + + Non-standard RPC methods for inspecting and debugging transactions. + + + + High-performance real-time Solana data streaming interface. + + + +*** + +## 2. Data APIs + +The [Data APIs](/docs/reference/data-overview) provide structured, indexed data that would be difficult to get via RPC alone. + +Use it for NFT metadata, token balances, transaction histories, enriched transfers, and analytics. Optimized for high-volume reads, dashboards, and data-heavy applications. + + + + Build a complete portfolio view of a user's wallet across tokens and NFTs. + + + + Get historical transactions for any address in a single request. + + + + Access real-time and historical token prices. + + + + Find, verify, and display NFTs across major blockchains. + + + + Subscribe to onchain events like transfers, transactions, and balance changes. + + + + Simulate transactions and see their effects before you send them. + + + +*** + +## 3. Wallet APIs / Account Abstraction Infrastructure + +Our [Smart Wallets](/docs/wallets) product gives you everything you need to build zero-friction user flows, from sign-up to checkout, using smart contract accounts. + +Use these APIs to handle user operations, sponsor gas, and implement smart accounts with account abstraction. + + + + Bundler API Quickstart for handling user operations. + + + + Gas Manager API Quickstart for sponsoring gas fees. + + + + Send transactions with smart accounts. + + + +*** + +## 4. Rollups + +Our [Rollups](/docs/reference/rollups-quickstart) product helps you run a dedicated rollup with full control over transaction speed, cost, and functionality. + +Launching a rollup can unlock new revenue streams, enable novel use cases, and provide a better user experience. + +# View the Stack rollup framework. + + + Send your first transaction using the SDK or API. + + +## Everything You Need for Onchain Applications + + + + Email, social, biometric, or EOA login. + + + Remove gas fees for users. + + + Multiple transactions in 1 click on EVM & Solana. + + + Pre-built UI components or fully whitelabel. + + + +## Frameworks + + + + Pre-built React components and hooks. + + + Native mobile wallet experiences. + + + Framework-agnostic implementation. + + + Server-side wallet management. + + + +![Smart Wallet Quickstart](https://github.com/user-attachments/assets/2903fb78-e632-4aaa-befd-5775c60e1ca2) + +# Feature Support By Chain + +> Alchemy's current feature availability for each of its supported chains + + + + ![[Chains](https://dashboard.alchemy.com/chains)](https://alchemyapi-res.cloudinary.com/image/upload/v1764179964/docs/api-reference/alchemy-transact/transaction-simulation/523fb8a9a9d899921ee1046d0ff1b389967a9976d1c6112ebbbe071ddd1ef374-image.png) + + + +## 📍 Network & Demo Contract + +This quickstart is configured to run on **Arbitrum Sepolia** testnet, by default. A free demo NFT contract has been deployed specifically for this quickstart, allowing you to mint NFTs without any setup or deployment steps. The contract is pre-configured and ready to use out of the box. ## 🚀 Quick start @@ -69,7 +406,7 @@ tailwind.config.ts ## 🏗️ How it works -1. `config.ts` initializes Account Kit with your API key, Base Sepolia chain, and Gas Sponsorship policy. +1. `config.ts` initializes Account Kit with your API key, chain, and Gas Sponsorship policy. 2. `Providers` wraps the app with `AlchemyAccountProvider` & React Query. 3. `LoginCard` opens the authentication modal (`useAuthModal`). 4. After login, `useSmartAccountClient` exposes the smart wallet. diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..034e848 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,21 @@ +# Security Policy + +## Supported Versions + +Use this section to tell people about which versions of your project are +currently being supported with security updates. + +| Version | Supported | +| ------- | ------------------ | +| 5.1.x | :white_check_mark: | +| 5.0.x | :x: | +| 4.0.x | :white_check_mark: | +| < 4.0 | :x: | + +## Reporting a Vulnerability + +Use this section to tell people how to report a vulnerability. + +Tell them where to go, how often they can expect to get an update on a +reported vulnerability, what to expect if the vulnerability is accepted or +declined, etc. diff --git a/app/components/nft-mint-card.tsx b/app/components/nft-mint-card.tsx index 06bb9cc..b24bb0e 100644 --- a/app/components/nft-mint-card.tsx +++ b/app/components/nft-mint-card.tsx @@ -1,5 +1,11 @@ -import { useState } from "react"; -import { ExternalLink, Loader2, PlusCircle } from "lucide-react"; +import { useState, useEffect } from "react"; +import { + ExternalLink, + Loader2, + PlusCircle, + ImageIcon, + CheckCircle, +} from "lucide-react"; import { Button } from "@/components/ui/button"; import { Card, @@ -15,15 +21,17 @@ import Link from "next/link"; import { useReadNFTData } from "@/app/hooks/useReadNFTData"; import { useMint } from "@/app/hooks/useMintNFT"; import { useSmartAccountClient } from "@account-kit/react"; -import { NFT_CONTRACT_ADDRESS } from "@/lib/constants"; +import { useNftContractAddress } from "@/app/hooks/useNftContractAddress"; export default function NftMintCard() { const [isImageLoading, setIsImageLoading] = useState(true); + const [showSuccess, setShowSuccess] = useState(true); + const nftContractAddress = useNftContractAddress(); const { client } = useSmartAccountClient({}); const { uri, count, isLoadingCount, refetchCount } = useReadNFTData({ - contractAddress: NFT_CONTRACT_ADDRESS, + contractAddress: nftContractAddress, ownerAddress: client?.account?.address, }); @@ -33,6 +41,17 @@ export default function NftMintCard() { }, }); + // Reset success animation when new transaction appears + useEffect(() => { + if (transactionUrl) { + setShowSuccess(true); + const timer = setTimeout(() => { + setShowSuccess(false); + }, 4000); + return () => clearTimeout(timer); + } + }, [transactionUrl]); + return ( @@ -105,7 +124,7 @@ export default function NftMintCard() { )} > - Mint New NFT + Mint New NFT {!!client?.chain?.name && `on ${client.chain.name}`} - View Transaction - + {showSuccess ? ( + <> +
+ Successful mint! + + + + ) : ( + <> + View Transaction + + + )} )} diff --git a/app/components/user-info-card.tsx b/app/components/user-info-card.tsx index 438cdec..713c317 100644 --- a/app/components/user-info-card.tsx +++ b/app/components/user-info-card.tsx @@ -1,4 +1,5 @@ -import { Info, ExternalLink, Copy } from "lucide-react"; +import { useState } from "react"; +import { ExternalLink, Copy } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Card, @@ -8,14 +9,27 @@ import { CardTitle, } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; +import { + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger, +} from "@/components/ui/tooltip"; import { formatAddress } from "@/lib/utils"; import { useUser, useSmartAccountClient } from "@account-kit/react"; export default function UserInfo() { + const [isCopied, setIsCopied] = useState(false); const user = useUser(); const userEmail = user?.email ?? "anon"; const { client } = useSmartAccountClient({}); + const handleCopy = () => { + navigator.clipboard.writeText(client?.account?.address ?? ""); + setIsCopied(true); + setTimeout(() => setIsCopied(false), 2000); + }; + return ( @@ -41,25 +55,32 @@ export default function UserInfo() { {formatAddress(client?.account?.address ?? "")} - + + + + + + +

Copied!

+
+
+