Skip to content
This repository was archived by the owner on Mar 26, 2026. It is now read-only.

Contacts#1711

Merged
DRadmir merged 12 commits intomainfrom
469-implement-contacts
Feb 23, 2026
Merged

Contacts#1711
DRadmir merged 12 commits intomainfrom
469-implement-contacts

Conversation

@DRadmir
Copy link
Copy Markdown
Contributor

@DRadmir DRadmir commented Feb 18, 2026

Simulator Screenshot - iPhone 17 Pro Max - 2026-02-18 at 16 41 23 Simulator Screenshot - iPhone 17 Pro Max - 2026-02-18 at 16 41 30 Simulator Screenshot - iPhone 17 Pro Max - 2026-02-18 at 16 41 58 Simulator Screenshot - iPhone 17 Pro Max - 2026-02-18 at 16 44 23 Simulator Screenshot - iPhone 17 Pro Max - 2026-02-18 at 16 45 03 Simulator Screenshot - iPhone 17 Pro Max - 2026-02-18 at 16 45 13 Simulator Screenshot - iPhone 17 Pro Max - 2026-02-18 at 16 45 26

Close: #469

- Add ContactsScene with list, add, edit, and delete functionality
- Add ManageContactScene for creating and editing contacts
- Add ContactService, ContactStore, and ContactRecord for data persistence
- Add ContactsRequest with chain filtering (EVM chains compatibility)
- Show contacts in Transfer Recipient scene filtered by chain
- Pass memo from contacts to transfer flow via RecipientAddress
- Add validation: disable save button when name/address empty
- Validate address and clear memo when network changes
- Remove unused SystemImage icons
- Use address as Contact ID for uniqueness
Implements one-to-many relationship between Contact and ContactAddress,
allowing contacts to have multiple addresses across different chains.
Adds QR scanner support for address input and proper localization.
…ment-contacts

# Conflicts:
#	Packages/PrimitivesComponents/Sources/Extensions/SwapProviderType+Gemstone.swift
#	Packages/Style/Sources/Extentions/Images+SystemImage.swift
#	Packages/Style/Sources/SystemImage.swift
#	core
@DRadmir DRadmir self-assigned this Feb 18, 2026
@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello @DRadmir, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request delivers a significant new 'Contacts' functionality, empowering users to efficiently manage their frequently used addresses. It provides a centralized place to store contact details and multiple associated blockchain addresses, which can then be seamlessly utilized during the asset transfer process. The implementation includes a new Swift package, dedicated UI scenes, robust ViewModel logic, and a persistent storage solution, all designed to enhance user convenience and streamline transaction workflows.

Highlights

  • New Contacts Feature: Introduced a comprehensive 'Contacts' feature allowing users to manage contact information and associated addresses within the application.
  • Seamless Integration: The Contacts feature is integrated into the Settings menu and the asset transfer flow, enabling users to easily select contact addresses as recipients.
  • Persistence Layer: Implemented new GRDB database models (ContactRecord, ContactAddressRecord) and a ContactStore for robust local storage of contact data.
  • Modular Architecture: Developed dedicated SwiftUI views and ViewModels for listing, adding, editing, and deleting contacts and their addresses, ensuring a clean and maintainable codebase.
  • Localization and UI Updates: Added new localization strings across multiple languages and updated UI components to support the new feature, including empty states and system images.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • Features/Contacts/Package.swift
    • Added a new Swift package for the Contacts feature, defining its products, platforms, and dependencies.
  • Features/Contacts/Sources/Scenes/ChainSelectorScene.swift
    • Added a new SwiftUI view for selecting a blockchain chain within the contact address management flow.
  • Features/Contacts/Sources/Scenes/ContactsScene.swift
    • Added the main SwiftUI view for displaying and managing a list of contacts, including add and delete functionality.
  • Features/Contacts/Sources/Scenes/ManageContactAddressNavigationStack.swift
    • Added a SwiftUI navigation stack for managing a single contact address, including chain selection and QR scanning.
  • Features/Contacts/Sources/Scenes/ManageContactAddressScene.swift
    • Added a SwiftUI view for inputting and validating contact address details, including paste and scan options.
  • Features/Contacts/Sources/Scenes/ManageContactNavigationStack.swift
    • Added a SwiftUI navigation stack for managing a single contact, allowing for adding and editing contact details and addresses.
  • Features/Contacts/Sources/Scenes/ManageContactScene.swift
    • Added a SwiftUI view for editing contact details (name, description) and managing associated addresses.
  • Features/Contacts/Sources/ViewModels/AddressItemViewModel.swift
    • Added a ViewModel to format and present contact address data for list items.
  • Features/Contacts/Sources/ViewModels/ContactItemViewModel.swift
    • Added a ViewModel to format and present contact data for list items.
  • Features/Contacts/Sources/ViewModels/ContactsViewModel.swift
    • Added a ViewModel to manage the state and logic for the main Contacts list scene.
  • Features/Contacts/Sources/ViewModels/ManageContactAddressViewModel.swift
    • Added a ViewModel to handle the state and logic for adding or editing a contact address.
  • Features/Contacts/Sources/ViewModels/ManageContactViewModel.swift
    • Added a ViewModel to manage the state and logic for adding or editing a contact.
  • Features/Contacts/Tests/ContactsTests/ManageContactAddressViewModelTests.swift
    • Added unit tests for the ManageContactAddressViewModel to verify button states and memo display logic.
  • Features/Contacts/Tests/ContactsTests/ManageContactViewModelTests.swift
    • Added unit tests for the ManageContactViewModel to verify button states based on contact details and addresses.
  • Features/Settings/Sources/Settings/Scenes/SettingsScene.swift
    • Updated the Settings scene to include a navigation link to the new Contacts feature.
  • Features/Settings/Sources/Settings/ViewModels/SettingsViewModel.swift
    • Updated the Settings ViewModel to provide title and image for the new Contacts entry.
  • Features/Transfer/Sources/Scenes/RecipientScene.swift
    • Updated the Recipient scene to import Store, observe contact queries, and integrate contact addresses into the recipient selection.
  • Features/Transfer/Sources/Types/RecipientAddressType.swift
    • Updated RecipientAddressType enum to include a new .contacts case.
  • Features/Transfer/Sources/ViewModels/RecipientSceneViewModel.swift
    • Updated the Recipient scene ViewModel to import Store, manage contact requests, and integrate contact addresses into recipient sections.
  • Gem.xcodeproj/project.pbxproj
    • Updated Xcode project file to include the new Contacts module and its dependencies.
  • Gem/Navigation/Settings/SettingsNavigationStack.swift
    • Updated the Settings navigation stack to import ContactService and Contacts, and added a navigation destination for the Contacts scene.
  • Gem/Services/AppResolver+Services.swift
    • Updated AppResolver to include ContactService in its services structure.
  • Gem/Services/ServicesFactory.swift
    • Updated ServicesFactory to instantiate and provide ContactService.
  • Gem/Types/Environment.swift
    • Updated EnvironmentValues to include contactService as an environment entry.
  • Packages/Components/Sources/StateView/StateEmptyView.swift
    • Updated StateEmptyView to add horizontal padding to the description text.
  • Packages/Components/Sources/Types/EmptyContentType.swift
    • Updated EmptyContentType enum to include a new .contacts case.
  • Packages/FeatureServices/ContactService/ContactService.swift
    • Added a new ContactService struct to provide an interface for managing contacts via the ContactStore.
  • Packages/FeatureServices/Package.swift
    • Updated the FeatureServices package to include the new ContactService library and its dependencies.
  • Packages/Localization/Sources/Localized.swift
    • Updated Localized.swift to include new localization keys for the Contacts feature and Earn empty states.
  • Packages/Localization/Sources/Resources/ar.lproj/Localizable.strings
    • Updated Arabic localization strings with new entries for Contacts and Earn empty states.
  • Packages/Localization/Sources/Resources/bn.lproj/Localizable.strings
    • Updated Bengali localization strings with new entries for Contacts and Earn empty states.
  • Packages/Localization/Sources/Resources/cs.lproj/Localizable.strings
    • Updated Czech localization strings with new entries for Contacts and Earn empty states.
  • Packages/Localization/Sources/Resources/da.lproj/Localizable.strings
    • Updated Danish localization strings with new entries for Contacts and Earn empty states.
  • Packages/Localization/Sources/Resources/de.lproj/Localizable.strings
    • Updated German localization strings with new entries for Contacts and Earn empty states.
  • Packages/Localization/Sources/Resources/en.lproj/Localizable.strings
    • Updated English localization strings with new entries for Contacts and Earn empty states.
  • Packages/Localization/Sources/Resources/es.lproj/Localizable.strings
    • Updated Spanish localization strings with new entries for Contacts and Earn empty states.
  • Packages/Localization/Sources/Resources/fa.lproj/Localizable.strings
    • Updated Farsi localization strings with new entries for Contacts and Earn empty states.
  • Packages/Localization/Sources/Resources/fil.lproj/Localizable.strings
    • Updated Filipino localization strings with new entries for Contacts and Earn empty states.
  • Packages/Localization/Sources/Resources/fr.lproj/Localizable.strings
    • Updated French localization strings with new entries for Contacts and Earn empty states.
  • Packages/Localization/Sources/Resources/ha.lproj/Localizable.strings
    • Updated Hausa localization strings with new entries for Contacts and Earn empty states.
  • Packages/Localization/Sources/Resources/he.lproj/Localizable.strings
    • Updated Hebrew localization strings with new entries for Contacts and Earn empty states.
  • Packages/Localization/Sources/Resources/hi.lproj/Localizable.strings
    • Updated Hindi localization strings with new entries for Contacts and Earn empty states.
  • Packages/Localization/Sources/Resources/id.lproj/Localizable.strings
    • Updated Indonesian localization strings with new entries for Contacts and Earn empty states.
  • Packages/Localization/Sources/Resources/it.lproj/Localizable.strings
    • Updated Italian localization strings with new entries for Contacts and Earn empty states.
  • Packages/Localization/Sources/Resources/ja.lproj/Localizable.strings
    • Updated Japanese localization strings with new entries for Contacts and Earn empty states.
  • Packages/Localization/Sources/Resources/ko.lproj/Localizable.strings
    • Updated Korean localization strings with new entries for Contacts and Earn empty states.
  • Packages/Localization/Sources/Resources/ms.lproj/Localizable.strings
    • Updated Malay localization strings with new entries for Contacts and Earn empty states.
  • Packages/Localization/Sources/Resources/nl.lproj/Localizable.strings
    • Updated Dutch localization strings with new entries for Contacts and Earn empty states.
  • Packages/Localization/Sources/Resources/pl.lproj/Localizable.strings
    • Updated Polish localization strings with new entries for Contacts and Earn empty states.
  • Packages/Localization/Sources/Resources/pt-BR.lproj/Localizable.strings
    • Updated Brazilian Portuguese localization strings with new entries for Contacts and Earn empty states.
  • Packages/Localization/Sources/Resources/ro.lproj/Localizable.strings
    • Updated Romanian localization strings with new entries for Contacts and Earn empty states.
  • Packages/Localization/Sources/Resources/ru.lproj/Localizable.strings
    • Updated Russian localization strings with new entries for Contacts and Earn empty states.
  • Packages/Localization/Sources/Resources/sw.lproj/Localizable.strings
    • Updated Swahili localization strings with new entries for Contacts and Earn empty states.
  • Packages/Localization/Sources/Resources/th.lproj/Localizable.strings
    • Updated Thai localization strings with new entries for Contacts and Earn empty states.
  • Packages/Localization/Sources/Resources/tr.lproj/Localizable.strings
    • Updated Turkish localization strings with new entries for Contacts and Earn empty states.
  • Packages/Localization/Sources/Resources/uk.lproj/Localizable.strings
    • Updated Ukrainian localization strings with new entries for Contacts and Earn empty states.
  • Packages/Localization/Sources/Resources/ur.lproj/Localizable.strings
    • Updated Urdu localization strings with new entries for Contacts and Earn empty states.
  • Packages/Localization/Sources/Resources/vi.lproj/Localizable.strings
    • Updated Vietnamese localization strings with new entries for Contacts and Earn empty states.
  • Packages/Localization/Sources/Resources/zh-Hans.lproj/Localizable.strings
    • Updated Simplified Chinese localization strings with new entries for Contacts and Earn empty states.
  • Packages/Localization/Sources/Resources/zh-Hant.lproj/Localizable.strings
    • Updated Traditional Chinese localization strings with new entries for Contacts and Earn empty states.
  • Packages/Primitives/Sources/Contact.swift
    • Added new Contact, ContactAddress, and ContactData structs to define the data models for contacts.
  • Packages/Primitives/Sources/Extensions/ContactData+Primitives.swift
    • Added an extension to ContactData to conform to Identifiable.
  • Packages/Primitives/Sources/RecipientAddress.swift
    • Updated RecipientAddress to include an optional memo field.
  • Packages/Primitives/Sources/Scenes.swift
    • Updated Scenes struct to include a new Contacts scene type.
  • Packages/Primitives/TestKit/Contact+PrimitivesTestKit.swift
    • Added mock extensions for Contact, ContactAddress, and ContactData for testing purposes.
  • Packages/PrimitivesComponents/Sources/ViewModels/ContactRecipientViewModel.swift
    • Added a new ViewModel to convert ContactData into RecipientAddress list items.
  • Packages/PrimitivesComponents/Sources/ViewModels/EmptyContentTypeViewModel.swift
    • Updated EmptyContentTypeViewModel to support the new .contacts empty state.
  • Packages/PrimitivesComponents/Tests/PrimitivesComponentsTests/ContactRecipientViewModelTests.swift
    • Added unit tests for ContactRecipientViewModel.
  • Packages/Store/Sources/Migrations.swift
    • Updated database migrations to create tables for ContactRecord and ContactAddressRecord.
  • Packages/Store/Sources/Models/ContactAddressRecord.swift
    • Added a new GRDB record struct for persisting contact addresses.
  • Packages/Store/Sources/Models/ContactRecord.swift
    • Added a new GRDB record struct for persisting contacts.
  • Packages/Store/Sources/Requests/ContactsRequest.swift
    • Added a new GRDB queryable struct for fetching contact data.
  • Packages/Store/Sources/Stores/ContactStore.swift
    • Added a new ContactStore to manage persistence operations for contacts and their addresses.
  • Packages/Store/Sources/Stores/StoreManager.swift
    • Updated StoreManager to include the new ContactStore.
  • Packages/Store/Sources/Types/ContactRecordInfo.swift
    • Added a new struct to combine ContactRecord and ContactAddressRecord for fetching contact data.
  • Packages/Store/TestKit/ContactStore+TestKit.swift
    • Added a mock extension for ContactStore for testing purposes.
  • Packages/Style/Sources/Extentions/Images+SystemImage.swift
    • Updated system image extensions, removing some unused images and adding new ones related to contacts.
  • Packages/Style/Sources/Images.swift
    • Updated Images enum to include new asset images for settings and empty content related to contacts.
  • Packages/Style/Sources/Resources/Assets.xcassets/settings/settings_contact.imageset/Contents.json
    • Added asset catalog entry for the new settings contact icon.
  • Packages/Style/Sources/Resources/Assets.xcassets/settings/settings_contact.imageset/Frame.svg
    • Added SVG asset for the new settings contact icon.
  • Packages/Style/Sources/SystemImage.swift
    • Updated SystemImage struct, removing some unused system images and adding new ones related to contacts.
  • core
    • Updated subproject commit hash.
Activity
  • A new 'Contacts' feature has been introduced, encompassing a dedicated Swift package with UI scenes, ViewModels, data models, and persistence logic.
  • The feature is integrated into the application's Settings menu and the existing asset transfer flow, allowing users to manage and select contact addresses.
  • New database tables (contacts and contact_addresses) and a ContactService have been added to handle the storage and retrieval of contact data.
  • Extensive localization updates have been made across multiple languages to support the new 'Contacts' and 'Earn' empty states.
  • Unit tests for the new ManageContactAddressViewModel and ManageContactViewModel have been added to ensure the reliability of the contact management logic.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a comprehensive 'Contacts' feature, which is well-structured with new scenes, view models, and database integration. The code quality is high, and it integrates cleanly with existing features like Settings and Transfers. My feedback focuses on improving error handling to provide a more robust user experience and ensuring all user-facing strings are properly localized for maintainability.

Comment thread Features/Contacts/Sources/ViewModels/ContactsViewModel.swift
Comment thread Features/Contacts/Sources/ViewModels/ManageContactViewModel.swift
Comment thread Features/Settings/Sources/Settings/ViewModels/SettingsViewModel.swift Outdated
Comment thread Features/Transfer/Sources/ViewModels/RecipientSceneViewModel.swift Outdated
Comment thread Packages/PrimitivesComponents/Sources/ViewModels/EmptyContentTypeViewModel.swift Outdated
Comment thread Packages/PrimitivesComponents/Sources/ViewModels/EmptyContentTypeViewModel.swift Outdated
Replace hardcoded "Contacts" strings with Localized.Contacts.title
and add empty state localization for contacts list.
@DRadmir DRadmir force-pushed the 469-implement-contacts branch 2 times, most recently from bca9a7f to 767a5f0 Compare February 19, 2026 16:37
Introduce createdAt/updatedAt to Contact and propagate the change through primitives, test kit and DB records; remove description from ContactAddress. Split contact persistence into addContact/updateContact in ContactService and ContactStore (update ContactRecord schema and ContactAddressRecord columns/logic). Refactor recipient UI/models by adding AssetImageTitleViewModel/View and new section view models (ContactRecipientSectionViewModel, WalletRecipientSectionViewModel), replace previous ContactRecipientViewModel, and update Receive/Recipient scenes and view models to use the new components. Add unit tests for the new section view models. Also add Chain EVM helpers, update ContactsRequest to consider compatible EVM chains, and remove the deprecated Stream newAssets event handling.
@DRadmir DRadmir force-pushed the 469-implement-contacts branch from 767a5f0 to 392fed8 Compare February 19, 2026 16:58
@DRadmir DRadmir marked this pull request as ready for review February 19, 2026 17:02
Refactor ManageContactAddressViewModel to remove the internal addressId and build ContactAddress via a new ContactAddress.new factory (id = chain.rawValue + "_" + address). Simplify view model logic (always enable save and remove hasChanges branch) and keep address checksum behavior. Add Contact+Primitives extension that provides the factory. Update ContactAddressRecord table schema to add onUpdate: .cascade for contactId and add a foreign key reference from address to AssetRecord with cascade on delete/update. Simplify ContactsRequest chain filtering to a direct equality check and remove the compatibleChains helper.
Comment thread Features/Contacts/Sources/ViewModels/ManageContactAddressViewModel.swift Outdated
Comment thread Packages/Store/Sources/Stores/ContactStore.swift Outdated
Comment thread Features/Transfer/Sources/ViewModels/ContactRecipientSectionViewModel.swift Outdated
Compute and apply address-level diffs when updating contacts so removed addresses are deleted instead of left orphaned. ContactService.updateContact now fetches existing address IDs, calculates a SyncDiff, and passes deleteAddressIds to the store before syncing names. ContactStore.updateContact signature was changed to accept deleteAddressIds, deletes matching address records, upserts provided addresses, and a new getAddressIds(contactId:) helper was added. A Contact.new factory was introduced to centralize Contact creation (preserving createdAt for edits and setting updatedAt). ManageContactViewModel was simplified: added Mode.contact accessor, currentContact now uses Contact.new with existing createdAt when editing, and the save-button enablement logic was simplified. ContactRecipientSectionViewModel grouping now uses the raw address string (no lowercasing) to preserve original casing.
Comment thread Features/Contacts/Sources/Scenes/ContactsScene.swift Outdated
Comment thread Features/Contacts/Sources/Scenes/ContactsScene.swift Outdated
Comment thread Features/Contacts/Sources/Scenes/ManageContactAddressNavigationStack.swift Outdated
Comment thread Features/Contacts/Sources/Scenes/ManageContactAddressScene.swift Outdated
Comment thread Features/Contacts/Sources/Scenes/ManageContactAddressScene.swift Outdated
Comment thread Features/Contacts/Sources/ViewModels/ContactsViewModel.swift Outdated
Comment thread Features/Contacts/Sources/ViewModels/ManageContactAddressViewModel.swift Outdated
Comment thread Features/Contacts/Sources/ViewModels/ManageContactViewModel.swift Outdated
Comment thread Packages/Primitives/Sources/Extensions/Chain+Primitives.swift Outdated
Comment thread Packages/Store/Sources/Models/ContactAddressRecord.swift Outdated
@DRadmir DRadmir force-pushed the 469-implement-contacts branch from f8a6836 to 2566d24 Compare February 23, 2026 05:01
- Update ContactsRequest to conform to DatabaseQueryable
- Replace observeQuery with bindQuery in ContactsScene and RecipientScene
- Use ObservableQuery in ContactsViewModel and RecipientSceneViewModel
@DRadmir DRadmir force-pushed the 469-implement-contacts branch from 2566d24 to 06e8e68 Compare February 23, 2026 05:07
@DRadmir DRadmir merged commit d489500 into main Feb 23, 2026
1 check passed
@DRadmir DRadmir deleted the 469-implement-contacts branch February 23, 2026 05:11
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement Contacts

2 participants