Skip to content

Commit 15965c6

Browse files
committed
Add HealthCheckService to monitor web3 connections
1 parent 515675e commit 15965c6

File tree

3 files changed

+84
-1
lines changed

3 files changed

+84
-1
lines changed

apps/iframe/src/main.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,13 @@ import "./index.css"
1313
import type { Logger } from "@happy.tech/common"
1414
import { QueryClientProvider } from "@tanstack/react-query"
1515
import { WagmiProvider } from "wagmi"
16+
import { HealthCheckService } from "#src/services/HealthCheckService"
1617
import { queryClient } from "./tanstack-query/config"
1718
import { logger } from "./utils/logger"
1819
import { config } from "./wagmi/config"
1920

21+
HealthCheckService.start()
22+
2023
// Create a new router instance
2124
const router = createRouter({ routeTree })
2225

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import { WalletType } from "@happy.tech/wallet-common"
2+
import { getCurrentChain } from "#src/state/chains"
3+
import { getInjectedClient } from "#src/state/injectedClient"
4+
import { getPublicClient } from "#src/state/publicClient"
5+
import { getUser } from "#src/state/user"
6+
import { getWalletClient } from "#src/state/walletClient"
7+
8+
/**
9+
* TODO: pick reasonable timeframe for this check. 1 second is likely much to fast
10+
*/
11+
const HEALTH_CHECK_INTERVAL = 1000
12+
13+
/**
14+
* HealthCheckService routinely checks if the public client, wallet client, and injected client
15+
* are connected to the correct & expected chain.
16+
*
17+
* TODO: if an error arises, we should try to correct and/or display connection issues in the wallet
18+
* TODO: we should differentiate between offline, and wrong chain
19+
*/
20+
export class HealthCheckService {
21+
static #_instance: HealthCheckService
22+
23+
#interval: NodeJS.Timeout | undefined = undefined
24+
25+
private constructor() {}
26+
27+
public static get instance(): HealthCheckService {
28+
HealthCheckService.#_instance ??= new HealthCheckService()
29+
return HealthCheckService.#_instance
30+
}
31+
32+
/**
33+
* Stop monitoring web3 connections
34+
*/
35+
public static stop(): void {
36+
clearInterval(HealthCheckService.instance.#interval)
37+
HealthCheckService.instance.#interval = undefined
38+
}
39+
40+
/**
41+
* Begin monitoring web3 connections
42+
*/
43+
public static start(): void {
44+
clearInterval(HealthCheckService.instance.#interval)
45+
HealthCheckService.instance.#interval = setInterval(() => {
46+
void HealthCheckService.instance.#check().catch((e) => {
47+
console.error("Health check failed", e)
48+
})
49+
}, HEALTH_CHECK_INTERVAL)
50+
}
51+
52+
async #check() {
53+
const user = getUser()
54+
const chain = getCurrentChain()
55+
const chainId = Number(chain.chainId)
56+
57+
const publicClient = getPublicClient()
58+
const walletClient = getWalletClient()
59+
const injectedClient = getInjectedClient()
60+
const connectedClient =
61+
user?.type === WalletType.Injected
62+
? injectedClient
63+
: user?.type === WalletType.Social
64+
? walletClient
65+
: undefined
66+
67+
const [publicClientChain, connectedChainId] = await Promise.all([
68+
publicClient.getChainId(),
69+
connectedClient?.getChainId(),
70+
])
71+
72+
if (publicClientChain !== chainId)
73+
console.warn(
74+
`Public Chain mismatch. PublicClient is connected to chain: ${publicClientChain}, but expected ${chainId}`,
75+
)
76+
if (user && connectedChainId !== chainId)
77+
console.warn(
78+
`Connected Chain mismatch. WalletClient is connected to chain: ${connectedChainId}, but expected ${chainId}`,
79+
)
80+
}
81+
}

apps/iframe/src/utils/checkIfRequestRequiresConfirmation.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ export function checkIfRequestRequiresConfirmation(
2727

2828
switch (payload.method) {
2929
// Users don't need to approve permissions that have already been granted.
30-
3130
case "eth_sendTransaction":
3231
return !hasPermissions(app, {
3332
[Permissions.SessionKey]: { target: payload.params[0].to },

0 commit comments

Comments
 (0)