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

Feature persistent store #22

Merged
merged 41 commits into from
Apr 23, 2021
Merged

Conversation

w-i-n-s
Copy link
Contributor

@w-i-n-s w-i-n-s commented Mar 12, 2021

This PR will resolve next issues:

* upstream/master:
  Fix address screen layout constraint, close Sjors#13
@Sjors
Copy link
Owner

Sjors commented Mar 25, 2021

Several tests are failing at the moment on Travis: https://travis-ci.com/github/Sjors/nthkey-ios/builds/220832007#L997

Please let me know when you think it's ready to test.

Copy link
Owner

@Sjors Sjors left a comment

Choose a reason for hiding this comment

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

Would it make sense to move NthKey.xcdatamodeld from SupportingFiles to Model?

NthKey/Model/DataManager.swift Outdated Show resolved Hide resolved
Copy link
Owner

@Sjors Sjors left a comment

Choose a reason for hiding this comment

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

The order here is a bit confusing:

Schermafbeelding 2021-04-05 om 13 15 25

The Mainnet / Testnet toggle only applies to the creation of a new wallet. Let's handle wallet creation in a model window (both Announce and adding by QR / JSON). However, this can be done in a followup PR.

I created a fresh seed and a multisig wallet with Specter, on testnet. For some reason the addresses don't match between Specter and the simulator.

NthKey/View/Settings/Wallet/WalletListView.swift Outdated Show resolved Hide resolved
NthKey/View/Settings/Wallet/WalletListView.swift Outdated Show resolved Hide resolved
NthKey/View/Settings/Wallet/WalletEntityView.swift Outdated Show resolved Hide resolved
@w-i-n-s
Copy link
Contributor Author

w-i-n-s commented Apr 6, 2021

@Sjors

I created a fresh seed and a multisig wallet with Specter, on testnet. For some reason the addresses don't match between Specter and the simulator.

Yes, the addresses creation process didn't take into account all the cosigners keys, just fixed it in f303327.

Note: Please remove the old wallet before your test. It can be performed by the long tap (UX isn't perfect for the moment). Because on addresses tab you can see addresses for the selected wallet, and if you just add new one (application didn't block you to add several copies of the same wallet for the moment) it will be hard to select right wallet.

@Sjors
Copy link
Owner

Sjors commented Apr 6, 2021

When scanning a QR code (or reading JSON) from Specter to import a wallet, you want to sanity check the network. Here's an example:

{ 
  "label": "NanoS with iPhone 12 simulator",
  "blockheight": 0,
  "descriptor": "wsh(sortedmulti(1,[048117aa\/48h\/1h\/0h\/2h]tpubDF5EvuWLmn6qak12tkKAi6wFHBBYFg22RxNycBHfMk43FeKgz5chhv1UANVuAmbF3PQopymtH54B1pKJomeMrH8cY9RUf6e51Dtt9vFxfsj\/0\/*,[ee081656\/48h\/1h\/0h\/2h]tpubDFFahYHoXpUZfqXEAP1KcuMCvJZ1s815LHFTtayUsg13GiZeJt9zvhx11bYRioSaxJ2FmjNaKN3Wjezbr5t3FxbD3yqJ5F22Gfds551iASQ\/0\/*))#99ajkvkr"
}

Ideally Specter should add a field with the network type, but the alternative way is to look at the xpub / tpub in descriptor. tpub is for testnet (and signet), xpub for mainnet.

If the user tries to import a wallet for the wrong network, just give an error. That should reduce complexity a bit in that last commit.

@w-i-n-s
Copy link
Contributor Author

w-i-n-s commented Apr 6, 2021

@Sjors

The order here is a bit confusing:
The Mainnet / Testnet toggle only applies to the creation of a new wallet. Let's handle wallet creation in a model window (both Announce and adding by QR / JSON). However, this can be done in a followup PR.

Yes, it is a good idea to guide user throw the "Add wallet" flow (Show QR to specter and scan QR from it to complete). I'll create issue for it.

Also, as I mention in #22 (comment) we have the same fingerprint for testnet/mainnet and we cannot separate which network contains the Specter wallet QR. So, better to ask user about it and remove toggle from AnnounceView

I'll follow you #22 (comment)

@Sjors
Copy link
Owner

Sjors commented Apr 6, 2021

I deleted and reimported the wallet, but the addresses are still not correct. In the above descriptor, the first address should be tb1q6um5p5gf5uhkwfw8t9g4rvlam7rxrah2n70sxx3j2h6s9sf8rpmqj2ktty) . I also notice it sometimes imports as testnet and other times as mainnet. Using a modal window, where the user first selects the network, should make all this less confusing (see #22 (review)).

The device fingerprint is the same for all networks; that's just the BIP32 standard.

@w-i-n-s
Copy link
Contributor Author

w-i-n-s commented Apr 6, 2021

I deleted and reimported the wallet, but the addresses are still not correct. In the above descriptor, the first address should be tb1q6um5p5gf5uhkwfw8t9g4rvlam7rxrah2n70sxx3j2h6s9sf8rpmqj2ktty) . I also notice it sometimes imports as testnet and other times as mainnet. Using a modal window, where the user first selects the network, should make all this less confusing (see #22 (review)).

Yes, the network recognition not working correctly at the moment, I'll fix it soon and let you know.

The device fingerprint is the same for all networks; that's just the BIP32 standard.

Okay, got it.

@@ -53,13 +53,9 @@ struct SeedManager {
precondition(false)
}
let seedHex = BIP39Mnemonic(entropy)!.seedHex()
let masterKey = HDKey(seedHex, .testnet)! // FIXME: HDKey in this case shouldn't depend on network, because fingerprint is unique for the device
Copy link
Owner

Choose a reason for hiding this comment

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

The HDKey object does depend on the network, but its fingerprint doesn't (please check). For the purpose of this function, using .mainnet looks better.
https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#master-key-generation

The differentiation between mainnet and testnet happens at depth 2: e.g. m/84'/0' (mainnet) vs m/84'/1' (testnet), but this doesn't really matter in practice.

Copy link
Contributor Author

@w-i-n-s w-i-n-s Apr 8, 2021

Choose a reason for hiding this comment

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

@Sjors Yes, the fingerprint is the same, but HDKey is network-relewant, just check it. Okay, we'll use .mainnet here. fixed in bcda176

var receivedNetwork: Network?
for key in desc.extendedKeys {
var keyNetwork: Network?
switch key.xpub.prefix(4) {
Copy link
Owner

Choose a reason for hiding this comment

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

Instead of parsing the string like this, I think you can use the HDKey constructor in LibWally with the full string and see which network it returns?

Copy link
Owner

Choose a reason for hiding this comment

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

This initiliazer:
https://github.com/blockchain/libwally-swift/blob/master/LibWally/BIP32.swift#L157

And then HDKey class has a method which uses libwally-core internals to figure out the network: https://github.com/blockchain/libwally-swift/blob/master/LibWally/BIP32.swift#L213

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@Sjors Yes, you are right. fixed in 8d06e25

@Sjors
Copy link
Owner

Sjors commented Apr 8, 2021

Alright, this seems to work! Can you tidy up the commits a bit, and maybe test it yourself with Specter? I'll then give it a final review and merge. I made some issues for (minor) improvements here: https://github.com/Sjors/nthkey-ios/milestone/1

@w-i-n-s
Copy link
Contributor Author

w-i-n-s commented Apr 9, 2021

@Sjors

Alright, this seems to work! Can you tidy up the commits a bit, and maybe test it yourself with Specter?

Sure, I test all cases for the scope before each commit. I mean small scope as a small piece of the whole task.

I'll then give it a final review and merge. I made some issues for (minor) improvements here: https://github.com/Sjors/nthkey-ios/milestone/1

It isn't ready yet.

  • sign PSBT. Required in this PR
  • mark an address as used (at the moment I didn't find a way to do it). Not required in this PR - could you please advice me?
  • TBC: Arrange the whole PR by commits (even rewrite the whole history of PR). For now, it seems dirty to me.

@Sjors
Copy link
Owner

Sjors commented Apr 9, 2021

mark an address as used

This can wait.

@w-i-n-s
Copy link
Contributor Author

w-i-n-s commented Apr 19, 2021

@Sjors

Please let me know when you think it's ready to test.
Now it ready for the manual tests. User can export device creds -> import wallet -> check list of addresses -> load and sign a transactions.

@w-i-n-s w-i-n-s marked this pull request as ready for review April 19, 2021 07:56
@w-i-n-s w-i-n-s changed the title WIP: Feature persistent store Feature persistent store Apr 19, 2021
@Sjors
Copy link
Owner

Sjors commented Apr 19, 2021

Recovering from a mnemonic works. Importing a wallet from Specter works. Receive addresses are correct. But the send tab has issues.

For some reason it's no longer hiding the change address. The 9899836 sats at the top should be hidden, because we can detect it's change.

Schermafbeelding 2021-04-19 om 11 00 10

The PSBT on clipboard is correct. The saved PSBT binary is also correct. But the QR is broken (obviously, it's too small):
IMG_7738

signer.hdKey
}
let us = Signer.getOurselfSigner()

self.isChange = output.isChange(signer: us.hdKey, inputs: inputs, cosigners: cosignerKeys, threshold: threshold)
Copy link
Owner

@Sjors Sjors Apr 19, 2021

Choose a reason for hiding this comment

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

Maybe cosignerKeys is not passed in correctly here, causing the change detection to break?
Schermafbeelding 2021-04-19 om 11 22 33

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@Sjors Actually, HDKeys did initialization use only description, without fingerprint (fixed in f880dcc). QR code was just a placeholder, after last fixes everything should work as far as my test shows same flow between master and current branch

prepare for handle scans
fix default wallet selection
add sign view model,
add code signers view model,
add data manager empty mock,
remove cosigners / hasWallet / fingerprint / mainnet saved values from user defaults,
add fingerprints foa all networks to user default saved values,
limit psbt manager / Signer / Document picker filename to testnet fo a while,
switch off "should have cosigners" precondition on sign view controller,
rename WalletManager to SeedManager,
remove unused code
fix wallet selection
move threshold to co-signers section
refactoring SignView and it model to FSM,
refactor SignViewController from UIHostingController to regular view controller,
remove threshold from UserDefaults,
remove Cosigners from Signer
@github-pages github-pages bot temporarily deployed to github-pages April 23, 2021 08:35 Inactive
@Sjors Sjors merged commit 907c8d5 into Sjors:master Apr 23, 2021
@Sjors Sjors mentioned this pull request Apr 23, 2021
2 tasks
@w-i-n-s w-i-n-s deleted the feature_persistent_store branch April 23, 2021 12:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants