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

Sign with sargon #1277

Merged
merged 29 commits into from
Jan 9, 2025
Merged

Sign with sargon #1277

merged 29 commits into from
Jan 9, 2025

Conversation

micbakos-rdx
Copy link
Contributor

@micbakos-rdx micbakos-rdx commented Dec 10, 2024

Description

This PR uses sargon to sign transactions, subintents, and rola. This is the first time that sargon can dictate and orchestrate what UI should be shown in host, and expect a response.

  • Instead of using AccessFactorSourcesProxy directly we use sargon os.
  • Then sargon os decides on the order of factor sources, factor instances and transactions, interacts with android with WalletInteractor
  • Then WalletInteractor is asking for signatures with AccessFactorSourcesProxy and returns back the result
    • Since we plug in sargon os components, the exceptions should always be of CommonException kind.
    • The only error the host should expect from sargon os when signing is the CommonException.SigningRejected.
    • The rest of the errors during signing are presented inside the bottom sheet. The user can either retry or dismiss. Such errors can be related to missing mnemonics, ledger communication or errors with the biometrics system.
  • GetSignaturesViewModel is now responsible of returning the signatures to sargon os. The only logic that it handles is that it groups into a single biometrics request, multiple mnemonics. There is no ordering of the factor sources as it was. The ordering is handled by signatures collector in sargon.
  • This view model can sign transactions, subintents and rola. In order to minimize the footprint of the view model, I created a Signable interface which works similar to a Signable in sargon.

### This PR is still WIP. Remaining tasks:

  • GetSignaturesViewModel needs to use BiometricsHandler for obvious reasons, but also to handle the BiometricsException gracefully.
  • Non fatal errors need to be shown in UI. One example is failing to sign with ledger due to blind signing being disabled. The user can fix it in their ledger device and retry without even having to reopen the bottom sheet.
  • Unfortunately sign auth, needs to use the signatures collector in sargon os which finds the path of least resistance when signing with multiple factors. One example is when we need to authorise multiple accounts. Some of those accounts might be configured with a ledger and some with device factor sources. Current AuthenticationSigner does not do that. So, sargonOs.signAuth needs to be integrated with signatures collector. Fortunately the android host will not change much in terms of implementation since the interactor is the sole point of friction.

@micbakos-rdx micbakos-rdx self-assigned this Dec 10, 2024
@micbakos-rdx micbakos-rdx force-pushed the feature/sign-with-sargon branch 2 times, most recently from 1fb76b6 to 7098d4d Compare December 24, 2024 08:24
@micbakos-rdx micbakos-rdx marked this pull request as ready for review December 24, 2024 11:11
Copy link
Contributor

@giannis-rdx giannis-rdx left a comment

Choose a reason for hiding this comment

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

excellent work!

I’m still reviewing and testing, but I’ve left some initial comments.

Additionally to the comments, you can go ahead and delete the ResolveNotaryAndSignersUseCase.

import kotlin.time.Duration.Companion.milliseconds

@Singleton
class WalletInteractor @Inject constructor(
Copy link
Contributor

Choose a reason for hiding this comment

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

maybe this class name should include the "sign" word, since it's all about signing?
E.g. "WalletSignerInteractor", "SignerInteractor"?
unless this WalletInteractor will implement other interactors later?

Another point to consider is that if this is solely about signing, perhaps we could move it under the accessfactorsources package?

Copy link
Contributor

Choose a reason for hiding this comment

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

Also you do not need the @Inject constructor here since you have already the @Provides module that does exactly this thing.

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 it is intended to be used for other interactions as well. Although this is something that can change.

@@ -67,6 +68,9 @@ class MainActivity : FragmentActivity() {
@Inject
lateinit var biometricsHandler: BiometricsHandler

@Inject
lateinit var getProfileUseCase: GetProfileUseCase
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this is not needed, right?

I removed it (locally in my branch) and signed a couple of transactions without issues.

Copy link
Contributor

Choose a reason for hiding this comment

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

👋🏽

@@ -195,45 +194,6 @@ fun Profile.addAccounts(
return updatedProfile.withUpdatedContentHint()
}

@Suppress("UnusedParameter")
fun Profile.addAuthSigningFactorInstanceForEntity(
Copy link
Contributor

Choose a reason for hiding this comment

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

remove it?

Copy link
Contributor

@sergiupuhalschi-rdx sergiupuhalschi-rdx left a comment

Choose a reason for hiding this comment

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

Looks nice and clean!

@@ -67,6 +68,9 @@ class MainActivity : FragmentActivity() {
@Inject
lateinit var biometricsHandler: BiometricsHandler

@Inject
lateinit var getProfileUseCase: GetProfileUseCase
Copy link
Contributor

Choose a reason for hiding this comment

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

This is not invoked anywhere, is it still needed here?

)
).perFactorSource
} else {
request.perFactorSource.map { perFactorSource ->
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 like to understand the behavior here. Why do we have different logic if the factorSourceKind is FactorSourceKind.DEVICE? Is it because we should only request the biometric prompt once? I assume a request with factorSourceKind == FactorSourceKind .DEVICE can have multiple perFactorSource but we need to ask for biometrics once to fulfill all of them?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Exactly as it currently stands, when FactorSourceKind.DEVICE is requested we perform poly sign. Meaning that we sign with multiple device factor sources with just one biometric. This is tbd though. One reason somewhat against this is what happens if one of those many devices misses the mnemonic. Do we fail the whole operation or we just return a signature of each device that can sign and skip the rest? How should that be depicted in the ui. I think we are going to discuss this tomorrow.

}
}

fun List<OutputPerFactorSource<Signable.ID.Transaction>>.into() = SignWithFactorsOutcomeOfTransactionIntentHash.Signed(
Copy link
Contributor

Choose a reason for hiding this comment

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

Perhaps a clearer name would be better, such as signed or toSigned?

@micbakos-rdx micbakos-rdx force-pushed the feature/sign-with-sargon branch from 6a87fad to 9028a72 Compare January 9, 2025 09:58
Copy link

sonarqubecloud bot commented Jan 9, 2025

Quality Gate Failed Quality Gate failed

Failed conditions
0.0% Coverage on New Code (required ≥ 40%)

See analysis details on SonarQube Cloud

Copy link
Contributor

@giannis-rdx giannis-rdx left a comment

Choose a reason for hiding this comment

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

Amazing work! 🙇🏽

@micbakos-rdx micbakos-rdx merged commit e26ad0d into main Jan 9, 2025
10 of 11 checks passed
@micbakos-rdx micbakos-rdx deleted the feature/sign-with-sargon branch January 9, 2025 15:57
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.

3 participants