Skip to content

Commit 9bc5a01

Browse files
committed
Add HealthCheckService to monitor web3 connections
1 parent d7a0e7d commit 9bc5a01

2 files changed

Lines changed: 75 additions & 0 deletions

File tree

apps/iframe/src/main.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,13 @@ import "./index.css"
88
import type { Logger } from "@happy.tech/common"
99
import { QueryClientProvider } from "@tanstack/react-query"
1010
import { WagmiProvider } from "wagmi"
11+
import { HealthCheckService } from "#src/services/HealthCheckService"
1112
import { queryClient } from "./tanstack-query/config"
1213
import { logger } from "./utils/logger"
1314
import { config } from "./wagmi/config"
1415

16+
HealthCheckService.start()
17+
1518
const router = createRouter({ routeTree })
1619

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

0 commit comments

Comments
 (0)