@rango-dev/widget-embedded 0.12.1-next.30 → 0.12.1-next.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 (69) hide show
  1. package/dist/Widget.d.ts.map +1 -1
  2. package/dist/components/AppRouter.d.ts +2 -0
  3. package/dist/components/AppRouter.d.ts.map +1 -1
  4. package/dist/components/AppRoutes.d.ts.map +1 -1
  5. package/dist/components/BlockchainsSection/BlockchainsSection.d.ts.map +1 -1
  6. package/dist/components/TokenList/TokenList.d.ts.map +1 -1
  7. package/dist/components/TokenList/TokenList.helpers.d.ts.map +1 -1
  8. package/dist/components/TokenList/TokenList.types.d.ts +0 -1
  9. package/dist/components/TokenList/TokenList.types.d.ts.map +1 -1
  10. package/dist/components/UpdateUrl.d.ts +6 -1
  11. package/dist/components/UpdateUrl.d.ts.map +1 -1
  12. package/dist/constants.d.ts +2 -0
  13. package/dist/constants.d.ts.map +1 -0
  14. package/dist/hooks/usePrepareBlockchainList.d.ts +18 -0
  15. package/dist/hooks/usePrepareBlockchainList.d.ts.map +1 -0
  16. package/dist/hooks/useSyncStoresWithConfig.d.ts +3 -0
  17. package/dist/hooks/useSyncStoresWithConfig.d.ts.map +1 -0
  18. package/dist/hooks/useWalletProviders.d.ts +3 -3
  19. package/dist/hooks/useWalletProviders.d.ts.map +1 -1
  20. package/dist/index.js +1 -1
  21. package/dist/index.js.map +4 -4
  22. package/dist/pages/SelectBlockchainPage.d.ts +1 -2
  23. package/dist/pages/SelectBlockchainPage.d.ts.map +1 -1
  24. package/dist/pages/SelectSwapItemsPage.d.ts +1 -5
  25. package/dist/pages/SelectSwapItemsPage.d.ts.map +1 -1
  26. package/dist/services/httpService.d.ts +0 -1
  27. package/dist/services/httpService.d.ts.map +1 -1
  28. package/dist/store/app.d.ts +26 -0
  29. package/dist/store/app.d.ts.map +1 -0
  30. package/dist/store/bestRoute.d.ts +4 -8
  31. package/dist/store/bestRoute.d.ts.map +1 -1
  32. package/dist/store/meta.d.ts +0 -2
  33. package/dist/store/meta.d.ts.map +1 -1
  34. package/dist/store/slices/config.d.ts +8 -0
  35. package/dist/store/slices/config.d.ts.map +1 -0
  36. package/dist/store/slices/data.d.ts +26 -0
  37. package/dist/store/slices/data.d.ts.map +1 -0
  38. package/dist/store/wallets.d.ts.map +1 -1
  39. package/dist/utils/configs.d.ts +3 -0
  40. package/dist/utils/configs.d.ts.map +1 -1
  41. package/dist/utils/wallets.d.ts +1 -1
  42. package/dist/utils/wallets.d.ts.map +1 -1
  43. package/package.json +2 -2
  44. package/src/Widget.tsx +11 -62
  45. package/src/components/AppRouter.tsx +3 -1
  46. package/src/components/AppRoutes.tsx +4 -28
  47. package/src/components/BlockchainsSection/BlockchainsSection.tsx +19 -41
  48. package/src/components/TokenList/TokenList.helpers.ts +6 -8
  49. package/src/components/TokenList/TokenList.tsx +24 -20
  50. package/src/components/TokenList/TokenList.types.ts +0 -1
  51. package/src/components/UpdateUrl.tsx +7 -1
  52. package/src/constants.ts +1 -0
  53. package/src/hooks/usePrepareBlockchainList.ts +125 -0
  54. package/src/hooks/useSyncStoresWithConfig.ts +102 -0
  55. package/src/hooks/useWalletProviders.ts +7 -7
  56. package/src/pages/SelectBlockchainPage.tsx +18 -23
  57. package/src/pages/SelectSwapItemsPage.tsx +52 -90
  58. package/src/services/httpService.ts +4 -5
  59. package/src/store/app.ts +15 -0
  60. package/src/store/bestRoute.ts +45 -71
  61. package/src/store/meta.ts +11 -29
  62. package/src/store/slices/config.ts +26 -0
  63. package/src/store/slices/data.ts +203 -0
  64. package/src/store/wallets.ts +0 -27
  65. package/src/utils/configs.ts +5 -2
  66. package/src/utils/wallets.ts +38 -18
  67. package/dist/components/BlockchainsSection/BlockchainSection.helpers.d.ts +0 -3
  68. package/dist/components/BlockchainsSection/BlockchainSection.helpers.d.ts.map +0 -1
  69. package/src/components/BlockchainsSection/BlockchainSection.helpers.ts +0 -20
@@ -21,6 +21,7 @@ import {
21
21
  } from '@rango-dev/ui';
22
22
  import React, { forwardRef, useEffect, useState } from 'react';
23
23
 
24
+ import { useAppStore } from '../../store/app';
24
25
  import { useMetaStore } from '../../store/meta';
25
26
  import { useWalletsStore } from '../../store/wallets';
26
27
  import { generateRangeColors } from '../../utils/common';
@@ -90,6 +91,7 @@ export function TokenList(props: PropTypes) {
90
91
  const [hasNextPage, setHasNextPage] = useState<boolean>(true);
91
92
  const loadingWallet = useWalletsStore.use.loading();
92
93
  const { blockchains } = useMetaStore.use.meta();
94
+ const { isTokenPinned } = useAppStore();
93
95
 
94
96
  // eslint-disable-next-line react/display-name
95
97
  const innerElementType: React.FC<CommonProps> = forwardRef((render, ref) => {
@@ -132,27 +134,29 @@ export function TokenList(props: PropTypes) {
132
134
  return (
133
135
  <VirtualizedList
134
136
  Item={({ index, style }) => {
135
- const address = tokens[index].address || '';
137
+ const token = tokens[index];
138
+
139
+ const address = token.address || '';
136
140
  const blockchain = blockchains.find(
137
- (blockchain) => blockchain.name === tokens[index].blockchain
141
+ (blockchain) => blockchain.name === token.blockchain
138
142
  );
139
143
  const color = generateRangeColors(
140
- tokens[index].symbol,
144
+ token.symbol,
141
145
  blockchain?.color || ''
142
146
  );
143
147
 
144
148
  const customCssForTag = {
145
- $$color: color[`${tokens[index].symbol}100`],
149
+ $$color: color[`${token.symbol}100`],
146
150
  [`.${darkTheme} &`]: {
147
- $$color: color[`${tokens[index].symbol}900`],
151
+ $$color: color[`${token.symbol}900`],
148
152
  },
149
153
  backgroundColor: '$$color',
150
154
  };
151
155
 
152
156
  const customCssForTagTitle = {
153
- $$color: color[`${tokens[index].symbol}700`],
157
+ $$color: color[`${token.symbol}700`],
154
158
  [`.${darkTheme} &`]: {
155
- $$color: color[`${tokens[index].symbol}100`],
159
+ $$color: color[`${token.symbol}100`],
156
160
  },
157
161
  color: '$$color',
158
162
  };
@@ -168,14 +172,14 @@ export function TokenList(props: PropTypes) {
168
172
  height: style?.height,
169
173
  }}
170
174
  tab-index={index}
171
- key={`${tokens[index].symbol}${tokens[index].address}`}
172
- id={`${tokens[index].symbol}${tokens[index].address}`}
175
+ key={`${token.symbol}${token.address}`}
176
+ id={`${token.symbol}${token.address}`}
173
177
  hasDivider
174
178
  onClick={() => onChange(tokens[index])}
175
179
  start={
176
180
  <ImageSection>
177
- <Image src={tokens[index].image} size={30} />
178
- {tokens[index].pin && (
181
+ <Image src={token.image} size={30} />
182
+ {isTokenPinned(token) && (
179
183
  <Pin>
180
184
  <PinIcon size={12} color="gray" />
181
185
  </Pin>
@@ -184,11 +188,11 @@ export function TokenList(props: PropTypes) {
184
188
  }
185
189
  title={
186
190
  blockchain?.type === 'COSMOS' ||
187
- !!tokens[index].name ||
188
- (!tokens[index].name && !address) ? (
191
+ !!token.name ||
192
+ (!token.name && !address) ? (
189
193
  <Title>
190
194
  <Typography variant="title" size="xmedium">
191
- {tokens[index].symbol}
195
+ {token.symbol}
192
196
  </Typography>
193
197
  <Divider direction="horizontal" size={4} />
194
198
  <Tag css={customCssForTag}>
@@ -196,7 +200,7 @@ export function TokenList(props: PropTypes) {
196
200
  variant="body"
197
201
  size="xsmall"
198
202
  css={customCssForTagTitle}>
199
- {tokens[index].blockchain}
203
+ {token.blockchain}
200
204
  </TagTitle>
201
205
  </Tag>
202
206
  </Title>
@@ -211,12 +215,12 @@ export function TokenList(props: PropTypes) {
211
215
  token: tokens[index],
212
216
  customCssForTag,
213
217
  customCssForTagTitle,
214
- name: tokens[index].name,
218
+ name: token.name,
215
219
  url: blockchain.info.addressUrl
216
220
  .split('{wallet}')
217
221
  .join(address),
218
222
  })
219
- : tokens[index].name || undefined
223
+ : token.name || undefined
220
224
  }
221
225
  end={
222
226
  loadingWallet ? (
@@ -229,15 +233,15 @@ export function TokenList(props: PropTypes) {
229
233
  tokens[index]?.balance && (
230
234
  <BalanceContainer>
231
235
  <Typography variant="title" size="small">
232
- {tokens[index].balance?.amount}
236
+ {token.balance?.amount}
233
237
  </Typography>
234
238
  <div />
235
- {tokens[index].balance?.usdValue && (
239
+ {token.balance?.usdValue && (
236
240
  <Typography
237
241
  variant="body"
238
242
  color="neutral800"
239
243
  size="xsmall">
240
- {`$${tokens[index].balance?.usdValue}`}
244
+ {`$${token.balance?.usdValue}`}
241
245
  </Typography>
242
246
  )}
243
247
  </BalanceContainer>
@@ -5,7 +5,6 @@ export interface TokenWithBalance extends Token {
5
5
  amount: string;
6
6
  usdValue: string;
7
7
  };
8
- pin?: boolean;
9
8
  }
10
9
 
11
10
  export interface PropTypes {
@@ -1,3 +1,5 @@
1
+ import type { WidgetConfig } from '../types';
2
+
1
3
  import { useEffect, useRef } from 'react';
2
4
  import {
3
5
  createSearchParams,
@@ -7,12 +9,15 @@ import {
7
9
 
8
10
  import { navigationRoutes } from '../constants/navigationRoutes';
9
11
  import { SearchParams } from '../constants/searchParams';
12
+ import { useSyncStoresWithConfig } from '../hooks/useSyncStoresWithConfig';
10
13
  import { useBestRouteStore } from '../store/bestRoute';
11
14
  import { useMetaStore } from '../store/meta';
12
15
  import { useUiStore } from '../store/ui';
13
16
  import { searchParamsToToken } from '../utils/routing';
14
17
 
15
- export function UpdateUrl() {
18
+ type Props = { config: WidgetConfig | undefined };
19
+
20
+ export function UpdateUrl(props: Props) {
16
21
  const firstRender = useRef(true);
17
22
  const [searchParams, setSearchParams] = useSearchParams();
18
23
  const location = useLocation();
@@ -31,6 +36,7 @@ export function UpdateUrl() {
31
36
  const loadingStatus = useMetaStore.use.loadingStatus();
32
37
  const { blockchains, tokens } = useMetaStore.use.meta();
33
38
  const setSelectedSwap = useUiStore.use.setSelectedSwap();
39
+ useSyncStoresWithConfig(props.config);
34
40
 
35
41
  useEffect(() => {
36
42
  const params: Record<string, string> = {};
@@ -0,0 +1 @@
1
+ export const RANGO_PUBLIC_API_KEY = 'c6381a79-2817-4602-83bf-6a641a409e32';
@@ -0,0 +1,125 @@
1
+ import type { BlockchainMeta } from 'rango-sdk';
2
+
3
+ import { useMemo, useRef } from 'react';
4
+
5
+ interface PrepareListOptions {
6
+ limit?: number;
7
+ selected?: string;
8
+ }
9
+
10
+ interface PrepareListOutput {
11
+ list: BlockchainMeta[];
12
+ more: BlockchainMeta[];
13
+ }
14
+
15
+ /**
16
+ *
17
+ * UI needs some specific logics like limiting the list and sorting,
18
+ * this function is getting the raw blockchains list and return a list for showing in UI.
19
+ *
20
+ */
21
+ export function usePrepareBlockchainList(
22
+ blockchains: BlockchainMeta[],
23
+ options?: PrepareListOptions
24
+ ): PrepareListOutput {
25
+ const prevSelectedBlockchain = useRef({ index: -1, name: '' });
26
+
27
+ blockchains.sort(sortByMostUsedBlockchains);
28
+
29
+ const blockchainsHash = blockchains
30
+ .map((blockchain) => blockchain.name)
31
+ .join('-');
32
+
33
+ return useMemo(() => {
34
+ const list: BlockchainMeta[] = blockchains;
35
+ let more: BlockchainMeta[] = [];
36
+
37
+ // Checking `limit` has set and it should be more than of the list items.
38
+ if (options?.limit && blockchains.length > options.limit) {
39
+ const start = options.limit;
40
+ /** Try find the blockchain and returns the index. */
41
+ const selectedIndex = options.selected
42
+ ? blockchains.findIndex(
43
+ (blockchains) => blockchains.name === options.selected
44
+ )
45
+ : -1;
46
+
47
+ const prevSelectedBlockchainWasInMoreSection =
48
+ prevSelectedBlockchain.current.index > options.limit - 1 &&
49
+ !!blockchains.find(
50
+ (blockchains) =>
51
+ blockchains.name === prevSelectedBlockchain.current.name
52
+ );
53
+
54
+ /*
55
+ * If the selected blockchain is in `more` section, we should move it to front of the list
56
+ */
57
+ if (
58
+ options.selected &&
59
+ ((prevSelectedBlockchainWasInMoreSection &&
60
+ selectedIndex < options.limit - 1) ||
61
+ selectedIndex > options.limit - 1)
62
+ ) {
63
+ blockchains.sort(
64
+ generateSortBySelectedFor(
65
+ prevSelectedBlockchainWasInMoreSection
66
+ ? prevSelectedBlockchain.current.name
67
+ : options.selected
68
+ )
69
+ );
70
+ }
71
+
72
+ /*
73
+ * Splice will modify the original list and returns the deleted items
74
+ * We use the deleted items as `more`
75
+ */
76
+ more = list.splice(start);
77
+ prevSelectedBlockchain.current = {
78
+ index: selectedIndex,
79
+ name: options.selected ?? '',
80
+ };
81
+ }
82
+
83
+ return {
84
+ list,
85
+ more,
86
+ };
87
+ }, [blockchainsHash]);
88
+ }
89
+
90
+ function generateSortBySelectedFor(selected: string) {
91
+ /** Move `selected` blockchain to the front of list. */
92
+ return function sortBySelected(a: BlockchainMeta, b: BlockchainMeta) {
93
+ if (a.name === selected) {
94
+ return -1;
95
+ }
96
+ if (b.name === selected) {
97
+ return 1;
98
+ }
99
+
100
+ return 0;
101
+ };
102
+ }
103
+
104
+ /** There is a hardcoded list of blockchains that we want to show them first in the list. */
105
+ function sortByMostUsedBlockchains(a: BlockchainMeta, b: BlockchainMeta) {
106
+ const mostUsed = ['ETH', 'COSMOS', 'OSMOSIS'];
107
+ const aIndexInMostUsed = mostUsed.findIndex((token) => token === a.name);
108
+ const bIndexInMostUsed = mostUsed.findIndex((token) => token === b.name);
109
+ const aIsMostUsed = aIndexInMostUsed > -1;
110
+ const bIsMostUsed = bIndexInMostUsed > -1;
111
+
112
+ if (aIsMostUsed && bIsMostUsed) {
113
+ return aIndexInMostUsed > bIndexInMostUsed ? 1 : -1;
114
+ }
115
+
116
+ if (aIsMostUsed) {
117
+ return -1;
118
+ }
119
+
120
+ if (bIsMostUsed) {
121
+ return 1;
122
+ }
123
+
124
+ return 0;
125
+ }
@@ -0,0 +1,102 @@
1
+ import type { WidgetConfig } from '../types';
2
+ import type { Asset } from 'rango-sdk';
3
+
4
+ import { useEffect, useRef } from 'react';
5
+
6
+ import { useBestRouteStore } from '../store/bestRoute';
7
+ import { useMetaStore } from '../store/meta';
8
+ import { useSettingsStore } from '../store/settings';
9
+ import { tokensAreEqual } from '../utils/wallets';
10
+
11
+ export function useSyncStoresWithConfig(config: WidgetConfig | undefined) {
12
+ const {
13
+ setInputAmount,
14
+ setToToken,
15
+ setToBlockchain,
16
+ setFromBlockchain,
17
+ setFromToken,
18
+ } = useBestRouteStore();
19
+
20
+ const {
21
+ meta: { tokens, blockchains },
22
+ loadingStatus: loadingMetaStatus,
23
+ } = useMetaStore();
24
+
25
+ const { setAffiliateRef, setAffiliatePercent, setAffiliateWallets } =
26
+ useSettingsStore();
27
+
28
+ const prevConfigFromToken = useRef<Asset | undefined>(undefined);
29
+ const prevConfigToToken = useRef<Asset | undefined>(undefined);
30
+ const prevConfigFromBlockchain = useRef<string | undefined>(undefined);
31
+ const prevConfigToBlockchain = useRef<string | undefined>(undefined);
32
+
33
+ useEffect(() => {
34
+ setInputAmount(config?.amount?.toString() || '');
35
+ }, [config?.amount]);
36
+
37
+ useEffect(() => {
38
+ if (loadingMetaStatus === 'success') {
39
+ const chain = blockchains.find(
40
+ (chain) => chain.name === config?.from?.blockchain
41
+ );
42
+ const token = tokens.find((t) =>
43
+ tokensAreEqual(t, config?.from?.token || null)
44
+ );
45
+
46
+ if (chain || (!chain && prevConfigFromBlockchain.current)) {
47
+ setFromBlockchain(chain ?? null);
48
+ }
49
+
50
+ if (token || (!token && prevConfigFromToken.current)) {
51
+ setFromToken(token ?? null);
52
+ }
53
+
54
+ prevConfigFromBlockchain.current = config?.from?.blockchain;
55
+ prevConfigFromToken.current = config?.from?.token;
56
+ }
57
+ }, [
58
+ config?.from?.token?.symbol,
59
+ config?.from?.token?.address,
60
+ config?.from?.blockchain,
61
+ config?.from?.blockchain,
62
+ loadingMetaStatus,
63
+ ]);
64
+
65
+ useEffect(() => {
66
+ if (loadingMetaStatus === 'success') {
67
+ const chain = blockchains.find(
68
+ (chain) => chain.name === config?.to?.blockchain
69
+ );
70
+ const token = tokens.find((t) =>
71
+ tokensAreEqual(t, config?.to?.token || null)
72
+ );
73
+
74
+ if (chain || (!chain && prevConfigToBlockchain.current)) {
75
+ setToBlockchain(chain ?? null);
76
+ }
77
+
78
+ if (token || (!token && prevConfigToToken.current)) {
79
+ setToToken(token ?? null);
80
+ }
81
+
82
+ prevConfigToBlockchain.current = config?.to?.blockchain;
83
+ prevConfigToToken.current = config?.to?.token;
84
+ }
85
+ }, [
86
+ config?.to?.token?.symbol,
87
+ config?.to?.token?.address,
88
+ config?.to?.token?.blockchain,
89
+ config?.to?.blockchain,
90
+ loadingMetaStatus,
91
+ ]);
92
+
93
+ useEffect(() => {
94
+ setAffiliateRef(config?.affiliate?.ref ?? null);
95
+ setAffiliatePercent(config?.affiliate?.percent ?? null);
96
+ setAffiliateWallets(config?.affiliate?.wallets ?? null);
97
+ }, [
98
+ config?.affiliate?.ref,
99
+ config?.affiliate?.percent,
100
+ config?.affiliate?.wallets,
101
+ ]);
102
+ }
@@ -1,11 +1,11 @@
1
- import { ProviderInterface } from '@rango-dev/wallets-react';
1
+ import type { WidgetConfig } from '../types';
2
+ import type { ProvidersOptions } from '../utils/providers';
3
+ import type { ProviderInterface } from '@rango-dev/wallets-react';
4
+
2
5
  import { useEffect } from 'react';
6
+
3
7
  import { useWalletsStore } from '../store/wallets';
4
- import { WidgetConfig } from '../types';
5
- import {
6
- matchAndGenerateProviders,
7
- ProvidersOptions,
8
- } from '../utils/providers';
8
+ import { matchAndGenerateProviders } from '../utils/providers';
9
9
 
10
10
  export function useWalletProviders(
11
11
  providers: WidgetConfig['wallets'],
@@ -22,7 +22,7 @@ export function useWalletProviders(
22
22
  generateProviders = matchAndGenerateProviders(providers, {
23
23
  walletConnectProjectId: options?.walletConnectProjectId,
24
24
  });
25
- }, [providers]);
25
+ }, [providers?.length]);
26
26
 
27
27
  return {
28
28
  providers: generateProviders,
@@ -7,47 +7,41 @@ import { Layout } from '../components/Layout';
7
7
  import { SearchInput } from '../components/SearchInput';
8
8
  import { navigationRoutes } from '../constants/navigationRoutes';
9
9
  import { useNavigateBack } from '../hooks/useNavigateBack';
10
+ import { useAppStore } from '../store/app';
10
11
  import { useBestRouteStore } from '../store/bestRoute';
11
12
  import { useMetaStore } from '../store/meta';
12
13
 
13
14
  interface PropTypes {
14
- type: 'from' | 'to';
15
- supportedBlockchains?: string[];
15
+ type: 'source' | 'destination';
16
16
  }
17
17
 
18
18
  export function SelectBlockchainPage(props: PropTypes) {
19
- const { type, supportedBlockchains } = props;
19
+ const { type } = props;
20
20
  const { navigateBackFrom } = useNavigateBack();
21
21
  const [searchedFor, setSearchedFor] = useState<string>('');
22
22
  const [blockchainCategory, setBlockchainCategory] = useState<string>('ALL');
23
23
  const setToBlockchain = useBestRouteStore.use.setToBlockchain();
24
24
  const setFromBlockchain = useBestRouteStore.use.setFromBlockchain();
25
- const {
26
- meta: { blockchains: allBlockchains },
27
- loadingStatus,
28
- } = useMetaStore();
29
- const blockchains = supportedBlockchains
30
- ? useMetaStore.use
31
- .meta()
32
- .blockchains.filter((chain) =>
33
- supportedBlockchains.includes(chain.name)
34
- )
35
- : useMetaStore.use.meta().blockchains;
25
+ const { loadingStatus } = useMetaStore();
26
+
27
+ const blockchains = useAppStore().blockchains({
28
+ type: type,
29
+ });
30
+ const routeKey = type === 'source' ? 'fromBlockchain' : 'toBlockchain';
36
31
 
37
32
  return (
38
33
  <Layout
39
34
  header={{
40
- onBack: navigateBackFrom.bind(
41
- null,
42
- navigationRoutes[`${type}Blockchain`]
43
- ),
35
+ onBack: () => {
36
+ navigateBackFrom(navigationRoutes[routeKey]);
37
+ },
44
38
  title: i18n.t(`Select Blockchain`),
45
39
  }}>
46
40
  <Divider size={12} />
47
41
  <SelectableCategoryList
48
42
  setCategory={setBlockchainCategory}
49
43
  category={blockchainCategory}
50
- blockchains={allBlockchains}
44
+ blockchains={blockchains}
51
45
  isLoading={loadingStatus === 'loading'}
52
46
  />
53
47
  <Divider size={24} />
@@ -68,12 +62,13 @@ export function SelectBlockchainPage(props: PropTypes) {
68
62
  searchedFor={searchedFor}
69
63
  blockchainCategory={blockchainCategory}
70
64
  onChange={(blockchain) => {
71
- if (type === 'from') {
72
- setFromBlockchain(blockchain, true);
65
+ if (type === 'source') {
66
+ setFromBlockchain(blockchain);
73
67
  } else {
74
- setToBlockchain(blockchain, true);
68
+ setToBlockchain(blockchain);
75
69
  }
76
- navigateBackFrom(navigationRoutes[`${type}Blockchain`]);
70
+
71
+ navigateBackFrom(navigationRoutes[routeKey]);
77
72
  }}
78
73
  />
79
74
  </Layout>