Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ea271d720d | |||
| 8d2e8b3d26 | |||
| 2a87533b12 | |||
| 499fd8a91d | |||
| e083bfcfe4 | |||
| 22c59be82c | |||
| f17e7378f7 | |||
| 1bb455675e | |||
| 73076a2b26 | |||
| 1e1bf25514 | |||
| 4df29535dc | |||
| 6f08b60789 | |||
| 9ec0f4a88e | |||
| 6b4b7f5cdd |
@@ -0,0 +1,2 @@
|
||||
.tmp
|
||||
hashes.json
|
||||
@@ -0,0 +1,25 @@
|
||||
name: 'Nym Hash Release'
|
||||
author: 'Nym Technologies SA'
|
||||
description: 'Generate hashes and signatures for assets in Nym releases'
|
||||
inputs:
|
||||
hash-type:
|
||||
description: 'Type of hash to generate (md5, sha1, sha256, sha512)'
|
||||
required: false
|
||||
default: 'sha256'
|
||||
file-name:
|
||||
description: 'File name to save as if desired'
|
||||
required: false
|
||||
default: 'hashes.json'
|
||||
release-tag-or-name-or-id:
|
||||
description: 'The tag/release to process. Uses the release id when trigger from a release.'
|
||||
required: false
|
||||
default: ''
|
||||
outputs:
|
||||
hashes:
|
||||
description: 'A string containing JSON with the release asset hashes and signatures'
|
||||
runs:
|
||||
using: 'node16'
|
||||
main: 'index.js'
|
||||
branding:
|
||||
icon: 'hash'
|
||||
color: 'green'
|
||||
@@ -0,0 +1,259 @@
|
||||
import hasha from "hasha";
|
||||
import fetch from "node-fetch";
|
||||
import { Octokit } from "@octokit/rest";
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
|
||||
async function run(assets, algorithm, filename, cache) {
|
||||
try {
|
||||
fs.mkdirSync('.tmp');
|
||||
} catch(e) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
const hashes = {};
|
||||
let numAwaiting = 0;
|
||||
for (const asset of assets) {
|
||||
if (filename === "" || asset.name !== filename) { // don't hash the hash file (if the file has the same name)
|
||||
numAwaiting++;
|
||||
|
||||
let buffer = null;
|
||||
let sig = null;
|
||||
if(cache) {
|
||||
// cache in `${WORKING_DIR}/.tmp/`
|
||||
const cacheFilename = path.resolve(`.tmp/${asset.name}`);
|
||||
if(!fs.existsSync(cacheFilename)) {
|
||||
console.log(`Downloading ${asset.browser_download_url}... to ${cacheFilename}`);
|
||||
buffer = Buffer.from(await fetch(asset.browser_download_url).then(res => res.arrayBuffer()));
|
||||
fs.writeFileSync(cacheFilename, buffer);
|
||||
} else {
|
||||
console.log(`Loading from ${cacheFilename}`);
|
||||
buffer = Buffer.from(fs.readFileSync(cacheFilename));
|
||||
|
||||
// console.log('Reading signature from content');
|
||||
// if(asset.name.endsWith('.sig')) {
|
||||
// sig = fs.readFileSync(cacheFilename).toString();
|
||||
// }
|
||||
}
|
||||
} else {
|
||||
// fetch always
|
||||
buffer = Buffer.from(await fetch(asset.browser_download_url).then(res => res.arrayBuffer()));
|
||||
}
|
||||
if(!hashes[asset.name]) {
|
||||
hashes[asset.name] = {};
|
||||
}
|
||||
|
||||
if(asset.name.endsWith('.sig')) {
|
||||
sig = buffer.toString();
|
||||
}
|
||||
|
||||
hashes[asset.name][algorithm] = hasha(new Uint8Array(buffer), {algorithm: algorithm});
|
||||
|
||||
let platform;
|
||||
let kind;
|
||||
if(asset.name.endsWith('.sig')) {
|
||||
kind = 'signature';
|
||||
}
|
||||
if(asset.name.endsWith('.app.tar.gz')) {
|
||||
platform = 'MacOS';
|
||||
kind = 'auto-updater';
|
||||
}
|
||||
if(asset.name.endsWith('.app.tar.gz.sig')) {
|
||||
platform = 'MacOS';
|
||||
kind = 'auto-updater-signature';
|
||||
}
|
||||
if(asset.name.endsWith('.dmg')) {
|
||||
platform = 'MacOS';
|
||||
kind = 'installer';
|
||||
}
|
||||
if(asset.name.endsWith('.msi.zip')) {
|
||||
platform = 'Windows';
|
||||
kind = 'auto-updater';
|
||||
}
|
||||
if(asset.name.endsWith('.msi.zip.sig')) {
|
||||
platform = 'Windows';
|
||||
kind = 'auto-updater-signature';
|
||||
}
|
||||
if(asset.name.endsWith('.msi')) {
|
||||
platform = 'Windows';
|
||||
kind = 'installer';
|
||||
}
|
||||
if(asset.name.endsWith('.AppImage.tar.gz')) {
|
||||
platform = 'Linux';
|
||||
kind = 'auto-updater';
|
||||
}
|
||||
if(asset.name.endsWith('.AppImage.tar.gz.sig')) {
|
||||
platform = 'Linux';
|
||||
kind = 'auto-updater-signature';
|
||||
}
|
||||
if(asset.name.endsWith('.AppImage')) {
|
||||
platform = 'Linux';
|
||||
kind = 'installer';
|
||||
}
|
||||
|
||||
hashes[asset.name].downloadUrl = asset.browser_download_url;
|
||||
|
||||
if(platform) {
|
||||
hashes[asset.name].platform = platform;
|
||||
}
|
||||
if(kind) {
|
||||
hashes[asset.name].kind = kind;
|
||||
}
|
||||
|
||||
// process Tauri signature files
|
||||
if(asset.name.endsWith('.sig')) {
|
||||
const otherFilename = asset.name.replace('.sig', '');
|
||||
if(!hashes[otherFilename]) {
|
||||
hashes[otherFilename] = {};
|
||||
}
|
||||
hashes[otherFilename].signature = sig;
|
||||
}
|
||||
}
|
||||
}
|
||||
return hashes;
|
||||
}
|
||||
|
||||
export async function createHashes({ assets, algorithm, filename, cache }) {
|
||||
const output = await run(assets, algorithm, filename, cache);
|
||||
if(filename?.length) {
|
||||
fs.writeFileSync(filename, JSON.stringify(output, null, 2));
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
export async function createHashesFromReleaseTagOrNameOrId({ releaseTagOrNameOrId, algorithm = 'sha256', filename = 'hashes.json', cache = false, upload = true }) {
|
||||
console.log("🚀🚀🚀 Getting releases");
|
||||
|
||||
let auth;
|
||||
let authStrategy;
|
||||
if(process.env.GITHUB_TOKEN) {
|
||||
console.log('Using GITHUB_TOKEN for auth');
|
||||
// authStrategy = createActionAuth();
|
||||
// auth = await authStrategy();
|
||||
}
|
||||
|
||||
const octokit = new Octokit({
|
||||
auth: process.env.GITHUB_TOKEN,
|
||||
request: { fetch }
|
||||
});
|
||||
const owner = "nymtech";
|
||||
const repo = "nym";
|
||||
|
||||
let releases;
|
||||
if(cache) {
|
||||
const cacheFilename = path.resolve(`.tmp/releases.json`);
|
||||
if(!fs.existsSync(cacheFilename)) {
|
||||
releases = await octokit.paginate(
|
||||
octokit.rest.repos.listReleases,
|
||||
{
|
||||
owner,
|
||||
repo,
|
||||
per_page: 100,
|
||||
},
|
||||
(response) => response.data
|
||||
);
|
||||
fs.writeFileSync(cacheFilename, JSON.stringify(releases, null, 2));
|
||||
} else {
|
||||
console.log('Loading releases from cache...');
|
||||
releases = JSON.parse(fs.readFileSync(cacheFilename));
|
||||
}
|
||||
} else {
|
||||
releases = await octokit.paginate(
|
||||
octokit.rest.repos.listReleases,
|
||||
{
|
||||
owner,
|
||||
repo,
|
||||
per_page: 100,
|
||||
},
|
||||
(response) => response.data
|
||||
)
|
||||
}
|
||||
|
||||
// process all releases by default
|
||||
let releasesToProcess = releases;
|
||||
|
||||
// process a single release
|
||||
if(releaseTagOrNameOrId) {
|
||||
releasesToProcess = releases.filter(r => {
|
||||
if (r.tag_name === releaseTagOrNameOrId) {
|
||||
return true;
|
||||
}
|
||||
if (`${r.id}` === `${releaseTagOrNameOrId}`) {
|
||||
return true;
|
||||
}
|
||||
if (r.name === releaseTagOrNameOrId) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
releasesToProcess.forEach(release => {
|
||||
const {tag_name, name} = release;
|
||||
const tagComponents = tag_name.split('-v');
|
||||
const componentName = tagComponents[0];
|
||||
const componentVersion = 'v' + tagComponents[1];
|
||||
|
||||
if(!tagComponents[1] || !name) {
|
||||
return;
|
||||
}
|
||||
|
||||
release.componentName = componentName;
|
||||
release.componentVersion = componentVersion;
|
||||
})
|
||||
|
||||
releasesToProcess = releasesToProcess.filter(release =>
|
||||
!!release.name && !!release.componentVersion
|
||||
);
|
||||
|
||||
console.log('Releases to process:');
|
||||
console.table(releasesToProcess.map(r => {
|
||||
const { id, name, tag_name, componentName, componentVersion, assets } = r;
|
||||
return { id, name, tag_name, componentName, componentVersion, assetCount: assets.length };
|
||||
}));
|
||||
|
||||
for(const release of releasesToProcess) {
|
||||
const {id, name, tag_name, html_url, componentName, componentVersion} = release;
|
||||
|
||||
const hashes = await createHashes({ assets: release.assets, algorithm, filename, cache });
|
||||
|
||||
const output = {
|
||||
id, name, tag_name, html_url,
|
||||
componentName,
|
||||
componentVersion,
|
||||
assets: hashes,
|
||||
};
|
||||
|
||||
if(upload) {
|
||||
console.log(`🚚 Uploading ${filename} to release name="${release.name}" id=${release.id} (${release.upload_url})...`);
|
||||
|
||||
const exists = (await octokit.repos.listReleaseAssets({ owner, repo, release_id: release.id })).data.find(a => a.name === filename)
|
||||
if (exists) {
|
||||
console.log(`Deleting existing asset ${filename}...`);
|
||||
await octokit.repos.deleteReleaseAsset({ owner, repo, asset_id: exists.id })
|
||||
console.log('Deleted existing asset');
|
||||
}
|
||||
|
||||
try {
|
||||
const data = JSON.stringify(output, null, 2);
|
||||
await octokit.rest.repos.uploadReleaseAsset({
|
||||
owner,
|
||||
repo,
|
||||
release_id: release.id,
|
||||
headers: {
|
||||
'X-GitHub-Api-Version': '2022-11-28'
|
||||
},
|
||||
name: filename,
|
||||
data,
|
||||
});
|
||||
console.log('✅ Upload to release is complete.');
|
||||
} catch(e) {
|
||||
console.log('❌ failed to upload:', e.message, e.status, e.response.data);
|
||||
console.log(e);
|
||||
process.exit(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import core from "@actions/core";
|
||||
import github from "@actions/github";
|
||||
import { createHashesFromReleaseTagOrNameOrId } from './create-hashes.mjs';
|
||||
|
||||
const algorithm = core.getInput('hash-type');
|
||||
const filename = core.getInput("file-name");
|
||||
|
||||
// use the release id from the payload if it is set
|
||||
const releaseTagOrNameOrId = core.getInput("release-tag-or-name-or-id") || github.context.payload.release?.id;
|
||||
|
||||
try {
|
||||
await createHashesFromReleaseTagOrNameOrId({ releaseTagOrNameOrId, algorithm, filename })
|
||||
} catch (error) {
|
||||
core.setFailed(error.message);
|
||||
}
|
||||
+536
@@ -0,0 +1,536 @@
|
||||
{
|
||||
"name": "ghaction-generate-release-hashes",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "ghaction-generate-release-hashes",
|
||||
"version": "1.0.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@actions/core": "^1.10.0",
|
||||
"@actions/github": "^5.1.1",
|
||||
"@octokit/auth-action": "^4.0.0",
|
||||
"@octokit/rest": "^20.0.1",
|
||||
"hasha": "^5.2.0",
|
||||
"node-fetch": "^3.2.10"
|
||||
}
|
||||
},
|
||||
"node_modules/@actions/core": {
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.10.0.tgz",
|
||||
"integrity": "sha512-2aZDDa3zrrZbP5ZYg159sNoLRb61nQ7awl5pSvIq5Qpj81vwDzdMRKzkWJGJuwVvWpvZKx7vspJALyvaaIQyug==",
|
||||
"dependencies": {
|
||||
"@actions/http-client": "^2.0.1",
|
||||
"uuid": "^8.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@actions/github": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@actions/github/-/github-5.1.1.tgz",
|
||||
"integrity": "sha512-Nk59rMDoJaV+mHCOJPXuvB1zIbomlKS0dmSIqPGxd0enAXBnOfn4VWF+CGtRCwXZG9Epa54tZA7VIRlJDS8A6g==",
|
||||
"dependencies": {
|
||||
"@actions/http-client": "^2.0.1",
|
||||
"@octokit/core": "^3.6.0",
|
||||
"@octokit/plugin-paginate-rest": "^2.17.0",
|
||||
"@octokit/plugin-rest-endpoint-methods": "^5.13.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@actions/http-client": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.1.1.tgz",
|
||||
"integrity": "sha512-qhrkRMB40bbbLo7gF+0vu+X+UawOvQQqNAA/5Unx774RS8poaOhThDOG6BGmxvAnxhQnDp2BG/ZUm65xZILTpw==",
|
||||
"dependencies": {
|
||||
"tunnel": "^0.0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/auth-action": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/auth-action/-/auth-action-4.0.0.tgz",
|
||||
"integrity": "sha512-sMm9lWZdiX6e89YFaLrgE9EFs94k58BwIkvjOtozNWUqyTmsrnWFr/M5LolaRzZ7Kmb5FbhF9hi7FEeE274SoQ==",
|
||||
"dependencies": {
|
||||
"@octokit/auth-token": "^4.0.0",
|
||||
"@octokit/types": "^11.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/auth-action/node_modules/@octokit/auth-token": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz",
|
||||
"integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==",
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/auth-action/node_modules/@octokit/openapi-types": {
|
||||
"version": "18.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-18.0.0.tgz",
|
||||
"integrity": "sha512-V8GImKs3TeQRxRtXFpG2wl19V7444NIOTDF24AWuIbmNaNYOQMWRbjcGDXV5B+0n887fgDcuMNOmlul+k+oJtw=="
|
||||
},
|
||||
"node_modules/@octokit/auth-action/node_modules/@octokit/types": {
|
||||
"version": "11.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-11.1.0.tgz",
|
||||
"integrity": "sha512-Fz0+7GyLm/bHt8fwEqgvRBWwIV1S6wRRyq+V6exRKLVWaKGsuy6H9QFYeBVDV7rK6fO3XwHgQOPxv+cLj2zpXQ==",
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": "^18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/auth-token": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz",
|
||||
"integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^6.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/core": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.6.0.tgz",
|
||||
"integrity": "sha512-7RKRKuA4xTjMhY+eG3jthb3hlZCsOwg3rztWh75Xc+ShDWOfDDATWbeZpAHBNRpm4Tv9WgBMOy1zEJYXG6NJ7Q==",
|
||||
"dependencies": {
|
||||
"@octokit/auth-token": "^2.4.4",
|
||||
"@octokit/graphql": "^4.5.8",
|
||||
"@octokit/request": "^5.6.3",
|
||||
"@octokit/request-error": "^2.0.5",
|
||||
"@octokit/types": "^6.0.3",
|
||||
"before-after-hook": "^2.2.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/endpoint": {
|
||||
"version": "6.0.12",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz",
|
||||
"integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^6.0.3",
|
||||
"is-plain-object": "^5.0.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/graphql": {
|
||||
"version": "4.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz",
|
||||
"integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==",
|
||||
"dependencies": {
|
||||
"@octokit/request": "^5.6.0",
|
||||
"@octokit/types": "^6.0.3",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/openapi-types": {
|
||||
"version": "12.11.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-12.11.0.tgz",
|
||||
"integrity": "sha512-VsXyi8peyRq9PqIz/tpqiL2w3w80OgVMwBHltTml3LmVvXiphgeqmY9mvBw9Wu7e0QWk/fqD37ux8yP5uVekyQ=="
|
||||
},
|
||||
"node_modules/@octokit/plugin-paginate-rest": {
|
||||
"version": "2.21.3",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.21.3.tgz",
|
||||
"integrity": "sha512-aCZTEf0y2h3OLbrgKkrfFdjRL6eSOo8komneVQJnYecAxIej7Bafor2xhuDJOIFau4pk0i/P28/XgtbyPF0ZHw==",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^6.40.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@octokit/core": ">=2"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/plugin-rest-endpoint-methods": {
|
||||
"version": "5.16.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.16.2.tgz",
|
||||
"integrity": "sha512-8QFz29Fg5jDuTPXVtey05BLm7OB+M8fnvE64RNegzX7U+5NUXcOcnpTIK0YfSHBg8gYd0oxIq3IZTe9SfPZiRw==",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^6.39.0",
|
||||
"deprecation": "^2.3.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@octokit/core": ">=3"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/request": {
|
||||
"version": "5.6.3",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.3.tgz",
|
||||
"integrity": "sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A==",
|
||||
"dependencies": {
|
||||
"@octokit/endpoint": "^6.0.1",
|
||||
"@octokit/request-error": "^2.1.0",
|
||||
"@octokit/types": "^6.16.1",
|
||||
"is-plain-object": "^5.0.0",
|
||||
"node-fetch": "^2.6.7",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/request-error": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz",
|
||||
"integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^6.0.3",
|
||||
"deprecation": "^2.0.0",
|
||||
"once": "^1.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/request/node_modules/node-fetch": {
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
|
||||
"integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
|
||||
"dependencies": {
|
||||
"whatwg-url": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "4.x || >=6.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"encoding": "^0.1.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"encoding": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/rest": {
|
||||
"version": "20.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-20.0.1.tgz",
|
||||
"integrity": "sha512-wROV21RwHQIMNb2Dgd4+pY+dVy1Dwmp85pBrgr6YRRDYRBu9Gb+D73f4Bl2EukZSj5hInq2Tui9o7gAQpc2k2Q==",
|
||||
"dependencies": {
|
||||
"@octokit/core": "^5.0.0",
|
||||
"@octokit/plugin-paginate-rest": "^8.0.0",
|
||||
"@octokit/plugin-request-log": "^4.0.0",
|
||||
"@octokit/plugin-rest-endpoint-methods": "^9.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/rest/node_modules/@octokit/auth-token": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz",
|
||||
"integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==",
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/rest/node_modules/@octokit/core": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.0.0.tgz",
|
||||
"integrity": "sha512-YbAtMWIrbZ9FCXbLwT9wWB8TyLjq9mxpKdgB3dUNxQcIVTf9hJ70gRPwAcqGZdY6WdJPZ0I7jLaaNDCiloGN2A==",
|
||||
"dependencies": {
|
||||
"@octokit/auth-token": "^4.0.0",
|
||||
"@octokit/graphql": "^7.0.0",
|
||||
"@octokit/request": "^8.0.2",
|
||||
"@octokit/request-error": "^5.0.0",
|
||||
"@octokit/types": "^11.0.0",
|
||||
"before-after-hook": "^2.2.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/rest/node_modules/@octokit/endpoint": {
|
||||
"version": "9.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.0.tgz",
|
||||
"integrity": "sha512-szrQhiqJ88gghWY2Htt8MqUDO6++E/EIXqJ2ZEp5ma3uGS46o7LZAzSLt49myB7rT+Hfw5Y6gO3LmOxGzHijAQ==",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^11.0.0",
|
||||
"is-plain-object": "^5.0.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/rest/node_modules/@octokit/graphql": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-7.0.1.tgz",
|
||||
"integrity": "sha512-T5S3oZ1JOE58gom6MIcrgwZXzTaxRnxBso58xhozxHpOqSTgDS6YNeEUvZ/kRvXgPrRz/KHnZhtb7jUMRi9E6w==",
|
||||
"dependencies": {
|
||||
"@octokit/request": "^8.0.1",
|
||||
"@octokit/types": "^11.0.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/rest/node_modules/@octokit/openapi-types": {
|
||||
"version": "18.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-18.0.0.tgz",
|
||||
"integrity": "sha512-V8GImKs3TeQRxRtXFpG2wl19V7444NIOTDF24AWuIbmNaNYOQMWRbjcGDXV5B+0n887fgDcuMNOmlul+k+oJtw=="
|
||||
},
|
||||
"node_modules/@octokit/rest/node_modules/@octokit/plugin-paginate-rest": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-8.0.0.tgz",
|
||||
"integrity": "sha512-2xZ+baZWUg+qudVXnnvXz7qfrTmDeYPCzangBVq/1gXxii/OiS//4shJp9dnCCvj1x+JAm9ji1Egwm1BA47lPQ==",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^11.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@octokit/core": ">=5"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/rest/node_modules/@octokit/plugin-request-log": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-4.0.0.tgz",
|
||||
"integrity": "sha512-2uJI1COtYCq8Z4yNSnM231TgH50bRkheQ9+aH8TnZanB6QilOnx8RMD2qsnamSOXtDj0ilxvevf5fGsBhBBzKA==",
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@octokit/core": ">=5"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/rest/node_modules/@octokit/plugin-rest-endpoint-methods": {
|
||||
"version": "9.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-9.0.0.tgz",
|
||||
"integrity": "sha512-KquMF/VB1IkKNiVnzJKspY5mFgGyLd7HzdJfVEGTJFzqu9BRFNWt+nwTCMuUiWc72gLQhRWYubTwOkQj+w/1PA==",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^11.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@octokit/core": ">=5"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/rest/node_modules/@octokit/request": {
|
||||
"version": "8.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.1.1.tgz",
|
||||
"integrity": "sha512-8N+tdUz4aCqQmXl8FpHYfKG9GelDFd7XGVzyN8rc6WxVlYcfpHECnuRkgquzz+WzvHTK62co5di8gSXnzASZPQ==",
|
||||
"dependencies": {
|
||||
"@octokit/endpoint": "^9.0.0",
|
||||
"@octokit/request-error": "^5.0.0",
|
||||
"@octokit/types": "^11.1.0",
|
||||
"is-plain-object": "^5.0.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/rest/node_modules/@octokit/request-error": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.0.0.tgz",
|
||||
"integrity": "sha512-1ue0DH0Lif5iEqT52+Rf/hf0RmGO9NWFjrzmrkArpG9trFfDM/efx00BJHdLGuro4BR/gECxCU2Twf5OKrRFsQ==",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^11.0.0",
|
||||
"deprecation": "^2.0.0",
|
||||
"once": "^1.4.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/rest/node_modules/@octokit/types": {
|
||||
"version": "11.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-11.1.0.tgz",
|
||||
"integrity": "sha512-Fz0+7GyLm/bHt8fwEqgvRBWwIV1S6wRRyq+V6exRKLVWaKGsuy6H9QFYeBVDV7rK6fO3XwHgQOPxv+cLj2zpXQ==",
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": "^18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/types": {
|
||||
"version": "6.41.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.41.0.tgz",
|
||||
"integrity": "sha512-eJ2jbzjdijiL3B4PrSQaSjuF2sPEQPVCPzBvTHJD9Nz+9dw2SGH4K4xeQJ77YfTq5bRQ+bD8wT11JbeDPmxmGg==",
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": "^12.11.0"
|
||||
}
|
||||
},
|
||||
"node_modules/before-after-hook": {
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz",
|
||||
"integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ=="
|
||||
},
|
||||
"node_modules/data-uri-to-buffer": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz",
|
||||
"integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==",
|
||||
"engines": {
|
||||
"node": ">= 12"
|
||||
}
|
||||
},
|
||||
"node_modules/deprecation": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
|
||||
"integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ=="
|
||||
},
|
||||
"node_modules/fetch-blob": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz",
|
||||
"integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/jimmywarting"
|
||||
},
|
||||
{
|
||||
"type": "paypal",
|
||||
"url": "https://paypal.me/jimmywarting"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"node-domexception": "^1.0.0",
|
||||
"web-streams-polyfill": "^3.0.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.20 || >= 14.13"
|
||||
}
|
||||
},
|
||||
"node_modules/formdata-polyfill": {
|
||||
"version": "4.0.10",
|
||||
"resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz",
|
||||
"integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==",
|
||||
"dependencies": {
|
||||
"fetch-blob": "^3.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.20.0"
|
||||
}
|
||||
},
|
||||
"node_modules/hasha": {
|
||||
"version": "5.2.2",
|
||||
"resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz",
|
||||
"integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==",
|
||||
"dependencies": {
|
||||
"is-stream": "^2.0.0",
|
||||
"type-fest": "^0.8.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/is-plain-object": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
|
||||
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/is-stream": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
|
||||
"integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/node-domexception": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
|
||||
"integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/jimmywarting"
|
||||
},
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://paypal.me/jimmywarting"
|
||||
}
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=10.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/node-fetch": {
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz",
|
||||
"integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==",
|
||||
"dependencies": {
|
||||
"data-uri-to-buffer": "^4.0.0",
|
||||
"fetch-blob": "^3.1.4",
|
||||
"formdata-polyfill": "^4.0.10"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/node-fetch"
|
||||
}
|
||||
},
|
||||
"node_modules/once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
|
||||
"dependencies": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"node_modules/tr46": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
||||
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
|
||||
},
|
||||
"node_modules/tunnel": {
|
||||
"version": "0.0.6",
|
||||
"resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
|
||||
"integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==",
|
||||
"engines": {
|
||||
"node": ">=0.6.11 <=0.7.0 || >=0.7.3"
|
||||
}
|
||||
},
|
||||
"node_modules/type-fest": {
|
||||
"version": "0.8.1",
|
||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
|
||||
"integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/universal-user-agent": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz",
|
||||
"integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w=="
|
||||
},
|
||||
"node_modules/uuid": {
|
||||
"version": "8.3.2",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
|
||||
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
|
||||
"bin": {
|
||||
"uuid": "dist/bin/uuid"
|
||||
}
|
||||
},
|
||||
"node_modules/web-streams-polyfill": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz",
|
||||
"integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==",
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/webidl-conversions": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
|
||||
},
|
||||
"node_modules/whatwg-url": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
|
||||
"dependencies": {
|
||||
"tr46": "~0.0.3",
|
||||
"webidl-conversions": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "nym-hash-release",
|
||||
"version": "1.0.0",
|
||||
"description": "Generate hashes and signatures for assets in Nym releases",
|
||||
"main": "index.js",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"local": "node run-local.mjs"
|
||||
},
|
||||
"dependencies": {
|
||||
"@actions/core": "^1.10.0",
|
||||
"@actions/github": "^5.1.1",
|
||||
"@octokit/auth-action": "^4.0.0",
|
||||
"@octokit/rest": "^20.0.1",
|
||||
"hasha": "^5.2.0",
|
||||
"node-fetch": "^3.2.10"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
import {createHashesFromReleaseTagOrNameOrId} from './create-hashes.mjs';
|
||||
|
||||
await createHashesFromReleaseTagOrNameOrId({releaseTagOrNameOrId: 119065724, cache: true, upload: false});
|
||||
await createHashesFromReleaseTagOrNameOrId({releaseTagOrNameOrId: '119065724', cache: true, upload: false});
|
||||
await createHashesFromReleaseTagOrNameOrId({releaseTagOrNameOrId: 'nym-connect-v1.1.19-snickers', cache: true, upload: false});
|
||||
await createHashesFromReleaseTagOrNameOrId({releaseTagOrNameOrId: 'Nym Connect v1.1.19-snickers', cache: true, upload: false});
|
||||
@@ -38,6 +38,7 @@ jobs:
|
||||
- name: Build all projects in documentation/ & move to ~/dist/docs/
|
||||
run: cd documentation && ./build_all_to_dist.sh
|
||||
continue-on-error: false
|
||||
|
||||
- name: Deploy branch master to dev
|
||||
continue-on-error: true
|
||||
uses: easingthemes/ssh-deploy@main
|
||||
@@ -49,6 +50,7 @@ jobs:
|
||||
REMOTE_USER: ${{ secrets.CD_WWW_REMOTE_USER }}
|
||||
TARGET: ${{ secrets.CD_WWW_REMOTE_TARGET }}/
|
||||
EXCLUDE: "/node_modules/"
|
||||
|
||||
- name: Deploy branch master to prod
|
||||
if: github.ref == 'refs/heads/master'
|
||||
uses: easingthemes/ssh-deploy@main
|
||||
@@ -60,6 +62,44 @@ jobs:
|
||||
REMOTE_USER: ${{ secrets.CD_WWW_REMOTE_USER }}
|
||||
TARGET: ${{ secrets.CD_WWW_REMOTE_TARGET }}/
|
||||
EXCLUDE: "/node_modules/"
|
||||
|
||||
- name: Post process
|
||||
run: cd documentation && ./post_process.sh
|
||||
continue-on-error: false
|
||||
|
||||
- name: Create Vercel project file
|
||||
uses: mobiledevops/secret-to-file-action@v1
|
||||
with:
|
||||
base64-encoded-secret: ${{ secrets.VERCEL_PROJECT_JSON_BASE64 }}
|
||||
filename: "project.json"
|
||||
is-executable: true
|
||||
working-directory: "./dist/docs/.vercel"
|
||||
|
||||
- name: Install Vercel CLI
|
||||
run: npm install --global vercel@latest
|
||||
|
||||
- name: Pull Vercel Environment Information (preview)
|
||||
if: github.ref != 'refs/heads/master'
|
||||
run: vercel pull --yes --environment=preview --token=${{ secrets.VERCEL_TOKEN }}
|
||||
working-directory: dist/docs
|
||||
- name: Pull Vercel Environment Information (production)
|
||||
if: github.ref == 'refs/heads/master'
|
||||
run: vercel pull --yes --environment=production --token=${{ secrets.VERCEL_TOKEN }}
|
||||
working-directory: dist/docs
|
||||
|
||||
- name: Build Project Artifacts
|
||||
run: vercel build --token=${{ secrets.VERCEL_TOKEN }}
|
||||
working-directory: dist/docs
|
||||
|
||||
- name: Deploy Project Artifacts to Vercel (preview)
|
||||
if: github.ref != 'refs/heads/master'
|
||||
run: vercel deploy --prebuilt --token=${{ secrets.VERCEL_TOKEN }}
|
||||
working-directory: dist/docs
|
||||
- name: Deploy Project Artifacts to Vercel (master)
|
||||
if: github.ref == 'refs/heads/master'
|
||||
run: vercel deploy --prebuilt --prod --token=${{ secrets.VERCEL_TOKEN }}
|
||||
working-directory: dist/docs
|
||||
|
||||
- name: Matrix - Node Install
|
||||
run: npm install
|
||||
working-directory: .github/workflows/support-files
|
||||
|
||||
@@ -112,31 +112,11 @@ jobs:
|
||||
files: |
|
||||
nym-connect/desktop/target/release/bundle/dmg/*.dmg
|
||||
nym-connect/desktop/target/release/bundle/macos/*.app.tar.gz*
|
||||
- id: release-info
|
||||
name: Prepare release info
|
||||
run: |
|
||||
ref=${{ github.ref_name }}
|
||||
semver="${ref##nym-connect-}" && semver="${semver##v}"
|
||||
echo "version=${semver}" >> "$GITHUB_OUTPUT"
|
||||
echo "filename=nym-connect_${semver}_x64.dmg " >> "$GITHUB_OUTPUT"
|
||||
echo "file_hash=${{ hashFiles('nym-connect/desktop/target/release/bundle/dmg/nym-connect_*_x64.dmg') }}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
push-release-data:
|
||||
if: ${{ (startsWith(github.ref, 'refs/tags/nym-connect-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
|
||||
uses: ./.github/workflows/push-release-data.yml
|
||||
uses: ./.github/workflows/release-calculate-hash.yml
|
||||
needs: publish-tauri
|
||||
with:
|
||||
release_tag: ${{ github.ref_name }}
|
||||
release_id: ${{ needs.publish-tauri.outputs.release_id }}
|
||||
release_date: ${{ needs.publish-tauri.outputs.release_date }}
|
||||
download_base_url: https://github.com/nymtech/nym/releases/download/${{ github.ref_name }}
|
||||
changelog_url: https://github.com/nymtech/nym/blob/${{ github.ref_name }}/nym-connect/desktop/CHANGELOG.md
|
||||
archive_url: https://github.com/nymtech/nym/releases/download/${{ github.ref_name }}/nym-connect.app.tar.gz
|
||||
sig_url: https://github.com/nymtech/nym/releases/download/${{ github.ref_name }}/nym-connect.app.tar.gz.sig
|
||||
version: ${{ needs.publish-tauri.outputs.version }}
|
||||
filename: ${{ needs.publish-tauri.outputs.filename }}
|
||||
file_hash: ${{ needs.publish-tauri.outputs.file_hash }}
|
||||
name: NymConnect
|
||||
category: connect
|
||||
platform: MacOS
|
||||
secrets: inherit
|
||||
|
||||
@@ -79,31 +79,11 @@ jobs:
|
||||
files: |
|
||||
nym-connect/desktop/target/release/bundle/appimage/*.AppImage
|
||||
nym-connect/desktop/target/release/bundle/appimage/*.AppImage.tar.gz*
|
||||
- id: release-info
|
||||
name: Prepare release info
|
||||
run: |
|
||||
ref=${{ github.ref_name }}
|
||||
semver="${ref##nym-connect-}" && semver="${semver##v}"
|
||||
echo "version=${semver}" >> "$GITHUB_OUTPUT"
|
||||
echo "filename=nym-connect_${semver}_amd64.AppImage" >> "$GITHUB_OUTPUT"
|
||||
echo "file_hash=${{ hashFiles('nym-connect/desktop/target/release/bundle/appimage/nym-connect_*_amd64.AppImage') }}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
push-release-data:
|
||||
if: ${{ (startsWith(github.ref, 'refs/tags/nym-connect-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
|
||||
uses: ./.github/workflows/push-release-data.yml
|
||||
uses: ./.github/workflows/release-calculate-hash.yml
|
||||
needs: publish-tauri
|
||||
with:
|
||||
release_tag: ${{ github.ref_name }}
|
||||
release_id: ${{ needs.publish-tauri.outputs.release_id }}
|
||||
release_date: ${{ needs.publish-tauri.outputs.release_date }}
|
||||
download_base_url: https://github.com/nymtech/nym/releases/download/${{ github.ref_name }}
|
||||
changelog_url: https://github.com/nymtech/nym/blob/${{ github.ref_name }}/nym-connect/desktop/CHANGELOG.md
|
||||
archive_url: https://github.com/nymtech/nym/releases/download/${{ github.ref_name }}/nym-connect_${{ needs.publish-tauri.outputs.version }}_amd64.AppImage.tar.gz
|
||||
sig_url: https://github.com/nymtech/nym/releases/download/${{ github.ref_name }}/nym-connect_${{ needs.publish-tauri.outputs.version }}_amd64.AppImage.tar.gz.sig
|
||||
version: ${{ needs.publish-tauri.outputs.version }}
|
||||
filename: ${{ needs.publish-tauri.outputs.filename }}
|
||||
file_hash: ${{ needs.publish-tauri.outputs.file_hash }}
|
||||
name: NymConnect
|
||||
category: connect
|
||||
platform: Ubuntu
|
||||
secrets: inherit
|
||||
|
||||
@@ -98,32 +98,11 @@ jobs:
|
||||
files: |
|
||||
nym-connect/desktop/target/release/bundle/msi/*.msi
|
||||
nym-connect/desktop/target/release/bundle/msi/*.msi.zip*
|
||||
- id: release-info
|
||||
name: Prepare release info
|
||||
shell: bash
|
||||
run: |
|
||||
ref=${{ github.ref_name }}
|
||||
semver="${ref##nym-connect-}" && semver="${semver##v}"
|
||||
echo "version=${semver}" >> "$GITHUB_OUTPUT"
|
||||
echo "filename=nym-connect_${semver}_x64_en-US.msi" >> "$GITHUB_OUTPUT"
|
||||
echo "file_hash=${{ hashFiles('nym-connect/desktop/target/release/bundle/msi/nym-connect_*_x64_en-US.msi') }}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
push-release-data:
|
||||
if: ${{ (startsWith(github.ref, 'refs/tags/nym-connect-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
|
||||
uses: ./.github/workflows/push-release-data.yml
|
||||
uses: ./.github/workflows/release-calculate-hash.yml
|
||||
needs: publish-tauri
|
||||
with:
|
||||
release_tag: ${{ github.ref_name }}
|
||||
release_id: ${{ needs.publish-tauri.outputs.release_id }}
|
||||
release_date: ${{ needs.publish-tauri.outputs.release_date }}
|
||||
download_base_url: https://github.com/nymtech/nym/releases/download/${{ github.ref_name }}
|
||||
changelog_url: https://github.com/nymtech/nym/blob/${{ github.ref_name }}/nym-connect/desktop/CHANGELOG.md
|
||||
archive_url: https://github.com/nymtech/nym/releases/download/${{ github.ref_name }}/nym-connect_${{ needs.publish-tauri.outputs.version }}_x64_en-US.msi.zip
|
||||
sig_url: https://github.com/nymtech/nym/releases/download/${{ github.ref_name }}/nym-connect_${{ needs.publish-tauri.outputs.version }}_x64_en-US.msi.zip.sig
|
||||
version: ${{ needs.publish-tauri.outputs.version }}
|
||||
filename: ${{ needs.publish-tauri.outputs.filename }}
|
||||
file_hash: ${{ needs.publish-tauri.outputs.file_hash }}
|
||||
name: NymConnect
|
||||
category: connect
|
||||
platform: Windows
|
||||
secrets: inherit
|
||||
|
||||
@@ -96,149 +96,10 @@ jobs:
|
||||
target/release/nym-network-statistics
|
||||
target/release/nym-cli
|
||||
|
||||
- id: release-info
|
||||
name: Prepare release info
|
||||
run: |
|
||||
semver="${${{ github.ref_name }}##nym-binaries-}" && semver="${semver##v}"
|
||||
echo "version=$semver" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- id: binary-hashes
|
||||
name: Generate binary hashes
|
||||
run: |
|
||||
echo "client_hash=${{ hashFiles('target/release/nym-client') }}" >> "$GITHUB_OUTPUT"
|
||||
echo "mixnode_hash=${{ hashFiles('target/release/nym-mixnode') }}" >> "$GITHUB_OUTPUT"
|
||||
echo "gateway_hash=${{ hashFiles('target/release/nym-gateway') }}" >> "$GITHUB_OUTPUT"
|
||||
echo "socks5_hash=${{ hashFiles('target/release/nym-socks5-client') }}" >> "$GITHUB_OUTPUT"
|
||||
echo "netreq_hash=${{ hashFiles('target/release/nym-network-requester') }}" >> "$GITHUB_OUTPUT"
|
||||
echo "cli_hash=${{ hashFiles('target/release/nym-cli') }}" >> "$GITHUB_OUTPUT"
|
||||
echo "netstat_hash=${{ hashFiles('target/release/nym-network-statistics') }}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- id: binary-versions
|
||||
name: Get binary versions
|
||||
run: |
|
||||
v=$(rg '^version = "(.*)"' -or '$1' clients/native/Cargo.toml) && echo "client_version=$v" >> "$GITHUB_OUTPUT"
|
||||
v=$(rg '^version = "(.*)"' -or '$1' mixnode/Cargo.toml) && echo "mixnode_version=$v" >> "$GITHUB_OUTPUT"
|
||||
v=$(rg '^version = "(.*)"' -or '$1' gateway/Cargo.toml) && echo "gateway_version=$v" >> "$GITHUB_OUTPUT"
|
||||
v=$(rg '^version = "(.*)"' -or '$1' clients/socks5/Cargo.toml) && echo "socks5_version=$v" >> "$GITHUB_OUTPUT"
|
||||
v=$(rg '^version = "(.*)"' -or '$1' service-providers/network-requester/Cargo.toml) && echo "netreq_version=$v" >> "$GITHUB_OUTPUT"
|
||||
v=$(rg '^version = "(.*)"' -or '$1' tools/nym-cli/Cargo.toml) && echo "cli_version=$v" >> "$GITHUB_OUTPUT"
|
||||
v=$(rg '^version = "(.*)"' -or '$1' service-providers/network-statistics/Cargo.toml) && echo "netstat_version=$v" >> "$GITHUB_OUTPUT"
|
||||
|
||||
push-release-data-client:
|
||||
if: ${{ (startsWith(github.ref, 'refs/tags/nym-binaries-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
|
||||
uses: ./.github/workflows/push-release-data.yml
|
||||
uses: ./.github/workflows/release-calculate-hash.yml
|
||||
needs: publish-nym
|
||||
with:
|
||||
release_tag: ${{ github.ref_name }}
|
||||
release_id: ${{ needs.publish-nym.outputs.release_id }}
|
||||
release_date: ${{ needs.publish-nym.outputs.release_date }}
|
||||
download_base_url: https://github.com/nymtech/nym/releases/download/${{ github.ref_name }}
|
||||
changelog_url: https://github.com/nymtech/nym/blob/${{ github.ref_name }}/CHANGELOG.md
|
||||
version: ${{ needs.publish-nym.outputs.client_version }}
|
||||
filename: nym-client
|
||||
file_hash: ${{ needs.publish-nym.outputs.client_hash }}
|
||||
name: Client
|
||||
category: binaries
|
||||
secrets: inherit
|
||||
|
||||
push-release-data-mixnode:
|
||||
if: ${{ (startsWith(github.ref, 'refs/tags/nym-binaries-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
|
||||
uses: ./.github/workflows/push-release-data.yml
|
||||
needs: publish-nym
|
||||
with:
|
||||
release_tag: ${{ github.ref_name }}
|
||||
release_id: ${{ needs.publish-nym.outputs.release_id }}
|
||||
release_date: ${{ needs.publish-nym.outputs.release_date }}
|
||||
download_base_url: https://github.com/nymtech/nym/releases/download/${{ github.ref_name }}
|
||||
changelog_url: https://github.com/nymtech/nym/blob/${{ github.ref_name }}/CHANGELOG.md
|
||||
version: ${{ needs.publish-nym.outputs.mixnode_version }}
|
||||
filename: nym-mixnode
|
||||
file_hash: ${{ needs.publish-nym.outputs.mixnode_hash }}
|
||||
name: Mixnode
|
||||
category: binaries
|
||||
secrets: inherit
|
||||
|
||||
push-release-data-gateway:
|
||||
if: ${{ (startsWith(github.ref, 'refs/tags/nym-binaries-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
|
||||
uses: ./.github/workflows/push-release-data.yml
|
||||
needs: publish-nym
|
||||
with:
|
||||
release_tag: ${{ github.ref_name }}
|
||||
release_id: ${{ needs.publish-nym.outputs.release_id }}
|
||||
release_date: ${{ needs.publish-nym.outputs.release_date }}
|
||||
download_base_url: https://github.com/nymtech/nym/releases/download/${{ github.ref_name }}
|
||||
changelog_url: https://github.com/nymtech/nym/blob/${{ github.ref_name }}/CHANGELOG.md
|
||||
version: ${{ needs.publish-nym.outputs.gateway_version }}
|
||||
filename: nym-gateway
|
||||
file_hash: ${{ needs.publish-nym.outputs.gateway_hash }}
|
||||
name: Gateway
|
||||
category: binaries
|
||||
secrets: inherit
|
||||
|
||||
push-release-data-socks5:
|
||||
if: ${{ (startsWith(github.ref, 'refs/tags/nym-binaries-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
|
||||
uses: ./.github/workflows/push-release-data.yml
|
||||
needs: publish-nym
|
||||
with:
|
||||
release_tag: ${{ github.ref_name }}
|
||||
release_id: ${{ needs.publish-nym.outputs.release_id }}
|
||||
release_date: ${{ needs.publish-nym.outputs.release_date }}
|
||||
download_base_url: https://github.com/nymtech/nym/releases/download/${{ github.ref_name }}
|
||||
changelog_url: https://github.com/nymtech/nym/blob/${{ github.ref_name }}/CHANGELOG.md
|
||||
version: ${{ needs.publish-nym.outputs.socks5_version }}
|
||||
filename: nym-socks5-client
|
||||
file_hash: ${{ needs.publish-nym.outputs.socks5_hash }}
|
||||
name: Socks5 Client
|
||||
category: binaries
|
||||
secrets: inherit
|
||||
|
||||
push-release-data-network-requester:
|
||||
if: ${{ (startsWith(github.ref, 'refs/tags/nym-binaries-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
|
||||
uses: ./.github/workflows/push-release-data.yml
|
||||
needs: publish-nym
|
||||
with:
|
||||
release_tag: ${{ github.ref_name }}
|
||||
release_id: ${{ needs.publish-nym.outputs.release_id }}
|
||||
release_date: ${{ needs.publish-nym.outputs.release_date }}
|
||||
download_base_url: https://github.com/nymtech/nym/releases/download/${{ github.ref_name }}
|
||||
changelog_url: https://github.com/nymtech/nym/blob/${{ github.ref_name }}/CHANGELOG.md
|
||||
version: ${{ needs.publish-nym.outputs.netreq_version }}
|
||||
filename: nym-network-requester
|
||||
file_hash: ${{ needs.publish-nym.outputs.netreq_hash }}
|
||||
name: Network Requester
|
||||
category: binaries
|
||||
secrets: inherit
|
||||
|
||||
push-release-data-cli:
|
||||
if: ${{ (startsWith(github.ref, 'refs/tags/nym-binaries-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
|
||||
uses: ./.github/workflows/push-release-data.yml
|
||||
needs: publish-nym
|
||||
with:
|
||||
release_tag: ${{ github.ref_name }}
|
||||
release_id: ${{ needs.publish-nym.outputs.release_id }}
|
||||
release_date: ${{ needs.publish-nym.outputs.release_date }}
|
||||
download_base_url: https://github.com/nymtech/nym/releases/download/${{ github.ref_name }}
|
||||
changelog_url: https://github.com/nymtech/nym/blob/${{ github.ref_name }}/CHANGELOG.md
|
||||
version: ${{ needs.publish-nym.outputs.cli_version }}
|
||||
filename: nym-cli
|
||||
file_hash: ${{ needs.publish-nym.outputs.cli_hash }}
|
||||
name: Cli
|
||||
category: binaries
|
||||
secrets: inherit
|
||||
|
||||
push-release-data-network-stat:
|
||||
if: ${{ (startsWith(github.ref, 'refs/tags/nym-binaries-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
|
||||
uses: ./.github/workflows/push-release-data.yml
|
||||
needs: publish-nym
|
||||
with:
|
||||
release_tag: ${{ github.ref_name }}
|
||||
release_id: ${{ needs.publish-nym.outputs.release_id }}
|
||||
release_date: ${{ needs.publish-nym.outputs.release_date }}
|
||||
download_base_url: https://github.com/nymtech/nym/releases/download/${{ github.ref_name }}
|
||||
changelog_url: https://github.com/nymtech/nym/blob/${{ github.ref_name }}/CHANGELOG.md
|
||||
version: ${{ needs.publish-nym.outputs.netstat_version }}
|
||||
filename: nym-network-statistics
|
||||
file_hash: ${{ needs.publish-nym.outputs.netstat_hash }}
|
||||
name: Network Statistics
|
||||
category: binaries
|
||||
secrets: inherit
|
||||
|
||||
@@ -100,31 +100,10 @@ jobs:
|
||||
nym-wallet/target/release/bundle/dmg/*.dmg
|
||||
nym-wallet/target/release/bundle/macos/*.app.tar.gz*
|
||||
|
||||
- id: release-info
|
||||
name: Prepare release info
|
||||
run: |
|
||||
ref=${{ github.ref_name }}
|
||||
semver="${ref##nym-wallet-}" && semver="${semver##v}"
|
||||
echo "version=${semver}" >> "$GITHUB_OUTPUT"
|
||||
echo "filename=nym-wallet_${semver}_x64.dmg" >> "$GITHUB_OUTPUT"
|
||||
echo "file_hash=${{ hashFiles('nym-wallet/target/release/bundle/dmg/nym-wallet_*_x64.dmg') }}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
push-release-data:
|
||||
if: ${{ (startsWith(github.ref, 'refs/tags/nym-wallet-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
|
||||
uses: ./.github/workflows/push-release-data.yml
|
||||
uses: ./.github/workflows/release-calculate-hash.yml
|
||||
needs: publish-tauri
|
||||
with:
|
||||
release_tag: ${{ github.ref_name }}
|
||||
release_id: ${{ needs.publish-tauri.outputs.release_id }}
|
||||
release_date: ${{ needs.publish-tauri.outputs.release_date }}
|
||||
download_base_url: https://github.com/nymtech/nym/releases/download/${{ github.ref_name }}
|
||||
changelog_url: https://github.com/nymtech/nym/blob/${{ github.ref_name }}/nym-wallet/CHANGELOG.md
|
||||
archive_url: https://github.com/nymtech/nym/releases/download/${{ github.ref_name }}/nym-wallet.app.tar.gz
|
||||
sig_url: https://github.com/nymtech/nym/releases/download/${{ github.ref_name }}/nym-wallet.app.tar.gz.sig
|
||||
version: ${{ needs.publish-tauri.outputs.version }}
|
||||
filename: ${{ needs.publish-tauri.outputs.filename }}
|
||||
file_hash: ${{ needs.publish-tauri.outputs.file_hash }}
|
||||
name: Wallet
|
||||
category: wallet
|
||||
platform: MacOS
|
||||
secrets: inherit
|
||||
|
||||
@@ -77,31 +77,10 @@ jobs:
|
||||
nym-wallet/target/release/bundle/appimage/*.AppImage
|
||||
nym-wallet/target/release/bundle/appimage/*.AppImage.tar.gz*
|
||||
|
||||
- id: release-info
|
||||
name: Prepare release info
|
||||
run: |
|
||||
ref=${{ github.ref_name }}
|
||||
semver="${ref##nym-wallet-}" && semver="${semver##v}"
|
||||
echo "version=${semver}" >> "$GITHUB_OUTPUT"
|
||||
echo "filename=nym-wallet_${semver}_amd64.AppImage" >> "$GITHUB_OUTPUT"
|
||||
echo "file_hash=${{ hashFiles('nym-wallet/target/release/bundle/appimage/nym-wallet_*_amd64.AppImage') }}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
push-release-data:
|
||||
if: ${{ (startsWith(github.ref, 'refs/tags/nym-wallet-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
|
||||
uses: ./.github/workflows/push-release-data.yml
|
||||
uses: ./.github/workflows/release-calculate-hash.yml
|
||||
needs: publish-tauri
|
||||
with:
|
||||
release_tag: ${{ github.ref_name }}
|
||||
release_id: ${{ needs.publish-tauri.outputs.release_id }}
|
||||
release_date: ${{ needs.publish-tauri.outputs.release_date }}
|
||||
download_base_url: https://github.com/nymtech/nym/releases/download/${{ github.ref_name }}
|
||||
changelog_url: https://github.com/nymtech/nym/blob/${{ github.ref_name }}/nym-wallet/CHANGELOG.md
|
||||
archive_url: https://github.com/nymtech/nym/releases/download/${{ github.ref_name }}/nym-wallet_${{ needs.publish-tauri.outputs.version }}_amd64.AppImage.tar.gz
|
||||
sig_url: https://github.com/nymtech/nym/releases/download/${{ github.ref_name }}/nym-wallet_${{ needs.publish-tauri.outputs.version }}_amd64.AppImage.tar.gz.sig
|
||||
version: ${{ needs.publish-tauri.outputs.version }}
|
||||
filename: ${{ needs.publish-tauri.outputs.filename }}
|
||||
file_hash: ${{ needs.publish-tauri.outputs.file_hash }}
|
||||
name: Wallet
|
||||
category: wallet
|
||||
platform: Ubuntu
|
||||
secrets: inherit
|
||||
|
||||
@@ -97,31 +97,10 @@ jobs:
|
||||
nym-wallet/target/release/bundle/msi/*.msi
|
||||
nym-wallet/target/release/bundle/msi/*.msi.zip*
|
||||
|
||||
- id: release-info
|
||||
name: Prepare release info
|
||||
run: |
|
||||
ref=${{ github.ref_name }}
|
||||
semver="${ref##nym-wallet-}" && semver="${semver##v}"
|
||||
echo "version=${semver}" >> "$GITHUB_OUTPUT"
|
||||
echo "filename=nym-wallet_${semver}_x64_en-US.msi" >> "$GITHUB_OUTPUT"
|
||||
echo "file_hash=${{ hashFiles('nym-wallet/target/release/bundle/msi/nym-wallet_*_x64_en-US.msi') }}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
push-release-data:
|
||||
if: ${{ (startsWith(github.ref, 'refs/tags/nym-wallet-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
|
||||
uses: ./.github/workflows/push-release-data.yml
|
||||
uses: ./.github/workflows/release-calculate-hash.yml
|
||||
needs: publish-tauri
|
||||
with:
|
||||
release_tag: ${{ github.ref_name }}
|
||||
release_id: ${{ needs.publish-tauri.outputs.release_id }}
|
||||
release_date: ${{ needs.publish-tauri.outputs.release_date }}
|
||||
download_base_url: https://github.com/nymtech/nym/releases/download/${{ github.ref_name }}
|
||||
changelog_url: https://github.com/nymtech/nym/blob/${{ github.ref_name }}/nym-wallet/CHANGELOG.md
|
||||
archive_url: https://github.com/nymtech/nym/releases/download/${{ github.ref_name }}/nym-wallet_${{ needs.publish-tauri.outputs.version }}_x64_en-US.msi.zip
|
||||
sig_url: https://github.com/nymtech/nym/releases/download/${{ github.ref_name }}/nym-wallet_${{ needs.publish-tauri.outputs.version }}_x64_en-US.msi.zip.sig
|
||||
version: ${{ needs.publish-tauri.outputs.version }}
|
||||
filename: ${{ needs.publish-tauri.outputs.filename }}
|
||||
file_hash: ${{ needs.publish-tauri.outputs.file_hash }}
|
||||
name: Wallet
|
||||
category: wallet
|
||||
platform: Windows
|
||||
secrets: inherit
|
||||
|
||||
@@ -1,212 +0,0 @@
|
||||
name: Push release data
|
||||
|
||||
env:
|
||||
strapi_download_url: 'https://strapi.feat-nym-update-nym-web.websites.dev.nymte.ch/api/downloaders'
|
||||
strapi_updater_url: 'https://strapi.feat-nym-update-nym-web.websites.dev.nymte.ch/api/updaters'
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
release_tag:
|
||||
required: true
|
||||
description: Release tag
|
||||
type: string
|
||||
release_id:
|
||||
required: true
|
||||
description: Release ID
|
||||
type: string
|
||||
release_date:
|
||||
required: true
|
||||
description: Release date
|
||||
type: string
|
||||
download_base_url:
|
||||
required: true
|
||||
description: Download base URL
|
||||
type: string
|
||||
changelog_url:
|
||||
required: true
|
||||
description: Changelog URL
|
||||
type: string
|
||||
archive_url:
|
||||
required: false
|
||||
description: Binary archive URL
|
||||
type: string
|
||||
sig_url:
|
||||
required: false
|
||||
description: Archive signature URL
|
||||
type: string
|
||||
version:
|
||||
required: true
|
||||
description: Release version (semver)
|
||||
type: string
|
||||
filename:
|
||||
required: true
|
||||
description: Binary file name
|
||||
type: string
|
||||
file_hash:
|
||||
required: true
|
||||
description: Binary hash (sha256)
|
||||
type: string
|
||||
name:
|
||||
required: true
|
||||
description: Name
|
||||
type: string
|
||||
category:
|
||||
required: true
|
||||
description: Category
|
||||
type: string
|
||||
platform:
|
||||
required: false
|
||||
description: Platform
|
||||
type: string
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
# ⚠ since inputs are limited to 10 max for workflow_dispatch
|
||||
# some properties were omitted
|
||||
version:
|
||||
required: true
|
||||
description: Release version (semver)
|
||||
type: string
|
||||
default: '1.0.0'
|
||||
release_id:
|
||||
required: true
|
||||
description: Release ID
|
||||
type: string
|
||||
default: '1234'
|
||||
release_date:
|
||||
required: true
|
||||
description: Release date
|
||||
type: string
|
||||
default: '2023-06-26T10:09:16Z'
|
||||
download_base_url:
|
||||
required: true
|
||||
description: Download base URL
|
||||
type: string
|
||||
default: 'https://github.com/nymtech/nym/releases/download/nym-wallet-v1.0.0'
|
||||
changelog_url:
|
||||
required: true
|
||||
description: Changelog URL
|
||||
type: string
|
||||
default: 'https://github.com/nymtech/nym/blob/nym-wallet-v1.0.0/nym-wallet/CHANGELOG.md'
|
||||
filename:
|
||||
required: true
|
||||
description: Binary file name
|
||||
type: string
|
||||
default: 'nym-wallet_1.0.0_amd64.AppImage'
|
||||
file_hash:
|
||||
required: true
|
||||
description: Binary hash (sha256)
|
||||
type: string
|
||||
default: 'xxx'
|
||||
name:
|
||||
required: true
|
||||
description: Name
|
||||
type: string
|
||||
default: 'Wallet'
|
||||
category:
|
||||
required: true
|
||||
description: Category
|
||||
default: 'wallet'
|
||||
type: choice
|
||||
options:
|
||||
- wallet
|
||||
- connect
|
||||
- binaries
|
||||
platform:
|
||||
required: false
|
||||
description: Platform
|
||||
default: 'Ubuntu'
|
||||
type: choice
|
||||
options:
|
||||
- Ubuntu
|
||||
- Windows
|
||||
- MacOS
|
||||
|
||||
jobs:
|
||||
push-download-data:
|
||||
name: Push download data to Strapi
|
||||
runs-on: custom-runner-linux
|
||||
|
||||
steps:
|
||||
- name: Release info
|
||||
run: |
|
||||
echo "version: ${{ inputs.version }}"
|
||||
echo "tag: ${{ inputs.release_tag }}"
|
||||
|
||||
- id: get_sig
|
||||
name: Get sig
|
||||
if: ${{ inputs.sig_url != null }}
|
||||
run: |
|
||||
output=$(curl -LsSf ${{ inputs.sig_url }})
|
||||
echo "sig=$output" >> "$GITHUB_OUTPUT"
|
||||
- id: strapi-request
|
||||
name: Strapi request
|
||||
uses: fjogeleit/http-request-action@v1
|
||||
with:
|
||||
url: ${{ env.strapi_download_url }}
|
||||
method: 'POST'
|
||||
bearerToken: ${{ secrets.STRAPI_API_TOKEN_RELEASES }}
|
||||
customHeaders: '{"Content-Type": "application/json"}'
|
||||
data: |
|
||||
{
|
||||
"data": {
|
||||
"releaseId": "${{ inputs.release_id }}",
|
||||
"releaseDate": "${{ inputs.release_date }}",
|
||||
"downloadBaseUrl": "${{ inputs.download_base_url }}",
|
||||
"changelogUrl": "${{ inputs.changelog_url }}",
|
||||
"version": "${{ inputs.version }}",
|
||||
"filename": "${{ inputs.filename }}",
|
||||
"name": "${{ inputs.name }}",
|
||||
"category": "${{ inputs.category }}",
|
||||
"platform": "${{ inputs.platform }}",
|
||||
"sha256": "${{ inputs.file_hash }}",
|
||||
"sig": "${{ steps.get_sig.outputs.sig }}"
|
||||
}
|
||||
}
|
||||
- name: Strapi Response
|
||||
run: |
|
||||
echo ${{ steps.strapi-request.outputs.response }}
|
||||
|
||||
push-update-data:
|
||||
name: Push update data to Strapi
|
||||
runs-on: custom-runner-linux
|
||||
# only push update data for tauri apps (desktop wallet and NC)
|
||||
if: ${{ inputs.category == 'wallet' || inputs.category == 'connect' }}
|
||||
|
||||
steps:
|
||||
- name: Release info
|
||||
run: |
|
||||
echo "version: ${{ inputs.version }}"
|
||||
echo "tag: ${{ inputs.release_tag }}"
|
||||
- id: get_sig
|
||||
name: Get sig
|
||||
if: ${{ inputs.sig_url != null }}
|
||||
run: |
|
||||
output=$(curl -LsSf ${{ inputs.sig_url }})
|
||||
echo "sig=$output" >> "$GITHUB_OUTPUT"
|
||||
- id: strapi-request
|
||||
name: Strapi request
|
||||
uses: fjogeleit/http-request-action@v1
|
||||
with:
|
||||
url: ${{ env.strapi_updater_url }}
|
||||
method: 'POST'
|
||||
bearerToken: ${{ secrets.STRAPI_API_TOKEN_RELEASES }}
|
||||
customHeaders: '{"Content-Type": "application/json"}'
|
||||
data: |
|
||||
{
|
||||
"data": {
|
||||
"releaseId": "${{ inputs.release_id }}",
|
||||
"releaseDate": "${{ inputs.release_date }}",
|
||||
"downloadUrl": "${{ inputs.archive_url }}",
|
||||
"changelog": "See ${{ inputs.changelog_url }} for the changelog",
|
||||
"version": "${{ inputs.version }}",
|
||||
"filename": "${{ inputs.filename }}",
|
||||
"category": "${{ inputs.category }}",
|
||||
"platform": "${{ inputs.platform }}",
|
||||
"sha256": "${{ inputs.file_hash }}",
|
||||
"sig": "${{ steps.get_sig.outputs.sig }}"
|
||||
}
|
||||
}
|
||||
- name: Strapi Response
|
||||
run: |
|
||||
echo ${{ steps.strapi-request.outputs.response }}
|
||||
@@ -1,18 +1,39 @@
|
||||
name: Releases - calculate file hashes
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
release_tag:
|
||||
description: 'Release tag'
|
||||
required: true
|
||||
type: string
|
||||
workflow_dispatch:
|
||||
release_tag:
|
||||
tag:
|
||||
description: 'Release tag'
|
||||
required: true
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Calculate hash
|
||||
runs-on: custom-runner-linux
|
||||
name: Calculate hash for assets in release
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: MCJack123/ghaction-generate-release-hashes@v3
|
||||
- name: Check out repository code
|
||||
uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
hash-type: sha256
|
||||
file-name: hashes.txt
|
||||
node-version: 18
|
||||
- name: Install packages
|
||||
run: cd ./.github/actions/nym-hash-releases && npm i
|
||||
|
||||
- uses: ./.github/actions/nym-hash-releases
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
release-tag-or-name-or-id: ${{ inputs.release_tag }}
|
||||
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: Asset Hashes
|
||||
path: hashes.txt
|
||||
path: hashes.json
|
||||
|
||||
@@ -4,6 +4,20 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [v1.1.30-twix] (2023-09-05)
|
||||
|
||||
- geo_aware_provider: fix too much filtering of gateways ([#3826])
|
||||
- network-requester: add description to config ([#3799])
|
||||
- Speedy mode - selects gateway based on latency in medium / speedy mode ([#3770])
|
||||
- Chore/enable versioning ([#3768])
|
||||
- Create explorer-client and use in geo aware provider ([#3824])
|
||||
|
||||
[#3826]: https://github.com/nymtech/nym/pull/3826
|
||||
[#3799]: https://github.com/nymtech/nym/pull/3799
|
||||
[#3770]: https://github.com/nymtech/nym/issues/3770
|
||||
[#3768]: https://github.com/nymtech/nym/pull/3768
|
||||
[#3824]: https://github.com/nymtech/nym/pull/3824
|
||||
|
||||
## [v1.1.29-snickers] (2023-08-29)
|
||||
|
||||
- Add EXPLORER_API configurable url ([#3810])
|
||||
|
||||
Generated
+9
-41
@@ -2768,7 +2768,7 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
|
||||
|
||||
[[package]]
|
||||
name = "explorer-api"
|
||||
version = "1.1.27"
|
||||
version = "1.1.28"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"clap 4.3.21",
|
||||
@@ -5638,7 +5638,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-api"
|
||||
version = "1.1.28"
|
||||
version = "1.1.29"
|
||||
dependencies = [
|
||||
"actix-web",
|
||||
"anyhow",
|
||||
@@ -5785,7 +5785,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-cli"
|
||||
version = "1.1.27"
|
||||
version = "1.1.28"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"base64 0.13.1",
|
||||
@@ -5858,7 +5858,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-client"
|
||||
version = "1.1.27"
|
||||
version = "1.1.28"
|
||||
dependencies = [
|
||||
"clap 4.3.21",
|
||||
"dirs 4.0.0",
|
||||
@@ -6166,7 +6166,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-gateway"
|
||||
version = "1.1.27"
|
||||
version = "1.1.28"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@@ -6321,7 +6321,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-mixnode"
|
||||
version = "1.1.28"
|
||||
version = "1.1.29"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bs58 0.4.0",
|
||||
@@ -6439,7 +6439,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-network-requester"
|
||||
version = "1.1.27"
|
||||
version = "1.1.28"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-file-watcher",
|
||||
@@ -6486,7 +6486,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-network-statistics"
|
||||
version = "1.1.27"
|
||||
version = "1.1.28"
|
||||
dependencies = [
|
||||
"dirs 4.0.0",
|
||||
"log",
|
||||
@@ -6573,38 +6573,6 @@ dependencies = [
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nym-payment-manager"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bip39",
|
||||
"clap 4.3.21",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"nym-bin-common",
|
||||
"nym-network-defaults",
|
||||
"nym-payment-manager-common",
|
||||
"nym-task",
|
||||
"nym-validator-client",
|
||||
"rocket",
|
||||
"rocket_cors",
|
||||
"rocket_okapi",
|
||||
"schemars",
|
||||
"serde",
|
||||
"sqlx 0.6.3",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nym-payment-manager-common"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"schemars",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nym-pemstore"
|
||||
version = "0.3.0"
|
||||
@@ -6683,7 +6651,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-socks5-client"
|
||||
version = "1.1.27"
|
||||
version = "1.1.28"
|
||||
dependencies = [
|
||||
"clap 4.3.21",
|
||||
"lazy_static",
|
||||
|
||||
@@ -64,7 +64,6 @@ members = [
|
||||
"common/nymsphinx/params",
|
||||
"common/nymsphinx/routing",
|
||||
"common/nymsphinx/types",
|
||||
"common/payment-manager",
|
||||
"common/pemstore",
|
||||
"common/socks5-client-core",
|
||||
"common/socks5/proxy-helpers",
|
||||
@@ -89,7 +88,6 @@ members = [
|
||||
"service-providers/network-statistics",
|
||||
"nym-api",
|
||||
"nym-api/nym-api-requests",
|
||||
"nym-connect/payment-manager",
|
||||
"nym-outfox",
|
||||
"tools/nym-cli",
|
||||
"tools/nym-nr-query",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "nym-client"
|
||||
version = "1.1.27"
|
||||
version = "1.1.28"
|
||||
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jędrzej Stuczyński <andrew@nymtech.net>"]
|
||||
description = "Implementation of the Nym Client"
|
||||
edition = "2021"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "nym-socks5-client"
|
||||
version = "1.1.27"
|
||||
version = "1.1.28"
|
||||
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>"]
|
||||
description = "A SOCKS5 localhost proxy that converts incoming messages to Sphinx and sends them to a Nym address"
|
||||
edition = "2021"
|
||||
|
||||
@@ -224,6 +224,6 @@ impl RealMessagesController<OsRng> {
|
||||
debug!("The reply controller has finished execution!");
|
||||
});
|
||||
|
||||
ack_control.start_with_shutdown(shutdown, packet_type);
|
||||
// ack_control.start_with_shutdown(shutdown, packet_type);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,12 +102,12 @@ impl PacketRouter {
|
||||
}
|
||||
}
|
||||
|
||||
if !received_acks.is_empty() {
|
||||
trace!("routing acks");
|
||||
if let Err(err) = self.ack_sender.unbounded_send(received_acks) {
|
||||
error!("failed to send ack: {err}");
|
||||
};
|
||||
}
|
||||
// if !received_acks.is_empty() {
|
||||
// trace!("routing acks");
|
||||
// if let Err(err) = self.ack_sender.unbounded_send(received_acks) {
|
||||
// error!("failed to send ack: {err}");
|
||||
// };
|
||||
// }
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,15 +14,15 @@ use std::path::PathBuf;
|
||||
pub struct Args {
|
||||
/// Config file of the client that is supposed to use the credential.
|
||||
#[clap(long)]
|
||||
pub client_config: PathBuf,
|
||||
pub(crate) client_config: PathBuf,
|
||||
|
||||
/// The amount of utokens the credential will hold.
|
||||
#[clap(long, default_value = "0")]
|
||||
pub amount: u64,
|
||||
pub(crate) amount: u64,
|
||||
|
||||
/// Path to a directory used to store recovery files for unconsumed deposits
|
||||
#[clap(long)]
|
||||
pub recovery_dir: PathBuf,
|
||||
pub(crate) recovery_dir: PathBuf,
|
||||
}
|
||||
|
||||
pub async fn execute(args: Args, client: SigningClient) -> anyhow::Result<()> {
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
[package]
|
||||
name = "nym-payment-manager-common"
|
||||
version = "0.1.0"
|
||||
authors.workspace = true
|
||||
repository.workspace = true
|
||||
homepage.workspace = true
|
||||
documentation.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
schemars = { version = "0.8", features = ["preserve_order"] }
|
||||
serde = { workspace = true }
|
||||
@@ -1,9 +0,0 @@
|
||||
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, schemars::JsonSchema)]
|
||||
pub struct PaymentResponse {
|
||||
pub unyms_bought: u64,
|
||||
}
|
||||
@@ -7,7 +7,7 @@ Each directory contains a readme with more information about running and contrib
|
||||
* `operators` contains node setup and maintenance guides hosted at [https://nymtech.net/operators](https://nymtech.net/operators)
|
||||
|
||||
## Scripts
|
||||
* `bump_versions.sh` allows you to update the `platform_release_version` and `wallet_release_version` variables in the `book.toml` of each mdbook project at once. You can also optionally update the `minimum_rust_version` as well. Helpful for lazy-updating when cutting a new version of the docs.
|
||||
* `build_all_to_dist.sh` is used by the `ci-dev.yml` and `cd-dev.yml` scripts for building all mdbook projects and moving the rendered html to `../dist/` to be rsynced with various servers.
|
||||
* `bump_versions.sh` allows you to update the ~~`platform_release_version` and~~ `wallet_release_version` variable~~s~~ in the `book.toml` of each mdbook project at once. You can also optionally update the `minimum_rust_version` as well. Helpful for lazy-updating when cutting a new version of the docs.
|
||||
* `build_all_to_dist.sh` is used by the `ci-dev.yml` and `cd-dev.yml` scripts for building all mdbook projects and moving the rendered html to `../dist/` to be rsynced with various servers.
|
||||
|
||||
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
#!/usr/bin/env bash
|
||||
# this takes two args: platform release version and wallet release version.
|
||||
# takes one manadatory arg and one optional arg: wallet release and minimum rust versions
|
||||
# it then uses sed to bump them in the three book.toml files.
|
||||
#
|
||||
# e.g if the upcoming platform release was v1.1.29 and the release version 1.2.9 you'd run this as:
|
||||
# `./bump_versions.sh "1.1.29" "1.2.9"`
|
||||
# e.g if the upcoming wallet release version was 1.2.9 you'd run this as:
|
||||
# `./bump_versions.sh "1.2.9"`
|
||||
#
|
||||
# you can also set the minumum rust version by passing an optional 3rd argument:
|
||||
# `./bump_versions.sh "1.1.29" "1.2.9" "1.67"`
|
||||
# you can also set the minumum rust version by passing an optional additional argument:
|
||||
# `./bump_versions.sh "1.2.9" "1.67"`
|
||||
|
||||
# array of project dirs
|
||||
declare -a projects=("docs" "dev-portal" "operators")
|
||||
|
||||
# check number of args passed
|
||||
if [ "$#" -lt 2 ] || [ "$#" -gt 3 ];
|
||||
if [ "$#" -lt 1 ] || [ "$#" -gt 2 ];
|
||||
then
|
||||
echo "failure: please pass at least 2 and at most 3 args: "
|
||||
echo "./bump_version.sh <new platform_release_version> <new wallet_release_version> [OPTIONAL]<new minimum_rust_version>"
|
||||
echo "failure: please pass at least 1 and at most 2 args: "
|
||||
echo "./bump_version.sh <new wallet_release_version> [OPTIONAL]<new minimum_rust_version>"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
@@ -29,8 +29,7 @@ else
|
||||
for i in "${projects[@]}"
|
||||
do
|
||||
# sed the vars in the book.toml file for each project
|
||||
echo "setting platform and wallet versions in $i/"
|
||||
sed -i 's/platform_release_version =.*/platform_release_version = "'$1'"/' "$i"/book.toml
|
||||
echo "setting wallet version in $i/"
|
||||
sed -i 's/wallet_release_version =.*/wallet_release_version = "'$2'"/' "$i"/book.toml
|
||||
if [ "$3" ]
|
||||
then
|
||||
|
||||
@@ -12,7 +12,7 @@ If you have built a project with Nym or are compiling and writing resources abou
|
||||
## Variables
|
||||
There are some variables that are shared across this book, such as the current latest software version.
|
||||
|
||||
Variables are denoted in the `.md` files wrapped in `{{}}` (e.g `{{platform_release_version}}` is the most recent release), and are located in the `book.toml` file under the `[preprocessor.variables.variables]` heading. If you are changing something like the software release version, minimum code versions in prerequisites, etc, **check in here first!**
|
||||
Variables are denoted in the `.md` files wrapped in `{{}}` (e.g `{{wallet_release_version}}`), and are located in the `book.toml` file under the `[preprocessor.variables.variables]` heading. If you are changing something like the software release version, minimum code versions in prerequisites, etc, **check in here first!**
|
||||
|
||||
## Building
|
||||
When working locally, it is recommended that you use `mdbook serve` to have a local version of the docs served on `localhost:3000`, with hot reloading on any changes made to files in the `src/` directory.
|
||||
|
||||
@@ -38,7 +38,7 @@ chapter-line-height = "2em"
|
||||
section-line-height = "1.5em"
|
||||
|
||||
# if true, never read and touch the files in theme dir
|
||||
turn-off = false
|
||||
turn-off = true
|
||||
|
||||
|
||||
[preprocessor.admonish]
|
||||
@@ -49,7 +49,6 @@ assets_version = "2.0.0" # do not edit: managed by `mdbook-admonish install`
|
||||
# https://gitlab.com/tglman/mdbook-variables/
|
||||
[preprocessor.variables.variables]
|
||||
minimum_rust_version = "1.66"
|
||||
platform_release_version = "1.1.29"
|
||||
wallet_release_version = "1.2.8"
|
||||
|
||||
[preprocessor.last-changed]
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 153 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.2 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 246 KiB |
@@ -110,7 +110,7 @@ Yes, it is supported.
|
||||
Yes. Follow the instructions in the [Ledger support for Nyx documentation](https://nymtech.net/docs/nyx/ledger-live.html).
|
||||
|
||||
### Where can I find network details such as deployed smart contract addresses?
|
||||
In the [`network defaults`](https://github.com/nymtech/nym/blob/release/{{platform_release_version}}/common/network-defaults/src/mainnet.rs) file.
|
||||
In the [`network defaults`](https://github.com/nymtech/nym/blob/master/common/network-defaults/src/mainnet.rs) file.
|
||||
|
||||
## `NYM` Token
|
||||
The token used to reward mixnet infrastructure operators - `NYM` - is one of the native tokens of the Nyx blockchain. The other token is `NYX`.
|
||||
@@ -198,4 +198,4 @@ For the moment then yes, the mixnet is free to use. There are no limits on the a
|
||||
No, although we do recommend that apps that wish to integrate look into running some of their own infrastructure such as gateways in order to assure uptime.
|
||||
|
||||
### How can I find out if an application is already supported by network requester services?
|
||||
You can check the [default allowed list](https://nymtech.net/.wellknown/network-requester/standard-allowed-list.txt) file to see which application traffic is whitelisted by default. If the domain is present on that list, it means that existing [network requesters](https://nymtech.net/docs/nodes/network-requester-setup.html) can be used to privacy-protect your application traffic. Simply use [NymConnect](../quickstart/nymconnect-gui.md) to connect to this service through the mixnet.
|
||||
You can check the [default allowed list](https://nymtech.net/.wellknown/network-requester/standard-allowed-list.txt) file to see which application traffic is whitelisted by default. If the domain is present on that list, it means that existing [network requesters](https://nymtech.net/docs/nodes/network-requester-setup.html) can be used to privacy-protect your application traffic. Simply use [NymConnect](../quickstart/nymconnect-gui.md) to connect to this service through the mixnet.
|
||||
|
||||
@@ -22,7 +22,7 @@ It’s packaged and available on the npm registry, so you can npm install it int
|
||||
|
||||
The webassembly client is most easily used via the [typescript sdk](https://nymtech.net/docs/sdk/typescript.html).
|
||||
|
||||
You can find example code in the [examples section](https://github.com/nymtech/nym/tree/release/{{platform_release_version}}/sdk/typescript/examples) of the codebase, and in the [typescript sdk docs](https://nymtech.net/docs/sdk/typescript.html).
|
||||
You can find example code in the [examples section](https://github.com/nymtech/nym/tree/master/sdk/typescript/examples) of the codebase, and in the [typescript sdk docs](https://nymtech.net/docs/sdk/typescript.html).
|
||||
|
||||
#### SOCKS client
|
||||
This client is useful for allowing existing applications to use the Nym mixnet without any code changes. All that’s necessary is that they can use one of the SOCKS5, SOCKS4a, or SOCKS4 proxy protocols (which many applications can - crypto wallets, browsers, chat applications etc).
|
||||
|
||||
@@ -11,7 +11,7 @@ Install NymConnect and select an application that you want to privacy-enhance fr
|
||||
**Please note that NymConnect is currently released in beta. Please report bugs via Github**.
|
||||
|
||||
## Usage instuctions
|
||||
* [Download](https://github.com/nymtech/nym/releases/tag/nym-connect-{{platform_release_version}}) and install NymConnect.
|
||||
* [Download](https://github.com/nymtech/nym/releases/) and install NymConnect.
|
||||
* Select your service provider from the dropdown menu.
|
||||
* Click `connect` - NymConnect will connect to a service provider and its SOCKS Proxy (IP) and Port will be displayed.
|
||||
* Click on IP or Port to copy their values to the clipboard.
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# Matrix NymConnect Integration
|
||||
|
||||

|
||||
|
||||
Chat applications became an essential part of human communication. Matrix chat has end to end encryption on protocol level and Element app users can sort their communication into spaces and rooms. Now the Matrix communities can rely on network privacy as NymConnect supports Matrix chat protocol.
|
||||
|
||||
|
||||
@@ -10,33 +10,35 @@ A team made up of Monero community members have successfully set up a service pr
|
||||
|
||||
## How can I use Monero over the Nym mixnet?
|
||||
|
||||
> Any syntax in `<>` brackets is a user's unique variable. Exchange with a corresponding name without the `<>` brackets.
|
||||
|
||||
The mainnet service provider to Monero over the Nym mixnet is now ready for use via [NymConnect](https://nymtech.net/download-nymconnect/).
|
||||
|
||||
* Download and open the latest version of [NymConnect](https://nymtech.net/download-nymconnect/).
|
||||
* Click on the top left options and go to Settings
|
||||
* Go to “Select service provider” and turn it on
|
||||
* For Mainnet, search for this provider or insert it manually:
|
||||
|
||||
* **Download** the latest version of [**NymConnect**](https://nymtech.net/download-nymconnect/).
|
||||
* Make sure your NymConnect is executable.
|
||||
```sh
|
||||
i1TiuoNp4jp9weffCW7tPnkb4hRTPydRjX8iXFVaYDG.88Z1hruuvbzWpdCE2xYnTbPNrr49j4s7mmUQC5wvRRLZ@3EPuxwGn2WP2HdxybzoDa5QsohYSP76aQQRUJuPMvk23
|
||||
# in Linux open terminal in the same folder and run:
|
||||
chmod +x ./nym-connect_<YOUR_VERSION>.AppImage
|
||||
```
|
||||
* **Open NymConnect app**
|
||||
* **Turn it on** - Monero wallet is listed in the apps supported by default, no need for any setup
|
||||
* **Copy** the **Socks5 address** and **Port**
|
||||
|
||||
* Go to the main NymConnect interface and connect to the mixnet
|
||||
Then go to your Monero wallet (desktop or CLI) and change the settings to run over socks5 proxy:
|
||||
|
||||
Then go to your Monero wallet (gui or otherwise) and change the settings to run over socks5 proxy:
|
||||
**Monero desktop wallet:**
|
||||
|
||||
**Monero desktop:**
|
||||
|
||||
* Settings -> Interface -> Socks5 proxy -> Add values: IP address `localhost`, Port `1080`
|
||||
* Settings -> Interface -> Socks5 proxy -> Add values: IP address `127.0.0.1`, Port `1080` (the values copied from NymConnect)
|
||||
|
||||
<!---commenting the video as it has a redundant part about manual NR setup
|
||||
<iframe width="700" height="400" src="https://www.youtube.com/embed/oSHnk1BG_f0" title="Demo: Connect Your Monero Wallet to the Nym Mixnet via NymConnect" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
|
||||
|
||||
**CLI**
|
||||
--->
|
||||
**CLI wallet**
|
||||
|
||||
* **Monerod:** add `--proxy 127.0.0.1:1080 --bootstrap-daemon-proxy 127.0.0.1:1080` to args
|
||||
|
||||
* **Monero-wallet-{rpc, cli}:** add `--proxy 127.0.0.1:1080 --daemon-ssl-allow-any-cert` to args
|
||||
|
||||
Follow the instructions and the Monero mainnet will be connected through to the Nym mixnet.
|
||||
|
||||
For those who want to try it out in testnet, a stagenet service provider is also available: [https://nymtech.net/.wellknown/connect/service-providers.json](https://nymtech.net/.wellknown/connect/service-providers.json)
|
||||
|
||||
Now your Monero traffic is protected by the network privacy of Nym Mixnet.
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
*This is a shortened version of a [Nym Community post](https://blog.nymtech.net/how-to-use-telegram-in-iraq-with-nymconnect-106a3b8dd050) written by Saliveja.*
|
||||
|
||||

|
||||
|
||||
The purpose of the following manual is not to promote Telegram but so people can use it with the Nym mixnet if they wish to, should a situation ask for that. This privacy-enhances Telegram at the network level and allows users to access the application from locations like where the application was banned.
|
||||
|
||||
See also: [Element (Matrix) over the Nym mixnet](./matrix.md): private, decentralised and secure messaging.
|
||||
@@ -10,7 +12,7 @@ See also: [Element (Matrix) over the Nym mixnet](./matrix.md): private, decentra
|
||||
|
||||
Here’s how to configure Telegram with NymConnect:
|
||||
|
||||
1. Download and install NymConnect ().**
|
||||
1. **Download and install NymConnect(https://nymtech.net/download-nymconnect/).**
|
||||
For more releases, check out [Github](https://github.com/nymtech/nym/tags). NymConnect is available for Linux, Windows, and MacOS.
|
||||
On Linux make sure NymConnect is executable. Opening a terminal in the same directory and run:
|
||||
```sh
|
||||
|
||||
@@ -16,7 +16,7 @@ To contribute tranlsations in a new language, please get in touch via [Matrix](h
|
||||
### Variables
|
||||
There are some variables that are shared across the entire docs site, such as the current latest software version.
|
||||
|
||||
Variables are denoted in the `.md` files wrapped in `{{}}` (e.g `{{platform_release_version}}` is the most recent release), and are located in the `book.toml` file under the `[preprocessor.variables.variables]` heading. If you are changing something like the software release version, minimum code versions in prerequisites, etc, **check in here first!**
|
||||
Variables are denoted in the `.md` files wrapped in `{{}}` (e.g `{{wallet_release_version}}`), and are located in the `book.toml` file under the `[preprocessor.variables.variables]` heading. If you are changing something like the software release version, minimum code versions in prerequisites, etc, **check in here first!**
|
||||
|
||||
### Diagrams
|
||||
Most diagrams are simply ascii. Copies are kept in `/diagrams/` for ease of reproducability. Created using [textik](https://textik.com/#).
|
||||
@@ -27,12 +27,6 @@ Example files are inserted as per normal with mdbook.
|
||||
|
||||
Some binary command outputs are generated using the [`cmdrun`](https://docs.rs/mdbook-cmdrun/latest/mdbook_cmdrun/) mdbook plugin.
|
||||
|
||||
### Updating platform version
|
||||
|
||||
When updating the version, make sure to change **both** the version in the `title` on line 2 of `book.toml`, as well as the `platform_release_version` variable in the same file.
|
||||
|
||||
> In the future this will be dealt with something like a preprocessor widget (todo).
|
||||
|
||||
## Building
|
||||
When working locally, it is recommended that you use `mdbook serve` to have a local version of the docs served on `localhost:3000`, with hot reloading on any changes made to files in the `src/` directory.
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ chapter-line-height = "2em"
|
||||
section-line-height = "1.5em"
|
||||
|
||||
# if true, never read and touch the files in theme dir: this is used to stop the looping reload issue referred to in the readme
|
||||
turn-off = false
|
||||
turn-off = true
|
||||
|
||||
[preprocessor.admonish]
|
||||
command = "mdbook-admonish"
|
||||
@@ -48,7 +48,6 @@ assets_version = "2.0.0" # do not edit: managed by `mdbook-admonish install`
|
||||
# https://gitlab.com/tglman/mdbook-variables/
|
||||
[preprocessor.variables.variables]
|
||||
minimum_rust_version = "1.66"
|
||||
platform_release_version = "1.1.29"
|
||||
wallet_release_version = "1.2.8"
|
||||
|
||||
[preprocessor.last-changed]
|
||||
@@ -91,7 +90,7 @@ git-repository-icon = "fa-github"
|
||||
# edit-url-template = "https://github.com/rust-lang/mdBook/edit/master/guide/{path}"
|
||||
# site-url = "/docs/"
|
||||
# cname = "nymtech.net"
|
||||
input-404 = "not-found.md"
|
||||
input-404 = "not-found.md"
|
||||
|
||||
[output.html.fold]
|
||||
enable = true # whether or not to enable section folding
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
|
||||
# Binaries
|
||||
- [Pre-built Binaries](binaries/pre-built-binaries.md)
|
||||
- [Binary Initialisation and Configuration](binaries/init-and-config.md)
|
||||
- [Building from Source](binaries/building-nym.md)
|
||||
- [Binary Initialisation and Configuration](binaries/init-and-config.md)
|
||||
<!-- - [Version Compatibility Table](binaries/version-compatiblity.md) -->
|
||||
|
||||
# Nodes
|
||||
|
||||
@@ -39,7 +39,7 @@ If you really don't want to use the shell script installer, the [Rust installati
|
||||
## Download and build Nym binaries
|
||||
The following commands will compile binaries into the `nym/target/release` directory:
|
||||
|
||||
```
|
||||
```sh
|
||||
rustup update
|
||||
git clone https://github.com/nymtech/nym.git
|
||||
cd nym
|
||||
@@ -47,10 +47,9 @@ cd nym
|
||||
git reset --hard # in case you made any changes on your branch
|
||||
git pull # in case you've checked it out before
|
||||
|
||||
git checkout release/{{platform_release_version}} # checkout to the latest release branch: `develop` will most likely be incompatible with deployed public networks
|
||||
git checkout master # master branch has the latest release version: `develop` will most likely be incompatible with deployed public networks
|
||||
|
||||
cargo build --release # build your binaries with **mainnet** configuration
|
||||
NETWORK=sandbox cargo build --release # build your binaries with **sandbox** configuration
|
||||
```
|
||||
|
||||
Quite a bit of stuff gets built. The key working parts are:
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
# Binary Initialisation and Configuration
|
||||
|
||||
All Nym binaries must first be initialised with `init` before being `run`.
|
||||
All Nym binaries must first be made executable and initialised with `init` before being `run`.
|
||||
|
||||
To make a binary executable, open terminal in the same directory and run:
|
||||
|
||||
```sh
|
||||
chmod +x <BINARY_NAME>
|
||||
# for example: chmod +x nym-mixnode
|
||||
```
|
||||
|
||||
The `init` command is usually where you pass flags specifying configuration arguments such as the gateway you wish to communicate with, the ports you wish your binary to listen on, etc.
|
||||
|
||||
|
||||
@@ -160,7 +160,7 @@ Create a service file for the socks5 client at `/etc/systemd/system/nym-socks5-c
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=Nym Socks5 Client ({{platform_release_version}})
|
||||
Description=Nym Socks5 Client
|
||||
StartLimitInterval=350
|
||||
StartLimitBurst=10
|
||||
|
||||
|
||||
@@ -109,7 +109,7 @@ Alternatively, a custom host can be set in the `config.toml` file under the `soc
|
||||
### Connecting to the local websocket
|
||||
The Nym native client exposes a websocket interface that your code connects to. To program your app, choose a websocket library for whatever language you're using. The **default** websocket port is `1977`, you can override that in the client config if you want.
|
||||
|
||||
The Nym monorepo includes websocket client example code for Rust, Go, Javacript, and Python, all of which can be found [here](https://github.com/nymtech/nym/tree/release/{{platform_release_version}}/clients/native/examples).
|
||||
The Nym monorepo includes websocket client example code for Rust, Go, Javacript, and Python, all of which can be found [here](https://github.com/nymtech/nym/tree/master/clients/native/examples).
|
||||
|
||||
> Rust users can run the examples with `cargo run --example <rust_file>.rs`, as the examples are not organised in the same way as the other examples, due to already being inside a Cargo project.
|
||||
|
||||
@@ -183,7 +183,7 @@ Nym [`ClientRequest`](https://github.com/nymtech/nym/blob/develop/clients/native
|
||||
|
||||
As a response the `native-client` will send a `ServerResponse` to be decoded.
|
||||
|
||||
You can find examples of sending and receiving binary data in the Rust, Python and Go [code examples](https://github.com/nymtech/nym/tree/release/{{platform_release_version}}/clients/native/examples), and an example project from the Nym community [BTC-BC](https://github.com/sgeisler/btcbc-rs/): Bitcoin transaction transmission via Nym, a client and service provider written in Rust.
|
||||
You can find examples of sending and receiving binary data in the Rust, Python and Go [code examples](https://github.com/nymtech/nym/tree/master/clients/native/examples), and an example project from the Nym community [BTC-BC](https://github.com/sgeisler/btcbc-rs/): Bitcoin transaction transmission via Nym, a client and service provider written in Rust.
|
||||
|
||||
#### Getting your own address
|
||||
Sometimes, when you start your app, it can be convenient to ask the native client to tell you what your own address is (from the saved configuration files). To do this, send:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Mixnet Contract
|
||||
|
||||
The Mixnet smart contract is a core piece of the Nym system, functioning as the mixnet directory and keeping track of delegations and rewards: the core functionality required by an incentivised mixnet. You can find the code and build instructions [here](https://github.com/nymtech/nym/tree/release/{{platform_release_version}}/contracts/mixnet).
|
||||
The Mixnet smart contract is a core piece of the Nym system, functioning as the mixnet directory and keeping track of delegations and rewards: the core functionality required by an incentivised mixnet. You can find the code and build instructions [here](https://github.com/nymtech/nym/tree/master/contracts/mixnet).
|
||||
|
||||
### Functionality
|
||||
The Mixnet contract has multiple functions:
|
||||
@@ -9,5 +9,5 @@ The Mixnet contract has multiple functions:
|
||||
* storing delegation and bond amounts.
|
||||
* storing reward amounts.
|
||||
|
||||
The addresses of deployed smart contracts can be found in the [`network-defaults`](https://github.com/nymtech/nym/blob/release/{{platform_release_version}}/common/network-defaults/src/mainnet.rs) directory of the codebase alongside other network default values.
|
||||
The addresses of deployed smart contracts can be found in the [`network-defaults`](https://github.com/nymtech/nym/blob/master/common/network-defaults/src/mainnet.rs) directory of the codebase alongside other network default values.
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
# Vesting Contract
|
||||
|
||||
The vesting contract allows for the creation of vesting accounts, allowing `NYM` tokens to vest over time, and for users to minimally interact with the Mixnet using their unvested tokens. You can find the code and build instructions [here](https://github.com/nymtech/nym/tree/release/{{platform_release_version}}/contracts/vesting).
|
||||
The vesting contract allows for the creation of vesting accounts, allowing `NYM` tokens to vest over time, and for users to minimally interact with the Mixnet using their unvested tokens. You can find the code and build instructions [here](https://github.com/nymtech/nym/tree/master/contracts/vesting).
|
||||
|
||||
### Functionality
|
||||
The Vesting contract has multiple functions:
|
||||
* Creating and storing vesting `NYM` token vesting accounts.
|
||||
* Interacting with the Mixnet using vesting (i.e. non-transferable) tokens, allowing users to delegate their unvested tokens.
|
||||
|
||||
The addresses of deployed smart contracts can be found in the [`network-defaults`](https://github.com/nymtech/nym/blob/release/{{platform_release_version}}/common/network-defaults/src/mainnet.rs) directory of the codebase alongside other network default values.
|
||||
The addresses of deployed smart contracts can be found in the [`network-defaults`](https://github.com/nymtech/nym/blob/master/common/network-defaults/src/mainnet.rs) directory of the codebase alongside other network default values.
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ The `mixnet` component currently exposes the logic of two clients: the [websocke
|
||||
The `coconut` component is currently being worked on. Right now it exposes logic allowing for the creation of coconut credentials on the Sandbox testnet.
|
||||
|
||||
## Websocket client examples
|
||||
> All the codeblocks below can be found in the `nym-sdk` [examples directory](https://github.com/nymtech/nym/tree/release/{{platform_release_version}}/sdk/rust/nym-sdk/examples) in the monorepo. Just navigate to `nym/sdk/rust/nym-sdk/examples/` and run the files from there. If you wish to run these outside of the workspace - such as if you want to use one as the basis for your own project - then make sure to import the `sdk`, `tokio`, and `nym_bin_common` crates.
|
||||
> All the codeblocks below can be found in the `nym-sdk` [examples directory](https://github.com/nymtech/nym/tree/master/sdk/rust/nym-sdk/examples) in the monorepo. Just navigate to `nym/sdk/rust/nym-sdk/examples/` and run the files from there. If you wish to run these outside of the workspace - such as if you want to use one as the basis for your own project - then make sure to import the `sdk`, `tokio`, and `nym_bin_common` crates.
|
||||
|
||||
### Different message types
|
||||
There are two methods for sending messages through the mixnet using your client:
|
||||
@@ -82,7 +82,7 @@ If you're integrating mixnet functionality into an existing app and want to inte
|
||||
### Anonymous replies with SURBs
|
||||
Both functions used to send messages through the mixnet (`send_message` and `send_plain_message`) send a pre-determined number of SURBs along with their messages by default.
|
||||
|
||||
The number of SURBs is set [here](https://github.com/nymtech/nym/blob/release/{{platform_release_version}}/sdk/rust/nym-sdk/src/mixnet/client.rs#L34):
|
||||
The number of SURBs is set [here](https://github.com/nymtech/nym/blob/master/sdk/rust/nym-sdk/src/mixnet/client.rs#L33):
|
||||
|
||||
```rust,noplayground
|
||||
{{#include ../../../../sdk/rust/nym-sdk/src/mixnet/client.rs:34}}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Typescript SDK
|
||||
The Typescript SDK allows developers to start building browser-based mixnet applications quickly, by simply importing the SDK into their code via NPM as they would any other Typescript library.
|
||||
|
||||
You can find the source code [here](https://github.com/nymtech/nym/tree/release/{{platform_release_version}}/sdk) and the library on NPM [here](https://www.npmjs.com/package/@nymproject/sdk).
|
||||
You can find the source code [here](https://github.com/nymtech/nym/tree/master/sdk) and the library on NPM [here](https://www.npmjs.com/package/@nymproject/sdk).
|
||||
|
||||
Currently developers can use the SDK to do the following **entirely in the browser**:
|
||||
* Create a client
|
||||
@@ -19,7 +19,7 @@ In the future the SDK will be made up of several components, each of which will
|
||||
| Validator | Sign & broadcast Nyx blockchain transactions, query the blockchain | ❌ |
|
||||
|
||||
### How it works
|
||||
The SDK can be thought of as a 'wrapper' around the compiled [WebAssembly client](https://github.com/nymtech/nym/tree/release/{{platform_release_version}}/clients/webassembly) code: it runs the client (a Wasm blob) in a web worker. This allows us to keep the work done by the client - such as the heavy lifting of creating and multiply-encrypting Sphinx packets - in a seperate thread from our UI, enabling you to build reactive frontends without worrying about the work done under the hood by the client eating your processing power.
|
||||
The SDK can be thought of as a 'wrapper' around the compiled [WebAssembly client](https://github.com/nymtech/nym/tree/master/clients/webassembly) code: it runs the client (a Wasm blob) in a web worker. This allows us to keep the work done by the client - such as the heavy lifting of creating and multiply-encrypting Sphinx packets - in a seperate thread from our UI, enabling you to build reactive frontends without worrying about the work done under the hood by the client eating your processing power.
|
||||
|
||||
The SDK exposes an interface that allows developers to interact with the Wasm blob inside the webworker from frontend code.
|
||||
|
||||
@@ -41,7 +41,7 @@ Support for environments with different bundlers will be added in subsequent rel
|
||||
|
||||
|
||||
### Using the SDK
|
||||
There are multiple example projects in [`nym/sdk/typescript/examples/`](https://github.com/nymtech/nym/tree/release/{{platform_release_version}}/sdk/typescript/examples/), each for a different frontend framework.
|
||||
There are multiple example projects in [`nym/sdk/typescript/examples/`](https://github.com/nymtech/nym/tree/master/sdk/typescript/examples/), each for a different frontend framework.
|
||||
|
||||
#### Vanilla HTML
|
||||
The best place to start if you just want to quickly get a basic frontend up and running with which to experiment is `examples/plain-html`:
|
||||
@@ -53,10 +53,10 @@ The best place to start if you just want to quickly get a basic frontend up and
|
||||
As you can see, all that is required to create an ephemeral keypair and connect to the mixnet is creating a client and then subscribing to the mixnet events coming down the websocket, and adding logic to deal with them.
|
||||
|
||||
#### Parcel
|
||||
If you don't want to use `Webpack` as your app bundler, we have an example with `Parcel` located at [`examples/parcel/`](https://github.com/nymtech/nym/tree/release/{{platform_release_version}}/sdk/typescript/examples/react-webpack-with-theme-example/parcel/).
|
||||
If you don't want to use `Webpack` as your app bundler, we have an example with `Parcel` located at [`examples/parcel/`](https://github.com/nymtech/nym/tree/master/sdk/typescript/examples/chat-app/parcel).
|
||||
|
||||
#### Create React App
|
||||
For React developers we have an example which is a basic React app scaffold with the additional logic for creating a client and subscribing to mixnet events in [`examples/react-webpack-with-theme-example/`](https://github.com/nymtech/nym/tree/release/{{platform_release_version}}/sdk/typescript/examples/react-webpack-with-theme-example/).
|
||||
For React developers we have an example which is a basic React app scaffold with the additional logic for creating a client and subscribing to mixnet events in [`examples/react-webpack-with-theme-example/`](https://github.com/nymtech/nym/tree/master/sdk/typescript/examples/chat-app/react-webpack-with-theme-example).
|
||||
|
||||
### Developers: think about what you're sending (and importing)!
|
||||
Think about what information your app sends. That goes for whatever you put into your Sphinx packet messages as well as what your app's environment may leak.
|
||||
|
||||
@@ -38,7 +38,7 @@ chapter-line-height = "2em"
|
||||
section-line-height = "1.5em"
|
||||
|
||||
# if true, never read and touch the files in theme dir: this is used to stop the looping reload issue referred to in the readme
|
||||
turn-off = false
|
||||
turn-off = true
|
||||
|
||||
[preprocessor.admonish]
|
||||
command = "mdbook-admonish"
|
||||
@@ -48,7 +48,6 @@ assets_version = "2.0.0" # do not edit: managed by `mdbook-admonish install`
|
||||
# https://gitlab.com/tglman/mdbook-variables/
|
||||
[preprocessor.variables.variables]
|
||||
minimum_rust_version = "1.66"
|
||||
platform_release_version = "1.1.29"
|
||||
wallet_release_version = "1.2.8"
|
||||
|
||||
[preprocessor.last-changed]
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
|
||||
# Binaries
|
||||
- [Pre-built Binaries](./binaries/pre-built-binaries.md)
|
||||
- [Binary Initialisation and Configuration](./binaries/init-and-config.md)
|
||||
- [Building from Source](./binaries/building-nym.md)
|
||||
- [Binary Initialisation and Configuration](./binaries/init-and-config.md)
|
||||
<!-- - [Version Compatibility Table](binaries/version-compatiblity.md) -->
|
||||
|
||||
# Operators Guides
|
||||
|
||||
@@ -39,7 +39,7 @@ If you really don't want to use the shell script installer, the [Rust installati
|
||||
## Download and build Nym binaries
|
||||
The following commands will compile binaries into the `nym/target/release` directory:
|
||||
|
||||
```
|
||||
```sh
|
||||
rustup update
|
||||
git clone https://github.com/nymtech/nym.git
|
||||
cd nym
|
||||
@@ -47,10 +47,9 @@ cd nym
|
||||
git reset --hard # in case you made any changes on your branch
|
||||
git pull # in case you've checked it out before
|
||||
|
||||
git checkout release/{{platform_release_version}} # checkout to the latest release branch: `develop` will most likely be incompatible with deployed public networks
|
||||
git checkout master # master branch has the latest release version: `develop` will most likely be incompatible with deployed public networks
|
||||
|
||||
cargo build --release # build your binaries with **mainnet** configuration
|
||||
NETWORK=sandbox cargo build --release # build your binaries with **sandbox** configuration
|
||||
```
|
||||
|
||||
Quite a bit of stuff gets built. The key working parts are:
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
# Binary Initialisation and Configuration
|
||||
|
||||
All Nym binaries must first be initialised with `init` before being `run`.
|
||||
All Nym binaries must first be made executable and initialised with `init` before being `run`.
|
||||
|
||||
To make a binary executable, open terminal in the same directory and run:
|
||||
|
||||
```sh
|
||||
chmod +x <BINARY_NAME>
|
||||
# for example: chmod +x nym-mixnode
|
||||
```
|
||||
|
||||
The `init` command is usually where you pass flags specifying configuration arguments such as the gateway you wish to communicate with, the ports you wish your binary to listen on, etc.
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@ It will look something like this:
|
||||
|_| |_|\__, |_| |_| |_|
|
||||
|___/
|
||||
|
||||
(nym-gateway - version {{platform_release_version}})
|
||||
(nym-gateway - version v1.1.29)
|
||||
|
||||
|
||||
>>> attempting to sign 2Mf8xYytgEeyJke9LA7TjhHoGQWNBEfgHZtTyy2krFJfGHSiqy7FLgTnauSkQepCZTqKN5Yfi34JQCuog9k6FGA2EjsdpNGAWHZiuUGDipyJ6UksNKRxnFKhYW7ri4MRduyZwbR98y5fQMLAwHne1Tjm9cXYCn8McfigNt77WAYwBk5bRRKmC34BJMmWcAxphcLES2v9RdSR68tkHSpy2C8STfdmAQs3tZg8bJS5Qa8pQdqx14TnfQAPLk3QYCynfUJvgcQTrg29aqCasceGRpKdQ3Tbn81MLXAGAs7JLBbiMEAhCezAr2kEN8kET1q54zXtKz6znTPgeTZoSbP8rzf4k2JKHZYWrHYF9JriXepuZTnyxAKAxvGFPBk8Z6KAQi33NRQkwd7MPyttatHna6kG9x7knffV6ebGzgRBf7NV27LurH8x4L1uUXwm1v1UYCA1WSBQ9Pp2JW69k5v5v7G9gBy8RUcZnMbeL26Qqb8WkuGcmuHhaFfoqSfV7PRHPpPT4M8uRqUyR4bjUtSJJM1yh6QSeZk9BEazzoJqPeYeGoiFDZ3LMj2jesbJweQR4caaYuRczK92UGSSqu9zBKmE45a
|
||||
|
||||
@@ -19,7 +19,7 @@ For example `./target/debug/nym-network-requester --no-banner build-info --outpu
|
||||
> The process is the similar for mix node, gateway and network requester. In the following steps we use a placeholder `<NODE>` in the commands, please change it for the type of node you want to upgrade. Any particularities for the given type of node are included.
|
||||
|
||||
Upgrading your node is a two-step process:
|
||||
* Updating the binary and `~/.nym/<NODE>/<YOUR_ID>/config.toml` on your VPS
|
||||
* Updating the binary and `~/.nym/<NODE>/<YOUR_ID>/config/config.toml` on your VPS
|
||||
* Updating the node information in the [mixnet smart contract](https://nymtech.net/docs/nyx/mixnet-contract.html). **This is the information that is present on the [mixnet explorer](https://explorer.nymtech.net)**.
|
||||
|
||||
### Step 1: Upgrading your binary
|
||||
@@ -230,7 +230,7 @@ Here's a systemd service file to do that:
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=Nym Mixnode ({{platform_release_version}})
|
||||
Description=Nym Mixnode <VERSION>
|
||||
StartLimitInterval=350
|
||||
StartLimitBurst=10
|
||||
|
||||
@@ -252,7 +252,7 @@ WantedBy=multi-user.target
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=Nym Gateway ({{platform_release_version}})
|
||||
Description=Nym Gateway <VERSION>
|
||||
StartLimitInterval=350
|
||||
StartLimitBurst=10
|
||||
|
||||
@@ -274,7 +274,7 @@ WantedBy=multi-user.target
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=Nym Network Requester ({{platform_release_version}})
|
||||
Description=Nym Network Requester <VERSION>
|
||||
StartLimitInterval=350
|
||||
StartLimitBurst=10
|
||||
|
||||
|
||||
@@ -87,13 +87,13 @@ Mixnode configuration completed.
|
||||
|_| |_|\__, |_| |_| |_|
|
||||
|___/
|
||||
|
||||
(nym-mixnode - version {{platform_release_version}})
|
||||
(nym-mixnode - version v1.1.29)
|
||||
|
||||
|
||||
Identity Key: DhmUYedPZvhP9MMwXdNpPaqCxxTQgjAg78s2nqtTTiNF","version":"{{platform_release_version}}"},"cost_params
|
||||
Identity Key: DhmUYedPZvhP9MMwXdNpPaqCxxTQgjAg78s2nqtTTiNF","version":"v1.1.29"},"cost_params
|
||||
Sphinx Key: CfZSy1jRfrfiVi9JYexjFWPqWkKoY72t7NdpWaq37K8Z
|
||||
Host: 62.240.134.189 (bind address: 62.240.134.189)
|
||||
Version: {{platform_release_version}}
|
||||
Version: v1.1.29
|
||||
Mix Port: 1789, Verloc port: 1790, Http Port: 8000
|
||||
```
|
||||
~~~
|
||||
@@ -134,7 +134,7 @@ It will look something like this:
|
||||
|_| |_|\__, |_| |_| |_|
|
||||
|___/
|
||||
|
||||
(nym-mixnode - version {{platform_release_version}})
|
||||
(nym-mixnode - version v1.1.29)
|
||||
|
||||
|
||||
>>> attempting to sign 22Z9wt4PyiBCbMiErxj5bBa4VCCFsjNawZ1KnLyMeV9pMUQGyksRVANbXHjWndMUaXNRnAuEVJW6UCxpRJwZe788hDt4sicsrv7iAXRajEq19cWPVybbUqgeo76wbXbCbRdg1FvVKgYZGZZp8D72p5zWhKSBRD44qgCrqzfV1SkiFEhsvcLUvZATdLRocAUL75KmWivyRiQjCE1XYEWyRH9yvRYn4TymWwrKVDtEB63zhHjATN4QEi2E5qSrSbBcmmqatXsKakbgSbQoLsYygcHx7tkwbQ2HDYzeiKP1t16Rhcjn6Ftc2FuXUNnTcibk2LQ1hiqu3FAq31bHUbzn2wiaPfm4RgqTwGM4eqnjBofwR3251wQSxbYwKUYwGsrkweRcoPuEaovApR9R19oJ7GVG5BrKmFwZWX3XFVuECe8vt1x9MY7DbQ3xhAapsHhThUmzN6JPPU4qbQ3PdMt3YVWy6oRhap97ma2dPMBaidebfgLJizpRU3Yu7mtb6E8vgi5Xnehrgtd35gitoJqJUY5sB1p6TDPd6vk3MVU1zqusrke7Lvrud4xKfCLqp672Bj9eGb2wPwow643CpHuMkhigfSWsv9jDq13d75EGTEiprC2UmWTzCJWHrDH7ka68DZJ5XXAW67DBewu7KUm1jrJkNs55vS83SWwm5RjzQLVhscdtCH1Bamec6uZoFBNVzjs21o7ax2WHDghJpGMxFi6dmdMCZpqn618t4
|
||||
|
||||
@@ -190,7 +190,7 @@ Stop the running process with `CTRL-C`, and create a service file for the reques
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=Nym Network Requester ({{platform_release_version}})
|
||||
Description=Nym Network Requester
|
||||
StartLimitInterval=350
|
||||
StartLimitBurst=10
|
||||
|
||||
|
||||
Executable
+7
@@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
# this is a script called by the github CI and CD workflows to post process CSS/image/href links for serving
|
||||
# several mdbooks from a subdirectory
|
||||
|
||||
cd scripts/post-process
|
||||
npm install
|
||||
node index.mjs
|
||||
@@ -0,0 +1,88 @@
|
||||
import { unified } from "unified";
|
||||
import parse from "rehype-parse";
|
||||
import inspectUrls from "@jsdevtools/rehype-url-inspector";
|
||||
import stringify from "rehype-stringify";
|
||||
import { read, write } from "to-vfile";
|
||||
import path from "path";
|
||||
import fs from "fs";
|
||||
import { glob } from "glob";
|
||||
|
||||
async function main() {
|
||||
const distDir = "../../../dist/docs";
|
||||
|
||||
const items = [];
|
||||
|
||||
const books = [
|
||||
'developers',
|
||||
'docs',
|
||||
'operators',
|
||||
];
|
||||
|
||||
for(const book of books)
|
||||
{
|
||||
// only process the root `index.html` files, because they have absolute paths instead of relative paths
|
||||
const filenames = [ path.resolve(distDir, book, 'index.html') ];
|
||||
|
||||
// leaving this here for a future where other files need to be processed
|
||||
// const filenames = await glob(path.resolve(distDir, book) + '/**/*.html');
|
||||
|
||||
for (const f of filenames) {
|
||||
// Create a Rehype processor with the inspectUrls plugin
|
||||
const processor = unified()
|
||||
.use(parse)
|
||||
.use(inspectUrls, {
|
||||
inspectEach(args) {
|
||||
const { url: rawUrl, propertyName } = args;
|
||||
const { tagName } = args.node;
|
||||
const filename = args.file.history[0];
|
||||
|
||||
const relativeFilename = path.relative(distDir, filename);
|
||||
const relativeDirectory = path.dirname(relativeFilename);
|
||||
|
||||
// remove relative paths from URL
|
||||
const bareUrl = rawUrl.split('/').filter(c => c !== '.' && c !== '..').join('/');
|
||||
let url;
|
||||
|
||||
if(rawUrl.includes('.html#')) {
|
||||
url = path.join(`/${relativeDirectory}`, bareUrl);
|
||||
} else if(rawUrl.startsWith('#')) {
|
||||
url = path.join(`/`, relativeFilename + bareUrl);
|
||||
} else {
|
||||
url = path.join(`/${book}`, bareUrl);
|
||||
}
|
||||
|
||||
// const item = { filename, relativeDirectory, tagName, propertyName, rawUrl, url };
|
||||
const item = { tagName, rawUrl, url };
|
||||
|
||||
// if(tagName === 'a') {
|
||||
// console.log(args);
|
||||
// }
|
||||
|
||||
if(!rawUrl.startsWith('http')) {
|
||||
if (tagName === 'link' || tagName === 'script' || tagName === 'a') {
|
||||
args.node.properties[propertyName] = url;
|
||||
items.push(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.use(stringify);
|
||||
|
||||
// Read the example HTML file
|
||||
const filename = path.resolve(distDir, f);
|
||||
console.log(`${filename}...`);
|
||||
|
||||
let file = await read(filename);
|
||||
|
||||
// Crawl the HTML file and find all the URLs
|
||||
const res = await processor.process(file);
|
||||
|
||||
fs.writeFileSync(filename, res.value);
|
||||
}
|
||||
}
|
||||
|
||||
// console.table(items);
|
||||
// console.log();
|
||||
}
|
||||
|
||||
main();
|
||||
+1313
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "nym-docs-post-process",
|
||||
"version": "1.0.0",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"process": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@jsdevtools/rehype-url-inspector": "^2.0.2",
|
||||
"glob": "^10.3.4",
|
||||
"rehype-parse": "^9.0.0",
|
||||
"rehype-stringify": "^10.0.0",
|
||||
"to-vfile": "^8.0.0",
|
||||
"unified": "^11.0.2"
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "explorer-api"
|
||||
version = "1.1.27"
|
||||
version = "1.1.28"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
use std::time::Duration;
|
||||
|
||||
use reqwest::StatusCode;
|
||||
|
||||
+2
-2
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "nym-gateway"
|
||||
version = "1.1.27"
|
||||
version = "1.1.28"
|
||||
authors = [
|
||||
"Dave Hrycyszyn <futurechimp@users.noreply.github.com>",
|
||||
"Jędrzej Stuczyński <andrew@nymtech.net>",
|
||||
@@ -37,7 +37,7 @@ serde_json = { workspace = true }
|
||||
sqlx = { version = "0.5", features = [ "runtime-tokio-rustls", "sqlite", "macros", "migrate", ] }
|
||||
subtle-encoding = { version = "0.5", features = ["bech32-preview"] }
|
||||
thiserror = "1"
|
||||
tokio = { version = "1.24.1", features = [ "rt-multi-thread", "net", "signal", "fs", ] }
|
||||
tokio = { workspace = true, features = [ "rt-multi-thread", "net", "signal", "fs", "time" ] }
|
||||
tokio-stream = { version = "0.1.11", features = ["fs"] }
|
||||
tokio-tungstenite = "0.14"
|
||||
tokio-util = { version = "0.7.4", features = ["codec"] }
|
||||
|
||||
@@ -1,13 +1,23 @@
|
||||
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::node::client_handling::websocket::message_receiver::MixMessageSender;
|
||||
use dashmap::DashMap;
|
||||
use nym_sphinx::DestinationAddressBytes;
|
||||
use std::sync::Arc;
|
||||
|
||||
use super::websocket::message_receiver::{IsActiveRequestSender, MixMessageSender};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct ActiveClientsStore(Arc<DashMap<DestinationAddressBytes, MixMessageSender>>);
|
||||
pub(crate) struct ActiveClientsStore(Arc<DashMap<DestinationAddressBytes, ClientIncomingChannels>>);
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct ClientIncomingChannels {
|
||||
// Mix messages coming from the mixnet to the handler of a client.
|
||||
pub mix_message_sender: MixMessageSender,
|
||||
|
||||
// Requests sent from the handler of one client to the handler of other clients.
|
||||
pub is_active_request_sender: IsActiveRequestSender,
|
||||
}
|
||||
|
||||
impl ActiveClientsStore {
|
||||
/// Creates new instance of `ActiveClientsStore` to store in-memory handles to all currently connected clients.
|
||||
@@ -21,13 +31,13 @@ impl ActiveClientsStore {
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `client`: address of the client for which to obtain the handle.
|
||||
pub(crate) fn get(&self, client: DestinationAddressBytes) -> Option<MixMessageSender> {
|
||||
pub(crate) fn get(&self, client: DestinationAddressBytes) -> Option<ClientIncomingChannels> {
|
||||
let entry = self.0.get(&client)?;
|
||||
let handle = entry.value();
|
||||
|
||||
// if the entry is stale, remove it from the map
|
||||
// if handle.is_valid() {
|
||||
if !handle.is_closed() {
|
||||
if !handle.mix_message_sender.is_closed() {
|
||||
Some(handle.clone())
|
||||
} else {
|
||||
// drop the reference to the map to prevent deadlocks
|
||||
@@ -52,8 +62,19 @@ impl ActiveClientsStore {
|
||||
///
|
||||
/// * `client`: address of the client for which to insert the handle.
|
||||
/// * `handle`: the sender channel for all mix packets to be pushed back onto the websocket
|
||||
pub(crate) fn insert(&self, client: DestinationAddressBytes, handle: MixMessageSender) {
|
||||
self.0.insert(client, handle);
|
||||
pub(crate) fn insert(
|
||||
&self,
|
||||
client: DestinationAddressBytes,
|
||||
handle: MixMessageSender,
|
||||
is_active_request_sender: IsActiveRequestSender,
|
||||
) {
|
||||
self.0.insert(
|
||||
client,
|
||||
ClientIncomingChannels {
|
||||
mix_message_sender: handle,
|
||||
is_active_request_sender,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// Get number of active clients in store
|
||||
|
||||
@@ -1,28 +1,39 @@
|
||||
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::node::client_handling::websocket::connection_handler::{ClientDetails, FreshHandler};
|
||||
use crate::node::client_handling::websocket::message_receiver::MixMessageReceiver;
|
||||
use crate::node::storage::error::StorageError;
|
||||
use crate::node::storage::Storage;
|
||||
use futures::StreamExt;
|
||||
use futures::{
|
||||
future::{FusedFuture, OptionFuture},
|
||||
FutureExt, StreamExt,
|
||||
};
|
||||
use log::*;
|
||||
use nym_gateway_requests::iv::IVConversionError;
|
||||
use nym_gateway_requests::types::{BinaryRequest, ServerResponse};
|
||||
use nym_gateway_requests::{ClientControlRequest, GatewayRequestsError};
|
||||
use nym_gateway_requests::{
|
||||
iv::{IVConversionError, IV},
|
||||
types::{BinaryRequest, ServerResponse},
|
||||
ClientControlRequest, GatewayRequestsError,
|
||||
};
|
||||
use nym_sphinx::forwarding::packet::MixPacket;
|
||||
use rand::{CryptoRng, Rng};
|
||||
use std::convert::TryFrom;
|
||||
use std::process;
|
||||
use thiserror::Error;
|
||||
use tokio::io::{AsyncRead, AsyncWrite};
|
||||
use tokio_tungstenite::tungstenite::protocol::Message;
|
||||
|
||||
use crate::node::client_handling::bandwidth::Bandwidth;
|
||||
use crate::node::client_handling::FREE_TESTNET_BANDWIDTH_VALUE;
|
||||
use nym_gateway_requests::iv::IV;
|
||||
use nym_task::TaskClient;
|
||||
use nym_validator_client::coconut::CoconutApiError;
|
||||
use rand::{CryptoRng, Rng};
|
||||
use thiserror::Error;
|
||||
use tokio::io::{AsyncRead, AsyncWrite};
|
||||
use tokio_tungstenite::tungstenite::{protocol::Message, Error as WsError};
|
||||
|
||||
use std::{convert::TryFrom, process, time::Duration};
|
||||
|
||||
use crate::node::{
|
||||
client_handling::{
|
||||
bandwidth::Bandwidth,
|
||||
websocket::{
|
||||
connection_handler::{ClientDetails, FreshHandler},
|
||||
message_receiver::{
|
||||
IsActive, IsActiveRequestReceiver, IsActiveResultSender, MixMessageReceiver,
|
||||
},
|
||||
},
|
||||
FREE_TESTNET_BANDWIDTH_VALUE,
|
||||
},
|
||||
storage::{error::StorageError, Storage},
|
||||
};
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub(crate) enum RequestHandlingError {
|
||||
@@ -97,6 +108,11 @@ pub(crate) struct AuthenticatedHandler<R, S, St> {
|
||||
inner: FreshHandler<R, S, St>,
|
||||
client: ClientDetails,
|
||||
mix_receiver: MixMessageReceiver,
|
||||
// Occasionally the handler is requested to ping the connected client for confirm that it's
|
||||
// active, such as when a duplicate connection is detected. This hashmap stores the oneshot
|
||||
// senders that are used to return the result of the ping to the handler requesting the ping.
|
||||
is_active_request_receiver: IsActiveRequestReceiver,
|
||||
is_active_ping_pending_reply: Option<(u64, IsActiveResultSender)>,
|
||||
}
|
||||
|
||||
// explicitly remove handle from the global store upon being dropped
|
||||
@@ -127,11 +143,14 @@ where
|
||||
fresh: FreshHandler<R, S, St>,
|
||||
client: ClientDetails,
|
||||
mix_receiver: MixMessageReceiver,
|
||||
is_active_request_receiver: IsActiveRequestReceiver,
|
||||
) -> Self {
|
||||
AuthenticatedHandler {
|
||||
inner: fresh,
|
||||
client,
|
||||
mix_receiver,
|
||||
is_active_request_receiver,
|
||||
is_active_ping_pending_reply: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -351,6 +370,29 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// Handles pong message received from the client.
|
||||
/// If the client is still active, the handler that requested the ping will receive a reply.
|
||||
async fn handle_pong(&mut self, msg: Vec<u8>) {
|
||||
if let Ok(msg) = msg.try_into() {
|
||||
let msg = u64::from_be_bytes(msg);
|
||||
trace!("Received pong from client: {}", msg);
|
||||
if let Some((tag, _)) = &self.is_active_ping_pending_reply {
|
||||
if tag == &msg {
|
||||
debug!("Reporting back to the handler that the client is still active");
|
||||
let tx = self.is_active_ping_pending_reply.take().unwrap().1;
|
||||
if let Err(err) = tx.send(IsActive::Active) {
|
||||
warn!("Failed to send pong reply back to the requesting handler: {err:?}");
|
||||
}
|
||||
} else {
|
||||
warn!(
|
||||
"Received pong reply from the client with unexpected tag: {}",
|
||||
msg
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Attempts to handle websocket message received from the connected client.
|
||||
///
|
||||
/// # Arguments
|
||||
@@ -363,10 +405,64 @@ where
|
||||
match raw_request {
|
||||
Message::Binary(bin_msg) => Some(self.handle_binary(bin_msg).await),
|
||||
Message::Text(text_msg) => Some(self.handle_text(text_msg).await),
|
||||
Message::Pong(msg) => {
|
||||
self.handle_pong(msg).await;
|
||||
None
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Send a ping to the connected client and return a tag identifying the ping.
|
||||
async fn send_ping(&mut self) -> Result<u64, WsError>
|
||||
where
|
||||
S: AsyncRead + AsyncWrite + Unpin,
|
||||
{
|
||||
let tag: u64 = rand::thread_rng().gen();
|
||||
debug!("Got request to ping our connection: {}", tag);
|
||||
self.inner
|
||||
.send_websocket_message(Message::Ping(tag.to_be_bytes().to_vec()))
|
||||
.await?;
|
||||
Ok(tag)
|
||||
}
|
||||
|
||||
/// Handles the ping timeout by responding back to the handler that requested the ping.
|
||||
async fn handle_ping_timeout(&mut self) {
|
||||
debug!("Ping timeout expired!");
|
||||
if let Some((_tag, reply_tx)) = self.is_active_ping_pending_reply.take() {
|
||||
if let Err(err) = reply_tx.send(IsActive::NotActive) {
|
||||
warn!("Failed to respond back to the handler requesting the ping: {err:?}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn handle_is_active_request(
|
||||
&mut self,
|
||||
reply_tx: IsActiveResultSender,
|
||||
) -> Result<(), WsError>
|
||||
where
|
||||
S: AsyncRead + AsyncWrite + Unpin,
|
||||
{
|
||||
if self.is_active_ping_pending_reply.is_some() {
|
||||
warn!("Received request to ping the client, but a ping is already in progress!");
|
||||
if let Err(err) = reply_tx.send(IsActive::BusyPinging) {
|
||||
warn!("Failed to respond back to the handler requesting the ping: {err:?}");
|
||||
}
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
match self.send_ping().await {
|
||||
Ok(tag) => {
|
||||
self.is_active_ping_pending_reply = Some((tag, reply_tx));
|
||||
Ok(())
|
||||
}
|
||||
Err(err) => {
|
||||
warn!("Failed to send ping to client: {err}. Assuming the connection is dead.");
|
||||
Err(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Simultaneously listens for incoming client requests, which realistically should only be
|
||||
/// binary requests to forward sphinx packets or increase bandwidth
|
||||
/// and for sphinx packets received from the mix network that should be sent back to the client.
|
||||
@@ -377,11 +473,32 @@ where
|
||||
{
|
||||
trace!("Started listening for ALL incoming requests...");
|
||||
|
||||
// Ping timeout future used to check if the client responded to our ping request
|
||||
let mut ping_timeout: OptionFuture<_> = None.into();
|
||||
|
||||
while !shutdown.is_shutdown() {
|
||||
tokio::select! {
|
||||
_ = shutdown.recv() => {
|
||||
log::trace!("client_handling::AuthenticatedHandler: received shutdown");
|
||||
}
|
||||
},
|
||||
// Received a request to ping the client to check if it's still active
|
||||
tx = self.is_active_request_receiver.next() => {
|
||||
match tx {
|
||||
None => break,
|
||||
Some(reply_tx) => {
|
||||
if self.handle_is_active_request(reply_tx).await.is_err() {
|
||||
break;
|
||||
}
|
||||
// NOTE: fuse here due to .is_terminated() check below
|
||||
ping_timeout = Some(Box::pin(tokio::time::sleep(Duration::from_millis(1000)).fuse())).into();
|
||||
}
|
||||
};
|
||||
},
|
||||
// The ping timeout expired, meaning the client didn't respond to our ping request
|
||||
_ = &mut ping_timeout, if !ping_timeout.is_terminated() => {
|
||||
ping_timeout = None.into();
|
||||
self.handle_ping_timeout().await;
|
||||
},
|
||||
socket_msg = self.inner.read_websocket_message() => {
|
||||
let socket_msg = match socket_msg {
|
||||
None => break,
|
||||
@@ -406,7 +523,13 @@ where
|
||||
}
|
||||
},
|
||||
mix_messages = self.mix_receiver.next() => {
|
||||
let mix_messages = mix_messages.expect("sender was unexpectedly closed! this shouldn't have ever happened!");
|
||||
let mix_messages = match mix_messages {
|
||||
None => {
|
||||
warn!("mix receiver was closed! Assuming the connection is dead.");
|
||||
break;
|
||||
}
|
||||
Some(mix_messages) => mix_messages,
|
||||
};
|
||||
if let Err(err) = self.inner.push_packets_to_client(&self.client.shared_keys, mix_messages).await {
|
||||
warn!("failed to send the unwrapped sphinx packets back to the client - {err}, assuming the connection is dead");
|
||||
break;
|
||||
|
||||
@@ -1,33 +1,43 @@
|
||||
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::node::client_handling::active_clients::ActiveClientsStore;
|
||||
use crate::node::client_handling::websocket::connection_handler::coconut::CoconutVerifier;
|
||||
use crate::node::client_handling::websocket::connection_handler::{
|
||||
AuthenticatedHandler, ClientDetails, InitialAuthResult, SocketStream,
|
||||
use futures::{
|
||||
channel::{mpsc, oneshot},
|
||||
SinkExt, StreamExt,
|
||||
};
|
||||
use crate::node::storage::error::StorageError;
|
||||
use crate::node::storage::Storage;
|
||||
use futures::{channel::mpsc, SinkExt, StreamExt};
|
||||
use log::*;
|
||||
use nym_crypto::asymmetric::identity;
|
||||
use nym_gateway_requests::authentication::encrypted_address::{
|
||||
EncryptedAddressBytes, EncryptedAddressConversionError,
|
||||
};
|
||||
use nym_gateway_requests::iv::{IVConversionError, IV};
|
||||
use nym_gateway_requests::registration::handshake::error::HandshakeError;
|
||||
use nym_gateway_requests::registration::handshake::{gateway_handshake, SharedKeys};
|
||||
use nym_gateway_requests::types::{ClientControlRequest, ServerResponse};
|
||||
use nym_gateway_requests::{BinaryResponse, PROTOCOL_VERSION};
|
||||
use nym_gateway_requests::{
|
||||
iv::{IVConversionError, IV},
|
||||
registration::handshake::{error::HandshakeError, gateway_handshake, SharedKeys},
|
||||
types::{ClientControlRequest, ServerResponse},
|
||||
BinaryResponse, PROTOCOL_VERSION,
|
||||
};
|
||||
use nym_mixnet_client::forwarder::MixForwardingSender;
|
||||
use nym_sphinx::DestinationAddressBytes;
|
||||
use rand::{CryptoRng, Rng};
|
||||
use std::convert::TryFrom;
|
||||
use std::sync::Arc;
|
||||
use std::{convert::TryFrom, sync::Arc, time::Duration};
|
||||
use thiserror::Error;
|
||||
use tokio::io::{AsyncRead, AsyncWrite};
|
||||
use tokio_tungstenite::tungstenite::{protocol::Message, Error as WsError};
|
||||
|
||||
use crate::node::{
|
||||
client_handling::{
|
||||
active_clients::ActiveClientsStore,
|
||||
websocket::{
|
||||
connection_handler::{
|
||||
coconut::CoconutVerifier, AuthenticatedHandler, ClientDetails, InitialAuthResult,
|
||||
SocketStream,
|
||||
},
|
||||
message_receiver::{IsActive, IsActiveRequestSender},
|
||||
},
|
||||
},
|
||||
storage::{error::StorageError, Storage},
|
||||
};
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub(crate) enum InitialAuthenticationError {
|
||||
#[error("Internal gateway storage error")]
|
||||
@@ -394,6 +404,59 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
async fn handle_duplicate_client(
|
||||
&mut self,
|
||||
address: DestinationAddressBytes,
|
||||
mut is_active_request_tx: IsActiveRequestSender,
|
||||
) -> Result<(), InitialAuthenticationError> {
|
||||
// Ask the other connection to ping if they are still active.
|
||||
// Use a oneshot channel to return the result to us
|
||||
let (ping_result_sender, ping_result_receiver) = oneshot::channel();
|
||||
log::debug!("Asking other connection handler to ping the connected client to see if it is still active");
|
||||
if let Err(err) = is_active_request_tx.send(ping_result_sender).await {
|
||||
warn!("Failed to send ping request to other handler: {err}");
|
||||
}
|
||||
|
||||
// Wait for the reply
|
||||
match tokio::time::timeout(Duration::from_millis(2000), ping_result_receiver).await {
|
||||
Ok(Ok(res)) => {
|
||||
match res {
|
||||
IsActive::NotActive => {
|
||||
// The other handler reported that the client is not active, so we can
|
||||
// disconnect the other client and continue with this connection.
|
||||
log::debug!("Other handler reports it is not active");
|
||||
self.active_clients_store.disconnect(address);
|
||||
}
|
||||
IsActive::Active => {
|
||||
// The other handled reported a positive reply, so we have to assume it's
|
||||
// still active and disconnect this connection.
|
||||
log::info!("Other handler reports it is active");
|
||||
return Err(InitialAuthenticationError::DuplicateConnection);
|
||||
}
|
||||
IsActive::BusyPinging => {
|
||||
// The other handler is already busy pinging the client, so we have to
|
||||
// assume it's still active and disconnect this connection.
|
||||
log::debug!("Other handler reports it is already busy pinging the client");
|
||||
return Err(InitialAuthenticationError::DuplicateConnection);
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(Err(_)) => {
|
||||
// Other channel failed to reply (the channel sender probably dropped)
|
||||
log::info!("Other connection failed to reply, disconnecting it in favour of this new connection");
|
||||
self.active_clients_store.disconnect(address);
|
||||
}
|
||||
Err(_) => {
|
||||
// Timeout waiting for reply
|
||||
log::warn!(
|
||||
"Other connection timed out, disconnecting it in favour of this new connection"
|
||||
);
|
||||
self.active_clients_store.disconnect(address);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Tries to handle the received authentication request by checking correctness of the received data.
|
||||
///
|
||||
/// # Arguments
|
||||
@@ -418,8 +481,11 @@ where
|
||||
let encrypted_address = EncryptedAddressBytes::try_from_base58_string(enc_address)?;
|
||||
let iv = IV::try_from_base58_string(iv)?;
|
||||
|
||||
if self.active_clients_store.get(address).is_some() {
|
||||
return Err(InitialAuthenticationError::DuplicateConnection);
|
||||
// Check for duplicate clients
|
||||
if let Some(client_tx) = self.active_clients_store.get(address) {
|
||||
log::warn!("Detected duplicate connection for client: {}", address);
|
||||
self.handle_duplicate_client(address, client_tx.is_active_request_sender)
|
||||
.await?;
|
||||
}
|
||||
|
||||
let shared_keys = self
|
||||
@@ -606,12 +672,19 @@ where
|
||||
}
|
||||
|
||||
return if let Some(client_details) = auth_result.client_details {
|
||||
self.active_clients_store
|
||||
.insert(client_details.address, mix_sender);
|
||||
// Channel for handlers to ask other handlers if they are still active.
|
||||
let (is_active_request_sender, is_active_request_receiver) =
|
||||
mpsc::unbounded();
|
||||
self.active_clients_store.insert(
|
||||
client_details.address,
|
||||
mix_sender,
|
||||
is_active_request_sender,
|
||||
);
|
||||
Some(AuthenticatedHandler::upgrade(
|
||||
self,
|
||||
client_details,
|
||||
mix_receiver,
|
||||
is_active_request_receiver,
|
||||
))
|
||||
} else {
|
||||
None
|
||||
|
||||
@@ -100,7 +100,7 @@ pub(crate) async fn handle_connection<R, S, St>(
|
||||
.await
|
||||
{
|
||||
None => {
|
||||
trace!("received shutdown signal while performing initial authetnication");
|
||||
trace!("received shutdown signal while performing initial authentication");
|
||||
return;
|
||||
}
|
||||
Some(None) => {
|
||||
|
||||
@@ -1,7 +1,20 @@
|
||||
// Copyright 2020 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use futures::channel::mpsc;
|
||||
use futures::channel::{mpsc, oneshot};
|
||||
|
||||
pub(crate) type MixMessageSender = mpsc::UnboundedSender<Vec<Vec<u8>>>;
|
||||
pub(crate) type MixMessageReceiver = mpsc::UnboundedReceiver<Vec<Vec<u8>>>;
|
||||
|
||||
// Channels used for one handler to requester another handler to check that the client is still
|
||||
// active. The result is then passed back to the requesting handler in the oneshot channel.
|
||||
pub(crate) type IsActiveRequestSender = mpsc::UnboundedSender<IsActiveResultSender>;
|
||||
pub(crate) type IsActiveRequestReceiver = mpsc::UnboundedReceiver<IsActiveResultSender>;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) enum IsActive {
|
||||
Active,
|
||||
NotActive,
|
||||
BusyPinging,
|
||||
}
|
||||
pub(crate) type IsActiveResultSender = oneshot::Sender<IsActive>;
|
||||
|
||||
@@ -70,9 +70,9 @@ impl<St: Storage> ConnectionHandler<St> {
|
||||
}
|
||||
|
||||
fn update_clients_store_cache_entry(&mut self, client_address: DestinationAddressBytes) {
|
||||
if let Some(client_sender) = self.active_clients_store.get(client_address) {
|
||||
if let Some(client_senders) = self.active_clients_store.get(client_address) {
|
||||
self.clients_store_cache
|
||||
.insert(client_address, client_sender);
|
||||
.insert(client_address, client_senders.mix_message_sender);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "nym-mixnode"
|
||||
version = "1.1.28"
|
||||
version = "1.1.29"
|
||||
authors = [
|
||||
"Dave Hrycyszyn <futurechimp@users.noreply.github.com>",
|
||||
"Jędrzej Stuczyński <andrew@nymtech.net>",
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "nym-api"
|
||||
version = "1.1.28"
|
||||
version = "1.1.29"
|
||||
authors = [
|
||||
"Dave Hrycyszyn <futurechimp@users.noreply.github.com>",
|
||||
"Jędrzej Stuczyński <andrew@nymtech.net>",
|
||||
|
||||
@@ -2,6 +2,14 @@
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [v1.1.20-twix] (2023-09-05)
|
||||
|
||||
- nym-connect directory error handling ([#3830])
|
||||
- NC - it should not be possible to toggle speedy mode while the connection is active ([#3816])
|
||||
|
||||
[#3830]: https://github.com/nymtech/nym/pull/3830
|
||||
[#3816]: https://github.com/nymtech/nym/issues/3816
|
||||
|
||||
## [v1.1.19-snickers] (2023-08-29)
|
||||
|
||||
- NymConnect sometimes fails to connect because the gateway it fetches from the validator-api to use is running an old version (of the gateway binary) ([#3788])
|
||||
|
||||
Generated
+16
-410
@@ -242,7 +242,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "279cf904654eeebfa37ac9bb1598880884924aab82e290aa65c9e77a0e142e06"
|
||||
dependencies = [
|
||||
"async-lock",
|
||||
"autocfg 1.1.0",
|
||||
"autocfg",
|
||||
"blocking",
|
||||
"futures-lite",
|
||||
]
|
||||
@@ -254,7 +254,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af"
|
||||
dependencies = [
|
||||
"async-lock",
|
||||
"autocfg 1.1.0",
|
||||
"autocfg",
|
||||
"cfg-if",
|
||||
"concurrent-queue",
|
||||
"futures-lite",
|
||||
@@ -284,7 +284,7 @@ checksum = "7a9d28b1d97e08915212e2e45310d47854eafa69600756fc735fb788f75199c9"
|
||||
dependencies = [
|
||||
"async-io",
|
||||
"async-lock",
|
||||
"autocfg 1.1.0",
|
||||
"autocfg",
|
||||
"blocking",
|
||||
"cfg-if",
|
||||
"event-listener",
|
||||
@@ -381,15 +381,6 @@ dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0dde43e75fd43e8a1bf86103336bc699aa8d17ad1be60c76c0bdfd4828e19b78"
|
||||
dependencies = [
|
||||
"autocfg 1.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
@@ -903,15 +894,6 @@ version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b"
|
||||
|
||||
[[package]]
|
||||
name = "cloudabi"
|
||||
version = "0.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cocoa"
|
||||
version = "0.24.1"
|
||||
@@ -987,18 +969,6 @@ dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "comfy-table"
|
||||
version = "6.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7e959d788268e3bf9d35ace83e81b124190378e4c91c9067524675e33394b8ba"
|
||||
dependencies = [
|
||||
"crossterm",
|
||||
"strum 0.24.1",
|
||||
"strum_macros 0.24.3",
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "concurrent-queue"
|
||||
version = "2.2.0"
|
||||
@@ -1239,7 +1209,7 @@ version = "0.9.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7"
|
||||
dependencies = [
|
||||
"autocfg 1.1.0",
|
||||
"autocfg",
|
||||
"cfg-if",
|
||||
"crossbeam-utils",
|
||||
"memoffset 0.9.0",
|
||||
@@ -1265,31 +1235,6 @@ dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossterm"
|
||||
version = "0.26.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a84cda67535339806297f1b331d6dd6320470d2a0fe65381e79ee9e156dd3d13"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"crossterm_winapi",
|
||||
"libc",
|
||||
"mio",
|
||||
"parking_lot 0.12.1",
|
||||
"signal-hook",
|
||||
"signal-hook-mio",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossterm_winapi"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crypto-bigint"
|
||||
version = "0.4.9"
|
||||
@@ -2221,12 +2166,6 @@ version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c8cbd1169bd7b4a0a20d92b9af7a7e0422888bd38a6f5ec29c1fd8c1558a272e"
|
||||
|
||||
[[package]]
|
||||
name = "fuchsia-cprng"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
|
||||
|
||||
[[package]]
|
||||
name = "funty"
|
||||
version = "2.0.0"
|
||||
@@ -3204,7 +3143,7 @@ version = "1.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
|
||||
dependencies = [
|
||||
"autocfg 1.1.0",
|
||||
"autocfg",
|
||||
"hashbrown 0.12.3",
|
||||
"serde",
|
||||
]
|
||||
@@ -3256,19 +3195,6 @@ dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "interprocess"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81f2533f3be42fffe3b5e63b71aeca416c1c3bc33e4e27be018521e76b1f38fb"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"rustc_version",
|
||||
"to_method",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "io-lifetimes"
|
||||
version = "1.0.11"
|
||||
@@ -3567,7 +3493,7 @@ version = "0.4.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16"
|
||||
dependencies = [
|
||||
"autocfg 1.1.0",
|
||||
"autocfg",
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
@@ -3670,7 +3596,7 @@ version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4"
|
||||
dependencies = [
|
||||
"autocfg 1.1.0",
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3679,7 +3605,7 @@ version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c"
|
||||
dependencies = [
|
||||
"autocfg 1.1.0",
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3717,7 +3643,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
@@ -3843,7 +3768,7 @@ version = "0.1.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
|
||||
dependencies = [
|
||||
"autocfg 1.1.0",
|
||||
"autocfg",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
@@ -3853,7 +3778,7 @@ version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0"
|
||||
dependencies = [
|
||||
"autocfg 1.1.0",
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
@@ -3864,7 +3789,7 @@ version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2"
|
||||
dependencies = [
|
||||
"autocfg 1.1.0",
|
||||
"autocfg",
|
||||
"libm",
|
||||
]
|
||||
|
||||
@@ -3950,59 +3875,9 @@ dependencies = [
|
||||
"pretty_env_logger",
|
||||
"semver 0.11.0",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"vergen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nym-cli-commands"
|
||||
version = "1.0.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"base64 0.13.1",
|
||||
"bip39",
|
||||
"bs58 0.4.0",
|
||||
"cfg-if",
|
||||
"clap",
|
||||
"comfy-table",
|
||||
"cosmrs",
|
||||
"cosmwasm-std",
|
||||
"cw-utils",
|
||||
"handlebars",
|
||||
"humantime-serde",
|
||||
"k256 0.13.1",
|
||||
"log",
|
||||
"nym-bandwidth-controller",
|
||||
"nym-bin-common",
|
||||
"nym-client-core",
|
||||
"nym-coconut-bandwidth-contract-common",
|
||||
"nym-coconut-dkg-common",
|
||||
"nym-config",
|
||||
"nym-contracts-common",
|
||||
"nym-credential-storage",
|
||||
"nym-credential-utils",
|
||||
"nym-credentials",
|
||||
"nym-crypto",
|
||||
"nym-mixnet-contract-common",
|
||||
"nym-multisig-contract-common",
|
||||
"nym-name-service-common",
|
||||
"nym-network-defaults",
|
||||
"nym-pemstore",
|
||||
"nym-service-provider-directory-common",
|
||||
"nym-sphinx",
|
||||
"nym-types",
|
||||
"nym-validator-client",
|
||||
"nym-vesting-contract-common",
|
||||
"rand 0.6.5",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tap",
|
||||
"thiserror",
|
||||
"time",
|
||||
"toml 0.5.11",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nym-client-core"
|
||||
version = "1.1.15"
|
||||
@@ -4117,11 +3992,10 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-connect"
|
||||
version = "1.1.19"
|
||||
version = "1.1.20"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bip39",
|
||||
"bs58 0.4.0",
|
||||
"dirs 4.0.0",
|
||||
"dotenvy",
|
||||
"eyre",
|
||||
@@ -4132,7 +4006,6 @@ dependencies = [
|
||||
"log",
|
||||
"nym-api-requests",
|
||||
"nym-bin-common",
|
||||
"nym-cli-commands",
|
||||
"nym-client-core",
|
||||
"nym-config",
|
||||
"nym-contracts-common",
|
||||
@@ -4158,7 +4031,6 @@ dependencies = [
|
||||
"tauri-build",
|
||||
"tauri-codegen",
|
||||
"tauri-macros",
|
||||
"tauri-plugin-deep-link",
|
||||
"tempfile",
|
||||
"thiserror",
|
||||
"time",
|
||||
@@ -4192,21 +4064,6 @@ dependencies = [
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nym-credential-utils"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"log",
|
||||
"nym-bandwidth-controller",
|
||||
"nym-client-core",
|
||||
"nym-config",
|
||||
"nym-credential-storage",
|
||||
"nym-credentials",
|
||||
"nym-validator-client",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nym-credentials"
|
||||
version = "0.1.0"
|
||||
@@ -4721,30 +4578,6 @@ dependencies = [
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nym-types"
|
||||
version = "1.0.0"
|
||||
dependencies = [
|
||||
"cosmrs",
|
||||
"cosmwasm-std",
|
||||
"eyre",
|
||||
"itertools",
|
||||
"log",
|
||||
"nym-coconut-interface",
|
||||
"nym-config",
|
||||
"nym-mixnet-contract-common",
|
||||
"nym-validator-client",
|
||||
"nym-vesting-contract-common",
|
||||
"reqwest",
|
||||
"schemars",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"strum 0.23.0",
|
||||
"thiserror",
|
||||
"ts-rs",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nym-validator-client"
|
||||
version = "0.1.0"
|
||||
@@ -4826,28 +4659,6 @@ dependencies = [
|
||||
"objc_id",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc-sys"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "99e1d07c6eab1ce8b6382b8e3c7246fe117ff3f8b34be065f5ebace6749fe845"
|
||||
|
||||
[[package]]
|
||||
name = "objc2"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "559c5a40fdd30eb5e344fbceacf7595a81e242529fb4e21cf5f43fb4f11ff98d"
|
||||
dependencies = [
|
||||
"objc-sys",
|
||||
"objc2-encode",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc2-encode"
|
||||
version = "3.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d079845b37af429bfe5dfa76e6d087d788031045b25cfc6fd898486fd9847666"
|
||||
|
||||
[[package]]
|
||||
name = "objc_exception"
|
||||
version = "0.1.2"
|
||||
@@ -5386,7 +5197,7 @@ version = "2.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce"
|
||||
dependencies = [
|
||||
"autocfg 1.1.0",
|
||||
"autocfg",
|
||||
"bitflags 1.3.2",
|
||||
"cfg-if",
|
||||
"concurrent-queue",
|
||||
@@ -5555,25 +5366,6 @@ version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09"
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
|
||||
dependencies = [
|
||||
"autocfg 0.1.8",
|
||||
"libc",
|
||||
"rand_chacha 0.1.1",
|
||||
"rand_core 0.4.2",
|
||||
"rand_hc 0.1.0",
|
||||
"rand_isaac",
|
||||
"rand_jitter",
|
||||
"rand_os",
|
||||
"rand_pcg 0.1.2",
|
||||
"rand_xorshift",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.7.3"
|
||||
@@ -5584,8 +5376,8 @@ dependencies = [
|
||||
"libc",
|
||||
"rand_chacha 0.2.2",
|
||||
"rand_core 0.5.1",
|
||||
"rand_hc 0.2.0",
|
||||
"rand_pcg 0.2.1",
|
||||
"rand_hc",
|
||||
"rand_pcg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -5599,16 +5391,6 @@ dependencies = [
|
||||
"rand_core 0.6.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef"
|
||||
dependencies = [
|
||||
"autocfg 0.1.8",
|
||||
"rand_core 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.2.2"
|
||||
@@ -5629,21 +5411,6 @@ dependencies = [
|
||||
"rand_core 0.6.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
|
||||
dependencies = [
|
||||
"rand_core 0.4.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.5.1"
|
||||
@@ -5672,15 +5439,6 @@ dependencies = [
|
||||
"rand 0.7.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_hc"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4"
|
||||
dependencies = [
|
||||
"rand_core 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_hc"
|
||||
version = "0.2.0"
|
||||
@@ -5690,50 +5448,6 @@ dependencies = [
|
||||
"rand_core 0.5.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_isaac"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08"
|
||||
dependencies = [
|
||||
"rand_core 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_jitter"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_core 0.4.2",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_os"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071"
|
||||
dependencies = [
|
||||
"cloudabi",
|
||||
"fuchsia-cprng",
|
||||
"libc",
|
||||
"rand_core 0.4.2",
|
||||
"rdrand",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_pcg"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44"
|
||||
dependencies = [
|
||||
"autocfg 0.1.8",
|
||||
"rand_core 0.4.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_pcg"
|
||||
version = "0.2.1"
|
||||
@@ -5743,15 +5457,6 @@ dependencies = [
|
||||
"rand_core 0.5.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_xorshift"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c"
|
||||
dependencies = [
|
||||
"rand_core 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "raw-window-handle"
|
||||
version = "0.5.2"
|
||||
@@ -5780,15 +5485,6 @@ dependencies = [
|
||||
"num_cpus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rdrand"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
|
||||
dependencies = [
|
||||
"rand_core 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.16"
|
||||
@@ -6635,17 +6331,6 @@ dependencies = [
|
||||
"signal-hook-registry",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-mio"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"mio",
|
||||
"signal-hook",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-registry"
|
||||
version = "1.4.1"
|
||||
@@ -6693,7 +6378,7 @@ version = "0.4.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d"
|
||||
dependencies = [
|
||||
"autocfg 1.1.0",
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -7074,47 +6759,6 @@ version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||
|
||||
[[package]]
|
||||
name = "strum"
|
||||
version = "0.23.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cae14b91c7d11c9a851d3fbc80a963198998c2a64eec840477fa92d8ce9b70bb"
|
||||
dependencies = [
|
||||
"strum_macros 0.23.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strum"
|
||||
version = "0.24.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f"
|
||||
|
||||
[[package]]
|
||||
name = "strum_macros"
|
||||
version = "0.23.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5bb0dc7ee9c15cea6199cde9a127fa16a4c5819af85395457ad72d68edc85a38"
|
||||
dependencies = [
|
||||
"heck 0.3.3",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rustversion",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strum_macros"
|
||||
version = "0.24.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59"
|
||||
dependencies = [
|
||||
"heck 0.4.1",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rustversion",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "subtle"
|
||||
version = "1.0.0"
|
||||
@@ -7385,22 +7029,6 @@ dependencies = [
|
||||
"tauri-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-deep-link"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4536f5f6602e8fdfaa7b3b185076c2a0704f8eb7015f4e58461eb483ec3ed1f8"
|
||||
dependencies = [
|
||||
"dirs 5.0.1",
|
||||
"interprocess",
|
||||
"log",
|
||||
"objc2",
|
||||
"once_cell",
|
||||
"tauri-utils",
|
||||
"windows-sys 0.48.0",
|
||||
"winreg 0.50.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tauri-runtime"
|
||||
version = "0.14.0"
|
||||
@@ -7704,12 +7332,6 @@ version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||
|
||||
[[package]]
|
||||
name = "to_method"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c7c4ceeeca15c8384bbc3e011dbd8fccb7f068a440b752b7d9b32ceb0ca0e2e8"
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.31.0"
|
||||
@@ -8050,12 +7672,6 @@ version = "1.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
|
||||
|
||||
[[package]]
|
||||
name = "unicode_categories"
|
||||
version = "0.1.1"
|
||||
@@ -8805,16 +8421,6 @@ dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winreg"
|
||||
version = "0.50.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wry"
|
||||
version = "0.24.3"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nym/nym-connect",
|
||||
"version": "1.1.19",
|
||||
"version": "1.1.20",
|
||||
"main": "index.js",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "nym-connect"
|
||||
version = "1.1.19"
|
||||
version = "1.1.20"
|
||||
description = "nym-connect"
|
||||
authors = ["Nym Technologies SA"]
|
||||
license = ""
|
||||
@@ -21,7 +21,6 @@ tauri-macros = "^1.2.1"
|
||||
[dependencies]
|
||||
anyhow = "1.0"
|
||||
bip39 = { version = "2.0.0", features = ["zeroize"] }
|
||||
bs58 = "0.4"
|
||||
dirs = "4.0"
|
||||
eyre = "0.6.5"
|
||||
fix-path-env = { git = "https://github.com/tauri-apps/fix-path-env-rs", branch = "release"}
|
||||
@@ -39,7 +38,6 @@ serde_json = "1.0"
|
||||
serde_repr = "0.1"
|
||||
tap = "1.0.1"
|
||||
tauri = { version = "^1.2.2", features = ["clipboard-write-text", "macos-private-api", "notification-all", "shell-open", "system-tray", "updater", "window-close", "window-minimize", "window-start-dragging"] }
|
||||
tauri-plugin-deep-link = "0.1.1"
|
||||
#tendermint-rpc = "0.23.0"
|
||||
thiserror = "1.0"
|
||||
time = { version = "0.3.17", features = ["local-offset"] }
|
||||
@@ -53,7 +51,6 @@ dotenvy = "0.15.7"
|
||||
|
||||
nym-client-core = { path = "../../../common/client-core" }
|
||||
nym-api-requests = { path = "../../../nym-api/nym-api-requests" }
|
||||
nym-cli-commands = { path = "../../../common/commands" }
|
||||
nym-contracts-common = { path = "../../../common/cosmwasm-smart-contracts/contracts-common"}
|
||||
nym-config = { path = "../../../common/config" }
|
||||
nym-crypto = { path = "../../../common/crypto" }
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
<!-- Add this file next to your tauri.conf.json file -->
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleURLTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CFBundleURLName</key>
|
||||
<!-- Obviously needs to be replaced with your app's bundle identifier -->
|
||||
<string>net.nymtech.connect</string>
|
||||
<key>CFBundleURLSchemes</key>
|
||||
<array>
|
||||
<!-- register the myapp:// and myscheme:// schemes -->
|
||||
<string>nym-connect</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1,39 +0,0 @@
|
||||
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::error::{BackendError, Result};
|
||||
use bip39::Mnemonic;
|
||||
use nym_cli_commands::coconut::issue_credentials::Args as CoconutArgs;
|
||||
use nym_cli_commands::context::{create_signing_client, get_network_details, ClientArgs};
|
||||
use std::path::PathBuf;
|
||||
use url::Url;
|
||||
|
||||
pub async fn handle_url(url: &str) -> Result<()> {
|
||||
let url = Url::parse(url)?;
|
||||
if url.scheme() != env!("CARGO_PKG_NAME") {
|
||||
return Err(BackendError::InvalidURLScheme {
|
||||
scheme: url.scheme().to_string(),
|
||||
});
|
||||
}
|
||||
let bytes = bs58::decode(url.path()).into_vec()?;
|
||||
let mnemonic = Mnemonic::from_entropy(&bytes)?;
|
||||
|
||||
let args = ClientArgs {
|
||||
config_env_file: None,
|
||||
nyxd_url: None,
|
||||
nym_api_url: None,
|
||||
mnemonic: Some(mnemonic),
|
||||
mixnet_contract_address: None,
|
||||
vesting_contract_address: None,
|
||||
};
|
||||
let network_details = get_network_details(&args)?;
|
||||
let client = create_signing_client(args, &network_details)?;
|
||||
let coconut_args = CoconutArgs {
|
||||
client_config: Default::default(),
|
||||
amount: 10,
|
||||
recovery_dir: PathBuf::default(),
|
||||
};
|
||||
nym_cli_commands::coconut::issue_credentials::execute(coconut_args, client).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -111,27 +111,6 @@ pub enum BackendError {
|
||||
url: reqwest::Url,
|
||||
status_code: reqwest::StatusCode,
|
||||
},
|
||||
|
||||
#[error("the URL provided has an unrecognized scheme: {scheme}")]
|
||||
InvalidURLScheme { scheme: String },
|
||||
|
||||
#[error("{source}")]
|
||||
BS58DecodeError {
|
||||
#[from]
|
||||
source: bs58::decode::Error,
|
||||
},
|
||||
|
||||
#[error("{source}")]
|
||||
Bip39Error {
|
||||
#[from]
|
||||
source: bip39::Error,
|
||||
},
|
||||
|
||||
#[error("{source}")]
|
||||
ContextError {
|
||||
#[from]
|
||||
source: nym_cli_commands::context::errors::ContextError,
|
||||
},
|
||||
}
|
||||
|
||||
impl Serialize for BackendError {
|
||||
|
||||
@@ -18,7 +18,6 @@ use crate::window::window_toggle;
|
||||
|
||||
mod config;
|
||||
mod constants;
|
||||
// mod deep_links;
|
||||
mod error;
|
||||
mod events;
|
||||
mod logging;
|
||||
@@ -31,7 +30,6 @@ mod tasks;
|
||||
mod window;
|
||||
|
||||
fn main() {
|
||||
tauri_plugin_deep_link::prepare("nym-connect");
|
||||
dotenvy::dotenv().ok();
|
||||
|
||||
setup_env(env::args().nth(1).map(PathBuf::from).as_ref());
|
||||
@@ -114,28 +112,7 @@ fn main() {
|
||||
);
|
||||
}
|
||||
})
|
||||
.setup(move |app| {
|
||||
let handle = app.handle();
|
||||
tauri_plugin_deep_link::register(env!("CARGO_PKG_NAME"), move |request| {
|
||||
let window = handle.windows();
|
||||
log::info!("Windows: {:?}", window.keys());
|
||||
if let Err(err) = window.emit("scheme-request-received", request) {
|
||||
log::error!("Failed to emit tauri event: {err}");
|
||||
}
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
// If you also need the url when the primary instance was started by the custom scheme, you currently have to read it yourself
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
// on macos the plugin handles this (macos doesn't use cli args for the url)
|
||||
if let Some(arg) = env::args().nth(1) {
|
||||
if let Err(e) = deep_links::handle_url(&arg) {
|
||||
log::error!("Could not handle URL {}: {:?}", request, e);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(crate::logging::setup_logging(app.app_handle(), monitoring)?)
|
||||
})
|
||||
.setup(move |app| Ok(crate::logging::setup_logging(app.app_handle(), monitoring)?))
|
||||
.system_tray(create_tray_menu())
|
||||
.on_system_tray_event(tray_menu_event_handler)
|
||||
.run(context)
|
||||
|
||||
@@ -8,11 +8,10 @@ use tokio::sync::RwLock;
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn start_connecting(
|
||||
coconut_enabled: bool,
|
||||
state: tauri::State<'_, Arc<RwLock<State>>>,
|
||||
window: tauri::Window<tauri::Wry>,
|
||||
) -> Result<ConnectResult> {
|
||||
log::info!("Start connecting with coconut enabled: {}", coconut_enabled);
|
||||
log::trace!("Start connecting");
|
||||
|
||||
let (msg_receiver, exit_status_receiver) = {
|
||||
let mut state_w = state.write().await;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"package": {
|
||||
"productName": "nym-connect",
|
||||
"version": "1.1.19"
|
||||
"version": "1.1.20"
|
||||
},
|
||||
"build": {
|
||||
"distDir": "../dist",
|
||||
|
||||
@@ -38,7 +38,7 @@ export type TClientContext = {
|
||||
setShowInfoModal: (show: boolean) => void;
|
||||
setServiceProvider: () => void;
|
||||
setGateway: () => void;
|
||||
startConnecting: (coconut_enabled: boolean) => Promise<void>;
|
||||
startConnecting: () => Promise<void>;
|
||||
startDisconnecting: () => Promise<void>;
|
||||
setUserDefinedGateway: React.Dispatch<React.SetStateAction<UserDefinedGateway>>;
|
||||
setUserDefinedSPAddress: React.Dispatch<React.SetStateAction<UserDefinedSPAddress>>;
|
||||
@@ -139,6 +139,15 @@ export const ClientContextProvider: FCWithChildren = ({ children }) => {
|
||||
setGateways(fetchedGateways);
|
||||
};
|
||||
|
||||
useEvents({
|
||||
onError: (e) => {
|
||||
setError(e);
|
||||
Sentry.captureException(e);
|
||||
},
|
||||
onGatewayPerformanceChange: (performance) => setGatewayPerformance(performance),
|
||||
onStatusChange: (status) => setConnectionStatus(status),
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
initialiseApp();
|
||||
}, []);
|
||||
@@ -151,9 +160,9 @@ export const ClientContextProvider: FCWithChildren = ({ children }) => {
|
||||
})();
|
||||
}, []);
|
||||
|
||||
const startConnecting = useCallback(async (value: boolean) => {
|
||||
const startConnecting = useCallback(async () => {
|
||||
try {
|
||||
await invoke('start_connecting', { coconutEnabled: value });
|
||||
await invoke('start_connecting');
|
||||
} catch (e) {
|
||||
setError({ title: 'Could not connect', message: e as string });
|
||||
console.log(e);
|
||||
@@ -234,25 +243,6 @@ export const ClientContextProvider: FCWithChildren = ({ children }) => {
|
||||
await getUserData();
|
||||
};
|
||||
|
||||
const handleSchemeRequest = async () => {
|
||||
if (connectionStatus === 'disconnected') {
|
||||
await setServiceProvider();
|
||||
await setGateway();
|
||||
await startConnecting(true);
|
||||
setConnectedSince(DateTime.now());
|
||||
}
|
||||
};
|
||||
|
||||
useEvents({
|
||||
onError: (e) => {
|
||||
setError(e);
|
||||
Sentry.captureException(e);
|
||||
},
|
||||
onGatewayPerformanceChange: (performance) => setGatewayPerformance(performance),
|
||||
onStatusChange: (status) => setConnectionStatus(status),
|
||||
onSchemeRequest: handleSchemeRequest,
|
||||
});
|
||||
|
||||
const contextValue = useMemo(
|
||||
() => ({
|
||||
mode,
|
||||
|
||||
@@ -11,12 +11,10 @@ export const useEvents = ({
|
||||
onError,
|
||||
onStatusChange,
|
||||
onGatewayPerformanceChange,
|
||||
onSchemeRequest,
|
||||
}: {
|
||||
onError: (error: Error) => void;
|
||||
onStatusChange: (status: ConnectionStatusKind) => void;
|
||||
onGatewayPerformanceChange: (status: GatewayPerformance) => void;
|
||||
onSchemeRequest: () => Promise<void>;
|
||||
}) => {
|
||||
const timerId = useRef<NodeJS.Timeout>();
|
||||
|
||||
@@ -67,13 +65,6 @@ export const useEvents = ({
|
||||
unlisten.push(result);
|
||||
});
|
||||
|
||||
listen('scheme-request-received', (e: TauriEvent) => {
|
||||
console.log(e);
|
||||
onSchemeRequest();
|
||||
}).then((result) => {
|
||||
unlisten.push(result);
|
||||
});
|
||||
|
||||
return () => {
|
||||
unlisten.forEach((unsubscribe) => unsubscribe());
|
||||
};
|
||||
|
||||
@@ -19,7 +19,7 @@ export const ConnectionPage = () => {
|
||||
Sentry.captureMessage('start connect', 'info');
|
||||
await context.setServiceProvider();
|
||||
await context.setGateway();
|
||||
await context.startConnecting(false);
|
||||
await context.startConnecting();
|
||||
context.setConnectedSince(DateTime.now());
|
||||
context.setShowInfoModal(true);
|
||||
break;
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
[package]
|
||||
name = "nym-payment-manager"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0"
|
||||
bip39 = { workspace = true }
|
||||
clap = { version = "4.0", features = ["cargo", "derive"] }
|
||||
lazy_static = "1.4.0"
|
||||
log = { workspace = true }
|
||||
schemars = { version = "0.8", features = ["preserve_order"] }
|
||||
rocket = { version = "0.5.0-rc.2", features = ["json"] }
|
||||
rocket_cors = { git = "https://github.com/lawliet89/rocket_cors", rev = "dfd3662c49e2f6fc37df35091cb94d82f7fb5915" }
|
||||
rocket_okapi = { version = "0.8.0-rc.2", features = ["swagger"] }
|
||||
serde = { workspace = true }
|
||||
sqlx = { version = "0.6.2", features = [
|
||||
"runtime-tokio-rustls",
|
||||
"sqlite",
|
||||
"macros",
|
||||
"migrate",
|
||||
] }
|
||||
thiserror = "1.0"
|
||||
tokio = { version = "1.24.1", features = [
|
||||
"rt-multi-thread",
|
||||
"macros",
|
||||
"signal",
|
||||
"time",
|
||||
] }
|
||||
|
||||
nym-bin-common = { path = "../../common/bin-common" }
|
||||
nym-network-defaults = { path = "../../common/network-defaults" }
|
||||
nym-payment-manager-common = { path = "../../common/payment-manager" }
|
||||
nym-task = { path = "../../common/task" }
|
||||
nym-validator-client = { path = "../../common/client-libs/validator-client" }
|
||||
|
||||
[build-dependencies]
|
||||
sqlx = { version = "0.6.2", features = [
|
||||
"runtime-tokio-rustls",
|
||||
"sqlite",
|
||||
"macros",
|
||||
"migrate",
|
||||
] }
|
||||
tokio = { version = "1.24.1", features = ["rt-multi-thread", "macros"] }
|
||||
@@ -1,28 +0,0 @@
|
||||
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use sqlx::{Connection, SqliteConnection};
|
||||
use std::env;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
let out_dir = env::var("OUT_DIR").unwrap();
|
||||
let database_path = format!("{}/nym-payment-manager-example.sqlite", out_dir);
|
||||
|
||||
let mut conn = SqliteConnection::connect(&format!("sqlite://{}?mode=rwc", database_path))
|
||||
.await
|
||||
.expect("Failed to create SQLx database connection");
|
||||
|
||||
sqlx::migrate!("./migrations")
|
||||
.run(&mut conn)
|
||||
.await
|
||||
.expect("Failed to perform SQLx migrations");
|
||||
|
||||
#[cfg(target_family = "unix")]
|
||||
println!("cargo:rustc-env=DATABASE_URL=sqlite://{}", &database_path);
|
||||
|
||||
#[cfg(target_family = "windows")]
|
||||
// for some strange reason we need to add a leading `/` to the windows path even though it's
|
||||
// not a valid windows path... but hey, it works...
|
||||
println!("cargo:rustc-env=DATABASE_URL=sqlite:///{}", &database_path);
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
CREATE TABLE payments
|
||||
(
|
||||
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
serial_number VARCHAR NOT NULL UNIQUE,
|
||||
unyms_bought INTEGER NOT NULL,
|
||||
paid BOOLEAN NOT NULL
|
||||
);
|
||||
@@ -1,31 +0,0 @@
|
||||
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use clap::Parser;
|
||||
use lazy_static::lazy_static;
|
||||
use nym_bin_common::bin_info;
|
||||
|
||||
lazy_static! {
|
||||
pub static ref PRETTY_BUILD_INFORMATION: String = bin_info!().pretty_print();
|
||||
}
|
||||
|
||||
// Helper for passing LONG_VERSION to clap
|
||||
fn pretty_build_info_static() -> &'static str {
|
||||
&PRETTY_BUILD_INFORMATION
|
||||
}
|
||||
|
||||
#[derive(Parser)]
|
||||
#[clap(author = "Nymtech", version, long_version = pretty_build_info_static(), about)]
|
||||
pub(crate) struct CliArgs {
|
||||
/// Path pointing to an env file that configures the Payment Manager.
|
||||
#[clap(short, long)]
|
||||
pub(crate) config_env_file: Option<std::path::PathBuf>,
|
||||
|
||||
/// Mnemonic of the Nym account holding the funds to be converted after successful payments
|
||||
#[clap(short, long)]
|
||||
pub(crate) mnemonic: bip39::Mnemonic,
|
||||
|
||||
/// Path pointing to the SQLite database containing payment data.
|
||||
#[clap(short, long)]
|
||||
pub(crate) db_path: std::path::PathBuf,
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::error::Error;
|
||||
use nym_network_defaults::NymNetworkDetails;
|
||||
use nym_validator_client::{nyxd, DirectSigningHttpRpcNyxdClient};
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::RwLock;
|
||||
|
||||
pub(crate) struct Client(pub(crate) Arc<RwLock<DirectSigningHttpRpcNyxdClient>>);
|
||||
|
||||
impl Clone for Client {
|
||||
fn clone(&self) -> Self {
|
||||
Client(Arc::clone(&self.0))
|
||||
}
|
||||
}
|
||||
|
||||
impl Client {
|
||||
pub(crate) fn new(
|
||||
details: &NymNetworkDetails,
|
||||
mnemonic: &bip39::Mnemonic,
|
||||
) -> Result<Self, Error> {
|
||||
let client_config = nyxd::Config::try_from_nym_network_details(details)?;
|
||||
let endpoint = details
|
||||
.endpoints
|
||||
.first()
|
||||
.ok_or(Error::EmptyValidatorList)?
|
||||
.nyxd_url
|
||||
.as_str();
|
||||
|
||||
let inner = DirectSigningHttpRpcNyxdClient::connect_with_mnemonic(
|
||||
client_config,
|
||||
endpoint,
|
||||
mnemonic.clone(),
|
||||
)?;
|
||||
|
||||
Ok(Client(Arc::new(RwLock::new(inner))))
|
||||
}
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use rocket::http::{ContentType, Status};
|
||||
use rocket::response::Responder;
|
||||
use rocket::{response, Request, Response};
|
||||
use rocket_okapi::gen::OpenApiGenerator;
|
||||
use rocket_okapi::okapi::openapi3::Responses;
|
||||
use rocket_okapi::response::OpenApiResponderInner;
|
||||
use rocket_okapi::util::ensure_status_code_exists;
|
||||
use std::io::Cursor;
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum Error {
|
||||
#[error("Database experienced an internal error - {0}")]
|
||||
InternalDatabaseError(#[from] sqlx::Error),
|
||||
|
||||
#[error("SQL migrate error - {0}")]
|
||||
DatabaseMigrateError(#[from] sqlx::migrate::MigrateError),
|
||||
|
||||
#[error("NyxdError - {0}")]
|
||||
NyxdError(#[from] nym_validator_client::nyxd::error::NyxdError),
|
||||
|
||||
#[error("Invalid payment requested")]
|
||||
InvalidPaymentRequest,
|
||||
|
||||
#[error("Bad deposit address")]
|
||||
BadAddress,
|
||||
|
||||
#[error("Empty list of validators")]
|
||||
EmptyValidatorList,
|
||||
}
|
||||
|
||||
impl<'r, 'o: 'r> Responder<'r, 'o> for Error {
|
||||
fn respond_to(self, _: &'r Request<'_>) -> response::Result<'o> {
|
||||
let err_msg = self.to_string();
|
||||
Response::build()
|
||||
.header(ContentType::Plain)
|
||||
.sized_body(err_msg.len(), Cursor::new(err_msg))
|
||||
.status(Status::BadRequest)
|
||||
.ok()
|
||||
}
|
||||
}
|
||||
|
||||
impl OpenApiResponderInner for Error {
|
||||
fn responses(_gen: &mut OpenApiGenerator) -> rocket_okapi::Result<Responses> {
|
||||
let mut responses = Responses::default();
|
||||
ensure_status_code_exists(&mut responses, 404);
|
||||
Ok(responses)
|
||||
}
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::cli::CliArgs;
|
||||
use crate::client::Client;
|
||||
use crate::state::{Config, State};
|
||||
use crate::storage::Storage;
|
||||
use anyhow::Result;
|
||||
use nym_network_defaults::NymNetworkDetails;
|
||||
use rocket::http::Method;
|
||||
use rocket::{Ignite, Rocket, Route};
|
||||
use rocket_cors::{AllowedHeaders, AllowedOrigins, Cors};
|
||||
use rocket_okapi::okapi::openapi3::OpenApi;
|
||||
use rocket_okapi::settings::OpenApiSettings;
|
||||
use rocket_okapi::swagger_ui::make_swagger_ui;
|
||||
use rocket_okapi::{mount_endpoints_and_merged_docs, openapi_get_routes_spec};
|
||||
|
||||
pub(crate) mod openapi;
|
||||
pub(crate) mod routes;
|
||||
|
||||
pub(crate) fn routes(settings: &OpenApiSettings) -> (Vec<Route>, OpenApi) {
|
||||
openapi_get_routes_spec![
|
||||
settings: routes::claim_payment,
|
||||
]
|
||||
}
|
||||
|
||||
fn setup_cors() -> Result<Cors> {
|
||||
let allowed_origins = AllowedOrigins::all();
|
||||
|
||||
// You can also deserialize this
|
||||
let cors = rocket_cors::CorsOptions {
|
||||
allowed_origins,
|
||||
allowed_methods: vec![Method::Post].into_iter().map(From::from).collect(),
|
||||
allowed_headers: AllowedHeaders::all(),
|
||||
allow_credentials: true,
|
||||
..Default::default()
|
||||
}
|
||||
.to_cors()?;
|
||||
|
||||
Ok(cors)
|
||||
}
|
||||
|
||||
pub(crate) async fn setup_rocket(args: &CliArgs) -> Result<Rocket<Ignite>> {
|
||||
let openapi_settings = rocket_okapi::settings::OpenApiSettings::default();
|
||||
let mut rocket = rocket::build();
|
||||
let storage = Storage::init(&args.db_path).await?;
|
||||
|
||||
mount_endpoints_and_merged_docs! {
|
||||
rocket,
|
||||
"/v1".to_owned(),
|
||||
openapi_settings,
|
||||
"/" => (vec![], openapi::custom_openapi_spec()),
|
||||
"" => routes(&openapi_settings),
|
||||
}
|
||||
|
||||
let details = NymNetworkDetails::new_from_env();
|
||||
let client = Client::new(&details, &args.mnemonic)?;
|
||||
let config = Config::new(details.chain_details.mix_denom.base.clone());
|
||||
let rocket = rocket
|
||||
.manage(State::new(storage, client, config))
|
||||
.mount("/swagger", make_swagger_ui(&openapi::get_docs()))
|
||||
.attach(setup_cors()?);
|
||||
|
||||
Ok(rocket.ignite().await?)
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use rocket_okapi::okapi::openapi3::OpenApi;
|
||||
use rocket_okapi::swagger_ui::SwaggerUIConfig;
|
||||
|
||||
pub fn custom_openapi_spec() -> OpenApi {
|
||||
use rocket_okapi::okapi::openapi3::*;
|
||||
OpenApi {
|
||||
openapi: OpenApi::default_version(),
|
||||
info: Info {
|
||||
title: "Nym Payment Manager".to_owned(),
|
||||
description: None,
|
||||
terms_of_service: None,
|
||||
contact: None,
|
||||
license: None,
|
||||
version: env!("CARGO_PKG_VERSION").to_owned(),
|
||||
..Default::default()
|
||||
},
|
||||
servers: get_servers(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
fn get_servers() -> Vec<rocket_okapi::okapi::openapi3::Server> {
|
||||
if std::env::var_os("CARGO").is_some() {
|
||||
return vec![];
|
||||
}
|
||||
vec![rocket_okapi::okapi::openapi3::Server {
|
||||
url: std::env::var("OPEN_API_BASE").unwrap_or_else(|_| "/v1/".to_owned()),
|
||||
description: Some("Payment Manager".to_owned()),
|
||||
..Default::default()
|
||||
}]
|
||||
}
|
||||
|
||||
pub(crate) fn get_docs() -> SwaggerUIConfig {
|
||||
SwaggerUIConfig {
|
||||
url: "../v1/openapi.json".to_owned(),
|
||||
..SwaggerUIConfig::default()
|
||||
}
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::error::Error;
|
||||
use crate::state::State;
|
||||
use nym_payment_manager_common::PaymentResponse;
|
||||
use nym_validator_client::nyxd::{AccountId, Coin};
|
||||
use rocket::serde::json::Json;
|
||||
use rocket::{post, State as RocketState};
|
||||
use rocket_okapi::okapi::schemars;
|
||||
use rocket_okapi::openapi;
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::str::FromStr;
|
||||
|
||||
// All strings are base58 encoded representations of structs
|
||||
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
|
||||
pub struct ClaimPaymentRequestBody {
|
||||
pub serial_number: String,
|
||||
pub deposit_address: String,
|
||||
}
|
||||
|
||||
#[openapi(tag = "payment")]
|
||||
#[post("/claim_payment", data = "<claim_payment_request_body>")]
|
||||
pub async fn claim_payment(
|
||||
claim_payment_request_body: Json<ClaimPaymentRequestBody>,
|
||||
state: &RocketState<State>,
|
||||
) -> Result<Json<PaymentResponse>, Error> {
|
||||
let payment = state
|
||||
.storage
|
||||
.manager
|
||||
.get_payment(&claim_payment_request_body.serial_number)
|
||||
.await?
|
||||
.ok_or(Error::InvalidPaymentRequest)?;
|
||||
|
||||
let recipient = AccountId::from_str(&claim_payment_request_body.deposit_address)
|
||||
.map_err(|_| Error::BadAddress)?;
|
||||
let amount = vec![Coin::new(
|
||||
payment.unyms_bought as u128,
|
||||
state.config.denom(),
|
||||
)];
|
||||
state
|
||||
.client
|
||||
.0
|
||||
.read()
|
||||
.await
|
||||
.send(&recipient, amount, "deposit via payment", None)
|
||||
.await?;
|
||||
|
||||
state.storage.manager.update_payment(payment.id).await?;
|
||||
|
||||
Ok(Json(PaymentResponse {
|
||||
unyms_bought: payment.unyms_bought as u64,
|
||||
}))
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use clap::Parser;
|
||||
use nym_bin_common::logging::setup_logging;
|
||||
use nym_network_defaults::setup_env;
|
||||
use nym_task::TaskManager;
|
||||
use std::error::Error;
|
||||
|
||||
mod cli;
|
||||
mod client;
|
||||
mod error;
|
||||
mod http;
|
||||
mod state;
|
||||
mod storage;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
|
||||
setup_logging();
|
||||
let args = cli::CliArgs::parse();
|
||||
setup_env(args.config_env_file.as_ref());
|
||||
|
||||
// let's build our rocket!
|
||||
let rocket = http::setup_rocket(&args).await?;
|
||||
|
||||
// setup shutdowns
|
||||
let shutdown = TaskManager::new(10);
|
||||
let rocket_shutdown_handle = rocket.shutdown();
|
||||
|
||||
// launch rocket
|
||||
tokio::spawn(rocket.launch());
|
||||
|
||||
// wait for termination
|
||||
shutdown.catch_interrupt().await.ok();
|
||||
rocket_shutdown_handle.notify();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::client::Client;
|
||||
use crate::storage::Storage;
|
||||
|
||||
pub struct Config {
|
||||
denom: String,
|
||||
}
|
||||
|
||||
impl Config {
|
||||
pub fn new(denom: String) -> Self {
|
||||
Config { denom }
|
||||
}
|
||||
|
||||
pub fn denom(&self) -> &str {
|
||||
&self.denom
|
||||
}
|
||||
}
|
||||
|
||||
pub struct State {
|
||||
pub(crate) storage: Storage,
|
||||
pub(crate) client: Client,
|
||||
pub(crate) config: Config,
|
||||
}
|
||||
|
||||
impl State {
|
||||
pub(crate) fn new(storage: Storage, client: Client, config: Config) -> Self {
|
||||
State {
|
||||
storage,
|
||||
client,
|
||||
config,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::storage::models::Payment;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct StorageManager {
|
||||
pub(crate) connection_pool: sqlx::SqlitePool,
|
||||
}
|
||||
|
||||
// all SQL goes here
|
||||
impl StorageManager {
|
||||
pub(crate) async fn get_payment(
|
||||
&self,
|
||||
serial_number: &str,
|
||||
) -> Result<Option<Payment>, sqlx::Error> {
|
||||
sqlx::query_as!(
|
||||
Payment,
|
||||
r#"
|
||||
SELECT *
|
||||
FROM payments
|
||||
WHERE serial_number = ?
|
||||
"#,
|
||||
serial_number
|
||||
)
|
||||
.fetch_optional(&self.connection_pool)
|
||||
.await
|
||||
}
|
||||
|
||||
pub(crate) async fn update_payment(&self, id: i64) -> Result<(), sqlx::Error> {
|
||||
sqlx::query!(
|
||||
r#"
|
||||
UPDATE payments
|
||||
SET paid = true
|
||||
WHERE id = ?
|
||||
"#,
|
||||
id
|
||||
)
|
||||
.execute(&self.connection_pool)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user