'use strict' ; import * as vscode from 'vscode' ; import { TransactionView } from '../webview/TransactionView' ; import { IBlockchainQuickPickItem , UserInputUtil } from './UserInputUtil' ; import { FabricGatewayConnectionManager } from '../fabric/FabricGatewayConnectionManager' ; import { VSCodeBlockchainOutputAdapter } from '../logging/VSCodeBlockchainOutputAdapter' ; import { ExtensionCommands } from '../../ExtensionCommands' ; import { InstantiatedTreeItem } from '../explorer/model/InstantiatedTreeItem' ; import { IFabricGatewayConnection , FabricSmartContractDefinition , LogType , FabricGatewayRegistryEntry } from 'ibm-blockchain-platform-common' ; import { GlobalState } from '../util/GlobalState' ; import ITransaction from '../interfaces/ITransaction' ; import ISmartContract from '../interfaces/ISmartContract' ; import IAssociatedTxData from '../interfaces/IAssociatedTxData' ; import { ContractTreeItem } from '../explorer/model/ContractTreeItem' ; interface IAppState { gatewayName : string ; smartContracts : ISmartContract [ ] ; associatedTxdata : IAssociatedTxData ; preselectedSmartContract : ISmartContract ; preselectedTransaction : ITransaction ; } export async function getSmartContracts ( connection , smartContractName , channelName , smartContractVersion ? ) { let contract ; let data ; let smartContracts = [ ] ; const channelMap = await connection . createChannelMap ( ) ; for ( const [ thisChannelName ] of channelMap ) { if ( ! channelName || channelName === thisChannelName ) { const chaincodes = await connection . getInstantiatedChaincode ( thisChannelName ) ; const channelPeerInfo = await connection . getChannelPeersInfo ( thisChannelName ) ; const peerNames = channelPeerInfo . map ( ( peer ) => { return peer . name ; } ) ; for ( const chaincode of chaincodes ) { let metadataObj ; try { metadataObj = await connection . getMetadata ( chaincode . name , thisChannelName ) ; } catch ( error ) { if ( ( chaincode . name === smartContractName ) && ( ! smartContractVersion || chaincode . version === smartContractVersion ) ) { data = { name : chaincode . name , version : chaincode . version , channel : thisChannelName , label : chaincode . name + '@' + chaincode . version , transactions : [ ] , namespace : undefined , contractName : undefined , peerNames } ; smartContracts . push ( data ) ; } continue ; } const contractsObject = metadataObj . contracts ; Object . keys ( contractsObject ) . forEach ( ( key ) => { if ( key !== 'org.hyperledger.fabric' && ( contractsObject [ key ] . transactions . length > 0 ) ) { if ( ( chaincode . name === smartContractName ) && ( ! smartContractVersion || chaincode . version === smartContractVersion ) ) { contract = metadataObj . contracts [ key ] ; data = { name : chaincode . name , version : chaincode . version , channel : thisChannelName , label : chaincode . name + '@' + chaincode . version , transactions : contract . transactions , contractName : contract . name , namespace : contract . name , peerNames , } ; smartContracts . push ( data ) ; } } } ) ; } } } return smartContracts ; } function getPreselectedSmartContract ( smartContracts , selectedSmartContract ) { if ( smartContracts . length === 0 || ! selectedSmartContract ) { return undefined ; } else if ( smartContracts . length === 1 ) { return smartContracts [ 0 ] ; } return smartContracts . find ( ( { contractName } ) => contractName && contractName === selectedSmartContract ) ; } function getPreselectedTransaction ( smartContracts , selectedTransactionName ) { for ( const contract of smartContracts ) { const foundTransaction = contract . transactions . find ( ( { name } ) => name === selectedTransactionName ) ; if ( foundTransaction ) { return foundTransaction ; } } } export async function openTransactionView ( treeItem ? , selectedTransactionName ? ) { const outputAdapter = VSCodeBlockchainOutputAdapter . instance ( ) ; outputAdapter . log ( LogType . INFO , undefined , `Open Transaction View` ) ; let smartContractName ; let smartContractVersion ; let currentChannelName ; let connection = FabricGatewayConnectionManager . instance ( ) . getConnection ( ) ; if ( ! connection ) { await vscode . commands . executeCommand ( ExtensionCommands . CONNECT_TO_GATEWAY ) ; connection = FabricGatewayConnectionManager . instance ( ) . getConnection ( ) ; if ( ! connection ) { return ; } } const gatewayRegistryEntry = await FabricGatewayConnectionManager . instance ( ) . getGatewayRegistryEntry ( ) ; const gatewayName = gatewayRegistryEntry . name ; if ( treeItem ) { smartContractName = treeItem . instantiatedChaincode ? treeItem . instantiatedChaincode . name : treeItem . name ; if ( treeItem instanceof InstantiatedTreeItem ) { smartContractVersion = treeItem . version ; currentChannelName = treeItem . channels [ 0 ] . label ; } else { smartContractVersion = treeItem . instantiatedChaincode . version ; currentChannelName = treeItem . channelName ; } } else { const chosenChannel = await UserInputUtil . showChannelFromGatewayQuickPickBox ( 'Select a channel' ) ; if ( ! chosenChannel ) { return ; } currentChannelName = chosenChannel . label ; const chosenSmartContract = await UserInputUtil . showClientInstantiatedSmartContractsQuickPick ( `Choose a smart contract` , currentChannelName ) ; if ( ! chosenSmartContract ) { return ; } smartContractName = chosenSmartContract . data . name ; smartContractVersion = chosenSmartContract . data . version ; } const smartContracts = await getSmartContracts ( connection , smartContractName , currentChannelName , smartContractVersion ) ; const preselectedSmartContract = getPreselectedSmartContract ( smartContracts , treeItem && treeItem . name ) ; const preselectedTransaction = selectedTransactionName && getPreselectedTransaction ( smartContracts , selectedTransactionName ) ; const associatedTxdata = { } ; if ( gatewayRegistryEntry && gatewayRegistryEntry . transactionDataDirectories && gatewayRegistryEntry . transactionDataDirectories . length > 0 ) { await Promise . all ( gatewayRegistryEntry . transactionDataDirectories . map ( async ( { chaincodeName , channelName , transactionDataPath } ) => { const transactions = await TransactionView . readTxdataFiles ( transactionDataPath ) ; associatedTxdata [ chaincodeName ] = { channelName , transactionDataPath , transactions , } ; } ) ) ; } const appState = { gatewayName , smartContracts , preselectedSmartContract , preselectedTransaction , associatedTxdata , } ; const context = GlobalState . getExtensionContext ( ) ; const reactView = new TransactionView ( context , appState ) ; await reactView . openView ( true ) ; return appState ; }