Skip to content

Commit

Permalink
refactor: initial commit keygen app (#1)
Browse files Browse the repository at this point in the history
* chore: initial commit keygen app

* chore: commit refactor keygen

* chore: update .cspell.json

* chore: update .cspell.json

* chore: update conventional

* chore: test update knip

* chore: update readme

* chore: update readme

* chore: update readme

* Update package.json

---------

Co-authored-by: アレクサンダー.eth <4975670+pavlovcik@users.noreply.github.com>
  • Loading branch information
molecula451 and 0x4007 authored Mar 1, 2024
1 parent e00d6be commit 766b1ef
Show file tree
Hide file tree
Showing 45 changed files with 10,438 additions and 28 deletions.
23 changes: 20 additions & 3 deletions .cspell.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,28 @@
{
"$schema": "https://raw.githubusercontent.com/streetsidesoftware/cspell/main/cspell.schema.json",
"version": "0.2",
"ignorePaths": ["**/*.json", "**/*.css", "node_modules", "**/*.log"],
"ignorePaths": ["**/*.json", "**/*.css", "node_modules", "**/*.log", "/lib"],
"useGitignore": true,
"language": "en",
"words": ["dataurl", "devpool", "outdir", "servedir"],
"dictionaries": ["typescript", "node", "software-terms"],
"words": [
"libsodium",
"keypair",
"URLSAFE",
"scalarmult",
"URLSAFE",
"binkey",
"URLSAFE",
"binsec",
"binsec",
"binkey",
"URLSAFE",
"URLSAFE",
"scalarmult",
"dataurl",
"outdir",
"servedir",
],
"dictionaries": ["typescript", "node", "software-terms", "html"],
"import": ["@cspell/dict-typescript/cspell-ext.json", "@cspell/dict-node/cspell-ext.json", "@cspell/dict-software-terms"],
"ignoreRegExpList": ["[0-9a-fA-F]{6}"]
}
2 changes: 1 addition & 1 deletion .github/workflows/conventional-commits.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ jobs:
name: Conventional Commits
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: ubiquity/action-conventional-commits@master
28 changes: 22 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,24 @@
# `@ubiquity/ts-template`
# `@ubiquity/keygen.ubq.fi`

This template repository includes support for the following:
### Generate a New Encrypted EVM Private Key

- TypeScript
- Environment Variables
- Conventional Commits
- Automatic deployment to Cloudflare Pages
1. **Visit the Key Generation Tool**
- Navigate to the permit key generation tool on the web.

2. **Generate a Key**
- Click on the "Generate" button on the webpage to initiate the key generation process.

3. **Input Your EVM Private Key**
- In the provided plain text field, paste your EVM Private Key. Ensure that it is 32 bytes in length.

4. **Encrypt Your Private Key**
- Once you've pasted your private key, click on the "Encrypt" button. This action will encrypt your private key, enhancing its security.

5. **Update GitHub Secrets**
- Copy the newly generated private key and update it on your GitHub Actions secret. Find the field labeled `x25519_PRIVATE_KEY` and replace its content with your generated x25519 private key.

6. **Update Configuration File**
- Next, take the cipher text, which is the encrypted version of your private key, and paste it into your `ubiquibot-config.yaml` file. Look for the field labeled `evmEncryptedPrivate` and replace its content with the cipher text.

7. **Double Check**
- Ensure that you've updated the GitHub Actions secret field `x25519_PRIVATE_KEY` with your already generated x25519 private key. This double check ensures that all components are aligned and your system remains secure.
12 changes: 5 additions & 7 deletions build/esbuild-build.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
// @ts-expect-error - Could not find a declaration file for module
import esbuild from "esbuild";
const typescriptEntries = ["static/main.ts"];
// const cssEntries = ["static/style.css"];
const entries = [
...typescriptEntries,
// ...cssEntries
];
const typescriptEntries = ["static/scripts/key-generator/keygen.ts"];
const cssEntries = ["static/styles/rewards/rewards.css", "static/styles/audit-report/audit.css", "static/styles/onboarding/onboarding.css"];
export const entries = [...typescriptEntries, ...cssEntries];

export const esBuildContext: esbuild.BuildOptions = {
sourcemap: true,
Expand All @@ -19,7 +17,7 @@ export const esBuildContext: esbuild.BuildOptions = {
".ttf": "dataurl",
".svg": "dataurl",
},
outdir: "static/dist",
outdir: "static/out",
};

esbuild
Expand Down
4 changes: 2 additions & 2 deletions knip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const config: KnipConfig = {
project: ["src/**/*.ts"],
ignore: ["src/types/config.ts"],
ignoreExportsUsedInFile: true,
ignoreDependencies: [],
ignoreDependencies: ["libsodium-wrappers", "eslint-config-prettier", "eslint-plugin-prettier"],
};

export default config;
export default config;
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "ts-template",
"version": "1.0.0",
"description": "Template repository with TypeScript support.",
"description": "X25519 Cipher generator for Ubiquity",
"main": "build/index.ts",
"author": "Ubiquity DAO",
"license": "MIT",
Expand All @@ -27,7 +27,8 @@
"open-source"
],
"dependencies": {
"dotenv": "^16.4.4"
"dotenv": "^16.4.4",
"libsodium-wrappers": "^0.7.13"
},
"devDependencies": {
"@commitlint/cli": "^18.6.1",
Expand Down
41 changes: 34 additions & 7 deletions static/index.html
Original file line number Diff line number Diff line change
@@ -1,13 +1,40 @@
<!doctype html>
<html lang="en">
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Ubiquity TypeScript Template</title>
<link rel="stylesheet" href="style.css" />
<title>Key Generator</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link href="out/styles/onboarding/onboarding.css" rel="stylesheet" />
</head>
<body>
<h1>Ubiquity TypeScript Template</h1>
<script type="module" src="dist/main.js"></script>
<div class="container" id="keyGenContent">
<h1 class="title">Key Generator</h1>
<div class="mb-3">
<label for="privKey" class="form-label">x25519_PRIVATE_KEY</label>
<input type="text" class="form-control" id="privKey" />
</div>
<div class="mb-3">
<label for="pubKey" class="form-label">x25519_PUBLIC_KEY (Optional if private key is supplied)</label>
<input type="text" class="form-control" id="pubKey" />
</div>
<div class="mb-3">
<label for="plainKey" class="form-label">PLAIN_TEXT</label>
<input type="text" class="form-control" id="plainKey" />
</div>
<div class="mb-3">
<label for="cipherKey" class="form-label">CIPHER_TEXT</label>
<input type="text" class="form-control" id="cipherKey" />
</div>
<div class="mb-3">
<label for="statusKey" class="form-label">STATUS</label>
<input type="text" class="form-control" id="statusKey" disabled="true" />
</div>
<div class="btn-container">
<button type="button" class="btn btn-primary mb-3" id="genBtn">🔑 Generate</button>
<button type="button" class="btn btn-primary mb-3" id="encryptBtn">🔒 Encrypt</button>
<button type="button" class="btn btn-primary mb-3" id="decryptBtn">🔓 Decrypt</button>
</div>
</div>
<script src="out/scripts/key-generator/keygen.js" type="application/javascript"></script>
</body>
</html>
134 changes: 134 additions & 0 deletions static/scripts/key-generator/keygen.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
import _sodium from "libsodium-wrappers";

const classes = ["error", "warning", "success"];
const CYPHER_KEY = "#cipherKey";

function statusToggle(target: "error" | "warning" | "success", value: string) {
const statusKey = document.querySelector("#statusKey") as HTMLInputElement;

classes.forEach((e) => {
if (e !== target) {
statusKey.classList.remove(e);
}
});
statusKey.classList.add(target);
statusKey.value = value;
}

async function sodiumKeyBox() {
const privKey = document.querySelector("#privKey") as HTMLInputElement;
const pubKey = document.querySelector("#pubKey") as HTMLInputElement;
const cipherKey = document.querySelector(CYPHER_KEY) as HTMLInputElement;
cipherKey.value = "";
try {
await _sodium.ready;
const sodium = _sodium;

const { privateKey, publicKey } = sodium.crypto_box_keypair("base64");
privKey.value = privateKey;
pubKey.value = publicKey;
statusToggle("success", `Success: Key Generation is ok.`);
} catch (error: unknown) {
if (error instanceof Error) {
statusToggle("error", `Error: ${error.message}`);
} else {
statusToggle("error", `Error: ${JSON.stringify(error)}`);
}
}
}

async function sodiumEncryptedSeal() {
const pubKey = document.querySelector("#pubKey") as HTMLInputElement;
const privKey = document.querySelector("#privKey") as HTMLInputElement;
const plainKey = document.querySelector("#plainKey") as HTMLInputElement;
const cipherKey = document.querySelector(CYPHER_KEY) as HTMLInputElement;
try {
await _sodium.ready;
const sodium = _sodium;

if (!privKey.value && !pubKey.value) {
statusToggle("error", `Error: You need to enter either public or private key.`);
return;
}
if (!pubKey.value && privKey.value) {
// derive public key from private key
const binPriv = sodium.from_base64(privKey.value, sodium.base64_variants.URLSAFE_NO_PADDING);
const binPub = sodium.crypto_scalarmult_base(binPriv);
const output = sodium.to_base64(binPub, sodium.base64_variants.URLSAFE_NO_PADDING);
pubKey.value = output;
}
const binkey = sodium.from_base64(pubKey.value, sodium.base64_variants.URLSAFE_NO_PADDING);
const binsec = sodium.from_string(plainKey.value);
const encBytes = sodium.crypto_box_seal(binsec, binkey);
const output = sodium.to_base64(encBytes, sodium.base64_variants.URLSAFE_NO_PADDING);
cipherKey.value = output;
statusToggle("success", `Success: Key Encryption is ok.`);
} catch (error: unknown) {
if (error instanceof Error) {
statusToggle("error", `Error: ${error.message}`);
} else {
statusToggle("error", `Error: ${JSON.stringify(error)}`);
}
}
}

async function sodiumOpenSeal() {
const pubKey = document.querySelector("#pubKey") as HTMLInputElement;
const privKey = document.querySelector("#privKey") as HTMLInputElement;
const cipherKey = document.querySelector("#cipherKey") as HTMLInputElement;
const plainKey = document.querySelector("#plainKey") as HTMLInputElement;
try {
await _sodium.ready;
const sodium = _sodium;

if (!privKey.value) {
statusToggle("error", `Error: You need to enter private key.`);
return;
}
if (!pubKey.value && privKey.value) {
// derive public key from private key
const binPriv = sodium.from_base64(privKey.value, sodium.base64_variants.URLSAFE_NO_PADDING);
const binPub = sodium.crypto_scalarmult_base(binPriv);
const output = sodium.to_base64(binPub, sodium.base64_variants.URLSAFE_NO_PADDING);
pubKey.value = output;
}
const binPub = sodium.from_base64(pubKey.value, sodium.base64_variants.URLSAFE_NO_PADDING);
const binPriv = sodium.from_base64(privKey.value, sodium.base64_variants.URLSAFE_NO_PADDING);
const binCipher = sodium.from_base64(cipherKey.value, sodium.base64_variants.URLSAFE_NO_PADDING);
const outText = sodium.crypto_box_seal_open(binCipher, binPub, binPriv, "text");
plainKey.value = outText;
statusToggle("success", `Success: Key Decryption is ok.`);
} catch (error: unknown) {
if (error instanceof Error) {
statusToggle("error", `Error: ${error.message}`);
} else {
statusToggle("error", `Error: ${JSON.stringify(error)}`);
}
}
}

function init() {
const genBtn = document.querySelector("#genBtn") as HTMLButtonElement;
const encryptBtn = document.querySelector("#encryptBtn") as HTMLButtonElement;
const decryptBtn = document.querySelector("#decryptBtn") as HTMLButtonElement;

genBtn.addEventListener("click", () => {
sodiumKeyBox().catch((error) => {
statusToggle("error", `Error: ${error.message}`);
});
});

encryptBtn.addEventListener("click", () => {
sodiumEncryptedSeal().catch((error) => {
statusToggle("error", `Error: ${error.message}`);
});
});

decryptBtn.addEventListener("click", () => {
sodiumOpenSeal().catch((error) => {
statusToggle("error", `Error: ${error.message}`);
});
});
}

init();
Loading

0 comments on commit 766b1ef

Please sign in to comment.