astra-modal-test 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/README.md +0 -0
  2. package/dist/astra-sdk.es.js +8 -0
  3. package/dist/astra-sdk.umd.js +12576 -0
  4. package/dist/ccip-Bpb4GlU6.mjs +146 -0
  5. package/dist/hooks.module-BBZfodGH.mjs +506 -0
  6. package/dist/index-BTsa09iy.mjs +84805 -0
  7. package/dist/index-CEtKkuP2.mjs +133 -0
  8. package/dist/index-CbWGAz3l.mjs +445 -0
  9. package/dist/index-DRPxIWUd.mjs +13720 -0
  10. package/dist/index-h9_6XS0r.mjs +2929 -0
  11. package/dist/secp256k1-3OC5y4qp.mjs +1578 -0
  12. package/dist/vite.svg +1 -0
  13. package/dist/w3m-modal-R9m1z1SQ.mjs +267 -0
  14. package/eslint.config.js +39 -0
  15. package/index.html +13 -0
  16. package/package.json +50 -0
  17. package/public/vite.svg +1 -0
  18. package/src/App.css +170 -0
  19. package/src/apis/lspApi.js +59 -0
  20. package/src/apis/request.js +59 -0
  21. package/src/assets/arrow-right.svg +3 -0
  22. package/src/assets/astr.svg +13 -0
  23. package/src/assets/bridge-loading.png +0 -0
  24. package/src/assets/network/base.png +0 -0
  25. package/src/assets/network/eth.png +0 -0
  26. package/src/assets/network/lighting.png +0 -0
  27. package/src/assets/network/ligtning.svg +22 -0
  28. package/src/assets/network/solona.png +0 -0
  29. package/src/assets/powerby.svg +14 -0
  30. package/src/assets/react.svg +1 -0
  31. package/src/assets/success.svg +3 -0
  32. package/src/assets/tip.svg +5 -0
  33. package/src/assets/tokens/sol.png +0 -0
  34. package/src/assets/tokens/usdc.png +0 -0
  35. package/src/assets/tokens/usdt.png +0 -0
  36. package/src/comps/AstraImage.jsx +23 -0
  37. package/src/comps/AstraModal.jsx +207 -0
  38. package/src/comps/AstraModalLogo.jsx +53 -0
  39. package/src/comps/AstraNetwork.jsx +115 -0
  40. package/src/comps/CheckErc20Button.jsx +28 -0
  41. package/src/comps/ConnectButton.jsx +37 -0
  42. package/src/comps/EllipsisMiddle.jsx +42 -0
  43. package/src/comps/ResultModal.jsx +307 -0
  44. package/src/comps/ToLightning.jsx +502 -0
  45. package/src/comps/ToToken.jsx +467 -0
  46. package/src/constants/contracts/abi/bridge.js +1246 -0
  47. package/src/constants/contracts/abi/index.js +3 -0
  48. package/src/constants/contracts/abi/usdt.js +130 -0
  49. package/src/constants/contracts/abi/watcher.js +523 -0
  50. package/src/constants/contracts/index.js +37 -0
  51. package/src/constants/index.js +5 -0
  52. package/src/font/ClashDisplay-Variable.ttf +0 -0
  53. package/src/font/ClashDisplay-Variable.woff +0 -0
  54. package/src/font/ClashDisplay-Variable.woff2 +0 -0
  55. package/src/hooks/useContract.js +127 -0
  56. package/src/hooks/useLspApi.js +53 -0
  57. package/src/hooks/useParseInvoice.js +85 -0
  58. package/src/index.css +69 -0
  59. package/src/index.jsx +112 -0
  60. package/src/lib/bolt11.min.js +1 -0
  61. package/src/main.jsx +41 -0
  62. package/src/store/index.js +25 -0
  63. package/src/theme.js +108 -0
  64. package/src/utils/index.js +36 -0
  65. package/vite.config.js +44 -0
@@ -0,0 +1,467 @@
1
+ import { memo } from "react";
2
+ import styled from "styled-components";
3
+ import useStore from "../store";
4
+ import { Form, Button, Select, Flex, QRCode, Statistic } from "antd";
5
+ import { useCallback, useEffect, useState, useMemo } from "react";
6
+ import AstraImage from "./AstraImage";
7
+ import { useAccount, useBalance } from "wagmi";
8
+ import { DoubleRightOutlined } from "@ant-design/icons";
9
+ import EllipsisMiddle from "./EllipsisMiddle";
10
+ import { useBridgeContract } from "../hooks/useContract";
11
+ import { useGetReserveInfo } from "../hooks/useLspApi";
12
+ import { toEVM, getSignature } from "../apis/lspApi";
13
+ import Decimal from "decimal.js";
14
+ import ConnectButton from "./ConnectButton";
15
+ import { formatAssetByDecimal } from "../utils";
16
+ import AstraNetwork from "./AstraNetwork";
17
+ import IconArrowRight from "../assets/arrow-right.svg";
18
+ const { Countdown } = Statistic;
19
+ const WrapperToLightning = styled.div``;
20
+
21
+ const FormItem = styled(Form.Item)`
22
+ .ant-form-item-label {
23
+ text-align: right;
24
+ }
25
+ `;
26
+ const AstraSelect = styled(Select)`
27
+ width: 60px !important;
28
+ .astra-select-selector {
29
+ padding: 0 0px !important;
30
+ }
31
+ .astra-select-selection-item {
32
+ display: flex !important;
33
+ align-items: center;
34
+ justify-content: center;
35
+ }
36
+ .astra-select-arrow {
37
+ color: #fff;
38
+ }
39
+ `;
40
+ const QRCodeWrapper = styled(Flex)`
41
+ /* margin-bottom: 20px; */
42
+ `;
43
+
44
+ const SubmitBtn = styled(Button)`
45
+ width: 100%;
46
+ display: flex;
47
+ justify-content: space-between;
48
+ padding: 0 30px;
49
+ font-size: 16px;
50
+ line-height: 42px;
51
+ margin-top: 10px;
52
+ `;
53
+
54
+ const BalanceFlex = styled(Flex)`
55
+ .available_token_balance {
56
+ font-size: 12px;
57
+ color: #fff;
58
+ }
59
+ `;
60
+ const AstraSendingReceived = styled.div`
61
+ padding: 8px 20px;
62
+ border-radius: 12px;
63
+ background: rgba(166, 166, 166, 0.1);
64
+ margin-bottom: 14px;
65
+ @media (max-width: 768px) {
66
+ padding: 8px 10px;
67
+ border-radius: 12px;
68
+ background: rgba(166, 166, 166, 0.1);
69
+ margin-bottom: 14px;
70
+ }
71
+ `;
72
+ const AstraFormItemOther = styled.div`
73
+ padding: 0 20px;
74
+ @media (max-width: 768px) {
75
+ padding: 0 10px;
76
+ }
77
+ `;
78
+ function ToToken({ messageApi }) {
79
+ const {
80
+ sendArgs,
81
+ allAssetPairs,
82
+ targetNetwork,
83
+ setCurrentAssetPair,
84
+ currentAssetPair,
85
+ onAstraInvoice,
86
+ setAstraModalShow,
87
+ } = useStore();
88
+
89
+ const [sendInvoice, setSendInvoice] = useState("");
90
+ const [tx, setTx] = useState("");
91
+ const account = useAccount();
92
+ const [form] = Form.useForm();
93
+ const [submitLoading, setSubmitLoading] = useState(false);
94
+ const [invoiceExpired, setInvoiceExpired] = useState(0);
95
+ const [isInvoiceExpired, setIsInvoiceExpired] = useState(false);
96
+ const [payInvoiceLoading, setPayInvoiceLoading] = useState(false);
97
+ const filterdAssetPairs = useMemo(() => {
98
+ return allAssetPairs.filter((pair) => {
99
+ return pair.asset.assetId === sendArgs.assetId;
100
+ });
101
+ }, [allAssetPairs, sendArgs.assetId]);
102
+ // console.log("🚀 ~ ToLightning ~ allAssetPairs:", allAssetPairs, receiveArgs);
103
+ const { reserveInfo } = useGetReserveInfo(targetNetwork, currentAssetPair);
104
+
105
+ const serviceFee = useMemo(() => {
106
+ const recieveBaseFee = reserveInfo?.toTokenBaseFee || 0;
107
+ return new Decimal(recieveBaseFee.toString()).div(10 ** 18).toFixed(4);
108
+ }, [reserveInfo?.toTokenBaseFee]);
109
+
110
+ const tokenBalanceRet = useBalance({
111
+ address: account?.address,
112
+ token: currentAssetPair?.token?.address,
113
+ enabled: !!currentAssetPair?.token?.address && !!account?.address,
114
+ formatUnits: currentAssetPair?.token?.decimal,
115
+ });
116
+
117
+ const mainnetBalanceRet = useBalance({
118
+ address: account?.address,
119
+ enabled: !!account?.address,
120
+ formatUnits: "ether",
121
+ });
122
+
123
+ const btnDisabled = useMemo(() => {
124
+ if (filterdAssetPairs?.length === 0) {
125
+ return true;
126
+ }
127
+ const mainetBalance = mainnetBalanceRet?.data?.value || 0;
128
+ if (Number(mainetBalance) < Number(reserveInfo?.toTokenBaseFee)) {
129
+ return true;
130
+ }
131
+ }, [
132
+ filterdAssetPairs?.length,
133
+ mainnetBalanceRet?.data?.value,
134
+ reserveInfo?.toTokenBaseFee,
135
+ ]);
136
+
137
+ const onResetInvoice = useCallback(() => {
138
+ setIsInvoiceExpired(false);
139
+ setInvoiceExpired(0);
140
+ setSendInvoice("");
141
+ }, []);
142
+ const { onDeposit } = useBridgeContract(account);
143
+
144
+ const onAssetPairChange = useCallback(
145
+ (pairId) => {
146
+ const selectedPair = pairId
147
+ ? allAssetPairs.find((pair) => pair.pairId === pairId)
148
+ : null;
149
+ setCurrentAssetPair(selectedPair);
150
+ },
151
+ [allAssetPairs, setCurrentAssetPair]
152
+ );
153
+ const onFinish = useCallback(async () => {
154
+ try {
155
+ setSubmitLoading(true);
156
+ onResetInvoice();
157
+ const max = Math.min(
158
+ Number(
159
+ formatAssetByDecimal(
160
+ reserveInfo?.maxToken,
161
+ currentAssetPair.token.decimal
162
+ )
163
+ ),
164
+ reserveInfo.max
165
+ );
166
+
167
+ if (sendArgs.amount > max || sendArgs.amount < reserveInfo.min) {
168
+ throw new Error(
169
+ `Amount should be between ${reserveInfo.min} and ${max}`
170
+ );
171
+ }
172
+
173
+ const retGetSignature = await getSignature({
174
+ chainId: targetNetwork.id,
175
+ amount: sendArgs.amount,
176
+ pairName: currentAssetPair?.pairName,
177
+ });
178
+ if (retGetSignature?.code !== 200) {
179
+ throw new Error(retGetSignature?.msg);
180
+ }
181
+ const signatureRes = retGetSignature?.data;
182
+ const hashlock = signatureRes.hashlock;
183
+ const fromAddr = signatureRes.lspAddress;
184
+
185
+ const tokenAddr = signatureRes.tokenAddress;
186
+ const amount = BigInt(signatureRes.amtInContract);
187
+ const timeLock = BigInt(signatureRes.deltaSecond);
188
+ const expiredAt = Date.now() + Number(timeLock) * 1000;
189
+ setInvoiceExpired(expiredAt);
190
+ const signature = signatureRes.signature;
191
+ const fee = BigInt(signatureRes.fee);
192
+
193
+ const depositArgs = {
194
+ hashlock,
195
+ fromAddr,
196
+ toAddr: account.address,
197
+ tokenAddr: tokenAddr,
198
+ amount: amount,
199
+ timeLock: timeLock,
200
+ toLightning: false,
201
+ fee: fee,
202
+ signature,
203
+ };
204
+
205
+ if (sendArgs.waitConfirm) {
206
+ const tx = await onDeposit(depositArgs, true, false);
207
+ setTx(tx);
208
+ if (tx) {
209
+ const request = {
210
+ assetId: currentAssetPair?.asset?.assetId,
211
+ amount: sendArgs.amount,
212
+ chainId: targetNetwork.id,
213
+ pairName: currentAssetPair?.pairName,
214
+ hashlock: signatureRes.hashlock,
215
+ depositTx: tx,
216
+ };
217
+ // setResultModalRequest({
218
+ // txHash: tx,
219
+ // timestamp: Date.now(),
220
+ // formatTokenAmt: sendArgs.amount,
221
+ // request
222
+ // })
223
+ // setAstraModalShow(false)
224
+ // setResultModalShow(true);
225
+ const retToEVM = await toEVM(request);
226
+ if (retToEVM.code === 200) {
227
+ messageApi.success("Submit success.");
228
+ setSendInvoice(retToEVM.data.invoice);
229
+ }
230
+ }
231
+ } else {
232
+ //TODO
233
+ }
234
+ } catch (e) {
235
+ const error = e.message;
236
+ if (error.includes("User rejected")) {
237
+ messageApi.error("User reject the request.");
238
+ } else {
239
+ messageApi.error(e.message);
240
+ }
241
+ } finally {
242
+ setSubmitLoading(false);
243
+ }
244
+ }, [
245
+ onResetInvoice,
246
+ reserveInfo,
247
+ currentAssetPair,
248
+ sendArgs.amount,
249
+ sendArgs.waitConfirm,
250
+ targetNetwork.id,
251
+ account.address,
252
+ onDeposit,
253
+ messageApi,
254
+ ]);
255
+
256
+ const btn = useMemo(() => {
257
+ if (!account?.address) {
258
+ return <ConnectButton />;
259
+ }
260
+ if (sendInvoice) {
261
+ return submitLoading ? (
262
+ <SubmitBtn type="primary" loading={submitLoading}>
263
+ <span>Waiting for Confirmation</span>
264
+ </SubmitBtn>
265
+ ) : (
266
+ <SubmitBtn
267
+ type="primary"
268
+ disabled={isInvoiceExpired || btnDisabled}
269
+ loading={payInvoiceLoading}
270
+ onClick={async () => {
271
+ setPayInvoiceLoading(true);
272
+ await onAstraInvoice(sendInvoice, tx)
273
+ .catch((e) => {
274
+ messageApi.error(e.message);
275
+ setPayInvoiceLoading(false);
276
+ return;
277
+ })
278
+ .finally(() => {
279
+ setPayInvoiceLoading(false);
280
+ });
281
+ setAstraModalShow(false);
282
+ }}
283
+ >
284
+ <span>Pay Invoice</span>
285
+ <img src={IconArrowRight} alt="" />
286
+ </SubmitBtn>
287
+ );
288
+ } else {
289
+ return (
290
+ <SubmitBtn
291
+ type="primary"
292
+ htmlType="submit"
293
+ loading={submitLoading}
294
+ disabled={isInvoiceExpired || btnDisabled}
295
+ >
296
+ <span>{submitLoading ? "Waiting for Confirmation" : "Submit"}</span>
297
+ <img src={IconArrowRight} alt="" />
298
+ </SubmitBtn>
299
+ );
300
+ }
301
+ }, [
302
+ account?.address,
303
+ btnDisabled,
304
+ isInvoiceExpired,
305
+ messageApi,
306
+ onAstraInvoice,
307
+ payInvoiceLoading,
308
+ sendInvoice,
309
+ setAstraModalShow,
310
+ submitLoading,
311
+ tx,
312
+ ]);
313
+
314
+ const onExpired = useCallback(() => {
315
+ setIsInvoiceExpired(true);
316
+ }, []);
317
+
318
+ useEffect(() => {
319
+ if (filterdAssetPairs?.length > 0) {
320
+ setCurrentAssetPair(filterdAssetPairs[0]);
321
+ form.setFieldValue("received", filterdAssetPairs?.[0]?.pairId);
322
+ }
323
+ }, [filterdAssetPairs, form, setCurrentAssetPair]);
324
+ return (
325
+ <WrapperToLightning>
326
+ <Form
327
+ name="basic"
328
+ form={form}
329
+ colon={false}
330
+ // labelCol={{
331
+ // span: 8,
332
+ // }}
333
+ // wrapperCol={{
334
+ // span: 16,
335
+ // }}
336
+ style={{
337
+ width: "100%",
338
+ }}
339
+ initialValues={{
340
+ remember: true,
341
+ }}
342
+ onFinish={onFinish}
343
+ autoComplete="off"
344
+ >
345
+ <AstraNetwork
346
+ messageApi={messageApi}
347
+ balance={mainnetBalanceRet?.data}
348
+ />
349
+ <AstraSendingReceived>
350
+ <FormItem label="Sending">
351
+ <Flex justify="end" align="center" gap="5px">
352
+ <AstraImage name={"Lightning"} />
353
+ <span className="fw500 colorcaff33">{sendArgs?.amount}</span>
354
+ <span className="fw500 colorcaff33">
355
+ {currentAssetPair?.asset?.name}
356
+ </span>
357
+ </Flex>
358
+ </FormItem>
359
+
360
+ <FormItem label="Received" style={{ marginBottom: 0 }}>
361
+ <Flex justify="end" align="center" gap="5px">
362
+ <FormItem name="received" noStyle className="form-item-pair">
363
+ <AstraSelect
364
+ variant="borderless"
365
+ options={filterdAssetPairs.map((pair) => ({
366
+ value: pair.pairId,
367
+ label: (
368
+ <AstraImage
369
+ name={pair.token.name}
370
+ width="22px"
371
+ height="22px"
372
+ />
373
+ ),
374
+ }))}
375
+ onChange={onAssetPairChange}
376
+ ></AstraSelect>
377
+ </FormItem>
378
+ <span>{sendArgs?.amount}</span>
379
+ <span>{currentAssetPair?.token?.name}</span>
380
+ </Flex>
381
+ <BalanceFlex justify="end" align="center" gap="5px">
382
+ <span className="available_token_balance">
383
+ Available:{tokenBalanceRet?.data?.formatted}{" "}
384
+ {tokenBalanceRet?.data?.symbol}
385
+ </span>
386
+ </BalanceFlex>
387
+ </FormItem>
388
+ </AstraSendingReceived>
389
+ <AstraFormItemOther>
390
+ <FormItem label="Service fee">
391
+ <Flex justify="end" align="center" gap="5px">
392
+ <span>{serviceFee}</span>
393
+ <AstraImage
394
+ name={targetNetwork?.name}
395
+ width="24px"
396
+ height="24px"
397
+ />
398
+ </Flex>
399
+ </FormItem>
400
+
401
+ <FormItem label="Receiving address">
402
+ <Flex justify="end" align="center" gap="5px">
403
+ <AstraImage name={targetNetwork?.name} />
404
+ <EllipsisMiddle suffixCount={6}>
405
+ {account?.address ?? "--"}
406
+ </EllipsisMiddle>
407
+ </Flex>
408
+ </FormItem>
409
+ <FormItem label="Route">
410
+ <Flex justify="end" align="center" gap="5px">
411
+ <AstraImage name="Lightning" />
412
+ <DoubleRightOutlined style={{ color: "#caff33" }} />
413
+ <AstraImage
414
+ name={targetNetwork?.name}
415
+ width="24px"
416
+ height="24px"
417
+ />
418
+ </Flex>
419
+ </FormItem>
420
+ </AstraFormItemOther>
421
+ {sendInvoice && (
422
+ <>
423
+ <QRCodeWrapper
424
+ justify="center"
425
+ align="center"
426
+ gap="10px"
427
+ vertical={true}
428
+ >
429
+ <QRCode
430
+ type="svg"
431
+ size={200}
432
+ errorLevel="M"
433
+ iconSize={40}
434
+ value={sendInvoice}
435
+ bordered={false}
436
+ status={isInvoiceExpired ? "expired" : "active"}
437
+ />
438
+ <Countdown
439
+ title="Invoice expires in"
440
+ valueStyle={{
441
+ color: "#caff33",
442
+ fontSize: "14px",
443
+ textAlign: "center",
444
+ }}
445
+ value={invoiceExpired}
446
+ onFinish={onExpired}
447
+ />
448
+ </QRCodeWrapper>
449
+ </>
450
+ )}
451
+
452
+ <FormItem
453
+ label={null}
454
+ labelCol={{
455
+ span: 0,
456
+ }}
457
+ wrapperCol={{
458
+ span: 24,
459
+ }}
460
+ >
461
+ <Flex justify="center"> {btn}</Flex>
462
+ </FormItem>
463
+ </Form>
464
+ </WrapperToLightning>
465
+ );
466
+ }
467
+ export default memo(ToToken);