@@ -421,6 +421,16 @@ <h1>NostrKey</h1>
421421
422422 <!-- NIP-46 panel -->
423423 < div id ="panel-nip46 " class ="panel " style ="display:none ">
424+ <!-- NostrKey as Bunker section -->
425+ < div id ="nip46-nostrkey-bunker " style ="margin-bottom:16px ">
426+ < h4 style ="font-size:14px;color:#2d2d2d;margin-bottom:8px "> NostrKey as Bunker</ h4 >
427+ < button id ="btn-start-bunker " class ="btn btn-connect "> Start NostrKey Bunker</ button >
428+ < p id ="bunker-server-uri " class ="mono " style ="font-size:12px;color:#75715e;word-break:break-all;margin-top:8px;display:none "> </ p >
429+ < p id ="bunker-server-error " class ="field-error "> </ p >
430+ </ div >
431+
432+ < div style ="text-align:center;color:#b0b0a8;font-size:13px;margin:12px 0 "> — or paste URI manually —</ div >
433+
424434 < div id ="nip46-loading " style ="padding:10px 0 ">
425435 < p style ="font-size:13px;color:#75715e "> Loading NIP-46 libraries…</ p >
426436 </ div >
@@ -481,6 +491,7 @@ <h3>Relays</h3>
481491 var formDirty = false ;
482492 var relayPool = null ;
483493 var nip46Session = null ;
494+ var bunkerServerActive = false ;
484495 var activeTab = 'nip07' ;
485496
486497 // === Utilities ===
@@ -913,6 +924,100 @@ <h3>Relays</h3>
913924 }
914925 }
915926
927+ // === Start NostrKey as Bunker ===
928+ async function startNostrKeyBunker ( ) {
929+ if ( ! window . nostr || ! window . nostr . nip46 ) {
930+ document . getElementById ( 'bunker-server-error' ) . textContent = 'NostrKey extension not detected' ;
931+ document . getElementById ( 'bunker-server-error' ) . style . display = '' ;
932+ return ;
933+ }
934+
935+ var btn = document . getElementById ( 'btn-start-bunker' ) ;
936+ var uriEl = document . getElementById ( 'bunker-server-uri' ) ;
937+ var errEl = document . getElementById ( 'bunker-server-error' ) ;
938+ btn . disabled = true ;
939+ btn . textContent = 'Starting\u2026' ;
940+ errEl . style . display = 'none' ;
941+
942+ try {
943+ log ( 'info' , 'Starting NostrKey bunker server\u2026' ) ;
944+ var result = await window . nostr . nip46 . startBunker ( {
945+ relayUrls : [ 'wss://relay.nostrkey.com' ]
946+ } ) ;
947+
948+ if ( ! result . success ) throw new Error ( result . error || 'Failed to start bunker' ) ;
949+
950+ bunkerServerActive = true ;
951+ var uri = result . uri ;
952+ uriEl . textContent = uri ;
953+ uriEl . style . display = '' ;
954+ btn . textContent = 'Bunker Running' ;
955+ log ( 'success' , 'Bunker server started' ) ;
956+ log ( 'info' , 'URI: ' + uri ) ;
957+
958+ // Auto-connect: wait for NIP-46 client to be ready, then connect
959+ log ( 'info' , 'Auto-connecting via NIP-46\u2026' ) ;
960+ var nip46 = window . __nip46 ;
961+ if ( ! nip46 || ! nip46 . loaded ) {
962+ // Wait a moment for the module to load
963+ await new Promise ( function ( resolve ) {
964+ var handler = function ( ) {
965+ window . removeEventListener ( 'nip46-loaded' , handler ) ;
966+ resolve ( ) ;
967+ } ;
968+ window . addEventListener ( 'nip46-loaded' , handler ) ;
969+ setTimeout ( resolve , 3000 ) ;
970+ } ) ;
971+ nip46 = window . __nip46 ;
972+ }
973+
974+ if ( ! nip46 || ! nip46 . loaded ) throw new Error ( 'NIP-46 client libraries not loaded' ) ;
975+
976+ var config = nip46 . parseBunkerUrl ( uri ) ;
977+ var session = new nip46 . Nip46Session ( config ) ;
978+ await session . connect ( ) ;
979+ log ( 'success' , 'NIP-46 session established via NostrKey bunker' ) ;
980+
981+ var pubkey = await session . getPublicKey ( ) ;
982+ connectedPubkey = pubkey ;
983+ nip46Session = session ;
984+ currentSigner = {
985+ getPublicKey : function ( ) { return Promise . resolve ( pubkey ) ; } ,
986+ signEvent : function ( e ) { return session . signEvent ( e ) ; }
987+ } ;
988+ log ( 'success' , 'Remote signer: ' + hexToNpub ( pubkey ) ) ;
989+
990+ relayPool = new RelayPool ( ALL_RELAYS ) ;
991+ log ( 'info' , 'Connecting to relays\u2026' ) ;
992+ await relayPool . connect ( ) ;
993+ updateRelayDots ( ) ;
994+
995+ updateConnectionUI ( true , pubkey ) ;
996+ enableForm ( true ) ;
997+
998+ log ( 'info' , 'Fetching profile\u2026' ) ;
999+ var profile = await fetchProfile ( pubkey ) ;
1000+ if ( profile ) {
1001+ populateForm ( profile ) ;
1002+ log ( 'success' , 'Profile loaded' ) ;
1003+ } else {
1004+ originalProfile = { } ;
1005+ log ( 'info' , 'No existing profile \u2014 create a new one' ) ;
1006+ }
1007+ } catch ( err ) {
1008+ log ( 'error' , 'Bunker start failed: ' + err . message ) ;
1009+ errEl . textContent = err . message ;
1010+ errEl . style . display = '' ;
1011+ btn . disabled = false ;
1012+ btn . textContent = 'Start NostrKey Bunker' ;
1013+ // Clean up server if it started but connect failed
1014+ if ( bunkerServerActive ) {
1015+ try { await window . nostr . nip46 . stopBunker ( ) ; } catch ( e ) { }
1016+ bunkerServerActive = false ;
1017+ }
1018+ }
1019+ }
1020+
9161021 // === Connect NIP-46 ===
9171022 async function connectNip46 ( ) {
9181023 var uri = document . getElementById ( 'bunker-uri' ) . value . trim ( ) ;
@@ -973,6 +1078,10 @@ <h3>Relays</h3>
9731078 if ( formDirty && ! confirm ( 'You have unsaved changes. Disconnect anyway?' ) ) return ;
9741079
9751080 if ( nip46Session ) { nip46Session . disconnect ( ) ; nip46Session = null ; }
1081+ if ( bunkerServerActive ) {
1082+ try { window . nostr . nip46 . stopBunker ( ) ; } catch ( e ) { }
1083+ bunkerServerActive = false ;
1084+ }
9761085 if ( relayPool ) { relayPool . disconnect ( ) ; relayPool = null ; }
9771086
9781087 currentSigner = null ;
@@ -994,6 +1103,13 @@ <h3>Relays</h3>
9941103 document . getElementById ( 'bunker-uri' ) . disabled = false ;
9951104 validateBunkerUri ( ) ;
9961105
1106+ // Reset bunker server UI
1107+ var btnBunker = document . getElementById ( 'btn-start-bunker' ) ;
1108+ btnBunker . textContent = 'Start NostrKey Bunker' ;
1109+ btnBunker . disabled = false ;
1110+ document . getElementById ( 'bunker-server-uri' ) . style . display = 'none' ;
1111+ document . getElementById ( 'bunker-server-error' ) . style . display = 'none' ;
1112+
9971113 log ( 'info' , 'Disconnected' ) ;
9981114 }
9991115
@@ -1054,6 +1170,7 @@ <h3>Relays</h3>
10541170 t . addEventListener ( 'click' , function ( ) { switchTab ( t . getAttribute ( 'data-tab' ) ) ; } ) ;
10551171 } ) ;
10561172 document . getElementById ( 'btn-nip07-connect' ) . addEventListener ( 'click' , connectNip07 ) ;
1173+ document . getElementById ( 'btn-start-bunker' ) . addEventListener ( 'click' , startNostrKeyBunker ) ;
10571174 document . getElementById ( 'btn-nip46-connect' ) . addEventListener ( 'click' , connectNip46 ) ;
10581175 document . getElementById ( 'btn-disconnect' ) . addEventListener ( 'click' , doDisconnect ) ;
10591176 document . getElementById ( 'btn-save' ) . addEventListener ( 'click' , saveProfile ) ;
0 commit comments