Currently NostrDB does not seem to handle encryption/decryption of DMs.
Since NostrDB now controls the block parsing process and fetches note
contents directly from the database, we have to add a specific condition
that injects decrypted content directly to the ndb content parser.
This is done in conjunction with some minor refactoring to `NdbBlocks`
and associated structs, as in C those are separated between the content
string and the offsets for each block, but in Swift this is more
ergonomically represented as a standalone/self-containing object.
No changelog entry is added because the previously broken version was
never released to the public, and therefore this fix produces no
user-facing changes compared to the last released version.
Changelog-None
Closes: https://github.com/damus-io/damus/issues/3106
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
NostrDB relies on manual memory management, so it is a good idea to
enable the address sanitizer on debug configurations, as it helps find
memory-related issues on the app, which will allow us to identify memory
issues and potential crashes earlier in the development process.
Changelog-None
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
This commit introduces new interfaces for working with NostrDB from
Swift, including `NostrFilter` conversion, subscription streaming via
AsyncStreams and lookup/wait functions.
No user-facing changes.
Changelog-None
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Huge refactor to add better structure to the project.
Separating features with their associated view and model structure.
This should be better organization and will allow us to improve the
overall architecture in the future.
I forsee many more improvements that can follow this change. e.g. MVVM Arch
As well as cleaning up duplicate, unused, functionality.
Many files have global functions that can also be moved or be renamed.
damus/
├── Features/
│ ├── <Feature>/
│ │ ├── Views/
│ │ └── Models/
├── Shared/
│ ├── Components/
│ ├── Media/
│ ├── Buttons/
│ ├── Extensions/
│ ├── Empty Views/
│ ├── ErrorHandling/
│ ├── Modifiers/
│ └── Utilities/
├── Core/
│ ├── Nostr/
│ ├── NIPs/
│ ├── DIPs/
│ ├── Types/
│ ├── Networking/
│ └── Storage/
Signed-off-by: ericholguin <ericholguin@apache.org>
Changelog-Changed: Renamed Friends of Friends to Trusted Network
Changelog-Added: Added popover tips to DMs and Notifications toolbars on Trusted Network button
Signed-off-by: Terry Yiu <git@tyiu.xyz>
Merge a bunch of changes from terry, translations, and me
Terry Yiu (4):
Add NIP-05 favicon to profile names and NIP-05 web of trust feed
Fix quotes view header alignment
Export strings for translation
Rename Bitcoin Beach wallet to Blink
Transifex (11):
Translate Localizable.strings in th
Translate Localizable.strings in th
Translate Localizable.strings in nl
Translate Localizable.strings in de
Translate Localizable.stringsdict in de
Translate Localizable.stringsdict in de
Translate Localizable.strings in th
Translate Localizable.strings in th
Translate Localizable.strings in th
Translate Localizable.strings in th
Translate Localizable.strings in th
William Casarin (2):
perf: don't use regex in trim_{prefix,suffix}
regex is overkill for this, and performance is quite bad
Fixes: b131c74ee3 ("Add prefix and suffix string trimming functions")
Signed-off-by: William Casarin <jb55@jb55.com>
Changelog-Changed: Added more human visible errors on NWC wallets to aid with troubleshooting
Changelog-Added: Added copy technical info button to user visible errors, so that users can more easily share errors with developers
Closes: https://github.com/damus-io/damus/issues/3010
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
This commit moves Kingfisher data to Apple's designated caches folder
to avoid it from being backed up to iCloud.
Closes: https://github.com/damus-io/damus/issues/2993
Changelog-Fixed: Fixed issue where cached images would be backed up to iCloud
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
This commit implements a one-click Coinos wallet setup.
This was implemented using the Coinos API, and using account details
that are deterministically generated from the user's private key.
Closes: https://github.com/damus-io/damus/issues/2961
Changelog-Added: Added one-click Coinos wallet setup
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
This commit implements a new layer called NostrNetworkManager,
responsible for managing interactions with the Nostr network, and
providing a higher level API that is easier and more secure to use for
the layer above it.
It also integrates it with the rest of the app, by moving RelayPool and PostBox
into NostrNetworkManager, along with all their usages.
Changelog-Added: Added NIP-65 relay list support
Changelog-Changed: Improved robustness of relay list handling
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
This commit introduces a new interface that makes it easier and safer to
handle unowned NostrDB notes, by leveraging new non-copyable and borrow
features from modern Swift.
Changelog-None
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
This commit adds the base models needed for the NIP-65 relay list support.
This introduces no user-facing changes.
Changelog-None
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
This PR redesigns the NWC wallet view. A new view is added to introduce zaps to users. The set up wallet view is simplified, with new and existing wallet setup separated.
This also adds new NWC features such as getBalance and listTransactions allowing users to see their balance and previous transactions made.
Changelog-Added: Added view introducing users to Zaps
Changelog-Added: Added new wallet view with balance and transactions list
Changelog-Changed: Improved integration with Nostr Wallet Connect wallets
Closes: https://github.com/damus-io/damus/issues/2900
Signed-off-by: ericholguin <ericholguin@apache.org>
Co-Authored-By: Daniel D’Aquino <daniel@daquino.me>
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Push notifications were not opened reliably. To improve robustness, the
following changes were introduced:
1. The notification opening logic was updated to become more similar to
URL handling, in a way that uses better defined interfaces and
functions that provide better result guarantees, by separating
complex handling logic, and the side-effects/mutations that
are made after computing the open action — instead of relying on a
complex logic function that produces side-effects as a result, which
obfuscates the actual behavior of the function.
2. The LoadableThreadView was expanded and renamed to
LoadableNostrEventView, to reflect that it can also handle non-thread
nostr events, such as DMs, which is a necessity for handling push
notifications.
3. A new type of Notify object, the `QueueableNotify` was introduced, to
address issues where the listener/handler is not instantiated at the
time the app notifies that there is a push notification to be opened.
This was implemented using async streams, which simplifies the usage
of this down to a simple "for-in" loop.
Closes: https://github.com/damus-io/damus/issues/2825
Changelog-Fixed: Fixed issue where some push notifications would not open in the app and leave users confused
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
This commit implements an optional developer feature to scramble text
and blur images to prevent distractions during development and testing.
It is not perfect (It breaks some mentions and rich text objects, and
does not scramble non-alphanumeric languages such as Japanese), but
good enough to avoid distractions while working on most features.
No changelog entry is needed because this is not meant for the final
user.
Changelog-None
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
This commit fixes an issue where the post view would scroll to the text
cursor at seemingly random times.
This was done by detaching the save view and its logic, so that we have
3 components:
1. The `PostView`
2. An auto-save view model (which is an Observable object)
3. A separate SwiftUI view for the auto-save indicator
The auto-save view model is shared between the `PostView` and the new
indicator view to ensure proper signaling and communication across
views.
However, this view model is only observed by the indicator view,
ensuring it updates its own view, while not causing any re-renders on
the rest of the `PostView`.
This refactor had the side-effect of making the auto-save logic and view
more reusable. It is now a separate collection of elements that can be
used anywhere else.
Beyond the scroll issue, this commit also prevents empty drafts from
being saved, by introducing the new save state called `.nothingToSave`
Note: No changelog item is needed because the new drafts feature was never
publicly released.
Changelog-None
Closes: https://github.com/damus-io/damus/issues/2826
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
This commit removes rust-nostr dependency, and replaces the NIP-44 logic
with a new NIP-44 module based on the Swift NostrSDK implementation.
The decision to move away from rust-nostr and the Swift NostrSDK was
made for the following reasons:
1. `rust-nostr` caused the app size to double
2. We only need NIP44 functionality, and we don't need to bring
everything else
3. The Swift NostrSDK caused conflicts around the secp256k1 dependency
that is hard to address
4. The way we do things in the codebase is far different from the Swift
NostrSDK, and we optimize it for use with NostrDB. Bringing it an
outside library causes significant complexity in integration with
NostrDB, and would effectively cause the codebase to be split into
two different ways of achieving the same results. Therefore it is
cleaner if we stick to our own Nostr structures and functions and
focus on maintaining them.
However, the library CryptoSwift was added as a dependency, to bring in
ChaCha20 which is not supported by CryptoKit (CryptoKit supports the
ChaCha20-Poly1305 cipher, but NIP-44 uses ChaCha20 with HMAC-SHA256
instead)
Closes: https://github.com/damus-io/damus/issues/2849
Changelog-Changed: Made internal changes to reduce the app binary size
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
This makes the microphone access request contain a message that is more
clear to the user
Changelog-Changed: Made the microphone access request message more clear to users
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
This commit makes drafts persistent.
It does so by:
1. Converting `DraftsArtifacts` into Nostr events
2. Wrapping those Nostr events into NIP-37 notes
3. Saving those NIP-37 notes into NostrDB
4. Loading those same notes at startup
5. Unwrapping NIP-37 notes into Nostr events
6. Parsing that into `DraftsArtifacts`, loaded into DamusState
7. PostView can then load these drafts
Furthermore, a UX indicator was added to show when a draft has been
saved.
Limitations:
1. No encoding/decoding roundtrip guarantees. That would require
extensive and heavy refactoring which is out of the scope of this
commit.
2. We rely on `UserSettings` to keep track of note ids, while we do not
have Ndb query capabilities
3. No NIP-37 relay sync support has been added yet, as that adds
important privacy and sync conflict considerations which are out of
the scope of this ticket, which is ensuring people don't lose their
progress while writing notes.
4. The main use cases and scenarios have been tested. Because of (1),
there may be some small inconsistencies on the stored version of the
draft, but care was taken to keep the substantial portions of the
content intact.
Closes: https://github.com/damus-io/damus/issues/1862
Changelog-Added: Added local persistence of note drafts
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
This commit fixes an issue where events in threads would occasionally
disappear.
Previously, the computation of parent events and reply events depended
on EventCache and had to be manually computed upon event selection
change. This may lead to inconsistencies if the computation is not
re-done after a new event that leads to a change in the model, or if certain
events are not yet on the cache. Instead, these are now computed
properties inside ThreadModel, and relies exclusively on the events
already in the ThreadModel.
Several other smaller improvements were made around the affected class,
including:
- Removing unused code for simplicity
- Configuring the class external interface with more intent, avoiding
misusage
- Adding more documentation on the usage of things, as well as
implementation notes on why certain design decisions were taken.
- Moving things to explicit actors, to integrate more structured concurrency
- Improving code efficiency to lower computational overhead on the main
actor
- Splitting concerns between objects with more intent and thoughful
design.
Changelog-Fixed: Fixed an issue where events on a thread view would occasionally disappear
Closes: https://github.com/damus-io/damus/issues/2791
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
This commit improves reliability on the handling of
external URLs.
This was achieved through the following improvements:
1. The URL handler interface is now well-defined, with more clear inputs
and outputs, to avoid silent failures and error paths that are hard to see
within convoluted logic paths
2. Side effects during URL parsing were almost completely removed for
more predictable behavior
3. Error handling logic was added to present errors to the user in a user-friendly manner,
instead of silently failing
4. Event loading logic was moved into a special new thread view, which
makes its own internal state evident to the user (i.e. whether
the note is loading, loaded, or if the note could not be found)
These changes make the URL opening logic more predictable, easy to
refactor, and helps ensure the user always gets some outcome from
opening a URL, even if it means showing a "not found" or "error" screen,
to eliminate cases where nothing seems to happen.
Closes: https://github.com/damus-io/damus/issues/2429
Changelog-Fixed: Improved robustness of the URL handler
Changelog-Added: Added user-friendly error view for errors around the app that would not fit in other places
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
This PR adds a button to allow users to easily connect to Coinos
Also cleans up and organizes assets.
Changelog-Added: Coinos connection button in Wallet view
Signed-off-by: ericholguin <ericholguin@apache.org>
This commit implements profile image cropping and optimization, as well
as a major refactor on EditPictureControl.
It now employs the following techniques:
- Users can now crop their profile pictures to fit a square aspect
ratio nicely and avoid issues with automatic resizing/cropping
- Profile images are resized to a 400px by 400px image before sending it
over the wire for better bandwidth usage
- Profile pictures are now tagged as such to the media uploaders, to
enable media optimization or special care on their end.
Integrating the cropping step was very difficult with the previous
structures, so `EditPictureControl` was heavily refactored to have
improved state handling and better testability:
1. Enums with associated values are being used to capture all of the
state in the picture selection process, as that helps ensure the
needed info in each step is there and more clearly delianeate
different steps — all at compile-time
2. The view was split into a view-model architecture, with almost all of
the view logic ported to the new view-model class, making the view
and the logic more clear to read as concerns are separated. This also
enables better testabilty
Several automated tests were added to cover EditPictureControl logic and
looks.
Closes: https://github.com/damus-io/damus/issues/2643
Changelog-Added: Profile image cropping tools
Changelog-Changed: Improved profile image bandwidth optimization
Changelog-Changed: Improved reliability of picture selector
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
This commit adds the SwiftyCrop dependency, to provide users with a way
to crop their profile images prior to upload
- Dependency version is commit-hash-locked for extra security and
reproducibility
- Reviewed code contents of the library to check for any user tracking
code. None was found
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Turn on strict concurrency checks on the compiler to make potential
concurrency issues more visible and aid during debugging, as well as to
start preparing us for Swift 6.
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>