/ src / utils / ServerJsonRpcProvider.ts
ServerJsonRpcProvider.ts
 1  import { Network } from '@ethersproject/networks';
 2  import { StaticJsonRpcProvider } from '@ethersproject/providers';
 3  
 4  /**
 5   * A JsonRpcProvider that routes requests through the server to keep private RPC URLs hidden
 6   */
 7  
 8  export class ServerJsonRpcProvider extends StaticJsonRpcProvider {
 9    private readonly chainId: number;
10  
11    constructor(chainId: number) {
12      // Use a dummy URL that will never be used
13      super('http://localhost', chainId);
14      this.chainId = chainId;
15    }
16  
17    /**
18     * Override the send method to route through our API instead of direct to RPC
19     * @param method The JSON-RPC method to call
20     * @param params The parameters for the JSON-RPC method
21     * @returns The result from the JSON-RPC method
22     */
23    // eslint-disable-next-line @typescript-eslint/no-explicit-any
24    public async send<P = any, R = any>(method: string, params: Array<P>): Promise<R> {
25      const apiUrl = '/api/rpc-proxy/';
26  
27      try {
28        const response = await fetch(apiUrl, {
29          method: 'POST',
30          headers: {
31            'Content-Type': 'application/json',
32          },
33          body: JSON.stringify({
34            chainId: this.chainId,
35            method,
36            params,
37          }),
38        });
39  
40        if (!response.ok) {
41          const errorText = await response.text();
42          try {
43            const errorData = JSON.parse(errorText);
44            throw new Error(errorData.error || `Failed with status ${response.status}`);
45          } catch (e) {
46            throw new Error(`Failed with status ${response.status}: ${errorText}`);
47          }
48        }
49  
50        const data = await response.json();
51  
52        if (data.error) {
53          throw new Error(data.error.message || 'RPC error');
54        }
55  
56        return data.result as R;
57      } catch (error) {
58        console.error('Error making RPC request through server proxy:', error);
59        throw error;
60      }
61    }
62  
63    // Override detectNetwork to manually set the network to avoid making requests
64    public async detectNetwork(): Promise<Network> {
65      return this.network;
66    }
67  }