9090 </div >
9191 </div >
9292
93+ <!-- Relay Configuration -->
94+ <div class =" form-group mb-3 mt-4" >
95+ <label for =" nostrRelays" class =" form-label" >Relay Servers:</label >
96+ <textarea
97+ id =" nostrRelays"
98+ class =" form-control"
99+ rows =" 3"
100+ v-model =" relaysText"
101+ placeholder =" Enter relay servers (one per line)"
102+ ></textarea >
103+ <div class =" form-text text-muted" >
104+ Enter relay servers (one per line) to publish your content to.
105+ </div >
106+ <div class =" form-check mt-2" >
107+ <input
108+ class =" form-check-input"
109+ type =" checkbox"
110+ id =" storeRelays"
111+ v-model =" storeRelays"
112+ />
113+ <label class =" form-check-label" for =" storeRelays" >
114+ Remember these relays for future posts
115+ </label >
116+ </div >
117+ </div >
118+
93119 <!-- Warning box when keys are generated -->
94120 <div v-if =" isNewlyGenerated" class =" alert alert-warning" >
95121 <div class =" d-flex align-items-center mb-2" >
@@ -280,6 +306,10 @@ export default {
280306 storeCredentials: true ,
281307 privateKeyVisible: false ,
282308 isNewlyGenerated: false ,
309+
310+ // Relay management
311+ relays: [" wss://relay.damus.io" , " wss://relay.nostr.band" , " wss://nos.lol" ],
312+ storeRelays: true ,
283313 };
284314 },
285315
@@ -295,19 +325,35 @@ export default {
295325 if (savedPrivateKey ) {
296326 this .privateKey = savedPrivateKey ;
297327 }
328+
329+ // Load saved relays
330+ this .loadSavedRelays ();
298331 },
299332
300333 computed: {
301334 nostrUrl() {
302335 return this .courseUrl ;
303336 },
337+
338+ relaysText: {
339+ get() {
340+ return this .relays .join (" \n " );
341+ },
342+ set(newValue ) {
343+ const relayArray = newValue .split (" \n " ).filter ((relay ) => relay .trim () !== " " );
344+ this .relays = relayArray ;
345+ },
346+ },
304347 },
305348
306349 methods: {
307350 close() {
308351 // Save credentials if requested
309352 this .saveCredentials ();
310353
354+ // Save relays if requested
355+ this .saveRelays ();
356+
311357 // Reset states
312358 this .isNewlyGenerated = false ;
313359 this .privateKeyVisible = false ;
@@ -316,15 +362,29 @@ export default {
316362 this .$emit (" close" );
317363 },
318364
365+ loadSavedRelays() {
366+ const savedRelays = localStorage .getItem (" nostrRelays" );
367+ if (savedRelays ) {
368+ try {
369+ this .relays = JSON .parse (savedRelays );
370+ } catch (e ) {
371+ console .error (" Error parsing saved relays:" , e );
372+ }
373+ }
374+ },
375+
376+ saveRelays() {
377+ if (this .storeRelays && this .relays .length > 0 ) {
378+ localStorage .setItem (" nostrRelays" , JSON .stringify (this .relays ));
379+ } else if (! this .storeRelays ) {
380+ localStorage .removeItem (" nostrRelays" );
381+ }
382+ },
383+
319384 generateKeyPair() {
320385 try {
321- // Generate a new private key
322386 const privateKey = generateSecretKey ();
323-
324- // Derive the public key from it
325387 const publicKey = getPublicKey (privateKey );
326-
327- // Convert to human-readable formats (npub, nsec)
328388 const npub = nip19 .npubEncode (publicKey );
329389 const nsec = nip19 .nsecEncode (privateKey );
330390
@@ -343,9 +403,7 @@ export default {
343403 },
344404
345405 copyToClipboard(text : string ) {
346- navigator .clipboard .writeText (text ).then (() => {
347- // Could show a small toast notification here
348- });
406+ navigator .clipboard .writeText (text ).then (() => {});
349407 },
350408
351409 saveCredentials() {
@@ -379,10 +437,14 @@ export default {
379437 return ;
380438 }
381439
382- // Save credentials if requested
440+ if (this .relays .length === 0 ) {
441+ alert (" Please enter at least one relay server." );
442+ return ;
443+ }
444+
383445 this .saveCredentials ();
446+ this .saveRelays ();
384447
385- // Loading indicator could be added here
386448 this .publishStatus = " loading" ;
387449
388450 const database = new Dexie ();
@@ -397,18 +459,9 @@ export default {
397459 const metaData = await meta ;
398460 const contentData = yDoc .getText (this .storageId ).toJSON ();
399461
400- console .log (" Content Data:" , contentData );
401- console .log (" Meta Data:" , metaData );
402-
403- // 1. Create a pool for relays
404462 const pool = new SimplePool ();
405- const relays = [
406- " wss://relay.damus.io" ,
407- " wss://relay.nostr.band" ,
408- " wss://nos.lol" ,
409- ];
463+ const relays = [... this .relays ];
410464
411- // 2. Decode the user's public key from npub format
412465 let pubkey;
413466 try {
414467 const decoded = nip19 .decode (this .publicKey );
@@ -419,61 +472,45 @@ export default {
419472 return ;
420473 }
421474
422- // 3. Prepare content
423475 const title = metaData ?.title || " LiaScript Course" ;
424476
425- // 4. Create the event (NIP-33 parameterized replaceable event)
426477 const event = {
427- kind: 30023 , // Long-form content
478+ kind: 30023 ,
428479 pubkey: pubkey ,
429480 created_at: Math .floor (Date .now () / 1000 ),
430481 tags: [
431- [" d" , this .storageId ], // Use storageId as identifier
482+ [" d" , this .storageId ],
432483 [" title" , title ],
433484 [" summary" , metaData ?.description || " LiaScript course material" ],
434485 ... this .tags .map ((tag ) => [" t" , tag ]),
435486 ],
436487 content: contentData ,
437488 };
438489
439- // 5. If user has provided private key, sign and publish
440490 if (this .privateKey ) {
441491 try {
442- // Decode private key
443492 const decoded = nip19 .decode (this .privateKey );
444493 const privkey = decoded .data ;
445494
446- // Sign the event - updated approach for newer nostr-tools
447495 event .id = getEventHash (event );
448496 const signedEvent = finalizeEvent (event , privkey );
449497
450- // Publish to relays
451- console .log (" Publishing event:" , signedEvent );
452-
453498 const pubs = pool .publish (relays , signedEvent );
454499
455- // Wait for at least one successful publish
456500 await Promise .any (pubs );
457501
458- // Create the naddr representation
459502 const naddr = nip19 .naddrEncode ({
460503 kind: 30023 ,
461504 pubkey: pubkey ,
462505 identifier: this .storageId ,
463506 relays: relays ,
464507 });
465508
466- // Set the published course URL
467509 this .publishedCourseUrl = ` https://liascript.github.io/course/?nostr:${naddr } ` ;
468510
469- console .log (" Published as naddr:" , " nostr:" + naddr );
470- console .log (" Published course URL:" , this .publishedCourseUrl );
471-
472- // Success!
473511 this .step = " success" ;
474512 this .publishStatus = " success" ;
475513
476- // Clear private key after successful publish for security
477514 this .privateKey = " " ;
478515 } catch (e ) {
479516 console .error (" Error publishing:" , e );
@@ -489,7 +526,6 @@ export default {
489526 alert (" Error processing document data." );
490527 this .publishStatus = " failed" ;
491528 } finally {
492- // Clean up
493529 provider .destroy ();
494530 yDoc .destroy ();
495531 }
0 commit comments