@djangocfg/ext-payments 1.0.17 → 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 +1 -1
- package/dist/config.js +1 -1
- package/dist/index.cjs +1175 -290
- package/dist/index.d.cts +226 -80
- package/dist/index.d.ts +226 -80
- package/dist/index.js +1157 -255
- package/package.json +9 -9
- package/src/WalletPage.tsx +100 -0
- package/src/api/generated/ext_payments/CLAUDE.md +6 -4
- package/src/api/generated/ext_payments/_utils/fetchers/ext_payments__payments.ts +37 -6
- package/src/api/generated/ext_payments/_utils/hooks/ext_payments__payments.ts +34 -3
- package/src/api/generated/ext_payments/_utils/schemas/Balance.schema.ts +1 -1
- 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/WithdrawalCreateResponse.schema.ts +22 -0
- package/src/api/generated/ext_payments/_utils/schemas/WithdrawalDetail.schema.ts +5 -5
- package/src/api/generated/ext_payments/_utils/schemas/WithdrawalList.schema.ts +2 -2
- package/src/api/generated/ext_payments/_utils/schemas/index.ts +3 -0
- package/src/api/generated/ext_payments/client.ts +1 -1
- package/src/api/generated/ext_payments/ext_payments__payments/client.ts +49 -4
- package/src/api/generated/ext_payments/ext_payments__payments/models.ts +33 -14
- package/src/api/generated/ext_payments/index.ts +1 -1
- package/src/api/generated/ext_payments/schema.json +167 -33
- package/src/components/AddFundsSheet.tsx +157 -73
- package/src/components/CurrencyCombobox.tsx +49 -0
- package/src/components/PaymentSheet.tsx +94 -32
- package/src/components/WithdrawSheet.tsx +121 -95
- package/src/components/WithdrawalSheet.tsx +332 -0
- package/src/components/index.ts +1 -8
- package/src/config.ts +1 -0
- package/src/contexts/WalletContext.tsx +10 -9
- package/src/contexts/index.ts +5 -1
- package/src/contexts/types.ts +46 -0
- package/src/hooks/index.ts +3 -0
- 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 +3 -0
- 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/components/ResponsiveSheet.tsx +0 -151
package/dist/index.js
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
|
+
import { createContext, useState, useMemo, useCallback, useEffect, useContext, useRef } from 'react';
|
|
2
|
+
import { initializeExtensionAPI, createExtensionAPI } from '@djangocfg/ext-base/api';
|
|
1
3
|
import { createConsola, consola } from 'consola';
|
|
2
4
|
import pRetry, { AbortError } from 'p-retry';
|
|
3
5
|
import { z } from 'zod';
|
|
4
|
-
import {
|
|
5
|
-
import { Plus, ArrowUpRight, RefreshCw, AlertCircle, XCircle, CheckCircle2, Loader2, Clock, ArrowDownLeft, History, ChevronRight, ExternalLink } from 'lucide-react';
|
|
6
|
-
import { Skeleton, Button, TokenIcon, ResponsiveSheet, ResponsiveSheetContent, ResponsiveSheetHeader, ResponsiveSheetTitle, ResponsiveSheetDescription, Form, FormField, FormItem, FormLabel, FormControl, Input, FormMessage, Combobox, Alert, AlertDescription, CopyButton, useIsMobile, Drawer, Dialog, DrawerContent, DialogContent, DrawerHeader, DialogHeader, DrawerTitle, DialogTitle, DrawerDescription, DialogDescription, DrawerFooter, DialogFooter } from '@djangocfg/ui-core';
|
|
7
|
-
import { cn } from '@djangocfg/ui-core/lib';
|
|
8
|
-
import * as React2 from 'react';
|
|
9
|
-
import { createContext, useState, useMemo, useCallback, useEffect, useContext } from 'react';
|
|
10
|
-
import useSWR2 from 'swr';
|
|
6
|
+
import useSWR, { useSWRConfig } from 'swr';
|
|
11
7
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
12
|
-
import
|
|
8
|
+
import { Plus, ArrowUpRight, RefreshCw, AlertCircle, XCircle, CheckCircle2, Loader2, Clock, ArrowDownLeft, History, ChevronRight, Ban, ExternalLink } from 'lucide-react';
|
|
9
|
+
import { Skeleton, Button, TokenIcon, useLocalStorage, ResponsiveSheet, ResponsiveSheetContent, ResponsiveSheetHeader, ResponsiveSheetTitle, ResponsiveSheetDescription, Form, FormField, FormItem, FormLabel, FormControl, Input, FormMessage, Alert, AlertDescription, CopyButton, Combobox } from '@djangocfg/ui-core';
|
|
10
|
+
import { cn } from '@djangocfg/ui-core/lib';
|
|
11
|
+
import moment3 from 'moment';
|
|
13
12
|
import { useForm } from 'react-hook-form';
|
|
14
13
|
import { zodResolver } from '@hookform/resolvers/zod';
|
|
15
14
|
import { createExtensionConfig } from '@djangocfg/ext-base';
|
|
@@ -38,12 +37,47 @@ var ExtPaymentsPayments = class {
|
|
|
38
37
|
/**
|
|
39
38
|
* Get available currencies
|
|
40
39
|
*
|
|
41
|
-
* Returns list of available currencies with token+network info
|
|
40
|
+
* Returns list of available currencies with token+network info, popular
|
|
41
|
+
* first
|
|
42
42
|
*/
|
|
43
43
|
async currenciesList() {
|
|
44
44
|
const response = await this.client.request("GET", "/cfg/payments/currencies/");
|
|
45
45
|
return response;
|
|
46
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* Get currency estimate
|
|
49
|
+
*
|
|
50
|
+
* Get estimated crypto amount for a given USD amount, including min amount
|
|
51
|
+
*/
|
|
52
|
+
async currenciesEstimateRetrieve(...args) {
|
|
53
|
+
const code = args[0];
|
|
54
|
+
const isParamsObject = args.length === 2 && typeof args[1] === "object" && args[1] !== null && !Array.isArray(args[1]);
|
|
55
|
+
let params;
|
|
56
|
+
if (isParamsObject) {
|
|
57
|
+
params = args[1];
|
|
58
|
+
} else {
|
|
59
|
+
params = { amount: args[1] };
|
|
60
|
+
}
|
|
61
|
+
const response = await this.client.request("GET", `/cfg/payments/currencies/${code}/estimate/`, { params });
|
|
62
|
+
return response;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Get withdrawal estimate
|
|
66
|
+
*
|
|
67
|
+
* Get estimated crypto amount for withdrawal with fee breakdown
|
|
68
|
+
*/
|
|
69
|
+
async currenciesWithdrawalEstimateRetrieve(...args) {
|
|
70
|
+
const code = args[0];
|
|
71
|
+
const isParamsObject = args.length === 2 && typeof args[1] === "object" && args[1] !== null && !Array.isArray(args[1]);
|
|
72
|
+
let params;
|
|
73
|
+
if (isParamsObject) {
|
|
74
|
+
params = args[1];
|
|
75
|
+
} else {
|
|
76
|
+
params = { amount: args[1] };
|
|
77
|
+
}
|
|
78
|
+
const response = await this.client.request("GET", `/cfg/payments/currencies/${code}/withdrawal-estimate/`, { params });
|
|
79
|
+
return response;
|
|
80
|
+
}
|
|
47
81
|
/**
|
|
48
82
|
* ViewSet for payment operations. Endpoints: - GET /payments/ - List
|
|
49
83
|
* user's payments - GET /payments/{id}/ - Get payment details - POST
|
|
@@ -721,8 +755,8 @@ var APIClient = class {
|
|
|
721
755
|
// src/api/generated/ext_payments/storage.ts
|
|
722
756
|
var LocalStorageAdapter = class {
|
|
723
757
|
logger;
|
|
724
|
-
constructor(
|
|
725
|
-
this.logger =
|
|
758
|
+
constructor(logger2) {
|
|
759
|
+
this.logger = logger2;
|
|
726
760
|
}
|
|
727
761
|
getItem(key) {
|
|
728
762
|
try {
|
|
@@ -764,8 +798,8 @@ var LocalStorageAdapter = class {
|
|
|
764
798
|
};
|
|
765
799
|
var CookieStorageAdapter = class {
|
|
766
800
|
logger;
|
|
767
|
-
constructor(
|
|
768
|
-
this.logger =
|
|
801
|
+
constructor(logger2) {
|
|
802
|
+
this.logger = logger2;
|
|
769
803
|
}
|
|
770
804
|
getItem(key) {
|
|
771
805
|
try {
|
|
@@ -814,8 +848,8 @@ var CookieStorageAdapter = class {
|
|
|
814
848
|
var MemoryStorageAdapter = class {
|
|
815
849
|
storage = /* @__PURE__ */ new Map();
|
|
816
850
|
logger;
|
|
817
|
-
constructor(
|
|
818
|
-
this.logger =
|
|
851
|
+
constructor(logger2) {
|
|
852
|
+
this.logger = logger2;
|
|
819
853
|
}
|
|
820
854
|
getItem(key) {
|
|
821
855
|
const value = this.storage.get(key) || null;
|
|
@@ -900,10 +934,13 @@ __export(schemas_exports, {
|
|
|
900
934
|
PaginatedPaymentListListSchema: () => PaginatedPaymentListListSchema,
|
|
901
935
|
PaginatedWithdrawalListListSchema: () => PaginatedWithdrawalListListSchema,
|
|
902
936
|
PaymentCreateRequestSchema: () => PaymentCreateRequestSchema,
|
|
937
|
+
PaymentCreateResponseSchema: () => PaymentCreateResponseSchema,
|
|
903
938
|
PaymentDetailSchema: () => PaymentDetailSchema,
|
|
904
939
|
PaymentListSchema: () => PaymentListSchema,
|
|
905
940
|
TransactionSchema: () => TransactionSchema,
|
|
941
|
+
WithdrawalCancelResponseSchema: () => WithdrawalCancelResponseSchema,
|
|
906
942
|
WithdrawalCreateRequestSchema: () => WithdrawalCreateRequestSchema,
|
|
943
|
+
WithdrawalCreateResponseSchema: () => WithdrawalCreateResponseSchema,
|
|
907
944
|
WithdrawalDetailSchema: () => WithdrawalDetailSchema,
|
|
908
945
|
WithdrawalListSchema: () => WithdrawalListSchema
|
|
909
946
|
});
|
|
@@ -912,7 +949,7 @@ var BalanceSchema = z.object({
|
|
|
912
949
|
balance_display: z.string(),
|
|
913
950
|
total_deposited: z.string(),
|
|
914
951
|
total_withdrawn: z.string(),
|
|
915
|
-
last_transaction_at: z.
|
|
952
|
+
last_transaction_at: z.string().datetime({ offset: true }).nullable()
|
|
916
953
|
});
|
|
917
954
|
var CurrencySchema = z.object({
|
|
918
955
|
code: z.string(),
|
|
@@ -934,8 +971,8 @@ var PaymentListSchema = z.object({
|
|
|
934
971
|
currency_token: z.string(),
|
|
935
972
|
status: z.nativeEnum(PaymentListStatus),
|
|
936
973
|
status_display: z.string(),
|
|
937
|
-
created_at: z.
|
|
938
|
-
completed_at: z.
|
|
974
|
+
created_at: z.string().datetime({ offset: true }),
|
|
975
|
+
completed_at: z.string().datetime({ offset: true }).nullable()
|
|
939
976
|
});
|
|
940
977
|
|
|
941
978
|
// src/api/generated/ext_payments/_utils/schemas/PaginatedPaymentListList.schema.ts
|
|
@@ -959,8 +996,8 @@ var WithdrawalListSchema = z.object({
|
|
|
959
996
|
currency_token: z.string(),
|
|
960
997
|
status: z.nativeEnum(WithdrawalListStatus),
|
|
961
998
|
status_display: z.string(),
|
|
962
|
-
created_at: z.
|
|
963
|
-
completed_at: z.
|
|
999
|
+
created_at: z.string().datetime({ offset: true }),
|
|
1000
|
+
completed_at: z.string().datetime({ offset: true }).nullable()
|
|
964
1001
|
});
|
|
965
1002
|
|
|
966
1003
|
// src/api/generated/ext_payments/_utils/schemas/PaginatedWithdrawalListList.schema.ts
|
|
@@ -999,14 +1036,21 @@ var PaymentDetailSchema = z.object({
|
|
|
999
1036
|
transaction_hash: z.string().nullable(),
|
|
1000
1037
|
explorer_link: z.string().nullable(),
|
|
1001
1038
|
confirmations_count: z.int(),
|
|
1002
|
-
expires_at: z.
|
|
1003
|
-
completed_at: z.
|
|
1004
|
-
created_at: z.
|
|
1039
|
+
expires_at: z.string().datetime({ offset: true }).nullable(),
|
|
1040
|
+
completed_at: z.string().datetime({ offset: true }).nullable(),
|
|
1041
|
+
created_at: z.string().datetime({ offset: true }),
|
|
1005
1042
|
is_completed: z.boolean(),
|
|
1006
1043
|
is_failed: z.boolean(),
|
|
1007
1044
|
is_expired: z.boolean(),
|
|
1008
1045
|
description: z.string()
|
|
1009
1046
|
});
|
|
1047
|
+
|
|
1048
|
+
// src/api/generated/ext_payments/_utils/schemas/PaymentCreateResponse.schema.ts
|
|
1049
|
+
var PaymentCreateResponseSchema = z.object({
|
|
1050
|
+
success: z.boolean(),
|
|
1051
|
+
payment: PaymentDetailSchema,
|
|
1052
|
+
qr_code_url: z.union([z.url(), z.literal("")]).nullable()
|
|
1053
|
+
});
|
|
1010
1054
|
var TransactionSchema = z.object({
|
|
1011
1055
|
id: z.string().regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i),
|
|
1012
1056
|
transaction_type: z.nativeEnum(TransactionTransactionType),
|
|
@@ -1016,12 +1060,7 @@ var TransactionSchema = z.object({
|
|
|
1016
1060
|
balance_after: z.string(),
|
|
1017
1061
|
payment_id: z.string().nullable(),
|
|
1018
1062
|
description: z.string(),
|
|
1019
|
-
created_at: z.
|
|
1020
|
-
});
|
|
1021
|
-
var WithdrawalCreateRequestSchema = z.object({
|
|
1022
|
-
amount_usd: z.string(),
|
|
1023
|
-
currency_code: z.string().min(1).max(20),
|
|
1024
|
-
wallet_address: z.string().min(1).max(255)
|
|
1063
|
+
created_at: z.string().datetime({ offset: true })
|
|
1025
1064
|
});
|
|
1026
1065
|
var WithdrawalDetailSchema = z.object({
|
|
1027
1066
|
id: z.string().regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i),
|
|
@@ -1042,11 +1081,28 @@ var WithdrawalDetailSchema = z.object({
|
|
|
1042
1081
|
transaction_hash: z.string().nullable(),
|
|
1043
1082
|
explorer_link: z.string().nullable(),
|
|
1044
1083
|
admin_notes: z.string(),
|
|
1045
|
-
created_at: z.
|
|
1046
|
-
approved_at: z.
|
|
1047
|
-
completed_at: z.
|
|
1048
|
-
rejected_at: z.
|
|
1049
|
-
cancelled_at: z.
|
|
1084
|
+
created_at: z.string().datetime({ offset: true }),
|
|
1085
|
+
approved_at: z.string().datetime({ offset: true }).nullable(),
|
|
1086
|
+
completed_at: z.string().datetime({ offset: true }).nullable(),
|
|
1087
|
+
rejected_at: z.string().datetime({ offset: true }).nullable(),
|
|
1088
|
+
cancelled_at: z.string().datetime({ offset: true }).nullable()
|
|
1089
|
+
});
|
|
1090
|
+
|
|
1091
|
+
// src/api/generated/ext_payments/_utils/schemas/WithdrawalCancelResponse.schema.ts
|
|
1092
|
+
var WithdrawalCancelResponseSchema = z.object({
|
|
1093
|
+
success: z.boolean(),
|
|
1094
|
+
withdrawal: WithdrawalDetailSchema,
|
|
1095
|
+
message: z.string()
|
|
1096
|
+
});
|
|
1097
|
+
var WithdrawalCreateRequestSchema = z.object({
|
|
1098
|
+
amount_usd: z.string(),
|
|
1099
|
+
currency_code: z.string().min(1).max(20),
|
|
1100
|
+
wallet_address: z.string().min(1).max(255)
|
|
1101
|
+
});
|
|
1102
|
+
var WithdrawalCreateResponseSchema = z.object({
|
|
1103
|
+
success: z.boolean(),
|
|
1104
|
+
withdrawal: WithdrawalDetailSchema,
|
|
1105
|
+
message: z.string()
|
|
1050
1106
|
});
|
|
1051
1107
|
|
|
1052
1108
|
// src/api/generated/ext_payments/validation-events.ts
|
|
@@ -1103,7 +1159,9 @@ __export(fetchers_exports, {
|
|
|
1103
1159
|
createPaymentsWithdrawalsCancelCreate: () => createPaymentsWithdrawalsCancelCreate,
|
|
1104
1160
|
createPaymentsWithdrawalsCreateCreate: () => createPaymentsWithdrawalsCreateCreate,
|
|
1105
1161
|
getPaymentsBalanceRetrieve: () => getPaymentsBalanceRetrieve,
|
|
1162
|
+
getPaymentsCurrenciesEstimateRetrieve: () => getPaymentsCurrenciesEstimateRetrieve,
|
|
1106
1163
|
getPaymentsCurrenciesList: () => getPaymentsCurrenciesList,
|
|
1164
|
+
getPaymentsCurrenciesWithdrawalEstimateRetrieve: () => getPaymentsCurrenciesWithdrawalEstimateRetrieve,
|
|
1107
1165
|
getPaymentsPaymentsList: () => getPaymentsPaymentsList,
|
|
1108
1166
|
getPaymentsPaymentsRetrieve: () => getPaymentsPaymentsRetrieve,
|
|
1109
1167
|
getPaymentsPaymentsStatusRetrieve: () => getPaymentsPaymentsStatusRetrieve,
|
|
@@ -1214,6 +1272,16 @@ async function getPaymentsCurrenciesList(client) {
|
|
|
1214
1272
|
const response = await api.ext_payments_payments.currenciesList();
|
|
1215
1273
|
return response;
|
|
1216
1274
|
}
|
|
1275
|
+
async function getPaymentsCurrenciesEstimateRetrieve(code, params, client) {
|
|
1276
|
+
const api = client || getAPIInstance();
|
|
1277
|
+
const response = await api.ext_payments_payments.currenciesEstimateRetrieve(code, params?.amount);
|
|
1278
|
+
return response;
|
|
1279
|
+
}
|
|
1280
|
+
async function getPaymentsCurrenciesWithdrawalEstimateRetrieve(code, params, client) {
|
|
1281
|
+
const api = client || getAPIInstance();
|
|
1282
|
+
const response = await api.ext_payments_payments.currenciesWithdrawalEstimateRetrieve(code, params?.amount);
|
|
1283
|
+
return response;
|
|
1284
|
+
}
|
|
1217
1285
|
async function getPaymentsPaymentsList(params, client) {
|
|
1218
1286
|
const api = client || getAPIInstance();
|
|
1219
1287
|
const response = await api.ext_payments_payments.paymentsList(params?.page, params?.page_size);
|
|
@@ -1386,7 +1454,7 @@ async function createPaymentsPaymentsCreateCreate(data, client) {
|
|
|
1386
1454
|
const api = client || getAPIInstance();
|
|
1387
1455
|
const response = await api.ext_payments_payments.paymentsCreateCreate(data);
|
|
1388
1456
|
try {
|
|
1389
|
-
return
|
|
1457
|
+
return PaymentCreateResponseSchema.parse(response);
|
|
1390
1458
|
} catch (error) {
|
|
1391
1459
|
consola.error("\u274C Zod Validation Failed");
|
|
1392
1460
|
consola.box(`createPaymentsPaymentsCreateCreate
|
|
@@ -1517,7 +1585,7 @@ async function createPaymentsWithdrawalsCancelCreate(id, client) {
|
|
|
1517
1585
|
const api = client || getAPIInstance();
|
|
1518
1586
|
const response = await api.ext_payments_payments.withdrawalsCancelCreate(id);
|
|
1519
1587
|
try {
|
|
1520
|
-
return
|
|
1588
|
+
return WithdrawalCancelResponseSchema.parse(response);
|
|
1521
1589
|
} catch (error) {
|
|
1522
1590
|
consola.error("\u274C Zod Validation Failed");
|
|
1523
1591
|
consola.box(`createPaymentsWithdrawalsCancelCreate
|
|
@@ -1559,7 +1627,7 @@ async function createPaymentsWithdrawalsCreateCreate(data, client) {
|
|
|
1559
1627
|
const api = client || getAPIInstance();
|
|
1560
1628
|
const response = await api.ext_payments_payments.withdrawalsCreateCreate(data);
|
|
1561
1629
|
try {
|
|
1562
|
-
return
|
|
1630
|
+
return WithdrawalCreateResponseSchema.parse(response);
|
|
1563
1631
|
} catch (error) {
|
|
1564
1632
|
consola.error("\u274C Zod Validation Failed");
|
|
1565
1633
|
consola.box(`createPaymentsWithdrawalsCreateCreate
|
|
@@ -1613,8 +1681,8 @@ var API = class {
|
|
|
1613
1681
|
constructor(baseUrl, options) {
|
|
1614
1682
|
this.baseUrl = baseUrl;
|
|
1615
1683
|
this.options = options;
|
|
1616
|
-
const
|
|
1617
|
-
this.storage = options?.storage || new LocalStorageAdapter(
|
|
1684
|
+
const logger2 = options?.loggerConfig ? new APILogger(options.loggerConfig) : void 0;
|
|
1685
|
+
this.storage = options?.storage || new LocalStorageAdapter(logger2);
|
|
1618
1686
|
this._loadTokensFromStorage();
|
|
1619
1687
|
this._client = new APIClient(this.baseUrl, {
|
|
1620
1688
|
retryConfig: this.options?.retryConfig,
|
|
@@ -1723,9 +1791,215 @@ var API = class {
|
|
|
1723
1791
|
return "./schema.json";
|
|
1724
1792
|
}
|
|
1725
1793
|
};
|
|
1794
|
+
|
|
1795
|
+
// src/api/index.ts
|
|
1726
1796
|
initializeExtensionAPI(configureAPI);
|
|
1727
1797
|
var apiPayments = createExtensionAPI(API);
|
|
1798
|
+
function usePaymentsBalanceRetrieve(client) {
|
|
1799
|
+
return useSWR(
|
|
1800
|
+
"cfg-payments-balance",
|
|
1801
|
+
() => getPaymentsBalanceRetrieve(client)
|
|
1802
|
+
);
|
|
1803
|
+
}
|
|
1804
|
+
function usePaymentsCurrenciesList(client) {
|
|
1805
|
+
return useSWR(
|
|
1806
|
+
"cfg-payments-currencies",
|
|
1807
|
+
() => getPaymentsCurrenciesList(client)
|
|
1808
|
+
);
|
|
1809
|
+
}
|
|
1810
|
+
function usePaymentsPaymentsList(params, client) {
|
|
1811
|
+
return useSWR(
|
|
1812
|
+
params ? ["cfg-payments-payments", params] : "cfg-payments-payments",
|
|
1813
|
+
() => getPaymentsPaymentsList(params, client)
|
|
1814
|
+
);
|
|
1815
|
+
}
|
|
1816
|
+
function useCreatePaymentsPaymentsCreateCreate() {
|
|
1817
|
+
const { mutate } = useSWRConfig();
|
|
1818
|
+
return async (data, client) => {
|
|
1819
|
+
const result = await createPaymentsPaymentsCreateCreate(data, client);
|
|
1820
|
+
mutate("cfg-payments-payments");
|
|
1821
|
+
return result;
|
|
1822
|
+
};
|
|
1823
|
+
}
|
|
1824
|
+
function usePaymentsTransactionsList(params, client) {
|
|
1825
|
+
return useSWR(
|
|
1826
|
+
params ? ["cfg-payments-transactions", params] : "cfg-payments-transactions",
|
|
1827
|
+
() => getPaymentsTransactionsList(params, client)
|
|
1828
|
+
);
|
|
1829
|
+
}
|
|
1830
|
+
function usePaymentsWithdrawalsList(params, client) {
|
|
1831
|
+
return useSWR(
|
|
1832
|
+
params ? ["cfg-payments-withdrawals", params] : "cfg-payments-withdrawals",
|
|
1833
|
+
() => getPaymentsWithdrawalsList(params, client)
|
|
1834
|
+
);
|
|
1835
|
+
}
|
|
1836
|
+
function useCreatePaymentsWithdrawalsCancelCreate() {
|
|
1837
|
+
const { mutate } = useSWRConfig();
|
|
1838
|
+
return async (id, client) => {
|
|
1839
|
+
const result = await createPaymentsWithdrawalsCancelCreate(id, client);
|
|
1840
|
+
mutate("cfg-payments-withdrawals-cancel");
|
|
1841
|
+
return result;
|
|
1842
|
+
};
|
|
1843
|
+
}
|
|
1844
|
+
function useCreatePaymentsWithdrawalsCreateCreate() {
|
|
1845
|
+
const { mutate } = useSWRConfig();
|
|
1846
|
+
return async (data, client) => {
|
|
1847
|
+
const result = await createPaymentsWithdrawalsCreateCreate(data, client);
|
|
1848
|
+
mutate("cfg-payments-withdrawals");
|
|
1849
|
+
return result;
|
|
1850
|
+
};
|
|
1851
|
+
}
|
|
1728
1852
|
var WalletContext = createContext(void 0);
|
|
1853
|
+
function WalletProvider({ children }) {
|
|
1854
|
+
const {
|
|
1855
|
+
data: balance,
|
|
1856
|
+
isLoading: isLoadingBalance,
|
|
1857
|
+
mutate: mutateBalance
|
|
1858
|
+
} = usePaymentsBalanceRetrieve(apiPayments);
|
|
1859
|
+
const {
|
|
1860
|
+
data: paymentsData,
|
|
1861
|
+
isLoading: isLoadingPayments,
|
|
1862
|
+
mutate: mutatePayments
|
|
1863
|
+
} = usePaymentsPaymentsList({ page: 1, page_size: 20 }, apiPayments);
|
|
1864
|
+
const {
|
|
1865
|
+
data: transactionsData,
|
|
1866
|
+
isLoading: isLoadingTransactions,
|
|
1867
|
+
mutate: mutateTransactions
|
|
1868
|
+
} = usePaymentsTransactionsList({ limit: 20 }, apiPayments);
|
|
1869
|
+
const {
|
|
1870
|
+
data: currenciesData,
|
|
1871
|
+
isLoading: isLoadingCurrencies,
|
|
1872
|
+
mutate: mutateCurrencies
|
|
1873
|
+
} = usePaymentsCurrenciesList(apiPayments);
|
|
1874
|
+
const {
|
|
1875
|
+
data: withdrawalsData,
|
|
1876
|
+
isLoading: isLoadingWithdrawals,
|
|
1877
|
+
mutate: mutateWithdrawals
|
|
1878
|
+
} = usePaymentsWithdrawalsList({ page: 1, page_size: 20 }, apiPayments);
|
|
1879
|
+
const createPaymentMutation = useCreatePaymentsPaymentsCreateCreate();
|
|
1880
|
+
const createWithdrawalMutation = useCreatePaymentsWithdrawalsCreateCreate();
|
|
1881
|
+
const cancelWithdrawalMutation = useCreatePaymentsWithdrawalsCancelCreate();
|
|
1882
|
+
const balanceAmount = useMemo(() => {
|
|
1883
|
+
if (!balance?.balance_usd) return 0;
|
|
1884
|
+
return parseFloat(balance.balance_usd) || 0;
|
|
1885
|
+
}, [balance]);
|
|
1886
|
+
const activity = useMemo(() => {
|
|
1887
|
+
const items = [];
|
|
1888
|
+
const payments = paymentsData?.results || [];
|
|
1889
|
+
for (const payment of payments) {
|
|
1890
|
+
items.push({
|
|
1891
|
+
id: `payment-${payment.id}`,
|
|
1892
|
+
type: "payment",
|
|
1893
|
+
amount: payment.amount_usd,
|
|
1894
|
+
amountDisplay: `+$${parseFloat(payment.amount_usd).toFixed(2)}`,
|
|
1895
|
+
currency: payment.currency_code,
|
|
1896
|
+
status: mapPaymentStatus(payment.status),
|
|
1897
|
+
statusDisplay: payment.status_display,
|
|
1898
|
+
description: `${payment.currency_code} payment`,
|
|
1899
|
+
createdAt: payment.created_at,
|
|
1900
|
+
payment
|
|
1901
|
+
});
|
|
1902
|
+
}
|
|
1903
|
+
const withdrawals = withdrawalsData?.results || [];
|
|
1904
|
+
for (const withdrawal of withdrawals) {
|
|
1905
|
+
items.push({
|
|
1906
|
+
id: `withdrawal-${withdrawal.id}`,
|
|
1907
|
+
type: "withdrawal",
|
|
1908
|
+
amount: withdrawal.amount_usd,
|
|
1909
|
+
amountDisplay: `-$${parseFloat(withdrawal.amount_usd).toFixed(2)}`,
|
|
1910
|
+
currency: withdrawal.currency_code,
|
|
1911
|
+
status: mapWithdrawalStatus(withdrawal.status),
|
|
1912
|
+
statusDisplay: withdrawal.status_display,
|
|
1913
|
+
description: `${withdrawal.currency_code} withdrawal`,
|
|
1914
|
+
createdAt: withdrawal.created_at,
|
|
1915
|
+
withdrawal
|
|
1916
|
+
});
|
|
1917
|
+
}
|
|
1918
|
+
const transactions = transactionsData?.results || transactionsData || [];
|
|
1919
|
+
if (Array.isArray(transactions)) {
|
|
1920
|
+
for (const tx of transactions) {
|
|
1921
|
+
if (tx.payment_id && payments.some((p) => p.id === tx.payment_id)) {
|
|
1922
|
+
continue;
|
|
1923
|
+
}
|
|
1924
|
+
const isDeposit = tx.transaction_type === "deposit";
|
|
1925
|
+
items.push({
|
|
1926
|
+
id: `tx-${tx.id}`,
|
|
1927
|
+
type: isDeposit ? "deposit" : "withdrawal",
|
|
1928
|
+
amount: tx.amount_usd,
|
|
1929
|
+
amountDisplay: `${isDeposit ? "+" : "-"}$${Math.abs(parseFloat(tx.amount_usd)).toFixed(2)}`,
|
|
1930
|
+
status: "completed",
|
|
1931
|
+
statusDisplay: "Completed",
|
|
1932
|
+
description: tx.description || tx.type_display,
|
|
1933
|
+
createdAt: tx.created_at,
|
|
1934
|
+
transaction: tx
|
|
1935
|
+
});
|
|
1936
|
+
}
|
|
1937
|
+
}
|
|
1938
|
+
items.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());
|
|
1939
|
+
return items;
|
|
1940
|
+
}, [paymentsData, withdrawalsData, transactionsData]);
|
|
1941
|
+
const currencies = useMemo(() => {
|
|
1942
|
+
const data = currenciesData?.currencies || currenciesData?.results || currenciesData || [];
|
|
1943
|
+
if (!Array.isArray(data)) return [];
|
|
1944
|
+
return data.filter((c) => c.is_enabled !== false).map((c) => ({
|
|
1945
|
+
code: c.code || c.currency_code || c.symbol,
|
|
1946
|
+
name: c.name || c.code,
|
|
1947
|
+
token: c.token || c.code,
|
|
1948
|
+
// Token symbol (e.g., USDT, WBTC) with fallback to code
|
|
1949
|
+
network: c.network || void 0,
|
|
1950
|
+
enabled: c.is_enabled !== false
|
|
1951
|
+
}));
|
|
1952
|
+
}, [currenciesData]);
|
|
1953
|
+
const addFunds = useCallback(async (data) => {
|
|
1954
|
+
const response = await createPaymentMutation(data, apiPayments);
|
|
1955
|
+
await Promise.all([mutateBalance(), mutatePayments(), mutateTransactions()]);
|
|
1956
|
+
return response.payment;
|
|
1957
|
+
}, [createPaymentMutation, mutateBalance, mutatePayments, mutateTransactions]);
|
|
1958
|
+
const withdraw = useCallback(async (data) => {
|
|
1959
|
+
const response = await createWithdrawalMutation(data, apiPayments);
|
|
1960
|
+
await Promise.all([mutateBalance(), mutateWithdrawals(), mutateTransactions()]);
|
|
1961
|
+
return response.withdrawal;
|
|
1962
|
+
}, [createWithdrawalMutation, mutateBalance, mutateWithdrawals, mutateTransactions]);
|
|
1963
|
+
const cancelWithdrawal = useCallback(async (id) => {
|
|
1964
|
+
await cancelWithdrawalMutation(id, apiPayments);
|
|
1965
|
+
await Promise.all([mutateBalance(), mutateWithdrawals(), mutateTransactions()]);
|
|
1966
|
+
}, [cancelWithdrawalMutation, mutateBalance, mutateWithdrawals, mutateTransactions]);
|
|
1967
|
+
const getPaymentDetails = useCallback(async (id) => {
|
|
1968
|
+
return apiPayments.ext_payments_payments.paymentsRetrieve(id);
|
|
1969
|
+
}, []);
|
|
1970
|
+
const getWithdrawalDetails = useCallback(async (id) => {
|
|
1971
|
+
return apiPayments.ext_payments_payments.withdrawalsRetrieve(id);
|
|
1972
|
+
}, []);
|
|
1973
|
+
const refreshWallet = useCallback(async () => {
|
|
1974
|
+
await Promise.all([
|
|
1975
|
+
mutateBalance(),
|
|
1976
|
+
mutatePayments(),
|
|
1977
|
+
mutateWithdrawals(),
|
|
1978
|
+
mutateTransactions(),
|
|
1979
|
+
mutateCurrencies()
|
|
1980
|
+
]);
|
|
1981
|
+
}, [mutateBalance, mutatePayments, mutateWithdrawals, mutateTransactions, mutateCurrencies]);
|
|
1982
|
+
const isLoading = isLoadingBalance || isLoadingPayments || isLoadingWithdrawals || isLoadingTransactions;
|
|
1983
|
+
const isLoadingActivity = isLoadingPayments || isLoadingWithdrawals || isLoadingTransactions;
|
|
1984
|
+
const value = {
|
|
1985
|
+
balance,
|
|
1986
|
+
balanceAmount,
|
|
1987
|
+
isLoadingBalance,
|
|
1988
|
+
activity,
|
|
1989
|
+
isLoadingActivity,
|
|
1990
|
+
hasMoreActivity: (paymentsData?.count || 0) > 20 || (withdrawalsData?.count || 0) > 20,
|
|
1991
|
+
currencies,
|
|
1992
|
+
isLoadingCurrencies,
|
|
1993
|
+
addFunds,
|
|
1994
|
+
withdraw,
|
|
1995
|
+
cancelWithdrawal,
|
|
1996
|
+
getPaymentDetails,
|
|
1997
|
+
getWithdrawalDetails,
|
|
1998
|
+
refreshWallet,
|
|
1999
|
+
isLoading
|
|
2000
|
+
};
|
|
2001
|
+
return /* @__PURE__ */ jsx(WalletContext.Provider, { value, children });
|
|
2002
|
+
}
|
|
1729
2003
|
function useWallet() {
|
|
1730
2004
|
const context = useContext(WalletContext);
|
|
1731
2005
|
if (!context) {
|
|
@@ -1733,6 +2007,44 @@ function useWallet() {
|
|
|
1733
2007
|
}
|
|
1734
2008
|
return context;
|
|
1735
2009
|
}
|
|
2010
|
+
function mapPaymentStatus(status) {
|
|
2011
|
+
switch (status?.toLowerCase()) {
|
|
2012
|
+
case "completed":
|
|
2013
|
+
case "success":
|
|
2014
|
+
case "finished":
|
|
2015
|
+
return "completed";
|
|
2016
|
+
case "pending":
|
|
2017
|
+
case "waiting":
|
|
2018
|
+
return "pending";
|
|
2019
|
+
case "confirming":
|
|
2020
|
+
case "partially_paid":
|
|
2021
|
+
return "confirming";
|
|
2022
|
+
case "expired":
|
|
2023
|
+
return "expired";
|
|
2024
|
+
case "failed":
|
|
2025
|
+
case "error":
|
|
2026
|
+
case "cancelled":
|
|
2027
|
+
return "failed";
|
|
2028
|
+
default:
|
|
2029
|
+
return "pending";
|
|
2030
|
+
}
|
|
2031
|
+
}
|
|
2032
|
+
function mapWithdrawalStatus(status) {
|
|
2033
|
+
switch (status?.toLowerCase()) {
|
|
2034
|
+
case "completed":
|
|
2035
|
+
return "completed";
|
|
2036
|
+
case "pending":
|
|
2037
|
+
case "approved":
|
|
2038
|
+
return "pending";
|
|
2039
|
+
case "processing":
|
|
2040
|
+
return "confirming";
|
|
2041
|
+
case "rejected":
|
|
2042
|
+
case "cancelled":
|
|
2043
|
+
return "failed";
|
|
2044
|
+
default:
|
|
2045
|
+
return "pending";
|
|
2046
|
+
}
|
|
2047
|
+
}
|
|
1736
2048
|
function BalanceHero({ onAddFunds, onWithdraw, className }) {
|
|
1737
2049
|
const { balance, balanceAmount, isLoadingBalance, refreshWallet } = useWallet();
|
|
1738
2050
|
const formattedBalance = new Intl.NumberFormat("en-US", {
|
|
@@ -1838,7 +2150,7 @@ function ActivityItem({ item, onClick }) {
|
|
|
1838
2150
|
const StatusIcon = config.icon;
|
|
1839
2151
|
const isPositive = item.type === "payment" || item.type === "deposit";
|
|
1840
2152
|
const DirectionIcon = isPositive ? ArrowDownLeft : ArrowUpRight;
|
|
1841
|
-
const relativeTime =
|
|
2153
|
+
const relativeTime = moment3(item.createdAt).fromNow();
|
|
1842
2154
|
return /* @__PURE__ */ jsxs(
|
|
1843
2155
|
"button",
|
|
1844
2156
|
{
|
|
@@ -1927,41 +2239,299 @@ function ActivityList({
|
|
|
1927
2239
|
)) })
|
|
1928
2240
|
] });
|
|
1929
2241
|
}
|
|
2242
|
+
function useEstimate({
|
|
2243
|
+
currencyCode,
|
|
2244
|
+
amountUsd,
|
|
2245
|
+
minAmount = 0,
|
|
2246
|
+
debounceMs = 300,
|
|
2247
|
+
skip = false
|
|
2248
|
+
}) {
|
|
2249
|
+
const [estimate, setEstimate] = useState(null);
|
|
2250
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
2251
|
+
const [error, setError] = useState(null);
|
|
2252
|
+
useEffect(() => {
|
|
2253
|
+
if (skip || !currencyCode || amountUsd < minAmount) {
|
|
2254
|
+
setEstimate(null);
|
|
2255
|
+
setError(null);
|
|
2256
|
+
return;
|
|
2257
|
+
}
|
|
2258
|
+
const fetchEstimate = async () => {
|
|
2259
|
+
setIsLoading(true);
|
|
2260
|
+
setError(null);
|
|
2261
|
+
try {
|
|
2262
|
+
const response = await apiPayments.ext_payments_payments.currenciesEstimateRetrieve(
|
|
2263
|
+
currencyCode,
|
|
2264
|
+
{ amount: amountUsd }
|
|
2265
|
+
);
|
|
2266
|
+
if (response?.success && response?.estimated_amount) {
|
|
2267
|
+
setEstimate({
|
|
2268
|
+
estimatedAmount: parseFloat(response.estimated_amount),
|
|
2269
|
+
usdRate: parseFloat(response.usd_rate) || 0,
|
|
2270
|
+
minAmountUsd: response.min_amount_usd ? parseFloat(response.min_amount_usd) : null,
|
|
2271
|
+
isStablecoin: response.is_stablecoin || false,
|
|
2272
|
+
// New fee fields
|
|
2273
|
+
amountToReceive: parseFloat(response.amount_to_receive) || amountUsd,
|
|
2274
|
+
serviceFeeUsd: parseFloat(response.service_fee_usd) || 0,
|
|
2275
|
+
serviceFeePercent: parseFloat(response.service_fee_percent) || 0,
|
|
2276
|
+
totalToPayUsd: parseFloat(response.total_to_pay_usd) || amountUsd
|
|
2277
|
+
});
|
|
2278
|
+
} else {
|
|
2279
|
+
setEstimate(null);
|
|
2280
|
+
}
|
|
2281
|
+
} catch (err) {
|
|
2282
|
+
console.error("Failed to fetch estimate:", err);
|
|
2283
|
+
setEstimate(null);
|
|
2284
|
+
setError(err instanceof Error ? err : new Error("Failed to fetch estimate"));
|
|
2285
|
+
} finally {
|
|
2286
|
+
setIsLoading(false);
|
|
2287
|
+
}
|
|
2288
|
+
};
|
|
2289
|
+
const timeoutId = setTimeout(fetchEstimate, debounceMs);
|
|
2290
|
+
return () => clearTimeout(timeoutId);
|
|
2291
|
+
}, [currencyCode, amountUsd, minAmount, debounceMs, skip]);
|
|
2292
|
+
return { estimate, isLoading, error };
|
|
2293
|
+
}
|
|
2294
|
+
function useWithdrawalEstimate({
|
|
2295
|
+
currencyCode,
|
|
2296
|
+
amountUsd,
|
|
2297
|
+
minAmount = 10,
|
|
2298
|
+
debounceMs = 300,
|
|
2299
|
+
skip = false
|
|
2300
|
+
}) {
|
|
2301
|
+
const [estimate, setEstimate] = useState(null);
|
|
2302
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
2303
|
+
const [error, setError] = useState(null);
|
|
2304
|
+
useEffect(() => {
|
|
2305
|
+
if (skip || !currencyCode || amountUsd < minAmount) {
|
|
2306
|
+
setEstimate(null);
|
|
2307
|
+
setError(null);
|
|
2308
|
+
return;
|
|
2309
|
+
}
|
|
2310
|
+
const fetchEstimate = async () => {
|
|
2311
|
+
setIsLoading(true);
|
|
2312
|
+
setError(null);
|
|
2313
|
+
try {
|
|
2314
|
+
const response = await apiPayments.ext_payments_payments.currenciesWithdrawalEstimateRetrieve(
|
|
2315
|
+
currencyCode,
|
|
2316
|
+
{ amount: amountUsd }
|
|
2317
|
+
);
|
|
2318
|
+
if (response?.success && response?.estimated_amount) {
|
|
2319
|
+
setEstimate({
|
|
2320
|
+
estimatedAmount: parseFloat(response.estimated_amount),
|
|
2321
|
+
usdRate: parseFloat(response.usd_rate) || 0,
|
|
2322
|
+
minAmountUsd: response.min_amount_usd ? parseFloat(response.min_amount_usd) : null,
|
|
2323
|
+
isStablecoin: response.is_stablecoin || false,
|
|
2324
|
+
// Withdrawal-specific fields
|
|
2325
|
+
amountRequested: parseFloat(response.amount_requested) || amountUsd,
|
|
2326
|
+
serviceFeeUsd: parseFloat(response.service_fee_usd) || 0,
|
|
2327
|
+
serviceFeePercent: parseFloat(response.service_fee_percent) || 0,
|
|
2328
|
+
networkFeeUsd: parseFloat(response.network_fee_usd) || 0,
|
|
2329
|
+
totalFeesUsd: parseFloat(response.total_fees_usd) || 0,
|
|
2330
|
+
amountToReceive: parseFloat(response.amount_to_receive) || 0
|
|
2331
|
+
});
|
|
2332
|
+
} else {
|
|
2333
|
+
setEstimate(null);
|
|
2334
|
+
}
|
|
2335
|
+
} catch (err) {
|
|
2336
|
+
console.error("Failed to fetch withdrawal estimate:", err);
|
|
2337
|
+
setEstimate(null);
|
|
2338
|
+
setError(err instanceof Error ? err : new Error("Failed to fetch withdrawal estimate"));
|
|
2339
|
+
} finally {
|
|
2340
|
+
setIsLoading(false);
|
|
2341
|
+
}
|
|
2342
|
+
};
|
|
2343
|
+
const timeoutId = setTimeout(fetchEstimate, debounceMs);
|
|
2344
|
+
return () => clearTimeout(timeoutId);
|
|
2345
|
+
}, [currencyCode, amountUsd, minAmount, debounceMs, skip]);
|
|
2346
|
+
return { estimate, isLoading, error };
|
|
2347
|
+
}
|
|
2348
|
+
function useCurrencyOptions(currencies) {
|
|
2349
|
+
return useMemo(() => {
|
|
2350
|
+
return currencies.map((c) => ({
|
|
2351
|
+
value: c.code,
|
|
2352
|
+
label: c.name,
|
|
2353
|
+
token: c.token,
|
|
2354
|
+
network: c.network
|
|
2355
|
+
}));
|
|
2356
|
+
}, [currencies]);
|
|
2357
|
+
}
|
|
2358
|
+
function useDefaultCurrency({
|
|
2359
|
+
currencyOptions,
|
|
2360
|
+
savedCurrency,
|
|
2361
|
+
currentValue,
|
|
2362
|
+
setValue
|
|
2363
|
+
}) {
|
|
2364
|
+
useEffect(() => {
|
|
2365
|
+
if (currencyOptions.length > 0 && !currentValue) {
|
|
2366
|
+
const savedOption = savedCurrency && currencyOptions.find((c) => c.value === savedCurrency);
|
|
2367
|
+
if (savedOption) {
|
|
2368
|
+
setValue(savedOption.value);
|
|
2369
|
+
} else {
|
|
2370
|
+
const usdt = currencyOptions.find((c) => c.value.includes("USDT"));
|
|
2371
|
+
setValue(usdt?.value || currencyOptions[0].value);
|
|
2372
|
+
}
|
|
2373
|
+
}
|
|
2374
|
+
}, [currencyOptions, savedCurrency, currentValue, setValue]);
|
|
2375
|
+
}
|
|
2376
|
+
function useAutoSave(value, save, validate) {
|
|
2377
|
+
const saveRef = useRef(save);
|
|
2378
|
+
const validateRef = useRef(validate);
|
|
2379
|
+
useEffect(() => {
|
|
2380
|
+
saveRef.current = save;
|
|
2381
|
+
validateRef.current = validate;
|
|
2382
|
+
});
|
|
2383
|
+
useEffect(() => {
|
|
2384
|
+
const isValid = validateRef.current ? validateRef.current(value) : Boolean(value);
|
|
2385
|
+
if (isValid) {
|
|
2386
|
+
saveRef.current(value);
|
|
2387
|
+
}
|
|
2388
|
+
}, [value]);
|
|
2389
|
+
}
|
|
2390
|
+
|
|
2391
|
+
// src/utils/format.ts
|
|
2392
|
+
function formatUsdRate(rate) {
|
|
2393
|
+
if (rate >= 1) {
|
|
2394
|
+
return rate.toLocaleString(void 0, {
|
|
2395
|
+
minimumFractionDigits: 2,
|
|
2396
|
+
maximumFractionDigits: 2
|
|
2397
|
+
});
|
|
2398
|
+
} else if (rate >= 0.01) {
|
|
2399
|
+
return rate.toLocaleString(void 0, {
|
|
2400
|
+
minimumFractionDigits: 2,
|
|
2401
|
+
maximumFractionDigits: 4
|
|
2402
|
+
});
|
|
2403
|
+
} else if (rate >= 1e-4) {
|
|
2404
|
+
return rate.toLocaleString(void 0, {
|
|
2405
|
+
minimumFractionDigits: 4,
|
|
2406
|
+
maximumFractionDigits: 6
|
|
2407
|
+
});
|
|
2408
|
+
} else {
|
|
2409
|
+
return rate.toLocaleString(void 0, {
|
|
2410
|
+
minimumFractionDigits: 6,
|
|
2411
|
+
maximumFractionDigits: 8
|
|
2412
|
+
});
|
|
2413
|
+
}
|
|
2414
|
+
}
|
|
2415
|
+
function formatCryptoAmount(amount, isStablecoin) {
|
|
2416
|
+
const decimals = isStablecoin ? 2 : 8;
|
|
2417
|
+
return amount.toFixed(decimals);
|
|
2418
|
+
}
|
|
2419
|
+
function formatUsdAmount(amount, alwaysShowCents = false) {
|
|
2420
|
+
if (alwaysShowCents) {
|
|
2421
|
+
return amount.toFixed(2);
|
|
2422
|
+
}
|
|
2423
|
+
const hasCents = amount % 1 !== 0;
|
|
2424
|
+
if (hasCents) {
|
|
2425
|
+
return amount.toFixed(2);
|
|
2426
|
+
}
|
|
2427
|
+
return amount.toFixed(0);
|
|
2428
|
+
}
|
|
2429
|
+
|
|
2430
|
+
// src/utils/errors.ts
|
|
2431
|
+
function extractErrorMessage(err, fallback = "An error occurred") {
|
|
2432
|
+
if (!err) return fallback;
|
|
2433
|
+
const error = err;
|
|
2434
|
+
const responseData = error.response?.data;
|
|
2435
|
+
const response = responseData || error.response;
|
|
2436
|
+
if (response) {
|
|
2437
|
+
if (typeof response.error === "string") return response.error;
|
|
2438
|
+
if (typeof response.message === "string") return response.message;
|
|
2439
|
+
if (typeof response.detail === "string") return response.detail;
|
|
2440
|
+
}
|
|
2441
|
+
if (typeof error.errorMessage === "string") return error.errorMessage;
|
|
2442
|
+
if (typeof error.message === "string") return error.message;
|
|
2443
|
+
return fallback;
|
|
2444
|
+
}
|
|
2445
|
+
var isDevelopment = process.env.NODE_ENV === "development";
|
|
2446
|
+
createConsola({
|
|
2447
|
+
level: isDevelopment ? 4 : 1
|
|
2448
|
+
}).withTag("ext-payments");
|
|
2449
|
+
function CurrencyCombobox({
|
|
2450
|
+
options,
|
|
2451
|
+
value,
|
|
2452
|
+
onChange,
|
|
2453
|
+
disabled,
|
|
2454
|
+
placeholder = "Select currency..."
|
|
2455
|
+
}) {
|
|
2456
|
+
return /* @__PURE__ */ jsx(
|
|
2457
|
+
Combobox,
|
|
2458
|
+
{
|
|
2459
|
+
options,
|
|
2460
|
+
value,
|
|
2461
|
+
onValueChange: onChange,
|
|
2462
|
+
placeholder,
|
|
2463
|
+
searchPlaceholder: "Search...",
|
|
2464
|
+
disabled,
|
|
2465
|
+
className: "h-14",
|
|
2466
|
+
renderOption: (option) => /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 flex-1", children: [
|
|
2467
|
+
/* @__PURE__ */ jsx(TokenIcon, { symbol: option.value, size: 24 }),
|
|
2468
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium", children: option.label })
|
|
2469
|
+
] }),
|
|
2470
|
+
renderValue: (option) => option && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
2471
|
+
/* @__PURE__ */ jsx(TokenIcon, { symbol: option.value, size: 24 }),
|
|
2472
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium", children: option.label })
|
|
2473
|
+
] })
|
|
2474
|
+
}
|
|
2475
|
+
);
|
|
2476
|
+
}
|
|
1930
2477
|
var AddFundsSchema = z.object({
|
|
1931
|
-
amount: z.number().min(1, "Minimum $1
|
|
2478
|
+
amount: z.number().min(1, "Minimum $1"),
|
|
1932
2479
|
currency: z.string().min(1, "Select a currency")
|
|
1933
2480
|
});
|
|
2481
|
+
var STORAGE_KEY = "payments:addFunds";
|
|
1934
2482
|
function AddFundsSheet({ open, onOpenChange, onSuccess }) {
|
|
1935
2483
|
const { currencies, isLoadingCurrencies, addFunds } = useWallet();
|
|
1936
2484
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
|
1937
2485
|
const [error, setError] = useState(null);
|
|
2486
|
+
const [saved, setSaved] = useLocalStorage(STORAGE_KEY, {
|
|
2487
|
+
currency: "",
|
|
2488
|
+
amount: 100
|
|
2489
|
+
});
|
|
1938
2490
|
const form = useForm({
|
|
1939
2491
|
resolver: zodResolver(AddFundsSchema),
|
|
1940
2492
|
defaultValues: {
|
|
1941
|
-
amount:
|
|
1942
|
-
currency:
|
|
2493
|
+
amount: saved.amount,
|
|
2494
|
+
currency: saved.currency
|
|
1943
2495
|
}
|
|
1944
2496
|
});
|
|
1945
|
-
const
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
2497
|
+
const watchedAmount = form.watch("amount");
|
|
2498
|
+
const watchedCurrency = form.watch("currency");
|
|
2499
|
+
useAutoSave(watchedAmount, (v) => setSaved((prev) => ({ ...prev, amount: v })), (v) => v > 0);
|
|
2500
|
+
useAutoSave(watchedCurrency, (v) => setSaved((prev) => ({ ...prev, currency: v })));
|
|
2501
|
+
const currencyOptions = useCurrencyOptions(currencies);
|
|
2502
|
+
useDefaultCurrency({
|
|
2503
|
+
currencyOptions,
|
|
2504
|
+
savedCurrency: saved.currency,
|
|
2505
|
+
currentValue: watchedCurrency,
|
|
2506
|
+
setValue: (v) => form.setValue("currency", v)
|
|
2507
|
+
});
|
|
2508
|
+
const { estimate, isLoading: isLoadingEstimate } = useEstimate({
|
|
2509
|
+
currencyCode: watchedCurrency,
|
|
2510
|
+
amountUsd: watchedAmount,
|
|
2511
|
+
minAmount: 1
|
|
2512
|
+
});
|
|
2513
|
+
const selectedCurrency = currencyOptions.find((c) => c.value === watchedCurrency);
|
|
2514
|
+
const displayData = useMemo(() => {
|
|
2515
|
+
if (!selectedCurrency || !estimate) return null;
|
|
2516
|
+
const token = selectedCurrency.token;
|
|
2517
|
+
const cryptoAmount = formatCryptoAmount(estimate.estimatedAmount, estimate.isStablecoin);
|
|
2518
|
+
const rate = formatUsdRate(estimate.usdRate);
|
|
2519
|
+
const belowMinimum = estimate.minAmountUsd ? watchedAmount < estimate.minAmountUsd : false;
|
|
2520
|
+
const minAmount = estimate.minAmountUsd ? formatUsdAmount(estimate.minAmountUsd) : void 0;
|
|
2521
|
+
return {
|
|
2522
|
+
token,
|
|
2523
|
+
cryptoAmount,
|
|
2524
|
+
rate,
|
|
2525
|
+
showRate: !estimate.isStablecoin && estimate.usdRate > 0,
|
|
2526
|
+
belowMinimum,
|
|
2527
|
+
minAmount,
|
|
2528
|
+
// Fee breakdown from API
|
|
2529
|
+
amountToReceive: estimate.amountToReceive,
|
|
2530
|
+
serviceFeeUsd: estimate.serviceFeeUsd,
|
|
2531
|
+
serviceFeePercent: estimate.serviceFeePercent,
|
|
2532
|
+
totalToPayUsd: estimate.totalToPayUsd
|
|
2533
|
+
};
|
|
2534
|
+
}, [selectedCurrency, estimate, watchedAmount]);
|
|
1965
2535
|
const handleSubmit = useCallback(async (data) => {
|
|
1966
2536
|
try {
|
|
1967
2537
|
setIsSubmitting(true);
|
|
@@ -1974,19 +2544,22 @@ function AddFundsSheet({ open, onOpenChange, onSuccess }) {
|
|
|
1974
2544
|
onOpenChange(false);
|
|
1975
2545
|
onSuccess?.(result);
|
|
1976
2546
|
} catch (err) {
|
|
1977
|
-
|
|
1978
|
-
setError(message);
|
|
2547
|
+
setError(extractErrorMessage(err, "Failed to create payment"));
|
|
1979
2548
|
} finally {
|
|
1980
2549
|
setIsSubmitting(false);
|
|
1981
2550
|
}
|
|
1982
2551
|
}, [addFunds, form, onOpenChange, onSuccess]);
|
|
1983
2552
|
const handleOpenChange = useCallback((open2) => {
|
|
1984
|
-
if (
|
|
2553
|
+
if (open2) {
|
|
2554
|
+
form.reset({
|
|
2555
|
+
amount: saved.amount,
|
|
2556
|
+
currency: saved.currency
|
|
2557
|
+
});
|
|
2558
|
+
} else {
|
|
1985
2559
|
setError(null);
|
|
1986
|
-
form.reset();
|
|
1987
2560
|
}
|
|
1988
2561
|
onOpenChange(open2);
|
|
1989
|
-
}, [form, onOpenChange]);
|
|
2562
|
+
}, [form, onOpenChange, saved]);
|
|
1990
2563
|
return /* @__PURE__ */ jsx(ResponsiveSheet, { open, onOpenChange: handleOpenChange, children: /* @__PURE__ */ jsxs(ResponsiveSheetContent, { className: "sm:max-w-md", children: [
|
|
1991
2564
|
/* @__PURE__ */ jsxs(ResponsiveSheetHeader, { children: [
|
|
1992
2565
|
/* @__PURE__ */ jsx(ResponsiveSheetTitle, { children: "Add Funds" }),
|
|
@@ -2008,7 +2581,7 @@ function AddFundsSheet({ open, onOpenChange, onSuccess }) {
|
|
|
2008
2581
|
type: "number",
|
|
2009
2582
|
step: "0.01",
|
|
2010
2583
|
min: "1",
|
|
2011
|
-
placeholder: "100
|
|
2584
|
+
placeholder: "100",
|
|
2012
2585
|
className: "pl-8 text-2xl h-14 font-semibold",
|
|
2013
2586
|
...field,
|
|
2014
2587
|
onChange: (e) => field.onChange(parseFloat(e.target.value) || 0)
|
|
@@ -2027,51 +2600,78 @@ function AddFundsSheet({ open, onOpenChange, onSuccess }) {
|
|
|
2027
2600
|
render: ({ field }) => /* @__PURE__ */ jsxs(FormItem, { children: [
|
|
2028
2601
|
/* @__PURE__ */ jsx(FormLabel, { children: "Pay with" }),
|
|
2029
2602
|
/* @__PURE__ */ jsx(FormControl, { children: /* @__PURE__ */ jsx(
|
|
2030
|
-
|
|
2603
|
+
CurrencyCombobox,
|
|
2031
2604
|
{
|
|
2032
2605
|
options: currencyOptions,
|
|
2033
2606
|
value: field.value,
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
searchPlaceholder: "Search...",
|
|
2037
|
-
disabled: isLoadingCurrencies,
|
|
2038
|
-
className: "h-14",
|
|
2039
|
-
renderOption: (option) => /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 flex-1", children: [
|
|
2040
|
-
/* @__PURE__ */ jsx(TokenIcon, { symbol: option.value, size: 24 }),
|
|
2041
|
-
/* @__PURE__ */ jsx("span", { className: "font-medium", children: option.label })
|
|
2042
|
-
] }),
|
|
2043
|
-
renderValue: (option) => option && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
2044
|
-
/* @__PURE__ */ jsx(TokenIcon, { symbol: option.value, size: 24 }),
|
|
2045
|
-
/* @__PURE__ */ jsx("span", { className: "font-medium", children: option.label })
|
|
2046
|
-
] })
|
|
2607
|
+
onChange: field.onChange,
|
|
2608
|
+
disabled: isLoadingCurrencies
|
|
2047
2609
|
}
|
|
2048
2610
|
) }),
|
|
2049
2611
|
/* @__PURE__ */ jsx(FormMessage, {})
|
|
2050
2612
|
] })
|
|
2051
2613
|
}
|
|
2052
2614
|
),
|
|
2053
|
-
|
|
2054
|
-
/* @__PURE__ */
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
] })
|
|
2615
|
+
selectedCurrency && watchedAmount >= 1 && /* @__PURE__ */ jsx("div", { className: "bg-muted rounded-xl p-4 space-y-2", children: isLoadingEstimate ? /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center py-2", children: [
|
|
2616
|
+
/* @__PURE__ */ jsx(Loader2, { className: "h-5 w-5 animate-spin text-muted-foreground" }),
|
|
2617
|
+
/* @__PURE__ */ jsx("span", { className: "ml-2 text-sm text-muted-foreground", children: "Getting rate..." })
|
|
2618
|
+
] }) : displayData ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2619
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between text-sm", children: [
|
|
2620
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "Amount" }),
|
|
2621
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
2622
|
+
"$",
|
|
2623
|
+
formatUsdAmount(displayData.amountToReceive)
|
|
2063
2624
|
] })
|
|
2064
2625
|
] }),
|
|
2065
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between text-sm
|
|
2626
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between text-sm", children: [
|
|
2627
|
+
/* @__PURE__ */ jsxs("span", { className: "text-muted-foreground", children: [
|
|
2628
|
+
"Service fee (",
|
|
2629
|
+
displayData.serviceFeePercent,
|
|
2630
|
+
"%)"
|
|
2631
|
+
] }),
|
|
2632
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
2633
|
+
"+$",
|
|
2634
|
+
formatUsdAmount(displayData.serviceFeeUsd)
|
|
2635
|
+
] })
|
|
2636
|
+
] }),
|
|
2637
|
+
displayData.showRate && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between text-sm text-muted-foreground", children: [
|
|
2066
2638
|
/* @__PURE__ */ jsx("span", { children: "Rate" }),
|
|
2067
2639
|
/* @__PURE__ */ jsxs("span", { children: [
|
|
2068
2640
|
"1 ",
|
|
2069
|
-
|
|
2641
|
+
displayData.token,
|
|
2070
2642
|
" = $",
|
|
2071
|
-
|
|
2643
|
+
displayData.rate
|
|
2644
|
+
] })
|
|
2645
|
+
] }),
|
|
2646
|
+
/* @__PURE__ */ jsx("div", { className: "border-t pt-2 mt-2", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
2647
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium", children: "You will send" }),
|
|
2648
|
+
/* @__PURE__ */ jsxs("div", { className: "text-right", children: [
|
|
2649
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 justify-end", children: [
|
|
2650
|
+
/* @__PURE__ */ jsx(TokenIcon, { symbol: displayData.token, size: 20 }),
|
|
2651
|
+
/* @__PURE__ */ jsxs("span", { className: "font-mono font-semibold text-lg", children: [
|
|
2652
|
+
displayData.cryptoAmount,
|
|
2653
|
+
" ",
|
|
2654
|
+
displayData.token
|
|
2655
|
+
] })
|
|
2656
|
+
] }),
|
|
2657
|
+
/* @__PURE__ */ jsxs("div", { className: "text-sm text-muted-foreground", children: [
|
|
2658
|
+
"~$",
|
|
2659
|
+
formatUsdAmount(displayData.totalToPayUsd)
|
|
2660
|
+
] })
|
|
2072
2661
|
] })
|
|
2662
|
+
] }) }),
|
|
2663
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between text-sm pt-2", children: [
|
|
2664
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "You will receive" }),
|
|
2665
|
+
/* @__PURE__ */ jsxs("span", { className: "font-medium", children: [
|
|
2666
|
+
"$",
|
|
2667
|
+
formatUsdAmount(displayData.amountToReceive)
|
|
2668
|
+
] })
|
|
2669
|
+
] }),
|
|
2670
|
+
displayData.belowMinimum && displayData.minAmount && /* @__PURE__ */ jsxs("div", { className: "text-sm text-destructive mt-2 pt-2 border-t border-destructive/20", children: [
|
|
2671
|
+
"Minimum amount: $",
|
|
2672
|
+
displayData.minAmount
|
|
2073
2673
|
] })
|
|
2074
|
-
] }),
|
|
2674
|
+
] }) : /* @__PURE__ */ jsx("div", { className: "text-center text-sm text-muted-foreground py-2", children: "Enter amount to see conversion" }) }),
|
|
2075
2675
|
error && /* @__PURE__ */ jsx(Alert, { variant: "destructive", children: /* @__PURE__ */ jsx(AlertDescription, { children: error }) }),
|
|
2076
2676
|
/* @__PURE__ */ jsx(
|
|
2077
2677
|
Button,
|
|
@@ -2079,7 +2679,7 @@ function AddFundsSheet({ open, onOpenChange, onSuccess }) {
|
|
|
2079
2679
|
type: "submit",
|
|
2080
2680
|
size: "lg",
|
|
2081
2681
|
className: "w-full h-14 text-lg rounded-xl",
|
|
2082
|
-
disabled: isSubmitting || currencyOptions.length === 0,
|
|
2682
|
+
disabled: isSubmitting || currencyOptions.length === 0 || isLoadingEstimate || displayData?.belowMinimum,
|
|
2083
2683
|
children: isSubmitting ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2084
2684
|
/* @__PURE__ */ jsx(RefreshCw, { className: "h-5 w-5 mr-2 animate-spin" }),
|
|
2085
2685
|
"Creating..."
|
|
@@ -2090,54 +2690,54 @@ function AddFundsSheet({ open, onOpenChange, onSuccess }) {
|
|
|
2090
2690
|
] }) });
|
|
2091
2691
|
}
|
|
2092
2692
|
var WithdrawSchema = z.object({
|
|
2093
|
-
amount: z.number().min(10, "Minimum $10
|
|
2693
|
+
amount: z.number().min(10, "Minimum $10"),
|
|
2094
2694
|
currency: z.string().min(1, "Select a currency"),
|
|
2095
2695
|
wallet_address: z.string().min(26, "Invalid wallet address")
|
|
2096
2696
|
});
|
|
2097
|
-
var
|
|
2098
|
-
var NETWORK_FEE_USD = 1;
|
|
2697
|
+
var STORAGE_KEY2 = "payments:withdraw";
|
|
2099
2698
|
function WithdrawSheet({ open, onOpenChange, onSuccess }) {
|
|
2100
2699
|
const { currencies, isLoadingCurrencies, withdraw, balanceAmount } = useWallet();
|
|
2101
2700
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
|
2102
2701
|
const [error, setError] = useState(null);
|
|
2702
|
+
const [saved, setSaved] = useLocalStorage(STORAGE_KEY2, {
|
|
2703
|
+
currency: "",
|
|
2704
|
+
wallet: ""
|
|
2705
|
+
});
|
|
2103
2706
|
const form = useForm({
|
|
2104
2707
|
resolver: zodResolver(WithdrawSchema),
|
|
2105
2708
|
defaultValues: {
|
|
2106
2709
|
amount: 10,
|
|
2107
|
-
currency:
|
|
2108
|
-
wallet_address:
|
|
2710
|
+
currency: saved.currency,
|
|
2711
|
+
wallet_address: saved.wallet
|
|
2109
2712
|
}
|
|
2110
2713
|
});
|
|
2111
|
-
const
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
const
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2714
|
+
const watchedAmount = form.watch("amount");
|
|
2715
|
+
const watchedCurrency = form.watch("currency");
|
|
2716
|
+
const watchedWallet = form.watch("wallet_address");
|
|
2717
|
+
useAutoSave(watchedCurrency, (v) => setSaved((prev) => ({ ...prev, currency: v })));
|
|
2718
|
+
useAutoSave(watchedWallet, (v) => setSaved((prev) => ({ ...prev, wallet: v })), (v) => v.length >= 26);
|
|
2719
|
+
const currencyOptions = useCurrencyOptions(currencies);
|
|
2720
|
+
useDefaultCurrency({
|
|
2721
|
+
currencyOptions,
|
|
2722
|
+
savedCurrency: saved.currency,
|
|
2723
|
+
currentValue: watchedCurrency,
|
|
2724
|
+
setValue: (v) => form.setValue("currency", v)
|
|
2725
|
+
});
|
|
2726
|
+
const selectedCurrency = currencyOptions.find((c) => c.value === watchedCurrency);
|
|
2727
|
+
const amount = watchedAmount || 0;
|
|
2728
|
+
const { estimate, isLoading: isLoadingEstimate } = useWithdrawalEstimate({
|
|
2729
|
+
currencyCode: watchedCurrency,
|
|
2730
|
+
amountUsd: amount,
|
|
2731
|
+
minAmount: 10,
|
|
2732
|
+
skip: amount < 10
|
|
2733
|
+
});
|
|
2734
|
+
const cryptoDisplay = useMemo(() => {
|
|
2735
|
+
if (!selectedCurrency || !estimate) return null;
|
|
2133
2736
|
return {
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
totalFee,
|
|
2137
|
-
finalAmount,
|
|
2138
|
-
cryptoAmount
|
|
2737
|
+
token: selectedCurrency.token,
|
|
2738
|
+
cryptoAmount: formatCryptoAmount(estimate.estimatedAmount, estimate.isStablecoin)
|
|
2139
2739
|
};
|
|
2140
|
-
}, [
|
|
2740
|
+
}, [selectedCurrency, estimate]);
|
|
2141
2741
|
const insufficientBalance = amount > balanceAmount;
|
|
2142
2742
|
const handleSubmit = useCallback(async (data) => {
|
|
2143
2743
|
try {
|
|
@@ -2152,19 +2752,23 @@ function WithdrawSheet({ open, onOpenChange, onSuccess }) {
|
|
|
2152
2752
|
onOpenChange(false);
|
|
2153
2753
|
onSuccess?.(result);
|
|
2154
2754
|
} catch (err) {
|
|
2155
|
-
|
|
2156
|
-
setError(message);
|
|
2755
|
+
setError(extractErrorMessage(err, "Failed to create withdrawal request"));
|
|
2157
2756
|
} finally {
|
|
2158
2757
|
setIsSubmitting(false);
|
|
2159
2758
|
}
|
|
2160
2759
|
}, [withdraw, form, onOpenChange, onSuccess]);
|
|
2161
2760
|
const handleOpenChange = useCallback((open2) => {
|
|
2162
|
-
if (
|
|
2761
|
+
if (open2) {
|
|
2762
|
+
form.reset({
|
|
2763
|
+
amount: 10,
|
|
2764
|
+
currency: saved.currency,
|
|
2765
|
+
wallet_address: saved.wallet
|
|
2766
|
+
});
|
|
2767
|
+
} else {
|
|
2163
2768
|
setError(null);
|
|
2164
|
-
form.reset();
|
|
2165
2769
|
}
|
|
2166
2770
|
onOpenChange(open2);
|
|
2167
|
-
}, [form, onOpenChange]);
|
|
2771
|
+
}, [form, onOpenChange, saved]);
|
|
2168
2772
|
return /* @__PURE__ */ jsx(ResponsiveSheet, { open, onOpenChange: handleOpenChange, children: /* @__PURE__ */ jsxs(ResponsiveSheetContent, { className: "sm:max-w-md", children: [
|
|
2169
2773
|
/* @__PURE__ */ jsxs(ResponsiveSheetHeader, { children: [
|
|
2170
2774
|
/* @__PURE__ */ jsx(ResponsiveSheetTitle, { children: "Withdraw" }),
|
|
@@ -2186,7 +2790,7 @@ function WithdrawSheet({ open, onOpenChange, onSuccess }) {
|
|
|
2186
2790
|
type: "number",
|
|
2187
2791
|
step: "0.01",
|
|
2188
2792
|
min: "10",
|
|
2189
|
-
placeholder: "10
|
|
2793
|
+
placeholder: "10",
|
|
2190
2794
|
className: "pl-8 text-2xl h-14 font-semibold",
|
|
2191
2795
|
...field,
|
|
2192
2796
|
onChange: (e) => field.onChange(parseFloat(e.target.value) || 0)
|
|
@@ -2196,7 +2800,7 @@ function WithdrawSheet({ open, onOpenChange, onSuccess }) {
|
|
|
2196
2800
|
/* @__PURE__ */ jsx(FormMessage, {}),
|
|
2197
2801
|
insufficientBalance && /* @__PURE__ */ jsxs("p", { className: "text-sm text-destructive mt-1", children: [
|
|
2198
2802
|
"Insufficient balance (Available: $",
|
|
2199
|
-
balanceAmount
|
|
2803
|
+
formatUsdAmount(balanceAmount),
|
|
2200
2804
|
")"
|
|
2201
2805
|
] })
|
|
2202
2806
|
] })
|
|
@@ -2210,23 +2814,12 @@ function WithdrawSheet({ open, onOpenChange, onSuccess }) {
|
|
|
2210
2814
|
render: ({ field }) => /* @__PURE__ */ jsxs(FormItem, { children: [
|
|
2211
2815
|
/* @__PURE__ */ jsx(FormLabel, { children: "Withdraw as" }),
|
|
2212
2816
|
/* @__PURE__ */ jsx(FormControl, { children: /* @__PURE__ */ jsx(
|
|
2213
|
-
|
|
2817
|
+
CurrencyCombobox,
|
|
2214
2818
|
{
|
|
2215
2819
|
options: currencyOptions,
|
|
2216
2820
|
value: field.value,
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
searchPlaceholder: "Search...",
|
|
2220
|
-
disabled: isLoadingCurrencies,
|
|
2221
|
-
className: "h-14",
|
|
2222
|
-
renderOption: (option) => /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 flex-1", children: [
|
|
2223
|
-
/* @__PURE__ */ jsx(TokenIcon, { symbol: option.value, size: 24 }),
|
|
2224
|
-
/* @__PURE__ */ jsx("span", { className: "font-medium", children: option.label })
|
|
2225
|
-
] }),
|
|
2226
|
-
renderValue: (option) => option && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
2227
|
-
/* @__PURE__ */ jsx(TokenIcon, { symbol: option.value, size: 24 }),
|
|
2228
|
-
/* @__PURE__ */ jsx("span", { className: "font-medium", children: option.label })
|
|
2229
|
-
] })
|
|
2821
|
+
onChange: field.onChange,
|
|
2822
|
+
disabled: isLoadingCurrencies
|
|
2230
2823
|
}
|
|
2231
2824
|
) }),
|
|
2232
2825
|
/* @__PURE__ */ jsx(FormMessage, {})
|
|
@@ -2257,36 +2850,49 @@ function WithdrawSheet({ open, onOpenChange, onSuccess }) {
|
|
|
2257
2850
|
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "Amount" }),
|
|
2258
2851
|
/* @__PURE__ */ jsxs("span", { children: [
|
|
2259
2852
|
"$",
|
|
2260
|
-
amount
|
|
2853
|
+
formatUsdAmount(amount)
|
|
2261
2854
|
] })
|
|
2262
2855
|
] }),
|
|
2263
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center
|
|
2264
|
-
/* @__PURE__ */ jsx(
|
|
2265
|
-
/* @__PURE__ */
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
/* @__PURE__ */ jsxs("span", { className: "text-destructive", children: [
|
|
2273
|
-
"-$",
|
|
2274
|
-
feeBreakdown.networkFee.toFixed(2)
|
|
2275
|
-
] })
|
|
2276
|
-
] }),
|
|
2277
|
-
/* @__PURE__ */ jsx("div", { className: "border-t pt-2 mt-2", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
2278
|
-
/* @__PURE__ */ jsx("span", { className: "font-medium", children: "You will receive" }),
|
|
2279
|
-
/* @__PURE__ */ jsxs("div", { className: "text-right", children: [
|
|
2280
|
-
/* @__PURE__ */ jsxs("div", { className: "font-semibold", children: [
|
|
2281
|
-
"$",
|
|
2282
|
-
feeBreakdown.finalAmount.toFixed(2)
|
|
2856
|
+
isLoadingEstimate ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-sm text-muted-foreground py-2", children: [
|
|
2857
|
+
/* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin" }),
|
|
2858
|
+
/* @__PURE__ */ jsx("span", { children: "Calculating fees..." })
|
|
2859
|
+
] }) : estimate ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2860
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between text-sm", children: [
|
|
2861
|
+
/* @__PURE__ */ jsxs("span", { className: "text-muted-foreground", children: [
|
|
2862
|
+
"Service fee (",
|
|
2863
|
+
estimate.serviceFeePercent,
|
|
2864
|
+
"%)"
|
|
2283
2865
|
] }),
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2866
|
+
/* @__PURE__ */ jsxs("span", { className: "text-destructive", children: [
|
|
2867
|
+
"-$",
|
|
2868
|
+
formatUsdAmount(estimate.serviceFeeUsd)
|
|
2287
2869
|
] })
|
|
2288
|
-
] })
|
|
2289
|
-
|
|
2870
|
+
] }),
|
|
2871
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between text-sm", children: [
|
|
2872
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "Network fee" }),
|
|
2873
|
+
/* @__PURE__ */ jsxs("span", { className: "text-destructive", children: [
|
|
2874
|
+
"-$",
|
|
2875
|
+
formatUsdAmount(estimate.networkFeeUsd)
|
|
2876
|
+
] })
|
|
2877
|
+
] }),
|
|
2878
|
+
/* @__PURE__ */ jsx("div", { className: "border-t pt-2 mt-2", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
2879
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium", children: "You will receive" }),
|
|
2880
|
+
/* @__PURE__ */ jsxs("div", { className: "text-right", children: [
|
|
2881
|
+
/* @__PURE__ */ jsxs("div", { className: "font-semibold", children: [
|
|
2882
|
+
"$",
|
|
2883
|
+
formatUsdAmount(estimate.amountToReceive)
|
|
2884
|
+
] }),
|
|
2885
|
+
cryptoDisplay && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 text-sm text-muted-foreground", children: [
|
|
2886
|
+
/* @__PURE__ */ jsx(TokenIcon, { symbol: cryptoDisplay.token, size: 16 }),
|
|
2887
|
+
/* @__PURE__ */ jsxs("span", { className: "font-mono", children: [
|
|
2888
|
+
cryptoDisplay.cryptoAmount,
|
|
2889
|
+
" ",
|
|
2890
|
+
cryptoDisplay.token
|
|
2891
|
+
] })
|
|
2892
|
+
] })
|
|
2893
|
+
] })
|
|
2894
|
+
] }) })
|
|
2895
|
+
] }) : null
|
|
2290
2896
|
] }),
|
|
2291
2897
|
/* @__PURE__ */ jsxs(Alert, { children: [
|
|
2292
2898
|
/* @__PURE__ */ jsx(AlertCircle, { className: "h-4 w-4" }),
|
|
@@ -2299,7 +2905,7 @@ function WithdrawSheet({ open, onOpenChange, onSuccess }) {
|
|
|
2299
2905
|
type: "submit",
|
|
2300
2906
|
size: "lg",
|
|
2301
2907
|
className: "w-full h-14 text-lg rounded-xl",
|
|
2302
|
-
disabled: isSubmitting || currencyOptions.length === 0 || insufficientBalance ||
|
|
2908
|
+
disabled: isSubmitting || currencyOptions.length === 0 || insufficientBalance || !estimate || estimate.amountToReceive <= 0 || isLoadingEstimate,
|
|
2303
2909
|
children: isSubmitting ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2304
2910
|
/* @__PURE__ */ jsx(RefreshCw, { className: "h-5 w-5 mr-2 animate-spin" }),
|
|
2305
2911
|
"Submitting..."
|
|
@@ -2310,6 +2916,229 @@ function WithdrawSheet({ open, onOpenChange, onSuccess }) {
|
|
|
2310
2916
|
] }) });
|
|
2311
2917
|
}
|
|
2312
2918
|
var statusConfig2 = {
|
|
2919
|
+
pending: {
|
|
2920
|
+
icon: Clock,
|
|
2921
|
+
color: "text-yellow-500",
|
|
2922
|
+
bg: "bg-yellow-500/10",
|
|
2923
|
+
label: "Pending Approval"
|
|
2924
|
+
},
|
|
2925
|
+
approved: {
|
|
2926
|
+
icon: CheckCircle2,
|
|
2927
|
+
color: "text-blue-500",
|
|
2928
|
+
bg: "bg-blue-500/10",
|
|
2929
|
+
label: "Approved"
|
|
2930
|
+
},
|
|
2931
|
+
processing: {
|
|
2932
|
+
icon: RefreshCw,
|
|
2933
|
+
color: "text-blue-500",
|
|
2934
|
+
bg: "bg-blue-500/10",
|
|
2935
|
+
label: "Processing",
|
|
2936
|
+
animate: true
|
|
2937
|
+
},
|
|
2938
|
+
completed: {
|
|
2939
|
+
icon: CheckCircle2,
|
|
2940
|
+
color: "text-green-500",
|
|
2941
|
+
bg: "bg-green-500/10",
|
|
2942
|
+
label: "Completed"
|
|
2943
|
+
},
|
|
2944
|
+
rejected: {
|
|
2945
|
+
icon: XCircle,
|
|
2946
|
+
color: "text-red-500",
|
|
2947
|
+
bg: "bg-red-500/10",
|
|
2948
|
+
label: "Rejected"
|
|
2949
|
+
},
|
|
2950
|
+
cancelled: {
|
|
2951
|
+
icon: Ban,
|
|
2952
|
+
color: "text-muted-foreground",
|
|
2953
|
+
bg: "bg-muted",
|
|
2954
|
+
label: "Cancelled"
|
|
2955
|
+
}
|
|
2956
|
+
};
|
|
2957
|
+
function WithdrawalSheet({ withdrawalId, open, onOpenChange }) {
|
|
2958
|
+
const { getWithdrawalDetails, cancelWithdrawal, refreshWallet } = useWallet();
|
|
2959
|
+
const { data: withdrawal, isLoading, error, mutate } = useSWR(
|
|
2960
|
+
open && withdrawalId ? ["withdrawal-details", withdrawalId] : null,
|
|
2961
|
+
() => getWithdrawalDetails(withdrawalId),
|
|
2962
|
+
{ refreshInterval: 3e4 }
|
|
2963
|
+
);
|
|
2964
|
+
const displayData = useMemo(() => {
|
|
2965
|
+
const s = withdrawal?.status?.toLowerCase() || "pending";
|
|
2966
|
+
const config2 = statusConfig2[s] || statusConfig2.pending;
|
|
2967
|
+
const isPending = s === "pending";
|
|
2968
|
+
const isCompleted = s === "completed";
|
|
2969
|
+
const isRejected = s === "rejected";
|
|
2970
|
+
const isCancelled = s === "cancelled";
|
|
2971
|
+
const isProcessing = s === "processing" || s === "approved";
|
|
2972
|
+
const canCancel2 = isPending;
|
|
2973
|
+
let description2 = "";
|
|
2974
|
+
if (isPending) description2 = "Waiting for admin approval";
|
|
2975
|
+
else if (isProcessing) description2 = "Your withdrawal is being processed";
|
|
2976
|
+
else if (isCompleted) description2 = "Withdrawal completed successfully";
|
|
2977
|
+
else if (isRejected) description2 = "Withdrawal was rejected";
|
|
2978
|
+
else if (isCancelled) description2 = "Withdrawal was cancelled";
|
|
2979
|
+
const amountUsd2 = withdrawal?.amount_usd ? `$${parseFloat(withdrawal.amount_usd).toFixed(2)}` : "";
|
|
2980
|
+
const finalAmountUsd2 = withdrawal?.final_amount_usd ? `$${parseFloat(withdrawal.final_amount_usd).toFixed(2)}` : "";
|
|
2981
|
+
const totalFeeUsd2 = withdrawal?.total_fee_usd ? `$${parseFloat(withdrawal.total_fee_usd).toFixed(2)}` : "";
|
|
2982
|
+
const createdAt2 = withdrawal?.created_at ? moment3.utc(withdrawal.created_at).local().format("MMM D, YYYY HH:mm") : "";
|
|
2983
|
+
const completedAt2 = withdrawal?.completed_at ? moment3.utc(withdrawal.completed_at).local().format("MMM D, YYYY HH:mm") : null;
|
|
2984
|
+
return {
|
|
2985
|
+
status: s,
|
|
2986
|
+
config: config2,
|
|
2987
|
+
isPending,
|
|
2988
|
+
isCompleted,
|
|
2989
|
+
isRejected,
|
|
2990
|
+
isCancelled,
|
|
2991
|
+
isProcessing,
|
|
2992
|
+
canCancel: canCancel2,
|
|
2993
|
+
description: description2,
|
|
2994
|
+
amountUsd: amountUsd2,
|
|
2995
|
+
finalAmountUsd: finalAmountUsd2,
|
|
2996
|
+
totalFeeUsd: totalFeeUsd2,
|
|
2997
|
+
createdAt: createdAt2,
|
|
2998
|
+
completedAt: completedAt2
|
|
2999
|
+
};
|
|
3000
|
+
}, [withdrawal]);
|
|
3001
|
+
const { config, canCancel, description, amountUsd, finalAmountUsd, totalFeeUsd, createdAt, completedAt } = displayData;
|
|
3002
|
+
const StatusIcon = config.icon;
|
|
3003
|
+
const handleCancel = async () => {
|
|
3004
|
+
if (!withdrawalId) return;
|
|
3005
|
+
try {
|
|
3006
|
+
await cancelWithdrawal(withdrawalId);
|
|
3007
|
+
await mutate();
|
|
3008
|
+
await refreshWallet();
|
|
3009
|
+
} catch (err) {
|
|
3010
|
+
console.error("Failed to cancel withdrawal:", err);
|
|
3011
|
+
}
|
|
3012
|
+
};
|
|
3013
|
+
return /* @__PURE__ */ jsx(ResponsiveSheet, { open, onOpenChange, children: /* @__PURE__ */ jsxs(ResponsiveSheetContent, { className: "sm:max-w-lg", children: [
|
|
3014
|
+
/* @__PURE__ */ jsxs(ResponsiveSheetHeader, { children: [
|
|
3015
|
+
/* @__PURE__ */ jsx(ResponsiveSheetTitle, { children: "Withdrawal Details" }),
|
|
3016
|
+
/* @__PURE__ */ jsx(ResponsiveSheetDescription, { children: description })
|
|
3017
|
+
] }),
|
|
3018
|
+
/* @__PURE__ */ jsxs("div", { className: "p-4 sm:p-0 sm:mt-4 overflow-y-auto max-h-[70vh]", children: [
|
|
3019
|
+
isLoading && /* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
|
|
3020
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-16 w-full rounded-xl" }),
|
|
3021
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-24 w-full rounded-xl" }),
|
|
3022
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-20 w-full rounded-xl" })
|
|
3023
|
+
] }),
|
|
3024
|
+
error && /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center justify-center py-12", children: [
|
|
3025
|
+
/* @__PURE__ */ jsx(XCircle, { className: "h-12 w-12 text-destructive mb-4" }),
|
|
3026
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground mb-4", children: "Failed to load withdrawal" }),
|
|
3027
|
+
/* @__PURE__ */ jsx(Button, { onClick: () => mutate(), children: "Try Again" })
|
|
3028
|
+
] }),
|
|
3029
|
+
withdrawal && !isLoading && /* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
|
|
3030
|
+
/* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-3 p-4 rounded-xl", config.bg), children: [
|
|
3031
|
+
/* @__PURE__ */ jsx(StatusIcon, { className: cn("h-6 w-6", config.color, config.animate && "animate-spin") }),
|
|
3032
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1", children: [
|
|
3033
|
+
/* @__PURE__ */ jsx("div", { className: "font-semibold", children: config.label }),
|
|
3034
|
+
withdrawal.admin_notes && /* @__PURE__ */ jsx("div", { className: "text-sm text-muted-foreground", children: withdrawal.admin_notes })
|
|
3035
|
+
] })
|
|
3036
|
+
] }),
|
|
3037
|
+
/* @__PURE__ */ jsxs("div", { className: "bg-muted rounded-xl p-4 space-y-3", children: [
|
|
3038
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
3039
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "Amount" }),
|
|
3040
|
+
/* @__PURE__ */ jsx("span", { className: "font-semibold", children: amountUsd })
|
|
3041
|
+
] }),
|
|
3042
|
+
totalFeeUsd && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between text-sm", children: [
|
|
3043
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "Total fees" }),
|
|
3044
|
+
/* @__PURE__ */ jsxs("span", { className: "text-destructive", children: [
|
|
3045
|
+
"-",
|
|
3046
|
+
totalFeeUsd
|
|
3047
|
+
] })
|
|
3048
|
+
] }),
|
|
3049
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between pt-2 border-t", children: [
|
|
3050
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "You receive" }),
|
|
3051
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
3052
|
+
/* @__PURE__ */ jsx(TokenIcon, { symbol: withdrawal.currency_code, size: 24 }),
|
|
3053
|
+
/* @__PURE__ */ jsx("span", { className: "font-mono font-bold text-lg", children: finalAmountUsd })
|
|
3054
|
+
] })
|
|
3055
|
+
] }),
|
|
3056
|
+
withdrawal.crypto_amount && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between text-sm", children: [
|
|
3057
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "Crypto amount" }),
|
|
3058
|
+
/* @__PURE__ */ jsxs("span", { className: "font-mono", children: [
|
|
3059
|
+
withdrawal.crypto_amount,
|
|
3060
|
+
" ",
|
|
3061
|
+
withdrawal.currency_token
|
|
3062
|
+
] })
|
|
3063
|
+
] })
|
|
3064
|
+
] }),
|
|
3065
|
+
withdrawal.wallet_address && /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
3066
|
+
/* @__PURE__ */ jsx("label", { className: "text-sm font-medium", children: "Destination Wallet" }),
|
|
3067
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
3068
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 p-3 bg-muted rounded-xl font-mono text-sm break-all", children: withdrawal.wallet_address }),
|
|
3069
|
+
/* @__PURE__ */ jsx(CopyButton, { value: withdrawal.wallet_address, variant: "outline", className: "shrink-0" })
|
|
3070
|
+
] })
|
|
3071
|
+
] }),
|
|
3072
|
+
withdrawal.transaction_hash && /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
3073
|
+
/* @__PURE__ */ jsx("label", { className: "text-sm font-medium", children: "Transaction Hash" }),
|
|
3074
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
3075
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 p-3 bg-muted rounded-xl font-mono text-sm break-all", children: withdrawal.transaction_hash }),
|
|
3076
|
+
/* @__PURE__ */ jsx(CopyButton, { value: withdrawal.transaction_hash, variant: "outline", className: "shrink-0" })
|
|
3077
|
+
] })
|
|
3078
|
+
] }),
|
|
3079
|
+
withdrawal.explorer_link && /* @__PURE__ */ jsxs(
|
|
3080
|
+
Button,
|
|
3081
|
+
{
|
|
3082
|
+
variant: "outline",
|
|
3083
|
+
className: "w-full",
|
|
3084
|
+
onClick: () => window.open(withdrawal.explorer_link, "_blank"),
|
|
3085
|
+
children: [
|
|
3086
|
+
/* @__PURE__ */ jsx(ExternalLink, { className: "h-4 w-4 mr-2" }),
|
|
3087
|
+
"View on Explorer"
|
|
3088
|
+
]
|
|
3089
|
+
}
|
|
3090
|
+
),
|
|
3091
|
+
canCancel && /* @__PURE__ */ jsxs(
|
|
3092
|
+
Button,
|
|
3093
|
+
{
|
|
3094
|
+
variant: "destructive",
|
|
3095
|
+
className: "w-full",
|
|
3096
|
+
onClick: handleCancel,
|
|
3097
|
+
children: [
|
|
3098
|
+
/* @__PURE__ */ jsx(Ban, { className: "h-4 w-4 mr-2" }),
|
|
3099
|
+
"Cancel Withdrawal"
|
|
3100
|
+
]
|
|
3101
|
+
}
|
|
3102
|
+
),
|
|
3103
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-2 text-xs text-muted-foreground pt-4 border-t", children: [
|
|
3104
|
+
/* @__PURE__ */ jsxs("div", { className: "flex justify-between", children: [
|
|
3105
|
+
/* @__PURE__ */ jsx("span", { children: "Withdrawal ID" }),
|
|
3106
|
+
/* @__PURE__ */ jsx("span", { className: "font-mono", children: withdrawal.id })
|
|
3107
|
+
] }),
|
|
3108
|
+
withdrawal.internal_withdrawal_id && /* @__PURE__ */ jsxs("div", { className: "flex justify-between", children: [
|
|
3109
|
+
/* @__PURE__ */ jsx("span", { children: "Reference #" }),
|
|
3110
|
+
/* @__PURE__ */ jsx("span", { className: "font-mono", children: withdrawal.internal_withdrawal_id })
|
|
3111
|
+
] }),
|
|
3112
|
+
/* @__PURE__ */ jsxs("div", { className: "flex justify-between", children: [
|
|
3113
|
+
/* @__PURE__ */ jsx("span", { children: "Created" }),
|
|
3114
|
+
/* @__PURE__ */ jsx("span", { children: createdAt })
|
|
3115
|
+
] }),
|
|
3116
|
+
completedAt && /* @__PURE__ */ jsxs("div", { className: "flex justify-between", children: [
|
|
3117
|
+
/* @__PURE__ */ jsx("span", { children: "Completed" }),
|
|
3118
|
+
/* @__PURE__ */ jsx("span", { children: completedAt })
|
|
3119
|
+
] }),
|
|
3120
|
+
withdrawal.currency_network && /* @__PURE__ */ jsxs("div", { className: "flex justify-between", children: [
|
|
3121
|
+
/* @__PURE__ */ jsx("span", { children: "Network" }),
|
|
3122
|
+
/* @__PURE__ */ jsx("span", { children: withdrawal.currency_network })
|
|
3123
|
+
] })
|
|
3124
|
+
] }),
|
|
3125
|
+
/* @__PURE__ */ jsxs(
|
|
3126
|
+
Button,
|
|
3127
|
+
{
|
|
3128
|
+
variant: "ghost",
|
|
3129
|
+
className: "w-full",
|
|
3130
|
+
onClick: () => mutate(),
|
|
3131
|
+
children: [
|
|
3132
|
+
/* @__PURE__ */ jsx(RefreshCw, { className: "h-4 w-4 mr-2" }),
|
|
3133
|
+
"Refresh Status"
|
|
3134
|
+
]
|
|
3135
|
+
}
|
|
3136
|
+
)
|
|
3137
|
+
] })
|
|
3138
|
+
] })
|
|
3139
|
+
] }) });
|
|
3140
|
+
}
|
|
3141
|
+
var statusConfig3 = {
|
|
2313
3142
|
pending: {
|
|
2314
3143
|
icon: Clock,
|
|
2315
3144
|
color: "text-yellow-500",
|
|
@@ -2342,10 +3171,10 @@ var statusConfig2 = {
|
|
|
2342
3171
|
label: "Expired"
|
|
2343
3172
|
}
|
|
2344
3173
|
};
|
|
2345
|
-
function PaymentSheet({ paymentId, open, onOpenChange }) {
|
|
3174
|
+
function PaymentSheet({ paymentId, open, onOpenChange, onCreateNew }) {
|
|
2346
3175
|
const { getPaymentDetails } = useWallet();
|
|
2347
3176
|
const [timeLeft, setTimeLeft] = useState("");
|
|
2348
|
-
const { data: payment, isLoading, error, mutate } =
|
|
3177
|
+
const { data: payment, isLoading, error, mutate } = useSWR(
|
|
2349
3178
|
open && paymentId ? ["payment-details", paymentId] : null,
|
|
2350
3179
|
() => getPaymentDetails(paymentId),
|
|
2351
3180
|
{ refreshInterval: 1e4 }
|
|
@@ -2353,14 +3182,14 @@ function PaymentSheet({ paymentId, open, onOpenChange }) {
|
|
|
2353
3182
|
useEffect(() => {
|
|
2354
3183
|
if (!payment?.expires_at) return;
|
|
2355
3184
|
const updateTimeLeft = () => {
|
|
2356
|
-
const now =
|
|
2357
|
-
const expires =
|
|
3185
|
+
const now = moment3();
|
|
3186
|
+
const expires = moment3.utc(payment.expires_at);
|
|
2358
3187
|
const diff = expires.diff(now);
|
|
2359
3188
|
if (diff <= 0) {
|
|
2360
3189
|
setTimeLeft("Expired");
|
|
2361
3190
|
return;
|
|
2362
3191
|
}
|
|
2363
|
-
const duration =
|
|
3192
|
+
const duration = moment3.duration(diff);
|
|
2364
3193
|
const hours = Math.floor(duration.asHours());
|
|
2365
3194
|
const minutes = duration.minutes();
|
|
2366
3195
|
const seconds = duration.seconds();
|
|
@@ -2370,22 +3199,59 @@ function PaymentSheet({ paymentId, open, onOpenChange }) {
|
|
|
2370
3199
|
const interval = setInterval(updateTimeLeft, 1e3);
|
|
2371
3200
|
return () => clearInterval(interval);
|
|
2372
3201
|
}, [payment?.expires_at]);
|
|
2373
|
-
const
|
|
3202
|
+
const displayData = useMemo(() => {
|
|
2374
3203
|
const s = payment?.status?.toLowerCase();
|
|
2375
|
-
|
|
2376
|
-
if (s === "
|
|
2377
|
-
if (s === "
|
|
2378
|
-
if (s === "
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
3204
|
+
let status;
|
|
3205
|
+
if (s === "completed" || s === "success" || s === "finished") status = "completed";
|
|
3206
|
+
else if (s === "confirming" || s === "partially_paid") status = "confirming";
|
|
3207
|
+
else if (s === "expired") status = "expired";
|
|
3208
|
+
else if (s === "failed" || s === "error" || s === "cancelled") status = "failed";
|
|
3209
|
+
else status = "pending";
|
|
3210
|
+
const config2 = statusConfig3[status];
|
|
3211
|
+
const isPending = status === "pending";
|
|
3212
|
+
const isExpired2 = status === "expired" || timeLeft === "Expired";
|
|
3213
|
+
const isCompleted = status === "completed";
|
|
3214
|
+
const isFailed = status === "failed";
|
|
3215
|
+
const isConfirming = status === "confirming";
|
|
3216
|
+
const canPay2 = isPending && !isExpired2;
|
|
3217
|
+
let description2 = "";
|
|
3218
|
+
if (canPay2) description2 = "Send cryptocurrency to complete payment";
|
|
3219
|
+
else if (isExpired2) description2 = "This payment has expired";
|
|
3220
|
+
else if (isCompleted) description2 = "Payment completed successfully";
|
|
3221
|
+
else if (isFailed) description2 = "Payment failed";
|
|
3222
|
+
else if (isConfirming) description2 = "Confirming your payment";
|
|
3223
|
+
const statusBadge2 = {
|
|
3224
|
+
bg: isExpired2 ? "bg-muted" : config2.bg,
|
|
3225
|
+
iconColor: isExpired2 ? "text-muted-foreground" : config2.color,
|
|
3226
|
+
iconAnimate: config2.animate,
|
|
3227
|
+
label: isExpired2 ? "Payment Expired" : config2.label,
|
|
3228
|
+
subtitle: canPay2 && timeLeft ? `Expires in ${timeLeft}` : isExpired2 ? "Please create a new payment to continue" : null
|
|
3229
|
+
};
|
|
3230
|
+
const qrCodeUrl2 = payment?.pay_address && canPay2 ? `https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=${encodeURIComponent(payment.pay_address)}` : null;
|
|
3231
|
+
const amountUsd2 = payment?.amount_usd ? `$${parseFloat(payment.amount_usd).toFixed(2)} USD` : "";
|
|
3232
|
+
const createdAt2 = payment?.created_at ? moment3.utc(payment.created_at).local().format("MMM D, YYYY HH:mm") : "";
|
|
3233
|
+
return {
|
|
3234
|
+
status,
|
|
3235
|
+
config: config2,
|
|
3236
|
+
isPending,
|
|
3237
|
+
isExpired: isExpired2,
|
|
3238
|
+
isCompleted,
|
|
3239
|
+
isFailed,
|
|
3240
|
+
isConfirming,
|
|
3241
|
+
canPay: canPay2,
|
|
3242
|
+
description: description2,
|
|
3243
|
+
statusBadge: statusBadge2,
|
|
3244
|
+
qrCodeUrl: qrCodeUrl2,
|
|
3245
|
+
amountUsd: amountUsd2,
|
|
3246
|
+
createdAt: createdAt2
|
|
3247
|
+
};
|
|
3248
|
+
}, [payment, timeLeft]);
|
|
3249
|
+
const { config, canPay, isExpired, description, statusBadge, qrCodeUrl, amountUsd, createdAt } = displayData;
|
|
2382
3250
|
const StatusIcon = config.icon;
|
|
2383
|
-
const qrCodeUrl = payment?.pay_address ? `https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=${encodeURIComponent(payment.pay_address)}` : null;
|
|
2384
|
-
const isPending = status === "pending";
|
|
2385
3251
|
return /* @__PURE__ */ jsx(ResponsiveSheet, { open, onOpenChange, children: /* @__PURE__ */ jsxs(ResponsiveSheetContent, { className: "sm:max-w-lg", children: [
|
|
2386
3252
|
/* @__PURE__ */ jsxs(ResponsiveSheetHeader, { children: [
|
|
2387
3253
|
/* @__PURE__ */ jsx(ResponsiveSheetTitle, { children: "Payment Details" }),
|
|
2388
|
-
/* @__PURE__ */ jsx(ResponsiveSheetDescription, { children:
|
|
3254
|
+
/* @__PURE__ */ jsx(ResponsiveSheetDescription, { children: description })
|
|
2389
3255
|
] }),
|
|
2390
3256
|
/* @__PURE__ */ jsxs("div", { className: "p-4 sm:p-0 sm:mt-4 overflow-y-auto max-h-[70vh]", children: [
|
|
2391
3257
|
isLoading && /* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
|
|
@@ -2399,14 +3265,11 @@ function PaymentSheet({ paymentId, open, onOpenChange }) {
|
|
|
2399
3265
|
/* @__PURE__ */ jsx(Button, { onClick: () => mutate(), children: "Try Again" })
|
|
2400
3266
|
] }),
|
|
2401
3267
|
payment && !isLoading && /* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
|
|
2402
|
-
/* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-3 p-4 rounded-xl",
|
|
2403
|
-
/* @__PURE__ */ jsx(StatusIcon, { className: cn("h-6 w-6",
|
|
3268
|
+
/* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-3 p-4 rounded-xl", statusBadge.bg), children: [
|
|
3269
|
+
/* @__PURE__ */ jsx(StatusIcon, { className: cn("h-6 w-6", statusBadge.iconColor, statusBadge.iconAnimate && "animate-spin") }),
|
|
2404
3270
|
/* @__PURE__ */ jsxs("div", { className: "flex-1", children: [
|
|
2405
|
-
/* @__PURE__ */ jsx("div", { className: "font-semibold", children:
|
|
2406
|
-
|
|
2407
|
-
"Expires in ",
|
|
2408
|
-
timeLeft
|
|
2409
|
-
] })
|
|
3271
|
+
/* @__PURE__ */ jsx("div", { className: "font-semibold", children: statusBadge.label }),
|
|
3272
|
+
statusBadge.subtitle && /* @__PURE__ */ jsx("div", { className: "text-sm text-muted-foreground", children: statusBadge.subtitle })
|
|
2410
3273
|
] })
|
|
2411
3274
|
] }),
|
|
2412
3275
|
/* @__PURE__ */ jsxs("div", { className: "bg-muted rounded-xl p-4 space-y-3", children: [
|
|
@@ -2423,30 +3286,38 @@ function PaymentSheet({ paymentId, open, onOpenChange }) {
|
|
|
2423
3286
|
] }),
|
|
2424
3287
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between text-sm", children: [
|
|
2425
3288
|
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "Equivalent" }),
|
|
2426
|
-
/* @__PURE__ */
|
|
2427
|
-
"$",
|
|
2428
|
-
parseFloat(payment.amount_usd).toFixed(2),
|
|
2429
|
-
" USD"
|
|
2430
|
-
] })
|
|
3289
|
+
/* @__PURE__ */ jsx("span", { className: "font-semibold", children: amountUsd })
|
|
2431
3290
|
] }),
|
|
2432
3291
|
payment.currency_network && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between text-sm pt-2 border-t", children: [
|
|
2433
3292
|
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "Network" }),
|
|
2434
3293
|
/* @__PURE__ */ jsx("span", { className: "font-medium", children: payment.currency_network })
|
|
2435
3294
|
] })
|
|
2436
3295
|
] }),
|
|
2437
|
-
qrCodeUrl &&
|
|
2438
|
-
payment.pay_address &&
|
|
3296
|
+
qrCodeUrl && /* @__PURE__ */ jsx("div", { className: "flex justify-center p-6 bg-white rounded-xl", children: /* @__PURE__ */ jsx("img", { src: qrCodeUrl, alt: "Payment QR Code", className: "w-48 h-48" }) }),
|
|
3297
|
+
payment.pay_address && canPay && /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
2439
3298
|
/* @__PURE__ */ jsx("label", { className: "text-sm font-medium", children: "Payment Address" }),
|
|
2440
3299
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
2441
3300
|
/* @__PURE__ */ jsx("div", { className: "flex-1 p-3 bg-muted rounded-xl font-mono text-sm break-all", children: payment.pay_address }),
|
|
2442
3301
|
/* @__PURE__ */ jsx(CopyButton, { value: payment.pay_address, variant: "outline", className: "shrink-0" })
|
|
2443
3302
|
] })
|
|
2444
3303
|
] }),
|
|
3304
|
+
isExpired && onCreateNew && /* @__PURE__ */ jsx(
|
|
3305
|
+
Button,
|
|
3306
|
+
{
|
|
3307
|
+
size: "lg",
|
|
3308
|
+
className: "w-full",
|
|
3309
|
+
onClick: () => {
|
|
3310
|
+
onOpenChange(false);
|
|
3311
|
+
onCreateNew();
|
|
3312
|
+
},
|
|
3313
|
+
children: "Create New Payment"
|
|
3314
|
+
}
|
|
3315
|
+
),
|
|
2445
3316
|
payment.transaction_hash && /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
2446
3317
|
/* @__PURE__ */ jsx("label", { className: "text-sm font-medium", children: "Transaction Hash" }),
|
|
2447
3318
|
/* @__PURE__ */ jsx("div", { className: "p-3 bg-muted rounded-xl font-mono text-sm break-all", children: payment.transaction_hash })
|
|
2448
3319
|
] }),
|
|
2449
|
-
payment.payment_url &&
|
|
3320
|
+
payment.payment_url && canPay && /* @__PURE__ */ jsxs(
|
|
2450
3321
|
Button,
|
|
2451
3322
|
{
|
|
2452
3323
|
variant: "outline",
|
|
@@ -2469,7 +3340,7 @@ function PaymentSheet({ paymentId, open, onOpenChange }) {
|
|
|
2469
3340
|
] }),
|
|
2470
3341
|
/* @__PURE__ */ jsxs("div", { className: "flex justify-between", children: [
|
|
2471
3342
|
/* @__PURE__ */ jsx("span", { children: "Created" }),
|
|
2472
|
-
/* @__PURE__ */ jsx("span", { children:
|
|
3343
|
+
/* @__PURE__ */ jsx("span", { children: createdAt })
|
|
2473
3344
|
] })
|
|
2474
3345
|
] }),
|
|
2475
3346
|
/* @__PURE__ */ jsxs(
|
|
@@ -2488,54 +3359,85 @@ function PaymentSheet({ paymentId, open, onOpenChange }) {
|
|
|
2488
3359
|
] })
|
|
2489
3360
|
] }) });
|
|
2490
3361
|
}
|
|
2491
|
-
var
|
|
2492
|
-
|
|
2493
|
-
const
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
}
|
|
2506
|
-
|
|
2507
|
-
const
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
}
|
|
2511
|
-
return /* @__PURE__ */
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
}
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
3362
|
+
var WalletContent = () => {
|
|
3363
|
+
const [addFundsOpen, setAddFundsOpen] = useState(false);
|
|
3364
|
+
const [withdrawOpen, setWithdrawOpen] = useState(false);
|
|
3365
|
+
const [selectedPaymentId, setSelectedPaymentId] = useState(null);
|
|
3366
|
+
const [paymentSheetOpen, setPaymentSheetOpen] = useState(false);
|
|
3367
|
+
const [selectedWithdrawalId, setSelectedWithdrawalId] = useState(null);
|
|
3368
|
+
const [withdrawalSheetOpen, setWithdrawalSheetOpen] = useState(false);
|
|
3369
|
+
const handleActivityClick = useCallback((item) => {
|
|
3370
|
+
if (item.payment) {
|
|
3371
|
+
setSelectedPaymentId(item.payment.id);
|
|
3372
|
+
setPaymentSheetOpen(true);
|
|
3373
|
+
} else if (item.withdrawal) {
|
|
3374
|
+
setSelectedWithdrawalId(item.withdrawal.id);
|
|
3375
|
+
setWithdrawalSheetOpen(true);
|
|
3376
|
+
}
|
|
3377
|
+
}, []);
|
|
3378
|
+
const handlePaymentCreated = useCallback((payment) => {
|
|
3379
|
+
setSelectedPaymentId(payment.id);
|
|
3380
|
+
setPaymentSheetOpen(true);
|
|
3381
|
+
}, []);
|
|
3382
|
+
return /* @__PURE__ */ jsxs("div", { className: "min-h-screen", children: [
|
|
3383
|
+
/* @__PURE__ */ jsx(
|
|
3384
|
+
BalanceHero,
|
|
3385
|
+
{
|
|
3386
|
+
onAddFunds: () => setAddFundsOpen(true),
|
|
3387
|
+
onWithdraw: () => setWithdrawOpen(true),
|
|
3388
|
+
className: "bg-muted/30 border-b"
|
|
3389
|
+
}
|
|
3390
|
+
),
|
|
3391
|
+
/* @__PURE__ */ jsx(
|
|
3392
|
+
ActivityList,
|
|
3393
|
+
{
|
|
3394
|
+
onItemClick: handleActivityClick,
|
|
3395
|
+
limit: 20,
|
|
3396
|
+
className: "max-w-2xl mx-auto pb-12"
|
|
3397
|
+
}
|
|
3398
|
+
),
|
|
3399
|
+
/* @__PURE__ */ jsx(
|
|
3400
|
+
AddFundsSheet,
|
|
3401
|
+
{
|
|
3402
|
+
open: addFundsOpen,
|
|
3403
|
+
onOpenChange: setAddFundsOpen,
|
|
3404
|
+
onSuccess: handlePaymentCreated
|
|
3405
|
+
}
|
|
3406
|
+
),
|
|
3407
|
+
/* @__PURE__ */ jsx(
|
|
3408
|
+
WithdrawSheet,
|
|
3409
|
+
{
|
|
3410
|
+
open: withdrawOpen,
|
|
3411
|
+
onOpenChange: setWithdrawOpen
|
|
3412
|
+
}
|
|
3413
|
+
),
|
|
3414
|
+
/* @__PURE__ */ jsx(
|
|
3415
|
+
PaymentSheet,
|
|
3416
|
+
{
|
|
3417
|
+
paymentId: selectedPaymentId,
|
|
3418
|
+
open: paymentSheetOpen,
|
|
3419
|
+
onOpenChange: setPaymentSheetOpen,
|
|
3420
|
+
onCreateNew: () => setAddFundsOpen(true)
|
|
3421
|
+
}
|
|
3422
|
+
),
|
|
3423
|
+
/* @__PURE__ */ jsx(
|
|
3424
|
+
WithdrawalSheet,
|
|
3425
|
+
{
|
|
3426
|
+
withdrawalId: selectedWithdrawalId,
|
|
3427
|
+
open: withdrawalSheetOpen,
|
|
3428
|
+
onOpenChange: setWithdrawalSheetOpen
|
|
3429
|
+
}
|
|
3430
|
+
)
|
|
3431
|
+
] });
|
|
3432
|
+
};
|
|
3433
|
+
function WalletPage() {
|
|
3434
|
+
return /* @__PURE__ */ jsx(WalletProvider, { children: /* @__PURE__ */ jsx(WalletContent, {}) });
|
|
2533
3435
|
}
|
|
2534
3436
|
|
|
2535
3437
|
// package.json
|
|
2536
3438
|
var package_default = {
|
|
2537
3439
|
name: "@djangocfg/ext-payments",
|
|
2538
|
-
version: "1.0.
|
|
3440
|
+
version: "1.0.19",
|
|
2539
3441
|
description: "Payments system extension for DjangoCFG",
|
|
2540
3442
|
keywords: [
|
|
2541
3443
|
"django",
|
|
@@ -2675,4 +3577,4 @@ export default function CryptoCheckout() {
|
|
|
2675
3577
|
]
|
|
2676
3578
|
});
|
|
2677
3579
|
|
|
2678
|
-
export { API, APIClient, APIError, APILogger, ActivityItem, ActivityList, AddFundsSheet, BalanceHero, BalanceSchema, CookieStorageAdapter, CurrencySchema, DEFAULT_RETRY_CONFIG, enums_exports as Enums, models_exports as ExtPaymentsPaymentsTypes, FetchAdapter, fetchers_exports as Fetchers, LocalStorageAdapter, MemoryStorageAdapter, NetworkError, PaginatedPaymentListListSchema, PaginatedWithdrawalListListSchema, PaymentCreateRequestSchema, PaymentDetailSchema, PaymentListSchema, PaymentSheet, REFRESH_TOKEN_KEY,
|
|
3580
|
+
export { API, APIClient, APIError, APILogger, ActivityItem, ActivityList, AddFundsSheet, BalanceHero, BalanceSchema, CookieStorageAdapter, CurrencySchema, DEFAULT_RETRY_CONFIG, enums_exports as Enums, models_exports as ExtPaymentsPaymentsTypes, FetchAdapter, fetchers_exports as Fetchers, LocalStorageAdapter, MemoryStorageAdapter, NetworkError, PaginatedPaymentListListSchema, PaginatedWithdrawalListListSchema, PaymentCreateRequestSchema, PaymentCreateResponseSchema, PaymentDetailSchema, PaymentListSchema, PaymentSheet, REFRESH_TOKEN_KEY, schemas_exports as Schemas, TOKEN_KEY, TransactionSchema, WalletPage, WithdrawSheet, WithdrawalCancelResponseSchema, WithdrawalCreateRequestSchema, WithdrawalCreateResponseSchema, WithdrawalDetailSchema, WithdrawalListSchema, WithdrawalSheet, apiPayments, clearAPITokens, configureAPI, createPaymentsPaymentsConfirmCreate, createPaymentsPaymentsCreateCreate, createPaymentsWithdrawalsCancelCreate, createPaymentsWithdrawalsCreateCreate, dispatchValidationError, extensionConfig, formatZodError, getAPIInstance, getPaymentsBalanceRetrieve, getPaymentsCurrenciesEstimateRetrieve, getPaymentsCurrenciesList, getPaymentsCurrenciesWithdrawalEstimateRetrieve, getPaymentsPaymentsList, getPaymentsPaymentsRetrieve, getPaymentsPaymentsStatusRetrieve, getPaymentsTransactionsList, getPaymentsWithdrawalsList, getPaymentsWithdrawalsRetrieve, isAPIConfigured, onValidationError, reconfigureAPI, resetAPI, shouldRetry, withRetry };
|