diff --git a/apps/wallet/src/ui/app/components/explorer-link/ExplorerLinkType.ts b/apps/core/src/enums/ExplorerLinkType.ts similarity index 100% rename from apps/wallet/src/ui/app/components/explorer-link/ExplorerLinkType.ts rename to apps/core/src/enums/ExplorerLinkType.ts diff --git a/apps/core/src/enums/index.ts b/apps/core/src/enums/index.ts new file mode 100644 index 00000000000..6dcfd1bcf7b --- /dev/null +++ b/apps/core/src/enums/index.ts @@ -0,0 +1,4 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +export * from './ExplorerLinkType'; diff --git a/apps/core/src/index.ts b/apps/core/src/index.ts index bc58d29353b..5aed649aada 100644 --- a/apps/core/src/index.ts +++ b/apps/core/src/index.ts @@ -3,6 +3,7 @@ // SPDX-License-Identifier: Apache-2.0 export * from './api'; +export * from './enums'; export * from './components'; export * from './utils'; export * from './hooks'; diff --git a/apps/wallet/src/shared/api-env.ts b/apps/core/src/utils/api-env.ts similarity index 100% rename from apps/wallet/src/shared/api-env.ts rename to apps/core/src/utils/api-env.ts diff --git a/apps/core/src/utils/getExplorerLink.ts b/apps/core/src/utils/getExplorerLink.ts new file mode 100644 index 00000000000..00ccd8685f0 --- /dev/null +++ b/apps/core/src/utils/getExplorerLink.ts @@ -0,0 +1,58 @@ +// Copyright (c) Mysten Labs, Inc. +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { getCustomNetwork } from '.'; +import { getNetwork, Network, NetworkId } from '@iota/iota-sdk/client'; +import { getAddressUrl, getObjectUrl, getTransactionUrl, getValidatorUrl } from '.'; +import { ExplorerLinkType } from '../enums'; + +export type ExplorerLinkConfig = + | { + type: ExplorerLinkType.Address; + address?: string; + useActiveAddress?: false; + } + | { + type: ExplorerLinkType.Address; + useActiveAddress: true; + } + | { type: ExplorerLinkType.Object; objectID: string; moduleName?: string } + | { type: ExplorerLinkType.Transaction; transactionID: string } + | { type: ExplorerLinkType.Validator; validator: string }; + +function getAddress(linkConfig: ExplorerLinkConfig, activeAddress: string | null) { + const { type } = linkConfig; + const isAddress = type === ExplorerLinkType.Address; + const isProvidedAddress = isAddress && !linkConfig.useActiveAddress; + return isProvidedAddress ? linkConfig.address : activeAddress; +} + +export function getExplorerLink( + linkConfig: ExplorerLinkConfig, + activeAddress: string | null, + network: NetworkId, +) { + const { type } = linkConfig; + const address = getAddress(linkConfig, activeAddress); + const objectID = type === ExplorerLinkType.Object ? linkConfig.objectID : null; + const transactionID = type === ExplorerLinkType.Transaction ? linkConfig.transactionID : null; + const validator = type === ExplorerLinkType.Validator ? linkConfig.validator : null; + const moduleName = type === ExplorerLinkType.Object ? linkConfig.moduleName : null; + + // fallback to localhost if customRPC is not set + const customExplorer = + network === Network.Custom ? getCustomNetwork().explorer : getNetwork(network).explorer; + + if (!address) return null; + switch (type) { + case ExplorerLinkType.Address: + return address && getAddressUrl(address, network, customExplorer); + case ExplorerLinkType.Object: + return objectID && getObjectUrl(objectID, network, customExplorer, moduleName); + case ExplorerLinkType.Transaction: + return transactionID && getTransactionUrl(transactionID, network, customExplorer); + case ExplorerLinkType.Validator: + return validator && getValidatorUrl(validator, network, customExplorer); + } +} diff --git a/apps/core/src/utils/getExplorerPaths.ts b/apps/core/src/utils/getExplorerPaths.ts new file mode 100644 index 00000000000..37b7f97020c --- /dev/null +++ b/apps/core/src/utils/getExplorerPaths.ts @@ -0,0 +1,47 @@ +// Copyright (c) Mysten Labs, Inc. +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { getNetwork, Network, NetworkId } from '@iota/iota-sdk/client'; + +function getExplorerUrl( + path: string, + network: NetworkId, + customExplorer: string, + getUrlWithDeviceId: (url: URL) => URL = (url) => url, +) { + const networkConfig = getNetwork(network); + const explorer = network === Network.Custom ? customExplorer : networkConfig?.explorer; + + const url = getUrlWithDeviceId(new URL(path, explorer)); + if (explorer) { + url.searchParams.append('network', network); + } + + return url.href; +} + +export function getObjectUrl( + objectID: string, + network: NetworkId, + customExplorer: string, + moduleName?: string | null, +) { + return getExplorerUrl( + `/object/${objectID}${moduleName ? `?module=${moduleName}` : ''}`, + network, + customExplorer, + ); +} + +export function getTransactionUrl(txDigest: string, network: NetworkId, customExplorer: string) { + return getExplorerUrl(`/txblock/${encodeURIComponent(txDigest)}`, network, customExplorer); +} + +export function getAddressUrl(address: string, network: NetworkId, customExplorer: string) { + return getExplorerUrl(`/address/${address}`, network, customExplorer); +} + +export function getValidatorUrl(address: string, network: NetworkId, customExplorer: string) { + return getExplorerUrl(`/validator/${address}`, network, customExplorer); +} diff --git a/apps/core/src/utils/index.ts b/apps/core/src/utils/index.ts index 31dd96fa3bb..6ad8af75914 100644 --- a/apps/core/src/utils/index.ts +++ b/apps/core/src/utils/index.ts @@ -15,6 +15,9 @@ export * from './filterAndSortTokenBalances'; export * from './getOwnerDisplay'; export * from './parseAmount'; export * from './parseObjectDetails'; +export * from './api-env'; +export * from './getExplorerPaths'; +export * from './getExplorerLink'; export * from './stake'; export * from './transaction'; diff --git a/apps/wallet-dashboard/app/(protected)/assets/[objectId]/page.tsx b/apps/wallet-dashboard/app/(protected)/assets/[objectId]/page.tsx index 37ba367c08c..7f42d41f04b 100644 --- a/apps/wallet-dashboard/app/(protected)/assets/[objectId]/page.tsx +++ b/apps/wallet-dashboard/app/(protected)/assets/[objectId]/page.tsx @@ -5,7 +5,7 @@ import React, { useCallback } from 'react'; import { useParams } from 'next/navigation'; -import { AssetCard, Button, RouteLink, SendAssetPopup } from '@/components'; +import { Button, RouteLink, SendAssetPopup, VisualAssetDetailsCard } from '@/components'; import { isAssetTransferable, useGetObject } from '@iota/core'; import { usePopups } from '@/hooks'; import { useCurrentAccount } from '@iota/dapp-kit'; @@ -31,7 +31,7 @@ const VisualAssetDetailPage = () => {
{asset?.data ? ( - + ) : (
Asset not found
)} diff --git a/apps/wallet-dashboard/app/(protected)/assets/page.tsx b/apps/wallet-dashboard/app/(protected)/assets/page.tsx index db4929addcf..00fe1d57e24 100644 --- a/apps/wallet-dashboard/app/(protected)/assets/page.tsx +++ b/apps/wallet-dashboard/app/(protected)/assets/page.tsx @@ -3,16 +3,14 @@ 'use client'; -import { AssetCard, PageSizeSelector, PaginationOptions } from '@/components'; -import { ASSETS_ROUTE } from '@/lib/constants/routes.constants'; +import { PageSizeSelector, PaginationOptions } from '@/components'; import { Panel, Title, Chip, TitleSize, DropdownPosition } from '@iota/apps-ui-kit'; import { hasDisplayData, useCursorPagination, useGetOwnedObjects } from '@iota/core'; import { useCurrentAccount } from '@iota/dapp-kit'; import { IotaObjectData } from '@iota/iota-sdk/client'; import { useState } from 'react'; import { AssetCategory } from '@/lib/enums'; -import { VisibilityOff } from '@iota/ui-icons'; -import { useRouter } from 'next/navigation'; +import { AssetList } from '@/components/AssetsList'; const PAGINATION_RANGE = [20, 40, 60]; @@ -30,7 +28,6 @@ const ASSET_CATEGORIES: { label: string; value: AssetCategory }[] = [ export default function AssetsDashboardPage(): React.JSX.Element { const [selectedCategory, setSelectedCategory] = useState(AssetCategory.Visual); const [limit, setLimit] = useState(PAGINATION_RANGE[1]); - const router = useRouter(); const account = useCurrentAccount(); const ownedObjectsQuery = useGetOwnedObjects(account?.address, undefined, limit); @@ -80,19 +77,7 @@ export default function AssetsDashboardPage(): React.JSX.Element { ))}
-
- {assetList.map((asset) => ( -
- } - onClick={() => - router.push(ASSETS_ROUTE.path + `/${asset.objectId}`) - } - /> -
- ))} -
+
{ - const params = useParams(); - const objectId = params.objectId as string; - const { data: asset } = useGetObject(objectId); - const activeAccount = useCurrentAccount(); - - const { openPopup, closePopup } = usePopups(); - - const showSendAssetPopup = useCallback(() => { - if (asset?.data) { - openPopup(); - } - }, [asset, openPopup, closePopup]); - - const assetIsTransferable = asset?.data ? isAssetTransferable(asset?.data) : false; - - return ( -
- - {asset?.data ? ( - - ) : ( -
Asset not found
- )} - {assetIsTransferable && activeAccount ? ( - - ) : null} -
- ); -}; - -export default VisualAssetDetailPage; diff --git a/apps/wallet-dashboard/components/AssetsList.tsx b/apps/wallet-dashboard/components/AssetsList.tsx new file mode 100644 index 00000000000..ca14660daff --- /dev/null +++ b/apps/wallet-dashboard/components/AssetsList.tsx @@ -0,0 +1,27 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { AssetCategory } from '@/lib/enums'; +import { IotaObjectData } from '@iota/iota-sdk/client'; +import { AssetTileLink } from '@/components'; + +interface AssetListProps { + assets: IotaObjectData[]; + selectedCategory: AssetCategory; +} + +const ASSET_LAYOUT: Record = { + [AssetCategory.Visual]: + 'grid-template-visual-assets grid max-h-[600px] gap-md overflow-auto py-sm', + [AssetCategory.Other]: 'flex flex-col overflow-auto py-sm', +}; + +export function AssetList({ assets, selectedCategory }: AssetListProps): React.JSX.Element { + return ( +
+ {assets.map((asset) => ( + + ))} +
+ ); +} diff --git a/apps/wallet-dashboard/components/Cards/VisualAssetDetailsCard.tsx b/apps/wallet-dashboard/components/Cards/VisualAssetDetailsCard.tsx new file mode 100644 index 00000000000..3a11c6dc561 --- /dev/null +++ b/apps/wallet-dashboard/components/Cards/VisualAssetDetailsCard.tsx @@ -0,0 +1,23 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { IotaObjectData } from '@iota/iota-sdk/client'; +import { VisualAssetTile } from '../tiles'; + +interface AssetDetailsCardProps { + asset: IotaObjectData; +} + +export function VisualAssetDetailsCard({ asset }: AssetDetailsCardProps): React.JSX.Element { + return ( +
+ +
+

Digest: {asset.digest}

+

Object ID: {asset.objectId}

+ {asset.type ?

Type: {asset.type}

: null} +

Version: {asset.version}

+
+
+ ); +} diff --git a/apps/wallet-dashboard/components/Cards/index.ts b/apps/wallet-dashboard/components/Cards/index.ts index 4f7b2563c0c..da687047e80 100644 --- a/apps/wallet-dashboard/components/Cards/index.ts +++ b/apps/wallet-dashboard/components/Cards/index.ts @@ -2,4 +2,4 @@ // SPDX-License-Identifier: Apache-2.0 export { default as StakeCard } from './StakeCard'; -export * from './AssetCard'; +export * from './VisualAssetDetailsCard'; diff --git a/apps/wallet-dashboard/components/Popup/Popups/SendAssetPopup.tsx b/apps/wallet-dashboard/components/Popup/Popups/SendAssetPopup.tsx index 8dbcf912276..679c4002d96 100644 --- a/apps/wallet-dashboard/components/Popup/Popups/SendAssetPopup.tsx +++ b/apps/wallet-dashboard/components/Popup/Popups/SendAssetPopup.tsx @@ -3,7 +3,7 @@ import React, { useCallback, useState } from 'react'; import { IotaObjectData } from '@iota/iota-sdk/client'; -import { AssetCard, Input } from '@/components'; +import { VisualAssetTile, Input } from '@/components'; import { Button } from '@/components/Buttons'; import { FlexDirection } from '@/lib/ui/enums'; import { useCurrentAccount } from '@iota/dapp-kit'; @@ -49,7 +49,7 @@ export default function SendAssetPopup({ asset, onClose }: SendAssetPopupProps): function onSendAssetSuccess() { addNotification('Transfer transaction successful', NotificationType.Success); onClose?.(); - router.push(ASSETS_ROUTE.path + '/visual-assets'); + router.push(ASSETS_ROUTE.path + '/assets'); } function onSendAssetError() { @@ -67,7 +67,7 @@ export default function SendAssetPopup({ asset, onClose }: SendAssetPopupProps): return (
- +
{ + if (type === AssetCategory.Visual) { + return { href: ASSETS_ROUTE.path + `/${asset.objectId}` }; + } else { + const explorerLink = + getExplorerLink({ + type: ExplorerLinkType.Object, + objectID: asset.objectId, + }) ?? ''; + + return { + href: explorerLink, + target: '_blank', + rel: 'noopener noreferrer', + }; + } + } + + return ( + + {type === AssetCategory.Visual ? ( + } /> + ) : ( + + )} + + ); +} diff --git a/apps/wallet-dashboard/components/tiles/NonVisualAssetTile.tsx b/apps/wallet-dashboard/components/tiles/NonVisualAssetTile.tsx new file mode 100644 index 00000000000..0758714510e --- /dev/null +++ b/apps/wallet-dashboard/components/tiles/NonVisualAssetTile.tsx @@ -0,0 +1,25 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { Card, CardAction, CardActionType, CardBody, CardType } from '@iota/apps-ui-kit'; +import { IotaObjectData } from '@iota/iota-sdk/client'; +import { formatAddress, parseStructTag } from '@iota/iota-sdk/utils'; +import { ArrowTopRight } from '@iota/ui-icons'; + +type NonVisualAssetCardProps = { + asset: IotaObjectData; +} & Pick, 'onClick'>; + +export function NonVisualAssetCard({ asset, onClick }: NonVisualAssetCardProps): React.JSX.Element { + const { address, module, name } = parseStructTag(asset.type!); + return ( + + + } /> + + ); +} diff --git a/apps/wallet-dashboard/components/Cards/AssetCard.tsx b/apps/wallet-dashboard/components/tiles/VisualAssetTile.tsx similarity index 97% rename from apps/wallet-dashboard/components/Cards/AssetCard.tsx rename to apps/wallet-dashboard/components/tiles/VisualAssetTile.tsx index 4aa47e8801d..6fbc03801c4 100644 --- a/apps/wallet-dashboard/components/Cards/AssetCard.tsx +++ b/apps/wallet-dashboard/components/tiles/VisualAssetTile.tsx @@ -14,7 +14,7 @@ interface AssetCardProps extends Pick[0], +) => ReturnType { + const { network } = useIotaClientContext(); + const address = useCurrentAccount()?.address || null; + + return (linkConfig) => getExplorerLink(linkConfig, address, network); +} diff --git a/apps/wallet/src/background/NetworkEnv.ts b/apps/wallet/src/background/NetworkEnv.ts index 0686efaaa2e..ea5b39ed07a 100644 --- a/apps/wallet/src/background/NetworkEnv.ts +++ b/apps/wallet/src/background/NetworkEnv.ts @@ -2,7 +2,7 @@ // Modifications Copyright (c) 2024 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -import { type NetworkEnvType } from '_src/shared/api-env'; +import { type NetworkEnvType } from '@iota/core'; import { isValidUrl } from '_src/shared/utils'; import { getDefaultNetwork, Network } from '@iota/iota-sdk/client'; import mitt from 'mitt'; diff --git a/apps/wallet/src/background/connections/index.ts b/apps/wallet/src/background/connections/index.ts index 783839375e2..d6b5c3c591b 100644 --- a/apps/wallet/src/background/connections/index.ts +++ b/apps/wallet/src/background/connections/index.ts @@ -6,7 +6,7 @@ import { createMessage } from '_messages'; import type { SetNetworkPayload } from '_payloads/network'; import type { Permission } from '_payloads/permissions'; import type { WalletStatusChange, WalletStatusChangePayload } from '_payloads/wallet-status-change'; -import type { NetworkEnvType } from '_src/shared/api-env'; +import type { NetworkEnvType } from '@iota/core'; import { type UIAccessibleEntityType } from '_src/shared/messaging/messages/payloads/MethodPayload'; import Browser from 'webextension-polyfill'; diff --git a/apps/wallet/src/dapp-interface/WalletStandardInterface.ts b/apps/wallet/src/dapp-interface/WalletStandardInterface.ts index 29429b238dd..5490718fdbc 100644 --- a/apps/wallet/src/dapp-interface/WalletStandardInterface.ts +++ b/apps/wallet/src/dapp-interface/WalletStandardInterface.ts @@ -21,7 +21,7 @@ import type { SignTransactionRequest, SignTransactionResponse, } from '_payloads/transactions'; -import { getCustomNetwork, type NetworkEnvType } from '_src/shared/api-env'; +import { getCustomNetwork, type NetworkEnvType } from '@iota/core'; import { type SignMessageRequest } from '_src/shared/messaging/messages/payloads/transactions/SignMessage'; import { isWalletStatusChangePayload } from '_src/shared/messaging/messages/payloads/wallet-status-change'; import { getNetwork, Network, type ChainType } from '@iota/iota-sdk/client'; diff --git a/apps/wallet/src/shared/iota-client.ts b/apps/wallet/src/shared/iota-client.ts index 85904c928ec..21eca1628df 100644 --- a/apps/wallet/src/shared/iota-client.ts +++ b/apps/wallet/src/shared/iota-client.ts @@ -3,8 +3,7 @@ // SPDX-License-Identifier: Apache-2.0 import networkEnv from '_src/background/NetworkEnv'; -import { type NetworkEnvType } from '_src/shared/api-env'; -import { SentryHttpTransport } from '@iota/core'; +import { type NetworkEnvType, SentryHttpTransport } from '@iota/core'; import { getNetwork, Network, IotaClient, IotaHTTPTransport } from '@iota/iota-sdk/client'; const iotaClientPerNetwork = new Map(); diff --git a/apps/wallet/src/shared/messaging/messages/payloads/network/index.ts b/apps/wallet/src/shared/messaging/messages/payloads/network/index.ts index 5e84a91c9cc..58c3b0498df 100644 --- a/apps/wallet/src/shared/messaging/messages/payloads/network/index.ts +++ b/apps/wallet/src/shared/messaging/messages/payloads/network/index.ts @@ -4,7 +4,7 @@ import { isBasePayload } from '_payloads'; import type { BasePayload, Payload } from '_payloads'; -import type { NetworkEnvType } from '_src/shared/api-env'; +import type { NetworkEnvType } from '@iota/core'; export interface SetNetworkPayload extends BasePayload { type: 'set-network'; diff --git a/apps/wallet/src/shared/messaging/messages/payloads/wallet-status-change/index.ts b/apps/wallet/src/shared/messaging/messages/payloads/wallet-status-change/index.ts index b873c235301..7ad4d571a28 100644 --- a/apps/wallet/src/shared/messaging/messages/payloads/wallet-status-change/index.ts +++ b/apps/wallet/src/shared/messaging/messages/payloads/wallet-status-change/index.ts @@ -4,7 +4,7 @@ import { isBasePayload } from '_payloads'; import type { BasePayload, Payload } from '_payloads'; -import type { NetworkEnvType } from '_src/shared/api-env'; +import type { NetworkEnvType } from '@iota/core'; export type WalletStatusChange = { network?: NetworkEnvType; diff --git a/apps/wallet/src/ui/app/background-client/index.ts b/apps/wallet/src/ui/app/background-client/index.ts index 8a29cd049db..a6da569d7fc 100644 --- a/apps/wallet/src/ui/app/background-client/index.ts +++ b/apps/wallet/src/ui/app/background-client/index.ts @@ -20,7 +20,7 @@ import { setPermissions } from '_redux/slices/permissions'; import { setTransactionRequests } from '_redux/slices/transaction-requests'; import { type MnemonicSerializedUiAccount } from '_src/background/accounts/MnemonicAccount'; import { type SeedSerializedUiAccount } from '_src/background/accounts/SeedAccount'; -import type { NetworkEnvType } from '_src/shared/api-env'; +import type { NetworkEnvType } from '@iota/core'; import { isMethodPayload, type MethodPayload, diff --git a/apps/wallet/src/ui/app/components/explorer-link/index.tsx b/apps/wallet/src/ui/app/components/explorer-link/index.tsx index be9f4f68ad9..0ce305b1087 100644 --- a/apps/wallet/src/ui/app/components/explorer-link/index.tsx +++ b/apps/wallet/src/ui/app/components/explorer-link/index.tsx @@ -4,7 +4,8 @@ import { ExternalLink } from '_components'; import type { ReactNode } from 'react'; -import { useExplorerLink, type ExplorerLinkConfig } from '../../hooks/useExplorerLink'; +import { type ExplorerLinkConfig, ExplorerLinkType } from '@iota/core'; +import { useExplorerLink } from '_hooks'; import st from './ExplorerLink.module.scss'; import clsx from 'clsx'; import { ArrowTopRight } from '@iota/ui-icons'; @@ -43,6 +44,6 @@ export function ExplorerLink({ ); } -export * from './ExplorerLinkType'; +export { ExplorerLinkType }; export default ExplorerLink; diff --git a/apps/wallet/src/ui/app/components/index.ts b/apps/wallet/src/ui/app/components/index.ts index 9bafd9cd168..b4261f15214 100644 --- a/apps/wallet/src/ui/app/components/index.ts +++ b/apps/wallet/src/ui/app/components/index.ts @@ -19,7 +19,6 @@ export * from './coin-icon'; export * from './error-boundary'; export * from './explorer-link'; export * from './explorer-link/Explorer'; -export * from './explorer-link/ExplorerLinkType'; export * from './external-link'; export * from './iota-apps'; export * from './iota-apps/IotaApp'; diff --git a/apps/wallet/src/ui/app/components/menu/content/WalletSettingsMenuList.tsx b/apps/wallet/src/ui/app/components/menu/content/WalletSettingsMenuList.tsx index dc706541a6d..8de6df26d6a 100644 --- a/apps/wallet/src/ui/app/components/menu/content/WalletSettingsMenuList.tsx +++ b/apps/wallet/src/ui/app/components/menu/content/WalletSettingsMenuList.tsx @@ -4,7 +4,7 @@ import { useNextMenuUrl, Overlay } from '_components'; import { useAppSelector } from '_hooks'; -import { getCustomNetwork } from '_src/shared/api-env'; +import { getCustomNetwork } from '@iota/core'; import { FAQ_LINK, ToS_LINK } from '_src/shared/constants'; import { formatAutoLock, useAutoLockMinutes } from '_src/ui/app/hooks/useAutoLockMinutes'; import FaucetRequestButton from '_src/ui/app/shared/faucet/FaucetRequestButton'; diff --git a/apps/wallet/src/ui/app/components/network-selector/index.tsx b/apps/wallet/src/ui/app/components/network-selector/index.tsx index b13a846d247..3bbeb7a7b8c 100644 --- a/apps/wallet/src/ui/app/components/network-selector/index.tsx +++ b/apps/wallet/src/ui/app/components/network-selector/index.tsx @@ -5,7 +5,7 @@ import { useAppDispatch, useAppSelector } from '_hooks'; import { changeActiveNetwork } from '_redux/slices/app'; import { ampli } from '_src/shared/analytics/ampli'; -import { getCustomNetwork } from '_src/shared/api-env'; +import { getCustomNetwork } from '@iota/core'; import { getAllNetworks, Network, type NetworkConfiguration } from '@iota/iota-sdk/client'; import { AnimatePresence, motion } from 'framer-motion'; import { useEffect, useMemo, useState } from 'react'; diff --git a/apps/wallet/src/ui/app/hooks/index.ts b/apps/wallet/src/ui/app/hooks/index.ts index c5f56ef733d..33244c68262 100644 --- a/apps/wallet/src/ui/app/hooks/index.ts +++ b/apps/wallet/src/ui/app/hooks/index.ts @@ -16,6 +16,7 @@ export { useGetTxnRecipientAddress } from './useGetTxnRecipientAddress'; export { useGetTransferAmount } from './useGetTransferAmount'; export { useOwnedNFT } from './useOwnedNFT'; export { useCopyToClipboard } from './useCopyToClipboard'; +export * from './useExplorerLink'; export * from './useTransactionData'; export * from './useActiveAddress'; diff --git a/apps/wallet/src/ui/app/hooks/useExplorerLink.ts b/apps/wallet/src/ui/app/hooks/useExplorerLink.ts index 1af1bf60335..33bfb54dd1b 100644 --- a/apps/wallet/src/ui/app/hooks/useExplorerLink.ts +++ b/apps/wallet/src/ui/app/hooks/useExplorerLink.ts @@ -2,65 +2,13 @@ // Modifications Copyright (c) 2024 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -import { getCustomNetwork } from '_src/shared/api-env'; -import { getNetwork, Network } from '@iota/iota-sdk/client'; -import { useMemo } from 'react'; - -import { - getAddressUrl, - getObjectUrl, - getTransactionUrl, - getValidatorUrl, - ExplorerLinkType, -} from '_components'; +import { type ExplorerLinkConfig, getExplorerLink as useGetExplorerLink } from '@iota/core'; import { useActiveAddress } from './useActiveAddress'; import useAppSelector from './useAppSelector'; -export type ExplorerLinkConfig = - | { - type: ExplorerLinkType.Address; - address?: string; - useActiveAddress?: false; - } - | { - type: ExplorerLinkType.Address; - useActiveAddress: true; - } - | { type: ExplorerLinkType.Object; objectID: string; moduleName?: string } - | { type: ExplorerLinkType.Transaction; transactionID: string } - | { type: ExplorerLinkType.Validator; validator: string }; - -function useAddress(linkConfig: ExplorerLinkConfig) { - const { type } = linkConfig; - const isAddress = type === ExplorerLinkType.Address; - const isProvidedAddress = isAddress && !linkConfig.useActiveAddress; - const activeAddress = useActiveAddress(); - return isProvidedAddress ? linkConfig.address : activeAddress; -} - export function useExplorerLink(linkConfig: ExplorerLinkConfig) { - const { type } = linkConfig; - const address = useAddress(linkConfig); - const network = useAppSelector(({ app }) => app.network); - const objectID = type === ExplorerLinkType.Object ? linkConfig.objectID : null; - const transactionID = type === ExplorerLinkType.Transaction ? linkConfig.transactionID : null; - const validator = type === ExplorerLinkType.Validator ? linkConfig.validator : null; - const moduleName = type === ExplorerLinkType.Object ? linkConfig.moduleName : null; - - // fallback to localhost if customRPC is not set - const customExplorer = - network === Network.Custom ? getCustomNetwork().explorer : getNetwork(network).explorer; - return useMemo(() => { - if (!address) return null; - switch (type) { - case ExplorerLinkType.Address: - return address && getAddressUrl(address, network, customExplorer); - case ExplorerLinkType.Object: - return objectID && getObjectUrl(objectID, network, customExplorer, moduleName); - case ExplorerLinkType.Transaction: - return transactionID && getTransactionUrl(transactionID, network, customExplorer); - case ExplorerLinkType.Validator: - return validator && getValidatorUrl(validator, network, customExplorer); - } - }, [type, address, network, customExplorer, moduleName, objectID, transactionID, validator]); + const app = useAppSelector(({ app }) => app); + const activeAddress = useActiveAddress(); + const link = useGetExplorerLink(linkConfig, activeAddress, app.network); + return link; } diff --git a/apps/wallet/src/ui/app/hooks/useInitialPageView.ts b/apps/wallet/src/ui/app/hooks/useInitialPageView.ts index 7ae9b3d2f54..1fde2375182 100644 --- a/apps/wallet/src/ui/app/hooks/useInitialPageView.ts +++ b/apps/wallet/src/ui/app/hooks/useInitialPageView.ts @@ -3,7 +3,7 @@ // SPDX-License-Identifier: Apache-2.0 import { ampli } from '_src/shared/analytics/ampli'; -import { getCustomNetwork } from '_src/shared/api-env'; +import { getCustomNetwork } from '@iota/core'; import { getNetwork } from '@iota/iota-sdk/client'; import { useEffect } from 'react'; import { useLocation } from 'react-router-dom'; diff --git a/apps/wallet/src/ui/app/redux/slices/app/index.ts b/apps/wallet/src/ui/app/redux/slices/app/index.ts index 8843a3f78b2..35600347357 100644 --- a/apps/wallet/src/ui/app/redux/slices/app/index.ts +++ b/apps/wallet/src/ui/app/redux/slices/app/index.ts @@ -4,7 +4,7 @@ import { walletApiProvider } from '_app/ApiProvider'; import type { RootState } from '_redux/RootReducer'; -import type { NetworkEnvType } from '_src/shared/api-env'; +import type { NetworkEnvType } from '@iota/core'; import type { AppThunkConfig } from '_store/thunk-extras'; import { getDefaultNetwork, type Network } from '@iota/iota-sdk/client'; import { createAsyncThunk, createSlice } from '@reduxjs/toolkit'; diff --git a/apps/wallet/src/ui/app/shared/faucet/FaucetRequestButton.tsx b/apps/wallet/src/ui/app/shared/faucet/FaucetRequestButton.tsx index b9dcb4d1576..fd8326069b2 100644 --- a/apps/wallet/src/ui/app/shared/faucet/FaucetRequestButton.tsx +++ b/apps/wallet/src/ui/app/shared/faucet/FaucetRequestButton.tsx @@ -3,7 +3,7 @@ // SPDX-License-Identifier: Apache-2.0 import { useAppSelector } from '_hooks'; -import { getCustomNetwork } from '_src/shared/api-env'; +import { getCustomNetwork } from '@iota/core'; import { getNetwork } from '@iota/iota-sdk/client'; import { FaucetRateLimitError } from '@iota/iota-sdk/faucet'; import { toast } from 'react-hot-toast';