@diviswap/sdk 1.7.16 → 1.7.17
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/dist/cli/index.js +1 -1
- package/dist/cli/templates/nextjs-app/actions.ts.hbs +45 -38
- package/dist/cli/templates/nextjs-app/api-hooks.ts.hbs +10 -10
- package/dist/cli/templates/nextjs-app/api-route.ts.hbs +65 -65
- package/dist/cli/templates/nextjs-app/auth-context.tsx.hbs +1 -1
- package/dist/cli/templates/nextjs-app/client.ts.hbs +4 -4
- package/dist/cli/templates/nextjs-app/dashboard-hooks.ts.hbs +7 -7
- package/dist/cli/templates/nextjs-app/example-page.tsx.hbs +9 -9
- package/dist/cli/templates/nextjs-app/hooks.ts.hbs +7 -7
- package/dist/cli/templates/nextjs-app/kyc-hooks.ts.hbs +2 -2
- package/dist/cli/templates/nextjs-app/kyc-wizard.css.hbs +16 -16
- package/dist/cli/templates/nextjs-app/kyc-wizard.tsx.hbs +71 -38
- package/dist/cli/templates/nextjs-app/layout-wrapper.tsx.hbs +4 -4
- package/dist/cli/templates/nextjs-app/layout.tsx.hbs +4 -4
- package/dist/cli/templates/nextjs-app/middleware.ts.hbs +15 -15
- package/dist/cli/templates/nextjs-app/provider-wrapper.tsx.hbs +4 -4
- package/dist/cli/templates/nextjs-app/provider.tsx.hbs +15 -15
- package/dist/cli/templates/nextjs-app/setup-provider.tsx.hbs +4 -4
- package/dist/cli/templates/react/api-client-wrapper.ts.hbs +11 -11
- package/dist/cli/templates/react/example.tsx.hbs +6 -6
- package/dist/cli/templates/react/tanstack-hooks.ts.hbs +14 -14
- package/dist/cli/templates/webhooks/nextjs.hbs +3 -3
- package/package.json +1 -1
- package/src/cli/templates/nextjs-app/actions.ts.hbs +45 -38
- package/src/cli/templates/nextjs-app/api-hooks.ts.hbs +10 -10
- package/src/cli/templates/nextjs-app/api-route.ts.hbs +65 -65
- package/src/cli/templates/nextjs-app/auth-context.tsx.hbs +1 -1
- package/src/cli/templates/nextjs-app/client.ts.hbs +4 -4
- package/src/cli/templates/nextjs-app/dashboard-hooks.ts.hbs +7 -7
- package/src/cli/templates/nextjs-app/example-page.tsx.hbs +9 -9
- package/src/cli/templates/nextjs-app/hooks.ts.hbs +7 -7
- package/src/cli/templates/nextjs-app/kyc-hooks.ts.hbs +2 -2
- package/src/cli/templates/nextjs-app/kyc-wizard.css.hbs +16 -16
- package/src/cli/templates/nextjs-app/kyc-wizard.tsx.hbs +71 -38
- package/src/cli/templates/nextjs-app/layout-wrapper.tsx.hbs +4 -4
- package/src/cli/templates/nextjs-app/layout.tsx.hbs +4 -4
- package/src/cli/templates/nextjs-app/middleware.ts.hbs +15 -15
- package/src/cli/templates/nextjs-app/provider-wrapper.tsx.hbs +4 -4
- package/src/cli/templates/nextjs-app/provider.tsx.hbs +15 -15
- package/src/cli/templates/nextjs-app/setup-provider.tsx.hbs +4 -4
- package/src/cli/templates/react/api-client-wrapper.ts.hbs +11 -11
- package/src/cli/templates/react/example.tsx.hbs +6 -6
- package/src/cli/templates/react/tanstack-hooks.ts.hbs +14 -14
- package/src/cli/templates/webhooks/nextjs.hbs +3 -3
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
import { useState } from 'react';
|
|
4
|
-
import { use{{prefix}}Auth } from '~/context/
|
|
4
|
+
import { use{{prefix}}Auth } from '~/context/diviswap-auth-context';
|
|
5
5
|
|
|
6
6
|
interface KYCFormData {
|
|
7
7
|
firstName: string;
|
|
@@ -53,7 +53,7 @@ export function use{{prefix}}KYC() {
|
|
|
53
53
|
};
|
|
54
54
|
|
|
55
55
|
// Call API to submit KYC
|
|
56
|
-
const response = await fetch('/api/
|
|
56
|
+
const response = await fetch('/api/diviswap', {
|
|
57
57
|
method: 'POST',
|
|
58
58
|
headers: { 'Content-Type': 'application/json' },
|
|
59
59
|
body: JSON.stringify({
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
/*
|
|
2
|
-
.
|
|
1
|
+
/* Diviswap KYC Wizard Styles */
|
|
2
|
+
.diviswap-kyc-container {
|
|
3
3
|
max-width: 600px;
|
|
4
4
|
margin: 0 auto;
|
|
5
5
|
padding: 2rem;
|
|
@@ -288,7 +288,7 @@
|
|
|
288
288
|
}
|
|
289
289
|
|
|
290
290
|
/* Modal */
|
|
291
|
-
.
|
|
291
|
+
.diviswap-kyc-modal-overlay {
|
|
292
292
|
position: fixed;
|
|
293
293
|
top: 0;
|
|
294
294
|
left: 0;
|
|
@@ -302,7 +302,7 @@
|
|
|
302
302
|
padding: 1rem;
|
|
303
303
|
}
|
|
304
304
|
|
|
305
|
-
.
|
|
305
|
+
.diviswap-kyc-modal {
|
|
306
306
|
background-color: white;
|
|
307
307
|
border-radius: 12px;
|
|
308
308
|
max-width: 600px;
|
|
@@ -311,54 +311,54 @@
|
|
|
311
311
|
overflow-y: auto;
|
|
312
312
|
}
|
|
313
313
|
|
|
314
|
-
.
|
|
314
|
+
.diviswap-kyc-modal .diviswap-kyc-container {
|
|
315
315
|
border: none;
|
|
316
316
|
box-shadow: none;
|
|
317
317
|
margin: 0;
|
|
318
318
|
}
|
|
319
319
|
|
|
320
320
|
/* Dark Theme */
|
|
321
|
-
.
|
|
321
|
+
.diviswap-kyc-container[data-theme="dark"] {
|
|
322
322
|
background-color: #1f2937;
|
|
323
323
|
color: #f9fafb;
|
|
324
324
|
border-color: #374151;
|
|
325
325
|
}
|
|
326
326
|
|
|
327
|
-
.
|
|
328
|
-
.
|
|
327
|
+
.diviswap-kyc-container[data-theme="dark"] .form-field input,
|
|
328
|
+
.diviswap-kyc-container[data-theme="dark"] .form-field select {
|
|
329
329
|
background-color: #374151;
|
|
330
330
|
border-color: #4b5563;
|
|
331
331
|
color: #f9fafb;
|
|
332
332
|
}
|
|
333
333
|
|
|
334
|
-
.
|
|
335
|
-
.
|
|
334
|
+
.diviswap-kyc-container[data-theme="dark"] .form-field input:focus,
|
|
335
|
+
.diviswap-kyc-container[data-theme="dark"] .form-field select:focus {
|
|
336
336
|
border-color: #6366f1;
|
|
337
337
|
}
|
|
338
338
|
|
|
339
|
-
.
|
|
339
|
+
.diviswap-kyc-container[data-theme="dark"] .review-section {
|
|
340
340
|
background-color: #374151;
|
|
341
341
|
border-color: #4b5563;
|
|
342
342
|
}
|
|
343
343
|
|
|
344
|
-
.
|
|
344
|
+
.diviswap-kyc-container[data-theme="dark"] .btn-secondary {
|
|
345
345
|
border-color: #4b5563;
|
|
346
346
|
color: #d1d5db;
|
|
347
347
|
}
|
|
348
348
|
|
|
349
|
-
.
|
|
349
|
+
.diviswap-kyc-container[data-theme="dark"] .btn-secondary:hover {
|
|
350
350
|
background-color: #374151;
|
|
351
351
|
border-color: #6b7280;
|
|
352
352
|
}
|
|
353
353
|
|
|
354
|
-
.
|
|
354
|
+
.diviswap-kyc-container[data-theme="dark"] .info-box {
|
|
355
355
|
background-color: #064e3b;
|
|
356
356
|
border-color: #047857;
|
|
357
357
|
}
|
|
358
358
|
|
|
359
359
|
/* Responsive Design */
|
|
360
360
|
@media (max-width: 640px) {
|
|
361
|
-
.
|
|
361
|
+
.diviswap-kyc-container {
|
|
362
362
|
padding: 1rem;
|
|
363
363
|
margin: 1rem;
|
|
364
364
|
}
|
|
@@ -417,7 +417,7 @@
|
|
|
417
417
|
|
|
418
418
|
/* High Contrast Mode */
|
|
419
419
|
@media (prefers-contrast: high) {
|
|
420
|
-
.
|
|
420
|
+
.diviswap-kyc-container {
|
|
421
421
|
border-width: 2px;
|
|
422
422
|
}
|
|
423
423
|
|
|
@@ -23,22 +23,55 @@ interface KycFormData {
|
|
|
23
23
|
country: string;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
interface
|
|
27
|
-
|
|
26
|
+
interface ThemeConfig {
|
|
27
|
+
primaryColor?: string;
|
|
28
|
+
backgroundColor?: string;
|
|
29
|
+
textColor?: string;
|
|
30
|
+
borderRadius?: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
interface KYCStatus {
|
|
34
|
+
verified: boolean;
|
|
35
|
+
status: string;
|
|
36
|
+
customerId?: string;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
interface DiviswapKYCProps {
|
|
40
|
+
onSuccess?: (status: KYCStatus) => void;
|
|
28
41
|
onError?: (error: Error) => void;
|
|
29
42
|
onClose?: () => void;
|
|
30
|
-
theme?: 'light' | 'dark' |
|
|
31
|
-
primaryColor?: string;
|
|
32
|
-
backgroundColor?: string;
|
|
33
|
-
textColor?: string;
|
|
34
|
-
borderRadius?: string;
|
|
35
|
-
};
|
|
43
|
+
theme?: 'light' | 'dark' | ThemeConfig;
|
|
36
44
|
steps?: KYCStep[];
|
|
37
45
|
autoClose?: boolean;
|
|
38
46
|
className?: string;
|
|
39
47
|
}
|
|
40
48
|
|
|
41
|
-
|
|
49
|
+
interface StepProps {
|
|
50
|
+
onNext: () => void;
|
|
51
|
+
onPrev?: () => void;
|
|
52
|
+
onClose?: () => void;
|
|
53
|
+
theme: ThemeConfig;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
interface FormStepProps extends StepProps {
|
|
57
|
+
formData: KycFormData;
|
|
58
|
+
updateFormData: (updates: Partial<KycFormData>) => void;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
interface ReviewStepProps {
|
|
62
|
+
formData: KycFormData;
|
|
63
|
+
onSubmit: () => void;
|
|
64
|
+
onPrev: () => void;
|
|
65
|
+
isSubmitting: boolean;
|
|
66
|
+
theme: ThemeConfig;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
interface SuccessStepProps {
|
|
70
|
+
onClose?: () => void;
|
|
71
|
+
theme: ThemeConfig;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export function DiviswapKYC({
|
|
42
75
|
onSuccess,
|
|
43
76
|
onError,
|
|
44
77
|
onClose,
|
|
@@ -46,7 +79,7 @@ export function LiberexKYC({
|
|
|
46
79
|
steps = ['intro', 'personal', 'identification', 'address', 'review', 'success'],
|
|
47
80
|
autoClose = false,
|
|
48
81
|
className = ''
|
|
49
|
-
}:
|
|
82
|
+
}: DiviswapKYCProps) {
|
|
50
83
|
const [currentStep, setCurrentStep] = useState<KYCStep>(steps[0]);
|
|
51
84
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
|
52
85
|
const [formData, setFormData] = useState<KycFormData>({
|
|
@@ -106,7 +139,7 @@ export function LiberexKYC({
|
|
|
106
139
|
};
|
|
107
140
|
|
|
108
141
|
// Call your KYC submission API
|
|
109
|
-
const response = await fetch('/api/
|
|
142
|
+
const response = await fetch('/api/diviswap', {
|
|
110
143
|
method: 'POST',
|
|
111
144
|
headers: { 'Content-Type': 'application/json' },
|
|
112
145
|
body: JSON.stringify({
|
|
@@ -132,9 +165,9 @@ export function LiberexKYC({
|
|
|
132
165
|
setTimeout(() => onClose?.(), 2000);
|
|
133
166
|
}
|
|
134
167
|
|
|
135
|
-
} catch (error
|
|
168
|
+
} catch (error) {
|
|
136
169
|
console.error('KYC submission error:', error);
|
|
137
|
-
onError?.(error);
|
|
170
|
+
onError?.(error instanceof Error ? error : new Error(String(error)));
|
|
138
171
|
} finally {
|
|
139
172
|
setIsSubmitting(false);
|
|
140
173
|
}
|
|
@@ -155,22 +188,22 @@ export function LiberexKYC({
|
|
|
155
188
|
};
|
|
156
189
|
|
|
157
190
|
const updateFormData = (updates: Partial<KycFormData>) => {
|
|
158
|
-
setFormData(prev => (
|
|
191
|
+
setFormData(prev => ({ ...prev, ...updates }));
|
|
159
192
|
};
|
|
160
193
|
|
|
161
|
-
const containerStyle =
|
|
194
|
+
const containerStyle = {
|
|
162
195
|
backgroundColor: themeConfig.backgroundColor,
|
|
163
196
|
color: themeConfig.textColor,
|
|
164
197
|
borderRadius: themeConfig.borderRadius
|
|
165
|
-
|
|
198
|
+
};
|
|
166
199
|
|
|
167
|
-
const primaryButtonStyle =
|
|
200
|
+
const primaryButtonStyle = {
|
|
168
201
|
backgroundColor: themeConfig.primaryColor,
|
|
169
202
|
borderRadius: themeConfig.borderRadius
|
|
170
|
-
|
|
203
|
+
};
|
|
171
204
|
|
|
172
205
|
return (
|
|
173
|
-
<div className={`
|
|
206
|
+
<div className={`diviswap-kyc-container ${className}`} style={containerStyle}>
|
|
174
207
|
{/* Progress Bar */}
|
|
175
208
|
{currentStep !== 'intro' && currentStep !== 'success' && (
|
|
176
209
|
<div className="progress-container">
|
|
@@ -180,7 +213,7 @@ export function LiberexKYC({
|
|
|
180
213
|
style=\{{
|
|
181
214
|
width: progressPercentage + '%',
|
|
182
215
|
backgroundColor: themeConfig.primaryColor
|
|
183
|
-
|
|
216
|
+
}}
|
|
184
217
|
/>
|
|
185
218
|
</div>
|
|
186
219
|
<div className="progress-text">
|
|
@@ -249,11 +282,11 @@ export function LiberexKYC({
|
|
|
249
282
|
}
|
|
250
283
|
|
|
251
284
|
// Step Components
|
|
252
|
-
function IntroStep({ onNext, onClose, theme }:
|
|
285
|
+
function IntroStep({ onNext, onClose, theme }: StepProps) {
|
|
253
286
|
return (
|
|
254
287
|
<div className="kyc-step intro-step">
|
|
255
288
|
<div className="step-header">
|
|
256
|
-
<CheckCircle className="step-icon" style=\{{ color: theme.primaryColor
|
|
289
|
+
<CheckCircle className="step-icon" style=\{{ color: theme.primaryColor }} />
|
|
257
290
|
<h2>Identity Verification</h2>
|
|
258
291
|
<p>We need to verify your identity to comply with financial regulations. This process takes about 3 minutes.</p>
|
|
259
292
|
</div>
|
|
@@ -286,7 +319,7 @@ function IntroStep({ onNext, onClose, theme }: any) {
|
|
|
286
319
|
<button
|
|
287
320
|
onClick={onNext}
|
|
288
321
|
className="btn-primary"
|
|
289
|
-
style=\{{ backgroundColor: theme.primaryColor
|
|
322
|
+
style=\{{ backgroundColor: theme.primaryColor }}
|
|
290
323
|
>
|
|
291
324
|
Start Verification
|
|
292
325
|
<ArrowRight className="btn-icon" />
|
|
@@ -301,7 +334,7 @@ function IntroStep({ onNext, onClose, theme }: any) {
|
|
|
301
334
|
);
|
|
302
335
|
}
|
|
303
336
|
|
|
304
|
-
function PersonalInfoStep({ formData, updateFormData, onNext, onPrev, theme }:
|
|
337
|
+
function PersonalInfoStep({ formData, updateFormData, onNext, onPrev, theme }: FormStepProps) {
|
|
305
338
|
const isValid = formData.firstName && formData.lastName && formData.email &&
|
|
306
339
|
formData.dobDay && formData.dobMonth && formData.dobYear;
|
|
307
340
|
|
|
@@ -402,7 +435,7 @@ function PersonalInfoStep({ formData, updateFormData, onNext, onPrev, theme }: a
|
|
|
402
435
|
onClick={onNext}
|
|
403
436
|
disabled={!isValid}
|
|
404
437
|
className="btn-primary"
|
|
405
|
-
style=\{{ backgroundColor: theme.primaryColor
|
|
438
|
+
style=\{{ backgroundColor: theme.primaryColor }}
|
|
406
439
|
>
|
|
407
440
|
Continue
|
|
408
441
|
<ArrowRight className="btn-icon" />
|
|
@@ -412,7 +445,7 @@ function PersonalInfoStep({ formData, updateFormData, onNext, onPrev, theme }: a
|
|
|
412
445
|
);
|
|
413
446
|
}
|
|
414
447
|
|
|
415
|
-
function IdentificationStep({ formData, updateFormData, onNext, onPrev, theme }:
|
|
448
|
+
function IdentificationStep({ formData, updateFormData, onNext, onPrev, theme }: FormStepProps) {
|
|
416
449
|
const isValid = formData.idType && formData.idNumber;
|
|
417
450
|
|
|
418
451
|
return (
|
|
@@ -465,7 +498,7 @@ function IdentificationStep({ formData, updateFormData, onNext, onPrev, theme }:
|
|
|
465
498
|
onClick={onNext}
|
|
466
499
|
disabled={!isValid}
|
|
467
500
|
className="btn-primary"
|
|
468
|
-
style=\{{ backgroundColor: theme.primaryColor
|
|
501
|
+
style=\{{ backgroundColor: theme.primaryColor }}
|
|
469
502
|
>
|
|
470
503
|
Continue
|
|
471
504
|
<ArrowRight className="btn-icon" />
|
|
@@ -475,7 +508,7 @@ function IdentificationStep({ formData, updateFormData, onNext, onPrev, theme }:
|
|
|
475
508
|
);
|
|
476
509
|
}
|
|
477
510
|
|
|
478
|
-
function AddressStep({ formData, updateFormData, onNext, onPrev, theme }:
|
|
511
|
+
function AddressStep({ formData, updateFormData, onNext, onPrev, theme }: FormStepProps) {
|
|
479
512
|
const isValid = formData.addressLine1 && formData.city && formData.state &&
|
|
480
513
|
formData.postalCode && formData.country;
|
|
481
514
|
|
|
@@ -567,7 +600,7 @@ function AddressStep({ formData, updateFormData, onNext, onPrev, theme }: any) {
|
|
|
567
600
|
onClick={onNext}
|
|
568
601
|
disabled={!isValid}
|
|
569
602
|
className="btn-primary"
|
|
570
|
-
style=\{{ backgroundColor: theme.primaryColor
|
|
603
|
+
style=\{{ backgroundColor: theme.primaryColor }}
|
|
571
604
|
>
|
|
572
605
|
Continue
|
|
573
606
|
<ArrowRight className="btn-icon" />
|
|
@@ -577,7 +610,7 @@ function AddressStep({ formData, updateFormData, onNext, onPrev, theme }: any) {
|
|
|
577
610
|
);
|
|
578
611
|
}
|
|
579
612
|
|
|
580
|
-
function ReviewStep({ formData, onSubmit, onPrev, isSubmitting, theme }:
|
|
613
|
+
function ReviewStep({ formData, onSubmit, onPrev, isSubmitting, theme }: ReviewStepProps) {
|
|
581
614
|
return (
|
|
582
615
|
<div className="kyc-step review-step">
|
|
583
616
|
<div className="step-header">
|
|
@@ -643,7 +676,7 @@ function ReviewStep({ formData, onSubmit, onPrev, isSubmitting, theme }: any) {
|
|
|
643
676
|
onClick={onSubmit}
|
|
644
677
|
disabled={isSubmitting}
|
|
645
678
|
className="btn-primary"
|
|
646
|
-
style=\{{ backgroundColor: theme.primaryColor
|
|
679
|
+
style=\{{ backgroundColor: theme.primaryColor }}
|
|
647
680
|
>
|
|
648
681
|
{isSubmitting ? (
|
|
649
682
|
<>
|
|
@@ -662,11 +695,11 @@ function ReviewStep({ formData, onSubmit, onPrev, isSubmitting, theme }: any) {
|
|
|
662
695
|
);
|
|
663
696
|
}
|
|
664
697
|
|
|
665
|
-
function SuccessStep({ onClose, theme }:
|
|
698
|
+
function SuccessStep({ onClose, theme }: SuccessStepProps) {
|
|
666
699
|
return (
|
|
667
700
|
<div className="kyc-step success-step">
|
|
668
701
|
<div className="step-header">
|
|
669
|
-
<CheckCircle className="step-icon success-icon" style=\{{ color: theme.primaryColor
|
|
702
|
+
<CheckCircle className="step-icon success-icon" style=\{{ color: theme.primaryColor }} />
|
|
670
703
|
<h2>Verification Submitted!</h2>
|
|
671
704
|
<p>Your identity verification has been submitted successfully. We'll review your information and notify you of the results.</p>
|
|
672
705
|
</div>
|
|
@@ -687,7 +720,7 @@ function SuccessStep({ onClose, theme }: any) {
|
|
|
687
720
|
<button
|
|
688
721
|
onClick={onClose}
|
|
689
722
|
className="btn-primary"
|
|
690
|
-
style=\{{ backgroundColor: theme.primaryColor
|
|
723
|
+
style=\{{ backgroundColor: theme.primaryColor }}
|
|
691
724
|
>
|
|
692
725
|
Continue
|
|
693
726
|
</button>
|
|
@@ -698,13 +731,13 @@ function SuccessStep({ onClose, theme }: any) {
|
|
|
698
731
|
}
|
|
699
732
|
|
|
700
733
|
// Export modal version
|
|
701
|
-
export function
|
|
734
|
+
export function DiviswapKYCModal({ isOpen, onClose, ...props }: DiviswapKYCProps & { isOpen: boolean }) {
|
|
702
735
|
if (!isOpen) return null;
|
|
703
736
|
|
|
704
737
|
return (
|
|
705
|
-
<div className="
|
|
706
|
-
<div className="
|
|
707
|
-
<
|
|
738
|
+
<div className="diviswap-kyc-modal-overlay">
|
|
739
|
+
<div className="diviswap-kyc-modal">
|
|
740
|
+
<DiviswapKYC {...props} onClose={onClose} />
|
|
708
741
|
</div>
|
|
709
742
|
</div>
|
|
710
743
|
);
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DiviswapProvider } from '@diviswap/sdk/react';
|
|
2
2
|
|
|
3
|
-
export default function
|
|
3
|
+
export default function DiviswapLayout({
|
|
4
4
|
children,
|
|
5
5
|
}: {
|
|
6
6
|
children: React.ReactNode;
|
|
7
7
|
}) {
|
|
8
8
|
return (
|
|
9
|
-
<
|
|
9
|
+
<DiviswapProvider>
|
|
10
10
|
{children}
|
|
11
|
-
</
|
|
11
|
+
</DiviswapProvider>
|
|
12
12
|
);
|
|
13
13
|
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DiviswapProvider } from './lbx-provider';
|
|
2
2
|
|
|
3
|
-
export default function
|
|
3
|
+
export default function DiviswapLayout({
|
|
4
4
|
children,
|
|
5
5
|
}: {
|
|
6
6
|
children: React.ReactNode;
|
|
7
7
|
}) {
|
|
8
8
|
return (
|
|
9
|
-
<
|
|
9
|
+
<DiviswapProvider>
|
|
10
10
|
{children}
|
|
11
|
-
</
|
|
11
|
+
</DiviswapProvider>
|
|
12
12
|
);
|
|
13
13
|
}
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
import { NextRequest, NextResponse } from 'next/server';
|
|
2
2
|
|
|
3
|
-
// This middleware adds
|
|
3
|
+
// This middleware adds Diviswap session information to requests
|
|
4
4
|
// Note: In middleware, we use request.cookies (not the async cookies() from next/headers)
|
|
5
|
-
export function
|
|
6
|
-
// Check for
|
|
7
|
-
const
|
|
5
|
+
export function diviswapMiddleware(request: NextRequest) {
|
|
6
|
+
// Check for Diviswap session cookie
|
|
7
|
+
const diviswapSession = request.cookies.get('diviswap_session');
|
|
8
8
|
|
|
9
|
-
if (!
|
|
9
|
+
if (!diviswapSession) {
|
|
10
10
|
// No session, proceed without authentication
|
|
11
11
|
return NextResponse.next();
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
// Add session to headers for API routes
|
|
15
15
|
const requestHeaders = new Headers(request.headers);
|
|
16
|
-
requestHeaders.set('x-
|
|
16
|
+
requestHeaders.set('x-diviswap-session', diviswapSession.value);
|
|
17
17
|
|
|
18
18
|
// You can also add other headers or perform additional checks here
|
|
19
|
-
requestHeaders.set('x-
|
|
19
|
+
requestHeaders.set('x-diviswap-client-version', '1.0.0');
|
|
20
20
|
|
|
21
21
|
return NextResponse.next({
|
|
22
22
|
request: {
|
|
@@ -26,24 +26,24 @@ export function liberexMiddleware(request: NextRequest) {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
// Optional: Add route protection
|
|
29
|
-
export function
|
|
30
|
-
const
|
|
29
|
+
export function protectDiviswapRoutes(request: NextRequest) {
|
|
30
|
+
const diviswapSession = request.cookies.get('diviswap_session');
|
|
31
31
|
|
|
32
32
|
// List of protected routes
|
|
33
33
|
const protectedRoutes = [
|
|
34
|
-
'/
|
|
35
|
-
'/
|
|
36
|
-
'/
|
|
34
|
+
'/diviswap/dashboard',
|
|
35
|
+
'/diviswap/transactions',
|
|
36
|
+
'/diviswap/settings'
|
|
37
37
|
];
|
|
38
38
|
|
|
39
39
|
const isProtectedRoute = protectedRoutes.some(route =>
|
|
40
40
|
request.nextUrl.pathname.startsWith(route)
|
|
41
41
|
);
|
|
42
42
|
|
|
43
|
-
if (isProtectedRoute && !
|
|
43
|
+
if (isProtectedRoute && !diviswapSession) {
|
|
44
44
|
// Redirect to login page
|
|
45
|
-
return NextResponse.redirect(new URL('/
|
|
45
|
+
return NextResponse.redirect(new URL('/diviswap', request.url));
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
return
|
|
48
|
+
return diviswapMiddleware(request);
|
|
49
49
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { DiviswapProvider } from '@diviswap/sdk/react';
|
|
4
4
|
|
|
5
|
-
// Wrapper to ensure client-side rendering for
|
|
6
|
-
export function
|
|
7
|
-
return <
|
|
5
|
+
// Wrapper to ensure client-side rendering for Diviswap components
|
|
6
|
+
export function DiviswapClientProvider({ children }: { children: React.ReactNode }) {
|
|
7
|
+
return <DiviswapProvider>{children}</DiviswapProvider>;
|
|
8
8
|
}
|
|
@@ -6,7 +6,7 @@ import type { User, Transaction, Payee, TransactionStatus } from './lbx-types';
|
|
|
6
6
|
import io, { Socket } from 'socket.io-client';
|
|
7
7
|
{{/if}}
|
|
8
8
|
|
|
9
|
-
interface
|
|
9
|
+
interface DiviswapContextValue {
|
|
10
10
|
// Customer state (for partner authentication)
|
|
11
11
|
customerId: string | null;
|
|
12
12
|
customerEmail: string | null;
|
|
@@ -63,11 +63,11 @@ interface LiberExContextValue {
|
|
|
63
63
|
{{/if}}
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
const
|
|
66
|
+
const DiviswapContext = createContext<DiviswapContextValue | null>(null);
|
|
67
67
|
|
|
68
68
|
// API client class
|
|
69
|
-
class
|
|
70
|
-
constructor(private baseUrl: string = '/api/
|
|
69
|
+
class DiviswapClient {
|
|
70
|
+
constructor(private baseUrl: string = '/api/diviswap') {}
|
|
71
71
|
|
|
72
72
|
private async request<T = any>(
|
|
73
73
|
endpoint: string,
|
|
@@ -168,7 +168,7 @@ class LiberExClient {
|
|
|
168
168
|
{{/if}}
|
|
169
169
|
}
|
|
170
170
|
|
|
171
|
-
export function
|
|
171
|
+
export function DiviswapProvider({ children }: { children: React.ReactNode }) {
|
|
172
172
|
const [customerId, setCustomerId] = useState<string | null>(null);
|
|
173
173
|
const [customerEmail, setCustomerEmail] = useState<string | null>(null);
|
|
174
174
|
const [loading, setLoading] = useState(false);
|
|
@@ -177,7 +177,7 @@ export function LiberExProvider({ children }: { children: React.ReactNode }) {
|
|
|
177
177
|
const [socket, setSocket] = useState<Socket | null>(null);
|
|
178
178
|
{{/if}}
|
|
179
179
|
|
|
180
|
-
const client = new
|
|
180
|
+
const client = new DiviswapClient('/api/diviswap');
|
|
181
181
|
|
|
182
182
|
// Initialize with demo customer for development
|
|
183
183
|
useEffect(() => {
|
|
@@ -192,7 +192,7 @@ export function LiberExProvider({ children }: { children: React.ReactNode }) {
|
|
|
192
192
|
useEffect(() => {
|
|
193
193
|
if (customerId && customerEmail) {
|
|
194
194
|
const socketInstance = io(
|
|
195
|
-
process.env.
|
|
195
|
+
process.env.NEXT_PUBLIC_DIVISWAP_WS_URL || 'wss://ws.diviswap.io',
|
|
196
196
|
{
|
|
197
197
|
auth: {
|
|
198
198
|
customerId,
|
|
@@ -205,11 +205,11 @@ export function LiberExProvider({ children }: { children: React.ReactNode }) {
|
|
|
205
205
|
);
|
|
206
206
|
|
|
207
207
|
socketInstance.on('connect', () => {
|
|
208
|
-
console.log('Connected to
|
|
208
|
+
console.log('Connected to Diviswap WebSocket');
|
|
209
209
|
});
|
|
210
210
|
|
|
211
211
|
socketInstance.on('disconnect', () => {
|
|
212
|
-
console.log('Disconnected from
|
|
212
|
+
console.log('Disconnected from Diviswap WebSocket');
|
|
213
213
|
});
|
|
214
214
|
|
|
215
215
|
socketInstance.on('transaction:update', (data) => {
|
|
@@ -368,7 +368,7 @@ export function LiberExProvider({ children }: { children: React.ReactNode }) {
|
|
|
368
368
|
}, [socket]);
|
|
369
369
|
{{/if}}
|
|
370
370
|
|
|
371
|
-
const value:
|
|
371
|
+
const value: DiviswapContextValue = {
|
|
372
372
|
customerId,
|
|
373
373
|
customerEmail,
|
|
374
374
|
loading,
|
|
@@ -393,16 +393,16 @@ export function LiberExProvider({ children }: { children: React.ReactNode }) {
|
|
|
393
393
|
};
|
|
394
394
|
|
|
395
395
|
return (
|
|
396
|
-
<
|
|
396
|
+
<DiviswapContext.Provider value={value}>
|
|
397
397
|
{children}
|
|
398
|
-
</
|
|
398
|
+
</DiviswapContext.Provider>
|
|
399
399
|
);
|
|
400
400
|
}
|
|
401
401
|
|
|
402
|
-
export function
|
|
403
|
-
const context = useContext(
|
|
402
|
+
export function useDiviswap() {
|
|
403
|
+
const context = useContext(DiviswapContext);
|
|
404
404
|
if (!context) {
|
|
405
|
-
throw new Error('
|
|
405
|
+
throw new Error('useDiviswap must be used within a DiviswapProvider');
|
|
406
406
|
}
|
|
407
407
|
return context;
|
|
408
408
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Add this to your root layout.tsx to enable
|
|
2
|
+
* Add this to your root layout.tsx to enable Diviswap functionality
|
|
3
3
|
*
|
|
4
4
|
* Example:
|
|
5
5
|
*
|
|
6
|
-
* import {
|
|
6
|
+
* import { DiviswapProvider } from '@diviswap/sdk/react';
|
|
7
7
|
*
|
|
8
8
|
* export default function RootLayout({
|
|
9
9
|
* children,
|
|
@@ -13,9 +13,9 @@
|
|
|
13
13
|
* return (
|
|
14
14
|
* <html lang="en">
|
|
15
15
|
* <body>
|
|
16
|
-
* <
|
|
16
|
+
* <DiviswapProvider>
|
|
17
17
|
* {children}
|
|
18
|
-
* </
|
|
18
|
+
* </DiviswapProvider>
|
|
19
19
|
* </body>
|
|
20
20
|
* </html>
|
|
21
21
|
* );
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* API client wrapper for custom backend integration
|
|
3
|
-
* This allows you to proxy
|
|
3
|
+
* This allows you to proxy Diviswap API calls through your own backend
|
|
4
4
|
* for additional security and custom logic
|
|
5
5
|
*/
|
|
6
6
|
|
|
@@ -40,46 +40,46 @@ class ApiClient {
|
|
|
40
40
|
return response.json();
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
//
|
|
44
|
-
|
|
43
|
+
// Diviswap-specific endpoints
|
|
44
|
+
diviswap = {
|
|
45
45
|
// Authentication
|
|
46
46
|
login: (email: string, password: string) =>
|
|
47
|
-
this.request('/
|
|
47
|
+
this.request('/diviswap', {
|
|
48
48
|
method: 'POST',
|
|
49
49
|
body: JSON.stringify({ action: 'login', email, password }),
|
|
50
50
|
}),
|
|
51
51
|
|
|
52
52
|
logout: () =>
|
|
53
|
-
this.request('/
|
|
53
|
+
this.request('/diviswap', {
|
|
54
54
|
method: 'POST',
|
|
55
55
|
body: JSON.stringify({ action: 'logout' }),
|
|
56
56
|
}),
|
|
57
57
|
|
|
58
58
|
getSession: () =>
|
|
59
|
-
this.request('/
|
|
59
|
+
this.request('/diviswap', { params: { resource: 'session' } }),
|
|
60
60
|
|
|
61
61
|
// Transactions
|
|
62
62
|
createTransaction: (data: any) =>
|
|
63
|
-
this.request('/
|
|
63
|
+
this.request('/diviswap', {
|
|
64
64
|
method: 'POST',
|
|
65
65
|
body: JSON.stringify({ action: 'createTransaction', ...data }),
|
|
66
66
|
}),
|
|
67
67
|
|
|
68
68
|
getTransactions: (filters?: any) =>
|
|
69
|
-
this.request('/
|
|
69
|
+
this.request('/diviswap', { params: { resource: 'transactions', ...filters } }),
|
|
70
70
|
|
|
71
71
|
// Payees
|
|
72
72
|
createPayee: (data: any) =>
|
|
73
|
-
this.request('/
|
|
73
|
+
this.request('/diviswap', {
|
|
74
74
|
method: 'POST',
|
|
75
75
|
body: JSON.stringify({ action: 'createPayee', ...data }),
|
|
76
76
|
}),
|
|
77
77
|
|
|
78
78
|
getPayees: () =>
|
|
79
|
-
this.request('/
|
|
79
|
+
this.request('/diviswap', { params: { resource: 'payees' } }),
|
|
80
80
|
|
|
81
81
|
deletePayee: (id: string) =>
|
|
82
|
-
this.request('/
|
|
82
|
+
this.request('/diviswap', {
|
|
83
83
|
method: 'DELETE',
|
|
84
84
|
params: { resource: 'payee', id },
|
|
85
85
|
}),
|