@getpara/create-para-app 0.1.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.
@@ -0,0 +1,637 @@
1
+ export function getEnvFileContent(apiKey, isNext) {
2
+ return isNext ? `NEXT_PUBLIC_PARA_API_KEY=${apiKey}\n` : `VITE_PARA_API_KEY=${apiKey}\n`;
3
+ }
4
+ export function getParaClientCode(isNext, isTypescript) {
5
+ if (isNext && !isTypescript) {
6
+ return `import { Environment, ParaWeb } from "@getpara/react-sdk";
7
+
8
+ const API_KEY = process.env.NEXT_PUBLIC_PARA_API_KEY;
9
+ export const para = new ParaWeb(Environment.BETA, API_KEY);
10
+ `;
11
+ }
12
+ if (isNext && isTypescript) {
13
+ return `import { Environment, ParaWeb } from "@getpara/react-sdk";
14
+
15
+ const API_KEY: string | undefined = process.env.NEXT_PUBLIC_PARA_API_KEY;
16
+ export const para = new ParaWeb(Environment.BETA, API_KEY || "");
17
+ `;
18
+ }
19
+ if (!isNext && !isTypescript) {
20
+ return `import { Environment, ParaWeb } from "@getpara/react-sdk";
21
+
22
+ const API_KEY = import.meta.env.VITE_PARA_API_KEY;
23
+ export const para = new ParaWeb(Environment.BETA, API_KEY);
24
+ `;
25
+ }
26
+ return `import { Environment, ParaWeb } from "@getpara/react-sdk";
27
+
28
+ const API_KEY: string | undefined = import.meta.env.VITE_PARA_API_KEY;
29
+ export const para = new ParaWeb(Environment.BETA, API_KEY || "");
30
+ `;
31
+ }
32
+ export function getWalletProviderCodeNextjs(networks, noAppRouter) {
33
+ const result = [];
34
+ if (!noAppRouter) {
35
+ const lines = [];
36
+ lines.push(`"use client";`, `import React, { PropsWithChildren } from "react";`, `import { para } from "@/client/para";`, `import { QueryClient, QueryClientProvider } from "@tanstack/react-query";`);
37
+ let needQueryClient = false;
38
+ let nest = '{children}';
39
+ if (networks.includes('evm')) {
40
+ needQueryClient = true;
41
+ lines.push(`import { ParaEvmProvider, walletConnectWallet, metaMaskWallet, rabbyWallet, rainbowWallet, coinbaseWallet, zerionWallet } from "@getpara/evm-wallet-connectors";`, `import { sepolia, celo, mainnet, polygon } from "wagmi/chains";`);
42
+ nest = `
43
+ <ParaEvmProvider
44
+ config={{
45
+ projectId: "YOUR_PROJECT_ID",
46
+ appName: "YOUR_APP_NAME",
47
+ chains: [mainnet, polygon, sepolia, celo],
48
+ wallets: [metaMaskWallet, rainbowWallet, walletConnectWallet, zerionWallet, coinbaseWallet, rabbyWallet],
49
+ para: para,
50
+ }}
51
+ >
52
+ ${nest}
53
+ </ParaEvmProvider>
54
+ `;
55
+ }
56
+ if (networks.includes('solana')) {
57
+ needQueryClient = true;
58
+ lines.push(`import { ParaSolanaProvider, glowWallet, phantomWallet, backpackWallet } from "@getpara/solana-wallet-connectors";`, `import { WalletAdapterNetwork } from "@solana/wallet-adapter-base";`, `import { clusterApiUrl } from "@solana/web3.js";`);
59
+ nest = `
60
+ <ParaSolanaProvider
61
+ endpoint={clusterApiUrl(WalletAdapterNetwork.Devnet)}
62
+ wallets={[glowWallet, phantomWallet, backpackWallet]}
63
+ chain={WalletAdapterNetwork.Devnet}
64
+ appIdentity={{
65
+ name: "YOUR_APP_NAME",
66
+ uri: typeof window !== "undefined" ? \`\${window.location.protocol}//\${window.location.host}\` : "",
67
+ }}
68
+ >
69
+ ${nest}
70
+ </ParaSolanaProvider>
71
+ `;
72
+ }
73
+ if (networks.includes('cosmos')) {
74
+ needQueryClient = true;
75
+ lines.push(`import { ParaCosmosProvider, keplrWallet, leapWallet } from "@getpara/cosmos-wallet-connectors";`, `import { cosmoshub } from "@getpara/graz/chains";`);
76
+ nest = `
77
+ <ParaCosmosProvider
78
+ chains={[{
79
+ ...cosmoshub,
80
+ rpc: "https://rpc.cosmos.directory/cosmoshub",
81
+ rest: "https://rest.cosmos.directory/cosmoshub",
82
+ }]}
83
+ wallets={[keplrWallet, leapWallet]}
84
+ selectedChainId={cosmoshub.chainId}
85
+ multiChain={false}
86
+ onSwitchChain={(chainId) => {
87
+ console.log("Switched chain to:", chainId);
88
+ }}
89
+ >
90
+ ${nest}
91
+ </ParaCosmosProvider>
92
+ `;
93
+ }
94
+ const queryClientSetup = needQueryClient ? `const queryClient = new QueryClient();` : '';
95
+ if (needQueryClient) {
96
+ nest = `
97
+ <QueryClientProvider client={queryClient}>
98
+ ${nest}
99
+ </QueryClientProvider>
100
+ `;
101
+ }
102
+ lines.push(`
103
+ ${queryClientSetup}
104
+
105
+ export function ParaWalletsProvider({ children }: PropsWithChildren) {
106
+ return (
107
+ <>
108
+ ${nest}
109
+ </>
110
+ );
111
+ }
112
+ `);
113
+ result.push({ fileName: 'ParaWalletsProvider', code: lines.join('\n') });
114
+ }
115
+ else {
116
+ const dynamicImport = [];
117
+ dynamicImport.push(`import React, { PropsWithChildren } from "react";`, `import dynamic from "next/dynamic";`);
118
+ dynamicImport.push(`
119
+ export const ParaWalletsProvider = dynamic(() => import("./ParaWalletsProviderFull").then(m => m.ParaWalletsProviderFull), {
120
+ ssr: false
121
+ });
122
+ `);
123
+ result.push({ fileName: 'ParaWalletsProvider', code: dynamicImport.join('\n') });
124
+ const fullProvider = [];
125
+ fullProvider.push(`"use client";`, `import React, { PropsWithChildren } from "react";`, `import { para } from "@/client/para";`, `import { QueryClient, QueryClientProvider } from "@tanstack/react-query";`);
126
+ let needQueryClient = false;
127
+ let nest = '{children}';
128
+ if (networks.includes('evm')) {
129
+ needQueryClient = true;
130
+ fullProvider.push(`import { ParaEvmProvider, walletConnectWallet, metaMaskWallet, rabbyWallet, rainbowWallet, coinbaseWallet, zerionWallet } from "@getpara/evm-wallet-connectors";`, `import { sepolia, celo, mainnet, polygon } from "wagmi/chains";`);
131
+ nest = `
132
+ <ParaEvmProvider
133
+ config={{
134
+ projectId: "YOUR_PROJECT_ID",
135
+ appName: "YOUR_APP_NAME",
136
+ chains: [mainnet, polygon, sepolia, celo],
137
+ wallets: [metaMaskWallet, rainbowWallet, walletConnectWallet, zerionWallet, coinbaseWallet, rabbyWallet],
138
+ para: para,
139
+ }}
140
+ >
141
+ ${nest}
142
+ </ParaEvmProvider>
143
+ `;
144
+ }
145
+ if (networks.includes('solana')) {
146
+ needQueryClient = true;
147
+ fullProvider.push(`import { ParaSolanaProvider, glowWallet, phantomWallet, backpackWallet } from "@getpara/solana-wallet-connectors";`, `import { WalletAdapterNetwork } from "@solana/wallet-adapter-base";`, `import { clusterApiUrl } from "@solana/web3.js";`);
148
+ nest = `
149
+ <ParaSolanaProvider
150
+ endpoint={clusterApiUrl(WalletAdapterNetwork.Devnet)}
151
+ wallets={[glowWallet, phantomWallet, backpackWallet]}
152
+ chain={WalletAdapterNetwork.Devnet}
153
+ appIdentity={{
154
+ name: "YOUR_APP_NAME",
155
+ uri: typeof window !== "undefined" ? \`\${window.location.protocol}//\${window.location.host}\` : "",
156
+ }}
157
+ >
158
+ ${nest}
159
+ </ParaSolanaProvider>
160
+ `;
161
+ }
162
+ if (networks.includes('cosmos')) {
163
+ needQueryClient = true;
164
+ fullProvider.push(`import { ParaCosmosProvider, keplrWallet, leapWallet } from "@getpara/cosmos-wallet-connectors";`, `import { cosmoshub } from "@getpara/graz/chains";`);
165
+ nest = `
166
+ <ParaCosmosProvider
167
+ chains={[{
168
+ ...cosmoshub,
169
+ rpc: "https://rpc.cosmos.directory/cosmoshub",
170
+ rest: "https://rest.cosmos.directory/cosmoshub",
171
+ }]}
172
+ wallets={[keplrWallet, leapWallet]}
173
+ selectedChainId={cosmoshub.chainId}
174
+ multiChain={false}
175
+ onSwitchChain={(chainId) => {
176
+ console.log("Switched chain to:", chainId);
177
+ }}
178
+ >
179
+ ${nest}
180
+ </ParaCosmosProvider>
181
+ `;
182
+ }
183
+ const qSetup = needQueryClient ? `const queryClient = new QueryClient();` : '';
184
+ if (needQueryClient) {
185
+ nest = `
186
+ <QueryClientProvider client={queryClient}>
187
+ ${nest}
188
+ </QueryClientProvider>
189
+ `;
190
+ }
191
+ fullProvider.push(`
192
+ ${qSetup}
193
+
194
+ export function ParaWalletsProviderFull({ children }: PropsWithChildren) {
195
+ return (
196
+ <>
197
+ ${nest}
198
+ </>
199
+ );
200
+ }
201
+ `);
202
+ result.push({ fileName: 'ParaWalletsProviderFull', code: fullProvider.join('\n') });
203
+ }
204
+ return result;
205
+ }
206
+ export function getWalletProviderCodeVite(networks) {
207
+ const lines = [];
208
+ lines.push(`import React, { PropsWithChildren } from "react";`, `import { para } from "@/client/para";`, `import { QueryClient, QueryClientProvider } from "@tanstack/react-query";`);
209
+ let needQueryClient = false;
210
+ let nest = '{children}';
211
+ if (networks.includes('evm')) {
212
+ needQueryClient = true;
213
+ lines.push(`import { ParaEvmProvider, walletConnectWallet, metaMaskWallet, rabbyWallet, rainbowWallet, coinbaseWallet, zerionWallet } from "@getpara/evm-wallet-connectors";`, `import { sepolia, celo, mainnet, polygon } from "wagmi/chains";`);
214
+ nest = `
215
+ <ParaEvmProvider
216
+ config={{
217
+ projectId: "YOUR_PROJECT_ID",
218
+ appName: "YOUR_APP_NAME",
219
+ chains: [mainnet, polygon, sepolia, celo],
220
+ wallets: [metaMaskWallet, rainbowWallet, walletConnectWallet, zerionWallet, coinbaseWallet, rabbyWallet],
221
+ para: para,
222
+ }}
223
+ >
224
+ ${nest}
225
+ </ParaEvmProvider>
226
+ `;
227
+ }
228
+ if (networks.includes('solana')) {
229
+ needQueryClient = true;
230
+ lines.push(`import { ParaSolanaProvider, glowWallet, phantomWallet, backpackWallet } from "@getpara/solana-wallet-connectors";`, `import { WalletAdapterNetwork } from "@solana/wallet-adapter-base";`, `import { clusterApiUrl } from "@solana/web3.js";`);
231
+ nest = `
232
+ <ParaSolanaProvider
233
+ endpoint={clusterApiUrl(WalletAdapterNetwork.Devnet)}
234
+ wallets={[glowWallet, phantomWallet, backpackWallet]}
235
+ chain={WalletAdapterNetwork.Devnet}
236
+ appIdentity={{
237
+ name: "YOUR_APP_NAME",
238
+ uri: typeof window !== "undefined" ? \`\${window.location.protocol}//\${window.location.host}\` : "",
239
+ }}
240
+ >
241
+ ${nest}
242
+ </ParaSolanaProvider>
243
+ `;
244
+ }
245
+ if (networks.includes('cosmos')) {
246
+ needQueryClient = true;
247
+ lines.push(`import { ParaCosmosProvider, keplrWallet, leapWallet } from "@getpara/cosmos-wallet-connectors";`, `import { cosmoshub } from "@getpara/graz/chains";`);
248
+ nest = `
249
+ <ParaCosmosProvider
250
+ chains={[{
251
+ ...cosmoshub,
252
+ rpc: "https://rpc.cosmos.directory/cosmoshub",
253
+ rest: "https://rest.cosmos.directory/cosmoshub",
254
+ }]}
255
+ wallets={[keplrWallet, leapWallet]}
256
+ selectedChainId={cosmoshub.chainId}
257
+ multiChain={false}
258
+ onSwitchChain={(chainId) => {
259
+ console.log("Switched chain to:", chainId);
260
+ }}
261
+ >
262
+ ${nest}
263
+ </ParaCosmosProvider>
264
+ `;
265
+ }
266
+ const queryClientSetup = needQueryClient ? `const queryClient = new QueryClient();` : '';
267
+ if (needQueryClient) {
268
+ nest = `
269
+ <QueryClientProvider client={queryClient}>
270
+ ${nest}
271
+ </QueryClientProvider>
272
+ `;
273
+ }
274
+ lines.push(`
275
+ ${queryClientSetup}
276
+
277
+ export function ParaWalletsProvider({ children }: PropsWithChildren) {
278
+ return (
279
+ <>
280
+ ${nest}
281
+ </>
282
+ );
283
+ }
284
+ `);
285
+ return lines.join('\n');
286
+ }
287
+ export function getHelloParaFile(tailwind, isTypescript, isNext) {
288
+ if (tailwind) {
289
+ const ext = isTypescript ? 'tsx' : 'jsx';
290
+ return `export default function HelloPara({ children }: { children: React.ReactNode }) {
291
+ return (
292
+ <div className="min-h-screen bg-[#fafafa]">
293
+ <main className="container mx-auto px-4 py-16">
294
+ <div className="text-center space-y-4 mb-12">
295
+ <h1 className="text-4xl md:text-6xl font-bold bg-gradient-to-r from-[#FF4E00] via-[#E73461] to-[#874AE3] text-transparent bg-clip-text">
296
+ Welcome to Para SDK
297
+ </h1>
298
+ <p className="text-lg text-gray-600 max-w-2xl mx-auto">
299
+ This template is pre-configured with Para SDK. The key files you'll work with are{" "}
300
+ <code className="px-2 py-1 bg-gray-100 rounded text-[#E73461] text-sm font-mono">
301
+ src/components/ParaWalletsProvider
302
+ </code>{" "}
303
+ for the provider and{" "}
304
+ <code className="px-2 py-1 bg-gray-100 rounded text-[#E73461] text-sm font-mono">
305
+ ${isNext ? 'src/app/page.tsx' : 'src/App.tsx'}
306
+ </code>{" "}
307
+ for the implementation.
308
+ </p>
309
+ </div>
310
+ <div className="grid md:grid-cols-3 gap-6 mb-12">
311
+ <div className="p-6 bg-white rounded-lg shadow-sm border border-gray-100">
312
+ <img
313
+ src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGNsYXNzPSJsdWNpZGUgbHVjaWRlLWNvZGUteG1sIj48cGF0aCBkPSJtMTggMTYgNC00LTQtNCIvPjxwYXRoIGQ9Im02IDgtNCA0IDQgNCIvPjxwYXRoIGQ9Im0xNC41IDQtNSAxNiIvPjwvc3ZnPg=="
314
+ className="w-10 h-10 text-[#FF4E00] mb-4"
315
+ alt="Code Icon"
316
+ />
317
+ <h3 className="text-lg font-semibold mb-2">Simple Integration</h3>
318
+ <p className="text-gray-600">
319
+ The ParaWalletsProvider is pre-configured. Just update your configuration in{" "}
320
+ <code className="px-1.5 py-0.5 bg-gray-100 rounded text-[#E73461] text-sm font-mono">
321
+ ParaWalletsProvider.${ext}
322
+ </code>
323
+ </p>
324
+ </div>
325
+ <div className="p-6 bg-white rounded-lg shadow-sm border border-gray-100">
326
+ <img
327
+ src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGNsYXNzPSJsdWNpZGUgbHVjaWRlLWJsb2NrcyI+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iNyIgeD0iMTQiIHk9IjMiIHJ4PSIxIi8+PHBhdGggZD0ibTEwIDIxVjhhMSAxIDAgMCAwLTEtMUg0YTEgMSAwIDAgMC0xIDF2MTJhMSAxIDAgMCAwIDEgMWgxMmExIDEgMCAwIDAgMS0xdi01YTEgMSAwIDAgMC0xLTFIMyIvPjwvc3ZnPg=="
328
+ className="w-10 h-10 text-[#E73461] mb-4"
329
+ alt="Blocks Icon"
330
+ />
331
+ <h3 className="text-lg font-semibold mb-2">Modular Design</h3>
332
+ <p className="text-gray-600">
333
+ All components are modular. Customize the modal and UI components in{" "}
334
+ <code className="px-1.5 py-0.5 bg-gray-100 rounded text-[#E73461] text-sm font-mono">
335
+ src/components/*
336
+ </code>
337
+ </p>
338
+ </div>
339
+ <div className="p-6 bg-white rounded-lg shadow-sm border border-gray-100">
340
+ <img
341
+ src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGNsYXNzPSJsdWNpZGUgbHVjaWRlLXphcCI+PHBhdGggZD0iTTQgMTRhMSAxIDAgMCAxLS43OC0xLjYzbDkuOS0xMC4yYS41LjUgMCAwIDEgLjg2LjQ2bC0xLjkyIDYuMDJBMSAxIDAgMCAwIDEzIDEwaDdhMSAxIDAgMCAxIC43OCAxLjYzbC05LjkgMTAuMmEuNS41IDAgMCAxLS44Ni0uNDZsMS45Mi02LjAyQTEgMSAwIDAgMCAxMSAxNHoiLz48L3N2Zz4="
342
+ className="w-10 h-10 text-[#874AE3] mb-4"
343
+ alt="Zap Icon"
344
+ />
345
+ <h3 className="text-lg font-semibold mb-2">Lightning Fast</h3>
346
+ <p className="text-gray-600">
347
+ Start building immediately. Your logic lives in{" "}
348
+ <code className="px-1.5 py-0.5 bg-gray-100 rounded text-[#E73461] text-sm font-mono">
349
+ ${isNext ? 'src/app/page.tsx' : 'src/App.tsx'}
350
+ </code>
351
+ </p>
352
+ </div>
353
+ </div>
354
+ {children}
355
+ </main>
356
+ </div>
357
+ );
358
+ }
359
+ `;
360
+ }
361
+ return `export default function HelloPara({ children }) {
362
+ return (
363
+ <div style={{ minHeight: '100vh', backgroundColor: '#fafafa' }}>
364
+ <main style={{ maxWidth: '1200px', margin: '0 auto', padding: '4rem 1rem' }}>
365
+ <div style={{ textAlign: 'center', marginBottom: '3rem' }}>
366
+ <h1 style={{ fontSize: '2.25rem', fontWeight: 'bold', background: 'linear-gradient(to right, #FF4E00, #E73461, #874AE3)', WebkitBackgroundClip: 'text', WebkitTextFillColor: 'transparent', backgroundClip: 'text', color: 'transparent' }}>
367
+ Welcome to Para SDK
368
+ </h1>
369
+ <p style={{ fontSize: '1.125rem', color: '#4B5563', maxWidth: '672px', margin: '0 auto' }}>
370
+ This template is pre-configured with Para SDK. The key files you'll work with are{" "}
371
+ <code style={{ padding: '0.25rem 0.5rem', backgroundColor: '#F3F4F6', borderRadius: '0.375rem', color: '#E73461', fontSize: '0.875rem', fontFamily: 'monospace' }}>
372
+ src/components/ParaWalletsProvider
373
+ </code>{" "}
374
+ for the provider and{" "}
375
+ <code style={{ padding: '0.25rem 0.5rem', backgroundColor: '#F3F4F6', borderRadius: '0.375rem', color: '#E73461', fontSize: '0.875rem', fontFamily: 'monospace' }}>
376
+ ${isNext ? 'src/app/page.jsx' : 'src/App.jsx'}
377
+ </code>{" "}
378
+ for the implementation.
379
+ </p>
380
+ </div>
381
+ <div style={{ display: 'grid', gridTemplateColumns: '1fr', gap: '1.5rem', marginBottom: '3rem' }}>
382
+ <div style={{ padding: '1.5rem', backgroundColor: '#FFFFFF', borderRadius: '0.5rem', boxShadow: '0 1px 2px rgba(0, 0, 0, 0.05)', border: '1px solid #F3F4F6' }}>
383
+ <img
384
+ src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2g9IjI0IiB2aWV3Qm94PSIwIDAgMjQgMjQiIGZpbGw9Im5vbmUiIHN0cm9rZT0iY3VycmVudENvbG9yIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgaWQ9ImNvZGVJY29uIj48cGF0aCBkPSJtMTggMTYgNC00LTQtNCIvPjxwYXRoIGQ9Im02IDgtNCA0IDQgNCIvPjxwYXRoIGQ9Im0xNC41IDQtNSAxNiIvPjwvc3ZnPg=="
385
+ alt="Code Icon"
386
+ style={{ width: '40px', height: '40px', marginBottom: '0.5rem' }}
387
+ />
388
+ <h3 style={{ fontSize: '1.125rem', fontWeight: '600', marginBottom: '0.5rem' }}>Simple Integration</h3>
389
+ <p style={{ color: '#4B5563' }}>
390
+ The ParaWalletsProvider is pre-configured. Just update your configuration in{" "}
391
+ <code style={{ padding: '0.375rem 0.5rem', backgroundColor: '#F3F4F6', borderRadius: '0.375rem', color: '#E73461', fontSize: '0.875rem', fontFamily: 'monospace' }}>
392
+ ParaWalletsProvider.jsx
393
+ </code>
394
+ </p>
395
+ </div>
396
+ <div style={{ padding: '1.5rem', backgroundColor: '#FFFFFF', borderRadius: '0.5rem', boxShadow: '0 1px 2px rgba(0, 0, 0, 0.05)', border: '1px solid #F3F4F6' }}>
397
+ <img
398
+ src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2g9IjI0IiB2aWV3Qm94PSIwIDAgMjQgMjQiIGZpbGw9Im5vbmUiIHN0cm9rZT0iY3VycmVudENvbG9yIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgaWQ9ImJsb2Nrc0ljb24iPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjciIHg9IjE0IiB5PSIzIiByeD0iMSIvPjxwYXRoIGQ9Im0xMCAyMVY4YTEgMSAwIDAgMC0xLTFINGExIDEgMCAwIDAtMSAxVjEyYTEgMSAwIDAgMCAxIDFoMTJhMSAxIDAgMCAwIC43OCAxLjYzbC05LjkgMTAuMmEuNS41IDAgMCAxLS44Ni0uNDZsMS45Mi02LjAyQTEgMSAwIDAgMCAxMSAxNHoiLz48L3N2Zz4="
399
+ alt="Blocks Icon"
400
+ style={{ width: '40px', height: '40px', marginBottom: '0.5rem' }}
401
+ />
402
+ <h3 style={{ fontSize: '1.125rem', fontWeight: '600', marginBottom: '0.5rem' }}>Modular Design</h3>
403
+ <p style={{ color: '#4B5563' }}>
404
+ All components are modular. Customize the modal and UI elements in{" "}
405
+ <code style={{ padding: '0.375rem 0.5rem', backgroundColor: '#F3F4F6', borderRadius: '0.375rem', color: '#E73461', fontSize: '0.875rem', fontFamily: 'monospace' }}>
406
+ src/components/*
407
+ </code>
408
+ </p>
409
+ </div>
410
+ <div style={{ padding: '1.5rem', backgroundColor: '#FFFFFF', borderRadius: '0.5rem', boxShadow: '0 1px 2px rgba(0, 0, 0, 0.05)', border: '1px solid #F3F4F6' }}>
411
+ <img
412
+ src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2g9IjI0IiB2aWV3Qm94PSIwIDAgMjQgMjQiIGZpbGw9Im5vbmUiIHN0cm9rZT0iY3VycmVudENvbG9yIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgaWQ9InphcEljb25JY29uIj48cGF0aCBkPSJNNCAxNGExIDEgMCAwIDEtLjc4LTEuNjNsOS45LTEwLjJhLjUuNSAwIDAgMSAuODYuNDZsLTEuOTIgNi4wMkExIDEgMCAwIDAgMTMgMTBoN2ExIDEgMCAwIDEgLjc4IDEuNjNsLTkuOSAxMC4yYS41LjUgMCAwIDEtLjg2LS40NmwxLjkyLTYuMDJBMSAxIDAgMCAwIDExIDE0eiIvPjwvc3ZnPg=="
413
+ alt="Zap Icon"
414
+ style={{ width: '40px', height: '40px', marginBottom: '0.5rem' }}
415
+ />
416
+ <h3 style={{ fontSize: '1.125rem', fontWeight: '600', marginBottom: '0.5rem' }}>Lightning Fast</h3>
417
+ <p style={{ color: '#4B5563' }}>
418
+ Start building immediately. Your logic lives in{" "}
419
+ <code style={{ padding: '0.375rem 0.5rem', backgroundColor: '#F3F4F6', borderRadius: '0.375rem', color: '#E73461', fontSize: '0.875rem', fontFamily: 'monospace' }}>
420
+ ${isNext ? 'src/app/page.jsx' : 'src/App.jsx'}
421
+ </code>
422
+ </p>
423
+ </div>
424
+ </div>
425
+ <div className="flex justify-center items-center">
426
+ {children}
427
+ </div>
428
+ </main>
429
+ </div>
430
+ );
431
+ }
432
+ `;
433
+ }
434
+ export function getHomeFile(tailwind, isNext, externalWalletSupport) {
435
+ const maybeUseClient = isNext ? `"use client";\n` : '';
436
+ const helloParaImport = isNext
437
+ ? `import HelloPara from "@/components/HelloPara";`
438
+ : `import HelloPara from "./HelloPara";`;
439
+ let externalImports = ``;
440
+ if (externalWalletSupport) {
441
+ if (isNext) {
442
+ externalImports = `import { ExternalWallet } from "@getpara/react-sdk";
443
+ import { ParaWalletsProvider } from "@/components/ParaWalletsProvider";`;
444
+ }
445
+ else {
446
+ externalImports = `import { ExternalWallet } from "@getpara/react-sdk";
447
+ import { ParaWalletsProvider } from "./ParaWalletsProvider";`;
448
+ }
449
+ }
450
+ const wrapBegin = externalWalletSupport ? `<ParaWalletsProvider>` : ``;
451
+ const wrapEnd = externalWalletSupport ? `</ParaWalletsProvider>` : ``;
452
+ const maybeClass = tailwind
453
+ ? `className="bg-[#FF4E00] hover:bg-[#E73461] text-white font-semibold py-2 px-4 rounded"`
454
+ : `className="open-button"`;
455
+ const externalWalletSnippet = externalWalletSupport
456
+ ? ` externalWallets={[
457
+ ExternalWallet.BACKPACK,
458
+ ExternalWallet.COINBASE,
459
+ ExternalWallet.GLOW,
460
+ ExternalWallet.KEPLR,
461
+ ExternalWallet.LEAP,
462
+ ExternalWallet.METAMASK,
463
+ ExternalWallet.PHANTOM,
464
+ ExternalWallet.RABBY,
465
+ ExternalWallet.RAINBOW,
466
+ ExternalWallet.WALLETCONNECT,
467
+ ExternalWallet.ZERION,
468
+ ]}`
469
+ : ``;
470
+ return `
471
+ ${maybeUseClient}import React, { useState } from "react";
472
+ import { para } from "@/client/para";
473
+ import { ParaModal, OAuthMethod, AuthLayout } from "@getpara/react-sdk";
474
+ import "@getpara/react-sdk/styles.css";
475
+ ${externalImports}
476
+ ${helloParaImport}
477
+
478
+ export default function Home() {
479
+ const [isOpen, setIsOpen] = useState(false);
480
+ const handleCloseModal = () => setIsOpen(false);
481
+
482
+ return (
483
+ <HelloPara>
484
+ ${wrapBegin}
485
+ <button onClick={() => setIsOpen(true)} ${maybeClass}>
486
+ Try the SDK
487
+ </button>
488
+ <ParaModal
489
+ para={para}
490
+ isOpen={isOpen}
491
+ onClose={handleCloseModal}
492
+ ${externalWalletSnippet}
493
+ disableEmailLogin={false}
494
+ disablePhoneLogin={false}
495
+ authLayout={[AuthLayout.AUTH_FULL]}
496
+ oAuthMethods={[
497
+ OAuthMethod.APPLE,
498
+ OAuthMethod.DISCORD,
499
+ OAuthMethod.FACEBOOK,
500
+ OAuthMethod.FARCASTER,
501
+ OAuthMethod.GOOGLE,
502
+ OAuthMethod.TWITTER,
503
+ ]}
504
+ onRampTestMode={true}
505
+ theme={{
506
+ foregroundColor: "#2D3648",
507
+ backgroundColor: "#FFFFFF",
508
+ accentColor: "#0066CC",
509
+ darkForegroundColor: "#E8EBF2",
510
+ darkBackgroundColor: "#1A1F2B",
511
+ darkAccentColor: "#4D9FFF",
512
+ mode: "light",
513
+ borderRadius: "none",
514
+ font: "Inter",
515
+ }}
516
+ appName="YOUR_APP_NAME"
517
+ logo="YOUR_APP_LOGO"
518
+ recoverySecretStepEnabled={true}
519
+ twoFactorAuthEnabled={false}
520
+ />
521
+ ${wrapEnd}
522
+ </HelloPara>
523
+ );
524
+ }
525
+ `;
526
+ }
527
+ export function getStylesNonTailwind() {
528
+ return `.outer {
529
+ min-height: 100vh;
530
+ background-color: #fafafa;
531
+ }
532
+
533
+ .main-container {
534
+ max-width: 1200px;
535
+ margin: 0 auto;
536
+ padding: 4rem 1rem;
537
+ }
538
+
539
+ .header {
540
+ text-align: center;
541
+ margin-bottom: 3rem;
542
+ }
543
+
544
+ .header > *:not(:last-child) {
545
+ margin-bottom: 1rem;
546
+ }
547
+
548
+ .title {
549
+ font-size: 2.25rem;
550
+ font-weight: bold;
551
+ background: linear-gradient(to right, #FF4E00, #E73461, #874AE3);
552
+ -webkit-background-clip: text;
553
+ -webkit-text-fill-color: transparent;
554
+ background-clip: text;
555
+ color: transparent;
556
+ }
557
+
558
+ .description {
559
+ font-size: 1.125rem;
560
+ color: #4B5563;
561
+ max-width: 672px;
562
+ margin: 0 auto;
563
+ }
564
+
565
+ .inline-code {
566
+ padding: 0.25rem 0.5rem;
567
+ background-color: #F3F4F6;
568
+ border-radius: 0.375rem;
569
+ color: #E73461;
570
+ font-size: 0.875rem;
571
+ font-family: monospace;
572
+ }
573
+
574
+ .grid-container {
575
+ display: grid;
576
+ grid-template-columns: 1fr;
577
+ gap: 1.5rem;
578
+ margin-bottom: 3rem;
579
+ }
580
+
581
+ @media (min-width: 768px) {
582
+ .grid-container {
583
+ grid-template-columns: repeat(3, 1fr);
584
+ }
585
+ }
586
+
587
+ .card {
588
+ padding: 1.5rem;
589
+ background-color: #FFFFFF;
590
+ border-radius: 0.5rem;
591
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
592
+ border: 1px solid #F3F4F6;
593
+ }
594
+
595
+ .card-icon {
596
+ width: 40px;
597
+ height: 40px;
598
+ margin-bottom: 1rem;
599
+ }
600
+
601
+ .icon-code {
602
+ color: #FF4E00;
603
+ }
604
+
605
+ .icon-blocks {
606
+ color: #E73461;
607
+ }
608
+
609
+ .icon-zap {
610
+ color: #874AE3;
611
+ }
612
+
613
+ .card-title {
614
+ font-size: 1.125rem;
615
+ font-weight: 600;
616
+ margin-bottom: 0.5rem;
617
+ }
618
+
619
+ .card-text {
620
+ color: #4B5563;
621
+ }
622
+
623
+ .open-button {
624
+ background-color: #FF4E00;
625
+ color: #FFFFFF;
626
+ font-weight: 600;
627
+ padding: 0.5rem 1rem;
628
+ border: none;
629
+ border-radius: 0.25rem;
630
+ cursor: pointer;
631
+ }
632
+
633
+ .open-button:hover {
634
+ background-color: #E73461;
635
+ }
636
+ `;
637
+ }