| … | … | @@ -1,152 +0,0 @@ |
| 1 | import { Hono } from "jsr:@hono/hono"; | |
| 2 | import { serveStatic } from 'jsr:@hono/hono/deno' | |
| 3 | import { marked } from 'https://esm.sh/gh/evbogue/bog5@de70376265/lib/marked.esm.js' | |
| 4 | ||
| 5 | import { foot, head } from "./template.js"; | |
| 6 | ||
| 7 | const app = new Hono(); | |
| 8 | ||
| 9 | const readme = await Deno.readTextFile('./README.md') | |
| 10 | ||
| 11 | app.get('/', async (c) => { | |
| 12 | const content = ` | |
| 13 | <div id="scroller"> | |
| 14 | <div class='message'> | |
| 15 | ${await marked(readme)} | |
| 16 | </div> | |
| 17 | </div> | |
| 18 | ` | |
| 19 | ||
| 20 | const html = await head('Index') + content + await foot() | |
| 21 | return await c.html(html) | |
| 22 | }) | |
| 23 | ||
| 24 | app.get('/try', async (c) => { | |
| 25 | ||
| 26 | const body = `<body> | |
| 27 | <div id='scroller'> | |
| 28 | <div class='message'> | |
| 29 | <h1>Try ANProto</h1> | |
| 30 | ||
| 31 | <p><em>An Interactive Demonstration</em></p> | |
| 32 | ||
| 33 | <p><strong>Step 1.</strong> Generate an ed25519 keypair</p> | |
| 34 | ||
| 35 | <code>const kp = await an.gen()</code> | |
| 36 | ||
| 37 | <input style='width: 100%;' id='key' placeholder='Make a keypair'></input> | |
| 38 | ||
| 39 | <button id='but'>Generate keypair</button> | |
| 40 | ||
| 41 | </div> | |
| 42 | ||
| 43 | <div class='message'> | |
| 44 | ||
| 45 | <p><strong>Step 2.</strong> Hash your blob with sha256</p> | |
| 46 | ||
| 47 | <code>const hash = await an.hash(content)</code> | |
| 48 | ||
| 49 | <input style='width: 100%;' id='content' placeholder='Write a message'></input> | |
| 50 | ||
| 51 | <button id='hash'>Generate hash</button> | |
| 52 | ||
| 53 | <span id='sha256'></span> | |
| 54 | ||
| 55 | </div> | |
| 56 | ||
| 57 | <div class='message'> | |
| 58 | ||
| 59 | <p><strong>Step 3.</strong> Sign the ANProto message</p> | |
| 60 | ||
| 61 | <code>const sig = await an.sign(hash, keypair)</code> | |
| 62 | ||
| 63 | <input style='width: 100%' id='sig'></input> | |
| 64 | ||
| 65 | <button id='sign'>Sign message</button> | |
| 66 | ||
| 67 | </div> | |
| 68 | <div class="message"> | |
| 69 | ||
| 70 | <p><strong>Step 4.</strong> Open the ANProto message</p> | |
| 71 | ||
| 72 | <code>const opened = await an.open(msg)</code> | |
| 73 | ||
| 74 | <input style='width: 100%;' id='openen'></input> | |
| 75 | ||
| 76 | <button id='open'>Open</button> | |
| 77 | ||
| 78 | </div> | |
| 79 | <div class="message"> | |
| 80 | ||
| 81 | <p><strong>Step 5.</strong> Retrieve the blob</p> | |
| 82 | ||
| 83 | <span id='msg'></span> | |
| 84 | ||
| 85 | <button id='get'>Get</button> | |
| 86 | ||
| 87 | </div> | |
| 88 | </div> | |
| 89 | </body> | |
| 90 | ||
| 91 | <script type='module'> | |
| 92 | import { an } from './an.js' | |
| 93 | ||
| 94 | const key = document.getElementById('key') | |
| 95 | const button = document.getElementById('but') | |
| 96 | ||
| 97 | button.onclick = async () => { | |
| 98 | key.value = await an.gen() | |
| 99 | } | |
| 100 | ||
| 101 | const content = document.getElementById('content') | |
| 102 | const hashbutton = document.getElementById('hash') | |
| 103 | const sha = document.getElementById('sha256') | |
| 104 | ||
| 105 | let blobs = [] | |
| 106 | ||
| 107 | hashbutton.onclick = async () => { | |
| 108 | sha.textContent = await an.hash(content.value) | |
| 109 | blobs[sha.textContent] = content.value | |
| 110 | } | |
| 111 | ||
| 112 | const siginput = document.getElementById('sig') | |
| 113 | const signbutton = document.getElementById('sign') | |
| 114 | ||
| 115 | signbutton.onclick = async () => { | |
| 116 | siginput.value = await an.sign(sha.textContent, key.value) | |
| 117 | } | |
| 118 | ||
| 119 | const openbutton = document.getElementById('open') | |
| 120 | ||
| 121 | const openen = document.getElementById('openen') | |
| 122 | ||
| 123 | openbutton.onclick = async () => { | |
| 124 | openen.value = await an.open(siginput.value) | |
| 125 | } | |
| 126 | ||
| 127 | const msgspan = document.getElementById('msg') | |
| 128 | const getbutton = document.getElementById('get') | |
| 129 | ||
| 130 | getbutton.onclick = async () => { | |
| 131 | msgspan.textContent = blobs[openen.value.substring(13)] | |
| 132 | if (openen.value.substring(13) == sha.textContent) { | |
| 133 | msgspan.textContent = msgspan.textContent + ' ✅' | |
| 134 | } else { | |
| 135 | msgspan.textContent = msgspan.textContent + ' ❌' | |
| 136 | } | |
| 137 | } | |
| 138 | ||
| 139 | </script>` | |
| 140 | ||
| 141 | const html = await head('Try it') + body + await foot() | |
| 142 | return await c.html(html) | |
| 143 | }) | |
| 144 | ||
| 145 | app.use('*', serveStatic({ | |
| 146 | root: './', | |
| 147 | onFound: (_path, c) => { | |
| 148 | c.header("Access-Control-Allow-Origin", "*") | |
| 149 | } | |
| 150 | })) | |
| 151 | ||
| 152 | export default app |
| … | … | @@ -0,0 +1,152 @@ |
| 1 | import { Hono } from "jsr:@hono/hono"; | |
| 2 | import { serveStatic } from 'jsr:@hono/hono/deno' | |
| 3 | import { marked } from 'https://esm.sh/gh/evbogue/bog5@de70376265/lib/marked.esm.js' | |
| 4 | ||
| 5 | import { foot, head } from "./template.js"; | |
| 6 | ||
| 7 | const app = new Hono(); | |
| 8 | ||
| 9 | const readme = await Deno.readTextFile('./README.md') | |
| 10 | ||
| 11 | app.get('/', async (c) => { | |
| 12 | const content = ` | |
| 13 | <div id="scroller"> | |
| 14 | <div class='message'> | |
| 15 | ${await marked(readme)} | |
| 16 | </div> | |
| 17 | </div> | |
| 18 | ` | |
| 19 | ||
| 20 | const html = await head('Index') + content + await foot() | |
| 21 | return await c.html(html) | |
| 22 | }) | |
| 23 | ||
| 24 | app.get('/try', async (c) => { | |
| 25 | ||
| 26 | const body = `<body> | |
| 27 | <div id='scroller'> | |
| 28 | <div class='message'> | |
| 29 | <h1>Try ANProto</h1> | |
| 30 | ||
| 31 | <p><em>An Interactive Demonstration</em></p> | |
| 32 | ||
| 33 | <p><strong>Step 1.</strong> Generate an ed25519 keypair</p> | |
| 34 | ||
| 35 | <code>const kp = await an.gen()</code> | |
| 36 | ||
| 37 | <input style='width: 100%;' id='key' placeholder='Make a keypair'></input> | |
| 38 | ||
| 39 | <button id='but'>Generate keypair</button> | |
| 40 | ||
| 41 | </div> | |
| 42 | ||
| 43 | <div class='message'> | |
| 44 | ||
| 45 | <p><strong>Step 2.</strong> Hash your blob with sha256</p> | |
| 46 | ||
| 47 | <code>const hash = await an.hash(content)</code> | |
| 48 | ||
| 49 | <input style='width: 100%;' id='content' placeholder='Write a message'></input> | |
| 50 | ||
| 51 | <button id='hash'>Generate hash</button> | |
| 52 | ||
| 53 | <span id='sha256'></span> | |
| 54 | ||
| 55 | </div> | |
| 56 | ||
| 57 | <div class='message'> | |
| 58 | ||
| 59 | <p><strong>Step 3.</strong> Sign the ANProto message</p> | |
| 60 | ||
| 61 | <code>const sig = await an.sign(hash, keypair)</code> | |
| 62 | ||
| 63 | <input style='width: 100%' id='sig'></input> | |
| 64 | ||
| 65 | <button id='sign'>Sign message</button> | |
| 66 | ||
| 67 | </div> | |
| 68 | <div class="message"> | |
| 69 | ||
| 70 | <p><strong>Step 4.</strong> Open the ANProto message</p> | |
| 71 | ||
| 72 | <code>const opened = await an.open(msg)</code> | |
| 73 | ||
| 74 | <input style='width: 100%;' id='openen'></input> | |
| 75 | ||
| 76 | <button id='open'>Open</button> | |
| 77 | ||
| 78 | </div> | |
| 79 | <div class="message"> | |
| 80 | ||
| 81 | <p><strong>Step 5.</strong> Retrieve the blob</p> | |
| 82 | ||
| 83 | <span id='msg'></span> | |
| 84 | ||
| 85 | <button id='get'>Get</button> | |
| 86 | ||
| 87 | </div> | |
| 88 | </div> | |
| 89 | </body> | |
| 90 | ||
| 91 | <script type='module'> | |
| 92 | import { an } from './an.js' | |
| 93 | ||
| 94 | const key = document.getElementById('key') | |
| 95 | const button = document.getElementById('but') | |
| 96 | ||
| 97 | button.onclick = async () => { | |
| 98 | key.value = await an.gen() | |
| 99 | } | |
| 100 | ||
| 101 | const content = document.getElementById('content') | |
| 102 | const hashbutton = document.getElementById('hash') | |
| 103 | const sha = document.getElementById('sha256') | |
| 104 | ||
| 105 | let blobs = [] | |
| 106 | ||
| 107 | hashbutton.onclick = async () => { | |
| 108 | sha.textContent = await an.hash(content.value) | |
| 109 | blobs[sha.textContent] = content.value | |
| 110 | } | |
| 111 | ||
| 112 | const siginput = document.getElementById('sig') | |
| 113 | const signbutton = document.getElementById('sign') | |
| 114 | ||
| 115 | signbutton.onclick = async () => { | |
| 116 | siginput.value = await an.sign(sha.textContent, key.value) | |
| 117 | } | |
| 118 | ||
| 119 | const openbutton = document.getElementById('open') | |
| 120 | ||
| 121 | const openen = document.getElementById('openen') | |
| 122 | ||
| 123 | openbutton.onclick = async () => { | |
| 124 | openen.value = await an.open(siginput.value) | |
| 125 | } | |
| 126 | ||
| 127 | const msgspan = document.getElementById('msg') | |
| 128 | const getbutton = document.getElementById('get') | |
| 129 | ||
| 130 | getbutton.onclick = async () => { | |
| 131 | msgspan.textContent = blobs[openen.value.substring(13)] | |
| 132 | if (openen.value.substring(13) == sha.textContent) { | |
| 133 | msgspan.textContent = msgspan.textContent + ' ✅' | |
| 134 | } else { | |
| 135 | msgspan.textContent = msgspan.textContent + ' ❌' | |
| 136 | } | |
| 137 | } | |
| 138 | ||
| 139 | </script>` | |
| 140 | ||
| 141 | const html = await head('Try it') + body + await foot() | |
| 142 | return await c.html(html) | |
| 143 | }) | |
| 144 | ||
| 145 | app.use('*', serveStatic({ | |
| 146 | root: './', | |
| 147 | onFound: (_path, c) => { | |
| 148 | c.header("Access-Control-Allow-Origin", "*") | |
| 149 | } | |
| 150 | })) | |
| 151 | ||
| 152 | export default app |