diff --git a/CMakeLists.txt b/CMakeLists.txt index 15d01f5..7a120ea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -77,9 +77,10 @@ target_precompile_headers(sagent PUBLIC src/pchheader.hpp) # Add target to generate the installer setup. add_custom_target(installer COMMAND mkdir -p ./build/sashimono-installer - COMMAND bash -c "cp -r ./build/{sagent,sashi,hpfs,user-install.sh,user-uninstall.sh,contract_template,mb-xrpl} ./build/sashimono-installer/" + COMMAND bash -c "cp -r ./build/{sagent,sashi,hpfs,user-install.sh,user-uninstall.sh,contract_template} ./build/sashimono-installer/" COMMAND bash -c "cp -r ./installer/{docker-install.sh,registry-install.sh,registry-uninstall.sh,sashimono-install.sh,sashimono-uninstall.sh} ./build/sashimono-installer/" COMMAND bash -c "cp -r ./dependencies/{user-cgcreate.sh,libblake3.so} ./build/sashimono-installer/" + COMMAND bash -c "cp -r ./mb-xrpl/dist/mb-xrpl ./build/sashimono-installer/" COMMAND tar cfz ./build/sashimono-installer.tar.gz --directory=./build/ sashimono-installer COMMAND rm -r ./build/sashimono-installer ) diff --git a/examples/sample-user-wallet/user-wallet.js b/examples/sample-user-wallet/user-wallet.js index de67ffb..c3e97b2 100644 --- a/examples/sample-user-wallet/user-wallet.js +++ b/examples/sample-user-wallet/user-wallet.js @@ -2,16 +2,13 @@ const fs = require('fs'); const readLine = require('readline'); const { v4: uuidv4 } = require('uuid'); const fetch = require('node-fetch'); -const xrpl = require('../../mb-xrpl/ripple-handler'); -const XrplAccount = xrpl.XrplAccount; -const RippleAPIWarpper = xrpl.RippleAPIWarpper; +const { XrplAccount, RippleAPIWarpper, Events, MemoFormats, MemoTypes } = require('../../mb-xrpl/lib/ripple-handler'); const RIPPLE_SERVER = 'wss://hooks-testnet.xrpl-labs.com'; const FAUSET_URL = 'https://hooks-testnet.xrpl-labs.com/newcreds'; const OWNER_PUBKEY = 'ed5cb83404120ac759609819591ef839b7d222c84f1f08b3012f490586159d2b50' const CONFIG_PATH = 'user.cfg'; -const REDEEM_FEE = 1; // Test Hook // rwQ7ECXhkF1ZF6qFHH4y7sc1y3ZnXgf6Rh @@ -64,7 +61,7 @@ class TestUser { this.xrplAcc = new XrplAccount(this.ripplAPI.api, this.cfg.xrpl.address, this.cfg.xrpl.secret); this.evernodeXrplAcc = new XrplAccount(this.ripplAPI.api, this.cfg.xrpl.hookAddress); - this.evernodeXrplAcc.events.on(xrpl.Events.PAYMENT, (data, error) => { + this.evernodeXrplAcc.events.on(Events.PAYMENT, (data, error) => { if (data) { // Check whether issued currency const isXrp = (typeof data.Amount !== "object"); @@ -79,8 +76,8 @@ class TestUser { data: m.Memo.MemoData ? hexToASCII(m.Memo.MemoData) : null }; }); - const instanceRef = deserialized.filter(m => m.data && m.type === xrpl.MemoTypes.INST_CRET_REF && m.format === xrpl.MemoFormats.BINARY); - const instanceInfo = deserialized.filter(m => m.data && m.type === xrpl.MemoTypes.INST_CRET_RESP && m.format === xrpl.MemoFormats.BINARY); + const instanceRef = deserialized.filter(m => m.data && m.type === MemoTypes.REDEEM_REF && m.format === MemoFormats.BINARY); + const instanceInfo = deserialized.filter(m => m.data && m.type === MemoTypes.REDEEM_RESP && m.format === MemoFormats.BINARY); if (instanceRef && instanceRef.length && instanceInfo && instanceInfo.length) { const ref = instanceRef[0].data; @@ -109,7 +106,7 @@ class TestUser { // Subscribe to transactions when api is reconnected. // Because API will be automatically reconnected if it's disconnected. - this.ripplAPI.events.on(xrpl.Events.RECONNECTED, (e) => { + this.ripplAPI.events.on(Events.RECONNECTED, (e) => { this.evernodeXrplAcc.subscribe(); }); @@ -122,7 +119,7 @@ class TestUser { } async inputPump() { - const inp = await this.askForInput(''); + const inp = await this.askForInput('Enter command'); if (inp && inp.length > 0) { switch (inp) { case 'create': @@ -139,7 +136,7 @@ class TestUser { askForInput(label, defaultValue) { return new Promise(resolve => { - this.rl.question(label ? `${label}? ` : '', (input) => { + this.rl.question(label ? `${label} : ` : '', (input) => { resolve(input && input.length > 0 ? input : defaultValue); }) }) @@ -333,6 +330,7 @@ class TestUser { } async createInstance() { + const tokenCount = await this.askForInput(`${this.cfg.xrpl.hostToken} amount (default:1)`, 1); const contractId = await this.askForInput('Contract ID (default:uuidv4)', uuidv4()); const image = await this.askForInput('Image: 1=ubuntu(default) | 2=nodejs', "1"); if (image != "1" && image != "2") { @@ -355,14 +353,15 @@ class TestUser { const memoData = JSON.stringify(data); const res = await this.xrplAcc.makePayment(this.cfg.xrpl.hookAddress, - REDEEM_FEE, + +tokenCount, this.cfg.xrpl.hostToken, this.cfg.xrpl.hostAddress, - [{ type: xrpl.MemoTypes.INST_CRET, format: xrpl.MemoFormats.BINARY, data: memoData }]); + [{ type: MemoTypes.REDEEM, format: MemoFormats.BINARY, data: memoData }]); if (res) { + console.log("Transaction succeed, wait for the instance creation..."); return new Promise(resolve => { - this.promises[res] = resolve + this.promises[res.txHash] = resolve; }); } else { diff --git a/installer/sashimono-install.sh b/installer/sashimono-install.sh index 4d12708..5866d98 100755 --- a/installer/sashimono-install.sh +++ b/installer/sashimono-install.sh @@ -183,7 +183,7 @@ if [ "$quiet" != "-q" ]; then Group=root Type=simple WorkingDirectory=$mb_xrpl_dir - ExecStart=node $mb_xrpl_dir $xrpl_server_url + ExecStart=node $mb_xrpl_dir $xrpl_server_url --enable-logging Restart=on-failure RestartSec=5 [Install] diff --git a/mb-xrpl/.gitignore b/mb-xrpl/.gitignore index 4924427..428de11 100644 --- a/mb-xrpl/.gitignore +++ b/mb-xrpl/.gitignore @@ -1,2 +1,5 @@ node_modules -mb-xrpl.cfg \ No newline at end of file +dist +log +mb-xrpl.cfg +mb-xrpl.sqlite \ No newline at end of file diff --git a/mb-xrpl/lib/logger.js b/mb-xrpl/lib/logger.js new file mode 100644 index 0000000..5a15871 --- /dev/null +++ b/mb-xrpl/lib/logger.js @@ -0,0 +1,31 @@ +const fs = require('fs'); +const path = require('path'); +const util = require('util'); + +const formatText = (text, logType = 'dbg') => { + const date = new Date().toISOString(). + replace(/T/, ' '). // Replace T with a space. + replace(/\..+/, ''). // Delete the dot and everything after. + replace(/-/, ''); // Delete the dashes. + + return `${date} [${logType}] ${text}\n`; +} + +exports.init = (logPath) => { + const dirname = path.dirname(logPath); + if (!fs.existsSync(dirname)) + fs.mkdirSync(dirname, { recursive: true }); + + // Formating logs and printing. + const ws = fs.createWriteStream(logPath, { flags: 'a' }); + console.log = function () { + const text = formatText(util.format.apply(this, arguments)); + ws.write(text); + process.stdout.write(text); + }; + console.error = function () { + const text = formatText(util.format.apply(this, arguments), 'err'); + ws.write(text); + process.stderr.write(text); + }; +} \ No newline at end of file diff --git a/mb-xrpl/ripple-handler.js b/mb-xrpl/lib/ripple-handler.js similarity index 92% rename from mb-xrpl/ripple-handler.js rename to mb-xrpl/lib/ripple-handler.js index 5772994..4117d3c 100644 --- a/mb-xrpl/ripple-handler.js +++ b/mb-xrpl/lib/ripple-handler.js @@ -6,10 +6,10 @@ const CONNECTION_RETRY_INTERVAL = 1000; const maxLedgerOffset = 10; const MemoTypes = { - INST_CRET: 'evndInstCreate', - INST_CRET_REF: 'evndInstCreateRef', - INST_CRET_RESP: 'evndInstCreateResp', - HOST_REG: 'evndHostReg' + REDEEM: 'evnRedeem', + REDEEM_REF: 'evnRedeemRef', + REDEEM_RESP: 'evnRedeemResp', + HOST_REG: 'evnHostReg' } const MemoFormats = { @@ -20,6 +20,7 @@ const MemoFormats = { const Events = { RECONNECTED: 'reconnected', + LEDGER: 'ledger', PAYMENT: 'payment' } @@ -68,6 +69,9 @@ class RippleAPIWarpper { } catch (e) { console.error(e); }; }); + this.api.on('ledger', (ledger) => { + this.events.emit(Events.LEDGER, ledger); + }); } async connect() { @@ -92,6 +96,10 @@ class RippleAPIWarpper { this.connectionRetryCount = 0; throw `Max connection retry count reached for ${this.rippleServer}. Try again later.`; } + + async getLedgerVersion() { + return (await this.api.getLedgerVersion()); + } } class XrplAccount { @@ -143,7 +151,7 @@ class XrplAccount { await this.api.submit(signed.signedTransaction); const verified = await this.verifyTransaction(signed.id, ledger, maxLedger); - return verified ? signed.id : false; + return verified ? verified : false; } async createTrustline(currency, issuer, limit, memos = null) { @@ -189,7 +197,7 @@ class XrplAccount { await this.api.submit(signed.signedTransaction); console.log("Submitted trust line."); const verified = await this.verifyTransaction(signed.id, ledger, maxLedger); - verified ? resolve(signed.id) : resolve(false); + verified ? resolve(verified) : resolve(false); })); } @@ -206,8 +214,7 @@ class XrplAccount { console.log(data.outcome.result); if (data.outcome.result !== 'tesSUCCESS') console.log("Transaction verification failed. Result: " + data.outcome.result); - - resolve(data.outcome.result === 'tesSUCCESS'); + resolve(data.outcome.result === 'tesSUCCESS' ? { txHash: data.id, ledgerVersion: data.outcome.ledgerVersion } : false); }).catch(error => { // If transaction not in latest validated ledger, try again until max ledger is hit. if (error instanceof this.api.errors.PendingLedgerVersionError || error instanceof this.api.errors.NotFoundError) { diff --git a/mb-xrpl/lib/sqlite-handler.js b/mb-xrpl/lib/sqlite-handler.js new file mode 100644 index 0000000..c1f60fd --- /dev/null +++ b/mb-xrpl/lib/sqlite-handler.js @@ -0,0 +1,153 @@ +const sqlite3 = require('sqlite3').verbose(); + +const DataTypes = { + TEXT: 'TEXT', + INTEGER: 'INTEGER', + NULL: 'NULL' +} + +class SqliteDatabase { + constructor(dbFile) { + this.dbFile = dbFile; + } + + open() { + this.db = new sqlite3.Database(this.dbFile); + } + + close() { + this.db.close(); + this.db = null; + } + + async createTableIfNotExists(tableName, columnInfo) { + if (!this.db) + throw 'Database connection is not open.'; + + const columns = columnInfo.map(c => { + let info = `${c.name} ${c.type}`; + if (c.default) + info += ` DEFAULT ${c.default}`; + if (c.unique) + info += ' UNIQUE'; + if (c.primary) + info += ' PRIMARY KEY'; + if (c.notNull) + info += ' NOT NULL'; + return info; + }).join(', '); + + const query = `CREATE TABLE IF NOT EXISTS ${tableName}(${columns})`; + await this.runQuery(query); + } + + getValues(tableName, filter = null) { + if (!this.db) + throw 'Database connection is not open.'; + + let values = []; + let filterStr = '1 AND ' + if (filter) { + const columnNames = Object.keys(filter); + for (const columnName of columnNames) { + filterStr += `${columnName} = ? AND `; + values.push(filter[columnName] ? filter[columnName] : 'NULL'); + } + } + filterStr = filterStr.slice(0, -5); + + const query = `SELECT * FROM ${tableName}` + (filterStr ? ` WHERE ${filterStr};` : ';'); + return new Promise((resolve, reject) => { + let rows = []; + this.db.each(query, values, function (err, row) { + if (err) { + reject(err); + return; + } + + rows.push(row); + }, function (err, count) { + if (err) { + reject(err); + return; + } + + resolve(rows); + }); + }); + } + + async insertValue(tableName, value) { + return (await this.insertValues(tableName, [value])); + } + + async updateValue(tableName, value, filter = null) { + if (!this.db) + throw 'Database connection is not open.'; + + let columnNames = Object.keys(value); + + let valueStr = ''; + let values = []; + for (const columnName of columnNames) { + valueStr += `${columnName} = ?,`; + values.push(value[columnName] ? value[columnName] : 'NULL'); + } + valueStr = valueStr.slice(0, -1); + + let filterStr = '1 AND ' + if (filter) { + columnNames = Object.keys(filter); + for (const columnName of columnNames) { + filterStr += `${columnName} = ? AND `; + values.push(filter[columnName] ? filter[columnName] : 'NULL'); + } + } + filterStr = filterStr.slice(0, -5); + + const query = `UPDATE ${tableName} SET ${valueStr} WHERE ${filterStr};`; + return (await this.runQuery(query, values)); + } + + async insertValues(tableName, values) { + if (!this.db) + throw 'Database connection is not open.'; + + if (values.length) { + const columnNames = Object.keys(values[0]); + + let rowValueStr = ''; + let rowValues = []; + for (const val of values) { + rowValueStr += '('; + for (const columnName of columnNames) { + rowValueStr += ('?,'); + rowValues.push(val[columnName] ? val[columnName] : 'NULL'); + } + rowValueStr = rowValueStr.slice(0, -1) + '),'; + } + rowValueStr = rowValueStr.slice(0, -1); + + const query = `INSERT INTO ${tableName}(${columnNames.join(', ')}) VALUES ${rowValueStr}`; + return (await this.runQuery(query, rowValues)); + } + } + + runQuery(query, params = null) { + return new Promise((resolve, reject) => { + this.db.run(query, params ? params : [], function (err) { + if (err) { + reject(err); + return; + } + + resolve({ lastId: this.lastID, changes: this.changes }); + }); + }); + } +} + +module.exports = { + SqliteDatabase, + DataTypes +} \ No newline at end of file diff --git a/mb-xrpl/mb-xrpl.js b/mb-xrpl/mb-xrpl.js index 58d60a2..b2669a0 100644 --- a/mb-xrpl/mb-xrpl.js +++ b/mb-xrpl/mb-xrpl.js @@ -1,14 +1,24 @@ const fs = require('fs'); -const { execSync } = require("child_process"); -const xrpl = require('./ripple-handler'); -const XrplAccount = xrpl.XrplAccount; -const RippleAPIWarpper = xrpl.RippleAPIWarpper; +const { exec } = require("child_process"); +const logger = require('./lib/logger'); +const { XrplAccount, RippleAPIWarpper, Events, MemoFormats, MemoTypes } = require('./lib/ripple-handler'); +const { SqliteDatabase, DataTypes } = require('./lib/sqlite-handler'); const CONFIG_PATH = 'mb-xrpl.cfg'; +const DB_PATH = 'mb-xrpl.sqlite'; +const DB_TABLE_NAME = 'redeem_ops'; const EVR_CUR_CODE = 'EVR'; const EVR_LIMIT = 99999999; const REG_FEE = 5; const RES_FEE = 0.000001; +const LEDGERS_PER_MOMENT = 72; + +const RedeemStatus = { + REDEEMING: 'Redeeming', + REDEEMED: 'Redeemed', + FAILED: 'Failed', + EXPIRED: 'Expired' +} const SASHI_CLI_PATH_DEV = "../build/sashi"; const SASHI_CLI_PATH_PROD = "/usr/bin/sashi"; @@ -22,33 +32,63 @@ const hexToASCII = (hex) => { } class MessageBoard { - constructor(configPath, sashiCliPath, rippleServer) { + constructor(configPath, dbPath, sashiCliPath, rippleServer) { this.configPath = configPath; + this.redeemTable = DB_TABLE_NAME; + this.expiryList = []; if (!fs.existsSync(this.configPath)) throw `${this.configPath} does not exist.`; else if (!fs.existsSync(sashiCliPath)) throw `Sashi CLI does not exist in ${sashiCliPath}.`; - this.readConfig(); this.sashiCli = new SashiCLI(sashiCliPath); this.ripplAPI = new RippleAPIWarpper(rippleServer); + this.db = new SqliteDatabase(dbPath); } async init() { + this.readConfig(); + if (!this.cfg.xrpl.address || !this.cfg.xrpl.secret || !this.cfg.xrpl.token || !this.cfg.xrpl.hookAddress) throw "Required cfg fields cannot be empty."; try { await this.ripplAPI.connect(); } catch (e) { throw e; } + this.db.open(); + await this.createRedeemTable(); + + const redeems = await this.getRedeemedRecords(); + for (const redeem of redeems) + this.addToExpiryList(redeem.tx_hash, redeem.container_name, this.getExpiryLedger(redeem.created_on_ledger, redeem.h_token_amount)); + + this.db.close(); + + // Check for instance expiry. + this.ripplAPI.events.on(Events.LEDGER, async (e) => { + const expired = this.expiryList.filter(x => x.expiryLedger <= e.ledgerVersion); + if (expired && expired.length) { + this.expiryList = this.expiryList.filter(x => x.expiryLedger > e.ledgerVersion); + + this.db.open(); + for (const x of expired) { + console.log(`Moments exceeded. Destroying ${x.containerName}`); + await this.sashiCli.destroyInstance(x.containerName); + await this.updateRedeemStatus(x.txHash, RedeemStatus.EXPIRED); + console.log(`Destroyed ${x.containerName}`); + } + this.db.close(); + } + }); + this.xrplAcc = new XrplAccount(this.ripplAPI.api, this.cfg.xrpl.address, this.cfg.xrpl.secret); // Create trustline with evernode account. if (!this.cfg.xrpl.regTrustHash) { const res = await this.xrplAcc.createTrustline(EVR_CUR_CODE, this.cfg.xrpl.hookAddress, EVR_LIMIT); if (res) { - this.cfg.xrpl.regTrustHash = res; + this.cfg.xrpl.regTrustHash = res.txHash; this.persistConfig(); console.log(`Created ${EVR_CUR_CODE} trustline with evernode account.`) } @@ -62,14 +102,14 @@ class MessageBoard { // REG_FEE, // EVR_CUR_CODE, // this.cfg.xrpl.address, - // [{ type: xrpl.MemoTypes.HOST_REG, format: xrpl.MemoFormats.TEXT, data: memoData }]); + // [{ type: MemoTypes.HOST_REG, format: MemoFormats.TEXT, data: memoData }]); const res = await this.xrplAcc.makePayment(this.cfg.xrpl.hookAddress, REG_FEE, "XRP", null, - [{ type: xrpl.MemoTypes.HOST_REG, format: xrpl.MemoFormats.TEXT, data: memoData }]); + [{ type: MemoTypes.HOST_REG, format: MemoFormats.TEXT, data: memoData }]); if (res) { - this.cfg.xrpl.regFeeHash = res; + this.cfg.xrpl.regFeeHash = res.txHash; this.persistConfig(); console.log('Registration payment made for evernode account.') } @@ -77,7 +117,7 @@ class MessageBoard { this.evernodeXrplAcc = new XrplAccount(this.ripplAPI.api, this.cfg.xrpl.hookAddress); - this.evernodeXrplAcc.events.on(xrpl.Events.PAYMENT, (data, error) => { + this.evernodeXrplAcc.events.on(Events.PAYMENT, async (data, error) => { if (data) { // Check whether issued currency const isIssuedCurrency = (typeof data.Amount === "object"); @@ -87,36 +127,61 @@ class MessageBoard { const token = data.Amount.currency; const issuer = data.Amount.issuer; const amount = parseInt(data.Amount.value); - const isInstruction = (token === this.cfg.xrpl.token && issuer === this.cfg.xrpl.address); - if (isInstruction) { + const isRedeem = (token === this.cfg.xrpl.token && issuer === this.cfg.xrpl.address); + if (isRedeem) { const memos = data.Memos; + const txHash = data.hash; + const txAccount = data.Account; const deserialized = memos.map(m => { return { type: m.Memo.MemoType ? hexToASCII(m.Memo.MemoType) : null, format: m.Memo.MemoFormat ? hexToASCII(m.Memo.MemoFormat) : null, data: m.Memo.MemoData ? hexToASCII(m.Memo.MemoData) : null }; - }).filter(m => m.data && m.type === xrpl.MemoTypes.INST_CRET && m.format === xrpl.MemoFormats.BINARY); - const txHash = data.hash; - const txAccount = data.Account; + }).filter(m => m.data && m.type === MemoTypes.REDEEM && m.format === MemoFormats.BINARY); + + this.db.open(); for (let instance of deserialized) { - let res; + + let createRes; + let hasError = false; try { - res = this.sashiCli.createInstance(JSON.parse(instance.data)); + console.log(`Received redeem from ${txAccount}`) + await this.createRedeemRecord(txHash, txAccount, amount); + createRes = await this.sashiCli.createInstance(JSON.parse(instance.data)); console.log(`Instance created for ${txAccount}`) } catch (e) { - res = e; - console.error(e) + hasError = true; + console.error(e); + createRes = { + code: 'REDEEM_ERR', + message: 'Error occured while redeeming.' + } } - this.xrplAcc.makePayment(this.cfg.xrpl.hookAddress, - RES_FEE, - "XRP", - null, - [{ type: xrpl.MemoTypes.INST_CRET_REF, format: xrpl.MemoFormats.BINARY, data: txHash }, - { type: xrpl.MemoTypes.INST_CRET_RESP, format: xrpl.MemoFormats.BINARY, data: res }]) - .then(res => console.log(res)).catch(console.error); + + try { + const data = await this.xrplAcc.makePayment(this.cfg.xrpl.hookAddress, + RES_FEE, + "XRP", + null, + [{ type: MemoTypes.REDEEM_REF, format: MemoFormats.BINARY, data: txHash }, + { type: MemoTypes.REDEEM_RESP, format: MemoFormats.BINARY, data: createRes }]); + + if (!hasError) { + this.addToExpiryList(txHash, createRes.content.name, this.getExpiryLedger(data.ledgerVersion, amount)); + await this.updateRedeemedRecord(txHash, createRes.content.name, data.ledgerVersion); + } + } + catch (e) { + hasError = true; + console.error(e); + } + + if (hasError) + await this.updateRedeemStatus(txHash, RedeemStatus.FAILED); } + this.db.close(); } } } @@ -128,11 +193,62 @@ class MessageBoard { // Subscribe to transactions when api is reconnected. // Because API will be automatically reconnected if it's disconnected. - this.ripplAPI.events.on(xrpl.Events.RECONNECTED, (e) => { + this.ripplAPI.events.on(Events.RECONNECTED, (e) => { this.evernodeXrplAcc.subscribe(); }); } + addToExpiryList(txHash, containerName, expiryLedger) { + this.expiryList.push({ + txHash: txHash, + containerName: containerName, + expiryLedger: expiryLedger, + }); + } + + async createRedeemTable() { + // Create table if not exists. + await this.db.createTableIfNotExists(this.redeemTable, [ + { name: 'timestamp', type: DataTypes.INTEGER, notNull: true }, + { name: 'tx_hash', type: DataTypes.TEXT, primary: true, notNull: true }, + { name: 'user_xrp_address', type: DataTypes.TEXT, notNull: true }, + { name: 'h_token_amount', type: DataTypes.INTEGER, notNull: true }, + { name: 'container_name', type: DataTypes.TEXT }, + { name: 'created_on_ledger', type: DataTypes.INTEGER }, + { name: 'status', type: DataTypes.TEXT, notNull: true } + ]); + } + + async getRedeemedRecords() { + return (await this.db.getValues(this.redeemTable, { status: RedeemStatus.REDEEMED })); + } + + async createRedeemRecord(txHash, txUserAddress, txAmount) { + await this.db.insertValue(this.redeemTable, { + timestamp: Date.now(), + tx_hash: txHash, + user_xrp_address: txUserAddress, + h_token_amount: txAmount, + status: RedeemStatus.REDEEMING + }); + } + + async updateRedeemedRecord(txHash, containerName, ledgerVersion) { + await this.db.updateValue(this.redeemTable, { + container_name: containerName, + created_on_ledger: ledgerVersion, + status: RedeemStatus.REDEEMED + }, { tx_hash: txHash }); + } + + async updateRedeemStatus(txHash, status) { + await this.db.updateValue(this.redeemTable, { status: status }, { tx_hash: txHash }); + } + + getExpiryLedger(createdOnLedger, moments) { + return createdOnLedger + (moments * LEDGERS_PER_MOMENT); + } + readConfig() { this.cfg = JSON.parse(fs.readFileSync(this.configPath).toString()); } @@ -147,41 +263,81 @@ class SashiCLI { this.cliPath = cliPath; } - createInstance(msg) { - if (!msg.type) - msg.type = 'create'; + async createInstance(requirements) { + if (!requirements.type) + requirements.type = 'create'; - let output = execSync(`${this.cliPath} json -m '${JSON.stringify(msg)}'`, { stdio: 'pipe' }); - let message = Buffer.from(output).toString(); - message = JSON.parse(message.substring(0, message.length - 1)); // Skipping the \n from the result. - if (message.content && typeof message.content == 'string' && message.content.endsWith("error")) - throw message; + const res = await this.execSashiCli(requirements); + if (res.content && typeof res.content == 'string' && res.content.endsWith("error")) + throw res; - return message; + return res; + } + + async destroyInstance(containerName) { + const msg = { + type: 'destroy', + container_name: containerName + }; + const res = await this.execSashiCli(msg); + if (res.content && typeof res.content == 'string' && res.content.endsWith("error")) + throw res; + + return res; + } + + execSashiCli(msg) { + return new Promise((resolve, reject) => { + exec(`${this.cliPath} json -m '${JSON.stringify(msg)}'`, { stdio: 'pipe' }, (err, stdout, stderr) => { + if (err || stderr) { + reject(err || stderr); + return; + } + + let message = Buffer.from(stdout).toString(); + resolve(JSON.parse(message.substring(0, message.length - 1))); // Skipping the \n from the result. + }); + }) } checkStatus() { - const output = execSync(`${this.cliPath} status`, { stdio: 'pipe' }); - let message = Buffer.from(output).toString(); - message = message.substring(0, message.length - 1); // Skipping the \n from the result. - console.log(`Sashi CLI : ${message}`); - return message; + return new Promise((resolve, reject) => { + exec(`${this.cliPath} status`, { stdio: 'pipe' }, (err, stdout, stderr) => { + if (err || stderr) { + reject(err || stderr); + return; + } + + let message = Buffer.from(stdout).toString(); + message = message.substring(0, message.length - 1); // Skipping the \n from the result. + console.log(`Sashi CLI : ${message}`); + resolve(message); + }); + }); } } async function main() { - // Read Ripple Server Url. const args = process.argv; + + // This is used for logging purposes. + // Logs are formatted with the timestamp and a log file will be created inside log directory. + if (args.includes('--enable-logging')) + logger.init('log/mb-xrpl.log'); + if (args.length < 3) - throw "Arguments mismatch.\n Usage: node mb-xrpl rippleServer"; + throw "Arguments mismatch.\n Usage: node mb-xrpl "; let sashiCliPath = SASHI_CLI_PATH_PROD; // Use sashi CLI in the build folder for dev environment. - if (args.length == 4 && args[3] == 'dev') + if (args.includes('--dev')) sashiCliPath = SASHI_CLI_PATH_DEV; + console.log('Starting the xrpl message board' + (args[3] == '--dev' ? ' (in dev mode)' : '')); + + // Read Ripple Server Url. const rippleServer = args[2]; - const mb = new MessageBoard(CONFIG_PATH, sashiCliPath, rippleServer); + const mb = new MessageBoard(CONFIG_PATH, DB_PATH, sashiCliPath, rippleServer); await mb.init(); } diff --git a/mb-xrpl/package-lock.json b/mb-xrpl/package-lock.json index f7f6d3d..a714aba 100644 --- a/mb-xrpl/package-lock.json +++ b/mb-xrpl/package-lock.json @@ -21,6 +21,11 @@ "@types/node": "*" } }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, "agent-base": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", @@ -29,6 +34,75 @@ "debug": "4" } }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "optional": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + }, + "are-we-there-yet": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "optional": true, + "requires": { + "safer-buffer": "~2.1.0" + } + }, "assert": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/assert/-/assert-2.0.0.tgz", @@ -40,11 +114,40 @@ "util": "^0.12.0" } }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "optional": true + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "optional": true + }, "available-typed-arrays": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.4.tgz", "integrity": "sha512-SA5mXJWrId1TaQjfxUYghbqQ/hYioKmLJvPJyDuYRtXXenFNMjj4hSSt1Cf1xsuXSXrtxrVC5Ot4eU6cOtBDdA==" }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "optional": true + }, + "aws4": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", + "optional": true + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, "base-x": { "version": "3.0.8", "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.8.tgz", @@ -58,6 +161,15 @@ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "optional": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, "big-integer": { "version": "1.6.48", "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.48.tgz", @@ -68,11 +180,29 @@ "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz", "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==" }, + "block-stream": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", + "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", + "optional": true, + "requires": { + "inherits": "~2.0.0" + } + }, "bn.js": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "brorand": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", @@ -96,6 +226,17 @@ "get-intrinsic": "^1.0.2" } }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "optional": true + }, + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + }, "cipher-base": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", @@ -105,6 +246,35 @@ "safe-buffer": "^5.0.1" } }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "optional": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, "create-hash": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", @@ -117,6 +287,15 @@ "sha.js": "^2.4.0" } }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "optional": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, "debug": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", @@ -130,6 +309,11 @@ "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==" }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" + }, "define-properties": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", @@ -138,6 +322,32 @@ "object-keys": "^1.0.12" } }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "optional": true + }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" + }, + "detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "optional": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, "elliptic": { "version": "6.5.4", "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", @@ -198,16 +408,97 @@ "resolved": "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz", "integrity": "sha1-wsNYJlYkfDnqEHyx5mUrb58kUjw=" }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "optional": true + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "optional": true + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "optional": true + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "optional": true + }, "foreach": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=" }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "optional": true + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "optional": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "fs-minipass": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", + "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "requires": { + "minipass": "^2.6.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "fstream": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "optional": true, + "requires": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + } + }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, "get-intrinsic": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", @@ -218,6 +509,50 @@ "has-symbols": "^1.0.1" } }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "optional": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "graceful-fs": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", + "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", + "optional": true + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "optional": true + }, + "har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "optional": true, + "requires": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + } + }, "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -244,6 +579,11 @@ "has-symbols": "^1.0.2" } }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" + }, "hash-base": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", @@ -273,6 +613,17 @@ "minimalistic-crypto-utils": "^1.0.1" } }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "optional": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, "https-proxy-agent": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", @@ -282,16 +633,46 @@ "debug": "4" } }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, "ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" }, + "ignore-walk": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.4.tgz", + "integrity": "sha512-PY6Ii8o1jMRA1z4F2hRkH/xN59ox43DavKvD3oDpfurRlOJyAHpifIwpbdv1n4jt4ov0jSpw3kQ4GhJnpBL6WQ==", + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, "inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, + "ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + }, "internal-slot": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", @@ -341,6 +722,14 @@ "has-tostringtag": "^1.0.0" } }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "^1.0.0" + } + }, "is-generator-function": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", @@ -408,11 +797,70 @@ "has-tostringtag": "^1.0.0" } }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "optional": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "optional": true + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "optional": true + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "optional": true + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "optional": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "optional": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "optional": true + }, "jsonschema": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.2.2.tgz", "integrity": "sha512-iX5OFQ6yx9NgbHCwse51ohhKgLuLL7Z5cNOeZOPIlDUtAMrxlruHLzVZxbltdHE5mEDXN+75oFOwq6Gn0MZwsA==" }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "optional": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, "lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", @@ -428,6 +876,21 @@ "safe-buffer": "^5.1.2" } }, + "mime-db": { + "version": "1.49.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.49.0.tgz", + "integrity": "sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA==", + "optional": true + }, + "mime-types": { + "version": "2.1.32", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.32.tgz", + "integrity": "sha512-hJGaVS4G4c9TSMYh2n6SQAGrC4RnfU+daP8G7cSCmaqNjiOoUY0VHCMS42pxnQmVF1GWwFhbHWn3RIxCqTmZ9A==", + "optional": true, + "requires": { + "mime-db": "1.49.0" + } + }, "minimalistic-assert": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", @@ -438,11 +901,195 @@ "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + }, + "minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", + "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", + "requires": { + "minipass": "^2.9.0" + } + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "requires": { + "minimist": "^1.2.5" + } + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, + "needle": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/needle/-/needle-2.9.0.tgz", + "integrity": "sha512-UBLC4P8w9to3rAhWOQYXIXzTUio9yVnDzIeKxfGbF+Hngy+2bXTqqFK+6nF42EAQKfJdezXK6vzMsefUa1Y3ag==", + "requires": { + "debug": "^3.2.6", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "node-addon-api": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", + "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==" + }, + "node-gyp": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.8.0.tgz", + "integrity": "sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA==", + "optional": true, + "requires": { + "fstream": "^1.0.0", + "glob": "^7.0.3", + "graceful-fs": "^4.1.2", + "mkdirp": "^0.5.0", + "nopt": "2 || 3", + "npmlog": "0 || 1 || 2 || 3 || 4", + "osenv": "0", + "request": "^2.87.0", + "rimraf": "2", + "semver": "~5.3.0", + "tar": "^2.0.0", + "which": "1" + } + }, + "node-pre-gyp": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.11.0.tgz", + "integrity": "sha512-TwWAOZb0j7e9eGaf9esRx3ZcLaE5tQ2lvYy1pb5IAaG1a2e2Kv5Lms1Y4hpj+ciXJRofIxxlt5haeQ/2ANeE0Q==", + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + }, + "dependencies": { + "nopt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", + "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "tar": { + "version": "4.4.19", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.19.tgz", + "integrity": "sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==", + "requires": { + "chownr": "^1.1.4", + "fs-minipass": "^1.2.7", + "minipass": "^2.9.0", + "minizlib": "^1.3.3", + "mkdirp": "^0.5.5", + "safe-buffer": "^5.2.1", + "yallist": "^3.1.1" + } + } + } + }, + "nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "optional": true, + "requires": { + "abbrev": "1" + } + }, + "npm-bundled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.2.tgz", + "integrity": "sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ==", + "requires": { + "npm-normalize-package-bin": "^1.0.1" + } + }, + "npm-normalize-package-bin": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz", + "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==" + }, + "npm-packlist": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.8.tgz", + "integrity": "sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==", + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1", + "npm-normalize-package-bin": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, "object-inspect": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", @@ -473,6 +1120,78 @@ "object-keys": "^1.1.1" } }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" + }, + "osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "optional": true + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "optional": true + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "optional": true + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "optional": true + }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + } + }, "readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", @@ -483,6 +1202,42 @@ "util-deprecate": "^1.0.1" } }, + "request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "optional": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + } + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "requires": { + "glob": "^7.1.3" + } + }, "ripemd160": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", @@ -565,6 +1320,26 @@ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "semver": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=" + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, "sha.js": { "version": "2.4.11", "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", @@ -584,6 +1359,48 @@ "object-inspect": "^1.9.0" } }, + "signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" + }, + "sqlite3": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-5.0.2.tgz", + "integrity": "sha512-1SdTNo+BVU211Xj1csWa8lV6KM0CtucDwRyA0VHl91wEH1Mgh7RxUpI4rVvG7OhHrzCSGaVyW5g8vKvlrk9DJA==", + "requires": { + "node-addon-api": "^3.0.0", + "node-gyp": "3.x", + "node-pre-gyp": "^0.11.0" + } + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "optional": true, + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, "string.prototype.trimend": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", @@ -610,6 +1427,55 @@ "safe-buffer": "~5.2.0" } }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" + }, + "tar": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz", + "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==", + "optional": true, + "requires": { + "block-stream": "*", + "fstream": "^1.0.12", + "inherits": "2" + } + }, + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "optional": true, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "optional": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "optional": true + }, "unbox-primitive": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", @@ -621,6 +1487,15 @@ "which-boxed-primitive": "^1.0.2" } }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "optional": true, + "requires": { + "punycode": "^2.1.0" + } + }, "util": { "version": "0.12.4", "resolved": "https://registry.npmjs.org/util/-/util-0.12.4.tgz", @@ -639,6 +1514,32 @@ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "optional": true + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "optional": true, + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "optional": true, + "requires": { + "isexe": "^2.0.0" + } + }, "which-boxed-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", @@ -663,6 +1564,24 @@ "has-tostringtag": "^1.0.0", "is-typed-array": "^1.1.6" } + }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" } } } diff --git a/mb-xrpl/package.json b/mb-xrpl/package.json index b135aeb..ad37028 100644 --- a/mb-xrpl/package.json +++ b/mb-xrpl/package.json @@ -1,9 +1,10 @@ { "name": "mb-xrpl", "scripts": { - "build": "ncc build mb-xrpl.js -o ../build/mb-xrpl" + "build": "ncc build mb-xrpl.js -o dist/mb-xrpl" }, "dependencies": { - "ripple-lib": "^1.9.8" + "ripple-lib": "^1.9.8", + "sqlite3": "^5.0.2" } } diff --git a/test/vm-cluster/cluster.sh b/test/vm-cluster/cluster.sh index 8540b39..1467a48 100755 --- a/test/vm-cluster/cluster.sh +++ b/test/vm-cluster/cluster.sh @@ -90,7 +90,7 @@ fi shopt -s expand_aliases alias sshskp='ssh -o StrictHostKeychecking=no' if [ "$sshpass" != "" ] && [ "$sshpass" != "null" ]; then - alias sshskp='sshpass -p $sshpass ssh -o StrictHostKeychecking=no' + alias sshskp="sshpass -p $sshpass ssh -o StrictHostKeychecking=no" fi function updateconfig() {