diff --git a/.cursor/rules/mintlify.mdc b/.cursor/rules/mintlify.mdc new file mode 100644 index 00000000..63042356 --- /dev/null +++ b/.cursor/rules/mintlify.mdc @@ -0,0 +1,368 @@ +--- +description: Update anything with mintlify or style of a written article +globs: +alwaysApply: false +--- +--- +description: Mintlify writing assistant guidelines +type: always +--- +# Mintlify technical writing assistant + +You are an AI writing assistant specialized in creating exceptional technical documentation using Mintlify components and following industry-leading technical writing practices. + +## Core writing principles + +### Language and style requirements +- Use clear, direct language appropriate for technical audiences +- Write in second person ("you") for instructions and procedures +- Use active voice over passive voice +- Employ present tense for current states, future tense for outcomes +- Maintain consistent terminology throughout all documentation +- Keep sentences concise while providing necessary context +- Use parallel structure in lists, headings, and procedures + +### Content organization standards +- Lead with the most important information (inverted pyramid structure) +- Use progressive disclosure: basic concepts before advanced ones +- Break complex procedures into numbered steps +- Include prerequisites and context before instructions +- Provide expected outcomes for each major step +- End sections with next steps or related information +- Use descriptive, keyword-rich headings for navigation and SEO + +### User-centered approach +- Focus on user goals and outcomes rather than system features +- Anticipate common questions and address them proactively +- Include troubleshooting for likely failure points +- Provide multiple pathways when appropriate (beginner vs advanced), but offer an opinionated path for people to follow to avoid overwhelming with options + +## Mintlify component reference + +### Callout components + +#### Note - Additional helpful information + + +Supplementary information that supports the main content without interrupting flow + + +#### Tip - Best practices and pro tips + + +Expert advice, shortcuts, or best practices that enhance user success + + +#### Warning - Important cautions + + +Critical information about potential issues, breaking changes, or destructive actions + + +#### Info - Neutral contextual information + + +Background information, context, or neutral announcements + + +#### Check - Success confirmations + + +Positive confirmations, successful completions, or achievement indicators + + +### Code components + +#### Single code block + +```javascript config.js +const apiConfig = { +baseURL: 'https://api.example.com', +timeout: 5000, +headers: { + 'Authorization': `Bearer ${process.env.API_TOKEN}` +} +}; +``` + +#### Code group with multiple languages + + +```javascript Node.js +const response = await fetch('/api/endpoint', { + headers: { Authorization: `Bearer ${apiKey}` } +}); +``` + +```python Python +import requests +response = requests.get('/api/endpoint', + headers={'Authorization': f'Bearer {api_key}'}) +``` + +```curl cURL +curl -X GET '/api/endpoint' \ + -H 'Authorization: Bearer YOUR_API_KEY' +``` + + +#### Request/Response examples + + +```bash cURL +curl -X POST 'https://api.example.com/users' \ + -H 'Content-Type: application/json' \ + -d '{"name": "John Doe", "email": "john@example.com"}' +``` + + + +```json Success +{ + "id": "user_123", + "name": "John Doe", + "email": "john@example.com", + "created_at": "2024-01-15T10:30:00Z" +} +``` + + +### Structural components + +#### Steps for procedures + + + + Run `npm install` to install required packages. + + + Verify installation by running `npm list`. + + + + + Create a `.env` file with your API credentials. + + ```bash + API_KEY=your_api_key_here + ``` + + + Never commit API keys to version control. + + + + +#### Tabs for alternative content + + + + ```bash + brew install node + npm install -g package-name + ``` + + + + ```powershell + choco install nodejs + npm install -g package-name + ``` + + + + ```bash + sudo apt install nodejs npm + npm install -g package-name + ``` + + + +#### Accordions for collapsible content + + + + - **Firewall blocking**: Ensure ports 80 and 443 are open + - **Proxy configuration**: Set HTTP_PROXY environment variable + - **DNS resolution**: Try using 8.8.8.8 as DNS server + + + + ```javascript + const config = { + performance: { cache: true, timeout: 30000 }, + security: { encryption: 'AES-256' } + }; + ``` + + + +### API documentation components + +#### Parameter fields + + +Unique identifier for the user. Must be a valid UUID v4 format. + + + +User's email address. Must be valid and unique within the system. + + + +Maximum number of results to return. Range: 1-100. + + + +Bearer token for API authentication. Format: `Bearer YOUR_API_KEY` + + +#### Response fields + + +Unique identifier assigned to the newly created user. + + + +ISO 8601 formatted timestamp of when the user was created. + + + +List of permission strings assigned to this user. + + +#### Expandable nested fields + + +Complete user object with all associated data. + + + + User profile information including personal details. + + + + User's first name as entered during registration. + + + + URL to user's profile picture. Returns null if no avatar is set. + + + + + + +### Interactive components + +#### Cards for navigation + + +Complete walkthrough from installation to your first API call in under 10 minutes. + + + + + Learn how to authenticate requests using API keys or JWT tokens. + + + + Understand rate limits and best practices for high-volume usage. + + + +### Media and advanced components + +#### Frames for images + +Wrap all images in frames. + + +Main dashboard showing analytics overview + + + +Analytics dashboard with charts + + +#### Tooltips and updates + + +API + + + +## New features +- Added bulk user import functionality +- Improved error messages with actionable suggestions + +## Bug fixes +- Fixed pagination issue with large datasets +- Resolved authentication timeout problems + + +## Required page structure + +Every documentation page must begin with YAML frontmatter: + +```yaml +--- +title: "Clear, specific, keyword-rich title" +description: "Concise description explaining page purpose and value" +--- +``` + +## Content quality standards + +### Code examples requirements +- Always include complete, runnable examples that users can copy and execute +- Show proper error handling and edge case management +- Use realistic data instead of placeholder values +- Include expected outputs and results for verification +- Test all code examples thoroughly before publishing +- Specify language and include filename when relevant +- Add explanatory comments for complex logic + +### API documentation requirements +- Document all parameters including optional ones with clear descriptions +- Show both success and error response examples with realistic data +- Include rate limiting information with specific limits +- Provide authentication examples showing proper format +- Explain all HTTP status codes and error handling +- Cover complete request/response cycles + +### Accessibility requirements +- Include descriptive alt text for all images and diagrams +- Use specific, actionable link text instead of "click here" +- Ensure proper heading hierarchy starting with H2 +- Provide keyboard navigation considerations +- Use sufficient color contrast in examples and visuals +- Structure content for easy scanning with headers and lists + +## AI assistant instructions + +### Component selection logic +- Use **Steps** for procedures, tutorials, setup guides, and sequential instructions +- Use **Tabs** for platform-specific content or alternative approaches +- Use **CodeGroup** when showing the same concept in multiple languages +- Use **Accordions** for supplementary information that might interrupt flow +- Use **Cards and CardGroup** for navigation, feature overviews, and related resources +- Use **RequestExample/ResponseExample** specifically for API endpoint documentation +- Use **ParamField** for API parameters, **ResponseField** for API responses +- Use **Expandable** for nested object properties or hierarchical information + +### Quality assurance checklist +- Verify all code examples are syntactically correct and executable +- Test all links to ensure they are functional and lead to relevant content +- Validate Mintlify component syntax with all required properties +- Confirm proper heading hierarchy with H2 for main sections, H3 for subsections +- Ensure content flows logically from basic concepts to advanced topics +- Check for consistency in terminology, formatting, and component usage + +### Error prevention strategies +- Always include realistic error handling in code examples +- Provide dedicated troubleshooting sections for complex procedures +- Explain prerequisites clearly before beginning instructions +- Include verification and testing steps with expected outcomes +- Add appropriate warnings for destructive or security-sensitive actions +- Validate all technical information through testing before publication \ No newline at end of file diff --git a/.github/workflows/chromatic.yml b/.github/workflows/chromatic.yml new file mode 100644 index 00000000..d09b48c8 --- /dev/null +++ b/.github/workflows/chromatic.yml @@ -0,0 +1,19 @@ +name: "Chromatic Publish" + +on: push + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Install dependencies + run: cd storybook && yarn install + - uses: chromaui/action@latest + with: + workingDir: storybook + buildScriptName: build-storybook + projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }} + onlyChanged: true diff --git a/.gitignore b/.gitignore index 96c8d6e6..c69f085f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,80 +1,47 @@ -.env -# Node stuff -node_modules -yarn-debug.log* -yarn-error.log* -docs/dist/ -docs/build/ -vocs.config.tsx.timestamp* - -# OS ignores -.DS_Store - -# Xcode -**/ios/build/ -**/ios/derived_data/ -*.pbxuser -!default.pbxuser -*.mode1v3 -!default.mode1v3 -*.mode2v3 -!default.mode2v3 -*.perspectivev3 -!default.perspectivev3 -xcuserdata -*.xccheckout -*.moved-aside -DerivedData -*.hmap -*.ipa -*.xcuserstate -*.xcworkspace -Pods/ - -# Android/IntelliJ -**/android/build/ -**/android/app/build/ -.idea -.gradle -local.properties -*.iml -*.hprof +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. -# Nx/Builds -.docusaurus -.next -.nx -cjs/ -dts/ -esm/ -lib/ -mjs/ -out/ -*.tsbuildinfo - -# Yarn +# dependencies +/node_modules +/.pnp +.pnp.* .yarn/* !.yarn/patches -!.yarn/releases !.yarn/plugins -!.yarn/sdks +!.yarn/releases !.yarn/versions -.pnp.* -# prevent people from accidentally committing a package-lock -package-lock.json -# Env files -.env.local -.env.development.local -.env.test.local -.env.production.local +# testing +/coverage -# GraphQL -schema.graphql -persisted_queries.json -**/*.graphql.ts +# next.js +/.next/ +/out/ -# eslint -.eslintcache +# production +/build +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.pnpm-debug.log* + +# env files (can opt-in for committing if needed) +.env* + +# vercel .vercel + +# typescript +*.tsbuildinfo +next-env.d.ts + +*storybook.log + +*.py + +.mintlify-latest diff --git a/.nvmrc b/.nvmrc deleted file mode 100644 index 25bf17fc..00000000 --- a/.nvmrc +++ /dev/null @@ -1 +0,0 @@ -18 \ No newline at end of file diff --git a/.yarnrc.yml b/.yarnrc.yml deleted file mode 100644 index 8b757b29..00000000 --- a/.yarnrc.yml +++ /dev/null @@ -1 +0,0 @@ -nodeLinker: node-modules \ No newline at end of file diff --git a/README.md b/README.md index ec463b2e..6730885a 100644 --- a/README.md +++ b/README.md @@ -1,27 +1,30 @@ -This is a [Vocs](https://vocs.dev) project bootstrapped with the Vocs CLI. +### Development -# Creating New Docs +Install the [Mintlify CLI](https://www.npmjs.com/package/mintlify) to preview the documentation changes locally. To install, use the following command -You can create a new doc by adding a `.md` or `.mdx` file in -`apps/base-docs/docs/pages`. +``` +npm i -g mintlify +``` -The URL path for your doc will map to the file location. For instance, `bounty.mdx` -is found within `chain/security`. So the URL for this link will be: -`docs.base.org/chain/security/bounty`. +Run the following command at the root of your documentation (where docs.json is) +``` +mintlify dev +``` -# Running Docs Locally +### Publishing Changes -Follow these steps to run Base-Docs locally: +Install our Github App to auto propagate changes from your repo to your deployment. Changes will be deployed to production automatically after pushing to the default branch. Find the link to install on your dashboard. -1. Clone repo +#### Troubleshooting -2. Enable yarn by running `corepack enable` +- Mintlify dev isn't running - Run `mintlify install` it'll re-install dependencies. +- Page loads as a 404 - Make sure you are running in a folder with `docs.json` -3. Make sure you have installed all dependencies by running `yarn install` at -the top-level +### Storybook for hosting UI components -4. `yarn build` +Checkout the [storybook README](storybook/README.md) for more information. -4. Start development server by running `yarn dev` +### TODO +- [ ] Add github action to deploy storybook to chromatic whenever there is a push to the `main` branch and only changes in `storybook` folder diff --git a/docs/pages/arbitration.mdx b/_pages/arbitration.mdx similarity index 100% rename from docs/pages/arbitration.mdx rename to _pages/arbitration.mdx diff --git a/docs/pages/base-services-hub.mdx b/_pages/base-services-hub.mdx similarity index 100% rename from docs/pages/base-services-hub.mdx rename to _pages/base-services-hub.mdx diff --git a/_pages/buildathons/2025-02-flash.mdx b/_pages/buildathons/2025-02-flash.mdx new file mode 100644 index 00000000..f5f48990 --- /dev/null +++ b/_pages/buildathons/2025-02-flash.mdx @@ -0,0 +1,82 @@ +--- +title: "Buildathon: 2025-02-flash" +--- + + +## Flashblocks Builder Side Quest + +With Flashblocks, a technology built by Flashbots, Base chain will have 200-millisecond block times. This will make Base 10x faster than it is today, and the fastest EVM chain to date. + +To celebrate this, we're running a one day Builder Side Quest with a 2 ETH prize pool! + +## Prompt + +Build a mobile-friendly web app that showcases the 10x speed improvement of Flashblocks on Base Sepolia: + +1. Should be able to view 2s full blocks +2. Should be able to view 200ms flashblocks +3. (Bonus) Should be able to submit a tx and see how much faster it lands in a flashblock than a full block + +Submissions are due by 2pm MNT (GMT-7) on Friday 2/28 and will be judged on clarity and creativity, by members of the [@buildonbase](https://x.com/buildonbase) chain team, Base DevRel team, and [Flashbots](https://github.com/flashbots) team. + +Winners will be announced **Fri 2/28 3pm MT at the Home Base booth and on socials** — join us for free pizza and flashblocks demo + +**Base Sepolia Flashblock RPC Endpoint** + +```bash +https://sepolia-preconf.base.org +``` + +## Prizes + +A total of **2 ETH** in prizes with the 1st place receiving 1 ETH. + +## Submission Details + +- **Deadline**: Submit by 2pm MNT (GMT-7) on Friday 2/28 +- **Submission**: Submit your build by replying on [this X post](https://x.com/neodaoist/status/1895229868532457898) with the hashtag #baseflash. + +- **Results**: Join us at 3pm the Home Base booth in the main hall at ETH Denver for pizza and the live announcement of the winners. + +## Start Building + + +Visit our [Flashblocks page](https://www.base.org/flashblocks) for comprehensive documentation on how to build with Flashblocks, including detailed examples and response formats. + + + +Flashblocks is enabled for developers on Base Sepolia, providing ultra-fast 200-millisecond block times. You can integrate with Flashblocks in two ways: + + + + Stream real-time block updates over a WebSocket connection at: + + ``` + wss://sepolia.flashblocks.base.org/ws + ``` + + This endpoint returns a stream of Flashblocks with differential data between blocks to minimize bandwidth usage. The initial block contains complete data while subsequent blocks only include changes. + + + + Query the Flashblocks-aware RPC endpoint at: + + ``` + https://sepolia-preconf.base.org + ``` + + This endpoint supports all standard Ethereum JSON-RPC methods plus Flashblocks-specific functionality. You can use the `pending` tag to retrieve the latest Flashblock: + + ```bash + curl https://sepolia-preconf.base.org \ + -X POST \ + -H "Content-Type: application/json" \ + -d '{ + "jsonrpc": "2.0", + "method": "eth_getBlockByNumber", + "params": ["pending", true], + "id": 1 + }' + ``` + + diff --git a/docs/pages/builderkits/agentkit/index.mdx b/_pages/builderkits/agentkit/index.mdx similarity index 100% rename from docs/pages/builderkits/agentkit/index.mdx rename to _pages/builderkits/agentkit/index.mdx diff --git a/_pages/builderkits/minikit/debugging.mdx b/_pages/builderkits/minikit/debugging.mdx new file mode 100644 index 00000000..e6d9eae5 --- /dev/null +++ b/_pages/builderkits/minikit/debugging.mdx @@ -0,0 +1,121 @@ +--- +title: "Common Issues & Debugging" +--- + + +This section outlines frequent issues encountered during the development of Mini Apps and how to resolve them. + +## Previews Not Rendering + +**Issue:** The app embed does not appear when previewed. + +Manifest Embed Example + +**Cause:** This is typically due to an incorrectly formatted or unreachable splashImageUrl in the farcaster.json manifest. + +### Correct Format + +```json +"splashImageUrl": "https://www.example.com/splash_image.png" +``` + +### Common Mistake + +```json +"splashImageUrl": "https://www.example.com//splash_image.png" +``` + +### Best Practices: + +- Ensure the url is correct without typos. Double slashes, like seen above, will break the mini app preview. +- Ensure the image is hosted at a publicly accessible URL. +- Confirm that the image meets the requirements: 200x200 pixels, under 1MB, and in PNG or JPG format. + +### Preview Tool + +To verify your embed, use the Warpcast Frame Developer Tool: + +[Embed Debugging](https://warpcast.com/~/developers/mini-apps/embed) + +## Manifest Debugging (farcaster.json) + +Ensure your domain's manifest at `/.well-known/farcaster.json` is properly configured. + +### Example Manifest + +```json +{ + "accountAssociation": { + "header": "BASE64_HEADER_STRING", + "payload": "BASE64_PAYLOAD_STRING", + "signature": "BASE64_SIGNATURE_STRING" + }, + "frame": { + "version": "next", + "name": "MiniKit", + "iconUrl": "https://example.com/icon.png", + "splashImageUrl": "https://example.com/splash.png", + "splashBackgroundColor": "#000000", + "homeUrl": "https://your-app.com" + } +} +``` + +### Checklist: + +- The domain in the payload must match the domain serving the manifest. +- Ensure all asset URLs (icon, splash) are reachable and correctly formatted. + +## Incorrect FID or Signature Errors + +This is often caused by a farcaster.json file that was signed using the wrong wallet. The signing wallet must match the custody address associated with your Farcaster account. + +**Issue:** You encounter errors related to an invalid FID or failed signature validation. + +**Cause:** The signing wallet does not match the Farcaster custody wallet. + +### Resolution + +To sign with the correct identity, import your Farcaster custody key into an external wallet: + + +To sign with the correct identity, import your Farcaster custody key into an external wallet: + +1. Open the Warpcast mobile app + +2. Navigate to: `Settings → Advanced → Farcaster Recovery Phrase` + +3. Copy the 24-word seed phrase + +4. Import the phrase into a compatible wallet (e.g., Coinbase Wallet Mobile App, MetaMask or Rabby) + +5. Use this wallet for signing the `accountAssociation` payload + + + +### Manifest Signing Utility + +Run the following to initiate the manifest signing workflow: + +```bash + npx create-onchain --manifest +``` + +This CLI will open the signing UI in your browser and update local .env values automatically. + + +This is required for generating valid signed manifests that link your domain to your Farcaster identity. + + + +## Developer Tools + +### Warpcast Frame Debugger + +Preview how your Mini App renders inside Farcaster: + +[Farcaster Debugging](https://warpcast.com/~/developers/frames) diff --git a/_pages/builderkits/minikit/overview.mdx b/_pages/builderkits/minikit/overview.mdx new file mode 100644 index 00000000..efd73d48 --- /dev/null +++ b/_pages/builderkits/minikit/overview.mdx @@ -0,0 +1,320 @@ +--- +title: MiniKit | Getting started +description: Easiest way to build Mini Apps on Base +--- + +# MiniKit + +MiniKit + +MiniKit is easiest way to build Mini Apps on Base, allowing developers to easily build applications without needing to know the details of the SDK implementation. It integrates seamlessly with OnchainKit components and provides Coinbase Wallet-specific hooks. + +## Why MiniKit? + +MiniKit streamlines mini-app development by providing a comprehensive toolkit that makes complex Frames SDK interactions intuitive: + +- **Simplified Development:** Build apps with minimal knowledge of the Frames SDK +- **Coinbase Wallet Integration:** Access Coinbase Wallet-specific hooks +- **Component Compatibility:** Use [OnchainKit](https://onchainkit.xyz/) components out of the box with MiniKit +- **Automatic Setup:** CLI tool for quick project scaffolding with webhooks and notifications +- **Account Association:** Simplified generation of account associations + +## Use Cases + +- Gaming mini apps +- Social mini apps +- Payment mini apps +- And many more possibilities! + +## Quick Start + +The fastest way to get started with MiniKit is to use the CLI to bootstrap a new project: + +```bash +npx create-onchain --mini +``` + +You can also follow our Quick Start guide [here](https://docs.base.org/builderkits/minikit/quickstart) + +This command will: + +1. Set up a new project with both frontend and backend components +2. Configure webhooks and notifications +3. Set up account association generation +4. Create a demo app showcasing onchain abilities using OnchainKit + +After running the command, follow the prompts to configure your project. + + +We recommend using [Vercel](https://vercel.com) to deploy your MiniKit app, as it integrates seamlessly with the upstash/redis backend required for frames, webhooks, and notifications. The CLI will guide you through setting up the necessary environment variables for your Redis database. + + + +## Provider + +The `MiniKitProvider` wraps your application and provides global access to the SDK's context. It handles initialization, events, and automatically applies client safeAreaInsets to ensure your app doesn't overlap parent application elements. + +```tsx +import { MiniKitProvider } from '@coinbase/onchainkit/minikit'; + +function App({ children }) { + return ( + + {children} + + ); +} +``` + +### Props + +The `MiniKitProvider` accepts the following props: + +```tsx +export type MiniKitProviderReact = { + children: React.ReactNode; + notificationProxyUrl?: string; + ...OnchainKitProviderProps +}; +``` + +- `children`: React components to be wrapped by the provider +- `notificationProxyUrl`: Optional URL to override the default `/api/notification` proxy +- All props from `OnchainKitProvider` are also supported + +The provider sets up wagmi and react-query providers automatically. It configures connectors to use the Farcaster connector if `sdk.context` is set, with a fallback to CoinbaseWallet. This allows the same application to run both in frames and as a standalone application. + +## Hooks + +MiniKit provides several utility hooks that wrap the SDK functionality, making it easy to access different features. + +### useMiniKit + +This hook handles initialization of the application and provides access to the SDK context. + +```tsx +const { setFrameReady, isFrameReady, context, updateClientContext, notificationProxyUrl } = useMiniKit(); + +// Call setFrameReady() when your app is ready to be shown +useEffect(() => { + if (!isFrameReady) { + setFrameReady(); + } +}, [isFrameReady, setFrameReady]); +``` + +**Returns:** + +```tsx +{ + ready: () => Promise; // Removes splash screen and shows the application + isReady: boolean; // Whether the app is ready to be shown + context: FrameContext | null; // The current frame context + updateClientContext: (params: UpdateClientContextParams) => void; // Update client context + notificationProxyUrl: string; // The notification proxy URL +} +``` + +### useAddFrame + +This hook adds a frame to the user's list of frames and returns notification details. + +```tsx +const addFrame = useAddFrame(); + +// Usage +const handleAddFrame = async () => { + const result = await addFrame(); + if (result) { + console.log('Frame added:', result.url, result.token); + } +}; +``` + +**Returns:** + +```tsx +() => Promise<{ + url: string; + token: string; +} | null> +``` + +### useNotification + +This hook allows sending notifications to users who have added your frame. It requires a token and URL, which are returned when a user adds your frame. + +```tsx +const sendNotification = useNotification(); + +// Usage +const handleSendNotification = () => { + sendNotification({ + title: 'New High Score!', + body: 'Congratulations on your new high score!' + }); +}; +``` + + +Notifications require a backend proxy to avoid CORS restrictions. The CLI automatically sets up this proxy at `/api/notification`, but you can override this in the `MiniKitProvider`. + + + +### useOpenUrl + +This hook wraps `sdk.actions.openUrl` and falls back to `window.open` when outside a frame context. + +```tsx +const openUrl = useOpenUrl(); + +// Usage + +``` + +### useClose + +This hook wraps the `sdk.actions.close` functionality. + +```tsx +const close = useClose(); + +// Usage + +``` + +### usePrimaryButton + +This hook accepts primary button options and a callback which will be called on click. + +```tsx +usePrimaryButton( + { text: 'Submit Score' }, + () => { + // Handle button click + submitScore(); + } +); +``` + +### useViewProfile + +This hook wraps `sdk.actions.viewProfile`, accepting an FID but falling back to the client's FID. + +```tsx +const viewMyProfile = useViewProfile(); // Uses client's FID +const viewUserProfile = useViewProfile(123456); // Uses specified FID + +// Usage + + +``` + +### useAuthenticate + +This hook allows users to sign in with Farcaster. It wraps the SDK's signIn message, adding a default nonce and verification. + +```tsx +const { signIn } = useAuthenticate(); + +// Usage +const handleSignIn = async () => { + const result = await signIn({ + domain: 'your-domain.com', + siweUri: 'https://your-domain.com/login' + }); + + if (result) { + // Handle successful authentication + console.log('Authenticated:', result); + } +}; +``` + + +Authentication requires additional setup utilizing an auth framework like next/auth or manually integrating session storage and route/component authentication. + + + +## CLI + +The MiniKit CLI is the easiest way to get started. It automatically creates a sample application that integrates different parts of the SDK and some OnchainKit components. + +```bash +npx create-onchain --mini +``` + +### Features + +The CLI creates an application with: + +1. **Frontend and Backend Integration** + + - Complete setup for adding frames, webhooks, and notifications + - Uses upstash/redis for data storage (compatible with Vercel) + - Requires users to sign up for an upstash/redis account and add their key and URL to the .env file + + + The CLI creates both frontend and backend components to support adding frames, webhooks, and notifications. While a frontend-only option was considered, the ability to add frames and handle notifications requires backend support. If you don't need these features, you can easily remove the database and related routes after project creation. + + + +2. **Account Association Generation** + + - Automatically generates valid account associations + - Configures the necessary environment variables + +3. **.well-known/farcaster.json Configuration** + + - Sets up the required configuration file: + + ```json + { + "accountAssociation": { + "header": "eyJmaWQiOjgxODAyNiwidHlwZSI6ImN1c3RvZHkiLCJrZXkiOiIweDU4YjU1MTNjMzk5OTYzMjU0MjMzMmU0ZTJlRDAyOThFQzFmRjE4MzEifQ", + "payload": "eyJkb21haW4iOiI4MGI2LTI2MDAtMWYxOC0yNGM5LTYxMDUtNS0wLTQtNzA2Lm5ncm9rLWZyZWUuYXBwIn0", + "signature": "MHhmOGQ1YzQyMmU3ZTZlMWNhMzU1ZmNmN2ZjYzFmYjMyZWRhZmEyNWU1NjJiMzlhYzE4OWNlMmM5ODU3Y2JjZWViNzlkZTk2ZjhiNTc5NzZjMDM2NzM4Y2UwYjhhOGQxZmMyZDFhYzA2NTdiZTU5N2VhZjFhZDE1ODBmMGQyYjJhODFi" + }, + "frame": { + "version": "next", + "name": "MiniKit", + "iconUrl": "https://onchainkit.xyz/favicon/48x48.png?v4-19-24", + "splashImageUrl": "https://onchainkit.xyz/favicon/48x48.png?v4-19-24", + "splashBackgroundColor": "#000000", + "homeUrl": "https://your-domain.app/minikit" + } + } + ``` + +4. **Notification Proxy** + + - Automatically sets up a proxy route at `/api/notification` + - Used by the `useNotification` hook when sending notifications + +5. **Webhooks** + - Implements webhooks using the Farcaster key registry contract for verification + - Allows applications to respond to events such as `FRAME_ADDED` + +### Demo Application + +The CLI also creates a demo snake game application that showcases: + +- Buttons to add the frame and connect your wallet +- High score tracking with attestations using OnchainKit's `` component +- Score display using OnchainKit's `` components to resolve ENS names +- Notifications for high scores (rate limited to one every 30 seconds) + +## Next Steps + +Now that you have MiniKit set up, you can: + +1. Explore the demo application to understand how the hooks work +2. Customize the application to fit your needs +3. Deploy your application to a hosting provider like Vercel + +Enjoy building! diff --git a/_pages/builderkits/minikit/quickstart.mdx b/_pages/builderkits/minikit/quickstart.mdx new file mode 100644 index 00000000..f032da67 --- /dev/null +++ b/_pages/builderkits/minikit/quickstart.mdx @@ -0,0 +1,371 @@ +--- +title: "MiniKit Quickstart" +--- + +This guide shows you how to get started with MiniKit, the easist way to build mini apps on Base! It can also be used to update an exisitng standalone app to a mini app. We'll start by setting up the template project with the CLI tool and then explore both built-in and additional features of MiniKit. + +## Prerequisites + +Before you begin developing with MiniKit, you'll need: + +1. **Farcaster Account**: Create an account on [Warpcast](https://warpcast.com/) to test and deploy your Mini Apps. + +2. **Coinbase Developer Platform Account** (Optional): Sign up for a [Coinbase Developer Platform](https://www.coinbase.com/en-nl/developer-platform) account if you need CDP API key for additional functionalities. + +## What is a Mini App? + +A mini app is a lightweight web app that runs directly inside [Farcaster Frames](https://docs.farcaster.xyz/developers/frames/v2/), without needing to open a browser or download anything. Built using familiar tools like Next.js and minikit, mini apps behave just like normal apps — but launch instantly from posts, making them feel native to the Farcaster experience. + +## Initial Setup + + + + ```bash + npx create-onchain --mini + ``` + + + You can get a CDP API key by going to the (CDP Portal)[portal.cdp.coinbase.com] and navigating API Keys -> Client API Key. + + + You will be asked if you'd like to set up your manifest. You can skip the manifest setup step as we'll handle that separately once we know our project's URL. + + + ```bash [Terminal] + cd your-project-name + npm install + npm run dev + ``` + + + These docs are LLM-friendly—reference [llms.txt](https://docs.base.org/builderkits/minikit/llms.txt) in your code editor to streamline builds and prompt smarter. + + + + + +## Testing Your Mini App + +To test your Mini App in Warpcast, you'll need a live URL. + +We recommend using [Vercel](https://vercel.com) to deploy your MiniKit app, as it integrates seamlessly with the upstash/redis backend required for stateful frames, webhooks, and notifications. + +Alternatively, you can use ngrok to tunnel your localhost to a live url. + + + + +**Pitfalls** + +To successfully test your app, you'll need the paid version of ngrok. The free veresion has an approval screen which can break the frame manifest. Also the url for the free version will change every time requiring you to update the manifest each time you start a new ngrok tunnel. + + + +1. Start your development server: + +```bash [Terminal] +npm run dev +``` + +2. Install and start ngrok to create a tunnel to your local server: + +```bash [Terminal] +# Install ngrok if you haven't already +npm install -g ngrok + +# Create a tunnel to your local server (assuming it's running on port 3000) +ngrok http 3000 +``` + +3. Copy the HTTPS URL provided by ngrok (e.g. `https://your-tunnel.ngrok.io`) + +4. Visit [Warpcast Frames Developer Tools](https://warpcast.com/~/developers/frames) + +5. In the "Preview Frames" section, paste your ngrok URL to test your mini app. + + + +### Deploying to Vercel + + + + ```sh + npm install -g vercel + ``` + + + ```sh + vercel + ``` + + + You can use `vercel env add` to set these up via CLI: + + - NEXT_PUBLIC_CDP_CLIENT_API_KEY (from [CDP Portal](https://portal.cdp.coinbase.com)) + - NEXT_PUBLIC_URL (deployed app URL) + - NEXT_PUBLIC_IMAGE_URL (optional) + - NEXT_PUBLIC_SPLASH_IMAGE_URL (optional) + - NEXT_PUBLIC_SPLASH_BACKGROUND_COLORs + + + +You can now test your mini app: + +1. Copy your deployed vercel URL +2. Visit [Warpcast Frames Developer Tools](https://warpcast.com/~/developers/frames) on web or mobile +3. Paste URL into "Preview Frames" +4. Tap Launch + +## Exploring Built-in Features + +The template comes with several pre-implemented features. Let's explore where they are and how they work. + +### MiniKitProvider + +The `MiniKitProvider` is set up in your `providers.tsx` file. It wraps your application to handle initialization, events, and automatically applie client safeAreaInsets to ensure your app doesn't overlap parent application elements. + +```tsx [app/providers.tsx] +import { MiniKitProvider } from '@coinbase/onchainkit/minikit'; + +export function Providers(props: { children: ReactNode }) { + return ( + + {props.children} + + ); +} +``` + +The MiniKitProvider also sets up your wagmi and react-query providers automatically, elimintaing that initial setup work. + +### useMiniKit + +The `useMiniKit` hook is implemented in your main page component (`app/page.tsx`). It handles initialization of the frame and provides access to the SDK context. + +```tsx [app/page.tsx] +const { setFrameReady, isFrameReady, context } = useMiniKit(); + +// The setFrameReady() function is called when your mini-app is ready to be shown +useEffect(() => { + if (!isFrameReady) { + setFrameReady(); + } + }, [setFrameReady, isFrameReady]); +``` + +### Creating the Manifest + +The Frame Manifest is required in order for users to save the frame to their account. This means its also required to send notifications to the user. We initially skipped this step when setting up the app. Now that we know our vercel url, we can configure our manifest. + +To set up the manifest, run the following in your Terminal + +```bash [Terminal] +npx create-onchain --manifest +``` + +Enter `y` to proceed with the setup and your browser will open to the following page: + +Manifest Setup + +The wallet that you connect must be your Farcaster custody wallet. You can import this wallet to your prefered wallet using the recovery phrase. You can find your recovery phrase in the Warpcast app under Settings -> Advanced -> Farcster recovery phrase. + +Once connected, add the vercel url and sign the manifest. This will automatically update your .env variables locally, but we'll need to update Vercel's .env variables. + +Create the following new .env variables in your vercel instance and paste the value you see in your local.env file + +- FARCASTER_HEADER +- FARCASTER_PAYLOAD +- FARCASTER_SIGNATURE + +Now that the manifest is correctly set up, the Save Frame button in the template app should work. We'll explore that below. + +### useAddFrame + +The `useAddFrame` hook is used to add your mini app to the user's list of mini apps. It's implemented in your main page component and displays a button in the top right allowing the user to add the mini app to their list. + +When a user adds the mini app, it returns a url and token, which is used for sending the user notifications. For this walkthrough we'll simply console.log those results to use them later when setting up notifications. + +```tsx [app/page.tsx] + +const addFrame = useAddFrame() + +// Usage in a button click handler +const handleAddFrame = async () => { + const result = await addFrame() + if (result) { + console.log('Frame added:', result.url, result.token) + } +} +``` + + +**Not for Production** + +In production, you'll want to save the url and token associated with each user in a persistent database so that you can send them notifications over time. + + + +### useOpenUrl + +The `useOpenUrl` hook is used to open external URLs from within the frame. In the template, its used in the footer button which links to the MiniKit page. + +```tsx [app/page.tsx] +const openUrl = useOpenUrl() + +// Usage in a button click handler + + +// Then in the return function +
+ +
+``` + +Now that we've reviewed the MiniKit teamplate and the functionality already implemented, lets add some additional MiniKit features. + +## Additional MiniKit Features + +Now, let's implement additional hooks provided by the MiniKit library. We'll add these features one by one. + +### `useClose` + +First, let's add the ability to close the frame from within the interface: + +```tsx [app/page.tsx] +// Add useClose to the import list +import { useMinikit, useAddFrame, useOpenUrl, useClose } from '@coinbase/onchainkit/minikit' + +// Add the hook +const close = useClose() + +// Add the button in the header right after the `saveFrameButton` +
+ {saveFrameButton} + +
+``` + +If you reload the frame in the Warpcast dev tools preview, you'll now see the close button in the top right. + +### `usePrimaryButton` + +The Primary Button is a button that always exists at the bottom of the frame. Its good for managing global state which is relevant throughout your mini app. + +For the template example, we'll use the Priamry Button to Pause and Restart the game. The game state is managed within the `snake.tsx` component, and we can easily add the `usePrimaryButton` hook there since the MiniKit hooks are available throughout the app. + +```tsx [/app/components/snake.tsx] +// add an import for usePrimaryButton +import {usePrimaryButton } from '@coinbase/onchainkit/minikit' + +// game state already exists, so we'll leverage that below. +usePrimaryButton( + {text: gameState == GameState.RUNNING ? 'PAUSE GAME' : 'START GAME'}, + () => { + setGameState(gameState == GameState.RUNNING ? GameState.PAUSED : GameState.RUNNING); + } +) +``` + +You'll notice that adding the Primary button takes up space at the bottom of the frame, which causes the "BUILT ON BASE WITH MINIKIT" button to move upwards and overlap with the contorls. +We can quickly fix that by changing the text to "BUILT WITH MINIKIT" and removing the `ml-4` style in the `className` of the ` +)} +``` + + +Notice that we first check if the user has added the frame to their list of mini apps before displaying the button. This is using the `context` object provided by `useMiniKit()`. If you don't see the button to send the notification, its likely because mini app hasn't been saved. + + + +## Conclusion + +Congratulations, you've created your first mini app, set up the manifest, added key MiniKit hooks, and sent your users a notification! We're excited to see what you build with MiniKit! diff --git a/_pages/builderkits/minikit/thinking-social.mdx b/_pages/builderkits/minikit/thinking-social.mdx new file mode 100644 index 00000000..4ca6f4d7 --- /dev/null +++ b/_pages/builderkits/minikit/thinking-social.mdx @@ -0,0 +1,189 @@ +--- +title: "Thinking Social" +--- + + +**Designing mini apps that people actually come back to.** + +Most apps can launch. But few become part of someone’s daily rhythm. +That’s usually not a product problem. It’s a people problem. + +Social mini apps live or die based on how they make people feel: seen, connected, curious or like they belong. That’s not something you tack on — it’s something you build in from the start. + +If you’re designing for feed-based platforms (like Warpcast, Threads, or anything with posts, reactions, and reply chains), this guide will help you: + +- Challenge your idea early +- Apply the right social patterns (if it makes sense) +- Build for behaviors, not just features + +## How to Use This Guide + +Welcome to your blueprint for designing social mini‑apps that people love to revisit. This guide is organized into distinct, actionable sections—each building on the last—to help you move from idea validation to deploying social features with purpose. + +1. **Pressure‑Test Your Idea** + Before writing a single line of code or sketching UI, use our four diagnostic questions to see if your concept naturally supports social behavior. Drop your one‑line idea into the supplied prompt to get clear insights on post frequency, social lift, content momentum, and emotional payoff. + +2. **Interpret Feedback & Choose Dimensions** + Analyze the responses. Identify which one or two social dimensions resonate most with your concept—whether it’s habit formation, community spark, content growth, or emotional reward. The guide shows you how to validate and prioritize those dimensions before moving forward. + +3. **Apply a Case Study Flow** + See a worked example that demonstrates how to translate test results into a prototype feature. This mini case study will illustrate rapid iteration, metric considerations, and how to decide when you’re ready to scale social elements. + +4. **Explore Three Core Patterns** + Dive into the heart of the guide—three social patterns designed to deepen engagement: + + - **Identity Playgrounds:** Customization and self‑expression + - **Co‑Creation Loops:** Collaboration and building on each other’s posts + - **Long‑Term Rituals:** Scheduled, shared activities that foster habit and community + + Each pattern includes explanations, real‑world examples, and copy‑and‑paste prompts to spark your own brainstorming. + +5. **Next Steps & Reflection** + Finish with a set of reflective questions and practical advice on measuring success. Use the closing prompts to refine your roadmap, plan experiments, and define key metrics for daily, weekly, and monthly engagement. + +**Tips for Getting the Most Out of This Guide:** + +- **Iterate Quickly:** Treat prompts and patterns as hypotheses. Prototype fast, gather data, and refine. +- **Stay Human‑Centered:** At every stage, ask: “How will this make someone feel?” +- **Measure What Matters:** Define metrics for each dimension early—then use them to validate your choices. +- **Keep It Simple:** You don’t need every pattern at once. Start with the one or two dimensions that align strongest with your concept. + +## Pressure-test your idea + +Before you get into features or UI, take a step back. Ask whether your idea wants to be social — or if you’re forcing it. These prompts are designed to give you structured, clear feedback if you drop them into a LLM or use them in your own reflection. + +**Prompt:** + +``` +Here’s a one-line description of my app: [insert idea]. + +Evaluate it across these questions: + +1. Why would someone post here more than once? +2. Would the experience be better with another person involved? +3. What kind of content might naturally fill the feed over time? +4. What emotional reward might someone feel when they open it? + +Please be direct. If the idea lacks natural social behavior, suggest ways it could evolve. + +``` + +### 1. Identity Playgrounds + +**The idea:** Give people ways to explore, express, or shape their identity within the app. + +**Why it works:** People don’t just use feeds to consume — they use them to perform. Customization invites play, self-expression, and experimentation. + +**Where it shows up:** Discord roles, Reddit flair, Tumblr themes. + +**Use it for:** Differentiation, emotional investment, repeat posting. + +**Prompt:** + +``` +Given my app idea: [insert idea], explore 2 ways users might express or explore identity. + +For each, include: +– What the user customizes or signals +– How that shows up in the feed +– Why that might matter over time +``` + +### 2. Co-Creation Loops + +**The idea:** Design behaviors that are better when shared — where users build on each other’s contributions. + +**Why it works:** The strongest feeds don’t just display content; they build momentum. If one person’s post sparks another, you get a chain reaction. + +**Where it shows up:** Remix threads, collab playlists, group journaling. + +**Use it for:** Participation loops, content momentum, chain reactions. + +**Prompt:** + +``` +How could users in [insert app idea] create something together or build on each other’s actions? +Return 3 co-creation flows that include: +– What kicks it off +– How others join in +– What the feed looks like after a few days + +``` + +### 3. Long-Term Rituals + +**The idea:** Introduce regular, shared behaviors that become a rhythm. + +**Why it works:** Rituals create predictability, belonging, and anticipation. They give users a reason to come back on a schedule. + +**Where it shows up:** Wordle scores, Monday memes, Friday drops, yearly Spotify Wrapped. + +**Use it for:** Habit loops, appointment-based engagement, social cohesion. + +**Prompt:** + +``` +Design 2 recurring rituals for [insert app idea]. + +For each, include: +– Frequency (daily, weekly, monthly) +– What users post +– What emotion or payoff they get +– How it could spread through the feed + +``` + +## Interpreting your feedback + +After you get back raw answers to the four pressure‑test questions, look for the one or two dimensions that most naturally fit your idea. Nail those first, then decide if you need to shore up any others. + +Spot your top dimensions +— Scan responses for signs of strength in: +• Repeat‑posting potential (“Daily check‑ins create habit.”) +• Social lift (“Comments spark friendly competition.”) +• Content momentum (“Automated reminders nudge new posts.”) +• Emotional payoff (“Badges tap into achievement.”) + +Validate your winners +For each chosen dimension, confirm the feedback includes a clear “good” example: + +Repeat‑posting: ≥1 post/week feels natural + +Social lift: involves others in a meaningful way + +Content momentum: community‑driven growth + +Emotional payoff: opening the app delivers a felt reward + +Sample snippet for “Emotional payoff”: + +“Users feel proud sharing progress, and peers cheer them on.” + +Decide your next move + +If your top 1–2 dimensions check out, skip straight to building social features around them—no need to perfect all four. + +If they’re weak, iterate on that dimension (e.g. add a relational hook or a habit prompt) before moving on. + +Example flow + +You see strong “Social lift” (“Friends’ reactions spark threads”) and decent “Emotional payoff” (“Likes feel rewarding”). + +You decide that’s enough social DNA to prototype a co‑posting feature—leaving “Content momentum” and “Repeat‑posting” for later. + +This way, you focus your energy on the social angles that truly resonate with your concept. Once those feel solid, you can explore the other patterns in Identity Playgrounds, Co‑Creation Loops, and Long‑Term Rituals. + +## Closing note + +The mini apps that thrive aren’t the most complex — they’re the ones that understand how people connect. + +**Remember:** + +- Social features only work when they reflect real human behavior +- A feed isn’t just content — it’s a shared ritual +- True engagement comes from meaning over mechanics + +As you build, ask: _Why would someone want to come back? Why would they share this with a friend?_ Those answers matter more than any feature list. + +The best apps don’t just fill feeds. They create places people want to return to. +So — what will your app make people feel? diff --git a/_pages/builderkits/onchainkit/api/build-deposit-to-morpho-tx.mdx b/_pages/builderkits/onchainkit/api/build-deposit-to-morpho-tx.mdx new file mode 100644 index 00000000..c76d4db6 --- /dev/null +++ b/_pages/builderkits/onchainkit/api/build-deposit-to-morpho-tx.mdx @@ -0,0 +1,27 @@ +--- +title: "`buildDepositToMorphoTx`" +--- + + +The `buildDepositToMorphoTx` function is used to build [Calls](/builderkits/onchainkit/transaction/types#calls) for depositing an asset to Morpho. These calls can be passed the `` component to send a transaction. + +## Usage + +```tsx twoslash [code] +import { buildDepositToMorphoTx } from '@coinbase/onchainkit/earn'; + +const calls = await buildDepositToMorphoTx({ + vaultAddress: '0x...', // Morpho vault address on Base + tokenAddress: '0x...', // Address of the token to deposit + amount: 1000000000000000000n, // Amount of tokens to deposit + recipientAddress: '0x...', // Address of the recipient +}); +``` + +## Returns + +[`Call[]`](/builderkits/onchainkit/transaction/types#calls) + +## Parameters + +[`DepositToMorphoParams`](/builderkits/onchainkit/earn/types#deposittomorphoparams) diff --git a/_pages/builderkits/onchainkit/api/build-mint-transaction.mdx b/_pages/builderkits/onchainkit/api/build-mint-transaction.mdx new file mode 100644 index 00000000..c4da29d8 --- /dev/null +++ b/_pages/builderkits/onchainkit/api/build-mint-transaction.mdx @@ -0,0 +1,49 @@ +--- +title: "`buildMintTransaction`" +--- + + +The `buildMintTransaction` function is used to get an unsigned transaction for minting an NFT. + +Before using them, make sure to obtain a [Client API Key](https://portal.cdp.coinbase.com/projects/api-keys/client-key) from Coinbase Developer Platform. + +## Usage + + +```tsx twoslash [code] +import { setOnchainKitConfig } from '@coinbase/onchainkit'; +import { buildMintTransaction } from '@coinbase/onchainkit/api'; + +const response = await buildMintTransaction({ + mintAddress: '0x...', + takerAddress: '0x...', + tokenId: '1', + quantity: 1, + network: 'networks/base-mainnet', +}); +``` + +```json [return value] +{ + "call_data": { + "from": "0x...", + "to": "0x...", + "data": "0x...", + "value": "0x000000000001" + } +} +``` + + +## Returns + +[`Promise`](/builderkits/onchainkit/api/types#buildminttransactionresponse) + +## Parameters + +[`BuildMintTransactionParams`](/builderkits/onchainkit/api/types#buildminttransactionparams) + +## Types + +- [`BuildMintTransactionResponse`](/builderkits/onchainkit/api/types#buildminttransactionresponse) +- [`BuildMintTransactionParams`](/builderkits/onchainkit/api/types#buildminttransactionparams) diff --git a/_pages/builderkits/onchainkit/api/build-swap-transaction.mdx b/_pages/builderkits/onchainkit/api/build-swap-transaction.mdx new file mode 100644 index 00000000..9d1a60ba --- /dev/null +++ b/_pages/builderkits/onchainkit/api/build-swap-transaction.mdx @@ -0,0 +1,130 @@ +--- +title: "`buildSwapTransaction`" +--- + + +The `buildSwapTransaction` function is used to get an unsigned transaction for a swap between two Tokens. + +Before using this function, make sure to obtain a [Client API Key](https://portal.cdp.coinbase.com/projects/api-keys/client-key) from Coinbase Developer Platform. + +## Usage + + +```tsx twoslash [code] +import { setOnchainKitConfig } from '@coinbase/onchainkit'; +import { buildSwapTransaction } from '@coinbase/onchainkit/api'; +import type { Token } from '@coinbase/onchainkit/token'; + +setOnchainKitConfig({ apiKey: 'YOUR_API_KEY' }); + +const fromToken: Token = { + name: 'ETH', + address: '', + symbol: 'ETH', + decimals: 18, + image: 'https://wallet-api-production.s3.amazonaws.com/uploads/tokens/eth_288.png', + chainId: 8453, +}; + +const toToken: Token = { + name: 'USDC', + address: '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913', + symbol: 'USDC', + decimals: 6, + image: + 'https://d3r81g40ycuhqg.cloudfront.net/wallet/wais/44/2b/442b80bd16af0c0d9b22e03a16753823fe826e5bfd457292b55fa0ba8c1ba213-ZWUzYjJmZGUtMDYxNy00NDcyLTg0NjQtMWI4OGEwYjBiODE2', + chainId: 8453, +}; + +const response = await buildSwapTransaction({ + fromAddress: '0x...', + from: fromToken, + to: toToken, + amount: '0.1', + useAggregator: false, +}); +``` + +```json [return value] +{ + "approveTransaction": { + "chainId": 8453, + "data": "", + "gas": 0, + "to": "", + "value": 0 + }, + "fee": { + "baseAsset": { + "name": "USDC", + "address": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913", + "currencyCode": "USDC", + "decimals": 6, + "imageURL": "https://d3r81g40ycuhqg.cloudfront.net/wallet/wais/44/2b/442b80bd16af0c0d9b22e03a16753823fe826e5bfd457292b55fa0ba8c1ba213-ZWUzYjJmZGUtMDYxNy00NDcyLTg0NjQtMWI4OGEwYjBiODE2", + "blockchain": "eth", + "aggregators": [Array], + "swappable": true, + "unverified": false, + "chainId": 8453 + }, + "percentage": "1", + "amount": "3517825" + }, + "quote": { + "from": { + "address": "", + "chainId": 8453, + "decimals": 18, + "image": "https://wallet-api-production.s3.amazonaws.com/uploads/tokens/eth_288.png", + "name": "ETH", + "symbol": "ETH" + }, + "to": { + "address": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913", + "chainId": 8453, + "decimals": 6, + "image": "https://d3r81g40ycuhqg.cloudfront.net/wallet/wais/44/2b/442b80bd16af0c0d9b22e03a16753823fe826e5bfd457292b55fa0ba8c1ba213-ZWUzYjJmZGUtMDYxNy00NDcyLTg0NjQtMWI4OGEwYjBiODE2", + "name": "USDC", + "symbol": "USDC" + }, + "fromAmount": "100000000000000000", + "toAmount": "348264739", + "amountReference": "from", + "priceImpact": "", + "chainId": 8453, + "highPriceImpact": false, + "slippage": "3", + "warning": { + "type": "warning", + "message": "This transaction has a very high likelihood of failing if submitted", + "description": "failed with 500000000 gas: insufficient funds for gas * price + value: address 0x4ed4E862860beD51a9570b96d89aF5E1B0Efefed have 0 want 100000000000000000" + } + }, + "transaction": { + "chainId": 8453, + "data": "0x...", + "gas": 419661, + "to": "0xdef1c0ded9bec7f1a1670819833240f027b25eff", + "value": 100000000000000000 + }, + "warning": { + "type": "warning", + "message": "This transaction has a very high likelihood of failing if submitted", + "description": "failed with 500000000 gas: insufficient funds for gas * price + value: address 0x4ed4E862860beD51a9570b96d89aF5E1B0Efefed have 0 want 100000000000000000" + } +} +``` + + +## Returns + +[`Promise`](/builderkits/onchainkit/api/types#buildswaptransactionresponse) + +## Parameters + +[`BuildSwapTransactionParams`](/builderkits/onchainkit/api/types#buildswaptransactionparams) + +## Types + +- [`BuildSwapTransactionResponse`](/builderkits/onchainkit/api/types#buildswaptransactionresponse) +- [`BuildSwapTransactionParams`](/builderkits/onchainkit/api/types#buildswaptransactionparams) diff --git a/_pages/builderkits/onchainkit/api/build-withdraw-from-morpho-tx.mdx b/_pages/builderkits/onchainkit/api/build-withdraw-from-morpho-tx.mdx new file mode 100644 index 00000000..bbd245a4 --- /dev/null +++ b/_pages/builderkits/onchainkit/api/build-withdraw-from-morpho-tx.mdx @@ -0,0 +1,27 @@ +--- +title: "`buildWithdrawFromMorphoTx`" +--- + + +The `buildWithdrawFromMorphoTx` function is used to build [Calls](/builderkits/onchainkit/transaction/types#calls) for withdrawing an asset from Morpho. These calls can be passed the `` component to send a transaction. + +## Usage + +```tsx twoslash [code] +import { buildWithdrawFromMorphoTx } from '@coinbase/onchainkit/earn'; + +const calls = await buildWithdrawFromMorphoTx({ + vaultAddress: '0x...', // Morpho vault address on Base + amount: 1000000000000000000n, // Amount of tokens to withdraw + recipientAddress: '0x...', // Address of the recipient +}); +``` + + +## Returns + +[`Call[]`](/builderkits/onchainkit/transaction/types#calls) + +## Parameters + +[`WithdrawFromMorphoParams`](/builderkits/onchainkit/earn/types#withdrawfrommorphoparams) diff --git a/_pages/builderkits/onchainkit/api/get-mint-details.mdx b/_pages/builderkits/onchainkit/api/get-mint-details.mdx new file mode 100644 index 00000000..4c690d0d --- /dev/null +++ b/_pages/builderkits/onchainkit/api/get-mint-details.mdx @@ -0,0 +1,63 @@ +--- +title: "`getMintDetails`" +--- + + +The `getMintDetails` function returns data required to view an NFT to be minted + +Before using them, make sure to obtain a [Client API Key](https://portal.cdp.coinbase.com/projects/api-keys/client-key) from Coinbase Developer Platform. + +## Usage + + +```tsx twoslash [code] +import { setOnchainKitConfig } from '@coinbase/onchainkit'; +import { getMintDetails } from '@coinbase/onchainkit/api'; + +const response = await getMintDetails({ + contractAddress: '0x...', + takerAddress: '0x...', + tokenId: '1', +}); +``` + +```json [return value] +{ + "name": "NFT Name", + "description": "NFT description", + "imageUrl": "https://example.com/image.png", + "animationUrl": "", + "mimeType": "image/png", + "contractType": "ERC721", + "price": { + "amount": "0.0001", + "currency": "ETH", + "amountUSD": "0.242271" + }, + "mintFee": { + "amount": "0", + "currency": "ETH", + "amountUSD": "0" + }, + "maxMintsPerWallet": 100, + "isEligibleToMint": true, + "creatorAddress": "0x...", + "network": "", + "totalTokens": "300", + "totalOwners": "200" +} +``` + + +## Returns + +[`Promise`](/builderkits/onchainkit/api/types#getmintdetailsresponse) + +## Parameters + +[`GetMintDetailsParams`](/builderkits/onchainkit/api/types#getmintdetailsparams) + +## Types + +- [`GetMintDetailsResponse`](/builderkits/onchainkit/api/types#getmintdetailsresponse) +- [`GetMintDetailsParams`](/builderkits/onchainkit/api/types#getmintdetailsparams) diff --git a/_pages/builderkits/onchainkit/api/get-portfolios.mdx b/_pages/builderkits/onchainkit/api/get-portfolios.mdx new file mode 100644 index 00000000..fcc6bec4 --- /dev/null +++ b/_pages/builderkits/onchainkit/api/get-portfolios.mdx @@ -0,0 +1,61 @@ +--- +title: "`getPortfolios`" +--- + + +The `getPortfolios` function returns an object containing an array of +portfolios for the provided addresses. Each portfolio is an object with the address +of the wallet, the fiat value of the portfolio, and an array of tokens held by the +provided address. + + +Before using this endpoint, make sure to obtain a [Client API Key](https://portal.cdp.coinbase.com/projects/api-keys/client-key) +from Coinbase Developer Platform. + + + + +Please note: `getPortfolios` is only available for Base mainnet and Ethereum mainnet. +You can control the network in the `OnchainKitProvider` by setting the `chain` prop. + + + +## Usage + + +```tsx twoslash [code] +import { setOnchainKitConfig } from '@coinbase/onchainkit'; +import { getPortfolios } from '@coinbase/onchainkit/api'; + +const response = await getPortfolios({ + addresses: ['0x...'], +}); +``` + +```json [return value] + "portfolios": [ + { + "address": "0x...", + "portfolioBalanceInUsd": 100, + "tokenBalances": [{ + "address": "0x...", + "chainId": 1, + "decimals": 18, + "image": "https://example.com/image.png", + "name": "Token Name", + "symbol": "TKN", + "cryptoBalance": 10, + "fiatBalance": 100 + }] + } + ] +``` + + +## Returns + +[`Promise`](/builderkits/onchainkit/api/types#getportfoliosresponse) + +## Parameters + +[`GetPortfoliosParams`](/builderkits/onchainkit/api/types#getportfoliosparams) diff --git a/_pages/builderkits/onchainkit/api/get-swap-quote.mdx b/_pages/builderkits/onchainkit/api/get-swap-quote.mdx new file mode 100644 index 00000000..5434d955 --- /dev/null +++ b/_pages/builderkits/onchainkit/api/get-swap-quote.mdx @@ -0,0 +1,91 @@ +--- +title: "`getSwapQuote`" +--- + + +The `getSwapQuote` function is used to get a quote for a swap between two Tokens. + +Before using them, make sure to obtain a [Client API Key](https://portal.cdp.coinbase.com/projects/api-keys/client-key) from Coinbase Developer Platform. + +## Usage + + +```tsx twoslash [code] +import { setOnchainKitConfig } from '@coinbase/onchainkit'; +import { getSwapQuote } from '@coinbase/onchainkit/api'; +import type { Token } from '@coinbase/onchainkit/token'; + +setOnchainKitConfig({ apiKey: 'YOUR_API_KEY' }); + +const fromToken: Token = { + name: 'ETH', + address: '', + symbol: 'ETH', + decimals: 18, + image: 'https://wallet-api-production.s3.amazonaws.com/uploads/tokens/eth_288.png', + chainId: 8453, +}; + +const toToken: Token = { + name: 'USDC', + address: '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913', + symbol: 'USDC', + decimals: 6, + image: + 'https://d3r81g40ycuhqg.cloudfront.net/wallet/wais/44/2b/442b80bd16af0c0d9b22e03a16753823fe826e5bfd457292b55fa0ba8c1ba213-ZWUzYjJmZGUtMDYxNy00NDcyLTg0NjQtMWI4OGEwYjBiODE2', + chainId: 8453, +}; + +const quote = await getSwapQuote({ + from: fromToken, + to: toToken, + amount: '0.001', + useAggregator: false, +}); +``` + +```json [return value] +{ + "amountReference": "from", + "chainId": 8453, + "from": { + "address": "", + "chainId": 8453, + "decimals": 18, + "image": "https://wallet-api-production.s3.amazonaws.com/uploads/tokens/eth_288.png", + "name": "ETH", + "symbol": "ETH" + }, + "to": { + "address": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913", + "chainId": 8453, + "decimals": 6, + "image": "https://d3r81g40ycuhqg.cloudfront.net/wallet/wais/…-ZWUzYjJmZGUtMDYxNy00NDcyLTg0NjQtMWI4OGEwYjBiODE2", + "name": "USDC", + "symbol": "USDC" + }, + "fromAmount": "1000000000000000", + "fromAmountUSD": "2.6519265340000002", + "toAmount": "2650405", + "toAmountUSD": "2.64980125", + "amountReference": "from", + "priceImpact": "0", + "chainId": 8453, + "highPriceImpact": false, + "slippage": "3" +} +``` + + +## Returns + +[`Promise`](/builderkits/onchainkit/api/types#getswapquoteresponse) + +## Parameters + +[`GetSwapQuoteParams`](/builderkits/onchainkit/api/types#getswapquoteparams) + +## Types + +- [`GetSwapQuoteResponse`](/builderkits/onchainkit/api/types#getswapquoteresponse) +- [`GetSwapQuoteParams`](/builderkits/onchainkit/api/types#getswapquoteparams) diff --git a/_pages/builderkits/onchainkit/api/get-token-details.mdx b/_pages/builderkits/onchainkit/api/get-token-details.mdx new file mode 100644 index 00000000..7f1f943b --- /dev/null +++ b/_pages/builderkits/onchainkit/api/get-token-details.mdx @@ -0,0 +1,52 @@ +--- +title: "`getTokenDetails`" +--- + + +The `getTokenDetails` function returns data required to view an NFT + +Before using them, make sure to obtain a [Client API Key](https://portal.cdp.coinbase.com/projects/api-keys/client-key) from Coinbase Developer Platform. + +## Usage + + +```tsx twoslash [code] +import { setOnchainKitConfig } from '@coinbase/onchainkit'; +import { getTokenDetails } from '@coinbase/onchainkit/api'; + +const response = await getTokenDetails({ + contractAddress: '0x...', + tokenId: '1', +}); +``` + +```json [return value] + "collectionName": "NFT Collection Name", + "collectionDescription": "NFT Collection Description", + "name": "NFT Name", + "description": "NFT Description", + "imageUrl": "https://example.com/image.png", + "animationUrl": "", + "ownerAddress": "0x...", + "lastSoldPrice": { + "amount": "0.0001", + "currency": "ETH", + "amountUSD": "0.242271" + }, + "mimeType": "image/png", + "contractType": "ERC721" +``` + + +## Returns + +[`Promise`](/builderkits/onchainkit/api/types#gettokendetailsresponse) + +## Parameters + +[`GetTokenDetailsParams`](/builderkits/onchainkit/api/types#gettokendetailsparams) + +## Types + +- [`GetTokenDetailsResponse`](/builderkits/onchainkit/api/types#gettokendetailsresponse) +- [`GetTokenDetailsParams`](/builderkits/onchainkit/api/types#gettokendetailsparams) diff --git a/_pages/builderkits/onchainkit/api/get-tokens.mdx b/_pages/builderkits/onchainkit/api/get-tokens.mdx new file mode 100644 index 00000000..836c4447 --- /dev/null +++ b/_pages/builderkits/onchainkit/api/get-tokens.mdx @@ -0,0 +1,107 @@ +--- +title: "`getTokens`" +--- + + +The `getTokens` function retrieves a list of tokens on Base by searching for the name, symbol, or address of a token. + +Before using them, make sure to obtain a [Client API Key](https://portal.cdp.coinbase.com/projects/api-keys/client-key) from Coinbase Developer Platform. + +## Usage + +Search by symbol + + +```tsx twoslash [code] +import { setOnchainKitConfig } from '@coinbase/onchainkit'; +import { getTokens } from '@coinbase/onchainkit/api'; // [!code focus] + +setOnchainKitConfig({ apiKey: 'YOUR_API_KEY' }); + +const tokens = await getTokens({ limit: '1', search: 'degen' }); // [!code focus] +``` + +```ts [return value] +[ + { + address: '0x4ed4e862860bed51a9570b96d89af5e1b0efefed', + chainId: 8453, + decimals: 18, + image: + 'https://d3r81g40ycuhqg.cloudfront.net/wallet/wais/3b/bf/3bbf118b5e6dc2f9e7fc607a6e7526647b4ba8f0bea87125f971446d57b296d2-MDNmNjY0MmEtNGFiZi00N2I0LWIwMTItMDUyMzg2ZDZhMWNm', + name: 'DEGEN', + symbol: 'DEGEN', + }, +]; +``` + + +Search by name + + +```tsx twoslash [code] +import { setOnchainKitConfig } from '@coinbase/onchainkit'; +import { getTokens } from '@coinbase/onchainkit/api'; // [!code focus] + +setOnchainKitConfig({ apiKey: 'YOUR_API_KEY' }); + +const tokens = await getTokens({ limit: '1', search: 'Wrapped Ether' }); // [!code focus] +``` + +```ts [return value] +[ + { + address: '0x4200000000000000000000000000000000000006', + chainId: 8453, + decimals: 18, + image: + 'https://d3r81g40ycuhqg.cloudfront.net/wallet/wais/47/bc/47bc3593c2dec7c846b66b7ba5f6fa6bd69ec34f8ebb931f2a43072e5aaac7a8-YmUwNmRjZDUtMjczYy00NDFiLWJhZDUtMzgwNjFmYWM0Njkx', + name: 'Wrapped Ether', + symbol: 'WETH', + }, +]; +``` + + +Search by address + + +```tsx twoslash [code] +import { setOnchainKitConfig } from '@coinbase/onchainkit'; +import { getTokens } from '@coinbase/onchainkit/api'; // [!code focus] + +setOnchainKitConfig({ apiKey: 'YOUR_API_KEY' }); + +const tokens = await getTokens({ + limit: '1', + search: '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913', +}); // [!code focus] +``` + +```ts [return value] +[ + { + address: '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913', + chainId: 8453, + decimals: 6, + image: + 'https://d3r81g40ycuhqg.cloudfront.net/wallet/wais/44/2b/442b80bd16af0c0d9b22e03a16753823fe826e5bfd457292b55fa0ba8c1ba213-ZWUzYjJmZGUtMDYxNy00NDcyLTg0NjQtMWI4OGEwYjBiODE2', + name: 'USDC', + symbol: 'USDC', + }, +]; +``` + + +## Returns + +[`Promise`](/builderkits/onchainkit/api/types#gettokensresponse) + +## Parameters + +[`GetTokensOptions`](/builderkits/onchainkit/api/types#gettokensoptions) + +## Types + +- [`GetTokensResponse`](/builderkits/onchainkit/api/types#gettokensresponse) +- [`GetTokensOptions`](/builderkits/onchainkit/api/types#gettokensoptions) diff --git a/docs/pages/builderkits/onchainkit/api/types.mdx b/_pages/builderkits/onchainkit/api/types.mdx similarity index 100% rename from docs/pages/builderkits/onchainkit/api/types.mdx rename to _pages/builderkits/onchainkit/api/types.mdx diff --git a/_pages/builderkits/onchainkit/appchain/bridge.mdx b/_pages/builderkits/onchainkit/appchain/bridge.mdx new file mode 100644 index 00000000..6aca34f3 --- /dev/null +++ b/_pages/builderkits/onchainkit/appchain/bridge.mdx @@ -0,0 +1,388 @@ +--- +title: · OnchainKit +description: Bridge to appchains with OnchainKit +--- + +import { Danger } from "/snippets/danger.mdx"; + +# `` + + +**⚠️ NOTE** + +The `AppchainBridge` component is alpha release software and is provided AS-IS. Use at your own risk. + + + +The `AppchainBridge` component provides a simple interface for implementing bridging to appchains with OnchainKit. + +## Prerequisites + +Before using the `AppchainBridge` component, ensure you've completed the [Getting Started](/builderkits/onchainkit/getting-started) steps. + +### Starting a new project + +If you're starting a new project, we recommend using `create onchain` to scaffold your project. + +```bash +npm create onchain@latest +``` + +### Adding to an existing project + +If you're adding `AppchainBridge` to an existing project, simply install OnchainKit. + + +```bash [npm] +npm install @coinbase/onchainkit +``` + +```bash [yarn] +yarn add @coinbase/onchainkit +``` + +```bash [pnpm] +pnpm add @coinbase/onchainkit +``` + +```bash [bun] +bun add @coinbase/onchainkit +``` + + +Wrap the `` around your app, following the steps in [Getting Started](/builderkits/onchainkit/installation/nextjs#add-providers). + +## Quickstart + +To use `AppchainBridge`, you'll need to create a custom chain for your network using Viem's [defineChain](https://viem.sh/docs/chains/introduction#custom-chains). + +You can retrieve the chain ID and your RPC URL from your appchain's dashboard in Coinbase Developer Platform. + +Once successfully created, add the custom chain to your Wagmi configuration, and provide it as a child component to `OnchainKitProvider`. + + +```tsx twoslash [chain.ts] +// @noErrors: 2554 +import { defineChain } from 'viem'; + +export const EXAMPLE_CHAIN = defineChain({ + id: 8453200000, // [!code ++] + name: 'Your Appchain Network', + nativeCurrency: { + name: 'Ethereum', + symbol: 'ETH', + decimals: 18, + }, + rpcUrls: { + default: { + http: ['https://your-rpc.appchain.base.org'], // [!code ++] + }, + }, +}); +``` + +```tsx twoslash [providers.tsx] +// @noErrors: 2554 +import { defineChain } from 'viem'; + +const EXAMPLE_CHAIN = defineChain({ + id: 8453200000, + name: 'Your Appchain Network', + nativeCurrency: { + name: 'Ethereum', + symbol: 'ETH', + decimals: 18, + }, + rpcUrls: { + default: { + http: ['https://your-rpc.appchain.base.org'], + }, + }, +}); +// ---cut-before--- +'use client'; + +import { baseSepolia } from 'wagmi/chains'; +import { OnchainKitProvider } from '@coinbase/onchainkit'; +import type { ReactNode } from 'react'; +import { createConfig, http, WagmiProvider } from 'wagmi'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; + +const wagmiConfig = createConfig({ + chains: [baseSepolia, EXAMPLE_CHAIN], // [!code ++] + transports: { + [baseSepolia.id]: http(), + [EXAMPLE_CHAIN.id]: http(), // [!code ++] + } +}); + +const queryClient = new QueryClient(); + +export function Providers(props: { children: ReactNode }) { + return ( + + + + {props.children} + + + + ); +} +``` + + +Use the custom chain to create an `Appchain` object. You can also render an icon in the UI using the `icon` prop. + +```tsx twoslash +// @noErrors: 2554 +import { defineChain } from 'viem'; +const EXAMPLE_CHAIN = defineChain({ + id: 8453200000, // [!code ++] + name: 'Your Appchain Network', + nativeCurrency: { + name: 'Ethereum', + symbol: 'ETH', + decimals: 18, + }, + rpcUrls: { + default: { + http: ['https://your-rpc.appchain.base.org'], // [!code ++] + }, + }, +}); +// ---cut-before--- +import type { Appchain } from '@coinbase/onchainkit/appchain'; + +const EXAMPLE_APPCHAIN: Appchain = { + chain: EXAMPLE_CHAIN, + icon: Your Appchain Network, +}; +``` + +Now, you can render the `AppchainBridge` component with the `chain` and `appchain` props. + +```tsx twoslash +// @noErrors: 2554 +import { defineChain } from 'viem'; +const EXAMPLE_CHAIN = defineChain({ + id: 8453200000, // [!code ++] + name: 'Your Appchain Network', + nativeCurrency: { + name: 'Ethereum', + symbol: 'ETH', + decimals: 18, + }, + rpcUrls: { + default: { + http: ['https://your-rpc.appchain.base.org'], // [!code ++] + }, + }, +}); +import type { Appchain } from '@coinbase/onchainkit/appchain'; + +const EXAMPLE_APPCHAIN: Appchain = { + chain: EXAMPLE_CHAIN, + icon: Your Appchain Network, +}; +// ---cut-before--- +import { AppchainBridge } from '@coinbase/onchainkit/appchain'; +import { baseSepolia } from 'viem/chains'; + + +``` + +## Custom bridgeable tokens + +By default, the bridgeable token is only native ETH. You can customize the bridgeable tokens by providing a `bridgeableTokens` prop to the `AppchainBridge` component. + +Let's add a custom "Appchain Token" to the bridgeable tokens array. + +```tsx twoslash +// @noErrors: 2554 +import { defineChain } from 'viem'; +const EXAMPLE_CHAIN = defineChain({ + id: 8453200000, // [!code ++] + name: 'Your Appchain Network', + nativeCurrency: { + name: 'Ethereum', + symbol: 'ETH', + decimals: 18, + }, + rpcUrls: { + default: { + http: ['https://your-rpc.appchain.base.org'], // [!code ++] + }, + }, +}); +import type { Appchain } from '@coinbase/onchainkit/appchain'; + +const EXAMPLE_APPCHAIN: Appchain = { + chain: EXAMPLE_CHAIN, + icon: Your Appchain Network, +}; +// ---cut-before--- +import type { BridgeableToken } from '@coinbase/onchainkit/appchain'; + +const customBridgeableTokens: BridgeableToken[] = [ + { + name: 'ETH', + address: '', + symbol: 'ETH', + decimals: 18, + image: + 'https://wallet-api-production.s3.amazonaws.com/uploads/tokens/eth_288.png', + chainId: 8453200000, + }, + { + address: '0x...', + remoteToken: '0x...', + name: 'Appchain Token', + symbol: 'ATKN', + decimals: 18, + chainId: 8453200000, + image: 'https://some-icon.com/icon.png', + }, +]; +``` + + +**⚠️ What is remoteToken?** + +The `remoteToken` field represents the token address on the appchain you're bridging to. + +ERC-20 tokens on the appchain must comply to the `IOptimismMintableERC20` interface to be bridgeable. + +Follow the [Optimism documentation](https://docs.optimism.io/app-developers/tutorials/bridging/standard-bridge-standard-token#create-an-l2-erc-20-token) to retrieve the `remoteToken` address for your ERC-20 token. + + + +You can then plug the `customBridgeableTokens` into the `AppchainBridge` component with the `bridgeableTokens` prop. + +```tsx twoslash +// @noErrors: 2554 +// @noErrors: 2304 +import type { BridgeableToken } from '@coinbase/onchainkit/appchain'; + +const customBridgeableTokens: BridgeableToken[] = [ + { + name: 'ETH', + address: '', + symbol: 'ETH', + decimals: 18, + image: + 'https://wallet-api-production.s3.amazonaws.com/uploads/tokens/eth_288.png', + chainId: 84532, + }, + { + address: '0x...', + remoteToken: '0x...', + name: 'Sandbox Token', + symbol: 'SBOX', + decimals: 18, + chainId: 8453200058, + image: 'https://img.cryptorank.io/coins/blocklords1670492311588.png', + }, +]; +// ---cut-before--- +import { AppchainBridge } from '@coinbase/onchainkit/appchain'; +import { baseSepolia } from 'viem/chains'; + + +``` + +### Chains with custom gas tokens + +For chains that use custom gas tokens, simply set the `isCustomGasToken` field to `true` on the custom gas token for your bridgeable token. + +```tsx twoslash +// @noErrors: 2554 +import type { BridgeableToken } from '@coinbase/onchainkit/appchain'; + +const customGasToken: BridgeableToken[] = [ + { + address: '0x...', + remoteToken: '0x...', + name: 'Appchain Token', + symbol: 'ATKN', + decimals: 18, + chainId: 8453200000, + image: 'https://some-icon.com/icon.png', + isCustomGasToken: true, // [!code ++] + }, +]; +``` + +### Fetching price for custom tokens + +By default, we provide a price feed for ETH and USDC. + +To fetch the price of custom ERC-20 tokens, you can override the `handleFetchPrice` function in the `AppchainBridge` component. This callback is run everytime the user changes the input amount. + +The function must match the following signature: + +```ts +(amount: string, token: Token) => Promise; +``` + +```tsx twoslash +// @noErrors: 2554 +// @noErrors: 2362 2363 2304 +import { AppchainBridge } from '@coinbase/onchainkit/appchain'; +import { baseSepolia } from 'viem/chains'; + +const handleFetchPrice = async (amount: string, token: Token) => { + // Example of fetching price + const price = await fetch(`https://api.example.com/price/${token.address}`); + return price * amount; +}; + + +``` + +## Components + +The `AppchainBridge` component includes the following subcomponents: + +- `` - A fully built bridge component that handles deposits and withdrawals. Also includes a `children` prop to render custom components. +- `` - A headless provider that provides the bridge context to child components. +- `` - A component that handles the amount input for bridging tokens. +- `` - A component that displays network information and allows network selection. +- `` - A component that triggers bridge transactions. +- `` - A component that handles the withdrawal interface. +- `` - A button component for toggling between networks. +- `` - A component that displays transaction success states. +- `` - A component that handles resuming interrupted bridge transactions. + +## Props + +- [`Appchain`](/builderkits/onchainkit/appchain/types#appchain) +- [`AppchainBridgeReact`](/builderkits/onchainkit/appchain/types#appchainbridgereact) +- [`AppchainBridgeProviderReact`](/builderkits/onchainkit/appchain/types#appchainbridgeproviderreact) +- [`AppchainBridgeContextType`](/builderkits/onchainkit/appchain/types#appchainbridgecontexttype) +- [`BridgeableToken`](/builderkits/onchainkit/appchain/types#bridgeabletoken) +- [`ChainWithIcon`](/builderkits/onchainkit/appchain/types#chainwithicon) +- [`AppchainConfig`](/builderkits/onchainkit/appchain/types#appchainconfig) +- [`AppchainBridgeSuccessReact`](/builderkits/onchainkit/appchain/types#appchainbridgesuccessreact) +- [`BridgeParams`](/builderkits/onchainkit/appchain/types#bridgeparams) +- [`ChainConfigParams`](/builderkits/onchainkit/appchain/types#chainconfigparams) +- [`UseDepositParams`](/builderkits/onchainkit/appchain/types#usedepositparams) +- [`UseWithdrawParams`](/builderkits/onchainkit/appchain/types#usewithdrawparams) +- [`UseDepositButtonParams`](/builderkits/onchainkit/appchain/types#usedepositbuttonparams) +- [`UseWithdrawButtonParams`](/builderkits/onchainkit/appchain/types#usewithdrawbuttonparams) diff --git a/docs/pages/builderkits/onchainkit/appchain/types.mdx b/_pages/builderkits/onchainkit/appchain/types.mdx similarity index 100% rename from docs/pages/builderkits/onchainkit/appchain/types.mdx rename to _pages/builderkits/onchainkit/appchain/types.mdx diff --git a/_pages/builderkits/onchainkit/buy/buy.mdx b/_pages/builderkits/onchainkit/buy/buy.mdx new file mode 100644 index 00000000..450ec44a --- /dev/null +++ b/_pages/builderkits/onchainkit/buy/buy.mdx @@ -0,0 +1,116 @@ +--- +title: · OnchainKit +description: Buy components & utilities +--- + +import { Danger } from "/snippets/danger.mdx"; +import { Avatar, Name } from '@coinbase/onchainkit/identity'; +import { Swap, SwapAmountInput, SwapButton, SwapDefault, SwapMessage, SwapToggleButton, SwapToast } from '@coinbase/onchainkit/swap'; +import { Buy } from '@coinbase/onchainkit/buy'; +import { Wallet, ConnectWallet } from '@coinbase/onchainkit/wallet'; +import App from '@/components/App'; +import SwapWrapper from '@/components/SwapWrapper'; +import BuyWrapper from '@/components/BuyWrapper'; + +# `` + +Buy + +The `Buy` components provide a comprehensive interface for users to purchase [Tokens](/builderkits/onchainkit/token/types#token). + +The `Buy` component supports token swaps from USDC and ETH by default with the option to provide an additional token of choice using the `fromToken` prop. In addition, users are able to purchase tokens using their Coinbase account, Apple Pay, or debit card. + + +The Apple Pay and Debit Card onramp options are only available for Coinbase supported assets. + + + +Before using, ensure you've completed all [Getting Started steps](/builderkits/onchainkit/getting-started). + + +This component requires a `projectId` to be set in the `OnchainKitProvider`. You can find your `projectId` on [Coinbase Developer Platform](https://portal.cdp.coinbase.com/products/onchainkit). + + + +## Usage + +Example using `@coinbase/onchainkit/buy`. + +```tsx twoslash +import { Buy } from '@coinbase/onchainkit/buy'; // [!code focus] +import type { Token } from '@coinbase/onchainkit/token'; + +export default function BuyComponents() { // [!code focus] + const degenToken: Token = { + name: 'DEGEN', + address: '0x4ed4e862860bed51a9570b96d89af5e1b0efefed', + symbol: 'DEGEN', + decimals: 18, + image: + 'https://d3r81g40ycuhqg.cloudfront.net/wallet/wais/3b/bf/3bbf118b5e6dc2f9e7fc607a6e7526647b4ba8f0bea87125f971446d57b296d2-MDNmNjY0MmEtNGFiZi00N2I0LWIwMTItMDUyMzg2ZDZhMWNm', + chainId: 8453, + }; + + return ( // [!code focus] + // [!code focus] + ) // [!code focus] +} // [!code focus] + +``` + + + + {({ address, toToken }) => { + return ( + + ) + }} + + + + +**Note: This interface is for demonstration purposes only.** + +Swap and Onramp flows will execute and work out of the box when you implement the component in your own app. + + + +### Sponsor gas with Paymaster + +To sponsor swap transactions for your users, toggle the Paymaster using the `isSponsored` prop. + +By default, this will use the [Coinbase Developer Platform](https://portal.cdp.coinbase.com/products/bundler-and-paymaster) Paymaster. + +You can configure sponsorship settings on the [Paymaster](https://portal.cdp.coinbase.com/products/bundler-and-paymaster) page. +For security reasons, we recommend setting up a contract allowlist in the Portal. Without a contract allowlist defined, your Paymaster will only be able to sponsor up to $1. + +The contract used in our Swap API is Uniswap's [Universal Router](https://basescan.org/address/0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD), which is deployed on Base at `0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD`. + +Note that gas sponsorship will only work for Smart Wallets. + +```tsx twoslash +import { Buy } from '@coinbase/onchainkit/buy'; // [!code focus] +import type { Token } from '@coinbase/onchainkit/token'; + +export default function BuyComponents() { // [!code focus] + const degenToken: Token = { + name: 'DEGEN', + address: '0x4ed4e862860bed51a9570b96d89af5e1b0efefed', + symbol: 'DEGEN', + decimals: 18, + image: + 'https://d3r81g40ycuhqg.cloudfront.net/wallet/wais/3b/bf/3bbf118b5e6dc2f9e7fc607a6e7526647b4ba8f0bea87125f971446d57b296d2-MDNmNjY0MmEtNGFiZi00N2I0LWIwMTItMDUyMzg2ZDZhMWNm', + chainId: 8453, + }; + + return ( // [!code focus] + // [!code focus] + ) // [!code focus] +} // [!code focus] +``` + +## Props + +- [`BuyReact`](/builderkits/onchainkit/buy/types#buyreact) diff --git a/docs/pages/builderkits/onchainkit/buy/types.mdx b/_pages/builderkits/onchainkit/buy/types.mdx similarity index 100% rename from docs/pages/builderkits/onchainkit/buy/types.mdx rename to _pages/builderkits/onchainkit/buy/types.mdx diff --git a/_pages/builderkits/onchainkit/checkout/checkout.mdx b/_pages/builderkits/onchainkit/checkout/checkout.mdx new file mode 100644 index 00000000..6a79df5c --- /dev/null +++ b/_pages/builderkits/onchainkit/checkout/checkout.mdx @@ -0,0 +1,458 @@ +--- +title: · OnchainKit +description: One-click checkout for onchain commerce +--- + +import { Danger } from "/snippets/danger.mdx"; +import { Checkout, CheckoutButton } from '@coinbase/onchainkit/checkout'; +import App from '@/components/App'; + +# `` + +The `Checkout` component provides a one-click checkout experience for onchain commerce - all for free. + +Our all-in-one solution simplifies payment processing for onchain developers, removing complex integrations, high fees, and onboarding friction. Whether you're selling digital goods, services, or in-game items, this tool is for you. + +Checkout + +## Features + +- **Plug-and-Play Integration:** Add our `Checkout` button with just a few lines of code. No backend required. +- **Seamless Onboarding:** Support Passkey wallets to eliminate onboarding drop-offs. +- **Real-time Merchant Tooling:** Get instant payment tracking, analytics, and reporting. +- **Dynamic Payment Flows:** Generate charges on the fly, handle variable pricing, and pass in custom metadata. + +## Prerequisites + +Before using the `Checkout` component, ensure you've completed the [Getting Started](/builderkits/onchainkit/getting-started) steps. + + +To use the `Checkout` component, you'll need to provide a Client API Key in `OnchainKitProvider`. You can get one following our [Getting Started](/builderkits/onchainkit/getting-started#get-your-client-api-key) steps. + + + +### Starting a new project + +If you're starting a new project, we recommend using `create onchain` to scaffold your project. + +```bash +npm create onchain@latest +``` + +### Adding to an existing project + +If you're adding `Checkout` to an existing project, simply install OnchainKit. + + +```bash [npm] +npm install @coinbase/onchainkit +``` + +```bash [yarn] +yarn add @coinbase/onchainkit +``` + +```bash [pnpm] +pnpm add @coinbase/onchainkit +``` + +```bash [bun] +bun add @coinbase/onchainkit +``` + + +Wrap the `` around your app, following the steps in [Getting Started](/builderkits/onchainkit/getting-started#add-providers). + +## Quickstart + +### Option 1: Simple Product Checkout + +Ideal for fixed-price items. Get started with minimal setup. + + + + Head to [Coinbase Commerce](https://beta.commerce.coinbase.com/) and sign up. This is where you’ll manage transactions, view reports, and configure payments. + + + In the Coinbase Commerce dashboard, create a new product and copy the `productId`. + + + ```tsx twoslash + import { Checkout, CheckoutButton, CheckoutStatus } from '@coinbase/onchainkit/checkout'; + + + // set coinbaseBranded for branding + + + ``` + + + + +### Option 2: Dynamic Charges + +For variable pricing, custom metadata, or multi-product checkouts, use backend-generated charges. + + + + Head to [Coinbase Commerce](https://beta.commerce.coinbase.com/) and sign up. This is where you’ll manage transactions, view reports, and configure payments. + + + In the [Coinbase Commerce dashboard](https://beta.commerce.coinbase.com/settings/security), create a new API Key under `Security` in `Settings`. + + + See [Using chargeHandler](/builderkits/onchainkit/checkout/checkout#using-chargehandler) for a code example. + + + ```tsx + const chargeHandler = async () => { + const response = await fetch('/createCharge', { method: 'POST' }); + const { id } = await response.json(); + return id; // Return charge ID + }; + + + + + ``` + + + +That's it! Start selling onchain with just a few lines of code. + +## Usage + +### Configuring a checkout + +#### Using `productId` + +You can create products on the Coinbase Commerce Portal and use them in the `Checkout` component through the `productId` prop. + +```tsx twoslash +import { Checkout, CheckoutButton } from '@coinbase/onchainkit/checkout'; + +export default function PayComponents() { + return ( +// ---cut-before--- + + + +// ---cut-after--- +); +} +``` + + + + + + + +#### Using `chargeHandler` + +Alternatively, you can create charges dynamically using the Coinbase Commerce API [Create Charge](https://docs.cdp.coinbase.com/commerce-onchain/reference/creates-a-charge) endpoint by passing the chargeID into Checkout via the `chargeHandler` prop. + +This function must have the signature `() => Promise` and must return a valid chargeId created by the create charge endpoint. + + +To create charges, you'll need a Coinbase Commerce [API Key](https://docs.cdp.coinbase.com/commerce-onchain/docs/getting-started). + + + + +**⚠️ Warning** + +You should protect your Coinbase Commerce API Key by only creating charges server-side. + + + + +```ts [backend.ts] +// This backend endpoint should create a charge and return the response. +app.post('/createCharge', async (req: Request, res: Response) => { + const options = { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Accept': 'application/json', + 'X-CC-Api-Key': 'your_api_key_here' // Replace this with your Coinbase Commerce API Key + }, + body: JSON.stringify({ + local_price: { amount: '1', currency: 'USDC' }, + pricing_type: 'fixed_price', + metadata: { some_field: "some_value" } // Optional: Attach metadata like order ID or customer details + }), + }; + + const response = await fetch('https://api.commerce.coinbase.com/charges', options); + const data = await response.json(); + + res.json(data); +}); + +``` + +```tsx twoslash [frontend.tsx] +import { Checkout, CheckoutButton } from '@coinbase/onchainkit/checkout'; + +const chargeHandler = async () => { + const response = await fetch('https://your-backend.com/createCharge', { method: 'POST' }); + const { id } = await response.json(); + return id; // Return charge ID +}; + + + + +``` + + +Note that `productId` and `chargeHandler` are mutually exclusive and only one can be provided as a prop to Checkout. + +### Handling a successful checkout + +To handle successful checkouts, use the `onStatus` prop to listen for the `success` callback. + +This callback will return a [LifecycleStatusData](/builderkits/onchainkit/checkout/checkout#advanced-usage) object including the [TransactionReceipt](https://github.com/wevm/viem/blob/main/src/types/transaction.ts#L38) and `chargeId`. + +For idempotent actions, like rendering your own success screen, you can simply check that the `statusName` is equal to `success`. + +For non-idempotent actions, like order fulfillment, we recommend one of the following approaches to verify a charge has been fully paid. + +1. (**Recommended**) Check the status of the `chargeId` using the [Coinbase Commerce API](https://docs.cdp.coinbase.com/commerce-onchain/docs/web3-payments-faq#how-can-i-verify-if-a-charge-has-been-fully-paid). +2. Set up a [Coinbase Commerce Webhook](https://docs.cdp.coinbase.com/commerce-onchain/docs/webhooks) which will notify you for successful payments. + +```tsx twoslash +import { Checkout, CheckoutButton } from '@coinbase/onchainkit/checkout'; +// ---cut-before--- +import type { LifecycleStatus } from '@coinbase/onchainkit/checkout'; // [!code focus] + +const statusHandler = async (status: LifecycleStatus) => { // [!code focus] + const { statusName, statusData } = status; // [!code focus] + switch (statusName) { // [!code focus] + case 'success': // [!code focus] + // handle success // [!code focus] + const { chargeId } = statusData; // [!code focus] + // use the charges api to verify the chargeId // [!code focus] + const options = { // [!code focus] + method: 'GET', // [!code focus] + headers: { // [!code focus] + 'Content-Type': 'application/json', // [!code focus] + 'Accept': 'application/json', // [!code focus] + 'X-CC-Api-Key': 'your_api_key_here' // Replace this with your Coinbase Commerce API Key // [!code focus] + } // [!code focus] + }; // [!code focus] + const response = await fetch(`https://api.commerce.coinbase.com/charges/${chargeId}`); // [!code focus] + } // [!code focus] +} // [!code focus] + + + + +// ---cut-after--- +``` + + +To verify charges, you'll need a Coinbase Commerce [API Key](https://docs.cdp.coinbase.com/commerce-onchain/docs/getting-started). + + + + +**⚠️ Warning** + +You should protect your Coinbase Commerce API Key by verifying charges server-side. This client-side code is only provided as an example. + + + +### Viewing successful checkouts + +You can view successful checkouts on the [Coinbase Commerce Merchant Dashboard](https://beta.commerce.coinbase.com/payments). + +Viewing successful checkouts + +## Customization + +### Add name and logo + +To customize the name and logo of your application rendered in the popup, set the `name` and `logo` values inside [OnchainKitProvider](/builderkits/onchainkit/config/onchainkit-provider#usage). + +```tsx twoslash [providers.tsx] +// @noErrors: 2304 - Cannot find name 'children' +import { base } from 'wagmi/chains'; +// ---cut-before--- +import { OnchainKitProvider } from '@coinbase/onchainkit'; + + + {children} + +// ---cut-after--- +``` + +
+ Add name and logo +
+ +### Add Coinbase branding + +You can add Coinbase branding to the component by using the `coinbaseBranded` prop on `CheckoutButton`. + +```tsx twoslash +import { Checkout, CheckoutButton } from '@coinbase/onchainkit/checkout'; + +export default function PayComponents() { + return ( +// ---cut-before--- + + + +// ---cut-after--- +); +} +``` + + + + + + + +### Disabling the button + +You can disable the button using the `disabled` prop on `CheckoutButton`. + +```tsx twoslash + +import { Checkout, CheckoutButton } from '@coinbase/onchainkit/checkout'; + +export default function PayComponents() { + return ( +// ---cut-before--- + + + +// ---cut-after--- +); +} +``` + + + + + + + +### Customize button + +You can customize the button text using the `text` prop on `CheckoutButton`. + +```tsx twoslash + +import { Checkout, CheckoutButton } from '@coinbase/onchainkit/checkout'; + +export default function PayComponents() { + return ( +// ---cut-before--- + + + +// ---cut-after--- +); +} +``` + + + + + + + +### Override styles + +We recommend style customization by setting a custom [OnchainKit theme](/builderkits/onchainkit//guides/themes#custom-theme). You can also override individual component styles using `className`. + +```tsx twoslash + +import { Checkout, CheckoutButton } from '@coinbase/onchainkit/checkout'; + +export default function PayComponents() { + return ( +// ---cut-before--- + + + +// ---cut-after--- +); +} +``` + + + + + + + +## Advanced Usage + +### Listening to the component lifecycle + +You can use our Checkout [`LifecycleStatus`](/builderkits/onchainkit/checkout/types#lifecyclestatus) and the `onStatus` prop to listen to transaction states. + +```tsx twoslash +import { Checkout, CheckoutButton } from '@coinbase/onchainkit/checkout'; +// ---cut-before--- +import type { LifecycleStatus } from '@coinbase/onchainkit/checkout'; // [!code focus] + +const statusHandler = (status: LifecycleStatus) => { // [!code focus] + const { statusName, statusData } = status; // [!code focus] + switch (statusName) { // [!code focus] + case 'success': // handle success // [!code focus] + case 'pending': // handle payment pending // [!code focus] + case 'error': // handle error // [!code focus] + default: // [!code focus] + // handle 'init' state + } // [!code focus] +} // [!code focus] + + + + +// ---cut-after--- +``` + +## Example use cases + +- **Demand-based pricing:** Allow users to select seats or ticket types for events, and dynamically calculate charges based on availability and demand. +- **Product bundles:** Provide users with the option to create custom product bundles, applying discounts or special pricing based on the selected items. +- **Freelance Services:** Allow clients to specify project details such as hours, deliverables, and deadlines, and generate charges based on these custom inputs. + +## Components + +The components are designed to work together hierarchically. For each component, ensure the following: + +- `` - Sets the `productId` or `chargeHandler` prop. +- `` - Branding and customization of the payment button. +- `` - The status of the payment. + +## Props + +- [`LifecycleStatus`](/builderkits/onchainkit/checkout/types#lifecyclestatus) +- [`CheckoutReact`](/builderkits/onchainkit/checkout/types#checkoutreact) +- [`CheckoutButtonReact`](/builderkits/onchainkit/checkout/types#checkoutbuttonreact) +- [`CheckoutStatusReact`](/builderkits/onchainkit/checkout/types#checkoutstatusreact) diff --git a/docs/pages/builderkits/onchainkit/checkout/types.mdx b/_pages/builderkits/onchainkit/checkout/types.mdx similarity index 100% rename from docs/pages/builderkits/onchainkit/checkout/types.mdx rename to _pages/builderkits/onchainkit/checkout/types.mdx diff --git a/_pages/builderkits/onchainkit/config/is-base.mdx b/_pages/builderkits/onchainkit/config/is-base.mdx new file mode 100644 index 00000000..62236ea3 --- /dev/null +++ b/_pages/builderkits/onchainkit/config/is-base.mdx @@ -0,0 +1,37 @@ +--- +title: "`isBase`" +--- + + +The `isBase` utility is designed to verify if the chain id is a valid Base or Base Sepolia chain id. + +## Usage + + +```tsx twoslash [code] +import { isBase } from '@coinbase/onchainkit'; + +// Base Mainnet (chain ID: 8453) +isBase({ chainId: 8453 }); // returns true + +// Base Sepolia (chain ID: 84532) +isBase({ chainId: 84532 }); // returns true + +// Ethereum (chain ID: 1) +isBase({ chainId: 1 }); // returns false +``` + +```ts [return value] +true; // When chainId is 8453 (Base Mainnet) or 84532 (Base Sepolia) +false; // For all other chain IDs +``` + + +## Returns + +`boolean` - Returns `true` if the chain id is Base or Base Sepolia, otherwise `false`. + +## Parameters + +[`IsBaseOptions`](./types#isbaseoptions) - See [`IsBaseOptions`](./types#isbaseoptions) for more details. + diff --git a/_pages/builderkits/onchainkit/config/is-ethereum.mdx b/_pages/builderkits/onchainkit/config/is-ethereum.mdx new file mode 100644 index 00000000..ea4c45b8 --- /dev/null +++ b/_pages/builderkits/onchainkit/config/is-ethereum.mdx @@ -0,0 +1,37 @@ +--- +title: "`isEthereum`" +--- + + +The `isEthereum` utility is designed to verify if the chain id is a valid Ethereum Mainnet or Ethereum Sepolia chain id. + +## Usage + + +```tsx twoslash [code] +import { isEthereum } from '@coinbase/onchainkit'; + +// Ethereum Mainnet (chain ID: 1) +isEthereum({ chainId: 1 }); // returns true + +// Ethereum Sepolia (chain ID: 11155111) +isEthereum({ chainId: 11155111 }); // returns true + +// Base (chain ID: 8453) +isEthereum({ chainId: 8453 }); // returns false +``` + +```ts [return value] +true; // When chainId is 1 (Ethereum Mainnet) or 11155111 (Ethereum Sepolia) +false; // For all other chain IDs +``` + + +## Returns + +`boolean` - Returns `true` if the chain id is Ethereum Mainnet or Ethereum Sepolia, otherwise `false`. + +## Parameters + +[`IsEthereumOptions`]: ./types#isethereumoptions + diff --git a/_pages/builderkits/onchainkit/config/onchainkit-provider.mdx b/_pages/builderkits/onchainkit/config/onchainkit-provider.mdx new file mode 100644 index 00000000..046f45ea --- /dev/null +++ b/_pages/builderkits/onchainkit/config/onchainkit-provider.mdx @@ -0,0 +1,145 @@ +--- +title: "``" +--- + + +Provides the OnchainKit React Context to the app. + +## Usage + +```tsx twoslash [app.tsx] +// @noErrors: 2304 - Cannot find name 'MyComponent' +import { base } from 'viem/chains'; +import { OnchainKitProvider } from '@coinbase/onchainkit'; + +const App = () => { + return ( + + + + ); +}; +``` + +## Props + +[`OnchainKitProviderReact`](/builderkits/onchainkit/config/types#onchainkitproviderreact) + +| Prop | Description | Required | +| -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | +| [`chain`](#chain) | The chain that your OnchainKit project supports. | Yes | +| [`apiKey`](#apikey) | Client API Key from Coinbase Developer Platform. | No | +| [`rpcUrl`](#rpc-url) | RPC URL for onchain requests. | No | +| [`projectId`](#project-id) | Your Coinbase Developer Platform Project ID. | No | +| [`config`](#config) | - `config.appearance` — Customize your OnchainKit project's appearance
- `config.paymaster` — Paymaster URL for gas sponsorship
- `config.wallet` — Wallet configuration options | No | +| [`schemaId`](#schema-id) | _[Deprecation Pending]_ The schema ID for attestations from the Ethereum Attestation Service (EAS). | No | +| [`address`](#address) | _[Deprecation Pending]_ This prop is no longer used. | No | + +### Chain + +`chain` specifies the chain on which your OnchainKit project will operate. + +This prop is required for all OnchainKit components. + +We recommend importing chain data from [viem](https://viem.sh/docs/chains/introduction). + +### `apiKey` + +`apiKey` is your Coinbase Developer Platform Client API Key. + +This prop is required for most OnchainKit components, including: + +- [``](/builderkits/onchainkit/checkout/checkout) +- [``](/builderkits/onchainkit/mint/nft-card) +- [``](/builderkits/onchainkit/mint/nft-mint-card) +- [``](/builderkits/onchainkit/swap/swap) +- [``](/builderkits/onchainkit/transaction/transaction) + +You can get a [Client API Key](https://portal.cdp.coinbase.com/projects/project-id/api-keys/client-key) +from Coinbase Developer Platform. + +OnchainKit copy Client API Key + +### RPC URL + +`rpcUrl` is required for any onchain requests. If you provide your own RPC URL, +OnchainKit will use it. + +If you do not provide your own RPC URL, you must provide an `apiKey`, which +enables OnchainKit to use the +[Coinbase Developer Platform Node](https://portal.cdp.coinbase.com/products/node). + +### Project ID + +`projectId` is your Coinbase Developer Platform Project ID. + +This prop is required for the `` component. + +You can obtain a Project ID from the [Coinbase Developer Platform](https://portal.cdp.coinbase.com/projects). + +OnchainKit copy Project ID + +### Config + +`config` is an object that can be used to customize the appearance and behavior +of the OnchainKit components. + +This prop has three keys: `appearance`, `paymaster`, and `wallet`. + +#### Appearance + +`appearance` manages the appearance of the OnchainKit components and has the following properties: + +- `name` — The name of your OnchainKit project +- `logo` — The URL of the logo for your OnchainKit project +- `mode` — The mode of the OnchainKit components. Can be `auto`, `dark`, or `light`. +- `theme` — The theme of the OnchainKit components. Can be `base`, `cyberpunk`, `default`, `hacker`, or a custom theme. + +Explore appearance options in the [OnchainKit Playground](https://onchainkit.xyz/playground). + +#### Paymaster + +`paymaster` represents the Paymaster URL that enables you to sponsor gas for your users. + +You can configure your Paymaster and obtain your Paymaster URL from the +[Coinbase Developer Platform](https://portal.cdp.coinbase.com/products/bundler-and-paymaster). + +#### Wallet + +`wallet` configures the wallet connection experience and has the following properties: + +- `display` — The display mode for the wallet interface. Can be either: + - `'modal'` — Shows wallet connection in a modal overlay with wallet aggregation + - `'classic'` — Shows wallet connection in the traditional inline style +- `termsUrl` — URL to your terms of service +- `privacyUrl` — URL to your privacy policy + +### Address _[Deprecation Pending]_ + +`address` is no longer used and will be removed in a future version of +OnchainKit. + +### Schema ID _[Deprecation Pending]_ + +`schemaId` is no longer used as OnchainKit now defaults to using Coinbase +attestations for the `` component. + +This prop will be removed in a future version of OnchainKit. diff --git a/_pages/builderkits/onchainkit/config/supplemental-providers.mdx b/_pages/builderkits/onchainkit/config/supplemental-providers.mdx new file mode 100644 index 00000000..db63dbc6 --- /dev/null +++ b/_pages/builderkits/onchainkit/config/supplemental-providers.mdx @@ -0,0 +1,87 @@ +--- +title: Supplemental Providers · OnchainKit +description: Customize the Wagmi and QueryClient providers +--- + +import StartBuilding from "/snippets/start-building.mdx"; + +# Custom Supplemental Providers + +Under the hood, OnchainKit will create our recommended Wagmi and QueryClient +providers. If you wish to customize the providers, you can do so by creating +these providers with your own configuration. + +For example, the following code creates custom Wagmi and QueryClient providers: + + +```tsx twoslash [wagmi.ts] +// @noErrors: 2554 +import { http, cookieStorage, createConfig, createStorage } from 'wagmi'; +import { base } from 'wagmi/chains'; // add baseSepolia for testing // [!code ++] +import { coinbaseWallet } from 'wagmi/connectors'; + +export function getConfig() { + return createConfig({ + chains: [base], // add baseSepolia for testing // [!code ++] + connectors: [ + coinbaseWallet({ + appName: 'OnchainKit', + preference: 'smartWalletOnly', + version: '4', + }), + ], + storage: createStorage({ + storage: cookieStorage, + }), + ssr: true, + transports: { + [base.id]: http(), // add baseSepolia for testing // [!code ++] + }, + }); +} + +declare module 'wagmi' { + interface Register { + config: ReturnType; + } +} +``` + +```tsx twoslash [providers.tsx] +// @noErrors: 2307 2580 2339 2554 - cannot find 'process', cannot find './wagmi', cannot find 'import.meta' +import { OnchainKitProvider } from '@coinbase/onchainkit'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { base } from 'wagmi/chains'; // add baseSepolia for testing // [!code ++] +import { type ReactNode, useState } from 'react'; +import { type State, WagmiProvider } from 'wagmi'; + +import { getConfig } from '@/wagmi'; // your import path may vary // [!code ++] + +export function Providers(props: { + children: ReactNode; + initialState?: State; +}) { + const [config] = useState(() => getConfig()); + const [queryClient] = useState(() => new QueryClient()); + const apiKey = // [!code ++] + typeof window !== 'undefined' // [!code ++] + ? window.ENV?.PUBLIC_ONCHAINKIT_API_KEY // [!code ++] + : undefined; // [!code ++] + + return ( + + + + {props.children} + + + + ); +} +``` + + + diff --git a/docs/pages/builderkits/onchainkit/config/types.mdx b/_pages/builderkits/onchainkit/config/types.mdx similarity index 100% rename from docs/pages/builderkits/onchainkit/config/types.mdx rename to _pages/builderkits/onchainkit/config/types.mdx diff --git a/_pages/builderkits/onchainkit/create-a-basename-profile-component.mdx b/_pages/builderkits/onchainkit/create-a-basename-profile-component.mdx new file mode 100644 index 00000000..7e08d16f --- /dev/null +++ b/_pages/builderkits/onchainkit/create-a-basename-profile-component.mdx @@ -0,0 +1,301 @@ +--- +title: 'Create a Basename Profile Component' +slug: /create-basename-profile-component +description: Learn how to create a component that displays social media and profile information for a given basename. +author: hughescoin +--- + +Onchain identities often include social media links and profile information stored as text records. In this tutorial, you'll learn how to create a component that fetches and displays this information for a given basename. + +## Objectives + +By the end of this tutorial you should be able to: + +- Fetch ENS text records for a basename +- Create a React component to display profile information +- Implement a dropdown to show/hide profile details + +## Prerequisites + +### React and TypeScript + +You should be familiar with React and TypeScript. If you're new to these technologies, consider reviewing the [React official documentation] first. + +### OnchainKit + +This tutorial uses Coinbase's [OnchainKit]. Familiarity with its basic concepts will be helpful. + +### Basename + +A basename with a few text records (Github, Twitter, website) is required for this tutorial. If you don't have a Basename. Get one [here](https://www.base.org/names). + +## Set a Text Record + +![image-basename](@/assets/images/basenames-tutorial/basename-profile-home.png) + +To set a text record for your basename, start by visiting `https://www.base.org/name/`. Connect your wallet to manage your profile, then click the `Manage profile` button. Add one or more text records, such as your X (formerly Twitter) URL. Once you've added the desired records, click the `Save` button at the bottom of the page. Finally, confirm and sign the transaction to make the changes onchain. + +![image-basename](@/assets/images/basenames-tutorial/confirm-textrecord-update.png) + +## Setting up the Environment + +First, clone or fork the [OnchainKit app template]: + +``` +git clone git@github.com:coinbase/onchain-app-template.git +``` + +Then, install the following dependencies: + +```bash +bun install framer-motion +bun install lucide-react +``` + +Create a `.env` file: + +``` +cp .env.local .env +``` + +Update the contents of the `.env` file to include a [Reown] (FKA WalletConnect) project ID and a CDP API key: + +``` +# ~~~ +NEXT_PUBLIC_GOOGLE_ANALYTICS_ID= + +# See https://www.coinbase.com/developer-platform/products/base-node +NEXT_PUBLIC_CDP_API_KEY= + +# ~~~ +NEXT_PUBLIC_ENVIRONMENT=localhost + +# See https://cloud.reown.com/ +NEXT_PUBLIC_WC_PROJECT_ID= + +``` + +## Creating the `Client` File + +Create a new file `client.ts` in your project's `src` directory: + +```typescript +import { http, createPublicClient } from 'viem'; +import { mainnet } from 'viem/chains'; + +export const publicClient = createPublicClient({ + chain: base, + transport: http(), +}); +``` + +This client will be used to interact with Base mainnet. + +## Creating the IdentityWrapper Component + +Create a new file `IdentityWrapper.tsx` in your `src/components` directory and import the following packages: + +```typescript +import React, { useState, useEffect } from 'react'; +import { Avatar, Name, getName } from '@coinbase/onchainkit/identity'; +import { motion } from 'framer-motion'; +import { Twitter, Github, Globe } from 'lucide-react'; +import { normalize } from 'viem/ens'; +import { publicClient } from '../client'; + +// Component code will go here +``` + +`IdentityWrapper` will fetch and display social media and profile information for a given Base address using OnchainKit and the Ethereum Name Service (ENS). It will query for the ENS name associated with the address and retrieve relevant text records (Twitter, GitHub, and website URL) using the specified resolver, storing this data in both component state and local storage for optimized performance. The component will be designed to present this information in a user-friendly, expandable format. + +## Implementing the Component Logic + +Add the following code to your `IdentityWrapper.tsx` file: + +```typescript +const IdentityWrapper: React.FC<{ address: string }> = ({ address }) => { + const [ensText, setEnsText] = useState<{ + twitter: string | null; + github: string | null; + url: string | null; + } | null>(null); + + const [isOpen, setIsOpen] = useState(false); + + const BASENAME_L2_RESOLVER_ADDRESS = '0xc6d566a56a1aff6508b41f6c90ff131615583bcd'; + + useEffect(() => { + const fetchEnsText = async () => { + if (address) { + try { + const name = await getName({ chain: base, address: address }); + const normalizedAddress = normalize(name as string); + const twitterText = await publicClient.getEnsText({ + name: normalizedAddress, + key: 'com.twitter', + universalResolverAddress: BASENAME_L2_RESOLVER_ADDRESS, + }); + const githubText = await publicClient.getEnsText({ + name: normalizedAddress, + key: 'com.github', + universalResolverAddress: BASENAME_L2_RESOLVER_ADDRESS, + }); + const urlText = await publicClient.getEnsText({ + name: normalizedAddress, + key: 'url', + universalResolverAddress: BASENAME_L2_RESOLVER_ADDRESS, + }); + const fetchedData = { + twitter: twitterText, + github: githubText, + url: urlText, + }; + setEnsText(fetchedData); + localStorage.setItem(address, JSON.stringify(fetchedData)); + } catch (error) { + console.error('Error fetching ENS text:', error); + } + } + }; + fetchEnsText(); + }, [address]); + + // Render logic will go here +}; + +export default IdentityWrapper; +``` + + +**Possible Basename Text Records:** + +The full list of existing text records for a basename: + +``` + Description, + Keywords, + Url, + Github, + Email, + Phone, + Twitter, + Farcaster, + Lens, + Telegram, + Discord, + Avatar +``` + + + +## Implementing the Render Logic + +Add the following render logic to your `IdentityWrapper` component: + +```typescript +return ( + <> + {address ? ( + +
+ + +
+ + {ensText && ( + + {ensText.twitter && ( +
+ + Twitter: + + {ensText.twitter} + +
+ )} + {ensText.github && ( +
+ + Github: + + {ensText.github} + +
+ )} + {ensText.url && ( + + )} +
+ )} +
+ ) : ( +
Connect your wallet to view your profile card.
+ )} + +); +``` + +## Using the Component + +To use this component in your app, import it into your desired page or component: + +```typescript +import IdentityWrapper from '../components/IdentityWrapper'; + +// In your render function: +; +``` + +![profile-dropdown](/images/basenames-tutorial/profile-component-dropdown.png) + +Example code snippets are available for: + +- [IdentityWrapper component](https://gist.github.com/hughescoin/5e5cd6cbfb3c6d1cada0a9d206b003c6) +- [Page.tsx](https://gist.github.com/hughescoin/49afc9e999d69d372a67186e804e693b) + +## Conclusion + +Congratulations! You've created a component that fetches and displays profile information for a given basename. This component can be easily integrated into your onchain app to provide users with a rich, interactive profile display. + +[OnchainKit]: https://github.com/coinbase/onchainkit +[Viem]: https://viem.sh/ +[Framer Motion]: https://www.framer.com/motion/ +[Lucide React]: https://lucide.dev/guide/packages/lucide-react +[React official documentation]: https://react.dev/ +[OnchainKit app template]: https://github.com/coinbase/onchain-app-template +[Reown]: https://cloud.reown.com/ + diff --git a/_pages/builderkits/onchainkit/earn/earn.mdx b/_pages/builderkits/onchainkit/earn/earn.mdx new file mode 100644 index 00000000..eba3ae12 --- /dev/null +++ b/_pages/builderkits/onchainkit/earn/earn.mdx @@ -0,0 +1,242 @@ +--- +title: · OnchainKit +description: Earn interest on your crypto with OnchainKit +--- + +import { EarnMain, EarnDeposit, RearrangedEarnDeposit, PredefinedInputDeposit } from '@/components/EarnComponents'; + +# `` + +The `Earn` component provides a simple interface for earning interest on your crypto via Morpho vaults on Base. + +## Prerequisites + +Before using the `Earn` component, ensure you've completed the [Getting Started](/builderkits/onchainkit/getting-started) steps. + +### Starting a new project + +If you're starting a new project, we recommend using `create onchain` to scaffold your project. + +```bash +npm create onchain@latest +``` + +### Adding to an existing project + +If you're adding `Earn` to an existing project, simply install OnchainKit. + + +```bash [npm] +npm install @coinbase/onchainkit +``` + +```bash [yarn] +yarn add @coinbase/onchainkit +``` + +```bash [pnpm] +pnpm add @coinbase/onchainkit +``` + +```bash [bun] +bun add @coinbase/onchainkit +``` + + +Wrap the `` around your app, following the steps in [Getting Started](/builderkits/onchainkit/getting-started#add-providers). + +## Quickstart + +To use `Earn`, you'll need to provide a `vaultAddress` prop. A vault address can be obtained from Morpho's [Vaults page](https://app.morpho.org/base/earn). + +```tsx twoslash +// @noErrors: 2307 +import { Earn } from '@coinbase/onchainkit/earn'; // [!code focus] + + // [!code focus] +``` + + + +## Customization + +### Custom components and layouts + +`Earn` accepts a `children` prop that can be used to render `Earn` subcomponents or custom components. + +For instance, you can render the `EarnDeposit` component by itself within the `Earn` component, along with any other custom components you'd like to render. + +```tsx twoslash +// @noErrors: 2307 +import { Earn, EarnDeposit } from '@coinbase/onchainkit/earn'; + + +
Custom header
+ +
Custom footer
+
+``` + + + +For more granular control, you can also render lower level subcomponents within `EarnDeposit` and `EarnWithdraw`. These subcomponents accept `className` props to customize their styles. + +```tsx twoslash +import { Earn, + EarnDeposit, + EarnDetails, + DepositBalance, + DepositAmountInput, + DepositButton } from '@coinbase/onchainkit/earn'; + + + + + + + + + +``` + + + +### Customizing styles + +The `Earn` component is best styled via a [OnchainKit theme](/builderkits/onchainkit/guides/themes#custom-theme). You can also override individual component styles using `className`. + +## Advanced Usage + +If you'd like to implement your own custom components, you can use `useEarnContext` within an `Earn` component to access context and build your own components. + +You can find the full interface for `EarnContextType` on the [Types page](/builderkits/onchainkit/earn/types#earncontexttype). + +Below, we use `useEarnContext` to implement a custom deposit interface by using `useEarnContext` to access the `depositAmount` and `setDepositAmount` context values. + + +```tsx twoslash [index.tsx] +// @noErrors: 2307 +import { Earn, useEarnContext } from '@coinbase/onchainkit/earn'; +import { CustomDepositButtons } from '@/custom-deposit-buttons'; + + + + + +``` + +```tsx twoslash [custom-deposit-buttons.tsx] +import {EarnDetails, + EarnDeposit, + useEarnContext, + DepositButton} from '@coinbase/onchainkit/earn'; + +const predefinedAmounts = ['0.1', '1', '10']; + +function CustomDepositButtons() { + const { depositAmount, setDepositAmount } = useEarnContext(); + + return ( + + +
+ {predefinedAmounts.map((amount) => { + const selected = amount === depositAmount; + return ( + + ); + })} +
+ +
+ ); +} +``` +
+ + + +Taking advantage of the data and methods provided by `useEarnContext`, developers can implement fully custom deposit and withdraw interfaces, modifying everything from UI elements to input behavior. + +## Examples + +### Sponsoring transactions + +To sponsor transactions, you can use the `isSponsored` prop. + +```tsx twoslash +// @noErrors: 2304 + +``` + +Ensure that your `OnchainKitProvider` has a `paymaster` configured: + +```tsx twoslash +// @noErrors: 2304 17008 1005 + +``` + + +If you have a contract allowlist set on Coinbase Developer Platform, you'll need to ensure that the following contract functions are allowed: + +- `deposit` on the Morpho vault +- `redeem` on the Morpho vault +- `approve` on the token being deposited + + + +## Components + +The `Earn` component includes the following subcomponents: + +- `` - A fully built Withdraw and Deposit component. Also includes a `children` prop to render custom components and provides `useEarnContext` to access the context values. +- `` - A headless provider that provides the `useEarnContext` hook to the `Earn` component. +- `` - A fully built deposit card. +- `` - A fully built withdraw card. +- `` - A component that displays the details of the vault. +- `` - A component that handles the deposit amount input. +- `` - A component that displays the balance underlying asset in the user's wallet. +- `` - A component that triggers the deposit transaction. +- `` - A component that handles the withdraw amount input. +- `` - A component that displays how much the user can withdraw from a vault. +- `` - A component that triggers the withdraw transaction. +- `` - A component that displays the yield details of the vault. +- `` - A component that displays the vault details. + +## Hooks + +- [`useEarnContext`](/builderkits/onchainkit/hooks/use-earn-context) - A hook that provides the context values of the `Earn` component. +- [`useBuildDepositToMorphoTx`](/builderkits/onchainkit/hooks/use-build-deposit-to-morpho-tx) - A hook that builds a deposit transaction to Morpho. +- [`useBuildWithdrawFromMorphoTx`](/builderkits/onchainkit/hooks/use-build-withdraw-from-morpho-tx) - A hook that builds a withdraw transaction from Morpho. +- [`useMorphoVault`](/builderkits/onchainkit/hooks/use-morpho-vault) - A hook that provides the details of a Morpho vault. + +## Props + +- [`LifecycleStatus`](/builderkits/onchainkit/earn/types#lifecyclestatus) +- [`EarnReact`](/builderkits/onchainkit/earn/types#earnreact) +- [`EarnProviderReact`](/builderkits/onchainkit/earn/types#earnproviderreact) +- [`EarnContextType`](/builderkits/onchainkit/earn/types#earncontexttype) +- [`EarnAmountInputReact`](/builderkits/onchainkit/earn/types#earnamountinputreact) +- [`DepositAmountInputReact`](/builderkits/onchainkit/earn/types#depositamountinputreact) +- [`WithdrawAmountInputReact`](/builderkits/onchainkit/earn/types#withdrawamountinputreact) +- [`EarnBalanceReact`](/builderkits/onchainkit/earn/types#earnbalancereact) +- [`DepositBalanceReact`](/builderkits/onchainkit/earn/types#depositbalancereact) +- [`WithdrawBalanceReact`](/builderkits/onchainkit/earn/types#withdrawbalancereact) +- [`EarnDepositReact`](/builderkits/onchainkit/earn/types#earndepositreact) +- [`EarnWithdrawReact`](/builderkits/onchainkit/earn/types#earnwithdrawreact) +- [`EarnDetailsReact`](/builderkits/onchainkit/earn/types#earndetailsreact) +- [`DepositButtonReact`](/builderkits/onchainkit/earn/types#depositbuttonreact) +- [`WithdrawButtonReact`](/builderkits/onchainkit/earn/types#withdrawbuttonreact) diff --git a/docs/pages/builderkits/onchainkit/earn/types.mdx b/_pages/builderkits/onchainkit/earn/types.mdx similarity index 100% rename from docs/pages/builderkits/onchainkit/earn/types.mdx rename to _pages/builderkits/onchainkit/earn/types.mdx diff --git a/_pages/builderkits/onchainkit/fund/fetch-onramp-config.mdx b/_pages/builderkits/onchainkit/fund/fetch-onramp-config.mdx new file mode 100644 index 00000000..f9786533 --- /dev/null +++ b/_pages/builderkits/onchainkit/fund/fetch-onramp-config.mdx @@ -0,0 +1,58 @@ +--- +title: "`fetchOnrampConfig`" +--- + + +The `fetchOnrampConfig` utility fetches the list of countries supported by Coinbase Onramp and their available payment methods. This is useful when you need to validate user eligibility or display available payment options. + +## Usage + + +```tsx twoslash [code] +import { fetchOnrampConfig } from '@coinbase/onchainkit/fund'; + +// When using with OnchainKitProvider +const config = await fetchOnrampConfig(); + +// When using without OnchainKitProvider or in non-React environment +const config2 = await fetchOnrampConfig('your-api-key'); +``` + +```json [return value] +{ + countries: [ + { + id: "US", + subdivisions: ["CA", "NY", "TX"], + paymentMethods: [ + { + id: "CARD", + name: "Credit or debit card", + description: "Pay with Visa or Mastercard", + currencies: ["USD", "EUR"], + minAmount: { value: "10.00", currency: "USD" }, + maxAmount: { value: "1000.00", currency: "USD" } + } + ] + } + ] +} +``` + + +## Parameters + +```typescript +/** + * Optional API key for Coinbase Onramp. If not provided, the API key from + * OnchainKitProvider will be used. Required when using the utility without + * OnchainKitProvider or in a non-React environment. + */ +apiKey?: string; +``` + +## Returns + +`Promise` - Returns a promise that resolves to the configuration data containing supported countries and their payment methods. + +See [`OnrampConfigResponseData`](/builderkits/onchainkit/fund/types#onrampconfigresponsedata) for response type details. diff --git a/_pages/builderkits/onchainkit/fund/fetch-onramp-options.mdx b/_pages/builderkits/onchainkit/fund/fetch-onramp-options.mdx new file mode 100644 index 00000000..d692e6ee --- /dev/null +++ b/_pages/builderkits/onchainkit/fund/fetch-onramp-options.mdx @@ -0,0 +1,78 @@ +--- +title: "`fetchOnrampOptions`" +--- + + +The `fetchOnrampOptions` utility retrieves supported fiat currencies and available crypto assets for a specific country. This information is essential for determining which assets can be purchased in the user's jurisdiction. + +## Usage + + +```tsx twoslash [code] +import { fetchOnrampOptions } from '@coinbase/onchainkit/fund'; + +const options = await fetchOnrampOptions({ + country: 'US', + subdivision: 'CA', // Required for US residents + apiKey: 'your-api-key', // Required when using without OnchainKitProvider or in non-React environment +}); +``` + +```json [return value] +{ + fiatCurrencies: [ + { + id: "USD", + name: "US Dollar", + symbol: "$" + } + ], + assets: [ + { + id: "ETH", + name: "Ethereum", + networks: [ + { + id: "ethereum", + name: "Ethereum", + config: { + chainId: "0x1" + } + } + ] + } + ] +} +``` + + +## Parameters + +```typescript +{ + /** + * ISO 3166-1 two-letter country code string representing + * the purchasing user’s country of residence, e.g., US. + */ + country: string; + /** + * ISO 3166-2 two-letter country subdivision code representing + * the purchasing user’s subdivision of residence within their country, + * e.g. NY. Required if the country=“US” because certain states (e.g., NY) + * have state specific asset restrictions. + */ + subdivision?: string; + /** + * Optional API key for Coinbase Onramp. If not provided, the API key from + * OnchainKitProvider will be used. Required when using the utility without + * OnchainKitProvider or in a non-React environment. + */ + apiKey?: string; +} +``` + +## Returns + +`Promise` - Returns a promise that resolves to the available options for the specified location. + +See [`OnrampOptionsResponseData`](/builderkits/onchainkit/fund/types#onrampoptionsresponsedata) for full response type details. diff --git a/_pages/builderkits/onchainkit/fund/fetch-onramp-quote.mdx b/_pages/builderkits/onchainkit/fund/fetch-onramp-quote.mdx new file mode 100644 index 00000000..9b812d17 --- /dev/null +++ b/_pages/builderkits/onchainkit/fund/fetch-onramp-quote.mdx @@ -0,0 +1,112 @@ +--- +title: "`fetchOnrampQuote`" +--- + + +The `fetchOnrampQuote` utility provides a quote based on the asset the user would like to purchase, plus the network, fiat payment, payment currency, payment method, and country. This is useful for getting pricing information and fees before initiating a transaction. + +## Usage + + +```tsx twoslash [code] +import { fetchOnrampQuote } from '@coinbase/onchainkit/fund'; + +const quote = await fetchOnrampQuote({ + purchaseCurrency: 'ETH', + purchaseNetwork: 'ethereum', + paymentCurrency: 'USD', + paymentMethod: 'CARD', + paymentAmount: '100.00', + country: 'US', + subdivision: 'CA', // Required for US residents + apiKey: 'your-api-key', // Required when using without OnchainKitProvider or in non-React environment +}); +``` + +```json [return value] +{ + "paymentTotal": { + "value": "105.00", + "currency": "USD" + }, + "paymentSubtotal": { + "value": "100.00", + "currency": "USD" + }, + "purchaseAmount": { + "value": "0.05", + "currency": "ETH" + }, + "coinbaseFee": { + "value": "3.00", + "currency": "USD" + }, + "networkFee": { + "value": "2.00", + "currency": "USD" + }, + "quoteId": "quote_123" +} +``` + + +## Parameters + +```typescript +{ + /** + * ID of the crypto asset the user wants to purchase. + * Retrieved from the options API. + */ + purchaseCurrency: string; + + /** + * Name of the network that the purchase currency should be purchased on. + * Retrieved from the options API. If omitted, the default network for + * the crypto currency is used. + */ + purchaseNetwork?: string; + + /** + * Fiat currency of the payment amount, e.g., USD. + */ + paymentCurrency: string; + + /** + * ID of payment method used to complete the purchase. + * Retrieved from the options API. + */ + paymentMethod: string; + + /** + * Fiat amount the user wants to spend to purchase the crypto currency, + * inclusive of fees with two decimals of precision, e.g., "100.00". + */ + paymentAmount: string; + + /** + * ISO 3166-1 two-digit country code string representing the purchasing + * user's country of residence, e.g., US. + */ + country: string; + + /** + * ISO 3166-2 two-digit country subdivision code. Required if country="US" + * because certain states (e.g., NY) have state specific asset restrictions. + */ + subdivision?: string; + + /** + * Optional API key for Coinbase Onramp. If not provided, the API key from + * OnchainKitProvider will be used. Required when using the utility without + * OnchainKitProvider or in a non-React environment. + */ + apiKey?: string; +} +``` + +## Returns + +`Promise` - Returns a promise that resolves to the quote data containing payment amounts, fees, and quote ID. + +See [`OnrampQuoteResponseData`](/builderkits/onchainkit/fund/types#onrampquoteresponsedata) for full response type details. diff --git a/_pages/builderkits/onchainkit/fund/fetch-onramp-transaction-status.mdx b/_pages/builderkits/onchainkit/fund/fetch-onramp-transaction-status.mdx new file mode 100644 index 00000000..0b1bf298 --- /dev/null +++ b/_pages/builderkits/onchainkit/fund/fetch-onramp-transaction-status.mdx @@ -0,0 +1,66 @@ +--- +title: "`fetchOnrampTransactionStatus`" +--- + + +The `fetchOnrampTransactionStatus` utility retrieves the status of onramp transactions for a specific user. This is useful for tracking the progress of crypto purchases and displaying transaction history. + +## Usage + + +```tsx twoslash [code] +import { fetchOnrampTransactionStatus } from '@coinbase/onchainkit/fund'; + +const transactions = await fetchOnrampTransactionStatus({ + partnerUserId: 'user123', + nextPageKey: '', + pageSize: '10', + apiKey: 'your-api-key', // Required when using without OnchainKitProvider or in non-React environment +}); +``` + +```json [return value] +{ + "transactions": [ + { + "id": "tx123", + "status": "ONRAMP_TRANSACTION_STATUS_SUCCESS", + "purchaseAmount": { "value": "0.1", "currency": "ETH" }, + "paymentAmount": { "value": "200.00", "currency": "USD" }, + "network": "ethereum", + "createdAt": "2024-01-01T12:00:00Z" + } + ], + "nextPageKey": "next_page_token", + "totalCount": "1" +} +``` + + +## Parameters + +```typescript +{ + /** + * A unique identifier that will be associated with any transactions created + * by the user during their Onramp session. You can use this with the + * Transaction Status API to check the status of the user's transaction. + * See https://docs.cdp.coinbase.com/onramp/docs/api-reporting#buy-transaction-status + */ + partnerUserId: string; // Your unique identifier for the user + nextPageKey: string; // Token for pagination + pageSize: string; // Number of transactions per page + /** + * Optional API key for Coinbase Onramp. If not provided, the API key from + * OnchainKitProvider will be used. Required when using the utility without + * OnchainKitProvider or in a non-React environment. + */ + apiKey?: string; +} +``` + +## Returns + +`Promise` - Returns a promise that resolves to the transaction status data. + +See [`OnrampTransactionStatusResponseData`](/builderkits/onchainkit/fund/types#onramptransactionstatusresponsedata) for full response type details. diff --git a/_pages/builderkits/onchainkit/fund/fund-button.mdx b/_pages/builderkits/onchainkit/fund/fund-button.mdx new file mode 100644 index 00000000..0f22e0cd --- /dev/null +++ b/_pages/builderkits/onchainkit/fund/fund-button.mdx @@ -0,0 +1,232 @@ +--- +title: · OnchainKit +description: The `` component provides a way for users to onramp from fiat to crypto from within your app. +--- + +import { Avatar, Name } from '@coinbase/onchainkit/identity'; +// import { FundButton } from '../../../../src/fund'; +import { FundButton, getOnrampBuyUrl } from '@coinbase/onchainkit/fund'; +import { Wallet, ConnectWallet } from '@coinbase/onchainkit/wallet'; +import App from '@/components/App'; +import FundWrapper from '@/components/FundWrapper'; + +# `` + +The `` component provides a way for users to fund their wallet without leaving your app. It automatically +detects the user's wallet type (EOA vs Smart Wallet) and directs them to the appropriate funding URL. + +If your user connects a Coinbase Smart Wallet, it provides an easy way to access the Coinbase Smart Wallet +[Fund](https://keys.coinbase.com/fund) flow. Users will be able to buy and receive crypto, or use their Coinbase +balances onchain with [Magic Spend](https://www.smartwallet.dev/guides/magic-spend). + +If your user connects any other EOA wallet, it provides an easy way to access [Coinbase Onramp](https://docs.cdp.coinbase.com/onramp/docs/welcome/) +where your users will also be able to buy crypto using a fiat payment method, or transfer existing crypto from their +Coinbase account. + +Before using it, ensure you've completed all [Getting Started steps](/builderkits/onchainkit/getting-started). + +## Walkthrough + + + + 1. Get your Project ID from the [Coinbase Developer Platform Dashboard](https://portal.cdp.coinbase.com/). + + OnchainKit copy Project Id + + 2. Add your Project ID to your `.env` file. + + ```tsx twoslash [.env] + // @noErrors + NEXT_PUBLIC_ONCHAINKIT_API_KEY=YOUR_PUBLIC_API_KEY + NEXT_PUBLIC_CDP_PROJECT_ID=YOUR_CDP_PROJECT_ID // [!code ++] + ``` + + + ```tsx twoslash + // @noErrors + + {props.children} + + ``` + + + ```tsx + import { FundButton } from '@coinbase/onchainkit/fund'; + + + ``` + + + + {({ address }) => { + if (address) { + return ( + + ) + } + return <> + + + + + + + ; + }} + + + + + + + +**Troubleshooting** + +If you see a "something went wrong" error message when navigating to pay.coinbase.com, make sure you have "enforce +secure initialization" disabled on the [Onramp config page in Coinbase Developer Platform Dashboard](https://portal.cdp.coinbase.com/products/onramp). + +OnchainKit require secure init + + + +## Customizing the funding experience + +You can customize the Coinbase Onramp experience by bringing your own Onramp URL and passing it to the `````` +component. We provide the [`getOnrampBuyUrl`](/builderkits/onchainkit/fund/get-onramp-buy-url) utility to help you generate a Coinbase Onramp +URL tailored to your use case. + +```tsx +import { FundButton, getOnrampBuyUrl } from '@coinbase/onchainkit/fund'; +import { useAccount } from 'wagmi'; + +const projectId = 'YOUR_CDP_PROJECT_ID'; +const { address } = useAccount(); + +const onrampBuyUrl = getOnrampBuyUrl({ + projectId, + addresses: { [address]: ['base'] }, + assets: ['USDC'], + presetFiatAmount: 20, + fiatCurrency: 'USD' +}); + + +``` + + + + {({ address, projectId }) => { + if (address && projectId) { + const onrampBuyUrl = getOnrampBuyUrl({ + projectId, + addresses: { [address]: ['base'] }, + assets: ['USDC'], + presetFiatAmount: 20, + fiatCurrency: 'USD' + }); + return ( + + ) + } + return <> + + + + + + + ; + }} + + + +You can choose to have the funding URL open in a popup or a new tab using the `openIn` prop. + +```tsx + +``` + + + + {({ address }) => { + if (address) { + return ( + + ) + } + return <> + + + + + + + ; + }} + + + +## Customizing the fund button + +You can override the text on the fund button using the `text` prop, and hide the icon with the `hideIcon` prop. + +```tsx + +``` + + + + {({ address }) => { + if (address) { + return ( + + ) + } + return <> + + + + + + + ; + }} + + + +You can hide the text with the `hideText` prop. + +```tsx + +``` + + + + {({ address }) => { + if (address) { + return ( + <> + + + ) + } + return <> + + + + + + + ; + }} + + + +See [`FundButtonReact`](/builderkits/onchainkit/fund/types#fundbuttonreact) for the full list of customization options. + +## Props +- [`FundButtonReact`](/builderkits/onchainkit/fund/types#fundbuttonreact) diff --git a/_pages/builderkits/onchainkit/fund/fund-card.mdx b/_pages/builderkits/onchainkit/fund/fund-card.mdx new file mode 100644 index 00000000..97bdfee7 --- /dev/null +++ b/_pages/builderkits/onchainkit/fund/fund-card.mdx @@ -0,0 +1,247 @@ +--- +title: · OnchainKit +description: The `` component provides a complete fiat onramp experience with amount input, currency switching, and payment method selection. +--- + +import { Avatar, Name } from '@coinbase/onchainkit/identity'; +import { FundCard } from '@coinbase/onchainkit/fund'; +import { Wallet, ConnectWallet } from '@coinbase/onchainkit/wallet'; +import App from '@/components/App'; +import FundWrapper from '@/components/FundWrapper'; + +# `` + +FundCard + +The `` component provides a complete fiat onramp experience within your app. It includes: + +- Amount input with fiat/crypto switching +- Payment method selection (Coinbase, Apple Pay, Debit Card) +- Automatic exchange rate updates +- Smart handling of payment method restrictions (based on country and subdivision) + + +The Apple Pay and Debit Card onramp options are only available for Coinbase supported assets. + + + +## Prerequisites + +Before using the `FundCard` component, ensure you've completed the [Getting Started](/builderkits/onchainkit/installation/nextjs#get-your-client-api-key) steps. + + +To use the `FundCard` component, you'll need to provide a Client API Key in `OnchainKitProvider`. You can get one following our [Getting Started](/builderkits/onchainkit/installation/nextjs#get-your-client-api-key) steps. + + + + +This component requires a `projectId` to be set in the `OnchainKitProvider`. You can find your `projectId` on [Coinbase Developer Platform](https://portal.cdp.coinbase.com/products/onchainkit). + + + +## Usage + +### Drop in the `` component + +```tsx +import { FundCard } from '@coinbase/onchainkit/fund'; + +; +``` + + + + {({ address }) => { + if (address) { + return ; + } + return ( + <> + + + + + + + + ); + }} + + + +## Customization + +### Custom Header and Button Text + +You can customize the header and button text: + +```tsx + +``` + + + + {({ address }) => { + if (address) { + return ( + + ); + } + return ( + <> + + + + + + + + ); + }} + + + +### Custom Currency + +You can specify which fiat currency to use: + +```tsx + +``` + +### Preset Amount Inputs + +You can specify preset amount buttons: + +```tsx +const presetAmountInputs = ['10', '20', '50'] as const; + +; +``` + + +**Note: 3 preset amount inputs are required in order to show the preset amount buttons.** + + + +### Custom Content + +You can provide custom children to completely customize the card content while keeping the fund button functionality: + +```tsx + +
+

Custom Header

+ + +
+
+``` + +You can also reuse the existing children from the default implementation and add your own custom content. + +```tsx +import { + FundCardHeader, + FundCardAmountInput, + FundCardAmountInputTypeSwitch, + FundCardPresetAmountInputList, + FundCardPaymentMethodDropdown, + FundCardSubmitButton, + } from '@coinbase/onchainkit/fund'; + + + +

Custom Header instead of the default "FundCardHeader"

+ + + +
Any custom content
+ + +
Any custom content
+
+``` + + +**Note:** If you are using the custom components then you are going to need to access the state of the `FundCard` component. You can do this by using the `useFundContext` hook. + + + +```tsx +const { + asset, + currency, + selectedPaymentMethod, + setSelectedPaymentMethod, + fundAmountFiat, + setFundAmountFiat, + fundAmountCrypto, + setFundAmountCrypto, + selectedInputType, + setSelectedInputType, + exchangeRate, + setExchangeRate, + exchangeRateLoading, + setExchangeRateLoading, + submitButtonState, + setSubmitButtonState, + paymentMethods, + setPaymentMethods, + paymentMethodsLoading, + setPaymentMethodsLoading, + headerText, + buttonText, + country, + subdivision, + lifecycleStatus, + updateLifecycleStatus, + presetAmountInputs, + } = useFundContext(); +``` + +## Props + +- [`FundCardPropsReact`](/builderkits/onchainkit/fund/types#fundcardpropsreact) + +## Related Components + +- [``](/builderkits/onchainkit/fund/fund-button) diff --git a/_pages/builderkits/onchainkit/fund/get-onramp-buy-url.mdx b/_pages/builderkits/onchainkit/fund/get-onramp-buy-url.mdx new file mode 100644 index 00000000..27ff06b3 --- /dev/null +++ b/_pages/builderkits/onchainkit/fund/get-onramp-buy-url.mdx @@ -0,0 +1,42 @@ +--- +title: "`getOnrampBuyUrl`" +--- + + +The `getOnrampBuyUrl` utility is a helper method to generate a Coinbase Onramp URL. It helps you customize the funding +experience for your users. For example: + +- Selecting which assets should be available to buy/send +- Selecting which networks crypto should be received on +- Setting a default buy/send amount +- Setting a redirect URL to return your users to your app after they complete the fund flow + +## Usage + + +```tsx twoslash [code] +import { getOnrampBuyUrl } from '@coinbase/onchainkit/fund'; + +const projectId = 'YOUR_CDP_PROJECT_ID'; +const onrampBuyUrl = getOnrampBuyUrl({ + projectId, + addresses: { '0x1': ['base'] }, + assets: ['USDC'], + presetFiatAmount: 20, + fiatCurrency: 'USD', + redirectUrl: 'https://yourapp.com/onramp-return?param=foo', +}); +``` + +```json [return value] +'https://pay.coinbase.com/buy?addresses=%7B%220x1%22%3A%5B%22base%22%5D%7D&appId=project-id&assets=%5B%22USDC%22%5D&fiatCurrency=USD&presetFiatAmount=20&redirectUrl=https%3A%2F%2Fyourapp.com%2Fonramp-return%3Fparam%3Dfoo' +``` + + +## Returns + +`string` - Returns a full Coinbase Onramp URL that you can redirect your users to, or open in a popup. + +## Parameters + +[`GetOnrampUrlWithProjectIdParams`](/builderkits/onchainkit/fund/types#getonrampurlwithprojectidparams) | [`GetOnrampUrlWithSessionTokenParams`](/builderkits/onchainkit/fund/types#getonrampurlwithsessiontokenparams) diff --git a/_pages/builderkits/onchainkit/fund/setup-onramp-event-listeners.mdx b/_pages/builderkits/onchainkit/fund/setup-onramp-event-listeners.mdx new file mode 100644 index 00000000..2272aad5 --- /dev/null +++ b/_pages/builderkits/onchainkit/fund/setup-onramp-event-listeners.mdx @@ -0,0 +1,60 @@ +--- +title: "`setupOnrampEventListeners`" +--- + + +The `setupOnrampEventListeners` utility sets up event listeners for the Coinbase Onramp widget. It helps you handle various events like successful purchases, exits, and other user interactions. + +## Usage + + +```tsx twoslash [code] +// @errors: 2305 +import { setupOnrampEventListeners } from '@coinbase/onchainkit/fund'; +import type { SuccessEventData, OnrampError, EventMetadata } from '@coinbase/onchainkit/fund'; +const unsubscribe = setupOnrampEventListeners({ + onSuccess: (data: SuccessEventData) => { + console.log('Purchase successful:', data); + }, + onExit: (error: OnrampError) => { + if (error) { + console.error('Exit with error:', error); + } + }, + onEvent: (event: EventMetadata) => { + console.log('Event received:', event); + }, +}); + +// Clean up when done +unsubscribe(); +``` + +```ts [return value] +// Returns an unsubscribe function +() => void +``` + + +## Parameters + +```typescript +{ + host?: string; // Optional custom host URL + onSuccess?: (data?: SuccessEventData) => void; // Success callback + onExit?: (error?: OnrampError) => void; // Exit callback + onEvent?: (event: EventMetadata) => void; // General event callback +} +``` + +## Returns + +`() => void` - Returns an unsubscribe function that removes the event listeners when called. + +## Event Types + +See the following type definitions for event data: + +- [`SuccessEventData`](/builderkits/onchainkit/fund/types#successeventdata) +- [`OnrampError`](/builderkits/onchainkit/fund/types#onramperror) +- [`EventMetadata`](/builderkits/onchainkit/fund/types#eventmetadata) diff --git a/docs/pages/builderkits/onchainkit/fund/types.mdx b/_pages/builderkits/onchainkit/fund/types.mdx similarity index 100% rename from docs/pages/builderkits/onchainkit/fund/types.mdx rename to _pages/builderkits/onchainkit/fund/types.mdx diff --git a/_pages/builderkits/onchainkit/getting-started.mdx b/_pages/builderkits/onchainkit/getting-started.mdx new file mode 100644 index 00000000..944e0610 --- /dev/null +++ b/_pages/builderkits/onchainkit/getting-started.mdx @@ -0,0 +1,56 @@ +--- +title: "Getting Started" +--- + +import StartBuilding from "/snippets/start-building.mdx"; +import InstallationOptions from '/snippets/installation-options.mdx'; + + +OnchainKit is your go-to SDK for building beautiful onchain applications. Ship in minutes, not weeks. + +Anyone can build an onchain app in 15 minutes with OnchainKit. No blockchain experience required. + +## Why OnchainKit? + +OnchainKit streamlines app development by providing a comprehensive toolkit that combines powerful onchain features with developer-friendly design: + +- **Ergonomic design:** Full-stack tools that make complex onchain interactions intuitive +- **Battle-tested patterns:** Industry best practices packaged into ready-to-use solutions +- **Purpose-built components:** Pre-built modules for common onchain workflows +- **Framework agnostic:** Compatible with any React-supporting framework +- **Supercharged by Base:** Deep integration with Base's protocol features and ecosystem + +## Automatic Installation + +OnchainKit Template + +We recommend starting a new OnchainKit app using `create onchain`, which sets up everything automatically for you. To create a project, run: + +```bash [Terminal] +npm create onchain@latest +``` + +After the prompts, `create onchain` will create a folder with your project name and install the required dependencies. + +You can also checkout our pre-built templates: + +- [Onchain Commerce](https://onchain-commerce-template.vercel.app/) +- [NFT minting](https://ock-mint.vercel.app/) +- [Funding flow](https://github.com/fakepixels/fund-component) +- [Social profile](https://github.com/fakepixels/ock-identity) + + + These docs are LLM-friendly—reference [llms.txt](https://docs.base.org/builderkits/onchainkit/llms.txt) in your code editor to streamline builds and prompt smarter. + + +## Manual Installation + +Add OnchainKit to your existing project manually. + + + + diff --git a/_pages/builderkits/onchainkit/guides/ai-prompting-guide.mdx b/_pages/builderkits/onchainkit/guides/ai-prompting-guide.mdx new file mode 100644 index 00000000..b0f6505c --- /dev/null +++ b/_pages/builderkits/onchainkit/guides/ai-prompting-guide.mdx @@ -0,0 +1,260 @@ +--- +title: 'AI Prompting Guide' +description: Learn practical AI prompting techniques to enhance your coding workflow and get better results from AI coding assistants. +author: sohey +--- + +# Developer's Guide to Effective AI Prompting + +This guide helps developers leverage AI tools effectively in their coding workflow. Whether you're using Cursor, GitHub Copilot, or other AI assistants, +these strategies will help you get better results and integrate AI smoothly into your development process. + +## **Understanding Context Windows** + +### **Why Context Matters** + +AI coding assistants have what's called a "context window" \- the amount of text they can "see" and consider when generating responses. Think of it as the AI's working memory: + +- Most modern AI assistants can process thousands of tokens (roughly 4-5 words per token) +- Everything you share and everything the AI responds with consumes this limited space +- Once the context window fills up, parts of your conversational history may be lost. + +This is why providing relevant context upfront is crucial \- the AI can only work with what it can "see" in its current context window. + +### **Optimizing for Context Windows** + +To get the most out of AI assistants: + +1. **Prioritize relevant information**: Focus on sharing the most important details first. +2. **Remove unnecessary content**: Avoid pasting irrelevant code or documentation. +3. **Structure your requests**: Use clear sections and formatting to make information easy to process. +4. **Reference external resources**: For large codebases, consider sharing only the most relevant files. + +For larger projects, create and reference a central documentation file that summarizes key information, rather than repeatedly explaining the same context. + +## **Setting Up AI Tools** + +### **Configuring Cursor Rules** + +Cursor Rules allow you to provide consistent context to Cursor AI, making it more effective at understanding your codebase and providing relevant suggestions. + +#### **Creating Cursor Rules** + +1. Open the Command Palette in Cursor: + - Mac: `Cmd + Shift + P` + - Windows/Linux: `Ctrl + Shift + P` +2. Search for "Cursor Rules" and select the option to create or edit rules + +3. Add project-specific rules that help Cursor understand your project: + + - [Next.js](https://raw.githubusercontent.com/PatrickJS/awesome-cursorrules/refs/heads/main/rules/nextjs-tailwind-typescript-apps-cursorrules-prompt/.cursorrules) + - [Astro](https://raw.githubusercontent.com/PatrickJS/awesome-cursorrules/refs/heads/main/rules/astro-typescript-cursorrules-prompt-file/.cursorrules) + - [Vite](https://raw.githubusercontent.com/PatrickJS/awesome-cursorrules/refs/heads/main/rules/typescript-vite-tailwind-cursorrules-prompt-file/.cursorrules) + +4. Save your rules file and Cursor will apply these rules to its AI suggestions + +### **Setting Up an OnchainKit Project** + +To create a new OnchainKit project: + +```shell +npm create onchain@latest +``` + +After creating your project, prompt to generate comprehensive documentation for your new OnchainKit project. + +### **Creating Project Documentation** + +A comprehensive instructions file helps AI tools understand your project better. This should be created early in your project and updated regularly. + +**Ready-to-Use Prompt for Creating Instructions.md:** + +``` +Create a detailed instructions.md file for my project with the following sections: + +1. Overview: Summarize the project goals, problem statements, and core functionality. +2. Tech Stack: List all technologies, libraries, frameworks with versions. +3. Project Structure: Document the file organization with explanations. +4. Coding Standards: Document style conventions, linting rules, and patterns. +5. User Stories: Key functionality from the user perspective. +6. APIs and Integrations: External services and how they connect. +``` + + +Note: When planning architecture or making complex design decisions, use AI models with strong reasoning—like o4 mini or Claude 3.7 Sonnet. They excel at thinking through tradeoffs, edge cases, and long-term planning. + + + +## **Effective Prompting Strategies** + +### **Be Specific and Direct** + +Start with clear commands and be specific about what you want. AI tools respond best to clear, direct instructions. + +**Example:** ❌ "Help me with my code" + ✅ "Refactor this authentication function to use async/await instead of nested then() calls" + +### **Provide Context for Complex Tasks** + +**Ready-to-Use Prompt:** + +``` + I'm working on a onchainkit project using [frameworks/libraries]. I need your help with: + +1. Problem: [describe specific issue] +2. Current approach: [explain what you've tried] +3. Constraints: [mention any technical limitations] +4. Expected outcome: [describe what success looks like] + +Here's the relevant documentation @https://docs.base.org/builderkits/onchainkit/llms.txt + +Here's the relevant code: +[paste your code] +``` + +### **Ask for Iterations** + +Start simple and refine through iterations rather than trying to get everything perfect in one go. + +**Ready-to-Use Prompt:** + +``` +Let's approach this step by step: +1. First, implement a basic version of [feature] with minimal functionality. +2. Then, we'll review and identify areas for improvement. +3. Next, let's add error handling and edge cases. +4. Finally, we'll optimize for performance. + +Please start with step 1 now. +``` + +## **Working with OnchainKit** + +### **Leveraging LLMs.txt for Documentation** + +The OnchainKit project provides optimized documentation in the form of LLMs.txt files. These files are specifically formatted to be consumed by AI models: + +1. Use [OnchainKit Documentation](https://docs.base.org/builderkits/onchainkit/llms.txt) +2. Find the component you want to implement +3. Copy the corresponding LLMs.txt url +4. Paste it into your prompt to provide context + +**Example LLMs.txt Usage:** + +``` +I'm implementing a swap component with OnchainKit. Here's the relevant LLMs.txt: + +@https://docs.base.org/builderkits/onchainkit/llms.txt + +Based on this documentation, please show me how to implement a wallet connector that: +1. Swap from Base USDC to Base ETH. +2. Handles connection states properly. +3. Includes error handling. +4. Follows best practices for user experience. +``` + +### **Component Integration Example** + +**Ready-to-Use Prompt for Token Balance Display:** + +``` +I need to implement a new feature in my project. + +1. Shows the connected wallet's balance of our {ERC20 token}. +2. It updates when the balance changes. +3. Handles loading and error states appropriately. +4. Follows our project's coding standards. +5. Update the instructions.md to reflect this new implementation. + +``` + +**_\*update the prompt a token of your choice_** + +## **Debugging with AI** + +### **Effective Debugging Prompts** + +**Ready-to-Use Prompt for Bug Analysis:** + +``` +I'm encountering an issue with my code: + +1. Expected behavior: [what should happen] +2. Actual behavior: [what's happening instead] +3. Error messages: [include any errors] +4. Relevant code: [paste the problematic code] + +Please analyze this situation step by step and help me: +1. Identify potential causes of this issue +2. Suggest debugging steps to isolate the problem +3. Propose possible solutions +``` + +**Ready-to-Use Prompt for Adding Debug Logs:** + +``` +I need to debug the following function. Please add comprehensive logging statements that will help me trace: +1. Input values and their types +2. Function execution flow +3. Intermediate state changes +4. Output values or errors + +Here's my code: +[paste your code] +``` + +### **When You're Stuck** + +If you're uncertain how to proceed: + +**Ready-to-Use Clarification Prompt:** + +``` +I'm unsure how to proceed with [specific task]. Here's what I know: +1. [context about the problem] +2. [what you've tried] +3. [specific areas where you need guidance] + +What additional information would help you provide better assistance? +``` + +## **Advanced Prompting Techniques** + +Modern AI assistants have capabilities that you can leverage with these advanced techniques: + +1. **Step-by-step reasoning**: Ask the AI to work through problems systematically + +``` +Please analyze this code step by step and identify potential issues. +``` + +2. **Format specification**: Request specific formats for clarity + +``` +Please structure your response as a tutorial with code examples and explanations. +``` + +3. **Length guidance**: Indicate whether you want brief or detailed responses + +``` +Please provide a concise explanation in 2-3 paragraphs. +``` + +4. **Clarify ambiguities**: Help resolve unclear points when you receive multiple options + +``` +I notice you suggested two approaches. To clarify, I'd prefer to use the first approach with TypeScript. +``` + +## **Best Practices Summary** + +1. **Understand context limitations**: Recognize that AI tools have finite context windows and prioritize information accordingly +2. **Provide relevant context**: Share code snippets, error messages, and project details that matter for your specific question +3. **Be specific in requests**: Clear, direct instructions yield better results than vague questions +4. **Break complex tasks into steps**: Iterative approaches often work better for complex problems +5. **Request explanations**: Ask the AI to explain generated code or concepts you don't understand +6. **Use formatting for clarity**: Structure your prompts with clear sections and formatting +7. **Reference documentation**: When working with specific libraries like OnchainKit, share relevant documentation +8. **Test and validate**: Always review and test AI-generated code before implementing +9. **Build on previous context**: Refer to earlier parts of your conversation when iterating +10. **Provide feedback**: Let the AI know what worked and what didn't to improve future responses diff --git a/_pages/builderkits/onchainkit/guides/build-onchain-apps.mdx b/_pages/builderkits/onchainkit/guides/build-onchain-apps.mdx new file mode 100644 index 00000000..4bf59cfe --- /dev/null +++ b/_pages/builderkits/onchainkit/guides/build-onchain-apps.mdx @@ -0,0 +1,98 @@ +--- +title: Build Onchain Apps · OnchainKit +description: Our onchain app template streamlines your initial app setup and seamlessly integrates onchain components with web2 infrastructure, saving you weeks of effort. +--- + +# Build Onchain Apps with OnchainKit ⛵️ 🌊 + +Build your first onchain app effortlessly with OnchainKit's **app template**. Save weeks of initial setup +and easily integrate onchain components with web2 infrastructure. + +Our opinionated approach streamlines early decisions, making your development process smoother. + +Whether you're a hackathon participant or an ambitious entrepreneur aiming to build the next big thing, this template is tailored for you. + +Build Onchain Apps with OnchainKit + +Play with it live [here](https://onchain-app-template.vercel.app). + +## Out of the box + +- Next.js v14 with App routing 🏗️ +- Ethereum L2 support through Base 🔵 +- Easy account creation with Smart Wallet +- Live examples for Minting and Paymaster experiences with wagmi and Viem 🚀 +- Latest styling best practices with Tailwind CSS 💅 +- Easy maintenance with linting, formatting, and tests ✅ + +## Getting Started + + + + Go to https://github.com/coinbase/onchain-app-template and click on the "Use this template" button to create a new repository based on the template. + + Use OnchainKit template + + + Get your [Client API Key](https://portal.cdp.coinbase.com/projects/api-keys/client-key) from Coinbase Developer Platform. + + OnchainKit copy Client API Key + + In order to use RainbowKit, you'd also need to obtain a Wallet Connector project ID at [WalletConnect](https://cloud.reown.com/app). + + + + Create a new file in your project's root directory and name it `.env`. + + OnchainKit define Client API Key + + ```tsx [.env] + NEXT_PUBLIC_CDP_API_KEY=YOUR_PUBLIC_API_KEY + NEXT_PUBLIC_WC_PROJECT_ID=YOUR_WALLETCONNECT_PROJECT_ID + ``` + + + In your new onchain app repository, run the following commands to install the dependencies: + + ```bash + # Install bun in case you don't have it + curl -fsSL https://bun.sh/install | bash + + # Install packages + bun i + ``` + + + Now you are ready to run the app and start building onchain experiences! + + ```bash + # Run Next app + bun run dev + ``` + + + +## Need more help? + +If you have any questions or need help, feel free to reach out to us on [Discord](https://discord.gg/invite/cdp) +or open a [Github issue](https://github.com/coinbase/onchainkit/issues) or DM us +on X at [@onchainkit](https://x.com/onchainkit), [@zizzamia](https://x.com/zizzamia), [@fkpxls](https://x.com/fkpxls). diff --git a/docs/pages/builderkits/onchainkit/guides/contribution.mdx b/_pages/builderkits/onchainkit/guides/contribution.mdx similarity index 100% rename from docs/pages/builderkits/onchainkit/guides/contribution.mdx rename to _pages/builderkits/onchainkit/guides/contribution.mdx diff --git a/docs/pages/builderkits/onchainkit/guides/lifecycle-status.mdx b/_pages/builderkits/onchainkit/guides/lifecycle-status.mdx similarity index 100% rename from docs/pages/builderkits/onchainkit/guides/lifecycle-status.mdx rename to _pages/builderkits/onchainkit/guides/lifecycle-status.mdx diff --git a/_pages/builderkits/onchainkit/guides/reporting-bug.mdx b/_pages/builderkits/onchainkit/guides/reporting-bug.mdx new file mode 100644 index 00000000..25c7ddc0 --- /dev/null +++ b/_pages/builderkits/onchainkit/guides/reporting-bug.mdx @@ -0,0 +1,29 @@ +--- +title: Reporting a bug · OnchainKit +description: Help us make OnchainKit better +--- + +# OnchainKit Bug Reporting Guide + +We look at all of your bug reports and will do our best to fix them as quickly as possible. + + + + Navigate to [Issues tab](https://github.com/coinbase/onchainkit/issues) on Github and click the "New issue" button. + + + Pick the "Bug Report" option and fill out the form to the best of your ability. + + + We'll do our best to respond to your issue on Github as soon as possible. + + + +### Have a special request? +You can tag us on [Discord](https://discord.com/channels/1220414409550336183/1253768005863739565) or DM us on [X](https://x.com/Onchainkit). + +We're most active on X and Discord, so if you're able to, please create an issue there. + +### Found a security vulnerability? +If you've found a security vulnerability, please report it to our [HackerOne Program](https://hackerone.com/coinbase?type=team). We offer generous rewards for bounties. + diff --git a/_pages/builderkits/onchainkit/guides/tailwind.mdx b/_pages/builderkits/onchainkit/guides/tailwind.mdx new file mode 100644 index 00000000..37c5cc7e --- /dev/null +++ b/_pages/builderkits/onchainkit/guides/tailwind.mdx @@ -0,0 +1,100 @@ +--- +title: Tailwind CSS Integration Guide · OnchainKit +description: Learn how to integrate Tailwind CSS with OnchainKit +--- + +# Tailwind CSS Integration Guide + +OnchainKit comes with first class support for `tailwindcss`. + + + + You can use the default styles without any customization. + Just place this at the top of your application's entry point to have the components work out of the box. + + ```javascript + import '@coinbase/onchainkit/styles.css'; + ``` + + + Depending on your dark mode setup, you may have to add `safelist: ['dark']` to your Tailwind config. + + ```javascript filename="tailwind.config.js" + /** @type {import('tailwindcss').Config} */ + export default { + content: ['./src/**/*.{ts,tsx}'], + darkMode: ['class'], // [!code focus] + safelist: ['dark'], // [!code focus] + theme: { + fontFamily: { + sans: ['Inter', 'sans-serif'], + }, + }, + plugins: [], + }; + ``` + + + There are many ways to handle color mode. + + In OnchainKit, toggling color mode works by adding / removing class name `dark` to the root html tag. + + + To override default colorscheme, you need to modify the following css variables: + + ```css + @tailwind base; + + @layer base { + :root { + --ock-font-family: 'your-custom-value'; + --ock-border-radius: 'your-custom-value'; + --ock-border-radius-inner: 'your-custom-value'; + --ock-text-inverse: 'your-custom-value'; + --ock-text-foreground: 'your-custom-value'; + --ock-text-foreground-muted: 'your-custom-value'; + --ock-text-error: 'your-custom-value'; + --ock-text-primary: 'your-custom-value'; + --ock-text-success: 'your-custom-value'; + --ock-text-warning: 'your-custom-value'; + --ock-text-disabled: 'your-custom-value'; + + --ock-bg-default: 'your-custom-value'; + --ock-bg-default-hover: 'your-custom-value'; + --ock-bg-default-active: 'your-custom-value'; + --ock-bg-alternate: 'your-custom-value'; + --ock-bg-alternate-hover: 'your-custom-value'; + --ock-bg-alternate-active: 'your-custom-value'; + --ock-bg-inverse: 'your-custom-value'; + --ock-bg-inverse-hover: 'your-custom-value'; + --ock-bg-inverse-active: 'your-custom-value'; + --ock-bg-primary: 'your-custom-value'; + --ock-bg-primary-hover: 'your-custom-value'; + --ock-bg-primary-active: 'your-custom-value'; + --ock-bg-primary-washed: 'your-custom-value'; + --ock-bg-primary-disabled: 'your-custom-value'; + --ock-bg-secondary: 'your-custom-value'; + --ock-bg-secondary-hover: 'your-custom-value'; + --ock-bg-secondary-active: 'your-custom-value'; + --ock-bg-error: 'your-custom-value'; + --ock-bg-warning: 'your-custom-value'; + --ock-bg-success: 'your-custom-value'; + --ock-bg-default-reverse: 'your-custom-value'; + + --ock-icon-color-primary: 'your-custom-value'; + --ock-icon-color-foreground: 'your-custom-value'; + --ock-icon-color-foreground-muted: 'your-custom-value'; + --ock-icon-color-inverse: 'your-custom-value'; + --ock-icon-color-error: 'your-custom-value'; + --ock-icon-color-success: 'your-custom-value'; + --ock-icon-color-warning: 'your-custom-value'; + + --ock-line-primary: 'your-custom-value'; + --ock-line-default: 'your-custom-value'; + --ock-line-heavy: 'your-custom-value'; + --ock-line-inverse: 'your-custom-value'; + } + } + ``` + + diff --git a/docs/pages/builderkits/onchainkit/guides/telemetry.mdx b/_pages/builderkits/onchainkit/guides/telemetry.mdx similarity index 100% rename from docs/pages/builderkits/onchainkit/guides/telemetry.mdx rename to _pages/builderkits/onchainkit/guides/telemetry.mdx diff --git a/docs/pages/builderkits/onchainkit/guides/themes.mdx b/_pages/builderkits/onchainkit/guides/themes.mdx similarity index 100% rename from docs/pages/builderkits/onchainkit/guides/themes.mdx rename to _pages/builderkits/onchainkit/guides/themes.mdx diff --git a/_pages/builderkits/onchainkit/guides/troubleshooting.mdx b/_pages/builderkits/onchainkit/guides/troubleshooting.mdx new file mode 100644 index 00000000..3b45fe27 --- /dev/null +++ b/_pages/builderkits/onchainkit/guides/troubleshooting.mdx @@ -0,0 +1,141 @@ +--- +title: "Troubleshooting" +--- + + +This guide covers common issues you may encounter while using OnchainKit. If you don't find your issue here, try searching our [GitHub Issues](https://github.com/coinbase/onchainkit/issues) or joining our [Discord Community](https://discord.gg/invite/cdp). + +## Common Issues + +### Environment Setup + +- **Missing API Key** + + - Error: "Project ID is required for this component" + - Solution: Add your Client API Key to `.env`: + + ```dotenv + NEXT_PUBLIC_CDP_API_KEY=YOUR_PUBLIC_API_KEY + ``` + +- **Invalid Environment Variables** + + - Error: "Cannot find environment variable" + - Solution: Use the correct variable name for your framework: + - Next.js: `NEXT_PUBLIC_CDP_API_KEY` + - Vite: `VITE_PUBLIC_ONCHAINKIT_API_KEY` + - Astro: `PUBLIC_ONCHAINKIT_API_KEY` + +- **Contracts Not Available** + - Error: "Contracts are not available" or "Contracts not available for LifecycleStatus" + - Solutions: + - Verify `NEXT_PUBLIC_ONCHAINKIT_API_KEY` is set correctly + - For Checkout component with `chargeHandler`, also set: + ```dotenv + NEXT_PUBLIC_COINBASE_COMMERCE_API_KEY=YOUR_COMMERCE_API_KEY + ``` + - Ensure API keys are properly exposed in your environment + +### Dependencies + +- **Version Compatibility** + - Issue: Unexpected behavior or type errors + - Solution: Ensure compatible versions: + ```json + { + "dependencies": { + "@coinbase/onchainkit": "latest", + "viem": "^2.0.0", + "@wagmi/core": "^2.0.0" + } + } + ``` + +### Provider Configuration + +- **Missing OnchainKitProvider** + + - Error: "OnchainKit context not found" + - Solution: Wrap your app with OnchainKitProvider and [configure](/builderkits/onchainkit/getting-started) properly: + + ```tsx + import { OnchainKitProvider } from '@coinbase/onchainkit'; + import { base } from 'viem/chains'; + + export default function App({ children }) { + return ( + + {children} + + ); + } + ``` + +### Wallet Connection + +- **Connection Failed** + + - Error: "Unable to connect wallet" + - Solutions: + - Verify wallet extension is installed and unlocked + - Check [supported chains configuration](/builderkits/onchainkit/wallet/wallet) + - Ensure proper network selection in wallet + - Verify RPC endpoints are accessible + +- **Chain Switching Issues** + - Error: "Failed to switch chain" + - Solutions: + - Verify chain ID is supported by OnchainKit + - Check wallet has required permissions + - Ensure RPC endpoints are configured correctly + - Add chain to wallet if not already added + +### Transaction Issues + +- **Gas Estimation Failed** + - Error: "Gas estimation failed" + - Solutions: + - Verify sufficient balance for gas + - Check transaction parameters are valid + - Ensure proper network [configuration](/builderkits/onchainkit/transaction/transaction) + +### Identity Components + +### Theme Issues + +- **Dark Mode Not Working** + + - Error: "Dark mode styles not applying" + - Solution: Configure Tailwind and OnchainKit properly: + + ```js + // tailwind.config.js + module.exports = { + darkMode: ['class'], + safelist: ['dark'], + // ... rest of config + } + ``` + +### React Native + +- ** React Native Support ** + - OnchainKit's components are not supported for use in React Native, however, you can use utility functions, like `getName`, as well as some hooks in your React Native app. When using these utility functions, you may need to import them directly rather than through the export file. + - Example: `import { getName } from '@coinbase/onchainkit/esm/identity/utils/getName.js';` rather than `import { getName } from '@coinbase/onchainkit/identity;` + +### Module Resolution + +- **Module Resolution Errors** + - Error: "Cannot find module ... or its corresponding type declarations. Consider updating to 'node16', 'nodenext', or 'bundler'" + - Solution: Update your Node.js version or use a compatible bundler. We recommend using Node 18+ and `"moduleResolution": "NodeNext"` for the best developer experience. OnchainKit supports only ES Modules and does not support CommonJS modules. + +## Getting Help + +Need more help? + +- [Discord Community](https://discord.gg/invite/cdp) +- [X/Twitter Support](https://x.com/onchainkit) +- [GitHub Issues](https://github.com/coinbase/onchainkit/issues) diff --git a/_pages/builderkits/onchainkit/guides/use-basename-in-onchain-app.mdx b/_pages/builderkits/onchainkit/guides/use-basename-in-onchain-app.mdx new file mode 100644 index 00000000..833afc8b --- /dev/null +++ b/_pages/builderkits/onchainkit/guides/use-basename-in-onchain-app.mdx @@ -0,0 +1,95 @@ +--- +title: Use Basename · OnchainKit +description: Integrate Basenames into your onchain app, in just a few steps. +--- +import { Avatar, Name } from '@coinbase/onchainkit/identity'; +import App from '@/components/App'; +import { base } from 'viem/chains'; + +# Use Basename + +Basenames are an essential onchain building block that empowers builders to establish their identity on Base by registering human-readable names for their wallet addresses. + +They operate entirely onchain, utilizing the same technology as ENS names, and are deployed on Base. + +You can integrate [Basenames](https://www.base.org/names) into your app with these few steps. + + + + Follow the [Getting Started](/builderkits/onchainkit/getting-started) guide to install the package. + + + Update to the latest version and choose from the following steps: a React component approach, a React hook, or a pure TypeScript utility function. + + + + +## React components with `` and `` + +Use the [``](/builderkits/onchainkit/identity/avatar) and [``](/builderkits/onchainkit/identity/name) components to display Basenames associated with Ethereum addresses. + +The `chain` prop is optional and setting to Base, it's what makes the components switch from ENS to Basenames. + +```tsx twoslash +// @noErrors: 2657 - JSX expressions must have one parent element +import { Avatar, Name } from '@coinbase/onchainkit/identity'; +import { base } from 'viem/chains'; + +const address = '0x02feeb0AdE57b6adEEdE5A4EEea6Cf8c21BeB6B1'; + +// omitted component code for brevity + + +``` + + + + + + +## React hooks with `useAvatar` and `useName` + +Use the [`useAvatar`](/builderkits/onchainkit/identity/use-avatar) and [`useName`](/builderkits/onchainkit/identity/use-name) hooks to get Basenames associated with Ethereum addresses. + +The hooks are incredibly useful for building custom components while leveraging OnchainKit for efficient data fetching. + + +```tsx twoslash [code] +import { useAvatar, useName } from '@coinbase/onchainkit/identity'; +import { base } from 'viem/chains'; + +const address = '0x02feeb0AdE57b6adEEdE5A4EEea6Cf8c21BeB6B1'; +const basename = 'zizzamia.base.eth'; +const { data: avatar, isLoading: avatarIsLoading } = await useAvatar({ ensName: basename, chain: base }); +const { data: name, isLoading: nameIsLoading } = await useName({ address, chain: base }); +``` + +```ts [return value] +{ data: 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzAwMCIgaGVpZ2h0PSIzMDAwIiB2aWV3Qm94PSIwIDAgMzAwMCAzMDAwIiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMF81NTY5XzcyODM1KSI+PHJlY3Qgd2lkdGg9IjMwMDAiIGhlaWdodD0iMzAwMCIgZmlsbD0iIzE1NURGRCIvPjxjaXJjbGUgY3g9IjE1MDAiIGN5PSIxNTAwIiByPSIxNTAwIiBmaWxsPSIjMTU1REZEIi8+PHBhdGggZD0iTTI3MTMuMTMgMTUwMEMyNzMxLjIgMTY4MC45MiAyNjE1LjEzIDE4MTguMTUgMjUwNy43OCAxOTI0LjQyQzIzOTQuNyAyMDMyLjEzIDIyOTAuNDQgMjEwOC44OCAyMjAwLjg4IDIyMDAuNjFDMjEwOS4xNSAyMjkwLjE2IDIwMzIuMjIgMjM5NC42MSAxOTI0LjUxIDI1MDcuNjhDMTgxOC4xNSAyNjE1LjA0IDE2ODAuOTIgMjczMS4xMSAxNTAwIDI3MTMuMTNDMTMxOS4wOCAyNzMxLjIgMTE4MS44NSAyNjE1LjEzIDEwNzUuNTggMjUwNy43OEM5NjcuODY2IDIzOTQuNyA4OTEuMTIgMjI5MC40NCA3OTkuMzg5IDIyMDAuODhDNzA5LjgzNyAyMTA5LjE1IDYwNS4zOSAyMDMyLjIyIDQ5Mi4zMTUgMTkyNC41MUMzODQuOTYyIDE4MTguMTUgMjY4Ljg5IDE2ODAuOTIgMjg2Ljg3MyAxNTAwQzI2OC43OTkgMTMxOS4wOCAzODQuODcxIDExODEuODUgNDkyLjIyNCAxMDc1LjU4QzYwNS4yOTkgOTY3Ljg2NiA3MDkuNTY0IDg5MS4xMiA3OTkuMTE2IDc5OS4zODlDODkwLjg0OCA3MDkuODM3IDk2Ny43NzUgNjA1LjM5IDEwNzUuNDkgNDkyLjMxNUMxMTgxLjg1IDM4NC44NzEgMTMxOS4wOCAyNjguNzk5IDE1MDAgMjg2Ljg3M0MxNjgwLjkyIDI2OC43OTkgMTgxOC4xNSAzODQuODcxIDE5MjQuNDIgNDkyLjIyNEMyMDMyLjEzIDYwNS4yOTkgMjEwOC44OCA3MDkuNTY0IDIyMDAuNjEgNzk5LjExNkMyMjkwLjE2IDg5MC44NDggMjM5NC42MSA5NjcuNzc1IDI1MDcuNjggMTA3NS40OUMyNjE1LjA0IDExODEuODUgMjczMS4xMSAxMzE5LjA4IDI3MTMuMTMgMTUwMFoiIGZpbGw9IndoaXRlIi8+PHBhdGggZD0iTTEzOTEuMDYgMTUwMEMxMzkxLjA2IDE2NDcuODkgMTM1OC40IDE3ODEuNjIgMTMwNS43NCAxODc4LjI4QzEyNTMuMDMgMTk3NS4wNSAxMTgwLjY5IDIwMzQgMTEwMS41MyAyMDM0QzEwMjIuMzYgMjAzNCA5NTAuMDMxIDE5NzUuMDUgODk3LjMxNCAxODc4LjI4Qzg0NC42NiAxNzgxLjYyIDgxMiAxNjQ3Ljg5IDgxMiAxNTAwQzgxMiAxMzUyLjExIDg0NC42NiAxMjE4LjM4IDg5Ny4zMTQgMTEyMS43MkM5NTAuMDMxIDEwMjQuOTUgMTAyMi4zNiA5NjYgMTEwMS41MyA5NjZDMTE4MC42OSA5NjYgMTI1My4wMyAxMDI0Ljk1IDEzMDUuNzQgMTEyMS43MkMxMzU4LjQgMTIxOC4zOCAxMzkxLjA2IDEzNTIuMTEgMTM5MS4wNiAxNTAwWiIgZmlsbD0iIzE1NURGRCIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSI2Ii8+PGVsbGlwc2UgY3g9IjExMDIuNTciIGN5PSIxMTk0LjkzIiByeD0iMTI2LjQxNCIgcnk9IjIzMS45MzQiIGZpbGw9IndoaXRlIi8+PHBhdGggZD0iTTIxODcuMTYgMTUwMEMyMTg3LjE2IDE2NDcuODkgMjE1NC41IDE3ODEuNjIgMjEwMS44NCAxODc4LjI4QzIwNDkuMTIgMTk3NS4wNSAxOTc2Ljc5IDIwMzQgMTg5Ny42MyAyMDM0QzE4MTguNDYgMjAzNCAxNzQ2LjEzIDE5NzUuMDUgMTY5My40MSAxODc4LjI4QzE2NDAuNzYgMTc4MS42MiAxNjA4LjEgMTY0Ny44OSAxNjA4LjEgMTUwMEMxNjA4LjEgMTM1Mi4xMSAxNjQwLjc2IDEyMTguMzggMTY5My40MSAxMTIxLjcyQzE3NDYuMTMgMTAyNC45NSAxODE4LjQ2IDk2NiAxODk3LjYzIDk2NkMxOTc2Ljc5IDk2NiAyMDQ5LjEyIDEwMjQuOTUgMjEwMS44NCAxMTIxLjcyQzIxNTQuNSAxMjE4LjM4IDIxODcuMTYgMTM1Mi4xMSAyMTg3LjE2IDE1MDBaIiBmaWxsPSIjMTU1REZEIiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjYiLz48ZWxsaXBzZSBjeD0iMTg5Ni41OCIgY3k9IjExOTQuOTMiIHJ4PSIxMjYuNDE0IiByeT0iMjMxLjkzNCIgZmlsbD0id2hpdGUiLz48L2c+PGRlZnM+PGNsaXBQYXRoIGlkPSJjbGlwMF81NTY5XzcyODM1Ij48cmVjdCB3aWR0aD0iMzAwMCIgaGVpZ2h0PSIzMDAwIiBmaWxsPSJ3aGl0ZSIvPjwvY2xpcFBhdGg+PC9kZWZzPjwvc3ZnPg==', isLoading: false } +{ data: 'zizzamia.base.eth', isLoading: false } +``` + + +## Typescript utility with `getAvatar` and `getName` + +Use the [`getAvatar`](/builderkits/onchainkit/identity/get-avatar) and [`getName`](/builderkits/onchainkit/identity/get-name) functions to get Basenames associated with Ethereum addresses. + +Being pure functions, it seamlessly integrates into any TypeScript project, including Vue, Angular, Svelte, or Node.js. + + +```tsx twoslash [code] +import { getAvatar, getName } from '@coinbase/onchainkit/identity'; +import { base } from 'viem/chains'; + +const address = '0x02feeb0AdE57b6adEEdE5A4EEea6Cf8c21BeB6B1'; +const basename = 'zizzamia.base.eth'; +const avatar = await getAvatar({ ensName: basename, chain: base }); +const name = await getName({ address, chain: base }); +``` + +```ts [return value] +data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzAwMCIgaGVpZ2h0PSIzMDAwIiB2aWV3Qm94PSIwIDAgMzAwMCAzMDAwIiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMF81NTY5XzcyODM1KSI+PHJlY3Qgd2lkdGg9IjMwMDAiIGhlaWdodD0iMzAwMCIgZmlsbD0iIzE1NURGRCIvPjxjaXJjbGUgY3g9IjE1MDAiIGN5PSIxNTAwIiByPSIxNTAwIiBmaWxsPSIjMTU1REZEIi8+PHBhdGggZD0iTTI3MTMuMTMgMTUwMEMyNzMxLjIgMTY4MC45MiAyNjE1LjEzIDE4MTguMTUgMjUwNy43OCAxOTI0LjQyQzIzOTQuNyAyMDMyLjEzIDIyOTAuNDQgMjEwOC44OCAyMjAwLjg4IDIyMDAuNjFDMjEwOS4xNSAyMjkwLjE2IDIwMzIuMjIgMjM5NC42MSAxOTI0LjUxIDI1MDcuNjhDMTgxOC4xNSAyNjE1LjA0IDE2ODAuOTIgMjczMS4xMSAxNTAwIDI3MTMuMTNDMTMxOS4wOCAyNzMxLjIgMTE4MS44NSAyNjE1LjEzIDEwNzUuNTggMjUwNy43OEM5NjcuODY2IDIzOTQuNyA4OTEuMTIgMjI5MC40NCA3OTkuMzg5IDIyMDAuODhDNzA5LjgzNyAyMTA5LjE1IDYwNS4zOSAyMDMyLjIyIDQ5Mi4zMTUgMTkyNC41MUMzODQuOTYyIDE4MTguMTUgMjY4Ljg5IDE2ODAuOTIgMjg2Ljg3MyAxNTAwQzI2OC43OTkgMTMxOS4wOCAzODQuODcxIDExODEuODUgNDkyLjIyNCAxMDc1LjU4QzYwNS4yOTkgOTY3Ljg2NiA3MDkuNTY0IDg5MS4xMiA3OTkuMTE2IDc5OS4zODlDODkwLjg0OCA3MDkuODM3IDk2Ny43NzUgNjA1LjM5IDEwNzUuNDkgNDkyLjMxNUMxMTgxLjg1IDM4NC44NzEgMTMxOS4wOCAyNjguNzk5IDE1MDAgMjg2Ljg3M0MxNjgwLjkyIDI2OC43OTkgMTgxOC4xNSAzODQuODcxIDE5MjQuNDIgNDkyLjIyNEMyMDMyLjEzIDYwNS4yOTkgMjEwOC44OCA3MDkuNTY0IDIyMDAuNjEgNzk5LjExNkMyMjkwLjE2IDg5MC44NDggMjM5NC42MSA5NjcuNzc1IDI1MDcuNjggMTA3NS40OUMyNjE1LjA0IDExODEuODUgMjczMS4xMSAxMzE5LjA4IDI3MTMuMTMgMTUwMFoiIGZpbGw9IndoaXRlIi8+PHBhdGggZD0iTTEzOTEuMDYgMTUwMEMxMzkxLjA2IDE2NDcuODkgMTM1OC40IDE3ODEuNjIgMTMwNS43NCAxODc4LjI4QzEyNTMuMDMgMTk3NS4wNSAxMTgwLjY5IDIwMzQgMTEwMS41MyAyMDM0QzEwMjIuMzYgMjAzNCA5NTAuMDMxIDE5NzUuMDUgODk3LjMxNCAxODc4LjI4Qzg0NC42NiAxNzgxLjYyIDgxMiAxNjQ3Ljg5IDgxMiAxNTAwQzgxMiAxMzUyLjExIDg0NC42NiAxMjE4LjM4IDg5Ny4zMTQgMTEyMS43MkM5NTAuMDMxIDEwMjQuOTUgMTAyMi4zNiA5NjYgMTEwMS41MyA5NjZDMTE4MC42OSA5NjYgMTI1My4wMyAxMDI0Ljk1IDEzMDUuNzQgMTEyMS43MkMxMzU4LjQgMTIxOC4zOCAxMzkxLjA2IDEzNTIuMTEgMTM5MS4wNiAxNTAwWiIgZmlsbD0iIzE1NURGRCIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSI2Ii8+PGVsbGlwc2UgY3g9IjExMDIuNTciIGN5PSIxMTk0LjkzIiByeD0iMTI2LjQxNCIgcnk9IjIzMS45MzQiIGZpbGw9IndoaXRlIi8+PHBhdGggZD0iTTIxODcuMTYgMTUwMEMyMTg3LjE2IDE2NDcuODkgMjE1NC41IDE3ODEuNjIgMjEwMS44NCAxODc4LjI4QzIwNDkuMTIgMTk3NS4wNSAxOTc2Ljc5IDIwMzQgMTg5Ny42MyAyMDM0QzE4MTguNDYgMjAzNCAxNzQ2LjEzIDE5NzUuMDUgMTY5My40MSAxODc4LjI4QzE2NDAuNzYgMTc4MS42MiAxNjA4LjEgMTY0Ny44OSAxNjA4LjEgMTUwMEMxNjA4LjEgMTM1Mi4xMSAxNjQwLjc2IDEyMTguMzggMTY5My40MSAxMTIxLjcyQzE3NDYuMTMgMTAyNC45NSAxODE4LjQ2IDk2NiAxODk3LjYzIDk2NkMxOTc2Ljc5IDk2NiAyMDQ5LjEyIDEwMjQuOTUgMjEwMS44NCAxMTIxLjcyQzIxNTQuNSAxMjE4LjM4IDIxODcuMTYgMTM1Mi4xMSAyMTg3LjE2IDE1MDBaIiBmaWxsPSIjMTU1REZEIiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjYiLz48ZWxsaXBzZSBjeD0iMTg5Ni41OCIgY3k9IjExOTQuOTMiIHJ4PSIxMjYuNDE0IiByeT0iMjMxLjkzNCIgZmlsbD0id2hpdGUiLz48L2c+PGRlZnM+PGNsaXBQYXRoIGlkPSJjbGlwMF81NTY5XzcyODM1Ij48cmVjdCB3aWR0aD0iMzAwMCIgaGVpZ2h0PSIzMDAwIiBmaWxsPSJ3aGl0ZSIvPjwvY2xpcFBhdGg+PC9kZWZzPjwvc3ZnPg== +zizzamia.base.eth; +``` + + diff --git a/docs/pages/builderkits/onchainkit/guides/using-ai-powered-ides.mdx b/_pages/builderkits/onchainkit/guides/using-ai-powered-ides.mdx similarity index 100% rename from docs/pages/builderkits/onchainkit/guides/using-ai-powered-ides.mdx rename to _pages/builderkits/onchainkit/guides/using-ai-powered-ides.mdx diff --git a/_pages/builderkits/onchainkit/hooks/use-build-deposit-to-morpho-tx.mdx b/_pages/builderkits/onchainkit/hooks/use-build-deposit-to-morpho-tx.mdx new file mode 100644 index 00000000..f3726718 --- /dev/null +++ b/_pages/builderkits/onchainkit/hooks/use-build-deposit-to-morpho-tx.mdx @@ -0,0 +1,32 @@ +--- +title: "`useBuildDepositToMorphoTx`" +--- + + +The `useBuildDepositToMorphoTx` hook is used to build a deposit transaction to Morpho from within a React component. + +The hook handles the following: + +- Fetching data required to build the transaction +- Using [`buildDepositToMorphoTx`](/builderkits/onchainkit/api/build-deposit-to-morpho-tx) to build the transaction +- Returning the transaction calls to be used with the `` component + +## Usage + +```tsx twoslash [code] +import { useBuildDepositToMorphoTx } from '@coinbase/onchainkit/earn'; + +const { calls } = useBuildDepositToMorphoTx({ + vaultAddress: '0x...', + recipientAddress: '0x...', + amount: '1000000000000000000', +}); +``` + +## Returns + +[`{ calls: Call[] }`](/builderkits/onchainkit/transaction/types#calls) + +## Parameters + +[`UseBuildDepositToMorphoTxParams`](/builderkits/onchainkit/earn/types#usebuilddeposittomorphotxparams) \ No newline at end of file diff --git a/_pages/builderkits/onchainkit/hooks/use-build-withdraw-from-morpho-tx.mdx b/_pages/builderkits/onchainkit/hooks/use-build-withdraw-from-morpho-tx.mdx new file mode 100644 index 00000000..42a9b9f5 --- /dev/null +++ b/_pages/builderkits/onchainkit/hooks/use-build-withdraw-from-morpho-tx.mdx @@ -0,0 +1,33 @@ +--- +title: "`useBuildWithdrawFromMorphoTx`" +--- + + +The `useBuildWithdrawFromMorphoTx` hook is used to build a withdraw transaction from Morpho from within a React component. + +The hook handles the following: + +- Fetching data required to build the transaction +- Using [`buildWithdrawFromMorphoTx`](/builderkits/onchainkit/api/build-withdraw-from-morpho-tx) to build the transaction +- Returning the transaction calls to be used with the `` component + +## Usage + +```tsx twoslash [code] +import { useBuildWithdrawFromMorphoTx } from '@coinbase/onchainkit/earn'; + +const { calls } = useBuildWithdrawFromMorphoTx({ + vaultAddress: '0x...', + recipientAddress: '0x...', + amount: '1000000000000000000', + tokenDecimals: 18, +}); +``` + +## Returns + +[`{ calls: Call[] }`](/builderkits/onchainkit/transaction/types#calls) + +## Parameters + +[`UseBuildWithdrawFromMorphoTxParams`](/builderkits/onchainkit/earn/types#usebuildwithdrawfrommorphotxparams) \ No newline at end of file diff --git a/_pages/builderkits/onchainkit/hooks/use-earn-context.mdx b/_pages/builderkits/onchainkit/hooks/use-earn-context.mdx new file mode 100644 index 00000000..af1aa8f1 --- /dev/null +++ b/_pages/builderkits/onchainkit/hooks/use-earn-context.mdx @@ -0,0 +1,35 @@ +--- +title: "`useEarnContext`" +--- + + +The `useEarnContext` hook is used to access the context values of the `Earn` component. + +It can be used to build fully custom deposit and withdraw interfaces and contains all relevant data about a Morpho vault. + + +## Usage + +Note: This hook should be used within a `` or `` (headless) component. + +```tsx twoslash [code] +import { useEarnContext } from '@coinbase/onchainkit/earn'; + +const { depositAmount, + setDepositAmount, + apy, + nativeApy, + rewards, + vaultFee, + vaultToken, + liquidity, + deposits + // ... + } = useEarnContext(); + +// Use the values to build a custom deposit interface! +``` + +## Returns + +[`EarnContextType`](/builderkits/onchainkit/earn/types#earncontexttype) diff --git a/_pages/builderkits/onchainkit/hooks/use-mint-details.mdx b/_pages/builderkits/onchainkit/hooks/use-mint-details.mdx new file mode 100644 index 00000000..579a97bc --- /dev/null +++ b/_pages/builderkits/onchainkit/hooks/use-mint-details.mdx @@ -0,0 +1,85 @@ +--- +title: "`useMintDetails`" +--- + + +The `useMintDetails` hook implements the `getMintDetails` API, returning the data required to view an NFT to be minted. + +It is implemented with [useQuery](https://tanstack.com/query/latest/docs/framework/react/reference/useQuery) from `@tanstack/react-query`, and returns a `UseQueryResult` object, allowing you to pass through all `@tanstack/react-query` options. + +Before using them, make sure to obtain a [Client API Key](https://portal.cdp.coinbase.com/projects/api-keys/client-key) from Coinbase Developer Platform. + +## Usage + + +```tsx twoslash [code] +import { useMintDetails } from '@coinbase/onchainkit/nft'; + +const Component = () => { + const { data, isLoading, error } = useMintDetails({ + contractAddress: '0x...', + takerAddress: '0x...', + tokenId: '1', + }); + + if (isLoading) return
Loading...
; + + return
{JSON.stringify(data)}
; +}; +``` + +```tsx [scaffolding] +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { OnchainKitProvider } from '@coinbase/onchainkit'; +import { useTokenDetails } from '@coinbase/onchainkit/nft'; + +const queryClient = new QueryClient(); + + + + + + +``` + + +```json [return value] +{ + "data": { + "name": "NFT Name", + "description": "NFT description", + "imageUrl": "https://example.com/image.png", + "animationUrl": "", + "mimeType": "image/png", + "contractType": "ERC721", + "price": { + "amount": "0.0001", + "currency": "ETH", + "amountUSD": "0.242271" + }, + "mintFee": { + "amount": "0", + "currency": "ETH", + "amountUSD": "0" + }, + "maxMintsPerWallet": 100, + "isEligibleToMint": true, + "creatorAddress": "0x...", + "network": "", + "totalTokens": "300", + "totalOwners": "200" + } +} +``` +
+ +## Returns + +[`UseQueryResult`](/builderkits/onchainkit/api/types#getmintdetailsresponse) + +## Parameters + +[`GetMintDetailsParams`](/builderkits/onchainkit/api/types#getmintdetailsparams) diff --git a/_pages/builderkits/onchainkit/hooks/use-morpho-vault.mdx b/_pages/builderkits/onchainkit/hooks/use-morpho-vault.mdx new file mode 100644 index 00000000..8ef23b06 --- /dev/null +++ b/_pages/builderkits/onchainkit/hooks/use-morpho-vault.mdx @@ -0,0 +1,32 @@ +--- +title: "`useMorphoVault`" +--- + + +The `useMorphoVault` hook fetches and returns comprehensive data about a Morpho vault, including APYs, balances, and rewards. + +## Usage + +```tsx +import { useMorphoVault } from '@coinbase/onchainkit/earn'; + +const { + balance, + totalApy, + rewards, + deposits, + liquidity, + // ... other values +} = useMorphoVault({ + vaultAddress: '0x...', + recipientAddress: '0x...', +}); +``` + +## Returns + +[`UseMorphoVaultReturnType`](/builderkits/onchainkit/earn/types#usemorphovaultreturntype) + +## Parameters + +[`UseMorphoVaultParams`](/builderkits/onchainkit/earn/types#usemorphovaultparams) diff --git a/_pages/builderkits/onchainkit/hooks/use-token-details.mdx b/_pages/builderkits/onchainkit/hooks/use-token-details.mdx new file mode 100644 index 00000000..67a0a27b --- /dev/null +++ b/_pages/builderkits/onchainkit/hooks/use-token-details.mdx @@ -0,0 +1,75 @@ +--- +title: "`useTokenDetails`" +--- + + +The `useTokenDetails` hook implements the `getTokenDetails` API, returning the data required to view an NFT. + +It is implemented with [useQuery](https://tanstack.com/query/latest/docs/framework/react/reference/useQuery) from `@tanstack/react-query`, and returns a `UseQueryResult` object, allowing you to pass through all `@tanstack/react-query` options. + +Before using them, make sure to obtain a [Client API Key](https://portal.cdp.coinbase.com/projects/api-keys/client-key) from Coinbase Developer Platform. + +## Usage + + +```tsx twoslash [code] +import { useTokenDetails } from '@coinbase/onchainkit/nft'; + +const Component = () => { + const { data, isLoading, error } = useTokenDetails({ + contractAddress: '0x...', + tokenId: '1', + }); + + if (isLoading) return
Loading...
; + + return
{JSON.stringify(data)}
; +}; +``` + +```tsx [scaffolding] +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { OnchainKitProvider } from '@coinbase/onchainkit'; +import { useTokenDetails } from '@coinbase/onchainkit/nft'; + +const queryClient = new QueryClient(); + + + + + + +``` + +```json [return value] +{ + "data": { + "collectionName": "NFT Collection Name", + "collectionDescription": "NFT Collection Description", + "name": "NFT Name", + "description": "NFT Description", + "imageUrl": "https://example.com/image.png", + "animationUrl": "", + "ownerAddress": "0x...", + "lastSoldPrice": { + "amount": "0.0001", + "currency": "ETH", + "amountUSD": "0.242271" + }, + "mimeType": "image/png", + "contractType": "ERC721" + } +} +``` +
+ +## Returns + +[`UseQueryResult`](/builderkits/onchainkit/api/types#gettokendetailsresponse) + +## Parameters + +[`GetTokenDetailsParams`](/builderkits/onchainkit/api/types#gettokendetailsparams) diff --git a/_pages/builderkits/onchainkit/identity/address.mdx b/_pages/builderkits/onchainkit/identity/address.mdx new file mode 100644 index 00000000..2c8b2464 --- /dev/null +++ b/_pages/builderkits/onchainkit/identity/address.mdx @@ -0,0 +1,56 @@ +--- +title: "`
`" +--- + +import { Address } from '@coinbase/onchainkit/identity'; +import { color } from '@coinbase/onchainkit/theme'; +import App from '@/components/App'; + + +The `Address` component is used to render a shortened user account address. + +## Usage + +Sliced account address: + +```tsx twoslash +import { Address } from '@coinbase/onchainkit/identity'; +
// [!code focus] +``` + + +
+ + +### Display full address + +Set `isSliced` to false, to display the full address: + +```tsx twoslash +import { Address } from '@coinbase/onchainkit/identity'; +
// [!code focus] +``` + + +
+ + +### Override styles + +You can override component styles using `className`. + +```tsx twoslash +import { Address } from '@coinbase/onchainkit/identity'; +
+``` + + +
+ + +## Props + +[`AddressReact`](/builderkits/onchainkit/identity/types#addressreact) diff --git a/_pages/builderkits/onchainkit/identity/avatar.mdx b/_pages/builderkits/onchainkit/identity/avatar.mdx new file mode 100644 index 00000000..11321850 --- /dev/null +++ b/_pages/builderkits/onchainkit/identity/avatar.mdx @@ -0,0 +1,125 @@ +--- +title: "``" +--- + +import { Avatar, Badge, Identity } from '@coinbase/onchainkit/identity'; +import App from '@/components/App'; +import { base } from 'viem/chains'; + + +The `Avatar` component is used to display ENS or [Basenames](https://www.base.org/names) avatar associated with Ethereum addresses. +When an avatar is not available, it defaults to blue color avatar. + +## Usage + +Address with an ENS avatar: +```tsx twoslash +import { Avatar } from '@coinbase/onchainkit/identity'; + // [!code focus] +``` + + + + +Address without an ENS or Basenames avatar defaults to a plain avatar: + +```tsx twoslash +import { Avatar } from '@coinbase/onchainkit/identity'; + // [!code focus] +``` + + + + +Address with a Basename avatar: + +```tsx twoslash +import { Avatar } from '@coinbase/onchainkit/identity'; +import { base } from 'viem/chains'; // [!code focus] + + // [!code focus] +``` + + + + + +Override styles via `className` prop: + +```tsx twoslash +import { Avatar } from '@coinbase/onchainkit/identity'; + // [!code focus] +``` + + + +Use `defaultComponent` prop to change the default avatar when ENS avatar is not found. +Use `loadingComponent` prop to change the loading placeholder: +```tsx twoslash +import { Avatar } from '@coinbase/onchainkit/identity'; + + + + + + )} + defaultComponent={( +
+ + + +
+ )} +/> +``` + + + + + + + )} + defaultComponent={( +
+ + + +
+ )} + /> +
+Show attestation on ENV avatar with [`Badge`](/builderkits/onchainkit/identity/badge) component. +Use [`OnchainKitProvider`](/builderkits/onchainkit/config/onchainkit-provider) or [`Identity`](/builderkits/onchainkit/identity/identity) component with the `schemaId` prop. +```tsx twoslash +import { Avatar, Badge, Identity } from '@coinbase/onchainkit/identity'; + + + + + +``` + + + + + + + +## Props +[`AvatarReact`](/builderkits/onchainkit/identity/types#AvatarReact) diff --git a/_pages/builderkits/onchainkit/identity/badge.mdx b/_pages/builderkits/onchainkit/identity/badge.mdx new file mode 100644 index 00000000..ac08e90e --- /dev/null +++ b/_pages/builderkits/onchainkit/identity/badge.mdx @@ -0,0 +1,154 @@ +--- +title: "``" +--- + +import { base } from 'viem/chains'; +import { Avatar, Badge, Name, Identity } from '@coinbase/onchainkit/identity'; +import App from '@/components/App'; + + +Use `Badge` component along with [`Avatar`](/builderkits/onchainkit/identity/avatar) or [`Name`](/builderkits/onchainkit/identity/name) components to display user attestations attached to their account + +## Usage + +Badge with default colors: + + +```tsx twoslash [tsx] +import { Badge } from '@coinbase/onchainkit/identity'; + // [!code focus] +``` + +```css [css] +.badge { + background: #4F46E5; + path { + fill: #F9FAFB; + } +} +``` + + + + + + +Badge with custom colors: + +```tsx twoslash +import { Badge } from '@coinbase/onchainkit/identity'; + // [!code focus] +``` + + + + + +## Badge with Tooltip + +You can enable a tooltip for the attestation badge to provide context about what the badge represents: + +```tsx twoslash +// @noErrors: 2657 +import { Badge } from '@coinbase/onchainkit/identity'; + + +``` + + + + + +With custom tooltip text: + +```tsx twoslash +// @noErrors: 2657 +import { Badge } from '@coinbase/onchainkit/identity'; + + +``` + + + + + +## Props + +[`BadgeReact`](/builderkits/onchainkit/identity/types#badgereact) + +| Prop | Type | Description | +|------|------|-------------| +| `className` | `string` | Optional className override for top span element | +| `tooltip` | `boolean \| string` | Controls whether the badge shows a tooltip on hover. When `true`, displays the attestation name. When a string is provided, shows that custom text instead. Defaults to `false` | + +## Badge on `` and `` + +Badge with [``](/builderkits/onchainkit/identity/name), best used when [``](/builderkits/onchainkit/identity/name) are displayed alongside [``](/builderkits/onchainkit/identity/avatar) components. + +In both examples we use the Coinbase [Verified Account](https://base.easscan.org/schema/view/0xf8b05c79f090979bf4a80270aba232dff11a10d9ca55c4f88de95317970f0de9) schema ID to show the Coinbase verified badge on the Name and Avatar components. + +```tsx twoslash +// @noErrors: 2657 +import { base } from 'viem/chains'; +import { Badge, Name, Identity } from '@coinbase/onchainkit/identity'; + +const address = '0x838aD0EAE54F99F1926dA7C3b6bFbF617389B4D9'; +const COINBASE_VERIFIED_ACCOUNT_SCHEMA_ID = + '0xf8b05c79f090979bf4a80270aba232dff11a10d9ca55c4f88de95317970f0de9'; + + + + {/* With tooltip that shows attestation name */} + + +``` + + + + + + + + + +Badge with [``](/builderkits/onchainkit/identity/avatar), best used when [``](/builderkits/onchainkit/identity/avatar) is not paired with any labels. + +```tsx twoslash +// @noErrors: 2657 +import { base } from 'viem/chains'; +import { Avatar, Badge, Identity } from '@coinbase/onchainkit/identity'; + +const address = '0x838aD0EAE54F99F1926dA7C3b6bFbF617389B4D9'; +const COINBASE_VERIFIED_ACCOUNT_SCHEMA_ID = + '0xf8b05c79f090979bf4a80270aba232dff11a10d9ca55c4f88de95317970f0de9'; + + + + {/* With custom tooltip text */} + + +``` + + + + + + + + diff --git a/_pages/builderkits/onchainkit/identity/get-address.mdx b/_pages/builderkits/onchainkit/identity/get-address.mdx new file mode 100644 index 00000000..bafc771b --- /dev/null +++ b/_pages/builderkits/onchainkit/identity/get-address.mdx @@ -0,0 +1,45 @@ +--- +title: "`getAddress`" +--- + + +The `getAddress` utility is designed to retrieve an address from an onchain identity provider for a given name. + +## Usage + +Get ENS Name from mainnet chain + + +```tsx twoslash [code] +import { getAddress } from '@coinbase/onchainkit/identity'; + +const address = await getAddress({ name: 'zizzamia.eth' }); +``` + +```ts [return value] +0x02feeb0AdE57b6adEEdE5A4EEea6Cf8c21BeB6B1 +``` + + +Get Basename from base chain + + +```tsx twoslash [code] +import { getAddress } from '@coinbase/onchainkit/identity'; +import { base } from 'viem/chains'; + +const address = await getAddress({ name: 'zizzamia.base.eth', chain: base }); +``` + +```ts [return value] +0x02feeb0AdE57b6adEEdE5A4EEea6Cf8c21BeB6B1 +``` + + +## Returns + +See [`GetAddressReturnType`](/builderkits/onchainkit/identity/types#getaddressreturntype) and [`GetAddress`](/builderkits/onchainkit/identity/types#getaddress) for more details. + +## Parameters + +See [`GetAddressReturnType`](/builderkits/onchainkit/identity/types#getaddressreturntype) and [`GetAddress`](/builderkits/onchainkit/identity/types#getaddress) for more details. diff --git a/_pages/builderkits/onchainkit/identity/get-attestations.mdx b/_pages/builderkits/onchainkit/identity/get-attestations.mdx new file mode 100644 index 00000000..33b43b11 --- /dev/null +++ b/_pages/builderkits/onchainkit/identity/get-attestations.mdx @@ -0,0 +1,86 @@ +--- +title: "`getAttestations`" +--- + + +The `getAttestations` function fetches attestations for a specified address +and blockchain in Ethereum Attestation Service (EAS). It allows optional filtering +based on schema IDs, revocation status, expiration time, and the number of attestations to return. + +In the example, we use the Coinbase [Verified Account](https://base.easscan.org/schema/view/0xf8b05c79f090979bf4a80270aba232dff11a10d9ca55c4f88de95317970f0de9) schema ID. + +## Usage + + +```tsx twoslash [code] +// @noErrors: 2345 - Argument of type string is not assignable to 0x{string} +import { getAttestations } from '@coinbase/onchainkit/identity'; +import { base } from 'viem/chains'; + +const COINBASE_VERIFIED_ACCOUNT_SCHEMA_ID = + '0xf8b05c79f090979bf4a80270aba232dff11a10d9ca55c4f88de95317970f0de9'; + +const address = '0x1234567890abcdef1234567890abcdef12345678'; +const attestationsOptions = { + schemas: [COINBASE_VERIFIED_ACCOUNT_SCHEMA_ID], +}; + +const attestations = await getAttestations(address, base, attestationsOptions); +``` + +```ts [return value] +const attestations = [ + { + attester: '0x357458739F90461b99789350868CD7CF330Dd7EE', + decodedDataJson: + '[{"name":"verifiedAccount","type":"bool","signature":"bool verifiedAccount","value":{"name":"verifiedAccount","type":"bool","value":true}}]', + expirationTime: 0, + id: '0xf1fdb9d102f4b7c1d3b729fc10fea68596301c831913468f3f77f2d631486e12', + recipient: '0x02feeb0AdE57b6adEEdE5A4EEea6Cf8c21BeB6B1', + revocationTime: 0, + revoked: false, + schemaId: '0xf8b05c79f090979bf4a80270aba232dff11a10d9ca55c4f88de95317970f0de9', + time: 1704433703, + timeCreated: 1704433705, + txid: '0x71e21910fd44c2b75b143cf71318507b60d09c5f3caf848109974dd397de9f37', + }, +]; +``` + + +## Returns + +[`Promise`](/builderkits/onchainkit/identity/types#attestation) + +See [Attestation](/builderkits/onchainkit/identity/types#attestation) and [GetEASAttestationsOptions](/builderkits/onchainkit/identity/types#geteasttestationsoptions) for more details. + +## Parameters + +### Address + +```ts +type Address = `0x${string}`; // The address for which attestations are being queried. +``` + +### Chain + +```ts +type Chain = { // The blockchain of interest. + id: string; + name: string; + network: string; + chainId: number; + nativeCurrency: { + name: string; + symbol: string; + decimals: number; + }; + rpcUrls: string[]; + blockExplorerUrls: string[]; +}; +``` + +### GetAttestationsOptions + +[GetEASAttestationsOptions](/builderkits/onchainkit/identity/types#geteasttestationsoptions) + diff --git a/_pages/builderkits/onchainkit/identity/get-avatar.mdx b/_pages/builderkits/onchainkit/identity/get-avatar.mdx new file mode 100644 index 00000000..e6c7dc34 --- /dev/null +++ b/_pages/builderkits/onchainkit/identity/get-avatar.mdx @@ -0,0 +1,51 @@ +--- +title: "`getAvatar`" +--- + + +The `getAvatar` utility is designed to retrieve an avatar image +URL from an onchain identity provider for a given name. + +Consider the utility instead of the hook when you +use it with Next.js or any Node.js backend. + +Supported providers: + +- [Basenames](https://www.base.org/names) +- ENS + +## Usage + +Get Basename avatar: + + +```tsx twoslash [code] +import { getAvatar } from '@coinbase/onchainkit/identity'; +import { base, mainnet } from 'viem/chains'; + +const baseAvatar = await getAvatar({ ensName: 'paulcramer.eth', chain: base }); +``` + +```ts [return value] +https://zku9gdedgba48lmr.public.blob.vercel-storage.com/basenames/avatar/paul.base.eth/1722120524815/FWUzoZmJ_400x400-kWjr2gMvjNe9hHMs9Z9LxGVGIME3By.jpg +``` + + +Get ENS avatar: + + +```tsx twoslash [code] +import { getAvatar } from '@coinbase/onchainkit/identity'; +import { mainnet } from 'viem/chains'; + +const ensAvatar = await getAvatar({ ensName: 'paulcramer.eth', chain: mainnet }); +``` + +```ts [return value] +https://euc.li/paulcramer.eth; +``` + + +## Returns + +[`Promise`](/builderkits/onchainkit/identity/types#getavatarreturntype) diff --git a/_pages/builderkits/onchainkit/identity/get-avatars.mdx b/_pages/builderkits/onchainkit/identity/get-avatars.mdx new file mode 100644 index 00000000..ced4b9a8 --- /dev/null +++ b/_pages/builderkits/onchainkit/identity/get-avatars.mdx @@ -0,0 +1,78 @@ +--- +title: "`getAvatars`" +--- + + +The `getAvatars` utility is designed to retrieve multiple avatars from an onchain identity +provider for an array of ENS names or Basenames in a single batch request. + +Consider the utility instead of the hook when you +use it with Next.js or any Node.js backend. + +## Usage + +Get avatars for multiple ENS names: + + +```tsx twoslash [code] +import { getAvatars } from '@coinbase/onchainkit/identity'; + +const ensNames = ['vitalik.eth', 'zizzamia.eth']; +const avatars = await getAvatars({ ensNames }); +``` + +```ts [return value] +[ + 'https://ipfs.io/ipfs/QmSP4nq9fnN9dAiCj42ug9Wa79rqmQerZXZch82VqpiH7U/image.gif', + 'https://ipfs.io/ipfs/QmQ9RT2SrZ6TWUjrQxG4bNnhb3nDqBE5Ld1j9GYvk3kTjf' +] +``` + + +Get avatars for multiple Basenames: + + +```tsx twoslash [code] +import { getAvatars } from '@coinbase/onchainkit/identity'; +import { base } from 'viem/chains'; + +const ensNames = ['zizzamia.base.eth', 'coinbase.base.eth']; +const avatars = await getAvatars({ ensNames, chain: base }); +``` + +```ts [return value] +[ + 'https://ipfs.io/ipfs/QmQ9RT2SrZ6TWUjrQxG4bNnhb3nDqBE5Ld1j9GYvk3kTjf', + 'https://ipfs.io/ipfs/QmXHFnSXcN7CSuVcyF3vyPgPcPvLQyLpKYBaNpx3x3bPAZ' +] +``` + + +Get avatars for a mix of ENS names and Basenames: + + +```tsx twoslash [code] +import { getAvatars } from '@coinbase/onchainkit/identity'; +import { base } from 'viem/chains'; + +const ensNames = ['vitalik.eth', 'zizzamia.base.eth']; +const avatars = await getAvatars({ ensNames, chain: base }); +``` + +```ts [return value] +[ + 'https://ipfs.io/ipfs/QmSP4nq9fnN9dAiCj42ug9Wa79rqmQerZXZch82VqpiH7U/image.gif', + 'https://ipfs.io/ipfs/QmQ9RT2SrZ6TWUjrQxG4bNnhb3nDqBE5Ld1j9GYvk3kTjf' +] +``` + + +## Returns + +Array of [`GetAvatarReturnType`](/builderkits/onchainkit/identity/types#getavatarreturntype) + +## Parameters + +### GetAvatars + +[`GetAvatars`](/builderkits/onchainkit/identity/types#getavatars) \ No newline at end of file diff --git a/_pages/builderkits/onchainkit/identity/get-name.mdx b/_pages/builderkits/onchainkit/identity/get-name.mdx new file mode 100644 index 00000000..0181f75b --- /dev/null +++ b/_pages/builderkits/onchainkit/identity/get-name.mdx @@ -0,0 +1,67 @@ +--- +title: "`getName`" +--- + + +The `getName` utility is designed to retrieve a name from an onchain identity +provider for a specific address. + +Consider the utility instead of the hook when you +use it with Next.js or any Node.js backend. + +## Usage + +Get ENS name from an address: + + +```tsx twoslash [code] +import { getName } from '@coinbase/onchainkit/identity'; + +const address = '0x02feeb0AdE57b6adEEdE5A4EEea6Cf8c21BeB6B1'; +const name = await getName({ address }); +``` + +```ts [return value] +zizzamia.eth; +``` + + +Get Basename from an address: + + +```tsx twoslash [code] +import { getName } from '@coinbase/onchainkit/identity'; +import { base } from 'viem/chains'; + +const address = '0x02feeb0AdE57b6adEEdE5A4EEea6Cf8c21BeB6B1'; +const name = await getName({ address, chain: base }); +``` + +```ts [return value] +zizzamia.base.eth; +``` + + +Get a sliced address when address does not have an ENS name: + + +```tsx twoslash [code] +import { getName } from '@coinbase/onchainkit/identity'; + +const address = '0x1234567890abcdef1234567890abcdef12345678'; +const name = await getName({ address }); +``` + +```ts [return value] +0x123...5678 +``` + + +## Returns + +See [GetNameReturnType](/builderkits/onchainkit/identity/types#getnamereturntype) and [GetName](/builderkits/onchainkit/identity/types#getname) for more details. + +## Parameters + +See [GetNameReturnType](/builderkits/onchainkit/identity/types#getnamereturntype) and [GetName](/builderkits/onchainkit/identity/types#getname) for more details. + diff --git a/_pages/builderkits/onchainkit/identity/get-names.mdx b/_pages/builderkits/onchainkit/identity/get-names.mdx new file mode 100644 index 00000000..9a93d626 --- /dev/null +++ b/_pages/builderkits/onchainkit/identity/get-names.mdx @@ -0,0 +1,77 @@ +--- +title: "`getNames`" +--- + + +The `getNames` utility is designed to retrieve multiple names from an onchain identity +provider for an array of addresses in a single batch request. + +Consider the utility instead of the hook when you +use it with Next.js or any Node.js backend. + +## Usage + +Get ENS names from multiple addresses: + + +```tsx twoslash [code] +import { getNames } from '@coinbase/onchainkit/identity'; + +const addresses = [ + '0x4bEf0221d6F7Dd0C969fe46a4e9b339a84F52FDF', + '0x838aD0EAE54F99F1926dA7C3b6bFbF617389B4D9' +]; +const names = await getNames({ addresses }); +``` + +```ts [return value] +['paulcramer.eth', 'vitalik.eth'] +``` + + +Get Basenames from multiple addresses: + + +```tsx twoslash [code] +import { getNames } from '@coinbase/onchainkit/identity'; +import { base } from 'viem/chains'; + +const addresses = [ + '0x4bEf0221d6F7Dd0C969fe46a4e9b339a84F52FDF', + '0x4bEf0221d6F7Dd0C969fe46a4e9b339a84F52FDF' +]; +const names = await getNames({ addresses, chain: base }); +``` + +```ts [return value] +['paul.base.eth', 'coinbase.base.eth'] +``` + + +Get a mix of ENS names and sliced addresses when some addresses don't have names: + + +```tsx twoslash [code] +import { getNames } from '@coinbase/onchainkit/identity'; + +const addresses = [ + '0x4bEf0221d6F7Dd0C969fe46a4e9b339a84F52FDF', + '0x1234567890abcdef1234567890abcdef12345678' +]; +const names = await getNames({ addresses }); +``` + +```ts [return value] +['paulcramer.eth', null] +``` + + +## Returns + +Array of [`GetNameReturnType`](/builderkits/onchainkit/identity/types#getnamereturntype) + +## Parameters + +### GetNames + +[`GetNames`](/builderkits/onchainkit/identity/types#getnames) \ No newline at end of file diff --git a/docs/pages/builderkits/onchainkit/identity/identity-card.mdx b/_pages/builderkits/onchainkit/identity/identity-card.mdx similarity index 100% rename from docs/pages/builderkits/onchainkit/identity/identity-card.mdx rename to _pages/builderkits/onchainkit/identity/identity-card.mdx diff --git a/docs/pages/builderkits/onchainkit/identity/identity.mdx b/_pages/builderkits/onchainkit/identity/identity.mdx similarity index 100% rename from docs/pages/builderkits/onchainkit/identity/identity.mdx rename to _pages/builderkits/onchainkit/identity/identity.mdx diff --git a/_pages/builderkits/onchainkit/identity/name.mdx b/_pages/builderkits/onchainkit/identity/name.mdx new file mode 100644 index 00000000..3880b12e --- /dev/null +++ b/_pages/builderkits/onchainkit/identity/name.mdx @@ -0,0 +1,93 @@ +--- +title: "``" +--- + +import { Badge, Name, Identity } from '@coinbase/onchainkit/identity'; +import App from '@/components/App'; +import { base } from 'viem/chains'; + + +The `Name` component is used to display ENS or [Basenames](https://www.base.org/names) associated with Ethereum addresses. + +## Usage + +Address with an ENS: + +```tsx twoslash +import { Name } from '@coinbase/onchainkit/identity'; + +const address = '0x02feeb0AdE57b6adEEdE5A4EEea6Cf8c21BeB6B1'; + // [!code focus] +``` + + + + + +Address with a Basename: + +```tsx twoslash +import { Name } from '@coinbase/onchainkit/identity'; +import { base } from 'viem/chains'; // [!code focus] + +const address = '0x02feeb0AdE57b6adEEdE5A4EEea6Cf8c21BeB6B1'; + // [!code focus] +``` + + + + + +### Override styles + +You can override component styles using `className`. + +```tsx twoslash +import { Name } from '@coinbase/onchainkit/identity'; + +const address = '0x02feeb0AdE57b6adEEdE5A4EEea6Cf8c21BeB6B1'; + +``` + + + + + +### Add attestation badge + +Show attestation on ENV name with [`Badge`](/builderkits/onchainkit/identity/badge) component. + +Use [`OnchainKitProvider`](/builderkits/onchainkit/config/onchainkit-provider) or [`Identity`](/builderkits/onchainkit/identity/identity) component with the `schemaId` prop. + +```tsx twoslash +import { Badge, Name, Identity } from '@coinbase/onchainkit/identity'; + +const address = '0x838aD0EAE54F99F1926dA7C3b6bFbF617389B4D9'; + + + + + +``` + + + + + + + + + +## Props + +[`NameReact`](/builderkits/onchainkit/identity/types#namereact) diff --git a/docs/pages/builderkits/onchainkit/identity/socials.mdx b/_pages/builderkits/onchainkit/identity/socials.mdx similarity index 100% rename from docs/pages/builderkits/onchainkit/identity/socials.mdx rename to _pages/builderkits/onchainkit/identity/socials.mdx diff --git a/docs/pages/builderkits/onchainkit/identity/types.mdx b/_pages/builderkits/onchainkit/identity/types.mdx similarity index 100% rename from docs/pages/builderkits/onchainkit/identity/types.mdx rename to _pages/builderkits/onchainkit/identity/types.mdx diff --git a/_pages/builderkits/onchainkit/identity/use-address.mdx b/_pages/builderkits/onchainkit/identity/use-address.mdx new file mode 100644 index 00000000..b89f2b72 --- /dev/null +++ b/_pages/builderkits/onchainkit/identity/use-address.mdx @@ -0,0 +1,30 @@ +--- +title: "`useAddress`" +--- + + +The `useAddress` hook is used to get an address from an onchain identity provider for a given name. + +It is implemented with [useQuery](https://tanstack.com/query/latest/docs/framework/react/reference/useQuery) from `@tanstack/react-query`, and returns a `UseQueryResult` object, allowing you to pass through all `@tanstack/react-query` options. + +## Usage + +```tsx twoslash +import { useAddress } from '@coinbase/onchainkit/identity'; + +const { data: address, isLoading } = useAddress({ name: 'zizzamia.base.eth' }); +``` + +## Returns + +[`useQuery>`](/builderkits/onchainkit/identity/types#getaddressreturntype) + +## Parameters + +### UseAddressOptions + +[`UseAddressOptions`](/builderkits/onchainkit/identity/types#useaddressoptions) + +### UseQueryOptions + +[`UseQueryOptions`](/builderkits/onchainkit/identity/types#usequeryoptions) diff --git a/_pages/builderkits/onchainkit/identity/use-avatar.mdx b/_pages/builderkits/onchainkit/identity/use-avatar.mdx new file mode 100644 index 00000000..466d5f66 --- /dev/null +++ b/_pages/builderkits/onchainkit/identity/use-avatar.mdx @@ -0,0 +1,31 @@ +--- +title: "`useAvatar`" +--- + + +The `useAvatar` hook is used to get avatar image URL from an onchain identity +provider for a given name. + +It is implemented with [useQuery](https://tanstack.com/query/latest/docs/framework/react/reference/useQuery) from `@tanstack/react-query`, and returns a `UseQueryResult` object, allowing you to pass through all `@tanstack/react-query` options. + +## Usage + +```tsx twoslash +import { useAvatar } from '@coinbase/onchainkit/identity'; + +const { data: avatar, isLoading } = useAvatar({ ensName: 'vitalik.eth' }); +``` + +## Returns + +[`useQuery>`](/builderkits/onchainkit/identity/types#getaddressreturntype) + +## Parameters + +### UseAvatarOptions + +[`UseAvatarOptions`](/builderkits/onchainkit/identity/types#useavataroptions) + +### UseQueryOptions + +[`UseQueryOptions`](/builderkits/onchainkit/identity/types#usequeryoptions) diff --git a/_pages/builderkits/onchainkit/identity/use-avatars.mdx b/_pages/builderkits/onchainkit/identity/use-avatars.mdx new file mode 100644 index 00000000..fd032419 --- /dev/null +++ b/_pages/builderkits/onchainkit/identity/use-avatars.mdx @@ -0,0 +1,68 @@ +--- +title: "`useAvatars`" +--- + + +The `useAvatars` hook is used to get multiple avatar image URLs from an onchain identity +provider for an array of ENS names or Basenames in a single batch request. + +It is implemented with [useQuery](https://tanstack.com/query/latest/docs/framework/react/reference/useQuery) from `@tanstack/react-query`, and returns a `UseQueryResult` object, allowing you to pass through all `@tanstack/react-query` options. + +## Usage + +Get avatars for multiple ENS names: + + +```tsx twoslash [code] +import { useAvatars } from '@coinbase/onchainkit/identity'; + +const ensNames = ['vitalik.eth', 'paulcramer.eth']; +const { data: avatars, isLoading } = useAvatars({ ensNames }); +``` + +```ts [return value] +{ + data: [ + 'https://ipfs.io/ipfs/QmSP4nq9fnN9dAiCj42ug9Wa79rqmQerZXZch82VqpiH7U/image.gif', + 'https://ipfs.io/ipfs/QmQ9RT2SrZ6TWUjrQxG4bNnhb3nDqBE5Ld1j9GYvk3kTjf' + ], + isLoading: false +} +``` + + +Get avatars for multiple Basenames: + + +```tsx twoslash [code] +import { useAvatars } from '@coinbase/onchainkit/identity'; +import { base } from 'viem/chains'; + +const ensNames = ['paul.base.eth', 'coinbase.base.eth']; +const { data: avatars, isLoading } = useAvatars({ ensNames, chain: base }); +``` + +```ts [return value] +{ + data: [ + 'https://ipfs.io/ipfs/QmQ9RT2SrZ6TWUjrQxG4bNnhb3nDqBE5Ld1j9GYvk3kTjf', + 'https://ipfs.io/ipfs/QmXHFnSXcN7CSuVcyF3vyPgPcPvLQyLpKYBaNpx3x3bPAZ' + ], + isLoading: false +} +``` + + +## Returns + +[`useQuery>`](/builderkits/onchainkit/identity/types#getavatarreturntype) + +## Parameters + +### UseAvatarsOptions + +[`UseAvatarsOptions`](/builderkits/onchainkit/identity/types#useavatarsoptions) + +### UseQueryOptions + +[`UseQueryOptions`](/builderkits/onchainkit/identity/types#usequeryoptions) \ No newline at end of file diff --git a/_pages/builderkits/onchainkit/identity/use-name.mdx b/_pages/builderkits/onchainkit/identity/use-name.mdx new file mode 100644 index 00000000..5171cf4c --- /dev/null +++ b/_pages/builderkits/onchainkit/identity/use-name.mdx @@ -0,0 +1,56 @@ +--- +title: "`useName`" +--- + + +The `useName` hook is used to get name from an onchain identity provider +for a given address. + +It is implemented with [useQuery](https://tanstack.com/query/latest/docs/framework/react/reference/useQuery) from `@tanstack/react-query`, and returns a `UseQueryResult` object, allowing you to pass through all `@tanstack/react-query` options. + +## Usage + +Get ENS name from an address: + + +```tsx twoslash [code] +import { useName } from '@coinbase/onchainkit/identity'; + +const address = '0x02feeb0AdE57b6adEEdE5A4EEea6Cf8c21BeB6B1'; +const { data: name, isLoading } = await useName({ address }); +``` + +```ts [return value] +{ data: 'zizzamia.eth', isLoading: false } +``` + + +Get Basename from an address: + + +```tsx twoslash [code] +import { useName } from '@coinbase/onchainkit/identity'; +import { base } from 'viem/chains'; + +const address = '0x02feeb0AdE57b6adEEdE5A4EEea6Cf8c21BeB6B1'; +const { data: name, isLoading } = await useName({ address, chain: base }); +``` + +```ts [return value] +{ data: 'zizzamia.base.eth', isLoading: false } +``` + + +## Returns + +[`useQuery>`](/builderkits/onchainkit/identity/types#getaddressreturntype) + +## Parameters + +### UseNameOptions + +[`UseNameOptions`](/builderkits/onchainkit/identity/types#usenameoptions) + +### UseQueryOptions + +[`UseQueryOptions`](/builderkits/onchainkit/identity/types#usequeryoptions) diff --git a/_pages/builderkits/onchainkit/identity/use-names.mdx b/_pages/builderkits/onchainkit/identity/use-names.mdx new file mode 100644 index 00000000..5865ed79 --- /dev/null +++ b/_pages/builderkits/onchainkit/identity/use-names.mdx @@ -0,0 +1,68 @@ +--- +title: "`useNames`" +--- + + +The `useNames` hook is used to get multiple names from an onchain identity provider +for an array of addresses in a single batch request. + +It is implemented with [useQuery](https://tanstack.com/query/latest/docs/framework/react/reference/useQuery) from `@tanstack/react-query`, and returns a `UseQueryResult` object, allowing you to pass through all `@tanstack/react-query` options. + +## Usage + +Get ENS names from multiple addresses: + + +```tsx twoslash [code] +import { useNames } from '@coinbase/onchainkit/identity'; + +const addresses = [ + '0x4bEf0221d6F7Dd0C969fe46a4e9b339a84F52FDF', + '0x838aD0EAE54F99F1926dA7C3b6bFbF617389B4D9' +]; +const { data: names, isLoading } = useNames({ addresses }); +``` + +```ts [return value] +{ + data: ['paulcramer.eth', 'vitalik.eth'], + isLoading: false +} +``` + + +Get Basenames from multiple addresses: + + +```tsx twoslash [code] +import { useNames } from '@coinbase/onchainkit/identity'; +import { base } from 'viem/chains'; + +const addresses = [ + '0x4bEf0221d6F7Dd0C969fe46a4e9b339a84F52FDF', + '0x4bEf0221d6F7Dd0C969fe46a4e9b339a84F52FDF' +]; +const { data: names, isLoading } = useNames({ addresses, chain: base }); +``` + +```ts [return value] +{ + data: ['paul.base.eth', 'coinbase.base.eth'], + isLoading: false +} +``` + + +## Returns + +[`useQuery>`](/builderkits/onchainkit/identity/types#getnamereturntype) + +## Parameters + +### UseNamesOptions + +[`UseNamesOptions`](/builderkits/onchainkit/identity/types#usenamesoptions) + +### UseQueryOptions + +[`UseQueryOptions`](/builderkits/onchainkit/identity/types#usequeryoptions) \ No newline at end of file diff --git a/_pages/builderkits/onchainkit/installation.mdx b/_pages/builderkits/onchainkit/installation.mdx new file mode 100644 index 00000000..96b450e4 --- /dev/null +++ b/_pages/builderkits/onchainkit/installation.mdx @@ -0,0 +1,13 @@ +--- +title: Installation · OnchainKit +description: Install OnchainKit using the top React frameworks +--- + +import InstallationOptions from '/snippets/installation-options.mdx'; + +# Installation + +How to install OnchainKit using the top React frameworks. + + + diff --git a/_pages/builderkits/onchainkit/installation/astro.mdx b/_pages/builderkits/onchainkit/installation/astro.mdx new file mode 100644 index 00000000..c0b98b9c --- /dev/null +++ b/_pages/builderkits/onchainkit/installation/astro.mdx @@ -0,0 +1,198 @@ +--- +title: Astro Installation · OnchainKit +description: Install OnchainKit using Astro +--- + +import StartBuilding from "/snippets/start-building.mdx"; + +# Astro Installation + +Install and configure OnchainKit with Astro. +If you are integrating OnchainKit into an existing project, +skip to the [OnchainKit installation](#install-onchainkit). + + + + Create a new Astro project by using the Astro CLI. + More information about Astro can be found [here](https://docs.astro.build/en/install-and-setup/#start-a-new-project). + + + ```bash [npm] + npm create astro@latest + ``` + + ```bash [yarn] + yarn create astro + ``` + + ```bash [pnpm] + pnpm create astro@latest + ``` + + + + Astro does not come with React by default, so if you are not already using React + in your application, you will need to install it. + + ```bash [Terminal] + npx astro add react + ``` + + + Add OnchainKit to your project by installing the `@coinbase/onchainkit` package. + + + ```bash [npm] + npm install @coinbase/onchainkit + ``` + + ```bash [yarn] + yarn add @coinbase/onchainkit + ``` + + ```bash [pnpm] + pnpm add @coinbase/onchainkit + ``` + + ```bash [bun] + bun add @coinbase/onchainkit + ``` + + + + Get your [Client API Key](https://portal.cdp.coinbase.com/projects/api-keys/client-key) from Coinbase Developer Platform. + + OnchainKit copy Client API Key + + Create a `.env` file in your project's root directory. + + OnchainKit define Client API Key + + Add your Client API Key to the `.env` file: + + ```dotenv [.env] + PUBLIC_ONCHAINKIT_API_KEY=YOUR_CLIENT_API_KEY + ``` + + + Create a `providers.tsx` file. Add `OnchainKitProvider` with your desired config. + + Under the hood, OnchainKit will create our recommended Wagmi and QueryClient + providers. If you wish to customize these providers, check out [Custom + Supplemental Providers](/builderkits/onchainkit/config/supplemental-providers). + + ```tsx twoslash [providers.tsx] + // @noErrors: 2307 2580 2339 - cannot find 'process', cannot find './wagmi', cannot find 'import.meta' + 'use client'; + + import type { ReactNode } from 'react'; + import { OnchainKitProvider } from '@coinbase/onchainkit'; + import { base } from 'wagmi/chains'; // add baseSepolia for testing // [!code ++] + + export function Providers(props: { children: ReactNode }) { + return ( + + {props.children} + + ); + } + ``` + + + After configuring the providers in step 4, you will need to wrap your OnchainKit components + with the `` component. + + There are two options for this: + + 1. Create a component, eg. `` that contains all OnchainKit components. + 2. Wrap every OnchainKit component individually. + + + ```tsx [ReactIsland] + import { AppProviders } from '../AppProviders'; + + export default function ReactIsland() { + return ( + + + + ); + } + ``` + + ```tsx [OnchainKit Wrappers] + import { AppProviders } from '../AppProviders'; + import { OnchainKitComponent } from '@coinbase/onchainkit'; + + export default function OnchainKitComponentWrapper() { + return ( + + + + ); + } + ``` + + + The advantage of ReactIsland is that you will only have a single provider at any time. + The drawback is that your OnchainKit components will all need to live in the same Island. + + The advantage of individual wrappers is that you can use OnchainKit components anywhere in your app. + The drawback is that you will have multiple providers if you use more than one OnchainKit component. + + + You can add OnchainKit components to your app by using the component(s) you + created above into your `.astro` files. + + For example, if you created a ReactIsland, you can add it to your + `src/pages/index.astro` file: + + ```astro [src/pages/index.astro] + --- + import Layout from '../layouts/Layout.astro'; + import ReactIsland from '../components/ReactIsland'; + --- + + +
+ ... + + ... +
+
+ ``` + + Don't forget to add the `client:only="react"` directive to your OnchainKit component, + as this is required for Astro to render React components. +
+ + OnchainKit components come with pre-configured styles. + To include these styles in your project, add the following import + statement at the top of the `Layout.astro` file: + + ```tsx + import '@coinbase/onchainkit/styles.css'; + ``` + + This ensures that the OnchainKit styles are loaded and applied to your entire application. + + - For Tailwind CSS users, check out our [Tailwind Integration Guide](/builderkits/onchainkit/guides/tailwind). + + - Update the appearance of components by using our built-in themes or crafting your own custom theme. + Explore the possibilities in our [Theming Guide](/builderkits/onchainkit/guides/themes). + +
+ + diff --git a/_pages/builderkits/onchainkit/installation/nextjs.mdx b/_pages/builderkits/onchainkit/installation/nextjs.mdx new file mode 100644 index 00000000..6ec71f31 --- /dev/null +++ b/_pages/builderkits/onchainkit/installation/nextjs.mdx @@ -0,0 +1,175 @@ +--- +title: Next.js Installation · OnchainKit +description: Install OnchainKit using Next.js +--- + +import StartBuilding from "/snippets/start-building.mdx"; + +# Next.js Installation + +Install and configure OnchainKit with Next.js. +If you are integrating OnchainKit into an existing project, +skip to the [OnchainKit installation](#install-onchainkit). + + + + Create a new Next.js project by using the Next.js CLI. + More information about Next.js can be found [here](https://nextjs.org/docs/getting-started/installation). + + ```bash [npm] + npx create-next-app@14 + ``` + + During the setup process you will encounter multiple prompts. + Make sure you enable TypeScript, ESLint, and Tailwind CSS. + + + Install OnchainKit in your project. + + + ```bash [npm] + npm install @coinbase/onchainkit + ``` + + ```bash [yarn] + yarn add @coinbase/onchainkit + ``` + + ```bash [pnpm] + pnpm add @coinbase/onchainkit + ``` + + ```bash [bun] + bun add @coinbase/onchainkit + ``` + + + + Get your [Client API Key](https://portal.cdp.coinbase.com/projects/api-keys/client-key) from Coinbase Developer Platform. + + OnchainKit copy Client API Key + + Create a `.env` file in your project's root directory. + + OnchainKit define Client API Key + + Add your Client API Key to the `.env` file: + + ```tsx [.env] + NEXT_PUBLIC_ONCHAINKIT_API_KEY=YOUR_CLIENT_API_KEY; + ``` + + + Create a `providers.tsx` file. Add `OnchainKitProvider` with your desired config. + + Under the hood, OnchainKit will create our recommended Wagmi and QueryClient + providers. If you wish to customize these providers, check out [Custom + Supplemental Providers](/builderkits/onchainkit/config/supplemental-providers). + + ```tsx twoslash [providers.tsx] + // @noErrors: 2307 2580 2339 - cannot find 'process', cannot find './wagmi', cannot find 'import.meta' + 'use client'; + + import type { ReactNode } from 'react'; + import { OnchainKitProvider } from '@coinbase/onchainkit'; + import { base } from 'wagmi/chains'; // add baseSepolia for testing // [!code ++] + + export function Providers(props: { children: ReactNode }) { + return ( + + {props.children} + + ); + } + ``` + + + After the setup, wrap your app with the above `` component. + + ```javascript [app.tsx] + import './globals.css'; + import { Providers } from './providers'; // [!code ++] + + export default function RootLayout({ + children, + }: Readonly<{ + children: React.ReactNode, + }>) { + return ( + + + + {children} + + + + ); + } + ``` + + + OnchainKit components come with pre-configured styles. To include these styles in your project, add the following import statement at the top of this file: + + ```javascript + import '@coinbase/onchainkit/styles.css'; + ``` + + For example, if you're using Next.js with the app router, your `app/layout.tsx` might look like this: + + ```tsx [layout.tsx] + import '@coinbase/onchainkit/styles.css'; // [!code ++] + import './globals.css'; + import type { Metadata } from 'next'; + import { Inter } from 'next/font/google'; + import { headers } from 'next/headers'; + import { type ReactNode } from 'react'; + import { cookieToInitialState } from 'wagmi'; + + import { getConfig } from '../wagmi'; + import { Providers } from './providers'; + + const inter = Inter({ subsets: ['latin'] }); + + export const metadata: Metadata = { + title: 'Create Wagmi', + description: 'Generated by create-wagmi', + }; + + export default function RootLayout(props: { children: ReactNode }) { + const initialState = cookieToInitialState( + getConfig(), + headers().get('cookie') + ); + return ( + + + {props.children} + + + ); + } + ``` + + This ensures that the OnchainKit styles are loaded and applied to your entire application. + + - For Tailwind CSS users, check out our [Tailwind Integration Guide](/builderkits/onchainkit/guides/tailwind). + + - Update the appearance of components by using our built-in themes or crafting your own custom theme. + Explore the possibilities in our [Theming Guide](/builderkits/onchainkit/guides/themes). + + + + + diff --git a/_pages/builderkits/onchainkit/installation/remix.mdx b/_pages/builderkits/onchainkit/installation/remix.mdx new file mode 100644 index 00000000..969c363a --- /dev/null +++ b/_pages/builderkits/onchainkit/installation/remix.mdx @@ -0,0 +1,196 @@ +--- +title: Remix Installation · OnchainKit +description: Install OnchainKit using Remix +--- + +import StartBuilding from "/snippets/start-building.mdx"; + +# Remix Installation + +Install and configure OnchainKit with Remix. +If you are integrating OnchainKit into an existing project, +skip to the [OnchainKit installation](#install-onchainkit). + + + + Create a new Remix project by using the Remix CLI. + More information about Remix can be found [here](https://remix.run/docs/en/main/start/quickstart). + + ```bash [Terminal] + npx create-remix@latest + ``` + + + Add OnchainKit to your project by installing the `@coinbase/onchainkit` package. + + + ```bash [npm] + npm install @coinbase/onchainkit + ``` + + ```bash [yarn] + yarn add @coinbase/onchainkit + ``` + + ```bash [pnpm] + pnpm add @coinbase/onchainkit + ``` + + ```bash [bun] + bun add @coinbase/onchainkit + ``` + + + + + Get your [Client API Key](https://portal.cdp.coinbase.com/projects/api-keys/client-key) from Coinbase Developer Platform. + + OnchainKit copy Client API Key + + Create a `.env` file in your project's root directory. + + OnchainKit define Client API Key + + Add your Client API Key to the `.env` file: + + ```dotenv [.env] + PUBLIC_ONCHAINKIT_API_KEY=YOUR_CLIENT_API_KEY + ``` + + Update the `app/root.tsx` file to provide access to your Client API Key + through `window.ENV`: + + ```tsx [app/root.tsx] + declare global { + interface Window { + ENV: { + PUBLIC_ONCHAINKIT_API_KEY: string; // [!code ++] + }; + } + } + + export async function loader() { + return json({ + ENV: { + PUBLIC_ONCHAINKIT_API_KEY: process.env.PUBLIC_ONCHAINKIT_API_KEY, // [!code ++] + }, + }); + } + ``` + + If this is the first env variable you've added to your project, you will need to + update the `Layout` component of `app/root.tsx` to make it available to your app: + + ```tsx [app/root.tsx] + export function Layout({ children }: { children: React.ReactNode }) { + const data = useLoaderData(); // [!code ++] + return ( + + + + + + + + + {children} + + \ No newline at end of file diff --git a/storybook/.storybook/preview.ts b/storybook/.storybook/preview.ts new file mode 100644 index 00000000..f5b1ca36 --- /dev/null +++ b/storybook/.storybook/preview.ts @@ -0,0 +1,103 @@ +import type { Preview } from "@storybook/react"; +import { themes } from "@storybook/theming"; + +// Extend Window interface to include our custom property +declare global { + interface Window { + __themeListenerAdded?: boolean; + } +} + +const preview: Preview = { + parameters: { + darkMode: { + // Override the default dark theme + dark: { ...themes.dark, appBg: "black" }, + // Override the default light theme + light: { ...themes.normal, appBg: "white" }, + darkClass: "dark", + lightClass: "light", + stylePreview: true, + }, + controls: { + matchers: { + color: /(background|color)$/i, + date: /Date$/i, + }, + }, + docs: { + story: { + inline: false, + iframeHeight: 400, + }, + }, + }, + // Add custom script to handle theme messages from parent window + decorators: [ + (Story) => { + // Add the message listener script only once + if (typeof window !== "undefined" && !window.__themeListenerAdded) { + window.__themeListenerAdded = true; + + const script = document.createElement("script"); + script.textContent = ` + (function() { + console.log('Storybook theme listener initialized'); + + // Listen for theme messages from parent window + window.addEventListener('message', function(event) { + console.log('Received message in Storybook iframe:', event.data); + + if (event.data && event.data.type === 'THEME_CHANGE') { + const { isDark, styles } = event.data; + console.log('Applying theme change:', { isDark, styles }); + + // Apply dark/light class to html element + if (isDark) { + document.documentElement.classList.add('dark'); + document.documentElement.classList.remove('light'); + } else { + document.documentElement.classList.add('light'); + document.documentElement.classList.remove('dark'); + } + + // Apply background styles + if (styles && styles.background) { + // Apply the background (either #0b0d0f for dark or transparent for light) + document.body.style.background = styles.background; + document.documentElement.style.background = styles.background; + } + + console.log('Theme applied successfully'); + } + }); + + // Also check if parent window has dark mode on initial load + try { + if (window.parent && window.parent !== window) { + const parentHasDark = window.parent.document.documentElement.classList.contains('dark'); + console.log('Parent has dark mode:', parentHasDark); + if (parentHasDark) { + document.documentElement.classList.add('dark'); + document.body.style.background = '#0b0d0f'; + document.documentElement.style.background = '#0b0d0f'; + } else { + document.documentElement.classList.add('light'); + document.body.style.background = 'transparent'; + document.documentElement.style.background = 'transparent'; + } + } + } catch (e) { + console.log('Cannot access parent document (expected for cross-origin)'); + } + })(); + `; + document.head.appendChild(script); + } + + return Story(); + }, + ], +}; + +export default preview; diff --git a/storybook/README.md b/storybook/README.md new file mode 100644 index 00000000..c4e5d6dd --- /dev/null +++ b/storybook/README.md @@ -0,0 +1,33 @@ +### Install Dependencies + +```bash install dependencies +npm install +``` + +```bash update dependencies +npm update +``` + +### Run Storybook + +```bash +npm run storybook +``` + +### URL format for iframes + +``` +https://-.chromatic.com/iframe.html?args=&id={path-to-story}&viewMode=story&dark=true&hero=true +``` + +examples: + +```jsx +