@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,89 @@
1
+ /**
2
+ * API client wrapper for custom backend integration
3
+ * This allows you to proxy Diviswap API calls through your own backend
4
+ * for additional security and custom logic
5
+ */
6
+
7
+ interface ApiOptions extends RequestInit {
8
+ params?: Record<string, any>;
9
+ }
10
+
11
+ class ApiClient {
12
+ private baseUrl: string;
13
+
14
+ constructor(baseUrl = '/api') {
15
+ this.baseUrl = baseUrl;
16
+ }
17
+
18
+ private async request<T = any>(endpoint: string, options: ApiOptions = {}): Promise<T> {
19
+ const { params, ...fetchOptions } = options;
20
+
21
+ let url = `${this.baseUrl}${endpoint}`;
22
+ if (params) {
23
+ const searchParams = new URLSearchParams(params);
24
+ url += `?${searchParams.toString()}`;
25
+ }
26
+
27
+ const response = await fetch(url, {
28
+ headers: {
29
+ 'Content-Type': 'application/json',
30
+ ...fetchOptions.headers,
31
+ },
32
+ ...fetchOptions,
33
+ });
34
+
35
+ if (!response.ok) {
36
+ const error = await response.json().catch(() => ({ message: 'Request failed' }));
37
+ throw new Error(error.message || `HTTP ${response.status}`);
38
+ }
39
+
40
+ return response.json();
41
+ }
42
+
43
+ // Diviswap-specific endpoints
44
+ diviswap = {
45
+ // Authentication
46
+ login: (email: string, password: string) =>
47
+ this.request('/diviswap', {
48
+ method: 'POST',
49
+ body: JSON.stringify({ action: 'login', email, password }),
50
+ }),
51
+
52
+ logout: () =>
53
+ this.request('/diviswap', {
54
+ method: 'POST',
55
+ body: JSON.stringify({ action: 'logout' }),
56
+ }),
57
+
58
+ getSession: () =>
59
+ this.request('/diviswap', { params: { resource: 'session' } }),
60
+
61
+ // Transactions
62
+ createTransaction: (data: any) =>
63
+ this.request('/diviswap', {
64
+ method: 'POST',
65
+ body: JSON.stringify({ action: 'createTransaction', ...data }),
66
+ }),
67
+
68
+ getTransactions: (filters?: any) =>
69
+ this.request('/diviswap', { params: { resource: 'transactions', ...filters } }),
70
+
71
+ // Payees
72
+ createPayee: (data: any) =>
73
+ this.request('/diviswap', {
74
+ method: 'POST',
75
+ body: JSON.stringify({ action: 'createPayee', ...data }),
76
+ }),
77
+
78
+ getPayees: () =>
79
+ this.request('/diviswap', { params: { resource: 'payees' } }),
80
+
81
+ deletePayee: (id: string) =>
82
+ this.request('/diviswap', {
83
+ method: 'DELETE',
84
+ params: { resource: 'payee', id },
85
+ }),
86
+ };
87
+ }
88
+
89
+ export const apiClient = new ApiClient();
@@ -0,0 +1,69 @@
1
+ import React from 'react';
2
+ import { DiviswapProvider, useDiviswap } from '@diviswap/sdk/react';
3
+ import { apiClient } from './api-client';
4
+
5
+ function TransactionDemo() {
6
+ const {
7
+ user,
8
+ loading,
9
+ error,
10
+ login,
11
+ logout,
12
+ createTransaction,
13
+ getTransactions
14
+ } = useDiviswap();
15
+
16
+ const handleLogin = async () => {
17
+ try {
18
+ await login('user@example.com', 'password');
19
+ } catch (error) {
20
+ console.error('Login failed:', error);
21
+ }
22
+ };
23
+
24
+ const handleOnramp = async () => {
25
+ try {
26
+ const transaction = await createTransaction({
27
+ amount: 100,
28
+ currency: 'USD',
29
+ address: '0x...',
30
+ chain: 'ethereum'
31
+ });
32
+ console.log('Transaction created:', transaction);
33
+ } catch (error) {
34
+ console.error('Transaction failed:', error);
35
+ }
36
+ };
37
+
38
+ if (loading) {
39
+ return <div>Loading...</div>;
40
+ }
41
+
42
+ if (error) {
43
+ return <div>Error: {error.message}</div>;
44
+ }
45
+
46
+ return (
47
+ <div className="diviswap-demo">
48
+ <h1>Diviswap Demo</h1>
49
+
50
+ {!user ? (
51
+ <button onClick={handleLogin}>Login</button>
52
+ ) : (
53
+ <div>
54
+ <p>Welcome, {user.email}!</p>
55
+ <button onClick={handleOnramp}>Create Onramp Transaction</button>
56
+ <button onClick={logout}>Logout</button>
57
+ </div>
58
+ )}
59
+ </div>
60
+ );
61
+ }
62
+
63
+ export default function App() {
64
+ return (
65
+ <DiviswapProvider>
66
+ <TransactionDemo />
67
+ </DiviswapProvider>
68
+ );
69
+ }
@@ -0,0 +1,185 @@
1
+ /**
2
+ * Example of using TanStack Query with Diviswap API routes
3
+ * This provides automatic caching, background refetching, and optimistic updates
4
+ */
5
+
6
+ import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
7
+ import { apiClient } from './api-client';
8
+
9
+ // Query keys for cache invalidation
10
+ const queryKeys = {
11
+ user: ['diviswap', 'user'],
12
+ transactions: (filters?: any) => ['diviswap', 'transactions', filters],
13
+ payees: ['diviswap', 'payees'],
14
+ fees: (amount: number) => ['diviswap', 'fees', amount],
15
+ };
16
+
17
+ // User hooks
18
+ export function useUser() {
19
+ return useQuery({
20
+ queryKey: queryKeys.user,
21
+ queryFn: () => apiClient.diviswap.getSession(),
22
+ retry: false,
23
+ staleTime: 5 * 60 * 1000, // 5 minutes
24
+ });
25
+ }
26
+
27
+ export function useLogin() {
28
+ const queryClient = useQueryClient();
29
+
30
+ return useMutation({
31
+ mutationFn: ({ email, password }: { email: string; password: string }) =>
32
+ apiClient.diviswap.login(email, password),
33
+ onSuccess: (data) => {
34
+ queryClient.setQueryData(queryKeys.user, data.user);
35
+ queryClient.invalidateQueries({ queryKey: queryKeys.transactions() });
36
+ queryClient.invalidateQueries({ queryKey: queryKeys.payees });
37
+ },
38
+ });
39
+ }
40
+
41
+ export function useLogout() {
42
+ const queryClient = useQueryClient();
43
+
44
+ return useMutation({
45
+ mutationFn: () => apiClient.diviswap.logout(),
46
+ onSuccess: () => {
47
+ queryClient.clear(); // Clear all cached data
48
+ },
49
+ });
50
+ }
51
+
52
+ // Transaction hooks
53
+ export function useTransactions(filters?: any) {
54
+ const { data: user } = useUser();
55
+
56
+ return useQuery({
57
+ queryKey: queryKeys.transactions(filters),
58
+ queryFn: () => apiClient.diviswap.getTransactions(filters),
59
+ enabled: !!user, // Only fetch if user is authenticated
60
+ staleTime: 30 * 1000, // 30 seconds
61
+ });
62
+ }
63
+
64
+ export function useCreateTransaction() {
65
+ const queryClient = useQueryClient();
66
+
67
+ return useMutation({
68
+ mutationFn: (data: any) => apiClient.diviswap.createTransaction(data),
69
+ onSuccess: () => {
70
+ // Invalidate and refetch transactions
71
+ queryClient.invalidateQueries({ queryKey: queryKeys.transactions() });
72
+ },
73
+ onError: (error) => {
74
+ console.error('Transaction failed:', error);
75
+ },
76
+ });
77
+ }
78
+
79
+ // Payee hooks
80
+ export function usePayees() {
81
+ const { data: user } = useUser();
82
+
83
+ return useQuery({
84
+ queryKey: queryKeys.payees,
85
+ queryFn: () => apiClient.diviswap.getPayees(),
86
+ enabled: !!user,
87
+ staleTime: 60 * 1000, // 1 minute
88
+ });
89
+ }
90
+
91
+ export function useCreatePayee() {
92
+ const queryClient = useQueryClient();
93
+
94
+ return useMutation({
95
+ mutationFn: (data: any) => apiClient.diviswap.createPayee(data),
96
+ onSuccess: (newPayee) => {
97
+ // Optimistically add the new payee to the cache
98
+ queryClient.setQueryData(queryKeys.payees, (old: any[] = []) => {
99
+ return [...old, newPayee];
100
+ });
101
+ },
102
+ });
103
+ }
104
+
105
+ export function useDeletePayee() {
106
+ const queryClient = useQueryClient();
107
+
108
+ return useMutation({
109
+ mutationFn: (id: string) => apiClient.diviswap.deletePayee(id),
110
+ onMutate: async (deletedId) => {
111
+ // Cancel in-flight queries
112
+ await queryClient.cancelQueries({ queryKey: queryKeys.payees });
113
+
114
+ // Snapshot current value
115
+ const previousPayees = queryClient.getQueryData(queryKeys.payees);
116
+
117
+ // Optimistically remove the payee
118
+ queryClient.setQueryData(queryKeys.payees, (old: any[] = []) => {
119
+ return old.filter(payee => payee.id !== deletedId);
120
+ });
121
+
122
+ return { previousPayees };
123
+ },
124
+ onError: (err, deletedId, context) => {
125
+ // Rollback on error
126
+ if (context?.previousPayees) {
127
+ queryClient.setQueryData(queryKeys.payees, context.previousPayees);
128
+ }
129
+ },
130
+ onSettled: () => {
131
+ // Always refetch after error or success
132
+ queryClient.invalidateQueries({ queryKey: queryKeys.payees });
133
+ },
134
+ });
135
+ }
136
+
137
+ {{#if (includes features "fees")}}
138
+ // Fee calculation hooks
139
+ export function useFeeCalculation(amount: number, enabled = true) {
140
+ return useQuery({
141
+ queryKey: queryKeys.fees(amount),
142
+ queryFn: () => apiClient.diviswap.calculateFees(amount),
143
+ enabled: enabled && amount > 0,
144
+ staleTime: 5 * 60 * 1000, // 5 minutes
145
+ gcTime: 10 * 60 * 1000, // 10 minutes (formerly cacheTime)
146
+ });
147
+ }
148
+ {{/if}}
149
+
150
+ // Example usage in a component:
151
+ /*
152
+ function MyComponent() {
153
+ const { data: user, isLoading: userLoading } = useUser();
154
+ const { data: transactions, isLoading: txLoading } = useTransactions({ limit: 10 });
155
+ const createTx = useCreateTransaction();
156
+
157
+ const handleCreateTransaction = async () => {
158
+ try {
159
+ await createTx.mutateAsync({
160
+ amount: 100,
161
+ type: 'onramp',
162
+ // ... other params
163
+ });
164
+ // Success! Transactions will automatically refetch
165
+ } catch (error) {
166
+ // Error handled by mutation
167
+ }
168
+ };
169
+
170
+ if (userLoading || txLoading) return <div>Loading...</div>;
171
+
172
+ return (
173
+ <div>
174
+ <h1>Welcome {user?.email}</h1>
175
+ <button
176
+ onClick={handleCreateTransaction}
177
+ disabled={createTx.isPending}
178
+ >
179
+ {createTx.isPending ? 'Creating...' : 'Create Transaction'}
180
+ </button>
181
+ {transactions?.map(tx => <div key={tx.id}>{tx.amount}</div>)}
182
+ </div>
183
+ );
184
+ }
185
+ */
@@ -0,0 +1,78 @@
1
+ export class LiberExClient {
2
+ constructor(private baseUrl: string = '/api/liberex') {}
3
+
4
+ private async request(endpoint: string, options: RequestInit = {}) {
5
+ const response = await fetch(`${this.baseUrl}${endpoint}`, {
6
+ ...options,
7
+ headers: {
8
+ 'Content-Type': 'application/json',
9
+ ...options.headers,
10
+ },
11
+ });
12
+
13
+ if (!response.ok) {
14
+ const error = await response.json();
15
+ throw new Error(error.message || 'Request failed');
16
+ }
17
+
18
+ return response.json();
19
+ }
20
+
21
+ async login(email: string, password: string) {
22
+ return this.request('', {
23
+ method: 'POST',
24
+ body: JSON.stringify({ action: 'login', email, password }),
25
+ });
26
+ }
27
+
28
+ async logout() {
29
+ return this.request('', {
30
+ method: 'POST',
31
+ body: JSON.stringify({ action: 'logout' }),
32
+ });
33
+ }
34
+
35
+ async register(data: any) {
36
+ return this.request('', {
37
+ method: 'POST',
38
+ body: JSON.stringify({ action: 'register', ...data }),
39
+ });
40
+ }
41
+
42
+ async checkSession() {
43
+ try {
44
+ return await this.request('?resource=session');
45
+ } catch {
46
+ return null;
47
+ }
48
+ }
49
+
50
+ async createTransaction(data: any) {
51
+ return this.request('', {
52
+ method: 'POST',
53
+ body: JSON.stringify({ action: 'createTransaction', ...data }),
54
+ });
55
+ }
56
+
57
+ async getPayees() {
58
+ return this.request('?resource=payees');
59
+ }
60
+
61
+ async getTransactions(params?: { limit?: number; offset?: number }) {
62
+ const searchParams = new URLSearchParams({
63
+ resource: 'transactions',
64
+ ...(params && {
65
+ limit: params.limit?.toString() || '10',
66
+ offset: params.offset?.toString() || '0',
67
+ }),
68
+ });
69
+ return this.request(`?${searchParams}`);
70
+ }
71
+
72
+ async calculateFees(data: { amount: number; type: 'onramp' | 'offramp' }) {
73
+ return this.request('', {
74
+ method: 'POST',
75
+ body: JSON.stringify({ action: 'calculateFees', ...data }),
76
+ });
77
+ }
78
+ }
@@ -0,0 +1,98 @@
1
+ import { NextRequest, NextResponse } from 'next/server';
2
+ import crypto from 'crypto';
3
+
4
+ // Verify webhook signature
5
+ function verifyWebhookSignature(
6
+ payload: string,
7
+ signature: string,
8
+ secret: string
9
+ ): boolean {
10
+ const expectedSignature = crypto
11
+ .createHmac('sha256', secret)
12
+ .update(payload)
13
+ .digest('hex');
14
+
15
+ return crypto.timingSafeEqual(
16
+ Buffer.from(signature),
17
+ Buffer.from(expectedSignature)
18
+ );
19
+ }
20
+
21
+ export async function POST(request: NextRequest) {
22
+ try {
23
+ // Get the raw body
24
+ const rawBody = await request.text();
25
+
26
+ // Get signature from headers
27
+ const signature = request.headers.get('x-diviswap-signature');
28
+
29
+ if (!signature) {
30
+ return NextResponse.json(
31
+ { error: 'Missing webhook signature' },
32
+ { status: 401 }
33
+ );
34
+ }
35
+
36
+ // Verify signature
37
+ const webhookSecret = process.env.DIVISWAP_WEBHOOK_SECRET;
38
+ if (!webhookSecret) {
39
+ console.error('DIVISWAP_WEBHOOK_SECRET not configured');
40
+ return NextResponse.json(
41
+ { error: 'Webhook secret not configured' },
42
+ { status: 500 }
43
+ );
44
+ }
45
+
46
+ const isValid = verifyWebhookSignature(rawBody, signature, webhookSecret);
47
+ if (!isValid) {
48
+ return NextResponse.json(
49
+ { error: 'Invalid webhook signature' },
50
+ { status: 401 }
51
+ );
52
+ }
53
+
54
+ // Parse the webhook payload
55
+ const webhook = JSON.parse(rawBody);
56
+
57
+ // Handle different webhook events
58
+ switch (webhook.event) {
59
+ case 'transaction.created':
60
+ console.log('Transaction created:', webhook.data);
61
+ // Handle new transaction
62
+ break;
63
+
64
+ case 'transaction.updated':
65
+ console.log('Transaction updated:', webhook.data);
66
+ // Handle transaction update
67
+ break;
68
+
69
+ case 'transaction.completed':
70
+ console.log('Transaction completed:', webhook.data);
71
+ // Handle completed transaction
72
+ break;
73
+
74
+ case 'transaction.failed':
75
+ console.log('Transaction failed:', webhook.data);
76
+ // Handle failed transaction
77
+ break;
78
+
79
+ case 'kyc.updated':
80
+ console.log('KYC status updated:', webhook.data);
81
+ // Handle KYC update
82
+ break;
83
+
84
+ default:
85
+ console.log('Unknown webhook event:', webhook.event);
86
+ }
87
+
88
+ // Return success response
89
+ return NextResponse.json({ received: true });
90
+
91
+ } catch (error) {
92
+ console.error('Webhook error:', error);
93
+ return NextResponse.json(
94
+ { error: 'Webhook processing failed' },
95
+ { status: 500 }
96
+ );
97
+ }
98
+ }