mirror of
https://github.com/hyperledger/fabric-samples.git
synced 2026-06-22 17:45:10 +00:00
Merge "[FAB-9033] TypeScript sample uses latest type defs" into release-1.4
This commit is contained in:
commit
ad87f324b9
7 changed files with 65 additions and 428 deletions
|
|
@ -18,6 +18,7 @@ import * as util from 'util';
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import * as helper from './helper';
|
import * as helper from './helper';
|
||||||
|
import { Peer, ProposalResponse, ChaincodeQueryResponse } from 'fabric-client';
|
||||||
|
|
||||||
// tslint:disable-next-line:no-var-requires
|
// tslint:disable-next-line:no-var-requires
|
||||||
const config = require('../app_config.json');
|
const config = require('../app_config.json');
|
||||||
|
|
@ -53,7 +54,8 @@ export async function installChaincode(
|
||||||
targets: helper.newPeers(peers, org),
|
targets: helper.newPeers(peers, org),
|
||||||
chaincodePath,
|
chaincodePath,
|
||||||
chaincodeId: chaincodeName,
|
chaincodeId: chaincodeName,
|
||||||
chaincodeVersion
|
chaincodeVersion,
|
||||||
|
txId: client.newTransactionID(true)
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
@ -64,7 +66,7 @@ export async function installChaincode(
|
||||||
const proposal = results[1];
|
const proposal = results[1];
|
||||||
let allGood = true;
|
let allGood = true;
|
||||||
|
|
||||||
proposalResponses.forEach((pr) => {
|
proposalResponses.forEach((pr: ProposalResponse) => {
|
||||||
let oneGood = false;
|
let oneGood = false;
|
||||||
if (pr.response && pr.response.status === 200) {
|
if (pr.response && pr.response.status === 200) {
|
||||||
oneGood = true;
|
oneGood = true;
|
||||||
|
|
@ -76,9 +78,10 @@ export async function installChaincode(
|
||||||
});
|
});
|
||||||
|
|
||||||
if (allGood) {
|
if (allGood) {
|
||||||
|
const proposalResponse = proposalResponses[0] as ProposalResponse;
|
||||||
logger.info(util.format(
|
logger.info(util.format(
|
||||||
'Successfully sent install Proposal and received ProposalResponse: Status - %s',
|
'Successfully sent install Proposal and received ProposalResponse: Status - %s',
|
||||||
proposalResponses[0].response.status));
|
proposalResponse.response.status));
|
||||||
logger.debug('\nSuccessfully Installed chaincode on organization ' + org +
|
logger.debug('\nSuccessfully Installed chaincode on organization ' + org +
|
||||||
'\n');
|
'\n');
|
||||||
return 'Successfully Installed chaincode on organization ' + org;
|
return 'Successfully Installed chaincode on organization ' + org;
|
||||||
|
|
|
||||||
|
|
@ -18,11 +18,14 @@ import * as util from 'util';
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import * as helper from './helper';
|
import * as helper from './helper';
|
||||||
|
import { ChannelEventHub, Peer, ProposalResponse, ChaincodeInvokeRequest,
|
||||||
|
ChaincodeQueryRequest, ChannelInfo } from 'fabric-client';
|
||||||
|
|
||||||
const logger = helper.getLogger('ChannelApi');
|
const logger = helper.getLogger('ChannelApi');
|
||||||
// tslint:disable-next-line:no-var-requires
|
// tslint:disable-next-line:no-var-requires
|
||||||
const config = require('../app_config.json');
|
const config = require('../app_config.json');
|
||||||
|
|
||||||
const allEventhubs: EventHub[] = [];
|
const allEventhubs: ChannelEventHub[] = [];
|
||||||
|
|
||||||
function buildTarget(peer: string, org: string): Peer {
|
function buildTarget(peer: string, org: string): Peer {
|
||||||
let target: Peer = null;
|
let target: Peer = null;
|
||||||
|
|
@ -132,40 +135,10 @@ export async function joinChannel(
|
||||||
block: genesisBlock
|
block: genesisBlock
|
||||||
};
|
};
|
||||||
|
|
||||||
const eventhubs = helper.newEventHubs(peers, org);
|
const results = await channel.joinChannel(request2);
|
||||||
eventhubs.forEach((eh) => {
|
|
||||||
eh.connect();
|
|
||||||
allEventhubs.push(eh);
|
|
||||||
});
|
|
||||||
|
|
||||||
const eventPromises: Array<Promise<any>> = [];
|
|
||||||
eventhubs.forEach((eh) => {
|
|
||||||
const txPromise = new Promise((resolve, reject) => {
|
|
||||||
const handle = setTimeout(reject, parseInt(config.eventWaitTime, 10));
|
|
||||||
eh.registerBlockEvent((block: any) => {
|
|
||||||
clearTimeout(handle);
|
|
||||||
// in real-world situations, a peer may have more than one channels so
|
|
||||||
// we must check that this block came from the channel we asked the peer to join
|
|
||||||
if (block.data.data.length === 1) {
|
|
||||||
// Config block must only contain one transaction
|
|
||||||
const channel_header = block.data.data[0].payload.header.channel_header;
|
|
||||||
if (channel_header.channel_id === channelName) {
|
|
||||||
resolve();
|
|
||||||
} else {
|
|
||||||
reject();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
eventPromises.push(txPromise);
|
|
||||||
});
|
|
||||||
|
|
||||||
const sendPromise = channel.joinChannel(request2);
|
|
||||||
const results = await Promise.all([sendPromise].concat(eventPromises));
|
|
||||||
|
|
||||||
logger.debug(util.format('Join Channel R E S P O N S E : %j', results));
|
logger.debug(util.format('Join Channel R E S P O N S E : %j', results));
|
||||||
if (results[0] && results[0][0] && results[0][0].response && results[0][0]
|
if (results[0] && results[0].response && results[0].response.status === 200) {
|
||||||
.response.status === 200) {
|
|
||||||
logger.info(util.format(
|
logger.info(util.format(
|
||||||
'Successfully joined peers in organization %s to the channel \'%s\'',
|
'Successfully joined peers in organization %s to the channel \'%s\'',
|
||||||
org, channelName));
|
org, channelName));
|
||||||
|
|
@ -216,7 +189,7 @@ export async function instantiateChainCode(
|
||||||
|
|
||||||
let allGood = true;
|
let allGood = true;
|
||||||
|
|
||||||
proposalResponses.forEach((pr) => {
|
proposalResponses.forEach((pr: ProposalResponse) => {
|
||||||
let oneGood = false;
|
let oneGood = false;
|
||||||
if (pr.response && pr.response.status === 200) {
|
if (pr.response && pr.response.status === 200) {
|
||||||
oneGood = true;
|
oneGood = true;
|
||||||
|
|
@ -228,15 +201,17 @@ export async function instantiateChainCode(
|
||||||
});
|
});
|
||||||
|
|
||||||
if (allGood) {
|
if (allGood) {
|
||||||
|
const responses = proposalResponses as ProposalResponse[];
|
||||||
|
const proposalResponse = responses[0];
|
||||||
logger.info(util.format(
|
logger.info(util.format(
|
||||||
// tslint:disable-next-line:max-line-length
|
// tslint:disable-next-line:max-line-length
|
||||||
'Successfully sent Proposal and received ProposalResponse: Status - %s, message - "%s", metadata - "%s", endorsement signature: %s',
|
'Successfully sent Proposal and received ProposalResponse: Status - %s, message - "%s", metadata - "%s", endorsement signature: %s',
|
||||||
proposalResponses[0].response.status, proposalResponses[0].response.message,
|
proposalResponse.response.status, proposalResponse.response.message,
|
||||||
proposalResponses[0].response.payload, proposalResponses[0].endorsement
|
proposalResponse.response.payload, proposalResponse.endorsement
|
||||||
.signature));
|
.signature));
|
||||||
|
|
||||||
const request2 = {
|
const request2 = {
|
||||||
proposalResponses,
|
proposalResponses: responses,
|
||||||
proposal
|
proposal
|
||||||
};
|
};
|
||||||
// set the transaction listener and set a timeout of 30sec
|
// set the transaction listener and set a timeout of 30sec
|
||||||
|
|
@ -245,15 +220,7 @@ export async function instantiateChainCode(
|
||||||
const deployId = txId.getTransactionID();
|
const deployId = txId.getTransactionID();
|
||||||
const ORGS = helper.getOrgs();
|
const ORGS = helper.getOrgs();
|
||||||
|
|
||||||
const eh = client.newEventHub();
|
const eh = channel.newChannelEventHub('peer1');
|
||||||
const data = fs.readFileSync(path.join(__dirname, ORGS[org].peers['peer1'][
|
|
||||||
'tls_cacerts'
|
|
||||||
]));
|
|
||||||
|
|
||||||
eh.setPeerAddr(ORGS[org].peers['peer1']['events'], {
|
|
||||||
'pem': Buffer.from(data).toString(),
|
|
||||||
'ssl-target-name-override': ORGS[org].peers['peer1']['server-hostname']
|
|
||||||
});
|
|
||||||
eh.connect();
|
eh.connect();
|
||||||
|
|
||||||
const txPromise: Promise<any> = new Promise((resolve, reject) => {
|
const txPromise: Promise<any> = new Promise((resolve, reject) => {
|
||||||
|
|
@ -262,7 +229,7 @@ export async function instantiateChainCode(
|
||||||
reject();
|
reject();
|
||||||
}, 30000);
|
}, 30000);
|
||||||
|
|
||||||
eh.registerTxEvent(deployId, (tx, code) => {
|
eh.registerTxEvent(deployId, (tx: string, code: string) => {
|
||||||
// logger.info(
|
// logger.info(
|
||||||
// 'The chaincode instantiate transaction has been committed on peer ' +
|
// 'The chaincode instantiate transaction has been committed on peer ' +
|
||||||
// eh._ep._endpoint.addr);
|
// eh._ep._endpoint.addr);
|
||||||
|
|
@ -346,7 +313,7 @@ export async function invokeChaincode(
|
||||||
const proposal = results[1];
|
const proposal = results[1];
|
||||||
let allGood = true;
|
let allGood = true;
|
||||||
|
|
||||||
proposalResponses.forEach((pr) => {
|
proposalResponses.forEach((pr: ProposalResponse) => {
|
||||||
let oneGood = false;
|
let oneGood = false;
|
||||||
if (pr.response && pr.response.status === 200) {
|
if (pr.response && pr.response.status === 200) {
|
||||||
oneGood = true;
|
oneGood = true;
|
||||||
|
|
@ -358,15 +325,17 @@ export async function invokeChaincode(
|
||||||
});
|
});
|
||||||
|
|
||||||
if (allGood) {
|
if (allGood) {
|
||||||
|
const responses = proposalResponses as ProposalResponse[];
|
||||||
|
const proposalResponse = responses[0];
|
||||||
logger.debug(util.format(
|
logger.debug(util.format(
|
||||||
// tslint:disable-next-line:max-line-length
|
// tslint:disable-next-line:max-line-length
|
||||||
'Successfully sent Proposal and received ProposalResponse: Status - %s, message - "%s", metadata - "%s", endorsement signature: %s',
|
'Successfully sent Proposal and received ProposalResponse: Status - %s, message - "%s", metadata - "%s", endorsement signature: %s',
|
||||||
proposalResponses[0].response.status, proposalResponses[0].response.message,
|
proposalResponse.response.status, proposalResponse.response.message,
|
||||||
proposalResponses[0].response.payload, proposalResponses[0].endorsement
|
proposalResponse.response.payload, proposalResponse.endorsement
|
||||||
.signature));
|
.signature));
|
||||||
|
|
||||||
const request2 = {
|
const request2 = {
|
||||||
proposalResponses,
|
proposalResponses: responses,
|
||||||
proposal
|
proposal
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -384,7 +353,7 @@ export async function invokeChaincode(
|
||||||
|
|
||||||
const eventhubs = helper.newEventHubs(peerNames, org);
|
const eventhubs = helper.newEventHubs(peerNames, org);
|
||||||
|
|
||||||
eventhubs.forEach((eh: EventHub) => {
|
eventhubs.forEach((eh: ChannelEventHub) => {
|
||||||
eh.connect();
|
eh.connect();
|
||||||
|
|
||||||
const txPromise = new Promise((resolve, reject) => {
|
const txPromise = new Promise((resolve, reject) => {
|
||||||
|
|
@ -452,11 +421,9 @@ export async function queryChaincode(
|
||||||
|
|
||||||
const user = await helper.getRegisteredUsers(username, org);
|
const user = await helper.getRegisteredUsers(username, org);
|
||||||
|
|
||||||
const txId = client.newTransactionID();
|
|
||||||
// send query
|
// send query
|
||||||
const request: ChaincodeQueryRequest = {
|
const request: ChaincodeQueryRequest = {
|
||||||
chaincodeId: chaincodeName,
|
chaincodeId: chaincodeName,
|
||||||
txId,
|
|
||||||
fcn,
|
fcn,
|
||||||
args
|
args
|
||||||
};
|
};
|
||||||
|
|
@ -470,7 +437,7 @@ export async function queryChaincode(
|
||||||
|
|
||||||
if (responsePayloads) {
|
if (responsePayloads) {
|
||||||
|
|
||||||
responsePayloads.forEach((rp) => {
|
responsePayloads.forEach((rp: Buffer) => {
|
||||||
logger.info(args[0] + ' now has ' + rp.toString('utf8') +
|
logger.info(args[0] + ' now has ' + rp.toString('utf8') +
|
||||||
' after the move');
|
' after the move');
|
||||||
return args[0] + ' now has ' + rp.toString('utf8') +
|
return args[0] + ' now has ' + rp.toString('utf8') +
|
||||||
|
|
@ -501,7 +468,7 @@ export async function getBlockByNumber(
|
||||||
const responsePayloads = await channel.queryBlock(parseInt(blockNumber, 10), target);
|
const responsePayloads = await channel.queryBlock(parseInt(blockNumber, 10), target);
|
||||||
|
|
||||||
if (responsePayloads) {
|
if (responsePayloads) {
|
||||||
logger.debug(responsePayloads);
|
logger.debug(responsePayloads.toString());
|
||||||
return responsePayloads; // response_payloads.data.data[0].buffer;
|
return responsePayloads; // response_payloads.data.data[0].buffer;
|
||||||
} else {
|
} else {
|
||||||
logger.error('response_payloads is null');
|
logger.error('response_payloads is null');
|
||||||
|
|
@ -554,7 +521,7 @@ export async function getChainInfo(peer: string, username: string, org: string)
|
||||||
if (blockChainInfo) {
|
if (blockChainInfo) {
|
||||||
// FIXME: Save this for testing 'getBlockByHash' ?
|
// FIXME: Save this for testing 'getBlockByHash' ?
|
||||||
logger.debug('===========================================');
|
logger.debug('===========================================');
|
||||||
logger.debug(blockChainInfo.currentBlockHash);
|
logger.debug(blockChainInfo.currentBlockHash.toString());
|
||||||
logger.debug('===========================================');
|
logger.debug('===========================================');
|
||||||
// logger.debug(blockchainInfo);
|
// logger.debug(blockchainInfo);
|
||||||
return blockChainInfo;
|
return blockChainInfo;
|
||||||
|
|
@ -583,7 +550,7 @@ export async function getChannels(peer: string, username: string, org: string) {
|
||||||
if (response) {
|
if (response) {
|
||||||
logger.debug('<<< channels >>>');
|
logger.debug('<<< channels >>>');
|
||||||
const channelNames: string[] = [];
|
const channelNames: string[] = [];
|
||||||
response.channels.forEach((ci) => {
|
response.channels.forEach((ci: ChannelInfo) => {
|
||||||
channelNames.push('channel id: ' + ci.channel_id);
|
channelNames.push('channel id: ' + ci.channel_id);
|
||||||
});
|
});
|
||||||
return response;
|
return response;
|
||||||
|
|
|
||||||
|
|
@ -19,13 +19,14 @@ import * as path from 'path';
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import * as util from 'util';
|
import * as util from 'util';
|
||||||
import config from '../config';
|
import config from '../config';
|
||||||
import hfc = require('fabric-client');
|
import Client = require('fabric-client');
|
||||||
|
import { User, UserOpts, Channel } from 'fabric-client';
|
||||||
// tslint:disable-next-line:no-var-requires
|
// tslint:disable-next-line:no-var-requires
|
||||||
const copService = require('fabric-ca-client');
|
const copService = require('fabric-ca-client');
|
||||||
|
|
||||||
const logger = log4js.getLogger('Helper');
|
const logger = log4js.getLogger('Helper');
|
||||||
logger.setLevel('DEBUG');
|
logger.setLevel('DEBUG');
|
||||||
hfc.setLogger(logger);
|
Client.setLogger(logger);
|
||||||
|
|
||||||
let ORGS: any;
|
let ORGS: any;
|
||||||
const clients = {};
|
const clients = {};
|
||||||
|
|
@ -44,7 +45,7 @@ function readAllFiles(dir: string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function getKeyStoreForOrg(org: string) {
|
function getKeyStoreForOrg(org: string) {
|
||||||
return hfc.getConfigSetting('keyValueStore') + '_' + org;
|
return Client.getConfigSetting('keyValueStore') + '_' + org;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setupPeers(channel: any, org: string, client: Client) {
|
function setupPeers(channel: any, org: string, client: Client) {
|
||||||
|
|
@ -87,7 +88,7 @@ function getMspID(org: string) {
|
||||||
|
|
||||||
function newRemotes(names: string[], forPeers: boolean, userOrg: string) {
|
function newRemotes(names: string[], forPeers: boolean, userOrg: string) {
|
||||||
const client = getClientForOrg(userOrg);
|
const client = getClientForOrg(userOrg);
|
||||||
|
const channel = getChannelForOrg(userOrg);
|
||||||
const targets: any[] = [];
|
const targets: any[] = [];
|
||||||
// find the peer that match the names
|
// find the peer that match the names
|
||||||
names.forEach((n) => {
|
names.forEach((n) => {
|
||||||
|
|
@ -100,11 +101,11 @@ function newRemotes(names: string[], forPeers: boolean, userOrg: string) {
|
||||||
'ssl-target-name-override': ORGS[userOrg].peers[n]['server-hostname']
|
'ssl-target-name-override': ORGS[userOrg].peers[n]['server-hostname']
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const peer = client.newPeer(ORGS[userOrg].peers[n].requests, grpcOpts);
|
||||||
if (forPeers) {
|
if (forPeers) {
|
||||||
targets.push(client.newPeer(ORGS[userOrg].peers[n].requests, grpcOpts));
|
targets.push(peer);
|
||||||
} else {
|
} else {
|
||||||
const eh = client.newEventHub();
|
const eh = channel.newChannelEventHub(peer);
|
||||||
eh.setPeerAddr(ORGS[userOrg].peers[n].events, grpcOpts);
|
|
||||||
targets.push(eh);
|
targets.push(eh);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -118,13 +119,13 @@ function newRemotes(names: string[], forPeers: boolean, userOrg: string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getAdminUser(userOrg: string): Promise<User> {
|
async function getAdminUser(userOrg: string): Promise<User> {
|
||||||
const users = hfc.getConfigSetting('admins');
|
const users = Client.getConfigSetting('admins');
|
||||||
const username = users[0].username;
|
const username = users[0].username;
|
||||||
const password = users[0].secret;
|
const password = users[0].secret;
|
||||||
|
|
||||||
const client = getClientForOrg(userOrg);
|
const client = getClientForOrg(userOrg);
|
||||||
|
|
||||||
const store = await hfc.newDefaultKeyValueStore({
|
const store = await Client.newDefaultKeyValueStore({
|
||||||
path: getKeyStoreForOrg(getOrgName(userOrg))
|
path: getKeyStoreForOrg(getOrgName(userOrg))
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -145,13 +146,14 @@ async function getAdminUser(userOrg: string): Promise<User> {
|
||||||
});
|
});
|
||||||
|
|
||||||
logger.info('Successfully enrolled user \'' + username + '\'');
|
logger.info('Successfully enrolled user \'' + username + '\'');
|
||||||
const userOptions: UserOptions = {
|
const userOptions: UserOpts = {
|
||||||
username,
|
username,
|
||||||
mspid: getMspID(userOrg),
|
mspid: getMspID(userOrg),
|
||||||
cryptoContent: {
|
cryptoContent: {
|
||||||
privateKeyPEM: enrollment.key.toBytes(),
|
privateKeyPEM: enrollment.key.toBytes(),
|
||||||
signedCertPEM: enrollment.certificate
|
signedCertPEM: enrollment.certificate
|
||||||
}
|
},
|
||||||
|
skipPersistence: false
|
||||||
};
|
};
|
||||||
|
|
||||||
const member = await client.createUser(userOptions);
|
const member = await client.createUser(userOptions);
|
||||||
|
|
@ -167,7 +169,7 @@ export function newEventHubs(names: string[], org: string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setupChaincodeDeploy() {
|
export function setupChaincodeDeploy() {
|
||||||
process.env.GOPATH = path.join(__dirname, hfc.getConfigSetting('CC_SRC_PATH'));
|
process.env.GOPATH = path.join(__dirname, Client.getConfigSetting('CC_SRC_PATH'));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getOrgs() {
|
export function getOrgs() {
|
||||||
|
|
@ -184,26 +186,26 @@ export function getChannelForOrg(org: string): Channel {
|
||||||
|
|
||||||
export function init() {
|
export function init() {
|
||||||
|
|
||||||
hfc.addConfigFile(path.join(__dirname, config.networkConfigFile));
|
Client.addConfigFile(path.join(__dirname, config.networkConfigFile));
|
||||||
hfc.addConfigFile(path.join(__dirname, '../app_config.json'));
|
Client.addConfigFile(path.join(__dirname, '../app_config.json'));
|
||||||
|
|
||||||
ORGS = hfc.getConfigSetting('network-config');
|
ORGS = Client.getConfigSetting('network-config');
|
||||||
|
|
||||||
// set up the client and channel objects for each org
|
// set up the client and channel objects for each org
|
||||||
for (const key in ORGS) {
|
for (const key in ORGS) {
|
||||||
if (key.indexOf('org') === 0) {
|
if (key.indexOf('org') === 0) {
|
||||||
const client = new hfc();
|
const client = new Client();
|
||||||
|
|
||||||
const cryptoSuite = hfc.newCryptoSuite();
|
const cryptoSuite = Client.newCryptoSuite();
|
||||||
// TODO: Fix it up as setCryptoKeyStore is only available for s/w impl
|
// TODO: Fix it up as setCryptoKeyStore is only available for s/w impl
|
||||||
(cryptoSuite as any).setCryptoKeyStore(
|
(cryptoSuite as any).setCryptoKeyStore(
|
||||||
hfc.newCryptoKeyStore({
|
Client.newCryptoKeyStore({
|
||||||
path: getKeyStoreForOrg(ORGS[key].name)
|
path: getKeyStoreForOrg(ORGS[key].name)
|
||||||
}));
|
}));
|
||||||
|
|
||||||
client.setCryptoSuite(cryptoSuite);
|
client.setCryptoSuite(cryptoSuite);
|
||||||
|
|
||||||
const channel = client.newChannel(hfc.getConfigSetting('channelName'));
|
const channel = client.newChannel(Client.getConfigSetting('channelName'));
|
||||||
channel.addOrderer(newOrderer(client));
|
channel.addOrderer(newOrderer(client));
|
||||||
|
|
||||||
clients[key] = client;
|
clients[key] = client;
|
||||||
|
|
@ -223,7 +225,7 @@ export async function getRegisteredUsers(
|
||||||
|
|
||||||
const client = getClientForOrg(userOrg);
|
const client = getClientForOrg(userOrg);
|
||||||
|
|
||||||
const store = await hfc.newDefaultKeyValueStore({
|
const store = await Client.newDefaultKeyValueStore({
|
||||||
path: getKeyStoreForOrg(getOrgName(userOrg))
|
path: getKeyStoreForOrg(getOrgName(userOrg))
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -259,13 +261,14 @@ export async function getRegisteredUsers(
|
||||||
}
|
}
|
||||||
logger.debug(username + ' enrolled successfully');
|
logger.debug(username + ' enrolled successfully');
|
||||||
|
|
||||||
const userOptions: UserOptions = {
|
const userOptions: UserOpts = {
|
||||||
username,
|
username,
|
||||||
mspid: getMspID(userOrg),
|
mspid: getMspID(userOrg),
|
||||||
cryptoContent: {
|
cryptoContent: {
|
||||||
privateKeyPEM: message.key.toBytes(),
|
privateKeyPEM: message.key.toBytes(),
|
||||||
signedCertPEM: message.certificate
|
signedCertPEM: message.certificate
|
||||||
}
|
},
|
||||||
|
skipPersistence: false
|
||||||
};
|
};
|
||||||
|
|
||||||
const member = await client.createUser(userOptions);
|
const member = await client.createUser(userOptions);
|
||||||
|
|
@ -286,15 +289,15 @@ export async function getOrgAdmin(userOrg: string): Promise<User> {
|
||||||
const certPEM = readAllFiles(certPath)[0].toString();
|
const certPEM = readAllFiles(certPath)[0].toString();
|
||||||
|
|
||||||
const client = getClientForOrg(userOrg);
|
const client = getClientForOrg(userOrg);
|
||||||
const cryptoSuite = hfc.newCryptoSuite();
|
const cryptoSuite = Client.newCryptoSuite();
|
||||||
|
|
||||||
if (userOrg) {
|
if (userOrg) {
|
||||||
(cryptoSuite as any).setCryptoKeyStore(
|
(cryptoSuite as any).setCryptoKeyStore(
|
||||||
hfc.newCryptoKeyStore({ path: getKeyStoreForOrg(getOrgName(userOrg)) }));
|
Client.newCryptoKeyStore({ path: getKeyStoreForOrg(getOrgName(userOrg)) }));
|
||||||
client.setCryptoSuite(cryptoSuite);
|
client.setCryptoSuite(cryptoSuite);
|
||||||
}
|
}
|
||||||
|
|
||||||
const store = await hfc.newDefaultKeyValueStore({
|
const store = await Client.newDefaultKeyValueStore({
|
||||||
path: getKeyStoreForOrg(getOrgName(userOrg))
|
path: getKeyStoreForOrg(getOrgName(userOrg))
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -306,6 +309,7 @@ export async function getOrgAdmin(userOrg: string): Promise<User> {
|
||||||
cryptoContent: {
|
cryptoContent: {
|
||||||
privateKeyPEM: keyPEM,
|
privateKeyPEM: keyPEM,
|
||||||
signedCertPEM: certPEM
|
signedCertPEM: certPEM
|
||||||
}
|
},
|
||||||
|
skipPersistence: false
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/body-parser": "^1.16.5",
|
"@types/body-parser": "^1.16.5",
|
||||||
|
"@types/bytebuffer": "^5.0.36",
|
||||||
"@types/cors": "^2.8.1",
|
"@types/cors": "^2.8.1",
|
||||||
"@types/express-jwt": "0.0.37",
|
"@types/express-jwt": "0.0.37",
|
||||||
"@types/express-session": "^1.15.3",
|
"@types/express-session": "^1.15.3",
|
||||||
|
|
@ -18,7 +19,7 @@
|
||||||
"@types/node": "^8.0.33",
|
"@types/node": "^8.0.33",
|
||||||
"express-bearer-token": "^2.1.0",
|
"express-bearer-token": "^2.1.0",
|
||||||
"jsonwebtoken": "^8.1.0",
|
"jsonwebtoken": "^8.1.0",
|
||||||
"ts-node": "^3.3.0",
|
"ts-node": "^7.0.1",
|
||||||
"tslint": "^5.6.0",
|
"tslint": "^5.6.0",
|
||||||
"tslint-microsoft-contrib": "^5.0.1",
|
"tslint-microsoft-contrib": "^5.0.1",
|
||||||
"typescript": "^2.5.3"
|
"typescript": "^2.5.3"
|
||||||
|
|
|
||||||
|
|
@ -51,21 +51,13 @@ function installNodeModules() {
|
||||||
echo "============== Installing node modules ============="
|
echo "============== Installing node modules ============="
|
||||||
npm install
|
npm install
|
||||||
fi
|
fi
|
||||||
copyIndex fabric-client/index.d.ts
|
|
||||||
copyIndex fabric-ca-client/index.d.ts
|
|
||||||
echo
|
echo
|
||||||
}
|
}
|
||||||
|
|
||||||
function copyIndex() {
|
|
||||||
if [ ! -f node_modules/$1 ]; then
|
|
||||||
cp types/$1 node_modules/$1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
restartNetwork
|
restartNetwork
|
||||||
|
|
||||||
installNodeModules
|
installNodeModules
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
PORT=4000 ts-node app.ts
|
PORT=4000 `npm bin`/ts-node app.ts
|
||||||
|
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
/**
|
|
||||||
* Copyright 2017 Kapil Sachdeva All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
declare module 'fabric-ca-client' {
|
|
||||||
}
|
|
||||||
|
|
@ -1,312 +0,0 @@
|
||||||
/**
|
|
||||||
* Copyright 2017 Kapil Sachdeva All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
declare enum Status {
|
|
||||||
UNKNOWN = 0,
|
|
||||||
SUCCESS = 200,
|
|
||||||
BAD_REQUEST = 400,
|
|
||||||
FORBIDDEN = 403,
|
|
||||||
NOT_FOUND = 404,
|
|
||||||
REQUEST_ENTITY_TOO_LARGE = 413,
|
|
||||||
INTERNAL_SERVER_ERROR = 500,
|
|
||||||
SERVICE_UNAVAILABLE = 503
|
|
||||||
}
|
|
||||||
|
|
||||||
type ChaicodeType = "golang" | "car" | "java";
|
|
||||||
|
|
||||||
interface ProtoBufObject {
|
|
||||||
toBuffer(): Buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface KeyOpts {
|
|
||||||
ephemeral: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ConnectionOptions {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ConfigSignature extends ProtoBufObject {
|
|
||||||
signature_header: Buffer;
|
|
||||||
signature: Buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ICryptoKey {
|
|
||||||
getSKI(): string;
|
|
||||||
isSymmetric(): boolean;
|
|
||||||
isPrivate(): boolean;
|
|
||||||
getPublicKey(): ICryptoKey;
|
|
||||||
toBytes(): string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ICryptoKeyStore {
|
|
||||||
getKey(ski: string): Promise<string>;
|
|
||||||
putKey(key: ICryptoKey): Promise<ICryptoKey>;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface IKeyValueStore {
|
|
||||||
getValue(name: string): Promise<string>;
|
|
||||||
setValue(name: string, value: string): Promise<string>;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface IdentityFiles {
|
|
||||||
privateKey: string;
|
|
||||||
signedCert: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface IdentityPEMs {
|
|
||||||
privateKeyPEM: string;
|
|
||||||
signedCertPEM: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface UserOptions {
|
|
||||||
username: string;
|
|
||||||
mspid: string;
|
|
||||||
cryptoContent: IdentityFiles | IdentityPEMs;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ICryptoSuite {
|
|
||||||
decrypt(key: ICryptoKey, cipherText: Buffer, opts: any): Buffer;
|
|
||||||
deriveKey(key: ICryptoKey): ICryptoKey;
|
|
||||||
encrypt(key: ICryptoKey, plainText: Buffer, opts: any): Buffer;
|
|
||||||
getKey(ski: string): Promise<ICryptoKey>;
|
|
||||||
generateKey(opts: KeyOpts): Promise<ICryptoKey>;
|
|
||||||
hash(msg: string, opts: any): string;
|
|
||||||
importKey(pem: string, opts: KeyOpts): ICryptoKey | Promise<ICryptoKey>;
|
|
||||||
sign(key: ICryptoKey, digest: Buffer): Buffer;
|
|
||||||
verify(key: ICryptoKey, signature: Buffer, digest: Buffer): boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ChannelRequest {
|
|
||||||
name: string;
|
|
||||||
orderer: Orderer;
|
|
||||||
envelope?: Buffer;
|
|
||||||
config?: Buffer;
|
|
||||||
txId?: TransactionId;
|
|
||||||
signatures: ConfigSignature[];
|
|
||||||
}
|
|
||||||
|
|
||||||
interface TransactionRequest {
|
|
||||||
proposalResponses: ProposalResponse[];
|
|
||||||
proposal: Proposal;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface BroadcastResponse {
|
|
||||||
status: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface IIdentity {
|
|
||||||
serialize(): Buffer;
|
|
||||||
getMSPId(): string;
|
|
||||||
isValid(): boolean;
|
|
||||||
getOrganizationUnits(): string;
|
|
||||||
verify(msg: Buffer, signature: Buffer, opts: any): boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ISigningIdentity {
|
|
||||||
sign(msg: Buffer, opts: any): Buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ChaincodeInstallRequest {
|
|
||||||
targets: Peer[];
|
|
||||||
chaincodePath: string;
|
|
||||||
chaincodeId: string;
|
|
||||||
chaincodeVersion: string;
|
|
||||||
chaincodePackage?: Buffer;
|
|
||||||
chaincodeType?: ChaicodeType;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ChaincodeInstantiateUpgradeRequest {
|
|
||||||
targets?: Peer[];
|
|
||||||
chaincodeType?: string;
|
|
||||||
chaincodeId: string;
|
|
||||||
chaincodeVersion: string;
|
|
||||||
txId: TransactionId;
|
|
||||||
fcn?: string;
|
|
||||||
args?: string[];
|
|
||||||
'endorsement-policy'?: any;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ChaincodeInvokeRequest {
|
|
||||||
targets?: Peer[];
|
|
||||||
chaincodeId: string;
|
|
||||||
txId: TransactionId;
|
|
||||||
fcn?: string;
|
|
||||||
args: string[];
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ChaincodeQueryRequest {
|
|
||||||
targets?: Peer[];
|
|
||||||
chaincodeId: string;
|
|
||||||
txId: TransactionId;
|
|
||||||
fcn?: string;
|
|
||||||
args: string[];
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ChaincodeInfo {
|
|
||||||
name: string;
|
|
||||||
version: string;
|
|
||||||
path: string;
|
|
||||||
input: string;
|
|
||||||
escc: string;
|
|
||||||
vscc: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ChannelInfo {
|
|
||||||
channel_id: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ChaincodeQueryResponse {
|
|
||||||
chaincodes: ChaincodeInfo[];
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ChannelQueryResponse {
|
|
||||||
channels: ChannelInfo[];
|
|
||||||
}
|
|
||||||
|
|
||||||
interface OrdererRequest {
|
|
||||||
txId: TransactionId;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface JoinChannelRequest {
|
|
||||||
txId: TransactionId;
|
|
||||||
targets: Peer[];
|
|
||||||
block: Buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ResponseObject {
|
|
||||||
status: Status;
|
|
||||||
message: string;
|
|
||||||
payload: Buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Proposal {
|
|
||||||
header: ByteBuffer;
|
|
||||||
payload: ByteBuffer;
|
|
||||||
extension: ByteBuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Header {
|
|
||||||
channel_header: ByteBuffer;
|
|
||||||
signature_header: ByteBuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ProposalResponse {
|
|
||||||
version: number;
|
|
||||||
timestamp: Date;
|
|
||||||
response: ResponseObject;
|
|
||||||
payload: Buffer;
|
|
||||||
endorsement: any;
|
|
||||||
}
|
|
||||||
|
|
||||||
type ProposalResponseObject = [Array<ProposalResponse>, Proposal, Header];
|
|
||||||
|
|
||||||
declare class Orderer {
|
|
||||||
}
|
|
||||||
|
|
||||||
declare class Peer {
|
|
||||||
setName(name: string): void;
|
|
||||||
getName(): string;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare class EventHub {
|
|
||||||
connect(): void;
|
|
||||||
disconnect(): void;
|
|
||||||
getPeerAddr(): string;
|
|
||||||
setPeerAddr(url: string, opts: ConnectionOptions): void;
|
|
||||||
isconnected(): boolean;
|
|
||||||
registerBlockEvent(onEvent: (b: any) => void, onError?: (err: Error) => void): number;
|
|
||||||
registerTxEvent(txId: string, onEvent: (txId: any, code: string) => void, onError?: (err: Error) => void): void;
|
|
||||||
unregisterTxEvent(txId: string): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare class Channel {
|
|
||||||
initialize(): Promise<void>;
|
|
||||||
addOrderer(orderer: Orderer): void;
|
|
||||||
addPeer(peer: Peer): void;
|
|
||||||
getGenesisBlock(request: OrdererRequest): Promise<any>;
|
|
||||||
getChannelConfig(): Promise<any>;
|
|
||||||
joinChannel(request: JoinChannelRequest): Promise<ProposalResponse>;
|
|
||||||
sendInstantiateProposal(request: ChaincodeInstantiateUpgradeRequest): Promise<ProposalResponseObject>;
|
|
||||||
sendTransactionProposal(request: ChaincodeInvokeRequest): Promise<ProposalResponseObject>;
|
|
||||||
sendTransaction(request: TransactionRequest): Promise<BroadcastResponse>;
|
|
||||||
queryByChaincode(request: ChaincodeQueryRequest): Promise<Buffer[]>;
|
|
||||||
queryBlock(blockNumber: number, target: Peer): Promise<any>;
|
|
||||||
queryTransaction(txId: string, target: Peer): Promise<any>;
|
|
||||||
queryInstantiatedChaincodes(target: Peer): Promise<ChaincodeQueryResponse>;
|
|
||||||
queryInfo(target: Peer): Promise<any>;
|
|
||||||
getOrderers(): Orderer[];
|
|
||||||
getPeers(): Peer[];
|
|
||||||
}
|
|
||||||
|
|
||||||
declare abstract class BaseClient {
|
|
||||||
static setLogger(logger: any): void;
|
|
||||||
static addConfigFile(path: string): void;
|
|
||||||
static getConfigSetting(name: string, default_value?: any): any;
|
|
||||||
static newCryptoSuite(): ICryptoSuite;
|
|
||||||
static newCryptoKeyStore(obj?: { path: string }): ICryptoKeyStore;
|
|
||||||
static newDefaultKeyValueStore(obj?: { path: string }): Promise<IKeyValueStore>;
|
|
||||||
setCryptoSuite(suite: ICryptoSuite): void;
|
|
||||||
getCryptoSuite(): ICryptoSuite;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare class TransactionId {
|
|
||||||
getTransactionID(): string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface UserConfig {
|
|
||||||
enrollmentID: string;
|
|
||||||
name: string
|
|
||||||
roles?: string[];
|
|
||||||
affiliation?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare class User {
|
|
||||||
isEnrolled(): boolean;
|
|
||||||
getName(): string;
|
|
||||||
getRoles(): string[];
|
|
||||||
setRoles(roles: string[]): void;
|
|
||||||
getAffiliation(): string;
|
|
||||||
setAffiliation(affiliation: string): void;
|
|
||||||
getIdentity(): IIdentity;
|
|
||||||
getSigningIdentity(): ISigningIdentity;
|
|
||||||
setCryptoSuite(suite: ICryptoSuite): void;
|
|
||||||
setEnrollment(privateKey: ICryptoKey, certificate: string, mspId: string): Promise<void>;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare class Client extends BaseClient {
|
|
||||||
isDevMode(): boolean;
|
|
||||||
getUserContext(name: string, checkPersistence: boolean): Promise<User> | User;
|
|
||||||
setUserContext(user: User, skipPersistence?: boolean): Promise<User>;
|
|
||||||
setDevMode(mode: boolean): void;
|
|
||||||
newOrderer(url: string, opts: ConnectionOptions): Orderer;
|
|
||||||
newChannel(name: string): Channel;
|
|
||||||
newPeer(url: string, opts: ConnectionOptions): Peer;
|
|
||||||
newEventHub(): EventHub;
|
|
||||||
newTransactionID(): TransactionId;
|
|
||||||
extractChannelConfig(envelope: Buffer): Buffer;
|
|
||||||
createChannel(request: ChannelRequest): Promise<BroadcastResponse>;
|
|
||||||
createUser(opts: UserOptions): Promise<User>;
|
|
||||||
signChannelConfig(config: Buffer): ConfigSignature;
|
|
||||||
setStateStore(store: IKeyValueStore): void;
|
|
||||||
installChaincode(request: ChaincodeInstallRequest): Promise<ProposalResponseObject>;
|
|
||||||
queryInstalledChaincodes(target: Peer): Promise<ChaincodeQueryResponse>;
|
|
||||||
queryChannels(target: Peer): Promise<ChannelQueryResponse>;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare module 'fabric-client' {
|
|
||||||
export = Client;
|
|
||||||
}
|
|
||||||
Loading…
Reference in a new issue