Compare commits

..

25 Commits

Author SHA1 Message Date
Santosh Pradhan
ed4e22a0ca
Merge f43c74187726d2873c71d93e8b9aff351c6f8c35 into 09b481f1ef5852ed50edce987dd719bd9588b125 2026-08-18 17:22:47 +03:00
callebtc
09b481f1ef
Merge pull request #876 from qutad/feat/announce-capability-bits
feat: Add announce capability bit assignments
2026-08-17 21:05:02 +02:00
callebtc
db97c60af1 Merge remote-tracking branch 'origin/main' into feat/announce-capability-bits 2026-08-17 20:40:43 +02:00
callebtc
2318b51630
Merge pull request #897 from permissionlesstech/codex/fix-command-processor-test-brace
Fix CommandProcessor test syntax
2026-08-17 20:38:39 +02:00
callebtc
03d1da5423 Fix CommandProcessor test syntax 2026-08-17 20:13:19 +02:00
callebtc
646044cd81 Clarify capability authentication scope 2026-08-17 19:14:05 +02:00
callebtc
35ed4417f0
Merge pull request #841 from phuctoan123/codex-fix-geohash-join-channel-routing
Fix geohash join channel routing
2026-08-17 19:09:26 +02:00
callebtc
9167013ac4
Merge pull request #863 from areebahmeddd/fix/preserve-wire-payload
feat: preserve original bytes during re-encoding of packets with foreign encoders
2026-08-17 19:08:01 +02:00
GitHub Action
b028270cc4 Automated update of relay data - Sun Aug 16 06:08:32 UTC 2026 2026-08-16 06:08:32 +00:00
wollow
22f87a493a Add announce capability bit assignments 2026-08-13 15:11:54 +03:00
callebtc
5156f7de89 Restore PRIVACY_POLICY.md 2026-08-12 01:55:05 +02:00
callebtc
93e9594bad
Merge pull request #873 from permissionlesstech/codex/bump-version-2.0.1
Prepare Android 2.0.1 release
2026-08-11 21:09:03 +02:00
callebtc
16a22316b2 Disable nondeterministic Compose group mapping 2026-08-11 20:42:26 +02:00
callebtc
c549bdb03f Bump Android release to 2.0.1 2026-08-11 20:08:57 +02:00
callebtc
c9938a36ea
Merge pull request #872 from permissionlesstech/codex/fix-reproducible-aab-mapping
Fix reproducible R8 mapping output
2026-08-11 19:57:31 +02:00
callebtc
6c5d7d1ef0 Fix reproducible R8 mapping output 2026-08-11 19:33:44 +02:00
callebtc
1a0d8713e4
Merge pull request #871 from permissionlesstech/watch-release-0.1.0
Prepare Wear 0.1.0 reproducible release
2026-08-11 18:14:29 +02:00
callebtc
c9a4e68157 Serialize reproducible release modules 2026-08-11 15:38:15 +02:00
callebtc
7e8ea63230 Prepare reproducible Wear 0.1.0 release 2026-08-11 15:19:39 +02:00
callebtc
47e725a4d8
Merge pull request #870 from permissionlesstech/bump-version-2.0.0
Bump phone app to 2.0.0
2026-08-11 15:12:58 +02:00
callebtc
920eed52d7 Bump phone app to 2.0.0 2026-08-11 12:13:16 +02:00
Kane Waldo
4007bae1e2 Fix syntax error in CommandProcessorTest 2026-08-11 09:20:39 +07:00
Toan Wizard
ca992d169c
Merge branch 'main' into codex-fix-geohash-join-channel-routing 2026-08-04 09:30:27 +07:00
Kane Waldo
83eaebc357 Fix geohash join channel routing 2026-07-31 11:20:58 +07:00
areebahmeddd
4b2a9c3b0d
preserve original bytes 2026-07-31 04:59:22 +05:30
22 changed files with 955 additions and 498 deletions

View File

@ -102,7 +102,7 @@ jobs:
"$RUNNER_TEMP/attestation-subjects/BITCHAT_SHA256SUMS.unsigned"
cp "$RUNNER_TEMP"/release-a/bitchat-android-*-unsigned.apk \
"$RUNNER_TEMP/attestation-subjects/"
cp "$RUNNER_TEMP/release-a/bitchat-android-release-unsigned.aab" \
cp "$RUNNER_TEMP"/release-a/bitchat-android-*-unsigned.aab \
"$RUNNER_TEMP/attestation-subjects/"
- name: Attest verified unsigned release

156
PRIVACY_POLICY.md Normal file
View File

@ -0,0 +1,156 @@
# bitchat Privacy Policy
*Last updated: January 2025*
## Our Commitment
bitchat is designed with privacy as its foundation. We believe private communication is a fundamental human right. This policy explains how bitchat protects your privacy.
## Summary
**WE DO NOT COLLECT ANY INFORMATION.**
- **No personal data collection** - We don't collect names, emails, or phone numbers
- **No location data collection** - Location is accessed only for local processing (BLE/Geohash) and is never collected or sent to us
- **Hybrid Functionality** - bitchat offers two modes of communication:
- **Bluetooth Mesh Chat**: This mode is completely offline, using peer-to-peer Bluetooth connections. It does not use any servers or internet connection.
- **Geohash Chat**: This mode uses an internet connection to communicate with others in a specific geographic area. It relies on Nostr relays for message transport.
- **No tracking** - We have no analytics, telemetry, or user tracking
- **Open source** - You can verify these claims by reading our code
## What Information bitchat Stores
### On Your Device Only
1. **Identity Key**
- A cryptographic key generated on first launch
- Stored locally in your device's secure storage
- Allows you to maintain "favorite" relationships across app restarts
- Never leaves your device
2. **Nickname**
- The display name you choose (or auto-generated)
- Stored only on your device
- Shared with peers you communicate with
3. **Message History** (if enabled)
- When room owners enable retention, messages are saved locally
- Stored encrypted on your device
- You can delete this at any time
4. **Favorite Peers**
- Public keys of peers you mark as favorites
- Stored only on your device
- Allows you to recognize these peers in future sessions
### Temporary Session Data
During each session, bitchat temporarily maintains:
- Active peer connections (forgotten when app closes)
- Routing information for message delivery
- Cached messages for offline peers (12 hours max)
## What Information is Shared
### With Other bitchat Users
When you use bitchat, nearby peers can see:
- Your chosen nickname
- Your ephemeral public key (changes each session)
- Messages you send to public rooms or directly to them
- Your approximate Bluetooth signal strength (for connection quality)
### With Room Members
When you join a password-protected room:
- Your messages are visible to others with the password
- Your nickname appears in the member list
- Room owners can see you've joined
## What We DON'T Do
bitchat **never**:
- Collects personal information
- Collects location history
- Transmits any data to us (the developers)
- Stores data on servers
- Shares data with third parties
- Uses analytics or telemetry
- Creates user profiles
- Requires registration
## Encryption
All private messages use end-to-end encryption:
- **X25519** for key exchange
- **AES-256-GCM** for message encryption
- **Ed25519** for digital signatures
- **Argon2id** for password-protected rooms
## Your Rights
You have complete control:
- **Delete Everything**: Triple-tap the logo to instantly wipe all data
- **Leave Anytime**: Close the app and your presence disappears
- **No Account**: Nothing to delete from servers because there are none
- **Portability**: Your data never leaves your device unless you export it
## Location Data & Permissions
To provide the core functionality of bitchat, we access your device's location data. This access is necessary for the following specific purposes:
### 1. Bluetooth Low Energy (BLE) Scanning
- **Why we need it:** The Android operating system requires Location permission to scan for nearby Bluetooth LE devices (especially on Android 11 and lower). This is a system-level requirement because Bluetooth scans can theoretically be used to derive location.
- **How we use it:** We use this permission strictly to discover other bitchat peers nearby for the "Bluetooth Mesh Chat" mode.
- **Privacy protection:** We do not record or store your location during this process. The data is processed instantaneously by the Android system to facilitate the connection.
### 2. Geohash Chat Functionality
- **Why we need it:** The "Geohash Chat" mode allows you to communicate with others in your approximate geographic area.
- **How we use it:** If you enable this mode, we access your location to calculate a "geohash" (a short alphanumeric string representing a geographic region). This geohash is used to find and subscribe to relevant channels on decentralized Nostr relays.
- **Privacy protection:**
- Your precise GPS coordinates are **never** sent to any server or peer.
- Only the coarse geohash (representing an area, not a pinpoint) is shared with the Nostr network.
- You can use the "Bluetooth Mesh Chat" mode without this feature if you prefer.
**We do not collect, store, or share your location history.** Location data is processed locally on your device to enable these specific features.
## Children's Privacy
bitchat does not knowingly collect information from children. The app has no age verification because it collects no personal information from anyone.
## Data Retention
- **Messages**: Deleted from memory when app closes (unless room retention is enabled)
- **Identity Key**: Persists until you delete the app
- **Favorites**: Persist until you remove them or delete the app
- **Everything Else**: Exists only during active sessions
## Security Measures
- All communication is encrypted
- No data transmitted to servers (there are none)
- Open source code for public audit
- Regular security updates
- Cryptographic signatures prevent tampering
## Changes to This Policy
If we update this policy:
- The "Last updated" date will change
- The updated policy will be included in the app
- No retroactive changes can affect data (since we don't collect any)
## Contact
bitchat is an open source project. For privacy questions:
- Review our code: https://github.com/yourusername/bitchat
- Open an issue on GitHub
- Join the discussion in public rooms
## Philosophy
Privacy isn't just a feature—it's the entire point. bitchat proves that modern communication doesn't require surrendering your privacy. No accounts, no servers, no surveillance. Just people talking freely.
---
*This policy is released into the public domain under The Unlicense, just like bitchat itself.*

View File

@ -30,8 +30,8 @@ android {
applicationId = "com.bitchat.droid"
minSdk = libs.versions.minSdk.get().toInt()
targetSdk = libs.versions.targetSdk.get().toInt()
versionCode = 36
versionName = "1.7.5"
versionCode = 38
versionName = "2.0.1"
buildConfigField(
"String",
"GITHUB_RELEASE_CERT_SHA256",
@ -111,6 +111,13 @@ android {
}
}
composeCompiler {
// Kotlin 2.4.10's optional Compose group-key mapping depends on unspecified
// class-file iteration order. Keep the normal R8 mapping, but omit that
// augmentation until its producer is deterministic across clean builds.
includeComposeMappingFile.set(false)
}
kotlin {
jvmToolchain(21)
compilerOptions {

View File

@ -1,414 +1,416 @@
Relay URL,Latitude,Longitude
nostr.n7ekb.net,47.4941,-122.294
relay.kilombino.com,43.6532,-79.3832
relay02.lnfi.network,35.6764,139.65
relay.liberbitworld.org,43.6532,-79.3832
articles.layer3.news,37.3387,-121.885
relay.nostr.net,43.6532,-79.3832
nostr.easycryptosend.it,43.6532,-79.3832
strfry.bonsai.com,39.0438,-77.4874
relay.olas.app:443,60.1699,24.9384
relay.sharegap.net,43.6532,-79.3832
relay.ditto.pub,43.6532,-79.3832
nostrride.io,37.3986,-121.964
relay.favillakey.io,-27.4705,153.026
nostr-relay.xbytez.io,50.6924,3.20113
relay.nostrmap.net:443,60.1699,24.9384
mostro-p2p.tech,50.1109,8.68213
relay.aidatanorge.no,43.6532,-79.3832
nostr.openhoofd.nl,51.5717,3.70417
relay.chatbett.de,40.7128,-74.006
relay.ohstr.com:443,43.6532,-79.3832
nostr.overmind.lol:443,43.6532,-79.3832
nostr.red5d.dev,43.6532,-79.3832
relay.snort.social,53.3498,-6.26031
relay.directsponsor.net,42.8864,-78.8784
relay.bullishbounty.com:443,43.6532,-79.3832
relay.scuba323.com,40.8218,-74.45
nostr.spicyz.io,43.6532,-79.3832
nostr.chaima.info,50.1109,8.68213
nostr.purpura.cloud,43.6532,-79.3832
relay.nostrops.com,32.71,-96.6745
relay.veganostr.com:443,60.1699,24.9384
relay.ohstr.com,43.6532,-79.3832
soloco.nl,43.6532,-79.3832
nostr.plantroon.com:443,50.1013,8.62643
relay.chorus.community:443,48.5333,10.7
relay.fiatdenier.com,43.7787,-79.5393
nostr.whitenode45.ddns.net,40.55,-74.4758
relay.cosmicbolt.net:443,37.3986,-121.964
relay.lanacoin-eternity.com:443,40.8302,-74.1299
relay.cosmicbolt.net,37.3986,-121.964
fanfares.nostr1.com:443,40.7057,-74.0136
nostr-kyomu-haskell.onrender.com,37.7775,-122.397
relay.keykeeper.world,40.7824,-74.0711
relay-testnet.k8s.layer3.news,37.3387,-121.885
dm-test-strfry-generic.samt.st,43.6532,-79.3832
relay.laantungir.net,-19.4692,-42.5315
nostr.sathoarder.com,48.5734,7.75211
relay.mccormick.cx:443,52.3563,4.95714
relay.solife.me,43.6532,-79.3832
relay.fountain.fm:443,43.6532,-79.3832
nostrcity-club.fly.dev,38.7946,-106.535
nostr.mas-family.eu,60.3478,15.7505
no.str.cr,8.96171,-83.5246
relay.wavefunc.live,41.8781,-87.6298
relay.cyberguy.fyi,52.6907,4.8181
adre.su,59.9311,30.3609
relay.erybody.com,41.4513,-81.7021
relay.mrmave.work,43.6532,-79.3832
relay.decentralia.fr,48.122,11.589
relay.mccormick.cx,52.3563,4.95714
nostr.dlcdevkit.com:443,40.0992,-83.1141
nostr-02.yakihonne.com,1.32123,103.695
nostr.21crypto.ch,47.5356,8.73209
slick.mjex.me,39.0418,-77.4744
nostr.spicyz.io:443,43.6532,-79.3832
relay-dev.gulugulu.moe,43.6532,-79.3832
relay.nostx.io,43.6532,-79.3832
relay.wisp.talk,49.4543,11.0746
relay.plebeian.market:443,50.1109,8.68213
relay.mostr.pub:443,43.6532,-79.3832
relay.aarpia.com,37.3986,-121.964
chat-relay.zap-work.com,43.6532,-79.3832
chat-relay.zap-work.com:443,43.6532,-79.3832
relay.mitchelltribe.com:443,39.0438,-77.4874
relay.paulstephenborile.com,49.4543,11.0746
relay.trotters.cc,43.6532,-79.3832
nexus.libernet.app:443,43.6532,-79.3832
syb.lol,34.0549,-118.243
relay.cypherflow.ai,48.8575,2.35138
relay.despera.space,52.1782,20.9926
relay.loveisbitcoin.com,43.6532,-79.3832
relay.rushmi0.win,43.6532,-79.3832
relay.degmods.com,50.4754,12.3683
relay.satlantis.io,39.0438,-77.4874
relay.underorion.se,50.1109,8.68213
nostr.mom:443,50.4754,12.3683
nostr-verified.wellorder.net,45.5201,-122.99
relay.nostreon.com,60.1699,24.9384
nostr.christiansass.de,54.3213,10.1349
rilo.nostria.app:443,43.6532,-79.3832
relay.trotters.cc:443,43.6532,-79.3832
kotukonostr.onrender.com,37.7775,-122.397
relay.nmail.li,50.9871,2.12554
relay.artio.inf.unibe.ch,46.9501,7.43678
nos.lol,50.4754,12.3683
nostr.snowbla.de:443,50.4754,12.3683
relay.openresist.com,43.6532,-79.3832
ribo.us.nostria.app,43.6532,-79.3832
bitchat.nostr1.com,40.7057,-74.0136
vm-1734.lnvps.cloud,53.3498,-6.26031
nostr-relay.xbytez.io:443,50.6924,3.20113
nostr.sathoarder.com:443,48.5734,7.75211
bcast.girino.org,43.6532,-79.3832
ribo.us.nostria.app:443,43.6532,-79.3832
strfry.shock.network,39.0438,-77.4874
relay.staging.plebeian.market:443,51.5072,-0.127586
offchain.pub:443,39.1585,-94.5728
relayone.soundhsa.com,39.0997,-94.5786
relay.libernet.app,43.6532,-79.3832
relay.earthly.city,34.1749,-118.54
relayrs.notoshi.win:443,43.6532,-79.3832
nostr.vulpem.com,49.4543,11.0746
relay.getsafebox.app:443,43.6532,-79.3832
relay.paulstephenborile.com:443,49.4543,11.0746
nostr.unkn0wn.world,46.8499,9.53287
relay.binaryrobot.com,43.6532,-79.3832
relay.wellorder.net,45.5201,-122.99
relayone.geektank.ai:443,39.0997,-94.5786
relay.wasabiwallet.io,43.6532,-79.3832
top.testrelay.top,43.6532,-79.3832
nostr.2b9t.xyz,34.0549,-118.243
relay.nostr.com,50.1109,8.68213
nostr.azzamo.net:443,52.2633,21.0283
nostr.dlcdevkit.com,40.0992,-83.1141
nostr.robosats.org,64.1476,-21.9392
nostr.iskarion.ddns.net,43.3076,-2.95421
relay2.angor.io,48.1046,11.6002
relay.mmwaves.de,48.8575,2.35138
relay.agorist.space:443,52.3734,4.89406
relay.dreamith.to,43.6532,-79.3832
nostr-02.uid.ovh,50.9871,2.12554
nostr.thebiglake.org,32.71,-96.6745
nostr-relay.corb.net,39.6478,-104.988
relay.dyne.org,49.0291,8.35705
nosflare-leefcore.leefcore.workers.dev,43.6532,-79.3832
relay.angor.io,48.1046,11.6002
nostrelay.circum.space,52.2245,8.826
nostr-01.uid.ovh,50.9871,2.12554
maxq.descendant.io,43.6532,-79.3832
offchain.bostr.online,43.6532,-79.3832
relay.binaryrobot.com:443,43.6532,-79.3832
nostr.planix.org,43.6532,-79.3832
tribune-panel-growing-noon.trycloudflare.com,43.6532,-79.3832
prl.plus,55.7628,37.5983
relay.mwaters.net,50.9871,2.12554
dev.relay.stream,43.6532,-79.3832
relay.bornheimer.app,50.1109,8.68213
inbox.scuba323.com,40.8218,-74.45
relay-us.zombi.cloudrodion.com,40.7862,-74.0743
relay.nuts.cash,52.3676,4.90414
bruh.samt.st,43.6532,-79.3832
nostr.carroarmato0.be:443,50.914,3.21378
relay.plebeian.market,50.1109,8.68213
schnorr.me:443,43.6532,-79.3832
nostr.thalheim.io:443,60.1699,24.9384
nostr.88mph.life,52.1941,-2.21905
cache.trustr.ing,43.6548,-79.3885
ec2.f7z.io,60.1699,24.9384
relay.btcforplebs.com,43.6532,-79.3832
nostr.liberty.fans,36.8767,-89.5879
syb.lol:443,34.0549,-118.243
nostr.islandarea.net:443,35.4669,-97.6473
nostr.mom,50.4754,12.3683
nostr.data.haus:443,50.4754,12.3683
strfry.bonsai.com:443,39.0438,-77.4874
nostr.highway15.net,28.0445,-82.6699
relay.wavlake.com:443,41.2619,-95.8608
relay.nostriot.com:443,41.5695,-83.9786
relay.gulugulu.moe:443,43.6532,-79.3832
rele.speyhard.fi,50.1109,8.68213
nostr.hoppe-relay.it.com,42.8864,-78.8784
nostr2.girino.org:443,43.6532,-79.3832
nostr.oxtr.dev,50.4754,12.3683
nostr.bitcoiner.social:443,40.7608,-111.891
nostrrelay.taylorperron.com,45.5029,-73.5723
nostr-01.yakihonne.com:443,1.32123,103.695
nostr.tagomago.me,42.3601,-71.0589
relay.hivetalk.org,40.8302,-74.1299
relay.sigit.io:443,50.4754,12.3683
relay.openresist.com:443,43.6532,-79.3832
cs-relay.nostrdev.com:443,50.4754,12.3683
no.str.cr:443,8.96171,-83.5246
relay.nearhood.co.uk,51.5134,-0.0890675
relay.lanavault.space,60.1699,24.9384
relay.guggero.org,46.5971,9.59652
nexus.libernet.app,43.6532,-79.3832
relay.nostriot.com,41.5695,-83.9786
dm-test-strfry-discovery.samt.st:443,43.6532,-79.3832
x.kojira.io:443,43.6532,-79.3832
nostr.4rs.nl,49.0291,8.35696
relayone.geektank.ai,39.0997,-94.5786
nostr.debate.report,50.1109,8.68213
relay.gulugulu.moe,43.6532,-79.3832
public.crostr.com,43.6532,-79.3832
offchain.pub,39.1585,-94.5728
relay.tdw.lol,41.8781,-87.6298
relay5.bitransfer.org,43.6532,-79.3832
relay.manneken.brussels,49.4543,11.0746
chorus.pjv.me,45.5201,-122.99
relay.fckstate.net,59.3293,18.0686
treuzkas.branruz.com,48.8575,2.35138
nostr-relay.cbrx.io,43.6532,-79.3832
nostr-relay.nextblockvending.com,47.2343,-119.853
nostr.fullstackcash.net,45.5201,-122.99
relay.primal.net,43.6532,-79.3832
relay.mappingbitcoin.com,43.6532,-79.3832
nostr.mikoshi.de,50.1109,8.68213
nostr.stakey.net,52.3676,4.90414
nostr-rs-relay-qj1h.onrender.com,37.7775,-122.397
relay.wavlake.com,41.2619,-95.8608
relay.ordoplay.com,50.1109,8.68213
relay.klabo.world,47.674,-122.122
buzz.cashu.space,50.1109,8.68213
relay.nostrhub.fr,48.1045,11.6004
portal-relay.pareto.space,49.0291,8.35696
dev-relay.nostreon.com,60.1699,24.9384
relay.islandbitcoin.com,12.8498,77.6545
testr.nymble.world,40.8054,-74.0241
relayrs.notoshi.win,43.6532,-79.3832
nostr-relay.corb.net:443,39.6478,-104.988
cdn.satellite.earth,40.8302,-74.1299
rilo.nostria.app,43.6532,-79.3832
nostr.pbfs.io,50.4754,12.3683
nostr2.girino.org,43.6532,-79.3832
0x-nostr-relay.fly.dev,38.7946,-106.535
nostr.girino.org,43.6532,-79.3832
relay.layer.systems,49.0291,8.35695
relay.olas.app,60.1699,24.9384
ribo.eu.nostria.app,43.6532,-79.3832
buzz.ac2n-share.kozow.com,45.764,4.83566
auth.nostr1.com,40.7057,-74.0136
relay.bitmacro.cloud,43.6532,-79.3832
relay.qstr.app,50.1109,8.68213
relay.ru.ac.th,13.7607,100.627
ribo.nostria.app:443,43.6532,-79.3832
relay.44billion.net,43.6532,-79.3832
cs-relay.nostrdev.com,50.4754,12.3683
relay.nostrian-conquest.com:443,41.223,-111.974
relay.bullishbounty.com,43.6532,-79.3832
relay.edufeed.org,49.4521,11.0767
porchlight.social,43.6532,-79.3832
nostr.bitcoiner.social,40.7608,-111.891
testnet-relay.samt.st,40.8302,-74.1299
relay.vrtmrz.net,43.6532,-79.3832
nostr.wecsats.io:443,43.6532,-79.3832
relay.satmaxt.xyz:443,43.6532,-79.3832
nostr.snowbla.de,50.4754,12.3683
nostr.rtvslawenia.com:443,49.4543,11.0746
relay.flashapp.me,43.6548,-79.3885
purplerelay.com:443,43.6532,-79.3832
relay.staging.plebeian.market,51.5072,-0.127586
relay.libernet.app:443,43.6532,-79.3832
relay.0xchat.com,43.6532,-79.3832
myvoiceourstory.org,37.3598,-121.981
nrs-01.darkcloudarcade.com:443,39.0997,-94.5786
relay.vrtmrz.net:443,43.6532,-79.3832
relay.zone667.com,60.1699,24.9384
nostr.nodesmap.com,59.3327,18.0656
relay.mostr.pub,43.6532,-79.3832
relay.veganostr.com:443,60.1699,24.9384
relay.dreamith.to,43.6532,-79.3832
buzz.cashu.space,50.1109,8.68213
relay.sincensura.org,43.6532,-79.3832
relayrs.notoshi.win:443,43.6532,-79.3832
nostr.bond,50.1109,8.68213
relay.edufeed.org,49.4521,11.0767
relay.bullishbounty.com:443,43.6532,-79.3832
relay.nostr.blockhenge.com,39.0438,-77.4874
relay2.fiatdenier.com,50.1013,8.62643
relay.mwaters.net,50.9871,2.12554
relay2.angor.io,48.1046,11.6002
memlay.v0l.io,53.3498,-6.26031
nostr.wecsats.io,43.6532,-79.3832
vm-1734.lnvps.cloud,53.3498,-6.26031
dm-test-strfry-discovery.samt.st:443,43.6532,-79.3832
nostr2.girino.org:443,43.6532,-79.3832
nostr.robosats.org,64.1476,-21.9392
relay.atsocy.com,43.6532,-79.3832
relayone.geektank.ai:443,39.0997,-94.5786
relay.olas.app:443,60.1699,24.9384
relay.nostu.be,40.4167,-3.70329
relay.otrta.me,50.1109,8.68213
nostr.spaceshell.xyz,43.6532,-79.3832
rilo.nostria.app,43.6532,-79.3832
relay.agorist.space,52.3734,4.89406
relayone.soundhsa.com:443,39.0997,-94.5786
relay.satmaxt.xyz,43.6532,-79.3832
relay.zapanimations.com,40.8054,-74.0241
relay.sovereignresonance.org,48.8575,2.35138
nostr.relay.hedwig.sh,60.1699,24.9384
relay-dev.gulugulu.moe:443,43.6532,-79.3832
relay.arx-ccn.com,50.4754,12.3683
nip85.nosfabrica.com,39.0997,-94.5786
relay.nostrmap.net,60.1699,24.9384
relay.bullishbounty.com,43.6532,-79.3832
nrs-01.darkcloudarcade.com,39.0997,-94.5786
spamspamspamspam.rest,43.6532,-79.3832
nostr.davenov.com,50.1109,8.68213
relay.littlebitstudios.com,43.6532,-79.3832
purplerelay.com,43.6532,-79.3832
nos.lol:443,50.4754,12.3683
relay2.veganostr.com,60.1699,24.9384
relay-rpi.edufeed.org,49.4521,11.0767
relay.lacrypta.ar,43.6532,-79.3832
relay.tdw.gg,34.0549,-118.243
relay.getvia.xyz,60.1699,24.9384
relay.lanacoin-eternity.com,40.8302,-74.1299
conduitl2.fly.dev,38.7946,-106.535
relay.angor.io:443,48.1046,11.6002
nostr.rtvslawenia.com,49.4543,11.0746
relay.wavefunc.live:443,41.8781,-87.6298
relay.wasabiwallet.io,43.6532,-79.3832
cs-relay.nostrdev.com:443,50.4754,12.3683
nostr.4rs.nl,49.0291,8.35696
nexus.libernet.app,43.6532,-79.3832
relay-dev.gulugulu.moe,43.6532,-79.3832
nostr.88mph.life,52.1941,-2.21905
relayone.soundhsa.com:443,39.0997,-94.5786
social.amanah.eblessing.co,48.1046,11.6002
relay.getsafebox.app,43.6532,-79.3832
relay.44billion.net,43.6532,-79.3832
relay.conduit.market,38.7946,-106.535
nostr.infero.net,35.6764,139.65
relay.staging.plebeian.market,51.5072,-0.127586
relay.snort.social,53.3498,-6.26031
purplerelay.com:443,43.6532,-79.3832
nostr.mas-family.eu,60.3478,15.7505
relay.ru.ac.th,13.7607,100.627
relay.openresist.com,43.6532,-79.3832
antiprimal.net,43.6532,-79.3832
relay.illuminodes.com,43.6532,-79.3832
relay.mmwaves.de:443,48.8575,2.35138
nostr.spicyz.io,43.6532,-79.3832
relay.nostrfeed.com,60.1699,24.9384
strfry.apps3.slidestr.net,40.4167,-3.70329
relay.directsponsor.net,42.8864,-78.8784
relay.nostrhub.fr,48.1045,11.6004
nostr.plantroon.com,50.1013,8.62643
nostr-verified.wellorder.net,45.5201,-122.99
relay.bnos.space:443,43.6532,-79.3832
relay.pyramid.li,47.4093,8.46503
public.crostr.com,43.6532,-79.3832
relay.kilombino.com,43.6532,-79.3832
relay.libernet.app:443,43.6532,-79.3832
relay.internationalright-wing.org,-22.4692,-48.9875
nostr.overmind.lol:443,43.6532,-79.3832
relay.ordoplay.com,50.1109,8.68213
mostro-p2p.tech,50.1109,8.68213
offchain.pub:443,39.1585,-94.5728
cs-relay.nostrdev.com,50.4754,12.3683
relay-can.zombi.cloudrodion.com,43.6532,-79.3832
nostr.unkn0wn.world,46.8499,9.53287
relay.shadowbip.com,50.1109,8.68213
relay.lanacoin-eternity.com:443,40.8302,-74.1299
relay.staging.commonshub.brussels,49.4543,11.0746
relay2.angor.io:443,48.1046,11.6002
relay.arx-ccn.com,50.4754,12.3683
relay.underorion.se,50.1109,8.68213
bread.nostrsms.com,40.8218,-74.45
relay.cypherflow.ai,48.8575,2.35138
nostr.islandarea.net:443,35.4669,-97.6473
relay.homeinhk.xyz,35.694,139.754
relay.ditto.pub:443,43.6532,-79.3832
nostr.fullstackcash.net,45.5201,-122.99
bitcoinostr.duckdns.org,38.9504,-0.14007
relay.trotters.cc,43.6532,-79.3832
portal-relay.pareto.space,49.0291,8.35696
relay.openresist.com:443,43.6532,-79.3832
relay.endfiat.money,59.3327,18.0656
nostr.hoppe-relay.it.com,42.8864,-78.8784
nostr.sovereignservices.xyz,43.6532,-79.3832
relay.fundstr.me,42.3601,-71.0589
relay5.bitransfer.org,43.6532,-79.3832
nrs-01.darkcloudarcade.com:443,39.0997,-94.5786
testr.nymble.world,40.8054,-74.0241
strfry.shock.network:443,39.0438,-77.4874
chorus.mikedilger.com:444,-36.8906,174.794
relay.minibolt.info,43.6532,-79.3832
nos.lol:443,50.4754,12.3683
relay.liberbitworld.org,43.6532,-79.3832
maxq.descendant.io,43.6532,-79.3832
nostrcity-club.fly.dev,38.7946,-106.535
relay.nostriot.com,41.5695,-83.9786
nostr.n7ekb.net,47.4941,-122.294
relay.erybody.com,41.4513,-81.7021
nostr-rs-relay-qj1h.onrender.com,37.7775,-122.397
nostrrelay.taylorperron.com,45.5029,-73.5723
syb.lol,34.0549,-118.243
relay.nostr.com,50.1109,8.68213
relay.hivetalk.org,40.8302,-74.1299
relay.degmods.com,50.4754,12.3683
relay.laantungir.net,-19.4692,-42.5315
relay.nearhood.co.uk,51.5134,-0.0890675
relay.tdw.lol,41.8781,-87.6298
ribo.us.nostria.app,43.6532,-79.3832
public.obelisk.ar,43.6532,-79.3832
prl.plus,55.7628,37.5983
21milionidinostr.duckdns.org,45.5192,9.08625
nostr.carroarmato0.be,50.914,3.21378
nostr.pbfs.io:443,50.4754,12.3683
ribo.nostria.app,43.6532,-79.3832
nostr.sovereignservices.xyz,43.6532,-79.3832
relay.mostr.pub,43.6532,-79.3832
schnorr.me,43.6532,-79.3832
x.kojira.io,43.6532,-79.3832
public.obelisk.ar,43.6532,-79.3832
relay.angor.io:443,48.1046,11.6002
nostr.oxtr.dev:443,50.4754,12.3683
nostr.ltd,19.076,72.8777
nostr.tac.lol:443,47.4748,-122.273
nostr.twinkle.lol,51.902,7.6657
relay.s-w.art,43.6532,-79.3832
relay.openfarmtools.org,60.1699,24.9384
nostr.hekster.org,37.3986,-121.964
strfry.apps3.slidestr.net,40.4167,-3.70329
relay.mypathtofire.de,42.8864,-78.8784
nostr.wecsats.io,43.6532,-79.3832
nostr.computingcache.com,34.0356,-118.442
nostr.janx.com,43.6532,-79.3832
bread.nostrsms.com,40.8218,-74.45
relay.chorus.community,48.5333,10.7
testnet-relay.samt.st:443,40.8302,-74.1299
relay.kaleidoswap.com,50.8476,4.35717
yabu.me,35.6092,139.73
nostr-dev.wellorder.net,45.5201,-122.99
relay.layer.systems:443,49.0291,8.35695
relay-can.zombi.cloudrodion.com,43.6532,-79.3832
nostr-relay.zimage.com,34.282,-118.439
relay.fundstr.me,42.3601,-71.0589
nostr.stakey.net:443,52.3676,4.90414
relay.satsmarkt.club,52.6907,4.8181
relay.satsapp.me,50.4754,12.3683
bendernostur.duckdns.org:8443,50.1109,8.68213
relay.illuminodes.com,43.6532,-79.3832
nostr.chaima.info:443,50.1109,8.68213
nostr.hekster.org:443,37.3986,-121.964
nostr.yutakobayashi.com,43.6532,-79.3832
freelay.sovbit.host,60.1699,24.9384
insta-relay.apps3.slidestr.net,40.4167,-3.70329
infinity-signal-relay.digitalforlifeagency.workers.dev,43.6532,-79.3832
relay.internationalright-wing.org,-22.4692,-48.9875
relay.mmwaves.de:443,48.8575,2.35138
public.crostr.com:443,43.6532,-79.3832
relay.nostrian-conquest.com,41.223,-111.974
relay-rpi.edufeed.org:443,49.4521,11.0767
relay2.angor.io:443,48.1046,11.6002
relay-fra.zombi.cloudrodion.com,48.8566,2.35222
bunk-test.feeds.relay.tools,38.6327,-90.1961
nostr-pr02.redscrypt.org,52.3676,4.90414
nostr.tac.lol,47.4748,-122.273
nostr.overpay.com,29.7449,-95.5343
relay.novospes.com,43.6532,-79.3832
nostrcity-club.fly.dev:443,38.7946,-106.535
relay01.lnfi.network,35.6764,139.65
relay.lightning.pub:443,39.0438,-77.4874
relay.pyramid.li,47.4093,8.46503
relay.nostu.be,40.4167,-3.70329
nostr-rs-relay.dev.fedibtc.com:443,39.0438,-77.4874
relay.endfiat.money:443,59.3327,18.0656
nostr.spaceshell.xyz,43.6532,-79.3832
21milionidinostr.duckdns.org,45.5192,9.08625
articles.layer3.news:443,37.3387,-121.885
wheat.happytavern.co,43.6532,-79.3832
nostr-rs-relay.dev.fedibtc.com,39.0438,-77.4874
nostr.na.social,43.6532,-79.3832
social.amanah.eblessing.co,48.1046,11.6002
reraw.pbla2fish.cc,43.6532,-79.3832
nostr.girino.org:443,43.6532,-79.3832
staging.yabu.me,35.6092,139.73
nostr.islandarea.net,35.4669,-97.6473
relay.endfiat.money,59.3327,18.0656
relay.mitchelltribe.com,39.0438,-77.4874
nostr.myshosholoza.co.za,52.3676,4.90414
relay.staging.commonshub.brussels,49.4543,11.0746
espelho.girino.org,43.6532,-79.3832
nostr.computingcache.com,45.5341,-122.956
relay.chorus.community:443,48.5333,10.7
nostr-relay.nextblockvending.com,47.2343,-119.853
nostr.easycryptosend.it,43.6532,-79.3832
no.str.cr:443,8.96171,-83.5246
nostr.snowbla.de:443,50.4754,12.3683
bridge.tagomago.me,42.3601,-71.0589
relay.agentry.com,42.8864,-78.8784
testnet.samt.st,43.6532,-79.3832
nostr.wild-vibes.ts.net,48.8566,2.35222
relay.getsafebox.app,43.6532,-79.3832
relay.notoshi.win,13.3396,100.93
bitcoinostr.duckdns.org,41.1976,1.11167
relay.sigit.io,50.4754,12.3683
bucket.coracle.social,37.7775,-122.397
dm-test-strfry-discovery.samt.st,43.6532,-79.3832
vault.iris.to:443,43.6532,-79.3832
relay.wisp.talk:443,49.4543,11.0746
relay.mostro.network,40.8302,-74.1299
nostr.l484.com,30.2672,-97.7431
relay.froth.zone,60.1699,24.9384
relay.beamhop.com,43.6532,-79.3832
relay.sincensura.org,43.6532,-79.3832
relay.ditto.pub:443,43.6532,-79.3832
nostr.azzamo.net,52.2633,21.0283
relay.edufeed.org:443,49.4521,11.0767
ribo.eu.nostria.app:443,43.6532,-79.3832
vault.iris.to,43.6532,-79.3832
nostr.plantroon.com,50.1013,8.62643
fanfares.nostr1.com,40.7057,-74.0136
budabit.nostr1.com,40.7057,-74.0136
relay.damus.io,43.6532,-79.3832
strfry.shock.network:443,39.0438,-77.4874
bitcoiner.social,40.7608,-111.891
basspistol.org,49.0291,8.35696
nostr.thalheim.io,60.1699,24.9384
relay.conduit.market,38.7946,-106.535
relay.yoinekodo.jp,43.6532,-79.3832
nostrbtc.com,43.6532,-79.3832
relay.lightning.pub,39.0438,-77.4874
nostr-01.yakihonne.com,1.32123,103.695
nostr-pub.wellorder.net,45.5201,-122.99
relay.endfiat.money:443,59.3327,18.0656
relay.klabo.world,47.674,-122.122
articles.layer3.news:443,37.3387,-121.885
nostr.21crypto.ch,47.5356,8.73209
relay.kaleidoswap.com,50.8476,4.35717
nostr.relay.hedwig.sh,60.1699,24.9384
nostr.yutakobayashi.com,43.6532,-79.3832
strfry.ymir.cloud,43.6532,-79.3832
relay.minibolt.info,43.6532,-79.3832
nostr.data.haus,50.4754,12.3683
relay.otrta.me,50.1109,8.68213
relay.samt.st,40.8302,-74.1299
relay.nostr.blockhenge.com,39.0438,-77.4874
relay.minibolt.info:443,43.6532,-79.3832
nostr.2b9t.xyz:443,34.0549,-118.243
relay.littlebitstudios.com,43.6532,-79.3832
testnet-relay.samt.st:443,40.8302,-74.1299
relay.islandbitcoin.com,12.8498,77.6545
relay.zone667.com,60.1699,24.9384
relay.lightning.pub:443,39.0438,-77.4874
relay.layer.systems:443,49.0291,8.35695
offchain.pub,39.1585,-94.5728
nos.lol,50.4754,12.3683
cdn.satellite.earth,40.8302,-74.1299
relay-us.zombi.cloudrodion.com,40.7862,-74.0743
relay.wisp.talk:443,49.4543,11.0746
nostr.hekster.org:443,37.3986,-121.964
nostr.mom:443,50.4754,12.3683
relay.mccormick.cx:443,52.3563,4.95714
dev.relay.stream,43.6532,-79.3832
dm-test-nostr-rs-42-disabled.samt.st,43.6532,-79.3832
relay.veganostr.com,60.1699,24.9384
relay.fountain.fm,43.6532,-79.3832
relay.vrtmrz.net:443,43.6532,-79.3832
relayone.soundhsa.com,39.0997,-94.5786
relay.agorist.space:443,52.3734,4.89406
relay-fra.zombi.cloudrodion.com,48.8566,2.35222
nostr.dlcdevkit.com:443,40.0992,-83.1141
node.kommonzenze.de,49.4521,11.0767
relay-arg.zombi.cloudrodion.com,1.35208,103.82
nostr.myshosholoza.co.za:443,52.3676,4.90414
temp.iris.to,43.6532,-79.3832
relay.nostrmap.net,60.1699,24.9384
relay.beamhop.com,43.6532,-79.3832
nostr.2b9t.xyz:443,34.0549,-118.243
relay.chatbett.de,40.7128,-74.006
relay.tdw.gg,34.0549,-118.243
budabit.nostr1.com,40.7057,-74.0136
nostr.novacisko.cz,52.2026,20.9397
relay.samt.st,40.8302,-74.1299
bruh.samt.st,43.6532,-79.3832
nostr.wild-vibes.ts.net,48.8566,2.35222
relay.opossumwire.org,34.0549,-118.243
relay.angor.io,48.1046,11.6002
relay.nostrmap.net:443,60.1699,24.9384
nostr-rs-relay.dev.fedibtc.com,39.0438,-77.4874
chat-relay.zap-work.com,43.6532,-79.3832
relay.earthly.city,34.1749,-118.54
relay.mappingbitcoin.com,43.6532,-79.3832
relay.satmaxt.xyz,43.6532,-79.3832
relay.primal.net,43.6532,-79.3832
relay.bornheimer.app,50.1109,8.68213
nostr.tagomago.me,42.3601,-71.0589
relay.orly.dev,32.7767,-96.797
no.str.cr,8.96171,-83.5246
auth.nostr1.com,40.7057,-74.0136
relay.opmaat.org,60.1699,24.9384
temp.iris.to,43.6532,-79.3832
conduitl2.fly.dev,38.7946,-106.535
yabu.me,35.6092,139.73
nostrride.io,37.3986,-121.964
nostr.plantroon.com:443,50.1013,8.62643
relay.wavlake.com,41.2619,-95.8608
nostrbtc.com,43.6532,-79.3832
relay.mitchelltribe.com:443,39.0438,-77.4874
relay.manneken.brussels,49.4543,11.0746
relay.lanacoin-eternity.com,40.8302,-74.1299
bendernostur.duckdns.org:8443,50.1109,8.68213
nostr-kyomu-haskell.onrender.com,37.7775,-122.397
nostr.nodesmap.com,59.3327,18.0656
nostr-01.yakihonne.com,1.32123,103.695
bunk-test.feeds.relay.tools,38.6327,-90.1961
relay.btcforplebs.com,43.6532,-79.3832
relay.beginningend.com,35.2227,-97.4786
nostr.iskarion.ddns.net,43.3076,-2.95421
nostr-relay.cbrx.io,43.6532,-79.3832
relay.nostrian-conquest.com,41.223,-111.974
relay.cosmicbolt.net:443,37.3986,-121.964
nostr.oxtr.dev:443,50.4754,12.3683
nostr-relay.acloud.kdns.fr,43.6532,-79.3832
relay.mccormick.cx,52.3563,4.95714
relay.fiatdenier.com,43.7787,-79.5393
nostr.bitcoiner.social:443,40.7608,-111.891
relay.gulugulu.moe:443,43.6532,-79.3832
relay.piazza.today,48.122,11.589
nostr.ac,38.958,-77.3592
strfry.bonsai.com,39.0438,-77.4874
dev-relay.nostreon.com,60.1699,24.9384
relay.olas.app,60.1699,24.9384
relay.loveisbitcoin.com,43.6532,-79.3832
strfry.bonsai.com:443,39.0438,-77.4874
nostr.tac.lol,47.4748,-122.273
rilo.nostria.app:443,43.6532,-79.3832
nostr.azzamo.net,52.2633,21.0283
nostr.wecsats.io:443,43.6532,-79.3832
relay.wellorder.net,45.5201,-122.99
relay.libernet.app,43.6532,-79.3832
nostr.thalheim.io,60.1699,24.9384
relayrs.notoshi.win,43.6532,-79.3832
ribo.nostria.app:443,43.6532,-79.3832
relay.gulugulu.moe,43.6532,-79.3832
relay.qstr.app,50.1109,8.68213
myvoiceourstory.org,37.3598,-121.981
nostr-relay.zimage.com,34.282,-118.439
treuzkas.branruz.com,48.8575,2.35138
top.testrelay.top,43.6532,-79.3832
relay.cyberguy.fyi,52.6907,4.8181
articles.layer3.news,37.3387,-121.885
nostr.sathoarder.com,48.5734,7.75211
nostr.carroarmato0.be:443,50.914,3.21378
nostr-02.uid.ovh,50.9871,2.12554
ribo.us.nostria.app:443,43.6532,-79.3832
relay.ditto.pub,43.6532,-79.3832
nostr.chaima.info:443,50.1109,8.68213
relay.bnos.space,43.6532,-79.3832
relay.solife.me,43.6532,-79.3832
relay.wavlake.com:443,41.2619,-95.8608
bucket.coracle.social,37.7775,-122.397
nostr.christiansass.de,52.5244,13.4105
relay.dyne.org,49.0291,8.35705
testnet-relay.samt.st,40.8302,-74.1299
nostream.seitendan.com,34.7062,135.493
basspistol.org,49.0291,8.35696
purplerelay.com,43.6532,-79.3832
relay.wisp.talk,49.4543,11.0746
relay.getsafebox.app:443,43.6532,-79.3832
freelay.sovbit.host,60.1699,24.9384
relay.sigit.io:443,50.4754,12.3683
buzz.ac2n-share.kozow.com,45.764,4.83566
relay.mostro.network,40.8302,-74.1299
nostrcheck.me,43.6532,-79.3832
nostr.rtvslawenia.com:443,49.4543,11.0746
insta-relay.apps3.slidestr.net,40.4167,-3.70329
nostr.vulpem.com,49.4543,11.0746
relay-na1.metanomalist.com,43.6532,-79.3832
chorus.bonsai.com,39.0438,-77.4874
ec2.f7z.io,60.1699,24.9384
relay-dev.gulugulu.moe:443,43.6532,-79.3832
nostr.twinkle.lol,51.902,7.6657
relay.lanavault.space,60.1699,24.9384
nostr.pbfs.io,50.4754,12.3683
bitchat.nostr1.com,40.7057,-74.0136
nostr.highway15.net,28.0445,-82.6699
nostr.tabordalab.com,60.1699,24.9384
relay.ohstr.com,43.6532,-79.3832
schnorr.me,43.6532,-79.3832
relay.s-w.art,43.6532,-79.3832
relay.nmail.li,50.9871,2.12554
bcast.girino.org,43.6532,-79.3832
relay.nostrops.com,32.71,-96.6745
dm-test-strfry-generic.samt.st,43.6532,-79.3832
relay.keykeeper.world,40.7824,-74.0711
relay.satsmarkt.club,52.6907,4.8181
adre.su,59.9311,30.3609
relay.edufeed.org:443,49.4521,11.0767
infinity-signal-relay.digitalforlifeagency.workers.dev,43.6532,-79.3832
relay.lightning.pub,39.0438,-77.4874
porchlight.social,43.6532,-79.3832
nostr.snowbla.de,50.4754,12.3683
relay.trotters.cc:443,43.6532,-79.3832
nostr-relay.xbytez.io,50.6924,3.20113
relay.nostr.net,43.6532,-79.3832
nostrcity-club.fly.dev:443,38.7946,-106.535
nostr.mikoshi.de,50.1109,8.68213
nostr.mom,50.4754,12.3683
schnorr.me:443,43.6532,-79.3832
chat-relay.zap-work.com:443,43.6532,-79.3832
relay.paulstephenborile.com:443,49.4543,11.0746
relay.fckstate.net,59.3293,18.0686
offchain.bostr.online,43.6532,-79.3832
nostr.oxtr.dev,50.4754,12.3683
testnet.samt.st,43.6532,-79.3832
nostr.planix.org,43.6532,-79.3832
relay.getvia.xyz,60.1699,24.9384
relay.lacrypta.ar,43.6532,-79.3832
nostr.janx.com,43.6532,-79.3832
relay.yoinekodo.jp,43.6532,-79.3832
nostrelay.circum.space,52.2245,8.826
staging.yabu.me,35.6092,139.73
relay.staging.plebeian.market:443,51.5072,-0.127586
reraw.pbla2fish.cc,43.6532,-79.3832
relay.satsapp.me,50.4754,12.3683
x.kojira.io,43.6532,-79.3832
relay.layer.systems,49.0291,8.35695
relay01.lnfi.network,35.6764,139.65
nostr.whitenode45.ddns.net,40.55,-74.4758
relay-rpi.edufeed.org,49.4521,11.0767
nostr-dev.wellorder.net,45.5201,-122.99
nostr.overmind.lol,43.6532,-79.3832
relay.aarpia.com,37.3986,-121.964
relayone.geektank.ai,39.0997,-94.5786
nostr.purpura.cloud,43.6532,-79.3832
nostr.data.haus:443,50.4754,12.3683
nexus.libernet.app:443,43.6532,-79.3832
nostr.thebiglake.org,32.71,-96.6745
relay.bowlafterbowl.com,32.9483,-96.7299
relay.mitchelltribe.com,39.0438,-77.4874
nostr-relay.xbytez.io:443,50.6924,3.20113
bitcoiner.social,40.7608,-111.891
relay.guggero.org,46.5971,9.59652
relay.mrmave.work,43.6532,-79.3832
relay.flashapp.me,43.6548,-79.3885
relay.mmwaves.de,48.8575,2.35138
nostr.red5d.dev,43.6532,-79.3832
relay.plebeian.market,50.1109,8.68213
nostr.girino.org,43.6532,-79.3832
relay02.lnfi.network,35.6764,139.65
relay.vrtmrz.net,43.6532,-79.3832
ynostr.yael.at,60.1699,24.9384
relay.cosmicbolt.net,37.3986,-121.964
nostr-rs-relay.dev.fedibtc.com:443,39.0438,-77.4874
nostrelay.circum.space:443,52.2245,8.826
nostr.notribe.net,40.8302,-74.1299
nostr.tac.lol:443,47.4748,-122.273
relay-arg.zombi.cloudrodion.com,1.35208,103.82
relay.agora.social,50.7383,15.0648
vault.iris.to:443,43.6532,-79.3832
relay.nexterz.com,43.6532,-79.3832
relay2.veganostr.com,60.1699,24.9384
strfry.shock.network,39.0438,-77.4874
relay.notoshi.win,13.3396,100.93
vault.iris.to,43.6532,-79.3832
relay.novospes.com,43.6532,-79.3832
nip85.nosfabrica.com,39.0997,-94.5786
relay-testnet.k8s.layer3.news,37.3387,-121.885
nostr.stakey.net,52.3676,4.90414
syb.lol:443,34.0549,-118.243
nostr-01.uid.ovh,50.9871,2.12554
nostr-02.yakihonne.com,1.32123,103.695
relay.favillakey.io,-27.4705,153.026
relay.plebeian.market:443,50.1109,8.68213
r.iqbqioza.com,43.6532,-79.3832
relay.ohstr.com:443,43.6532,-79.3832
relay.paulstephenborile.com,49.4543,11.0746
nostr.2b9t.xyz,34.0549,-118.243
slick.mjex.me,39.0418,-77.4744
nostr.hekster.org,37.3986,-121.964
nostr.stakey.net:443,52.3676,4.90414
relay.sharegap.net,43.6532,-79.3832
relay.veganostr.com,60.1699,24.9384
nosflare-leefcore.leefcore.workers.dev,43.6532,-79.3832
nostr.data.haus,50.4754,12.3683
x.kojira.io:443,43.6532,-79.3832
relay.nostx.io,43.6532,-79.3832
wheat.happytavern.co,43.6532,-79.3832
nostr.myshosholoza.co.za:443,52.3676,4.90414
inbox.scuba323.com,40.8218,-74.45
nostr.chaima.info,50.1109,8.68213
relay.nostriches.club,43.6532,-79.3832
fanfares.nostr1.com,40.7057,-74.0136
relay.bitmacro.cloud,43.6532,-79.3832
relay.mostr.pub:443,43.6532,-79.3832
nostr.spicyz.io:443,43.6532,-79.3832
relay.agentry.com,42.8864,-78.8784
nostr.thalheim.io:443,60.1699,24.9384
tribune-panel-growing-noon.trycloudflare.com,43.6532,-79.3832
relay.mypathtofire.de,42.8864,-78.8784
nostr-relay.corb.net:443,39.6478,-104.988
dm-test-strfry-discovery.samt.st,43.6532,-79.3832
nostr.debate.report,50.1109,8.68213
relay.nostrcheck.me,43.6532,-79.3832
relay.scuba323.com,40.8218,-74.45
relay.decentralia.fr,48.122,11.589
fanfares.nostr1.com:443,40.7057,-74.0136
relay.sigit.io,50.4754,12.3683
ribo.nostria.app,43.6532,-79.3832
nostr.davenov.com,50.1109,8.68213
nostr.azzamo.net:443,52.2633,21.0283
ribo.eu.nostria.app,43.6532,-79.3832
nostr-01.yakihonne.com:443,1.32123,103.695
desktop-r082364.tail4b3c94.ts.net,48.8566,2.35222
0x-nostr-relay.fly.dev,38.7946,-106.535
soloco.nl,43.6532,-79.3832
relay.chorus.community,48.5333,10.7
nostr.sathoarder.com:443,48.5734,7.75211
nostr.myshosholoza.co.za,52.3676,4.90414
cache.trustr.ing,43.6548,-79.3885
nostr.islandarea.net,35.4669,-97.6473
nostr-relay.corb.net,39.6478,-104.988
relay-rpi.edufeed.org:443,49.4521,11.0767
rele.speyhard.fi,50.1109,8.68213
relay.pocketnostr.com,40.8054,-74.0241
relay.nuts.cash,52.3676,4.90414
spamspamspamspam.rest,43.6532,-79.3832
nostr.dlcdevkit.com,40.0992,-83.1141
relay.satlantis.io,39.0438,-77.4874
nostr.na.social,43.6532,-79.3832
relay.nostreon.com,60.1699,24.9384

1 Relay URL Latitude Longitude
nostr.n7ekb.net 47.4941 -122.294
relay.kilombino.com 43.6532 -79.3832
relay02.lnfi.network 35.6764 139.65
relay.liberbitworld.org 43.6532 -79.3832
articles.layer3.news 37.3387 -121.885
relay.nostr.net 43.6532 -79.3832
nostr.easycryptosend.it 43.6532 -79.3832
strfry.bonsai.com 39.0438 -77.4874
relay.olas.app:443 60.1699 24.9384
relay.sharegap.net 43.6532 -79.3832
relay.ditto.pub 43.6532 -79.3832
nostrride.io 37.3986 -121.964
relay.favillakey.io -27.4705 153.026
nostr-relay.xbytez.io 50.6924 3.20113
relay.nostrmap.net:443 60.1699 24.9384
mostro-p2p.tech 50.1109 8.68213
relay.aidatanorge.no 43.6532 -79.3832
nostr.openhoofd.nl 51.5717 3.70417
relay.chatbett.de 40.7128 -74.006
relay.ohstr.com:443 43.6532 -79.3832
nostr.overmind.lol:443 43.6532 -79.3832
nostr.red5d.dev 43.6532 -79.3832
relay.snort.social 53.3498 -6.26031
relay.directsponsor.net 42.8864 -78.8784
relay.bullishbounty.com:443 43.6532 -79.3832
relay.scuba323.com 40.8218 -74.45
nostr.spicyz.io 43.6532 -79.3832
nostr.chaima.info 50.1109 8.68213
nostr.purpura.cloud 43.6532 -79.3832
relay.nostrops.com 32.71 -96.6745
relay.veganostr.com:443 60.1699 24.9384
relay.ohstr.com 43.6532 -79.3832
soloco.nl 43.6532 -79.3832
nostr.plantroon.com:443 50.1013 8.62643
relay.chorus.community:443 48.5333 10.7
relay.fiatdenier.com 43.7787 -79.5393
nostr.whitenode45.ddns.net 40.55 -74.4758
relay.cosmicbolt.net:443 37.3986 -121.964
relay.lanacoin-eternity.com:443 40.8302 -74.1299
relay.cosmicbolt.net 37.3986 -121.964
fanfares.nostr1.com:443 40.7057 -74.0136
nostr-kyomu-haskell.onrender.com 37.7775 -122.397
relay.keykeeper.world 40.7824 -74.0711
relay-testnet.k8s.layer3.news 37.3387 -121.885
dm-test-strfry-generic.samt.st 43.6532 -79.3832
relay.laantungir.net -19.4692 -42.5315
nostr.sathoarder.com 48.5734 7.75211
relay.mccormick.cx:443 52.3563 4.95714
relay.solife.me 43.6532 -79.3832
relay.fountain.fm:443 43.6532 -79.3832
nostrcity-club.fly.dev 38.7946 -106.535
nostr.mas-family.eu 60.3478 15.7505
no.str.cr 8.96171 -83.5246
relay.wavefunc.live 41.8781 -87.6298
relay.cyberguy.fyi 52.6907 4.8181
adre.su 59.9311 30.3609
relay.erybody.com 41.4513 -81.7021
relay.mrmave.work 43.6532 -79.3832
relay.decentralia.fr 48.122 11.589
relay.mccormick.cx 52.3563 4.95714
nostr.dlcdevkit.com:443 40.0992 -83.1141
nostr-02.yakihonne.com 1.32123 103.695
nostr.21crypto.ch 47.5356 8.73209
slick.mjex.me 39.0418 -77.4744
nostr.spicyz.io:443 43.6532 -79.3832
relay-dev.gulugulu.moe 43.6532 -79.3832
relay.nostx.io 43.6532 -79.3832
relay.wisp.talk 49.4543 11.0746
relay.plebeian.market:443 50.1109 8.68213
relay.mostr.pub:443 43.6532 -79.3832
relay.aarpia.com 37.3986 -121.964
chat-relay.zap-work.com 43.6532 -79.3832
chat-relay.zap-work.com:443 43.6532 -79.3832
relay.mitchelltribe.com:443 39.0438 -77.4874
relay.paulstephenborile.com 49.4543 11.0746
relay.trotters.cc 43.6532 -79.3832
nexus.libernet.app:443 43.6532 -79.3832
syb.lol 34.0549 -118.243
relay.cypherflow.ai 48.8575 2.35138
relay.despera.space 52.1782 20.9926
relay.loveisbitcoin.com 43.6532 -79.3832
relay.rushmi0.win 43.6532 -79.3832
relay.degmods.com 50.4754 12.3683
relay.satlantis.io 39.0438 -77.4874
relay.underorion.se 50.1109 8.68213
nostr.mom:443 50.4754 12.3683
nostr-verified.wellorder.net 45.5201 -122.99
relay.nostreon.com 60.1699 24.9384
nostr.christiansass.de 54.3213 10.1349
rilo.nostria.app:443 43.6532 -79.3832
relay.trotters.cc:443 43.6532 -79.3832
kotukonostr.onrender.com 37.7775 -122.397
relay.nmail.li 50.9871 2.12554
relay.artio.inf.unibe.ch 46.9501 7.43678
nos.lol 50.4754 12.3683
nostr.snowbla.de:443 50.4754 12.3683
relay.openresist.com 43.6532 -79.3832
ribo.us.nostria.app 43.6532 -79.3832
bitchat.nostr1.com 40.7057 -74.0136
vm-1734.lnvps.cloud 53.3498 -6.26031
nostr-relay.xbytez.io:443 50.6924 3.20113
nostr.sathoarder.com:443 48.5734 7.75211
bcast.girino.org 43.6532 -79.3832
ribo.us.nostria.app:443 43.6532 -79.3832
strfry.shock.network 39.0438 -77.4874
relay.staging.plebeian.market:443 51.5072 -0.127586
offchain.pub:443 39.1585 -94.5728
relayone.soundhsa.com 39.0997 -94.5786
relay.libernet.app 43.6532 -79.3832
relay.earthly.city 34.1749 -118.54
relayrs.notoshi.win:443 43.6532 -79.3832
nostr.vulpem.com 49.4543 11.0746
relay.getsafebox.app:443 43.6532 -79.3832
relay.paulstephenborile.com:443 49.4543 11.0746
nostr.unkn0wn.world 46.8499 9.53287
relay.binaryrobot.com 43.6532 -79.3832
relay.wellorder.net 45.5201 -122.99
relayone.geektank.ai:443 39.0997 -94.5786
relay.wasabiwallet.io 43.6532 -79.3832
top.testrelay.top 43.6532 -79.3832
nostr.2b9t.xyz 34.0549 -118.243
relay.nostr.com 50.1109 8.68213
nostr.azzamo.net:443 52.2633 21.0283
nostr.dlcdevkit.com 40.0992 -83.1141
nostr.robosats.org 64.1476 -21.9392
nostr.iskarion.ddns.net 43.3076 -2.95421
relay2.angor.io 48.1046 11.6002
relay.mmwaves.de 48.8575 2.35138
relay.agorist.space:443 52.3734 4.89406
relay.dreamith.to 43.6532 -79.3832
nostr-02.uid.ovh 50.9871 2.12554
nostr.thebiglake.org 32.71 -96.6745
nostr-relay.corb.net 39.6478 -104.988
relay.dyne.org 49.0291 8.35705
nosflare-leefcore.leefcore.workers.dev 43.6532 -79.3832
relay.angor.io 48.1046 11.6002
nostrelay.circum.space 52.2245 8.826
nostr-01.uid.ovh 50.9871 2.12554
maxq.descendant.io 43.6532 -79.3832
offchain.bostr.online 43.6532 -79.3832
relay.binaryrobot.com:443 43.6532 -79.3832
nostr.planix.org 43.6532 -79.3832
tribune-panel-growing-noon.trycloudflare.com 43.6532 -79.3832
prl.plus 55.7628 37.5983
relay.mwaters.net 50.9871 2.12554
dev.relay.stream 43.6532 -79.3832
relay.bornheimer.app 50.1109 8.68213
inbox.scuba323.com 40.8218 -74.45
relay-us.zombi.cloudrodion.com 40.7862 -74.0743
relay.nuts.cash 52.3676 4.90414
bruh.samt.st 43.6532 -79.3832
nostr.carroarmato0.be:443 50.914 3.21378
relay.plebeian.market 50.1109 8.68213
schnorr.me:443 43.6532 -79.3832
nostr.thalheim.io:443 60.1699 24.9384
nostr.88mph.life 52.1941 -2.21905
cache.trustr.ing 43.6548 -79.3885
ec2.f7z.io 60.1699 24.9384
relay.btcforplebs.com 43.6532 -79.3832
nostr.liberty.fans 36.8767 -89.5879
syb.lol:443 34.0549 -118.243
nostr.islandarea.net:443 35.4669 -97.6473
nostr.mom 50.4754 12.3683
nostr.data.haus:443 50.4754 12.3683
strfry.bonsai.com:443 39.0438 -77.4874
nostr.highway15.net 28.0445 -82.6699
relay.wavlake.com:443 41.2619 -95.8608
relay.nostriot.com:443 41.5695 -83.9786
relay.gulugulu.moe:443 43.6532 -79.3832
rele.speyhard.fi 50.1109 8.68213
nostr.hoppe-relay.it.com 42.8864 -78.8784
nostr2.girino.org:443 43.6532 -79.3832
nostr.oxtr.dev 50.4754 12.3683
nostr.bitcoiner.social:443 40.7608 -111.891
nostrrelay.taylorperron.com 45.5029 -73.5723
nostr-01.yakihonne.com:443 1.32123 103.695
nostr.tagomago.me 42.3601 -71.0589
relay.hivetalk.org 40.8302 -74.1299
relay.sigit.io:443 50.4754 12.3683
relay.openresist.com:443 43.6532 -79.3832
cs-relay.nostrdev.com:443 50.4754 12.3683
no.str.cr:443 8.96171 -83.5246
relay.nearhood.co.uk 51.5134 -0.0890675
relay.lanavault.space 60.1699 24.9384
relay.guggero.org 46.5971 9.59652
nexus.libernet.app 43.6532 -79.3832
relay.nostriot.com 41.5695 -83.9786
dm-test-strfry-discovery.samt.st:443 43.6532 -79.3832
x.kojira.io:443 43.6532 -79.3832
nostr.4rs.nl 49.0291 8.35696
relayone.geektank.ai 39.0997 -94.5786
nostr.debate.report 50.1109 8.68213
relay.gulugulu.moe 43.6532 -79.3832
public.crostr.com 43.6532 -79.3832
offchain.pub 39.1585 -94.5728
relay.tdw.lol 41.8781 -87.6298
relay5.bitransfer.org 43.6532 -79.3832
relay.manneken.brussels 49.4543 11.0746
chorus.pjv.me 45.5201 -122.99
relay.fckstate.net 59.3293 18.0686
treuzkas.branruz.com 48.8575 2.35138
nostr-relay.cbrx.io 43.6532 -79.3832
nostr-relay.nextblockvending.com 47.2343 -119.853
nostr.fullstackcash.net 45.5201 -122.99
relay.primal.net 43.6532 -79.3832
relay.mappingbitcoin.com 43.6532 -79.3832
nostr.mikoshi.de 50.1109 8.68213
nostr.stakey.net 52.3676 4.90414
nostr-rs-relay-qj1h.onrender.com 37.7775 -122.397
relay.wavlake.com 41.2619 -95.8608
relay.ordoplay.com 50.1109 8.68213
relay.klabo.world 47.674 -122.122
buzz.cashu.space 50.1109 8.68213
relay.nostrhub.fr 48.1045 11.6004
portal-relay.pareto.space 49.0291 8.35696
dev-relay.nostreon.com 60.1699 24.9384
relay.islandbitcoin.com 12.8498 77.6545
testr.nymble.world 40.8054 -74.0241
relayrs.notoshi.win 43.6532 -79.3832
nostr-relay.corb.net:443 39.6478 -104.988
cdn.satellite.earth 40.8302 -74.1299
rilo.nostria.app 43.6532 -79.3832
nostr.pbfs.io 50.4754 12.3683
nostr2.girino.org 43.6532 -79.3832
0x-nostr-relay.fly.dev 38.7946 -106.535
nostr.girino.org 43.6532 -79.3832
relay.layer.systems 49.0291 8.35695
relay.olas.app 60.1699 24.9384
ribo.eu.nostria.app 43.6532 -79.3832
buzz.ac2n-share.kozow.com 45.764 4.83566
auth.nostr1.com 40.7057 -74.0136
relay.bitmacro.cloud 43.6532 -79.3832
relay.qstr.app 50.1109 8.68213
relay.ru.ac.th 13.7607 100.627
ribo.nostria.app:443 43.6532 -79.3832
relay.44billion.net 43.6532 -79.3832
cs-relay.nostrdev.com 50.4754 12.3683
relay.nostrian-conquest.com:443 41.223 -111.974
relay.bullishbounty.com 43.6532 -79.3832
relay.edufeed.org 49.4521 11.0767
porchlight.social 43.6532 -79.3832
2 nostr.bitcoiner.social 40.7608 -111.891
3 testnet-relay.samt.st relay.mostr.pub 40.8302 43.6532 -74.1299 -79.3832
4 relay.vrtmrz.net relay.veganostr.com:443 43.6532 60.1699 -79.3832 24.9384
5 nostr.wecsats.io:443 relay.dreamith.to 43.6532 -79.3832
6 relay.satmaxt.xyz:443 buzz.cashu.space 43.6532 50.1109 -79.3832 8.68213
7 nostr.snowbla.de relay.sincensura.org 50.4754 43.6532 12.3683 -79.3832
8 nostr.rtvslawenia.com:443 relayrs.notoshi.win:443 49.4543 43.6532 11.0746 -79.3832
9 relay.flashapp.me nostr.bond 43.6548 50.1109 -79.3885 8.68213
10 purplerelay.com:443 relay.edufeed.org 43.6532 49.4521 -79.3832 11.0767
11 relay.staging.plebeian.market relay.bullishbounty.com:443 51.5072 43.6532 -0.127586 -79.3832
12 relay.libernet.app:443 relay.nostr.blockhenge.com 43.6532 39.0438 -79.3832 -77.4874
13 relay.0xchat.com relay2.fiatdenier.com 43.6532 50.1013 -79.3832 8.62643
14 myvoiceourstory.org relay.mwaters.net 37.3598 50.9871 -121.981 2.12554
15 nrs-01.darkcloudarcade.com:443 relay2.angor.io 39.0997 48.1046 -94.5786 11.6002
16 relay.vrtmrz.net:443 memlay.v0l.io 43.6532 53.3498 -79.3832 -6.26031
17 relay.zone667.com nostr.wecsats.io 60.1699 43.6532 24.9384 -79.3832
18 nostr.nodesmap.com vm-1734.lnvps.cloud 59.3327 53.3498 18.0656 -6.26031
19 dm-test-strfry-discovery.samt.st:443 43.6532 -79.3832
20 nostr2.girino.org:443 43.6532 -79.3832
21 nostr.robosats.org 64.1476 -21.9392
22 relay.atsocy.com 43.6532 -79.3832
23 relayone.geektank.ai:443 39.0997 -94.5786
24 relay.olas.app:443 60.1699 24.9384
25 relay.nostu.be 40.4167 -3.70329
26 relay.otrta.me 50.1109 8.68213
27 nostr.spaceshell.xyz 43.6532 -79.3832
28 rilo.nostria.app 43.6532 -79.3832
29 relay.agorist.space 52.3734 4.89406
30 relayone.soundhsa.com:443 relay.nostrmap.net 39.0997 60.1699 -94.5786 24.9384
31 relay.satmaxt.xyz relay.bullishbounty.com 43.6532 -79.3832
relay.zapanimations.com 40.8054 -74.0241
relay.sovereignresonance.org 48.8575 2.35138
nostr.relay.hedwig.sh 60.1699 24.9384
relay-dev.gulugulu.moe:443 43.6532 -79.3832
relay.arx-ccn.com 50.4754 12.3683
nip85.nosfabrica.com 39.0997 -94.5786
32 nrs-01.darkcloudarcade.com 39.0997 -94.5786
33 spamspamspamspam.rest relay.angor.io:443 43.6532 48.1046 -79.3832 11.6002
nostr.davenov.com 50.1109 8.68213
relay.littlebitstudios.com 43.6532 -79.3832
purplerelay.com 43.6532 -79.3832
nos.lol:443 50.4754 12.3683
relay2.veganostr.com 60.1699 24.9384
relay-rpi.edufeed.org 49.4521 11.0767
relay.lacrypta.ar 43.6532 -79.3832
relay.tdw.gg 34.0549 -118.243
relay.getvia.xyz 60.1699 24.9384
relay.lanacoin-eternity.com 40.8302 -74.1299
conduitl2.fly.dev 38.7946 -106.535
34 nostr.rtvslawenia.com 49.4543 11.0746
35 relay.wavefunc.live:443 relay.wasabiwallet.io 41.8781 43.6532 -87.6298 -79.3832
36 cs-relay.nostrdev.com:443 50.4754 12.3683
37 nostr.4rs.nl 49.0291 8.35696
38 nexus.libernet.app 43.6532 -79.3832
39 relay-dev.gulugulu.moe 43.6532 -79.3832
40 nostr.88mph.life 52.1941 -2.21905
41 relayone.soundhsa.com:443 39.0997 -94.5786
42 social.amanah.eblessing.co 48.1046 11.6002
43 relay.getsafebox.app 43.6532 -79.3832
44 relay.44billion.net 43.6532 -79.3832
45 relay.conduit.market 38.7946 -106.535
46 nostr.infero.net 35.6764 139.65
47 relay.staging.plebeian.market 51.5072 -0.127586
48 relay.snort.social 53.3498 -6.26031
49 purplerelay.com:443 43.6532 -79.3832
50 nostr.mas-family.eu 60.3478 15.7505
51 relay.ru.ac.th 13.7607 100.627
52 relay.openresist.com 43.6532 -79.3832
53 antiprimal.net 43.6532 -79.3832
54 relay.illuminodes.com 43.6532 -79.3832
55 relay.mmwaves.de:443 48.8575 2.35138
56 nostr.spicyz.io 43.6532 -79.3832
57 relay.nostrfeed.com 60.1699 24.9384
58 strfry.apps3.slidestr.net 40.4167 -3.70329
59 relay.directsponsor.net 42.8864 -78.8784
60 relay.nostrhub.fr 48.1045 11.6004
61 nostr.plantroon.com 50.1013 8.62643
62 nostr-verified.wellorder.net 45.5201 -122.99
63 relay.bnos.space:443 43.6532 -79.3832
64 relay.pyramid.li 47.4093 8.46503
65 public.crostr.com 43.6532 -79.3832
66 relay.kilombino.com 43.6532 -79.3832
67 relay.libernet.app:443 43.6532 -79.3832
68 relay.internationalright-wing.org -22.4692 -48.9875
69 nostr.overmind.lol:443 43.6532 -79.3832
70 relay.ordoplay.com 50.1109 8.68213
71 mostro-p2p.tech 50.1109 8.68213
72 offchain.pub:443 39.1585 -94.5728
73 cs-relay.nostrdev.com 50.4754 12.3683
74 relay-can.zombi.cloudrodion.com 43.6532 -79.3832
75 nostr.unkn0wn.world 46.8499 9.53287
76 relay.shadowbip.com 50.1109 8.68213
77 relay.lanacoin-eternity.com:443 40.8302 -74.1299
78 relay.staging.commonshub.brussels 49.4543 11.0746
79 relay2.angor.io:443 48.1046 11.6002
80 relay.arx-ccn.com 50.4754 12.3683
81 relay.underorion.se 50.1109 8.68213
82 bread.nostrsms.com 40.8218 -74.45
83 relay.cypherflow.ai 48.8575 2.35138
84 nostr.islandarea.net:443 35.4669 -97.6473
85 relay.homeinhk.xyz 35.694 139.754
86 relay.ditto.pub:443 43.6532 -79.3832
87 nostr.fullstackcash.net 45.5201 -122.99
88 bitcoinostr.duckdns.org 38.9504 -0.14007
89 relay.trotters.cc 43.6532 -79.3832
90 portal-relay.pareto.space 49.0291 8.35696
91 relay.openresist.com:443 43.6532 -79.3832
92 relay.endfiat.money 59.3327 18.0656
93 nostr.hoppe-relay.it.com 42.8864 -78.8784
94 nostr.sovereignservices.xyz 43.6532 -79.3832
95 relay.fundstr.me 42.3601 -71.0589
96 relay5.bitransfer.org 43.6532 -79.3832
97 nrs-01.darkcloudarcade.com:443 39.0997 -94.5786
98 testr.nymble.world 40.8054 -74.0241
99 strfry.shock.network:443 39.0438 -77.4874
100 chorus.mikedilger.com:444 -36.8906 174.794
101 relay.minibolt.info 43.6532 -79.3832
102 nos.lol:443 50.4754 12.3683
103 relay.liberbitworld.org 43.6532 -79.3832
104 maxq.descendant.io 43.6532 -79.3832
105 nostrcity-club.fly.dev 38.7946 -106.535
106 relay.nostriot.com 41.5695 -83.9786
107 nostr.n7ekb.net 47.4941 -122.294
108 relay.erybody.com 41.4513 -81.7021
109 nostr-rs-relay-qj1h.onrender.com 37.7775 -122.397
110 nostrrelay.taylorperron.com 45.5029 -73.5723
111 syb.lol 34.0549 -118.243
112 relay.nostr.com 50.1109 8.68213
113 relay.hivetalk.org 40.8302 -74.1299
114 relay.degmods.com 50.4754 12.3683
115 relay.laantungir.net -19.4692 -42.5315
116 relay.nearhood.co.uk 51.5134 -0.0890675
117 relay.tdw.lol 41.8781 -87.6298
118 ribo.us.nostria.app 43.6532 -79.3832
119 public.obelisk.ar 43.6532 -79.3832
120 prl.plus 55.7628 37.5983
121 21milionidinostr.duckdns.org 45.5192 9.08625
122 nostr.carroarmato0.be 50.914 3.21378
123 nostr.pbfs.io:443 50.4754 12.3683
ribo.nostria.app 43.6532 -79.3832
nostr.sovereignservices.xyz 43.6532 -79.3832
relay.mostr.pub 43.6532 -79.3832
schnorr.me 43.6532 -79.3832
x.kojira.io 43.6532 -79.3832
public.obelisk.ar 43.6532 -79.3832
relay.angor.io:443 48.1046 11.6002
nostr.oxtr.dev:443 50.4754 12.3683
nostr.ltd 19.076 72.8777
nostr.tac.lol:443 47.4748 -122.273
nostr.twinkle.lol 51.902 7.6657
relay.s-w.art 43.6532 -79.3832
relay.openfarmtools.org 60.1699 24.9384
nostr.hekster.org 37.3986 -121.964
strfry.apps3.slidestr.net 40.4167 -3.70329
relay.mypathtofire.de 42.8864 -78.8784
nostr.wecsats.io 43.6532 -79.3832
nostr.computingcache.com 34.0356 -118.442
nostr.janx.com 43.6532 -79.3832
bread.nostrsms.com 40.8218 -74.45
relay.chorus.community 48.5333 10.7
testnet-relay.samt.st:443 40.8302 -74.1299
relay.kaleidoswap.com 50.8476 4.35717
yabu.me 35.6092 139.73
nostr-dev.wellorder.net 45.5201 -122.99
relay.layer.systems:443 49.0291 8.35695
relay-can.zombi.cloudrodion.com 43.6532 -79.3832
nostr-relay.zimage.com 34.282 -118.439
relay.fundstr.me 42.3601 -71.0589
nostr.stakey.net:443 52.3676 4.90414
relay.satsmarkt.club 52.6907 4.8181
relay.satsapp.me 50.4754 12.3683
bendernostur.duckdns.org:8443 50.1109 8.68213
relay.illuminodes.com 43.6532 -79.3832
nostr.chaima.info:443 50.1109 8.68213
nostr.hekster.org:443 37.3986 -121.964
nostr.yutakobayashi.com 43.6532 -79.3832
freelay.sovbit.host 60.1699 24.9384
insta-relay.apps3.slidestr.net 40.4167 -3.70329
infinity-signal-relay.digitalforlifeagency.workers.dev 43.6532 -79.3832
relay.internationalright-wing.org -22.4692 -48.9875
relay.mmwaves.de:443 48.8575 2.35138
124 public.crostr.com:443 43.6532 -79.3832
125 relay.nostrian-conquest.com espelho.girino.org 41.223 43.6532 -111.974 -79.3832
126 relay-rpi.edufeed.org:443 nostr.computingcache.com 49.4521 45.5341 11.0767 -122.956
127 relay2.angor.io:443 relay.chorus.community:443 48.1046 48.5333 11.6002 10.7
128 relay-fra.zombi.cloudrodion.com nostr-relay.nextblockvending.com 48.8566 47.2343 2.35222 -119.853
129 bunk-test.feeds.relay.tools nostr.easycryptosend.it 38.6327 43.6532 -90.1961 -79.3832
130 nostr-pr02.redscrypt.org no.str.cr:443 52.3676 8.96171 4.90414 -83.5246
131 nostr.tac.lol nostr.snowbla.de:443 47.4748 50.4754 -122.273 12.3683
nostr.overpay.com 29.7449 -95.5343
relay.novospes.com 43.6532 -79.3832
nostrcity-club.fly.dev:443 38.7946 -106.535
relay01.lnfi.network 35.6764 139.65
relay.lightning.pub:443 39.0438 -77.4874
relay.pyramid.li 47.4093 8.46503
relay.nostu.be 40.4167 -3.70329
nostr-rs-relay.dev.fedibtc.com:443 39.0438 -77.4874
relay.endfiat.money:443 59.3327 18.0656
nostr.spaceshell.xyz 43.6532 -79.3832
21milionidinostr.duckdns.org 45.5192 9.08625
articles.layer3.news:443 37.3387 -121.885
wheat.happytavern.co 43.6532 -79.3832
nostr-rs-relay.dev.fedibtc.com 39.0438 -77.4874
nostr.na.social 43.6532 -79.3832
social.amanah.eblessing.co 48.1046 11.6002
reraw.pbla2fish.cc 43.6532 -79.3832
nostr.girino.org:443 43.6532 -79.3832
staging.yabu.me 35.6092 139.73
nostr.islandarea.net 35.4669 -97.6473
relay.endfiat.money 59.3327 18.0656
relay.mitchelltribe.com 39.0438 -77.4874
nostr.myshosholoza.co.za 52.3676 4.90414
relay.staging.commonshub.brussels 49.4543 11.0746
132 bridge.tagomago.me 42.3601 -71.0589
133 relay.agentry.com relay.endfiat.money:443 42.8864 59.3327 -78.8784 18.0656
134 testnet.samt.st relay.klabo.world 43.6532 47.674 -79.3832 -122.122
135 nostr.wild-vibes.ts.net articles.layer3.news:443 48.8566 37.3387 2.35222 -121.885
136 relay.getsafebox.app nostr.21crypto.ch 43.6532 47.5356 -79.3832 8.73209
137 relay.notoshi.win relay.kaleidoswap.com 13.3396 50.8476 100.93 4.35717
138 bitcoinostr.duckdns.org nostr.relay.hedwig.sh 41.1976 60.1699 1.11167 24.9384
139 relay.sigit.io nostr.yutakobayashi.com 50.4754 43.6532 12.3683 -79.3832
bucket.coracle.social 37.7775 -122.397
dm-test-strfry-discovery.samt.st 43.6532 -79.3832
vault.iris.to:443 43.6532 -79.3832
relay.wisp.talk:443 49.4543 11.0746
relay.mostro.network 40.8302 -74.1299
nostr.l484.com 30.2672 -97.7431
relay.froth.zone 60.1699 24.9384
relay.beamhop.com 43.6532 -79.3832
relay.sincensura.org 43.6532 -79.3832
relay.ditto.pub:443 43.6532 -79.3832
nostr.azzamo.net 52.2633 21.0283
relay.edufeed.org:443 49.4521 11.0767
ribo.eu.nostria.app:443 43.6532 -79.3832
vault.iris.to 43.6532 -79.3832
nostr.plantroon.com 50.1013 8.62643
fanfares.nostr1.com 40.7057 -74.0136
budabit.nostr1.com 40.7057 -74.0136
relay.damus.io 43.6532 -79.3832
strfry.shock.network:443 39.0438 -77.4874
bitcoiner.social 40.7608 -111.891
basspistol.org 49.0291 8.35696
nostr.thalheim.io 60.1699 24.9384
relay.conduit.market 38.7946 -106.535
relay.yoinekodo.jp 43.6532 -79.3832
nostrbtc.com 43.6532 -79.3832
relay.lightning.pub 39.0438 -77.4874
nostr-01.yakihonne.com 1.32123 103.695
nostr-pub.wellorder.net 45.5201 -122.99
140 strfry.ymir.cloud 43.6532 -79.3832
141 relay.minibolt.info relay.littlebitstudios.com 43.6532 -79.3832
142 nostr.data.haus testnet-relay.samt.st:443 50.4754 40.8302 12.3683 -74.1299
143 relay.otrta.me relay.islandbitcoin.com 50.1109 12.8498 8.68213 77.6545
144 relay.samt.st relay.zone667.com 40.8302 60.1699 -74.1299 24.9384
145 relay.nostr.blockhenge.com relay.lightning.pub:443 39.0438 -77.4874
146 relay.minibolt.info:443 relay.layer.systems:443 43.6532 49.0291 -79.3832 8.35695
147 nostr.2b9t.xyz:443 offchain.pub 34.0549 39.1585 -118.243 -94.5728
148 nos.lol 50.4754 12.3683
149 cdn.satellite.earth 40.8302 -74.1299
150 relay-us.zombi.cloudrodion.com 40.7862 -74.0743
151 relay.wisp.talk:443 49.4543 11.0746
152 nostr.hekster.org:443 37.3986 -121.964
153 nostr.mom:443 50.4754 12.3683
154 relay.mccormick.cx:443 52.3563 4.95714
155 dev.relay.stream 43.6532 -79.3832
156 dm-test-nostr-rs-42-disabled.samt.st 43.6532 -79.3832
157 relay.veganostr.com relay.vrtmrz.net:443 60.1699 43.6532 24.9384 -79.3832
158 relay.fountain.fm relayone.soundhsa.com 43.6532 39.0997 -79.3832 -94.5786
159 relay.agorist.space:443 52.3734 4.89406
160 relay-fra.zombi.cloudrodion.com 48.8566 2.35222
161 nostr.dlcdevkit.com:443 40.0992 -83.1141
162 node.kommonzenze.de 49.4521 11.0767
163 relay-arg.zombi.cloudrodion.com relay.beamhop.com 1.35208 43.6532 103.82 -79.3832
164 nostr.myshosholoza.co.za:443 nostr.2b9t.xyz:443 52.3676 34.0549 4.90414 -118.243
165 temp.iris.to relay.chatbett.de 43.6532 40.7128 -79.3832 -74.006
166 relay.nostrmap.net relay.tdw.gg 60.1699 34.0549 24.9384 -118.243
167 budabit.nostr1.com 40.7057 -74.0136
168 nostr.novacisko.cz 52.2026 20.9397
169 relay.samt.st 40.8302 -74.1299
170 bruh.samt.st 43.6532 -79.3832
171 nostr.wild-vibes.ts.net 48.8566 2.35222
172 relay.opossumwire.org 34.0549 -118.243
173 relay.angor.io 48.1046 11.6002
174 relay.nostrmap.net:443 60.1699 24.9384
175 nostr-rs-relay.dev.fedibtc.com 39.0438 -77.4874
176 chat-relay.zap-work.com 43.6532 -79.3832
177 relay.earthly.city 34.1749 -118.54
178 relay.mappingbitcoin.com 43.6532 -79.3832
179 relay.satmaxt.xyz 43.6532 -79.3832
180 relay.primal.net 43.6532 -79.3832
181 relay.bornheimer.app 50.1109 8.68213
182 nostr.tagomago.me 42.3601 -71.0589
183 relay.orly.dev 32.7767 -96.797
184 no.str.cr 8.96171 -83.5246
185 auth.nostr1.com 40.7057 -74.0136
186 relay.opmaat.org 60.1699 24.9384
187 temp.iris.to 43.6532 -79.3832
188 conduitl2.fly.dev 38.7946 -106.535
189 yabu.me 35.6092 139.73
190 nostrride.io 37.3986 -121.964
191 nostr.plantroon.com:443 50.1013 8.62643
192 relay.wavlake.com 41.2619 -95.8608
193 nostrbtc.com 43.6532 -79.3832
194 relay.mitchelltribe.com:443 39.0438 -77.4874
195 relay.manneken.brussels 49.4543 11.0746
196 relay.lanacoin-eternity.com 40.8302 -74.1299
197 bendernostur.duckdns.org:8443 50.1109 8.68213
198 nostr-kyomu-haskell.onrender.com 37.7775 -122.397
199 nostr.nodesmap.com 59.3327 18.0656
200 nostr-01.yakihonne.com 1.32123 103.695
201 bunk-test.feeds.relay.tools 38.6327 -90.1961
202 relay.btcforplebs.com 43.6532 -79.3832
203 relay.beginningend.com 35.2227 -97.4786
204 nostr.iskarion.ddns.net 43.3076 -2.95421
205 nostr-relay.cbrx.io 43.6532 -79.3832
206 relay.nostrian-conquest.com 41.223 -111.974
207 relay.cosmicbolt.net:443 37.3986 -121.964
208 nostr.oxtr.dev:443 50.4754 12.3683
209 nostr-relay.acloud.kdns.fr 43.6532 -79.3832
210 relay.mccormick.cx 52.3563 4.95714
211 relay.fiatdenier.com 43.7787 -79.5393
212 nostr.bitcoiner.social:443 40.7608 -111.891
213 relay.gulugulu.moe:443 43.6532 -79.3832
214 relay.piazza.today 48.122 11.589
215 nostr.ac 38.958 -77.3592
216 strfry.bonsai.com 39.0438 -77.4874
217 dev-relay.nostreon.com 60.1699 24.9384
218 relay.olas.app 60.1699 24.9384
219 relay.loveisbitcoin.com 43.6532 -79.3832
220 strfry.bonsai.com:443 39.0438 -77.4874
221 nostr.tac.lol 47.4748 -122.273
222 rilo.nostria.app:443 43.6532 -79.3832
223 nostr.azzamo.net 52.2633 21.0283
224 nostr.wecsats.io:443 43.6532 -79.3832
225 relay.wellorder.net 45.5201 -122.99
226 relay.libernet.app 43.6532 -79.3832
227 nostr.thalheim.io 60.1699 24.9384
228 relayrs.notoshi.win 43.6532 -79.3832
229 ribo.nostria.app:443 43.6532 -79.3832
230 relay.gulugulu.moe 43.6532 -79.3832
231 relay.qstr.app 50.1109 8.68213
232 myvoiceourstory.org 37.3598 -121.981
233 nostr-relay.zimage.com 34.282 -118.439
234 treuzkas.branruz.com 48.8575 2.35138
235 top.testrelay.top 43.6532 -79.3832
236 relay.cyberguy.fyi 52.6907 4.8181
237 articles.layer3.news 37.3387 -121.885
238 nostr.sathoarder.com 48.5734 7.75211
239 nostr.carroarmato0.be:443 50.914 3.21378
240 nostr-02.uid.ovh 50.9871 2.12554
241 ribo.us.nostria.app:443 43.6532 -79.3832
242 relay.ditto.pub 43.6532 -79.3832
243 nostr.chaima.info:443 50.1109 8.68213
244 relay.bnos.space 43.6532 -79.3832
245 relay.solife.me 43.6532 -79.3832
246 relay.wavlake.com:443 41.2619 -95.8608
247 bucket.coracle.social 37.7775 -122.397
248 nostr.christiansass.de 52.5244 13.4105
249 relay.dyne.org 49.0291 8.35705
250 testnet-relay.samt.st 40.8302 -74.1299
251 nostream.seitendan.com 34.7062 135.493
252 basspistol.org 49.0291 8.35696
253 purplerelay.com 43.6532 -79.3832
254 relay.wisp.talk 49.4543 11.0746
255 relay.getsafebox.app:443 43.6532 -79.3832
256 freelay.sovbit.host 60.1699 24.9384
257 relay.sigit.io:443 50.4754 12.3683
258 buzz.ac2n-share.kozow.com 45.764 4.83566
259 relay.mostro.network 40.8302 -74.1299
260 nostrcheck.me 43.6532 -79.3832
261 nostr.rtvslawenia.com:443 49.4543 11.0746
262 insta-relay.apps3.slidestr.net 40.4167 -3.70329
263 nostr.vulpem.com 49.4543 11.0746
264 relay-na1.metanomalist.com 43.6532 -79.3832
265 chorus.bonsai.com 39.0438 -77.4874
266 ec2.f7z.io 60.1699 24.9384
267 relay-dev.gulugulu.moe:443 43.6532 -79.3832
268 nostr.twinkle.lol 51.902 7.6657
269 relay.lanavault.space 60.1699 24.9384
270 nostr.pbfs.io 50.4754 12.3683
271 bitchat.nostr1.com 40.7057 -74.0136
272 nostr.highway15.net 28.0445 -82.6699
273 nostr.tabordalab.com 60.1699 24.9384
274 relay.ohstr.com 43.6532 -79.3832
275 schnorr.me 43.6532 -79.3832
276 relay.s-w.art 43.6532 -79.3832
277 relay.nmail.li 50.9871 2.12554
278 bcast.girino.org 43.6532 -79.3832
279 relay.nostrops.com 32.71 -96.6745
280 dm-test-strfry-generic.samt.st 43.6532 -79.3832
281 relay.keykeeper.world 40.7824 -74.0711
282 relay.satsmarkt.club 52.6907 4.8181
283 adre.su 59.9311 30.3609
284 relay.edufeed.org:443 49.4521 11.0767
285 infinity-signal-relay.digitalforlifeagency.workers.dev 43.6532 -79.3832
286 relay.lightning.pub 39.0438 -77.4874
287 porchlight.social 43.6532 -79.3832
288 nostr.snowbla.de 50.4754 12.3683
289 relay.trotters.cc:443 43.6532 -79.3832
290 nostr-relay.xbytez.io 50.6924 3.20113
291 relay.nostr.net 43.6532 -79.3832
292 nostrcity-club.fly.dev:443 38.7946 -106.535
293 nostr.mikoshi.de 50.1109 8.68213
294 nostr.mom 50.4754 12.3683
295 schnorr.me:443 43.6532 -79.3832
296 chat-relay.zap-work.com:443 43.6532 -79.3832
297 relay.paulstephenborile.com:443 49.4543 11.0746
298 relay.fckstate.net 59.3293 18.0686
299 offchain.bostr.online 43.6532 -79.3832
300 nostr.oxtr.dev 50.4754 12.3683
301 testnet.samt.st 43.6532 -79.3832
302 nostr.planix.org 43.6532 -79.3832
303 relay.getvia.xyz 60.1699 24.9384
304 relay.lacrypta.ar 43.6532 -79.3832
305 nostr.janx.com 43.6532 -79.3832
306 relay.yoinekodo.jp 43.6532 -79.3832
307 nostrelay.circum.space 52.2245 8.826
308 staging.yabu.me 35.6092 139.73
309 relay.staging.plebeian.market:443 51.5072 -0.127586
310 reraw.pbla2fish.cc 43.6532 -79.3832
311 relay.satsapp.me 50.4754 12.3683
312 x.kojira.io 43.6532 -79.3832
313 relay.layer.systems 49.0291 8.35695
314 relay01.lnfi.network 35.6764 139.65
315 nostr.whitenode45.ddns.net 40.55 -74.4758
316 relay-rpi.edufeed.org 49.4521 11.0767
317 nostr-dev.wellorder.net 45.5201 -122.99
318 nostr.overmind.lol 43.6532 -79.3832
319 relay.aarpia.com 37.3986 -121.964
320 relayone.geektank.ai 39.0997 -94.5786
321 nostr.purpura.cloud 43.6532 -79.3832
322 nostr.data.haus:443 50.4754 12.3683
323 nexus.libernet.app:443 43.6532 -79.3832
324 nostr.thebiglake.org 32.71 -96.6745
325 relay.bowlafterbowl.com 32.9483 -96.7299
326 relay.mitchelltribe.com 39.0438 -77.4874
327 nostr-relay.xbytez.io:443 50.6924 3.20113
328 bitcoiner.social 40.7608 -111.891
329 relay.guggero.org 46.5971 9.59652
330 relay.mrmave.work 43.6532 -79.3832
331 relay.flashapp.me 43.6548 -79.3885
332 relay.mmwaves.de 48.8575 2.35138
333 nostr.red5d.dev 43.6532 -79.3832
334 relay.plebeian.market 50.1109 8.68213
335 nostr.girino.org 43.6532 -79.3832
336 relay02.lnfi.network 35.6764 139.65
337 relay.vrtmrz.net 43.6532 -79.3832
338 ynostr.yael.at 60.1699 24.9384
339 relay.cosmicbolt.net 37.3986 -121.964
340 nostr-rs-relay.dev.fedibtc.com:443 39.0438 -77.4874
341 nostrelay.circum.space:443 52.2245 8.826
342 nostr.notribe.net nostr.tac.lol:443 40.8302 47.4748 -74.1299 -122.273
343 relay-arg.zombi.cloudrodion.com 1.35208 103.82
344 relay.agora.social 50.7383 15.0648
345 vault.iris.to:443 43.6532 -79.3832
346 relay.nexterz.com 43.6532 -79.3832
347 relay2.veganostr.com 60.1699 24.9384
348 strfry.shock.network 39.0438 -77.4874
349 relay.notoshi.win 13.3396 100.93
350 vault.iris.to 43.6532 -79.3832
351 relay.novospes.com 43.6532 -79.3832
352 nip85.nosfabrica.com 39.0997 -94.5786
353 relay-testnet.k8s.layer3.news 37.3387 -121.885
354 nostr.stakey.net 52.3676 4.90414
355 syb.lol:443 34.0549 -118.243
356 nostr-01.uid.ovh 50.9871 2.12554
357 nostr-02.yakihonne.com 1.32123 103.695
358 relay.favillakey.io -27.4705 153.026
359 relay.plebeian.market:443 50.1109 8.68213
360 r.iqbqioza.com 43.6532 -79.3832
361 relay.ohstr.com:443 43.6532 -79.3832
362 relay.paulstephenborile.com 49.4543 11.0746
363 nostr.2b9t.xyz 34.0549 -118.243
364 slick.mjex.me 39.0418 -77.4744
365 nostr.hekster.org 37.3986 -121.964
366 nostr.stakey.net:443 52.3676 4.90414
367 relay.sharegap.net 43.6532 -79.3832
368 relay.veganostr.com 60.1699 24.9384
369 nosflare-leefcore.leefcore.workers.dev 43.6532 -79.3832
370 nostr.data.haus 50.4754 12.3683
371 x.kojira.io:443 43.6532 -79.3832
372 relay.nostx.io 43.6532 -79.3832
373 wheat.happytavern.co 43.6532 -79.3832
374 nostr.myshosholoza.co.za:443 52.3676 4.90414
375 inbox.scuba323.com 40.8218 -74.45
376 nostr.chaima.info 50.1109 8.68213
377 relay.nostriches.club 43.6532 -79.3832
378 fanfares.nostr1.com 40.7057 -74.0136
379 relay.bitmacro.cloud 43.6532 -79.3832
380 relay.mostr.pub:443 43.6532 -79.3832
381 nostr.spicyz.io:443 43.6532 -79.3832
382 relay.agentry.com 42.8864 -78.8784
383 nostr.thalheim.io:443 60.1699 24.9384
384 tribune-panel-growing-noon.trycloudflare.com 43.6532 -79.3832
385 relay.mypathtofire.de 42.8864 -78.8784
386 nostr-relay.corb.net:443 39.6478 -104.988
387 dm-test-strfry-discovery.samt.st 43.6532 -79.3832
388 nostr.debate.report 50.1109 8.68213
389 relay.nostrcheck.me 43.6532 -79.3832
390 relay.scuba323.com 40.8218 -74.45
391 relay.decentralia.fr 48.122 11.589
392 fanfares.nostr1.com:443 40.7057 -74.0136
393 relay.sigit.io 50.4754 12.3683
394 ribo.nostria.app 43.6532 -79.3832
395 nostr.davenov.com 50.1109 8.68213
396 nostr.azzamo.net:443 52.2633 21.0283
397 ribo.eu.nostria.app 43.6532 -79.3832
398 nostr-01.yakihonne.com:443 1.32123 103.695
399 desktop-r082364.tail4b3c94.ts.net 48.8566 2.35222
400 0x-nostr-relay.fly.dev 38.7946 -106.535
401 soloco.nl 43.6532 -79.3832
402 relay.chorus.community 48.5333 10.7
403 nostr.sathoarder.com:443 48.5734 7.75211
404 nostr.myshosholoza.co.za 52.3676 4.90414
405 cache.trustr.ing 43.6548 -79.3885
406 nostr.islandarea.net 35.4669 -97.6473
407 nostr-relay.corb.net 39.6478 -104.988
408 relay-rpi.edufeed.org:443 49.4521 11.0767
409 rele.speyhard.fi 50.1109 8.68213
410 relay.pocketnostr.com 40.8054 -74.0241
411 relay.nuts.cash 52.3676 4.90414
412 spamspamspamspam.rest 43.6532 -79.3832
413 nostr.dlcdevkit.com 40.0992 -83.1141
414 relay.satlantis.io 39.0438 -77.4874
415 nostr.na.social 43.6532 -79.3832
416 relay.nostreon.com 60.1699 24.9384

View File

@ -29,9 +29,23 @@ data class PeerCapabilities(val rawValue: Long) : Parcelable {
companion object {
val NONE = PeerCapabilities(0)
val PREKEYS = PeerCapabilities(1L shl 0)
val WIFI_BULK = PeerCapabilities(1L shl 1)
val GATEWAY = PeerCapabilities(1L shl 2)
val GROUPS = PeerCapabilities(1L shl 3)
val BOARD = PeerCapabilities(1L shl 4)
val VOUCH = PeerCapabilities(1L shl 5)
val MESH_DIAGNOSTICS = PeerCapabilities(1L shl 6)
val BRIDGE = PeerCapabilities(1L shl 7)
/** Noise-encrypted private BitchatFilePacket using payload type 0x20. */
val PRIVATE_MEDIA = PeerCapabilities(1L shl 8)
val PRIVATE_MEDIA_RECEIPTS = PeerCapabilities(1L shl 9)
/** Reserved by iOS; decode it but do not advertise or act on it. */
val NON_DESTRUCTIVE_NOISE_REPLACEMENT = PeerCapabilities(1L shl 10)
/** Capabilities implemented by this Android build. */
val LOCAL_SUPPORTED = PRIVATE_MEDIA

View File

@ -1,6 +1,7 @@
package com.bitchat.android.protocol
import android.os.Parcelable
import kotlinx.parcelize.IgnoredOnParcel
import kotlinx.parcelize.Parcelize
import java.nio.ByteBuffer
import java.nio.ByteOrder
@ -34,6 +35,27 @@ object SpecialRecipients {
val BROADCAST = ByteArray(8) { 0xFF.toByte() } // All 0xFF = broadcast
}
/**
* Payload as it arrived on the wire, set by [BinaryProtocol.decode].
*
* Signatures cover a re-encoding of the packet, and verification re-encodes too.
* DEFLATE output is not canonical and clients use different encoders
* (java.util.zip.Deflater here, Apple's compression_encode_buffer on iOS), so
* re-compressing can change the preimage and reject a valid packet. Reusing these
* bytes also stops a relay, which re-encodes on TTL decrement, from substituting
* its own encoding.
*
* [forPayload] ties the bytes to the payload they decode to: replace the payload
* and the encoder compresses instead.
*
* Not a data class: generated equals/hashCode over ByteArray compares references.
*/
class WirePayload(
val bytes: ByteArray,
val compressed: Boolean,
val forPayload: ByteArray
)
/**
* Binary packet format - 100% backward compatible with iOS version
*
@ -61,7 +83,10 @@ data class BitchatPacket(
val payload: ByteArray,
var signature: ByteArray? = null, // Changed from val to var for packet signing
var ttl: UByte,
var route: List<ByteArray>? = null // Optional source route: ordered list of peerIDs (8 bytes each), not including sender and final recipient
var route: List<ByteArray>? = null, // Optional source route: ordered list of peerIDs (8 bytes each), not including sender and final recipient
// Set by BinaryProtocol.decode. Not part of packet identity, so it stays out of
// the parcel, equals and hashCode. Losing it only costs a re-compression.
@IgnoredOnParcel val wirePayload: WirePayload? = null
) : Parcelable {
constructor(
@ -100,7 +125,8 @@ data class BitchatPacket(
payload = payload,
signature = null, // Remove signature for signing
route = route,
ttl = com.bitchat.android.util.AppConstants.SYNC_TTL_HOPS // Use fixed TTL=0 for signing to ensure relay compatibility
ttl = com.bitchat.android.util.AppConstants.SYNC_TTL_HOPS, // Use fixed TTL=0 for signing to ensure relay compatibility
wirePayload = wirePayload // preimage must use the originator's bytes
)
return BinaryProtocol.encode(unsignedPacket)
}
@ -214,7 +240,17 @@ object BinaryProtocol {
var originalPayloadSize: Int? = null
var isCompressed = false
if (CompressionUtil.shouldCompress(payload)) {
// Re-encode of a decoded packet: reuse the originator's bytes (see WirePayload).
val wire = packet.wirePayload
if (wire != null && wire.forPayload.contentEquals(packet.payload)) {
if (wire.compressed) {
payload = wire.bytes
originalPayloadSize = packet.payload.size
isCompressed = true
}
// Uncompressed on the wire: keep it that way. shouldCompress agrees
// across clients, but the "only if smaller" check need not.
} else if (CompressionUtil.shouldCompress(payload)) {
CompressionUtil.compress(payload)?.let { compressedPayload ->
originalPayloadSize = payload.size
payload = compressedPayload
@ -450,6 +486,8 @@ object BinaryProtocol {
} else null
// Payload
// Kept so the packet can be re-encoded byte-identically (see WirePayload).
var receivedCompressed: ByteArray? = null
val payload = if (isCompressed) {
val lengthFieldBytes = if (version >= 2u.toUByte()) 4 else 2
if (payloadLength.toInt() < lengthFieldBytes) return null
@ -488,6 +526,8 @@ object BinaryProtocol {
val expandedPayload = CompressionUtil.withDecompressionResources(resourceBytes) {
val compressedPayload = ByteArray(compressedSize)
buffer.get(compressedPayload)
// Captured here so the allocation stays inside the reservation.
receivedCompressed = compressedPayload
decompress(compressedPayload, originalSize)
} ?: return null
if (expandedPayload.size != originalSize) {
@ -520,7 +560,12 @@ object BinaryProtocol {
payload = payload,
signature = signature,
ttl = ttl,
route = route
route = route,
wirePayload = WirePayload(
bytes = receivedCompressed ?: payload,
compressed = receivedCompressed != null,
forPayload = payload
)
)
} catch (e: Exception) {

View File

@ -1,5 +1,6 @@
package com.bitchat.android.ui
import com.bitchat.android.geohash.ChannelID
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import java.security.MessageDigest
@ -16,7 +17,8 @@ class ChannelManager(
private val state: ChatState,
private val messageManager: MessageManager,
private val dataManager: DataManager,
private val coroutineScope: CoroutineScope
private val coroutineScope: CoroutineScope,
private val onSwitchToMeshLocation: () -> Unit = {}
) {
// Channel encryption and security
@ -109,6 +111,8 @@ class ChannelManager(
fun switchToChannel(channel: String?) {
state.setCurrentChannel(channel)
state.setSelectedPrivateChatPeer(null)
state.setSelectedLocationChannel(ChannelID.Mesh)
onSwitchToMeshLocation()
// Clear unread count
channel?.let { ch ->

View File

@ -140,7 +140,17 @@ class ChatViewModel(
private val conversationListPreferences =
com.bitchat.android.services.ConversationListPreferences.getInstance(getApplication())
private val messageManager = MessageManager(state)
private val channelManager = ChannelManager(state, messageManager, dataManager, viewModelScope)
private val channelManager = ChannelManager(
state,
messageManager,
dataManager,
viewModelScope,
onSwitchToMeshLocation = {
com.bitchat.android.geohash.LocationChannelManager
.getInstance(getApplication())
.select(com.bitchat.android.geohash.ChannelID.Mesh)
}
)
// Create Noise session delegate for clean dependency injection
private val noiseSessionDelegate = object : NoiseSessionDelegate {

View File

@ -942,6 +942,61 @@ class BinaryProtocolTest {
assertTrue("Payload must match", payload.contentEquals(decoded.payload))
}
/**
* Re-encoding preserves a payload compressed by a different DEFLATE encoder
*
* Verification re-encodes the packet, so a re-encode must reproduce the
* originator's bytes. iOS compresses with Apple's compression_encode_buffer,
* which need not match java.util.zip.Deflater byte for byte.
*
* The payload is wrapped in a raw-DEFLATE "stored" block (BTYPE=00): valid, it
* inflates correctly, and no compressor would emit it, so it stands in for a
* foreign encoder without a second compression library. Compared unpadded so
* the result does not depend on how padding is generated.
*/
@Test
fun `re-encoding preserves a foreign encoder's compressed payload`() {
val payload = "the mesh is up near the north gate. relay running all evening. "
.repeat(4)
.toByteArray()
// Raw DEFLATE stored block: BFINAL=1 BTYPE=00, then LEN and NLEN little-endian.
val stored = ByteArray(5 + payload.size)
stored[0] = 0x01
stored[1] = (payload.size and 0xFF).toByte()
stored[2] = ((payload.size shr 8) and 0xFF).toByte()
stored[3] = (payload.size.inv() and 0xFF).toByte()
stored[4] = ((payload.size.inv() shr 8) and 0xFF).toByte()
payload.copyInto(stored, 5)
val buffer = ByteBuffer.allocate(1024).apply { order(ByteOrder.BIG_ENDIAN) }
buffer.put(2.toByte()) // version = 2
buffer.put(MessageType.MESSAGE.value.toByte()) // type
buffer.put(5.toByte()) // ttl
buffer.putLong(fixedTimestamp.toLong()) // timestamp (8 bytes)
buffer.put(BinaryProtocol.Flags.IS_COMPRESSED.toByte()) // flags
buffer.putInt(stored.size + 4) // payloadLength incl. originalSize
buffer.put(hexToBytes(senderHex)) // senderID (8 bytes)
buffer.putInt(payload.size) // originalSize
buffer.put(stored) // compressed payload
val raw = ByteArray(buffer.position())
buffer.rewind()
buffer.get(raw)
val decoded = BinaryProtocol.decode(raw)
assertNotNull("Foreign-encoded frame must decode", decoded)
assertArrayEquals("Payload must inflate to the original", payload, decoded!!.payload)
val reEncoded = BinaryProtocol.encode(decoded, padding = false)
assertNotNull("Re-encode must succeed", reEncoded)
assertArrayEquals(
"Re-encode must reproduce the originator's bytes, or a valid signature stops verifying",
raw,
reEncoded
)
}
/**
* v2 compression bomb is rejected
*

View File

@ -24,11 +24,12 @@ import org.robolectric.RobolectricTestRunner
import java.util.Date
@RunWith(RobolectricTestRunner::class)
class CommandProcessorTest() {
class CommandProcessorTest {
private val context: Context = ApplicationProvider.getApplicationContext()
@OptIn(ExperimentalCoroutinesApi::class)
private val testDispatcher = UnconfinedTestDispatcher()
private val testScope = TestScope(testDispatcher)
@OptIn(ExperimentalCoroutinesApi::class)
private val testDispatcher = UnconfinedTestDispatcher()
private val testScope = TestScope(testDispatcher)
private val chatState = ChatState(scope = testScope)
private lateinit var commandProcessor: CommandProcessor
@ -63,11 +64,11 @@ class CommandProcessorTest() {
val channel = "channel-1"
val result = commandProcessor.processCommand(
command = "/j $channel",
meshService = meshService,
myPeerID = "peer-id",
onSendMessage = { a, b, c -> { } },
viewModel = null
command = "/j $channel",
meshService = meshService,
myPeerID = "peer-id",
onSendMessage = { a, b, c -> { } },
viewModel = null
)
assertEquals(result, true)
@ -163,6 +164,24 @@ class CommandProcessorTest() {
assertEquals(0, chatState.getMessagesValue().size)
}
@Test
fun `join command leaves active geohash selection for mesh channel routing`() {
chatState.setSelectedLocationChannel(
ChannelID.Location(GeohashChannel(GeohashChannelLevel.REGION, "9q"))
)
commandProcessor.processCommand(
command = "/join backchannel",
meshService = meshService,
myPeerID = "peer-id",
onSendMessage = { _, _, _ -> },
viewModel = null
)
assertEquals("#backchannel", chatState.getCurrentChannelValue())
assertEquals(ChannelID.Mesh, chatState.selectedLocationChannel.value)
}
@Test
fun `clearSuggestions hides the command suggestion popup`() {
// Typing "/" opens the command popup.
@ -187,5 +206,6 @@ class CommandProcessorTest() {
commandProcessor.clearSuggestions()
assertFalse(chatState.getShowMentionSuggestionsValue())
assertTrue(chatState.getMentionSuggestionsValue().isEmpty())
}
}

View File

@ -12,9 +12,38 @@ class IdentityAnnouncementTest {
private val signingKey = ByteArray(32) { 0x22 }
@Test
fun `private media capability uses iOS little-endian bytes`() {
fun `capability assignments and encoding match iOS`() {
assertEquals(1L shl 0, PeerCapabilities.PREKEYS.rawValue)
assertEquals(1L shl 1, PeerCapabilities.WIFI_BULK.rawValue)
assertEquals(1L shl 2, PeerCapabilities.GATEWAY.rawValue)
assertEquals(1L shl 3, PeerCapabilities.GROUPS.rawValue)
assertEquals(1L shl 4, PeerCapabilities.BOARD.rawValue)
assertEquals(1L shl 5, PeerCapabilities.VOUCH.rawValue)
assertEquals(1L shl 6, PeerCapabilities.MESH_DIAGNOSTICS.rawValue)
assertEquals(1L shl 7, PeerCapabilities.BRIDGE.rawValue)
assertEquals(1L shl 8, PeerCapabilities.PRIVATE_MEDIA.rawValue)
assertEquals(1L shl 9, PeerCapabilities.PRIVATE_MEDIA_RECEIPTS.rawValue)
assertEquals(1L shl 10, PeerCapabilities.NON_DESTRUCTIVE_NOISE_REPLACEMENT.rawValue)
val assigned = PeerCapabilities((1L shl 11) - 1)
assertArrayEquals(byteArrayOf(0xFF.toByte(), 0x07), assigned.encoded())
assertEquals(assigned, PeerCapabilities.decode(assigned.encoded()))
}
@Test
fun `capability encoding is minimal and preserves low 64 unknown bits`() {
assertArrayEquals(byteArrayOf(0x00), PeerCapabilities.NONE.encoded())
assertArrayEquals(byteArrayOf(0x01), PeerCapabilities.PREKEYS.encoded())
assertArrayEquals(byteArrayOf(0x00, 0x01), PeerCapabilities.PRIVATE_MEDIA.encoded())
assertTrue(PeerCapabilities.decode(byteArrayOf(0x00, 0x01)).contains(PeerCapabilities.PRIVATE_MEDIA))
val future = PeerCapabilities.decode(
byteArrayOf(0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80.toByte(), 0x55)
)
assertEquals(Long.MIN_VALUE or 1L, future.rawValue)
assertArrayEquals(
byteArrayOf(0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80.toByte()),
future.encoded()
)
}
@Test
@ -71,5 +100,6 @@ class IdentityAnnouncementTest {
.capabilities!!
.contains(PeerCapabilities.PRIVATE_MEDIA)
)
assertEquals(PeerCapabilities.PRIVATE_MEDIA, PeerCapabilities.LOCAL_SUPPORTED)
}
}

View File

@ -29,9 +29,16 @@ Existing TLVs (unchanged):
Other optional extension:
- `0x05` CAPABILITIES: Minimal little-endian feature bitfield. Bit 8 advertises
authenticated Noise private media (`PRIVATE_MEDIA_V1`); its exact value is
`00 01`. An empty value is valid and means no advertised capabilities.
- `0x05` CAPABILITIES: Minimal little-endian feature bitfield. Assigned bits
match iOS: 0 prekeys, 1 Wi-Fi bulk, 2 gateway, 3 private groups, 4 board,
5 vouch, 6 mesh diagnostics, 7 bridge, 8 authenticated Noise private media,
9 private-media receipts, and 10 reserved non-destructive Noise replacement.
Bit 8's exact value is `00 01`. An empty value is valid and means no
advertised capabilities. For this announcement TLV, unknown bits and bytes
beyond the low 64 bits must be tolerated for forward compatibility. This
tolerance does not apply to the Noise-authenticated peer-state payload
`0x21`, whose capability field must be canonical and 1...8 bytes; see
`PRIVATE_MEDIA_V1.md`.
New TLV (optional):
@ -69,6 +76,12 @@ This matches the on‑wire 8‑byte `senderID`/`recipientID` encoding used in th
security-sensitive bit is trusted only after the signed announcement key is
bound to the matching remote static key from a live Noise handshake; see
`PRIVATE_MEDIA_V1.md`.
- Capability bits are independent discovery hints. Implementations advertise
only wire features they implement and must not infer support from platform,
app version, or unrelated transports with similar names.
- Private-media receipts and retry (bit 9) require the current Noise
generation's authenticated `0x21` peer state to prove both bits 8 and 9. An
announcement alone never authorizes that behavior.
- If a `0x04` TLV is present:
- Interpret the value as `N = length / 8` peer IDs (ignore trailing non‑aligned bytes).
- Each 8‑byte chunk is decoded back to a 16‑hex‑char peer ID string (lowercase).

View File

@ -11,11 +11,10 @@ The central rule is:
No keystore or password is stored in GitHub, GitHub Actions, the repository,
release notes, or workflow artifacts.
This runbook currently releases only the phone app, `com.bitchat.droid`.
The `:wear` module is tested and dependency-locked in CI but is not included in
the canonical release artifact set. Do not publish its development-signed
outputs. Wear distribution requires a separate signing identity, reproducible
artifact contract, Play listing, and maintainer runbook.
This runbook releases both the phone and Wear OS apps under the shared Play
application ID `com.bitchat.droid`. Wear releases use the independent version
code range beginning at `1000000001`; every phone and Wear artifact uploaded to
one Play listing must have a unique version code.
For the technical trust model and third-party verification instructions, see
[Reproducible builds](reproducible-builds.md).
@ -28,7 +27,7 @@ For the technical trust model and third-party verification instructions, see
| Create tag | Maintainer machine | Signed `vX.Y.Z` tag |
| Build twice | GitHub Actions | Two identical unsigned APK/AAB builds |
| Promote build | GitHub Actions | Attested `verified-unsigned-release` artifact |
| Sign | Maintainer machine | Three installable APKs and one Play upload AAB |
| Sign | Maintainer machine | Four installable APKs and two Play upload AABs |
| Test Play build | Play Console internal track | Play-generated APKs tested before public rollout |
| Prepare release | Maintainer machine and GitHub draft | Checksummed public release assets |
| Publish | GitHub Releases and Play Console | Public GitHub release and promoted Play rollout |
@ -42,8 +41,8 @@ These are four separate signing identities:
2. **GitHub APK signature**: lets Android install and update the APKs published
on GitHub. Use the existing GitHub release key. Its certificate SHA-256 must
match `BITCHAT_GITHUB_RELEASE_CERT_SHA256` in `gradle.properties`.
3. **Play upload signature**: the maintainer signs the AAB with the Play upload
key so Play will accept it.
3. **Play upload signature**: the maintainer signs both AABs with the Play
upload key so Play will accept them.
4. **Play app signature**: Google generates device APKs and signs them with the
separate Play app-signing key.
@ -119,9 +118,10 @@ a command line, in a shell profile, or in a release-notes file.
## 1. Prepare and approve the release commit
1. Update `versionCode` and `versionName` in `app/build.gradle.kts`.
`versionCode` must be greater than every build previously uploaded to Play.
`versionName` must match the release tag without the leading `v`.
1. Update `versionCode` and `versionName` in `app/build.gradle.kts`. For a Wear
release, also update them in `wear/build.gradle.kts` using the reserved Wear
version-code range. Every code must be unique across both form factors.
The phone `versionName` must match the release tag without the leading `v`.
2. Merge all intended release changes into `main`.
3. Confirm required CI checks are green.
4. Complete the
@ -147,6 +147,7 @@ Set shell variables for the rest of the release:
export REPOSITORY=permissionlesstech/bitchat-android
export TAG=vX.Y.Z
export VERSION_CODE=NN
export WEAR_VERSION_CODE=1000000001
export RELEASE_DIR="release-${TAG#v}"
```
@ -156,6 +157,7 @@ Confirm the source version:
grep -nE 'versionCode|versionName' app/build.gradle.kts
test "$(sed -n 's/.*versionName = "\([^"]*\)".*/\1/p' app/build.gradle.kts)" = "${TAG#v}"
test "$(sed -n 's/.*versionCode = \([0-9][0-9]*\).*/\1/p' app/build.gradle.kts)" = "$VERSION_CODE"
test "$(sed -n 's/.*versionCode = \([0-9_][0-9_]*\).*/\1/p' wear/build.gradle.kts | tr -d _)" = "$WEAR_VERSION_CODE"
```
Stop if either `test` command fails.
@ -251,6 +253,8 @@ The directory must initially contain exactly these canonical files:
- `bitchat-android-x86-unsigned.apk`
- `bitchat-android-x86_64-unsigned.apk`
- `bitchat-android-release-unsigned.aab`
- `bitchat-android-wear-unsigned.apk`
- `bitchat-android-wear-release-unsigned.aab`
Verify the checksum manifest:
@ -328,6 +332,7 @@ It creates:
- `bitchat-android-arm64.apk`
- `bitchat-android-universal.apk`
- `bitchat-android-wear.apk`
- `bitchat-android-x86_64.apk`
The unsigned armv7 and x86 APKs remain available for reproducibility, but are
@ -337,7 +342,7 @@ If the helper stops after creating any signed file, do not continue or overwrite
files manually. Start again in a new directory downloaded from the same
successful workflow run.
## 6. Sign the Google Play AAB locally
## 6. Sign the Google Play AABs locally
Set the pinned JDK and Play upload-key locations, then load the passwords:
@ -361,18 +366,20 @@ Run:
tools/reproducible-builds/sign-play-bundle.sh "$RELEASE_DIR"
```
The helper creates `bitchat-android-play-upload.aab`, verifies its JAR
signature, proves that every non-signature payload entry matches the canonical
The helper creates `bitchat-android-play-upload.aab` and
`bitchat-android-wear-play-upload.aab`, verifies their JAR signatures, proves
that every non-signature payload entry matches the corresponding canonical
unsigned AAB, and updates `SHA256SUMS`.
This is the only file to upload to Play Console:
These are the only files to upload to Play Console:
```text
release-X.Y.Z/bitchat-android-play-upload.aab
release-X.Y.Z/bitchat-android-wear-play-upload.aab
```
Do not upload an APK or `bitchat-android-release-unsigned.aab` to Play. Do not
open Android Studio and rebuild the bundle.
Do not upload an APK or either `*-release-unsigned.aab` to Play. Do not open
Android Studio and rebuild the bundles.
Remove passwords from the environment after both signing steps:
@ -394,16 +401,20 @@ tools/reproducible-builds/prepare-github-release.sh "$RELEASE_DIR"
The helper verifies all checksums and renames the public build information and
checksum manifests. It refuses missing or pre-existing release files.
The final GitHub Release must contain all 13 files below:
The final GitHub Release must contain all 17 files below:
| Asset | Signed? | Why it is published |
|---|---:|---|
| `bitchat-android-arm64.apk` | APK release key | Primary direct-install APK |
| `bitchat-android-universal.apk` | APK release key | Fallback direct-install APK |
| `bitchat-android-x86_64.apk` | APK release key | x86_64 install APK |
| Five `bitchat-android-*-unsigned.apk` files | No | Reproducibility inputs for every ABI target |
| `bitchat-android-wear.apk` | APK release key | Wear OS direct-install APK |
| Five phone `bitchat-android-*-unsigned.apk` files | No | Reproducibility inputs for every phone ABI target |
| `bitchat-android-release-unsigned.aab` | No | Canonical reproducible Play input |
| `bitchat-android-play-upload.aab` | Play upload key | Exact bundle uploaded to Play |
| `bitchat-android-wear-unsigned.apk` | No | Canonical reproducible Wear install input |
| `bitchat-android-wear-release-unsigned.aab` | No | Canonical reproducible Wear Play input |
| `bitchat-android-wear-play-upload.aab` | Play upload key | Exact bundle uploaded to the Wear OS track |
| `BITCHAT_BUILDINFO.json` | GitHub attestation | Source commit and pinned toolchain |
| `BITCHAT_SHA256SUMS.unsigned` | GitHub attestation | Original canonical CI manifest |
| `BITCHAT_SHA256SUMS` | No detached signature | SHA-256 for every published asset |
@ -432,12 +443,13 @@ Create a local release-notes file. At minimum it must contain:
## Bitchat Android vX.Y.Z
- Version code: NN
- Wear version: 0.1.0 (code 1000000001)
- Source tag: vX.Y.Z
- GitHub APK signing certificate SHA-256: FINGERPRINT
- Play upload certificate SHA-256: FINGERPRINT
- Play app-signing certificate SHA-256: FINGERPRINT
Checksums, canonical unsigned APK/AAB inputs, the exact Play upload AAB, and
Checksums, canonical unsigned APK/AAB inputs, the exact Play upload AABs, and
build information are attached. See `docs/reproducible-builds.md` for public
verification instructions.
@ -474,7 +486,7 @@ gh release view "$TAG" --repo "$REPOSITORY" --web
Keep it as a draft until the Play internal-track checks below pass.
## 9. Upload and test the AAB in Google Play
## 9. Upload and test the AABs in Google Play
1. Open Play Console and select `com.bitchat.droid`.
2. Open **Test and release > Testing > Internal testing**.
@ -495,16 +507,23 @@ Keep it as a draft until the Play internal-track checks below pass.
10. In **Setup > App integrity**, confirm the Play app-signing certificate
SHA-256 is the value recorded in the GitHub release notes.
Promote this same tested Play release from internal testing to production.
Do not rebuild or upload a second AAB for production. Use a staged production
rollout when appropriate.
For the initial Wear release, open **Test and release > Advanced settings >
Form factors**, add Wear OS, upload the required Wear screenshot, and use the
dedicated **Wear OS only** test track. Upload exactly
`bitchat-android-wear-play-upload.aab`, confirm version code `1000000001`, and
complete the Wear OS opt-in and review flow. Promote the already-tested Wear
artifact on its dedicated track; do not add it to the mobile track.
Promote these same tested Play releases from their test tracks to their
respective production tracks. Do not rebuild or upload replacement AABs for
production. Use staged production rollouts when appropriate.
Google signs the device APKs with the Play app-signing key, so Play-delivered
APKs will not be byte-identical to the GitHub APKs. That is expected.
## 10. Publish GitHub and promote Play
After the internal Play build passes and the GitHub draft has all 13 assets:
After both Play test builds pass and the GitHub draft has all 17 assets:
```bash
gh release edit "$TAG" \
@ -539,7 +558,7 @@ tools/reproducible-builds/verify-github-release.sh "$TAG"
Also verify:
- the GitHub release is marked **Latest**;
- the three signed APKs install and show the expected version;
- the four signed APKs install and show the expected version;
- the Play listing shows the intended production version and rollout state;
- a Play-installed build is signed by the app-signing certificate recorded in
the release notes; and
@ -572,10 +591,10 @@ Also verify:
- [ ] `verified-unsigned-release` downloaded by run ID
- [ ] Checksums, source commit, and attestations verified
- [ ] GitHub APKs signed locally with the pinned certificate
- [ ] Play AAB signed locally with the registered upload key
- [ ] `BITCHAT_SHA256SUMS` verifies all 13 release assets
- [ ] Phone and Wear Play AABs signed locally with the registered upload key
- [ ] `BITCHAT_SHA256SUMS` verifies all 17 release assets
- [ ] GitHub draft created with certificate fingerprints and all assets
- [ ] Exact signed AAB uploaded to and tested on Play internal track
- [ ] Exact signed phone and Wear AABs uploaded to and tested on their tracks
- [ ] GitHub Release published
- [ ] Same tested Play release promoted to production
- [ ] Public GitHub and Play verification completed
@ -586,3 +605,5 @@ Also verify:
- [GitHub CLI: create a release](https://cli.github.com/manual/gh_release_create)
- [Google Play App Signing](https://support.google.com/googleplay/android-developer/answer/9842756)
- [Play Console App bundle explorer](https://support.google.com/googleplay/android-developer/answer/9859152)
- [Package and distribute Wear OS apps](https://developer.android.com/training/wearables/packaging)
- [Manage form-factor releases on dedicated tracks](https://support.google.com/googleplay/android-developer/answer/13295490)

View File

@ -1,16 +1,14 @@
# Reproducible builds
Bitchat's canonical phone-app release build produces byte-for-byte reproducible
unsigned APKs and an unsigned Android App Bundle (AAB). CI builds the release
Bitchat's canonical release build produces byte-for-byte reproducible unsigned
phone and Wear OS APKs and Android App Bundles (AABs). CI builds the release
twice in independent jobs and exposes a verified release artifact only when
every canonical byte matches. The `:wear` module is tested and
dependency-locked but is outside this phone artifact contract until a separate
Wear release and signing process is defined.
every canonical byte matches.
Signing remains local: no keystore or signing password is stored in or exposed
to GitHub Actions. Anyone can reproduce the unsigned artifacts; maintainers
download the verified CI output, sign the selected GitHub APKs and Play upload
AAB locally, then manually publish those exact files.
AABs locally, then manually publish those exact files.
Maintainers should use the complete
[Android maintainer release guide](maintainer-release-guide.md) for the
@ -33,10 +31,15 @@ GitHub/Google Play publication checklist.
The build uses a clean source tree, an isolated Gradle user home, UTC, a stable
locale, `SOURCE_DATE_EPOCH` from the Git commit, no Gradle build or configuration
cache, fresh tasks, and a non-incremental in-process Kotlin compiler. Native
builds remap source paths and release validation rejects host paths in packaged
libraries. The container overlays a canonical `local.properties`, so an ignored
Android Studio file cannot redirect Gradle to a host-specific SDK.
cache, fresh tasks, a non-incremental in-process Kotlin compiler, and R8's
deterministic-debugging mode. The R8 mode uses one compiler thread and disables
randomized input shuffling. The regular R8 ProGuard map remains embedded in each
AAB. Kotlin 2.4.10's optional Compose group-key mapping augmentation is disabled
because its duplicate-key selection depends on unspecified class-file iteration
order across clean builds. Native builds remap source paths and release
validation rejects host paths in packaged libraries. The container overlays a
canonical `local.properties`, so an ignored Android Studio file cannot redirect
Gradle to a host-specific SDK.
AGP's embedded VCS record is disabled because its Git discovery depends on the
host checkout layout. The canonical `BUILDINFO.json` and GitHub provenance
@ -56,8 +59,10 @@ The authoritative pins are:
## Reproduce a release locally
Requirements are Git, Docker with Linux/amd64 support, and enough free space for
the Android and Gradle images and dependencies.
Requirements are Git, Docker with Linux/amd64 support, more than 8 GiB of memory
available to the Docker VM (16 GiB recommended), and enough free space for the
Android and Gradle images and dependencies. R8's single-threaded deterministic
mode can exceed an 8 GiB Docker memory limit while optimizing the phone app.
```bash
git clone https://github.com/permissionlesstech/bitchat-android.git
@ -71,6 +76,8 @@ The output contains:
- unsigned APKs for arm64, armv7, x86, x86_64, and universal installs
- `bitchat-android-release-unsigned.aab`
- `bitchat-android-wear-unsigned.apk`
- `bitchat-android-wear-release-unsigned.aab`
- `BUILDINFO.json`
- `SHA256SUMS.unsigned`
@ -104,13 +111,13 @@ tools/reproducible-builds/verify-github-release.sh vX.Y.Z
That command:
1. downloads all release APKs, the AAB, build information, and checksum files;
1. downloads all release APKs, AABs, build information, and checksum files;
2. verifies the canonical unsigned build's GitHub artifact-attestation subjects
against this repository;
3. verifies `BITCHAT_SHA256SUMS`;
4. checks that the local source commit is the release commit;
5. rebuilds in the pinned container; and
6. byte-compares every unsigned APK, the unsigned AAB, build information, and
6. byte-compares every unsigned APK, both unsigned AABs, build information, and
the unsigned checksum manifest.
To verify the published checksums and attestations without rebuilding:
@ -154,8 +161,8 @@ gh attestation verify bitchat-android-universal-unsigned.apk \
Google Play App Signing changes the verification boundary:
- maintainers upload a signed AAB using the upload key;
- Google Play generates optimized, device-specific APK splits from that AAB;
- maintainers upload signed phone and Wear AABs using the upload key;
- Google Play generates optimized, device-specific APK splits from those AABs;
- Google signs the delivered APKs with the app-signing key.
Consequently, a Play-delivered APK is not expected to be byte-identical to the
@ -163,8 +170,8 @@ GitHub universal APK or to a locally built APK. Use this procedure instead:
1. In Play Console, open **Test and release > App bundle explorer**, select the
release/version code, and download the original app bundle if that option is
available to your account. Compare its unsigned payload with the reproduced
`bitchat-android-release-unsigned.aab`:
available to your account. Compare its unsigned payload with the matching
reproduced phone or Wear AAB:
```bash
tools/reproducible-builds/compare-archive-payloads.sh \
@ -204,9 +211,10 @@ maintainers to retain the uploaded AAB, publish its digest and provenance, and
record the Play version code and app-signing certificate fingerprint alongside
the release.
The GitHub workflow builds and attests the canonical unsigned AAB. A maintainer
locally creates `bitchat-android-play-upload.aab` from that exact file and
uploads it manually to Google Play.
The GitHub workflow builds and attests both canonical unsigned AABs. A
maintainer locally creates `bitchat-android-play-upload.aab` and
`bitchat-android-wear-play-upload.aab` from those exact files and uploads them
manually to Google Play.
## Maintainer release process

View File

@ -2142,6 +2142,9 @@
<artifact name="aapt2-9.3.1-15703166-osx.jar">
<sha256 value="1e35bc2ce18c3aae840be2a29659ce50d6043e907a44d98ee1cf375d044fa29c" origin="Generated by Gradle"/>
</artifact>
<artifact name="aapt2-9.3.1-15703166-windows.jar">
<sha256 value="b1006ecec7e5936257e95e97f3eba7ef439d3e44178967cc048f86c9119fb231" origin="Generated by Gradle"/>
</artifact>
<artifact name="aapt2-9.3.1-15703166.pom">
<sha256 value="edb82dcbe738ca78b31612cb307bf99e5f02f25c8125048f933e792fd7778beb" origin="Generated by Gradle"/>
</artifact>
@ -4906,6 +4909,9 @@
</artifact>
</component>
<component group="org.junit" name="junit-bom" version="5.9.2">
<artifact name="junit-bom-5.9.2.module">
<sha256 value="ab137ba5a8e32c9b066bf9126a1c76dd5614b724ba5c0b02549772b5e9f4cf1f" origin="Generated by Gradle"/>
</artifact>
<artifact name="junit-bom-5.9.2.pom">
<sha256 value="2ed07d65845131f5336a86476c9a4056b59d0b58b9815ab3679bb0f36f35f705" origin="Generated by Gradle"/>
</artifact>

View File

@ -42,6 +42,9 @@ if ! [[ "$SOURCE_DATE_EPOCH" =~ ^[0-9]+$ ]]; then
fi
gradle_args=(
# R8 otherwise randomizes input traversal and uses multiple compiler threads.
# The optimized DEX can still match while its embedded ProGuard map differs.
-Dcom.android.tools.r8.deterministicdebugging=1
-Pkotlin.compiler.execution.strategy=in-process
-Pkotlin.incremental=false
--no-build-cache
@ -56,11 +59,20 @@ cd "$PROJECT_ROOT"
aab_source="$PROJECT_ROOT/app/build/outputs/bundle/release/app-release.aab"
if [ ! -f "$aab_source" ]; then
echo "error: expected release AAB not found" >&2
echo "error: expected phone release AAB not found" >&2
exit 1
fi
cp "$aab_source" "$OUTPUT_DIR/bitchat-android-release-unsigned.aab"
./gradlew "${gradle_args[@]}" :wear:clean :wear:bundleRelease
wear_aab_source="$PROJECT_ROOT/wear/build/outputs/bundle/release/wear-release.aab"
if [ ! -f "$wear_aab_source" ]; then
echo "error: expected Wear release AAB not found" >&2
exit 1
fi
cp "$wear_aab_source" "$OUTPUT_DIR/bitchat-android-wear-release-unsigned.aab"
# AGP cannot build split APKs and an app bundle from the same intermediates.
./gradlew "${gradle_args[@]}" :app:clean :app:assembleRelease
@ -81,6 +93,15 @@ for source_name in "${!apk_names[@]}"; do
cp "$source_path" "$OUTPUT_DIR/${apk_names[$source_name]}"
done
./gradlew "${gradle_args[@]}" :wear:clean :wear:assembleRelease
wear_apk_source="$PROJECT_ROOT/wear/build/outputs/apk/release/wear-release-unsigned.apk"
if [ ! -f "$wear_apk_source" ]; then
echo "error: expected Wear release APK not found" >&2
exit 1
fi
cp "$wear_apk_source" "$OUTPUT_DIR/bitchat-android-wear-unsigned.apk"
source_commit="${BITCHAT_SOURCE_COMMIT:-$(git -C "$PROJECT_ROOT" rev-parse HEAD)}"
if ! [[ "$source_commit" =~ ^([0-9a-f]{40}|[0-9a-f]{64})$ ]]; then
echo "error: source commit must be a full Git object ID" >&2
@ -109,6 +130,7 @@ EOF
sha256sum BUILDINFO.json
sha256sum bitchat-android-*-unsigned.apk
sha256sum bitchat-android-release-unsigned.aab
sha256sum bitchat-android-wear-release-unsigned.aab
} | sort -k2 > SHA256SUMS.unsigned
)

View File

@ -12,6 +12,8 @@ artifacts=(
bitchat-android-armv7-unsigned.apk
bitchat-android-release-unsigned.aab
bitchat-android-universal-unsigned.apk
bitchat-android-wear-release-unsigned.aab
bitchat-android-wear-unsigned.apk
bitchat-android-x86-unsigned.apk
bitchat-android-x86_64-unsigned.apk
)

View File

@ -30,6 +30,10 @@ required=(
bitchat-android-release-unsigned.aab
bitchat-android-universal-unsigned.apk
bitchat-android-universal.apk
bitchat-android-wear-play-upload.aab
bitchat-android-wear-release-unsigned.aab
bitchat-android-wear-unsigned.apk
bitchat-android-wear.apk
bitchat-android-x86-unsigned.apk
bitchat-android-x86_64-unsigned.apk
bitchat-android-x86_64.apk
@ -53,6 +57,8 @@ for artifact_path in "$RELEASE_DIR"/*; do
bitchat-android-armv7-unsigned.apk|\
bitchat-android-play-upload.aab|bitchat-android-release-unsigned.aab|\
bitchat-android-universal-unsigned.apk|bitchat-android-universal.apk|\
bitchat-android-wear-play-upload.aab|bitchat-android-wear-release-unsigned.aab|\
bitchat-android-wear-unsigned.apk|bitchat-android-wear.apk|\
bitchat-android-x86-unsigned.apk|\
bitchat-android-x86_64-unsigned.apk|bitchat-android-x86_64.apk)
;;

View File

@ -48,13 +48,6 @@ fi
"${SHA256[@]}" -c SHA256SUMS.unsigned
)
UNSIGNED_AAB="$RELEASE_DIR/bitchat-android-release-unsigned.aab"
SIGNED_AAB="$RELEASE_DIR/bitchat-android-play-upload.aab"
if [ -e "$SIGNED_AAB" ]; then
echo "error: signed Play upload AAB already exists" >&2
exit 1
fi
TEMP_DIR="$(mktemp -d)"
trap 'rm -rf "$TEMP_DIR"' EXIT
STOREPASS_FILE="$TEMP_DIR/storepass"
@ -63,17 +56,40 @@ printf '%s\n' "$BITCHAT_PLAY_KEYSTORE_PASSWORD" > "$STOREPASS_FILE"
printf '%s\n' "$BITCHAT_PLAY_KEY_PASSWORD" > "$KEYPASS_FILE"
chmod 600 "$STOREPASS_FILE" "$KEYPASS_FILE"
"$JARSIGNER" \
-keystore "$KEYSTORE" \
-storepass:file "$STOREPASS_FILE" \
-keypass:file "$KEYPASS_FILE" \
-digestalg SHA-256 \
-signedjar "$SIGNED_AAB" \
"$UNSIGNED_AAB" \
"$BITCHAT_PLAY_UPLOAD_KEY_ALIAS"
unsigned_names=(
"bitchat-android-release-unsigned.aab"
"bitchat-android-wear-release-unsigned.aab"
)
signed_names=(
"bitchat-android-play-upload.aab"
"bitchat-android-wear-play-upload.aab"
)
"$JARSIGNER" -verify "$SIGNED_AAB" >/dev/null
"$SCRIPT_DIR/compare-archive-payloads.sh" "$UNSIGNED_AAB" "$SIGNED_AAB"
for ((index = 0; index < ${#unsigned_names[@]}; index++)); do
unsigned_aab="$RELEASE_DIR/${unsigned_names[$index]}"
signed_aab="$RELEASE_DIR/${signed_names[$index]}"
if [ ! -f "$unsigned_aab" ]; then
echo "error: unsigned Play AAB not found: ${unsigned_names[$index]}" >&2
exit 1
fi
if [ -e "$signed_aab" ]; then
echo "error: signed Play upload AAB already exists: ${signed_names[$index]}" >&2
exit 1
fi
"$JARSIGNER" \
-keystore "$KEYSTORE" \
-storepass:file "$STOREPASS_FILE" \
-keypass:file "$KEYPASS_FILE" \
-digestalg SHA-256 \
-signedjar "$signed_aab" \
"$unsigned_aab" \
"$BITCHAT_PLAY_UPLOAD_KEY_ALIAS"
"$JARSIGNER" -verify "$signed_aab" >/dev/null
"$SCRIPT_DIR/compare-archive-payloads.sh" "$unsigned_aab" "$signed_aab"
done
(
cd "$RELEASE_DIR"
@ -86,4 +102,4 @@ chmod 600 "$STOREPASS_FILE" "$KEYPASS_FILE"
} | sort -k2 > SHA256SUMS
)
echo "Verified unsigned AAB was signed locally with the Play upload key and checksummed."
echo "Verified unsigned phone and Wear AABs were signed locally with the Play upload key and checksummed."

View File

@ -68,11 +68,13 @@ export BITCHAT_GITHUB_KEY_PASSWORD
unsigned_names=(
"bitchat-android-arm64-unsigned.apk"
"bitchat-android-universal-unsigned.apk"
"bitchat-android-wear-unsigned.apk"
"bitchat-android-x86_64-unsigned.apk"
)
signed_names=(
"bitchat-android-arm64.apk"
"bitchat-android-universal.apk"
"bitchat-android-wear.apk"
"bitchat-android-x86_64.apk"
)

View File

@ -50,6 +50,8 @@ attested_artifacts=(
bitchat-android-armv7-unsigned.apk
bitchat-android-release-unsigned.aab
bitchat-android-universal-unsigned.apk
bitchat-android-wear-release-unsigned.aab
bitchat-android-wear-unsigned.apk
bitchat-android-x86-unsigned.apk
bitchat-android-x86_64-unsigned.apk
)

View File

@ -9,21 +9,29 @@ plugins {
android {
namespace = "com.bitchat.watch"
compileSdk = libs.versions.compileSdk.get().toInt()
buildToolsVersion = libs.versions.buildTools.get()
defaultConfig {
applicationId = "com.bitchat.watch"
applicationId = "com.bitchat.droid"
minSdk = 33 // Wear OS 4 (Pixel Watch 1+): the S+ Bluetooth permissions the app
// declares only exist from API 31, and API 30 would additionally require location
// for BLE scan results, which the app deliberately refuses.
targetSdk = libs.versions.targetSdk.get().toInt()
versionCode = 1
versionName = "0.1.0"
// Wear releases use a separate high range because Play requires every artifact in
// one application ID to have a unique version code across all form factors.
versionCode = 1_000_000_002
versionName = "0.1.1"
vectorDrawables {
useSupportLibrary = true
}
}
dependenciesInfo {
includeInApk = false
includeInBundle = false
}
buildTypes {
release {
isMinifyEnabled = true
@ -32,9 +40,9 @@ android {
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
// Sign with the debug key so release builds can be installed over the
// debug app during development (same signature = seamless upgrade).
signingConfig = signingConfigs.getByName("debug")
vcsInfo {
include = false
}
}
}
@ -57,6 +65,13 @@ android {
}
}
composeCompiler {
// Kotlin 2.4.10's optional Compose group-key mapping depends on unspecified
// class-file iteration order. Keep the normal R8 mapping, but omit that
// augmentation until its producer is deterministic across clean builds.
includeComposeMappingFile.set(false)
}
// Shared bitchat protocol stack: compiled from :app sources in place (never moved/copied by hand).
// AGP's source directory sets no longer support include/exclude filters, so a Sync task
// materializes a filtered mirror into build/sharedSrc and that directory is added as a source
@ -158,6 +173,7 @@ tasks.matching { it.name.contains("UnitTest", ignoreCase = true) }.configureEach
}
kotlin {
jvmToolchain(21)
compilerOptions {
jvmTarget.set(JvmTarget.JVM_11)
}