@djangocfg/ext-payments 1.0.14 → 1.0.19

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 (76) hide show
  1. package/dist/config.cjs +5 -8
  2. package/dist/config.js +5 -8
  3. package/dist/index.cjs +1906 -1043
  4. package/dist/index.d.cts +644 -59
  5. package/dist/index.d.ts +644 -59
  6. package/dist/index.js +1886 -1040
  7. package/package.json +13 -16
  8. package/src/WalletPage.tsx +100 -0
  9. package/src/api/generated/ext_payments/CLAUDE.md +10 -4
  10. package/src/api/generated/ext_payments/_utils/fetchers/ext_payments__payments.ts +268 -5
  11. package/src/api/generated/ext_payments/_utils/hooks/ext_payments__payments.ts +102 -3
  12. package/src/api/generated/ext_payments/_utils/schemas/Balance.schema.ts +1 -1
  13. package/src/api/generated/ext_payments/_utils/schemas/PaginatedWithdrawalListList.schema.ts +24 -0
  14. package/src/api/generated/ext_payments/_utils/schemas/PaymentCreateRequest.schema.ts +21 -0
  15. package/src/api/generated/ext_payments/_utils/schemas/PaymentCreateResponse.schema.ts +22 -0
  16. package/src/api/generated/ext_payments/_utils/schemas/PaymentDetail.schema.ts +3 -3
  17. package/src/api/generated/ext_payments/_utils/schemas/PaymentList.schema.ts +2 -2
  18. package/src/api/generated/ext_payments/_utils/schemas/Transaction.schema.ts +1 -1
  19. package/src/api/generated/ext_payments/_utils/schemas/WithdrawalCancelResponse.schema.ts +22 -0
  20. package/src/api/generated/ext_payments/_utils/schemas/WithdrawalCreateRequest.schema.ts +21 -0
  21. package/src/api/generated/ext_payments/_utils/schemas/WithdrawalCreateResponse.schema.ts +22 -0
  22. package/src/api/generated/ext_payments/_utils/schemas/WithdrawalDetail.schema.ts +42 -0
  23. package/src/api/generated/ext_payments/_utils/schemas/WithdrawalList.schema.ts +29 -0
  24. package/src/api/generated/ext_payments/_utils/schemas/index.ts +8 -0
  25. package/src/api/generated/ext_payments/client.ts +1 -1
  26. package/src/api/generated/ext_payments/enums.ts +36 -0
  27. package/src/api/generated/ext_payments/ext_payments__payments/client.ts +104 -6
  28. package/src/api/generated/ext_payments/ext_payments__payments/models.ts +168 -8
  29. package/src/api/generated/ext_payments/index.ts +1 -1
  30. package/src/api/generated/ext_payments/schema.json +752 -42
  31. package/src/components/ActivityItem.tsx +118 -0
  32. package/src/components/ActivityList.tsx +93 -0
  33. package/src/components/AddFundsSheet.tsx +342 -0
  34. package/src/components/BalanceHero.tsx +102 -0
  35. package/src/components/CurrencyCombobox.tsx +49 -0
  36. package/src/components/PaymentSheet.tsx +352 -0
  37. package/src/components/WithdrawSheet.tsx +355 -0
  38. package/src/components/WithdrawalSheet.tsx +332 -0
  39. package/src/components/index.ts +11 -0
  40. package/src/config.ts +1 -0
  41. package/src/contexts/WalletContext.tsx +356 -0
  42. package/src/contexts/index.ts +13 -42
  43. package/src/contexts/types.ts +43 -37
  44. package/src/hooks/index.ts +3 -20
  45. package/src/hooks/useCurrencyOptions.ts +79 -0
  46. package/src/hooks/useEstimate.ts +113 -0
  47. package/src/hooks/useWithdrawalEstimate.ts +117 -0
  48. package/src/index.ts +9 -18
  49. package/src/types/index.ts +78 -0
  50. package/src/utils/errors.ts +36 -0
  51. package/src/utils/format.ts +65 -0
  52. package/src/utils/index.ts +3 -0
  53. package/src/contexts/BalancesContext.tsx +0 -63
  54. package/src/contexts/CurrenciesContext.tsx +0 -64
  55. package/src/contexts/OverviewContext.tsx +0 -173
  56. package/src/contexts/PaymentsContext.tsx +0 -122
  57. package/src/contexts/PaymentsExtensionProvider.tsx +0 -56
  58. package/src/contexts/README.md +0 -201
  59. package/src/contexts/RootPaymentsContext.tsx +0 -66
  60. package/src/layouts/PaymentsLayout/PaymentsLayout.tsx +0 -90
  61. package/src/layouts/PaymentsLayout/components/CreatePaymentDialog.tsx +0 -274
  62. package/src/layouts/PaymentsLayout/components/PaymentDetailsDialog.tsx +0 -287
  63. package/src/layouts/PaymentsLayout/components/index.ts +0 -2
  64. package/src/layouts/PaymentsLayout/events.ts +0 -47
  65. package/src/layouts/PaymentsLayout/index.ts +0 -16
  66. package/src/layouts/PaymentsLayout/types.ts +0 -6
  67. package/src/layouts/PaymentsLayout/views/overview/components/BalanceCard.tsx +0 -121
  68. package/src/layouts/PaymentsLayout/views/overview/components/RecentPayments.tsx +0 -139
  69. package/src/layouts/PaymentsLayout/views/overview/components/index.ts +0 -2
  70. package/src/layouts/PaymentsLayout/views/overview/index.tsx +0 -21
  71. package/src/layouts/PaymentsLayout/views/payments/components/PaymentsList.tsx +0 -279
  72. package/src/layouts/PaymentsLayout/views/payments/components/index.ts +0 -1
  73. package/src/layouts/PaymentsLayout/views/payments/index.tsx +0 -18
  74. package/src/layouts/PaymentsLayout/views/transactions/components/TransactionsList.tsx +0 -260
  75. package/src/layouts/PaymentsLayout/views/transactions/components/index.ts +0 -1
  76. package/src/layouts/PaymentsLayout/views/transactions/index.tsx +0 -18
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Wallet Components (Apple-style)
3
+ */
4
+
5
+ export { BalanceHero } from './BalanceHero';
6
+ export { ActivityList } from './ActivityList';
7
+ export { ActivityItem } from './ActivityItem';
8
+ export { AddFundsSheet } from './AddFundsSheet';
9
+ export { WithdrawSheet } from './WithdrawSheet';
10
+ export { WithdrawalSheet } from './WithdrawalSheet';
11
+ export { PaymentSheet } from './PaymentSheet';
package/src/config.ts CHANGED
@@ -4,6 +4,7 @@
4
4
 
5
5
  import { createExtensionConfig } from '@djangocfg/ext-base';
6
6
 
7
+ // @ts-ignore - package.json is not typed
7
8
  import packageJson from '../package.json';
8
9
 
9
10
  export const extensionConfig = createExtensionConfig(packageJson, {
@@ -0,0 +1,356 @@
1
+ /**
2
+ * Wallet Context (Apple-style unified)
3
+ *
4
+ * Single context for all wallet operations:
5
+ * - Balance
6
+ * - Activity (payments + transactions merged)
7
+ * - Currencies
8
+ * - Payment operations
9
+ */
10
+
11
+ 'use client';
12
+
13
+ import React, { createContext, ReactNode, useContext, useMemo, useCallback } from 'react';
14
+
15
+ import { apiPayments } from '../api';
16
+ import {
17
+ usePaymentsBalanceRetrieve,
18
+ usePaymentsPaymentsList,
19
+ usePaymentsTransactionsList,
20
+ usePaymentsCurrenciesList,
21
+ usePaymentsWithdrawalsList,
22
+ useCreatePaymentsPaymentsCreateCreate,
23
+ useCreatePaymentsWithdrawalsCreateCreate,
24
+ useCreatePaymentsWithdrawalsCancelCreate,
25
+ } from '../api/generated/ext_payments/_utils/hooks';
26
+
27
+ import type {
28
+ Balance,
29
+ PaymentList,
30
+ Transaction,
31
+ PaymentCreateRequest,
32
+ PaymentDetail,
33
+ WithdrawalCreateRequest,
34
+ WithdrawalDetail,
35
+ WithdrawalList,
36
+ } from '../api/generated/ext_payments/_utils/schemas';
37
+
38
+ // ─────────────────────────────────────────────────────────────────────────────
39
+ // Types
40
+ // ─────────────────────────────────────────────────────────────────────────────
41
+
42
+ export type ActivityType = 'payment' | 'deposit' | 'withdrawal';
43
+
44
+ export interface ActivityItem {
45
+ id: string;
46
+ type: ActivityType;
47
+ amount: string;
48
+ amountDisplay: string;
49
+ currency?: string;
50
+ status: 'pending' | 'completed' | 'failed' | 'expired' | 'confirming';
51
+ statusDisplay: string;
52
+ description: string;
53
+ createdAt: string;
54
+ // Original data for details
55
+ payment?: PaymentList;
56
+ transaction?: Transaction;
57
+ withdrawal?: WithdrawalList;
58
+ }
59
+
60
+ export interface Currency {
61
+ code: string;
62
+ name: string;
63
+ token: string;
64
+ network?: string;
65
+ enabled: boolean;
66
+ }
67
+
68
+ export interface WalletContextValue {
69
+ // Balance
70
+ balance: Balance | undefined;
71
+ balanceAmount: number;
72
+ isLoadingBalance: boolean;
73
+
74
+ // Activity (merged payments + transactions)
75
+ activity: ActivityItem[];
76
+ isLoadingActivity: boolean;
77
+ hasMoreActivity: boolean;
78
+
79
+ // Currencies
80
+ currencies: Currency[];
81
+ isLoadingCurrencies: boolean;
82
+
83
+ // Operations
84
+ addFunds: (data: PaymentCreateRequest) => Promise<PaymentDetail>;
85
+ withdraw: (data: WithdrawalCreateRequest) => Promise<WithdrawalDetail>;
86
+ cancelWithdrawal: (id: string) => Promise<void>;
87
+ getPaymentDetails: (id: string) => Promise<PaymentDetail | undefined>;
88
+ getWithdrawalDetails: (id: string) => Promise<WithdrawalDetail | undefined>;
89
+ refreshWallet: () => Promise<void>;
90
+
91
+ // Loading state
92
+ isLoading: boolean;
93
+ }
94
+
95
+ // ─────────────────────────────────────────────────────────────────────────────
96
+ // Context
97
+ // ─────────────────────────────────────────────────────────────────────────────
98
+
99
+ const WalletContext = createContext<WalletContextValue | undefined>(undefined);
100
+
101
+ // ─────────────────────────────────────────────────────────────────────────────
102
+ // Provider
103
+ // ─────────────────────────────────────────────────────────────────────────────
104
+
105
+ export function WalletProvider({ children }: { children: ReactNode }) {
106
+ // Fetch balance
107
+ const {
108
+ data: balance,
109
+ isLoading: isLoadingBalance,
110
+ mutate: mutateBalance,
111
+ } = usePaymentsBalanceRetrieve(apiPayments);
112
+
113
+ // Fetch recent payments
114
+ const {
115
+ data: paymentsData,
116
+ isLoading: isLoadingPayments,
117
+ mutate: mutatePayments,
118
+ } = usePaymentsPaymentsList({ page: 1, page_size: 20 }, apiPayments);
119
+
120
+ // Fetch recent transactions
121
+ const {
122
+ data: transactionsData,
123
+ isLoading: isLoadingTransactions,
124
+ mutate: mutateTransactions,
125
+ } = usePaymentsTransactionsList({ limit: 20 }, apiPayments);
126
+
127
+ // Fetch currencies
128
+ const {
129
+ data: currenciesData,
130
+ isLoading: isLoadingCurrencies,
131
+ mutate: mutateCurrencies,
132
+ } = usePaymentsCurrenciesList(apiPayments);
133
+
134
+ // Fetch recent withdrawals
135
+ const {
136
+ data: withdrawalsData,
137
+ isLoading: isLoadingWithdrawals,
138
+ mutate: mutateWithdrawals,
139
+ } = usePaymentsWithdrawalsList({ page: 1, page_size: 20 }, apiPayments);
140
+
141
+ // Mutation hooks
142
+ const createPaymentMutation = useCreatePaymentsPaymentsCreateCreate();
143
+ const createWithdrawalMutation = useCreatePaymentsWithdrawalsCreateCreate();
144
+ const cancelWithdrawalMutation = useCreatePaymentsWithdrawalsCancelCreate();
145
+
146
+ // Parse balance amount
147
+ const balanceAmount = useMemo(() => {
148
+ if (!balance?.balance_usd) return 0;
149
+ return parseFloat(balance.balance_usd) || 0;
150
+ }, [balance]);
151
+
152
+ // Merge and sort activity (payments + withdrawals + transactions)
153
+ const activity = useMemo<ActivityItem[]>(() => {
154
+ const items: ActivityItem[] = [];
155
+
156
+ // Add payments (deposits)
157
+ const payments = paymentsData?.results || [];
158
+ for (const payment of payments) {
159
+ items.push({
160
+ id: `payment-${payment.id}`,
161
+ type: 'payment',
162
+ amount: payment.amount_usd,
163
+ amountDisplay: `+$${parseFloat(payment.amount_usd).toFixed(2)}`,
164
+ currency: payment.currency_code,
165
+ status: mapPaymentStatus(payment.status),
166
+ statusDisplay: payment.status_display,
167
+ description: `${payment.currency_code} payment`,
168
+ createdAt: payment.created_at,
169
+ payment,
170
+ });
171
+ }
172
+
173
+ // Add withdrawals
174
+ const withdrawals = withdrawalsData?.results || [];
175
+ for (const withdrawal of withdrawals) {
176
+ items.push({
177
+ id: `withdrawal-${withdrawal.id}`,
178
+ type: 'withdrawal',
179
+ amount: withdrawal.amount_usd,
180
+ amountDisplay: `-$${parseFloat(withdrawal.amount_usd).toFixed(2)}`,
181
+ currency: withdrawal.currency_code,
182
+ status: mapWithdrawalStatus(withdrawal.status),
183
+ statusDisplay: withdrawal.status_display,
184
+ description: `${withdrawal.currency_code} withdrawal`,
185
+ createdAt: withdrawal.created_at,
186
+ withdrawal,
187
+ });
188
+ }
189
+
190
+ // Add transactions (only if not linked to a payment/withdrawal already shown)
191
+ const transactions = transactionsData?.results || transactionsData || [];
192
+ if (Array.isArray(transactions)) {
193
+ for (const tx of transactions) {
194
+ // Skip if this transaction is linked to a payment we already have
195
+ if (tx.payment_id && payments.some(p => p.id === tx.payment_id)) {
196
+ continue;
197
+ }
198
+
199
+ const isDeposit = tx.transaction_type === 'deposit';
200
+ items.push({
201
+ id: `tx-${tx.id}`,
202
+ type: isDeposit ? 'deposit' : 'withdrawal',
203
+ amount: tx.amount_usd,
204
+ amountDisplay: `${isDeposit ? '+' : '-'}$${Math.abs(parseFloat(tx.amount_usd)).toFixed(2)}`,
205
+ status: 'completed',
206
+ statusDisplay: 'Completed',
207
+ description: tx.description || tx.type_display,
208
+ createdAt: tx.created_at,
209
+ transaction: tx,
210
+ });
211
+ }
212
+ }
213
+
214
+ // Sort by date, newest first
215
+ items.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());
216
+
217
+ return items;
218
+ }, [paymentsData, withdrawalsData, transactionsData]);
219
+
220
+ // Parse currencies
221
+ const currencies = useMemo<Currency[]>(() => {
222
+ const data = currenciesData?.currencies || currenciesData?.results || currenciesData || [];
223
+ if (!Array.isArray(data)) return [];
224
+
225
+ return data
226
+ .filter((c: any) => c.is_enabled !== false)
227
+ .map((c: any) => ({
228
+ code: c.code || c.currency_code || c.symbol,
229
+ name: c.name || c.code,
230
+ token: c.token || c.code, // Token symbol (e.g., USDT, WBTC) with fallback to code
231
+ network: c.network || undefined,
232
+ enabled: c.is_enabled !== false,
233
+ }));
234
+ }, [currenciesData]);
235
+
236
+ // Operations
237
+ const addFunds = useCallback(async (data: PaymentCreateRequest): Promise<PaymentDetail> => {
238
+ const response = await createPaymentMutation(data, apiPayments);
239
+ // Refresh all data
240
+ await Promise.all([mutateBalance(), mutatePayments(), mutateTransactions()]);
241
+ // API returns { success, payment, qr_code_url } - extract payment
242
+ return response.payment;
243
+ }, [createPaymentMutation, mutateBalance, mutatePayments, mutateTransactions]);
244
+
245
+ const withdraw = useCallback(async (data: WithdrawalCreateRequest): Promise<WithdrawalDetail> => {
246
+ const response = await createWithdrawalMutation(data, apiPayments);
247
+ // Refresh all data
248
+ await Promise.all([mutateBalance(), mutateWithdrawals(), mutateTransactions()]);
249
+ // API returns { success, withdrawal, message } - extract withdrawal
250
+ return response.withdrawal;
251
+ }, [createWithdrawalMutation, mutateBalance, mutateWithdrawals, mutateTransactions]);
252
+
253
+ const cancelWithdrawal = useCallback(async (id: string): Promise<void> => {
254
+ await cancelWithdrawalMutation(id, apiPayments);
255
+ // Refresh all data
256
+ await Promise.all([mutateBalance(), mutateWithdrawals(), mutateTransactions()]);
257
+ }, [cancelWithdrawalMutation, mutateBalance, mutateWithdrawals, mutateTransactions]);
258
+
259
+ const getPaymentDetails = useCallback(async (id: string): Promise<PaymentDetail | undefined> => {
260
+ return apiPayments.ext_payments_payments.paymentsRetrieve(id);
261
+ }, []);
262
+
263
+ const getWithdrawalDetails = useCallback(async (id: string): Promise<WithdrawalDetail | undefined> => {
264
+ return apiPayments.ext_payments_payments.withdrawalsRetrieve(id);
265
+ }, []);
266
+
267
+ const refreshWallet = useCallback(async () => {
268
+ await Promise.all([
269
+ mutateBalance(),
270
+ mutatePayments(),
271
+ mutateWithdrawals(),
272
+ mutateTransactions(),
273
+ mutateCurrencies(),
274
+ ]);
275
+ }, [mutateBalance, mutatePayments, mutateWithdrawals, mutateTransactions, mutateCurrencies]);
276
+
277
+ // Combined loading state
278
+ const isLoading = isLoadingBalance || isLoadingPayments || isLoadingWithdrawals || isLoadingTransactions;
279
+ const isLoadingActivity = isLoadingPayments || isLoadingWithdrawals || isLoadingTransactions;
280
+
281
+ const value: WalletContextValue = {
282
+ balance,
283
+ balanceAmount,
284
+ isLoadingBalance,
285
+ activity,
286
+ isLoadingActivity,
287
+ hasMoreActivity: (paymentsData?.count || 0) > 20 || (withdrawalsData?.count || 0) > 20,
288
+ currencies,
289
+ isLoadingCurrencies,
290
+ addFunds,
291
+ withdraw,
292
+ cancelWithdrawal,
293
+ getPaymentDetails,
294
+ getWithdrawalDetails,
295
+ refreshWallet,
296
+ isLoading,
297
+ };
298
+
299
+ return <WalletContext.Provider value={value}>{children}</WalletContext.Provider>;
300
+ }
301
+
302
+ // ─────────────────────────────────────────────────────────────────────────────
303
+ // Hook
304
+ // ─────────────────────────────────────────────────────────────────────────────
305
+
306
+ export function useWallet(): WalletContextValue {
307
+ const context = useContext(WalletContext);
308
+ if (!context) {
309
+ throw new Error('useWallet must be used within WalletProvider');
310
+ }
311
+ return context;
312
+ }
313
+
314
+ // ─────────────────────────────────────────────────────────────────────────────
315
+ // Helpers
316
+ // ─────────────────────────────────────────────────────────────────────────────
317
+
318
+ function mapPaymentStatus(status: string): ActivityItem['status'] {
319
+ switch (status?.toLowerCase()) {
320
+ case 'completed':
321
+ case 'success':
322
+ case 'finished':
323
+ return 'completed';
324
+ case 'pending':
325
+ case 'waiting':
326
+ return 'pending';
327
+ case 'confirming':
328
+ case 'partially_paid':
329
+ return 'confirming';
330
+ case 'expired':
331
+ return 'expired';
332
+ case 'failed':
333
+ case 'error':
334
+ case 'cancelled':
335
+ return 'failed';
336
+ default:
337
+ return 'pending';
338
+ }
339
+ }
340
+
341
+ function mapWithdrawalStatus(status: string): ActivityItem['status'] {
342
+ switch (status?.toLowerCase()) {
343
+ case 'completed':
344
+ return 'completed';
345
+ case 'pending':
346
+ case 'approved':
347
+ return 'pending';
348
+ case 'processing':
349
+ return 'confirming';
350
+ case 'rejected':
351
+ case 'cancelled':
352
+ return 'failed';
353
+ default:
354
+ return 'pending';
355
+ }
356
+ }
@@ -1,45 +1,16 @@
1
- // Payments
2
- export {
3
- PaymentsProvider,
4
- usePaymentsContext
5
- } from './PaymentsContext';
6
- export type {
7
- PaymentsContextValue,
8
- } from './PaymentsContext';
9
-
10
- // Balances
11
- export {
12
- BalancesProvider,
13
- useBalancesContext
14
- } from './BalancesContext';
15
- export type {
16
- BalancesContextValue,
17
- } from './BalancesContext';
1
+ /**
2
+ * Payments Context Exports
3
+ */
18
4
 
19
- // Currencies
20
- export {
21
- CurrenciesProvider,
22
- useCurrenciesContext
23
- } from './CurrenciesContext';
24
- export type {
25
- CurrenciesContextValue,
26
- } from './CurrenciesContext';
5
+ // Types (single source of truth)
6
+ export * from './types';
27
7
 
28
- // Overview
8
+ // Context
29
9
  export {
30
- OverviewProvider,
31
- useOverviewContext
32
- } from './OverviewContext';
33
- export type {
34
- OverviewContextValue,
35
- } from './OverviewContext';
36
-
37
- // Root Payments (Global)
38
- export {
39
- RootPaymentsProvider,
40
- useRootPaymentsContext
41
- } from './RootPaymentsContext';
42
- export type {
43
- RootPaymentsContextValue,
44
- } from './RootPaymentsContext';
45
-
10
+ WalletProvider,
11
+ useWallet,
12
+ type WalletContextValue,
13
+ type ActivityItem,
14
+ type ActivityType,
15
+ type Currency,
16
+ } from './WalletContext';
@@ -1,40 +1,46 @@
1
1
  /**
2
- * Payments Types
3
- * Centralized type definitions for payments contexts
2
+ * Payments Context Types
3
+ *
4
+ * Re-exports all types and enums from generated API for payments.
5
+ * This is the single source of truth for payment types.
4
6
  */
5
7
 
6
- import type {
7
- usePaymentsPaymentsList,
8
- usePaymentsPaymentsRetrieve,
9
- usePaymentsBalanceRetrieve,
10
- usePaymentsCurrenciesList,
11
- usePaymentsTransactionsList,
12
- } from '../api/generated/ext_payments/_utils/hooks';
13
-
14
- // ─────────────────────────────────────────────────────────────────────────
15
- // Payments Types
16
- // ─────────────────────────────────────────────────────────────────────────
17
-
18
- export type PaginatedPaymentListList = NonNullable<Awaited<ReturnType<typeof usePaymentsPaymentsList>>['data']>;
19
- export type PaymentDetail = NonNullable<Awaited<ReturnType<typeof usePaymentsPaymentsRetrieve>>['data']>;
20
- export type PaymentList = NonNullable<Awaited<ReturnType<typeof usePaymentsPaymentsList>>['data']> extends { results: infer T } ? T extends Array<infer U> ? U : never : never;
21
-
22
- // ─────────────────────────────────────────────────────────────────────────
23
- // Balance Types
24
- // ─────────────────────────────────────────────────────────────────────────
25
-
26
- export type Balance = NonNullable<Awaited<ReturnType<typeof usePaymentsBalanceRetrieve>>['data']>;
27
-
28
- // ─────────────────────────────────────────────────────────────────────────
29
- // Currency Types
30
- // ─────────────────────────────────────────────────────────────────────────
31
-
32
- export type Currency = NonNullable<Awaited<ReturnType<typeof usePaymentsCurrenciesList>>['data']> extends { results: infer T } ? T extends Array<infer U> ? U : never : never;
33
- export type PaginatedCurrencyList = NonNullable<Awaited<ReturnType<typeof usePaymentsCurrenciesList>>['data']>;
34
-
35
- // ─────────────────────────────────────────────────────────────────────────
36
- // Transaction Types
37
- // ─────────────────────────────────────────────────────────────────────────
38
-
39
- export type Transaction = NonNullable<Awaited<ReturnType<typeof usePaymentsTransactionsList>>['data']> extends { results: infer T } ? T extends Array<infer U> ? U : never : never;
40
- export type PaginatedTransactionList = NonNullable<Awaited<ReturnType<typeof usePaymentsTransactionsList>>['data']>;
8
+ // Import and re-export enums
9
+ import * as PaymentsEnums from '../api/generated/ext_payments/enums';
10
+
11
+ // =============================================================================
12
+ // Payment Enums
13
+ // =============================================================================
14
+ export const PaymentStatus = PaymentsEnums.PaymentDetailStatus;
15
+ export const PaymentListStatus = PaymentsEnums.PaymentListStatus;
16
+ export const TransactionType = PaymentsEnums.TransactionTransactionType;
17
+ export const WithdrawalStatus = PaymentsEnums.WithdrawalDetailStatus;
18
+ export const WithdrawalListStatus = PaymentsEnums.WithdrawalListStatus;
19
+
20
+ // Type exports for TypeScript
21
+ export type PaymentStatus = PaymentsEnums.PaymentDetailStatus;
22
+ export type PaymentListStatus = PaymentsEnums.PaymentListStatus;
23
+ export type TransactionType = PaymentsEnums.TransactionTransactionType;
24
+ export type WithdrawalStatus = PaymentsEnums.WithdrawalDetailStatus;
25
+ export type WithdrawalListStatus = PaymentsEnums.WithdrawalListStatus;
26
+
27
+ // =============================================================================
28
+ // Payment Schemas
29
+ // =============================================================================
30
+ export type { Balance } from '../api/generated/ext_payments/_utils/schemas/Balance.schema';
31
+ export type { Currency } from '../api/generated/ext_payments/_utils/schemas/Currency.schema';
32
+ export type { PaymentDetail } from '../api/generated/ext_payments/_utils/schemas/PaymentDetail.schema';
33
+ export type { PaymentList } from '../api/generated/ext_payments/_utils/schemas/PaymentList.schema';
34
+ export type { PaymentCreateRequest } from '../api/generated/ext_payments/_utils/schemas/PaymentCreateRequest.schema';
35
+ export type { PaymentCreateResponse } from '../api/generated/ext_payments/_utils/schemas/PaymentCreateResponse.schema';
36
+ export type { PaginatedPaymentListList } from '../api/generated/ext_payments/_utils/schemas/PaginatedPaymentListList.schema';
37
+ export type { Transaction } from '../api/generated/ext_payments/_utils/schemas/Transaction.schema';
38
+
39
+ // =============================================================================
40
+ // Withdrawal Schemas
41
+ // =============================================================================
42
+ export type { WithdrawalDetail } from '../api/generated/ext_payments/_utils/schemas/WithdrawalDetail.schema';
43
+ export type { WithdrawalList } from '../api/generated/ext_payments/_utils/schemas/WithdrawalList.schema';
44
+ export type { WithdrawalCreateRequest } from '../api/generated/ext_payments/_utils/schemas/WithdrawalCreateRequest.schema';
45
+ export type { WithdrawalCreateResponse } from '../api/generated/ext_payments/_utils/schemas/WithdrawalCreateResponse.schema';
46
+ export type { PaginatedWithdrawalListList } from '../api/generated/ext_payments/_utils/schemas/PaginatedWithdrawalListList.schema';
@@ -1,20 +1,3 @@
1
- 'use client';
2
-
3
- /**
4
- * @djangocfg/ext-payments/hooks
5
- *
6
- * React hooks for payments extension.
7
- * Use this entry point in client components.
8
- */
9
-
10
- // Re-export everything from main entry (server-safe code)
11
- export * from '../index';
12
-
13
- // SWR hooks from generated API
14
- export * from '../api/generated/ext_payments/_utils/hooks';
15
-
16
- // Payments contexts (from local contexts)
17
- export * from '../contexts';
18
-
19
- // Layout components (they use hooks internally)
20
- export * from '../layouts/PaymentsLayout/components';
1
+ export * from './useEstimate';
2
+ export * from './useWithdrawalEstimate';
3
+ export * from './useCurrencyOptions';
@@ -0,0 +1,79 @@
1
+ 'use client';
2
+
3
+ /**
4
+ * Hooks for currency selection
5
+ */
6
+
7
+ import { useMemo, useEffect, useCallback, useRef } from 'react';
8
+ import type { Currency } from '../contexts/WalletContext';
9
+ import type { CurrencyOption } from '../types';
10
+
11
+ /**
12
+ * Map currencies to combobox options
13
+ */
14
+ export function useCurrencyOptions(currencies: Currency[]): CurrencyOption[] {
15
+ return useMemo(() => {
16
+ return currencies.map((c) => ({
17
+ value: c.code,
18
+ label: c.name,
19
+ token: c.token,
20
+ network: c.network,
21
+ }));
22
+ }, [currencies]);
23
+ }
24
+
25
+ interface UseDefaultCurrencyOptions {
26
+ currencyOptions: CurrencyOption[];
27
+ savedCurrency: string;
28
+ currentValue: string;
29
+ setValue: (value: string) => void;
30
+ }
31
+
32
+ /**
33
+ * Set default currency when options load (saved or USDT fallback)
34
+ */
35
+ export function useDefaultCurrency({
36
+ currencyOptions,
37
+ savedCurrency,
38
+ currentValue,
39
+ setValue,
40
+ }: UseDefaultCurrencyOptions): void {
41
+ useEffect(() => {
42
+ if (currencyOptions.length > 0 && !currentValue) {
43
+ // Prefer saved currency if it exists in options
44
+ const savedOption = savedCurrency && currencyOptions.find(c => c.value === savedCurrency);
45
+ if (savedOption) {
46
+ setValue(savedOption.value);
47
+ } else {
48
+ // Fallback to USDT or first available
49
+ const usdt = currencyOptions.find(c => c.value.includes('USDT'));
50
+ setValue(usdt?.value || currencyOptions[0].value);
51
+ }
52
+ }
53
+ }, [currencyOptions, savedCurrency, currentValue, setValue]);
54
+ }
55
+
56
+ /**
57
+ * Auto-save value to localStorage when it changes
58
+ */
59
+ export function useAutoSave<T>(
60
+ value: T,
61
+ save: (value: T) => void,
62
+ validate?: (value: T) => boolean
63
+ ): void {
64
+ // Use refs to avoid infinite loops from unstable function references
65
+ const saveRef = useRef(save);
66
+ const validateRef = useRef(validate);
67
+
68
+ useEffect(() => {
69
+ saveRef.current = save;
70
+ validateRef.current = validate;
71
+ });
72
+
73
+ useEffect(() => {
74
+ const isValid = validateRef.current ? validateRef.current(value) : Boolean(value);
75
+ if (isValid) {
76
+ saveRef.current(value);
77
+ }
78
+ }, [value]);
79
+ }