Skip to content

Commit

Permalink
feat: add session->clientId router
Browse files Browse the repository at this point in the history
  • Loading branch information
dawidsowardx committed Jan 29, 2024
1 parent 3f911ae commit 53357f2
Show file tree
Hide file tree
Showing 20 changed files with 310 additions and 40 deletions.
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"@mui/material": "^5.14.0",
"@radixdlt/babylon-gateway-api-sdk": "^1.2.7",
"@radixdlt/connect-button": "^1.0.1",
"@radixdlt/radix-connect-schemas": "^1.2.0",
"@radixdlt/radix-connect-schemas": "^1.3.0-cap36.1",
"@radixdlt/radix-connect-webrtc": "^1.0.4",
"@stitches/react": "^1.2.8",
"@types/blake2b": "^2.1.0",
Expand Down
21 changes: 19 additions & 2 deletions src/chrome/background/background.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import { RadixNetworkConfigById } from '@radixdlt/babylon-gateway-api-sdk'
import { openRadixDevToolsPage } from './open-radix-dev-tools-page'
import { sendMessage } from 'chrome/messages/send-message'
import { Connections } from 'pairing/state/connections'
import { SessionRouter } from 'chrome/offscreen/session-router'
import { createTab } from 'chrome/helpers/create-tab'

const logger = utilsLogger.getSubLogger({ name: 'background' })

Expand Down Expand Up @@ -55,6 +57,12 @@ const handleStorageChange = (
),
)
}

if (changes['sessionRouter'] && area === 'local') {
messageHandler.sendMessageAndWaitForConfirmation(
createMessage.setSessionRouterData(changes['sessionRouter'].newValue),
)
}
}

const ledgerTabWatcher = LedgerTabWatcher()
Expand Down Expand Up @@ -114,12 +122,21 @@ chrome.notifications.onButtonClicked.addListener(handleNotificationClick)
chrome.storage.onChanged.addListener(handleStorageChange)
chrome.action.onClicked.addListener(openParingPopup)
chrome.runtime.onInstalled.addListener(handleOnInstallExtension)

if (isDevMode) {
chrome.runtime.onInstalled.addListener(() => {
createTab(
`chrome-extension://${chrome.runtime.id}/src/chrome/offscreen/index.html`,
)
})
} else {
createOffscreen()
}

chrome.runtime.onStartup.addListener(() => {
logger.debug('onStartup')
})

createOffscreen()

chrome.contextMenus?.removeAll(() => {
if (isDevMode) {
chrome.contextMenus.create({
Expand Down
58 changes: 57 additions & 1 deletion src/chrome/background/message-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import {
WalletInteraction,
} from './notification-dispatcher'
import { getExtensionOptions } from 'options'
import { chromeLocalStore } from 'chrome/helpers/chrome-local-store'
import { RadixNetworkConfigById } from '@radixdlt/babylon-gateway-api-sdk'

export type BackgroundMessageHandler = ReturnType<
typeof BackgroundMessageHandler
Expand All @@ -44,6 +46,8 @@ export const BackgroundMessageHandler =
message: Message,
sendMessageWithConfirmation: SendMessageWithConfirmation,
): MessageHandlerOutput => {
if (message?.discriminator !== 'log')
logger?.debug('incoming bg message', message.discriminator)
switch (message?.discriminator) {
case messageDiscriminator.getExtensionOptions:
return getExtensionOptions()
Expand Down Expand Up @@ -129,11 +133,47 @@ export const BackgroundMessageHandler =
}

case messageDiscriminator.walletResponse: {
const sessionId = message.data?.metadata?.sessionId
const clientId = message.data?.metadata?.clientId

logger?.debug('bg knows about', sessionId, clientId, message.data)
if (
sessionId &&
clientId &&
message.data?.discriminator &&
message.data.discriminator !== 'failure'
) {
chromeLocalStore.getSingleItem('sessionRouter').map((data) => {
if (!data) {
logger?.debug('adding sessionId->clientId mapping')
return chromeLocalStore.setSingleItem('sessionRouter', {
[sessionId]: clientId,
})
}

if (data[sessionId] && data[sessionId] !== clientId) {
logger?.warn(
`sessionRouter has clientId ${data[sessionId]} for ${sessionId} but we've just had a response from ${clientId}`,
)
} else if (!data[sessionId]) {
logger?.debug('adding sessionId->clientId mapping')
return chromeLocalStore.setSingleItem('sessionRouter', {
...data,
[sessionId]: clientId,
})
}

logger?.debug('not updating clientId nor sessionId')
})
}

const canBePolled = (message: any) => {
return (
message.data?.items?.discriminator === 'transaction' &&
message.data?.items?.send?.transactionIntentHash &&
message.data?.metadata?.networkId
message.data?.metadata?.networkId &&
RadixNetworkConfigById[message.data?.metadata?.networkId]
?.gatewayUrl
)
}

Expand All @@ -158,6 +198,22 @@ export const BackgroundMessageHandler =
return okAsync({ sendConfirmation: false })
}

case messageDiscriminator.getSessionRouterData: {
return chromeLocalStore
.getItem('sessionRouter')
.map((data) => ({
sendConfirmation: true,
data,
}))
.mapErr(() => ({
reason: 'failedToGetSessionRouterData',
}))
}

case messageDiscriminator.addToSessionRouter: {
logger?.debug(message)
}

case messageDiscriminator.dAppRequest: {
hasConnections().map((hasConnections) => {
if (hasConnections) {
Expand Down
2 changes: 2 additions & 0 deletions src/chrome/content-script/content-script.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ chrome.storage.onChanged.addListener(
},
)

logger.debug('content-script loaded')

hasConnections().map((hasConnections) => {
sendMessageToDapp(createMessage.extensionStatus(hasConnections))
})
5 changes: 4 additions & 1 deletion src/chrome/messages/_types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ export const messageDiscriminator = {
setConnections: 'setConnections',
setRadixConnectConfiguration: 'setRadixConnectConfiguration',
getExtensionOptions: 'getExtensionOptions',
getSessionRouterData: 'getSessionRouterData',
setSessionRouterData: 'setSessionRouterData',
addToSessionRouter: 'addToSessionRouter',
dAppRequest: 'dAppRequest',
closeLedgerTab: 'closeLedgerTab',
focusLedgerTab: 'focusLedgerTab',
Expand Down Expand Up @@ -153,7 +156,7 @@ export type Messages = {
{ data: Record<string, any> }
>
[messageDiscriminator.dAppRequest]: MessageBuilder<
MessageDiscriminator['dAppRequest'],
MessageDiscriminator[typeof messageDiscriminator.dAppRequest],
{ data: WalletInteractionWithOrigin }
>
[messageDiscriminator.walletMessage]: MessageBuilder<
Expand Down
13 changes: 11 additions & 2 deletions src/chrome/messages/create-message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,20 @@ import { MessageLifeCycleEvent } from 'chrome/dapp/_types'
import { ILogObj, ILogObjMeta } from 'tslog/dist/types/interfaces'
import { WalletInteractionWithOrigin } from '@radixdlt/radix-connect-schemas'
import { Connections } from 'pairing/state/connections'
import { ClientId, SessionId } from 'chrome/offscreen/session-router'

export const createMessage = {
openParingPopup: () => ({
discriminator: 'openParingPopup',
}),
getSessionRouterData: () => ({
discriminator: messageDiscriminator.getSessionRouterData,
source: 'offscreen',
}),
setSessionRouterData: (data: Record<SessionId, ClientId>) => ({
discriminator: messageDiscriminator.setSessionRouterData,
data,
}),
extensionStatus: (isWalletLinked: boolean) => ({
eventType: 'extensionStatus',
isExtensionAvailable: true,
Expand Down Expand Up @@ -76,9 +85,9 @@ export const createMessage = {
dAppRequest: (
source: MessageSource,
data: WalletInteractionWithOrigin,
): Messages['dAppRequest'] => ({
): Messages[typeof messageDiscriminator.dAppRequest] => ({
source,
discriminator: 'dAppRequest',
discriminator: messageDiscriminator.dAppRequest,
messageId: crypto.randomUUID(),
data,
}),
Expand Down
10 changes: 8 additions & 2 deletions src/chrome/messages/message-client.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { OffscreenMessageHandler } from 'chrome/offscreen/message-handler'
import { walletConnectionClientFactory } from 'chrome/offscreen/wallet-connection/factory'
import { WalletConnectionMessageHandler } from 'chrome/offscreen/wallet-connection/message-handler'
import { Message } from './_types'
import { SessionRouter } from 'chrome/offscreen/session-router'

const logger = new Logger()

Expand Down Expand Up @@ -47,7 +48,9 @@ const createTestHelper = ({
ledgerToWalletQueue,
incomingWalletMessageQueue,
messagesRouter,
sessionRouter: SessionRouter(),
logger,
clientId: 'random-mock-client-id',
}),
'offScreen',
createInput(messageClientSubjects),
Expand All @@ -60,8 +63,11 @@ const createTestHelper = ({
[
'456',
walletConnectionClientFactory({
connectionPassword: '',
walletName: 'Test Mock Wallet',
connection: {
password: '',
walletName: 'Test Mock Wallet',
clientId: 'mock',
},
logger,
messagesRouter,
connectorClient: {
Expand Down
1 change: 1 addition & 0 deletions src/chrome/offscreen/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@
<body>
<div id="logs"></div>
<script type="module" src="/src/chrome/offscreen/offscreen.ts"></script>

</body>
</html>
22 changes: 17 additions & 5 deletions src/chrome/offscreen/message-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ import {
import { WalletConnectionClient } from './wallet-connection/wallet-connection-client'
import { radixConnectConfig } from 'config'
import { Connections } from 'pairing/state/connections'
import type { walletConnectionClientFactory } from './wallet-connection/factory'
import {
sessionRouter,
type walletConnectionClientFactory,
} from './wallet-connection/factory'

export type OffscreenMessageHandler = ReturnType<typeof OffscreenMessageHandler>
export const OffscreenMessageHandler = (input: {
Expand All @@ -21,6 +24,7 @@ export const OffscreenMessageHandler = (input: {
}): MessageHandler => {
let radixConnectConfiguration: string
const logsClient = input.logsClient
const logger = input.logger
const connectionsMap = input.connectionsMap

return (message: Message): MessageHandlerOutput => {
Expand All @@ -33,11 +37,12 @@ export const OffscreenMessageHandler = (input: {
connectionsMap.delete(id)
}

logger?.debug('connection', connection)

connectionsMap.set(
id,
input.walletConnectionClientFactory({
connectionPassword: connection.password,
walletName: connection.walletName,
connection,
logger: input.logger || appLogger,
radixConnectConfiguration,
}),
Expand All @@ -55,7 +60,7 @@ export const OffscreenMessageHandler = (input: {
}

case messageDiscriminator.restartConnector: {
for (const [key, connection] of connectionsMap) {
for (const [, connection] of connectionsMap) {
connection.connectorClient.restart()
}
return okAsync({ sendConfirmation: true })
Expand All @@ -66,7 +71,7 @@ export const OffscreenMessageHandler = (input: {
radixConnectConfiguration =
connectorExtensionOptions.radixConnectConfiguration

for (const [id, connection] of connectionsMap) {
for (const [, connection] of connectionsMap) {
connection.setConnectionConfig(
radixConnectConfig[
connectorExtensionOptions.radixConnectConfiguration
Expand All @@ -77,6 +82,13 @@ export const OffscreenMessageHandler = (input: {
return okAsync({ sendConfirmation: true })
}

case messageDiscriminator.setSessionRouterData: {
const { data } = message
sessionRouter.refreshStore(data)
logger?.info('setSessionRouterData', data)
return okAsync({ sendConfirmation: true })
}

case messageDiscriminator.downloadLogs: {
logsClient.download()
return okAsync({ sendConfirmation: false })
Expand Down
12 changes: 10 additions & 2 deletions src/chrome/offscreen/offscreen.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { AppLogger, logger as utilsLogger } from 'utils/logger'
import { MessagesRouter } from 'chrome/offscreen/wallet-connection/messages-router'
import { logger as utilsLogger } from 'utils/logger'
import { createMessage } from 'chrome/messages/create-message'
import { OffscreenMessageHandler } from 'chrome/offscreen/message-handler'
import { MessageClient } from 'chrome/messages/message-client'
Expand All @@ -10,6 +9,7 @@ import { LogsClient } from './logs-client'
import { Connections } from 'pairing/state/connections'
import { WalletConnectionClient } from './wallet-connection/wallet-connection-client'
import { walletConnectionClientFactory } from './wallet-connection/factory'
import { ClientId, SessionId } from './session-router'

const logsClient = LogsClient()

Expand Down Expand Up @@ -46,6 +46,14 @@ messageClient
),
)

messageClient
.sendMessageAndWaitForConfirmation<Record<SessionId, ClientId>>(
createMessage.getSessionRouterData(),
)
.andThen((data) =>
messageClient.handleMessage(createMessage.setSessionRouterData(data)),
)

const TWO_MINUTES = 120_000
const everyTwoMinute$ = timer(0, TWO_MINUTES)

Expand Down
33 changes: 33 additions & 0 deletions src/chrome/offscreen/session-router.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { ok } from 'neverthrow'

export type SessionRouter = ReturnType<typeof SessionRouter>

export type SessionId = string
export type ClientId = string

export const SessionRouter = () => {
const store = new Map<SessionId, ClientId>()

const add = (sessionId: SessionId, clientId: ClientId) => {
store.set(sessionId, clientId)
return ok(undefined)
}

const removeBySessionId = (sessionId: SessionId) => store.delete(sessionId)

const getClientId = (sessionId: SessionId) => store.get(sessionId)

const refreshStore = (data: Record<SessionId, ClientId>) => {
store.clear()
Object.entries(data).forEach(([sessionId, clientId]) => {
store.set(sessionId, clientId)
})
}

return {
refreshStore,
getClientId,
store,
removeBySessionId,
}
}
Loading

0 comments on commit 53357f2

Please sign in to comment.