-
Notifications
You must be signed in to change notification settings - Fork 1
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
Sargon OS Boot fixes #212
Sargon OS Boot fixes #212
Conversation
@@ -151,6 +151,38 @@ impl SargonOS { | |||
Ok(()) | |||
} | |||
|
|||
pub async fn derive_wallet( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why "derive"? This is not deriving anything..?
Why "wallet"?
Can we name it something "profile with accounts" ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wanted to keep the wallet name consistent with the other "entry" methods like
new_wallet
import_wallet
delete_wallet
Maybe new_wallet_with_derived_bdfs
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh I had forgot we had functions called import_wallet.
Right I think my idea is that we loosely define "wallet = (Profile, (BDFS) Mnemonic).
Maybe new_profile_with_restored_accounts
?
Btw! Are we asserting that the SecureStorage does in fact contain the device factor source?
If not, we should right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately that is impossible. I wanted to do the same, but in order to do that I need another biometric prompt. The same should apply to import wallet.
Why is that?
- If we need to ask for biometrics only once, we need to pass the mnemonic to ffi. I am not sure if we want to do that. If we ever did that, then sargon os could check the validity and store it. Thus having total control over it.
- Otherwise we let the host store the mnemonic, as it used to, but now this method will need to read the mnemonic again, asking for biometrics for a second time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, I think we should do any of those too.
We are already passing the mnemonic across FFI in the form of entropy. So I think best pass a PrivateHierarchicalDeterministicFactorSource from Host, that way we know user has intact "wallet"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or well, we know if we also check that the accounts are controlled by that DeviceFactorSource
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am in favour of passing the mnemonic over FFI, unless there are some specific concerns. Can't see any in particular.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are already passing the mnemonic across FFI in the form of entropy.
You are right @CyonAlexRDX I forgot about that. Will make the changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@CyonAlexRDX I have implemented the logic to
- pass the
PrivateHierarchicalDeterministicFactorSource
into the function - Validate the accounts public keys
- Ensure that secure storage succeeds saving the mnemonic
84c7af6
Please let me know if the execution is valid
|
||
let mainnet_network = match maybe_accounts { | ||
None => ProfileNetwork::new_empty_on(NetworkID::Mainnet), | ||
Some(accounts) => ProfileNetwork::new_with_accounts( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we not assert that all accounts are controlled by the BDFS? Maybe not, if accounts passed is a mix of Ledger accounts has software.
Hmmm
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wanted to ask about that. We are currently only checking if the accounts are not on mainnet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Issue is that this probably seems like a very generic purpose API, while it should be used only when recovering with a Seed Phrase which by definition can be only BDFS currently. It is meant to replace this Host logic.
...n-android/src/main/java/com/radixdlt/sargon/os/driver/AndroidBiometricAuthorizationDriver.kt
Show resolved
Hide resolved
jvm/sargon-android/src/main/java/com/radixdlt/sargon/os/driver/AndroidStorageDriver.kt
Show resolved
Hide resolved
jvm/sargon-android/src/main/java/com/radixdlt/sargon/os/storage/KeySpec.kt
Show resolved
Hide resolved
examples/android/src/main/java/com/radixdlt/sargon/android/ExampleApplication.kt
Outdated
Show resolved
Hide resolved
biometricsResultsChannel.send(result) | ||
} | ||
biometricRequestsChannel | ||
.receiveAsFlow() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why you define the biometricRequestsChannel
and biometricsResultsChannel
as Channel
and then receive the as Flow
?
Why not to define them as Flows?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wanted to implement a logic of two cold flows. Sargon os can ask for biometrics at any time. So I wanted to solve 2 problems
- No activity is yet
STARTED
in order to handle biometrics. Remember in order to ask for biometrics, we need a reference to aFragmentActivity
. In order for the biometrics dialog to show up, we need the activity to be at least started. So I wanted to have a suspending function waiting for an activity to either register and start or return from background. This is whybiometricRequestsChannel
exists. It waits for the request to be handled by one activity. - The
biometricsResultsChannel
is waiting for the USER to respond. The values of the channel will be emitted by another function.
.map(|c| c.transaction_signing.public_key) | ||
.map_err(|_| CommonError::EntitiesNotDerivedByFactorSource) | ||
}) | ||
.try_collect()?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cool, I did not know about try_collect
, we should embrace it!
I think I'd prefer let ..: Vec<T> = ....try_collect()?
be rewritten as let .. = ....try_collect::<Vec<_>>()?
where try_collect::<Vec<_>>()
is verbatim, the _
usage tells rust to fill it in (which it can do based on .map(|c| c.transaction_signing.public_key)
.
That is the code style I've mostly used elsewhere in Sargon - the advantage is that for long chains of functional calls one can control the return type at the end of the chain, which one typically does by adding yet another map that makes it a bit easier to maintain IMO.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like doing this too, but this does not compile. I cannot find a sane way to make this compile.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An example of this working is this:
.try_collect::<_, Vec<_>, _>()?;
Does this look more readable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah it is generic over many things. Right, yeah I prefer that actually
|
||
if !hd_factor_source | ||
.mnemonic_with_passphrase | ||
.validate_public_keys(hd_keys) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice! so now we assert that all factor instances are indeed controlled by the specified mnemonic
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM,I like the change to PrivateHDFS
.
Left a minor remark about code style
), | ||
AccountLockerClaimableResource.Fungible( | ||
resourceAddress = ResourceAddress.init("resource_rdx1tknxxxxxxxxxradxrdxxxxxxxxx009923554798xxxxxxxxxradxrd"), | ||
amount = 1500.toDecimal192() | ||
), | ||
AccountLockerClaimableResource.NonFungible( | ||
resourceAddress = ResourceAddress.init("resource_rdx1n2ekdd2m0jsxjt9wasmu3p49twy2yfalpaa6wf08md46sk8dfmldnd"), | ||
ids = listOf(NonFungibleLocalId.stringId("foobar")) | ||
numberOfItems = 1.toULong() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry about this, it escaped me while working on the account locker. It's good that we have the kotlin-test workflow fixed now and it shouldn't happen anymore.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @sergiupuhalschi-rdx wanted to ask you about this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great job! It's impressive how you found what was the issue with the Keystore secret key generation and fixed it 🏅
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! Amazing work 🔥!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🦅
@GhenadieVP Latest commit 8505a88 addresses deleting old ephemeral profile and associated mnemonic when booting again. |
* wip * wip * fix test * wip * fix ios tests * test * update * wip
* wip * fix * fix * wip * wip * wip
Sargon Rust changes
derive_wallet
in sargon os. This method can be used when restoring a profile from only a seed phrase and some accounts retrieved from GW.SecureStorageAccessError
. This is used specifically in Android were the secure storage driver may fail to read from or write to secure storage key which is secured under biometrics. Currently mnemonics fall under this category. This error can be caused by several states of the system. Since I didn't want to make this Android specific, I introducedSecureStorageAccessErrorKind
which will mostly be used for Android. Most of these kinds are system related and two are related to the user cancelling the authorisation. Although, a suggestion, would be for iOS to returnSecureStorageAccessError(errorKind: .userCancelled)
, maybe when authorisation is cancelled since this seems to be the only possible error on iOS. Whatever the decision is, it will not make any difference.Sargon Android changes
SargonOsManager
: Holds a reference to sargon os. Boots sargon when initialised. Implemented as a singleton.AndroidProfileStateChangeDriver
: Holds the state of the currentProfileState
no need for the host to do that.encrypt
method to first encrypt and then encode to base64 and not the other way around. This was a bug.KeySpec. reset
. Please take a look at its doc to understand what it does and what problems it fixes especially onAndroid API <= 30