mirror of
https://github.com/EvernodeXRPL/sashimono.git
synced 2026-04-29 15:38:00 +00:00
Merge branch 'release' into beta-v3-release
This commit is contained in:
1
.gitmodules
vendored
1
.gitmodules
vendored
@@ -1,3 +1,4 @@
|
||||
[submodule "evernode-bootstrap-contract"]
|
||||
path = evernode-bootstrap-contract
|
||||
url = https://github.com/HotPocketDev/evernode-bootstrap-contract.git
|
||||
branch = release
|
||||
|
||||
@@ -47,7 +47,7 @@ Run `make installer` ('installer.tar.gz' will be placed in build directory)
|
||||
|
||||
1. Node app which is listening to the host xrpl account.
|
||||
1. `cd mb-xrpl && npm install` (You only have to do this once)
|
||||
1. `node app.js new [address] [secret] [governerAddress] [domain or ip] [leaseAmount] [rippledServer]` will create new config files called `mb-xrpl.cfg` and `secret.cfg`
|
||||
1. `node app.js new [address] [secretPath] [governorAddress] [domain or ip] [leaseAmount] [rippledServer] [ipv6Subnet] [ipv6Interface] [network]` will create new config files called `mb-xrpl.cfg` and `secret.cfg`
|
||||
1. `node app.js betagen [governerAddress] [domain or ip] [leaseAmount]` will generate beta host account and populate the configs.
|
||||
1. `node app.js register [countryCode] [cpuMicroSec] [ramKb] [swapKb] [diskKb] [totalInstanceCount] [cpuModel] [cpuCount] [cpuSpeed] [emailAddress] [description(optional)]` will register the host on Evernode.
|
||||
1. `node app.js deregister` will deregister the host from Evernode.
|
||||
|
||||
19
dependencies/user-uninstall.sh
vendored
19
dependencies/user-uninstall.sh
vendored
@@ -7,6 +7,7 @@ peer_port=$2
|
||||
user_port=$3
|
||||
instance_name=$4
|
||||
prefix="sashi"
|
||||
max_kill_attempts=5
|
||||
|
||||
# Check whether this is a valid sashimono username.
|
||||
[ ${#user} -lt 24 ] || [ ${#user} -gt 32 ] || [[ ! "$user" =~ ^$prefix[0-9]+$ ]] && echo "ARGS,UNINST_ERR" && exit 1
|
||||
@@ -55,18 +56,16 @@ for mnt in "${mntarr[@]}"; do
|
||||
done
|
||||
|
||||
# Force kill user processes.
|
||||
procs=$(ps -U $user 2>/dev/null | wc -l)
|
||||
if [ "$procs" != "0" ]; then
|
||||
|
||||
# Wait for some time and check again.
|
||||
i=0
|
||||
while true; do
|
||||
sleep 1
|
||||
procs=$(ps -U $user 2>/dev/null | wc -l)
|
||||
if [ "$procs" != "0" ]; then
|
||||
echo "Force killing user processes."
|
||||
pkill -SIGKILL -u "$user"
|
||||
fi
|
||||
|
||||
fi
|
||||
[ "$procs" == "1" ] && echo "All user processes terminated." && break
|
||||
[[ $i -ge $max_kill_attempts ]] && echo "Max force user process kill attempts $max_kill_attempts reached. Abondaning." && break
|
||||
((i++))
|
||||
echo "Force killing user processes. Retrying $i..."
|
||||
pkill -SIGKILL -u "$user"
|
||||
done
|
||||
|
||||
echo "Removing cgroups"
|
||||
# Delete config values.
|
||||
|
||||
Submodule evernode-bootstrap-contract updated: e40c3ae705...13b6f708bf
@@ -4,6 +4,12 @@ const evernode = require("evernode-js-client");
|
||||
const process = require("process");
|
||||
const fs = require("fs");
|
||||
const ip6addr = require('ip6addr');
|
||||
const keypairs = require('ripple-keypairs');
|
||||
const http = require('http');
|
||||
const crypto = require('crypto');
|
||||
const { appenv } = require("../../mb-xrpl/lib/appenv");
|
||||
|
||||
let NETWORK = appenv.NETWORK;
|
||||
|
||||
function checkParams(args, count) {
|
||||
for (let i = 0; i < count; i++) {
|
||||
@@ -18,11 +24,16 @@ const funcs = {
|
||||
'validate-server': async (args) => {
|
||||
checkParams(args, 1);
|
||||
const rippledUrl = args[0];
|
||||
const xrplApi = new evernode.XrplApi(rippledUrl, { autoReconnect: false });
|
||||
await evernode.Defaults.useNetwork(NETWORK);
|
||||
evernode.Defaults.set({
|
||||
rippledServer: rippledUrl
|
||||
});
|
||||
const xrplApi = new evernode.XrplApi(null, { autoReconnect: false });
|
||||
await xrplApi.connect();
|
||||
await xrplApi.disconnect();
|
||||
return { success: true };
|
||||
},
|
||||
|
||||
'validate-account': async (args) => {
|
||||
checkParams(args, 3);
|
||||
const rippledUrl = args[0];
|
||||
@@ -30,15 +41,22 @@ const funcs = {
|
||||
const accountAddress = args[2];
|
||||
const validateFor = args[3] || "register";
|
||||
|
||||
const xrplApi = new evernode.XrplApi(rippledUrl, { autoReconnect: false });
|
||||
await evernode.Defaults.useNetwork(NETWORK);
|
||||
|
||||
evernode.Defaults.set({
|
||||
rippledServer: rippledUrl,
|
||||
governorAddress: governorAddress
|
||||
});
|
||||
|
||||
const xrplApi = new evernode.XrplApi(null, { autoReconnect: false });
|
||||
await xrplApi.connect();
|
||||
|
||||
const hostClient = new evernode.HostClient(accountAddress, null, {
|
||||
rippledServer: rippledUrl,
|
||||
governorAddress: governorAddress,
|
||||
evernode.Defaults.set({
|
||||
xrplApi: xrplApi
|
||||
});
|
||||
|
||||
const hostClient = new evernode.HostClient(accountAddress, null);
|
||||
|
||||
if (!await hostClient.xrplAcc.exists())
|
||||
return { success: false, result: "Account not found." };
|
||||
|
||||
@@ -71,15 +89,26 @@ const funcs = {
|
||||
await xrplApi.disconnect();
|
||||
return { success: true };
|
||||
},
|
||||
|
||||
'validate-keys': async (args) => {
|
||||
checkParams(args, 3);
|
||||
const rippledUrl = args[0];
|
||||
const accountAddress = args[1];
|
||||
const accountSecret = args[2];
|
||||
|
||||
const xrplApi = new evernode.XrplApi(rippledUrl, { autoReconnect: false });
|
||||
await evernode.Defaults.useNetwork(NETWORK);
|
||||
|
||||
evernode.Defaults.set({
|
||||
rippledServer: rippledUrl
|
||||
});
|
||||
|
||||
const xrplApi = new evernode.XrplApi(null, { autoReconnect: false });
|
||||
await xrplApi.connect();
|
||||
|
||||
evernode.Defaults.set({
|
||||
xrplApi: xrplApi
|
||||
});
|
||||
|
||||
const xrplAcc = new evernode.XrplAccount(accountAddress, accountSecret, {
|
||||
xrplApi: xrplApi
|
||||
});
|
||||
@@ -91,31 +120,33 @@ const funcs = {
|
||||
},
|
||||
|
||||
'access-evernode-cfg': async (args) => {
|
||||
checkParams(args, 4);
|
||||
checkParams(args, 3);
|
||||
const rippledUrl = args[0];
|
||||
const governorAddress = args[1];
|
||||
const accountAddress = args[2];
|
||||
const configName = args[3];
|
||||
const configName = args[2];
|
||||
|
||||
const xrplApi = new evernode.XrplApi(rippledUrl, { autoReconnect: false });
|
||||
await evernode.Defaults.useNetwork(NETWORK);
|
||||
|
||||
evernode.Defaults.set({
|
||||
rippledServer: rippledUrl,
|
||||
governorAddress: governorAddress
|
||||
});
|
||||
|
||||
const xrplApi = new evernode.XrplApi(null, { autoReconnect: false });
|
||||
await xrplApi.connect();
|
||||
|
||||
const hostClient = new evernode.HostClient(accountAddress, null, {
|
||||
rippledServer: rippledUrl,
|
||||
governorAddress: governorAddress,
|
||||
evernode.Defaults.set({
|
||||
xrplApi: xrplApi
|
||||
});
|
||||
|
||||
if (!await hostClient.xrplAcc.exists())
|
||||
return { success: false, result: "Account not found." };
|
||||
const governorClient = await evernode.HookClientFactory.create(evernode.HookTypes.governor);
|
||||
await governorClient.connect();
|
||||
const config = await governorClient.config;
|
||||
|
||||
await hostClient.connect();
|
||||
const config = hostClient.config;
|
||||
|
||||
await hostClient.disconnect();
|
||||
await governorClient.disconnect();
|
||||
await xrplApi.disconnect();
|
||||
|
||||
return { success: true, result: config[configName] };
|
||||
return { success: true, result: typeof config[configName] === 'object' ? JSON.stringify(config[configName]) : `${config[configName]}` };
|
||||
},
|
||||
|
||||
'transfer': async (args) => {
|
||||
@@ -126,15 +157,22 @@ const funcs = {
|
||||
const accountSecret = args[3];
|
||||
const transfereeAddress = args[4];
|
||||
|
||||
const xrplApi = new evernode.XrplApi(rippledUrl, { autoReconnect: false });
|
||||
await evernode.Defaults.useNetwork(NETWORK);
|
||||
|
||||
evernode.Defaults.set({
|
||||
rippledServer: rippledUrl,
|
||||
governorAddress: governorAddress
|
||||
});
|
||||
|
||||
const xrplApi = new evernode.XrplApi(null, { autoReconnect: false });
|
||||
await xrplApi.connect();
|
||||
|
||||
const hostClient = new evernode.HostClient(accountAddress, accountSecret, {
|
||||
rippledServer: rippledUrl,
|
||||
governorAddress: governorAddress,
|
||||
evernode.Defaults.set({
|
||||
xrplApi: xrplApi
|
||||
});
|
||||
|
||||
const hostClient = new evernode.HostClient(accountAddress, accountSecret);
|
||||
|
||||
if (!await hostClient.xrplAcc.exists())
|
||||
return { success: false, result: "Account not found." };
|
||||
|
||||
@@ -203,7 +241,314 @@ const funcs = {
|
||||
}
|
||||
|
||||
return { success: false };
|
||||
},
|
||||
|
||||
'check-acc-condition': async (args) => {
|
||||
checkParams(args, 3);
|
||||
const rippledUrl = args[0];
|
||||
const governorAddress = args[1];
|
||||
const accountAddress = args[2];
|
||||
|
||||
await evernode.Defaults.useNetwork(NETWORK);
|
||||
|
||||
evernode.Defaults.set({
|
||||
rippledServer: rippledUrl,
|
||||
governorAddress: governorAddress
|
||||
});
|
||||
|
||||
const xrplApi = new evernode.XrplApi(null, { autoReconnect: false });
|
||||
await xrplApi.connect();
|
||||
|
||||
evernode.Defaults.set({
|
||||
xrplApi: xrplApi
|
||||
});
|
||||
|
||||
const hostClient = new evernode.HostClient(accountAddress, null);
|
||||
const terminateConnections = async () => {
|
||||
await hostClient.disconnect();
|
||||
await xrplApi.disconnect();
|
||||
}
|
||||
|
||||
try {
|
||||
// In order to handle the account not found issue via catch block.
|
||||
await hostClient.connect();
|
||||
const trustline = await hostClient.xrplAcc.getTrustLines(evernode.EvernodeConstants.EVR, hostClient.config.evrIssuerAddress);
|
||||
if (trustline.length > 0) {
|
||||
await terminateConnections();
|
||||
return { success: true, result: 'RC-PREPARED' }
|
||||
} else {
|
||||
await terminateConnections();
|
||||
return { success: true, result: 'RC-FRESH' };
|
||||
}
|
||||
} catch (err) {
|
||||
await terminateConnections();
|
||||
|
||||
if ((err.data?.error === 'actNotFound'))
|
||||
return { success: true, result: "RC-FRESH" };
|
||||
return { success: false, result: "Error occurred in account condition check." };
|
||||
}
|
||||
},
|
||||
|
||||
'check-balance': async (args) => {
|
||||
checkParams(args, 5);
|
||||
const rippledUrl = args[0];
|
||||
const governorAddress = args[1];
|
||||
const accountAddress = args[2];
|
||||
const tokenType = args[3];
|
||||
const expectedBalance = args[4];
|
||||
|
||||
const WAIT_PERIOD = 120; // seconds
|
||||
|
||||
await evernode.Defaults.useNetwork(NETWORK);
|
||||
|
||||
evernode.Defaults.set({
|
||||
rippledServer: rippledUrl,
|
||||
governorAddress: governorAddress
|
||||
});
|
||||
|
||||
try {
|
||||
const xrplApi = new evernode.XrplApi(null, { autoReconnect: false });
|
||||
await xrplApi.connect();
|
||||
|
||||
evernode.Defaults.set({
|
||||
xrplApi: xrplApi
|
||||
});
|
||||
|
||||
const hostClient = new evernode.HostClient(accountAddress, null);
|
||||
const terminateConnections = async () => {
|
||||
await hostClient.disconnect();
|
||||
await xrplApi.disconnect();
|
||||
}
|
||||
|
||||
let attempts = 0;
|
||||
let balance = 0;
|
||||
while (attempts >= 0) {
|
||||
try {
|
||||
// In order to handle the account not found issue via catch block.
|
||||
await hostClient.connect();
|
||||
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
if (tokenType === 'NATIVE')
|
||||
balance = Number((await hostClient.xrplAcc.getInfo()).Balance) / 1000000;
|
||||
else
|
||||
balance = Number(await hostClient.getEVRBalance());
|
||||
|
||||
if (balance < expectedBalance) {
|
||||
if (++attempts <= WAIT_PERIOD)
|
||||
continue;
|
||||
|
||||
await terminateConnections();
|
||||
return { success: false, result: "Funds not received within timeout." };
|
||||
}
|
||||
|
||||
break;
|
||||
} catch (err) {
|
||||
if (err.data?.error === 'actNotFound' && ++attempts <= WAIT_PERIOD) {
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
continue;
|
||||
}
|
||||
await terminateConnections();
|
||||
return { success: false, result: (err.data?.error === 'actNotFound') ? "Funds not received within timeout." : "Error occurred in account balance check." };
|
||||
}
|
||||
}
|
||||
|
||||
await terminateConnections();
|
||||
return { success: true, result: `${balance}` };
|
||||
} catch {
|
||||
return { success: false, result: "Error occurred in websocket connection." };
|
||||
}
|
||||
},
|
||||
|
||||
'generate-account': async (args) => {
|
||||
let seed = null;
|
||||
if (args[0])
|
||||
seed = args[0];
|
||||
else
|
||||
seed = keypairs.generateSeed({ algorithm: "ecdsa-secp256k1" });
|
||||
|
||||
const keypair = keypairs.deriveKeypair(seed);
|
||||
const createdKeypair = {
|
||||
address: keypairs.deriveAddress(keypair.publicKey),
|
||||
secret: seed
|
||||
}
|
||||
return { success: true, result: typeof createdKeypair === 'object' ? JSON.stringify(createdKeypair) : `${createdKeypair}` };
|
||||
},
|
||||
|
||||
'prepare-host': async (args) => {
|
||||
checkParams(args, 4);
|
||||
const rippledUrl = args[0];
|
||||
const governorAddress = args[1];
|
||||
const accountAddress = args[2];
|
||||
const accountSecret = args[3];
|
||||
// Optional
|
||||
const domain = args[4] ? args[4] : "";
|
||||
|
||||
const WAIT_PERIOD = 120; // seconds
|
||||
|
||||
await evernode.Defaults.useNetwork(NETWORK);
|
||||
|
||||
evernode.Defaults.set({
|
||||
rippledServer: rippledUrl,
|
||||
governorAddress: governorAddress
|
||||
});
|
||||
|
||||
const xrplApi = new evernode.XrplApi(null, { autoReconnect: false });
|
||||
await xrplApi.connect();
|
||||
|
||||
evernode.Defaults.set({
|
||||
xrplApi: xrplApi
|
||||
});
|
||||
|
||||
const hostClient = new evernode.HostClient(accountAddress, accountSecret);
|
||||
await hostClient.connect();
|
||||
|
||||
const terminateConnections = async () => {
|
||||
await hostClient.disconnect();
|
||||
await xrplApi.disconnect();
|
||||
}
|
||||
|
||||
{
|
||||
let attempts = 0;
|
||||
while (attempts >= 0) {
|
||||
try {
|
||||
await hostClient.prepareAccount(domain);
|
||||
break;
|
||||
}
|
||||
catch (err) {
|
||||
if (err.data?.error === 'actNotFound' && ++attempts <= WAIT_PERIOD) {
|
||||
// Wait and retry.
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
continue;
|
||||
}
|
||||
|
||||
await terminateConnections();
|
||||
return { success: false, result: "Error occurred in account preparation." };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await terminateConnections();
|
||||
return { success: true };
|
||||
|
||||
},
|
||||
|
||||
// Starts an HTTP server on port 80 and check whether that's reachable via
|
||||
// the provided domain.
|
||||
'validate-domain': async (args) => {
|
||||
checkParams(args, 2);
|
||||
const domain = args[0];
|
||||
const port = parseInt(args[1]);
|
||||
const urlPath = "/" + crypto.randomBytes(16).toString('hex');
|
||||
const responseString = crypto.randomBytes(16).toString('hex');
|
||||
|
||||
const server = http.createServer((req, res) => {
|
||||
if (req.url === urlPath) {
|
||||
res.writeHead(200, { "Content-Type": "text/plain" });
|
||||
res.end(responseString + '\n');
|
||||
} else {
|
||||
res.writeHead(404, { 'Content-Type': 'text/plain' });
|
||||
res.end('Not Found\n');
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
await new Promise((resolve, reject) => {
|
||||
server.on('error', function (e) {
|
||||
// We assume this is an error when starting to listen.
|
||||
reject("listen_error");
|
||||
});
|
||||
|
||||
server.listen(port, () => {
|
||||
// Server started. Now send a request via public domain.
|
||||
|
||||
const reqOptions = {
|
||||
hostname: domain,
|
||||
port: port,
|
||||
path: urlPath,
|
||||
method: "GET"
|
||||
};
|
||||
|
||||
const req = http.request(reqOptions, (res) => {
|
||||
let data = "";
|
||||
|
||||
res.on("data", (chunk) => {
|
||||
data += chunk;
|
||||
});
|
||||
|
||||
// request completion event.
|
||||
res.on("end", () => {
|
||||
server.close();
|
||||
if (data.startsWith(responseString)) {
|
||||
resolve();
|
||||
} else {
|
||||
// Return string does not match our responseString. Most probably response was
|
||||
// sent by some other server. Not by us.
|
||||
reject("domain_error")
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
req.on("error", (e) => {
|
||||
server.close();
|
||||
reject("domain_error")
|
||||
});
|
||||
|
||||
req.setTimeout(3000, () => { // 3 second request timeout
|
||||
req.destroy();
|
||||
server.close();
|
||||
reject("domain_error");
|
||||
});
|
||||
|
||||
req.end();
|
||||
});
|
||||
});
|
||||
|
||||
return { success: true, result: "ok" };
|
||||
|
||||
} catch (errorCode) {
|
||||
return { success: false, result: errorCode };
|
||||
}
|
||||
},
|
||||
|
||||
'compute-xah-requirement': async (args) => {
|
||||
checkParams(args, 2);
|
||||
const rippledUrl = args[0];
|
||||
const incReserveCount = Number(args[1]);
|
||||
|
||||
await evernode.Defaults.useNetwork(NETWORK);
|
||||
|
||||
evernode.Defaults.set({
|
||||
rippledServer: rippledUrl
|
||||
});
|
||||
|
||||
try {
|
||||
const xrplApi = new evernode.XrplApi(null, { autoReconnect: false });
|
||||
await xrplApi.connect();
|
||||
|
||||
evernode.Defaults.set({
|
||||
xrplApi: xrplApi
|
||||
});
|
||||
|
||||
const serverInfo = await xrplApi.getServerInfo();
|
||||
if (serverInfo?.info?.validated_ledger) {
|
||||
const reserves = serverInfo.info.validated_ledger
|
||||
const estimate = (reserves?.reserve_base_native ?? reserves?.reserve_base_xrp) + (reserves?.reserve_inc_native ?? reserves?.reserve_inc_xrp) * incReserveCount;
|
||||
|
||||
if (estimate > 0) {
|
||||
await xrplApi.disconnect();
|
||||
return { success: true, result: `${estimate}` };
|
||||
}
|
||||
}
|
||||
|
||||
await xrplApi.disconnect();
|
||||
return { success: false, result: "Failed to retrieve the estimation." };
|
||||
|
||||
|
||||
} catch {
|
||||
return { success: false, result: "Error occurred in websocket connection." };
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function handleResponse(resp) {
|
||||
@@ -222,10 +567,20 @@ function handleResponse(resp) {
|
||||
async function app() {
|
||||
|
||||
try {
|
||||
const networkIdx = process.argv.findIndex(a => a.startsWith('network:'));
|
||||
if (networkIdx >= 0) {
|
||||
const sp = process.argv[networkIdx].split(':');
|
||||
if (sp.length > 1 && sp[1]) {
|
||||
NETWORK = sp[1];
|
||||
process.argv.splice(networkIdx, 1);
|
||||
}
|
||||
}
|
||||
|
||||
const command = process.argv[2];
|
||||
if (!command)
|
||||
throw "Command not specified.";
|
||||
|
||||
|
||||
const resp = await funcs[command](process.argv.splice(3));
|
||||
if (!resp)
|
||||
throw "No response.";
|
||||
|
||||
258
installer/jshelper/package-lock.json
generated
258
installer/jshelper/package-lock.json
generated
@@ -6,8 +6,9 @@
|
||||
"": {
|
||||
"name": "evernode-setup-helper",
|
||||
"dependencies": {
|
||||
"evernode-js-client": "0.6.20",
|
||||
"ip6addr": "0.2.5"
|
||||
"evernode-js-client": "0.6.24",
|
||||
"ip6addr": "0.2.5",
|
||||
"ripple-keypairs": "1.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@noble/hashes": {
|
||||
@@ -363,9 +364,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/evernode-js-client": {
|
||||
"version": "0.6.20",
|
||||
"resolved": "https://registry.npmjs.org/evernode-js-client/-/evernode-js-client-0.6.20.tgz",
|
||||
"integrity": "sha512-OC6VNAhwqnNvUc0NhffxwNI9bTDH+BkD/KBTC5Xuwoiq8BhRfYhmfHBnD6M9K5AvLqv+Jxdufc3l1AlzHgILWg==",
|
||||
"version": "0.6.24",
|
||||
"resolved": "https://registry.npmjs.org/evernode-js-client/-/evernode-js-client-0.6.24.tgz",
|
||||
"integrity": "sha512-sT7eoN796ueo0+yZl6KpQOzINuXrYW88YlZCm2PxzRqv5G4TqgqUGFgs+GSESkxuVRkw2LBX9WcUCGwbAt6K9g==",
|
||||
"dependencies": {
|
||||
"elliptic": "6.5.4",
|
||||
"libsodium-wrappers": "0.7.10",
|
||||
@@ -376,6 +377,27 @@
|
||||
"xrpl-binary-codec": "1.4.2"
|
||||
}
|
||||
},
|
||||
"node_modules/evernode-js-client/node_modules/bn.js": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz",
|
||||
"integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ=="
|
||||
},
|
||||
"node_modules/evernode-js-client/node_modules/ripple-keypairs": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ripple-keypairs/-/ripple-keypairs-1.1.0.tgz",
|
||||
"integrity": "sha512-Zlmbtn2YUpW4uKlLm2/tpkY5RC/EXQlkJwIIKp0AoF9D23pJ43/EuipNW2F6qURdbkUezDwB0bMV7uRXip3x2w==",
|
||||
"dependencies": {
|
||||
"bn.js": "^5.1.1",
|
||||
"brorand": "^1.0.5",
|
||||
"elliptic": "^6.5.4",
|
||||
"hash.js": "^1.0.3",
|
||||
"ripple-address-codec": "^4.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10",
|
||||
"npm": ">=7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ext": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz",
|
||||
@@ -818,19 +840,18 @@
|
||||
}
|
||||
},
|
||||
"node_modules/ripple-keypairs": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ripple-keypairs/-/ripple-keypairs-1.1.0.tgz",
|
||||
"integrity": "sha512-Zlmbtn2YUpW4uKlLm2/tpkY5RC/EXQlkJwIIKp0AoF9D23pJ43/EuipNW2F6qURdbkUezDwB0bMV7uRXip3x2w==",
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/ripple-keypairs/-/ripple-keypairs-1.3.1.tgz",
|
||||
"integrity": "sha512-dmPlraWKJciFJxHcoubDahGnoIalG5e/BtV6HNDUs7wLXmtnLMHt6w4ed9R8MTL2zNrVPiIdI/HCtMMo0Tm7JQ==",
|
||||
"dependencies": {
|
||||
"bn.js": "^5.1.1",
|
||||
"brorand": "^1.0.5",
|
||||
"elliptic": "^6.5.4",
|
||||
"hash.js": "^1.0.3",
|
||||
"ripple-address-codec": "^4.2.0"
|
||||
"ripple-address-codec": "^4.3.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10",
|
||||
"npm": ">=7.0.0"
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/ripple-keypairs/node_modules/bn.js": {
|
||||
@@ -838,6 +859,18 @@
|
||||
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz",
|
||||
"integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ=="
|
||||
},
|
||||
"node_modules/ripple-keypairs/node_modules/ripple-address-codec": {
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/ripple-address-codec/-/ripple-address-codec-4.3.1.tgz",
|
||||
"integrity": "sha512-Qa3+9wKVvpL/xYtT6+wANsn0A1QcC5CT6IMZbRJZ/1lGt7gmwIfsrCuz1X0+LCEO7zgb+3UT1I1dc0k/5dwKQQ==",
|
||||
"dependencies": {
|
||||
"base-x": "^3.0.9",
|
||||
"create-hash": "^1.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/ripple-secret-codec": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/ripple-secret-codec/-/ripple-secret-codec-1.0.3.tgz",
|
||||
@@ -1119,21 +1152,6 @@
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/xrpl-accountlib/node_modules/ripple-keypairs": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ripple-keypairs/-/ripple-keypairs-1.3.0.tgz",
|
||||
"integrity": "sha512-LzM3Up9Pwz3dYqnczzNptimN3AxtjeGbDGeiOzREzbkslKiZcJ615b/ghBN4H23SC6W1GAL95juEzzimDi4THw==",
|
||||
"dependencies": {
|
||||
"bn.js": "^5.1.1",
|
||||
"brorand": "^1.0.5",
|
||||
"elliptic": "^6.5.4",
|
||||
"hash.js": "^1.0.3",
|
||||
"ripple-address-codec": "^4.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/xrpl-binary-codec": {
|
||||
"version": "1.4.2",
|
||||
"resolved": "https://registry.npmjs.org/xrpl-binary-codec/-/xrpl-binary-codec-1.4.2.tgz",
|
||||
@@ -1190,38 +1208,6 @@
|
||||
"ripple-keypairs": "^1.1.5"
|
||||
}
|
||||
},
|
||||
"node_modules/xrpl-secret-numbers/node_modules/bn.js": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz",
|
||||
"integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ=="
|
||||
},
|
||||
"node_modules/xrpl-secret-numbers/node_modules/ripple-address-codec": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ripple-address-codec/-/ripple-address-codec-4.3.0.tgz",
|
||||
"integrity": "sha512-Tvd81i7hpDmNqHvkj6iYlj8Tv3I1Romw5gfjni9eacewJvGV2xe+p2y0FAw39z72qfciRMhQyHvpnviBcWVBNw==",
|
||||
"dependencies": {
|
||||
"base-x": "^3.0.9",
|
||||
"create-hash": "^1.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/xrpl-secret-numbers/node_modules/ripple-keypairs": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ripple-keypairs/-/ripple-keypairs-1.3.0.tgz",
|
||||
"integrity": "sha512-LzM3Up9Pwz3dYqnczzNptimN3AxtjeGbDGeiOzREzbkslKiZcJ615b/ghBN4H23SC6W1GAL95juEzzimDi4THw==",
|
||||
"dependencies": {
|
||||
"bn.js": "^5.1.1",
|
||||
"brorand": "^1.0.5",
|
||||
"elliptic": "^6.5.4",
|
||||
"hash.js": "^1.0.3",
|
||||
"ripple-address-codec": "^4.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/xrpl-sign-keypairs": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/xrpl-sign-keypairs/-/xrpl-sign-keypairs-2.2.0.tgz",
|
||||
@@ -1233,11 +1219,6 @@
|
||||
"ripple-keypairs": "^1.1.4"
|
||||
}
|
||||
},
|
||||
"node_modules/xrpl-sign-keypairs/node_modules/bn.js": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz",
|
||||
"integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ=="
|
||||
},
|
||||
"node_modules/xrpl-sign-keypairs/node_modules/ripple-address-codec": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ripple-address-codec/-/ripple-address-codec-4.3.0.tgz",
|
||||
@@ -1267,26 +1248,6 @@
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/xrpl-sign-keypairs/node_modules/ripple-keypairs": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ripple-keypairs/-/ripple-keypairs-1.3.0.tgz",
|
||||
"integrity": "sha512-LzM3Up9Pwz3dYqnczzNptimN3AxtjeGbDGeiOzREzbkslKiZcJ615b/ghBN4H23SC6W1GAL95juEzzimDi4THw==",
|
||||
"dependencies": {
|
||||
"bn.js": "^5.1.1",
|
||||
"brorand": "^1.0.5",
|
||||
"elliptic": "^6.5.4",
|
||||
"hash.js": "^1.0.3",
|
||||
"ripple-address-codec": "^4.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/xrpl/node_modules/bn.js": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz",
|
||||
"integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ=="
|
||||
},
|
||||
"node_modules/xrpl/node_modules/ripple-address-codec": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ripple-address-codec/-/ripple-address-codec-4.3.0.tgz",
|
||||
@@ -1299,21 +1260,6 @@
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/xrpl/node_modules/ripple-keypairs": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ripple-keypairs/-/ripple-keypairs-1.3.0.tgz",
|
||||
"integrity": "sha512-LzM3Up9Pwz3dYqnczzNptimN3AxtjeGbDGeiOzREzbkslKiZcJ615b/ghBN4H23SC6W1GAL95juEzzimDi4THw==",
|
||||
"dependencies": {
|
||||
"bn.js": "^5.1.1",
|
||||
"brorand": "^1.0.5",
|
||||
"elliptic": "^6.5.4",
|
||||
"hash.js": "^1.0.3",
|
||||
"ripple-address-codec": "^4.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/yaeti": {
|
||||
"version": "0.0.6",
|
||||
"resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz",
|
||||
@@ -1597,9 +1543,9 @@
|
||||
}
|
||||
},
|
||||
"evernode-js-client": {
|
||||
"version": "0.6.20",
|
||||
"resolved": "https://registry.npmjs.org/evernode-js-client/-/evernode-js-client-0.6.20.tgz",
|
||||
"integrity": "sha512-OC6VNAhwqnNvUc0NhffxwNI9bTDH+BkD/KBTC5Xuwoiq8BhRfYhmfHBnD6M9K5AvLqv+Jxdufc3l1AlzHgILWg==",
|
||||
"version": "0.6.24",
|
||||
"resolved": "https://registry.npmjs.org/evernode-js-client/-/evernode-js-client-0.6.24.tgz",
|
||||
"integrity": "sha512-sT7eoN796ueo0+yZl6KpQOzINuXrYW88YlZCm2PxzRqv5G4TqgqUGFgs+GSESkxuVRkw2LBX9WcUCGwbAt6K9g==",
|
||||
"requires": {
|
||||
"elliptic": "6.5.4",
|
||||
"libsodium-wrappers": "0.7.10",
|
||||
@@ -1608,6 +1554,25 @@
|
||||
"xrpl": "2.2.1",
|
||||
"xrpl-accountlib": "2.2.0",
|
||||
"xrpl-binary-codec": "1.4.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"bn.js": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz",
|
||||
"integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ=="
|
||||
},
|
||||
"ripple-keypairs": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ripple-keypairs/-/ripple-keypairs-1.1.0.tgz",
|
||||
"integrity": "sha512-Zlmbtn2YUpW4uKlLm2/tpkY5RC/EXQlkJwIIKp0AoF9D23pJ43/EuipNW2F6qURdbkUezDwB0bMV7uRXip3x2w==",
|
||||
"requires": {
|
||||
"bn.js": "^5.1.1",
|
||||
"brorand": "^1.0.5",
|
||||
"elliptic": "^6.5.4",
|
||||
"hash.js": "^1.0.3",
|
||||
"ripple-address-codec": "^4.2.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"ext": {
|
||||
@@ -1943,21 +1908,30 @@
|
||||
}
|
||||
},
|
||||
"ripple-keypairs": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ripple-keypairs/-/ripple-keypairs-1.1.0.tgz",
|
||||
"integrity": "sha512-Zlmbtn2YUpW4uKlLm2/tpkY5RC/EXQlkJwIIKp0AoF9D23pJ43/EuipNW2F6qURdbkUezDwB0bMV7uRXip3x2w==",
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/ripple-keypairs/-/ripple-keypairs-1.3.1.tgz",
|
||||
"integrity": "sha512-dmPlraWKJciFJxHcoubDahGnoIalG5e/BtV6HNDUs7wLXmtnLMHt6w4ed9R8MTL2zNrVPiIdI/HCtMMo0Tm7JQ==",
|
||||
"requires": {
|
||||
"bn.js": "^5.1.1",
|
||||
"brorand": "^1.0.5",
|
||||
"elliptic": "^6.5.4",
|
||||
"hash.js": "^1.0.3",
|
||||
"ripple-address-codec": "^4.2.0"
|
||||
"ripple-address-codec": "^4.3.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"bn.js": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz",
|
||||
"integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ=="
|
||||
},
|
||||
"ripple-address-codec": {
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/ripple-address-codec/-/ripple-address-codec-4.3.1.tgz",
|
||||
"integrity": "sha512-Qa3+9wKVvpL/xYtT6+wANsn0A1QcC5CT6IMZbRJZ/1lGt7gmwIfsrCuz1X0+LCEO7zgb+3UT1I1dc0k/5dwKQQ==",
|
||||
"requires": {
|
||||
"base-x": "^3.0.9",
|
||||
"create-hash": "^1.1.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -2134,11 +2108,6 @@
|
||||
"ws": "^8.2.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"bn.js": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz",
|
||||
"integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ=="
|
||||
},
|
||||
"ripple-address-codec": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ripple-address-codec/-/ripple-address-codec-4.3.0.tgz",
|
||||
@@ -2147,18 +2116,6 @@
|
||||
"base-x": "^3.0.9",
|
||||
"create-hash": "^1.1.2"
|
||||
}
|
||||
},
|
||||
"ripple-keypairs": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ripple-keypairs/-/ripple-keypairs-1.3.0.tgz",
|
||||
"integrity": "sha512-LzM3Up9Pwz3dYqnczzNptimN3AxtjeGbDGeiOzREzbkslKiZcJ615b/ghBN4H23SC6W1GAL95juEzzimDi4THw==",
|
||||
"requires": {
|
||||
"bn.js": "^5.1.1",
|
||||
"brorand": "^1.0.5",
|
||||
"elliptic": "^6.5.4",
|
||||
"hash.js": "^1.0.3",
|
||||
"ripple-address-codec": "^4.3.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -2209,18 +2166,6 @@
|
||||
"decimal.js": "^10.2.0",
|
||||
"ripple-address-codec": "^4.3.0"
|
||||
}
|
||||
},
|
||||
"ripple-keypairs": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ripple-keypairs/-/ripple-keypairs-1.3.0.tgz",
|
||||
"integrity": "sha512-LzM3Up9Pwz3dYqnczzNptimN3AxtjeGbDGeiOzREzbkslKiZcJ615b/ghBN4H23SC6W1GAL95juEzzimDi4THw==",
|
||||
"requires": {
|
||||
"bn.js": "^5.1.1",
|
||||
"brorand": "^1.0.5",
|
||||
"elliptic": "^6.5.4",
|
||||
"hash.js": "^1.0.3",
|
||||
"ripple-address-codec": "^4.3.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -2274,34 +2219,6 @@
|
||||
"@types/brorand": "^1.0.30",
|
||||
"brorand": "^1.1.0",
|
||||
"ripple-keypairs": "^1.1.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"bn.js": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz",
|
||||
"integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ=="
|
||||
},
|
||||
"ripple-address-codec": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ripple-address-codec/-/ripple-address-codec-4.3.0.tgz",
|
||||
"integrity": "sha512-Tvd81i7hpDmNqHvkj6iYlj8Tv3I1Romw5gfjni9eacewJvGV2xe+p2y0FAw39z72qfciRMhQyHvpnviBcWVBNw==",
|
||||
"requires": {
|
||||
"base-x": "^3.0.9",
|
||||
"create-hash": "^1.1.2"
|
||||
}
|
||||
},
|
||||
"ripple-keypairs": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ripple-keypairs/-/ripple-keypairs-1.3.0.tgz",
|
||||
"integrity": "sha512-LzM3Up9Pwz3dYqnczzNptimN3AxtjeGbDGeiOzREzbkslKiZcJ615b/ghBN4H23SC6W1GAL95juEzzimDi4THw==",
|
||||
"requires": {
|
||||
"bn.js": "^5.1.1",
|
||||
"brorand": "^1.0.5",
|
||||
"elliptic": "^6.5.4",
|
||||
"hash.js": "^1.0.3",
|
||||
"ripple-address-codec": "^4.3.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"xrpl-sign-keypairs": {
|
||||
@@ -2315,11 +2232,6 @@
|
||||
"ripple-keypairs": "^1.1.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"bn.js": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz",
|
||||
"integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ=="
|
||||
},
|
||||
"ripple-address-codec": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ripple-address-codec/-/ripple-address-codec-4.3.0.tgz",
|
||||
@@ -2341,18 +2253,6 @@
|
||||
"decimal.js": "^10.2.0",
|
||||
"ripple-address-codec": "^4.3.0"
|
||||
}
|
||||
},
|
||||
"ripple-keypairs": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ripple-keypairs/-/ripple-keypairs-1.3.0.tgz",
|
||||
"integrity": "sha512-LzM3Up9Pwz3dYqnczzNptimN3AxtjeGbDGeiOzREzbkslKiZcJ615b/ghBN4H23SC6W1GAL95juEzzimDi4THw==",
|
||||
"requires": {
|
||||
"bn.js": "^5.1.1",
|
||||
"brorand": "^1.0.5",
|
||||
"elliptic": "^6.5.4",
|
||||
"hash.js": "^1.0.3",
|
||||
"ripple-address-codec": "^4.3.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
"build": "ncc build index.js --minify -o dist"
|
||||
},
|
||||
"dependencies": {
|
||||
"evernode-js-client": "0.6.20",
|
||||
"ip6addr": "0.2.5"
|
||||
"evernode-js-client": "0.6.24",
|
||||
"ip6addr": "0.2.5",
|
||||
"ripple-keypairs": "1.3.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ stage "Installing dependencies"
|
||||
# To fix - Repository 'https://apprepo.vultr.com/ubuntu universal InRelease' changed its 'Codename' value from 'buster' to 'universal'
|
||||
apt-get update --allow-releaseinfo-change
|
||||
apt-get install -y uidmap fuse3 cgroup-tools quota curl openssl jq
|
||||
|
||||
# uidmap # Required for rootless docker.
|
||||
# slirp4netns # Required for high performance rootless networking.
|
||||
# fuse3 # Required for hpfs.
|
||||
@@ -40,8 +41,13 @@ apt-get install -y uidmap fuse3 cgroup-tools quota curl openssl jq
|
||||
# Install nodejs if not exists.
|
||||
if ! command -v node &>/dev/null; then
|
||||
stage "Installing nodejs"
|
||||
apt-get -y install ca-certificates # In case nodejs package certitficates are renewed.
|
||||
curl -sL https://deb.nodesource.com/setup_16.x | bash -
|
||||
apt-get install -y ca-certificates curl gnupg
|
||||
mkdir -p /etc/apt/keyrings
|
||||
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg
|
||||
|
||||
NODE_MAJOR=16
|
||||
echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list
|
||||
apt-get update
|
||||
apt-get -y install nodejs
|
||||
else
|
||||
version=$(node -v | cut -d '.' -f1)
|
||||
|
||||
@@ -16,7 +16,7 @@ diskKB=${9}
|
||||
lease_amount=${10}
|
||||
rippled_server=${11}
|
||||
xrpl_account_address=${12}
|
||||
xrpl_account_secret=${13}
|
||||
xrpl_account_secret_path=${13}
|
||||
email_address=${14}
|
||||
tls_key_file=${15}
|
||||
tls_cert_file=${16}
|
||||
@@ -27,6 +27,7 @@ ipv6_net_interface=${20}
|
||||
|
||||
script_dir=$(dirname "$(realpath "$0")")
|
||||
desired_slirp4netns_version="1.2.1"
|
||||
setup_helper_dir="/tmp/evernode-setup-helpers"
|
||||
|
||||
function stage() {
|
||||
echo "STAGE $1" # This is picked up by the setup console output filter.
|
||||
@@ -55,48 +56,6 @@ function set_cpu_info() {
|
||||
[ -z $cpu_mhz ] && cpu_mhz=$(lscpu | grep -i "^CPU MHz:" | sed 's/CPU MHz://g' | sed 's/\.[0-9]*//g' | xargs)
|
||||
}
|
||||
|
||||
function enable_evernode_auto_updater() {
|
||||
# Create the service.
|
||||
echo "[Unit]
|
||||
Description=Service for the Evernode auto-update.
|
||||
After=network.target
|
||||
[Service]
|
||||
User=root
|
||||
Group=root
|
||||
Type=oneshot
|
||||
ExecStart=/usr/bin/evernode update -q
|
||||
[Install]
|
||||
WantedBy=multi-user.target" >/etc/systemd/system/$EVERNODE_AUTO_UPDATE_SERVICE.service
|
||||
|
||||
# Create a timer for the service (every two hours).
|
||||
echo "[Unit]
|
||||
Description=Timer for the Evernode auto-update.
|
||||
# Allow manual starts
|
||||
RefuseManualStart=no
|
||||
# Allow manual stops
|
||||
RefuseManualStop=no
|
||||
[Timer]
|
||||
Unit=$EVERNODE_AUTO_UPDATE_SERVICE.service
|
||||
OnCalendar=0/12:00:00
|
||||
# Execute job if it missed a run due to machine being off
|
||||
Persistent=true
|
||||
# To prevent rush time, adding 2 hours delay
|
||||
RandomizedDelaySec=7200
|
||||
[Install]
|
||||
WantedBy=timers.target" >/etc/systemd/system/$EVERNODE_AUTO_UPDATE_SERVICE.timer
|
||||
|
||||
# Reload the systemd daemon.
|
||||
systemctl daemon-reload
|
||||
|
||||
echo "Enabling Evernode auto update service..."
|
||||
systemctl enable $EVERNODE_AUTO_UPDATE_SERVICE.service
|
||||
|
||||
echo "Enabling Evernode auto update timer..."
|
||||
systemctl enable $EVERNODE_AUTO_UPDATE_SERVICE.timer
|
||||
echo "Starting Evernode auto update timer..."
|
||||
systemctl start $EVERNODE_AUTO_UPDATE_SERVICE.timer
|
||||
}
|
||||
|
||||
function setup_certbot() {
|
||||
stage "Setting up letsencrypt certbot"
|
||||
|
||||
@@ -230,13 +189,16 @@ rm -r "$tmp"
|
||||
openssl req -newkey rsa:2048 -new -nodes -x509 -days 365 -keyout $SASHIMONO_DATA/contract_template/cfg/tlskey.pem \
|
||||
-out $SASHIMONO_DATA/contract_template/cfg/tlscert.pem -subj "/C=HP/CN=$(jq -r '.hp.host_address' $SASHIMONO_DATA/sa.cfg)"
|
||||
|
||||
# Setup tls certs used for contract instance websockets.
|
||||
[ "$UPGRADE" == "0" ] && setup_tls_certs
|
||||
|
||||
# Install Sashimono agent binaries into sashimono bin dir.
|
||||
cp "$script_dir"/{sagent,hpfs,user-cgcreate.sh,user-install.sh,user-uninstall.sh,docker-registry-uninstall.sh} $SASHIMONO_BIN
|
||||
chmod -R +x $SASHIMONO_BIN
|
||||
|
||||
# Setup tls certs used for contract instance websockets.
|
||||
[ "$UPGRADE" == "0" ] && setup_tls_certs
|
||||
|
||||
# Copy the temporary setup-helper directory content to SASHIMONO_BIN directory.
|
||||
cp -Rdp $setup_helper_dir $SASHIMONO_BIN/evernode-setup-helpers
|
||||
|
||||
# Copy Blake3 and update linker library cache.
|
||||
[ ! -f /usr/local/lib/libblake3.so ] && cp "$script_dir"/libblake3.so /usr/local/lib/ && ldconfig
|
||||
|
||||
@@ -275,9 +237,13 @@ if [ "$NO_MB" == "" ]; then
|
||||
|
||||
cp -r "$script_dir"/mb-xrpl $SASHIMONO_BIN
|
||||
|
||||
# Creating message board user (if not exists).
|
||||
# Create MB_XRPL_USER if does not exists.
|
||||
if ! grep -q "^$MB_XRPL_USER:" /etc/passwd; then
|
||||
useradd --shell /usr/sbin/nologin -m $MB_XRPL_USER
|
||||
fi
|
||||
|
||||
# Assign message board user priviledges.
|
||||
if ! id -nG "$MB_XRPL_USER" | grep -qw "$SASHIADMIN_GROUP"; then
|
||||
usermod --lock $MB_XRPL_USER
|
||||
usermod -a -G $SASHIADMIN_GROUP $MB_XRPL_USER
|
||||
loginctl enable-linger $MB_XRPL_USER # Enable lingering to support service installation.
|
||||
@@ -289,18 +255,14 @@ if [ "$NO_MB" == "" ]; then
|
||||
# Change ownership to message board user.
|
||||
chown -R "$MB_XRPL_USER":"$MB_XRPL_USER" $MB_XRPL_DATA
|
||||
|
||||
# Betage and register if not upgrade mode.
|
||||
# Register if not upgrade mode.
|
||||
if [ "$UPGRADE" == "0" ]; then
|
||||
# Setup and register the account.
|
||||
if ! sudo -u $MB_XRPL_USER MB_DATA_DIR=$MB_XRPL_DATA node $MB_XRPL_BIN reginfo basic >/dev/null 2>&1; then
|
||||
stage "Configuring host xrpl account"
|
||||
echo "Using registry: $EVERNODE_REGISTRY_ADDRESS"
|
||||
|
||||
# Commented for now, because 'betagen' will no longer be used.
|
||||
# ! sudo -u $MB_XRPL_USER MB_DATA_DIR=$MB_XRPL_DATA node $MB_XRPL_BIN betagen $EVERNODE_GOVERNOR_ADDRESS $inetaddr $lease_amount $rippled_server $xrpl_account_secret && echo "XRPLACC_FAILURE" && rollback
|
||||
# doreg=1
|
||||
|
||||
! sudo -u $MB_XRPL_USER MB_DATA_DIR=$MB_XRPL_DATA node $MB_XRPL_BIN new $xrpl_account_address $xrpl_account_secret $EVERNODE_GOVERNOR_ADDRESS $inetaddr $lease_amount $rippled_server $ipv6_subnet $ipv6_net_interface && echo "XRPLACC_FAILURE" && rollback
|
||||
! sudo -u $MB_XRPL_USER MB_DATA_DIR=$MB_XRPL_DATA node $MB_XRPL_BIN new $xrpl_account_address $xrpl_account_secret_path $EVERNODE_GOVERNOR_ADDRESS $inetaddr $lease_amount $rippled_server $ipv6_subnet $ipv6_net_interface $NETWORK && echo "XRPLACC_FAILURE" && rollback
|
||||
doreg=1
|
||||
fi
|
||||
|
||||
@@ -364,7 +326,7 @@ else
|
||||
fi
|
||||
|
||||
if [[ "$NO_MB" == "" && -f $MB_XRPL_DATA/mb-xrpl.cfg ]]; then
|
||||
! sudo -u "$MB_XRPL_USER" MB_DATA_DIR="$MB_XRPL_DATA" node "$MB_XRPL_BIN" upgrade $EVERNODE_GOVERNOR_ADDRESS && rollback
|
||||
! sudo -u "$MB_XRPL_USER" MB_DATA_DIR="$MB_XRPL_DATA" node "$MB_XRPL_BIN" upgrade && rollback
|
||||
fi
|
||||
|
||||
# Install Sashimono Agent systemd service.
|
||||
@@ -448,11 +410,6 @@ if [ ! -f /run/reboot-required.pkgs ] || [ ! -n "$(grep sashimono /run/reboot-re
|
||||
fi
|
||||
fi
|
||||
|
||||
stage "Configuring auto updater service"
|
||||
|
||||
# Enable the Evernode Auto Updater Service.
|
||||
enable_evernode_auto_updater
|
||||
|
||||
echo "Sashimono installed successfully."
|
||||
|
||||
exit 0
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
# Sashimono agent uninstall script.
|
||||
# This must be executed with root privileges.
|
||||
|
||||
export TRANSFER=${TRANSFER:-0}
|
||||
|
||||
[ "$UPGRADE" == "0" ] && echo "---Sashimono uninstaller---" || echo "---Sashimono uninstaller (for upgrade)---"
|
||||
|
||||
force=$1
|
||||
@@ -30,24 +32,6 @@ function cgrulesengd_servicename() {
|
||||
fi
|
||||
}
|
||||
|
||||
function remove_evernode_auto_updater() {
|
||||
|
||||
echo "Removing Evernode auto update timer..."
|
||||
systemctl stop $EVERNODE_AUTO_UPDATE_SERVICE.timer
|
||||
systemctl disable $EVERNODE_AUTO_UPDATE_SERVICE.timer
|
||||
service_path="/etc/systemd/system/$EVERNODE_AUTO_UPDATE_SERVICE.timer"
|
||||
rm $service_path
|
||||
|
||||
echo "Removing Evernode auto update service..."
|
||||
systemctl stop $EVERNODE_AUTO_UPDATE_SERVICE.service
|
||||
systemctl disable $EVERNODE_AUTO_UPDATE_SERVICE.service
|
||||
service_path="/etc/systemd/system/$EVERNODE_AUTO_UPDATE_SERVICE.service"
|
||||
rm $service_path
|
||||
|
||||
# Reload the systemd daemon.
|
||||
systemctl daemon-reload
|
||||
}
|
||||
|
||||
function cleanup_certbot_ssl() {
|
||||
# revoke/delete certs if certbot is used.
|
||||
if command -v certbot &>/dev/null && [ -f "$SASHIMONO_DATA/sa.cfg" ]; then
|
||||
@@ -195,7 +179,6 @@ if grep -q "^$MB_XRPL_USER:" /etc/passwd; then
|
||||
pkill -u $MB_XRPL_USER # Kill any running processes.
|
||||
sleep 0.5
|
||||
userdel -f "$MB_XRPL_USER"
|
||||
rm -r /home/"${MB_XRPL_USER:?}"
|
||||
|
||||
fi
|
||||
|
||||
@@ -215,7 +198,4 @@ groupdel $SASHIADMIN_GROUP
|
||||
|
||||
[ "$UPGRADE" == "0" ] && echo "Sashimono uninstalled successfully." || echo "Sashimono uninstalled successfully. Your data has been preserved."
|
||||
|
||||
# Remove the Evernode Auto Updater Service.
|
||||
[ "$UPGRADE" == "0" ] && remove_evernode_auto_updater
|
||||
|
||||
exit 0
|
||||
|
||||
1447
installer/setup-old.sh
Normal file
1447
installer/setup-old.sh
Normal file
File diff suppressed because it is too large
Load Diff
1021
installer/setup.sh
1021
installer/setup.sh
File diff suppressed because it is too large
Load Diff
@@ -15,25 +15,20 @@ async function main() {
|
||||
if (process.argv.length >= 3) {
|
||||
if (process.argv.length >= 9 && process.argv[2] === 'new') {
|
||||
const accountAddress = process.argv[3];
|
||||
const accountSecret = process.argv[4];
|
||||
const accountSecretPath = process.argv[4];
|
||||
const governorAddress = process.argv[5];
|
||||
const domain = process.argv[6];
|
||||
const leaseAmount = process.argv[7];
|
||||
const rippledServer = process.argv[8];
|
||||
const ipv6Subnet = (process.argv[9] === '-') ? null : process.argv[9];
|
||||
const ipv6NetInterface = (process.argv[10] === '-') ? null : process.argv[10];
|
||||
const network = process.argv.length > 11 ? process.argv[11] : appenv.NETWORK;
|
||||
const setup = new Setup();
|
||||
const acc = await setup.setupHostAccount(accountAddress, accountSecret, rippledServer, governorAddress, domain);
|
||||
setup.newConfig(acc.address, acc.secret, governorAddress, parseFloat(leaseAmount), rippledServer, ipv6Subnet, ipv6NetInterface);
|
||||
}
|
||||
else if (process.argv.length === 7 && process.argv[2] === 'betagen') {
|
||||
const governorAddress = process.argv[3];
|
||||
const domain = process.argv[4];
|
||||
const leaseAmount = process.argv[5];
|
||||
const rippledServer = process.argv[6];
|
||||
const setup = new Setup();
|
||||
const acc = await setup.generateBetaHostAccount(rippledServer, governorAddress, domain);
|
||||
setup.newConfig(acc.address, acc.secret, governorAddress, parseFloat(leaseAmount), rippledServer);
|
||||
setup.newConfig(accountAddress, accountSecretPath, governorAddress, parseFloat(leaseAmount), rippledServer, ipv6Subnet, ipv6NetInterface, network);
|
||||
|
||||
if (appenv.IS_DEV_MODE) {
|
||||
await setup.prepareHostAccount(domain);
|
||||
}
|
||||
}
|
||||
else if (process.argv.length >= 13 && process.argv[2] === 'register') {
|
||||
await new Setup().register(process.argv[3], parseInt(process.argv[4]), parseInt(process.argv[5]),
|
||||
@@ -51,8 +46,8 @@ async function main() {
|
||||
else if (process.argv.length === 4 && process.argv[2] === 'reginfo' && process.argv[3] === 'basic') {
|
||||
await new Setup().regInfo(true);
|
||||
}
|
||||
else if (process.argv.length === 4 && process.argv[2] === 'upgrade') {
|
||||
await new Setup().upgrade(process.argv[3]);
|
||||
else if (process.argv.length >= 3 && process.argv[2] === 'upgrade') {
|
||||
await new Setup().upgrade();
|
||||
}
|
||||
else if ((process.argv.length === 8) && process.argv[2] === 'reconfig') {
|
||||
if (process.argv[5] == '-') process.argv[5] = null;
|
||||
@@ -73,13 +68,15 @@ async function main() {
|
||||
else if (process.argv.length >= 4 && process.argv[2] === 'governance') {
|
||||
await GovernanceManager.handleCommand(process.argv[3], ...process.argv.slice(4));
|
||||
}
|
||||
else if (process.argv.length >= 3 && process.argv[2] === 'regkey') {
|
||||
await new Setup().setRegularKey(process.argv[3]);
|
||||
}
|
||||
else if (process.argv[2] === 'help') {
|
||||
console.log(`Usage:
|
||||
node index.js - Run message board.
|
||||
node index.js version - Print version.
|
||||
node index.js new [address] [secret] [governorAddress] [leaseAmount] [rippledServer] [ipv6Subnet] [ipv6Interface] - Create new config files.
|
||||
node index.js betagen [governorAddress] [domain or ip] [leaseAmount] [rippledServer] - Generate beta host account and populate the configs.
|
||||
node index.js register [countryCode] [cpuMicroSec] [ramKb] [swapKb] [diskKb] [totalInstanceCount] [description] - Register the host on Evernode.
|
||||
node index.js new [address] [secretPath] [governorAddress] [domain or ip] [leaseAmount] [rippledServer] [ipv6Subnet] [ipv6Interface] [network] - Create new config files.
|
||||
node index.js register [countryCode] [cpuMicroSec] [ramKb] [swapKb] [diskKb] [totalInstanceCount] [description] [network] - Register the host on Evernode.
|
||||
node index.js transfer [transfereeAddress] - Initiate a transfer.
|
||||
node index.js deregister - Deregister the host from Evernode.
|
||||
node index.js reginfo - Display Evernode registration info.
|
||||
@@ -87,6 +84,7 @@ async function main() {
|
||||
node index.js reconfig [leaseAmount] [totalInstanceCount] [rippledServer] - Update message board configuration.
|
||||
node index.js delete [containerName] - Delete an instance and recreate the lease offer
|
||||
node index.js governance [command] [args] - Governance handling.
|
||||
node index.js regkey [regularKey] - Regular key management.
|
||||
node index.js help - Print help.`);
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
const process = require('process');
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
|
||||
let appenv = {
|
||||
IS_DEV_MODE: process.env.MB_DEV === "1",
|
||||
FILE_LOG_ENABLED: process.env.MB_FILE_LOG === "1",
|
||||
DATA_DIR: process.env.MB_DATA_DIR || __dirname,
|
||||
FAUCET_URL: process.env.MB_FAUCET_URL || "https://hooks-testnet-v3.xrpl-labs.com/newcreds",
|
||||
DEFAULT_RIPPLED_SERVER: 'wss://hooks-testnet-v3.xrpl-labs.com',
|
||||
DEFAULT_FULL_HISTORY_NODE: 'wss://hooks-testnet-v3.xrpl-labs.com' // If we migrate to Main NET, this should be configured with the relevant full history Node WebSocket.
|
||||
DATA_DIR: process.env.MB_DATA_DIR || __dirname
|
||||
}
|
||||
|
||||
appenv = {
|
||||
...appenv,
|
||||
CONFIG_PATH: appenv.DATA_DIR + '/mb-xrpl.cfg',
|
||||
SECRET_CONFIG_PATH: appenv.DATA_DIR + '/secret.cfg',
|
||||
GOVERNANCE_CONFIG_PATH: appenv.DATA_DIR + '/governance.cfg',
|
||||
LOG_PATH: appenv.DATA_DIR + '/log/mb-xrpl.log',
|
||||
DB_PATH: appenv.DATA_DIR + '/mb-xrpl.sqlite',
|
||||
@@ -28,9 +25,17 @@ appenv = {
|
||||
ORPHAN_PRUNE_SCHEDULER_INTERVAL_HOURS: 4,
|
||||
SASHIMONO_SCHEDULER_INTERVAL_SECONDS: 2,
|
||||
SASHI_CLI_PATH: appenv.IS_DEV_MODE ? "../build/sashi" : "/usr/bin/sashi",
|
||||
MB_VERSION: '0.7.2',
|
||||
TOS_HASH: '757A0237B44D8B2BBB04AE2BAD5813858E0AECD2F0B217075E27E0630BA74314' // This is the sha256 hash of TOS text.
|
||||
MB_VERSION: '0.8.0',
|
||||
TOS_HASH: '0801677EBCB2F76EF97D531549D8B27DB2C7A4A8EE7F60032AE40184247F0810', // This is the sha256 hash of EVERNODE-HOSTING-PRINCIPLES.pdf.
|
||||
NETWORK: 'mainnet'
|
||||
}
|
||||
|
||||
const getSecretPath = () => {
|
||||
return fs.existsSync(appenv.CONFIG_PATH) ? JSON.parse(fs.readFileSync(appenv.CONFIG_PATH).toString()).xrpl.secretPath : "";
|
||||
}
|
||||
|
||||
appenv = { ...appenv, SECRET_CONFIG_PATH: getSecretPath() }
|
||||
|
||||
Object.freeze(appenv);
|
||||
|
||||
module.exports = {
|
||||
|
||||
@@ -28,15 +28,10 @@ class ConfigHelper {
|
||||
return config;
|
||||
}
|
||||
|
||||
static writeConfig(config, configPath, secretConfigPath) {
|
||||
static writeConfig(config, configPath) {
|
||||
let publicCfg = JSON.parse(JSON.stringify(config)); // Make a copy. So, referenced object won't get changed.
|
||||
const secretCfg = {
|
||||
xrpl: {
|
||||
secret: publicCfg.xrpl.secret
|
||||
}
|
||||
}
|
||||
delete publicCfg.xrpl.secret;
|
||||
fs.writeFileSync(secretConfigPath, JSON.stringify(secretCfg, null, 2), { mode: 0o600 }); // Set file permission so only current user can read/write.
|
||||
if ('secret' in publicCfg.xrpl)
|
||||
delete publicCfg.xrpl.secret;
|
||||
fs.writeFileSync(configPath, JSON.stringify(publicCfg, null, 2), { mode: 0o644 }); // Set file permission so only current user can read/write and others can read.
|
||||
}
|
||||
|
||||
|
||||
@@ -4,12 +4,18 @@ const fs = require('fs');
|
||||
const { appenv } = require('./appenv');
|
||||
const { ConfigHelper } = require('./config-helper');
|
||||
|
||||
function setEvernodeDefaults(governorAddress, rippledServer, xrplApi) {
|
||||
evernode.Defaults.set({
|
||||
governorAddress: governorAddress,
|
||||
rippledServer: rippledServer,
|
||||
xrplApi: xrplApi
|
||||
});
|
||||
async function setEvernodeDefaults(network, governorAddress, rippledServer) {
|
||||
await evernode.Defaults.useNetwork(network || appenv.NETWORK);
|
||||
|
||||
if (governorAddress)
|
||||
evernode.Defaults.set({
|
||||
governorAddress: governorAddress
|
||||
});
|
||||
|
||||
if (rippledServer)
|
||||
evernode.Defaults.set({
|
||||
rippledServer: rippledServer
|
||||
});
|
||||
}
|
||||
|
||||
class GovernanceManager {
|
||||
@@ -181,7 +187,7 @@ class GovernanceManager {
|
||||
// Secret is needed for propose, withdraw, and report in order to send the transaction
|
||||
const sashiMBConfig = ConfigHelper.readConfig(appenv.CONFIG_PATH,
|
||||
(command == 'propose' || command === 'withdraw' || command === 'report') ? appenv.SECRET_CONFIG_PATH : null);
|
||||
setEvernodeDefaults(sashiMBConfig.xrpl.governorAddress, sashiMBConfig.xrpl.rippledServer);
|
||||
await setEvernodeDefaults(sashiMBConfig.xrpl.network, sashiMBConfig.xrpl.governorAddress, sashiMBConfig.xrpl.rippledServer);
|
||||
hostClient = new evernode.HostClient(sashiMBConfig.xrpl.address, sashiMBConfig.xrpl.secret);
|
||||
}
|
||||
const mgr = new GovernanceManager(appenv.GOVERNANCE_CONFIG_PATH);
|
||||
|
||||
@@ -52,9 +52,20 @@ class MessageBoard {
|
||||
if (!this.cfg.version || !this.cfg.xrpl.address || !this.cfg.xrpl.secret || !this.cfg.xrpl.governorAddress)
|
||||
throw "Required cfg fields cannot be empty.";
|
||||
|
||||
this.xrplApi = new evernode.XrplApi(this.cfg.xrpl.rippledServer);
|
||||
await evernode.Defaults.useNetwork(this.cfg.xrpl.network || appenv.NETWORK);
|
||||
|
||||
if (this.cfg.xrpl.governorAddress)
|
||||
evernode.Defaults.set({
|
||||
governorAddress: this.cfg.xrpl.governorAddress
|
||||
});
|
||||
|
||||
if (this.cfg.xrpl.rippledServer)
|
||||
evernode.Defaults.set({
|
||||
rippledServer: this.cfg.xrpl.rippledServer
|
||||
});
|
||||
|
||||
this.xrplApi = new evernode.XrplApi();
|
||||
evernode.Defaults.set({
|
||||
governorAddress: this.cfg.xrpl.governorAddress,
|
||||
xrplApi: this.xrplApi
|
||||
})
|
||||
await this.xrplApi.connect();
|
||||
@@ -448,9 +459,6 @@ class MessageBoard {
|
||||
}
|
||||
|
||||
async #startHeartBeatScheduler() {
|
||||
// Sending a heartbeat at startup
|
||||
await this.#sendHeartbeat();
|
||||
|
||||
const momentSize = this.hostClient.config.momentSize;
|
||||
const halfMomentSize = momentSize / 2; // Getting half of moment size
|
||||
const timeout = momentSize * 1000; // Converting seconds to milliseconds.
|
||||
@@ -462,10 +470,24 @@ class MessageBoard {
|
||||
await this.#sendHeartbeat();
|
||||
};
|
||||
|
||||
const currentTimestamp = evernode.UtilHelpers.getCurrentUnixTime();
|
||||
const currentMomentStartIdx = await this.hostClient.getMomentStartIndex();
|
||||
const currentMoment = await this.hostClient.getMoment();
|
||||
const currentMomentDuration = currentTimestamp - currentMomentStartIdx;
|
||||
const hostInfo = await this.hostClient.getRegistration();
|
||||
|
||||
// If the start index is in the begining of the moment, delay the heartbeat scheduler 1 minute to make sure the hook timestamp is not in previous moment when accepting the heartbeat.
|
||||
const startTimeout = (evernode.UtilHelpers.getCurrentUnixTime() - currentMomentStartIdx) < halfMomentSize ? ((momentSize + 60) * 1000) : ((momentSize) * 1000);
|
||||
// Schedule the next heartbeat based on last heartbeat occurrence.
|
||||
// NOTE : Initially checks whether host has sent a heartbeat in the current moment or not.
|
||||
// If schedule the next heartbeat based on its last heartbeat.
|
||||
// If it is not further checks whether it is about to send the heartbeat at the second half of a moment or not.
|
||||
// If the current timestamp lies in the second half of the moment, schedule the next heartbeat withing the next moment (in the its first half).
|
||||
// If it is not schedule it right now.
|
||||
const schedule = (this.lastHeartbeatMoment === currentMoment)
|
||||
? momentSize - (currentTimestamp - hostInfo.lastHeartbeatIndex)
|
||||
: (currentMomentDuration > halfMomentSize && currentMomentDuration < momentSize) ? halfMomentSize : 0;
|
||||
|
||||
// If the start index is in the beginning of the moment, delay the heartbeat scheduler 1 minute to make sure the hook timestamp is not in previous moment when accepting the heartbeat.
|
||||
const startTimeout = (currentMomentDuration) < halfMomentSize ? ((schedule + 60) * 1000) : ((schedule) * 1000);
|
||||
|
||||
setTimeout(async () => {
|
||||
await scheduler();
|
||||
@@ -602,7 +624,7 @@ class MessageBoard {
|
||||
}
|
||||
|
||||
async #catchupMissedLeases() {
|
||||
const fullHistoryXrplApi = new evernode.XrplApi(appenv.DEFAULT_FULL_HISTORY_NODE);
|
||||
const fullHistoryXrplApi = new evernode.XrplApi();
|
||||
await fullHistoryXrplApi.connect();
|
||||
|
||||
this.db.open();
|
||||
@@ -1065,7 +1087,7 @@ class MessageBoard {
|
||||
}
|
||||
|
||||
persistConfig() {
|
||||
ConfigHelper.writeConfig(this.cfg, this.configPath, this.secretConfigPath);
|
||||
ConfigHelper.writeConfig(this.cfg, this.configPath);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -49,7 +49,13 @@ class SashiCLI {
|
||||
execSashiCli(msg) {
|
||||
this.#waiting = true;
|
||||
return new Promise((resolve, reject) => {
|
||||
exec(`${this.cliPath} json -m '${JSON.stringify(msg)}'`, { stdio: 'pipe' }, (err, stdout, stderr) => {
|
||||
let command = `${this.cliPath} json -m '${JSON.stringify(msg)}'`;
|
||||
|
||||
if (msg.type === "create") {
|
||||
command = `DEV_MODE=1 ${command}`;
|
||||
}
|
||||
|
||||
exec(command, { stdio: 'pipe' }, (err, stdout, stderr) => {
|
||||
this.#waiting = false;
|
||||
|
||||
if (err || stderr) {
|
||||
|
||||
@@ -8,12 +8,18 @@ const { ConfigHelper } = require('./config-helper');
|
||||
const { SashiCLI } = require('./sashi-cli');
|
||||
const { UtilHelper } = require('./util-helper');
|
||||
|
||||
function setEvernodeDefaults(governorAddress, rippledServer, xrplApi = null) {
|
||||
evernode.Defaults.set({
|
||||
governorAddress: governorAddress,
|
||||
rippledServer: rippledServer || appenv.DEFAULT_RIPPLED_SERVER,
|
||||
xrplApi: xrplApi
|
||||
});
|
||||
async function setEvernodeDefaults(network, governorAddress, rippledServer) {
|
||||
await evernode.Defaults.useNetwork(network || appenv.NETWORK);
|
||||
|
||||
if (governorAddress)
|
||||
evernode.Defaults.set({
|
||||
governorAddress: governorAddress
|
||||
});
|
||||
|
||||
if (rippledServer)
|
||||
evernode.Defaults.set({
|
||||
rippledServer: rippledServer
|
||||
});
|
||||
}
|
||||
|
||||
class Setup {
|
||||
@@ -37,32 +43,21 @@ class Setup {
|
||||
})
|
||||
}
|
||||
|
||||
async #generateFaucetAccount() {
|
||||
console.log("Generating faucet account...");
|
||||
const resp = await this.#httpPost(appenv.FAUCET_URL);
|
||||
const json = JSON.parse(resp);
|
||||
|
||||
// If Hooks TEST NET is used.
|
||||
return {
|
||||
address: json.address,
|
||||
secret: json.secret
|
||||
};
|
||||
}
|
||||
|
||||
#getConfig(readSecret = true) {
|
||||
return ConfigHelper.readConfig(appenv.CONFIG_PATH, readSecret ? appenv.SECRET_CONFIG_PATH : null);
|
||||
}
|
||||
|
||||
#saveConfig(cfg) {
|
||||
ConfigHelper.writeConfig(cfg, appenv.CONFIG_PATH, appenv.SECRET_CONFIG_PATH);
|
||||
ConfigHelper.writeConfig(cfg, appenv.CONFIG_PATH);
|
||||
}
|
||||
|
||||
newConfig(address = "", secret = "", governorAddress = "", leaseAmount = 0, rippledServer = null, ipv6Subnet = null, ipv6NetInterface = null) {
|
||||
newConfig(address = "", secretPath = "", governorAddress = "", leaseAmount = 0, rippledServer = null, ipv6Subnet = null, ipv6NetInterface = null, network = "") {
|
||||
const baseConfig = {
|
||||
version: appenv.MB_VERSION,
|
||||
xrpl: {
|
||||
network: network,
|
||||
address: address,
|
||||
secret: secret,
|
||||
secretPath: secretPath,
|
||||
governorAddress: governorAddress,
|
||||
rippledServer: rippledServer || appenv.DEFAULT_RIPPLED_SERVER,
|
||||
leaseAmount: leaseAmount
|
||||
@@ -72,18 +67,22 @@ class Setup {
|
||||
this.#saveConfig(ipv6NetInterface ? { ...baseConfig, networking: { ipv6: { subnet: ipv6Subnet, interface: ipv6NetInterface } } } : baseConfig);
|
||||
}
|
||||
|
||||
async setupHostAccount(address, secret, rippledServer, governorAddress, domain) {
|
||||
async prepareHostAccount(domain) {
|
||||
|
||||
setEvernodeDefaults(governorAddress, rippledServer);
|
||||
|
||||
const xrplApi = new evernode.XrplApi(rippledServer);
|
||||
const acc = new evernode.XrplAccount(address, secret, { xrplApi: xrplApi });
|
||||
const config = this.#getConfig();
|
||||
const acc = config.xrpl;
|
||||
await setEvernodeDefaults(acc.network, acc.governorAddress, acc.rippledServer);
|
||||
|
||||
// Prepare host account.
|
||||
{
|
||||
const hostClient = new evernode.HostClient(acc.address, acc.secret);
|
||||
await hostClient.connect();
|
||||
|
||||
// Update the Defaults with "xrplApi" of the client.
|
||||
evernode.Defaults.set({
|
||||
xrplApi: hostClient.xrplApi
|
||||
});
|
||||
|
||||
console.log(`Preparing host account:${acc.address} (domain:${domain} registry:${hostClient.config.registryAddress})`);
|
||||
|
||||
// Sometimes we may get 'account not found' error from rippled when some servers in the cluster
|
||||
@@ -110,70 +109,6 @@ class Setup {
|
||||
await hostClient.disconnect();
|
||||
}
|
||||
|
||||
return acc;
|
||||
}
|
||||
|
||||
async generateBetaHostAccount(rippledServer, governorAddress, domain) {
|
||||
|
||||
setEvernodeDefaults(governorAddress, rippledServer);
|
||||
|
||||
const acc = await this.#generateFaucetAccount();
|
||||
|
||||
// Prepare host account.
|
||||
{
|
||||
const hostClient = new evernode.HostClient(acc.address, acc.secret);
|
||||
await hostClient.connect();
|
||||
|
||||
console.log(`Preparing host account:${acc.address} (domain:${domain} registry:${hostClient.config.registryAddress})`);
|
||||
|
||||
// Sometimes we may get 'account not found' error from rippled when some servers in the testnet cluster
|
||||
// haven't still updated the ledger. In such cases, we retry several times before giving up.
|
||||
{
|
||||
let attempts = 0;
|
||||
while (attempts >= 0) {
|
||||
try {
|
||||
await hostClient.prepareAccount(domain);
|
||||
break;
|
||||
}
|
||||
catch (err) {
|
||||
if (err.data?.error === 'actNotFound' && ++attempts <= 5) {
|
||||
console.log("actNotFound - retrying...")
|
||||
// Wait and retry.
|
||||
await new Promise(resolve => setTimeout(resolve, 3000));
|
||||
continue;
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get beta EVRs from foundation to host account.
|
||||
{
|
||||
console.log("Requesting beta EVRs...");
|
||||
await hostClient.xrplAcc.makePayment(hostClient.config.foundationAddress,
|
||||
evernode.XrplConstants.MIN_XRP_AMOUNT,
|
||||
evernode.XrplConstants.XRP,
|
||||
null,
|
||||
[{ type: 'giftBetaEvr', format: '', data: '' }]);
|
||||
|
||||
// Keep watching our EVR balance.
|
||||
let attempts = 0;
|
||||
while (attempts >= 0) {
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
const balance = await hostClient.getEVRBalance();
|
||||
if (balance === '0') {
|
||||
if (++attempts <= 20)
|
||||
continue;
|
||||
throw "EVR funds not received within timeout.";
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
await hostClient.disconnect();
|
||||
}
|
||||
|
||||
return acc;
|
||||
}
|
||||
|
||||
async register(countryCode, cpuMicroSec, ramKb, swapKb, diskKb, totalInstanceCount, cpuModel, cpuCount, cpuSpeed, emailAddress, description) {
|
||||
@@ -181,13 +116,15 @@ class Setup {
|
||||
let cpuModelFormatted = cpuModel.replaceAll('_', ' ');
|
||||
const config = this.#getConfig();
|
||||
const acc = config.xrpl;
|
||||
setEvernodeDefaults(acc.governorAddress, acc.rippledServer);
|
||||
await setEvernodeDefaults(acc.network, acc.governorAddress, acc.rippledServer);
|
||||
|
||||
const hostClient = new evernode.HostClient(acc.address, acc.secret);
|
||||
await hostClient.connect();
|
||||
|
||||
// Update the Defaults with "xrplApi" of the client.
|
||||
setEvernodeDefaults(acc.governorAddress, acc.rippledServer, hostClient.xrplApi);
|
||||
evernode.Defaults.set({
|
||||
xrplApi: hostClient.xrplApi
|
||||
});
|
||||
|
||||
const isAReReg = await hostClient.isTransferee();
|
||||
const evrBalance = await hostClient.getEVRBalance();
|
||||
@@ -230,13 +167,15 @@ class Setup {
|
||||
async deregister() {
|
||||
console.log("Deregistering host...");
|
||||
const acc = this.#getConfig().xrpl;
|
||||
setEvernodeDefaults(acc.governorAddress, acc.rippledServer);
|
||||
await setEvernodeDefaults(acc.network, acc.governorAddress, acc.rippledServer);
|
||||
|
||||
const hostClient = new evernode.HostClient(acc.address, acc.secret);
|
||||
await hostClient.connect();
|
||||
|
||||
// Update the Defaults with "xrplApi" of the client.
|
||||
setEvernodeDefaults(acc.governorAddress, acc.rippledServer, hostClient.xrplApi);
|
||||
evernode.Defaults.set({
|
||||
xrplApi: hostClient.xrplApi
|
||||
});
|
||||
|
||||
await this.burnMintedURITokens(hostClient.xrplAcc);
|
||||
await hostClient.deregister();
|
||||
@@ -249,7 +188,7 @@ class Setup {
|
||||
console.log(`Governor address: ${acc?.governorAddress}`);
|
||||
|
||||
if (!isBasic) {
|
||||
setEvernodeDefaults(acc.governorAddress, acc.rippledServer);
|
||||
await setEvernodeDefaults(acc.network, acc.governorAddress, acc.rippledServer);
|
||||
|
||||
try {
|
||||
const hostClient = new evernode.HostClient(acc.address);
|
||||
@@ -257,7 +196,9 @@ class Setup {
|
||||
console.log(`Registry address: ${hostClient.config.registryAddress}`);
|
||||
console.log(`Heartbeat address: ${hostClient.config.heartbeatAddress}`);
|
||||
|
||||
setEvernodeDefaults(acc.governorAddress, acc.rippledServer, hostClient.xrplApi);
|
||||
evernode.Defaults.set({
|
||||
xrplApi: hostClient.xrplApi
|
||||
});
|
||||
|
||||
const [evrBalance, hostInfo] = await Promise.all([hostClient.getEVRBalance(), hostClient.getRegistration()]);
|
||||
if (hostInfo) {
|
||||
@@ -279,7 +220,7 @@ class Setup {
|
||||
}
|
||||
|
||||
// Upgrades existing message board data to the new version.
|
||||
async upgrade(governorAddress) {
|
||||
async upgrade() {
|
||||
|
||||
// Do a simple version change in the config.
|
||||
const cfg = this.#getConfig();
|
||||
@@ -289,19 +230,6 @@ class Setup {
|
||||
if (!cfg.xrpl.rippledServer)
|
||||
cfg.xrpl.rippledServer = appenv.DEFAULT_RIPPLED_SERVER
|
||||
|
||||
if (!cfg.xrpl.governorAddress) {
|
||||
setEvernodeDefaults(governorAddress, cfg.xrpl.rippledServer);
|
||||
|
||||
const hostClient = new evernode.HostClient(cfg.xrpl.address, cfg.xrpl.secret);
|
||||
await hostClient.connect();
|
||||
|
||||
setEvernodeDefaults(governorAddress, cfg.xrpl.rippledServer, hostClient.xrplApi);
|
||||
|
||||
cfg.xrpl.governorAddress = governorAddress;
|
||||
|
||||
await hostClient.disconnect();
|
||||
}
|
||||
|
||||
this.#saveConfig(cfg);
|
||||
|
||||
await Promise.resolve(); // async placeholder.
|
||||
@@ -311,13 +239,15 @@ class Setup {
|
||||
async hostInfo() {
|
||||
|
||||
const acc = this.#getConfig(false).xrpl;
|
||||
setEvernodeDefaults(acc.governorAddress, acc.rippledServer);
|
||||
await setEvernodeDefaults(acc.network, acc.governorAddress, acc.rippledServer);
|
||||
|
||||
const hostClient = new evernode.HostClient(acc.address);
|
||||
await hostClient.connect();
|
||||
|
||||
// Update the Defaults with "xrplApi" of the client.
|
||||
setEvernodeDefaults(acc.governorAddress, acc.rippledServer, hostClient.xrplApi);
|
||||
evernode.Defaults.set({
|
||||
xrplApi: hostClient.xrplApi
|
||||
});
|
||||
|
||||
const hostInfo = await hostClient.getHostInfo();
|
||||
|
||||
@@ -331,13 +261,15 @@ class Setup {
|
||||
|
||||
console.log("Updating host...");
|
||||
const acc = this.#getConfig().xrpl;
|
||||
setEvernodeDefaults(acc.governorAddress, acc.rippledServer);
|
||||
await setEvernodeDefaults(acc.network, acc.governorAddress, acc.rippledServer);
|
||||
|
||||
const hostClient = new evernode.HostClient(acc.address, acc.secret);
|
||||
await hostClient.connect();
|
||||
|
||||
// Update the Defaults with "xrplApi" of the client.
|
||||
setEvernodeDefaults(acc.governorAddress, acc.rippledServer, hostClient.xrplApi);
|
||||
evernode.Defaults.set({
|
||||
xrplApi: hostClient.xrplApi
|
||||
});
|
||||
|
||||
const hostInfo = await hostClient.getHostInfo();
|
||||
await hostClient.updateRegInfo(hostInfo.activeInstances, null, null, null, null, null, null, null, null, emailAddress);
|
||||
@@ -385,12 +317,14 @@ class Setup {
|
||||
async transfer(transfereeAddress) {
|
||||
console.log("Transferring host...");
|
||||
const acc = this.#getConfig().xrpl;
|
||||
setEvernodeDefaults(acc.governorAddress, acc.rippledServer);
|
||||
await setEvernodeDefaults(acc.network, acc.governorAddress, acc.rippledServer);
|
||||
|
||||
const hostClient = new evernode.HostClient(acc.address, acc.secret);
|
||||
await hostClient.connect();
|
||||
|
||||
setEvernodeDefaults(acc.governorAddress, acc.rippledServer, hostClient.xrplApi);
|
||||
evernode.Defaults.set({
|
||||
xrplApi: hostClient.xrplApi
|
||||
});
|
||||
|
||||
await hostClient.transfer(transfereeAddress);
|
||||
await this.burnMintedURITokens(hostClient.xrplAcc);
|
||||
@@ -410,7 +344,7 @@ class Setup {
|
||||
else if (totalInstanceCount && isNaN(totalInstanceCount))
|
||||
throw 'Maximum instance count should be a number';
|
||||
|
||||
const leaseAmountParsed = leaseAmount ? parseInt(leaseAmount) : 0;
|
||||
const leaseAmountParsed = leaseAmount ? parseFloat(leaseAmount) : 0;
|
||||
const totalInstanceCountParsed = totalInstanceCount ? parseInt(totalInstanceCount) : 0;
|
||||
|
||||
// Return if not changed.
|
||||
@@ -448,13 +382,14 @@ class Setup {
|
||||
let hostClient;
|
||||
|
||||
async function initClients(rippledServer) {
|
||||
setEvernodeDefaults(acc.governorAddress, rippledServer);
|
||||
await setEvernodeDefaults(acc.network, acc.governorAddress, rippledServer);
|
||||
xrplApi = new evernode.XrplApi();
|
||||
hostClient = new evernode.HostClient(acc.address, acc.secret, { xrplApi: xrplApi });
|
||||
await xrplApi.connect();
|
||||
await hostClient.connect();
|
||||
setEvernodeDefaults(acc.governorAddress, acc.rippledServer, xrplApi);
|
||||
|
||||
evernode.Defaults.set({
|
||||
xrplApi: xrplApi
|
||||
});
|
||||
}
|
||||
|
||||
async function deinitClients() {
|
||||
@@ -594,12 +529,14 @@ class Setup {
|
||||
lease = lease[0];
|
||||
|
||||
const acc = this.#getConfig().xrpl;
|
||||
setEvernodeDefaults(acc.governorAddress, acc.rippledServer);
|
||||
await setEvernodeDefaults(acc.network, acc.governorAddress, acc.rippledServer);
|
||||
|
||||
xrplApi = new evernode.XrplApi(acc.rippledServer);
|
||||
await xrplApi.connect();
|
||||
|
||||
setEvernodeDefaults(acc.governorAddress, acc.rippledServer, xrplApi);
|
||||
evernode.Defaults.set({
|
||||
xrplApi: xrplApi
|
||||
});
|
||||
|
||||
// Get the existing uriToken of the lease.
|
||||
const uriToken = (await (new evernode.XrplAccount(lease.tenant_xrp_address, null, { xrplApi: xrplApi }).getURITokens()))?.find(n => n.index == lease.container_name);
|
||||
@@ -643,7 +580,43 @@ class Setup {
|
||||
if (xrplApi)
|
||||
await xrplApi.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
async setRegularKey(regularKey) {
|
||||
{
|
||||
const acc = this.#getConfig().xrpl;
|
||||
await setEvernodeDefaults(acc.network, acc.governorAddress, acc.rippledServer);
|
||||
|
||||
if (regularKey) {
|
||||
console.log(`Setting Regular Key...`);
|
||||
}
|
||||
else {
|
||||
console.log(`Deleting Regular Key...`);
|
||||
}
|
||||
|
||||
try {
|
||||
await setEvernodeDefaults(acc.network, acc.governorAddress, acc.rippledServer);
|
||||
|
||||
const xrplApi = new evernode.XrplApi(acc.rippledServer, { autoReconnect: false });
|
||||
await xrplApi.connect();
|
||||
|
||||
const xrplAcc = new evernode.XrplAccount(acc.address, acc.secret, { xrplApi: xrplApi });
|
||||
|
||||
await xrplAcc.setRegularKey(regularKey);
|
||||
|
||||
if (regularKey) {
|
||||
console.log(`Regular key ${regularKey} was assigned to account ${acc.address} successfully.`);
|
||||
}
|
||||
else {
|
||||
console.log(`Regular key was deleted from account ${acc.address} successfully.`);
|
||||
}
|
||||
|
||||
await xrplApi.disconnect();
|
||||
}
|
||||
catch (e) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
14
mb-xrpl/package-lock.json
generated
14
mb-xrpl/package-lock.json
generated
@@ -6,7 +6,7 @@
|
||||
"": {
|
||||
"name": "mb-xrpl",
|
||||
"dependencies": {
|
||||
"evernode-js-client": "0.6.20",
|
||||
"evernode-js-client": "0.6.24",
|
||||
"ip6addr": "0.2.5",
|
||||
"sqlite3": "5.0.2"
|
||||
},
|
||||
@@ -980,9 +980,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/evernode-js-client": {
|
||||
"version": "0.6.20",
|
||||
"resolved": "https://registry.npmjs.org/evernode-js-client/-/evernode-js-client-0.6.20.tgz",
|
||||
"integrity": "sha512-OC6VNAhwqnNvUc0NhffxwNI9bTDH+BkD/KBTC5Xuwoiq8BhRfYhmfHBnD6M9K5AvLqv+Jxdufc3l1AlzHgILWg==",
|
||||
"version": "0.6.24",
|
||||
"resolved": "https://registry.npmjs.org/evernode-js-client/-/evernode-js-client-0.6.24.tgz",
|
||||
"integrity": "sha512-sT7eoN796ueo0+yZl6KpQOzINuXrYW88YlZCm2PxzRqv5G4TqgqUGFgs+GSESkxuVRkw2LBX9WcUCGwbAt6K9g==",
|
||||
"dependencies": {
|
||||
"elliptic": "6.5.4",
|
||||
"libsodium-wrappers": "0.7.10",
|
||||
@@ -4010,9 +4010,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"evernode-js-client": {
|
||||
"version": "0.6.20",
|
||||
"resolved": "https://registry.npmjs.org/evernode-js-client/-/evernode-js-client-0.6.20.tgz",
|
||||
"integrity": "sha512-OC6VNAhwqnNvUc0NhffxwNI9bTDH+BkD/KBTC5Xuwoiq8BhRfYhmfHBnD6M9K5AvLqv+Jxdufc3l1AlzHgILWg==",
|
||||
"version": "0.6.24",
|
||||
"resolved": "https://registry.npmjs.org/evernode-js-client/-/evernode-js-client-0.6.24.tgz",
|
||||
"integrity": "sha512-sT7eoN796ueo0+yZl6KpQOzINuXrYW88YlZCm2PxzRqv5G4TqgqUGFgs+GSESkxuVRkw2LBX9WcUCGwbAt6K9g==",
|
||||
"requires": {
|
||||
"elliptic": "6.5.4",
|
||||
"libsodium-wrappers": "0.7.10",
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"build": "npm run lint && ncc build app.js --minify -o dist"
|
||||
},
|
||||
"dependencies": {
|
||||
"evernode-js-client": "0.6.20",
|
||||
"evernode-js-client": "0.6.24",
|
||||
"sqlite3": "5.0.2",
|
||||
"ip6addr": "0.2.5"
|
||||
},
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#include "cli-manager.hpp"
|
||||
#include "version.hpp"
|
||||
|
||||
#define DEV_MODE "DEV_MODE"
|
||||
|
||||
std::string exec_dir;
|
||||
|
||||
/**
|
||||
@@ -90,6 +92,7 @@ int parse_cmd(int argc, char **argv)
|
||||
std::string json_message;
|
||||
json->add_option("-m,--message", json_message, "JSON message");
|
||||
|
||||
create->group(""); //Hides 'create' command from help-all
|
||||
std::string owner, contract_id, image, outbound_ipv6, outbound_net_interface;
|
||||
create->add_option("-o,--owner", owner, "Hex (ed-prefixed) public key of the instance owner");
|
||||
create->add_option("-c,--contract-id", contract_id, "Contract Id (GUID) of the instance");
|
||||
@@ -126,6 +129,25 @@ int parse_cmd(int argc, char **argv)
|
||||
}
|
||||
|
||||
// Verifying subcommands.
|
||||
|
||||
bool is_dev_mode = (getenv(DEV_MODE) != nullptr);
|
||||
|
||||
if (!is_dev_mode)
|
||||
{
|
||||
if(create->parsed()){
|
||||
std::cout << "Command not supported: Run with --help or --help-all for more information." << std::endl;
|
||||
return -1;
|
||||
}
|
||||
if(json->parsed() && !json_message.empty()){
|
||||
jsoncons::json json_data = jsoncons::json::parse(json_message);
|
||||
if (json_data.contains("type") && json_data["type"].as_string() == "create")
|
||||
{
|
||||
std::cout << "Command not supported: Run with --help or --help-all for more information." << std::endl;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (version->parsed())
|
||||
{
|
||||
std::cout << "Sashimono CLI version " << version::CLI_VERSION << std::endl;
|
||||
|
||||
@@ -69,7 +69,7 @@ namespace conf
|
||||
cfg.system.max_cpu_us = !cpu_us ? 900000 : cpu_us; // Total CPU allocation out of 1000000 microsec (1 sec).
|
||||
cfg.system.max_storage_kbytes = !disk_kbytes ? 5242880 : disk_kbytes;
|
||||
|
||||
cfg.docker.image_prefix = "evernodedev/sashimono:";
|
||||
cfg.docker.image_prefix = "evernode/sashimono:";
|
||||
cfg.docker.registry_port = docker_registry_port;
|
||||
|
||||
cfg.log.max_file_count = 50;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
namespace version
|
||||
{
|
||||
// Sashimono agent version. Written to new configs.
|
||||
constexpr const char *AGENT_VERSION = "0.7.2";
|
||||
constexpr const char *AGENT_VERSION = "0.8.0";
|
||||
|
||||
// Minimum compatible config version (this will be used to validate configs).
|
||||
constexpr const char *MIN_CONFIG_VERSION = "0.5.0";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM evernodedev/hotpocket:0.6.3-ubt.20.04
|
||||
FROM evernode/hotpocket:0.6.4-ubt.20.04
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install --no-install-recommends -y unzip jq \
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM evernodedev/hotpocket:0.6.3-ubt.20.04-njs.20
|
||||
FROM evernode/hotpocket:0.6.4-ubt.20.04-njs.20
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install --no-install-recommends -y unzip jq \
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
img=evernodedev/sashimono
|
||||
img=evernode/sashimono
|
||||
|
||||
docker build -t $img:hp.latest-ubt.20.04 -t $img:hp.0.6.3-ubt.20.04 -f ./Dockerfile.ubt.20.04 .
|
||||
docker build -t $img:hp.latest-ubt.20.04-njs.20 -t $img:hp.0.6.3-ubt.20.04-njs.20 -f ./Dockerfile.ubt.20.04-njs .
|
||||
docker build -t $img:hp.latest-ubt.20.04 -t $img:hp.0.6.4-ubt.20.04 -f ./Dockerfile.ubt.20.04 .
|
||||
docker build -t $img:hp.latest-ubt.20.04-njs.20 -t $img:hp.0.6.4-ubt.20.04-njs.20 -f ./Dockerfile.ubt.20.04-njs .
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
img=evernodedev/sashimono
|
||||
img=evernode/sashimono
|
||||
|
||||
docker image push --all-tags $img
|
||||
@@ -473,7 +473,7 @@ if [ $mode == "create" ] || [ $mode == "createall" ]; then
|
||||
config=$(echo "$config" | jq -c ".mesh.known_peers = [$peers]" | jq -c ".contract.unl = [\"$pubkey\"]")
|
||||
fi
|
||||
|
||||
command="sashi json -m '{\"type\":\"create\",\"owner_pubkey\":\"$ownerpubkey\",\"contract_id\":\"$contractid\",\"image\":\"$image\",\"config\":$config}'"
|
||||
command="DEV_MODE=1 sashi json -m '{\"type\":\"create\",\"owner_pubkey\":\"$ownerpubkey\",\"contract_id\":\"$contractid\",\"image\":\"$image\",\"config\":$config}'"
|
||||
output=$(sshskp $sshuser@$hostaddr $command | tr '\0' '\n')
|
||||
# If an output received consider updating the json file.
|
||||
if [ ! "$output" = "" ]; then
|
||||
|
||||
Reference in New Issue
Block a user