rpc-client.js
1 /*! 2 * lib/bitcoind_rpc/rpc-client.js 3 * Copyright © 2019 – Katana Cryptographic Ltd. All Rights Reserved. 4 */ 5 6 7 import { RPCClient } from 'rpc-bitcoin' 8 9 import network from '../bitcoin/network.js' 10 import keysFile from '../../keys/index.js' 11 import util from '../util.js' 12 import Logger from '../logger.js' 13 14 const keys = keysFile[network.key] 15 16 /** 17 * @typedef {import('rpc-bitcoin').RPCIniOptions} RPCIniOptions 18 */ 19 20 /** 21 * Wrapper for bitcoind rpc client 22 * @param {RPCIniOptions=} options 23 * @returns {RPCClient} 24 */ 25 export const createRpcClient = (options = {}) => { 26 return new RPCClient({ 27 url: `http://${keys.bitcoind.rpc.host}`, 28 port: keys.bitcoind.rpc.port, 29 user: keys.bitcoind.rpc.user, 30 pass: keys.bitcoind.rpc.pass, 31 timeout: 2 * 60 * 1000, // 2 minutes 32 ...options 33 }) 34 } 35 36 /** 37 * Check if an error returned by bitcoin-rpc-client 38 * is a connection error. 39 * @param {string} error - error message 40 * @returns {boolean} returns true if message related to a connection error 41 */ 42 export const isConnectionError = (error) => { 43 if (typeof error !== 'string') 44 return false 45 46 const isTimeoutError = (error.includes('connect ETIMEDOUT')) 47 const isConnRejected = (error.includes('Connection Rejected')) 48 49 return (isTimeoutError || isConnRejected) 50 } 51 52 /** 53 * Check if the rpc api is ready to process requests 54 * @returns {Promise<void>} 55 */ 56 export const waitForBitcoindRpcApi = async () => { 57 let client = createRpcClient() 58 59 try { 60 const networkInfo = await client.getnetworkinfo() 61 62 if (networkInfo.subversion.includes('Knots')) { 63 Logger.error(null, `Unsupported Bitcoin client detected: ${networkInfo.subversion}. Exiting...`) 64 process.exit(0) 65 } 66 } catch { 67 client = null 68 Logger.info('Bitcoind RPC : API is still unreachable. New attempt in 20s.') 69 await util.delay(20000) 70 return await waitForBitcoindRpcApi() 71 } 72 }