Files
sovereign_browser/tests/test_nostr.html
T

171 lines
6.1 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>sovereign browser — window.nostr test</title>
<style>
body {
font-family: "Courier New", Courier, monospace;
max-width: 800px;
margin: 40px auto;
padding: 20px;
background: #1a1a1a;
color: #e0e0e0;
}
h1 { color: #ff4444; }
h2 { color: #ff8888; margin-top: 30px; }
button {
font-family: monospace;
font-size: 14px;
padding: 8px 16px;
margin: 4px;
background: #333;
color: #e0e0e0;
border: 1px solid #555;
border-radius: 4px;
cursor: pointer;
}
button:hover { background: #444; border-color: #777; }
button:active { background: #222; }
pre {
background: #0d0d0d;
border: 1px solid #333;
border-radius: 4px;
padding: 12px;
overflow-x: auto;
white-space: pre-wrap;
word-wrap: break-word;
font-size: 13px;
line-height: 1.4;
}
.result { border-left: 3px solid #ff4444; padding-left: 12px; margin: 10px 0; }
.success { color: #44ff44; }
.error { color: #ff4444; }
.label { color: #888; font-size: 12px; }
#status { font-weight: bold; padding: 8px; border-radius: 4px; margin: 10px 0; }
.status-ok { background: #1a3a1a; color: #44ff44; }
.status-err { background: #3a1a1a; color: #ff4444; }
.status-wait { background: #3a3a1a; color: #ffff44; }
</style>
</head>
<body>
<h1>sovereign browser — window.nostr test</h1>
<p class="label">This page tests the NIP-07 window.nostr API injected by the browser.</p>
<div id="status">Checking for window.nostr…</div>
<h2>1. Get Public Key</h2>
<p>Call <code>window.nostr.getPublicKey()</code> to retrieve your Nostr public key.</p>
<button onclick="testGetPublicKey()">Get Public Key</button>
<div id="pubkey-result" class="result"></div>
<h2>2. Sign Event</h2>
<p>Create and sign a kind-1 text note via <code>window.nostr.signEvent()</code>.</p>
<input type="text" id="note-text" value="Hello from sovereign browser!" style="width:400px; font-family:monospace; padding:4px; background:#333; color:#e0e0e0; border:1px solid #555; border-radius:4px;">
<button onclick="testSignEvent()">Sign Event</button>
<div id="sign-result" class="result"></div>
<h2>3. Get Relays</h2>
<p>Call <code>window.nostr.getRelays()</code> to get the browser's relay list.</p>
<button onclick="testGetRelays()">Get Relays</button>
<div id="relays-result" class="result"></div>
<h2>4. NIP-44 Encrypt/Decrypt (self)</h2>
<p>Encrypt a message to yourself and decrypt it back.</p>
<input type="text" id="encrypt-text" value="Secret test message" style="width:400px; font-family:monospace; padding:4px; background:#333; color:#e0e0e0; border:1px solid #555; border-radius:4px;">
<button onclick="testNip44()">Test NIP-44</button>
<div id="nip44-result" class="result"></div>
<script>
// Check if window.nostr is available
function checkNostr() {
var status = document.getElementById('status');
if (typeof window.nostr !== 'undefined' && window.nostr !== null) {
status.className = 'status-ok';
status.textContent = '✓ window.nostr is available';
} else {
status.className = 'status-err';
status.textContent = '✗ window.nostr is NOT available — are you running this in sovereign browser?';
}
}
function showResult(elementId, success, content) {
var el = document.getElementById(elementId);
var cls = success ? 'success' : 'error';
el.innerHTML = '<span class="' + cls + '">' + (success ? '✓' : '✗') + '</span> <pre>' + escapeHtml(content) + '</pre>';
}
function escapeHtml(text) {
var div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
async function testGetPublicKey() {
var el = 'pubkey-result';
try {
showResult(el, true, 'Calling window.nostr.getPublicKey()…');
var pubkey = await window.nostr.getPublicKey();
showResult(el, true, 'Public key (hex): ' + pubkey);
} catch(e) {
showResult(el, false, 'Error: ' + e.message);
}
}
async function testSignEvent() {
var el = 'sign-result';
try {
var content = document.getElementById('note-text').value;
var event = {
kind: 1,
content: content,
tags: [],
created_at: Math.floor(Date.now() / 1000)
};
showResult(el, true, 'Calling window.nostr.signEvent() with:\n' + JSON.stringify(event, null, 2));
var signed = await window.nostr.signEvent(event);
showResult(el, true, 'Signed event:\n' + JSON.stringify(signed, null, 2));
} catch(e) {
showResult(el, false, 'Error: ' + e.message);
}
}
async function testGetRelays() {
var el = 'relays-result';
try {
showResult(el, true, 'Calling window.nostr.getRelays()…');
var relays = await window.nostr.getRelays();
showResult(el, true, 'Relays: ' + JSON.stringify(relays, null, 2));
} catch(e) {
showResult(el, false, 'Error: ' + e.message);
}
}
async function testNip44() {
var el = 'nip44-result';
try {
var text = document.getElementById('encrypt-text').value;
var pubkey = await window.nostr.getPublicKey();
showResult(el, true, 'Encrypting "' + text + '" to self (' + pubkey.substring(0, 16) + '…)');
var ciphertext = await window.nostr.nip44.encrypt(pubkey, text);
showResult(el, true, 'Ciphertext: ' + ciphertext.substring(0, 80) + '…');
var decrypted = await window.nostr.nip44.decrypt(pubkey, ciphertext);
if (decrypted === text) {
showResult(el, true, 'Round-trip verified!\nOriginal: ' + text + '\nDecrypted: ' + decrypted);
} else {
showResult(el, false, 'Round-trip FAILED!\nOriginal: ' + text + '\nDecrypted: ' + decrypted);
}
} catch(e) {
showResult(el, false, 'Error: ' + e.message);
}
}
// Run check on load
checkNostr();
</script>
</body>
</html>