@pioneer-platform/pioneer-react 0.0.1 → 0.2.32

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 (93) hide show
  1. package/.eslintrc.js +24 -0
  2. package/.github/workflows/release.yml +22 -0
  3. package/.github/workflows/update-license.yml +11 -0
  4. package/.lintstagedrc.json +6 -0
  5. package/.prettierrc +7 -0
  6. package/.vscode/extensions.json +8 -0
  7. package/CHANGELOG.md +5 -0
  8. package/LICENSE +21 -0
  9. package/README.md +40 -0
  10. package/commitlint.config.js +3 -0
  11. package/dist/assets/404 Error-rafiki.svg +1 -0
  12. package/dist/assets/Building blocks-amico.svg +1 -0
  13. package/dist/assets/chakra-ui-logomark-colored.svg +10 -0
  14. package/dist/assets/favicon.svg +0 -0
  15. package/dist/assets/react-icon.svg +7 -0
  16. package/dist/assets/ts-logo-512.svg +1 -0
  17. package/dist/assets/vite-logo.svg +15 -0
  18. package/dist/index.js +384249 -0
  19. package/dist/index_3bde86fb.js +205 -0
  20. package/dist/index_49fce0b0.js +384033 -0
  21. package/dist/index_d01e819c.css +63 -0
  22. package/dist/manifest.json +12 -0
  23. package/dist/robots.txt +6 -0
  24. package/index.html +13 -0
  25. package/netlify.toml +10 -0
  26. package/package.json +70 -10
  27. package/public/assets/404 Error-rafiki.svg +1 -0
  28. package/public/assets/Building blocks-amico.svg +1 -0
  29. package/public/assets/chakra-ui-logomark-colored.svg +10 -0
  30. package/public/assets/favicon.svg +0 -0
  31. package/public/assets/react-icon.svg +7 -0
  32. package/public/assets/ts-logo-512.svg +1 -0
  33. package/public/assets/vite-logo.svg +15 -0
  34. package/public/manifest.json +12 -0
  35. package/public/robots.txt +6 -0
  36. package/renovate.json +11 -0
  37. package/src/App.tsx +21 -0
  38. package/src/index.tsx +41 -0
  39. package/src/lib/assets/Icons/KeepKeyIcon.tsx +13 -0
  40. package/src/lib/assets/Icons/KeplrIcon.tsx +140 -0
  41. package/src/lib/assets/Icons/MetaMaskIcon.tsx +126 -0
  42. package/src/lib/assets/Icons/TallyHoIcon.tsx +17 -0
  43. package/src/lib/assets/Icons/XDEFIIcon.tsx +32 -0
  44. package/src/lib/assets/favicon.ico +0 -0
  45. package/src/lib/assets/png/keepkey.png +0 -0
  46. package/src/lib/assets/png/keplr.png +0 -0
  47. package/src/lib/assets/png/metamask.png +0 -0
  48. package/src/lib/assets/png/pioneer.png +0 -0
  49. package/src/lib/components/AssetSelect/index.tsx +166 -0
  50. package/src/lib/components/BlockchainSelect/index.tsx +166 -0
  51. package/src/lib/components/MiddleEllipsis/index.tsx +27 -0
  52. package/src/lib/components/WalletSelect/index.tsx +112 -0
  53. package/src/lib/components/auth/RequireAuth.tsx +22 -0
  54. package/src/lib/components/modals/AssetModal.tsx +67 -0
  55. package/src/lib/components/modals/SettingsModal.tsx +76 -0
  56. package/src/lib/components/pioneer/Pioneer/Balances.tsx +266 -0
  57. package/src/lib/components/pioneer/Pioneer/MiddleEllipsis.tsx +27 -0
  58. package/src/lib/components/pioneer/Pioneer/Nodes.tsx +0 -0
  59. package/src/lib/components/pioneer/Pioneer/Paths.tsx +290 -0
  60. package/src/lib/components/pioneer/Pioneer/Pubkey.tsx +67 -0
  61. package/src/lib/components/pioneer/Pioneer/Pubkeys.tsx +265 -0
  62. package/src/lib/components/pioneer/Pioneer/Receive.tsx +26 -0
  63. package/src/lib/components/pioneer/Pioneer/Send.tsx +135 -0
  64. package/src/lib/components/pioneer/Pioneer/View.tsx +44 -0
  65. package/src/lib/components/pioneer/Pioneer/Wallets.tsx +166 -0
  66. package/src/lib/components/pioneer/index.tsx +525 -0
  67. package/src/lib/components/utils/index.tsx +47 -0
  68. package/src/lib/context/Pioneer/index.tsx +420 -0
  69. package/src/lib/layout/Footer.tsx +22 -0
  70. package/src/lib/layout/Header.tsx +38 -0
  71. package/src/lib/layout/Meta.tsx +25 -0
  72. package/src/lib/layout/Pioneer/Balances.tsx +290 -0
  73. package/src/lib/layout/Pioneer/MiddleEllipsis.tsx +27 -0
  74. package/src/lib/layout/Pioneer/Pubkey.tsx +67 -0
  75. package/src/lib/layout/Pioneer/Receive.tsx +26 -0
  76. package/src/lib/layout/Pioneer/Send.tsx +135 -0
  77. package/src/lib/layout/Pioneer/View.tsx +44 -0
  78. package/src/lib/layout/Pioneer/Wallets.tsx +166 -0
  79. package/src/lib/layout/ThemeToggle.tsx +16 -0
  80. package/src/lib/layout/index.tsx +29 -0
  81. package/src/lib/pages/404/index.tsx +36 -0
  82. package/src/lib/pages/home/components/CTASection.tsx +36 -0
  83. package/src/lib/pages/home/components/SomeImage.tsx +36 -0
  84. package/src/lib/pages/home/components/SomeText.tsx +16 -0
  85. package/src/lib/pages/home/index.tsx +87 -0
  86. package/src/lib/router/Routings.tsx +45 -0
  87. package/src/lib/router/routes.tsx +13 -0
  88. package/src/lib/styles/theme/config.ts +5 -0
  89. package/src/lib/styles/theme/index.ts +17 -0
  90. package/tsconfig.json +19 -9
  91. package/turbo.json +17 -0
  92. package/vercel.json +4 -0
  93. package/vite.config.ts +110 -0
@@ -0,0 +1,525 @@
1
+ import {
2
+ chakra,
3
+ Stack,
4
+ CircularProgress,
5
+ Drawer,
6
+ DrawerOverlay,
7
+ DrawerContent,
8
+ DrawerHeader,
9
+ DrawerBody,
10
+ Tabs,
11
+ TabList,
12
+ TabPanels,
13
+ Tab,
14
+ TabPanel,
15
+ Avatar,
16
+ AvatarBadge,
17
+ Box,
18
+ Button,
19
+ Flex,
20
+ HStack,
21
+ IconButton,
22
+ Link,
23
+ Menu,
24
+ Image,
25
+ MenuButton,
26
+ MenuDivider,
27
+ Icon,
28
+ MenuItem,
29
+ MenuList,
30
+ Spacer,
31
+ Text,
32
+ useDisclosure,
33
+ Accordion,
34
+ AccordionItem,
35
+ AccordionButton,
36
+ AccordionIcon,
37
+ AccordionPanel,
38
+ SimpleGrid,
39
+ Card,
40
+ CardHeader,
41
+ Heading,
42
+ CardBody,
43
+ CardFooter,
44
+ Modal,
45
+ ModalOverlay,
46
+ ModalContent,
47
+ ModalHeader,
48
+ ModalCloseButton,
49
+ ModalBody,
50
+ ModalFooter,
51
+ Select,
52
+ } from "@chakra-ui/react";
53
+ import { SetStateAction, useContext, useEffect, useState } from "react";
54
+ import { FaCog } from "react-icons/fa";
55
+ import { Img } from "react-image";
56
+ import { KeepKeyIcon } from "lib/assets/Icons/KeepKeyIcon";
57
+ // @ts-ignore
58
+ import KEEPKEY_ICON from "lib/assets/png/keepkey.png";
59
+ // @ts-ignore
60
+ import METAMASK_ICON from "lib/assets/png/metamask.png";
61
+ // @ts-ignore
62
+ import PIONEER_ICON from "lib/assets/png/pioneer.png";
63
+ //@ts-ignore
64
+ import { ModalContext } from "lib/components/modals";
65
+ import SettingsModal from "lib/components/modals/SettingsModal";
66
+ import { MiddleEllipsis } from "lib/components/utils";
67
+ import { usePioneer } from "lib/context/Pioneer";
68
+
69
+ import Balances from "./Pioneer/Balances";
70
+ import Wallets from "./Pioneer/Wallets";
71
+
72
+ const getWalletType = (user: { walletDescriptions: any[] }, context: any) => {
73
+ if (user && user.walletDescriptions) {
74
+ const wallet = user.walletDescriptions.find((w) => w.id === context);
75
+ return wallet ? wallet.type : null;
76
+ }
77
+ return null;
78
+ };
79
+
80
+ const getWalletBadgeContent = (walletType: string) => {
81
+ const icons: any = {
82
+ metamask: METAMASK_ICON,
83
+ keepkey: KEEPKEY_ICON,
84
+ native: PIONEER_ICON,
85
+ };
86
+
87
+ const icon = icons[walletType];
88
+
89
+ return (
90
+ <AvatarBadge boxSize="1.25em" bg="green.500">
91
+ <Image rounded="full" src={icon} />
92
+ </AvatarBadge>
93
+ );
94
+ };
95
+
96
+ const getWalletSettingsContent = (walletType: string) => {
97
+ const icons: any = {
98
+ metamask: METAMASK_ICON,
99
+ keepkey: KEEPKEY_ICON,
100
+ native: PIONEER_ICON,
101
+ };
102
+
103
+ const icon = icons[walletType];
104
+
105
+ if (!icon) {
106
+ return <div />;
107
+ }
108
+
109
+ return icon;
110
+ };
111
+
112
+ const Pioneer = () => {
113
+ const { state, dispatch } = usePioneer();
114
+ const { api, app, user, status } = state;
115
+ const { isOpen, onOpen, onClose } = useDisclosure();
116
+
117
+ // local
118
+ const [copySuccess, setCopySuccess] = useState(false);
119
+ const [walletType, setWalletType] = useState("");
120
+ const [walletDescriptions, setWalletDescriptions] = useState([]);
121
+ const [walletsAvailable, setWalletsAvailable] = useState([]);
122
+ const [metamaskPaired, setMetamaskPaired] = useState(false);
123
+ const [keepkeyPaired, setKeepkeyPaired] = useState(false);
124
+ const [nativePaired, setNativePaired] = useState(false);
125
+ const [pioneerImage, setPioneerImage] = useState("");
126
+ const [walletSettingsContext, setWalletSettingsContext] = useState("");
127
+ const [context, setContext] = useState("");
128
+ const [assetContext, setAssetContext] = useState("");
129
+ const [assetContextImage, setAssetContextImage] = useState("");
130
+ const [blockchainContext, setBlockchainContext] = useState("");
131
+ const [pubkeyContext, setPubkeyContext] = useState("");
132
+ const [blockchainContextImage, setBlockchainContextImage] = useState("");
133
+ const [isSynced, setIsSynced] = useState(false);
134
+ const [isPioneer, setIsPioneer] = useState(false);
135
+ const [isFox, setIsFox] = useState(false);
136
+ const [pubkeys, setPubkeys] = useState([]);
137
+ const [balances, setBalances] = useState([]);
138
+
139
+ const settingsSelected = async function () {
140
+ try {
141
+ //console.log("settingsSelected");
142
+ onOpen();
143
+ } catch (e) {
144
+ console.error(e);
145
+ }
146
+ };
147
+
148
+ const setContextWallet = async function (wallet: string) {
149
+ try {
150
+ //console.log("setContextWallet: ", wallet);
151
+ // eslint-disable-next-line no-console
152
+ //console.log("wallets: ", app.wallets);
153
+ const matchedWallet = app.wallets.find(
154
+ (w: { type: string }) => w.type === wallet
155
+ );
156
+ //console.log("matchedWallet: ", matchedWallet);
157
+ if (matchedWallet) {
158
+ setWalletType(matchedWallet.type);
159
+ const context = await app.setContext(matchedWallet.wallet);
160
+ //console.log("result change: ", context);
161
+ //console.log("app.context: ", app.context);
162
+ setContext(app.context);
163
+ //console.log(
164
+ // "app.pubkeyContext: ",
165
+ // app.pubkeyContext.master || app.pubkeyContext.pubkey
166
+ // );
167
+ const pubkeyContext =
168
+ app.pubkeyContext.master || app.pubkeyContext.pubkey;
169
+ setPubkeyContext(pubkeyContext);
170
+ dispatch({ type: "SET_CONTEXT", payload: app.context });
171
+ dispatch({ type: "SET_PUBKEY_CONTEXT", payload: app.pubkeyContext });
172
+ // dispatch({ type: "SET_WALLET", payload: wallet });
173
+ } else {
174
+ //console.log("No wallet matched the type of the context");
175
+ }
176
+ } catch (e) {
177
+ console.error("header e: ", e);
178
+ }
179
+ };
180
+
181
+ const setUser = async function () {
182
+ try {
183
+ if (app && app.wallets) {
184
+ const {
185
+ wallets,
186
+ balances,
187
+ pubkeys,
188
+ pubkeyContext,
189
+ assetContext,
190
+ blockchainContext,
191
+ } = app;
192
+ // eslint-disable-next-line no-console
193
+ //console.log("wallets: ", wallets);
194
+ //console.log(
195
+ // "pubkeyContext: ",
196
+ // pubkeyContext?.master || pubkeyContext?.pubkey
197
+ // );
198
+ //console.log("blockchainContext: ", blockchainContext);
199
+ setAssetContext(assetContext);
200
+ setBlockchainContext(blockchainContext);
201
+ if (pubkeyContext?.master || pubkeyContext?.pubkey)
202
+ setPubkeyContext(pubkeyContext?.master || pubkeyContext?.pubkey);
203
+
204
+ for (let i = 0; i < wallets.length; i++) {
205
+ const wallet = wallets[i];
206
+ //console.log("wallet: ", wallet);
207
+ if (wallet.type === "keepkey") {
208
+ wallet.icon = KeepKeyIcon;
209
+ }
210
+ if (wallet.type === "metamask") {
211
+ setMetamaskPaired(true);
212
+ }
213
+ if (wallet.type === "keepkey") {
214
+ setKeepkeyPaired(true);
215
+ }
216
+ if (wallet.type === "native") {
217
+ setNativePaired(true);
218
+ }
219
+ wallet.paired = true;
220
+ wallets[i] = wallet;
221
+ }
222
+ // eslint-disable-next-line no-console
223
+ //console.log("wallets: ", wallets);
224
+ if (balances) {
225
+ setBalances(balances);
226
+ }
227
+
228
+ // @ts-ignore
229
+ window.ethereum.on("accountsChanged", async function (accounts: any) {
230
+ // Time to reload your interface with accounts[0]!
231
+ // //console.log('accountsChanged: ', accounts);
232
+ // TODO register new pubkeys
233
+ const walletsPaired = app.wallets;
234
+ //console.log("walletsPaired: ", walletsPaired);
235
+ //console.log("pioneer context: ", app?.context);
236
+ //if context is metamask
237
+ if (app?.context === "metamask.wallet") {
238
+ //console.log("MetaMask is in context");
239
+ const addressMetaMask = accounts[0];
240
+ //console.log("addressMetaMask: ", addressMetaMask);
241
+ setPubkeyContext(addressMetaMask);
242
+ if (addressMetaMask !== app.pubkey) {
243
+ //push event
244
+ const pubkeyContext = app.pubkeyContext;
245
+ pubkeyContext.pubkey = addressMetaMask;
246
+ pubkeyContext.master = addressMetaMask;
247
+ pubkeyContext.address = addressMetaMask;
248
+ dispatch({ type: "SET_PUBKEY_CONTEXT", payload: pubkeyContext });
249
+ }
250
+ }
251
+ //if address[0] !== pubkey
252
+
253
+ // re-register metamask with more pubkeys
254
+ });
255
+ }
256
+ } catch (e) {
257
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
258
+ // @ts-ignore
259
+ // eslint-disable-next-line no-console
260
+ console.error("header e: ", e);
261
+ // setKeepKeyError("Bridge is offline!");
262
+ }
263
+ };
264
+
265
+ useEffect(() => {
266
+ setUser();
267
+ }, [
268
+ status,
269
+ app,
270
+ app?.wallets,
271
+ app?.context,
272
+ app?.assetContext,
273
+ app?.blockchainConext,
274
+ app?.pubkeyContext,
275
+ ]);
276
+
277
+ useEffect(() => {
278
+ dispatch({ type: "SET_CONTEXT", payload: context });
279
+ setContext(app?.context);
280
+ }, [app?.context]); // once on startup
281
+
282
+ useEffect(() => {
283
+ dispatch({ type: "SET_ASSET_CONTEXT", payload: app?.assetContext });
284
+ setAssetContext(app?.assetContext?.symbol);
285
+ //console.log(app?.assetContext);
286
+ }, [app?.assetContext?.name]); // once on startup
287
+
288
+ useEffect(() => {
289
+ dispatch({
290
+ type: "SET_BLOCKCHAIN_CONTEXT",
291
+ payload: app?.blockchainContext,
292
+ });
293
+ setBlockchainContext(app?.blockchainContext?.name);
294
+ //console.log(app?.blockchainContext);
295
+ }, [app?.blockchainContext?.name]); // once on startup
296
+
297
+ useEffect(() => {
298
+ dispatch({ type: "SET_PUBKEYS_CONTEXT", payload: app?.pubkeyContext });
299
+ setPubkeyContext(app?.pubkeyContext?.master || app?.pubkeyContext?.pubkey);
300
+ }, [app?.pubkeyContext?.pubkey]); // once on startup
301
+
302
+ const avatarContent = api ? (
303
+ getWalletBadgeContent(walletType)
304
+ ) : (
305
+ <AvatarBadge boxSize="1em" bg="red.500">
306
+ <CircularProgress isIndeterminate size="1em" color="white" />
307
+ </AvatarBadge>
308
+ );
309
+
310
+ // @ts-ignore
311
+ // @ts-ignore
312
+ return (
313
+ <Menu>
314
+ <MenuButton
315
+ as={Button}
316
+ rounded="full"
317
+ variant="link"
318
+ cursor="pointer"
319
+ minW={100}
320
+ >
321
+ <Avatar size="lg">
322
+ {isPioneer ? (
323
+ <Avatar size="lg" src={pioneerImage}>
324
+ {avatarContent}
325
+ </Avatar>
326
+ ) : (
327
+ <Avatar size="lg" src={PIONEER_ICON}>
328
+ {avatarContent}
329
+ </Avatar>
330
+ )}
331
+ </Avatar>
332
+ </MenuButton>
333
+ <MenuList>
334
+ <Box borderBottomWidth="1px" p="4">
335
+ <HStack justifyContent="space-between">
336
+ <Button
337
+ leftIcon={
338
+ <Avatar size="xs" src={getWalletSettingsContent(walletType)}>
339
+ <AvatarBadge boxSize="0.75em" bg="green.500" />
340
+ </Avatar>
341
+ }
342
+ >
343
+ <small>
344
+ <MiddleEllipsis text={context} />
345
+ </small>
346
+ </Button>
347
+ <IconButton
348
+ icon={<FaCog />}
349
+ isRound
350
+ onClick={() => settingsSelected()}
351
+ aria-label="Settings"
352
+ />
353
+ <SettingsModal isOpen={isOpen} onClose={onClose} />
354
+ </HStack>
355
+ </Box>
356
+ <Box
357
+ borderWidth="1px"
358
+ borderRadius="md"
359
+ p="4"
360
+ textAlign="left"
361
+ maxWidth="300px"
362
+ width="100%"
363
+ >
364
+ <div>
365
+ <Flex alignItems="center">
366
+ <small>status: {status}</small>
367
+ </Flex>
368
+ <Card
369
+ p={2}
370
+ borderRadius="md"
371
+ boxShadow="sm"
372
+ mb={2}
373
+ className="caip"
374
+ >
375
+ <Flex justifyContent="space-between" alignItems="center">
376
+ <Flex alignItems="center">
377
+ <Avatar size="md" src={app?.assetContext?.image} mr={2} />
378
+ <Box fontSize="sm" fontWeight="bold">
379
+ Asset:
380
+ </Box>
381
+ </Flex>
382
+ <Box fontSize="sm" textAlign="right">
383
+ {app?.assetContext?.symbol}
384
+ </Box>
385
+ </Flex>
386
+ <Flex justifyContent="space-between">
387
+ <Box fontSize="xs"></Box>
388
+ <Box fontSize="xs" textAlign="right">
389
+ caip:
390
+ <MiddleEllipsis text={app?.assetContext?.caip} />
391
+ </Box>
392
+ </Flex>
393
+ </Card>
394
+
395
+ {/* Blockchain Card */}
396
+ <Card
397
+ p={2}
398
+ borderRadius="md"
399
+ boxShadow="sm"
400
+ mb={2}
401
+ className="caip"
402
+ >
403
+ <Flex justifyContent="space-between" alignItems="center">
404
+ <Flex alignItems="center">
405
+ <Avatar
406
+ size="md"
407
+ src={app?.blockchainContext?.image}
408
+ mr={2}
409
+ />
410
+ <Box fontSize="sm" fontWeight="bold">
411
+ Blockchain:
412
+ </Box>
413
+ </Flex>
414
+ <Box fontSize="sm" textAlign="right">
415
+ {app?.blockchainContext?.name}
416
+ </Box>
417
+ </Flex>
418
+ <Flex justifyContent="space-between">
419
+ <Box fontSize="xs"></Box>
420
+ <Box fontSize="xs" textAlign="right">
421
+ caip:
422
+ <MiddleEllipsis text={app?.blockchainContext?.caip} />
423
+ </Box>
424
+ </Flex>
425
+ </Card>
426
+
427
+ {/* Pubkey Card */}
428
+ <Card p={2} borderRadius="md" boxShadow="sm" className="caip">
429
+ <Flex justifyContent="space-between" alignItems="center">
430
+ <Flex alignItems="center">
431
+ {/*<Img*/}
432
+ {/* src={[app?.pubkeyContext?.walletImage]}*/}
433
+ {/* //@ts-ignore*/}
434
+ {/* loader={() => <Avatar size="md" src={app?.pubkeyContext?.walletImage} />} // Fixed: Make sure <Avatar /> returns an Element*/}
435
+ {/* //@ts-ignore*/}
436
+ {/* unloader={() => <Avatar size="md" src={app?.pubkeyContext?.walletImage} />} // Fixed: Make sure <Avatar /> returns an Element*/}
437
+ {/* container={(children) => (*/}
438
+ {/* <div*/}
439
+ {/* style={{*/}
440
+ {/* width: "32px",*/}
441
+ {/* height: "32px",*/}
442
+ {/* borderRadius: "50%",*/}
443
+ {/* overflow: "hidden",*/}
444
+ {/* }}*/}
445
+ {/* >*/}
446
+ {/* {children}*/}
447
+ {/* </div>*/}
448
+ {/* )}*/}
449
+ {/*/>*/}
450
+ <Box fontSize="sm" fontWeight="bold">
451
+ Pubkey Path:
452
+ </Box>
453
+ </Flex>
454
+ <Box fontSize="sm" textAlign="right">
455
+ <MiddleEllipsis text={app?.pubkeyContext?.path} />
456
+ </Box>
457
+ </Flex>
458
+ <Flex justifyContent="space-between">
459
+ <Box fontSize="xs">Pubkey:</Box>
460
+ <Box fontSize="xs" textAlign="right">
461
+ <MiddleEllipsis text={app?.pubkeyContext?.pubkey} />
462
+ </Box>
463
+ </Flex>
464
+ </Card>
465
+ </div>
466
+ </Box>
467
+
468
+ <MenuItem>
469
+ <SimpleGrid columns={3} row={1}>
470
+ <Card align="center" onClick={() => setContextWallet("native")}>
471
+ <CardBody>
472
+ <Avatar src={PIONEER_ICON}>
473
+ {nativePaired ? (
474
+ <div>
475
+ <AvatarBadge boxSize="1.25em" bg="green.500" />
476
+ </div>
477
+ ) : (
478
+ <div>
479
+ <AvatarBadge boxSize="1.25em" bg="red.500" />
480
+ </div>
481
+ )}
482
+ </Avatar>
483
+ </CardBody>
484
+ <small>Pioneer</small>
485
+ </Card>
486
+ <Card align="center" onClick={() => setContextWallet("metamask")}>
487
+ <CardBody>
488
+ <Avatar src={METAMASK_ICON}>
489
+ {metamaskPaired ? (
490
+ <div>
491
+ <AvatarBadge boxSize="1.25em" bg="green.500" />
492
+ </div>
493
+ ) : (
494
+ <div>
495
+ <AvatarBadge boxSize="1.25em" bg="red.500" />
496
+ </div>
497
+ )}
498
+ </Avatar>
499
+ </CardBody>
500
+ <small>MetaMask</small>
501
+ </Card>
502
+ <Card align="center" onClick={() => setContextWallet("keepkey")}>
503
+ <CardBody>
504
+ <Avatar src={KEEPKEY_ICON}>
505
+ {keepkeyPaired ? (
506
+ <div>
507
+ <AvatarBadge boxSize="1.25em" bg="green.500" />
508
+ </div>
509
+ ) : (
510
+ <div>
511
+ <AvatarBadge boxSize="1.25em" bg="red.500" />
512
+ </div>
513
+ )}
514
+ </Avatar>
515
+ </CardBody>
516
+ <small>KeepKey</small>
517
+ </Card>
518
+ </SimpleGrid>
519
+ </MenuItem>
520
+ </MenuList>
521
+ </Menu>
522
+ );
523
+ };
524
+
525
+ export default Pioneer;
@@ -0,0 +1,47 @@
1
+ // If you defined MiddleEllipsisProps, make sure to export it
2
+ export interface MiddleEllipsisProps {
3
+ text: string;
4
+ // ... other properties if they exist
5
+ }
6
+
7
+ // Existing code with exported interface
8
+ export const checkKeepkeyAvailability = async () => {
9
+ try {
10
+ const response = await fetch("http://localhost:1646/spec/swagger.json");
11
+ if (response.status === 200) {
12
+ return true;
13
+ }
14
+ } catch (error) {
15
+ console.error(error);
16
+ return false;
17
+ }
18
+ return false;
19
+ };
20
+
21
+ export const timeout = (ms: number | undefined): Promise<void> => {
22
+ return new Promise((resolve, reject) => {
23
+ setTimeout(() => {
24
+ reject(new Error("Timeout"));
25
+ }, ms);
26
+ });
27
+ };
28
+
29
+ export const MiddleEllipsis: React.FC<MiddleEllipsisProps> = ({ text }) => {
30
+ const maxLength = 20;
31
+ const ellipsis = "...";
32
+
33
+ if (!text || text.length <= maxLength) {
34
+ return <span>{text}</span>;
35
+ }
36
+
37
+ const frontPart = text.slice(0, 7);
38
+ const backPart = text.slice(-10);
39
+
40
+ return (
41
+ <span>
42
+ {frontPart}
43
+ {ellipsis}
44
+ {backPart}
45
+ </span>
46
+ );
47
+ };