import { Coin, AccountMap, TransactionMap, SubscriptionResponse, ErrorResponse, SuccessResponse, parseResponse, parseSubResponse } from "frontblock-generic/Types"; import { FrontblockApi as FrontblockApi } from "frontblock-generic/Api"; import { Plugin, socketioRPC } from "frontblock-generic/Plugin" import * as Logger from 'log4js' Logger.configure({ appenders: { "frontblock-api-client": { type: 'stdout' }, //app: { type: 'file', filename: 'application.log' } }, categories: { default: { appenders: [ 'frontblock-api-client' ], level: 'debug' } } }) const logger = Logger.getLogger("frontblock-api-client") const bsock = require('bsock') export type FrontblockApiConf = { apiHost:string apiPort:number tls?:boolean apiKey?:string } /** * Frontblock api connection lib * * Can be used solo and also is a valid frontblock plugin on the customer-side */ export default class FrontblockApiClient implements FrontblockApi, Plugin{ name: string = 'ApiClient' protected apikey:string = "" protected conf:FrontblockApiConf; protected socket private started:boolean = false constructor(conf?:FrontblockApiConf){ if(conf == null){ conf = { apiHost: "localhost", apiKey: "", apiPort: 10000, tls: false } this.conf = conf }else{ if(conf.apiKey != null) this.apikey = conf.apiKey this.conf = conf } } exportRPCs(): socketioRPC[] { const quit = async(uid:string) => {return await this.quit(this.apikey, uid) } return [ { name: "subscribe", rpc: async (coin: C, account: AccountMap[C]) => { return await this.subscribe(this.apikey, coin, account)}, type: 'call', visibility: 'private' },{ name: "subsume", rpc: async (coin: C, account: AccountMap[C], callback: (tx: TransactionMap[C]) => void) => { return await this.subsume(this.apikey, coin, account, callback)}, type: 'hook', unhook: quit, visibility: 'private' },{ name: 'unsubscribe', rpc: async(uid:string) => { return await this.unsubscribe(this.apikey, uid) }, type: 'unhook', visibility: 'private' },{ name: 'consume', rpc: async(uid: string, callback: (tx: TransactionMap[C]) => void) => {return await this.consume(this.apikey, uid, callback)}, type: 'hook', unhook: quit, visibility: 'private' },{ name: 'quit', rpc: async(consumerUid:string) => {return await this.quit(this.apikey, consumerUid)}, type: 'call', visibility: 'private' } ] } start(): void { if(this.started){ logger.warn("FrontblockApiClient has already been started. Ignoring") return } logger.info("Starting apiClient with ", this.conf) this.socket = bsock.connect(this.conf.apiPort, this.conf.apiHost, this.conf.tls!=null?this.conf.tls:false) this.started = true } stop(): void { if(!this.started){ logger.warn("FrontblockApiClient has not been started. Ignoring") return } this.socket.close() } async consume(apikey: string, uid: string, callback: (tx: TransactionMap[C]) => void): Promise { const r = await this.socket.call("consume", apikey, uid) const res = parseSubResponse(r) if(res instanceof SubscriptionResponse){ this.socket.hook(res.uid, callback) } return res } async quit(apikey: string, consumerUid: string): Promise { const r = await this.socket.call("quit", apikey, consumerUid) const res = parseResponse(r) return res } async subscribe(apikey: string, coin: C, account: AccountMap[C]): Promise { const r = await this.socket.call("subscribe", apikey, coin, account) const res = parseSubResponse(r) return res } async subsume(apikey: string, coin: C, account: AccountMap[C], callback: (tx: TransactionMap[C]) => void): Promise { const r = await this.socket.call("subsume", apikey, coin, account) const res = parseSubResponse(r) if(res instanceof SubscriptionResponse){ this.socket.hook(res.uid, callback) } return res } async unsubscribe(apikey:string, uid: string): Promise { const r = await this.socket.call('unsubscribe', apikey, uid) const res = parseResponse(r) if(res instanceof SuccessResponse) this.socket.unhook(uid) return res } async getPluginList(): Promise { return await this.socket.call('getPluginList') } }