This commit is contained in:
Your Name 2025-09-24 10:48:35 -04:00
parent 9dc7cdacec
commit 6f46fce625
5 changed files with 68 additions and 30 deletions

4
.gitignore vendored
View File

@ -1 +1,3 @@
Nostr_NIPs/ Nostr_NIPs/
nostr_login_lite/
style_guide/

View File

@ -1,3 +1,3 @@
#!/bin/bash #!/bin/bash
rsync -avz --progress web/{superball.html,thrower.html,superball-shared.css} ubuntu@laantungir.net:WWW/superball/ rsync -avz --chmod=644 --progress web/{superball.html,thrower.html,superball-shared.css} ubuntu@laantungir.net:WWW/superball/

@ -1 +1 @@
Subproject commit a7dceb115626f3cab558802a753e52b34a527c2b Subproject commit 3109a93163427b97067fc5e8a7377e81fad91f62

View File

@ -101,8 +101,9 @@
extension: true, extension: true,
local: true, local: true,
seedphrase: true, seedphrase: true,
readonly: false,
connect: true, connect: true,
remote: false, remote: true,
otp: false otp: false
}, },
debug: true debug: true
@ -1622,6 +1623,19 @@
? userNameElement.textContent ? userNameElement.textContent
: 'User'; : 'User';
// Helper function to get thrower name
function getThrowerName(bounce, bounceNumber) {
const throwerPubkey = bounce.throwerPubkey;
const thrower = discoveredThrowers.find(t => t.pubkey === throwerPubkey);
if (thrower && thrower.name !== 'Unnamed Thrower') {
return thrower.name;
}
// Fallback to generic naming
return `Superball ${bounceNumber}`;
}
// Start with user sending the outermost bounce // Start with user sending the outermost bounce
let currentTime = baseTime; let currentTime = baseTime;
@ -1630,6 +1644,7 @@
const bounceNumber = index + 1; const bounceNumber = index + 1;
const isFirst = (index === 0); const isFirst = (index === 0);
const isLast = (index === bounces.length - 1); const isLast = (index === bounces.length - 1);
const throwerName = getThrowerName(bounce, bounceNumber);
if (isFirst) { if (isFirst) {
// User sends the outermost routing event (first bounce created) // User sends the outermost routing event (first bounce created)
@ -1649,7 +1664,7 @@
flow.push({ flow.push({
time: currentTime, time: currentTime,
actor: `Relay (${relays.join(', ')})`, actor: `Relay (${relays.join(', ')})`,
action: `Event available for Superball ${bounceNumber}`, action: `Event available for ${throwerName}`,
size: routingEventSize size: routingEventSize
}); });
} }
@ -1665,12 +1680,21 @@
// Last bounce - posts final event // Last bounce - posts final event
const finalEventSize = JSON.stringify(finalEvent).length + paddingAdjustment; const finalEventSize = JSON.stringify(finalEvent).length + paddingAdjustment;
const finalRelays = getRelaysForBounce(bounceNumber); const finalRelays = getRelaysForBounce(bounceNumber);
const delaySeconds = getDelayForBounce(bounceNumber);
const paddingAdded = getPaddingAdjustmentForBounce(bounceNumber);
// Create detailed final action description
let actionDescription = `Grabs message, waits ${delaySeconds} seconds`;
if (paddingAdded > 0) {
actionDescription += `, adds ${paddingAdded} bytes of padding`;
}
actionDescription += `, and publishes your original message to: ${finalRelays.join(', ')}`;
// Step 3: Superball decrypts and sends final message // Step 3: Superball decrypts and sends final message
flow.push({ flow.push({
time: currentTime, time: currentTime,
actor: `Superball ${bounceNumber}`, actor: throwerName,
action: `Decrypts and publishes your original message`, action: actionDescription,
size: Math.max(finalEventSize, 0) size: Math.max(finalEventSize, 0)
}); });
@ -1685,14 +1709,24 @@
} else { } else {
// Intermediate bounce - forwards to next superball // Intermediate bounce - forwards to next superball
const nextBounce = bounces[index + 1]; const nextBounce = bounces[index + 1];
const nextThrowerName = getThrowerName(nextBounce, bounceNumber + 1);
const nextRoutingSize = JSON.stringify(nextBounce.routingEvent).length + paddingAdjustment; const nextRoutingSize = JSON.stringify(nextBounce.routingEvent).length + paddingAdjustment;
const nextRelays = getRelaysForBounce(bounceNumber + 1); // Next superball's relays const nextRelays = getRelaysForBounce(bounceNumber + 1); // Next superball's relays
const delaySeconds = getDelayForBounce(bounceNumber);
const paddingAdded = getPaddingAdjustmentForBounce(bounceNumber);
// Create detailed forwarding action description
let actionDescription = `Grabs message, waits ${delaySeconds} seconds`;
if (paddingAdded > 0) {
actionDescription += `, adds ${paddingAdded} bytes of padding`;
}
actionDescription += `, and forwards to: ${nextRelays.join(', ')}`;
// Step 3: Superball forwards to next relay // Step 3: Superball forwards to next relay
flow.push({ flow.push({
time: currentTime, time: currentTime,
actor: `Superball ${bounceNumber}`, actor: throwerName,
action: `Forwards routing event to next hop`, action: actionDescription,
size: Math.max(nextRoutingSize, 0) size: Math.max(nextRoutingSize, 0)
}); });
@ -1701,7 +1735,7 @@
flow.push({ flow.push({
time: currentTime, time: currentTime,
actor: `Relay (${nextRelays.join(', ')})`, actor: `Relay (${nextRelays.join(', ')})`,
action: `Event available for Superball ${bounceNumber + 1}`, action: `Event available for ${nextThrowerName}`,
size: Math.max(nextRoutingSize, 0) size: Math.max(nextRoutingSize, 0)
}); });
} }

View File

@ -12,12 +12,13 @@
<div id="login-section"> <div id="login-section">
<h1>Superball Thrower</h1> <h1>Superball Thrower</h1>
<h3 style="max-width: 500px; margin: 0 auto;">Login as an existing or new Thrower, not with your personal key.</h3>
<div id="login-container"></div> <div id="login-container"></div>
</div> </div>
<div id="main-content" class="hidden"> <div id="main-content" class="hidden">
<h1>Superball Thrower</h1> <h1>Superball Thrower</h1>
<!-- Profile Section - matching superball.html presentation --> <!-- Profile Section - matching superball.html presentation -->
<img id="profile-picture"> <img id="profile-picture">
<div id="profile-name"></div> <div id="profile-name"></div>
@ -26,7 +27,7 @@
<!-- Start Thrower Button (moved above main section) --> <!-- Start Thrower Button (moved above main section) -->
<div style="margin: 20px 0 5px 0; width: 100%;"> <div style="margin: 20px 0 5px 0; width: 100%;">
<button id="daemon-toggle" class="button-primary" onclick="toggleDaemon()" <button id="daemon-toggle" class="button-primary" onclick="toggleDaemon()"
style="width: 100%; font-size: 16px; font-weight: bold; margin-bottom: 0;"> style="width: 100%; font-size: 16px; font-weight: bold; margin-bottom: 0;">
<span id="daemon-button-text">Start Thrower</span> <span id="daemon-button-text">Start Thrower</span>
</button> </button>
</div> </div>
@ -228,8 +229,9 @@
extension: true, extension: true,
local: true, local: true,
seedphrase: true, seedphrase: true,
readonly: false,
connect: true, connect: true,
remote: false, remote: true,
otp: false otp: false
}, },
debug: true debug: true
@ -693,14 +695,14 @@
}); });
const results = await Promise.allSettled(publishPromises); const results = await Promise.allSettled(publishPromises);
let successCount = 0; let successCount = 0;
let failureCount = 0; let failureCount = 0;
results.forEach((promiseResult) => { results.forEach((promiseResult) => {
if (promiseResult.status === 'fulfilled') { if (promiseResult.status === 'fulfilled') {
const { relayUrl, success, error } = promiseResult.value; const { relayUrl, success, error } = promiseResult.value;
if (success) { if (success) {
successCount++; successCount++;
console.log('SUCCESS', `✅ Relay list published successfully to ${relayUrl}`); console.log('SUCCESS', `✅ Relay list published successfully to ${relayUrl}`);
@ -716,7 +718,7 @@
if (successCount > 0) { if (successCount > 0) {
showStatus('relay-status', 'Relay configuration saved successfully!', 'success'); showStatus('relay-status', 'Relay configuration saved successfully!', 'success');
console.log('SUCCESS', `Relay list published to ${successCount} out of ${relaysToUse.length} relays`); console.log('SUCCESS', `Relay list published to ${successCount} out of ${relaysToUse.length} relays`);
// Return to display mode after successful save // Return to display mode after successful save
cancelRelayEdit(); cancelRelayEdit();
} else { } else {
@ -869,7 +871,7 @@
try { try {
const message = JSON.parse(event.data); const message = JSON.parse(event.data);
console.log('INFO', `Received from ${relayUrl}:`, message); console.log('INFO', `Received from ${relayUrl}:`, message);
// Log ALL responses from relay in processing log // Log ALL responses from relay in processing log
addLogEntry('info', `📥 Response from ${relayUrl}: ${JSON.stringify(message)}`); addLogEntry('info', `📥 Response from ${relayUrl}: ${JSON.stringify(message)}`);
@ -1003,7 +1005,7 @@
const results = await Promise.allSettled(publishPromises); const results = await Promise.allSettled(publishPromises);
let successCount = 0; let successCount = 0;
results.forEach((promiseResult) => { results.forEach((promiseResult) => {
if (promiseResult.status === 'fulfilled' && promiseResult.value.success) { if (promiseResult.status === 'fulfilled' && promiseResult.value.success) {
successCount++; successCount++;
@ -1220,11 +1222,11 @@
const results = await Promise.allSettled(publishPromises); const results = await Promise.allSettled(publishPromises);
let successCount = 0; let successCount = 0;
let failureCount = 0; let failureCount = 0;
results.forEach((promiseResult) => { results.forEach((promiseResult) => {
if (promiseResult.status === 'fulfilled') { if (promiseResult.status === 'fulfilled') {
const { relayUrl, success, error } = promiseResult.value; const { relayUrl, success, error } = promiseResult.value;
if (success) { if (success) {
successCount++; successCount++;
console.log('SUCCESS', `✅ Thrower info published successfully to ${relayUrl}`); console.log('SUCCESS', `✅ Thrower info published successfully to ${relayUrl}`);
@ -1361,11 +1363,11 @@
const results = await Promise.allSettled(publishPromises); const results = await Promise.allSettled(publishPromises);
let successCount = 0; let successCount = 0;
results.forEach((promiseResult) => { results.forEach((promiseResult) => {
if (promiseResult.status === 'fulfilled') { if (promiseResult.status === 'fulfilled') {
const { relayUrl, success, error } = promiseResult.value; const { relayUrl, success, error } = promiseResult.value;
if (success) { if (success) {
successCount++; successCount++;
console.log('SUCCESS', `✅ Thrower info auto-republished to ${relayUrl}`); console.log('SUCCESS', `✅ Thrower info auto-republished to ${relayUrl}`);
@ -1584,7 +1586,7 @@
// Mark this event ID as processed // Mark this event ID as processed
processedEventIds.add(event.id); processedEventIds.add(event.id);
addLogEntry('info', `Received routing event: ${event.id.substring(0, 16)}...`); addLogEntry('info', `Received routing event: ${event.id.substring(0, 16)}...`);
try { try {
@ -1686,15 +1688,15 @@
// DEBUG: Check authentication state before attempting decryption // DEBUG: Check authentication state before attempting decryption
addLogEntry('info', `DEBUG AUTHENTICATION STATE CHECK:`); addLogEntry('info', `DEBUG AUTHENTICATION STATE CHECK:`);
// Check if window.nostr exists // Check if window.nostr exists
addLogEntry('info', ` window.nostr exists: ${!!window.nostr}`); addLogEntry('info', ` window.nostr exists: ${!!window.nostr}`);
addLogEntry('info', ` window.nostr constructor: ${window.nostr?.constructor?.name}`); addLogEntry('info', ` window.nostr constructor: ${window.nostr?.constructor?.name}`);
// Check if NOSTR_LOGIN_LITE exists and getAuthState function // Check if NOSTR_LOGIN_LITE exists and getAuthState function
addLogEntry('info', ` window.NOSTR_LOGIN_LITE exists: ${!!window.NOSTR_LOGIN_LITE}`); addLogEntry('info', ` window.NOSTR_LOGIN_LITE exists: ${!!window.NOSTR_LOGIN_LITE}`);
addLogEntry('info', ` getAuthState function exists: ${!!window.NOSTR_LOGIN_LITE?.getAuthState}`); addLogEntry('info', ` getAuthState function exists: ${!!window.NOSTR_LOGIN_LITE?.getAuthState}`);
// Get current auth state // Get current auth state
let authState = null; let authState = null;
try { try {
@ -1951,7 +1953,7 @@
try { try {
// Wait for all publishing attempts to complete // Wait for all publishing attempts to complete
const results = await Promise.allSettled(publishPromises); const results = await Promise.allSettled(publishPromises);
let successCount = 0; let successCount = 0;
let failureCount = 0; let failureCount = 0;
const successfulRelays = []; const successfulRelays = [];
@ -1961,7 +1963,7 @@
results.forEach((promiseResult, index) => { results.forEach((promiseResult, index) => {
if (promiseResult.status === 'fulfilled') { if (promiseResult.status === 'fulfilled') {
const { relayUrl, success, result, error } = promiseResult.value; const { relayUrl, success, result, error } = promiseResult.value;
if (success) { if (success) {
successCount++; successCount++;
successfulRelays.push(relayUrl); successfulRelays.push(relayUrl);
@ -1985,7 +1987,7 @@
if (successCount > 0) { if (successCount > 0) {
addLogEntry('success', `Successfully published to: ${successfulRelays.join(', ')}`); addLogEntry('success', `Successfully published to: ${successfulRelays.join(', ')}`);
// Log full published event (only once for successful publications) // Log full published event (only once for successful publications)
addLogEntry('info', `Full published event:\n${JSON.stringify(event, null, 2)}`); addLogEntry('info', `Full published event:\n${JSON.stringify(event, null, 2)}`);
} }