Skip to content

Commit

Permalink
build for gh-pages
Browse files Browse the repository at this point in the history
  • Loading branch information
Meshiest committed Sep 18, 2024
1 parent c33942c commit a562da3
Show file tree
Hide file tree
Showing 2 changed files with 392 additions and 0 deletions.
224 changes: 224 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
<!DOCTYPE html>
<html>
<head>
<title>Aleo Testnet2 Tools</title>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/@picocss/[email protected]/css/pico.classless.min.css"
/>
<style>
.hidden {
display: none;
}
input[readonly] {
opacity: 0.6;
cursor: copy;
}
label {
font-weight: bold;
transition: color 0.2s ease;
}
label:has(input[aria-invalid='true']) {
color: var(--pico-form-element-invalid-border-color);
}
label:has(input[aria-invalid='true']:focus) {
color: var(--pico-form-element-invalid-active-border-color);
}
label:has(input[aria-invalid='false']) {
color: var(--pico-form-element-valid-border-color);
}
label:has(input[aria-invalid='false']:focus) {
color: var(--pico-form-element-valid-active-border-color);
}
</style>
</head>
<body>
<main class="hidden" id="wasmWarning">
<article>
<header>
<h3>Unable to load Web Assembly</h3>
</header>
<p>
This page uses
<a href="https://webassembly.org/" rel="noopener noreferer"
>WebAssembly</a
>
to run Rust code in the browser. Your browser does not support
WebAssembly, or something prevented it from loading.
</p>
</article>
</main>
<header>
<h1>Aleo Testnet2 Tools</h1>
<p>
Sign and verify messages using your Testnet2 private key. Compare your
Testnet2 address to your Mainnet address.
</p>
<h3>Table of Contents</h3>
<ul>
<li><a href="#sign">Sign a Message</a></li>
<li><a href="#verify">Verify a Signature</a></li>
<li><a href="#derive">Derive Addresses from a Private Key</a></li>
<li><a href="#selfhost">Self Host this Site</a></li>
</ul>
</header>
<main>
<section>
<h2 id="sign">Sign a Message</h2>
<p>
Enter a private key and a message to generate an Aleo Testnet2
compatible signature.
</p>
<form id="signForm">
<label for="sign_privateKey">
Testnet2 Private Key
<input
name="sign_privateKey"
autocomplete="off"
type="password"
placeholder="Testnet2 Private Key"
aria-label="Private Key"
required
/>
</label>
<label for="sign_message">
Message to Sign
<input
name="sign_message"
autocomplete="off"
type="text"
placeholder="Message to Sign"
aria-label="Message"
required
/>
</label>
<label for="sign_signature">
Signature
<input
name="sign_signature"
autocomplete="off"
type="text"
placeholder="Signature"
aria-label="Signature"
readonly
/>
</label>
</form>
</section>
<section>
<h2 id="verify">Verify a Message</h2>
<p>
Enter an address, a message, and a Testnet2 signature verify
authenticity.
</p>
<form id="verifyForm">
<label for="verify_address">
Testnet2 Address
<input
name="verify_address"
autocomplete="off"
type="text"
placeholder="Testnet2 Address"
aria-label="Address"
required
/>
</label>
<label for="verify_message">
Message to Verify
<input
name="verify_message"
autocomplete="off"
type="text"
placeholder="Message to Verify"
aria-label="Message"
required
/>
</label>
<label for="verify_signature">
Signature to Verify
<input
name="verify_signature"
autocomplete="off"
type="text"
placeholder="Signature to Verify"
aria-label="Signature"
required
/>
</label>
</form>
</section>
<section>
<h2 id="derive">Derive Addresses from a Testnet2 Private Key</h2>
<p>
Enter an address, a message, and a Testnet2 signature verify
authenticity.
</p>
<form id="deriveForm">
<label for="derive_privateKey">
Testnet2 Private Key
<input
name="derive_privateKey"
autocomplete="off"
type="password"
placeholder="Testnet2 Private Key"
aria-label="Private Key"
required
/>
</label>
<label for="derive_address2">
Derived Testnet2 Address
<input
name="derive_address2"
autocomplete="off"
type="text"
placeholder="Testnet2 Address"
aria-label="Testnet2 Address"
readonly
/>
</label>
<label for="derive_address">
Derived Mainnet Address
<input
name="derive_address"
autocomplete="off"
type="text"
placeholder="Mainnet Address"
aria-label="Mainnet Address"
readonly
/>
</label>
</form>
</section>
<section>
<h2 id="selfhost">Self Host this Site</h2>
<p>
The source code for this website is available in the
<a
rel="noopener noreferer"
href="https://github.com/monadicus/aleo-testnet2-tools"
>
monadicus/aleo-testnet2-tools
</a>
repository.
</p>
</section>
</main>
<footer>
<small>
<a
rel="noopener noreferer"
href="https://github.com/monadicus/aleo-testnet2-tools"
>Source code</a
>
&bullet;
<a rel="noopener noreferer" href="https://aleo.org/">Aleo</a>
&bullet;
<a rel="noopener noreferer" href="https://github.com/Aleonet/snarkOS"
>snarkOS</a
>
&bullet; Built with <a href="https://picocss.com">Pico</a>
</small>
</footer>
<script type="module" src="./script.mjs"></script>
</body>
</html>
168 changes: 168 additions & 0 deletions script.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
import init, * as tools from './pkg/aleo_testnet2_wasm_suite.js';

/** query selector @returns {Element} */
const $ = document.querySelector.bind(document);
/** query selector all @returns {Element[]} */
const $$ = q => Array.from(document.querySelectorAll(q));

/**
* @param {Element} el
* @param {boolean | null} isInvalid
*/
function setInvalid(el, isInvalid = true) {
if (isInvalid === null) {
el.removeAttribute('aria-invalid');
return;
}
el.setAttribute('aria-invalid', isInvalid + '');
}

/** @param {Element} el */
const clearInvalid = el => setInvalid(el, null);

/** @typedef {({form: HTMLFormElement} | Record<string, HTMLInputElement>)} FormElements */

/**
* get the inputs from a form
* @param {string} formId
* @returns {FormElements}
*/
function formElems(formId) {
const form = $('#' + formId);
const elems = $$(`#${formId} input`);
if (!form || elems.length === 0) return null;

const entries = Object.fromEntries(
elems.map(e => [e.getAttribute('name').split('_').slice(1).join('_'), e])
);

return { form, ...entries };
}

const debounce = (fn, duration = 250) => {
let timeout;
return function debounced() {
clearTimeout(timeout);
timeout = setTimeout(fn, duration);
};
};

/**
* @param {string} formId Form Id
* @param {(inputs: Record<string, HTMLInputElement>) => {}} handler
*/
function formHandler(formId, handler) {
const { form, ...inputs } = formElems(formId);
if (!inputs) {
console.error('invalid selectors for form', formId);
return;
}

const invoker = debounce(() => {
for (const key in inputs) {
/** @type {HTMLInputElement} */
const el = inputs[key];
clearInvalid(el);
if (el.hasAttribute('readonly')) {
el.value = '';
}
}
handler(inputs);
});

for (const key in inputs) {
/** @type {HTMLInputElement} */
const el = inputs[key];
clearInvalid(el);

if (el.hasAttribute('readonly')) {
el.setAttribute('data-tooltip', 'Click to copy to clipboard');
const copyDone = debounce(() => clearInvalid(el), 1000);

// copy text to clipboard on click
el.addEventListener('click', _event => {
if (el.value.length === 0) return;

el.select();
el.setSelectionRange(0, 99999);

try {
navigator.clipboard.writeText(el.value);
setInvalid(el, false);
} catch (err) {
console.log('error copying text to clipboard', err);
setInvalid(el);
}
copyDone();
});
} else {
el.addEventListener('change', invoker);
el.addEventListener('keyup', invoker);
el.addEventListener('paste', invoker);
}
}
}

init()
.then(() => {
formHandler('signForm', ({ message, privateKey, signature }) => {
if (privateKey.value.length === 0) return;

try {
tools.testnet2_address(privateKey.value);
} catch (err) {
setInvalid(privateKey);
signature.value = err.toString();
return;
}

try {
signature.value = tools.testnet2_sign(privateKey.value, message.value);
} catch (err) {
setInvalid(message);
signature.value = err.toString();
return;
}
});

formHandler('verifyForm', ({ address, message, signature }) => {
if (address.value.length === 0) return;
if (!tools.check_testnet2_address(address.value)) {
return setInvalid(address);
}

if (signature.value.length === 0) return;

try {
setInvalid(
signature,
!tools.testnet2_verify(address.value, message.value, signature.value)
);
} catch (err) {
console.log('error verifying address:', err);
setInvalid(signature);
}
});

formHandler('deriveForm', ({ privateKey, address, address2 }) => {
if (privateKey.value.length === 0) return;

try {
address2.value = tools.testnet2_address(privateKey.value);
} catch (err) {
setInvalid(address2);
address2.value = err.toString();
}

try {
address.value = tools.mainnet_address(privateKey.value);
} catch (e) {
setInvalid(address);
address.value = e.toString();
}
});
})
.catch(e => {
console.log(e);
$('#wasmWarning').classList.remove('hidden');
});

0 comments on commit a562da3

Please sign in to comment.