import axios , { AxiosRequestConfig } from "axios" ; import { DEFAULT_REQ } from "../consts" ; import { compareArray } from "../helper" ; import logger from "../logging" ; import { timeout } from "../settings" ; import { BaseTransaction } from "../tx/transaction/BaseTransaction" ; const log = logger ( "rpc" ) ; export interface RPCRequest { method : string ; params : any [ ] ; id : number ; } export interface RPCResponse { jsonrpc : string ; id : number ; result : any ; error ? : RPCErrorResponse ; } export interface RPCErrorResponse { code : number ; message : string ; } param url param req param config returns export async function queryRPC ( url , req , config = { } ) { const body = Object . assign ( { } , DEFAULT_REQ , req ) ; const conf = Object . assign ( { headers : { "Content-Type" : "application/json" } , timeout : timeout . rpc , } , config ) ; const response = await axios . post ( url , body , conf ) ; return response . data ; } /**
 * A Query object helps us to construct and record requests
 */ export class Query { param addr public static getAccountState ( addr ) { return new Query ( { method : "getaccountstate" , params : [ addr ] , } ) ; } param assetId public static getAssetState ( assetId ) { return new Query ( { method : "getassetstate" , params : [ assetId ] , } ) ; } param indexOrHash param verbose public static getBlock ( indexOrHash , verbose = 1 ) { return new Query ( { method : "getblock" , params : [ indexOrHash , verbose ] , } ) ; } param { number } index public static getBlockHash ( index ) { return new Query ( { method : "getblockhash" , params : [ index ] , } ) ; } /**
     * This Query returns the hash of the highest block.
     */ public static getBestBlockHash ( ) { return new Query ( { method : "getbestblockhash" , } ) ; } /**
     * This Query returns the current block height.
     */ public static getBlockCount ( ) { return new Query ( { method : "getblockcount" , } ) ; } param index public static getBlockSysFee ( index ) { return new Query ( { method : "getblocksysfee" , params : [ index ] , } ) ; } /**
     * This Query returns the number of other nodes that this node is connected to.
     */ public static getConnectionCount ( ) { return new Query ( { method : "getconnectioncount" , } ) ; } param scriptHash public static getContractState ( scriptHash ) { return new Query ( { method : "getcontractstate" , params : [ scriptHash ] , } ) ; } /**
     * This Query returns the list of nodes that this node is connected to.
     */ public static getPeers ( ) { return new Query ( { method : "getpeers" , } ) ; } /**
     * This Query returns the transaction hashes of the transactions waiting to be processed at the node.
     */ public static getRawMemPool ( ) { return new Query ( { method : "getrawmempool" , } ) ; } param txid param verbose public static getRawTransaction ( txid , verbose = 1 ) { return new Query ( { method : "getrawtransaction" , params : [ txid , verbose ] , } ) ; } param scriptHash param key public static getStorage ( scriptHash , key ) { return new Query ( { method : "getstorage" , params : [ scriptHash , key ] , } ) ; } param txid param index public static getTxOut ( txid , index ) { return new Query ( { method : "gettxout" , params : [ txid , index ] , } ) ; } return public static getValidators ( ) { return new Query ( { method : "getvalidators" , } ) ; } /**
     * This Query returns the node version.
     */ public static getVersion ( ) { return new Query ( { method : "getversion" , } ) ; } param scriptHash param params public static invoke ( scriptHash , ... params ) { return new Query ( { method : "invoke" , params : [ scriptHash , params ] , } ) ; } param scriptHash param operation param params public static invokeFunction ( scriptHash , operation , ... params ) { return new Query ( { method : "invokefunction" , params : [ scriptHash , operation , params ] , } ) ; } param script public static invokeScript ( script ) { return new Query ( { method : "invokescript" , params : [ script ] , } ) ; } param transaction public static sendRawTransaction ( transaction ) { const serialized = transaction instanceof BaseTransaction ? transaction . serialize ( true ) : transaction ; return new Query ( { method : "sendrawtransaction" , params : [ serialized ] , } ) ; } param block public static submitBlock ( block ) { return new Query ( { method : "submitblock" , params : [ block ] , } ) ; } param addr public static validateAddress ( addr ) { return new Query ( { method : "validateaddress" , params : [ addr ] , } ) ; } param addr public static getUnspents ( addr ) { return new Query ( { method : "getunspents" , params : [ addr ] , } ) ; } param addr public static getUnclaimed ( addr ) { return new Query ( { method : "getunclaimed" , params : [ addr ] , } ) ; } param addr public static getClaimable ( addr ) { return new Query ( { method : "getclaimable" , params : [ addr ] , } ) ; } public req : RPCRequest ; public res : any ; public completed : boolean ; public parse ? : ( res : any ) => any ; public get id ( ) : number { return this . req . id ; } public get method ( ) : string { return this . req . method ; } public get params ( ) : any [ ] { return this . req . params ; } public constructor ( req ) { this . req = Object . assign ( { } , DEFAULT_REQ , req ) ; this . completed = false ; } public get [ Symbol . toStringTag ] ( ) : string { return "Query" ; } /**
     * Attaches a parser method to the Query. This method will be used to parse the response.
     */ public parseWith ( parser ) { this . parse = parser ; return this ; } param url param config public async execute ( url , config = { } ) { if ( this . completed ) { throw new Error ( "This request has been sent" ) ; } const response = await queryRPC ( url , this . req , config ) ; this . res = response ; this . completed = true ; if ( response . error ) { throw new Error ( `${ url }: ${ response . error . message }` ) ; } if ( this . parse ) { log . info ( `Query[${ this . req . method }] successful` ) ; return this . parse ( response . result ) ; } return response ; } public export ( ) { return Object . assign ( { } , this . req , { params : this . req . params . map ( ( p ) => { if ( typeof p === "object" ) { return JSON . parse ( JSON . stringify ( p ) ) ; } return p ; } ) , } ) ; } public equals ( other ) { return ( this . req . id === other . id && this . req . method === other . method && compareArray ( this . req . params , other . params || [ ] ) ) ; } } export default Query ;