import { CONST , logging , u , wallet } from "@cityofzion/neon-core" ; import * as internal from "../../settings" ; import axios from "axios" ; import { filterHttpsOnly , findGoodNodesFromHeight , getBestUrl , PastTransaction , RpcNode , } from "../common" ; import { NeoscanBalance , NeoscanClaim , NeoscanPastTx , NeoscanTx , NeoscanV1GetBalanceResponse , NeoscanV1GetClaimableResponse , NeoscanV1GetHeightResponse , NeoscanV1GetUnclaimedResponse , } from "./responses" ; const log = logging . default ( "api" ) ; function parseUnspent ( unspentArr ) { return unspentArr . map ( ( coin ) => { return { index : coin . n , txid : coin . txid , value : coin . value , } ; } ) ; } function parseClaims ( claimArr ) { return claimArr . map ( ( c ) => { return { start : c . start_height , end : c . end_height , index : c . n , claim : c . unclaimed , txid : c . txid , value : c . value , } ; } ) ; } function getChange ( vin , vout , assetId ) { const totalOut = vin . filter ( ( i ) => i . asset === assetId ) . reduce ( ( p , c ) => p . add ( c . value ) , new u . Fixed8 ( 0 ) ) ; const totalIn = vout . filter ( ( i ) => i . asset === assetId ) . reduce ( ( p , c ) => p . add ( c . value ) , new u . Fixed8 ( 0 ) ) ; return totalIn . minus ( totalOut ) ; } function parseTxHistory ( rawTxs , address ) { return rawTxs . map ( ( tx ) => { const vin = tx . vin . filter ( ( i ) => i . address_hash === address ) . map ( ( i ) => ( { asset : i . asset , value : i . value } ) ) ; const vout = tx . vouts . filter ( ( o ) => o . address_hash === address ) . map ( ( i ) => ( { asset : i . asset , value : i . value } ) ) ; const change = { NEO : getChange ( vin , vout , CONST . ASSET_ID . NEO ) , GAS : getChange ( vin , vout , CONST . ASSET_ID . GAS ) , } ; return { txid : tx . txid , blockHeight : tx . block_height , change , } ; } ) ; } param url returns export async function getRPCEndpoint ( url ) { const response = await axios . get ( url + "/v1/get_all_nodes" ) ; let nodes = response . data as RpcNode [ ] ; if ( internal . settings . httpsOnly ) { nodes = filterHttpsOnly ( nodes ) ; } const goodNodes = findGoodNodesFromHeight ( nodes ) ; const bestRPC = await getBestUrl ( goodNodes ) ; return bestRPC ; } param url param address return export async function getBalance ( url , address ) { const response = await axios . get ( url + "/v1/get_balance/" + address ) ; const data = response . data as NeoscanV1GetBalanceResponse ; if ( data . address === "not found" && data . balance === null ) { return new wallet . Balance ( { net : url , address } ) ; } const bal = new wallet . Balance ( { net : url , address : data . address , } ) ; const neoscanBalances = data . balance as NeoscanBalance [ ] ; for ( const b of neoscanBalances ) { if ( b . amount > 0 && b . unspent . length > 0 ) { bal . addAsset ( b . asset , { unspent : parseUnspent ( b . unspent ) , } as Partial < wallet . AssetBalanceLike > ) ; } else { bal . addToken ( b . asset , b . amount ) ; } } log . info ( `Retrieved Balance for ${ address } from neoscan ${ url }` ) ; return bal ; } param url param address return export async function getClaims ( url , address ) { const response = await axios . get ( url + "/v1/get_claimable/" + address ) ; const data = response . data as NeoscanV1GetClaimableResponse ; if ( data . address === "not found" && data . claimable === null ) { return new wallet . Claims ( { address : data . address } ) ; } const claims = parseClaims ( data . claimable as NeoscanClaim [ ] ) ; log . info ( `Retrieved Claims for ${ address } from neoscan ${ url }` ) ; return new wallet . Claims ( { net : url , address : data . address , claims , } ) ; } param url param address return export async function getMaxClaimAmount ( url , address ) { const response = await axios . get ( url + "/v1/get_unclaimed/" + address ) ; const data = response . data as NeoscanV1GetUnclaimedResponse ; log . info ( `Retrieved maximum amount of gas claimable after spending all NEO for ${ address } from neoscan ${ url }` ) ; return new u . Fixed8 ( data . unclaimed || 0 ) ; } param url return export async function getHeight ( url ) { const response = await axios . get ( url + "/v1/get_height" ) ; const data = response . data as NeoscanV1GetHeightResponse ; return data . height ; } param { string } net param { string } address return { Promise < PastTransaction [ ] > } export async function getTransactionHistory ( url , address ) { const response = await axios . get ( url + "/v1/get_last_transactions_by_address/" + address ) ; const data = response . data as NeoscanPastTx [ ] ; log . info ( `Retrieved History for ${ address } from neoscan ${ url }` ) ; return parseTxHistory ( data , address ) ; }