+ Amethyst
+ ++ Nostr + Client for + Android
+ +Join the + social network you + control.
+ + ++ Download and + Install
+ ++ Supported + Features
+ +-
+
- + + Events / Relay + Subscriptions + (NIP-01) + +
- + + Follow List (NIP-02) + +
- + + OpenTimestamps + Attestations + (NIP-03) + +
- + + Private Messages + (NIP-04) + +
- + + DNS Address (NIP-05) + +
- + + Mnemonic seed phrase + (NIP-06) + +
- + + WebBrowser Signer + (NIP-07, Not + applicable) + +
- + + Old-style mentions + (NIP-08) + +
- + + Event Deletion + (NIP-09) + +
- + + Replies, mentions, + Threads, and + Notifications + (NIP-10) + +
- + + Relay Information + Document (NIP-11) + +
- + + Generic Tag Queries + (NIP-12) + +
- + + Proof of Work + Display (NIP-13) + +
- + + Proof of Work + Calculations + (NIP-13) + +
- + + Events with a + Subject (NIP-14) + +
- + + Marketplace (NIP-15) + +
- + + Event Treatment + (NIP-16) + +
- + + Image/Video/Url/LnInvoice + Previews + +
- + + Reposts, Quotes, + Generic Reposts + (NIP-18) + +
- + + Bech Encoding + support (NIP-19) + +
- + + Command Results + (NIP-20) + +
- + + URI Support (NIP-21) + +
- + + Long-form Content + (NIP-23) + +
- + + User Profile Fields + / Relay list + (NIP-24) + +
- + + Reactions (NIP-25) + +
- + + Delegated Event + Signing (NIP-26, + Will not implement) + +
- + + Text Note References + (NIP-27) + +
- + + Public Chats + (NIP-28) + +
- + + Custom Emoji + (NIP-30) + +
- + + Event kind summaries + (NIP-31) + +
- + + Labeling (NIP-32) + +
- + + Parameterized + Replaceable Events + (NIP-33) + +
- + + Git Stuff + (NIP-34/Draft) + +
- + + Sensitive Content + (NIP-36) + +
- + + Note Edits + (NIP-37/Draft) + +
- + + User Status Event + (NIP-38) + +
- + + External Identities + (NIP-39) + +
- + + Expiration Support + (NIP-40) + +
- + + Relay Authentication + (NIP-42) + +
- + + Event Counts + (NIP-45, Will not + implement) + +
- + + Nostr Connect + (NIP-46) + +
- + + Wallet Connect API + (NIP-47) + +
- + + Proxy Tags (NIP-48, + Not applicable) + +
- + + Private key + encryption for + import/export + (NIP-49) + +
- + + Online Relay Search + (NIP-50) + +
- + + Lists (NIP-51) + +
- + + Calendar Events + (NIP-52) + +
- + + Live Activities + & Live Chats + (NIP-53) + +
- + + Inline Metadata + (NIP-55 - Draft) + +
- + + Reporting (NIP-56) + +
- + + Lightning Tips + +
- + + Zaps (NIP-57) + +
- + + Private Zaps + +
- + + Zap Splits (NIP-57) + +
- + + Gift Wraps & + Seals (NIP-59) + +
- + + Zapraiser (NIP-TBD) + +
- + + Badges (NIP-58) + +
- + + Relay List Metadata + (NIP-65) + +
- + + Polls (NIP-69) + +
- + + Moderated + Communities (NIP-72) + +
- + + Zap Goals (NIP-75) + +
- + + Arbitrary Custom App + Data (NIP-78) + +
- + + Highlights (NIP-84) + +
- + + Recommended + Application Handlers + (NIP-89) + +
- + + Data Vending Machine + (NIP-90) + +
- + + Inline Metadata + (NIP-92) + +
- + + Verifiable file URLs + (NIP-94) + +
- + + Binary Blobs + (NIP-95) + +
- + + HTTP File Storage + Integration (NIP-96 + Draft) + +
- + + HTTP Auth (NIP-98) + +
- + + Classifieds (NIP-99) + +
- + + Private Messages and + Small Groups + (NIP-24/Draft) + +
- + + Versioned Encrypted + Payloads + (NIP-44/Draft) + +
- + + Audio Tracks + (zapstr.live) + (kind:31337) + +
- + + Push Notifications + (Google and Unified + Push) + +
- + + In-Device Automatic + Translations + +
- + + Hashtag Following + and Custom Hashtags + +
- + + Login with QR + +
- + + Bounty support + (nostrbounties.com) + +
- + + De-googled F-Droid + flavor + +
- + + Multiple Accounts + +
- + + Markdown Support + +
- + + FHIR Payloads + (kind:82) + +
- + + Decentralized Wiki + (kind:30818) + +
- + + Embed events + +
- + + Image/Video Capture + in the app + +
- + + Local Database + +
- + + Workspaces + +
- + + Infinity Scroll + +
+ Privacy + and Information + Permanence
+ +Relays know + your IP address, your + name, your location + (guessed from IP), your + pub key, all your + contacts, and other + relays, and can read + every action you do + (post, like, boost, + quote, report, etc) + except for Private Zaps + and Private DMs. While + the content of direct + messages (DMs) is only + visible to you and your + DM counterparty, + everyone can see when + you and your + counterparty DM each + other.
+If you want to + improve your privacy, + consider utilizing a + service that masks your + IP address (e.g. a VPN + or Tor) from trackers + online.
+The relay also + learns which public keys + you are requesting, + meaning your public key + will be tied to your IP + address.
+Information + shared on Nostr can be + re-broadcasted to other + servers and should be + assumed permanent for + privacy purposes. There + is no way to guarantee + the deletion of any + content once posted.
++ Development + Overview
+ +This + repository is split + between Amethyst and + Quartz:
+-
+
- Amethyst is a native + Android app made + with Kotlin and + Jetpack Compose. + +
- Quartz is our own + Nostr-commons + library to host + classes that are of + interest to other + Nostr Clients. + +
The app + architecture consists of + the UI, which uses the + usual + State/ViewModel/Composition, + the service layer that + connects with Nostr + relays, + and the model/repository + layer, which keeps all + Nostr objects in memory, + in a full OO graph.
+The repository + layer stores Nostr + Events as Notes and + Users separately. Those + classes use LiveData and + Flow objects to + allow the UI and other + parts of the app to + subscribe to each + Note/User and receive + updates when they + happen. + They are also + responsible for updating + viewModels when needed. + As the user scrolls + through Events, the + Datasource classes + are updated to receive + more information about + those particular + Events.
+Most of the UI + is reactive to changes + in the repository + classes. The service + layer assembles Nostr + filters for each need of + the app, + receives the data from + the Relay, and sends it + to the repository. + Connection with relays + is never closed during + the use of the app. + The UI receives a + notification that + objects have been + updated. Instances of + User and Notes are + mutable directly. + There will never be two + Notes with the same ID + or two User instances + with the same + pubkey.
+Lastly, the + user's account + information (private + key/pub key) is stored + in the Android KeyStore + for security.
++ Setup
+ +Make sure to + have the following + pre-requisites + installed:
+-
+
- Java 17+ +
- Android Studio +
- Android 8.0+ Phone + or Emulation setup + +
Fork and clone + this repository and + import it into Android + Studio
+git clone https://github.com/vitorpamplona/amethyst.git
+ Use an Android + Studio build action to + install and run the app + on your device or a + simulator.
++ Building
+ +Build the + app:
+./gradlew assembleDebug
+ + Testing
+ +./gradlew test
+./gradlew connectedAndroidTest
+ + Linting
+ +./gradlew spotlessCheck
+./gradlew spotlessApply
+ + Installing on + device
+ +For the + F-Droid build:
+./gradlew installFdroidDebug
+ For the Play + build:
+./gradlew installPlayDebug
+ + Deploying
+ +-
+
- Generate a new + signing key + +
keytool -genkey -v -keystore <my-release-key.keystore> -alias <alias_name> -keyalg RSA -keysize 2048 -validity 10000
+openssl base64 < <my-release-key.keystore> | tr -d '\n' | tee some_signing_key.jks.base64.txt
+
+ -
+
- Create four Secret
+ Key variables on
+ your GitHub
+ repository and fill
+ in the signing key
+ information
+
-
+
KEY_ALIAS
+ <-<alias_name>
+
+ KEY_PASSWORD
+ <-<your + password>
+
+ KEY_STORE_PASSWORD
+ <-<your + key + store + password>
+
+ SIGNING_KEY
+ <- the + data from +<my-release-key.keystore>
+
+
+ - Change the
versionCode
+ andversionName
+ onapp/build.gradle
+
+ - Commit and push. + +
- Tag the commit with
+
v{x.x.x}
+
+ - Let the Create
+ Release GitHub
+ Action build a
+ new
aab
+ file. +
+ - Add your CHANGE LOG + to the description + of the new release + +
- Download the
aab
+ file and upload it + to the PlayStore. +
+
Using + the + Quartz library
+ +Setup JitPack.io + to your build file
+Add maven
+ { url
+ 'https://jitpack.io'
+ }
to
+ settings.gradle at the
+ end of repositories:
dependencyResolutionManagement {
+ repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
+ repositories {
+ mavenCentral()
+ maven { url 'https://jitpack.io' }
+ }
+}
+ Add the + dependency
+implementation('com.github.vitorpamplona.amethyst:quartz:v0.85.1')
+ + Contributing
+ +Issues can be + logged on: https://gitworkshop.dev/repo/amethyst +
+GitHub + issues and pull + requests here are + also welcome. + Translations can be + provided via Crowdin +
+You can also + send patches through + Nostr using GitStr + to + this + nostr address +
+By + contributing to this + repository, you agree to + license your work under + the MIT license. Any + work contributed where + you are not the original + author must contain its + license header with the + original author(s) and + source.
++ Screenshots
+ +FollowFeeds | +ChatsGroup | +LiveStreams | +Notifications + | +
---|---|---|---|
+ ![]() |
+
+ ![]() |
+
+ ![]() |
+
+ ![]() |
+
+ Contributors
+ +MIT + License
+ +Copyright (c) 2023 Vitor Pamplona + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. ++