- Added rest api support for the TIC blockchain deployment

- Refer README for instructions
parent e6cbda43
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# TypeScript v1 declaration files
typings/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
.env.test
# parcel-bundler cache (https://parceljs.org/)
.cache
# Next.js build output
.next
# Nuxt.js build / generate output
.nuxt
dist
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and *not* Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
wallet/
# Reference : https://github.com/mhart/alpine-node#example-dockerfile-for-your-own-nodejs-project
# This stage installs our modules
FROM mhart/alpine-node:12
LABEL stage=rest-api-stage1-docker-builder
WORKDIR /app
COPY package.json package-lock.json ./
# If you have native dependencies, you'll need extra tools
# RUN apk add --no-cache make gcc g++ python3
RUN apk add --no-cache make g++ python3
RUN npm ci --prod
# Then we copy over the modules from above onto a `slim` image
FROM mhart/alpine-node:slim-12
LABEL stage=rest-api-stage2-docker-builder
# If possible, run your container using `docker run --init`
# Otherwise, you can use `tini`:
# RUN apk add --no-cache tini
# ENTRYPOINT ["/sbin/tini", "--"]
WORKDIR /app
COPY --from=0 /app .
COPY . .
EXPOSE 3001
CMD [ "node", "rest_api.js" ]
\ No newline at end of file
This diff is collapsed.
# fabric_as_code_restapi
# Rest API Usage Instructions
[Rest API Usage Instructions with curl examples](curl_instructions/README.md)
# Requirements
1. Bityoga fabric should be up and running
2. Node version
- Supports node version >=v11.0.0
- Tested with v11.0.0
# Run Instructions
1. ## Clone this repository
- git clone https://github.com/bityoga/fabric_as_code_restapi.git
2. ## Run npm install
- cd fabric_as_code_restapi/
- #### Set node version
- nvm use node v11.0.0 (using nvm)
- **Execute Command :** npm install
3. ## Update fabric ip address in 'smart_energy_app/fabric_node_sdk_helper/network_profile.json'
- (For other New App Developers) fabric_node_sdk_helper is available in git repository : https://github.com/bityoga/fabric_node_sdk_helper.git
- **update the url ip addresses of orderer, peer2, orgca, tlsca (4 places)**.
- update it with your prime manager's ip address
4. ## Retrieve hyperledger fabric tls certificates of 'orderer' and 'peer2'
#### Through shell script - needs ssh permission
- cd smart_energy_app/fabric_node_sdk_helper
- In 'smart_energy_app/fabric_node_sdk_helper/get_tls_certificates.sh' Replace **IP_ADDRESS="178.62.207.235"** with your fabric prime manager's ip address
- **Execute Command :** bash get_tls_certificates.sh
#### (OR) Through Manual scp commands - needs ssh permission
- Replace ipaddress in the below scp commands with your fabric prime manager's ip address.
- scp -r root@178.62.207.235:/root/hlft-store/orgca/orderer/msp/tls/ca.crt .smart_energy_app/fabric_node_sdk_helper/hlft-store/orderer/tls-msp/tlscacerts/ca.crt
- scp -r root@178.62.207.235:/root/hlft-store/orgca/peer2/msp/tls/ca.crt .smart_energy_app/fabric_node_sdk_helper/hlft-store/peer2/tls-msp/tlscacerts/ca.crt
#### (OR) Manually edit the following two files - no need of ssh permission
- smart_energy_app/fabric_node_sdk_helper/hlft-store/orderer/tls-msp/tlscacerts/ca.crt
- smart_energy_app/fabric_node_sdk_helper/hlft-store/peer2/tls-msp/tlscacerts/ca.crt
5. ## Start App
**## Using node ##**
- cd fabric_as_code_restapi/
- **Execute Command :** node rest_api.js
- app will be running in 'localhost' at port 3001
- open in browser: http://localhost:3001/
**## Using "nodemon" (Live reload app on save - No need to restart app everytime - Just refresh browser after every save) ##**
-**Install Nodemon (if not installed)** - npm install -g nodemon
- cd smart_energy_app/
- **Execute Command :** nodemon rest_api.js
- app will be running in 'localhost' at port 3001
- open in browser: http://localhost:3001/
- Now everytime you make some changes to file and save it, the app will automatically reload again. We need to refresh the browser to see the changes.
## Dockerisation
### 1) Build Docker Image
```sh
$ git clone https://github.com/bityoga/fabric_as_code_restapi.git
$ cd fabric_as_code_restapi
```
Do step 3 & 4 as said above
```sh
$ docker build --tag rest-api .
```
### 2a) Run as a docker container
```sh
$ docker run -d --name rest-api -p 3001:3001 rest-api:latest
```
### 2b) Run as a docker service with replicas
```sh
$ docker service create --name rest-api-service --replicas 1 -p 3001:3001 rest-api:latest
```
{
"rest_api_port":3001,
"fabric_ca_admin_user_name":"admin1",
"fabric_ca_admin_password":"admin1pw",
"fabric_organisation_msp_name":"hlfMSP",
"fabric_ca_organisation_name":"orgca",
"rest_api_admin_user_name":"rest_api_admin_user",
"rest_api_admin_password":"rest_api_admin_password",
"rest_api_admin_user_role":"client"
}
\ No newline at end of file
#!/bin/bash
set -x #echo on
docker build --tag rest-api . &&
docker image prune --filter label=stage=rest-api-stage1-docker-builder --force &&
docker image prune --filter label=stage=rest-api-stage2-docker-builder --force &&
docker image rm mhart/alpine-node:12 --force &&
docker image rm mhart/alpine-node:slim-12 --force
# Rest API Usage Instructions
## Curl Examples
### 1) Get Authentication token
- **Api endpoint :** /jwt
- **Required Post Data :** Rest_Api_Admin_User_Name, Rest_Api_Admin_Password
- **Example curl command :**
```sh
curl -H "Content-Type: application/json" --request POST -d '{"Rest_Api_Admin_User_Name":"rest_api_admin_user","Rest_Api_Admin_Password":"rest_api_admin_password"}' http://localhost:3001/jwt | jq '.'
```
- **Sample Success Response :**
```json
{
"status": "success",
"response": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJib2R5Ijoic3R1ZmYiLCJpYXQiOjE2MDQzNDExNzR9.Um_pFgR3-O9rRBeO7bqvQPQM1EpBWUh5V6ZXuVjqT-4"
}
```
- **Sample Failure Response :**
```json
{
"status": "fail",
"error": "Not Authorised - User Name and Password wrong"
}
```
### 2) Register User
- **Api endpoint :** /register
- **Required Post Data :** User_Name, User_Password, User_Role
- **Example curl command :**
```sh
curl -H "Content-Type: application/json" --request POST -d '{"User_Name":"7xyzzgtrtvyp","User_Password":"7xyzzgttrvyp","User_Role":"client"}' -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJib2R5Ijoic3R1ZmYiLCJpYXQiOjE2MDQzNDA3MTR9._F7oqjK7vooX1Tj-FCzHcnT7g7KkLrAaVPNXq3Y1IhM" http://localhost:3001/register | jq '.
```
- **Sample Success Response :**
```json
{
"status": "success",
"response": {
"User_Name": "test_user2",
"User_Password": "test_user2",
"User_Role": "client",
"User_Private_Key": "-----BEGIN PRIVATE KEY-----\r\nMIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgSSjLV989TX6P8FfN\r\nNrMrymuIV+Wq8/hLFKs/bGTwld2hRANCAAQJbe24E8DAsC6mwKWdX/kNQwI8lO7u\r\npvFerU+FAvCSetJcHaEC3Rq5bcvD5gn6M2EX9CsyGY86PPiJvCJjBKV+\r\n-----END PRIVATE KEY-----\r\n",
"User_Public_Key": "-----BEGIN PUBLIC KEY-----\r\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAECW3tuBPAwLAupsClnV/5DUMCPJTu\r\n7qbxXq1PhQLwknrSXB2hAt0auW3Lw+YJ+jNhF/QrMhmPOjz4ibwiYwSlfg==\r\n-----END PUBLIC KEY-----\r\n",
"User_Enrollment_Certificate": "{\"name\":\"test_user2\",\"mspid\":\"hlfMSP\",\"roles\":null,\"affiliation\":\"\",\"enrollmentSecret\":\"\",\"enrollment\":{\"signingIdentity\":\"eb727214d511ce94a9d77ab11d3aad5ee3b1973d9b00ce3809423ab89ecd1a98\",\"identity\":{\"certificate\":\"-----BEGIN CERTIFICATE-----\\nMIICRjCCAeygAwIBAgIUP9hOKMbIETtIUeGp/V+xgG4eF7cwCgYIKoZIzj0EAwIw\\nXTELMAkGA1UEBhMCVVMxFzAVBgNVBAgTDk5vcnRoIENhcm9saW5hMRQwEgYDVQQK\\nEwtIeXBlcmxlZGdlcjEPMA0GA1UECxMGRmFicmljMQ4wDAYDVQQDEwVvcmdjYTAe\\nFw0yMDExMDIxODQwMDBaFw0yMTExMDIxODQ1MDBaMCYxDzANBgNVBAsTBmNsaWVu\\ndDETMBEGA1UEAwwKdGVzdF91c2VyMjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA\\nBAlt7bgTwMCwLqbApZ1f+Q1DAjyU7u6m8V6tT4UC8JJ60lwdoQLdGrlty8PmCfoz\\nYRf0KzIZjzo8+Im8ImMEpX6jgcAwgb0wDgYDVR0PAQH/BAQDAgeAMAwGA1UdEwEB\\n/wQCMAAwHQYDVR0OBBYEFMcgiuXQoQS1EzYteMdC+CbZszzXMB8GA1UdIwQYMBaA\\nFFZt+fT49HhEQbD5w5nwhfpyyupCMF0GCCoDBAUGBwgBBFF7ImF0dHJzIjp7Imhm\\nLkFmZmlsaWF0aW9uIjoiIiwiaGYuRW5yb2xsbWVudElEIjoidGVzdF91c2VyMiIs\\nImhmLlR5cGUiOiJjbGllbnQifX0wCgYIKoZIzj0EAwIDSAAwRQIhAIo+NDygO5xj\\nCMIUEQDr/VyWFObpEIsN22eSq91QM6OnAiAOy1+WOWmPLjGs+NPbON+7kJyad68b\\n+DMfEidaTnbBVA==\\n-----END CERTIFICATE-----\\n\"}}}",
"Registered_Timestamp": "2020-11-02T18:45:04.629Z",
"registerStatus": "success"
}
}
```
- **Sample Failure Response :**
```json
{
"status": "fail",
"response": {
"registerStatus": "fail",
"registerError": "An identity for the user \"test_user\" already exists in the wallet"
}
}
```
### 3) Query Chaincode
- **Api endpoint :** /query
- **Required Post Data :** Channel_Name, Chaincode_Name, Chaincode_Function_Name, Chaincode_Function_Json_Arguments
- **Example curl command :**
```sh
curl -H "Content-Type: application/json" --request POST -d '{"Channel_Name":"appchannel","Chaincode_Name":"energy","Chaincode_Function_Name":"ReadAsset","Chaincode_Function_Json_Arguments":["[\"ark\"]"]}' -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJib2R5Ijoic3R1ZmYiLCJpYXQiOjE2MDQzNDA3MTR9._F7oqjK7vooX1Tj-FCzHcnT7g7KkLrAaVPNXq3Y1IhM" http://localhost:3001/query | jq '.'
```
- **Sample Success Response :**
```json
{
"status": "success",
"response": {
"queryStatus": "success",
"queryResponse": {
"Balance": "1000",
"ID": "ark",
"Type": "Initial Credit"
}
}
}
```
- **Sample Failure Response :**
```json
{
"status": "success",
"response": {
"queryStatus": "fail",
"queryError": "Failed to evaluate transaction: Error: error in simulation: transaction returned with failure: Error: The user arkk does not exist"
}
}
```
### 4) Invoke Chaincode
- **Api endpoint :** /invoke
- **Required Post Data :** Channel_Name, Chaincode_Name, Chaincode_Function_Name, Chaincode_Function_Json_Arguments
- **Example curl command :**
```sh
curl -H "Content-Type: application/json" --request POST -d '{"Channel_Name":"appchannel","Chaincode_Name":"energy","Chaincode_Function_Name":"TransferBalance","Chaincode_Function_Json_Arguments":["[\"ark\",\"ark2\",\"10\",\"Buy Energy\"]"]}' -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJib2R5Ijoic3R1ZmYiLCJpYXQiOjE2MDQzNDA3MTR9._F7oqjK7vooX1Tj-FCzHcnT7g7KkLrAaVPNXq3Y1IhM" http://localhost:3001/invoke | jq '.'
```
- **Sample Success Response :**
```json
{
"status": "success",
"response": "{\"invokeStatus\":\"success\",\"invokeResponse\":\"\"}"
}
```
- **Sample Failure Response :**
```json
{
"status": "success",
"response": "{\"invokeStatus\":\"fail\",\"invokeError\":\"Failed to evaluate transaction: Error: No valid responses from any peers. 1 peer error responses:\\n peer=peer2, status=500, message=error in simulation: transaction returned with failure: Error: The user ark22 does not exist\"}"
}
```
const sqlite3_async = require("sqlite-async");
var fs = require("fs").promises;
const { write_certificates_from_db_to_wallet } = require("./fileread");
async function sqlite_json_insert(db_name, json_dict, table_name) {
let insert_status;
try {
table_keys = Object.keys(json_dict).join(", ");
table_values = Object.values(json_dict).join("','");
let sql =
"INSERT INTO " +
table_name +
"(" +
table_keys +
") VALUES ('" +
table_values +
"')";
console.log(sql);
// open the database connection
let db_con = await sqlite3_async.open(db_name);
insert_status = await db_con.run(sql);
if ("changes" in insert_status) {
if (insert_status["changes"] > 0) {
insert_status = "success";
}
}
await db_con.close();
} catch (e) {
insert_status = e;
} finally {
return insert_status;
}
}
async function check_login_and_load_certificates(
db_name,
user_name,
user_password
) {
let login_status = {};
login_status["status"] = "";
try {
console.log("1");
let db_con = await sqlite3_async.open(db_name);
let let_sql_query =
'SELECT * FROM User where User.User_Name = "' + user_name + '" ;';
console.log(let_sql_query);
const result = await db_con.all(let_sql_query);
await db_con.close();
console.log(result.length);
console.log("2");
if (result.length > 0) {
let user_info = result[0];
login_status["User_Id"] = user_info["User_Id"];
if (user_info["User_Password"] === user_password) {
let enrollment_json = JSON.parse(
user_info["User_Enrollment_Certificate"]
);
let enrollment_signingIdentity =
enrollment_json["enrollment"]["signingIdentity"];
console.log(
"enrollment_signingIdentity = " + enrollment_signingIdentity
);
console.log("3");
//console.log(user_info);
write_status = await write_certificates_from_db_to_wallet(
user_info,
enrollment_signingIdentity
);
console.log(write_status);
login_status["status"] = write_status;
console.log("4");
} else {
login_status["status"] = "Password is wrong";
}
} else {
login_status["status"] = "Account does not exist - Please register";
}
} catch (e) {
console.log(e);
login_status["status"] = e;
} finally {
console.log("5");
return login_status;
}
}
async function db_query(db_name, let_sql_query) {
let status;
try {
console.log("1");
let db_con = await sqlite3_async.open(db_name);
//let let_sql_query = 'SELECT * FROM '+table_name+';';
console.log(let_sql_query);
const result = await db_con.all(let_sql_query);
await db_con.close();
console.log(result.length);
console.log("2");
status = result;
} catch (e) {
console.log(e);
status = e;
} finally {
console.log("5");
return status;
}
}
module.exports = {
sqlite_json_insert: sqlite_json_insert,
check_login_and_load_certificates: check_login_and_load_certificates,
db_query: db_query,
};
# Fabric SDK Adaptor
Node sdk examples to interact with bityoga fabric set up
# Requirements
1. Bityoga fabric sdk should be up and running
2. Node version
- Supports node version >=8
- Tested with v8.10.0
# Run Instructions
1. ## Clone this repository into your app directory
- git clone https://github.com/bityoga/fabric_node_sdk_helper.git
2. ## Update your app's package.json
- Edit your app's **package.json with the "fabric_node_sdk_helper/package.json"** found in this repository.
3. ## Run npm install
- #### Set node version
- nvm use node v8.9.0 (using nvm)
- npm install
3. ## Update ip address in 'fabric_node_sdk_helper/network_profile.json'
- **update the url ip addresses of orderer, peer2, orgca, tlsca (4 places).**
- update it with your prime manager's ip address
4. ## Retrieve hyperledger fabric tls certificates of 'orderer' and 'peer2'
#### Through shell script - needs ssh permission
- cd fabric_node_sdk_helper/
- In 'fabric_node_sdk_helper/get_tls_certificates.sh' Replace **IP_ADDRESS="178.62.207.235"** with your fabric prime manager's ip address
- **Execute Command :** bash get_tls_certificates.sh
#### (OR) Through Manual scp commands - needs ssh permission
- Replace ipaddress in the below scp commands with your fabric prime manager's ip address.
- scp -r root@178.62.207.235:/root/hlft-store/orderer/tls-msp/tlscacerts/tls-tlsca-7054.pem ./fabric_node_sdk_helper/hlft-store/orderer/tls-msp/tlscacerts/tls-tlsca-7054.pem
- scp -r root@178.62.207.235:/root/hlft-store/peer2/tls-msp/tlscacerts/tls-tlsca-7054.pem ./fabric_node_sdk_helper/hlft-store/peer2/tls-msp/tlscacerts/tls-tlsca-7054.pem
#### (OR) Manually edit the following two files - no need of ssh permission
- fabric_node_sdk_helper/hlft-store/orderer/tls-msp/tlscacerts/tls-tlsca-7054.pem
- fabric_node_sdk_helper/hlft-store/peer2/tls-msp/tlscacerts/tls-tlsca-7054.pem
5. ## Enroll admin
- #### Call this function "once" when your app starts.
- When this function is called, a **wallet** directory will be created in the current directory
- Admin user will be enrolled and the certificates will availalble in **wallet** directory
- If fabric certificates are changed in future, this wallet directory should cleaned, and this function must be called again to get the new certificates
- check wallet directory
- a directory named 'admin' will be available
- certificates for admin will be available under this directory.
- sample :
``` Javascript
// import fabric node sdk helper functions
const enrollAdmin = require('./fabric_node_sdk_helper/enrollAdmin');
async function main() {
admin_enroll_status = await enrollAdmin();
console.log(admin_enroll_status);
}
main();
```
6. ## Register user
- sample :
``` Javascript
// import fabric node sdk helper functions
const registerUser = require('./fabric_node_sdk_helper/registerUser');
app.post('/register', async (req, res) => {
let user_name = req.body.uname;
let user_password = req.body.psw;
let user_role = "client";
let register_status = await registerUser(user_name,
user_password,
user_role);
let response = {
status:register_status
};
res.json(response);
});
```
- check wallet directory
- a directory with the name of the 'registerd user name' will be available
- certificates for the registerd user will be available under this directory.
7. ## Query a chaincode
- sample :
``` Javascript
// import fabric node sdk helper functions
const querychaincode = require('./fabric_node_sdk_helper/query');
app.post('/query', async (req, res) => {
let user_name = req.body.uname;
let CHANNEL_NAME = "appchannel";
let CHAIN_CODE_NAME = "carcc";
let CHAIN_CODE_FUNCTION_NAME = "listCars";
// Without Arguments
let query_result = await querychaincode(user_name,CHANNEL_NAME,CHAIN_CODE_NAME, CHAIN_CODE_FUNCTION_NAME);
// With Arguments
let query_result = await querychaincode(user_name,CHANNEL_NAME,CHAIN_CODE_NAME, CHAIN_CODE_FUNCTION_NAME , "a");
let response = {
"status":"success",
"data":query_result
};
console.log(response);
res.json(response);
});
```
8. ## Invoke a chaincode
- sample :
``` Javascript
// import fabric node sdk helper functions
const invokechaincode = require('./fabric_node_sdk_helper/invoke');
app.post('/invoke', async (req, res) => {
let user_name = req.body.uname;
let car_license_plate = req.body.car_license_plate;
let CHANNEL_NAME = "appchannel";
let CHAIN_CODE_NAME = "carcc";
let CHAIN_CODE_FUNCTION_NAME = "listCars";
let invoke_result = await invokechaincode(user_name,
CHANNEL_NAME,
CHAIN_CODE_NAME,
CHAIN_CODE_FUNCTION_NAME,
car_license_plate,
"Opel","Corsa","Light Blue","7","2050","1");
let response = {
"status":"success",
"data":invoke_result
};
console.log(response);
res.json(response);
});
```
/*
* SPDX-License-Identifier: Apache-2.0
*/
"use strict";
const FabricCAServices = require("fabric-ca-client");
const { FileSystemWallet, X509WalletMixin } = require("fabric-network");
const fs = require("fs");
const path = require("path");
const ccpPath = path.resolve(__dirname, ".", "network_profile.json");
const ccpJSON = fs.readFileSync(ccpPath, "utf8");
const ccp = JSON.parse(ccpJSON);
async function enrollAdmin(
admin_username,
admin_password,
organisation_msp,
ca_organisation_name
) {
let return_value;
try {
// Create a new CA client for interacting with the CA.
const caInfo = ccp.certificateAuthorities[ca_organisation_name];
console.log(caInfo);
const caTLSCACerts = [];
//const caTLSCACerts = caInfo.tlsCACerts.pem;
const ca = new FabricCAServices(
caInfo.url,
{ trustedRoots: caTLSCACerts, verify: false },
caInfo.caName
);
// Create a new file system based wallet for managing identities.
const walletPath = path.join(process.cwd(), "wallet");
const wallet = new FileSystemWallet(walletPath);
console.log(`Wallet path: ${walletPath}`);
// Check to see if we've already enrolled the admin user.
const adminExists = await wallet.exists("admin");
if (adminExists) {
return_value =
'An identity for the admin user "admin" already exists in the wallet';
} else {
// Enroll the admin user, and import the new identity into the wallet.
const enrollment = await ca.enroll({
enrollmentID: admin_username,
enrollmentSecret: admin_password,
});
const identity = X509WalletMixin.createIdentity(
organisation_msp,
enrollment.certificate,
enrollment.key.toBytes()
);
await wallet.import("admin", identity);
return_value =
'Successfully enrolled admin user "admin" and imported it into the wallet';
}
} catch (error) {
return_value = `Failed to enroll admin user "admin": ${error}`;
} finally {
console.log("'enrollAdmin' function -> returning value");
return return_value;
}
}
module.exports = enrollAdmin;
#!/bin/bash
set -x #echo on
IP_ADDRESS="157.230.182.168"
REMOTE_MACHINE_ORDERER_TLS_CERT_FILE="/root/hlft-store/orgca/orderer/msp/tls/ca.crt"
REMOTE_MACHINE_PEER2_TLS_CERT_FILE="/root/hlft-store/orgca/peer2/msp/tls/ca.crt"
LOCAL_ORDER_TLS_CERT_FILE="./hlft-store/orderer/tls-msp/tlscacerts/ca.crt"
LOCAL_ORDER_PEER2_CERT_FILE="./hlft-store/peer2/tls-msp/tlscacerts/ca.crt"
scp -r root@$IP_ADDRESS:$REMOTE_MACHINE_ORDERER_TLS_CERT_FILE $LOCAL_ORDER_TLS_CERT_FILE &&
scp -r root@$IP_ADDRESS:$REMOTE_MACHINE_PEER2_TLS_CERT_FILE $LOCAL_ORDER_PEER2_CERT_FILE
-----BEGIN CERTIFICATE-----
MIIB/zCCAaegAwIBAgIUJQAycqIM5mHkMRYSZD1rH6n77LMwCgYIKoZIzj0EAwIw
XTELMAkGA1UEBhMCVVMxFzAVBgNVBAgTDk5vcnRoIENhcm9saW5hMRQwEgYDVQQK
EwtIeXBlcmxlZGdlcjEPMA0GA1UECxMGRmFicmljMQ4wDAYDVQQDEwV0bHNjYTAe
Fw0yMDEwMTkxNzU5MDBaFw0zNTEwMTYxNzU5MDBaMF0xCzAJBgNVBAYTAlVTMRcw
FQYDVQQIEw5Ob3J0aCBDYXJvbGluYTEUMBIGA1UEChMLSHlwZXJsZWRnZXIxDzAN
BgNVBAsTBkZhYnJpYzEOMAwGA1UEAxMFdGxzY2EwWTATBgcqhkjOPQIBBggqhkjO
PQMBBwNCAASThUiGKMXIylPz46lYQgDBuyfIO9+4Rq/4t1f4ViRKXnilQQSEhe9Y
pEaCnAQGUwjh5dMfcShUST+UrZl11cwSo0UwQzAOBgNVHQ8BAf8EBAMCAQYwEgYD
VR0TAQH/BAgwBgEB/wIBATAdBgNVHQ4EFgQUM4SIyrjHKIU7v8aguPxYwygR3cYw
CgYIKoZIzj0EAwIDRgAwQwIfJVYEAnbU1OHjfU2T0M7I4UYIjDgiHo2v8f6Tz2hE
9gIgFfzLSNAL6yC/zcZFdI+YeD61wtxJG8X5bgCYMwYB96k=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIB/zCCAaegAwIBAgIUJQAycqIM5mHkMRYSZD1rH6n77LMwCgYIKoZIzj0EAwIw
XTELMAkGA1UEBhMCVVMxFzAVBgNVBAgTDk5vcnRoIENhcm9saW5hMRQwEgYDVQQK
EwtIeXBlcmxlZGdlcjEPMA0GA1UECxMGRmFicmljMQ4wDAYDVQQDEwV0bHNjYTAe
Fw0yMDEwMTkxNzU5MDBaFw0zNTEwMTYxNzU5MDBaMF0xCzAJBgNVBAYTAlVTMRcw
FQYDVQQIEw5Ob3J0aCBDYXJvbGluYTEUMBIGA1UEChMLSHlwZXJsZWRnZXIxDzAN
BgNVBAsTBkZhYnJpYzEOMAwGA1UEAxMFdGxzY2EwWTATBgcqhkjOPQIBBggqhkjO
PQMBBwNCAASThUiGKMXIylPz46lYQgDBuyfIO9+4Rq/4t1f4ViRKXnilQQSEhe9Y
pEaCnAQGUwjh5dMfcShUST+UrZl11cwSo0UwQzAOBgNVHQ8BAf8EBAMCAQYwEgYD
VR0TAQH/BAgwBgEB/wIBATAdBgNVHQ4EFgQUM4SIyrjHKIU7v8aguPxYwygR3cYw
CgYIKoZIzj0EAwIDRgAwQwIfJVYEAnbU1OHjfU2T0M7I4UYIjDgiHo2v8f6Tz2hE
9gIgFfzLSNAL6yC/zcZFdI+YeD61wtxJG8X5bgCYMwYB96k=
-----END CERTIFICATE-----
/*
* SPDX-License-Identifier: Apache-2.0
*/
"use strict";
const { FileSystemWallet, Gateway } = require("fabric-network");
const fs = require("fs");
const path = require("path");
const ccpPath = path.resolve(__dirname, ".", "network_profile.json");
async function invokechaincode(
USER_NAME,
CHANNEL_NAME,
CHAIN_CODE_NAME,
CHAIN_CODE_FUNCTION_NAME,
...ARGS
) {
let jsonResponse = {};
try {
// Create a new file system based wallet for managing identities.
const walletPath = path.join(process.cwd(), "wallet");
const wallet = new FileSystemWallet(walletPath);
console.log(`Wallet path: ${walletPath}`);
// Check to see if we've already enrolled the user.
const userExists = await wallet.exists(USER_NAME);
if (!userExists) {
jsonResponse["invokeStatus"] = "fail";
jsonResponse["invokeError"] =
"An identity for the user " +
USER_NAME +
" does not exist in the wallet.";
} else {
// Create a new gateway for connecting to our peer node.
const gateway = new Gateway();
await gateway.connect(ccpPath, {
wallet,
identity: USER_NAME,
discovery: { enabled: false, asLocalhost: false },
});
// Get the network (channel) our contract is deployed to.
const network = await gateway.getNetwork(CHANNEL_NAME);
// Get the contract from the network.
const contract = network.getContract(CHAIN_CODE_NAME);
// Submit the specified transaction.
let invokeResponse = await contract.submitTransaction(
CHAIN_CODE_FUNCTION_NAME,
...ARGS
);
jsonResponse["invokeStatus"] = "success";
jsonResponse["invokeResponse"] = invokeResponse.toString();
console.log("Transaction has been submitted");
// Disconnect from the gateway.
await gateway.disconnect();
}
} catch (error) {
jsonResponse["invokeStatus"] = "fail";
jsonResponse["invokeError"] = `Failed to evaluate transaction: ${error}`;
} finally {
console.log("####### Invoke Status ########");
console.log(
`Transaction Invoke has been evaluated, result is: ${JSON.stringify(
jsonResponse
)}`
);
return JSON.stringify(jsonResponse);
}
}
module.exports = invokechaincode;
{
"name": "hlf-bityoga",
"version": "1.0.0",
"client": {
"organization": "hlf",
"connection": {
"timeout": {
"peer": {
"endorser": "300"
}
}
}
},
"channels": {
"appchannel": {
"orderers": ["orderer"],
"peers": {
"peer2": {
"endorsingPeer": "true",
"chaincodeQuery": "true",
"ledgerQuery": "true",
"eventSource": "true",
"discover": "true"
},
"peer1": {
"endorsingPeer": "false",
"chaincodeQuery": "false",
"ledgerQuery": "true",
"eventSource": "false",
"discover": "true"
}
}
}
},
"organizations": {
"hlf": {
"mspid": "hlfMSP",
"peers": ["peer2", "peer1"],
"certificateAuthorities": ["orgca", "tlsca"]
}
},
"orderers": {
"orderer": {
"url": "grpcs://157.230.182.168:8053",
"tlsCACerts": {
"path": "./hlft-store/orderer/tls-msp/tlscacerts/ca.crt"
},
"grpcOptions": {
"ssl-target-name-override": "orderer"
}
}
},
"peers": {
"peer2": {
"url": "grpcs://157.230.182.168:8055",
"tlsCACerts": {
"path": "./hlft-store/peer2/tls-msp/tlscacerts/ca.crt"
},
"grpcOptions": {
"ssl-target-name-override": "peer2"
}
}
},
"certificateAuthorities": {
"orgca": {
"caName": "orgca",
"url": "https://157.230.182.168:8052",
"httpOptions": {
"verify": false
}
},
"tlsca": {
"caName": "tlsca",
"url": "https://157.230.182.168:8081",
"httpOptions": {
"verify": false
}
}
}
}
{
"engines": {
"node": ">=8",
"npm": ">=5"
},
"scripts": {
"lint": "eslint .",
"pretest": "npm run lint",
"test": "nyc mocha --recursive"
},
"engineStrict": true,
"author": "Hyperledger",
"license": "Apache-2.0",
"dependencies": {
"fabric-ca-client": "~1.4.3",
"fabric-network": "~1.4.3"
},
"devDependencies": {
"chai": "^4.2.0",
"eslint": "^5.9.0",
"mocha": "^5.2.0",
"nyc": "^15.0.0",
"sinon": "^7.1.1",
"sinon-chai": "^3.3.0"
},
"nyc": {
"exclude": [
"coverage/**",
"test/**"
],
"reporter": [
"text-summary",
"html"
],
"all": true,
"check-coverage": true,
"statements": 100,
"branches": 100,
"functions": 100,
"lines": 100
}
}
/*
* SPDX-License-Identifier: Apache-2.0
*/
"use strict";
const { FileSystemWallet, Gateway } = require("fabric-network");
const fs = require("fs");
const path = require("path");
const ccpPath = path.resolve(__dirname, ".", "network_profile.json");
async function querychaincode(
USER_NAME,
CHANNEL_NAME,
CHAIN_CODE_NAME,
CHAIN_CODE_FUNCTION_NAME,
...ARGS
) {
let jsonResponse = {};
try {
// Create a new file system based wallet for managing identities.
const walletPath = path.join(process.cwd(), "wallet");
const wallet = new FileSystemWallet(walletPath);
console.log(`Wallet path: ${walletPath}`);
// Check to see if we've already enrolled the user.
const userExists = await wallet.exists(USER_NAME);
if (!userExists) {
jsonResponse["queryStatus"] = "fail";
jsonResponse["queryError"] =
"An identity for the user " +
USER_NAME +
" does not exist in the wallet.";
} else {
// Create a new gateway for connecting to our peer node.
const gateway = new Gateway();
await gateway.connect(ccpPath, {
wallet,
identity: USER_NAME,
discovery: { enabled: false, asLocalhost: false },
});
// Get the network (channel) our contract is deployed to.
const network = await gateway.getNetwork(CHANNEL_NAME);
// Get the contract from the network.
const contract = network.getContract(CHAIN_CODE_NAME);
console.log(ARGS);
console.log(CHAIN_CODE_FUNCTION_NAME);
let queryResponse = await contract.evaluateTransaction(
CHAIN_CODE_FUNCTION_NAME,
...ARGS
);
jsonResponse["queryStatus"] = "success";
jsonResponse["queryResponse"] = JSON.parse(queryResponse.toString());
}
} catch (error) {
jsonResponse["queryStatus"] = "fail";
jsonResponse["queryError"] = `Failed to evaluate transaction: ${error}`;
} finally {
console.log("####### Query Status ########");
console.log(
`Transaction Query has been evaluated, result is: ${JSON.stringify(
jsonResponse
)}`
);
return JSON.stringify(jsonResponse);
}
}
module.exports = querychaincode;
/*
* SPDX-License-Identifier: Apache-2.0
*/
"use strict";
const {
FileSystemWallet,
Gateway,
X509WalletMixin,
} = require("fabric-network");
const path = require("path");
const ccpPath = path.resolve(__dirname, ".", "network_profile.json");
async function registerUser(user_name, user_password, user_role) {
let jsonResponse = {};
try {
// Create a new file system based wallet for managing identities.
const walletPath = path.join(process.cwd(), "wallet");
const wallet = new FileSystemWallet(walletPath);
console.log(`Wallet path: ${walletPath}`);
// Check to see if we've already enrolled the user.
const userExists = await wallet.exists(user_name);
if (userExists) {
jsonResponse["registerStatus"] = "fail";
jsonResponse["registerError"] =
'An identity for the user "' +
user_name +
'" already exists in the wallet';
} else {
// Check to see if we've already enrolled the admin user.
const adminExists = await wallet.exists("admin");
if (!adminExists) {
jsonResponse["registerStatus"] = "fail";
jsonResponse["registerError"] =
"An identity for the admin user 'admin' does not exist in the wallet. Call 'enrollAdmin' function before retrying";
} else {
// Create a new gateway for connecting to our peer node.
const gateway = new Gateway();
await gateway.connect(ccpPath, {
wallet,
identity: "admin",
discovery: { enabled: true, asLocalhost: false },
});
// Get the CA client object from the gateway for interacting with the CA.
const ca = gateway.getClient().getCertificateAuthority();
const adminIdentity = gateway.getCurrentIdentity();
console.log(user_name, user_role, user_password);
// Register the user, enroll the user, and import the new identity into the wallet.
const secret = await ca.register(
{
enrollmentID: user_name,
role: user_role,
enrollmentSecret: user_password,
},
adminIdentity
);
const enrollment = await ca.enroll({
enrollmentID: user_name,
enrollmentSecret: secret,
});
const userIdentity = X509WalletMixin.createIdentity(
"hlfMSP",
enrollment.certificate,
enrollment.key.toBytes()
);
await wallet.import(user_name, userIdentity);
jsonResponse["registerStatus"] = "success";
jsonResponse["registerIdentity"] = userIdentity;
console.log(
'Successfully registered and enrolled user "' +
user_name +
'" with role "' +
user_role +
'" and imported it into the wallet'
);
}
}
} catch (error) {
jsonResponse["registerStatus"] = "success";
jsonResponse["registerError"] =
"Failed to register user " + user_name + ": " + error;
} finally {
console.log("####### Register Status ########");
console.log(`Register response is: ${JSON.stringify(jsonResponse)}`);
return JSON.stringify(jsonResponse);
}
}
module.exports = registerUser;
var fs = require('fs').promises;
async function load_certificates_from_wallet(user_name) {
let certificates_json = {};
let cert_path = './wallet/'+user_name+'/';
try {
//get all filenames under a directory
var file_list = await fs.readdir(cert_path);
console.log(file_list);
for (index = 0; index < file_list.length; index++) {
console.log(file_list[index]);
if (file_list[index].includes('-priv')) {
let full_file_path = cert_path + file_list[index];
//read file contents to a string
certificates_json['User_Private_Key'] = await fs.readFile(full_file_path, "utf8");
}
if (file_list[index].includes('-pub')) {
let full_file_path = cert_path + file_list[index];
//read file contents to a string
certificates_json['User_Public_Key'] = await fs.readFile(full_file_path, "utf8");
}
if (file_list[index].includes(user_name)) {
let full_file_path = cert_path + file_list[index];
//read file contents to a string
certificates_json['User_Enrollment_Certificate'] = await fs.readFile(full_file_path, "utf8");
}
}
}
catch(e) {
console.log(e);
}
finally {
return certificates_json;
}
}
async function checkDirectorySync(directory) {
try {
await fs.stat(directory);
} catch(e) {
await fs.mkdir(directory);
}
}
async function write_certificates_from_db_to_wallet(db_user_info,enrollment_signingIdentity) {
let write_status;
let user_name = db_user_info['User_Name'];
let cert_path = './wallet/'+user_name+'/';
try {
//get all filenames under a directory
await checkDirectorySync(cert_path);
var file_list = await fs.readdir(cert_path);
if(file_list.length==0){
console.log(db_user_info["User_Private_Key"]);
await fs.writeFile(cert_path+enrollment_signingIdentity+"-priv", db_user_info["User_Private_Key"]);
await fs.writeFile(cert_path+enrollment_signingIdentity+"-pub", db_user_info["User_Public_Key"]);
await fs.writeFile(cert_path+user_name, db_user_info["User_Enrollment_Certificate"]);
write_status = "success";
}
else {
write_status = "success";
}
}
catch(e) {
write_status = e;
}
finally {
return write_status;
}
}
// async function check_file_load_to_wallet(user_name) {
// let load_status = await write_certificates_from_db_to_wallet(user_name);
// console.log(load_status);
// }
// let user_info = {};
// user_info["User_Name"] = "ark";
// user_info["User_Password"] = "ark";
// check_file_load_to_wallet(user_info);
// async function check_file_load_to_db(user_name) {
// let load_status = await load_certificates_from_wallet(user_name);
// console.log(load_status);
// }
// await check_file_load_to_db('ark');
module.exports = {
load_certificates_from_wallet : load_certificates_from_wallet,
write_certificates_from_db_to_wallet : write_certificates_from_db_to_wallet
};
\ No newline at end of file
This diff is collapsed.
{
"name": "fabric_as_code_restapi",
"version": "1.0.0",
"description": "fabric as code rest api",
"main": "rest_app.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/bityoga/fabric_as_code_restapi.git"
},
"keywords": [
"fabric",
"as",
"code",
"rest",
"api",
"hyper",
"fabric",
"rest",
"api"
],
"author": "anandhakumar palanisamy",
"license": "Apache-2.0",
"bugs": {
"url": "https://github.com/bityoga/fabric_as_code_restapi/issues"
},
"homepage": "https://github.com/bityoga/fabric_as_code_restapi#readme",
"dependencies": {
"crypto": "^1.0.1",
"express": "^4.17.1",
"fabric-ca-client": "~1.4.3",
"fabric-network": "~1.4.3",
"fs": "0.0.1-security",
"jsonwebtoken": "^8.5.1",
"sqlite-async": "^1.1.0"
},
"devDependencies": {
"chai": "^4.2.0",
"eslint": "^5.9.0",
"mocha": "^5.2.0",
"nyc": "^15.0.0",
"sinon": "^7.1.1",
"sinon-chai": "^3.3.0"
}
}
// import required node js libraries
const fs = require("fs");
const path = require("path");
const express = require("express");
const jwt = require("jsonwebtoken");
const bodyParser = require("body-parser");
var crypto = require("crypto");
// import fabric node sdk helper functions
const enrollAdmin = require("./fabric_node_sdk_helper/enrollAdmin");
const registerUser = require("./fabric_node_sdk_helper/registerUser");
const querychaincode = require("./fabric_node_sdk_helper/query");
const invokechaincode = require("./fabric_node_sdk_helper/invoke");
const { load_certificates_from_wallet } = require("./fileread");
const { sqlite_json_insert } = require("./db_query");
// Global variables;
const API_CONFIG_FILE = "api_config.json";
const DB_NAME = "rest_api_db.sqlite";
// Global variable to store the api config from file
let apiConfigJson;
// Load api config from json file
try {
const apiConfigFilePath = path.resolve(__dirname, ".", API_CONFIG_FILE);
const apiConfigFileContent = fs.readFileSync(apiConfigFilePath, "utf8");
apiConfigJson = JSON.parse(apiConfigFileContent);
console.log(apiConfigJson);
} catch (e) {
console.log(e);
throw Error("API Start Error - Error while reading API config", e);
}
// Declare a express app object
const app = express();
// Body-parser - to support JSON-encoded bodies
app.use(bodyParser.json());
app.use(
bodyParser.urlencoded({
// to support URL-encoded bodies
extended: true,
})
);
app.get("/", (req, res) => res.send("tic Restful Api"));
app.post("/jwt", (req, res) => {
let jsonResponse = {};
let postRequestData;
try {
postRequestData = req.body;
console.log("postRequestData");
if (
postRequestData["Rest_Api_Admin_User_Name"] ===
apiConfigJson["rest_api_admin_user_name"] &&
postRequestData["Rest_Api_Admin_Password"] ===
apiConfigJson["rest_api_admin_password"]
) {
console.log("inside if");
let privateKey =
apiConfigJson["rest_api_admin_user_name"] +
apiConfigJson["rest_api_admin_password"];
let privateKeyHash = crypto
.createHash("md5")
.update(privateKey)
.digest("hex");
console.log(privateKeyHash);
let token = jwt.sign({ body: "stuff" }, privateKeyHash, {
algorithm: "HS256",
});
jsonResponse["status"] = "success";
jsonResponse["response"] = token;
} else {
jsonResponse["status"] = "fail";
jsonResponse["error"] = "Not Authorised - User Name and Password wrong";
}
} catch (error) {
jsonResponse["status"] = "fail";
jsonResponse["error"] = error;
} finally {
console.log("########### jwt Response #################");
console.log(jsonResponse);
res.json(jsonResponse);
}
});
app.post("/register", isAuthorized, async (req, res) => {
console.log("inside register");
let postRequestData;
let registerStatus = "success";
let registeredUserInfo;
let fabricRegisterStatus;
let jsonResponse = {};
try {
postRequestData = req.body;
console.log(postRequestData);
fabricRegisterStatus = JSON.parse(
await registerUser(
postRequestData["User_Name"],
postRequestData["User_Password"],
postRequestData["User_Role"]
)
);
console.log(fabricRegisterStatus);
if (fabricRegisterStatus["registerStatus"].includes("success")) {
let userCertificatesJson = await load_certificates_from_wallet(
postRequestData["User_Name"]
);
let currentTimestamp = { Registered_Timestamp: new Date() };
registeredUserInfo = {
...postRequestData,
...userCertificatesJson,
...currentTimestamp,
};
let insertStatus = await sqlite_json_insert(
DB_NAME,
registeredUserInfo,
"User"
);
registerStatus = insertStatus;
jsonResponse["status"] = registerStatus;
registeredUserInfo["registerStatus"] =
fabricRegisterStatus["registerStatus"];
jsonResponse["response"] = registeredUserInfo;
} else {
jsonResponse["status"] = "fail";
jsonResponse["response"] = fabricRegisterStatus;
}
} catch (e) {
console.log(e);
registerStatus = e;
jsonResponse["status"] = "fail";
jsonResponse["error"] = e;
} finally {
res.json(jsonResponse);
}
});
app.post("/query", isAuthorized, async (req, res) => {
let jsonResponse = {};
let postRequestData;
try {
postRequestData = req.body;
console.log(postRequestData);
let functionArguments = generate_function_arguments(postRequestData);
let fabricQueryResult = await querychaincode.apply(this, functionArguments);
jsonResponse["status"] = "success";
jsonResponse["response"] = JSON.parse(fabricQueryResult);
} catch (e) {
console.log(e);
jsonResponse["status"] = "fail";
jsonResponse["error"] = e;
} finally {
res.json(jsonResponse);
}
});
app.post("/invoke", isAuthorized, async (req, res) => {
let jsonResponse = {};
let postRequestData;
try {
postRequestData = req.body;
console.log(postRequestData);
let functionArguments = generate_function_arguments(postRequestData);
let fabricInvokeResult = await invokechaincode.apply(
this,
functionArguments
);
jsonResponse["status"] = "success";
jsonResponse["response"] = fabricInvokeResult;
} catch (e) {
console.log(e);
jsonResponse["status"] = "fail";
jsonResponse["error"] = e;
} finally {
res.json(jsonResponse);
}
});
function generate_function_arguments(postRequestData) {
let functionArguments = [];
functionArguments.push(apiConfigJson["rest_api_admin_user_name"]);
functionArguments.push(postRequestData["Channel_Name"]);
functionArguments.push(postRequestData["Chaincode_Name"]);
functionArguments.push(postRequestData["Chaincode_Function_Name"]);
let chaincodeFunctionArguments = JSON.parse(
postRequestData["Chaincode_Function_Json_Arguments"]
);
console.log("chaincodeFunctionArguments");
console.log(chaincodeFunctionArguments);
if (Array.isArray(chaincodeFunctionArguments)) {
functionArguments.push(...chaincodeFunctionArguments);
} else {
functionArguments.push(chaincodeFunctionArguments);
}
console.log("functionArguments");
console.log(functionArguments);
return functionArguments;
}
function isAuthorized(req, res, next) {
if (typeof req.headers.authorization !== "undefined") {
// retrieve the authorization header and parse out the
// JWT using the split function
let token = req.headers.authorization.split(" ")[1];
// Generate rest api privateKeyHash to generate token
let privateKey =
apiConfigJson["rest_api_admin_user_name"] +
apiConfigJson["rest_api_admin_password"];
let privateKeyHash = crypto
.createHash("md5")
.update(privateKey)
.digest("hex");
console.log(privateKeyHash);
// Here we validate that the JSON Web Token is valid and has been
// created using the same private pass phrase
jwt.verify(token, privateKeyHash, { algorithm: "HS256" }, (err, user) => {
// if there has been an error...
if (err) {
// shut them out!
res.status(500).json({ error: "Not Authorized" });
}
// if the JWT is valid, allow them to hit
// the intended endpoint
return next();
});
} else {
// No authorization header exists on the incoming
// request, return not authorized
res.status(500).json({ error: "Not Authorized" });
}
}
async function main() {
try {
const admin_enroll_status = await enrollAdmin(
apiConfigJson["fabric_ca_admin_user_name"],
apiConfigJson["fabric_ca_admin_password"],
apiConfigJson["fabric_organisation_msp_name"],
apiConfigJson["fabric_ca_organisation_name"]
);
console.log(admin_enroll_status);
const apiAdminUserRegisterStatus = await registerUser(
apiConfigJson["rest_api_admin_user_name"],
apiConfigJson["rest_api_admin_password"],
apiConfigJson["rest_api_admin_user_role"]
);
console.log(apiAdminUserRegisterStatus);
} catch (error) {
throw Error("API Start Error - Error while enrolling admin", e);
} finally {
const port = apiConfigJson["rest_api_port"];
app.listen(port, () => console.log(`Rest Api listening on port ${port}!`));
}
}
main();
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment