From 05bb99c4bddec1c6c7fd2baa3d79bffa606cf291 Mon Sep 17 00:00:00 2001 From: Alissa Crane Date: Wed, 18 Dec 2024 15:11:00 -0800 Subject: [PATCH] chore: add `Buy` to playground (#1766) Co-authored-by: Alissa Crane --- package.json | 6 ++ .../nextjs-app-router/components/Demo.tsx | 2 + .../components/DemoOptions.tsx | 1 + .../nextjs-app-router/components/demo/Buy.tsx | 67 +++++++++++++++++++ .../components/form/active-component.tsx | 1 + playground/nextjs-app-router/lib/constants.ts | 42 ++++++++++++ .../nextjs-app-router/types/onchainkit.ts | 1 + src/buy/components/BuyTokenItem.tsx | 7 +- 8 files changed, 125 insertions(+), 2 deletions(-) create mode 100644 playground/nextjs-app-router/components/demo/Buy.tsx diff --git a/package.json b/package.json index 43bb163411..f3d7b69a55 100644 --- a/package.json +++ b/package.json @@ -121,6 +121,12 @@ "import": "./esm/core/api/index.js", "default": "./esm/core/api/index.js" }, + "./buy": { + "types": "./esm/buy/index.d.ts", + "module": "./esm/buy/index.js", + "import": "./esm/buy/index.js", + "default": "./esm/buy/index.js" + }, "./checkout": { "types": "./esm/checkout/index.d.ts", "module": "./esm/checkout/index.js", diff --git a/playground/nextjs-app-router/components/Demo.tsx b/playground/nextjs-app-router/components/Demo.tsx index 17327c727f..9e9d76aa95 100644 --- a/playground/nextjs-app-router/components/Demo.tsx +++ b/playground/nextjs-app-router/components/Demo.tsx @@ -5,6 +5,7 @@ import { cn } from '@/lib/utils'; import { OnchainKitComponent } from '@/types/onchainkit'; import { useContext, useEffect, useState } from 'react'; import DemoOptions from './DemoOptions'; +import BuyDemo from './demo/Buy'; import CheckoutDemo from './demo/Checkout'; import FundDemo from './demo/Fund'; import IdentityDemo from './demo/Identity'; @@ -21,6 +22,7 @@ import WalletDemo from './demo/Wallet'; import WalletDefaultDemo from './demo/WalletDefault'; const activeComponentMapping: Record = { + [OnchainKitComponent.Buy]: BuyDemo, [OnchainKitComponent.Fund]: FundDemo, [OnchainKitComponent.Identity]: IdentityDemo, [OnchainKitComponent.Transaction]: TransactionDemo, diff --git a/playground/nextjs-app-router/components/DemoOptions.tsx b/playground/nextjs-app-router/components/DemoOptions.tsx index 8220569ff0..1c11330b45 100644 --- a/playground/nextjs-app-router/components/DemoOptions.tsx +++ b/playground/nextjs-app-router/components/DemoOptions.tsx @@ -21,6 +21,7 @@ const COMMON_OPTIONS = [ const COMPONENT_CONFIG: Partial< Record React.JSX.Element)[]> > = { + [OnchainKitComponent.Buy]: [Chain, PaymasterUrl, IsSponsored, SwapConfig], [OnchainKitComponent.Checkout]: [ Chain, PaymasterUrl, diff --git a/playground/nextjs-app-router/components/demo/Buy.tsx b/playground/nextjs-app-router/components/demo/Buy.tsx new file mode 100644 index 0000000000..b2d34396ea --- /dev/null +++ b/playground/nextjs-app-router/components/demo/Buy.tsx @@ -0,0 +1,67 @@ +import { ENVIRONMENT, ENVIRONMENT_VARIABLES } from '@/lib/constants'; +import { Buy } from '@coinbase/onchainkit/buy'; +import type { LifecycleStatus } from '@coinbase/onchainkit/swap'; +import type { SwapError } from '@coinbase/onchainkit/swap'; +import { useCallback, useContext } from 'react'; +import type { TransactionReceipt } from 'viem'; +import { base } from 'viem/chains'; +import { degenToken } from '../../lib/constants'; +import { AppContext } from '../AppProvider'; + +const FALLBACK_DEFAULT_MAX_SLIPPAGE = 3; + +function BuyComponent() { + const { chainId, isSponsored, defaultMaxSlippage } = useContext(AppContext); + const handleOnStatus = useCallback((lifecycleStatus: LifecycleStatus) => { + console.log('Status:', lifecycleStatus); + }, []); + const handleOnSuccess = useCallback( + (transactionReceipt?: TransactionReceipt) => { + console.log('Success:', transactionReceipt); + }, + [], + ); + const handleOnError = useCallback((swapError: SwapError) => { + console.log('Error:', swapError); + }, []); + return ( +
+ {chainId !== base.id ? ( +
+
+ Buy Demo is only available on Base. +
+ You're connected to a different network. Switch to Base to continue + using the app. +
+
+ ) : ( + <> + )} + {ENVIRONMENT_VARIABLES[ENVIRONMENT.ENVIRONMENT] === 'production' && + chainId === base.id ? ( +
+ Note: Buy is disabled on production. To test, run the app locally. +
+ ) : null} + +
+ ); +} +export default function BuyDemo() { + return ( +
+ +
+ ); +} diff --git a/playground/nextjs-app-router/components/form/active-component.tsx b/playground/nextjs-app-router/components/form/active-component.tsx index 2df018cf2f..ca750043c2 100644 --- a/playground/nextjs-app-router/components/form/active-component.tsx +++ b/playground/nextjs-app-router/components/form/active-component.tsx @@ -26,6 +26,7 @@ export function ActiveComponent() { + Buy Fund Identity diff --git a/playground/nextjs-app-router/lib/constants.ts b/playground/nextjs-app-router/lib/constants.ts index 2ddb1e1a65..a48e13e8e1 100644 --- a/playground/nextjs-app-router/lib/constants.ts +++ b/playground/nextjs-app-router/lib/constants.ts @@ -1,4 +1,6 @@ +import type { Token } from '@coinbase/onchainkit/token'; import type { Address } from 'viem'; +import { base } from 'viem/chains'; export const deployedContracts: Record = { [8543]: { @@ -25,3 +27,43 @@ export const ENVIRONMENT_VARIABLES: Record = [ENVIRONMENT.PROJECT_ID]: process.env.NEXT_PUBLIC_PROJECT_ID, [ENVIRONMENT.RESERVOIR_API_KEY]: process.env.NEXT_PUBLIC_RESERVOIR_API_KEY, }; + +export const ethToken: Token = { + name: 'ETH', + address: '', + symbol: 'ETH', + decimals: 18, + image: + 'https://wallet-api-production.s3.amazonaws.com/uploads/tokens/eth_288.png', + chainId: base.id, +}; + +export const usdcToken: Token = { + name: 'USDC', + address: '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913', + symbol: 'USDC', + decimals: 6, + image: + 'https://d3r81g40ycuhqg.cloudfront.net/wallet/wais/44/2b/442b80bd16af0c0d9b22e03a16753823fe826e5bfd457292b55fa0ba8c1ba213-ZWUzYjJmZGUtMDYxNy00NDcyLTg0NjQtMWI4OGEwYjBiODE2', + chainId: base.id, +}; + +export const degenToken: Token = { + name: 'DEGEN', + address: '0x4ed4e862860bed51a9570b96d89af5e1b0efefed', + symbol: 'DEGEN', + decimals: 18, + image: + 'https://d3r81g40ycuhqg.cloudfront.net/wallet/wais/3b/bf/3bbf118b5e6dc2f9e7fc607a6e7526647b4ba8f0bea87125f971446d57b296d2-MDNmNjY0MmEtNGFiZi00N2I0LWIwMTItMDUyMzg2ZDZhMWNm', + chainId: base.id, +}; + +export const daiToken: Token = { + name: 'DAI', + address: '0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb', + symbol: 'DAI', + decimals: 18, + image: + 'https://d3r81g40ycuhqg.cloudfront.net/wallet/wais/92/13/9213e31b84c98a693f4c624580fdbe6e4c1cb550efbba15aa9ea68fd25ffb90c-ZTE1NmNjMGUtZGVkYi00ZDliLWI2N2QtNTY2ZWRjMmYwZmMw', + chainId: base.id, +}; diff --git a/playground/nextjs-app-router/types/onchainkit.ts b/playground/nextjs-app-router/types/onchainkit.ts index 93471f8cbf..5099779892 100644 --- a/playground/nextjs-app-router/types/onchainkit.ts +++ b/playground/nextjs-app-router/types/onchainkit.ts @@ -1,4 +1,5 @@ export enum OnchainKitComponent { + Buy = 'buy', Fund = 'fund', Identity = 'identity', IdentityCard = 'identity-card', diff --git a/src/buy/components/BuyTokenItem.tsx b/src/buy/components/BuyTokenItem.tsx index 9f8f4b0692..f20bfc99c7 100644 --- a/src/buy/components/BuyTokenItem.tsx +++ b/src/buy/components/BuyTokenItem.tsx @@ -1,6 +1,6 @@ import { useCallback, useMemo } from 'react'; import { getRoundedAmount } from '../../core/utils/getRoundedAmount'; -import { cn, color } from '../../styles/theme'; +import { cn, color, pressable } from '../../styles/theme'; import type { SwapUnit } from '../../swap/types'; import { TokenImage } from '../../token'; import { useBuyContext } from './BuyProvider'; @@ -31,7 +31,10 @@ export function BuyTokenItem({ swapUnit }: { swapUnit?: SwapUnit }) { return (