Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ABW-1472] Allow user to toggle Verbose / Summary when making ledger requests #474

Merged

Conversation

CyonAlexRDX
Copy link
Contributor

@CyonAlexRDX CyonAlexRDX commented May 4, 2023

Jira ticket: ABW-1472

Description

Adds a setting (in Profile.AppPrefences.Display) to change Ledger Hardware wallet display mode during signing, either .verbose or .summary, since we only have those two possible values (and we have not identified the need for a third one) we can represent it as a Toggle (bool).

In SignWithFactorSourcesOfKindLedger we now read this mode from Profile using appPreferencesClient

Video

trim.193A3FC2-65AC-4392-95BE-2E4521AB6176.MOV

PR submission checklist

  • I have tested account to account transfer flow and have confirmed that it works

@CyonAlexRDX CyonAlexRDX marked this pull request as ready for review May 4, 2023 17:58
@@ -49,6 +49,12 @@ extension SigningFactors {
}
}

extension FactorSourcesClient {
public func getFactorSources(ofKind kind: FactorSourceKind) async throws -> Set<FactorSource> {
Copy link
Contributor

@kugel3 kugel3 May 4, 2023

Choose a reason for hiding this comment

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

I suppose we don't want this to be nonempty, since it can legitimately be empty, but one could argue that it should still be an identified array, since the set will only guarantee that it's unique with respect to the whole factor source (it seems like it uses synthesized hashing), but we actually know that it's unique also with respect to id alone, which is stronger.

Since it's a getter the set doesn't sacrifice any safety w.r.t this function, but perhaps the consumer would benefit from the extra information. Or not.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

👍 changed to IdentfiedArrayOf and upgraded FactorSourcesClient a bit with useful convenience query methods

@@ -3,6 +3,8 @@ import FeaturePrelude
extension GeneralSettings.State {
var viewState: GeneralSettings.ViewState {
.init(
hasAnyLedgerHardwareWalletFactorSources: hasAnyLedgerHardwareWalletFactorSources,
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd argue that "any" is superfluous here

displayHashOnLedgerDisplay: true
))
}
}

extension FactorSource.LedgerHardwareWallet.SigningDisplayMode {
// seperation so that we do not accidentally break profile or RadixConnect
Copy link
Contributor

Choose a reason for hiding this comment

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

Separation in the sense that we have two identical enums?

@@ -9,6 +9,12 @@ extension FactorSource {
case nanoSPlus = "nanoS+"
case nanoX
}

public enum SigningDisplayMode: String, Sendable, Hashable, Codable {
Copy link
Contributor

Choose a reason for hiding this comment

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

I would prefer to break this out instead of copying it, but maybe there is no natural place to put it

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I started using the same enum, but I think it might be something that might bite us in the ass later, which is why I for LedgerDevice enum as well against every fiber of my being chose to duplicate the models. This kind of repetition hurts my soul, but I still think it is the right choice here. The reason is that yes they do share the same Codable values now, but logically they are different models. One model is a CAP21 contract between wallet and Connector Extension, the other is the CRUCIAL internals of Profile, which if accidentally changed, breaks the whole app.

We are iterating both domains a lot still, thus it feels safest to keep them apart.

Does that make sense?

Copy link
Contributor

Choose a reason for hiding this comment

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

OK that makes sense

@@ -11,6 +13,11 @@ extension GeneralSettings.State {
// MARK: - GeneralSettings.View
extension GeneralSettings {
public struct ViewState: Equatable {
let hasAnyLedgerHardwareWalletFactorSources: Bool

/// only to be displayed if `hasAnyLedgerHardwareWalletFactorSources` is true
Copy link
Contributor

Choose a reason for hiding this comment

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

I would not have been able to resist the temptation to make an enum here

enum LedgerHardwareWalletFactorSourcesPresent {
    case zero
    case some(displayMode: Mode)
}

which would probably just make things more complex

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeah I started out doing something like that too, but was not really worth it

ToggleView(
title: "Verbose Ledger transaction signing",
subtitle: "When signing with your Ledger hardware wallet, should all instructions be displayed?",
isOn: viewStore.binding(
Copy link
Contributor

@kugel3 kugel3 May 4, 2023

Choose a reason for hiding this comment

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

Since you're only using the binding in here, you could create it outside and pass it in. This has no practical benefit, it's merely philosophical since this view is very unlikely to be reused...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think unnecessary variables in ResultBuilders are ugly :D matter of taste I guess...

Comment on lines 8 to 9
var preferences: AppPreferences?

var hasAnyLedgerHardwareWalletFactorSources: Bool = false
Copy link
Contributor

Choose a reason for hiding this comment

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

I suppose the properties should also be public, strictly speaking?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes you are right

@@ -36,6 +49,13 @@ public struct GeneralSettings: Sendable, FeatureReducer {
return .fireAndForget {
try await appPreferencesClient.updatePreferences(preferences)
}

case let .useVerboseModeToggled(useVerboseMode):
Copy link
Contributor

Choose a reason for hiding this comment

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

Couldn't we just put the mode here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

the problem with bindings and mapping them, it is a hassel... I feel the logic of mapping from Bool (which Toggle uses) to DisplayMode is a job for the reducer, not the view.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah yes if it's the one that goes into the binding then sure, bool makes more sense

Copy link
Contributor

@kugel3 kugel3 left a comment

Choose a reason for hiding this comment

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

Looks great, I just have some pedantic comments

guard softwareAccounts.allSatisfy({ $0.accountType == .software }) else {
assertionFailure("Unexpectedly received hardware account, unable to verify.")
return nil
}
do {
let factorSourceIDs = try await getFactorSources(ofKind: .device)
// cannot use `getFactorSources:ofKind`
Copy link
Contributor

Choose a reason for hiding this comment

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

Out of curiosity, why not?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

because we are inside the init of Self and getFactorSource:ofKind is a non static func, I myself silly enough tried to call it, which ofc does not work, since we are in the process of init Self :D

Copy link
Contributor Author

Choose a reason for hiding this comment

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

one could complicate matters with static func but deemed it not worth it.

@CyonAlexRDX CyonAlexRDX merged commit 01a9b9a into main May 5, 2023
@CyonAlexRDX CyonAlexRDX deleted the ABW-1472_settings_for_ledgerHardwareDevice_displayMode branch May 5, 2023 10:27
This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

2 participants