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