@diviswap/sdk 1.7.6

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.
Files changed (66) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +510 -0
  3. package/bin/create-diviswap-app.js +25 -0
  4. package/bin/diviswap-sdk.js +4 -0
  5. package/dist/cli/index.js +1888 -0
  6. package/dist/cli/templates/nextjs-app/actions.ts.hbs +259 -0
  7. package/dist/cli/templates/nextjs-app/api-hooks.ts.hbs +439 -0
  8. package/dist/cli/templates/nextjs-app/api-route.ts.hbs +502 -0
  9. package/dist/cli/templates/nextjs-app/auth-context.tsx.hbs +59 -0
  10. package/dist/cli/templates/nextjs-app/client.ts.hbs +116 -0
  11. package/dist/cli/templates/nextjs-app/dashboard-hooks.ts.hbs +180 -0
  12. package/dist/cli/templates/nextjs-app/example-page.tsx.hbs +276 -0
  13. package/dist/cli/templates/nextjs-app/hooks.ts.hbs +252 -0
  14. package/dist/cli/templates/nextjs-app/kyc-hooks.ts.hbs +87 -0
  15. package/dist/cli/templates/nextjs-app/kyc-wizard.css.hbs +433 -0
  16. package/dist/cli/templates/nextjs-app/kyc-wizard.tsx.hbs +711 -0
  17. package/dist/cli/templates/nextjs-app/layout-wrapper.tsx.hbs +13 -0
  18. package/dist/cli/templates/nextjs-app/layout.tsx.hbs +13 -0
  19. package/dist/cli/templates/nextjs-app/middleware.ts.hbs +49 -0
  20. package/dist/cli/templates/nextjs-app/provider-wrapper.tsx.hbs +8 -0
  21. package/dist/cli/templates/nextjs-app/provider.tsx.hbs +408 -0
  22. package/dist/cli/templates/nextjs-app/setup-provider.tsx.hbs +25 -0
  23. package/dist/cli/templates/nextjs-app/types.ts.hbs +159 -0
  24. package/dist/cli/templates/react/api-client-wrapper.ts.hbs +89 -0
  25. package/dist/cli/templates/react/example.tsx.hbs +69 -0
  26. package/dist/cli/templates/react/tanstack-hooks.ts.hbs +185 -0
  27. package/dist/cli/templates/webhooks/nextjs.hbs +98 -0
  28. package/dist/index.d.mts +91 -0
  29. package/dist/index.d.ts +91 -0
  30. package/dist/index.js +2339 -0
  31. package/dist/index.js.map +1 -0
  32. package/dist/index.mjs +2313 -0
  33. package/dist/index.mjs.map +1 -0
  34. package/dist/react/index.d.mts +192 -0
  35. package/dist/react/index.d.ts +192 -0
  36. package/dist/react/index.js +1083 -0
  37. package/dist/react/index.js.map +1 -0
  38. package/dist/react/index.mjs +1064 -0
  39. package/dist/react/index.mjs.map +1 -0
  40. package/dist/wallet-BEGvzNtB.d.mts +1614 -0
  41. package/dist/wallet-BEGvzNtB.d.ts +1614 -0
  42. package/package.json +102 -0
  43. package/src/cli/templates/index.ts +65 -0
  44. package/src/cli/templates/nextjs-app/actions.ts.hbs +259 -0
  45. package/src/cli/templates/nextjs-app/api-hooks.ts.hbs +439 -0
  46. package/src/cli/templates/nextjs-app/api-route.ts.hbs +502 -0
  47. package/src/cli/templates/nextjs-app/auth-context.tsx.hbs +59 -0
  48. package/src/cli/templates/nextjs-app/client.ts.hbs +116 -0
  49. package/src/cli/templates/nextjs-app/dashboard-hooks.ts.hbs +180 -0
  50. package/src/cli/templates/nextjs-app/example-page.tsx.hbs +276 -0
  51. package/src/cli/templates/nextjs-app/hooks.ts.hbs +252 -0
  52. package/src/cli/templates/nextjs-app/kyc-hooks.ts.hbs +87 -0
  53. package/src/cli/templates/nextjs-app/kyc-wizard.css.hbs +433 -0
  54. package/src/cli/templates/nextjs-app/kyc-wizard.tsx.hbs +711 -0
  55. package/src/cli/templates/nextjs-app/layout-wrapper.tsx.hbs +13 -0
  56. package/src/cli/templates/nextjs-app/layout.tsx.hbs +13 -0
  57. package/src/cli/templates/nextjs-app/middleware.ts.hbs +49 -0
  58. package/src/cli/templates/nextjs-app/provider-wrapper.tsx.hbs +8 -0
  59. package/src/cli/templates/nextjs-app/provider.tsx.hbs +408 -0
  60. package/src/cli/templates/nextjs-app/setup-provider.tsx.hbs +25 -0
  61. package/src/cli/templates/nextjs-app/types.ts.hbs +159 -0
  62. package/src/cli/templates/react/api-client-wrapper.ts.hbs +89 -0
  63. package/src/cli/templates/react/example.tsx.hbs +69 -0
  64. package/src/cli/templates/react/tanstack-hooks.ts.hbs +185 -0
  65. package/src/cli/templates/shared/client.ts +78 -0
  66. package/src/cli/templates/webhooks/nextjs.hbs +98 -0
@@ -0,0 +1,1888 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ var commander = require('commander');
5
+ var fs = require('fs');
6
+ var path = require('path');
7
+ var child_process = require('child_process');
8
+ var prompts = require('prompts');
9
+ var kleur = require('kleur');
10
+ var Handlebars = require('handlebars');
11
+ var crypto = require('crypto');
12
+
13
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
14
+
15
+ var prompts__default = /*#__PURE__*/_interopDefault(prompts);
16
+ var kleur__default = /*#__PURE__*/_interopDefault(kleur);
17
+ var Handlebars__default = /*#__PURE__*/_interopDefault(Handlebars);
18
+ var crypto__default = /*#__PURE__*/_interopDefault(crypto);
19
+
20
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
21
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
22
+ }) : x)(function(x) {
23
+ if (typeof require !== "undefined") return require.apply(this, arguments);
24
+ throw Error('Dynamic require of "' + x + '" is not supported');
25
+ });
26
+ async function detectFramework() {
27
+ const projectRoot = process.cwd();
28
+ const packageJsonPath = path.join(projectRoot, "package.json");
29
+ if (!fs.existsSync(packageJsonPath)) {
30
+ return null;
31
+ }
32
+ try {
33
+ const packageJson = JSON.parse(
34
+ fs.readFileSync(packageJsonPath, "utf-8")
35
+ );
36
+ const deps = {
37
+ ...packageJson.dependencies,
38
+ ...packageJson.devDependencies
39
+ };
40
+ if (deps["next"]) {
41
+ if (fs.existsSync(path.join(projectRoot, "app")) || fs.existsSync(path.join(projectRoot, "src/app"))) {
42
+ return "nextjs-app";
43
+ }
44
+ if (fs.existsSync(path.join(projectRoot, "pages")) || fs.existsSync(path.join(projectRoot, "src/pages"))) {
45
+ return "nextjs-pages";
46
+ }
47
+ return "nextjs-app";
48
+ }
49
+ if (deps["vue"]) {
50
+ const vueVersion = deps["vue"];
51
+ if (vueVersion.startsWith("^3") || vueVersion.startsWith("3")) {
52
+ return "vue3";
53
+ }
54
+ return "vue";
55
+ }
56
+ if (deps["react"] && !deps["next"]) {
57
+ return "react";
58
+ }
59
+ if (deps["@angular/core"]) {
60
+ return "angular";
61
+ }
62
+ if (deps["svelte"]) {
63
+ return "svelte";
64
+ }
65
+ if (deps["nuxt"]) {
66
+ return "nuxt";
67
+ }
68
+ } catch (error) {
69
+ }
70
+ return null;
71
+ }
72
+ function getPackageRoot() {
73
+ if (fs.existsSync(path.join(process.cwd(), "src", "cli", "templates"))) {
74
+ return process.cwd();
75
+ }
76
+ try {
77
+ const npmBinPath = process.env.npm_execpath || "";
78
+ if (npmBinPath) {
79
+ const nodeModulesPath = path.dirname(path.dirname(npmBinPath));
80
+ const packagePath = path.join(nodeModulesPath, "@99darwin", "diviswap-sdk");
81
+ if (fs.existsSync(path.join(packagePath, "dist", "cli", "templates"))) {
82
+ return packagePath;
83
+ }
84
+ }
85
+ } catch {
86
+ }
87
+ const cwd = process.cwd();
88
+ const pathsToCheck = [
89
+ path.join(cwd, "node_modules", "@99darwin", "diviswap-sdk"),
90
+ path.join(path.dirname(cwd), "node_modules", "@99darwin", "diviswap-sdk"),
91
+ path.join(path.dirname(path.dirname(cwd)), "node_modules", "@99darwin", "diviswap-sdk")
92
+ ];
93
+ for (const packagePath of pathsToCheck) {
94
+ if (fs.existsSync(path.join(packagePath, "dist", "cli", "templates"))) {
95
+ return packagePath;
96
+ }
97
+ }
98
+ try {
99
+ const packageJsonPath = __require.resolve("@diviswap/sdk/package.json");
100
+ return path.dirname(packageJsonPath);
101
+ } catch {
102
+ return path.join(cwd, "node_modules", "@99darwin", "diviswap-sdk");
103
+ }
104
+ }
105
+
106
+ // src/cli/templates/index.ts
107
+ Handlebars__default.default.registerHelper("includes", (array, value) => {
108
+ return array && array.includes(value);
109
+ });
110
+ Handlebars__default.default.registerHelper("json", (value) => {
111
+ return JSON.stringify(value, null, 2);
112
+ });
113
+ var templateCache = /* @__PURE__ */ new Map();
114
+ function getTemplate(templateName, data) {
115
+ let template = templateCache.get(templateName);
116
+ if (!template) {
117
+ const packageRoot = getPackageRoot();
118
+ const possiblePaths = [
119
+ // Development paths - try different extensions
120
+ path.join(packageRoot, "src", "cli", "templates", `${templateName}.hbs`),
121
+ path.join(packageRoot, "src", "cli", "templates", `${templateName}.ts.hbs`),
122
+ path.join(packageRoot, "src", "cli", "templates", `${templateName}.tsx.hbs`),
123
+ // Production paths - try different extensions
124
+ path.join(packageRoot, "dist", "cli", "templates", `${templateName}.hbs`),
125
+ path.join(packageRoot, "dist", "cli", "templates", `${templateName}.ts.hbs`),
126
+ path.join(packageRoot, "dist", "cli", "templates", `${templateName}.tsx.hbs`)
127
+ ];
128
+ let templateSource = null;
129
+ for (const path of possiblePaths) {
130
+ if (fs.existsSync(path)) {
131
+ templateSource = fs.readFileSync(path, "utf-8");
132
+ break;
133
+ }
134
+ }
135
+ if (!templateSource) {
136
+ console.error(`Template ${templateName} not found. Searched in:`);
137
+ possiblePaths.forEach((p) => console.error(` - ${p}`));
138
+ templateSource = getInlineTemplateSource(templateName);
139
+ }
140
+ template = Handlebars__default.default.compile(templateSource);
141
+ templateCache.set(templateName, template);
142
+ }
143
+ return template(data);
144
+ }
145
+ function getInlineTemplateSource(templateName) {
146
+ console.warn(`Template ${templateName} not found in filesystem, returning empty template`);
147
+ return "// Template not found";
148
+ }
149
+
150
+ // src/cli/utils/file-generator.ts
151
+ function detectNextjsSrcDir(projectRoot) {
152
+ return fs.existsSync(path.join(projectRoot, "src/app")) || fs.existsSync(path.join(projectRoot, "src/pages"));
153
+ }
154
+ async function generateFiles(options) {
155
+ const { framework, features, projectRoot } = options;
156
+ const generatedFiles = [];
157
+ const ensureFile = (relativePath, content) => {
158
+ const fullPath = path.join(projectRoot, relativePath);
159
+ const dir = path.dirname(fullPath);
160
+ if (!fs.existsSync(dir)) {
161
+ fs.mkdirSync(dir, { recursive: true });
162
+ }
163
+ fs.writeFileSync(fullPath, content);
164
+ generatedFiles.push(relativePath);
165
+ };
166
+ switch (framework) {
167
+ case "nextjs-app":
168
+ await generateNextjsAppFiles(ensureFile, features, projectRoot);
169
+ break;
170
+ case "nextjs-pages":
171
+ await generateNextjsPagesFiles(ensureFile, features, projectRoot);
172
+ break;
173
+ case "react":
174
+ await generateReactFiles(ensureFile, features);
175
+ break;
176
+ case "vue3":
177
+ await generateVue3Files(ensureFile, features);
178
+ break;
179
+ case "vanilla":
180
+ await generateVanillaFiles(ensureFile, features);
181
+ break;
182
+ }
183
+ if (features.includes("webhooks")) {
184
+ await generateWebhookFiles(ensureFile, framework, projectRoot);
185
+ }
186
+ return generatedFiles;
187
+ }
188
+ async function generateNextjsAppFiles(ensureFile, features, projectRoot) {
189
+ const useSrc = projectRoot ? detectNextjsSrcDir(projectRoot) : false;
190
+ const prefix = useSrc ? "src/" : "";
191
+ ensureFile(
192
+ `${prefix}app/api/diviswap/route.ts`,
193
+ getTemplate("nextjs-app/api-route", { features })
194
+ );
195
+ if (features.includes("example")) {
196
+ ensureFile(
197
+ `${prefix}app/diviswap/page.tsx`,
198
+ getTemplate("nextjs-app/example-page", { features })
199
+ );
200
+ ensureFile(
201
+ `${prefix}app/diviswap/layout.tsx`,
202
+ getTemplate("nextjs-app/layout-wrapper", { features })
203
+ );
204
+ }
205
+ ensureFile(
206
+ `${prefix}app/diviswap/actions.ts`,
207
+ getTemplate("nextjs-app/actions", { features })
208
+ );
209
+ ensureFile(
210
+ `${prefix}components/diviswap-provider.tsx`,
211
+ getTemplate("nextjs-app/provider-wrapper", { features })
212
+ );
213
+ ensureFile(
214
+ `${prefix}context/diviswap-auth-context.tsx`,
215
+ getTemplate("nextjs-app/auth-context", { features, prefix: "Diviswap" })
216
+ );
217
+ ensureFile(
218
+ `${prefix}hooks/useLiberexData.ts`,
219
+ getTemplate("nextjs-app/dashboard-hooks", { features })
220
+ );
221
+ ensureFile(
222
+ `${prefix}hooks/useLiberexKYC.ts`,
223
+ getTemplate("nextjs-app/kyc-hooks", { features })
224
+ );
225
+ ensureFile(
226
+ `${prefix}components/diviswap-kyc-wizard.tsx`,
227
+ getTemplate("nextjs-app/kyc-wizard", { features })
228
+ );
229
+ ensureFile(
230
+ `${prefix}components/diviswap-kyc-wizard.css`,
231
+ getTemplate("nextjs-app/kyc-wizard.css", { features })
232
+ );
233
+ }
234
+ async function generateNextjsPagesFiles(ensureFile, features, projectRoot) {
235
+ const useSrc = projectRoot ? detectNextjsSrcDir(projectRoot) : false;
236
+ const prefix = useSrc ? "src/" : "";
237
+ ensureFile(
238
+ `${prefix}pages/api/diviswap/auth.ts`,
239
+ getTemplate("nextjs-pages/api-auth", { features })
240
+ );
241
+ ensureFile(
242
+ `${prefix}pages/api/diviswap/transactions.ts`,
243
+ getTemplate("nextjs-pages/api-transactions", { features })
244
+ );
245
+ ensureFile(
246
+ `${prefix}lib/diviswap/provider.tsx`,
247
+ getTemplate("nextjs-pages/provider", { features })
248
+ );
249
+ ensureFile(
250
+ `${prefix}pages/diviswap.tsx`,
251
+ getTemplate("nextjs-pages/example-page", { features })
252
+ );
253
+ ensureFile(
254
+ `${prefix}lib/diviswap/hooks.ts`,
255
+ getTemplate("nextjs-pages/hooks", { features })
256
+ );
257
+ ensureFile(
258
+ `${prefix}lib/diviswap/client.ts`,
259
+ getTemplate("nextjs-pages/client", { features })
260
+ );
261
+ }
262
+ async function generateReactFiles(ensureFile, features, projectRoot) {
263
+ ensureFile(
264
+ "src/diviswap/api-client.ts",
265
+ getTemplate("react/api-client-wrapper", { features })
266
+ );
267
+ if (features.includes("example")) {
268
+ ensureFile(
269
+ "src/diviswap/example.tsx",
270
+ getTemplate("react/example", { features })
271
+ );
272
+ }
273
+ }
274
+ async function generateVue3Files(ensureFile, features) {
275
+ ensureFile(
276
+ "src/plugins/diviswap.ts",
277
+ getTemplate("vue3/plugin", { features })
278
+ );
279
+ ensureFile(
280
+ "src/composables/useDiviswap.ts",
281
+ getTemplate("vue3/composable", { features })
282
+ );
283
+ ensureFile(
284
+ "src/components/DiviswapProvider.vue",
285
+ getTemplate("vue3/provider", { features })
286
+ );
287
+ ensureFile(
288
+ "src/components/TransactionButton.vue",
289
+ getTemplate("vue3/transaction-button", { features })
290
+ );
291
+ ensureFile(
292
+ "src/diviswap/client.ts",
293
+ getTemplate("vue3/client", { features })
294
+ );
295
+ ensureFile(
296
+ "src/views/DiviswapExample.vue",
297
+ getTemplate("vue3/example", { features })
298
+ );
299
+ ensureFile(
300
+ "src/diviswap/types.ts",
301
+ getTemplate("vue3/types", { features })
302
+ );
303
+ }
304
+ async function generateVanillaFiles(ensureFile, features) {
305
+ ensureFile(
306
+ "diviswap/client.js",
307
+ getTemplate("vanilla/client", { features })
308
+ );
309
+ ensureFile(
310
+ "diviswap/example.html",
311
+ getTemplate("vanilla/example-html", { features })
312
+ );
313
+ ensureFile(
314
+ "diviswap/example.js",
315
+ getTemplate("vanilla/example-js", { features })
316
+ );
317
+ ensureFile(
318
+ "diviswap/styles.css",
319
+ getTemplate("vanilla/styles", { features })
320
+ );
321
+ }
322
+ async function generateWebhookFiles(ensureFile, framework, projectRoot) {
323
+ if (framework.includes("nextjs")) {
324
+ const useSrc = projectRoot ? detectNextjsSrcDir(projectRoot) : false;
325
+ const prefix = useSrc ? "src/" : "";
326
+ ensureFile(
327
+ framework === "nextjs-app" ? `${prefix}app/api/webhooks/diviswap/route.ts` : `${prefix}pages/api/webhooks/diviswap.ts`,
328
+ getTemplate("webhooks/nextjs", { framework })
329
+ );
330
+ } else {
331
+ ensureFile(
332
+ "server/webhooks/diviswap.js",
333
+ getTemplate("webhooks/generic", {})
334
+ );
335
+ }
336
+ }
337
+ async function validatePartnerCredentials(keyId, secretKey, authMethod = "hmac", environment = "sandbox") {
338
+ try {
339
+ const apiUrl = environment === "sandbox" ? "https://dev-api.diviswap.io" : "https://api.diviswap.io";
340
+ const testPath = "/api/v1/fees";
341
+ const method = "GET";
342
+ const body = "";
343
+ let headers = {
344
+ "Content-Type": "application/json",
345
+ "X-Client-Id": keyId
346
+ };
347
+ if (authMethod === "hmac") {
348
+ const hmacHeaders = generateHMACHeaders(method, testPath, "", body, keyId, secretKey);
349
+ headers = { ...headers, ...hmacHeaders };
350
+ } else {
351
+ const jwt = generateJWT(keyId, secretKey);
352
+ headers["Authorization"] = `Bearer ${jwt}`;
353
+ }
354
+ const controller = new AbortController();
355
+ const timeoutId = setTimeout(() => controller.abort(), 1e4);
356
+ const response = await fetch(`${apiUrl}${testPath}`, {
357
+ method,
358
+ headers,
359
+ signal: controller.signal
360
+ });
361
+ clearTimeout(timeoutId);
362
+ if (response.status === 200 || response.status === 403) {
363
+ return {
364
+ valid: true,
365
+ message: `Partner credentials validated successfully (${authMethod.toUpperCase()})`
366
+ };
367
+ } else if (response.status === 401) {
368
+ return {
369
+ valid: false,
370
+ message: `Invalid partner credentials. Please check your Key ID and Secret Key.`
371
+ };
372
+ } else if (response.status === 404) {
373
+ return {
374
+ valid: false,
375
+ message: `Invalid environment. The ${environment} API endpoint was not found.`
376
+ };
377
+ }
378
+ return {
379
+ valid: true,
380
+ message: `Warning: Could not fully validate partner credentials (status: ${response.status}). Proceeding anyway...`
381
+ };
382
+ } catch (error) {
383
+ const errorMessage = error instanceof Error ? error.message : "Unknown error";
384
+ return {
385
+ valid: true,
386
+ message: `Warning: Could not connect to ${environment} API (${errorMessage}). Proceeding anyway...`
387
+ };
388
+ }
389
+ }
390
+ function generateHMACHeaders(method, path, queryString, body, keyId, secretKey) {
391
+ const timestamp = Math.floor(Date.now() / 1e3);
392
+ const nonce = crypto__default.default.randomBytes(32).toString("base64url");
393
+ const bodyHash = crypto__default.default.createHash("sha256").update(body).digest("hex");
394
+ const canonical = `${method}
395
+ ${path}
396
+ ${queryString}
397
+ ${bodyHash}
398
+ ${timestamp}
399
+ ${nonce}`;
400
+ const signature = crypto__default.default.createHmac("sha256", secretKey).update(canonical).digest("base64");
401
+ return {
402
+ "Authorization": `HMAC ${keyId}:${signature}:${timestamp}:${nonce}`
403
+ };
404
+ }
405
+ function generateJWT(keyId, secretKey, expiresIn = 300) {
406
+ const header = { alg: "HS256", typ: "JWT" };
407
+ const now = Math.floor(Date.now() / 1e3);
408
+ const payload = {
409
+ iss: keyId,
410
+ aud: "api.diviswap.io",
411
+ exp: now + Math.min(expiresIn, 300),
412
+ iat: now
413
+ };
414
+ const encodedHeader = Buffer.from(JSON.stringify(header)).toString("base64url");
415
+ const encodedPayload = Buffer.from(JSON.stringify(payload)).toString("base64url");
416
+ const signature = crypto__default.default.createHmac("sha256", secretKey).update(`${encodedHeader}.${encodedPayload}`).digest("base64url");
417
+ return `${encodedHeader}.${encodedPayload}.${signature}`;
418
+ }
419
+ var frameworkFiles = {
420
+ "nextjs-app": [
421
+ "app/api/diviswap/route.ts",
422
+ "app/diviswap/provider.tsx",
423
+ "app/diviswap/client.ts",
424
+ "app/diviswap/page.tsx",
425
+ "app/diviswap/layout.tsx",
426
+ "app/diviswap/hooks.ts",
427
+ "app/diviswap/types.ts",
428
+ "app/diviswap/actions.ts"
429
+ ],
430
+ "nextjs-pages": [
431
+ "pages/api/diviswap/auth.ts",
432
+ "pages/api/diviswap/transactions.ts",
433
+ "lib/diviswap/provider.tsx",
434
+ "pages/diviswap.tsx",
435
+ "lib/diviswap/hooks.ts",
436
+ "lib/diviswap/client.ts"
437
+ ],
438
+ "react": [
439
+ "src/diviswap/provider.tsx",
440
+ "src/diviswap/hooks.ts",
441
+ "src/diviswap/client.ts",
442
+ "src/diviswap/components/TransactionButton.tsx",
443
+ "src/diviswap/components/PayeeSelector.tsx",
444
+ "src/diviswap/example.tsx",
445
+ "src/diviswap/types.ts"
446
+ ],
447
+ "vue3": [
448
+ "src/plugins/diviswap.ts",
449
+ "src/composables/useDiviswap.ts",
450
+ "src/components/DiviswapProvider.vue",
451
+ "src/components/TransactionButton.vue",
452
+ "src/diviswap/client.ts",
453
+ "src/views/DiviswapExample.vue",
454
+ "src/diviswap/types.ts"
455
+ ],
456
+ "vanilla": [
457
+ "diviswap/client.js",
458
+ "diviswap/example.html",
459
+ "diviswap/example.js",
460
+ "diviswap/styles.css"
461
+ ]
462
+ };
463
+ async function checkExistingFiles(framework, projectRoot) {
464
+ const files = frameworkFiles[framework] || [];
465
+ const existingFiles = [];
466
+ for (const file of files) {
467
+ const fullPath = path.join(projectRoot, file);
468
+ if (fs.existsSync(fullPath)) {
469
+ existingFiles.push(file);
470
+ }
471
+ }
472
+ return existingFiles;
473
+ }
474
+ function updateNextConfig(projectRoot) {
475
+ const configFiles = ["next.config.ts", "next.config.js", "next.config.mjs"];
476
+ let configPath = null;
477
+ for (const file of configFiles) {
478
+ const fullPath = path.join(projectRoot, file);
479
+ if (fs.existsSync(fullPath)) {
480
+ configPath = fullPath;
481
+ break;
482
+ }
483
+ }
484
+ if (!configPath) {
485
+ return false;
486
+ }
487
+ try {
488
+ const content = fs.readFileSync(configPath, "utf-8");
489
+ if (content.includes("DIVISWAP_API_KEY")) {
490
+ return true;
491
+ }
492
+ const diviswapEnvVars = `
493
+ DIVISWAP_API_KEY: process.env.DIVISWAP_API_KEY,
494
+ DIVISWAP_CLIENT_ID: process.env.DIVISWAP_CLIENT_ID,
495
+ NEXT_PUBLIC_DIVISWAP_ENV: process.env.NEXT_PUBLIC_DIVISWAP_ENV,`;
496
+ let updatedContent;
497
+ if (content.includes("env:")) {
498
+ updatedContent = content.replace(
499
+ /env:\s*{([^}]*)}/,
500
+ (match, existingVars) => {
501
+ const needsComma = existingVars.trim().length > 0 && !existingVars.trim().endsWith(",");
502
+ return `env: {${existingVars}${needsComma ? "," : ""}${diviswapEnvVars}
503
+ }`;
504
+ }
505
+ );
506
+ } else {
507
+ if (content.includes("nextConfig")) {
508
+ updatedContent = content.replace(
509
+ /const nextConfig[^{]*{/,
510
+ (match) => `${match}
511
+ env: {${diviswapEnvVars}
512
+ },`
513
+ );
514
+ } else if (content.includes("module.exports")) {
515
+ updatedContent = content.replace(
516
+ /module\.exports\s*=\s*{/,
517
+ (match) => `${match}
518
+ env: {${diviswapEnvVars}
519
+ },`
520
+ );
521
+ } else {
522
+ return false;
523
+ }
524
+ }
525
+ if (updatedContent !== content) {
526
+ fs.writeFileSync(configPath, updatedContent);
527
+ return true;
528
+ }
529
+ return false;
530
+ } catch (error) {
531
+ console.error("Failed to update Next.js config:", error);
532
+ return false;
533
+ }
534
+ }
535
+
536
+ // src/cli/commands/init-v2.ts
537
+ async function init(options) {
538
+ console.log(kleur__default.default.blue().bold("\n\u{1F680} Welcome to Diviswap SDK Setup\n"));
539
+ try {
540
+ let framework = options.framework;
541
+ if (!framework) {
542
+ const detected = await detectFramework();
543
+ if (detected) {
544
+ const response2 = await prompts__default.default({
545
+ type: "confirm",
546
+ name: "confirmFramework",
547
+ message: `Detected ${kleur__default.default.cyan(detected)} project. Is this correct?`,
548
+ initial: true
549
+ });
550
+ if (response2.confirmFramework) {
551
+ framework = detected;
552
+ }
553
+ }
554
+ if (!framework) {
555
+ const response2 = await prompts__default.default({
556
+ type: "select",
557
+ name: "selectedFramework",
558
+ message: "What framework are you using?",
559
+ choices: [
560
+ { title: "Next.js (App Router)", value: "nextjs-app" },
561
+ { title: "Next.js (Pages Router)", value: "nextjs-pages" },
562
+ { title: "React", value: "react" },
563
+ { title: "Vue 3", value: "vue3" },
564
+ { title: "Vanilla JavaScript", value: "vanilla" },
565
+ { title: "Other (manual setup)", value: "other" }
566
+ ]
567
+ });
568
+ framework = response2.selectedFramework;
569
+ }
570
+ }
571
+ let environment = options.env || "sandbox";
572
+ if (!options.skipEnv && !options.env) {
573
+ const envResponse = await prompts__default.default({
574
+ type: "select",
575
+ name: "environment",
576
+ message: "Which environment are you using?",
577
+ choices: [
578
+ { title: "Production", value: "production", description: "Live environment for real transactions" },
579
+ { title: "Sandbox", value: "sandbox", description: "Testing environment with mock data" }
580
+ ],
581
+ initial: 1
582
+ // Default to sandbox for safety
583
+ });
584
+ environment = envResponse.environment || "sandbox";
585
+ }
586
+ let keyId;
587
+ let secretKey;
588
+ let authMethod = "hmac";
589
+ if (!options.skipEnv) {
590
+ console.log(kleur__default.default.yellow("\n\u{1F4DD} Partner Authentication Credentials\n"));
591
+ console.log("Partner credentials are provided by Diviswap after approval.");
592
+ console.log("Contact Diviswap support if you need partner access.");
593
+ const authMethodResponse = await prompts__default.default({
594
+ type: "select",
595
+ name: "authMethod",
596
+ message: "Which authentication method do you want to use?",
597
+ choices: [
598
+ {
599
+ title: "HMAC (Recommended)",
600
+ value: "hmac",
601
+ description: "Request signing with HMAC-SHA256 - highest security"
602
+ },
603
+ {
604
+ title: "JWT",
605
+ value: "jwt",
606
+ description: "JSON Web Tokens - easier for some integrations"
607
+ }
608
+ ],
609
+ initial: 0
610
+ });
611
+ authMethod = authMethodResponse.authMethod || "hmac";
612
+ const partnerCredentials = await prompts__default.default([
613
+ {
614
+ type: "password",
615
+ name: "keyId",
616
+ message: "Enter your Partner Key ID (pk_...):",
617
+ validate: (input) => {
618
+ if (!input || input.trim().length === 0) {
619
+ return "Partner Key ID is required";
620
+ }
621
+ if (!input.startsWith("pk_")) {
622
+ return 'Partner Key ID should start with "pk_"';
623
+ }
624
+ return true;
625
+ }
626
+ },
627
+ {
628
+ type: "password",
629
+ name: "secretKey",
630
+ message: "Enter your Partner Secret Key (sk_...):",
631
+ validate: (input) => {
632
+ if (!input || input.trim().length === 0) {
633
+ return "Partner Secret Key is required";
634
+ }
635
+ if (!input.startsWith("sk_")) {
636
+ return 'Partner Secret Key should start with "sk_"';
637
+ }
638
+ return true;
639
+ }
640
+ }
641
+ ]);
642
+ keyId = partnerCredentials.keyId;
643
+ secretKey = partnerCredentials.secretKey;
644
+ console.log(`
645
+ Validating partner credentials with ${environment} API...`);
646
+ const validation = await validatePartnerCredentials(keyId, secretKey, authMethod, environment);
647
+ if (validation.valid) {
648
+ console.log(kleur__default.default.green(`\u2705 ${validation.message}`));
649
+ } else {
650
+ console.log(kleur__default.default.red(`\u274C ${validation.message}`));
651
+ const continueResponse = await prompts__default.default({
652
+ type: "confirm",
653
+ name: "continue",
654
+ message: "Do you want to continue with these credentials anyway?",
655
+ initial: false
656
+ });
657
+ if (!continueResponse.continue) {
658
+ console.log(kleur__default.default.yellow("\nAborted. Please check your partner credentials and try again."));
659
+ process.exit(1);
660
+ }
661
+ }
662
+ if (validation.valid && validation.message?.includes("Warning")) {
663
+ console.log(kleur__default.default.yellow(validation.message));
664
+ }
665
+ }
666
+ console.log(kleur__default.default.yellow("\n\u{1F4CB} Select features to include\n"));
667
+ const response = await prompts__default.default({
668
+ type: "multiselect",
669
+ name: "features",
670
+ message: "Select features to include:",
671
+ choices: [
672
+ { title: "On-ramp (Crypto purchases)", value: "onramp", selected: true },
673
+ { title: "Off-ramp (Crypto withdrawals)", value: "offramp", selected: true },
674
+ { title: "Integrator Fees", value: "fees", selected: true },
675
+ { title: "Webhook Support", value: "webhooks", selected: false },
676
+ { title: "Real-time Updates (WebSocket)", value: "realtime", selected: false },
677
+ { title: "Example Page (Demo implementation)", value: "example", selected: false }
678
+ ],
679
+ hint: "- Space to select. Return to submit",
680
+ instructions: false
681
+ });
682
+ const features = response.features || ["onramp", "offramp", "fees"];
683
+ if (!response.features) {
684
+ console.log(kleur__default.default.yellow("\nNo features selected, using defaults: onramp, offramp, fees"));
685
+ }
686
+ if (!options.force) {
687
+ const existingFiles = await checkExistingFiles(framework, process.cwd());
688
+ if (existingFiles.length > 0) {
689
+ console.log(kleur__default.default.yellow("\n\u26A0\uFE0F The following files already exist:\n"));
690
+ existingFiles.forEach((file) => console.log(kleur__default.default.gray(` - ${file}`)));
691
+ const response2 = await prompts__default.default({
692
+ type: "confirm",
693
+ name: "confirmOverwrite",
694
+ message: "Do you want to overwrite these files?",
695
+ initial: false
696
+ });
697
+ if (!response2.confirmOverwrite) {
698
+ console.log(kleur__default.default.yellow("\nAborted. No files were modified."));
699
+ process.exit(0);
700
+ }
701
+ }
702
+ }
703
+ console.log(kleur__default.default.blue("\n\u{1F4C1} Generating files...\n"));
704
+ const generatedFiles = await generateFiles({
705
+ framework,
706
+ features,
707
+ projectRoot: process.cwd()
708
+ });
709
+ if (!options.skipEnv && keyId && secretKey) {
710
+ const envFile = framework.includes("nextjs") ? ".env.local" : ".env";
711
+ const envPath = path.join(process.cwd(), envFile);
712
+ let envContent = "";
713
+ if (fs.existsSync(envPath)) {
714
+ envContent = fs.readFileSync(envPath, "utf-8");
715
+ }
716
+ const envVars = [
717
+ `DIVISWAP_PARTNER_KEY_ID=${keyId}`,
718
+ `DIVISWAP_PARTNER_SECRET_KEY=${secretKey}`,
719
+ `NEXT_PUBLIC_DIVISWAP_ENV=${environment}`
720
+ ];
721
+ const newEnvVars = envVars.filter((envVar) => {
722
+ const key = envVar.split("=")[0];
723
+ return !envContent.includes(key);
724
+ });
725
+ if (newEnvVars.length > 0) {
726
+ const separator = envContent && !envContent.endsWith("\n") ? "\n" : "";
727
+ fs.appendFileSync(envPath, separator + "# Diviswap SDK Configuration (Partner Authentication)\n" + newEnvVars.join("\n") + "\n");
728
+ console.log(kleur__default.default.green(`\u2705 Updated ${envFile} with partner authentication credentials`));
729
+ }
730
+ }
731
+ if (framework.includes("nextjs")) {
732
+ console.log("\nUpdating Next.js configuration...");
733
+ const configUpdated = updateNextConfig(process.cwd());
734
+ if (configUpdated) {
735
+ console.log(kleur__default.default.green("\u2705 Updated next.config with Diviswap environment variables"));
736
+ }
737
+ }
738
+ if (!options.skipInstall) {
739
+ console.log("Installing dependencies...");
740
+ try {
741
+ const packageManager = fs.existsSync(path.join(process.cwd(), "yarn.lock")) ? "yarn" : fs.existsSync(path.join(process.cwd(), "pnpm-lock.yaml")) ? "pnpm" : "npm";
742
+ const deps = ["@diviswap/sdk"];
743
+ if (features.includes("realtime")) {
744
+ deps.push("socket.io-client");
745
+ }
746
+ child_process.execSync(`${packageManager} ${packageManager === "npm" ? "install" : "add"} ${deps.join(" ")}`, {
747
+ stdio: "inherit"
748
+ });
749
+ console.log(kleur__default.default.green("\u2705 Dependencies installed successfully!"));
750
+ } catch (error) {
751
+ console.log(kleur__default.default.red("\u274C Failed to install dependencies. Please run npm/yarn/pnpm install manually."));
752
+ }
753
+ }
754
+ console.log(kleur__default.default.green().bold("\n\u2728 Diviswap SDK setup complete!\n"));
755
+ console.log("Generated files:");
756
+ generatedFiles.forEach((file) => {
757
+ console.log(kleur__default.default.gray(` - ${file}`));
758
+ });
759
+ console.log(kleur__default.default.cyan("\n\u{1F4D6} Next steps:\n"));
760
+ if (framework.includes("nextjs")) {
761
+ console.log("1. Add DiviswapClientProvider to your providers:");
762
+ console.log(kleur__default.default.gray(" // app/providers.tsx or app/layout.tsx"));
763
+ console.log(kleur__default.default.gray(' import { DiviswapClientProvider } from "./components/diviswap-provider"'));
764
+ console.log(kleur__default.default.gray(" "));
765
+ console.log(kleur__default.default.gray(" // In your providers chain:"));
766
+ console.log(kleur__default.default.gray(" <DiviswapClientProvider>"));
767
+ console.log(kleur__default.default.gray(" {children}"));
768
+ console.log(kleur__default.default.gray(" </DiviswapClientProvider>"));
769
+ console.log("\n2. Start your development server:");
770
+ console.log(kleur__default.default.gray(" npm run dev"));
771
+ if (features.includes("example")) {
772
+ console.log("\n3. Visit the example page:");
773
+ console.log(kleur__default.default.gray(" http://localhost:3000/diviswap"));
774
+ } else {
775
+ console.log("\n3. Use the Diviswap hooks in your components:");
776
+ console.log(kleur__default.default.gray(' import { useDiviswap } from "@diviswap/sdk/react"'));
777
+ }
778
+ } else if (framework === "react") {
779
+ console.log("1. Import and use the Diviswap provider:");
780
+ console.log(kleur__default.default.gray(' import { DiviswapProvider } from "@diviswap/sdk/react"'));
781
+ console.log("\n2. Wrap your app with the provider:");
782
+ console.log(kleur__default.default.gray(" <DiviswapProvider><App /></DiviswapProvider>"));
783
+ console.log("\n3. Use the hooks in your components:");
784
+ console.log(kleur__default.default.gray(' import { useDiviswap } from "@diviswap/sdk/react"'));
785
+ }
786
+ console.log("\n\u{1F4DA} Documentation: https://docs.diviswap.io");
787
+ console.log("\u{1F4AC} Support: support@diviswap.io\n");
788
+ } catch (error) {
789
+ console.error(kleur__default.default.red("\n\u274C Setup failed:"), error instanceof Error ? error.message : error);
790
+ process.exit(1);
791
+ }
792
+ }
793
+ async function createApp(projectName, options) {
794
+ console.log(kleur__default.default.blue().bold("\n\u{1F680} Create Diviswap-Powered App\n"));
795
+ if (!projectName) {
796
+ const response = await prompts__default.default({
797
+ type: "text",
798
+ name: "name",
799
+ message: "What is your project name?",
800
+ initial: "diviswap-app",
801
+ validate: (input) => {
802
+ if (/^(?:@[a-z0-9-*~][a-z0-9-*._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/.test(input)) {
803
+ return true;
804
+ }
805
+ return "Project name must be a valid npm package name";
806
+ }
807
+ });
808
+ projectName = response.name;
809
+ }
810
+ const projectPath = path.join(process.cwd(), projectName);
811
+ if (fs.existsSync(projectPath)) {
812
+ const response = await prompts__default.default({
813
+ type: "confirm",
814
+ name: "overwrite",
815
+ message: `Directory ${projectName} already exists. Overwrite?`,
816
+ initial: false
817
+ });
818
+ if (!response.overwrite) {
819
+ console.log(kleur__default.default.yellow("Aborted."));
820
+ process.exit(1);
821
+ }
822
+ }
823
+ let packageManager = "npm";
824
+ if (options.useYarn) packageManager = "yarn";
825
+ else if (options.usePnpm) packageManager = "pnpm";
826
+ else if (!options.useNpm) {
827
+ if (fs.existsSync(path.join(process.cwd(), "yarn.lock"))) packageManager = "yarn";
828
+ else if (fs.existsSync(path.join(process.cwd(), "pnpm-lock.yaml"))) packageManager = "pnpm";
829
+ }
830
+ let template = options.template || "nextjs";
831
+ if (!["nextjs", "react", "vue"].includes(template)) {
832
+ const response = await prompts__default.default({
833
+ type: "select",
834
+ name: "selectedTemplate",
835
+ message: "Select a project template:",
836
+ choices: [
837
+ { title: "Next.js (Full-stack React framework)", value: "nextjs" },
838
+ { title: "React (Single-page application)", value: "react" },
839
+ { title: "Vue 3 (Progressive framework)", value: "vue" }
840
+ ]
841
+ });
842
+ template = response.selectedTemplate;
843
+ }
844
+ const useTypeScript = !options.javascript;
845
+ console.log(kleur__default.default.cyan("\n\u{1F4CB} Project Configuration:"));
846
+ console.log(` Name: ${kleur__default.default.white(projectName)}`);
847
+ console.log(` Template: ${kleur__default.default.white(template)}`);
848
+ console.log(` TypeScript: ${kleur__default.default.white(useTypeScript ? "Yes" : "No")}`);
849
+ console.log(` Package Manager: ${kleur__default.default.white(packageManager)}`);
850
+ console.log(` Directory: ${kleur__default.default.white(projectPath)}`);
851
+ console.log();
852
+ console.log("Creating project...");
853
+ try {
854
+ fs.mkdirSync(projectPath, { recursive: true });
855
+ process.chdir(projectPath);
856
+ switch (template) {
857
+ case "nextjs":
858
+ await createNextJsProject(projectPath, {
859
+ ...options,
860
+ typescript: useTypeScript,
861
+ packageManager
862
+ });
863
+ break;
864
+ case "react":
865
+ await createReactProject(projectPath, {
866
+ ...options,
867
+ typescript: useTypeScript,
868
+ packageManager
869
+ });
870
+ break;
871
+ case "vue":
872
+ await createVueProject(projectPath, {
873
+ ...options,
874
+ typescript: useTypeScript,
875
+ packageManager
876
+ });
877
+ break;
878
+ }
879
+ console.log(kleur__default.default.green("\u2705 Project created successfully!"));
880
+ console.log(kleur__default.default.blue("\n\u{1F527} Setting up Diviswap SDK...\n"));
881
+ const frameworkMap = {
882
+ "nextjs": options.app ? "nextjs-app" : "nextjs-pages",
883
+ "react": "react",
884
+ "vue": "vue3"
885
+ };
886
+ await init({
887
+ framework: frameworkMap[template],
888
+ skipInstall: false,
889
+ skipEnv: false
890
+ });
891
+ console.log(kleur__default.default.green().bold("\n\u2728 Your Diviswap-powered app is ready!\n"));
892
+ console.log("Next steps:");
893
+ console.log(kleur__default.default.gray(` cd ${projectName}`));
894
+ console.log(kleur__default.default.gray(` ${packageManager} ${packageManager === "npm" ? "run dev" : "dev"}`));
895
+ console.log();
896
+ console.log("Visit your app at:");
897
+ console.log(kleur__default.default.cyan(" http://localhost:3000"));
898
+ if (template === "nextjs" || template === "react") {
899
+ console.log();
900
+ console.log("Diviswap integration available at:");
901
+ console.log(kleur__default.default.cyan(" http://localhost:3000/diviswap"));
902
+ }
903
+ console.log();
904
+ } catch (error) {
905
+ console.log(kleur__default.default.red("\u274C Failed to create project"));
906
+ console.error(kleur__default.default.red("Error:"), error);
907
+ process.exit(1);
908
+ }
909
+ }
910
+ async function createNextJsProject(projectPath, options) {
911
+ const { typescript, packageManager, eslint, tailwind, app, srcDir, importAlias } = options;
912
+ const packageJson = {
913
+ name: path.basename(projectPath),
914
+ version: "0.1.0",
915
+ private: true,
916
+ scripts: {
917
+ dev: "next dev",
918
+ build: "next build",
919
+ start: "next start",
920
+ lint: "next lint"
921
+ },
922
+ dependencies: {
923
+ "react": "^18.2.0",
924
+ "react-dom": "^18.2.0",
925
+ "next": "^14.0.0",
926
+ "@diviswap/sdk": "latest"
927
+ },
928
+ devDependencies: typescript ? {
929
+ "@types/node": "^20.0.0",
930
+ "@types/react": "^18.2.0",
931
+ "@types/react-dom": "^18.2.0",
932
+ "typescript": "^5.0.0"
933
+ } : {}
934
+ };
935
+ if (eslint) {
936
+ packageJson.devDependencies = {
937
+ ...packageJson.devDependencies,
938
+ "eslint": "^8.0.0",
939
+ "eslint-config-next": "^14.0.0"
940
+ };
941
+ }
942
+ if (tailwind) {
943
+ packageJson.devDependencies = {
944
+ ...packageJson.devDependencies,
945
+ "tailwindcss": "^3.3.0",
946
+ "postcss": "^8.4.0",
947
+ "autoprefixer": "^10.4.0"
948
+ };
949
+ }
950
+ fs.writeFileSync("package.json", JSON.stringify(packageJson, null, 2));
951
+ if (typescript) {
952
+ const tsConfig = {
953
+ compilerOptions: {
954
+ target: "es5",
955
+ lib: ["dom", "dom.iterable", "esnext"],
956
+ allowJs: true,
957
+ skipLibCheck: true,
958
+ strict: true,
959
+ forceConsistentCasingInFileNames: true,
960
+ noEmit: true,
961
+ esModuleInterop: true,
962
+ module: "esnext",
963
+ moduleResolution: "bundler",
964
+ resolveJsonModule: true,
965
+ isolatedModules: true,
966
+ jsx: "preserve",
967
+ incremental: true,
968
+ paths: importAlias ? {
969
+ [importAlias.replace("/*", "/*")]: [`./${srcDir ? "src/" : ""}*`]
970
+ } : {}
971
+ },
972
+ include: ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
973
+ exclude: ["node_modules"]
974
+ };
975
+ fs.writeFileSync("tsconfig.json", JSON.stringify(tsConfig, null, 2));
976
+ }
977
+ const nextConfig = `/** @type {import('next').NextConfig} */
978
+ const nextConfig = {
979
+ reactStrictMode: true,
980
+ }
981
+
982
+ module.exports = nextConfig
983
+ `;
984
+ fs.writeFileSync("next.config.js", nextConfig);
985
+ if (app) {
986
+ fs.mkdirSync(srcDir ? "src/app" : "app", { recursive: true });
987
+ const layoutContent = `${typescript ? "import type { Metadata } from 'next'\n" : ""}import './globals.css'
988
+
989
+ ${typescript ? "export const metadata: Metadata" : "export const metadata"} = {
990
+ title: 'Diviswap App',
991
+ description: 'Built with Diviswap SDK',
992
+ }
993
+
994
+ export default function RootLayout({
995
+ children,
996
+ }${typescript ? ": { children: React.ReactNode }" : ""}) {
997
+ return (
998
+ <html lang="en">
999
+ <body>{children}</body>
1000
+ </html>
1001
+ )
1002
+ }`;
1003
+ fs.writeFileSync(srcDir ? "src/app/layout.tsx" : "app/layout.tsx", layoutContent);
1004
+ const pageContent = `export default function Home() {
1005
+ return (
1006
+ <main className="flex min-h-screen flex-col items-center justify-center p-24">
1007
+ <h1 className="text-4xl font-bold mb-8">Welcome to Diviswap</h1>
1008
+ <p className="text-xl mb-8">Your crypto rails integration is ready!</p>
1009
+ <a
1010
+ href="/diviswap"
1011
+ className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
1012
+ >
1013
+ Go to Diviswap Dashboard
1014
+ </a>
1015
+ </main>
1016
+ )
1017
+ }`;
1018
+ fs.writeFileSync(srcDir ? "src/app/page.tsx" : "app/page.tsx", pageContent);
1019
+ const globalsContent2 = tailwind ? `@tailwind base;
1020
+ @tailwind components;
1021
+ @tailwind utilities;` : `html, body {
1022
+ padding: 0;
1023
+ margin: 0;
1024
+ font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
1025
+ Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
1026
+ }
1027
+
1028
+ * {
1029
+ box-sizing: border-box;
1030
+ }`;
1031
+ fs.writeFileSync(srcDir ? "src/app/globals.css" : "app/globals.css", globalsContent2);
1032
+ } else {
1033
+ fs.mkdirSync(srcDir ? "src/pages" : "pages", { recursive: true });
1034
+ fs.mkdirSync(srcDir ? "src/styles" : "styles", { recursive: true });
1035
+ const appContent = `${typescript ? "import type { AppProps } from 'next/app'\n" : ""}import '../styles/globals.css'
1036
+
1037
+ export default function App(${typescript ? "{ Component, pageProps }: AppProps" : "{ Component, pageProps }"}) {
1038
+ return <Component {...pageProps} />
1039
+ }`;
1040
+ fs.writeFileSync(srcDir ? "src/pages/_app.tsx" : "pages/_app.tsx", appContent);
1041
+ const indexContent = `export default function Home() {
1042
+ return (
1043
+ <main className="flex min-h-screen flex-col items-center justify-center p-24">
1044
+ <h1 className="text-4xl font-bold mb-8">Welcome to Diviswap</h1>
1045
+ <p className="text-xl mb-8">Your crypto rails integration is ready!</p>
1046
+ <a
1047
+ href="/diviswap"
1048
+ className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
1049
+ >
1050
+ Go to Diviswap Dashboard
1051
+ </a>
1052
+ </main>
1053
+ )
1054
+ }`;
1055
+ fs.writeFileSync(srcDir ? "src/pages/index.tsx" : "pages/index.tsx", indexContent);
1056
+ fs.writeFileSync(srcDir ? "src/styles/globals.css" : "styles/globals.css", globalsContent);
1057
+ }
1058
+ if (tailwind) {
1059
+ const tailwindConfig = `/** @type {import('tailwindcss').Config} */
1060
+ module.exports = {
1061
+ content: [
1062
+ './${srcDir ? "src/" : ""}{pages,app,components}/**/*.{js,ts,jsx,tsx,mdx}',
1063
+ ],
1064
+ theme: {
1065
+ extend: {},
1066
+ },
1067
+ plugins: [],
1068
+ }`;
1069
+ fs.writeFileSync("tailwind.config.js", tailwindConfig);
1070
+ const postcssConfig = `module.exports = {
1071
+ plugins: {
1072
+ tailwindcss: {},
1073
+ autoprefixer: {},
1074
+ },
1075
+ }`;
1076
+ fs.writeFileSync("postcss.config.js", postcssConfig);
1077
+ }
1078
+ const gitignore = `# dependencies
1079
+ /node_modules
1080
+ /.pnp
1081
+ .pnp.js
1082
+
1083
+ # testing
1084
+ /coverage
1085
+
1086
+ # next.js
1087
+ /.next/
1088
+ /out/
1089
+
1090
+ # production
1091
+ /build
1092
+
1093
+ # misc
1094
+ .DS_Store
1095
+ *.pem
1096
+
1097
+ # debug
1098
+ npm-debug.log*
1099
+ yarn-debug.log*
1100
+ yarn-error.log*
1101
+
1102
+ # local env files
1103
+ .env*.local
1104
+
1105
+ # vercel
1106
+ .vercel
1107
+
1108
+ # typescript
1109
+ *.tsbuildinfo
1110
+ next-env.d.ts`;
1111
+ fs.writeFileSync(".gitignore", gitignore);
1112
+ const readme = `# ${path.basename(projectPath)}
1113
+
1114
+ A Next.js application powered by Diviswap SDK for seamless crypto rails integration.
1115
+
1116
+ ## Getting Started
1117
+
1118
+ First, run the development server:
1119
+
1120
+ \`\`\`bash
1121
+ ${packageManager} ${packageManager === "npm" ? "run dev" : "dev"}
1122
+ \`\`\`
1123
+
1124
+ Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
1125
+
1126
+ ## Diviswap Integration
1127
+
1128
+ The Diviswap SDK has been pre-configured in this project. Visit [http://localhost:3000/diviswap](http://localhost:3000/diviswap) to see the integration in action.
1129
+
1130
+ ### Features
1131
+
1132
+ - \u2705 On-ramp (Buy crypto with fiat)
1133
+ - \u2705 Off-ramp (Sell crypto for fiat)
1134
+ - \u2705 Payee management
1135
+ - \u2705 Transaction history
1136
+ - \u2705 Real-time updates
1137
+
1138
+ ## Learn More
1139
+
1140
+ - [Diviswap Documentation](https://docs.diviswap.io)
1141
+ - [Next.js Documentation](https://nextjs.org/docs)
1142
+
1143
+ ## Deploy on Vercel
1144
+
1145
+ The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com).`;
1146
+ fs.writeFileSync("README.md", readme);
1147
+ console.log(kleur__default.default.cyan("\n\u{1F4E6} Installing dependencies...\n"));
1148
+ child_process.execSync(`${packageManager} install`, { stdio: "inherit" });
1149
+ }
1150
+ async function createReactProject(projectPath, options) {
1151
+ const { typescript, packageManager, eslint, tailwind } = options;
1152
+ const packageJson = {
1153
+ name: path.basename(projectPath),
1154
+ version: "0.1.0",
1155
+ private: true,
1156
+ dependencies: {
1157
+ "react": "^18.2.0",
1158
+ "react-dom": "^18.2.0",
1159
+ "react-router-dom": "^6.20.0",
1160
+ "@diviswap/sdk": "latest"
1161
+ },
1162
+ devDependencies: {
1163
+ "@vitejs/plugin-react": "^4.2.0",
1164
+ "vite": "^5.0.0"
1165
+ },
1166
+ scripts: {
1167
+ dev: "vite",
1168
+ build: "vite build",
1169
+ preview: "vite preview",
1170
+ lint: eslint ? "eslint . --ext .js,.jsx,.ts,.tsx" : 'echo "No linting configured"'
1171
+ }
1172
+ };
1173
+ if (typescript) {
1174
+ packageJson.devDependencies = {
1175
+ ...packageJson.devDependencies,
1176
+ "@types/react": "^18.2.0",
1177
+ "@types/react-dom": "^18.2.0",
1178
+ "typescript": "^5.0.0"
1179
+ };
1180
+ }
1181
+ if (eslint) {
1182
+ packageJson.devDependencies = {
1183
+ ...packageJson.devDependencies,
1184
+ "eslint": "^8.0.0",
1185
+ "eslint-plugin-react": "^7.33.0",
1186
+ "eslint-plugin-react-hooks": "^4.6.0"
1187
+ };
1188
+ }
1189
+ if (tailwind) {
1190
+ packageJson.devDependencies = {
1191
+ ...packageJson.devDependencies,
1192
+ "tailwindcss": "^3.3.0",
1193
+ "postcss": "^8.4.0",
1194
+ "autoprefixer": "^10.4.0"
1195
+ };
1196
+ }
1197
+ fs.writeFileSync("package.json", JSON.stringify(packageJson, null, 2));
1198
+ const viteConfig = `import { defineConfig } from 'vite'
1199
+ import react from '@vitejs/plugin-react'
1200
+
1201
+ export default defineConfig({
1202
+ plugins: [react()],
1203
+ })`;
1204
+ fs.writeFileSync(typescript ? "vite.config.ts" : "vite.config.js", viteConfig);
1205
+ if (typescript) {
1206
+ const tsConfig = {
1207
+ compilerOptions: {
1208
+ target: "ES2020",
1209
+ useDefineForClassFields: true,
1210
+ lib: ["ES2020", "DOM", "DOM.Iterable"],
1211
+ module: "ESNext",
1212
+ skipLibCheck: true,
1213
+ moduleResolution: "bundler",
1214
+ allowImportingTsExtensions: true,
1215
+ resolveJsonModule: true,
1216
+ isolatedModules: true,
1217
+ noEmit: true,
1218
+ jsx: "react-jsx",
1219
+ strict: true,
1220
+ noUnusedLocals: true,
1221
+ noUnusedParameters: true,
1222
+ noFallthroughCasesInSwitch: true
1223
+ },
1224
+ include: ["src"],
1225
+ references: [{ path: "./tsconfig.node.json" }]
1226
+ };
1227
+ fs.writeFileSync("tsconfig.json", JSON.stringify(tsConfig, null, 2));
1228
+ const tsConfigNode = {
1229
+ compilerOptions: {
1230
+ composite: true,
1231
+ skipLibCheck: true,
1232
+ module: "ESNext",
1233
+ moduleResolution: "bundler",
1234
+ allowSyntheticDefaultImports: true
1235
+ },
1236
+ include: ["vite.config.ts"]
1237
+ };
1238
+ fs.writeFileSync("tsconfig.node.json", JSON.stringify(tsConfigNode, null, 2));
1239
+ }
1240
+ fs.mkdirSync("src", { recursive: true });
1241
+ fs.mkdirSync("public", { recursive: true });
1242
+ const indexHtml = `<!doctype html>
1243
+ <html lang="en">
1244
+ <head>
1245
+ <meta charset="UTF-8" />
1246
+ <link rel="icon" type="image/svg+xml" href="/vite.svg" />
1247
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
1248
+ <title>Diviswap React App</title>
1249
+ </head>
1250
+ <body>
1251
+ <div id="root"></div>
1252
+ <script type="module" src="/src/main.${typescript ? "tsx" : "jsx"}"></script>
1253
+ </body>
1254
+ </html>`;
1255
+ fs.writeFileSync("index.html", indexHtml);
1256
+ const mainContent = `import React from 'react'
1257
+ import ReactDOM from 'react-dom/client'
1258
+ import App from './App${typescript ? "" : ".jsx"}'
1259
+ import './index.css'
1260
+
1261
+ ReactDOM.createRoot(document.getElementById('root')${typescript ? "!" : ""}).render(
1262
+ <React.StrictMode>
1263
+ <App />
1264
+ </React.StrictMode>,
1265
+ )`;
1266
+ fs.writeFileSync(`src/main.${typescript ? "tsx" : "jsx"}`, mainContent);
1267
+ const appContent = `import { BrowserRouter as Router, Routes, Route, Link } from 'react-router-dom'
1268
+
1269
+ function App() {
1270
+ return (
1271
+ <Router>
1272
+ <div className="min-h-screen bg-gray-100">
1273
+ <Routes>
1274
+ <Route path="/" element={<Home />} />
1275
+ <Route path="/diviswap/*" element={<div>Diviswap integration will be added here</div>} />
1276
+ </Routes>
1277
+ </div>
1278
+ </Router>
1279
+ )
1280
+ }
1281
+
1282
+ function Home() {
1283
+ return (
1284
+ <div className="flex min-h-screen flex-col items-center justify-center p-24">
1285
+ <h1 className="text-4xl font-bold mb-8">Welcome to Diviswap</h1>
1286
+ <p className="text-xl mb-8">Your crypto rails integration is ready!</p>
1287
+ <Link
1288
+ to="/diviswap"
1289
+ className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
1290
+ >
1291
+ Go to Diviswap Dashboard
1292
+ </Link>
1293
+ </div>
1294
+ )
1295
+ }
1296
+
1297
+ export default App`;
1298
+ fs.writeFileSync(`src/App.${typescript ? "tsx" : "jsx"}`, appContent);
1299
+ const indexCss = tailwind ? `@tailwind base;
1300
+ @tailwind components;
1301
+ @tailwind utilities;` : `:root {
1302
+ font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
1303
+ line-height: 1.5;
1304
+ font-weight: 400;
1305
+ }
1306
+
1307
+ body {
1308
+ margin: 0;
1309
+ display: flex;
1310
+ place-items: center;
1311
+ min-width: 320px;
1312
+ min-height: 100vh;
1313
+ }`;
1314
+ fs.writeFileSync("src/index.css", indexCss);
1315
+ if (tailwind) {
1316
+ const tailwindConfig = `/** @type {import('tailwindcss').Config} */
1317
+ export default {
1318
+ content: [
1319
+ "./index.html",
1320
+ "./src/**/*.{js,ts,jsx,tsx}",
1321
+ ],
1322
+ theme: {
1323
+ extend: {},
1324
+ },
1325
+ plugins: [],
1326
+ }`;
1327
+ fs.writeFileSync("tailwind.config.js", tailwindConfig);
1328
+ const postcssConfig = `export default {
1329
+ plugins: {
1330
+ tailwindcss: {},
1331
+ autoprefixer: {},
1332
+ },
1333
+ }`;
1334
+ fs.writeFileSync("postcss.config.js", postcssConfig);
1335
+ }
1336
+ const gitignore = `# Logs
1337
+ logs
1338
+ *.log
1339
+ npm-debug.log*
1340
+ yarn-debug.log*
1341
+ yarn-error.log*
1342
+ pnpm-debug.log*
1343
+ lerna-debug.log*
1344
+
1345
+ node_modules
1346
+ dist
1347
+ dist-ssr
1348
+ *.local
1349
+
1350
+ # Editor directories and files
1351
+ .vscode/*
1352
+ !.vscode/extensions.json
1353
+ .idea
1354
+ .DS_Store
1355
+ *.suo
1356
+ *.ntvs*
1357
+ *.njsproj
1358
+ *.sln
1359
+ *.sw?
1360
+
1361
+ # Env files
1362
+ .env*.local`;
1363
+ fs.writeFileSync(".gitignore", gitignore);
1364
+ const readme = `# ${path.basename(projectPath)}
1365
+
1366
+ A React application powered by Diviswap SDK for seamless crypto rails integration.
1367
+
1368
+ ## Getting Started
1369
+
1370
+ First, run the development server:
1371
+
1372
+ \`\`\`bash
1373
+ ${packageManager} ${packageManager === "npm" ? "run dev" : "dev"}
1374
+ \`\`\`
1375
+
1376
+ Open [http://localhost:5173](http://localhost:5173) with your browser to see the result.
1377
+
1378
+ ## Diviswap Integration
1379
+
1380
+ The Diviswap SDK has been pre-configured in this project. Visit [http://localhost:5173/diviswap](http://localhost:5173/diviswap) to see the integration in action.
1381
+
1382
+ ### Features
1383
+
1384
+ - \u2705 On-ramp (Buy crypto with fiat)
1385
+ - \u2705 Off-ramp (Sell crypto for fiat)
1386
+ - \u2705 Payee management
1387
+ - \u2705 Transaction history
1388
+ - \u2705 Real-time updates
1389
+
1390
+ ## Learn More
1391
+
1392
+ - [Diviswap Documentation](https://docs.diviswap.io)
1393
+ - [React Documentation](https://react.dev)
1394
+ - [Vite Documentation](https://vitejs.dev)`;
1395
+ fs.writeFileSync("README.md", readme);
1396
+ console.log(kleur__default.default.cyan("\n\u{1F4E6} Installing dependencies...\n"));
1397
+ child_process.execSync(`${packageManager} install`, { stdio: "inherit" });
1398
+ }
1399
+ async function createVueProject(projectPath, options) {
1400
+ const { typescript, packageManager, eslint, tailwind } = options;
1401
+ const packageJson = {
1402
+ name: path.basename(projectPath),
1403
+ version: "0.1.0",
1404
+ private: true,
1405
+ scripts: {
1406
+ dev: "vite",
1407
+ build: "vite build",
1408
+ preview: "vite preview",
1409
+ lint: eslint ? "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore" : 'echo "No linting configured"'
1410
+ },
1411
+ dependencies: {
1412
+ "vue": "^3.3.0",
1413
+ "vue-router": "^4.2.0",
1414
+ "@diviswap/sdk": "latest"
1415
+ },
1416
+ devDependencies: {
1417
+ "@vitejs/plugin-vue": "^4.5.0",
1418
+ "vite": "^5.0.0"
1419
+ }
1420
+ };
1421
+ if (typescript) {
1422
+ packageJson.devDependencies = {
1423
+ ...packageJson.devDependencies,
1424
+ "@vue/tsconfig": "^0.5.0",
1425
+ "typescript": "^5.0.0",
1426
+ "vue-tsc": "^1.8.0"
1427
+ };
1428
+ }
1429
+ if (eslint) {
1430
+ packageJson.devDependencies = {
1431
+ ...packageJson.devDependencies,
1432
+ "@rushstack/eslint-patch": "^1.3.0",
1433
+ "@vue/eslint-config-typescript": typescript ? "^12.0.0" : void 0,
1434
+ "eslint": "^8.0.0",
1435
+ "eslint-plugin-vue": "^9.0.0"
1436
+ };
1437
+ }
1438
+ if (tailwind) {
1439
+ packageJson.devDependencies = {
1440
+ ...packageJson.devDependencies,
1441
+ "tailwindcss": "^3.3.0",
1442
+ "postcss": "^8.4.0",
1443
+ "autoprefixer": "^10.4.0"
1444
+ };
1445
+ }
1446
+ Object.keys(packageJson.devDependencies).forEach((key) => {
1447
+ if (packageJson.devDependencies[key] === void 0) {
1448
+ delete packageJson.devDependencies[key];
1449
+ }
1450
+ });
1451
+ fs.writeFileSync("package.json", JSON.stringify(packageJson, null, 2));
1452
+ const viteConfig = `import { fileURLToPath, URL } from 'node:url'
1453
+ import { defineConfig } from 'vite'
1454
+ import vue from '@vitejs/plugin-vue'
1455
+
1456
+ export default defineConfig({
1457
+ plugins: [vue()],
1458
+ resolve: {
1459
+ alias: {
1460
+ '@': fileURLToPath(new URL('./src', import.meta.url))
1461
+ }
1462
+ }
1463
+ })`;
1464
+ fs.writeFileSync(typescript ? "vite.config.ts" : "vite.config.js", viteConfig);
1465
+ if (typescript) {
1466
+ const tsConfig = {
1467
+ extends: "@vue/tsconfig/tsconfig.dom.json",
1468
+ include: ["env.d.ts", "src/**/*", "src/**/*.vue"],
1469
+ exclude: ["src/**/__tests__/*"],
1470
+ compilerOptions: {
1471
+ composite: true,
1472
+ baseUrl: ".",
1473
+ paths: {
1474
+ "@/*": ["./src/*"]
1475
+ }
1476
+ }
1477
+ };
1478
+ fs.writeFileSync("tsconfig.json", JSON.stringify(tsConfig, null, 2));
1479
+ fs.writeFileSync("env.d.ts", '/// <reference types="vite/client" />\n');
1480
+ }
1481
+ fs.mkdirSync("src", { recursive: true });
1482
+ fs.mkdirSync("src/components", { recursive: true });
1483
+ fs.mkdirSync("src/views", { recursive: true });
1484
+ fs.mkdirSync("public", { recursive: true });
1485
+ const indexHtml = `<!DOCTYPE html>
1486
+ <html lang="en">
1487
+ <head>
1488
+ <meta charset="UTF-8">
1489
+ <link rel="icon" href="/favicon.ico">
1490
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
1491
+ <title>Diviswap Vue App</title>
1492
+ </head>
1493
+ <body>
1494
+ <div id="app"></div>
1495
+ <script type="module" src="/src/main.${typescript ? "ts" : "js"}"></script>
1496
+ </body>
1497
+ </html>`;
1498
+ fs.writeFileSync("index.html", indexHtml);
1499
+ const mainContent = `import { createApp } from 'vue'
1500
+ import App from './App.vue'
1501
+ import router from './router'
1502
+ import './style.css'
1503
+
1504
+ const app = createApp(App)
1505
+ app.use(router)
1506
+ app.mount('#app')`;
1507
+ fs.writeFileSync(`src/main.${typescript ? "ts" : "js"}`, mainContent);
1508
+ const appVue = `<template>
1509
+ <div id="app">
1510
+ <RouterView />
1511
+ </div>
1512
+ </template>
1513
+
1514
+ <script${typescript ? ' setup lang="ts"' : " setup"}>
1515
+ import { RouterView } from 'vue-router'
1516
+ </script>
1517
+
1518
+ <style scoped>
1519
+ #app {
1520
+ min-height: 100vh;
1521
+ }
1522
+ </style>`;
1523
+ fs.writeFileSync("src/App.vue", appVue);
1524
+ fs.mkdirSync("src/router", { recursive: true });
1525
+ const routerContent = `import { createRouter, createWebHistory } from 'vue-router'
1526
+ import HomeView from '../views/HomeView.vue'
1527
+
1528
+ const router = createRouter({
1529
+ history: createWebHistory(import.meta.env.BASE_URL),
1530
+ routes: [
1531
+ {
1532
+ path: '/',
1533
+ name: 'home',
1534
+ component: HomeView
1535
+ },
1536
+ {
1537
+ path: '/diviswap',
1538
+ name: 'diviswap',
1539
+ component: () => import('../views/DiviswapView.vue')
1540
+ }
1541
+ ]
1542
+ })
1543
+
1544
+ export default router`;
1545
+ fs.writeFileSync(`src/router/index.${typescript ? "ts" : "js"}`, routerContent);
1546
+ const homeView = `<template>
1547
+ <div class="flex min-h-screen flex-col items-center justify-center p-24">
1548
+ <h1 class="text-4xl font-bold mb-8">Welcome to Diviswap</h1>
1549
+ <p class="text-xl mb-8">Your crypto rails integration is ready!</p>
1550
+ <RouterLink
1551
+ to="/diviswap"
1552
+ class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
1553
+ >
1554
+ Go to Diviswap Dashboard
1555
+ </RouterLink>
1556
+ </div>
1557
+ </template>
1558
+
1559
+ <script${typescript ? ' setup lang="ts"' : " setup"}>
1560
+ import { RouterLink } from 'vue-router'
1561
+ </script>`;
1562
+ fs.writeFileSync("src/views/HomeView.vue", homeView);
1563
+ const diviswapView = `<template>
1564
+ <div class="p-8">
1565
+ <h1 class="text-2xl font-bold mb-4">Diviswap Integration</h1>
1566
+ <p>Diviswap SDK will be integrated here</p>
1567
+ </div>
1568
+ </template>
1569
+
1570
+ <script${typescript ? ' setup lang="ts"' : " setup"}>
1571
+ // Diviswap integration will be added by the init command
1572
+ </script>`;
1573
+ fs.writeFileSync("src/views/DiviswapView.vue", diviswapView);
1574
+ const styleCss = tailwind ? `@tailwind base;
1575
+ @tailwind components;
1576
+ @tailwind utilities;` : `:root {
1577
+ font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
1578
+ }
1579
+
1580
+ body {
1581
+ margin: 0;
1582
+ min-width: 320px;
1583
+ min-height: 100vh;
1584
+ }`;
1585
+ fs.writeFileSync("src/style.css", styleCss);
1586
+ if (tailwind) {
1587
+ const tailwindConfig = `/** @type {import('tailwindcss').Config} */
1588
+ export default {
1589
+ content: [
1590
+ "./index.html",
1591
+ "./src/**/*.{vue,js,ts,jsx,tsx}",
1592
+ ],
1593
+ theme: {
1594
+ extend: {},
1595
+ },
1596
+ plugins: [],
1597
+ }`;
1598
+ fs.writeFileSync("tailwind.config.js", tailwindConfig);
1599
+ const postcssConfig = `export default {
1600
+ plugins: {
1601
+ tailwindcss: {},
1602
+ autoprefixer: {},
1603
+ },
1604
+ }`;
1605
+ fs.writeFileSync("postcss.config.js", postcssConfig);
1606
+ }
1607
+ const gitignore = `# Logs
1608
+ logs
1609
+ *.log
1610
+ npm-debug.log*
1611
+ yarn-debug.log*
1612
+ yarn-error.log*
1613
+ pnpm-debug.log*
1614
+ lerna-debug.log*
1615
+
1616
+ node_modules
1617
+ .DS_Store
1618
+ dist
1619
+ dist-ssr
1620
+ coverage
1621
+ *.local
1622
+
1623
+ /cypress/videos/
1624
+ /cypress/screenshots/
1625
+
1626
+ # Editor directories and files
1627
+ .vscode/*
1628
+ !.vscode/extensions.json
1629
+ .idea
1630
+ *.suo
1631
+ *.ntvs*
1632
+ *.njsproj
1633
+ *.sln
1634
+ *.sw?
1635
+
1636
+ # Env files
1637
+ .env*.local`;
1638
+ fs.writeFileSync(".gitignore", gitignore);
1639
+ const readme = `# ${path.basename(projectPath)}
1640
+
1641
+ A Vue 3 application powered by Diviswap SDK for seamless crypto rails integration.
1642
+
1643
+ ## Getting Started
1644
+
1645
+ First, run the development server:
1646
+
1647
+ \`\`\`bash
1648
+ ${packageManager} ${packageManager === "npm" ? "run dev" : "dev"}
1649
+ \`\`\`
1650
+
1651
+ Open [http://localhost:5173](http://localhost:5173) with your browser to see the result.
1652
+
1653
+ ## Diviswap Integration
1654
+
1655
+ The Diviswap SDK has been pre-configured in this project. Visit [http://localhost:5173/diviswap](http://localhost:5173/diviswap) to see the integration in action.
1656
+
1657
+ ### Features
1658
+
1659
+ - \u2705 On-ramp (Buy crypto with fiat)
1660
+ - \u2705 Off-ramp (Sell crypto for fiat)
1661
+ - \u2705 Payee management
1662
+ - \u2705 Transaction history
1663
+ - \u2705 Real-time updates
1664
+
1665
+ ## Learn More
1666
+
1667
+ - [Diviswap Documentation](https://docs.diviswap.io)
1668
+ - [Vue 3 Documentation](https://vuejs.org)
1669
+ - [Vite Documentation](https://vitejs.dev)`;
1670
+ fs.writeFileSync("README.md", readme);
1671
+ console.log(kleur__default.default.cyan("\n\u{1F4E6} Installing dependencies...\n"));
1672
+ child_process.execSync(`${packageManager} install`, { stdio: "inherit" });
1673
+ }
1674
+ var SCAFFOLDED_FILES = {
1675
+ "nextjs-app": [
1676
+ "src/app/api/diviswap/route.ts",
1677
+ "app/api/diviswap/route.ts",
1678
+ "src/app/diviswap/page.tsx",
1679
+ "app/diviswap/page.tsx",
1680
+ "src/app/diviswap/layout.tsx",
1681
+ "app/diviswap/layout.tsx",
1682
+ "src/app/diviswap/actions.ts",
1683
+ "app/diviswap/actions.ts",
1684
+ "src/components/diviswap-provider.tsx",
1685
+ "components/diviswap-provider.tsx",
1686
+ "src/context/diviswap-auth-context.tsx",
1687
+ "context/diviswap-auth-context.tsx",
1688
+ "src/hooks/useLiberexData.ts",
1689
+ "hooks/useLiberexData.ts",
1690
+ "src/hooks/useLiberexKYC.ts",
1691
+ "hooks/useLiberexKYC.ts",
1692
+ "src/app/api/webhooks/diviswap/route.ts",
1693
+ "app/api/webhooks/diviswap/route.ts"
1694
+ ],
1695
+ "nextjs-pages": [
1696
+ "src/pages/api/diviswap/auth.ts",
1697
+ "pages/api/diviswap/auth.ts",
1698
+ "src/pages/api/diviswap/transactions.ts",
1699
+ "pages/api/diviswap/transactions.ts",
1700
+ "src/lib/diviswap/provider.tsx",
1701
+ "lib/diviswap/provider.tsx",
1702
+ "src/pages/diviswap.tsx",
1703
+ "pages/diviswap.tsx",
1704
+ "src/lib/diviswap/hooks.ts",
1705
+ "lib/diviswap/hooks.ts",
1706
+ "src/lib/diviswap/client.ts",
1707
+ "lib/diviswap/client.ts",
1708
+ "src/pages/api/webhooks/diviswap.ts",
1709
+ "pages/api/webhooks/diviswap.ts"
1710
+ ],
1711
+ "react": [
1712
+ "src/diviswap/api-client.ts",
1713
+ "src/diviswap/example.tsx"
1714
+ ],
1715
+ "vue3": [
1716
+ "src/plugins/diviswap.ts",
1717
+ "src/composables/useDiviswap.ts",
1718
+ "src/components/DiviswapProvider.vue",
1719
+ "src/components/TransactionButton.vue",
1720
+ "src/diviswap/client.ts",
1721
+ "src/views/DiviswapExample.vue",
1722
+ "src/diviswap/types.ts"
1723
+ ],
1724
+ "vanilla": [
1725
+ "diviswap/client.js",
1726
+ "diviswap/example.html",
1727
+ "diviswap/example.js",
1728
+ "diviswap/styles.css"
1729
+ ]
1730
+ };
1731
+ var SCAFFOLDED_DIRECTORIES = [
1732
+ "src/app/diviswap",
1733
+ "app/diviswap",
1734
+ "src/app/api/diviswap",
1735
+ "app/api/diviswap",
1736
+ "src/app/api/webhooks/diviswap",
1737
+ "app/api/webhooks/diviswap",
1738
+ "src/context",
1739
+ "context",
1740
+ "src/hooks",
1741
+ "hooks",
1742
+ "src/lib/diviswap",
1743
+ "lib/diviswap",
1744
+ "src/pages/api/diviswap",
1745
+ "pages/api/diviswap",
1746
+ "src/pages/api/webhooks",
1747
+ "pages/api/webhooks",
1748
+ "src/diviswap",
1749
+ "diviswap"
1750
+ ];
1751
+ var ENV_VARIABLES = [
1752
+ "DIVISWAP_PARTNER_KEY_ID",
1753
+ "DIVISWAP_PARTNER_SECRET_KEY",
1754
+ "NEXT_PUBLIC_DIVISWAP_ENV"
1755
+ ];
1756
+ async function uninstall(options = {}) {
1757
+ console.log(kleur__default.default.red().bold("\\n\u{1F5D1}\uFE0F Diviswap SDK Uninstall\\n"));
1758
+ const projectRoot = process.cwd();
1759
+ if (!options.force) {
1760
+ const confirmation = await prompts__default.default({
1761
+ type: "confirm",
1762
+ name: "confirmUninstall",
1763
+ message: kleur__default.default.yellow("Are you sure you want to remove all Diviswap SDK files and configuration?"),
1764
+ initial: false
1765
+ });
1766
+ if (!confirmation.confirmUninstall) {
1767
+ console.log(kleur__default.default.gray("Uninstall cancelled."));
1768
+ return;
1769
+ }
1770
+ }
1771
+ console.log(kleur__default.default.blue("\u{1F50D} Scanning for Diviswap files...\\n"));
1772
+ let filesRemoved = 0;
1773
+ let dirsRemoved = 0;
1774
+ for (const [framework, files] of Object.entries(SCAFFOLDED_FILES)) {
1775
+ for (const file of files) {
1776
+ const filePath = path.join(projectRoot, file);
1777
+ if (fs.existsSync(filePath)) {
1778
+ try {
1779
+ fs.unlinkSync(filePath);
1780
+ console.log(kleur__default.default.gray(`\u2713 Removed: ${file}`));
1781
+ filesRemoved++;
1782
+ } catch (error) {
1783
+ console.log(kleur__default.default.yellow(`\u26A0 Could not remove: ${file} (${error instanceof Error ? error.message : "unknown error"})`));
1784
+ }
1785
+ }
1786
+ }
1787
+ }
1788
+ console.log(kleur__default.default.blue("\\n\u{1F5C2}\uFE0F Cleaning up empty directories...\\n"));
1789
+ for (const dir of SCAFFOLDED_DIRECTORIES) {
1790
+ const dirPath = path.join(projectRoot, dir);
1791
+ if (fs.existsSync(dirPath)) {
1792
+ try {
1793
+ const files = __require("fs").readdirSync(dirPath);
1794
+ if (files.length === 0) {
1795
+ fs.rmSync(dirPath, { recursive: true });
1796
+ console.log(kleur__default.default.gray(`\u2713 Removed directory: ${dir}`));
1797
+ dirsRemoved++;
1798
+ }
1799
+ } catch (error) {
1800
+ }
1801
+ }
1802
+ }
1803
+ if (!options.keepConfig) {
1804
+ console.log(kleur__default.default.blue("\\n\u{1F527} Cleaning environment variables...\\n"));
1805
+ const envFiles = [".env", ".env.local", ".env.development", ".env.production"];
1806
+ for (const envFile of envFiles) {
1807
+ const envPath = path.join(projectRoot, envFile);
1808
+ if (fs.existsSync(envPath)) {
1809
+ try {
1810
+ let envContent = fs.readFileSync(envPath, "utf-8");
1811
+ let modified = false;
1812
+ for (const envVar of ENV_VARIABLES) {
1813
+ const regex = new RegExp(`^${envVar}=.*$`, "gm");
1814
+ if (regex.test(envContent)) {
1815
+ envContent = envContent.replace(regex, "").replace(/\\n\\n+/g, "\\n").trim();
1816
+ modified = true;
1817
+ console.log(kleur__default.default.gray(`\u2713 Removed ${envVar} from ${envFile}`));
1818
+ }
1819
+ }
1820
+ if (modified) {
1821
+ fs.writeFileSync(envPath, envContent + "\\n");
1822
+ }
1823
+ } catch (error) {
1824
+ console.log(kleur__default.default.yellow(`\u26A0 Could not clean ${envFile}: ${error instanceof Error ? error.message : "unknown error"}`));
1825
+ }
1826
+ }
1827
+ }
1828
+ }
1829
+ console.log(kleur__default.default.blue("\\n\u{1F4E6} Checking package.json...\\n"));
1830
+ const packageJsonPath = path.join(projectRoot, "package.json");
1831
+ if (fs.existsSync(packageJsonPath)) {
1832
+ try {
1833
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
1834
+ let modified = false;
1835
+ if (packageJson.dependencies && packageJson.dependencies["@diviswap/sdk"]) {
1836
+ delete packageJson.dependencies["@diviswap/sdk"];
1837
+ modified = true;
1838
+ console.log(kleur__default.default.gray("\u2713 Removed @diviswap/sdk from dependencies"));
1839
+ }
1840
+ if (packageJson.devDependencies && packageJson.devDependencies["@diviswap/sdk"]) {
1841
+ delete packageJson.devDependencies["@diviswap/sdk"];
1842
+ modified = true;
1843
+ console.log(kleur__default.default.gray("\u2713 Removed @diviswap/sdk from devDependencies"));
1844
+ }
1845
+ if (modified) {
1846
+ fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + "\\n");
1847
+ const installDeps = await prompts__default.default({
1848
+ type: "confirm",
1849
+ name: "installDeps",
1850
+ message: "Run npm install to update dependencies?",
1851
+ initial: true
1852
+ });
1853
+ if (installDeps.installDeps) {
1854
+ const { execSync: execSync3 } = __require("child_process");
1855
+ try {
1856
+ console.log(kleur__default.default.blue("\\n\u{1F4E6} Running npm install..."));
1857
+ execSync3("npm install", { stdio: "inherit", cwd: projectRoot });
1858
+ } catch (error) {
1859
+ console.log(kleur__default.default.yellow("\u26A0 Failed to run npm install. Please run it manually."));
1860
+ }
1861
+ }
1862
+ }
1863
+ } catch (error) {
1864
+ console.log(kleur__default.default.yellow(`\u26A0 Could not update package.json: ${error instanceof Error ? error.message : "unknown error"}`));
1865
+ }
1866
+ }
1867
+ console.log(kleur__default.default.green().bold("\\n\u2705 Uninstall Complete!\\n"));
1868
+ console.log(kleur__default.default.white(`Files removed: ${filesRemoved}`));
1869
+ console.log(kleur__default.default.white(`Directories removed: ${dirsRemoved}`));
1870
+ if (options.keepConfig) {
1871
+ console.log(kleur__default.default.yellow("\\n\u26A0 Environment variables were preserved (--keep-config flag)"));
1872
+ }
1873
+ console.log(kleur__default.default.gray("\\nThe Diviswap SDK has been removed from your project.\\n"));
1874
+ }
1875
+
1876
+ // package.json
1877
+ var version = "1.7.6";
1878
+
1879
+ // src/cli/index.ts
1880
+ var program = new commander.Command();
1881
+ program.name("diviswap-sdk").description("Diviswap SDK CLI - Streamline your crypto rails integration").version(version);
1882
+ program.command("init").description("Initialize Diviswap SDK in your existing project").option("-f, --framework <type>", "Framework type (nextjs-app, nextjs-pages, react, vue3, etc.)").option("-e, --env <environment>", "Environment (production or sandbox)", "sandbox").option("--skip-install", "Skip automatic dependency installation").option("--skip-env", "Skip environment variable setup").option("--force", "Overwrite existing files").action(init);
1883
+ program.command("create-app [project-name]").alias("create").description("Create a new project with Diviswap SDK pre-configured").option("-t, --template <type>", "Project template (nextjs, react, vue)", "nextjs").option("--use-npm", "Use npm instead of detecting package manager").option("--use-yarn", "Use Yarn instead of detecting package manager").option("--use-pnpm", "Use pnpm instead of detecting package manager").option("--typescript", "Use TypeScript (default)", true).option("--javascript", "Use JavaScript instead of TypeScript").option("--eslint", "Include ESLint configuration", true).option("--tailwind", "Include Tailwind CSS", true).option("--app", "Use App Router (Next.js only)", true).option("--src-dir", "Use src directory", true).option("--import-alias <alias>", "Import alias", "@/*").action(createApp);
1884
+ program.command("uninstall").alias("remove").description("Remove Diviswap SDK files and configuration from your project").option("--force", "Skip confirmation prompt").option("--keep-config", "Keep environment variables").action(uninstall);
1885
+ if (!process.argv.slice(2).length) {
1886
+ program.outputHelp();
1887
+ }
1888
+ program.parse();