create-universal-dapp 1.0.7 → 1.0.9
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.
|
@@ -1 +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,
|
|
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,CAmB5E"}
|
package/dist/templates/nextjs.js
CHANGED
|
@@ -4,19 +4,12 @@ import ora from 'ora';
|
|
|
4
4
|
export async function createNextjsApp(options) {
|
|
5
5
|
const spinner = ora('Setting up Next.js project...').start();
|
|
6
6
|
try {
|
|
7
|
-
// Create package.json
|
|
8
7
|
await createNextjsPackageJson(options);
|
|
9
|
-
// Create Next.js configuration files
|
|
10
8
|
await createNextjsConfig(options);
|
|
11
|
-
// Create source structure
|
|
12
9
|
await createNextjsSourceFiles(options);
|
|
13
|
-
// Create Push Chain integration files
|
|
14
|
-
await createPushChainIntegration(options);
|
|
15
|
-
// Create ESLint config if requested
|
|
16
10
|
if (options.eslint) {
|
|
17
11
|
await createESLintConfig(options);
|
|
18
12
|
}
|
|
19
|
-
// Create Tailwind config (Tailwind-only setup)
|
|
20
13
|
await createPostcssConfig(options);
|
|
21
14
|
spinner.succeed('Next.js project structure created');
|
|
22
15
|
}
|
|
@@ -27,17 +20,17 @@ export async function createNextjsApp(options) {
|
|
|
27
20
|
}
|
|
28
21
|
async function createNextjsPackageJson(options) {
|
|
29
22
|
const baseDevDeps = {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
23
|
+
'@tailwindcss/postcss': '^4',
|
|
24
|
+
'@types/node': '^20',
|
|
25
|
+
'@types/react': '^19',
|
|
26
|
+
'@types/react-dom': '^19',
|
|
27
|
+
tailwindcss: '^4',
|
|
28
|
+
typescript: '^5',
|
|
36
29
|
};
|
|
37
30
|
const eslintDevDeps = {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
31
|
+
'@eslint/eslintrc': '^3',
|
|
32
|
+
eslint: '^9',
|
|
33
|
+
'eslint-config-next': '15.5.3',
|
|
41
34
|
};
|
|
42
35
|
const devDependencies = {
|
|
43
36
|
...baseDevDeps,
|
|
@@ -46,33 +39,32 @@ async function createNextjsPackageJson(options) {
|
|
|
46
39
|
const packageJson = {
|
|
47
40
|
name: options.projectName,
|
|
48
41
|
private: true,
|
|
49
|
-
version:
|
|
50
|
-
type:
|
|
42
|
+
version: '0.0.0',
|
|
43
|
+
type: 'module',
|
|
51
44
|
scripts: {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
...(options.eslint && { lint:
|
|
45
|
+
dev: 'next dev',
|
|
46
|
+
build: 'next build',
|
|
47
|
+
start: 'next start',
|
|
48
|
+
...(options.eslint && { lint: 'eslint .' }),
|
|
56
49
|
},
|
|
57
50
|
dependencies: {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
51
|
+
'@pushchain/ui-kit': '^4.0.8',
|
|
52
|
+
next: '15.5.3',
|
|
53
|
+
react: '19.1.0',
|
|
54
|
+
'react-dom': '19.1.0',
|
|
62
55
|
},
|
|
63
56
|
devDependencies,
|
|
64
57
|
};
|
|
65
|
-
|
|
66
|
-
Object.keys(packageJson.scripts).forEach(key => {
|
|
58
|
+
Object.keys(packageJson.scripts).forEach((key) => {
|
|
67
59
|
const scripts = packageJson.scripts;
|
|
68
|
-
if (scripts[key] === undefined)
|
|
60
|
+
if (scripts[key] === undefined)
|
|
69
61
|
delete scripts[key];
|
|
70
|
-
}
|
|
71
62
|
});
|
|
72
|
-
await fs.writeJSON(path.join(options.targetDir, 'package.json'), packageJson, {
|
|
63
|
+
await fs.writeJSON(path.join(options.targetDir, 'package.json'), packageJson, {
|
|
64
|
+
spaces: 2,
|
|
65
|
+
});
|
|
73
66
|
}
|
|
74
67
|
async function createNextjsConfig(options) {
|
|
75
|
-
// Next.js config
|
|
76
68
|
const nextConfig = `import type { NextConfig } from "next";
|
|
77
69
|
|
|
78
70
|
const nextConfig: NextConfig = {
|
|
@@ -80,54 +72,101 @@ const nextConfig: NextConfig = {
|
|
|
80
72
|
reactStrictMode: true,
|
|
81
73
|
};
|
|
82
74
|
|
|
83
|
-
export default nextConfig
|
|
75
|
+
export default nextConfig;
|
|
76
|
+
`;
|
|
84
77
|
await fs.writeFile(path.join(options.targetDir, 'next.config.ts'), nextConfig);
|
|
85
|
-
// TypeScript config
|
|
86
78
|
const tsConfig = {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
}
|
|
79
|
+
compilerOptions: {
|
|
80
|
+
target: 'ES2017',
|
|
81
|
+
lib: ['dom', 'dom.iterable', 'esnext'],
|
|
82
|
+
allowJs: true,
|
|
83
|
+
skipLibCheck: true,
|
|
84
|
+
strict: true,
|
|
85
|
+
noEmit: true,
|
|
86
|
+
esModuleInterop: true,
|
|
87
|
+
module: 'esnext',
|
|
88
|
+
moduleResolution: 'bundler',
|
|
89
|
+
resolveJsonModule: true,
|
|
90
|
+
isolatedModules: true,
|
|
91
|
+
jsx: 'preserve',
|
|
92
|
+
incremental: true,
|
|
93
|
+
paths: {
|
|
94
|
+
'@/*': ['./src/*'],
|
|
95
|
+
},
|
|
104
96
|
},
|
|
105
|
-
|
|
106
|
-
|
|
97
|
+
include: ['next-env.d.ts', '**/*.ts', '**/*.tsx'],
|
|
98
|
+
exclude: ['node_modules'],
|
|
107
99
|
};
|
|
108
|
-
await fs.writeJSON(path.join(options.targetDir, 'tsconfig.json'), tsConfig, {
|
|
100
|
+
await fs.writeJSON(path.join(options.targetDir, 'tsconfig.json'), tsConfig, {
|
|
101
|
+
spaces: 2,
|
|
102
|
+
});
|
|
109
103
|
}
|
|
110
104
|
async function createNextjsSourceFiles(options) {
|
|
111
|
-
// Create src directory structure
|
|
112
105
|
const srcDir = path.join(options.targetDir, 'src');
|
|
113
|
-
const
|
|
106
|
+
const pagesDir = path.join(srcDir, 'pages');
|
|
114
107
|
const stylesDir = path.join(srcDir, 'styles');
|
|
115
|
-
await fs.ensureDir(
|
|
108
|
+
await fs.ensureDir(pagesDir);
|
|
116
109
|
await fs.ensureDir(stylesDir);
|
|
117
|
-
//
|
|
118
|
-
const
|
|
110
|
+
// ✅ All PushChainProviders logic in _app.tsx (no separate file)
|
|
111
|
+
const appFile = `import "@/styles/globals.css";
|
|
119
112
|
import type { AppProps } from "next/app";
|
|
120
|
-
|
|
113
|
+
|
|
114
|
+
import {
|
|
115
|
+
PushUI,
|
|
116
|
+
PushUniversalWalletProvider,
|
|
117
|
+
type AppMetadata,
|
|
118
|
+
type ProviderConfigProps,
|
|
119
|
+
} from "@pushchain/ui-kit";
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Next.js App Wrapper + Push Chain Provider
|
|
123
|
+
*
|
|
124
|
+
* - Uses PushUniversalWalletProvider to enable Universal logins
|
|
125
|
+
* - Configure network, login options, modal, and RPCs below
|
|
126
|
+
*/
|
|
127
|
+
|
|
128
|
+
const walletConfig: ProviderConfigProps = {
|
|
129
|
+
network: PushUI.CONSTANTS.PUSH_NETWORK.TESTNET,
|
|
130
|
+
|
|
131
|
+
login: {
|
|
132
|
+
email: true,
|
|
133
|
+
google: true,
|
|
134
|
+
wallet: {
|
|
135
|
+
enabled: true,
|
|
136
|
+
},
|
|
137
|
+
appPreview: true,
|
|
138
|
+
},
|
|
139
|
+
|
|
140
|
+
modal: {
|
|
141
|
+
loginLayout: PushUI.CONSTANTS.LOGIN.LAYOUT.SPLIT,
|
|
142
|
+
connectedLayout: PushUI.CONSTANTS.CONNECTED.LAYOUT.HOVER,
|
|
143
|
+
appPreview: true,
|
|
144
|
+
connectedInteraction: PushUI.CONSTANTS.CONNECTED.INTERACTION.BLUR,
|
|
145
|
+
},
|
|
146
|
+
|
|
147
|
+
chainConfig: {
|
|
148
|
+
rpcUrls: {
|
|
149
|
+
"eip155:11155111": ["https://sepolia.gateway.tenderly.co/"],
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
const appMetadata: AppMetadata = {
|
|
155
|
+
logoUrl: "https://avatars.githubusercontent.com/u/64157541?v=4",
|
|
156
|
+
title: "${options.projectName}",
|
|
157
|
+
description:
|
|
158
|
+
"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.",
|
|
159
|
+
};
|
|
121
160
|
|
|
122
161
|
export default function App({ Component, pageProps }: AppProps) {
|
|
123
162
|
return (
|
|
124
|
-
<
|
|
163
|
+
<PushUniversalWalletProvider config={walletConfig} app={appMetadata}>
|
|
125
164
|
<Component {...pageProps} />
|
|
126
|
-
</
|
|
165
|
+
</PushUniversalWalletProvider>
|
|
127
166
|
);
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
|
|
167
|
+
}
|
|
168
|
+
`;
|
|
169
|
+
await fs.writeFile(path.join(pagesDir, '_app.tsx'), appFile);
|
|
131
170
|
const document = `import { Html, Head, Main, NextScript } from "next/document";
|
|
132
171
|
|
|
133
172
|
export default function Document() {
|
|
@@ -140,28 +179,28 @@ export default function Document() {
|
|
|
140
179
|
</body>
|
|
141
180
|
</Html>
|
|
142
181
|
);
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
|
|
182
|
+
}
|
|
183
|
+
`;
|
|
184
|
+
await fs.writeFile(path.join(pagesDir, '_document.tsx'), document);
|
|
146
185
|
const page = `'use client'
|
|
147
186
|
|
|
148
187
|
import { PushUniversalAccountButton, usePushWalletContext } from '@pushchain/ui-kit'
|
|
149
188
|
|
|
150
189
|
function App() {
|
|
151
190
|
const { universalAccount } = usePushWalletContext();
|
|
152
|
-
|
|
191
|
+
|
|
153
192
|
return (
|
|
154
193
|
<div className="min-h-screen p-8">
|
|
155
194
|
<div className="max-w-[800px] mx-auto">
|
|
156
195
|
<div className="text-center mb-8">
|
|
157
196
|
<h1 className="text-[2.5rem] font-bold mb-4">
|
|
158
|
-
Welcome to
|
|
197
|
+
Welcome to ${options.projectName}
|
|
159
198
|
</h1>
|
|
160
199
|
<p className="text-[1.2rem] text-gray-400 mb-8">
|
|
161
200
|
Your Push Chain application is ready to go!
|
|
162
201
|
</p>
|
|
163
202
|
</div>
|
|
164
|
-
|
|
203
|
+
|
|
165
204
|
<div className="max-w-[600px] mx-auto p-8 border border-gray-300 rounded-lg text-center">
|
|
166
205
|
<h2 className="mb-4">Push Chain Integration</h2>
|
|
167
206
|
|
|
@@ -172,11 +211,11 @@ function App() {
|
|
|
172
211
|
{universalAccount ? "Connected" : "Not Connected"}
|
|
173
212
|
</span>
|
|
174
213
|
</div>
|
|
175
|
-
|
|
214
|
+
|
|
176
215
|
<div className="mb-8 justify-items-center">
|
|
177
216
|
<PushUniversalAccountButton />
|
|
178
217
|
</div>
|
|
179
|
-
|
|
218
|
+
|
|
180
219
|
{universalAccount && (
|
|
181
220
|
<div className="mt-8 p-4 bg-gray-100 text-neutral-800 rounded-md text-left">
|
|
182
221
|
<h3 className="font-bold mb-2">Account Details:</h3>
|
|
@@ -185,12 +224,11 @@ function App() {
|
|
|
185
224
|
</pre>
|
|
186
225
|
</div>
|
|
187
226
|
)}
|
|
188
|
-
|
|
227
|
+
|
|
189
228
|
<div className="text-[0.9rem] text-gray-400 mt-8 text-left">
|
|
190
229
|
<p><strong>Next steps:</strong></p>
|
|
191
230
|
<ul className="my-2 pl-6 list-disc">
|
|
192
|
-
<li>
|
|
193
|
-
<li>Customize the app metadata with your branding</li>
|
|
231
|
+
<li>Update walletConfig/appMetadata in <code>pages/_app.tsx</code></li>
|
|
194
232
|
<li>Add your chain configuration and RPC URLs</li>
|
|
195
233
|
<li>Explore the @pushchain/ui-kit for more components</li>
|
|
196
234
|
</ul>
|
|
@@ -201,9 +239,9 @@ function App() {
|
|
|
201
239
|
)
|
|
202
240
|
}
|
|
203
241
|
|
|
204
|
-
export default App
|
|
205
|
-
|
|
206
|
-
|
|
242
|
+
export default App
|
|
243
|
+
`;
|
|
244
|
+
await fs.writeFile(path.join(pagesDir, 'index.tsx'), page);
|
|
207
245
|
const globalCss = `@import "tailwindcss";
|
|
208
246
|
|
|
209
247
|
:root {
|
|
@@ -224,107 +262,9 @@ export default App`;
|
|
|
224
262
|
h1 {
|
|
225
263
|
font-size: 3.2em;
|
|
226
264
|
line-height: 1.1;
|
|
227
|
-
}`;
|
|
228
|
-
await fs.writeFile(path.join(stylesDir, 'globals.css'), globalCss);
|
|
229
265
|
}
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
const providersDir = path.join(options.targetDir, 'src', 'providers');
|
|
233
|
-
await fs.ensureDir(providersDir);
|
|
234
|
-
// Create PushChainProviders.tsx following your pattern but with Next.js specific comments
|
|
235
|
-
const pushchainProviders = `'use client'
|
|
236
|
-
|
|
237
|
-
import {
|
|
238
|
-
PushUI,
|
|
239
|
-
PushUniversalWalletProvider,
|
|
240
|
-
type AppMetadata,
|
|
241
|
-
type ProviderConfigProps,
|
|
242
|
-
} from "@pushchain/ui-kit";
|
|
243
|
-
|
|
244
|
-
/**
|
|
245
|
-
* PushChainProviders Component for Next.js
|
|
246
|
-
*
|
|
247
|
-
* This component wraps your entire Next.js application with Push Chain's Universal Wallet Provider.
|
|
248
|
-
* It configures the wallet connection options, network settings, and app metadata.
|
|
249
|
-
*
|
|
250
|
-
* Configuration Guide:
|
|
251
|
-
* - network: Choose between MAINNET, TESTNET, or DEV
|
|
252
|
-
* - login: Configure authentication methods (email, google, wallet)
|
|
253
|
-
* - modal: Customize the UI appearance and behavior
|
|
254
|
-
* - chainConfig: Add your custom RPC endpoints
|
|
255
|
-
* - appMetadata: Brand your app with logo, title, and description
|
|
256
|
-
*
|
|
257
|
-
* Next.js Specific Notes:
|
|
258
|
-
* - This component uses 'use client' directive for client-side functionality
|
|
259
|
-
* - Environment variables should be prefixed with NEXT_PUBLIC_ for client access
|
|
260
|
-
* - Metadata is also configured in app/layout.tsx for SEO
|
|
261
|
-
*/
|
|
262
|
-
|
|
263
|
-
const PushChainProviders = ({ children }: { children: React.ReactNode }) => {
|
|
264
|
-
// Wallet configuration - customize these settings for your app
|
|
265
|
-
const walletConfig: ProviderConfigProps = {
|
|
266
|
-
// Network selection: MAINNET for production, TESTNET for development
|
|
267
|
-
network: PushUI.CONSTANTS.PUSH_NETWORK.TESTNET,
|
|
268
|
-
|
|
269
|
-
// Login options - enable/disable authentication methods
|
|
270
|
-
login: {
|
|
271
|
-
email: true, // Allow email authentication
|
|
272
|
-
google: true, // Allow Google OAuth
|
|
273
|
-
wallet: {
|
|
274
|
-
enabled: true, // Allow wallet connection (MetaMask, etc.)
|
|
275
|
-
},
|
|
276
|
-
appPreview: true, // Show app preview in login modal
|
|
277
|
-
},
|
|
278
|
-
|
|
279
|
-
// Modal UI customization
|
|
280
|
-
modal: {
|
|
281
|
-
// Layout: SPLIT (side-by-side) or STACKED (vertical)
|
|
282
|
-
loginLayout: PushUI.CONSTANTS.LOGIN.LAYOUT.SPLIT,
|
|
283
|
-
|
|
284
|
-
// Connected wallet display: HOVER (on hover) or FULL (always visible)
|
|
285
|
-
connectedLayout: PushUI.CONSTANTS.CONNECTED.LAYOUT.HOVER,
|
|
286
|
-
|
|
287
|
-
// Show app preview in modals
|
|
288
|
-
appPreview: true,
|
|
289
|
-
|
|
290
|
-
// Background interaction when modal is open: BLUR or NONE
|
|
291
|
-
connectedInteraction: PushUI.CONSTANTS.CONNECTED.INTERACTION.BLUR,
|
|
292
|
-
},
|
|
293
|
-
|
|
294
|
-
// Chain configuration - add your custom RPC endpoints here
|
|
295
|
-
chainConfig: {
|
|
296
|
-
rpcUrls: {
|
|
297
|
-
// Ethereum Sepolia testnet (for testing)
|
|
298
|
-
"eip155:11155111": ["https://sepolia.gateway.tenderly.co/"],
|
|
299
|
-
|
|
300
|
-
// Add more chains as needed:
|
|
301
|
-
// "eip155:1": ["https://mainnet.infura.io/v3/YOUR_PROJECT_ID"], // Ethereum Mainnet
|
|
302
|
-
},
|
|
303
|
-
},
|
|
304
|
-
};
|
|
305
|
-
|
|
306
|
-
// App metadata - customize with your app's branding
|
|
307
|
-
const appMetadata: AppMetadata = {
|
|
308
|
-
// Your app's logo URL (can be a URL or base64 data URI)
|
|
309
|
-
logoUrl: "https://avatars.githubusercontent.com/u/64157541?v=4",
|
|
310
|
-
|
|
311
|
-
// Your app's display name
|
|
312
|
-
title: "${options.projectName}",
|
|
313
|
-
|
|
314
|
-
// Brief description of your app (shown in wallet connection prompts)
|
|
315
|
-
description:
|
|
316
|
-
"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.",
|
|
317
|
-
};
|
|
318
|
-
|
|
319
|
-
return (
|
|
320
|
-
<PushUniversalWalletProvider config={walletConfig} app={appMetadata}>
|
|
321
|
-
{children}
|
|
322
|
-
</PushUniversalWalletProvider>
|
|
323
|
-
);
|
|
324
|
-
};
|
|
325
|
-
|
|
326
|
-
export { PushChainProviders };`;
|
|
327
|
-
await fs.writeFile(path.join(providersDir, 'PushChainProviders.tsx'), pushchainProviders);
|
|
266
|
+
`;
|
|
267
|
+
await fs.writeFile(path.join(stylesDir, 'globals.css'), globalCss);
|
|
328
268
|
}
|
|
329
269
|
async function createESLintConfig(options) {
|
|
330
270
|
const config = `import { dirname } from "path";
|
|
@@ -353,10 +293,10 @@ const eslintConfig = [
|
|
|
353
293
|
|
|
354
294
|
export default eslintConfig;
|
|
355
295
|
`;
|
|
356
|
-
|
|
296
|
+
// NOTE: eslint.config.mjs should be a file, not JSON
|
|
297
|
+
await fs.writeFile(path.join(options.targetDir, 'eslint.config.mjs'), config);
|
|
357
298
|
}
|
|
358
299
|
async function createPostcssConfig(options) {
|
|
359
|
-
// PostCSS config
|
|
360
300
|
const postcssConfig = `const config = {
|
|
361
301
|
plugins: ["@tailwindcss/postcss"],
|
|
362
302
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nextjs.js","sourceRoot":"","sources":["../../src/templates/nextjs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,GAAG,MAAM,KAAK,CAAC;AAGtB,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,OAAuB;IAC3D,MAAM,OAAO,GAAG,GAAG,CAAC,+BAA+B,CAAC,CAAC,KAAK,EAAE,CAAC;IAE7D,IAAI,CAAC;QACH,
|
|
1
|
+
{"version":3,"file":"nextjs.js","sourceRoot":"","sources":["../../src/templates/nextjs.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vite.d.ts","sourceRoot":"","sources":["../../src/templates/vite.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAExD,wBAAsB,aAAa,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"vite.d.ts","sourceRoot":"","sources":["../../src/templates/vite.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAExD,wBAAsB,aAAa,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAoB1E;AAmUD,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CA6B/E"}
|
package/dist/templates/vite.js
CHANGED
|
@@ -4,15 +4,11 @@ import ora from 'ora';
|
|
|
4
4
|
export async function createViteApp(options) {
|
|
5
5
|
const spinner = ora('Setting up Vite project...').start();
|
|
6
6
|
try {
|
|
7
|
-
// Create package.json
|
|
8
7
|
await createVitePackageJson(options);
|
|
9
|
-
// Create Vite configuration files
|
|
10
8
|
await createViteConfig(options);
|
|
11
|
-
// Create source structure
|
|
12
9
|
await createViteSourceFiles(options);
|
|
13
|
-
//
|
|
14
|
-
await createPushChainIntegration(options);
|
|
15
|
-
// Create ESLint config if requested
|
|
10
|
+
// ✅ no separate providers file anymore
|
|
11
|
+
// await createPushChainIntegration(options);
|
|
16
12
|
if (options.eslint) {
|
|
17
13
|
await createESLintConfig(options);
|
|
18
14
|
}
|
|
@@ -25,20 +21,20 @@ export async function createViteApp(options) {
|
|
|
25
21
|
}
|
|
26
22
|
async function createVitePackageJson(options) {
|
|
27
23
|
const baseDevDeps = {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
24
|
+
'@tailwindcss/vite': '^4.1.13',
|
|
25
|
+
'@types/react': '^19.1.10',
|
|
26
|
+
'@types/react-dom': '^19.1.7',
|
|
27
|
+
'@vitejs/plugin-react': '^5.0.0',
|
|
28
|
+
tailwindcss: '^4.1.13',
|
|
29
|
+
typescript: '^5.8.3',
|
|
30
|
+
vite: '^7.1.2',
|
|
35
31
|
};
|
|
36
32
|
const eslintDevDeps = {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
33
|
+
'@eslint/js': '^9.33.0',
|
|
34
|
+
eslint: '^9.33.0',
|
|
35
|
+
'typescript-eslint': '^8.39.1',
|
|
36
|
+
'eslint-plugin-react-hooks': '^5.2.0',
|
|
37
|
+
'eslint-plugin-react-refresh': '^0.4.20',
|
|
42
38
|
};
|
|
43
39
|
const devDependencies = {
|
|
44
40
|
...baseDevDeps,
|
|
@@ -47,38 +43,36 @@ async function createVitePackageJson(options) {
|
|
|
47
43
|
const packageJson = {
|
|
48
44
|
name: options.projectName,
|
|
49
45
|
private: true,
|
|
50
|
-
version:
|
|
51
|
-
type:
|
|
46
|
+
version: '0.0.0',
|
|
47
|
+
type: 'module',
|
|
52
48
|
scripts: {
|
|
53
|
-
dev:
|
|
54
|
-
build:
|
|
55
|
-
...(options.eslint && { lint:
|
|
56
|
-
preview:
|
|
49
|
+
dev: 'vite',
|
|
50
|
+
build: 'tsc && vite build',
|
|
51
|
+
...(options.eslint && { lint: 'eslint .' }),
|
|
52
|
+
preview: 'vite preview',
|
|
57
53
|
},
|
|
58
54
|
dependencies: {
|
|
59
|
-
react:
|
|
60
|
-
|
|
61
|
-
|
|
55
|
+
react: '^19.1.1',
|
|
56
|
+
'react-dom': '^19.1.1',
|
|
57
|
+
'@pushchain/ui-kit': '^4.0.8',
|
|
62
58
|
},
|
|
63
59
|
devDependencies,
|
|
64
60
|
};
|
|
65
|
-
|
|
66
|
-
Object.keys(packageJson.scripts).forEach(key => {
|
|
61
|
+
Object.keys(packageJson.scripts).forEach((key) => {
|
|
67
62
|
const scripts = packageJson.scripts;
|
|
68
|
-
if (scripts[key] === undefined)
|
|
63
|
+
if (scripts[key] === undefined)
|
|
69
64
|
delete scripts[key];
|
|
70
|
-
}
|
|
71
65
|
});
|
|
72
|
-
await fs.writeJSON(path.join(options.targetDir, 'package.json'), packageJson, {
|
|
66
|
+
await fs.writeJSON(path.join(options.targetDir, 'package.json'), packageJson, {
|
|
67
|
+
spaces: 2,
|
|
68
|
+
});
|
|
73
69
|
}
|
|
74
70
|
async function createViteConfig(options) {
|
|
75
|
-
// Vite config
|
|
76
71
|
const viteConfig = `import { defineConfig } from 'vite'
|
|
77
72
|
import react from '@vitejs/plugin-react'
|
|
78
73
|
import path from 'path'
|
|
79
74
|
import tailwindcss from '@tailwindcss/vite'
|
|
80
75
|
|
|
81
|
-
// https://vitejs.dev/config/
|
|
82
76
|
export default defineConfig({
|
|
83
77
|
plugins: [react(), tailwindcss()],
|
|
84
78
|
resolve: {
|
|
@@ -86,75 +80,70 @@ export default defineConfig({
|
|
|
86
80
|
"@": path.resolve(__dirname, "./src"),
|
|
87
81
|
},
|
|
88
82
|
},
|
|
89
|
-
})
|
|
83
|
+
})
|
|
84
|
+
`;
|
|
90
85
|
await fs.writeFile(path.join(options.targetDir, 'vite.config.ts'), viteConfig);
|
|
91
|
-
// TypeScript config
|
|
92
86
|
const tsConfig = {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
{ "path": "./tsconfig.app.json" },
|
|
96
|
-
{ "path": "./tsconfig.node.json" }
|
|
97
|
-
]
|
|
87
|
+
files: [],
|
|
88
|
+
references: [{ path: './tsconfig.app.json' }, { path: './tsconfig.node.json' }],
|
|
98
89
|
};
|
|
99
|
-
await fs.writeJSON(path.join(options.targetDir, 'tsconfig.json'), tsConfig, {
|
|
100
|
-
|
|
90
|
+
await fs.writeJSON(path.join(options.targetDir, 'tsconfig.json'), tsConfig, {
|
|
91
|
+
spaces: 2,
|
|
92
|
+
});
|
|
101
93
|
const tsAppConfig = {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
"noFallthroughCasesInSwitch": true,
|
|
122
|
-
"noUncheckedSideEffectImports": true
|
|
94
|
+
compilerOptions: {
|
|
95
|
+
tsBuildInfoFile: './node_modules/.tmp/tsconfig.app.tsbuildinfo',
|
|
96
|
+
target: 'ES2022',
|
|
97
|
+
useDefineForClassFields: true,
|
|
98
|
+
lib: ['ES2022', 'DOM', 'DOM.Iterable'],
|
|
99
|
+
module: 'ESNext',
|
|
100
|
+
skipLibCheck: true,
|
|
101
|
+
moduleResolution: 'bundler',
|
|
102
|
+
allowImportingTsExtensions: true,
|
|
103
|
+
verbatimModuleSyntax: true,
|
|
104
|
+
moduleDetection: 'force',
|
|
105
|
+
noEmit: true,
|
|
106
|
+
jsx: 'react-jsx',
|
|
107
|
+
strict: true,
|
|
108
|
+
noUnusedLocals: true,
|
|
109
|
+
noUnusedParameters: true,
|
|
110
|
+
erasableSyntaxOnly: true,
|
|
111
|
+
noFallthroughCasesInSwitch: true,
|
|
112
|
+
noUncheckedSideEffectImports: true,
|
|
123
113
|
},
|
|
124
|
-
|
|
114
|
+
include: ['src'],
|
|
125
115
|
};
|
|
126
|
-
await fs.writeJSON(path.join(options.targetDir, 'tsconfig.app.json'), tsAppConfig, {
|
|
127
|
-
|
|
116
|
+
await fs.writeJSON(path.join(options.targetDir, 'tsconfig.app.json'), tsAppConfig, {
|
|
117
|
+
spaces: 2,
|
|
118
|
+
});
|
|
128
119
|
const tsNodeConfig = {
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
"noFallthroughCasesInSwitch": true,
|
|
147
|
-
"noUncheckedSideEffectImports": true
|
|
120
|
+
compilerOptions: {
|
|
121
|
+
tsBuildInfoFile: './node_modules/.tmp/tsconfig.node.tsbuildinfo',
|
|
122
|
+
target: 'ES2023',
|
|
123
|
+
lib: ['ES2023'],
|
|
124
|
+
module: 'ESNext',
|
|
125
|
+
skipLibCheck: true,
|
|
126
|
+
moduleResolution: 'bundler',
|
|
127
|
+
allowImportingTsExtensions: true,
|
|
128
|
+
verbatimModuleSyntax: true,
|
|
129
|
+
moduleDetection: 'force',
|
|
130
|
+
noEmit: true,
|
|
131
|
+
strict: true,
|
|
132
|
+
noUnusedLocals: true,
|
|
133
|
+
noUnusedParameters: true,
|
|
134
|
+
erasableSyntaxOnly: true,
|
|
135
|
+
noFallthroughCasesInSwitch: true,
|
|
136
|
+
noUncheckedSideEffectImports: true,
|
|
148
137
|
},
|
|
149
|
-
|
|
138
|
+
include: ['vite.config.ts'],
|
|
150
139
|
};
|
|
151
|
-
await fs.writeJSON(path.join(options.targetDir, 'tsconfig.node.json'), tsNodeConfig, {
|
|
140
|
+
await fs.writeJSON(path.join(options.targetDir, 'tsconfig.node.json'), tsNodeConfig, {
|
|
141
|
+
spaces: 2,
|
|
142
|
+
});
|
|
152
143
|
}
|
|
153
144
|
async function createViteSourceFiles(options) {
|
|
154
|
-
// Create src directory structure
|
|
155
145
|
const srcDir = path.join(options.targetDir, 'src');
|
|
156
146
|
await fs.ensureDir(srcDir);
|
|
157
|
-
// Create index.html
|
|
158
147
|
const indexHtml = `<!doctype html>
|
|
159
148
|
<html lang="en">
|
|
160
149
|
<head>
|
|
@@ -167,57 +156,98 @@ async function createViteSourceFiles(options) {
|
|
|
167
156
|
<div id="root"></div>
|
|
168
157
|
<script type="module" src="/src/main.tsx"></script>
|
|
169
158
|
</body>
|
|
170
|
-
</html
|
|
159
|
+
</html>
|
|
160
|
+
`;
|
|
171
161
|
await fs.writeFile(path.join(options.targetDir, 'index.html'), indexHtml);
|
|
172
|
-
//
|
|
162
|
+
// ✅ Provider wrapper now lives inside main.tsx (no providers folder/file)
|
|
173
163
|
const mainTsx = `import { StrictMode } from 'react'
|
|
174
164
|
import { createRoot } from 'react-dom/client'
|
|
175
165
|
import './index.css'
|
|
176
166
|
import App from './App.tsx'
|
|
177
|
-
|
|
167
|
+
|
|
168
|
+
import {
|
|
169
|
+
PushUI,
|
|
170
|
+
PushUniversalWalletProvider,
|
|
171
|
+
type AppMetadata,
|
|
172
|
+
type ProviderConfigProps,
|
|
173
|
+
} from '@pushchain/ui-kit'
|
|
174
|
+
|
|
175
|
+
const walletConfig: ProviderConfigProps = {
|
|
176
|
+
network: PushUI.CONSTANTS.PUSH_NETWORK.TESTNET,
|
|
177
|
+
|
|
178
|
+
login: {
|
|
179
|
+
email: true,
|
|
180
|
+
google: true,
|
|
181
|
+
wallet: { enabled: true },
|
|
182
|
+
appPreview: true,
|
|
183
|
+
},
|
|
184
|
+
|
|
185
|
+
modal: {
|
|
186
|
+
loginLayout: PushUI.CONSTANTS.LOGIN.LAYOUT.SPLIT,
|
|
187
|
+
connectedLayout: PushUI.CONSTANTS.CONNECTED.LAYOUT.HOVER,
|
|
188
|
+
appPreview: true,
|
|
189
|
+
connectedInteraction: PushUI.CONSTANTS.CONNECTED.INTERACTION.BLUR,
|
|
190
|
+
},
|
|
191
|
+
|
|
192
|
+
chainConfig: {
|
|
193
|
+
rpcUrls: {
|
|
194
|
+
'eip155:11155111': ['https://sepolia.gateway.tenderly.co/'],
|
|
195
|
+
},
|
|
196
|
+
},
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
const appMetadata: AppMetadata = {
|
|
200
|
+
logoUrl: 'https://avatars.githubusercontent.com/u/64157541?v=4',
|
|
201
|
+
title: '${options.projectName}',
|
|
202
|
+
description:
|
|
203
|
+
"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.",
|
|
204
|
+
}
|
|
178
205
|
|
|
179
206
|
createRoot(document.getElementById('root')!).render(
|
|
180
207
|
<StrictMode>
|
|
181
|
-
<
|
|
208
|
+
<PushUniversalWalletProvider config={walletConfig} app={appMetadata}>
|
|
182
209
|
<App />
|
|
183
|
-
</
|
|
210
|
+
</PushUniversalWalletProvider>
|
|
184
211
|
</StrictMode>,
|
|
185
|
-
)
|
|
212
|
+
)
|
|
213
|
+
`;
|
|
186
214
|
await fs.writeFile(path.join(srcDir, 'main.tsx'), mainTsx);
|
|
187
|
-
// Create App.tsx
|
|
188
215
|
const appTsx = `import './App.css'
|
|
189
216
|
import { PushUniversalAccountButton, usePushWalletContext } from '@pushchain/ui-kit'
|
|
190
217
|
|
|
191
218
|
function App() {
|
|
192
|
-
const { universalAccount } = usePushWalletContext()
|
|
193
|
-
|
|
219
|
+
const { universalAccount } = usePushWalletContext()
|
|
220
|
+
|
|
194
221
|
return (
|
|
195
222
|
<div className="min-h-screen p-8">
|
|
196
223
|
<div className="max-w-[800px] mx-auto">
|
|
197
224
|
<div className="text-center mb-8">
|
|
198
225
|
<h1 className="text-[2.5rem] font-bold mb-4">
|
|
199
|
-
Welcome to
|
|
226
|
+
Welcome to ${options.projectName}
|
|
200
227
|
</h1>
|
|
201
228
|
<p className="text-[1.2rem] text-gray-400 mb-8">
|
|
202
229
|
Your Push Chain application is ready to go!
|
|
203
230
|
</p>
|
|
204
231
|
</div>
|
|
205
|
-
|
|
232
|
+
|
|
206
233
|
<div className="max-w-[600px] mx-auto p-8 border border-gray-300 rounded-lg text-center">
|
|
207
234
|
<h2 className="mb-4">Push Chain Integration</h2>
|
|
208
235
|
|
|
209
236
|
<div className="mb-4">
|
|
210
237
|
<span
|
|
211
|
-
className={
|
|
238
|
+
className={
|
|
239
|
+
"px-2 py-1 rounded text-white text-[12px] " +
|
|
240
|
+
(universalAccount ? "bg-green-500" : "bg-gray-500")
|
|
241
|
+
}
|
|
212
242
|
>
|
|
213
243
|
{universalAccount ? "Connected" : "Not Connected"}
|
|
214
244
|
</span>
|
|
215
245
|
</div>
|
|
216
|
-
|
|
246
|
+
|
|
217
247
|
<div className="mb-8 justify-items-center">
|
|
218
248
|
<PushUniversalAccountButton />
|
|
219
249
|
</div>
|
|
220
|
-
|
|
250
|
+
|
|
221
251
|
{universalAccount && (
|
|
222
252
|
<div className="mt-8 p-4 bg-gray-100 text-neutral-800 rounded-md text-left">
|
|
223
253
|
<h3 className="font-bold mb-2">Account Details:</h3>
|
|
@@ -226,13 +256,12 @@ function App() {
|
|
|
226
256
|
</pre>
|
|
227
257
|
</div>
|
|
228
258
|
)}
|
|
229
|
-
|
|
259
|
+
|
|
230
260
|
<div className="text-[0.9rem] text-gray-400 mt-8 text-left">
|
|
231
261
|
<p><strong>Next steps:</strong></p>
|
|
232
262
|
<ul className="my-2 pl-6 list-disc">
|
|
233
|
-
<li>
|
|
234
|
-
<li>
|
|
235
|
-
<li>Add your chain configuration and RPC URLs</li>
|
|
263
|
+
<li>Update walletConfig/appMetadata in <code>src/main.tsx</code></li>
|
|
264
|
+
<li>Add more chains + RPC URLs</li>
|
|
236
265
|
<li>Explore the @pushchain/ui-kit for more components</li>
|
|
237
266
|
</ul>
|
|
238
267
|
</div>
|
|
@@ -242,9 +271,9 @@ function App() {
|
|
|
242
271
|
)
|
|
243
272
|
}
|
|
244
273
|
|
|
245
|
-
export default App
|
|
274
|
+
export default App
|
|
275
|
+
`;
|
|
246
276
|
await fs.writeFile(path.join(srcDir, 'App.tsx'), appTsx);
|
|
247
|
-
// Create App.css
|
|
248
277
|
const appCss = `#root {
|
|
249
278
|
max-width: 1280px;
|
|
250
279
|
margin: 0 auto;
|
|
@@ -252,43 +281,9 @@ export default App`;
|
|
|
252
281
|
text-align: center;
|
|
253
282
|
}
|
|
254
283
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
padding: 1.5em;
|
|
258
|
-
will-change: filter;
|
|
259
|
-
transition: filter 300ms;
|
|
260
|
-
}
|
|
261
|
-
.logo:hover {
|
|
262
|
-
filter: drop-shadow(0 0 2em #646cffaa);
|
|
263
|
-
}
|
|
264
|
-
.logo.react:hover {
|
|
265
|
-
filter: drop-shadow(0 0 2em #61dafbaa);
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
@keyframes logo-spin {
|
|
269
|
-
from {
|
|
270
|
-
transform: rotate(0deg);
|
|
271
|
-
}
|
|
272
|
-
to {
|
|
273
|
-
transform: rotate(360deg);
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
@media (prefers-reduced-motion: no-preference) {
|
|
278
|
-
a:nth-of-type(2) .logo {
|
|
279
|
-
animation: logo-spin infinite 20s linear;
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
.card {
|
|
284
|
-
padding: 2em;
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
.read-the-docs {
|
|
288
|
-
color: #888;
|
|
289
|
-
}`;
|
|
284
|
+
/* keep rest if you want */
|
|
285
|
+
`;
|
|
290
286
|
await fs.writeFile(path.join(srcDir, 'App.css'), appCss);
|
|
291
|
-
// Create index.css (Tailwind directives only)
|
|
292
287
|
const indexCss = `@import "tailwindcss";
|
|
293
288
|
|
|
294
289
|
:root {
|
|
@@ -307,15 +302,6 @@ export default App`;
|
|
|
307
302
|
-webkit-text-size-adjust: 100%;
|
|
308
303
|
}
|
|
309
304
|
|
|
310
|
-
a {
|
|
311
|
-
font-weight: 500;
|
|
312
|
-
color: #646cff;
|
|
313
|
-
text-decoration: inherit;
|
|
314
|
-
}
|
|
315
|
-
a:hover {
|
|
316
|
-
color: #535bf2;
|
|
317
|
-
}
|
|
318
|
-
|
|
319
305
|
body {
|
|
320
306
|
margin: 0;
|
|
321
307
|
display: flex;
|
|
@@ -323,146 +309,11 @@ body {
|
|
|
323
309
|
min-width: 320px;
|
|
324
310
|
min-height: 100vh;
|
|
325
311
|
}
|
|
326
|
-
|
|
327
|
-
h1 {
|
|
328
|
-
font-size: 3.2em;
|
|
329
|
-
line-height: 1.1;
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
button {
|
|
333
|
-
border-radius: 8px;
|
|
334
|
-
border: 1px solid transparent;
|
|
335
|
-
padding: 0.6em 1.2em;
|
|
336
|
-
font-size: 1em;
|
|
337
|
-
font-weight: 500;
|
|
338
|
-
font-family: inherit;
|
|
339
|
-
background-color: #1a1a1a;
|
|
340
|
-
cursor: pointer;
|
|
341
|
-
transition: border-color 0.25s;
|
|
342
|
-
}
|
|
343
|
-
button:hover {
|
|
344
|
-
border-color: #646cff;
|
|
345
|
-
}
|
|
346
|
-
button:focus,
|
|
347
|
-
button:focus-visible {
|
|
348
|
-
outline: 4px auto -webkit-focus-ring-color;
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
.container {
|
|
352
|
-
max-width: 1200px;
|
|
353
|
-
margin: 0 auto;
|
|
354
|
-
padding: 0 20px;
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
@media (prefers-color-scheme: light) {
|
|
358
|
-
:root {
|
|
359
|
-
color: #213547;
|
|
360
|
-
background-color: #ffffff;
|
|
361
|
-
}
|
|
362
|
-
a:hover {
|
|
363
|
-
color: #747bff;
|
|
364
|
-
}
|
|
365
|
-
button {
|
|
366
|
-
background-color: #f9f9f9;
|
|
367
|
-
}
|
|
368
|
-
}`;
|
|
312
|
+
`;
|
|
369
313
|
await fs.writeFile(path.join(srcDir, 'index.css'), indexCss);
|
|
370
|
-
// Create vite-env.d.ts
|
|
371
314
|
const viteEnv = `/// <reference types="vite/client" />`;
|
|
372
315
|
await fs.writeFile(path.join(srcDir, 'vite-env.d.ts'), viteEnv);
|
|
373
316
|
}
|
|
374
|
-
async function createPushChainIntegration(options) {
|
|
375
|
-
// Create providers directory
|
|
376
|
-
const providersDir = path.join(options.targetDir, 'src', 'providers');
|
|
377
|
-
await fs.ensureDir(providersDir);
|
|
378
|
-
// Create PushChainProviders.tsx following your pattern
|
|
379
|
-
const pushchainProviders = `import {
|
|
380
|
-
PushUI,
|
|
381
|
-
PushUniversalWalletProvider,
|
|
382
|
-
type AppMetadata,
|
|
383
|
-
type ProviderConfigProps,
|
|
384
|
-
} from "@pushchain/ui-kit";
|
|
385
|
-
|
|
386
|
-
/**
|
|
387
|
-
* PushChainProviders Component
|
|
388
|
-
*
|
|
389
|
-
* This component wraps your entire application with Push Chain's Universal Wallet Provider.
|
|
390
|
-
* It configures the wallet connection options, network settings, and app metadata.
|
|
391
|
-
*
|
|
392
|
-
* Configuration Guide:
|
|
393
|
-
* - network: Choose between MAINNET, TESTNET, or DEV
|
|
394
|
-
* - login: Configure authentication methods (email, google, wallet)
|
|
395
|
-
* - modal: Customize the UI appearance and behavior
|
|
396
|
-
* - chainConfig: Add your custom RPC endpoints
|
|
397
|
-
* - appMetadata: Brand your app with logo, title, and description
|
|
398
|
-
*/
|
|
399
|
-
|
|
400
|
-
const PushChainProviders = ({ children }: { children: React.ReactNode }) => {
|
|
401
|
-
// Wallet configuration - customize these settings for your app
|
|
402
|
-
const walletConfig: ProviderConfigProps = {
|
|
403
|
-
// Network selection: MAINNET for production, TESTNET for development
|
|
404
|
-
network: PushUI.CONSTANTS.PUSH_NETWORK.TESTNET,
|
|
405
|
-
|
|
406
|
-
// Login options - enable/disable authentication methods
|
|
407
|
-
login: {
|
|
408
|
-
email: true, // Allow email authentication
|
|
409
|
-
google: true, // Allow Google OAuth
|
|
410
|
-
wallet: {
|
|
411
|
-
enabled: true, // Allow wallet connection (MetaMask, etc.)
|
|
412
|
-
},
|
|
413
|
-
appPreview: true, // Show app preview in login modal
|
|
414
|
-
},
|
|
415
|
-
|
|
416
|
-
// Modal UI customization
|
|
417
|
-
modal: {
|
|
418
|
-
// Layout: SPLIT (side-by-side) or STACKED (vertical)
|
|
419
|
-
loginLayout: PushUI.CONSTANTS.LOGIN.LAYOUT.SPLIT,
|
|
420
|
-
|
|
421
|
-
// Connected wallet display: HOVER (on hover) or FULL (always visible)
|
|
422
|
-
connectedLayout: PushUI.CONSTANTS.CONNECTED.LAYOUT.HOVER,
|
|
423
|
-
|
|
424
|
-
// Show app preview in modals
|
|
425
|
-
appPreview: true,
|
|
426
|
-
|
|
427
|
-
// Background interaction when modal is open: BLUR or NONE
|
|
428
|
-
connectedInteraction: PushUI.CONSTANTS.CONNECTED.INTERACTION.BLUR,
|
|
429
|
-
},
|
|
430
|
-
|
|
431
|
-
// Chain configuration - add your custom RPC endpoints here
|
|
432
|
-
chainConfig: {
|
|
433
|
-
rpcUrls: {
|
|
434
|
-
// Ethereum Sepolia testnet (for testing)
|
|
435
|
-
"eip155:11155111": ["https://sepolia.gateway.tenderly.co/"],
|
|
436
|
-
|
|
437
|
-
// Add more chains as needed:
|
|
438
|
-
// "eip155:1": ["https://mainnet.infura.io/v3/YOUR_PROJECT_ID"], // Ethereum Mainnet
|
|
439
|
-
},
|
|
440
|
-
},
|
|
441
|
-
};
|
|
442
|
-
|
|
443
|
-
// App metadata - customize with your app's branding
|
|
444
|
-
const appMetadata: AppMetadata = {
|
|
445
|
-
// Your app's logo URL (can be a URL or base64 data URI)
|
|
446
|
-
logoUrl: "https://avatars.githubusercontent.com/u/64157541?v=4",
|
|
447
|
-
|
|
448
|
-
// Your app's display name
|
|
449
|
-
title: "${options.projectName}",
|
|
450
|
-
|
|
451
|
-
// Brief description of your app (shown in wallet connection prompts)
|
|
452
|
-
description:
|
|
453
|
-
"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.",
|
|
454
|
-
};
|
|
455
|
-
|
|
456
|
-
return (
|
|
457
|
-
<PushUniversalWalletProvider config={walletConfig} app={appMetadata}>
|
|
458
|
-
{children}
|
|
459
|
-
</PushUniversalWalletProvider>
|
|
460
|
-
);
|
|
461
|
-
};
|
|
462
|
-
|
|
463
|
-
export { PushChainProviders };`;
|
|
464
|
-
await fs.writeFile(path.join(providersDir, 'PushChainProviders.tsx'), pushchainProviders);
|
|
465
|
-
}
|
|
466
317
|
export async function createESLintConfig(options) {
|
|
467
318
|
if (!options.eslint)
|
|
468
319
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vite.js","sourceRoot":"","sources":["../../src/templates/vite.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,GAAG,MAAM,KAAK,CAAC;AAGtB,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAAuB;IACzD,MAAM,OAAO,GAAG,GAAG,CAAC,4BAA4B,CAAC,CAAC,KAAK,EAAE,CAAC;IAE1D,IAAI,CAAC;QACH,
|
|
1
|
+
{"version":3,"file":"vite.js","sourceRoot":"","sources":["../../src/templates/vite.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,GAAG,MAAM,KAAK,CAAC;AAGtB,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAAuB;IACzD,MAAM,OAAO,GAAG,GAAG,CAAC,4BAA4B,CAAC,CAAC,KAAK,EAAE,CAAC;IAE1D,IAAI,CAAC;QACH,MAAM,qBAAqB,CAAC,OAAO,CAAC,CAAC;QACrC,MAAM,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAChC,MAAM,qBAAqB,CAAC,OAAO,CAAC,CAAC;QAErC,uCAAuC;QACvC,6CAA6C;QAE7C,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACnB,MAAM,kBAAkB,CAAC,OAAO,CAAC,CAAC;QACpC,CAAC;QAED,OAAO,CAAC,OAAO,CAAC,gCAAgC,CAAC,CAAC;IACpD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC;QAC9C,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,KAAK,UAAU,qBAAqB,CAAC,OAAuB;IAC1D,MAAM,WAAW,GAA2B;QAC1C,mBAAmB,EAAE,SAAS;QAC9B,cAAc,EAAE,UAAU;QAC1B,kBAAkB,EAAE,SAAS;QAC7B,sBAAsB,EAAE,QAAQ;QAChC,WAAW,EAAE,SAAS;QACtB,UAAU,EAAE,QAAQ;QACpB,IAAI,EAAE,QAAQ;KACf,CAAC;IAEF,MAAM,aAAa,GAA2B;QAC5C,YAAY,EAAE,SAAS;QACvB,MAAM,EAAE,SAAS;QACjB,mBAAmB,EAAE,SAAS;QAC9B,2BAA2B,EAAE,QAAQ;QACrC,6BAA6B,EAAE,SAAS;KACzC,CAAC;IAEF,MAAM,eAAe,GAAG;QACtB,GAAG,WAAW;QACd,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC;KACzC,CAAC;IAEF,MAAM,WAAW,GAAG;QAClB,IAAI,EAAE,OAAO,CAAC,WAAW;QACzB,OAAO,EAAE,IAAI;QACb,OAAO,EAAE,OAAO;QAChB,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE;YACP,GAAG,EAAE,MAAM;YACX,KAAK,EAAE,mBAAmB;YAC1B,GAAG,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;YAC3C,OAAO,EAAE,cAAc;SACxB;QACD,YAAY,EAAE;YACZ,KAAK,EAAE,SAAS;YAChB,WAAW,EAAE,SAAS;YACtB,mBAAmB,EAAE,QAAQ;SAC9B;QACD,eAAe;KAChB,CAAC;IAEF,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;QAC/C,MAAM,OAAO,GAAG,WAAW,CAAC,OAAc,CAAC;QAC3C,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,SAAS;YAAE,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;IAEH,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,cAAc,CAAC,EAAE,WAAW,EAAE;QAC5E,MAAM,EAAE,CAAC;KACV,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,gBAAgB,CAAC,OAAuB;IACrD,MAAM,UAAU,GAAG;;;;;;;;;;;;;CAapB,CAAC;IAEA,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,gBAAgB,CAAC,EAAE,UAAU,CAAC,CAAC;IAE/E,MAAM,QAAQ,GAAG;QACf,KAAK,EAAE,EAAE;QACT,UAAU,EAAE,CAAC,EAAE,IAAI,EAAE,qBAAqB,EAAE,EAAE,EAAE,IAAI,EAAE,sBAAsB,EAAE,CAAC;KAChF,CAAC;IAEF,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,eAAe,CAAC,EAAE,QAAQ,EAAE;QAC1E,MAAM,EAAE,CAAC;KACV,CAAC,CAAC;IAEH,MAAM,WAAW,GAAG;QAClB,eAAe,EAAE;YACf,eAAe,EAAE,8CAA8C;YAC/D,MAAM,EAAE,QAAQ;YAChB,uBAAuB,EAAE,IAAI;YAC7B,GAAG,EAAE,CAAC,QAAQ,EAAE,KAAK,EAAE,cAAc,CAAC;YACtC,MAAM,EAAE,QAAQ;YAChB,YAAY,EAAE,IAAI;YAElB,gBAAgB,EAAE,SAAS;YAC3B,0BAA0B,EAAE,IAAI;YAChC,oBAAoB,EAAE,IAAI;YAC1B,eAAe,EAAE,OAAO;YACxB,MAAM,EAAE,IAAI;YACZ,GAAG,EAAE,WAAW;YAEhB,MAAM,EAAE,IAAI;YACZ,cAAc,EAAE,IAAI;YACpB,kBAAkB,EAAE,IAAI;YACxB,kBAAkB,EAAE,IAAI;YACxB,0BAA0B,EAAE,IAAI;YAChC,4BAA4B,EAAE,IAAI;SACnC;QACD,OAAO,EAAE,CAAC,KAAK,CAAC;KACjB,CAAC;IAEF,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,mBAAmB,CAAC,EAAE,WAAW,EAAE;QACjF,MAAM,EAAE,CAAC;KACV,CAAC,CAAC;IAEH,MAAM,YAAY,GAAG;QACnB,eAAe,EAAE;YACf,eAAe,EAAE,+CAA+C;YAChE,MAAM,EAAE,QAAQ;YAChB,GAAG,EAAE,CAAC,QAAQ,CAAC;YACf,MAAM,EAAE,QAAQ;YAChB,YAAY,EAAE,IAAI;YAElB,gBAAgB,EAAE,SAAS;YAC3B,0BAA0B,EAAE,IAAI;YAChC,oBAAoB,EAAE,IAAI;YAC1B,eAAe,EAAE,OAAO;YACxB,MAAM,EAAE,IAAI;YAEZ,MAAM,EAAE,IAAI;YACZ,cAAc,EAAE,IAAI;YACpB,kBAAkB,EAAE,IAAI;YACxB,kBAAkB,EAAE,IAAI;YACxB,0BAA0B,EAAE,IAAI;YAChC,4BAA4B,EAAE,IAAI;SACnC;QACD,OAAO,EAAE,CAAC,gBAAgB,CAAC;KAC5B,CAAC;IAEF,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,oBAAoB,CAAC,EAAE,YAAY,EAAE;QACnF,MAAM,EAAE,CAAC;KACV,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,qBAAqB,CAAC,OAAuB;IAC1D,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IACnD,MAAM,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAE3B,MAAM,SAAS,GAAG;;;;;;aAMP,OAAO,CAAC,WAAW;;;;;;;CAO/B,CAAC;IACA,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,YAAY,CAAC,EAAE,SAAS,CAAC,CAAC;IAE1E,0EAA0E;IAC1E,MAAM,OAAO,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YAsCN,OAAO,CAAC,WAAW;;;;;;;;;;;;CAY9B,CAAC;IAEA,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,OAAO,CAAC,CAAC;IAE3D,MAAM,MAAM,GAAG;;;;;;;;;;;yBAWQ,OAAO,CAAC,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiD3C,CAAC;IAEA,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,CAAC,CAAC;IAEzD,MAAM,MAAM,GAAG;;;;;;;;CAQhB,CAAC;IACA,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,CAAC,CAAC;IAEzD,MAAM,QAAQ,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;CAyBlB,CAAC;IACA,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,EAAE,QAAQ,CAAC,CAAC;IAE7D,MAAM,OAAO,GAAG,uCAAuC,CAAC;IACxD,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,eAAe,CAAC,EAAE,OAAO,CAAC,CAAC;AAClE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,OAAuB;IAC9D,IAAI,CAAC,OAAO,CAAC,MAAM;QAAE,OAAO;IAE5B,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;CAuBhB,CAAC;IAEA,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,kBAAkB,CAAC,EAAE,MAAM,CAAC,CAAC;AAC/E,CAAC"}
|