import path from 'path' ; import fs from 'fs-extra' ; import YAML from 'js-yaml' ; import { parse , stringify } from 'envfile' ; import CryptoConfigYaml from '../model/yaml/network/cryptoConfigYaml' ; import ConnectionProfileYaml from '../model/yaml/network/connectionProfileYaml' ; import ConfigtxYaml , { ConfigtxOrgs , OrdererOrganizationInterface , PeerOrganizationInterface } from '../model/yaml/network/configtx' ; import { ConfigEnvType } from '../model/type/config.type' ; import OrdererDockerComposeYaml from '../model/yaml/docker-compose/ordererDockerComposeYaml' ; import PeerDockerComposeYaml from '../model/yaml/docker-compose/peerDockerComposeYaml' ; import CaDockerComposeYaml from '../model/yaml/docker-compose/caComposeYaml' ; import { OrgJsonType } from '../model/type/org.type' ; import { ProcessError } from '../util' ; import { Config } from '../config' ; import { DockerComposeYamlInterface } from '../model/yaml/docker-compose/dockerComposeYaml' ; import ExplorerConnectionProfileYaml from '../model/yaml/explorer/explorerConnectionProfileYaml' ; import ExplorerConfigYaml from '../model/yaml/explorer/explorerConfigYaml' ; import ExplorerDockerComposeYaml from '../model/yaml/docker-compose/explorerDockerComposeYaml' ; export enum InstanceTypeEnum { ca = 'ca' , orderer = 'orderer' , peer = 'peer' } export default class BdkFile { private config : Config ; private bdkPath : string ; private envPath : string ; private orgPath : string ; constructor ( config , networkName = config . networkName ) { this . config = config ; this . bdkPath = `${ config . infraConfig . bdkPath }/${ networkName }` ; this . envPath = `${ config . infraConfig . bdkPath }/.env` ; this . orgPath = '' ; } public getRootFilePath ( ) { return this . bdkPath ; } public getEnv ( ) { if ( ! fs . existsSync ( this . envPath ) ) throw new ProcessError ( 'Missing process: Run <bdk config init> first' ) ; return parse ( fs . readFileSync ( this . envPath ) . toString ( ) ) as unknown as ConfigEnvType ; } public createEnv ( initEnv ) { fs . mkdirSync ( `${ this . config . infraConfig . bdkPath }` , { recursive : true } ) ; fs . writeFileSync ( this . envPath , stringify ( initEnv ) ) ; } public deleteNetworkFolder ( ) { fs . rmdirSync ( `${ this . bdkPath }` , { recursive : true } ) ; } public createNetworkFolder ( ) { fs . mkdirSync ( `${ this . bdkPath }` , { recursive : true } ) ; } public createCaFolder ( ) { fs . mkdirSync ( `${ this . bdkPath }/ca` , { recursive : true } ) ; } private createConfigYamlFolder ( ) { fs . mkdirSync ( `${ this . bdkPath }/config-yaml` , { recursive : true } ) ; } private createConfigYamlOrgsFolder ( ) { fs . mkdirSync ( `${ this . bdkPath }/config-yaml/orgs` , { recursive : true } ) ; } private createTlsFolder ( orgDomainName ) { fs . mkdirSync ( `${ this . bdkPath }/tlsca/${ orgDomainName }` , { recursive : true } ) ; } public createChannelFolder ( channelName ) { fs . mkdirSync ( `${ this . bdkPath }/channel-artifacts/${ channelName }` , { recursive : true } ) ; } public createCryptoConfigYaml ( cryptoConfigYaml ) { this . createConfigYamlFolder ( ) ; fs . writeFileSync ( `${ this . bdkPath }/config-yaml/crypto-config.yaml` , cryptoConfigYaml . getYamlString ( ) ) ; } public createConfigtx ( configtxYaml ) { this . createConfigYamlFolder ( ) ; fs . writeFileSync ( `${ this . bdkPath }/config-yaml/configtx.yaml` , configtxYaml . getYamlString ( ) ) ; } public createConfigtxPeerOrg ( peerOrg ) { this . createConfigYamlOrgsFolder ( ) ; fs . writeFileSync ( `${ this . bdkPath }/config-yaml/orgs/peer-${ peerOrg . Name }.json` , JSON . stringify ( peerOrg ) ) ; } public createConfigtxOrdererOrg ( ordererOrg ) { this . createConfigYamlOrgsFolder ( ) ; fs . writeFileSync ( `${ this . bdkPath }/config-yaml/orgs/orderer-${ ordererOrg . Name }.json` , JSON . stringify ( ordererOrg ) ) ; } public getOrdererServerCertToBase64 ( hostname , domain ) { return fs . readFileSync ( `${ this . bdkPath }/ordererOrganizations/${ domain }/orderers/${ hostname }.${ domain }/tls/server.crt` ) . toString ( 'base64' ) ; } public getConfigtxOrgs ( ) { const configtxOrgs = { ordererOrgs : { } , peerOrgs : { } , } ; fs . readdirSync ( `${ this . bdkPath }/config-yaml/orgs` ) . forEach ( ( filename ) => { const peerOrg = filename . match ( /(?<=^peer-).*(?=\.json$)/ ) ?. [ 0 ] ; const ordererOrg = filename . match ( /(?<=^orderer-).*(?=\.json$)/ ) ?. [ 0 ] ; if ( ordererOrg ) { configtxOrgs . ordererOrgs [ ordererOrg ] = JSON . parse ( fs . readFileSync ( `${ this . bdkPath }/config-yaml/orgs/${ filename }` ) . toString ( ) ) ; } else if ( peerOrg ) { configtxOrgs . peerOrgs [ peerOrg ] = JSON . parse ( fs . readFileSync ( `${ this . bdkPath }/config-yaml/orgs/${ filename }` ) . toString ( ) ) ; } } ) ; return configtxOrgs ; } public copyOrdererOrgTLSCa ( hostname , domain ) { this . createTlsFolder ( `${ hostname }.${ domain }` ) ; fs . copyFileSync ( `${ this . bdkPath }/ordererOrganizations/${ domain }/orderers/${ hostname }.${ domain }/tls/ca.crt` , `${ this . bdkPath }/tlsca/${ hostname }.${ domain }/ca.crt` ) ; } public copyPeerOrgTLSCa ( hostname , domain ) { this . createTlsFolder ( `${ hostname }.${ domain }` ) ; fs . copyFileSync ( `${ this . bdkPath }/peerOrganizations/${ domain }/peers/${ hostname }.${ domain }/tls/ca.crt` , `${ this . bdkPath }/tlsca/${ hostname }.${ domain }/ca.crt` ) ; } public getPeerOrgTlsCertString ( number , domain ) { let tlsCert = fs . readFileSync ( `${ this . bdkPath }/peerOrganizations/${ domain }/peers/peer${ number }.${ domain }/tls/ca.crt` ) . toString ( ) ; if ( fs . pathExistsSync ( `${ this . bdkPath }/peerOrganizations/${ domain }/peers/peer${ number }.${ domain }/tls/tlscacerts` ) ) { tlsCert = tlsCert + fs . readFileSync ( this . newestFileInFolder ( `${ this . bdkPath }/peerOrganizations/${ domain }/peers/peer${ number }.${ domain }/tls/tlscacerts` ) ) . toString ( ) ; } return tlsCert ; } public getPeerOrgCaCertString ( domain ) { return fs . readFileSync ( `${ this . bdkPath }/peerOrganizations/${ domain }/ca/ca.${ domain }-cert.pem` ) . toString ( ) ; } public getChannelConfigString ( channelName , fileName ) { return fs . readFileSync ( `${ this . bdkPath }/channel-artifacts/${ channelName }/${ fileName }.json` ) . toString ( ) ; } public getOrgConfigJson ( name ) { return fs . readFileSync ( `${ this . bdkPath }/org-json/${ name }.json` ) . toString ( ) ; } public getOrdererOrgConsenter ( name ) { return fs . readFileSync ( `${ this . bdkPath }/org-json/${ name }-consenter.json` ) . toString ( ) ; } public createConnectionFile ( name , domain , connectionProfileYaml ) { fs . writeFileSync ( `${ this . bdkPath }/peerOrganizations/${ domain }/connection-${ name }.json` , connectionProfileYaml . getJsonString ( ) ) ; fs . writeFileSync ( `${ this . bdkPath }/peerOrganizations/${ domain }/connection-${ name }.yaml` , connectionProfileYaml . getYamlString ( ) ) ; } public getConnectionFile ( name , domain ) { return new ConnectionProfileYaml ( JSON . parse ( fs . readFileSync ( `${ this . bdkPath }/peerOrganizations/${ domain }/connection-${ name }.json` ) . toString ( ) ) ) ; } public getDockerComposeYamlPath ( hostName , type ) { return `${ this . bdkPath }/docker-compose/docker-compose-${ type }-${ hostName }.yaml` ; } private getExplorerRootFilePath ( ) { return `${ this . bdkPath }/fabric-explorer` ; } private createExplorerFolder ( ) { fs . mkdirSync ( `${ this . getExplorerRootFilePath ( ) }/connection-profile` , { recursive : true } ) ; } public getExplorerDockerComposeYamlPath ( ) { return `${ this . getExplorerRootFilePath ( ) }/docker-compose.yaml` ; } public createDockerComposeYaml ( hostName , dockerComposeYaml ) { const type = ( ( ) => { if ( dockerComposeYaml instanceof OrdererDockerComposeYaml ) { return InstanceTypeEnum . orderer ; } else if ( dockerComposeYaml instanceof PeerDockerComposeYaml ) { return InstanceTypeEnum . peer ; } else if ( dockerComposeYaml instanceof CaDockerComposeYaml ) { return InstanceTypeEnum . ca ; } return InstanceTypeEnum . orderer ; } ) ( ) ; fs . mkdirSync ( `${ this . bdkPath }/docker-compose` , { recursive : true } ) ; fs . writeFileSync ( this . getDockerComposeYamlPath ( hostName , type ) , dockerComposeYaml . getYamlString ( ) ) ; } public createExplorerDockerComposeYaml ( explorerConnectionProfileYaml ) { this . createExplorerFolder ( ) ; fs . writeFileSync ( this . getExplorerDockerComposeYamlPath ( ) , explorerConnectionProfileYaml . getYamlString ( ) ) ; } public getDockerComposeYaml ( hostName , type ) { return YAML . load ( fs . readFileSync ( this . getDockerComposeYamlPath ( hostName , type ) ) . toString ( ) ) as DockerComposeYamlInterface ; } public createOrgConfigEnv ( filename , dotEnv ) { fs . mkdirSync ( `${ this . bdkPath }/env` , { recursive : true } ) ; fs . writeFileSync ( `${ this . bdkPath }/env/${ filename }.env` , dotEnv ) ; } public getOrgConfigEnv ( filename ) { return parse ( fs . readFileSync ( `${ this . bdkPath }/env/${ filename }.env` ) . toString ( ) ) ; } private createChannelConfigtxFolder ( channelName ) { fs . mkdirSync ( `${ this . bdkPath }/config-yaml/${ channelName }Channel` , { recursive : true } ) ; } public createChannelConfigtx ( channelName , configtxYaml ) { this . createChannelConfigtxFolder ( channelName ) ; fs . writeFileSync ( `${ this . bdkPath }/config-yaml/${ channelName }Channel/configtx.yaml` , configtxYaml . getYamlString ( ) ) ; } public createChannelArtifact ( channelName ) { fs . mkdirSync ( `${ this . bdkPath }/channel-artifacts/${ channelName }` , { recursive : true } ) ; } public createChaincodeFolder ( ) { fs . mkdirSync ( `${ this . bdkPath }/chaincode` , { recursive : true } ) ; } public createOrgDefinitionJson ( name , orgJson ) { fs . mkdirSync ( `${ this . bdkPath }/org-json` , { recursive : true } ) ; fs . writeFileSync ( `${ this . bdkPath }/org-json/${ name }.json` , orgJson ) ; } public createOrdererOrgConsenterJson ( name , consenterJson ) { fs . mkdirSync ( `${ this . bdkPath }/org-json` , { recursive : true } ) ; fs . writeFileSync ( `${ this . bdkPath }/org-json/${ name }-consenter.json` , consenterJson ) ; } public createExportOrgDefinitionJson ( exportOrgJson , file ) { const splitFilePath = file . split ( '/' , 3 ) ; for ( let i = 0 ; i < splitFilePath . length - 1 ; i ++ ) { fs . mkdirSync ( `${ splitFilePath [ i ] }` , { recursive : true } ) ; } fs . writeFileSync ( `${ file }` , JSON . stringify ( exportOrgJson ) ) ; } public createChannelConfigJson ( channelName , fileName , channelConfigJson ) { fs . writeFileSync ( `${ this . bdkPath }/channel-artifacts/${ channelName }/${ fileName }.json` , channelConfigJson ) ; } public createExplorerConnectionProfile ( networkName , explorerConnectionProfileYaml ) { this . createExplorerFolder ( ) ; fs . writeFileSync ( `${ this . getExplorerRootFilePath ( ) }/connection-profile/${ networkName }.json` , explorerConnectionProfileYaml . getJsonString ( ) ) ; } public createExplorerConfig ( explorerConfig ) { this . createExplorerFolder ( ) ; fs . writeFileSync ( `${ this . getExplorerRootFilePath ( ) }/config.json` , explorerConfig . getJsonString ( ) ) ; } public getExplorerConfig ( ) { return new ExplorerConfigYaml ( JSON . parse ( fs . readFileSync ( `${ this . getExplorerRootFilePath ( ) }/config.json` ) . toString ( ) ) ) ; } public getDockerComposeList ( ) { const dockerComposeFiles = fs . existsSync ( `${ this . bdkPath }/docker-compose` ) ? fs . readdirSync ( `${ this . bdkPath }/docker-compose` ) . map ( fileName => fileName . match ( /(?<=^docker-compose-).*(?=.yaml$)/ ) ?. [ 0 ] ) . filter ( x => x !== undefined ) as string [ ] : [ ] ; return ( ( ) => { const dccList = { peer : [ ] as string [ ] , orderer : [ ] as string [ ] , ca : [ ] as string [ ] } ; dockerComposeFiles . forEach ( fileName => { if ( fileName . startsWith ( 'orderer-' ) ) dccList . orderer . push ( fileName . slice ( 8 ) ) ; else if ( fileName . startsWith ( 'peer-' ) ) dccList . peer . push ( fileName . slice ( 5 ) ) ; else if ( fileName . startsWith ( 'ca-' ) ) dccList . ca . push ( fileName . slice ( 3 ) ) ; } ) ; return dccList ; } ) ( ) ; } private setOrgPath ( orgName , type ) { this . orgPath = `${ this . bdkPath }/${ type }Organizations/${ orgName }` ; } public caFormatOrg ( orgName , clientId , type , hostname ) { this . setOrgPath ( hostname , type ) ; fs . mkdirSync ( `${ this . orgPath }/ca` , { recursive : true } ) ; fs . mkdirSync ( `${ this . orgPath }/msp/admincerts` , { recursive : true } ) ; fs . mkdirSync ( `${ this . orgPath }/msp/tlscacerts` , { recursive : true } ) ; fs . mkdirSync ( `${ this . orgPath }/msp/tlsintermediatecerts` , { recursive : true } ) ; fs . copySync ( `${ this . bdkPath }/ca/${ clientId }@${ orgName }/msp` , `${ this . orgPath }/msp` ) ; fs . copyFileSync ( this . newestFileInFolder ( `${ this . orgPath }/msp/cacerts` ) , `${ this . orgPath }/msp/tlscacerts/tlsca.${ hostname }-cert.pem` ) ; fs . copySync ( `${ this . orgPath }/msp/intermediatecerts` , `${ this . orgPath }/msp/tlsintermediatecerts` ) ; fs . copyFileSync ( this . newestFileInFolder ( `${ this . orgPath }/msp/intermediatecerts` ) , `${ this . orgPath }/ca/ca.${ hostname }-cert.pem` ) ; fs . writeFileSync ( `${ this . orgPath }/msp/config.yaml` , 'NodeOUs:\n  Enable: true\n  ClientOUIdentifier:\n    OrganizationalUnitIdentifier: client\n  PeerOUIdentifier:\n    OrganizationalUnitIdentifier: peer\n  AdminOUIdentifier:\n    OrganizationalUnitIdentifier: admin\n  OrdererOUIdentifier:\n    OrganizationalUnitIdentifier: orderer\n' ) ; } public caFormatOrderer ( orgName , ordererName , hostname ) { this . setOrgPath ( hostname , 'orderer' ) ; fs . mkdirSync ( `${ this . orgPath }/orderers/${ ordererName }/msp/admincerts` , { recursive : true } ) ; fs . mkdirSync ( `${ this . orgPath }/orderers/${ ordererName }/msp/tlscacerts` , { recursive : true } ) ; fs . mkdirSync ( `${ this . orgPath }/orderers/${ ordererName }/msp/tlsintermediatecerts` , { recursive : true } ) ; fs . copySync ( `${ this . bdkPath }/ca/${ ordererName }@${ orgName }` , `${ this . orgPath }/orderers/${ ordererName }` ) ; fs . copySync ( `${ this . orgPath }/orderers/${ ordererName }/msp/cacerts` , `${ this . orgPath }/orderers/${ ordererName }/msp/tlscacerts` ) ; fs . copySync ( `${ this . orgPath }/orderers/${ ordererName }/msp/intermediatecerts` , `${ this . orgPath }/orderers/${ ordererName }/msp/tlsintermediatecerts` ) ; fs . copyFileSync ( this . newestFileInFolder ( `${ this . orgPath }/orderers/${ ordererName }/tls/tlsintermediatecerts` ) , `${ this . orgPath }/orderers/${ ordererName }/tls/ca.crt` ) ; fs . copyFileSync ( this . newestFileInFolder ( `${ this . orgPath }/orderers/${ ordererName }/tls/signcerts` ) , `${ this . orgPath }/orderers/${ ordererName }/tls/server.crt` ) ; fs . copyFileSync ( this . newestFileInFolder ( `${ this . orgPath }/orderers/${ ordererName }/tls/keystore` ) , `${ this . orgPath }/orderers/${ ordererName }/tls/server.key` ) ; fs . copyFileSync ( this . newestFileInFolder ( `${ this . orgPath }/orderers/${ ordererName }/tls/keystore` ) , `${ this . orgPath }/orderers/${ ordererName }/tls/keystore/priv_sk` ) ; const userList = fs . existsSync ( `${ this . orgPath }/users/` ) ? fs . readdirSync ( `${ this . orgPath }/users/` ) : [ ] ; userList . forEach ( ( user ) => { if ( user . toLocaleLowerCase ( ) . startsWith ( 'admin' ) ) { fs . copySync ( `${ this . orgPath }/users/${ user }/msp/signcerts/` , `${ this . orgPath }/orderers/${ ordererName }/msp/admincerts` ) ; } } ) ; } public caFormatPeer ( orgName , peerName , hostname ) { this . setOrgPath ( hostname , 'peer' ) ; fs . mkdirSync ( `${ this . orgPath }/peers/${ peerName }/msp/admincerts` , { recursive : true } ) ; fs . mkdirSync ( `${ this . orgPath }/peers/${ peerName }/msp/tlscacerts` , { recursive : true } ) ; fs . mkdirSync ( `${ this . orgPath }/peers/${ peerName }/msp/tlsintermediatecerts` , { recursive : true } ) ; fs . copySync ( `${ this . bdkPath }/ca/${ peerName }@${ orgName }` , `${ this . orgPath }/peers/${ peerName }` ) ; try { fs . copyFileSync ( this . newestFileInFolder ( `${ this . orgPath }/peers/${ peerName }/msp/cacerts` ) , `${ this . orgPath }/peers/${ peerName }/msp/tlscacerts/tlsca.${ hostname }-cert.pem` ) ; } catch { fs . copyFileSync ( this . newestFileInFolder ( `${ this . orgPath }/peers/${ peerName }/msp/cacerts` ) , `${ this . orgPath }/peers/${ peerName }/msp/tlscacerts/tlsca.${ hostname }-cert.pem` ) ; } fs . copySync ( `${ this . orgPath }/peers/${ peerName }/msp/intermediatecerts` , `${ this . orgPath }/peers/${ peerName }/msp/tlsintermediatecerts` ) ; fs . copyFileSync ( this . newestFileInFolder ( `${ this . orgPath }/peers/${ peerName }/tls/tlsintermediatecerts` ) , `${ this . orgPath }/peers/${ peerName }/tls/ca.crt` ) ; fs . copyFileSync ( this . newestFileInFolder ( `${ this . orgPath }/peers/${ peerName }/tls/signcerts` ) , `${ this . orgPath }/peers/${ peerName }/tls/server.crt` ) ; fs . copyFileSync ( this . newestFileInFolder ( `${ this . orgPath }/peers/${ peerName }/tls/keystore` ) , `${ this . orgPath }/peers/${ peerName }/tls/server.key` ) ; fs . copyFileSync ( this . newestFileInFolder ( `${ this . orgPath }/peers/${ peerName }/tls/keystore` ) , `${ this . orgPath }/peers/${ peerName }/tls/keystore/priv_sk` ) ; const userList = fs . existsSync ( `${ this . orgPath }/users/` ) ? fs . readdirSync ( `${ this . orgPath }/users/` ) : [ ] ; userList . forEach ( ( user ) => { if ( user . toLocaleLowerCase ( ) . startsWith ( 'admin' ) ) { fs . copySync ( `${ this . orgPath }/users/${ user }/msp/signcerts/` , `${ this . orgPath }/peers/${ peerName }/msp/admincerts` ) ; } } ) ; } public caFormatUser ( orgName , userName , type , hostname ) { this . setOrgPath ( hostname , type ) ; fs . mkdirSync ( `${ this . orgPath }/users/${ userName }` , { recursive : true } ) ; fs . copySync ( `${ this . bdkPath }/ca/${ userName }@${ orgName }/user` , `${ this . orgPath }/users/${ userName }/msp` ) ; fs . copySync ( `${ this . orgPath }/users/${ userName }/msp/signcerts/` , `${ this . orgPath }/msp/admincerts` ) ; fs . copySync ( `${ this . orgPath }/users/${ userName }/msp/signcerts/` , `${ this . orgPath }/users/${ userName }/msp/admincerts` ) ; if ( userName . toLocaleLowerCase ( ) . startsWith ( 'admin' ) && fs . existsSync ( `${ this . orgPath }/${ type }s/` ) ) { fs . readdirSync ( `${ this . orgPath }/${ type }s/` ) . forEach ( ( hostname ) => { fs . copySync ( `${ this . orgPath }/users/${ userName }/msp/signcerts/` , `${ this . orgPath }/${ type }s/${ hostname }/msp/admincerts` ) ; } ) ; } } public static newestFileName ( folderName ) { const files = fs . readdirSync ( folderName ) ; const newest = { fileName : 'stub' , created : new Date ( 'December 31, 1999 00:00:00' ) } ; files . forEach ( function ( file ) { const stats = fs . statSync ( path . join ( folderName , file ) ) ; if ( stats . ctime > newest . created ) { newest . fileName = file ; newest . created = stats . ctime ; } } ) ; return newest . fileName ; } private newestFileInFolder ( folderName ) { return `${ folderName }/${ BdkFile . newestFileName ( folderName ) }` ; } private createPackageIdFolder ( ) { fs . mkdirSync ( `${ this . bdkPath }/chaincode/package-id` , { recursive : true } ) ; } public savePackageId ( chaincodeLabel , packageId ) { this . createPackageIdFolder ( ) ; fs . writeFileSync ( `${ this . bdkPath }/chaincode/package-id/${ chaincodeLabel }` , packageId ) ; } public getPackageId ( chaincodeLabel ) { if ( ! fs . existsSync ( `${ this . bdkPath }/chaincode/package-id/${ chaincodeLabel }` ) ) { throw new Error ( 'Should install chaincode or getChaincodePackageId first' ) ; } return fs . readFileSync ( `${ this . bdkPath }/chaincode/package-id/${ chaincodeLabel }` ) . toString ( ) ; } public getDecodedChannelConfig ( channelName ) { return JSON . parse ( fs . readFileSync ( `${ this . bdkPath }/channel-artifacts/${ channelName }/${ channelName }.json` ) . toString ( ) ) ; } public getAdminPrivateKeyPem ( domain ) { return fs . readFileSync ( this . newestFileInFolder ( `${ this . bdkPath }/peerOrganizations/${ domain }/users/Admin@${ domain }/msp/keystore` ) ) . toString ( ) ; } public getAdminPrivateKeyFilename ( domain ) { return BdkFile . newestFileName ( `${ this . bdkPath }/peerOrganizations/${ domain }/users/Admin@${ domain }/msp/keystore` ) ; } public getAdminSignCert ( domain ) { return fs . readFileSync ( this . newestFileInFolder ( `${ this . bdkPath }/peerOrganizations/${ domain }/users/Admin@${ domain }/msp/signcerts` ) ) . toString ( ) ; } public getAdminSignCertFilename ( domain ) { return BdkFile . newestFileName ( `${ this . bdkPath }/peerOrganizations/${ domain }/users/Admin@${ domain }/msp/signcerts` ) ; } public getChannelJson ( channel , filename ) { return fs . readFileSync ( `${ this . bdkPath }/channel-artifacts/${ channel }/${ filename }.json` ) . toString ( ) ; } }