| … | … | @@ -2,23 +2,32 @@ |
| 2 | 2 | |
| 3 | 3 | the **A**uthenticated and **N**on-networked protocol or **AN**other protocol |
| 4 | 4 | |
| 5 | ed25519 keypairs sign timestamp + hash in base64 | |
| 6 | ||
| 7 | *** | |
| 8 | ||
| 5 | 9 | (we wanted aproto, but the dot com was taken) |
| 6 | 10 | |
| 7 | 11 | [anproto.com](https://anproto.com) |
| 8 | 12 | |
| 9 | 13 | try it at [anproto.com/try](https://anproto.com/try) or use a client such as [wiredove](https://wiredove.net/) |
| 10 | 14 | |
| 15 | *** | |
| 11 | 16 | |
| 12 | ed25519 keypairs sign timestamp + hash in base64 | |
| 17 | ### What is ANProto? | |
| 13 | 18 | |
| 14 | 19 | + ANProto is the spiritual successor to [secure-scuttlebot](https://scuttlebot.io), but without all of the extra stuff that is difficult to maintain. |
| 15 | 20 | + ANProto is an attempt to argue that [ATProto](https://atprotocom.) is too involved in it's own networking infrastructure to be usefully decentralized. |
| 16 | 21 | + ANProto operates under the working theory that [Nostr](https://fiatjaf.com/nostr.html) will never reach anyone besides Bitcoiners. |
| 17 | 22 | |
| 23 | *** | |
| 24 | ||
| 18 | 25 | ### Bring your own network! |
| 19 | 26 | |
| 20 | 27 | ANProto works over any networking stack. Open the messages from your URL bar! Email them to your friends! Load them on a USB stick an slingshot them over a river! ANProto is non-networked, so you can send and retrieve the messages anyway you want. Try the fetch API or Websockets if you want a good place to start. But maybe dork out trying to send ANProto messages via Bluetooth, LoRa, or sync them via local wifi like you did with Scuttlebot! |
| 21 | 28 | |
| 29 | *** | |
| 30 | ||
| 22 | 31 | ### the JavaScript library! |
| 23 | 32 | |
| 24 | 33 | use Deno or your browser |
| … | … | @@ -1,19 +1,18 @@ |
| 1 | 1 | import { Hono } from "jsr:@hono/hono"; |
| 2 | 2 | import { serveStatic } from 'jsr:@hono/hono/deno' |
| 3 | import { marked } from 'https://esm.sh/gh/evbogue/bog5@de70376265/lib/marked.esm.js' | |
| 3 | 4 | |
| 4 | 5 | import { foot, head } from "./template.js"; |
| 5 | 6 | |
| 6 | 7 | const app = new Hono(); |
| 7 | 8 | |
| 9 | const readme = await Deno.readTextFile('./README.md') | |
| 10 | ||
| 8 | 11 | app.get('/', async (c) => { |
| 9 | 12 | const content = ` |
| 10 | 13 | <div id="scroller"> |
| 11 | 14 | <div class='message'> |
| 12 | <h1>ANProto</h1> | |
| 13 | <p>Try ANProto online:</p> | |
| 14 | <p><a href="./try">Try ANProto</a></p> | |
| 15 | <p>The Official ANProto Client: | |
| 16 | <p><a href="https://wiredove.net/">Wiredove</a></p> | |
| 15 | ${await marked(readme)} | |
| 17 | 16 | </div> |
| 18 | 17 | </div> |
| 19 | 18 | ` |
| … | … | @@ -33,7 +32,7 @@ app.get('/try', async (c) => { |
| 33 | 32 | |
| 34 | 33 | <p><strong>Step 1.</strong> Generate an ed25519 keypair</p> |
| 35 | 34 | |
| 36 | <code>const kp = await a.gen()</code> | |
| 35 | <code>const kp = await an.gen()</code> | |
| 37 | 36 | |
| 38 | 37 | <input style='width: 100%;' id='key' placeholder='Make a keypair'></input> |
| 39 | 38 | |
| … | … | @@ -45,7 +44,7 @@ app.get('/try', async (c) => { |
| 45 | 44 | |
| 46 | 45 | <p><strong>Step 2.</strong> Hash your blob with sha256</p> |
| 47 | 46 | |
| 48 | <code>const hash = await a.hash(content)</code> | |
| 47 | <code>const hash = await an.hash(content)</code> | |
| 49 | 48 | |
| 50 | 49 | <input style='width: 100%;' id='content' placeholder='Write a message'></input> |
| 51 | 50 | |
| … | … | @@ -59,7 +58,7 @@ app.get('/try', async (c) => { |
| 59 | 58 | |
| 60 | 59 | <p><strong>Step 3.</strong> Sign the ANProto message</p> |
| 61 | 60 | |
| 62 | <code>const sig = await a.sign(hash, keypair)</code> | |
| 61 | <code>const sig = await an.sign(hash, keypair)</code> | |
| 63 | 62 | |
| 64 | 63 | <input style='width: 100%' id='sig'></input> |
| 65 | 64 | |
| … | … | @@ -70,7 +69,7 @@ app.get('/try', async (c) => { |
| 70 | 69 | |
| 71 | 70 | <p><strong>Step 4.</strong> Open the ANProto message</p> |
| 72 | 71 | |
| 73 | <code>const opened = await a.open(msg)</code> | |
| 72 | <code>const opened = await an.open(msg)</code> | |
| 74 | 73 | |
| 75 | 74 | <input style='width: 100%;' id='openen'></input> |
| 76 | 75 |
| … | … | @@ -11,7 +11,7 @@ body { |
| 11 | 11 | |
| 12 | 12 | blockquote { border-left: 5px solid #f5f5f5; margin-left: none; padding-left: 10px; color: #777; } |
| 13 | 13 | |
| 14 | p, h1, h2, h3, h4, h5, h6 { margin-top: 0px; margin-bottom: 2px; } | |
| 14 | p, h1, h2, h3, h4, h5, h6 { margin-top: 5px; margin-bottom: 5px; } | |
| 15 | 15 | |
| 16 | 16 | pre { |
| 17 | 17 | //color: #dd1144; |
| … | … | @@ -139,8 +139,8 @@ iframe { |
| 139 | 139 | background-color: #181818; |
| 140 | 140 | color: #f5f5f5; |
| 141 | 141 | } |
| 142 | #navbar { background-color: rgba(24,24,24,0.2); border-bottom: 1px solid orange;} | |
| 143 | #navbar a { color: orange;} | |
| 142 | #navbar { background-color: rgba(24,24,24,0.2); border-bottom: 1px solid #FE7A00;} | |
| 143 | #navbar a { color: #FE7A00;} | |
| 144 | 144 | #navbar:hover { border-bottom: 1px solid magenta;} |
| 145 | 145 | .message { background-color: #222; border: 1px solid #333;} |
| 146 | 146 | .message:hover { border: 1px solid magenta;} |
| … | … | @@ -151,7 +151,7 @@ iframe { |
| 151 | 151 | button:hover { background: #222;} |
| 152 | 152 | hr { border: 1px solid #333;} |
| 153 | 153 | pre, code { background: #333; color: #f5f5f5;} |
| 154 | a {color: orange;} | |
| 154 | a {color: #FE7A00;} | |
| 155 | 155 | } |
| 156 | 156 | |
| 157 | 157 | .content {margin-top: 5px;} |