import { JSONPath } from 'jsonpath-plus' ; import * as TezosRPCTypes from '../../types/tezos/TezosRPCResponseTypes' ; import { TezosRequestError } from '../../types/tezos/TezosErrorTypes' ; import { TezosConstants } from '../../types/tezos/TezosConstants' ; import FetchSelector from '../../utils/FetchSelector' ; import LogSelector from '../../utils/LoggerSelector' ; const log = LogSelector . log ; const fetch = FetchSelector . fetch ; /**
 * Utility functions for interacting with a Tezos node.
 */ export namespace TezosNodeReader { param { string } server param { string } command returns { Promise < object > } function performGetRequest ( server , command ) { const url = `${ server }/${ command }` ; return fetch ( url , { method : 'get' } ) . then ( response => { if ( ! response . ok ) { log . error ( `TezosNodeReader.performGetRequest error: ${ response . status } for ${ command } on ${ server }` ) ; throw new TezosRequestError ( response . status , response . statusText , url , null ) ; } return response ; } ) . then ( response => { const json = response . json ( ) ; log . debug ( `TezosNodeReader.performGetRequest response: ${ json } for ${ command } on ${ server }` ) ; return json ; } ) ; } param { string } server param { string } accountHash returns export async function getDelegate ( server , accountHash ) { const contractData = await getAccountForBlock ( server , 'head' , accountHash ) ; return contractData . delegate ; } param { string } server param { string } hash param { string } chainid returns { Promise < TezosRPCTypes . TezosBlock > } export function getBlock ( server , hash = 'head' , chainid = 'main' ) { return performGetRequest ( server , `chains/${ chainid }/blocks/${ hash }` ) . then ( json => { return < TezosRPCTypes . TezosBlock > json ; } ) ; } param { string } server returns { Promise < TezosRPCTypes . TezosBlock > } export function getBlockHead ( server ) { return getBlock ( server ) ; } param { string } server param { number } offset param { string } chainid export async function getBlockAtOffset ( server , offset , chainid = 'main' ) { if ( offset <= 0 ) { return getBlock ( server ) ; } const head = await getBlock ( server ) ; return performGetRequest ( server , `chains/${ chainid }/blocks/${ Number ( head [ 'header' ] [ 'level' ] ) - offset }` ) . then ( json => { return < TezosRPCTypes . TezosBlock > json ; } ) ; } param { string } server param { string } blockHash param { string } accountHash param { string } chainid returns { Promise < Account > } export function getAccountForBlock ( server , blockHash , accountHash , chainid = 'main' ) { return performGetRequest ( server , `chains/${ chainid }/blocks/${ blockHash }/context/contracts/${ accountHash }` ) . then ( json => < TezosRPCTypes . Contract > json ) ; } param { string } server param { string } accountHash param { string } chainid returns { Promise < number > } export async function getCounterForAccount ( server , accountHash , chainid = 'main' ) { const counter = await performGetRequest ( server , `chains/${ chainid }/blocks/head/context/contracts/${ accountHash }/counter` ) . then ( r => r . toString ( ) ) ; return parseInt ( counter . toString ( ) , 10 ) ; } param { string } server param { string } accountHash param chainid export async function getSpendableBalanceForAccount ( server , accountHash , chainid = 'main' ) { const account = await performGetRequest ( server , `chains/${ chainid }/blocks/head/context/contracts/${ accountHash }` ) . then ( json => < TezosRPCTypes . Contract > json ) ; return parseInt ( account . balance . toString ( ) , 10 ) ; } param { string } server param { string } block param { string } accountHash param { string } chainid returns { Promise < string > } export async function getAccountManagerForBlock ( server , block , accountHash , chainid = 'main' ) { const key = await performGetRequest ( server , `chains/${ chainid }/blocks/${ block }/context/contracts/${ accountHash }/manager_key` ) ; return key ? key . toString ( ) : '' ; } param { string } server param { string } accountHash returns { Promise < boolean > } export async function isImplicitAndEmpty ( server , accountHash ) { const account = await getAccountForBlock ( server , 'head' , accountHash ) ; const isImplicit = accountHash . toLowerCase ( ) . startsWith ( 'tz' ) ; const isEmpty = Number ( account . balance ) === 0 ; return ( isImplicit && isEmpty ) ; } param { string } server param { string } accountHash returns { Promise < boolean > } export async function isManagerKeyRevealedForAccount ( server , accountHash ) { const managerKey = await getAccountManagerForBlock ( server , 'head' , accountHash ) ; return managerKey . length > 0 ; } export function getContractStorage ( server , accountHash , block = 'head' , chainid = 'main' ) { return performGetRequest ( server , `chains/${ chainid }/blocks/${ block }/context/contracts/${ accountHash }/storage` ) ; } param { string } server param index param key param { string } block param { string } chainid export function getValueForBigMapKey ( server , index , key , block = 'head' , chainid = 'main' ) { return performGetRequest ( server , `chains/${ chainid }/blocks/${ block }/context/big_maps/${ index }/${ key }` ) ; } param { string } server param { string } operationGroupId param { string } chainid export async function getMempoolOperation ( server , operationGroupId , chainid = 'main' ) { const mempoolContent = await performGetRequest ( server , `chains/${ chainid }/mempool/pending_operations` ) . catch ( ( ) => undefined ) ; const jsonresult = JSONPath ( { path : `$.applied[?(@.hash=='${ operationGroupId }')]` , json : mempoolContent } ) ; return jsonresult [ 0 ] ; } param { string } server param { string } branch param { string } chainid returns { Promise < number > } export async function estimateBranchTimeout ( server , branch , chainid = 'main' ) { const refBlock = getBlock ( server , branch , chainid ) ; const headBlock = getBlock ( server , 'head' , chainid ) ; var result = await Promise . all ( [ refBlock , headBlock ] ) . then ( blocks => Number ( blocks [ 1 ] [ 'header' ] [ 'level' ] ) - Number ( blocks [ 0 ] [ 'header' ] [ 'level' ] ) ) ; return TezosConstants . MaxBranchOffset - result ; } param { string } server param accountHash param { string } chainid export async function getMempoolOperationsForAccount ( server , accountHash , chainid = 'main' ) { const mempoolContent = await performGetRequest ( server , `chains/${ chainid }/mempool/pending_operations` ) . catch ( ( ) => undefined ) ; const a = mempoolContent . applied . filter ( g => g . contents . some ( s => ( s . source === accountHash || s . destination === accountHash ) ) ) ; const o = a . map ( g => { g . contents = g . contents . filter ( s => ( s . source === accountHash || s . destination === accountHash ) ) ; return g ; } ) ; return o ; } param { string } server param { string } chainid export async function getChainId ( server , chainid = 'main' ) { return performGetRequest ( server , `chains/${ chainid }/chain_id` ) . then ( r => r . toString ( ) ) ; } }