@diviswap/sdk 1.7.11 → 1.7.14
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 +8 -2
- package/dist/cli/templates/nextjs-app/actions.ts.hbs +32 -32
- 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 +5 -5
- package/dist/cli/templates/nextjs-app/dashboard-hooks.ts.hbs +7 -7
- package/dist/cli/templates/nextjs-app/example-page.tsx.hbs +5 -5
- package/dist/cli/templates/nextjs-app/hooks.ts.hbs +7 -7
- package/dist/cli/templates/nextjs-app/kyc-hooks.ts.hbs +3 -3
- package/dist/cli/templates/nextjs-app/kyc-wizard.css.hbs +16 -16
- package/dist/cli/templates/nextjs-app/kyc-wizard.tsx.hbs +24 -24
- 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 +16 -16
- package/dist/cli/templates/nextjs-app/setup-provider.tsx.hbs +4 -4
- package/dist/cli/templates/react/api-client-wrapper.ts.hbs +13 -13
- 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 +2 -1
- package/src/cli/templates/index.ts +13 -2
- package/src/cli/templates/nextjs-app/actions.ts.hbs +32 -32
- 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 +5 -5
- package/src/cli/templates/nextjs-app/dashboard-hooks.ts.hbs +7 -7
- package/src/cli/templates/nextjs-app/example-page.tsx.hbs +5 -5
- package/src/cli/templates/nextjs-app/hooks.ts.hbs +7 -7
- package/src/cli/templates/nextjs-app/kyc-hooks.ts.hbs +3 -3
- package/src/cli/templates/nextjs-app/kyc-wizard.css.hbs +16 -16
- package/src/cli/templates/nextjs-app/kyc-wizard.tsx.hbs +24 -24
- 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 +16 -16
- package/src/cli/templates/nextjs-app/setup-provider.tsx.hbs +4 -4
- package/src/cli/templates/react/api-client-wrapper.ts.hbs +13 -13
- 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
|
@@ -82,7 +82,7 @@ export function LiberexKYC({
|
|
|
82
82
|
setIsSubmitting(true);
|
|
83
83
|
try {
|
|
84
84
|
// Format date of birth
|
|
85
|
-
const dateOfBirth =
|
|
85
|
+
const dateOfBirth = formData.dobYear + '-' + formData.dobMonth.padStart(2, '0') + '-' + formData.dobDay.padStart(2, '0');
|
|
86
86
|
|
|
87
87
|
// Prepare KYC data
|
|
88
88
|
const kycData = {
|
|
@@ -106,7 +106,7 @@ export function LiberexKYC({
|
|
|
106
106
|
};
|
|
107
107
|
|
|
108
108
|
// Call your KYC submission API
|
|
109
|
-
const response = await fetch('/api/
|
|
109
|
+
const response = await fetch('/api/liberex', {
|
|
110
110
|
method: 'POST',
|
|
111
111
|
headers: { 'Content-Type': 'application/json' },
|
|
112
112
|
body: JSON.stringify({
|
|
@@ -155,32 +155,32 @@ export function LiberexKYC({
|
|
|
155
155
|
};
|
|
156
156
|
|
|
157
157
|
const updateFormData = (updates: Partial<KycFormData>) => {
|
|
158
|
-
setFormData(prev => ({ ...prev, ...updates }));
|
|
158
|
+
setFormData(prev => (\{{ ...prev, ...updates \}}));
|
|
159
159
|
};
|
|
160
160
|
|
|
161
|
-
const containerStyle = {
|
|
161
|
+
const containerStyle = \{{
|
|
162
162
|
backgroundColor: themeConfig.backgroundColor,
|
|
163
163
|
color: themeConfig.textColor,
|
|
164
164
|
borderRadius: themeConfig.borderRadius
|
|
165
|
-
};
|
|
165
|
+
\}};
|
|
166
166
|
|
|
167
|
-
const primaryButtonStyle = {
|
|
167
|
+
const primaryButtonStyle = \{{
|
|
168
168
|
backgroundColor: themeConfig.primaryColor,
|
|
169
169
|
borderRadius: themeConfig.borderRadius
|
|
170
|
-
};
|
|
170
|
+
\}};
|
|
171
171
|
|
|
172
172
|
return (
|
|
173
|
-
<div className={`
|
|
173
|
+
<div className={`liberex-kyc-container ${className}`} style={containerStyle}>
|
|
174
174
|
{/* Progress Bar */}
|
|
175
175
|
{currentStep !== 'intro' && currentStep !== 'success' && (
|
|
176
176
|
<div className="progress-container">
|
|
177
177
|
<div className="progress-bar">
|
|
178
|
-
<div
|
|
179
|
-
className="progress-fill"
|
|
180
|
-
style
|
|
181
|
-
width:
|
|
182
|
-
backgroundColor: themeConfig.primaryColor
|
|
183
|
-
}}
|
|
178
|
+
<div
|
|
179
|
+
className="progress-fill"
|
|
180
|
+
style=\{{
|
|
181
|
+
width: progressPercentage + '%',
|
|
182
|
+
backgroundColor: themeConfig.primaryColor
|
|
183
|
+
\}}
|
|
184
184
|
/>
|
|
185
185
|
</div>
|
|
186
186
|
<div className="progress-text">
|
|
@@ -253,7 +253,7 @@ function IntroStep({ onNext, onClose, theme }: any) {
|
|
|
253
253
|
return (
|
|
254
254
|
<div className="kyc-step intro-step">
|
|
255
255
|
<div className="step-header">
|
|
256
|
-
<CheckCircle className="step-icon" style
|
|
256
|
+
<CheckCircle className="step-icon" style=\{{ color: theme.primaryColor \}} />
|
|
257
257
|
<h2>Identity Verification</h2>
|
|
258
258
|
<p>We need to verify your identity to comply with financial regulations. This process takes about 3 minutes.</p>
|
|
259
259
|
</div>
|
|
@@ -286,7 +286,7 @@ function IntroStep({ onNext, onClose, theme }: any) {
|
|
|
286
286
|
<button
|
|
287
287
|
onClick={onNext}
|
|
288
288
|
className="btn-primary"
|
|
289
|
-
style
|
|
289
|
+
style=\{{ backgroundColor: theme.primaryColor \}}
|
|
290
290
|
>
|
|
291
291
|
Start Verification
|
|
292
292
|
<ArrowRight className="btn-icon" />
|
|
@@ -402,7 +402,7 @@ function PersonalInfoStep({ formData, updateFormData, onNext, onPrev, theme }: a
|
|
|
402
402
|
onClick={onNext}
|
|
403
403
|
disabled={!isValid}
|
|
404
404
|
className="btn-primary"
|
|
405
|
-
style
|
|
405
|
+
style=\{{ backgroundColor: theme.primaryColor \}}
|
|
406
406
|
>
|
|
407
407
|
Continue
|
|
408
408
|
<ArrowRight className="btn-icon" />
|
|
@@ -465,7 +465,7 @@ function IdentificationStep({ formData, updateFormData, onNext, onPrev, theme }:
|
|
|
465
465
|
onClick={onNext}
|
|
466
466
|
disabled={!isValid}
|
|
467
467
|
className="btn-primary"
|
|
468
|
-
style
|
|
468
|
+
style=\{{ backgroundColor: theme.primaryColor \}}
|
|
469
469
|
>
|
|
470
470
|
Continue
|
|
471
471
|
<ArrowRight className="btn-icon" />
|
|
@@ -567,7 +567,7 @@ function AddressStep({ formData, updateFormData, onNext, onPrev, theme }: any) {
|
|
|
567
567
|
onClick={onNext}
|
|
568
568
|
disabled={!isValid}
|
|
569
569
|
className="btn-primary"
|
|
570
|
-
style
|
|
570
|
+
style=\{{ backgroundColor: theme.primaryColor \}}
|
|
571
571
|
>
|
|
572
572
|
Continue
|
|
573
573
|
<ArrowRight className="btn-icon" />
|
|
@@ -643,7 +643,7 @@ function ReviewStep({ formData, onSubmit, onPrev, isSubmitting, theme }: any) {
|
|
|
643
643
|
onClick={onSubmit}
|
|
644
644
|
disabled={isSubmitting}
|
|
645
645
|
className="btn-primary"
|
|
646
|
-
style
|
|
646
|
+
style=\{{ backgroundColor: theme.primaryColor \}}
|
|
647
647
|
>
|
|
648
648
|
{isSubmitting ? (
|
|
649
649
|
<>
|
|
@@ -666,7 +666,7 @@ function SuccessStep({ onClose, theme }: any) {
|
|
|
666
666
|
return (
|
|
667
667
|
<div className="kyc-step success-step">
|
|
668
668
|
<div className="step-header">
|
|
669
|
-
<CheckCircle className="step-icon success-icon" style
|
|
669
|
+
<CheckCircle className="step-icon success-icon" style=\{{ color: theme.primaryColor \}} />
|
|
670
670
|
<h2>Verification Submitted!</h2>
|
|
671
671
|
<p>Your identity verification has been submitted successfully. We'll review your information and notify you of the results.</p>
|
|
672
672
|
</div>
|
|
@@ -687,7 +687,7 @@ function SuccessStep({ onClose, theme }: any) {
|
|
|
687
687
|
<button
|
|
688
688
|
onClick={onClose}
|
|
689
689
|
className="btn-primary"
|
|
690
|
-
style
|
|
690
|
+
style=\{{ backgroundColor: theme.primaryColor \}}
|
|
691
691
|
>
|
|
692
692
|
Continue
|
|
693
693
|
</button>
|
|
@@ -702,8 +702,8 @@ export function LiberexKYCModal({ isOpen, onClose, ...props }: LiberexKYCProps &
|
|
|
702
702
|
if (!isOpen) return null;
|
|
703
703
|
|
|
704
704
|
return (
|
|
705
|
-
<div className="
|
|
706
|
-
<div className="
|
|
705
|
+
<div className="liberex-kyc-modal-overlay">
|
|
706
|
+
<div className="liberex-kyc-modal">
|
|
707
707
|
<LiberexKYC {...props} onClose={onClose} />
|
|
708
708
|
</div>
|
|
709
709
|
</div>
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { LiberExProvider } from '@99darwin/liberex-sdk/react';
|
|
2
2
|
|
|
3
|
-
export default function
|
|
3
|
+
export default function LiberExLayout({
|
|
4
4
|
children,
|
|
5
5
|
}: {
|
|
6
6
|
children: React.ReactNode;
|
|
7
7
|
}) {
|
|
8
8
|
return (
|
|
9
|
-
<
|
|
9
|
+
<LiberExProvider>
|
|
10
10
|
{children}
|
|
11
|
-
</
|
|
11
|
+
</LiberExProvider>
|
|
12
12
|
);
|
|
13
13
|
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { LiberExProvider } from './lbx-provider';
|
|
2
2
|
|
|
3
|
-
export default function
|
|
3
|
+
export default function LiberExLayout({
|
|
4
4
|
children,
|
|
5
5
|
}: {
|
|
6
6
|
children: React.ReactNode;
|
|
7
7
|
}) {
|
|
8
8
|
return (
|
|
9
|
-
<
|
|
9
|
+
<LiberExProvider>
|
|
10
10
|
{children}
|
|
11
|
-
</
|
|
11
|
+
</LiberExProvider>
|
|
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 LiberEx 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 liberexMiddleware(request: NextRequest) {
|
|
6
|
+
// Check for LiberEx session cookie
|
|
7
|
+
const liberexSession = request.cookies.get('liberex_session');
|
|
8
8
|
|
|
9
|
-
if (!
|
|
9
|
+
if (!liberexSession) {
|
|
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-liberex-session', liberexSession.value);
|
|
17
17
|
|
|
18
18
|
// You can also add other headers or perform additional checks here
|
|
19
|
-
requestHeaders.set('x-
|
|
19
|
+
requestHeaders.set('x-liberex-client-version', '1.0.0');
|
|
20
20
|
|
|
21
21
|
return NextResponse.next({
|
|
22
22
|
request: {
|
|
@@ -26,24 +26,24 @@ export function diviswapMiddleware(request: NextRequest) {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
// Optional: Add route protection
|
|
29
|
-
export function
|
|
30
|
-
const
|
|
29
|
+
export function protectLiberExRoutes(request: NextRequest) {
|
|
30
|
+
const liberexSession = request.cookies.get('liberex_session');
|
|
31
31
|
|
|
32
32
|
// List of protected routes
|
|
33
33
|
const protectedRoutes = [
|
|
34
|
-
'/
|
|
35
|
-
'/
|
|
36
|
-
'/
|
|
34
|
+
'/liberex/dashboard',
|
|
35
|
+
'/liberex/transactions',
|
|
36
|
+
'/liberex/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 && !liberexSession) {
|
|
44
44
|
// Redirect to login page
|
|
45
|
-
return NextResponse.redirect(new URL('/
|
|
45
|
+
return NextResponse.redirect(new URL('/liberex', request.url));
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
return
|
|
48
|
+
return liberexMiddleware(request);
|
|
49
49
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { LiberExProvider } from '@99darwin/liberex-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 LiberEx components
|
|
6
|
+
export function LiberExClientProvider({ children }: { children: React.ReactNode }) {
|
|
7
|
+
return <LiberExProvider>{children}</LiberExProvider>;
|
|
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 LiberExContextValue {
|
|
10
10
|
// Customer state (for partner authentication)
|
|
11
11
|
customerId: string | null;
|
|
12
12
|
customerEmail: string | null;
|
|
@@ -63,17 +63,17 @@ interface DiviswapContextValue {
|
|
|
63
63
|
{{/if}}
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
const
|
|
66
|
+
const LiberExContext = createContext<LiberExContextValue | null>(null);
|
|
67
67
|
|
|
68
68
|
// API client class
|
|
69
|
-
class
|
|
70
|
-
constructor(private baseUrl: string = '/api/
|
|
69
|
+
class LiberExClient {
|
|
70
|
+
constructor(private baseUrl: string = '/api/liberex') {}
|
|
71
71
|
|
|
72
72
|
private async request<T = any>(
|
|
73
73
|
endpoint: string,
|
|
74
74
|
options: RequestInit = {}
|
|
75
75
|
): Promise<T> {
|
|
76
|
-
const response = await fetch(
|
|
76
|
+
const response = await fetch(this.baseUrl + endpoint, {
|
|
77
77
|
...options,
|
|
78
78
|
headers: {
|
|
79
79
|
'Content-Type': 'application/json',
|
|
@@ -168,7 +168,7 @@ class DiviswapClient {
|
|
|
168
168
|
{{/if}}
|
|
169
169
|
}
|
|
170
170
|
|
|
171
|
-
export function
|
|
171
|
+
export function LiberExProvider({ 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 DiviswapProvider({ 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 LiberExClient('/api/liberex');
|
|
181
181
|
|
|
182
182
|
// Initialize with demo customer for development
|
|
183
183
|
useEffect(() => {
|
|
@@ -192,7 +192,7 @@ export function DiviswapProvider({ 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_LIBEREX_WS_URL || 'wss://ws.liberex.io',
|
|
196
196
|
{
|
|
197
197
|
auth: {
|
|
198
198
|
customerId,
|
|
@@ -205,11 +205,11 @@ export function DiviswapProvider({ children }: { children: React.ReactNode }) {
|
|
|
205
205
|
);
|
|
206
206
|
|
|
207
207
|
socketInstance.on('connect', () => {
|
|
208
|
-
console.log('Connected to
|
|
208
|
+
console.log('Connected to LiberEx WebSocket');
|
|
209
209
|
});
|
|
210
210
|
|
|
211
211
|
socketInstance.on('disconnect', () => {
|
|
212
|
-
console.log('Disconnected from
|
|
212
|
+
console.log('Disconnected from LiberEx WebSocket');
|
|
213
213
|
});
|
|
214
214
|
|
|
215
215
|
socketInstance.on('transaction:update', (data) => {
|
|
@@ -368,7 +368,7 @@ export function DiviswapProvider({ children }: { children: React.ReactNode }) {
|
|
|
368
368
|
}, [socket]);
|
|
369
369
|
{{/if}}
|
|
370
370
|
|
|
371
|
-
const value:
|
|
371
|
+
const value: LiberExContextValue = {
|
|
372
372
|
customerId,
|
|
373
373
|
customerEmail,
|
|
374
374
|
loading,
|
|
@@ -393,16 +393,16 @@ export function DiviswapProvider({ children }: { children: React.ReactNode }) {
|
|
|
393
393
|
};
|
|
394
394
|
|
|
395
395
|
return (
|
|
396
|
-
<
|
|
396
|
+
<LiberExContext.Provider value={value}>
|
|
397
397
|
{children}
|
|
398
|
-
</
|
|
398
|
+
</LiberExContext.Provider>
|
|
399
399
|
);
|
|
400
400
|
}
|
|
401
401
|
|
|
402
|
-
export function
|
|
403
|
-
const context = useContext(
|
|
402
|
+
export function useLiberEx() {
|
|
403
|
+
const context = useContext(LiberExContext);
|
|
404
404
|
if (!context) {
|
|
405
|
-
throw new Error('
|
|
405
|
+
throw new Error('useLiberEx must be used within a LiberExProvider');
|
|
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 LiberEx functionality
|
|
3
3
|
*
|
|
4
4
|
* Example:
|
|
5
5
|
*
|
|
6
|
-
* import {
|
|
6
|
+
* import { LiberExProvider } from '@99darwin/liberex-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
|
+
* <LiberExProvider>
|
|
17
17
|
* {children}
|
|
18
|
-
* </
|
|
18
|
+
* </LiberExProvider>
|
|
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 LiberEx API calls through your own backend
|
|
4
4
|
* for additional security and custom logic
|
|
5
5
|
*/
|
|
6
6
|
|
|
@@ -18,10 +18,10 @@ class ApiClient {
|
|
|
18
18
|
private async request<T = any>(endpoint: string, options: ApiOptions = {}): Promise<T> {
|
|
19
19
|
const { params, ...fetchOptions } = options;
|
|
20
20
|
|
|
21
|
-
let url =
|
|
21
|
+
let url = this.baseUrl + endpoint;
|
|
22
22
|
if (params) {
|
|
23
23
|
const searchParams = new URLSearchParams(params);
|
|
24
|
-
url +=
|
|
24
|
+
url += '?' + searchParams.toString();
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
const response = await fetch(url, {
|
|
@@ -40,46 +40,46 @@ class ApiClient {
|
|
|
40
40
|
return response.json();
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
//
|
|
44
|
-
|
|
43
|
+
// LiberEx-specific endpoints
|
|
44
|
+
liberex = {
|
|
45
45
|
// Authentication
|
|
46
46
|
login: (email: string, password: string) =>
|
|
47
|
-
this.request('/
|
|
47
|
+
this.request('/liberex', {
|
|
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('/liberex', {
|
|
54
54
|
method: 'POST',
|
|
55
55
|
body: JSON.stringify({ action: 'logout' }),
|
|
56
56
|
}),
|
|
57
57
|
|
|
58
58
|
getSession: () =>
|
|
59
|
-
this.request('/
|
|
59
|
+
this.request('/liberex', { params: { resource: 'session' } }),
|
|
60
60
|
|
|
61
61
|
// Transactions
|
|
62
62
|
createTransaction: (data: any) =>
|
|
63
|
-
this.request('/
|
|
63
|
+
this.request('/liberex', {
|
|
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('/liberex', { params: { resource: 'transactions', ...filters } }),
|
|
70
70
|
|
|
71
71
|
// Payees
|
|
72
72
|
createPayee: (data: any) =>
|
|
73
|
-
this.request('/
|
|
73
|
+
this.request('/liberex', {
|
|
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('/liberex', { params: { resource: 'payees' } }),
|
|
80
80
|
|
|
81
81
|
deletePayee: (id: string) =>
|
|
82
|
-
this.request('/
|
|
82
|
+
this.request('/liberex', {
|
|
83
83
|
method: 'DELETE',
|
|
84
84
|
params: { resource: 'payee', id },
|
|
85
85
|
}),
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { LiberExProvider, useLiberEx } from '@99darwin/liberex-sdk/react';
|
|
3
3
|
import { apiClient } from './api-client';
|
|
4
4
|
|
|
5
5
|
function TransactionDemo() {
|
|
@@ -11,7 +11,7 @@ function TransactionDemo() {
|
|
|
11
11
|
logout,
|
|
12
12
|
createTransaction,
|
|
13
13
|
getTransactions
|
|
14
|
-
} =
|
|
14
|
+
} = useLiberEx();
|
|
15
15
|
|
|
16
16
|
const handleLogin = async () => {
|
|
17
17
|
try {
|
|
@@ -44,8 +44,8 @@ function TransactionDemo() {
|
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
return (
|
|
47
|
-
<div className="
|
|
48
|
-
<h1>
|
|
47
|
+
<div className="liberex-demo">
|
|
48
|
+
<h1>LiberEx Demo</h1>
|
|
49
49
|
|
|
50
50
|
{!user ? (
|
|
51
51
|
<button onClick={handleLogin}>Login</button>
|
|
@@ -62,8 +62,8 @@ function TransactionDemo() {
|
|
|
62
62
|
|
|
63
63
|
export default function App() {
|
|
64
64
|
return (
|
|
65
|
-
<
|
|
65
|
+
<LiberExProvider>
|
|
66
66
|
<TransactionDemo />
|
|
67
|
-
</
|
|
67
|
+
</LiberExProvider>
|
|
68
68
|
);
|
|
69
69
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Example of using TanStack Query with
|
|
2
|
+
* Example of using TanStack Query with LiberEx API routes
|
|
3
3
|
* This provides automatic caching, background refetching, and optimistic updates
|
|
4
4
|
*/
|
|
5
5
|
|
|
@@ -8,17 +8,17 @@ import { apiClient } from './api-client';
|
|
|
8
8
|
|
|
9
9
|
// Query keys for cache invalidation
|
|
10
10
|
const queryKeys = {
|
|
11
|
-
user: ['
|
|
12
|
-
transactions: (filters?: any) => ['
|
|
13
|
-
payees: ['
|
|
14
|
-
fees: (amount: number) => ['
|
|
11
|
+
user: ['liberex', 'user'],
|
|
12
|
+
transactions: (filters?: any) => ['liberex', 'transactions', filters],
|
|
13
|
+
payees: ['liberex', 'payees'],
|
|
14
|
+
fees: (amount: number) => ['liberex', 'fees', amount],
|
|
15
15
|
};
|
|
16
16
|
|
|
17
17
|
// User hooks
|
|
18
18
|
export function useUser() {
|
|
19
19
|
return useQuery({
|
|
20
20
|
queryKey: queryKeys.user,
|
|
21
|
-
queryFn: () => apiClient.
|
|
21
|
+
queryFn: () => apiClient.liberex.getSession(),
|
|
22
22
|
retry: false,
|
|
23
23
|
staleTime: 5 * 60 * 1000, // 5 minutes
|
|
24
24
|
});
|
|
@@ -29,7 +29,7 @@ export function useLogin() {
|
|
|
29
29
|
|
|
30
30
|
return useMutation({
|
|
31
31
|
mutationFn: ({ email, password }: { email: string; password: string }) =>
|
|
32
|
-
apiClient.
|
|
32
|
+
apiClient.liberex.login(email, password),
|
|
33
33
|
onSuccess: (data) => {
|
|
34
34
|
queryClient.setQueryData(queryKeys.user, data.user);
|
|
35
35
|
queryClient.invalidateQueries({ queryKey: queryKeys.transactions() });
|
|
@@ -42,7 +42,7 @@ export function useLogout() {
|
|
|
42
42
|
const queryClient = useQueryClient();
|
|
43
43
|
|
|
44
44
|
return useMutation({
|
|
45
|
-
mutationFn: () => apiClient.
|
|
45
|
+
mutationFn: () => apiClient.liberex.logout(),
|
|
46
46
|
onSuccess: () => {
|
|
47
47
|
queryClient.clear(); // Clear all cached data
|
|
48
48
|
},
|
|
@@ -55,7 +55,7 @@ export function useTransactions(filters?: any) {
|
|
|
55
55
|
|
|
56
56
|
return useQuery({
|
|
57
57
|
queryKey: queryKeys.transactions(filters),
|
|
58
|
-
queryFn: () => apiClient.
|
|
58
|
+
queryFn: () => apiClient.liberex.getTransactions(filters),
|
|
59
59
|
enabled: !!user, // Only fetch if user is authenticated
|
|
60
60
|
staleTime: 30 * 1000, // 30 seconds
|
|
61
61
|
});
|
|
@@ -65,7 +65,7 @@ export function useCreateTransaction() {
|
|
|
65
65
|
const queryClient = useQueryClient();
|
|
66
66
|
|
|
67
67
|
return useMutation({
|
|
68
|
-
mutationFn: (data: any) => apiClient.
|
|
68
|
+
mutationFn: (data: any) => apiClient.liberex.createTransaction(data),
|
|
69
69
|
onSuccess: () => {
|
|
70
70
|
// Invalidate and refetch transactions
|
|
71
71
|
queryClient.invalidateQueries({ queryKey: queryKeys.transactions() });
|
|
@@ -82,7 +82,7 @@ export function usePayees() {
|
|
|
82
82
|
|
|
83
83
|
return useQuery({
|
|
84
84
|
queryKey: queryKeys.payees,
|
|
85
|
-
queryFn: () => apiClient.
|
|
85
|
+
queryFn: () => apiClient.liberex.getPayees(),
|
|
86
86
|
enabled: !!user,
|
|
87
87
|
staleTime: 60 * 1000, // 1 minute
|
|
88
88
|
});
|
|
@@ -92,7 +92,7 @@ export function useCreatePayee() {
|
|
|
92
92
|
const queryClient = useQueryClient();
|
|
93
93
|
|
|
94
94
|
return useMutation({
|
|
95
|
-
mutationFn: (data: any) => apiClient.
|
|
95
|
+
mutationFn: (data: any) => apiClient.liberex.createPayee(data),
|
|
96
96
|
onSuccess: (newPayee) => {
|
|
97
97
|
// Optimistically add the new payee to the cache
|
|
98
98
|
queryClient.setQueryData(queryKeys.payees, (old: any[] = []) => {
|
|
@@ -106,7 +106,7 @@ export function useDeletePayee() {
|
|
|
106
106
|
const queryClient = useQueryClient();
|
|
107
107
|
|
|
108
108
|
return useMutation({
|
|
109
|
-
mutationFn: (id: string) => apiClient.
|
|
109
|
+
mutationFn: (id: string) => apiClient.liberex.deletePayee(id),
|
|
110
110
|
onMutate: async (deletedId) => {
|
|
111
111
|
// Cancel in-flight queries
|
|
112
112
|
await queryClient.cancelQueries({ queryKey: queryKeys.payees });
|
|
@@ -139,7 +139,7 @@ export function useDeletePayee() {
|
|
|
139
139
|
export function useFeeCalculation(amount: number, enabled = true) {
|
|
140
140
|
return useQuery({
|
|
141
141
|
queryKey: queryKeys.fees(amount),
|
|
142
|
-
queryFn: () => apiClient.
|
|
142
|
+
queryFn: () => apiClient.liberex.calculateFees(amount),
|
|
143
143
|
enabled: enabled && amount > 0,
|
|
144
144
|
staleTime: 5 * 60 * 1000, // 5 minutes
|
|
145
145
|
gcTime: 10 * 60 * 1000, // 10 minutes (formerly cacheTime)
|
|
@@ -24,7 +24,7 @@ export async function POST(request: NextRequest) {
|
|
|
24
24
|
const rawBody = await request.text();
|
|
25
25
|
|
|
26
26
|
// Get signature from headers
|
|
27
|
-
const signature = request.headers.get('x-
|
|
27
|
+
const signature = request.headers.get('x-liberex-signature');
|
|
28
28
|
|
|
29
29
|
if (!signature) {
|
|
30
30
|
return NextResponse.json(
|
|
@@ -34,9 +34,9 @@ export async function POST(request: NextRequest) {
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
// Verify signature
|
|
37
|
-
const webhookSecret = process.env.
|
|
37
|
+
const webhookSecret = process.env.LIBEREX_WEBHOOK_SECRET;
|
|
38
38
|
if (!webhookSecret) {
|
|
39
|
-
console.error('
|
|
39
|
+
console.error('LIBEREX_WEBHOOK_SECRET not configured');
|
|
40
40
|
return NextResponse.json(
|
|
41
41
|
{ error: 'Webhook secret not configured' },
|
|
42
42
|
{ status: 500 }
|