herald-exchange-onramp_offramp-widget 1.0.1 → 1.0.3
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/Readme.md +10 -4
- package/dist/index.js +8 -8
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +8 -8
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/assets/css/style.module.css +144 -0
- package/src/components/NewBuyField.tsx +29 -15
- package/src/components/SellAdminCryptoAccount.tsx +7 -5
- package/src/components/sandbox/CardForm.tsx +211 -0
- package/src/components/sandbox/Overview.tsx +121 -0
- package/src/components/sandbox/SandBox.tsx +35 -0
- package/src/components/sandbox/SandboxTransactionDetails.tsx +75 -0
package/package.json
CHANGED
@@ -907,6 +907,9 @@ button:disabled {
|
|
907
907
|
.input-error {
|
908
908
|
color: var(--faile-sdk-color);
|
909
909
|
}
|
910
|
+
.input_error {
|
911
|
+
color: var(--faile-sdk-color);
|
912
|
+
}
|
910
913
|
|
911
914
|
.required {
|
912
915
|
color: var(--faile-sdk-color);
|
@@ -1433,3 +1436,144 @@ button:disabled {
|
|
1433
1436
|
transform: rotate(1turn);
|
1434
1437
|
}
|
1435
1438
|
}
|
1439
|
+
|
1440
|
+
/* SANDBOX */
|
1441
|
+
|
1442
|
+
.card_form_container {
|
1443
|
+
display: flex;
|
1444
|
+
justify-content: center;
|
1445
|
+
align-items: center;
|
1446
|
+
padding: 2rem;
|
1447
|
+
}
|
1448
|
+
|
1449
|
+
.card_form {
|
1450
|
+
width: 100%;
|
1451
|
+
max-width: 400px;
|
1452
|
+
}
|
1453
|
+
|
1454
|
+
.card_form h2 {
|
1455
|
+
text-align: center;
|
1456
|
+
margin-bottom: 1.5rem;
|
1457
|
+
}
|
1458
|
+
|
1459
|
+
.card_form label {
|
1460
|
+
display: block;
|
1461
|
+
margin-bottom: 0.3rem;
|
1462
|
+
font-weight: 500;
|
1463
|
+
}
|
1464
|
+
|
1465
|
+
.card_form input {
|
1466
|
+
width: 100%;
|
1467
|
+
padding: 0.5rem;
|
1468
|
+
margin-bottom: 0.2rem;
|
1469
|
+
border-radius: 6px;
|
1470
|
+
border: 1px solid #aaa;
|
1471
|
+
font-size: 1rem;
|
1472
|
+
}
|
1473
|
+
|
1474
|
+
.card_row {
|
1475
|
+
display: flex;
|
1476
|
+
gap: 1rem;
|
1477
|
+
}
|
1478
|
+
|
1479
|
+
.card_row > div {
|
1480
|
+
flex: 1;
|
1481
|
+
}
|
1482
|
+
|
1483
|
+
/* SANDBOX Result selection */
|
1484
|
+
.result_step_container {
|
1485
|
+
max-width: 400px;
|
1486
|
+
margin: auto;
|
1487
|
+
padding: 2rem;
|
1488
|
+
border: 1px solid #ccc;
|
1489
|
+
border-radius: 10px;
|
1490
|
+
background: transparent;
|
1491
|
+
text-align: center;
|
1492
|
+
}
|
1493
|
+
|
1494
|
+
.result_step_container h2 {
|
1495
|
+
margin-bottom: 1.5rem;
|
1496
|
+
}
|
1497
|
+
|
1498
|
+
.result_options {
|
1499
|
+
display: flex;
|
1500
|
+
justify-content: space-between;
|
1501
|
+
margin-bottom: 1.5rem;
|
1502
|
+
gap: 1rem;
|
1503
|
+
}
|
1504
|
+
|
1505
|
+
.result_option {
|
1506
|
+
padding: 1rem;
|
1507
|
+
border: 1px solid var(--dark-sdk-color);
|
1508
|
+
border-radius: 6px;
|
1509
|
+
cursor: pointer;
|
1510
|
+
font-size: 1.1rem;
|
1511
|
+
transition: all 0.2s ease-in-out;
|
1512
|
+
text-align: center;
|
1513
|
+
}
|
1514
|
+
|
1515
|
+
/* SUCCESS selected */
|
1516
|
+
.success {
|
1517
|
+
background-color: #32cd32;
|
1518
|
+
color: white;
|
1519
|
+
border-color: #32cd32;
|
1520
|
+
font-weight: bold;
|
1521
|
+
transform: scale(1.1);
|
1522
|
+
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.3);
|
1523
|
+
}
|
1524
|
+
|
1525
|
+
/* FAILURE selected */
|
1526
|
+
.failure {
|
1527
|
+
background-color: #dc3545;
|
1528
|
+
color: white;
|
1529
|
+
border-color: #dc3545;
|
1530
|
+
font-weight: bold;
|
1531
|
+
transform: scale(1.1);
|
1532
|
+
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.3);
|
1533
|
+
}
|
1534
|
+
|
1535
|
+
.result_option:hover {
|
1536
|
+
border-color: var(--primay-sdk-color);
|
1537
|
+
}
|
1538
|
+
|
1539
|
+
/* SELL ADMIN CRYPTO SUCCESS / FAILURE OPTION */
|
1540
|
+
|
1541
|
+
.sell_admin_crypto_result_options {
|
1542
|
+
display: flex;
|
1543
|
+
|
1544
|
+
align-items: center;
|
1545
|
+
margin-bottom: 1.5rem;
|
1546
|
+
gap: 1rem;
|
1547
|
+
}
|
1548
|
+
.sell_admin_crypto_result_option {
|
1549
|
+
padding: 0.5rem 1rem;
|
1550
|
+
cursor: pointer;
|
1551
|
+
font-size: 1rem;
|
1552
|
+
transition: all 0.2s ease-in-out;
|
1553
|
+
text-align: center;
|
1554
|
+
border: 1px solid var(--dark-sdk-color);
|
1555
|
+
border-radius: 0.5rem;
|
1556
|
+
}
|
1557
|
+
|
1558
|
+
.sell_admin_crypto_success {
|
1559
|
+
background-color: #32cd32;
|
1560
|
+
color: white;
|
1561
|
+
border-color: #32cd32;
|
1562
|
+
|
1563
|
+
font-weight: bold;
|
1564
|
+
transform: scale(1.1);
|
1565
|
+
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.3);
|
1566
|
+
}
|
1567
|
+
|
1568
|
+
.sell_admin_crypto_failure {
|
1569
|
+
background-color: #dc3545;
|
1570
|
+
color: white;
|
1571
|
+
border-color: #dc3545;
|
1572
|
+
font-weight: bold;
|
1573
|
+
transform: scale(1.1);
|
1574
|
+
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.3);
|
1575
|
+
}
|
1576
|
+
|
1577
|
+
.hidden_radio {
|
1578
|
+
display: none;
|
1579
|
+
}
|
@@ -14,6 +14,7 @@ import type {
|
|
14
14
|
rulesType,
|
15
15
|
} from "./types";
|
16
16
|
import styles from "../assets/css/style.module.css";
|
17
|
+
import SandBox from "./sandbox/SandBox";
|
17
18
|
|
18
19
|
type NewBuyFieldProps = {
|
19
20
|
apiKey: string;
|
@@ -67,6 +68,7 @@ const NewBuyField = ({
|
|
67
68
|
maxAmount: "1000.00000",
|
68
69
|
});
|
69
70
|
|
71
|
+
const [sandboxData, setSandboxData] = useState<any>(null);
|
70
72
|
useEffect(() => {
|
71
73
|
fetchCurrencies();
|
72
74
|
fetchCommissions();
|
@@ -75,7 +77,6 @@ const NewBuyField = ({
|
|
75
77
|
|
76
78
|
const fetchCurrencies = () => {
|
77
79
|
const baseUrl = getBaseUrl(mode);
|
78
|
-
console.log({ mode, baseUrl });
|
79
80
|
|
80
81
|
handleApiCall({
|
81
82
|
url: `${baseUrl}/api/lookup/currencies`,
|
@@ -361,6 +362,10 @@ const NewBuyField = ({
|
|
361
362
|
.then((data) => {
|
362
363
|
if (data?.data?.redirect_url) {
|
363
364
|
setRedirectURL(data.data.redirect_url);
|
365
|
+
setSandboxData({
|
366
|
+
...fiatDetails,
|
367
|
+
apiResponse: data?.data,
|
368
|
+
});
|
364
369
|
setBuyStep(2);
|
365
370
|
} else if (!data.success) {
|
366
371
|
addToast(data?.message, "error");
|
@@ -664,20 +669,29 @@ const NewBuyField = ({
|
|
664
669
|
</div>
|
665
670
|
<div className={styles.bank_titles}>Back</div>
|
666
671
|
</div>
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
672
|
+
{mode === "development" ? (
|
673
|
+
<SandBox
|
674
|
+
apiKey={apiKey}
|
675
|
+
clientReferenceID={clientReferenceID}
|
676
|
+
data={sandboxData}
|
677
|
+
setSandboxData={setSandboxData}
|
678
|
+
/>
|
679
|
+
) : (
|
680
|
+
<iframe
|
681
|
+
title="Buy Crypto"
|
682
|
+
id="chat-widget"
|
683
|
+
src={redirectURL}
|
684
|
+
style={{
|
685
|
+
width: "100%",
|
686
|
+
minHeight: "calc(100vh - 400px)",
|
687
|
+
// minHeight: "calc(100vh - 23%)",
|
688
|
+
// maxHeight: "calc(100vh - 10%)",
|
689
|
+
border: "none",
|
690
|
+
zIndex: "9999",
|
691
|
+
overflow: "auto",
|
692
|
+
}}
|
693
|
+
></iframe>
|
694
|
+
)}
|
681
695
|
</>
|
682
696
|
)}
|
683
697
|
</>
|
@@ -201,7 +201,7 @@ const SellAdminCryptoAccount = ({
|
|
201
201
|
const currency = tokenSellData.selectedCrypto;
|
202
202
|
const expected_amount = tokenSellData.from_amount;
|
203
203
|
|
204
|
-
if (walletAddress) {
|
204
|
+
if (walletAddress && mode === "production") {
|
205
205
|
const startTimestamp = Date.now();
|
206
206
|
// let rpcUrl = SUPPORTED_RPC_NODES[SupportedTokens[token]];
|
207
207
|
|
@@ -219,6 +219,8 @@ const SellAdminCryptoAccount = ({
|
|
219
219
|
fetchTransactions(token, walletAddress, startTimestamp, expected_amount);
|
220
220
|
}
|
221
221
|
}, 10000);
|
222
|
+
} else {
|
223
|
+
handleManualHash();
|
222
224
|
}
|
223
225
|
// generateQRDetails(walletAddress, token, tokenSellData.from_currency);
|
224
226
|
}
|
@@ -423,10 +425,10 @@ const SellAdminCryptoAccount = ({
|
|
423
425
|
setMonitoring(false);
|
424
426
|
};
|
425
427
|
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
428
|
+
const handleManualHash = () => {
|
429
|
+
setMonitoring(false);
|
430
|
+
setAutomaticHash(false);
|
431
|
+
};
|
430
432
|
return (
|
431
433
|
<>
|
432
434
|
<div className={styles.bank_head}>
|
@@ -0,0 +1,211 @@
|
|
1
|
+
import React, { useState } from "react";
|
2
|
+
// import "./sandbox.css";
|
3
|
+
import styles from "../../assets/css/style.module.css";
|
4
|
+
const CardForm = ({
|
5
|
+
setSandboxStep,
|
6
|
+
}: {
|
7
|
+
setSandboxStep: React.Dispatch<React.SetStateAction<number>>;
|
8
|
+
}) => {
|
9
|
+
const [form, setForm] = useState({
|
10
|
+
name: "",
|
11
|
+
number: "",
|
12
|
+
expiry: "",
|
13
|
+
cvv: "",
|
14
|
+
});
|
15
|
+
|
16
|
+
const [errors, setErrors] = useState({
|
17
|
+
name: "",
|
18
|
+
number: "",
|
19
|
+
expiry: "",
|
20
|
+
cvv: "",
|
21
|
+
});
|
22
|
+
|
23
|
+
const formatCardNumber = (value: string) => {
|
24
|
+
return value
|
25
|
+
.replace(/\D/g, "") // Remove non-digits
|
26
|
+
.replace(/(.{4})/g, "$1 ") // Add space every 4 digits
|
27
|
+
.trim();
|
28
|
+
};
|
29
|
+
|
30
|
+
const formatExpiry = (value: string) => {
|
31
|
+
const cleaned = value.replace(/\D/g, "");
|
32
|
+
if (cleaned.length >= 3) {
|
33
|
+
return cleaned.slice(0, 2) + "/" + cleaned.slice(2, 4);
|
34
|
+
}
|
35
|
+
return cleaned;
|
36
|
+
};
|
37
|
+
|
38
|
+
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
39
|
+
const { name, value } = e.target;
|
40
|
+
|
41
|
+
let error = "";
|
42
|
+
|
43
|
+
let formattedValue = value;
|
44
|
+
if (name === "name") {
|
45
|
+
if (!formattedValue.trim()) {
|
46
|
+
error = "Cardholder name is required.";
|
47
|
+
} else {
|
48
|
+
const isAlpha = /^[A-Za-z\s]+$/.test(formattedValue);
|
49
|
+
if (!isAlpha) {
|
50
|
+
error = "Enter only alphabets";
|
51
|
+
}
|
52
|
+
}
|
53
|
+
}
|
54
|
+
|
55
|
+
if (name === "number") {
|
56
|
+
formattedValue = formatCardNumber(value);
|
57
|
+
|
58
|
+
if (!/^\d{4} \d{4} \d{4} \d{4}$/.test(formattedValue)) {
|
59
|
+
error = "Enter a valid 16-digit card number.";
|
60
|
+
}
|
61
|
+
}
|
62
|
+
if (name === "expiry") {
|
63
|
+
formattedValue = formatExpiry(value);
|
64
|
+
|
65
|
+
if (!/^(0[1-9]|1[0-2])\/\d{2}$/.test(formattedValue)) {
|
66
|
+
error = "Use MM/YY format.";
|
67
|
+
} else {
|
68
|
+
const [mm, yy] = formattedValue.split("/").map(Number);
|
69
|
+
const now = new Date();
|
70
|
+
const currentMonth = now.getMonth() + 1;
|
71
|
+
const currentYear = now.getFullYear() % 100; // last two digits
|
72
|
+
|
73
|
+
if (yy < currentYear || (yy === currentYear && mm < currentMonth)) {
|
74
|
+
error = "Expiry date must be in the future.";
|
75
|
+
}
|
76
|
+
}
|
77
|
+
}
|
78
|
+
if (name === "cvv") {
|
79
|
+
formattedValue = value.replace(/\D/g, "");
|
80
|
+
|
81
|
+
if (!/^\d{3,4}$/.test(formattedValue)) {
|
82
|
+
error = "CVV must be 3 or 4 digits.";
|
83
|
+
}
|
84
|
+
} // only digits
|
85
|
+
|
86
|
+
setErrors((prevErrors) => ({
|
87
|
+
...prevErrors,
|
88
|
+
[name]: error,
|
89
|
+
}));
|
90
|
+
|
91
|
+
setForm((prev) => ({ ...prev, [name]: formattedValue }));
|
92
|
+
};
|
93
|
+
|
94
|
+
const validate = () => {
|
95
|
+
const newErrors = {
|
96
|
+
name: "",
|
97
|
+
number: "",
|
98
|
+
expiry: "",
|
99
|
+
cvv: "",
|
100
|
+
};
|
101
|
+
|
102
|
+
if (!form.name.trim()) {
|
103
|
+
newErrors.name = "Cardholder name is required.";
|
104
|
+
}
|
105
|
+
|
106
|
+
if (!/^\d{4} \d{4} \d{4} \d{4}$/.test(form.number)) {
|
107
|
+
newErrors.number = "Enter a valid 16-digit card number.";
|
108
|
+
}
|
109
|
+
|
110
|
+
if (!/^(0[1-9]|1[0-2])\/\d{2}$/.test(form.expiry)) {
|
111
|
+
newErrors.expiry = "Use MM/YY format.";
|
112
|
+
} else {
|
113
|
+
const [mm, yy] = form.expiry.split("/").map(Number);
|
114
|
+
const now = new Date();
|
115
|
+
const currentMonth = now.getMonth() + 1;
|
116
|
+
const currentYear = now.getFullYear() % 100; // last two digits
|
117
|
+
|
118
|
+
if (yy < currentYear || (yy === currentYear && mm < currentMonth)) {
|
119
|
+
newErrors.expiry = "Expiry date must be in the future.";
|
120
|
+
}
|
121
|
+
}
|
122
|
+
|
123
|
+
if (!/^\d{3,4}$/.test(form.cvv)) {
|
124
|
+
newErrors.cvv = "CVV must be 3 or 4 digits.";
|
125
|
+
}
|
126
|
+
|
127
|
+
setErrors(newErrors);
|
128
|
+
|
129
|
+
return Object.values(newErrors).every((error) => !error);
|
130
|
+
};
|
131
|
+
const handleSubmit = (e: React.FormEvent) => {
|
132
|
+
e.preventDefault();
|
133
|
+
if (validate()) {
|
134
|
+
console.log("Valid card data:", form);
|
135
|
+
setSandboxStep(2);
|
136
|
+
}
|
137
|
+
};
|
138
|
+
|
139
|
+
return (
|
140
|
+
<div className={styles.card_form_container}>
|
141
|
+
<form onSubmit={handleSubmit} className={styles.card_form} noValidate>
|
142
|
+
<h2>Enter Card Details</h2>
|
143
|
+
|
144
|
+
<label htmlFor="name">Cardholder Name</label>
|
145
|
+
<input
|
146
|
+
type="text"
|
147
|
+
id="name"
|
148
|
+
name="name"
|
149
|
+
placeholder="John Doe"
|
150
|
+
value={form.name}
|
151
|
+
onChange={handleChange}
|
152
|
+
required
|
153
|
+
/>
|
154
|
+
{errors.name && <span className={styles.input_error}>{errors.name}</span>}
|
155
|
+
|
156
|
+
<label htmlFor="number">Card Number</label>
|
157
|
+
<input
|
158
|
+
type="text"
|
159
|
+
id="number"
|
160
|
+
name="number"
|
161
|
+
placeholder="1234 5678 9012 3456"
|
162
|
+
maxLength={19}
|
163
|
+
value={form.number}
|
164
|
+
onChange={handleChange}
|
165
|
+
required
|
166
|
+
/>
|
167
|
+
{errors.number && <span className={styles.input_error}>{errors.number}</span>}
|
168
|
+
|
169
|
+
<div className={styles.card_row}>
|
170
|
+
<div>
|
171
|
+
<label htmlFor="expiry">Expiry (MM/YY)</label>
|
172
|
+
<input
|
173
|
+
type="text"
|
174
|
+
id="expiry"
|
175
|
+
name="expiry"
|
176
|
+
placeholder="08/27"
|
177
|
+
maxLength={5}
|
178
|
+
value={form.expiry}
|
179
|
+
onChange={handleChange}
|
180
|
+
required
|
181
|
+
/>
|
182
|
+
{errors.expiry && <span className={styles.input_error}>{errors.expiry}</span>}
|
183
|
+
</div>
|
184
|
+
|
185
|
+
<div>
|
186
|
+
<label htmlFor="cvv">CVV</label>
|
187
|
+
<input
|
188
|
+
type="password"
|
189
|
+
id="cvv"
|
190
|
+
name="cvv"
|
191
|
+
placeholder="123"
|
192
|
+
maxLength={4}
|
193
|
+
value={form.cvv}
|
194
|
+
onChange={handleChange}
|
195
|
+
required
|
196
|
+
/>
|
197
|
+
{errors.cvv && <span className={styles.input_error}>{errors.cvv}</span>}
|
198
|
+
</div>
|
199
|
+
</div>
|
200
|
+
|
201
|
+
<div className={styles.ramp_action}>
|
202
|
+
<button type="submit" className={`${styles.action_btn} ${styles.primary}`}>
|
203
|
+
Continue
|
204
|
+
</button>
|
205
|
+
</div>
|
206
|
+
</form>
|
207
|
+
</div>
|
208
|
+
);
|
209
|
+
};
|
210
|
+
|
211
|
+
export default CardForm;
|
@@ -0,0 +1,121 @@
|
|
1
|
+
import React, { useState } from "react";
|
2
|
+
import styles from "../../assets/css/style.module.css";
|
3
|
+
import { handleApiCall } from "../api";
|
4
|
+
import { getBaseUrl } from "../utils";
|
5
|
+
import { useToast } from "../../hooks/toastProvider";
|
6
|
+
import { Spinner } from "../loader";
|
7
|
+
|
8
|
+
const CardResultOption = ({
|
9
|
+
setSandboxStep,
|
10
|
+
data,
|
11
|
+
apiKey,
|
12
|
+
clientReferenceID,
|
13
|
+
setSandboxData,
|
14
|
+
}: {
|
15
|
+
setSandboxStep: React.Dispatch<React.SetStateAction<number>>;
|
16
|
+
data: any;
|
17
|
+
apiKey: string;
|
18
|
+
clientReferenceID: string;
|
19
|
+
setSandboxData: React.Dispatch<React.SetStateAction<any>>;
|
20
|
+
}) => {
|
21
|
+
const { addToast } = useToast();
|
22
|
+
const [transactionLoading, setTransactionLoading] = useState(false);
|
23
|
+
const handleConfirm = () => {
|
24
|
+
setTransactionLoading(true);
|
25
|
+
|
26
|
+
const baseUrl = getBaseUrl("development");
|
27
|
+
|
28
|
+
handleApiCall({
|
29
|
+
url: `${baseUrl}/api/onramp/transactions/status/${data?.apiResponse?.onramp_transaction?.unique_id}`,
|
30
|
+
method: "POST",
|
31
|
+
headers: {
|
32
|
+
"X-API-KEY": apiKey,
|
33
|
+
"User-Id": clientReferenceID,
|
34
|
+
},
|
35
|
+
onSuccess: (result: any) => {
|
36
|
+
if (result?.success) {
|
37
|
+
setSandboxData({
|
38
|
+
...data,
|
39
|
+
transactionDetails: result?.data,
|
40
|
+
});
|
41
|
+
addToast(`${result?.message}`, "success");
|
42
|
+
} else {
|
43
|
+
setSandboxData({
|
44
|
+
...data,
|
45
|
+
transactionDetails: result?.data,
|
46
|
+
});
|
47
|
+
addToast(`${result?.message}`, "error");
|
48
|
+
}
|
49
|
+
setTransactionLoading(false);
|
50
|
+
setSandboxStep(3);
|
51
|
+
},
|
52
|
+
onError: (error: any) => {
|
53
|
+
addToast(`${error}`, "error");
|
54
|
+
setTransactionLoading(false);
|
55
|
+
},
|
56
|
+
});
|
57
|
+
};
|
58
|
+
|
59
|
+
return (
|
60
|
+
<div className={styles.details_frame}>
|
61
|
+
<div className={styles.f_details_head}>
|
62
|
+
<div></div>
|
63
|
+
<div className={styles.f_details_titles}>Overview</div>
|
64
|
+
</div>
|
65
|
+
<div className={styles.f_details_info_box}>
|
66
|
+
<div className={styles.f_details_card}>
|
67
|
+
<span>You pay</span>
|
68
|
+
<span>
|
69
|
+
{data?.apiResponse?.onramp_transaction?.from_value}
|
70
|
+
{data?.apiResponse?.onramp_transaction?.from}
|
71
|
+
</span>
|
72
|
+
</div>
|
73
|
+
<div className={styles.f_details_card}>
|
74
|
+
<span>Rate</span>
|
75
|
+
<span>
|
76
|
+
1 {data?.apiResponse?.onramp_transaction?.from} =
|
77
|
+
{data?.apiResponse?.onramp_transaction?.exchange_rate}{" "}
|
78
|
+
{data?.apiResponse?.onramp_transaction?.to}
|
79
|
+
</span>
|
80
|
+
</div>
|
81
|
+
<div className={styles.f_details_card}>
|
82
|
+
<span>Fee</span>
|
83
|
+
<span>
|
84
|
+
{data?.apiResponse?.onramp_transaction?.service_fee}
|
85
|
+
{data?.apiResponse?.onramp_transaction?.from}
|
86
|
+
</span>
|
87
|
+
</div>
|
88
|
+
<div className={styles.f_details_card}>
|
89
|
+
<span>You Receive</span>
|
90
|
+
<span>
|
91
|
+
{data?.apiResponse?.onramp_transaction?.to_value}{" "}
|
92
|
+
{data?.apiResponse?.onramp_transaction?.to}
|
93
|
+
</span>
|
94
|
+
</div>
|
95
|
+
|
96
|
+
<div className={styles.f_details_card}>
|
97
|
+
<span>Wallet</span>
|
98
|
+
<span>
|
99
|
+
{data?.apiResponse?.onramp_transaction?.wallet_address?.length > 15
|
100
|
+
? `${data?.apiResponse?.onramp_transaction?.wallet_address?.slice(
|
101
|
+
0,
|
102
|
+
5
|
103
|
+
)}...${data?.apiResponse?.onramp_transaction?.wallet_address?.slice(-5)}`
|
104
|
+
: data?.apiResponse?.onramp_transaction?.wallet_address}
|
105
|
+
</span>
|
106
|
+
</div>
|
107
|
+
</div>
|
108
|
+
<div className={styles.ramp_action}>
|
109
|
+
<button
|
110
|
+
type="button"
|
111
|
+
onClick={handleConfirm}
|
112
|
+
className={`${styles.action_btn} ${styles.primary}`}
|
113
|
+
>
|
114
|
+
Confirm {transactionLoading && <Spinner />}
|
115
|
+
</button>
|
116
|
+
</div>
|
117
|
+
</div>
|
118
|
+
);
|
119
|
+
};
|
120
|
+
|
121
|
+
export default CardResultOption;
|
@@ -0,0 +1,35 @@
|
|
1
|
+
import { useState } from "react";
|
2
|
+
import CardForm from "./CardForm";
|
3
|
+
import CardResultOption from "./Overview";
|
4
|
+
import CardTransactionDetails from "./SandboxTransactionDetails";
|
5
|
+
|
6
|
+
const SandBox = ({
|
7
|
+
data,
|
8
|
+
apiKey,
|
9
|
+
clientReferenceID,
|
10
|
+
setSandboxData,
|
11
|
+
}: {
|
12
|
+
data: any;
|
13
|
+
apiKey: string;
|
14
|
+
clientReferenceID: string;
|
15
|
+
setSandboxData: (data: any) => void;
|
16
|
+
}) => {
|
17
|
+
const [sandboxStep, setSandboxStep] = useState(1);
|
18
|
+
return (
|
19
|
+
<div>
|
20
|
+
{sandboxStep === 1 && <CardForm setSandboxStep={setSandboxStep} />}
|
21
|
+
{sandboxStep === 2 && (
|
22
|
+
<CardResultOption
|
23
|
+
apiKey={apiKey}
|
24
|
+
clientReferenceID={clientReferenceID}
|
25
|
+
data={data}
|
26
|
+
setSandboxStep={setSandboxStep}
|
27
|
+
setSandboxData={setSandboxData}
|
28
|
+
/>
|
29
|
+
)}
|
30
|
+
{sandboxStep === 3 && <CardTransactionDetails data={data} />}
|
31
|
+
</div>
|
32
|
+
);
|
33
|
+
};
|
34
|
+
|
35
|
+
export default SandBox;
|