diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index d3798025..a1a06b79 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -13,8 +13,8 @@ android {
applicationId = "com.bitchat.droid"
minSdk = libs.versions.minSdk.get().toInt()
targetSdk = libs.versions.targetSdk.get().toInt()
- versionCode = 18
- versionName = "1.2.2"
+ versionCode = 19
+ versionName = "1.2.3"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 2b61df2f..9516695d 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -41,6 +41,12 @@
android:supportsRtl="true"
android:theme="@style/Theme.BitchatAndroid"
tools:targetApi="31">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/assets/nostr_relays.csv b/app/src/main/assets/nostr_relays.csv
index 47e6582c..293271d1 100644
--- a/app/src/main/assets/nostr_relays.csv
+++ b/app/src/main/assets/nostr_relays.csv
@@ -1,273 +1,263 @@
Relay URL,Latitude,Longitude
-relay.chorus.community,50.1109,8.68213
-relay-rpi.edufeed.org,49.4543,11.0746
-nostr.chaima.info,50.1109,8.68213
-relay.nostraddress.com,43.6532,-79.3832
-nostr.middling.mydns.jp,35.8099,140.12
-nostr.myshosholoza.co.za,52.3676,4.90414
-n.ok0.org,-37.7254,176.133
-relay.21e6.cz,50.1682,14.0546
-premium.primal.net,43.6532,-79.3832
-relay.stream.labs.h3.se,59.4016,17.9455
-nostr.night7.space,50.4754,12.3683
-nostr.4rs.nl,49.0291,8.35696
-relay.notoshi.win,13.7683,100.54
-nostr.carroarmato0.be,50.9017,3.52588
-relay.angor.io,48.1046,11.6002
-relay.nostriot.com,41.5695,-83.9786
-nostr-pub.wellorder.net,45.5201,-122.99
-relay04.lnfi.network,39.0997,-94.5786
-x.kojira.io,43.6532,-79.3832
-strfry.felixzieger.de,50.1013,8.62643
-purpura.cloud,43.6532,-79.3832
-alien.macneilmediagroup.com,43.6532,-79.3832
-wot.sudocarlos.com,51.5072,-0.127586
-relay02.lnfi.network,39.0997,-94.5786
-relay.getsafebox.app,43.6532,-79.3832
-wot.sebastix.social,51.8933,4.42083
-relay.dwadziesciajeden.pl,52.2297,21.0122
-nostr.roundrockbitcoiners.com,40.8054,-74.0241
-nostr.dlsouza.lol,50.1109,8.68213
-nostr-relay.shirogaku.xyz,43.6532,-79.3832
-yabu.me,35.6092,139.73
-nostr.stakey.net,52.3676,4.90414
-relay.sincensura.org,43.6532,-79.3832
-nostr-02.czas.top,51.2277,6.77346
-soloco.nl,43.6532,-79.3832
-nostream.breadslice.com,43.6532,-79.3832
-nostr.camalolo.com,24.1469,120.684
-nostr-dev.wellorder.net,45.5201,-122.99
-nostr.pleb.one,38.6327,-90.1961
-cyberspace.nostr1.com,40.7357,-74.1724
-relay.illuminodes.com,47.6061,-122.333
-satsage.xyz,37.3986,-121.964
-nostr.data.haus,50.4754,12.3683
-nostr.jfischer.org,49.0291,8.35696
-r.bitcoinhold.net,43.6532,-79.3832
-relay.barine.co,43.6532,-79.3832
-wot.sovbit.host,64.1466,-21.9426
-nostr.vulpem.com,49.4543,11.0746
-nostr.kalf.org,52.3676,4.90414
-nostr.thebiglake.org,32.71,-96.6745
-relay.bitcoinveneto.org,64.1466,-21.9426
-wot.dergigi.com,64.1476,-21.9392
-nos.xmark.cc,50.6924,3.20113
-nostr.88mph.life,43.6532,-79.3832
-relay.mess.ch,47.3591,8.55292
-nostr.thaliyal.com,40.8218,-74.45
-nostr.notribe.net,40.8302,-74.1299
-relay.orangepill.ovh,49.1689,-0.358841
-relay.artiostr.ch,43.6532,-79.3832
-relay.13room.space,43.6532,-79.3832
-relay.primal.net,43.6532,-79.3832
-strfry.shock.network,41.8959,-88.2169
-nostr.2b9t.xyz,34.0549,-118.243
-ribo.af.nostria.app,-26.2041,28.0473
-a.nos.lol,50.4754,12.3683
-relay.mccormick.cx,52.3563,4.95714
-relay.mostro.network,40.8302,-74.1299
-relay.bitcoinartclock.com,50.4754,12.3683
-nostr-relay.cbrx.io,43.6532,-79.3832
-prl.plus,55.7623,37.6381
-relay.endfiat.money,43.6532,-79.3832
-relay.hook.cafe,43.6532,-79.3832
-relay.siamdev.cc,13.9178,100.424
-wot.nostr.party,36.1627,-86.7816
-wot.basspistol.org,49.4521,11.0767
-dev-nostr.bityacht.io,25.0797,121.234
-orangesync.tech,51.5072,-0.127586
-nostr.casa21.space,43.6532,-79.3832
-relay.digitalezukunft.cyou,45.5019,-73.5674
-relay.nostrcheck.me,43.6532,-79.3832
-inbox.mycelium.social,38.627,-90.1994
-nostr.liberty.fans,36.9104,-89.5875
-nostr-verified.wellorder.net,45.5201,-122.99
-relay.sigit.io,50.4754,12.3683
-tollbooth.stens.dev,51.223,6.78245
-relay.nostromo.social,49.4543,11.0746
-wheat.happytavern.co,43.6532,-79.3832
-relay.vrtmrz.net,43.6532,-79.3832
-relayrs.notoshi.win,43.6532,-79.3832
-travis-shears-nostr-relay-v2.fly.dev,41.8781,-87.6298
-nostr.community.ath.cx,45.5029,-73.5723
-wot.girino.org,43.6532,-79.3832
-nostr.coincrowd.fund,39.0438,-77.4874
-relay.freeplace.nl,52.3676,4.90414
-nostr-03.dorafactory.org,1.35208,103.82
-relay5.bitransfer.org,43.6532,-79.3832
-nostr.tac.lol,47.4748,-122.273
-nostr.sagaciousd.com,49.2827,-123.121
-nostr.girino.org,43.6532,-79.3832
-nostr.jerrynya.fun,31.2304,121.474
-relay.agorist.space,52.3734,4.89406
-inbox.azzamo.net,52.2633,21.0283
-wot.codingarena.top,50.4754,12.3683
-relay.degmods.com,50.4754,12.3683
-articles.layer3.news,37.3387,-121.885
-nostr.rblb.it,43.4633,11.8796
-relay.davidebtc.me,51.5072,-0.127586
-relay.hodl.ar,-34.5904,-58.629
-nostr.rtvslawenia.com,49.4543,11.0746
-relay01.lnfi.network,39.0997,-94.5786
-strfry.bonsai.com,37.8715,-122.273
-relay.nostr.place,32.7767,-96.797
-relay.bitcoindistrict.org,43.6532,-79.3832
-relay.aloftus.io,34.0881,-118.379
-nostr.massmux.com,51.5072,-0.127586
-relay.wellorder.net,45.5201,-122.99
-santo.iguanatech.net,40.8302,-74.1299
relay.damus.io,43.6532,-79.3832
-relay.javi.space,43.4633,11.8796
-relay.nosto.re,51.8933,4.42083
-relay.utxo.farm,35.6916,139.768
-relay.fr13nd5.com,52.5233,13.3426
-librerelay.aaroniumii.com,43.6532,-79.3832
-relay.cypherflow.ai,48.8566,2.35222
-relay.letsfo.com,51.098,17.0321
-nostr.0x7e.xyz,47.4988,8.72369
-relay.bullishbounty.com,43.6532,-79.3832
-relay.tagayasu.xyz,43.6715,-79.38
-nostr.plantroon.com,50.1013,8.62643
-strfry.openhoofd.nl,51.9229,4.40833
-nostrelites.org,41.8781,-87.6298
-relay.credenso.cafe,43.1149,-80.7228
-relay.conduit.market,43.6532,-79.3832
-relay.olas.app,50.4754,12.3683
-relay.nostrdice.com,-33.8688,151.209
-nostr.oxtr.dev,50.4754,12.3683
-relay.nostr.band,60.1699,24.9384
-khatru.nostrver.se,51.8933,4.42083
-relay.coinos.io,43.6532,-79.3832
-nostr.l484.com,30.2944,-97.6223
-purplerelay.com,50.1109,8.68213
-relay.nostrhub.fr,48.1046,11.6002
-black.nostrcity.club,41.8781,-87.6298
-nostr.snowbla.de,60.1699,24.9384
-no.str.cr,9.93388,-84.0849
-nostr.rikmeijer.nl,50.4754,12.3683
-nproxy.kristapsk.lv,60.1699,24.9384
-wot.soundhsa.com,34.0479,-118.256
-nostr.kungfu-g.rip,33.7946,-84.4488
-nostr.spaceshell.xyz,43.6532,-79.3832
-nostr.mikoshi.de,50.1109,8.68213
-gnostr.com,40.9017,29.1616
-noxir.kpherox.dev,34.8587,135.509
-nostr.ser1.net,12.9716,77.5946
-nostr-relay.zimage.com,34.282,-118.439
nostr2.girino.org,43.6532,-79.3832
-dev-relay.lnfi.network,39.0997,-94.5786
-nostr.hifish.org,47.3769,8.54169
-itanostr.space,52.2931,4.79099
-srtrelay.c-stellar.net,43.6532,-79.3832
-wot.dtonon.com,43.6532,-79.3832
-relay.mwaters.net,50.9871,2.12554
-relay.nostr.net,50.4754,12.3683
-relay.nostx.io,43.6532,-79.3832
-relay.laantungir.net,-19.4692,-42.5315
-pyramid.fiatjaf.com,50.1109,8.68213
-nostr.einundzwanzig.space,50.1109,8.68213
-relay.satlantis.io,32.8769,-80.0114
-nostr-relay.amethyst.name,35.7327,-78.8503
-fanfares.nostr1.com,40.7057,-74.0136
-relay.evanverma.com,40.8302,-74.1299
-relay.wavlake.com,41.2619,-95.8608
-relay.bitchat.party,53.5501,-113.469
-nostr.yael.at,52.3563,4.95714
-fenrir-s.notoshi.win,43.6532,-79.3832
-relay.nostr.wirednet.jp,34.704,135.495
-relay.origin.land,35.6673,139.751
-relay.goodmorningbitcoin.com,43.6532,-79.3832
-relay.mattybs.lol,43.6532,-79.3832
-relay.nostr.vet,52.6467,4.7395
-relay.arx-ccn.com,50.4754,12.3683
-nostr.agentcampfire.com,50.8933,6.05805
-ribo.eu.nostria.app,52.3676,4.90414
-nostr.huszonegy.world,47.4979,19.0402
-nostr-rs-relay-ishosta.phamthanh.me,43.6532,-79.3832
-temp.iris.to,43.6532,-79.3832
-relay.etch.social,41.2619,-95.8608
-relay.hasenpfeffr.com,39.0438,-77.4874
-relay.exit.pub,50.4754,12.3683
-relay.chakany.systems,43.6532,-79.3832
-nostr.coincards.com,45.4002,-75.8064
-nostr.hekster.org,37.3986,-121.964
-nostr-relay.psfoundation.info,39.0438,-77.4874
-nostr-2.21crypto.ch,47.1928,8.81494
-nostr-rs-relay.dev.fedibtc.com,39.0438,-77.4874
-relay.toastr.net,40.8054,-74.0241
-relay.wolfcoil.com,35.6092,139.73
-nostr-02.dorafactory.org,1.35208,103.82
-portal-relay.pareto.space,49.4543,11.0746
-nostr.makibisskey.work,43.6532,-79.3832
-shu04.shugur.net,25.2604,55.2989
-relay.lnfi.network,39.0438,-77.4874
-nostr.smut.cloud,43.6532,-79.3832
-nostr.diakod.com,43.6532,-79.3832
-relay.lumina.rocks,49.0291,8.35695
-nostr.now,36.55,139.733
-relay.mockingyou.com,37.5485,-121.989
-nostr.blankfors.se,60.1699,24.9384
-adre.su,59.9311,30.3609
-nostr.tadryanom.me,43.6532,-79.3832
-relay2.angor.io,48.1046,11.6002
-shu02.shugur.net,21.4902,39.2246
-nostrelay.circum.space,51.2217,6.77616
-nostr.spacecitynode.com,29.7057,-95.2706
-vidono.apps.slidestr.net,48.8566,2.35222
-relay.btcwill.win,43.6532,-79.3832
-orangepiller.org,60.1699,24.9384
-solo.itsalldance.space,32.71,-96.6745
-relay.zone667.com,60.1699,24.9384
-nostr.azzamo.net,52.2633,21.0283
-internationalright-wing.org,-22.5986,-48.8003
-shu05.shugur.net,48.8566,2.35222
-relay.lifpay.me,1.35208,103.82
-slick.mjex.me,39.048,-77.4817
-theoutpost.life,64.1476,-21.9392
-nostr.rohoss.com,50.1109,8.68213
-relay.cosmicbolt.net,37.3986,-121.964
-relay.jeffg.fyi,43.6532,-79.3832
-nostr.satstralia.com,64.1476,-21.9392
-relay-admin.thaliyal.com,40.8218,-74.45
-social.proxymana.net,60.1699,24.9384
-nostr.sathoarder.com,48.5734,7.75211
-wot.nostr.place,30.2672,-97.7431
-nostr-relay-1.trustlessenterprise.com,43.6532,-79.3832
-relay.nsnip.io,60.1699,24.9384
-nostr.zenon.network,43.5009,-70.4428
-relay.copylaradio.com,50.8198,-1.08798
-relay.nostrhub.tech,49.4543,11.0746
-ithurtswhenip.ee,51.0238,-1.33713
-nostr-01.yakihonne.com,1.32123,103.695
-nostr-relay.online,43.6532,-79.3832
-vitor.nostr1.com,40.7057,-74.0136
-relay-testnet.k8s.layer3.news,37.3387,-121.885
-schnorr.me,43.6532,-79.3832
-relay.artx.market,43.652,-79.3633
-nostr.21crypto.ch,47.1928,8.81494
-relayone.soundhsa.com,34.0479,-118.256
-relay.puresignal.news,43.6532,-79.3832
nostr.n7ekb.net,47.4941,-122.294
-wot.brightbolt.net,47.6735,-116.781
-nostr.overmind.lol,43.6532,-79.3832
-relay.magiccity.live,25.8128,-80.2377
-kitchen.zap.cooking,43.6532,-79.3832
-relay.satsdays.com,1.35208,103.82
-nostr-02.yakihonne.com,1.32123,103.695
-offchain.pub,36.1809,-115.241
-nostr.lojong.info,43.6532,-79.3832
-relay.tapestry.ninja,40.8054,-74.0241
-zap.watch,45.5029,-73.5723
-nostrelay.memory-art.xyz,43.6532,-79.3832
-nostr.spicyz.io,43.6532,-79.3832
-nostr.mom,50.4754,12.3683
-nos.lol,50.4754,12.3683
+rnostr.breadslice.com,43.6532,-79.3832
+portal-relay.pareto.space,49.4543,11.0746
+relay.hasenpfeffr.com,39.0438,-77.4874
+nostr.blankfors.se,60.1699,24.9384
+relay5.bitransfer.org,43.6532,-79.3832
+santo.iguanatech.net,40.8302,-74.1299
+nostr.ser1.net,12.9716,77.5946
+nostr.stakey.net,52.3676,4.90414
+relayrs.notoshi.win,43.6532,-79.3832
+orangepiller.org,60.1699,24.9384
+temp.iris.to,43.6532,-79.3832
+relay.cypherflow.ai,48.8566,2.35222
+nostr.kalf.org,52.3676,4.90414
+relay.unknown.cloud,43.6532,-79.3832
+relay.artx.market,43.652,-79.3633
+relay.arx-ccn.com,50.4754,12.3683
relay.electriclifestyle.com,26.2897,-80.1293
-wot.nostr.net,43.6532,-79.3832
-nostr.primz.org,43.6532,-79.3832
+nostr-relay.online,43.6532,-79.3832
+relay.jeffg.fyi,43.6532,-79.3832
+relay.wellorder.net,45.5201,-122.99
+relay01.lnfi.network,39.0997,-94.5786
+noxir.kpherox.dev,34.8587,135.509
+wot.sebastix.social,51.8933,4.42083
+nostr.overmind.lol,43.6532,-79.3832
nostr.red5d.dev,43.6532,-79.3832
-relay.0xchat.com,1.35208,103.82
-relay.moinsen.com,50.4754,12.3683
-relay03.lnfi.network,39.0997,-94.5786
+nostr.zenon.network,43.5009,-70.4428
+cyberspace.nostr1.com,40.7128,-74.006
+fenrir-s.notoshi.win,43.6532,-79.3832
+no.str.cr,9.92857,-84.0528
+relay.nostrdice.com,-33.8688,151.209
+nostr.data.haus,50.4754,12.3683
+relay.g1sms.fr,43.9432,2.07537
+relay.fundstr.me,42.3601,-71.0589
+nostr.thaliyal.com,40.8218,-74.45
+relay.mccormick.cx,52.3563,4.95714
+nostr.makibisskey.work,43.6532,-79.3832
+shu01.shugur.net,21.4902,39.2246
+relay.angor.io,48.1046,11.6002
+nostr.primz.org,43.6532,-79.3832
+nostr-02.yakihonne.com,1.32123,103.695
+relay.freeplace.nl,52.3676,4.90414
+relay.snort.social,43.6532,-79.3832
+nostr.rohoss.com,50.1109,8.68213
+relay.getsafebox.app,43.6532,-79.3832
+nostr.88mph.life,43.6532,-79.3832
+wot.sovbit.host,64.1466,-21.9426
+nostr-02.dorafactory.org,1.35208,103.82
+itanostr.space,52.2931,4.79099
+ribo.af.nostria.app,-26.2041,28.0473
+nostr.azzamo.net,52.2633,21.0283
+relay.fountain.fm,39.0997,-94.5786
relay.holzeis.me,43.6532,-79.3832
+relay.sincensura.org,43.6532,-79.3832
+nostr-dev.wellorder.net,45.5201,-122.99
+relay.hodl.ar,-32.94,-60.6745
+nostr-relay.psfoundation.info,39.0438,-77.4874
+relay.goodmorningbitcoin.com,43.6532,-79.3832
+nostr.rtvslawenia.com,49.4543,11.0746
+relay.13room.space,43.6532,-79.3832
+nostr-02.czas.top,53.471,9.88208
+relay.chorus.community,50.1109,8.68213
+shu04.shugur.net,25.2604,55.2989
+satsage.xyz,37.3986,-121.964
+relay.bullishbounty.com,43.6532,-79.3832
+nostr.sagaciousd.com,49.2827,-123.121
+relay.nostromo.social,49.4543,11.0746
+relay.magiccity.live,25.8128,-80.2377
relay-dev.satlantis.io,40.8302,-74.1299
+nostr.coincrowd.fund,39.0438,-77.4874
+shu05.shugur.net,48.8566,2.35222
+nostrelay.memory-art.xyz,43.6532,-79.3832
+nostr.now,36.55,139.733
+nostr-pub.wellorder.net,45.5201,-122.99
+nos.lol,50.4754,12.3683
+wot.dergigi.com,64.1476,-21.9392
+inbox.azzamo.net,52.2633,21.0283
+nostr.mikoshi.de,50.1109,8.68213
+librerelay.aaroniumii.com,43.6532,-79.3832
+relay.nosto.re,51.8933,4.42083
+relay.lumina.rocks,49.0291,8.35695
+kitchen.zap.cooking,43.6532,-79.3832
+zap.watch,45.5029,-73.5723
+nostr.spacecitynode.com,29.7057,-95.2706
+nostr.bilthon.dev,25.8128,-80.2377
+relay.aloftus.io,34.0881,-118.379
+shu02.shugur.net,21.4902,39.2246
+relay.mwaters.net,50.9871,2.12554
+relay.moinsen.com,50.4754,12.3683
+nostr.kungfu-g.rip,33.7946,-84.4488
+nostr.sathoarder.com,48.5734,7.75211
+nostream.breadslice.com,43.6532,-79.3832
+slick.mjex.me,39.048,-77.4817
+nostr.jerrynya.fun,31.2304,121.474
+articles.layer3.news,37.3387,-121.885
+nostr.satstralia.com,64.1476,-21.9392
+relay.degmods.com,50.4754,12.3683
+relay.0xchat.com,1.35208,103.82
+relay.nostx.io,43.6532,-79.3832
+relay.siamdev.cc,13.9178,100.424
+relay.mattybs.lol,43.6532,-79.3832
+relay.bitcoinveneto.org,64.1466,-21.9426
+nostr.tadryanom.me,43.6532,-79.3832
+nostr.spaceshell.xyz,43.6532,-79.3832
+relay.nostr.band,60.1699,24.9384
+relay03.lnfi.network,39.0997,-94.5786
+schnorr.me,43.6532,-79.3832
+khatru.nostrver.se,51.8933,4.42083
+dealtime-footwear-angry-records.trycloudflare.com,43.6532,-79.3832
+relay.endfiat.money,43.6532,-79.3832
+internationalright-wing.org,-22.5022,-48.7114
+nostr.mom,50.4754,12.3683
+nostrue.com,40.8054,-74.0241
+relay.chakany.systems,43.6532,-79.3832
+vidono.apps.slidestr.net,48.8566,2.35222
+relay.stream.labs.h3.se,59.4016,17.9455
+gnostr.com,40.9017,29.1616
+relay.origin.land,35.6673,139.751
+relay.sigit.io,50.4754,12.3683
+theoutpost.life,64.1476,-21.9392
+adre.su,59.9311,30.3609
+soloco.nl,43.6532,-79.3832
+wot.soundhsa.com,34.0479,-118.256
+nos.xmark.cc,50.6924,3.20113
+nostr-relay.zimage.com,34.282,-118.439
+nostr.pleb.one,38.6327,-90.1961
+purpura.cloud,43.6532,-79.3832
+ribo.us.nostria.app,41.5868,-93.625
+relay.digitalezukunft.cyou,45.5019,-73.5674
+relay.mess.ch,47.3591,8.55292
+relay.javi.space,43.4633,11.8796
+nostr.jfischer.org,49.0291,8.35696
+nostr.rblb.it,43.4633,11.8796
+relay.nostriot.com,41.5695,-83.9786
+nostr.21crypto.ch,47.4988,8.72369
+relay.nostr.vet,52.6467,4.7395
+fanfares.nostr1.com,40.7057,-74.0136
+relay.copylaradio.com,51.223,6.78245
+relay.mostro.network,40.8302,-74.1299
+nostr-rs-relay-ishosta.phamthanh.me,43.6532,-79.3832
+relay.lifpay.me,1.35208,103.82
+nostr.tac.lol,47.4748,-122.273
+relay.nostraddress.com,43.6532,-79.3832
+wot.sudocarlos.com,51.5072,-0.127586
+nostr.spicyz.io,43.6532,-79.3832
+relay02.lnfi.network,39.0997,-94.5786
+nostr.4rs.nl,49.0291,8.35696
+relay.21e6.cz,50.1682,14.0546
+nostr.casa21.space,43.6532,-79.3832
+wot.codingarena.top,50.4754,12.3683
+nostr-01.yakihonne.com,1.32123,103.695
+strfry.openhoofd.nl,51.9229,4.40833
+nostr.plantroon.com,50.1013,8.62643
+dev-nostr.bityacht.io,25.0797,121.234
+ribo.eu.nostria.app,52.3676,4.90414
+wot.nostr.place,30.2672,-97.7431
+relay.dwadziesciajeden.pl,52.2297,21.0122
+prl.plus,55.7623,37.6381
+relay.bitcoinartclock.com,50.4754,12.3683
+nostr.2b9t.xyz,34.0549,-118.243
+a.nos.lol,50.4754,12.3683
+relay.wavlake.com,41.2619,-95.8608
+relay.toastr.net,40.8054,-74.0241
+wheat.happytavern.co,43.6532,-79.3832
+relay.lnfi.network,39.0438,-77.4874
+nostr.liberty.fans,36.9104,-89.5875
+vitor.nostr1.com,40.7057,-74.0136
+nostr.thebiglake.org,32.71,-96.6745
+relay.exit.pub,50.4754,12.3683
+freelay.sovbit.host,64.1476,-21.9392
+purplerelay.com,50.1109,8.68213
+nostr.camalolo.com,24.1469,120.684
+black.nostrcity.club,41.8781,-87.6298
+relay.barine.co,43.6532,-79.3832
+nostr.0x7e.xyz,47.4988,8.72369
+relayone.soundhsa.com,34.0479,-118.256
+relay.vrtmrz.net,43.6532,-79.3832
+nostr-03.dorafactory.org,1.35208,103.82
+r.bitcoinhold.net,43.6532,-79.3832
+relay.agorist.space,52.3734,4.89406
+nostr-relay.amethyst.name,39.0067,-77.4291
+relay-rpi.edufeed.org,49.4543,11.0746
+orangesync.tech,50.1109,8.68213
+relay04.lnfi.network,39.0997,-94.5786
+nostr.hifish.org,47.4043,8.57398
+relay.nostr.wirednet.jp,34.706,135.493
+nostr.girino.org,43.6532,-79.3832
+strfry.felixzieger.de,50.1013,8.62643
+nostr.night7.space,50.4754,12.3683
+nostr.oxtr.dev,50.4754,12.3683
+relay.nostrhub.fr,48.1046,11.6002
+nostr.rikmeijer.nl,50.4754,12.3683
+wot.basspistol.org,49.4521,11.0767
+nostr.coincards.com,53.5501,-113.469
+solo.itsalldance.space,32.71,-96.6745
+relay.puresignal.news,43.6532,-79.3832
+nostrelay.circum.space,51.2217,6.77616
+relay.btcforplebs.com,43.6532,-79.3832
+nostr.diakod.com,43.6532,-79.3832
+tollbooth.stens.dev,51.223,6.78245
+relay.usefusion.ai,39.0438,-77.4874
+relay-admin.thaliyal.com,40.8218,-74.45
+nproxy.kristapsk.lv,60.1699,24.9384
+nostr-verified.wellorder.net,45.5201,-122.99
+wot.brightbolt.net,47.6735,-116.781
+relay.orangepill.ovh,49.1689,-0.358841
+relay.olas.app,50.4754,12.3683
+offchain.pub,36.1809,-115.241
+nostr.l484.com,30.2944,-97.6223
+relay.nostrhub.tech,49.4543,11.0746
+relay.tapestry.ninja,40.8054,-74.0241
+nostr.snowbla.de,60.1699,24.9384
+relay.letsfo.com,51.098,17.0321
+relay.tagayasu.xyz,43.6715,-79.38
+strfry.bonsai.com,37.8715,-122.273
+nostr-relay-1.trustlessenterprise.com,43.6532,-79.3832
+nostr.smut.cloud,43.6532,-79.3832
+x.kojira.io,43.6532,-79.3832
+yabu.me,35.6092,139.73
+relay.zone667.com,60.1699,24.9384
+relay.bitcoindistrict.org,43.6532,-79.3832
+pyramid.fiatjaf.com,50.1109,8.68213
+nostr.hekster.org,37.3986,-121.964
+relay.laantungir.net,-19.4692,-42.5315
+relay.cosmicbolt.net,37.3986,-121.964
+strfry.shock.network,41.8959,-88.2169
+relay.coinos.io,43.6532,-79.3832
+wot.nostr.net,43.6532,-79.3832
+nostr.einundzwanzig.space,50.1109,8.68213
+premium.primal.net,43.6532,-79.3832
+dev-relay.lnfi.network,39.0997,-94.5786
+ynostr.yael.at,60.1699,24.9384
+relay.fr13nd5.com,52.5233,13.3426
+nostr.lojong.info,43.6532,-79.3832
+srtrelay.c-stellar.net,43.6532,-79.3832
+nostr.myshosholoza.co.za,52.3676,4.90414
+alien.macneilmediagroup.com,43.6532,-79.3832
+relay.utxo.farm,35.6916,139.768
+relay.ru.ac.th,13.7584,100.622
+relay2.angor.io,48.1046,11.6002
+relay.seq1.net,43.6532,-79.3832
+relay.illuminodes.com,47.6061,-122.333
+relay.satlantis.io,32.8769,-80.0114
+relay.primal.net,43.6532,-79.3832
+nostr.vulpem.com,49.4543,11.0746
+relay.evanverma.com,40.8302,-74.1299
+nostr.chaima.info,51.223,6.78245
+relay.notoshi.win,13.7829,100.546
+nostr.carroarmato0.be,50.9928,3.26317
+relay.ditto.pub,43.6532,-79.3832
+relay.credenso.cafe,43.1149,-80.7228
+relay.nostr.place,32.7767,-96.797
+relay.conduit.market,43.6532,-79.3832
+nostr.huszonegy.world,47.4979,19.0402
+nostr-rs-relay.dev.fedibtc.com,39.0438,-77.4874
+wot.nostr.party,36.1627,-86.7816
+wot.dtonon.com,43.6532,-79.3832
+nostr.middling.mydns.jp,35.8099,140.12
+nostr-2.21crypto.ch,47.4988,8.72369
+nostr.dlsouza.lol,50.1109,8.68213
diff --git a/app/src/main/java/com/bitchat/android/favorites/FavoritesPersistenceService.kt b/app/src/main/java/com/bitchat/android/favorites/FavoritesPersistenceService.kt
index f1366243..fe04c7b2 100644
--- a/app/src/main/java/com/bitchat/android/favorites/FavoritesPersistenceService.kt
+++ b/app/src/main/java/com/bitchat/android/favorites/FavoritesPersistenceService.kt
@@ -9,11 +9,12 @@ import java.util.*
/**
* Bridging Noise and Nostr favorites
- * Direct port from iOS FavoritesPersistenceService.swift
+ * Direct port from iOS FavoritesPersistenceService.swift, with Android-specific
+ * peerID (16-hex) -> npub indexing for Nostr DM routing.
*/
data class FavoriteRelationship(
val peerNoisePublicKey: ByteArray, // Noise static public key (32 bytes)
- val peerNostrPublicKey: String?, // npub bech32 string
+ val peerNostrPublicKey: String?, // npub bech32 string
val peerNickname: String,
val isFavorite: Boolean, // We favorited them
val theyFavoritedUs: Boolean, // They favorited us
@@ -21,22 +22,22 @@ data class FavoriteRelationship(
val lastUpdated: Date
) {
val isMutual: Boolean get() = isFavorite && theyFavoritedUs
-
+
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
-
+
other as FavoriteRelationship
-
+
if (!peerNoisePublicKey.contentEquals(other.peerNoisePublicKey)) return false
if (peerNostrPublicKey != other.peerNostrPublicKey) return false
if (peerNickname != other.peerNickname) return false
if (isFavorite != other.isFavorite) return false
if (theyFavoritedUs != other.theyFavoritedUs) return false
-
+
return true
}
-
+
override fun hashCode(): Int {
var result = peerNoisePublicKey.contentHashCode()
result = 31 * result + (peerNostrPublicKey?.hashCode() ?: 0)
@@ -54,20 +55,21 @@ interface FavoritesChangeListener {
/**
* Manages favorites with Noise↔Nostr mapping
- * Singleton pattern matching iOS implementation
+ * Singleton pattern matching iOS implementation.
*/
class FavoritesPersistenceService private constructor(private val context: Context) {
-
+
companion object {
private const val TAG = "FavoritesPersistenceService"
- private const val FAVORITES_KEY = "favorite_relationships"
-
+ private const val FAVORITES_KEY = "favorite_relationships" // noiseHex -> relationship
+ private const val PEERID_INDEX_KEY = "favorite_peerid_index" // peerID(16-hex) -> npub
+
@Volatile
private var INSTANCE: FavoritesPersistenceService? = null
-
+
val shared: FavoritesPersistenceService
get() = INSTANCE ?: throw IllegalStateException("FavoritesPersistenceService not initialized")
-
+
fun initialize(context: Context) {
if (INSTANCE == null) {
synchronized(this) {
@@ -78,46 +80,40 @@ class FavoritesPersistenceService private constructor(private val context: Conte
}
}
}
-
+
private val stateManager = SecureIdentityStateManager(context)
private val gson = Gson()
- private val favorites = mutableMapOf() // noiseKeyHex -> relationship
+ private val favorites = mutableMapOf() // noiseHex -> relationship
+ // NEW: Index by current mesh peerID (16-hex) for direct lookup when sending Nostr DMs from mesh context
+ private val peerIdIndex = mutableMapOf() // peerID (lowercase 16-hex) -> npub
private val listeners = mutableListOf()
-
+
init {
loadFavorites()
+ loadPeerIdIndex()
}
-
- /**
- * Get favorite status for Noise public key
- */
+
+ /** Get favorite status for Noise public key */
fun getFavoriteStatus(noisePublicKey: ByteArray): FavoriteRelationship? {
val keyHex = noisePublicKey.joinToString("") { "%02x".format(it) }
return favorites[keyHex]
}
-
- /**
- * Get favorite status for 16-hex peerID
- */
+
+ /** Get favorite status for 16-hex peerID (by noiseHex prefix match) */
fun getFavoriteStatus(peerID: String): FavoriteRelationship? {
- // For 16-hex peerIDs, we need to find the corresponding full Noise key
- // This is a simplified lookup - in practice you'd use fingerprint matching
+ val pid = peerID.lowercase()
for ((_, relationship) in favorites) {
val noiseKeyHex = relationship.peerNoisePublicKey.joinToString("") { "%02x".format(it) }
- if (noiseKeyHex.startsWith(peerID)) {
- return relationship
- }
+ if (noiseKeyHex.startsWith(pid)) return relationship
}
return null
}
-
- /**
- * Update Nostr public key for a peer
- */
+
+ /** Update Nostr public key for a peer (indexed by Noise key) */
fun updateNostrPublicKey(noisePublicKey: ByteArray, nostrPubkey: String) {
val keyHex = noisePublicKey.joinToString("") { "%02x".format(it) }
val existing = favorites[keyHex]
-
+
if (existing != null) {
val updated = existing.copy(
peerNostrPublicKey = nostrPubkey,
@@ -125,7 +121,6 @@ class FavoritesPersistenceService private constructor(private val context: Conte
)
favorites[keyHex] = updated
} else {
- // Create new relationship
val relationship = FavoriteRelationship(
peerNoisePublicKey = noisePublicKey,
peerNostrPublicKey = nostrPubkey,
@@ -137,19 +132,54 @@ class FavoritesPersistenceService private constructor(private val context: Conte
)
favorites[keyHex] = relationship
}
-
+
saveFavorites()
notifyChanged(keyHex)
Log.d(TAG, "Updated Nostr pubkey association for ${keyHex.take(16)}...")
}
-
- /**
- * Update favorite status
- */
+
+ /** NEW: Update Nostr pubkey for specific mesh peerID (16-hex). */
+ fun updateNostrPublicKeyForPeerID(peerID: String, nostrPubkey: String) {
+ val pid = peerID.lowercase()
+ if (pid.length == 16 && pid.matches(Regex("^[0-9a-f]+$"))) {
+ peerIdIndex[pid] = nostrPubkey
+ savePeerIdIndex()
+ Log.d(TAG, "Indexed npub for peerID ${pid.take(8)}…")
+ } else {
+ Log.w(TAG, "updateNostrPublicKeyForPeerID called with non-16hex peerID: $peerID")
+ }
+ }
+
+ /** NEW: Resolve Nostr pubkey via current peerID mapping (fast path). */
+ fun findNostrPubkeyForPeerID(peerID: String): String? {
+ return peerIdIndex[peerID.lowercase()]
+ }
+
+ /** NEW: Resolve peerID (16-hex) for a given Nostr pubkey (npub or hex). */
+ fun findPeerIDForNostrPubkey(nostrPubkey: String): String? {
+ // First, try direct match in peerIdIndex (values are stored as npub strings)
+ peerIdIndex.entries.firstOrNull { it.value.equals(nostrPubkey, ignoreCase = true) }?.let { return it.key }
+
+ // Attempt legacy mapping via favorites Noise key association
+ val targetHex = normalizeNostrKeyToHex(nostrPubkey)
+ if (targetHex != null) {
+ // Find relationship with matching nostr pubkey (normalized to hex) and then try to map to current peerID via noise key prefix
+ val rel = favorites.values.firstOrNull { it.peerNostrPublicKey?.let { stored -> normalizeNostrKeyToHex(stored) } == targetHex }
+ if (rel != null) {
+ val noiseHex = rel.peerNoisePublicKey.joinToString("") { "%02x".format(it) }
+ // Return 16-hex prefix as best-effort if no explicit mapping exists
+ return noiseHex.take(16)
+ }
+ }
+ return null
+ }
+
+ /** Update favorite status */
fun updateFavoriteStatus(noisePublicKey: ByteArray, nickname: String, isFavorite: Boolean) {
val keyHex = noisePublicKey.joinToString("") { "%02x".format(it) }
+
val existing = favorites[keyHex]
-
+
val updated = if (existing != null) {
existing.copy(
peerNickname = nickname,
@@ -168,21 +198,19 @@ class FavoritesPersistenceService private constructor(private val context: Conte
lastUpdated = Date()
)
}
-
+
favorites[keyHex] = updated
saveFavorites()
notifyChanged(keyHex)
Log.d(TAG, "Updated favorite status for $nickname: $isFavorite")
}
-
- /**
- * Update peer favorited us status
- */
+
+ /** Update peer favorited-us flag */
fun updatePeerFavoritedUs(noisePublicKey: ByteArray, theyFavoritedUs: Boolean) {
val keyHex = noisePublicKey.joinToString("") { "%02x".format(it) }
val existing = favorites[keyHex]
-
+
if (existing != null) {
val updated = existing.copy(
theyFavoritedUs = theyFavoritedUs,
@@ -191,101 +219,98 @@ class FavoritesPersistenceService private constructor(private val context: Conte
favorites[keyHex] = updated
saveFavorites()
notifyChanged(keyHex)
-
+
Log.d(TAG, "Updated peer favorited us for ${keyHex.take(16)}...: $theyFavoritedUs")
}
}
-
- /**
- * Get all mutual favorites
- */
- fun getMutualFavorites(): List {
- return favorites.values.filter { it.isMutual }
- }
-
- /**
- * Get all favorites we have
- */
- fun getOurFavorites(): List {
- return favorites.values.filter { it.isFavorite }
- }
-
- /**
- * Clear all favorites
- */
+
+ fun getMutualFavorites(): List = favorites.values.filter { it.isMutual }
+ fun getOurFavorites(): List = favorites.values.filter { it.isFavorite }
+
fun clearAllFavorites() {
favorites.clear()
saveFavorites()
+ peerIdIndex.clear()
+ savePeerIdIndex()
Log.i(TAG, "Cleared all favorites")
notifyAllCleared()
}
-
- /**
- * Find Noise key by Nostr pubkey
- */
+
+ /** Find Noise key by Nostr pubkey */
fun findNoiseKey(forNostrPubkey: String): ByteArray? {
val targetHex = normalizeNostrKeyToHex(forNostrPubkey) ?: return null
return favorites.values.firstOrNull { rel ->
- rel.peerNostrPublicKey?.let { stored ->
- normalizeNostrKeyToHex(stored)
- } == targetHex
+ rel.peerNostrPublicKey?.let { stored -> normalizeNostrKeyToHex(stored) } == targetHex
}?.peerNoisePublicKey
}
-
- /**
- * Find Nostr pubkey by Noise key
- */
+
+ /** Find Nostr pubkey by Noise key */
fun findNostrPubkey(forNoiseKey: ByteArray): String? {
val keyHex = forNoiseKey.joinToString("") { "%02x".format(it) }
return favorites[keyHex]?.peerNostrPublicKey
}
-
- // MARK: - Private Methods
-
+
+ // MARK: - Persistence
+
private fun loadFavorites() {
try {
- // Use public methods instead of reflection to access encrypted preferences
val favoritesJson = stateManager.getSecureValue(FAVORITES_KEY)
if (favoritesJson != null) {
val type = object : TypeToken