diff --git a/src/chrome/background/message-handler.ts b/src/chrome/background/message-handler.ts index b0df0b28..2ce5a5b7 100644 --- a/src/chrome/background/message-handler.ts +++ b/src/chrome/background/message-handler.ts @@ -22,8 +22,9 @@ import { notificationDispatcher } from './notification-dispatcher' import { getExtensionOptions } from 'options' import { chromeLocalStore } from 'chrome/helpers/chrome-local-store' import { RadixNetworkConfigById } from '@radixdlt/babylon-gateway-api-sdk' -import { ConnectionsClient } from 'pairing/state/connections' +import { Connections, ConnectionsClient } from 'pairing/state/connections' import { WalletInteraction } from '@radixdlt/radix-dapp-toolkit' +import { getSessionRouterData } from 'chrome/offscreen/session-router' export type BackgroundMessageHandler = ReturnType< typeof BackgroundMessageHandler @@ -38,7 +39,7 @@ export const BackgroundMessageHandler = }: Partial<{ logger?: AppLogger ledgerTabWatcher: ReturnType - getConnections: () => ResultAsync + getConnections: () => ResultAsync closePopup: () => ResultAsync openParingPopup: () => ResultAsync }>) => @@ -58,25 +59,15 @@ export const BackgroundMessageHandler = switch (message?.discriminator) { case messageDiscriminator.getExtensionOptions: - return getExtensionOptions() - .mapErr((error) => ({ - reason: 'failedToGetExtensionOptions', - jsError: Error('failedToGetExtensionOptions'), - })) - .map((options) => ({ - sendConfirmation: true, - data: { options }, - })) + return getExtensionOptions().map((options) => ({ + sendConfirmation: true, + data: { options }, + })) case messageDiscriminator.getConnections: - return getConnections() - .mapErr((error) => ({ - reason: 'failedToGetConnections', - jsError: error, - })) - .map((data) => ({ - sendConfirmation: true, - data, - })) + return getConnections().map((data) => ({ + sendConfirmation: true, + data, + })) case messageDiscriminator.openParingPopup: return openParingPopup() @@ -202,15 +193,10 @@ export const BackgroundMessageHandler = } case messageDiscriminator.getSessionRouterData: { - return chromeLocalStore - .getItem('sessionRouter') - .map((data) => ({ - sendConfirmation: true, - data, - })) - .mapErr(() => ({ - reason: 'failedToGetSessionRouterData', - })) + return getSessionRouterData().map((data) => ({ + sendConfirmation: true, + data, + })) } case messageDiscriminator.dAppRequest: { diff --git a/src/chrome/helpers/get-connections.ts b/src/chrome/helpers/get-connections.ts index 58f4de6e..a3d027bb 100644 --- a/src/chrome/helpers/get-connections.ts +++ b/src/chrome/helpers/get-connections.ts @@ -1,11 +1,12 @@ import { Connections } from 'pairing/state/connections' import { chromeLocalStore } from './chrome-local-store' -import { ResultAsync } from 'neverthrow' +import { ResultAsync, ok } from 'neverthrow' -export const getConnections = (): ResultAsync => +export const getConnections = (): ResultAsync => chromeLocalStore .getItem('connections') .map(({ connections }) => connections || {}) + .orElse(() => ok({})) export const hasConnections = () => getConnections().map( diff --git a/src/chrome/offscreen/helpers/offscreen-initialization-messages.ts b/src/chrome/offscreen/helpers/offscreen-initialization-messages.ts index c5949997..a81f9a57 100644 --- a/src/chrome/offscreen/helpers/offscreen-initialization-messages.ts +++ b/src/chrome/offscreen/helpers/offscreen-initialization-messages.ts @@ -33,10 +33,10 @@ export const OffscreenInitializationMessages = ( }, sessionRouterData: () => { messageClient - .sendMessageAndWaitForConfirmation<{ - sessionRouter: Record - }>(createMessage.getSessionRouterData()) - .andThen(({ sessionRouter }) => + .sendMessageAndWaitForConfirmation>( + createMessage.getSessionRouterData(), + ) + .andThen((sessionRouter) => messageClient.handleMessage( createMessage.setSessionRouterData(sessionRouter, 'offScreen'), ), diff --git a/src/chrome/offscreen/message-handler.ts b/src/chrome/offscreen/message-handler.ts index f713c5b2..e5ca7e6e 100644 --- a/src/chrome/offscreen/message-handler.ts +++ b/src/chrome/offscreen/message-handler.ts @@ -111,8 +111,8 @@ export const OffscreenMessageHandler = (input: { case messageDiscriminator.setSessionRouterData: { const { data } = message - sessionRouter.refreshStore(data) - logger?.info('setSessionRouterData', data) + logger?.info('setSessionRouterData', message) + sessionRouter.refreshStore(data || {}) return okAsync({ sendConfirmation: true }) } diff --git a/src/chrome/offscreen/session-router.ts b/src/chrome/offscreen/session-router.ts index 68d6cd81..a1b13953 100644 --- a/src/chrome/offscreen/session-router.ts +++ b/src/chrome/offscreen/session-router.ts @@ -1,3 +1,6 @@ +import { chromeLocalStore } from 'chrome/helpers/chrome-local-store' +import { ResultAsync, ok } from 'neverthrow' + export type SessionRouter = ReturnType export type SessionId = string @@ -22,3 +25,14 @@ export const SessionRouter = () => { store, } } + +export const sessionRouter = SessionRouter() + +export const getSessionRouterData = (): ResultAsync< + Record, + never +> => + chromeLocalStore + .getItem('sessionRouter') + .map(({ sessionRouter }) => sessionRouter || {}) + .orElse(() => ok({})) diff --git a/src/components/linked-wallet/linked-wallet.scss b/src/components/linked-wallet/linked-wallet.scss index 47f5c214..133a7755 100644 --- a/src/components/linked-wallet/linked-wallet.scss +++ b/src/components/linked-wallet/linked-wallet.scss @@ -15,3 +15,7 @@ button { display: inline-flex; transition: transform 0.3s ease-in-out; } + +.shared-accounts-collapse-button.rotate { + margin-top: 5px; +} diff --git a/src/components/linked-wallet/shared-accounts.tsx b/src/components/linked-wallet/shared-accounts.tsx index ed40a801..53b14d3b 100644 --- a/src/components/linked-wallet/shared-accounts.tsx +++ b/src/components/linked-wallet/shared-accounts.tsx @@ -2,7 +2,7 @@ import ChevronDown from './chevron-down.svg' import { Account as AccountType } from '@radixdlt/radix-dapp-toolkit' import { Account } from 'components/account/account' import { Box, Collapse } from '@mui/material' -import { useEffect, useState } from 'react' +import { useState } from 'react' export const SharedAccounts = (props: { accounts?: AccountType[] @@ -11,7 +11,7 @@ export const SharedAccounts = (props: { const [isCollapsed, setIsCollapsed] = useState(!props.isJustLinked) return ( - + {props.accounts?.map((account) => ( diff --git a/src/options/index.ts b/src/options/index.ts index 245c4868..157e68eb 100644 --- a/src/options/index.ts +++ b/src/options/index.ts @@ -1,7 +1,7 @@ import { chromeLocalStore } from 'chrome/helpers/chrome-local-store' import { logger } from 'utils/logger' import { defaultRadixConnectConfig } from 'config' -import { ResultAsync } from 'neverthrow' +import { ResultAsync, ok } from 'neverthrow' import { ed25519 } from '@noble/curves/ed25519' const privateKey = ed25519.utils.randomPrivateKey() @@ -10,9 +10,9 @@ const publicKey = ed25519.getPublicKey(privateKey) export type ConnectorExtensionOptions = { publicKey: string privateKey: string - showDAppRequestNotifications?: boolean - showTransactionResultNotifications?: boolean radixConnectConfiguration: string + showDAppRequestNotifications: boolean + showTransactionResultNotifications: boolean } export const defaultConnectorExtensionOptions: ConnectorExtensionOptions = { @@ -23,11 +23,13 @@ export const defaultConnectorExtensionOptions: ConnectorExtensionOptions = { radixConnectConfiguration: defaultRadixConnectConfig, } -export const getSingleOptionValue = (key: keyof ConnectorExtensionOptions) => +export const getSingleOptionValue = ( + key: T, +): ResultAsync => chromeLocalStore .getSingleItem('options') .map((options) => options?.[key] || defaultConnectorExtensionOptions[key]) - .mapErr(() => defaultConnectorExtensionOptions[key]) + .orElse(() => ok(defaultConnectorExtensionOptions[key])) export const getShowDAppRequestNotifications = () => getSingleOptionValue('showDAppRequestNotifications') @@ -37,7 +39,7 @@ export const getShowTransactionResultNotifications = () => export const getExtensionOptions = (): ResultAsync< ConnectorExtensionOptions, - ConnectorExtensionOptions + never > => { return chromeLocalStore .getSingleItem('options') @@ -45,7 +47,7 @@ export const getExtensionOptions = (): ResultAsync< ...defaultConnectorExtensionOptions, ...options, })) - .mapErr(() => defaultConnectorExtensionOptions) + .orElse(() => ok(defaultConnectorExtensionOptions)) } export const setConnectorExtensionOptions = ( diff --git a/src/pairing/components/connection-password.tsx b/src/pairing/components/connection-password.tsx index d39ca488..ee6c4185 100644 --- a/src/pairing/components/connection-password.tsx +++ b/src/pairing/components/connection-password.tsx @@ -22,7 +22,7 @@ export const ConnectionPassword = ({ <> - {connectionsClient.hasNoConnections() ? ( - - {`Don't have Radix Wallet?`} - - ) : ( + {connectionsClient.hasConnections() ? ( Cancel + ) : ( + + {`Don't have Radix Wallet?`} + )} diff --git a/src/pairing/components/connection-status.tsx b/src/pairing/components/connection-status.tsx index f2eb1ee3..6bdd9745 100644 --- a/src/pairing/components/connection-status.tsx +++ b/src/pairing/components/connection-status.tsx @@ -38,7 +38,7 @@ export const ConnectionStatus = () => { useEffect(() => { if (connectionsClient.isLoading()) return - if (connectionsClient.hasNoConnections()) { + if (!connectionsClient.hasConnections()) { navigate('/pairing') } }, [connections]) @@ -79,7 +79,7 @@ export const ConnectionStatus = () => { ) } - return ( + return connectionsClient.hasConnections() ? ( <> { {renderForgetWalletConfirmation()} {renderChangeWalletName()} - ) + ) : null } diff --git a/src/pairing/state/connections.ts b/src/pairing/state/connections.ts index dc11c3c3..ca0e727d 100644 --- a/src/pairing/state/connections.ts +++ b/src/pairing/state/connections.ts @@ -22,7 +22,7 @@ export const useConnections = () => { useEffect(() => { chromeLocalStore.getItem('connections').map((result) => { if (JSON.stringify(result.connections) !== JSON.stringify(connections)) { - setConnections(result.connections || null) + setConnections(result.connections || {}) } }) const listener = ( @@ -69,8 +69,8 @@ export const ConnectionsClient = (connections?: Connections | null) => { }) } - const hasNoConnections = () => { - return connections && Object.keys(connections).length === 0 + const hasConnections = () => { + return connections && Object.keys(connections).length > 0 } const isLoading = () => { @@ -137,7 +137,7 @@ export const ConnectionsClient = (connections?: Connections | null) => { entries, isLoading, updateName, - hasNoConnections, + hasConnections, updateAccounts, connections, } diff --git a/src/queues/storage/chrome-local-storage.ts b/src/queues/storage/chrome-local-storage.ts deleted file mode 100644 index 4c33a0ea..00000000 --- a/src/queues/storage/chrome-local-storage.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { ok, ResultAsync } from 'neverthrow' -import { StorageProvider } from 'queues/_types' -import { parseJSON } from 'utils' - -export const ChromeLocalStorage = (): StorageProvider => { - const store = new Map() - - const getData = (key: string): Promise => - new Promise((resolve, reject) => { - try { - const data = store.get(key) - resolve(data ?? undefined) - } catch (error) { - reject(error) - } - }) - - const setData = (key: string, data: unknown): Promise => - new Promise((resolve, reject) => { - try { - store.set(key, JSON.stringify(data)) - resolve(undefined) - } catch (error) { - reject(error) - } - }) - - return { - getData: (key: string) => - ResultAsync.fromPromise(getData(key), (error) => error as Error).andThen( - (data) => (data ? parseJSON(data) : ok(undefined)), - ), - setData: (key: string, data: unknown) => - ResultAsync.fromPromise(setData(key, data), (error) => error as Error), - } -}