@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.
- package/dist/config.cjs +5 -8
- package/dist/config.js +5 -8
- package/dist/index.cjs +1906 -1043
- package/dist/index.d.cts +644 -59
- package/dist/index.d.ts +644 -59
- package/dist/index.js +1886 -1040
- package/package.json +13 -16
- package/src/WalletPage.tsx +100 -0
- package/src/api/generated/ext_payments/CLAUDE.md +10 -4
- package/src/api/generated/ext_payments/_utils/fetchers/ext_payments__payments.ts +268 -5
- package/src/api/generated/ext_payments/_utils/hooks/ext_payments__payments.ts +102 -3
- package/src/api/generated/ext_payments/_utils/schemas/Balance.schema.ts +1 -1
- package/src/api/generated/ext_payments/_utils/schemas/PaginatedWithdrawalListList.schema.ts +24 -0
- package/src/api/generated/ext_payments/_utils/schemas/PaymentCreateRequest.schema.ts +21 -0
- package/src/api/generated/ext_payments/_utils/schemas/PaymentCreateResponse.schema.ts +22 -0
- package/src/api/generated/ext_payments/_utils/schemas/PaymentDetail.schema.ts +3 -3
- package/src/api/generated/ext_payments/_utils/schemas/PaymentList.schema.ts +2 -2
- package/src/api/generated/ext_payments/_utils/schemas/Transaction.schema.ts +1 -1
- package/src/api/generated/ext_payments/_utils/schemas/WithdrawalCancelResponse.schema.ts +22 -0
- package/src/api/generated/ext_payments/_utils/schemas/WithdrawalCreateRequest.schema.ts +21 -0
- package/src/api/generated/ext_payments/_utils/schemas/WithdrawalCreateResponse.schema.ts +22 -0
- package/src/api/generated/ext_payments/_utils/schemas/WithdrawalDetail.schema.ts +42 -0
- package/src/api/generated/ext_payments/_utils/schemas/WithdrawalList.schema.ts +29 -0
- package/src/api/generated/ext_payments/_utils/schemas/index.ts +8 -0
- package/src/api/generated/ext_payments/client.ts +1 -1
- package/src/api/generated/ext_payments/enums.ts +36 -0
- package/src/api/generated/ext_payments/ext_payments__payments/client.ts +104 -6
- package/src/api/generated/ext_payments/ext_payments__payments/models.ts +168 -8
- package/src/api/generated/ext_payments/index.ts +1 -1
- package/src/api/generated/ext_payments/schema.json +752 -42
- package/src/components/ActivityItem.tsx +118 -0
- package/src/components/ActivityList.tsx +93 -0
- package/src/components/AddFundsSheet.tsx +342 -0
- package/src/components/BalanceHero.tsx +102 -0
- package/src/components/CurrencyCombobox.tsx +49 -0
- package/src/components/PaymentSheet.tsx +352 -0
- package/src/components/WithdrawSheet.tsx +355 -0
- package/src/components/WithdrawalSheet.tsx +332 -0
- package/src/components/index.ts +11 -0
- package/src/config.ts +1 -0
- package/src/contexts/WalletContext.tsx +356 -0
- package/src/contexts/index.ts +13 -42
- package/src/contexts/types.ts +43 -37
- package/src/hooks/index.ts +3 -20
- package/src/hooks/useCurrencyOptions.ts +79 -0
- package/src/hooks/useEstimate.ts +113 -0
- package/src/hooks/useWithdrawalEstimate.ts +117 -0
- package/src/index.ts +9 -18
- package/src/types/index.ts +78 -0
- package/src/utils/errors.ts +36 -0
- package/src/utils/format.ts +65 -0
- package/src/utils/index.ts +3 -0
- package/src/contexts/BalancesContext.tsx +0 -63
- package/src/contexts/CurrenciesContext.tsx +0 -64
- package/src/contexts/OverviewContext.tsx +0 -173
- package/src/contexts/PaymentsContext.tsx +0 -122
- package/src/contexts/PaymentsExtensionProvider.tsx +0 -56
- package/src/contexts/README.md +0 -201
- package/src/contexts/RootPaymentsContext.tsx +0 -66
- package/src/layouts/PaymentsLayout/PaymentsLayout.tsx +0 -90
- package/src/layouts/PaymentsLayout/components/CreatePaymentDialog.tsx +0 -274
- package/src/layouts/PaymentsLayout/components/PaymentDetailsDialog.tsx +0 -287
- package/src/layouts/PaymentsLayout/components/index.ts +0 -2
- package/src/layouts/PaymentsLayout/events.ts +0 -47
- package/src/layouts/PaymentsLayout/index.ts +0 -16
- package/src/layouts/PaymentsLayout/types.ts +0 -6
- package/src/layouts/PaymentsLayout/views/overview/components/BalanceCard.tsx +0 -121
- package/src/layouts/PaymentsLayout/views/overview/components/RecentPayments.tsx +0 -139
- package/src/layouts/PaymentsLayout/views/overview/components/index.ts +0 -2
- package/src/layouts/PaymentsLayout/views/overview/index.tsx +0 -21
- package/src/layouts/PaymentsLayout/views/payments/components/PaymentsList.tsx +0 -279
- package/src/layouts/PaymentsLayout/views/payments/components/index.ts +0 -1
- package/src/layouts/PaymentsLayout/views/payments/index.tsx +0 -18
- package/src/layouts/PaymentsLayout/views/transactions/components/TransactionsList.tsx +0 -260
- package/src/layouts/PaymentsLayout/views/transactions/components/index.ts +0 -1
- 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
|
@@ -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
|
+
}
|
package/src/contexts/index.ts
CHANGED
|
@@ -1,45 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
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
|
-
//
|
|
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
|
-
//
|
|
8
|
+
// Context
|
|
29
9
|
export {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
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';
|
package/src/contexts/types.ts
CHANGED
|
@@ -1,40 +1,46 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Payments Types
|
|
3
|
-
*
|
|
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
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
export type
|
|
20
|
-
export type
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
export type
|
|
33
|
-
export type
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
//
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
export type
|
|
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';
|
package/src/hooks/index.ts
CHANGED
|
@@ -1,20 +1,3 @@
|
|
|
1
|
-
|
|
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
|
+
}
|