@coinbase/create-cdp-app 0.0.10 → 0.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/README.md +8 -1
  2. package/dist/index.js +10 -8
  3. package/dist/index.js.map +1 -1
  4. package/package.json +1 -1
  5. package/template-nextjs/README.md +85 -0
  6. package/template-nextjs/_gitignore +45 -0
  7. package/template-nextjs/env.example +3 -0
  8. package/template-nextjs/eslint.config.mjs +16 -0
  9. package/template-nextjs/next-env.d.ts +5 -0
  10. package/template-nextjs/next.config.ts +7 -0
  11. package/template-nextjs/package.json +28 -0
  12. package/template-nextjs/src/app/globals.css +306 -0
  13. package/template-nextjs/src/app/icon.svg +5 -0
  14. package/template-nextjs/src/app/layout.tsx +22 -0
  15. package/template-nextjs/src/app/page.tsx +16 -0
  16. package/template-nextjs/src/components/ClientApp.tsx +27 -0
  17. package/template-nextjs/src/components/Header.tsx +61 -0
  18. package/template-nextjs/src/components/Icons.tsx +68 -0
  19. package/template-nextjs/src/components/Loading.tsx +15 -0
  20. package/template-nextjs/src/components/Providers.tsx +33 -0
  21. package/template-nextjs/src/components/SignInScreen.tsx +17 -0
  22. package/template-nextjs/src/components/SignedInScreen.tsx +64 -0
  23. package/template-nextjs/src/components/Transaction.tsx +128 -0
  24. package/template-nextjs/src/components/UserBalance.tsx +42 -0
  25. package/template-nextjs/tsconfig.json +27 -0
  26. package/{template-react-components → template-react}/README.md +13 -6
  27. package/template-react/public/eth.svg +25 -0
  28. package/template-react/public/logo.svg +5 -0
  29. package/{template-react-components → template-react}/src/Header.tsx +1 -1
  30. package/template-react/src/theme.ts +32 -0
  31. /package/{template-react-components → template-nextjs}/public/eth.svg +0 -0
  32. /package/{template-react-components → template-nextjs}/public/logo.svg +0 -0
  33. /package/{template-react-components/src → template-nextjs/src/components}/theme.ts +0 -0
  34. /package/{template-react-components → template-react}/_gitignore +0 -0
  35. /package/{template-react-components → template-react}/env.example +0 -0
  36. /package/{template-react-components → template-react}/eslint.config.js +0 -0
  37. /package/{template-react-components → template-react}/index.html +0 -0
  38. /package/{template-react-components → template-react}/package.json +0 -0
  39. /package/{template-react-components → template-react}/src/App.tsx +0 -0
  40. /package/{template-react-components → template-react}/src/Icons.tsx +0 -0
  41. /package/{template-react-components → template-react}/src/Loading.tsx +0 -0
  42. /package/{template-react-components → template-react}/src/SignInScreen.tsx +0 -0
  43. /package/{template-react-components → template-react}/src/SignedInScreen.tsx +0 -0
  44. /package/{template-react-components → template-react}/src/Transaction.tsx +0 -0
  45. /package/{template-react-components → template-react}/src/UserBalance.tsx +0 -0
  46. /package/{template-react-components → template-react}/src/config.ts +0 -0
  47. /package/{template-react-components → template-react}/src/index.css +0 -0
  48. /package/{template-react-components → template-react}/src/main.tsx +0 -0
  49. /package/{template-react-components → template-react}/src/vite-env.d.ts +0 -0
  50. /package/{template-react-components → template-react}/tsconfig.app.json +0 -0
  51. /package/{template-react-components → template-react}/tsconfig.json +0 -0
  52. /package/{template-react-components → template-react}/tsconfig.node.json +0 -0
  53. /package/{template-react-components → template-react}/vite.config.ts +0 -0
@@ -0,0 +1,27 @@
1
+ "use client";
2
+
3
+ import { useIsInitialized, useIsSignedIn } from "@coinbase/cdp-hooks";
4
+
5
+ import Loading from "@/components/Loading";
6
+ import SignedInScreen from "@/components/SignedInScreen";
7
+ import SignInScreen from "@/components/SignInScreen";
8
+
9
+ /**
10
+ * A component that displays the client app.
11
+ */
12
+ export default function ClientApp() {
13
+ const isInitialized = useIsInitialized();
14
+ const isSignedIn = useIsSignedIn();
15
+
16
+ return (
17
+ <div className="app flex-col-container flex-grow">
18
+ {!isInitialized && <Loading />}
19
+ {isInitialized && (
20
+ <>
21
+ {!isSignedIn && <SignInScreen />}
22
+ {isSignedIn && <SignedInScreen />}
23
+ </>
24
+ )}
25
+ </div>
26
+ );
27
+ }
@@ -0,0 +1,61 @@
1
+ "use client";
2
+ import { useEvmAddress } from "@coinbase/cdp-hooks";
3
+ import { AuthButton } from "@coinbase/cdp-react/components/AuthButton";
4
+ import { useEffect, useState } from "react";
5
+
6
+ import { IconCheck, IconCopy, IconUser } from "@/components/Icons";
7
+
8
+ /**
9
+ * Header component
10
+ */
11
+ export default function Header() {
12
+ const evmAddress = useEvmAddress();
13
+ const [isCopied, setIsCopied] = useState(false);
14
+
15
+ const copyAddress = async () => {
16
+ if (!evmAddress) return;
17
+ try {
18
+ await navigator.clipboard.writeText(evmAddress);
19
+ setIsCopied(true);
20
+ } catch (error) {
21
+ console.error(error);
22
+ }
23
+ };
24
+
25
+ useEffect(() => {
26
+ if (!isCopied) return;
27
+ const timeout = setTimeout(() => {
28
+ setIsCopied(false);
29
+ }, 2000);
30
+ return () => clearTimeout(timeout);
31
+ }, [isCopied]);
32
+
33
+ return (
34
+ <header>
35
+ <div className="header-inner">
36
+ <h1 className="site-title">CDP React StarterKit</h1>
37
+ <div className="user-info flex-row-container">
38
+ {evmAddress && (
39
+ <button
40
+ aria-label="copy wallet address"
41
+ className="flex-row-container copy-address-button"
42
+ onClick={copyAddress}
43
+ >
44
+ {!isCopied && (
45
+ <>
46
+ <IconUser className="user-icon user-icon--user" />
47
+ <IconCopy className="user-icon user-icon--copy" />
48
+ </>
49
+ )}
50
+ {isCopied && <IconCheck className="user-icon user-icon--check" />}
51
+ <span className="wallet-address">
52
+ {evmAddress.slice(0, 6)}...{evmAddress.slice(-4)}
53
+ </span>
54
+ </button>
55
+ )}
56
+ <AuthButton />
57
+ </div>
58
+ </div>
59
+ </header>
60
+ );
61
+ }
@@ -0,0 +1,68 @@
1
+ "use client";
2
+
3
+ import { type ReactNode, type SVGProps } from "react";
4
+
5
+ const SvgIcon = ({ children, ...props }: SVGProps<SVGSVGElement> & { children: ReactNode }) => {
6
+ return (
7
+ <svg
8
+ xmlns="http://www.w3.org/2000/svg"
9
+ fill="currentColor"
10
+ role="img"
11
+ aria-hidden={props["aria-label"] ? undefined : true}
12
+ {...props}
13
+ >
14
+ {children}
15
+ </svg>
16
+ );
17
+ };
18
+
19
+ /**
20
+ * Check icon
21
+ *
22
+ * @param props - SVG props
23
+ * @returns SVG element
24
+ */
25
+ export const IconCheck = (props: Omit<SVGProps<SVGSVGElement>, "viewBox">) => {
26
+ return (
27
+ <SvgIcon width="24" height="24" viewBox="0 0 24 24" {...props}>
28
+ <path
29
+ fillRule="evenodd"
30
+ d="M19.916 4.626a.75.75 0 0 1 .208 1.04l-9 13.5a.75.75 0 0 1-1.154.114l-6-6a.75.75 0 0 1 1.06-1.06l5.353 5.353 8.493-12.74a.75.75 0 0 1 1.04-.207Z"
31
+ clipRule="evenodd"
32
+ />
33
+ </SvgIcon>
34
+ );
35
+ };
36
+
37
+ /**
38
+ * Copy icon
39
+ *
40
+ * @param props - SVG props
41
+ * @returns SVG element
42
+ */
43
+ export const IconCopy = (props: Omit<SVGProps<SVGSVGElement>, "viewBox">) => {
44
+ return (
45
+ <SvgIcon width="24" height="24" viewBox="0 0 24 24" {...props}>
46
+ <path d="M7.5 3.375c0-1.036.84-1.875 1.875-1.875h.375a3.75 3.75 0 0 1 3.75 3.75v1.875C13.5 8.161 14.34 9 15.375 9h1.875A3.75 3.75 0 0 1 21 12.75v3.375C21 17.16 20.16 18 19.125 18h-9.75A1.875 1.875 0 0 1 7.5 16.125V3.375Z" />
47
+ <path d="M15 5.25a5.23 5.23 0 0 0-1.279-3.434 9.768 9.768 0 0 1 6.963 6.963A5.23 5.23 0 0 0 17.25 7.5h-1.875A.375.375 0 0 1 15 7.125V5.25ZM4.875 6H6v10.125A3.375 3.375 0 0 0 9.375 19.5H16.5v1.125c0 1.035-.84 1.875-1.875 1.875h-9.75A1.875 1.875 0 0 1 3 20.625V7.875C3 6.839 3.84 6 4.875 6Z" />
48
+ </SvgIcon>
49
+ );
50
+ };
51
+
52
+ /**
53
+ * User icon
54
+ *
55
+ * @param props - SVG props
56
+ * @returns SVG element
57
+ */
58
+ export const IconUser = (props: Omit<SVGProps<SVGSVGElement>, "viewBox">) => {
59
+ return (
60
+ <SvgIcon width="24" height="24" viewBox="0 0 24 24" {...props}>
61
+ <path
62
+ fillRule="evenodd"
63
+ d="M18.685 19.097A9.723 9.723 0 0 0 21.75 12c0-5.385-4.365-9.75-9.75-9.75S2.25 6.615 2.25 12a9.723 9.723 0 0 0 3.065 7.097A9.716 9.716 0 0 0 12 21.75a9.716 9.716 0 0 0 6.685-2.653Zm-12.54-1.285A7.486 7.486 0 0 1 12 15a7.486 7.486 0 0 1 5.855 2.812A8.224 8.224 0 0 1 12 20.25a8.224 8.224 0 0 1-5.855-2.438ZM15.75 9a3.75 3.75 0 1 1-7.5 0 3.75 3.75 0 0 1 7.5 0Z"
64
+ clipRule="evenodd"
65
+ />
66
+ </SvgIcon>
67
+ );
68
+ };
@@ -0,0 +1,15 @@
1
+ "use client";
2
+
3
+ import { LoadingSpinner } from "@coinbase/cdp-react/components/LoadingSpinner";
4
+
5
+ /**
6
+ * App loading screen
7
+ */
8
+ export default function Loading() {
9
+ return (
10
+ <main>
11
+ <h1 className="sr-only">Loading</h1>
12
+ <LoadingSpinner />
13
+ </main>
14
+ );
15
+ }
@@ -0,0 +1,33 @@
1
+ "use client";
2
+
3
+ import { CDPReactProvider } from "@coinbase/cdp-react/components/CDPReactProvider";
4
+
5
+ import { theme } from "@/components/theme";
6
+
7
+ interface ProvidersProps {
8
+ children: React.ReactNode;
9
+ }
10
+
11
+ const CDP_CONFIG = {
12
+ projectId: process.env.NEXT_PUBLIC_CDP_PROJECT_ID ?? "",
13
+ };
14
+
15
+ const APP_CONFIG = {
16
+ name: "CDP Next.js StarterKit",
17
+ logoUrl: "http://localhost:3000/logo.svg",
18
+ };
19
+
20
+ /**
21
+ * Providers component that wraps the application in all requisite providers
22
+ *
23
+ * @param props - { object } - The props for the Providers component
24
+ * @param props.children - { React.ReactNode } - The children to wrap
25
+ * @returns The wrapped children
26
+ */
27
+ export default function Providers({ children }: ProvidersProps) {
28
+ return (
29
+ <CDPReactProvider config={CDP_CONFIG} app={APP_CONFIG} theme={theme}>
30
+ {children}
31
+ </CDPReactProvider>
32
+ );
33
+ }
@@ -0,0 +1,17 @@
1
+ "use client";
2
+
3
+ import { AuthButton } from "@coinbase/cdp-react/components/AuthButton";
4
+
5
+ /**
6
+ * Sign in screen
7
+ */
8
+ export default function SignInScreen() {
9
+ return (
10
+ <main className="card card--login">
11
+ <h1 className="sr-only">Sign in</h1>
12
+ <p className="card-title">Welcome!</p>
13
+ <p>Please sign in to continue.</p>
14
+ <AuthButton />
15
+ </main>
16
+ );
17
+ }
@@ -0,0 +1,64 @@
1
+ "use client";
2
+
3
+ import { useEvmAddress, useIsSignedIn } from "@coinbase/cdp-hooks";
4
+ import { useCallback, useEffect, useMemo, useState } from "react";
5
+ import { createPublicClient, http, formatEther } from "viem";
6
+ import { baseSepolia } from "viem/chains";
7
+
8
+ import Header from "@/components/Header";
9
+ import Transaction from "@/components/Transaction";
10
+ import UserBalance from "@/components/UserBalance";
11
+
12
+ /**
13
+ * Create a viem client to access user's balance on the Base Sepolia network
14
+ */
15
+ const client = createPublicClient({
16
+ chain: baseSepolia,
17
+ transport: http(),
18
+ });
19
+
20
+ /**
21
+ * The Signed In screen
22
+ */
23
+ export default function SignedInScreen() {
24
+ const isSignedIn = useIsSignedIn();
25
+ const evmAddress = useEvmAddress();
26
+ const [balance, setBalance] = useState<bigint | undefined>(undefined);
27
+
28
+ const formattedBalance = useMemo(() => {
29
+ if (balance === undefined) return undefined;
30
+ return formatEther(balance);
31
+ }, [balance]);
32
+
33
+ const getBalance = useCallback(async () => {
34
+ if (!evmAddress) return;
35
+ const balance = await client.getBalance({
36
+ address: evmAddress,
37
+ });
38
+ setBalance(balance);
39
+ }, [evmAddress]);
40
+
41
+ useEffect(() => {
42
+ getBalance();
43
+ const interval = setInterval(getBalance, 500);
44
+ return () => clearInterval(interval);
45
+ }, [getBalance]);
46
+
47
+ return (
48
+ <>
49
+ <Header />
50
+ <main className="main flex-col-container flex-grow">
51
+ <div className="main-inner flex-col-container">
52
+ <div className="card card--user-balance">
53
+ <UserBalance balance={formattedBalance} />
54
+ </div>
55
+ <div className="card card--transaction">
56
+ {isSignedIn && evmAddress && (
57
+ <Transaction balance={formattedBalance} onSuccess={getBalance} />
58
+ )}
59
+ </div>
60
+ </div>
61
+ </main>
62
+ </>
63
+ );
64
+ }
@@ -0,0 +1,128 @@
1
+ "use client";
2
+ import { useSendEvmTransaction, useEvmAddress } from "@coinbase/cdp-hooks";
3
+ import { Button } from "@coinbase/cdp-react/components/Button";
4
+ import { LoadingSkeleton } from "@coinbase/cdp-react/components/LoadingSkeleton";
5
+ import { type MouseEvent, useCallback, useMemo, useState } from "react";
6
+
7
+ interface Props {
8
+ balance?: string;
9
+ onSuccess?: () => void;
10
+ }
11
+
12
+ /**
13
+ * This component demonstrates how to send an EVM transaction using the CDP hooks.
14
+ *
15
+ * @param {Props} props - The props for the Transaction component.
16
+ * @param {string} [props.balance] - The user's balance.
17
+ * @param {() => void} [props.onSuccess] - A function to call when the transaction is successful.
18
+ * @returns A component that displays a transaction form and a transaction hash.
19
+ */
20
+ export default function Transaction(props: Props) {
21
+ const { balance, onSuccess } = props;
22
+ const sendEvmTransaction = useSendEvmTransaction();
23
+ const evmAddress = useEvmAddress();
24
+
25
+ const [isPending, setIsPending] = useState(false);
26
+ const [transactionHash, setTransactionHash] = useState<string | null>(null);
27
+ const hasBalance = useMemo(() => {
28
+ return balance && balance !== "0";
29
+ }, [balance]);
30
+
31
+ const handleSendTransaction = useCallback(
32
+ async (e: MouseEvent<HTMLButtonElement>) => {
33
+ if (!evmAddress) {
34
+ return;
35
+ }
36
+
37
+ e.preventDefault();
38
+ setIsPending(true);
39
+
40
+ const { transactionHash } = await sendEvmTransaction({
41
+ transaction: {
42
+ to: evmAddress, // Send to yourself for testing
43
+ value: 1000000000000n, // 0.000001 ETH in wei
44
+ gas: 21000n,
45
+ chainId: 84532, // Base Sepolia
46
+ type: "eip1559",
47
+ },
48
+ evmAccount: evmAddress,
49
+ network: "base-sepolia",
50
+ });
51
+
52
+ setTransactionHash(transactionHash);
53
+ setIsPending(false);
54
+ onSuccess?.();
55
+ },
56
+ [evmAddress, sendEvmTransaction, onSuccess],
57
+ );
58
+
59
+ return (
60
+ <>
61
+ {balance === undefined && (
62
+ <>
63
+ <h2 className="card-title">Send a transaction</h2>
64
+ <LoadingSkeleton className="loading--text" />
65
+ <LoadingSkeleton className="loading--btn" />
66
+ </>
67
+ )}
68
+ {balance !== undefined && (
69
+ <>
70
+ {!transactionHash && (
71
+ <>
72
+ <h2 className="card-title">Send a transaction</h2>
73
+ {hasBalance && (
74
+ <>
75
+ <p>Send 0.000001 ETH to yourself on Base Sepolia</p>
76
+ <Button
77
+ className="tx-button"
78
+ onClick={handleSendTransaction}
79
+ isPending={isPending}
80
+ >
81
+ Send Transaction
82
+ </Button>
83
+ </>
84
+ )}
85
+ {!hasBalance && (
86
+ <>
87
+ <p>You need ETH to send a transaction, but you have none.</p>
88
+ <p>
89
+ Get some from{" "}
90
+ <a
91
+ href="https://portal.cdp.coinbase.com/products/faucet"
92
+ target="_blank"
93
+ rel="noopener noreferrer"
94
+ >
95
+ Base Sepolia Faucet
96
+ </a>
97
+ </p>
98
+ </>
99
+ )}
100
+ </>
101
+ )}
102
+ {transactionHash && (
103
+ <>
104
+ <h2 className="card-title">Transaction sent</h2>
105
+ <p>
106
+ Transaction hash:{" "}
107
+ <a
108
+ href={`https://sepolia.basescan.org/tx/${transactionHash}`}
109
+ target="_blank"
110
+ rel="noopener noreferrer"
111
+ >
112
+ {transactionHash.slice(0, 6)}...{transactionHash.slice(-4)}
113
+ </a>
114
+ </p>
115
+ <Button
116
+ variant="secondary"
117
+ className="tx-button"
118
+ onClick={() => setTransactionHash(null)}
119
+ >
120
+ Send another transaction
121
+ </Button>
122
+ </>
123
+ )}
124
+ </>
125
+ )}
126
+ </>
127
+ );
128
+ }
@@ -0,0 +1,42 @@
1
+ "use client";
2
+ import { LoadingSkeleton } from "@coinbase/cdp-react/components/LoadingSkeleton";
3
+
4
+ interface Props {
5
+ balance?: string;
6
+ }
7
+
8
+ /**
9
+ * A component that displays the user's balance.
10
+ *
11
+ * @param {Props} props - The props for the UserBalance component.
12
+ * @param {string} [props.balance] - The user's balance.
13
+ * @returns A component that displays the user's balance.
14
+ */
15
+ export default function UserBalance(props: Props) {
16
+ const { balance } = props;
17
+ return (
18
+ <>
19
+ <h2 className="card-title">Available balance</h2>
20
+ <p className="user-balance flex-col-container flex-grow">
21
+ {balance === undefined && <LoadingSkeleton as="span" className="loading--balance" />}
22
+ {balance !== undefined && (
23
+ <span className="flex-row-container">
24
+ <img src="/eth.svg" alt="" className="balance-icon" />
25
+ <span>{balance}</span>
26
+ <span className="sr-only">Ethereum</span>
27
+ </span>
28
+ )}
29
+ </p>
30
+ <p>
31
+ Get testnet ETH from{" "}
32
+ <a
33
+ href="https://portal.cdp.coinbase.com/products/faucet"
34
+ target="_blank"
35
+ rel="noopener noreferrer"
36
+ >
37
+ Base Sepolia Faucet
38
+ </a>
39
+ </p>
40
+ </>
41
+ );
42
+ }
@@ -0,0 +1,27 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2017",
4
+ "lib": ["dom", "dom.iterable", "esnext"],
5
+ "allowJs": true,
6
+ "skipLibCheck": true,
7
+ "strict": true,
8
+ "noEmit": true,
9
+ "esModuleInterop": true,
10
+ "module": "esnext",
11
+ "moduleResolution": "bundler",
12
+ "resolveJsonModule": true,
13
+ "isolatedModules": true,
14
+ "jsx": "preserve",
15
+ "incremental": true,
16
+ "plugins": [
17
+ {
18
+ "name": "next"
19
+ }
20
+ ],
21
+ "paths": {
22
+ "@/*": ["./src/*"]
23
+ }
24
+ },
25
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
26
+ "exclude": ["node_modules"]
27
+ }
@@ -1,16 +1,23 @@
1
1
  # CDP React App
2
2
 
3
- This project was generated with [`@coinbase/create-cdp-app`](https://github.com/coinbase/cdp-web) using the React Components template.
3
+ This project was generated with [`@coinbase/create-cdp-app`](https://coinbase.github.io/cdp-web/modules/_coinbase_create-cdp-app.html) using the React template.
4
4
 
5
5
  ## Project Structure
6
6
 
7
7
  ```
8
8
  src/
9
- ├── App.tsx # Main application component with CDP initialization and CDP AuthButton
10
- ├── Transaction.tsx # Example transaction flow using CDP Hooks
11
- ├── assets/ # Static assets
12
- ├── index.css # Global styles
13
- └── main.tsx # Entry point with CDP provider setup
9
+ ├── App.tsx # Main application component with routing and layout
10
+ ├── config.ts # CDP configuration settings
11
+ ├── Header.tsx # Navigation header with authentication status
12
+ ├── Icons.tsx # Reusable icon components
13
+ ├── index.css # Global styles and theme variables
14
+ ├── Loading.tsx # Loading state component
15
+ ├── main.tsx # Entry point with CDP provider setup
16
+ ├── SignedInScreen.tsx # Screen displayed after successful authentication
17
+ ├── SignInScreen.tsx # Authentication screen with CDP sign-in flow
18
+ ├── theme.ts # Theme configuration and styling constants
19
+ ├── Transaction.tsx # Example transaction flow using CDP Hooks
20
+ ├── UserBalance.tsx # Component to display user's wallet balance
14
21
  ```
15
22
 
16
23
  ## Getting Started
@@ -0,0 +1,25 @@
1
+ <svg
2
+ xmlns="http://www.w3.org/2000/svg"
3
+ width="32"
4
+ height="32"
5
+ viewBox="0 0 32 32"
6
+ aria-hidden="true"
7
+ >
8
+ <g fill="none" fillRule="evenodd">
9
+ <circle cx="16" cy="16" r="16" fill="#627EEA" />
10
+ <g fill="#FFF" fillRule="nonzero">
11
+ <path fillOpacity=".602" d="M16.498 4v8.87l7.497 3.35z" />
12
+ <path d="M16.498 4L9 16.22l7.498-3.35z" />
13
+ <path
14
+ fillOpacity=".602"
15
+ d="M16.498 21.968v6.027L24 17.616z"
16
+ />
17
+ <path d="M16.498 27.995v-6.028L9 17.616z" />
18
+ <path
19
+ fillOpacity=".2"
20
+ d="M16.498 20.573l7.497-4.353-7.497-3.348z"
21
+ />
22
+ <path fillOpacity=".602" d="M9 16.22l7.498 4.353v-7.701z" />
23
+ </g>
24
+ </g>
25
+ </svg>
@@ -0,0 +1,5 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 128 128">
2
+ <circle cx="64" cy="64" r="64" fill="#008080" />
3
+ <path fill="#FFF"
4
+ d="M78.91 76.225q.7 0 1.25.54l3.39 3.68q-2.82 3.49-6.93 5.35-4.11 1.85-9.87 1.85-5.15 0-9.26-1.76-4.12-1.76-7.03-4.89-2.91-3.14-4.46-7.49t-1.55-9.51q0-5.21 1.66-9.55 1.66-4.33 4.69-7.47 3.02-3.14 7.21-4.88 4.2-1.74 9.28-1.74 5.06 0 8.98 1.66t6.67 4.35l-2.88 4q-.25.39-.65.67-.4.29-1.11.29-.48 0-.99-.27t-1.12-.67-1.41-.88-1.85-.88q-1.06-.4-2.45-.67-1.39-.28-3.22-.28-3.1 0-5.68 1.11-2.57 1.1-4.43 3.2-1.86 2.09-2.88 5.12-1.02 3.02-1.02 6.89 0 3.91 1.1 6.95t2.99 5.12 4.45 3.18q2.56 1.11 5.5 1.11 1.76 0 3.19-.2 1.42-.19 2.62-.6 1.2-.42 2.27-1.08 1.08-.65 2.13-1.61.32-.29.67-.47.36-.17.74-.17" />
5
+ </svg>
@@ -32,7 +32,7 @@ function Header() {
32
32
  return (
33
33
  <header>
34
34
  <div className="header-inner">
35
- <h1 className="site-title">CDP React StarterKit</h1>
35
+ <h1 className="site-title">CDP Next.js StarterKit</h1>
36
36
  <div className="user-info flex-row-container">
37
37
  {evmAddress && (
38
38
  <button
@@ -0,0 +1,32 @@
1
+ import { type Theme } from "@coinbase/cdp-react/theme";
2
+
3
+ export const theme: Partial<Theme> = {
4
+ "colors-background": "var(--cdp-example-card-bg-color)",
5
+ "colors-backgroundOverlay": "var(--cdp-example-bg-overlay-color)",
6
+ "colors-backgroundSkeleton": "var(--cdp-example-bg-skeleton-color)",
7
+ "colors-text": "var(--cdp-example-text-color)",
8
+ "colors-textSecondary": "var(--cdp-example-text-secondary-color)",
9
+ "colors-border": "var(--cdp-example-card-border-color)",
10
+ "colors-primary": "var(--cdp-example-accent-color)",
11
+ "colors-primaryText": "var(--cdp-example-accent-foreground-color)",
12
+ "colors-primaryHoverBackground": "var(--cdp-example-accent-hover-color)",
13
+ "colors-primaryHoverText": "var(--cdp-example-accent-foreground-color)",
14
+ "colors-primaryFocusRing": "var(--cdp-example-accent-color)",
15
+ "colors-secondary": "var(--cdp-example-bg-low-contrast-color)",
16
+ "colors-secondaryText": "var(--cdp-example-text-color)",
17
+ "colors-secondaryHoverBackground": "var(--cdp-example-bg-low-contrast-color)",
18
+ "colors-secondaryHoverText": "var(--cdp-example-text-color)",
19
+ "colors-secondaryFocusRing": "var(--cdp-example-accent-color)",
20
+ "colors-inputBackground": "var(--cdp-example-card-bg-color)",
21
+ "colors-inputBorder": "var(--cdp-example-text-secondary-color)",
22
+ "colors-inputText": "var(--cdp-example-text-color)",
23
+ "colors-inputLabel": "var(--cdp-example-text-color)",
24
+ "colors-inputPlaceholder": "var(--cdp-example-text-secondary-color)",
25
+ "colors-inputFocusBorder": "var(--cdp-example-accent-color)",
26
+ "colors-linkText": "var(--cdp-example-accent-color)",
27
+ "colors-linkHover": "var(--cdp-example-accent-hover-color)",
28
+ "colors-linkSecondaryText": "var(--cdp-example-text-color)",
29
+ "colors-linkSecondaryHover": "var(--cdp-example-text-color)",
30
+ "fontFamily-sans": "var(--cdp-example-font-family)",
31
+ fontSizeBase: "var(--cdp-example-base-font-size)",
32
+ };