Skip to content

Commit

Permalink
add apps/connector logger
Browse files Browse the repository at this point in the history
  • Loading branch information
felicio committed Jan 13, 2025
1 parent b286ef2 commit d8d683a
Show file tree
Hide file tree
Showing 13 changed files with 248 additions and 10 deletions.
5 changes: 5 additions & 0 deletions .changeset/sharp-cheetahs-breathe.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'connector': patch
---

add logger
8 changes: 8 additions & 0 deletions apps/connector/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,11 @@ FLAG_CONNECTOR_ENABLED=1 '/Volumes/Status Desktop/Status.app/Contents/MacOS/nim_
## Testing

Download latest build from last merged PR or build from source. To use the extension see the load steps from [Development](#development) section.

### Logging

Browser > Console

```
await connector.enableLogging(true)
```
5 changes: 5 additions & 0 deletions apps/connector/eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ import configs, { tailwindcssConfigs } from '@status-im/eslint-config'
export default [
...configs,
...tailwindcssConfigs,
{
rules: {
'no-console': 'error',
},
},
{
files: ['**/*.ts', '**/*.tsx'],
rules: {
Expand Down
1 change: 1 addition & 0 deletions apps/connector/global.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ import type { Provider } from './src/contents/provider'
declare global {
interface Window {
ethereum: Provider
registration?: ServiceWorkerRegistration
}
}
8 changes: 8 additions & 0 deletions apps/connector/src/background.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,11 @@ chrome.action.onClicked.addListener(async tab => {
type: 'status:icon:clicked',
} satisfies ServiceWorkerMessage)
})

chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.method === 'toggleLogging') {
storage.set('status:logging', message.params[0])

sendResponse(message.params[0])
}
})
73 changes: 73 additions & 0 deletions apps/connector/src/contents/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { ProxyMessage } from '~messages/proxy-message'

import type { RequestArguments } from '~lib/request-arguments'
import type { PlasmoCSConfig } from 'plasmo'

export const config: PlasmoCSConfig = {
matches: ['https://*/*'],
world: 'MAIN',
run_at: 'document_start',
all_frames: false,
}

Object.defineProperties(window, {
connector: {
value: {
enableLogging: (value = true) => {
// shared web storage with host page and content scripts (Web Storage API)
window.localStorage.setItem('status:logging', JSON.stringify(value))

// service worker extension storage (extension storage API)
request({
method: 'toggleLogging',
params: [value],
})

return value
},
},
configurable: false,
writable: false,
},
})

async function request(args: RequestArguments) {
const { method, params } = args

const messageChannel = new MessageChannel()

return new Promise((resolve, reject) => {
messageChannel.port1.onmessage = ({ data }) => {
try {
const message = ProxyMessage.parse(data)

messageChannel.port1.close()

switch (message.type) {
case 'status:proxy:success': {
resolve(message.data)

return
}
case 'status:proxy:error': {
reject(new Error(message.error.message))

return
}
}
} catch {
return
}
}

const mainMessage = {
type: 'status:main',
data: {
method,
params,
},
}

window.postMessage(mainMessage, window.origin, [messageChannel.port2])
})
}
21 changes: 19 additions & 2 deletions apps/connector/src/contents/provider.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { logger } from '~lib/logger'
import { ProviderRpcError } from '~lib/provider-rpc-error'
import { RequestArguments } from '~lib/request-arguments'
import { ProxyMessage } from '~messages/proxy-message'
Expand Down Expand Up @@ -96,18 +97,24 @@ export class Provider {
this.#listeners.get('connect')?.({ chainId: '0x1' })
this.#listeners.get('connected')?.({ chainId: '0x1' })
this.connected = true

logger.info('connected::')
}

if (method === 'wallet_switchEthereumChain') {
this.#listeners.get('chainChanged')?.(message.data)
this.#listeners.get('networkChanged')?.(message.data)

logger.info('chainChanged::')
}

resolve(message.data)

return
}
case 'status:proxy:error': {
logger.error(message.error)

// note: for those dApps that make call after having permissions revoked
if (
message.error.message === 'dApp is not permitted by user' &&
Expand Down Expand Up @@ -148,15 +155,21 @@ export class Provider {
}

public on(event: Event, handler: (args: unknown) => void): void {
logger.info('on::', event, handler)

this.#listeners.set(event, handler)
}

/** @deprecated */
public async close(): Promise<void> {
public async close(...args: unknown[]): Promise<void> {
logger.info('close::', args)

this.disconnect()
}

public removeListener(event: Event): void {
public removeListener(event: Event, handler: (args: unknown) => void): void {
logger.info('removeListener::', event, handler)

// note: not all dapps remove these on disconnect
if (event === 'close' || event === 'disconnect') {
this.disconnect()
Expand All @@ -166,6 +179,8 @@ export class Provider {
}

public async enable() {
logger.info('enable::')

return true
}

Expand All @@ -176,6 +191,8 @@ export class Provider {

this.connected = false

logger.info('disconnect::')

await this.request({
method: 'wallet_revokePermissions',
params: [
Expand Down
55 changes: 49 additions & 6 deletions apps/connector/src/contents/proxy.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { getFaviconUrl } from '~lib/get-favicon-url'
import { logger } from '~lib/logger'
import { MainMessage } from '~messages/main-message'
import { ProviderMessage } from '~messages/provider-message'

import { DesktopClient } from '../lib/desktop-client'
Expand All @@ -13,7 +15,7 @@ export const config: PlasmoCSConfig = {

const desktopClient = new DesktopClient()

const handleMessage = async (event: MessageEvent) => {
const handleProviderMessage = async (event: MessageEvent) => {
if (event.origin !== window.origin) {
return
}
Expand All @@ -39,13 +41,17 @@ const handleMessage = async (event: MessageEvent) => {
}

try {
logger.info('request::', message.data)

const response = await desktopClient.send({
...message.data,
name: window.location.hostname,
url: window.origin,
iconUrl: getFaviconUrl() ?? '',
})

logger.info('response::', response)

event.ports[0].postMessage({
type: 'status:proxy:success',
data: response,
Expand All @@ -71,12 +77,10 @@ const handleMessage = async (event: MessageEvent) => {
}
}

const proxyMessage: ProxyMessage = {
event.ports[0].postMessage({
type: 'status:proxy:error',
error: proxyError,
}

event.ports[0].postMessage(proxyMessage)
} satisfies ProxyMessage)
}
}

Expand Down Expand Up @@ -108,4 +112,43 @@ function isRpcError(
)
}

window.addEventListener('message', handleMessage)
window.addEventListener('message', handleProviderMessage)

const handleMainMessage = async (event: MessageEvent) => {
if (event.origin !== window.origin) {
return
}

let message: MainMessage
try {
message = MainMessage.parse(event.data)
} catch {
return
}

if (message.type !== 'status:main') {
return
}

try {
const response = await chrome.runtime.sendMessage(
chrome.runtime.id,
message.data,
)

event.ports[0].postMessage({
type: 'status:proxy:success',
data: response,
} satisfies ProxyMessage)
} catch (error) {
event.ports[0].postMessage({
type: 'status:proxy:error',
error: {
code: -32603,
message: isError(error) ? error.message : 'Internal error',
},
} satisfies ProxyMessage)
}
}

window.addEventListener('message', handleMainMessage)
9 changes: 7 additions & 2 deletions apps/connector/src/hooks/use-local-storage.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { useEffect, useState } from 'react'

import { logger } from '~lib/logger'

export function useLocalStorage<T>(
key: string,
initialValue: T,
Expand All @@ -10,7 +12,8 @@ export function useLocalStorage<T>(
try {
const item = window.localStorage.getItem(key)
setStoredValue(item ? JSON.parse(item) : initialValue)
} catch {
} catch (error) {
logger.error(error)
setStoredValue(initialValue)
}
}, [])
Expand Down Expand Up @@ -39,7 +42,9 @@ export function useLocalStorage<T>(
setStoredValue(valueToStore)
window.localStorage.setItem(key, JSON.stringify(valueToStore))
window.dispatchEvent(new Event('storage'))
} catch {}
} catch (error) {
logger.error(error)
}
}

return [storedValue, setValue]
Expand Down
13 changes: 13 additions & 0 deletions apps/connector/src/lib/desktop-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { WebSocketProvider } from 'ethers'

import { config } from '~config'

import { logger } from './logger'

import type { RequestArguments } from '~lib/request-arguments'
import type { WebSocketLike } from 'ethers'

Expand All @@ -19,6 +21,7 @@ export class DesktopClient {
return
}

logger.info('stop::')
this.#rpcClient?.destroy()
this.#rpcClient = null

Expand All @@ -27,6 +30,7 @@ export class DesktopClient {

public async send(args: DesktopRequestArguments) {
if (!this.#rpcClient) {
logger.info('start::')
this.#rpcClient = new WebSocketProvider(
config.desktop.rpc.url,
'mainnet',
Expand All @@ -41,6 +45,11 @@ export class DesktopClient {

await waitUntilOpen(this.#rpcClient.websocket)

logger.info('client::', {
method: config.desktop.rpc.method,
params: [JSON.stringify(args)],
})

return await this.#rpcClient.send(config.desktop.rpc.method, [
JSON.stringify(args),
])
Expand Down Expand Up @@ -71,6 +80,10 @@ async function waitUntilOpen(websocket: WebSocketLike) {
reject(new Error('Timed out to connect to the RPC server'))
}, 30 * 1000)

if (websocket.readyState === WebSocket.CONNECTING) {
logger.warn('Waiting for the RPC server to connect')
}

const onopen = websocket.onopen?.bind(websocket)
websocket.onopen = event => {
onopen?.(event)
Expand Down
Loading

0 comments on commit d8d683a

Please sign in to comment.