/ test-api / src / utils / rpcUtils.js
rpcUtils.js
  1  import axios from 'axios';
  2  import { getProxyUrl, getApiConfig, handleApiError } from './apiUtils';
  3  
  4  /**
  5   * Make a JSON-RPC request to the proxy
  6   * @param {string} method - RPC method name
  7   * @param {Array} params - RPC method parameters
  8   * @param {string} network - Network path (e.g., 'ethereum/mainnet')
  9   * @param {string} token - Optional JWT token
 10   * @param {Object} basicAuth - Optional basic auth {username, password}
 11   * @returns {Promise<Object>} RPC response or error
 12   */
 13  export const makeRpcRequest = async (method, params = [], network = 'ethereum/mainnet', token = null, basicAuth = null) => {
 14    try {
 15      const proxyUrl = getProxyUrl();
 16      const rpcPayload = {
 17        jsonrpc: '2.0',
 18        method: method,
 19        params: params,
 20        id: 1  // Use constant ID for better caching since we handle requests synchronously
 21      };
 22  
 23      console.log(`Making ${method} request to ${network}:`, rpcPayload);
 24      
 25      const response = await axios.post(
 26        `${proxyUrl}/${network}`, 
 27        rpcPayload, 
 28        getApiConfig(token, basicAuth)
 29      );
 30  
 31      console.log(`${method} response:`, response.data);
 32  
 33      return {
 34        success: true,
 35        data: response.data,
 36        method: method,
 37        network: network,
 38        timestamp: new Date().toLocaleString()
 39      };
 40    } catch (error) {
 41      console.error(`Error making ${method} request:`, error);
 42      const errorInfo = handleApiError(error);
 43      
 44      return {
 45        success: false,
 46        error: errorInfo,
 47        method: method,
 48        network: network,
 49        timestamp: new Date().toLocaleString()
 50      };
 51    }
 52  };
 53  
 54  /**
 55   * Make a permanent cache RPC request (eth_chainId)
 56   * @param {string} network - Network path
 57   * @param {string} token - Optional JWT token
 58   * @param {Object} basicAuth - Optional basic auth
 59   * @returns {Promise<Object>} RPC response or error
 60   */
 61  export const makePermanentCacheRequest = async (network = 'ethereum/mainnet', token = null, basicAuth = null) => {
 62    const result = await makeRpcRequest('eth_chainId', [], network, token, basicAuth);
 63    return { ...result, cacheType: 'permanent' };
 64  };
 65  
 66  /**
 67   * Make a short cache RPC request (eth_blockNumber)
 68   * @param {string} network - Network path
 69   * @param {string} token - Optional JWT token
 70   * @param {Object} basicAuth - Optional basic auth
 71   * @returns {Promise<Object>} RPC response or error
 72   */
 73  export const makeShortCacheRequest = async (network = 'ethereum/mainnet', token = null, basicAuth = null) => {
 74    const result = await makeRpcRequest('eth_blockNumber', [], network, token, basicAuth);
 75    return { ...result, cacheType: 'short' };
 76  };
 77  
 78  /**
 79   * Make a minimal cache RPC request (eth_gasPrice)
 80   * @param {string} network - Network path
 81   * @param {string} token - Optional JWT token
 82   * @param {Object} basicAuth - Optional basic auth
 83   * @returns {Promise<Object>} RPC response or error
 84   */
 85  export const makeMinimalCacheRequest = async (network = 'ethereum/mainnet', token = null, basicAuth = null) => {
 86    const result = await makeRpcRequest('eth_gasPrice', [], network, token, basicAuth);
 87    return { ...result, cacheType: 'minimal' };
 88  };
 89  
 90  /**
 91   * Make multiple RPC requests in parallel
 92   * @param {Array} requests - Array of request objects {method, params, cacheType}
 93   * @param {string} network - Network path
 94   * @param {string} token - Optional JWT token
 95   * @param {Object} basicAuth - Optional basic auth
 96   * @returns {Promise<Array>} Array of RPC responses
 97   */
 98  export const makeParallelRpcRequests = async (requests, network = 'ethereum/mainnet', token = null, basicAuth = null) => {
 99    const promises = requests.map(request => {
100      const result = makeRpcRequest(request.method, request.params || [], network, token, basicAuth);
101      if (request.cacheType) {
102        return result.then(r => ({ ...r, cacheType: request.cacheType }));
103      }
104      return result;
105    });
106  
107    try {
108      return await Promise.all(promises);
109    } catch (error) {
110      console.error('Error in parallel RPC requests:', error);
111      throw error;
112    }
113  };
114  
115  /**
116   * Make all three cache type requests (permanent, short, minimal)
117   * @param {string} network - Network path
118   * @param {string} token - Optional JWT token
119   * @param {Object} basicAuth - Optional basic auth
120   * @returns {Promise<Object>} Object with results for each cache type
121   */
122  export const makeAllCacheTypeRequests = async (network = 'ethereum/mainnet', token = null, basicAuth = null) => {
123    try {
124      const requests = [
125        { method: 'eth_chainId', params: [], cacheType: 'permanent' },
126        { method: 'eth_blockNumber', params: [], cacheType: 'short' },
127        { method: 'eth_gasPrice', params: [], cacheType: 'minimal' }
128      ];
129  
130      const results = await makeParallelRpcRequests(requests, network, token, basicAuth);
131      
132      return {
133        permanent: results[0],
134        short: results[1],
135        minimal: results[2]
136      };
137    } catch (error) {
138      console.error('Error making all cache type requests:', error);
139      throw error;
140    }
141  };
142  
143  /**
144   * Test RPC connectivity with basic method
145   * @param {string} network - Network path
146   * @param {string} token - Optional JWT token
147   * @param {Object} basicAuth - Optional basic auth
148   * @returns {Promise<Object>} Connection test result
149   */
150  export const testRpcConnectivity = async (network = 'ethereum/mainnet', token = null, basicAuth = null) => {
151    const startTime = Date.now();
152    
153    try {
154      const result = await makeRpcRequest('eth_blockNumber', [], network, token, basicAuth);
155      const responseTime = Date.now() - startTime;
156      
157      return {
158        success: result.success,
159        network: network,
160        responseTime: responseTime,
161        blockNumber: result.success ? result.data.result : null,
162        error: result.success ? null : result.error,
163        timestamp: new Date().toLocaleString()
164      };
165    } catch (error) {
166      const responseTime = Date.now() - startTime;
167      return {
168        success: false,
169        network: network,
170        responseTime: responseTime,
171        blockNumber: null,
172        error: handleApiError(error),
173        timestamp: new Date().toLocaleString()
174      };
175    }
176  };
177  
178  /**
179   * Format RPC result for display
180   * @param {Object} result - RPC result object
181   * @returns {Object} Formatted result for UI display
182   */
183  export const formatRpcResult = (result) => {
184    if (!result) return null;
185  
186    return {
187      method: result.method,
188      network: result.network,
189      cacheType: result.cacheType || 'unknown',
190      timestamp: result.timestamp,
191      success: result.success,
192      responseData: result.success ? result.data : null,
193      error: result.success ? null : result.error,
194      displayValue: result.success ? result.data.result : 'Error'
195    };
196  };
197  
198  /**
199   * Get display color for cache type
200   * @param {string} cacheType - Cache type (permanent, short, minimal)
201   * @returns {string} CSS color value
202   */
203  export const getCacheTypeColor = (cacheType) => {
204    switch (cacheType) {
205      case 'permanent':
206        return '#4CAF50';
207      case 'short':
208        return '#FF9800';
209      case 'minimal':
210        return '#2196F3';
211      default:
212        return '#666';
213    }
214  };
215  
216  /**
217   * Get display emoji for cache type
218   * @param {string} cacheType - Cache type (permanent, short, minimal)
219   * @returns {string} Emoji character
220   */
221  export const getCacheTypeEmoji = (cacheType) => {
222    switch (cacheType) {
223      case 'permanent':
224        return '🔒';
225      case 'short':
226        return '⏱️';
227      case 'minimal':
228        return '⚡';
229      default:
230        return '❓';
231    }
232  };