Merge branch 'release/1.2'
This commit is contained in:
commit
6e4eb2fbb6
|
@ -0,0 +1,3 @@
|
||||||
|
APIKEY=
|
||||||
|
APIMODE=
|
||||||
|
# Available modes: dev, startup, grow
|
|
@ -1,4 +1,7 @@
|
||||||
/node_modules
|
/node_modules
|
||||||
/orbitdb
|
/orbitdb
|
||||||
|
/receipts
|
||||||
|
/proyectsReceipts
|
||||||
package-lock.json
|
package-lock.json
|
||||||
.env
|
.env
|
||||||
|
.directory
|
||||||
|
|
91
README.md
91
README.md
|
@ -15,39 +15,40 @@ DECA's Carbon Credits OrbitDB Code and configs, everything you need for setting
|
||||||
## Carbon Credit Structure
|
## Carbon Credit Structure
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
{
|
|
||||||
/*
|
/*
|
||||||
CC - Carbon credits
|
CC - Carbon credits
|
||||||
Unix Time is date and time based in the UTC 0
|
Unix Time is date and time based in the UTC 0
|
||||||
example for the first carbon credit that is 1365209
|
example for the first carbon credit that is 1365209
|
||||||
*/
|
*/
|
||||||
SerialNo: 'GS1-1-MX-GS2441-16-2018-17438-328-328',
|
[
|
||||||
CCAddress: 'https://registry.goldstandard.org/credit-blocks/details/107995', //Address GS Registry
|
{
|
||||||
issueDate: 1552953600, // CC creation UnixTime
|
//CCID: unique Carbon Credit Hash in DECAs registry (used as receipt and control)
|
||||||
cancelDate: 1587214800, // CC cancelation cancelation UnixTime
|
CCID: 'a67178fa3cb20e49f748050871f4f10784693bde1b9ec805740ff9c63b93860d',
|
||||||
ccVintageStart: 1514764800, // CC what year it was created in UnixTime
|
SerialNo: 'GS1-1-MX-GS2441-16-2018-17438-328-328',
|
||||||
ccVintageEnd: 1514764800, // CC what year it was created in UnixTime
|
ccAddress: 'https://registry.goldstandard.org/credit-blocks/details/107995', //Address GS Registry
|
||||||
ccCategory: 'Energy Efficiency - Domestic', // CC category agricultural
|
issueDate: 1552953600, // CC creation UnixTime
|
||||||
ccMeasurement: 'VER(TCO2e)', //CC Measurement
|
cancelDate: 1587168000, // CC cancelation cancelation UnixTime
|
||||||
ccStandard: 'GS', // CC standard Woodland Carbon Credit
|
ccCategory: 'Energy Efficiency - Domestic', // CC category agricultural
|
||||||
countryCode: 'MX' // Country code
|
ccStandard: 'GS', // CC standard GoldStandard Carbon Credit
|
||||||
ccProjectID: 'GS2441', // CC project ID in the original backlog is it unique?
|
cancelPrice: { qty: '19.5', divisa: 'USD' },
|
||||||
ccID: 17438-328-328,
|
ccProjectID: 'GS2441', // CC project ID in the original backlog
|
||||||
CCAdquisitionRecipt: 'QmWWQSuPMS6aXCbZKpEjPHPUZN2NjB3YrhJTHsV4X3vb2t', //Recipt of CC in IPFS
|
countryCode: 'MX', // Country code
|
||||||
cancelPrice: {
|
cancelRemaks: 'Cancel by account 1067262',
|
||||||
qty: 19.50,
|
ccVintageEnd: 1546214400, // CC what end date it was created in UnixTime
|
||||||
divisa : 'USD'},
|
ccMeasurement: 'VER(TCO2e)', //CC Measurement
|
||||||
conversionPrice:{
|
ccVintageStart: 1514764800, // CC what date year it was created in UnixTime
|
||||||
USD: 19.50,
|
conversionPrice: {
|
||||||
EUR: 17.93,
|
BTC: 0.0027239430402556876,
|
||||||
CNY: 137.93,
|
CNY: 137.92740063195478,
|
||||||
BTC: 0.0027,
|
ETH: 0.10952545708624091,
|
||||||
LTC: 0.45,
|
EUR: 17.93351483640976,
|
||||||
ETH: 0.11,
|
GBP: 15.588145399888809,
|
||||||
},
|
LTC: 0.45310691929120134,
|
||||||
cancelRemaks: 'Cancel by account 1067262',
|
USD: 19.5
|
||||||
}
|
},
|
||||||
|
CCAdquisitionRecipt: 'QmYw6JTNABDDfXvc3U2BfURjF5Zzx9eG3N43wJqHc4upDL' //Recipt of CC in IPFS
|
||||||
|
}
|
||||||
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
@ -281,3 +282,37 @@ WantedBy=multi-user.target
|
||||||
```
|
```
|
||||||
**NOTE: service must be set as active (running), if not please verify the preview steps**
|
**NOTE: service must be set as active (running), if not please verify the preview steps**
|
||||||
|
|
||||||
|
# IPFS pin projects receipts
|
||||||
|
|
||||||
|
**You can help us by pinning DECA's project receipts into IPFS which will give deeper trust to DECA.**
|
||||||
|
|
||||||
|
We have a script in order to pin (replicate into your node) the projects receipts that DECA got, so that
|
||||||
|
any one can have a proof that we bought this receipts as public information. Also you can store a copy of this receipts which will be added by IPFS hash into this script.
|
||||||
|
|
||||||
|
> run the IPFS pin script
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ /receipts.sh
|
||||||
|
connect Qmd4Cv2fNwixP6cabEnTVFkF57GUGD6VBEcDhUkqHPG4X9 success
|
||||||
|
connect QmfBASmqe3Az9AUjCxx3dtomSmbZEiJCsXusPxznjNnjU5 success
|
||||||
|
connect QmQBAsbA49q7QrKhetJpbo5gKxQQiL6sxVXCep5skmuHsq success
|
||||||
|
connect QmZL1otpiCzWMEJTHXbQ5Hb4aFE7TKLjAuuBAAet1WAgtD success
|
||||||
|
|
||||||
|
IPFS PIN DECA's Carbon Credits Receipts?:
|
||||||
|
Enter Y for Yes, N for No:Y
|
||||||
|
Pinning Receipts by IPFS hash
|
||||||
|
pinned QmYw6JTNABDDfXvc3U2BfURjF5Zzx9eG3N43wJqHc4upDL recursively
|
||||||
|
|
||||||
|
IPFS GET(Download) DECA's Carbon Credits Receipts?:
|
||||||
|
Enter Y for Yes, N for No:Y
|
||||||
|
Getting Receipts by IPFS hash
|
||||||
|
Default receipts file is ./receipts...
|
||||||
|
Saving file(s) to ./proyectsReceipts
|
||||||
|
135.34 KiB / 135.34 KiB [======================================================================================================================================] 100.00% 0s
|
||||||
|
Bye ;)
|
||||||
|
|
||||||
|
$ ls proyectsReceipts
|
||||||
|
QmYw6JTNABDDfXvc3U2BfURjF5Zzx9eG3N43wJqHc4upDL
|
||||||
|
```
|
||||||
|
|
||||||
|
As you can see in the above example we pin the receipt by running " ./receipts.sh ", also we Download this receipt with should be allocated in the directory projects Receipts.
|
||||||
|
|
|
@ -1,66 +1,66 @@
|
||||||
|
const moment = require('moment');
|
||||||
const request = require('request-promise');
|
const request = require('request-promise');
|
||||||
|
require('dotenv').config();
|
||||||
require('dotenv').config()
|
|
||||||
|
|
||||||
// Source: https://apiv2.bitcoinaverage.com/
|
// Source: https://apiv2.bitcoinaverage.com/
|
||||||
|
|
||||||
const divisaTraceback = async(timestamp, divisa, amount) => {
|
const divisaTraceback = async(timestamp, divisa, amount) => {
|
||||||
let crypto = ['BTC', 'ETH', 'LTC']
|
let crypto = ['BTC', 'ETH', 'LTC']
|
||||||
let normal = ['USD', 'GBP', 'CNY', 'EUR'];
|
let normal = ['USD', 'GBP', 'CNY', 'EUR'];
|
||||||
let opt = { method: 'GET', json: true };
|
if(amount > 0) {
|
||||||
let cryptoHeaders = {
|
let divisaTraceback = {};
|
||||||
'X-Testing': 'testing',
|
let resolution = await getResolution(timestamp);
|
||||||
'x-ba-key': process.env.APIKEY
|
if(crypto.includes(divisa)) {
|
||||||
}
|
divisaTraceback[crypto.splice(crypto.indexOf(divisa), 1)[0]] = Number(amount);
|
||||||
try {
|
Object.assign(divisaTraceback, await requestIteration(normal, divisa, true, timestamp, amount, resolution));
|
||||||
if((Date.now() - 7776000000) <= (timestamp * 1000)) {
|
Object.assign(divisaTraceback, await requestIteration(crypto, 'USD', false, timestamp, divisaTraceback['USD'], resolution));
|
||||||
if(crypto.includes(divisa) || normal.includes(divisa)) {
|
}
|
||||||
if(amount > 0) {
|
else if (normal.includes(divisa)) {
|
||||||
opt.headers = cryptoHeaders;
|
divisaTraceback[normal.splice(normal.indexOf(divisa), 1)[0]] = Number(amount);
|
||||||
let divisaTraceback = {};
|
Object.assign(divisaTraceback, await requestIteration(crypto, divisa, false, timestamp, amount, resolution));
|
||||||
|
Object.assign(divisaTraceback, await requestIteration(normal, 'BTC', true, timestamp, divisaTraceback['BTC'], resolution));
|
||||||
|
} else throw new Error('Currency target invalid');
|
||||||
|
|
||||||
if(crypto.includes(divisa)) {
|
console.log(` Resolution: ${resolution}`);
|
||||||
divisaTraceback[crypto.splice(crypto.indexOf(divisa), 1)[0]] = Number(amount);
|
return(divisaTraceback);
|
||||||
Object.assign(divisaTraceback, await requestIteration(normal, divisa, true, timestamp, amount));
|
} else throw new Error('The amount must be 0 or higher');
|
||||||
Object.assign(divisaTraceback, await requestIteration(crypto, 'USD', false, timestamp, divisaTraceback['USD']));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
divisaTraceback[normal.splice(normal.indexOf(divisa), 1)[0]] = Number(amount);
|
|
||||||
Object.assign(divisaTraceback, await requestIteration(crypto, divisa, false, timestamp, amount));
|
|
||||||
Object.assign(divisaTraceback, await requestIteration(normal, 'BTC', true, timestamp, divisaTraceback['BTC']));
|
|
||||||
}
|
|
||||||
return(divisaTraceback);
|
|
||||||
} else return('The amount must be greater that 0');
|
|
||||||
} else return('Currency target invalid');
|
|
||||||
} else return('Date out of range')
|
|
||||||
} catch(e) {
|
|
||||||
return(e);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const requestIteration = async(set, divisa, flag, timestamp, amount) => {
|
const requestIteration = async(set, divisa, flag, timestamp, amount, resolution) => {
|
||||||
|
timestamp = timestamp.format('X');
|
||||||
let opt = {
|
let opt = {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
json: true,
|
json: true,
|
||||||
headers: {
|
headers: {
|
||||||
'X-Testing': 'testing',
|
|
||||||
'x-ba-key': process.env.APIKEY
|
'x-ba-key': process.env.APIKEY
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let res = {};
|
let res = {};
|
||||||
for (element in set) {
|
for (element in set) {
|
||||||
if(flag) {
|
if(flag) {
|
||||||
opt.uri = `https://apiv2.bitcoinaverage.com/indices/global/history/${divisa}${set[element]}?at=${timestamp}&resolution=hour`;
|
opt.uri = `https://apiv2.bitcoinaverage.com/indices/global/history/${divisa}${set[element]}?at=${timestamp}&resolution=${resolution}`;
|
||||||
let { average } = await request(opt);
|
let { average, time } = await request(opt);
|
||||||
res[set[element]] = average * amount;
|
res[set[element]] = average * amount;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
opt.uri = `https://apiv2.bitcoinaverage.com/indices/global/history/${set[element]}${divisa}?at=${timestamp}&resolution=hour`;
|
opt.uri = `https://apiv2.bitcoinaverage.com/indices/global/history/${set[element]}${divisa}?at=${timestamp}&resolution=${resolution}`;
|
||||||
let { average } = await request(opt);
|
let { average, time } = await request(opt);
|
||||||
res[set[element]] = amount / average;
|
res[set[element]] = amount / average;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getResolution = async(timestamp) => {
|
||||||
|
let resolution = 'day';
|
||||||
|
if(process.env.APIMODE == 'dev') {
|
||||||
|
if(timestamp >= moment.utc().subtract(2, 'hours')) resolution = 'minute';
|
||||||
|
else if(timestamp >= moment().subtract(10, 'days')) resolution = 'hour';
|
||||||
|
} else if(process.env.APIMODE == 'startup' || process.env.APIMODE == 'grow') {
|
||||||
|
if(timestamp >= moment.utc().subtract(24, 'hours')) resolution = 'minute';
|
||||||
|
else if(timestamp >= moment.utc().subtract(31, 'days')) resolution = 'hour';
|
||||||
|
} else throw new Error('Bad config at .env file');
|
||||||
|
return resolution;
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = divisaTraceback;
|
module.exports = divisaTraceback;
|
2
index.js
2
index.js
|
@ -3,7 +3,7 @@ const IpfsClient = require('ipfs-http-client');
|
||||||
const OrbitDB = require('orbit-db');
|
const OrbitDB = require('orbit-db');
|
||||||
//Instance of ipfs locally in ipfs daemon
|
//Instance of ipfs locally in ipfs daemon
|
||||||
const node = IpfsClient('http://localhost:5001');
|
const node = IpfsClient('http://localhost:5001');
|
||||||
const addressDB = 'decaCCDB';
|
const addressDB = '/orbitdb/zdpuAykPJ4qtBg2toS2vxr5eaPfGEBJmvGerM7V7x8qn5c8hW/decaCCDB';
|
||||||
|
|
||||||
//Async function to replicate or create a doc database
|
//Async function to replicate or create a doc database
|
||||||
async function createReplicate() {
|
async function createReplicate() {
|
||||||
|
|
241
interfaz.js
241
interfaz.js
|
@ -5,6 +5,7 @@ let inquirer = require('inquirer');
|
||||||
let moment = require('moment');
|
let moment = require('moment');
|
||||||
let hasher = require('node-object-hash')
|
let hasher = require('node-object-hash')
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
const addressDB = 'decaCCDB';
|
const addressDB = 'decaCCDB';
|
||||||
|
|
||||||
|
@ -17,6 +18,9 @@ const hashSortCoerce = hasher({ sort: true, coerce: true });
|
||||||
|
|
||||||
//Function to start application
|
//Function to start application
|
||||||
const main = async () => {
|
const main = async () => {
|
||||||
|
if (!fs.existsSync('./receipts')){
|
||||||
|
fs.mkdirSync('./receipts');
|
||||||
|
}
|
||||||
const orbitdb = await OrbitDB.createInstance(ipfs)
|
const orbitdb = await OrbitDB.createInstance(ipfs)
|
||||||
const db = await orbitdb.docs(addressDB, { indexBy: 'CCID' });
|
const db = await orbitdb.docs(addressDB, { indexBy: 'CCID' });
|
||||||
await db.load();
|
await db.load();
|
||||||
|
@ -36,8 +40,10 @@ const main = async () => {
|
||||||
}]);
|
}]);
|
||||||
if (mainMenu == 'Show carbon credit records') {
|
if (mainMenu == 'Show carbon credit records') {
|
||||||
let data = db.get('');
|
let data = db.get('');
|
||||||
|
console.log(` ${data.length} records found`);
|
||||||
while (true) {
|
while (true) {
|
||||||
let { showMenu } = await inquirer.prompt([{
|
const fileName = moment.utc().format();
|
||||||
|
let { showMenu } = await inquirer.prompt({
|
||||||
type: 'list',
|
type: 'list',
|
||||||
name: 'showMenu',
|
name: 'showMenu',
|
||||||
message: 'Select an option',
|
message: 'Select an option',
|
||||||
|
@ -45,24 +51,33 @@ const main = async () => {
|
||||||
'Show in terminal',
|
'Show in terminal',
|
||||||
'Save as JSON',
|
'Save as JSON',
|
||||||
'Save as CSV',
|
'Save as CSV',
|
||||||
|
'Save as TXT',
|
||||||
'Back to main menu'
|
'Back to main menu'
|
||||||
]
|
]
|
||||||
}]);
|
});
|
||||||
if (showMenu == 'Show in terminal') {
|
if (showMenu == 'Show in terminal') {
|
||||||
for (element in data) {
|
for (element in data) {
|
||||||
showData(data[element], 0);
|
showData(data[element]);
|
||||||
console.log('-------------------------------------\n');
|
console.log('-------------------------------------\n');
|
||||||
}
|
}
|
||||||
} else if (showMenu == 'Save as JSON') {
|
} else if (showMenu == 'Save as JSON') {
|
||||||
fs.writeFileSync(`/tmp/${moment().format()}.json`, JSON.stringify(data));
|
fs.writeFileSync(path.resolve('receipts', `${fileName}.json`), JSON.stringify(data));
|
||||||
console.log(`File saved in /tmp/${moment().format()}.json`);
|
console.log(`File saved in ${path.resolve('receipts', fileName + '.json')}`);
|
||||||
} else if (showMenu == 'Save as CSV') {
|
} else if (showMenu == 'Save as CSV') {
|
||||||
let csv = '';
|
let csv = await JSONToCSV(data);
|
||||||
for (element in data) csv += await JSONToCSV(data[element]);
|
fs.writeFileSync(path.resolve('receipts', `${fileName}.csv`), csv);
|
||||||
fs.writeFileSync(`/tmp/${moment().format()}.csv`, csv);
|
console.log(`File saved in ${path.resolve('receipts', fileName + '.csv')}`);
|
||||||
console.log(`File saved in /tmp/${moment().format()}.csv`);
|
} else if (showMenu == 'Save as TXT') {
|
||||||
}
|
let stream = fs.createWriteStream(path.resolve('receipts', `${fileName}.txt`));
|
||||||
else if (showMenu == 'Back to main menu') {
|
let result = await elemInsert(data);
|
||||||
|
stream.once('open', function (fd) {
|
||||||
|
for (let i = 0; i < result.length; i++) {
|
||||||
|
stream.write(result[i] + '\n');
|
||||||
|
}
|
||||||
|
stream.end();
|
||||||
|
});
|
||||||
|
console.log(`File saved in ${path.resolve('receipts', fileName + '.txt')}`);
|
||||||
|
} else if (showMenu == 'Back to main menu') {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -91,7 +106,7 @@ const main = async () => {
|
||||||
}
|
}
|
||||||
while (true) {
|
while (true) {
|
||||||
await init();
|
await init();
|
||||||
console.clear();
|
//console.clear();
|
||||||
console.log('Select one to modify the field.\n');
|
console.log('Select one to modify the field.\n');
|
||||||
let carbonCreditMenu = await generateData(carbonCredit, 0);
|
let carbonCreditMenu = await generateData(carbonCredit, 0);
|
||||||
let { insertMenu } = await inquirer.prompt([{
|
let { insertMenu } = await inquirer.prompt([{
|
||||||
|
@ -111,42 +126,55 @@ const main = async () => {
|
||||||
}]);
|
}]);
|
||||||
if (insertMenu == 'Insert current register') {
|
if (insertMenu == 'Insert current register') {
|
||||||
if (await validateInsertion(carbonCredit)) {
|
if (await validateInsertion(carbonCredit)) {
|
||||||
carbonCredit.conversionPrice = await divisaTraceback(
|
try{
|
||||||
moment.utc(carbonCredit.cancelDate + ' +0000', 'DD-MM-YYYY HH:mm Z').unix(),
|
carbonCredit.conversionPrice = await divisaTraceback(
|
||||||
carbonCredit.cancelPrice.divisa,
|
moment.utc(carbonCredit.cancelDate, 'DD-MM-YYYY HH:mm Z'),
|
||||||
carbonCredit.cancelPrice.qty
|
carbonCredit.cancelPrice.divisa,
|
||||||
);
|
carbonCredit.cancelPrice.qty
|
||||||
showData(carbonCredit, 0);
|
);
|
||||||
serialNoPart=carbonCredit.SerialNo.split('-');
|
if(carbonCredit.conversionPrice === 'error') throw new Error('Error at getting currencies price.');
|
||||||
serialFloor=serialNoPart[7];
|
showData(carbonCredit);
|
||||||
serialTop=serialNoPart[8];
|
serialNoPart=carbonCredit.SerialNo.split('-');
|
||||||
var totalCC = 1+parseInt(serialTop)-parseInt(serialFloor);
|
serialFloor=serialNoPart[7];
|
||||||
let { input } = await inquirer.prompt([{
|
serialTop=serialNoPart[8];
|
||||||
type: 'input',
|
let totalCC = 1+parseInt(serialTop)-parseInt(serialFloor);
|
||||||
name: 'input',
|
let { input } = await inquirer.prompt([{
|
||||||
message: 'Data is correct, you will insert '+ String(totalCC) +" carbon credits y | n:",
|
type: 'input',
|
||||||
}]);
|
name: 'input',
|
||||||
if (input == 'y') {
|
message: 'Data is correct, you will insert '+ String(totalCC) +" carbon credits y | n:",
|
||||||
carbonCredit.issueDate = moment(carbonCredit.issueDate + ' +0000', 'DD-MM-YYYY HH:mm Z').unix();
|
}]);
|
||||||
carbonCredit.cancelDate = moment(carbonCredit.cancelDate + ' +0000', 'DD-MM-YYYY HH:mm Z').unix();
|
if (input == 'y') {
|
||||||
carbonCredit.ccVintageStart = moment(carbonCredit.ccVintageStart + ' +0000', 'DD-MM-YYYY HH:mm Z').unix();
|
carbonCredit.issueDate = moment(carbonCredit.issueDate + ' +0000', 'DD-MM-YYYY HH:mm Z').unix();
|
||||||
carbonCredit.ccVintageEnd = moment(carbonCredit.ccVintageEnd + ' +0000', 'DD-MM-YYYY HH:mm Z').unix();
|
carbonCredit.cancelDate = moment(carbonCredit.cancelDate + ' +0000', 'DD-MM-YYYY HH:mm Z').unix();
|
||||||
carbonCredit.CCID = await hashSortCoerce.hash(carbonCredit);
|
carbonCredit.ccVintageStart = moment(carbonCredit.ccVintageStart + ' +0000', 'DD-MM-YYYY HH:mm Z').unix();
|
||||||
const hash = await db.put(carbonCredit);
|
carbonCredit.ccVintageEnd = moment(carbonCredit.ccVintageEnd + ' +0000', 'DD-MM-YYYY HH:mm Z').unix();
|
||||||
console.log(`Successful insertion, CCID: ${carbonCredit.CCID}, hash: ${hash}.`);
|
const fileName = moment.utc().format();
|
||||||
for(var i=parseInt(serialFloor)+1; i<=serialTop; i++){
|
let stream = fs.createWriteStream(path.resolve('receipts', fileName + '.txt'));
|
||||||
var tempCarbonCredit = {...carbonCredit};
|
stream.once('open', async function (fd) {
|
||||||
tempCarbonCredit.SerialNo= await asyncCCSerialNo(serialNoPart,i)
|
carbonCredit.CCID = await hashSortCoerce.hash(carbonCredit);
|
||||||
tempCarbonCredit.CCID = await hashSortCoerce.hash(tempCarbonCredit);
|
const hash = await db.put(carbonCredit);
|
||||||
const hash = await db.put(tempCarbonCredit);
|
stream.write(`CCID: ${carbonCredit.CCID} SerialNo: ${carbonCredit.SerialNo} \n`);
|
||||||
console.log(`Successful insertion, CCID: ${tempCarbonCredit.CCID}, hash: ${hash}.`);
|
for (let i = parseInt(serialFloor) + 1; i <= serialTop; i++) {
|
||||||
|
let tempCarbonCredit = {
|
||||||
|
...carbonCredit
|
||||||
|
};
|
||||||
|
tempCarbonCredit.SerialNo = await asyncCCSerialNo(serialNoPart, i)
|
||||||
|
tempCarbonCredit.CCID = await hashSortCoerce.hash(tempCarbonCredit);
|
||||||
|
const hash = await db.put(tempCarbonCredit);
|
||||||
|
stream.write(`CCID: ${tempCarbonCredit.CCID} SerialNo: ${tempCarbonCredit.SerialNo} \n`);
|
||||||
|
}
|
||||||
|
stream.end();
|
||||||
|
});
|
||||||
|
console.log(`Inserted ${totalCC} carbon credits.`);
|
||||||
|
console.log(`Receipts saved in ${path.resolve('receipts', fileName + '.txt')}`);
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
console.clear();
|
||||||
|
console.log('Insertion aborted');
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
console.log(`Inserted ${totalCC} carbon credits.`);
|
} catch(e) {
|
||||||
break;
|
console.log(`Error at divisaTraceback: ${e.message}`);
|
||||||
} else {
|
|
||||||
console.clear();
|
|
||||||
console.log('Insertion aborted');
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -182,12 +210,15 @@ const main = async () => {
|
||||||
if (input == '') console.log('Input mustn\'t be empty');
|
if (input == '') console.log('Input mustn\'t be empty');
|
||||||
else if (insertMenu == 'issueDate' || insertMenu == 'cancelDate' || insertMenu == 'ccVintageStart' || insertMenu == 'ccVintageEnd') {
|
else if (insertMenu == 'issueDate' || insertMenu == 'cancelDate' || insertMenu == 'ccVintageStart' || insertMenu == 'ccVintageEnd') {
|
||||||
const date = moment.utc(input + ' +0000', 'DD-MM-YYYY HH:mm');
|
const date = moment.utc(input + ' +0000', 'DD-MM-YYYY HH:mm');
|
||||||
if (date.isValid() && insertMenu == 'cancelDate' && moment() >= date && date >= moment().subtract(10, 'days')) {
|
console.log(date);
|
||||||
carbonCredit[insertMenu] = date.format('DD-MM-YYYY HH:mm Z');
|
if(date.isValid() && moment.utc() >= date) {
|
||||||
}
|
if(insertMenu != 'cancelDate') carbonCredit[insertMenu] = date.format('DD-MM-YYYY HH:mm Z');
|
||||||
else if (date.isValid() && insertMenu != 'cancelDate' && moment() >= date) {
|
else if((date >= moment.utc().subtract(3, 'months') && process.env.APIMODE == 'dev') ||
|
||||||
carbonCredit[insertMenu] = date.format('DD-MM-YYYY HH:mm Z');
|
(date >= moment.utc().subtract(1, 'years') && process.env.APIMODE == 'startup') ||
|
||||||
} else console.log(' Date must follow next syntax: dd-mm-yyyy hh-mm and cancel date must be 10 days old at most');
|
(date >= moment.utc().subtract(7, 'years') && process.env.APIMODE == 'grow')) {
|
||||||
|
carbonCredit[insertMenu] = date.format('DD-MM-YYYY HH:mm Z');
|
||||||
|
} else console.error(' Date is too old to get pricing data');
|
||||||
|
} else console.error(' Date must follow next syntax: dd-mm-yyyy hh-mm and can\'t be in the future');
|
||||||
}
|
}
|
||||||
else if (insertMenu == 'qty') {
|
else if (insertMenu == 'qty') {
|
||||||
if (parseFloat(input)) carbonCredit.cancelPrice[insertMenu] = input;
|
if (parseFloat(input)) carbonCredit.cancelPrice[insertMenu] = input;
|
||||||
|
@ -204,11 +235,13 @@ const main = async () => {
|
||||||
else if (mainMenu == 'Search carbon credits') {
|
else if (mainMenu == 'Search carbon credits') {
|
||||||
let { searchMenu } = await inquirer.prompt([{
|
let { searchMenu } = await inquirer.prompt([{
|
||||||
type: 'list',
|
type: 'list',
|
||||||
|
pageSize: 24,
|
||||||
name: 'searchMenu',
|
name: 'searchMenu',
|
||||||
message: 'Search carbon credit by:',
|
message: 'Search carbon credit by:',
|
||||||
choices: [
|
choices: [
|
||||||
'Category',
|
'Category',
|
||||||
'CCID',
|
'CCID',
|
||||||
|
'SerialNo',
|
||||||
'Standard',
|
'Standard',
|
||||||
'Project Id',
|
'Project Id',
|
||||||
'Vintage Date',
|
'Vintage Date',
|
||||||
|
@ -237,8 +270,12 @@ const main = async () => {
|
||||||
message: 'Select CCID',
|
message: 'Select CCID',
|
||||||
choices: choicesSearch
|
choices: choicesSearch
|
||||||
}]).then(answer => {
|
}]).then(answer => {
|
||||||
console.log(db.get(answer.CCID))
|
let query = db.get(answer.CCID);
|
||||||
})
|
for (element in query) {
|
||||||
|
showData(query[element]);
|
||||||
|
console.log('-------------------------------------\n');
|
||||||
|
}
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
console.clear();
|
console.clear();
|
||||||
console.log("No registries found")
|
console.log("No registries found")
|
||||||
|
@ -248,6 +285,28 @@ const main = async () => {
|
||||||
console.log('Search canceled');
|
console.log('Search canceled');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (searchMenu == 'SerialNo') {
|
||||||
|
let { input } = await inquirer.prompt([{
|
||||||
|
type: 'input',
|
||||||
|
name: 'input',
|
||||||
|
message: 'SerialNo: ',
|
||||||
|
}]);
|
||||||
|
let { confirm } = await inquirer.prompt([{
|
||||||
|
type: 'input',
|
||||||
|
name: 'confirm',
|
||||||
|
message: 'Confirm y | n: ',
|
||||||
|
}]);
|
||||||
|
if (confirm == 'y') {
|
||||||
|
const data = db.query((doc) => doc.SerialNo == input);
|
||||||
|
for (element in data) {
|
||||||
|
showData(data[element]);
|
||||||
|
console.log('-------------------------------------\n');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.clear();
|
||||||
|
console.log('Search canceled');
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (searchMenu == 'CCID') {
|
else if (searchMenu == 'CCID') {
|
||||||
let { input } = await inquirer.prompt([{
|
let { input } = await inquirer.prompt([{
|
||||||
type: 'input',
|
type: 'input',
|
||||||
|
@ -260,7 +319,8 @@ const main = async () => {
|
||||||
message: 'Confirm y | n: ',
|
message: 'Confirm y | n: ',
|
||||||
}]);
|
}]);
|
||||||
if (confirm == 'y') {
|
if (confirm == 'y') {
|
||||||
console.log(db.get(input))
|
showData(db.get(input)[0]);
|
||||||
|
console.log('-------------------------------------\n');
|
||||||
} else {
|
} else {
|
||||||
console.clear();
|
console.clear();
|
||||||
console.log('Search canceled');
|
console.log('Search canceled');
|
||||||
|
@ -287,7 +347,11 @@ const main = async () => {
|
||||||
message: 'Select CCID',
|
message: 'Select CCID',
|
||||||
choices: choicesSearch
|
choices: choicesSearch
|
||||||
}]).then(answer => {
|
}]).then(answer => {
|
||||||
console.log(db.get(answer.CCID))
|
let query = db.get(answer.CCID);
|
||||||
|
for (element in query) {
|
||||||
|
showData(query[element]);
|
||||||
|
console.log('-------------------------------------\n');
|
||||||
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
console.clear();
|
console.clear();
|
||||||
|
@ -319,7 +383,11 @@ const main = async () => {
|
||||||
message: 'Select CCID',
|
message: 'Select CCID',
|
||||||
choices: choicesSearch
|
choices: choicesSearch
|
||||||
}]).then(answer => {
|
}]).then(answer => {
|
||||||
console.log(db.get(answer.CCID))
|
let query = db.get(answer.CCID);
|
||||||
|
for (element in query) {
|
||||||
|
showData(query[element]);
|
||||||
|
console.log('-------------------------------------\n');
|
||||||
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
console.clear();
|
console.clear();
|
||||||
|
@ -333,6 +401,7 @@ const main = async () => {
|
||||||
else if (searchMenu == 'Vintage Date') {
|
else if (searchMenu == 'Vintage Date') {
|
||||||
let { vintageMenu } = await inquirer.prompt([{
|
let { vintageMenu } = await inquirer.prompt([{
|
||||||
type: 'list',
|
type: 'list',
|
||||||
|
pageSize: 24,
|
||||||
name: 'vintageMenu',
|
name: 'vintageMenu',
|
||||||
message: 'Search carbon credit by:',
|
message: 'Search carbon credit by:',
|
||||||
choices: [
|
choices: [
|
||||||
|
@ -364,7 +433,11 @@ const main = async () => {
|
||||||
message: 'Select CCID',
|
message: 'Select CCID',
|
||||||
choices: choicesSearch
|
choices: choicesSearch
|
||||||
}]).then(answer => {
|
}]).then(answer => {
|
||||||
console.log(db.get(answer.CCID))
|
let query = db.get(answer.CCID);
|
||||||
|
for (element in query) {
|
||||||
|
showData(query[element]);
|
||||||
|
console.log('-------------------------------------\n');
|
||||||
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
console.clear();
|
console.clear();
|
||||||
|
@ -397,7 +470,11 @@ const main = async () => {
|
||||||
message: 'Select CCID',
|
message: 'Select CCID',
|
||||||
choices: choicesSearch
|
choices: choicesSearch
|
||||||
}]).then(answer => {
|
}]).then(answer => {
|
||||||
console.log(db.get(answer.CCID))
|
let query = db.get(answer.CCID);
|
||||||
|
for (element in query) {
|
||||||
|
showData(query[element]);
|
||||||
|
console.log('-------------------------------------\n');
|
||||||
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
console.clear();
|
console.clear();
|
||||||
|
@ -433,7 +510,11 @@ const main = async () => {
|
||||||
message: 'Select CCID',
|
message: 'Select CCID',
|
||||||
choices: choicesSearch
|
choices: choicesSearch
|
||||||
}]).then(answer => {
|
}]).then(answer => {
|
||||||
console.log(db.get(answer.CCID))
|
let query = db.get(answer.CCID);
|
||||||
|
for (element in query) {
|
||||||
|
showData(query[element]);
|
||||||
|
console.log('-------------------------------------\n');
|
||||||
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
console.clear();
|
console.clear();
|
||||||
|
@ -514,6 +595,14 @@ const elemSearch = async (objectSearch) => {
|
||||||
return elems;
|
return elems;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const elemInsert = async (objectShow) => {
|
||||||
|
let elems = [];
|
||||||
|
for (let key in objectShow) {
|
||||||
|
elems.push('CCID: ' + objectShow[key]['CCID'] + ' SerialNumber: ' + objectShow[key]['SerialNo']);
|
||||||
|
}
|
||||||
|
return elems;
|
||||||
|
}
|
||||||
|
|
||||||
const generateData = async (data, n) => {
|
const generateData = async (data, n) => {
|
||||||
let menu = [];
|
let menu = [];
|
||||||
let tab = ' '.repeat(n);
|
let tab = ' '.repeat(n);
|
||||||
|
@ -522,7 +611,7 @@ const generateData = async (data, n) => {
|
||||||
menu.push({ name: element, disabled: ' ' });
|
menu.push({ name: element, disabled: ' ' });
|
||||||
menu = menu.concat(await generateData(data[element], n + 1));
|
menu = menu.concat(await generateData(data[element], n + 1));
|
||||||
} else {
|
} else {
|
||||||
let space = ' '.repeat(20 - element.length);
|
let space = ' '.repeat(25 - element.length);
|
||||||
space = space.substring(0, space.length - tab.length);
|
space = space.substring(0, space.length - tab.length);
|
||||||
menu.push(`${tab}${element}${space}${data[element]}`);
|
menu.push(`${tab}${element}${space}${data[element]}`);
|
||||||
}
|
}
|
||||||
|
@ -536,7 +625,7 @@ const asyncCCSerialNo = async (serialNoPart, index) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
//Show carbon credit data
|
//Show carbon credit data
|
||||||
const showData = async (data, n) => {
|
const showData = async (data, n = 0) => {
|
||||||
for (element in data) {
|
for (element in data) {
|
||||||
for (let i = 0; i < n; i++) process.stdout.write('\t');
|
for (let i = 0; i < n; i++) process.stdout.write('\t');
|
||||||
if (typeof (data[element]) == 'object') {
|
if (typeof (data[element]) == 'object') {
|
||||||
|
@ -575,14 +664,28 @@ const showErrorData = async (data) => {
|
||||||
|
|
||||||
//Parse json to csv
|
//Parse json to csv
|
||||||
const JSONToCSV = async (data, n) => {
|
const JSONToCSV = async (data, n) => {
|
||||||
let csv = '';
|
let csv;
|
||||||
for (element in data) {
|
for (element in data[0]) {
|
||||||
if (typeof (data[element]) == 'object') {
|
console.log(typeof(data[0][element]));
|
||||||
validateInsertion(data[element]);
|
console.log(data[0][element]);
|
||||||
|
if (typeof data[0][element] == 'object') {
|
||||||
|
console.log('Entro aqui')
|
||||||
|
for(subelement in data[0][element]) csv += `${element} - ${subelement}, `;
|
||||||
}
|
}
|
||||||
else csv += `${data[element]}, `
|
else csv += `${element}, `;
|
||||||
|
}
|
||||||
|
csv = csv.slice(0, -2);
|
||||||
|
csv += '\n';
|
||||||
|
for(record in data) {
|
||||||
|
for (element in data[record]) {
|
||||||
|
if (typeof data[record][element] == 'object') {
|
||||||
|
for(subelement in data[0][element]) csv += `${data[record][element][subelement]}, `;
|
||||||
|
}
|
||||||
|
else csv += `${data[record][element]}, `;
|
||||||
|
}
|
||||||
|
csv = csv.slice(0, -2);
|
||||||
|
csv += '\n';
|
||||||
}
|
}
|
||||||
if (n == 0) csv += '\n';
|
|
||||||
return csv;
|
return csv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
./connectNodes.sh
|
||||||
|
|
||||||
|
# Receipts and Files to PIN
|
||||||
|
FilesHashList=("QmYw6JTNABDDfXvc3U2BfURjF5Zzx9eG3N43wJqHc4upDL" ) # \
|
||||||
|
#"" \
|
||||||
|
#"" \)
|
||||||
|
echo ""
|
||||||
|
echo "IPFS PIN DECA's Carbon Credits Receipts?:"
|
||||||
|
|
||||||
|
read -p "Enter Y for Yes, N for No:" choice
|
||||||
|
case "$choice" in
|
||||||
|
Y | y) echo "Pinning Receipts by IPFS hash";
|
||||||
|
for val in ${FilesHashList[*]}; do
|
||||||
|
/usr/local/bin/ipfs pin add $val
|
||||||
|
done
|
||||||
|
;;
|
||||||
|
N | n) ;;
|
||||||
|
|
||||||
|
*) echo "no option selected";;
|
||||||
|
esac
|
||||||
|
|
||||||
|
receiptsRoute=./proyectsReceipts
|
||||||
|
echo ""
|
||||||
|
echo "IPFS GET(Download) DECA's Carbon Credits Receipts?:"
|
||||||
|
|
||||||
|
read -p "Enter Y for Yes, N for No:" choice
|
||||||
|
case "$choice" in
|
||||||
|
Y | y) echo "Getting Receipts by IPFS hash";
|
||||||
|
echo "Default receipts file is ./receipts..."
|
||||||
|
mkdir $receiptsRoute
|
||||||
|
for val in ${FilesHashList[*]}; do
|
||||||
|
/usr/local/bin/ipfs get $val -o $receiptsRoute
|
||||||
|
done
|
||||||
|
;;
|
||||||
|
N | n) ;;
|
||||||
|
|
||||||
|
*) echo "no option selected";;
|
||||||
|
esac
|
||||||
|
|
||||||
|
echo "Bye ;) $USERNAME"
|
||||||
|
|
Loading…
Reference in New Issue