@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.
- package/bin/index.ts +2 -0
- package/dist/commands/scaffold.js +137 -0
- package/dist/index.js +48 -0
- package/dist/integrations/codeGenerators.js +637 -0
- package/dist/integrations/packageJsonHelpers.js +77 -0
- package/dist/integrations/sdkSetup.js +24 -0
- package/dist/integrations/sdkSetupNextjs.js +111 -0
- package/dist/integrations/sdkSetupVite.js +82 -0
- package/dist/package.json +40 -0
- package/dist/prompts/interactive.js +98 -0
- package/dist/src/index.js +43 -0
- package/dist/templates/nextjs.js +61 -0
- package/dist/templates/vite-react.js +43 -0
- package/dist/utils/exec.js +16 -0
- package/dist/utils/formatting.js +31 -0
- package/dist/utils/logger.js +19 -0
- package/package.json +41 -0
- package/src/commands/scaffold.ts +196 -0
- package/src/index.ts +43 -0
- package/src/integrations/codeGenerators.ts +690 -0
- package/src/integrations/packageJsonHelpers.ts +71 -0
- package/src/integrations/sdkSetup.ts +13 -0
- package/src/integrations/sdkSetupNextjs.ts +122 -0
- package/src/integrations/sdkSetupVite.ts +87 -0
- package/src/prompts/interactive.ts +113 -0
- package/src/templates/nextjs.ts +54 -0
- package/src/templates/vite-react.ts +33 -0
- package/src/utils/exec.ts +6 -0
- package/src/utils/formatting.ts +18 -0
- package/src/utils/logger.ts +25 -0
- package/tsconfig.json +18 -0
|
@@ -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
|
+
}
|