create-universal-dapp 1.0.0

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.
package/README.md ADDED
@@ -0,0 +1,165 @@
1
+ # create-universal-dapp
2
+
3
+ A CLI tool to scaffold Push Chain applications with your choice of framework and tooling.
4
+
5
+ ## Quick Start
6
+
7
+ ```bash
8
+ npm install -g create-universal-dapp
9
+ create-universal-dapp my-app
10
+ ```
11
+
12
+ Or use npx:
13
+
14
+ ```bash
15
+ npx create-universal-dapp my-app
16
+ ```
17
+
18
+ ## Features
19
+
20
+ - ⚡ **Multiple Frameworks**: Choose between Next.js or Vite (React)
21
+ - 🔧 **ESLint**: Optional code linting setup
22
+ - 📦 **Push Chain Integration**: Pre-configured with @pushchain/core and @pushchain/ui-kit
23
+ - 🚀 **TypeScript**: Full TypeScript support out of the box
24
+ - 🎨 **Styling**: Tailwind CSS set up by default
25
+
26
+ ## Usage
27
+
28
+ ### Interactive Mode
29
+
30
+ Run the CLI without arguments to enter interactive mode:
31
+
32
+ ```bash
33
+ create-universal-dapp
34
+ ```
35
+
36
+ You'll be prompted to:
37
+ 1. Choose your project name
38
+ 2. Select a framework (Next.js or Vite)
39
+ 3. Enable/disable ESLint
40
+
41
+ ### Command Line Options
42
+
43
+ ```bash
44
+ create-universal-dapp my-app --framework nextjs --eslint
45
+ ```
46
+
47
+ Available options:
48
+ - `-f, --framework <framework>`: Choose 'nextjs' or 'vite'
49
+ - `--eslint / --no-eslint`: Include/exclude ESLint configuration
50
+
51
+ ## Generated Project Structure
52
+
53
+ ### Next.js Project
54
+ ```
55
+ my-app/
56
+ ├── src/
57
+ │ ├── app/
58
+ │ │ ├── globals.css
59
+ │ │ ├── layout.tsx
60
+ │ │ └── page.tsx
61
+ │ ├── components/
62
+ │ └── lib/
63
+ │ ├── pushchain.tsx # Push Chain provider
64
+ │ └── utils.ts # Utility functions
65
+ ├── package.json
66
+ ├── next.config.js
67
+ ├── tsconfig.json
68
+ └── tailwind.config.js
69
+ ```
70
+
71
+ ### Vite Project
72
+ ```
73
+ my-app/
74
+ ├── src/
75
+ │ ├── components/
76
+ │ ├── lib/
77
+ │ │ ├── pushchain.tsx # Push Chain provider
78
+ │ │ └── utils.ts # Utility functions
79
+ │ ├── App.tsx
80
+ │ ├── main.tsx
81
+ │ └── index.css
82
+ ├── index.html
83
+ ├── package.json
84
+ ├── vite.config.ts
85
+ ├── tsconfig.json
86
+ └── tailwind.config.js
87
+ ```
88
+
89
+ ## Push Chain Integration
90
+
91
+ The generated project includes:
92
+
93
+ ### 1. PushChain Provider
94
+ A React context provider that manages the Push Chain connection:
95
+
96
+ ```typescript
97
+ import { usePushChain } from '@/lib/pushchain'
98
+
99
+ function MyComponent() {
100
+ const { pushChain, isConnected, connect, disconnect, error } = usePushChain()
101
+
102
+ // Use Push Chain methods here
103
+ }
104
+ ```
105
+
106
+ ### 2. Demo Component
107
+ A working example showing how to:
108
+ - Connect to Push Chain
109
+ - Send messages
110
+ - Handle errors
111
+ - Display connection status
112
+
113
+ ### 3. Environment Variables
114
+ Configure your Push Chain settings:
115
+
116
+ ```env
117
+ # Next.js
118
+ NEXT_PUBLIC_PUSHCHAIN_API_KEY=your_api_key_here
119
+ NEXT_PUBLIC_PUSHCHAIN_NETWORK=testnet
120
+
121
+ # Vite
122
+ VITE_PUSHCHAIN_API_KEY=your_api_key_here
123
+ VITE_PUSHCHAIN_NETWORK=testnet
124
+ ```
125
+
126
+ ## Development
127
+
128
+ To work on this CLI tool:
129
+
130
+ ```bash
131
+ git clone https://github.com/pushchainxyz/create-universal-dapp
132
+ cd create-universal-dapp
133
+ npm install
134
+ npm run build
135
+ npm link
136
+ ```
137
+
138
+ Then you can test it:
139
+
140
+ ```bash
141
+ create-universal-dapp test-app
142
+ ```
143
+
144
+ ## Scripts
145
+
146
+ - `npm run build` - Build the CLI
147
+ - `npm run dev` - Run in development mode
148
+ - `npm start` - Run the built CLI
149
+
150
+ ## Next Steps
151
+
152
+ After creating your project:
153
+
154
+ 1. **Configure Environment Variables**: Set up your Push Chain API keys
155
+ 2. **Customize the Integration**: Replace example code with your specific Push Chain functionality
156
+ 3. **Add Features**: Build upon the generated structure
157
+ 4. **Explore Push Chain**: Check out the @pushchain/ui-kit for additional components
158
+
159
+ ## Contributing
160
+
161
+ Contributions are welcome! Please feel free to submit a Pull Request.
162
+
163
+ ## License
164
+
165
+ MIT
@@ -0,0 +1,2 @@
1
+ export declare function createPushApp(projectName?: string, options?: any): Promise<void>;
2
+ //# sourceMappingURL=create.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"AAUA,wBAAsB,aAAa,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,iBAmDtE"}
@@ -0,0 +1,52 @@
1
+ import chalk from 'chalk';
2
+ import ora from 'ora';
3
+ import fs from 'fs-extra';
4
+ import { getProjectOptions } from '../utils/prompts.js';
5
+ import { createNextjsApp } from '../templates/nextjs.js';
6
+ import { createViteApp } from '../templates/vite.js';
7
+ export async function createPushApp(projectName, options) {
8
+ try {
9
+ // Get project configuration from user
10
+ const projectOptions = await getProjectOptions(projectName, options);
11
+ console.log(chalk.blue('\n📋 Project Configuration:'));
12
+ console.log(chalk.gray(` Project Name: ${projectOptions.projectName}`));
13
+ console.log(chalk.gray(` Framework: ${projectOptions.framework}`));
14
+ console.log(chalk.gray(` ESLint: ${projectOptions.eslint ? 'Yes' : 'No'}`));
15
+ console.log(chalk.gray(` Target Directory: ${projectOptions.targetDir}\n`));
16
+ // Check if directory already exists
17
+ if (await fs.pathExists(projectOptions.targetDir)) {
18
+ console.log(chalk.red(`❌ Directory ${projectOptions.projectName} already exists!`));
19
+ process.exit(1);
20
+ }
21
+ // Create project directory
22
+ const spinner = ora('Creating project directory...').start();
23
+ await fs.ensureDir(projectOptions.targetDir);
24
+ spinner.succeed('Project directory created');
25
+ // Generate project based on framework choice
26
+ if (projectOptions.framework === 'nextjs') {
27
+ await createNextjsApp(projectOptions);
28
+ }
29
+ else {
30
+ await createViteApp(projectOptions);
31
+ }
32
+ // Skipping auto-install to save time; user will install manually
33
+ console.log(chalk.green(`
34
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
35
+ `));
36
+ console.log(chalk.green.bold(` 🎉 SUCCESS! Project Created! 🎉 `));
37
+ console.log(chalk.cyan(` Your Push Chain Universal App is ready to go! `));
38
+ console.log(chalk.green(`
39
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
40
+ `));
41
+ console.log(chalk.blue.bold('\n🚀 Next Steps:'));
42
+ console.log(chalk.white(` cd ${projectOptions.projectName}`));
43
+ console.log(chalk.white(` npm install`));
44
+ console.log(chalk.white(` npm run dev`));
45
+ console.log(chalk.green('\n Happy Building! 🚀✨\n'));
46
+ }
47
+ catch (error) {
48
+ console.error(chalk.red('❌ Error creating project:'), error);
49
+ process.exit(1);
50
+ }
51
+ }
52
+ //# sourceMappingURL=create.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create.js","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env node
2
+ import { program } from 'commander';
3
+ import chalk from 'chalk';
4
+ import { createPushApp } from './commands/create.js';
5
+ console.log(chalk.cyan.bold(`
6
+ $$$$$$\\ $$\\ $$$$$$\\ $$\\ $$\\
7
+ $$ __$$\\ $$ | $$ __$$\\ $$ | $$\\
8
+ $$ / $$ |$$\\ $$\\ $$$$$$$\\ $$$$$$$\\ $$ / \\__|$$$$$$$\\ $$$$$$\\ $$ |$$$$$$$\\
9
+ $$$$$$$ |$$ | $$ |$$ _____| $$ __$$\\ $$ | $$ __$$\\ \\____$$\\ $$ |$$ __$$\\
10
+ $$ ____/ $$ | $$ |\\$$$$$$\\ $$ | $$ | $$ | $$ | $$ | $$$$$$$ |$$ |$$ | $$ |
11
+ $$ | $$ | $$ | \\____$$\\ $$ | $$ | $$ | $$\\ $$ | $$ |$$ __$$ |$$ |$$ | $$ |
12
+ $$ | \\$$$$$$ |$$$$$$$ | $$ | $$ | \\$$$$$$ |$$ | $$ |\\$$$$$$$ |$$ |$$ | $$ |
13
+ \\__| \\______/ \\_______/ \\__| \\__| \\______/ \\__| \\__| \\_______|\\__|\\__| \\__|
14
+ `));
15
+ program
16
+ .name('create-universal-dapp')
17
+ .description('CLI tool to scaffold Push Chain universal applications')
18
+ .version('1.0.0');
19
+ program
20
+ .argument('[project-name]', 'name of the project')
21
+ .option('-f, --framework <framework>', 'framework to use (nextjs or vite)')
22
+ .option('--eslint', 'include ESLint configuration')
23
+ .option('--no-eslint', 'skip ESLint configuration')
24
+ .action(createPushApp);
25
+ program.parse();
26
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;;;;;;;;;CAS3B,CAAC,CAAC,CAAC;AAEJ,OAAO;KACJ,IAAI,CAAC,uBAAuB,CAAC;KAC7B,WAAW,CAAC,wDAAwD,CAAC;KACrE,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO;KACJ,QAAQ,CAAC,gBAAgB,EAAE,qBAAqB,CAAC;KACjD,MAAM,CAAC,6BAA6B,EAAE,mCAAmC,CAAC;KAC1E,MAAM,CAAC,UAAU,EAAE,8BAA8B,CAAC;KAClD,MAAM,CAAC,aAAa,EAAE,2BAA2B,CAAC;KAClD,MAAM,CAAC,aAAa,CAAC,CAAC;AAEzB,OAAO,CAAC,KAAK,EAAE,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { ProjectOptions } from '../types/index.js';
2
+ export declare function createNextjsApp(options: ProjectOptions): Promise<void>;
3
+ //# sourceMappingURL=nextjs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nextjs.d.ts","sourceRoot":"","sources":["../../src/templates/nextjs.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAExD,wBAAsB,eAAe,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CA6B5E"}
@@ -0,0 +1,406 @@
1
+ import fs from 'fs-extra';
2
+ import path from 'path';
3
+ import ora from 'ora';
4
+ export async function createNextjsApp(options) {
5
+ const spinner = ora('Setting up Next.js project...').start();
6
+ try {
7
+ // Create package.json
8
+ await createNextjsPackageJson(options);
9
+ // Create Next.js configuration files
10
+ await createNextjsConfig(options);
11
+ // Create source structure
12
+ await createNextjsSourceFiles(options);
13
+ // Create Push Chain integration files
14
+ await createPushChainIntegration(options);
15
+ // Create ESLint config if requested
16
+ if (options.eslint) {
17
+ await createESLintConfig(options);
18
+ }
19
+ // Create Tailwind config (Tailwind-only setup)
20
+ await createTailwindConfig(options);
21
+ spinner.succeed('Next.js project structure created');
22
+ }
23
+ catch (error) {
24
+ spinner.fail('Failed to create Next.js project');
25
+ throw error;
26
+ }
27
+ }
28
+ async function createNextjsPackageJson(options) {
29
+ const packageJson = {
30
+ name: options.projectName,
31
+ version: "0.1.0",
32
+ private: true,
33
+ scripts: {
34
+ dev: "next dev",
35
+ build: "next build",
36
+ start: "next start",
37
+ lint: options.eslint ? "next lint" : undefined
38
+ },
39
+ dependencies: {
40
+ react: "^18.3.1",
41
+ "react-dom": "^18.3.1",
42
+ next: "^14.0.0",
43
+ "@pushchain/ui-kit": "^1.1.33"
44
+ },
45
+ devDependencies: {
46
+ typescript: "^5.2.2",
47
+ "@types/node": "^20.8.0",
48
+ "@types/react": "^18.2.33",
49
+ "@types/react-dom": "^18.2.14",
50
+ tailwindcss: "^3.3.0",
51
+ autoprefixer: "^10.4.16",
52
+ postcss: "^8.4.31"
53
+ }
54
+ };
55
+ // Remove undefined values
56
+ Object.keys(packageJson.scripts).forEach(key => {
57
+ const scripts = packageJson.scripts;
58
+ if (scripts[key] === undefined) {
59
+ delete scripts[key];
60
+ }
61
+ });
62
+ await fs.writeJSON(path.join(options.targetDir, 'package.json'), packageJson, { spaces: 2 });
63
+ }
64
+ async function createNextjsConfig(options) {
65
+ // Next.js config
66
+ const nextConfig = `/** @type {import('next').NextConfig} */
67
+ const nextConfig = {
68
+ // Add any Next.js config options here
69
+ }
70
+
71
+ module.exports = nextConfig`;
72
+ await fs.writeFile(path.join(options.targetDir, 'next.config.js'), nextConfig);
73
+ // TypeScript config
74
+ const tsConfig = {
75
+ compilerOptions: {
76
+ target: "es5",
77
+ lib: ["dom", "dom.iterable", "es6"],
78
+ allowJs: true,
79
+ skipLibCheck: true,
80
+ strict: true,
81
+ forceConsistentCasingInFileNames: true,
82
+ noEmit: true,
83
+ esModuleInterop: true,
84
+ module: "esnext",
85
+ moduleResolution: "bundler",
86
+ resolveJsonModule: true,
87
+ isolatedModules: true,
88
+ jsx: "preserve",
89
+ incremental: true,
90
+ plugins: [
91
+ {
92
+ name: "next"
93
+ }
94
+ ],
95
+ baseUrl: ".",
96
+ paths: {
97
+ "@/*": ["./src/*"]
98
+ }
99
+ },
100
+ include: ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
101
+ exclude: ["node_modules"]
102
+ };
103
+ await fs.writeJSON(path.join(options.targetDir, 'tsconfig.json'), tsConfig, { spaces: 2 });
104
+ }
105
+ async function createNextjsSourceFiles(options) {
106
+ // Create src directory structure
107
+ const srcDir = path.join(options.targetDir, 'src');
108
+ const appDir = path.join(srcDir, 'app');
109
+ await fs.ensureDir(appDir);
110
+ // Create app layout
111
+ const layout = `import './globals.css'
112
+ import { Inter } from 'next/font/google'
113
+ import { PushChainProviders } from '@/providers/PushChainProviders'
114
+ import type { Metadata } from 'next'
115
+
116
+ const inter = Inter({ subsets: ['latin'] })
117
+
118
+ export const metadata: Metadata = {
119
+ title: '${options.projectName}',
120
+ description: 'A Push Chain application built with Next.js - enabling universal blockchain access and shared state management.',
121
+ keywords: ['Push Chain', 'blockchain', 'Web3', 'universal wallet', 'Next.js'],
122
+ authors: [{ name: '${options.projectName} Team' }],
123
+ creator: '${options.projectName}',
124
+ publisher: '${options.projectName}',
125
+ formatDetection: {
126
+ email: false,
127
+ address: false,
128
+ telephone: false,
129
+ },
130
+ metadataBase: new URL('https://your-domain.com'), // Replace with your actual domain
131
+ openGraph: {
132
+ title: '${options.projectName}',
133
+ description: 'A Push Chain application built with Next.js',
134
+ url: 'https://your-domain.com', // Replace with your actual URL
135
+ siteName: '${options.projectName}',
136
+ locale: 'en_US',
137
+ type: 'website',
138
+ },
139
+ twitter: {
140
+ card: 'summary_large_image',
141
+ title: '${options.projectName}',
142
+ description: 'A Push Chain application built with Next.js',
143
+ creator: '@your_twitter_handle', // Replace with your Twitter handle
144
+ },
145
+ robots: {
146
+ index: true,
147
+ follow: true,
148
+ googleBot: {
149
+ index: true,
150
+ follow: true,
151
+ 'max-video-preview': -1,
152
+ 'max-image-preview': 'large',
153
+ 'max-snippet': -1,
154
+ },
155
+ },
156
+ }
157
+
158
+ export default function RootLayout({
159
+ children,
160
+ }: {
161
+ children: React.ReactNode
162
+ }) {
163
+ return (
164
+ <html lang="en">
165
+ <body className={inter.className}>
166
+ <PushChainProviders>
167
+ {children}
168
+ </PushChainProviders>
169
+ </body>
170
+ </html>
171
+ )
172
+ }`;
173
+ await fs.writeFile(path.join(appDir, 'layout.tsx'), layout);
174
+ // Create main page
175
+ const page = `'use client'
176
+
177
+ import { PushUniversalAccountButton, usePushWalletContext } from '@pushchain/ui-kit'
178
+
179
+ export default function Home() {
180
+ const { universalAccount } = usePushWalletContext();
181
+
182
+ console.log("universalAccount", universalAccount);
183
+
184
+ return (
185
+ <main className="min-h-screen bg-white text-gray-900 p-8">
186
+ <div className="container mx-auto max-w-4xl">
187
+ <div className="text-center mb-8">
188
+ <h1 className="text-4xl font-bold mb-4">
189
+ Welcome to ${options.projectName}
190
+ </h1>
191
+ <p className="text-lg text-gray-600 mb-8">
192
+ Your Push Chain application is ready to go!
193
+ </p>
194
+ </div>
195
+
196
+ <div className="max-w-2xl mx-auto border rounded-lg shadow-sm p-6">
197
+ <div className="flex items-center justify-between mb-4">
198
+ <h2 className="text-2xl font-semibold">Push Chain Integration</h2>
199
+ <span className={"inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-semibold text-white " + (universalAccount ? 'bg-green-500' : 'bg-gray-500')}>
200
+ {universalAccount ? 'Connected' : 'Not Connected'}
201
+ </span>
202
+ </div>
203
+
204
+ <div className="flex justify-center mb-6">
205
+ <PushUniversalAccountButton />
206
+ </div>
207
+
208
+ {universalAccount && (
209
+ <div className="mt-6 p-4 bg-gray-100 rounded-lg">
210
+ <h3 className="font-semibold mb-2">Account Details:</h3>
211
+ <pre className="text-sm overflow-auto">
212
+ {JSON.stringify(universalAccount, null, 2)}
213
+ </pre>
214
+ </div>
215
+ )}
216
+
217
+ <div className="text-sm text-gray-600 mt-6">
218
+ <p className="font-medium">Next steps:</p>
219
+ <ul className="list-disc list-inside space-y-1 mt-2">
220
+ <li>Configure your Push Chain settings in providers/PushChainProviders.tsx</li>
221
+ <li>Customize the app metadata in app/layout.tsx</li>
222
+ <li>Add your chain configuration and RPC URLs</li>
223
+ <li>Explore the @pushchain/ui-kit for more components</li>
224
+ </ul>
225
+ </div>
226
+ </div>
227
+ </div>
228
+ </main>
229
+ )
230
+ }`;
231
+ await fs.writeFile(path.join(appDir, 'page.tsx'), page);
232
+ // Create global CSS (Tailwind directives only)
233
+ const globalCss = `@tailwind base;
234
+ @tailwind components;
235
+ @tailwind utilities;`;
236
+ await fs.writeFile(path.join(appDir, 'globals.css'), globalCss);
237
+ }
238
+ async function createPushChainIntegration(options) {
239
+ // Create providers directory
240
+ const providersDir = path.join(options.targetDir, 'src', 'providers');
241
+ await fs.ensureDir(providersDir);
242
+ // Create PushChainProviders.tsx following your pattern but with Next.js specific comments
243
+ const pushchainProviders = `'use client'
244
+
245
+ import {
246
+ PushUI,
247
+ PushUniversalWalletProvider,
248
+ type AppMetadata,
249
+ type ProviderConfigProps,
250
+ } from "@pushchain/ui-kit";
251
+
252
+ /**
253
+ * PushChainProviders Component for Next.js
254
+ *
255
+ * This component wraps your entire Next.js application with Push Chain's Universal Wallet Provider.
256
+ * It configures the wallet connection options, network settings, and app metadata.
257
+ *
258
+ * Configuration Guide:
259
+ * - network: Choose between MAINNET, TESTNET, or DEV
260
+ * - login: Configure authentication methods (email, google, wallet)
261
+ * - modal: Customize the UI appearance and behavior
262
+ * - chainConfig: Add your custom RPC endpoints
263
+ * - appMetadata: Brand your app with logo, title, and description
264
+ *
265
+ * Next.js Specific Notes:
266
+ * - This component uses 'use client' directive for client-side functionality
267
+ * - Environment variables should be prefixed with NEXT_PUBLIC_ for client access
268
+ * - Metadata is also configured in app/layout.tsx for SEO
269
+ */
270
+
271
+ const PushChainProviders = ({ children }: { children: React.ReactNode }) => {
272
+ // Wallet configuration - customize these settings for your app
273
+ const walletConfig: ProviderConfigProps = {
274
+ // Network selection: MAINNET for production, TESTNET for development
275
+ network: PushUI.CONSTANTS.PUSH_NETWORK.TESTNET,
276
+
277
+ // Login options - enable/disable authentication methods
278
+ login: {
279
+ email: true, // Allow email authentication
280
+ google: true, // Allow Google OAuth
281
+ wallet: {
282
+ enabled: true, // Allow wallet connection (MetaMask, etc.)
283
+ },
284
+ appPreview: true, // Show app preview in login modal
285
+ },
286
+
287
+ // Modal UI customization
288
+ modal: {
289
+ // Layout: SPLIT (side-by-side) or STACKED (vertical)
290
+ loginLayout: PushUI.CONSTANTS.LOGIN.LAYOUT.SPLIT,
291
+
292
+ // Connected wallet display: HOVER (on hover) or FULL (always visible)
293
+ connectedLayout: PushUI.CONSTANTS.CONNECTED.LAYOUT.HOVER,
294
+
295
+ // Show app preview in modals
296
+ appPreview: true,
297
+
298
+ // Background interaction when modal is open: BLUR or NONE
299
+ connectedInteraction: PushUI.CONSTANTS.CONNECTED.INTERACTION.BLUR,
300
+ },
301
+
302
+ // Chain configuration - add your custom RPC endpoints here
303
+ chainConfig: {
304
+ rpcUrls: {
305
+ // Ethereum Sepolia testnet (for testing)
306
+ "eip155:11155111": ["https://sepolia.gateway.tenderly.co/"],
307
+
308
+ // Add more chains as needed:
309
+ // "eip155:1": ["https://mainnet.infura.io/v3/YOUR_PROJECT_ID"], // Ethereum Mainnet
310
+ // "eip155:137": ["https://polygon-rpc.com/"], // Polygon
311
+ // "eip155:42161": ["https://arb1.arbitrum.io/rpc"], // Arbitrum
312
+ // "eip155:10": ["https://mainnet.optimism.io"], // Optimism
313
+ // "eip155:8453": ["https://mainnet.base.org"], // Base
314
+ },
315
+ },
316
+ };
317
+
318
+ // App metadata - customize with your app's branding
319
+ const appMetadata: AppMetadata = {
320
+ // Your app's logo URL (can be a URL or base64 data URI)
321
+ logoUrl: "https://avatars.githubusercontent.com/u/64157541?v=4",
322
+
323
+ // Your app's display name
324
+ title: "${options.projectName}",
325
+
326
+ // Brief description of your app (shown in wallet connection prompts)
327
+ description:
328
+ "Push Chain is a shared state L1 blockchain that allows all chains to unify, enabling apps of any chain to be accessed by users of any chain.",
329
+ };
330
+
331
+ return (
332
+ <PushUniversalWalletProvider config={walletConfig} app={appMetadata}>
333
+ {children}
334
+ </PushUniversalWalletProvider>
335
+ );
336
+ };
337
+
338
+ export { PushChainProviders };`;
339
+ await fs.writeFile(path.join(providersDir, 'PushChainProviders.tsx'), pushchainProviders);
340
+ // Create .env.local file for Next.js with configuration notes
341
+ const envFile = `# Push Chain Configuration for Next.js
342
+ #
343
+ # This file contains environment variables for your Push Chain application.
344
+ # In Next.js, client-side variables must be prefixed with NEXT_PUBLIC_
345
+ #
346
+ # IMPORTANT: Never commit sensitive API keys to version control!
347
+ # This file (.env.local) is automatically ignored by Git.
348
+
349
+ # Push Chain Network Configuration
350
+ # Options: mainnet, testnet, dev
351
+ NEXT_PUBLIC_PUSHCHAIN_NETWORK=testnet
352
+
353
+ # Optional: Custom API endpoints (if you have specific requirements)
354
+ # NEXT_PUBLIC_PUSHCHAIN_API_ENDPOINT=https://your-custom-endpoint.com
355
+
356
+ # Optional: App-specific configuration
357
+ # NEXT_PUBLIC_APP_NAME=${options.projectName}
358
+ # NEXT_PUBLIC_APP_VERSION=1.0.0
359
+
360
+ # Server-side only variables (without NEXT_PUBLIC_ prefix)
361
+ # These are only available in API routes and server components
362
+ # PRIVATE_API_KEY=your_private_key_here`;
363
+ await fs.writeFile(path.join(options.targetDir, '.env.local'), envFile);
364
+ }
365
+ async function createESLintConfig(options) {
366
+ const eslintConfig = {
367
+ extends: [
368
+ "next/core-web-vitals",
369
+ "@typescript-eslint/recommended"
370
+ ],
371
+ parser: "@typescript-eslint/parser",
372
+ plugins: ["@typescript-eslint"],
373
+ rules: {
374
+ "@typescript-eslint/no-unused-vars": "warn",
375
+ "@typescript-eslint/no-explicit-any": "warn"
376
+ }
377
+ };
378
+ await fs.writeJSON(path.join(options.targetDir, '.eslintrc.json'), eslintConfig, { spaces: 2 });
379
+ }
380
+ async function createTailwindConfig(options) {
381
+ const tailwindConfig = `/** @type {import('tailwindcss').Config} */
382
+ module.exports = {
383
+ darkMode: ["class"],
384
+ content: [
385
+ './pages/**/*.{ts,tsx}',
386
+ './components/**/*.{ts,tsx}',
387
+ './app/**/*.{ts,tsx}',
388
+ './src/**/*.{ts,tsx}',
389
+ ],
390
+ theme: {
391
+ extend: {},
392
+ },
393
+ plugins: [],
394
+ }`;
395
+ await fs.writeFile(path.join(options.targetDir, 'tailwind.config.js'), tailwindConfig);
396
+ // PostCSS config
397
+ const postcssConfig = `module.exports = {
398
+ plugins: {
399
+ tailwindcss: {},
400
+ autoprefixer: {},
401
+ },
402
+ }`;
403
+ await fs.writeFile(path.join(options.targetDir, 'postcss.config.js'), postcssConfig);
404
+ }
405
+ // Removed shadcn config and components for Tailwind-only setup
406
+ //# sourceMappingURL=nextjs.js.map