feature(@desktop/keycard): generating addresses on a Keycard
Generating addresses was done on the status-go side, but now since `ExportPublic` flow from the keycard library supports deriving addresses for list of derivation paths we're using it in the desktop app for `SetupNewKeycardNewSeedPhrase` flow.
This commit is contained in:
parent
0e65f2a7ff
commit
8600ef35b3
|
@ -420,12 +420,18 @@ proc runStoreMetadataFlow*(self: Controller, cardName: string, pin: string, wall
|
|||
self.cancelCurrentFlow()
|
||||
self.keycardService.startStoreMetadataFlow(cardName, pin, walletPaths)
|
||||
|
||||
proc runDeriveAccountFlow*(self: Controller, bip44Path = "", pin = "") =
|
||||
proc runDeriveAccountFlow*(self: Controller, bip44Path: string, pin: string) =
|
||||
if not serviceApplicable(self.keycardService):
|
||||
return
|
||||
self.cancelCurrentFlow()
|
||||
self.keycardService.startExportPublicFlow(bip44Path, exportMasterAddr=true, exportPrivateAddr=false, pin)
|
||||
|
||||
proc runDeriveAccountFlow*(self: Controller, bip44Paths: seq[string], pin: string) =
|
||||
if not serviceApplicable(self.keycardService):
|
||||
return
|
||||
self.cancelCurrentFlow()
|
||||
self.keycardService.startExportPublicFlow(bip44Paths, exportMasterAddr=true, exportPrivateAddr=false, pin)
|
||||
|
||||
proc runAuthenticationFlow*(self: Controller, keyUid = "") =
|
||||
## For signing a transaction we need to provide a key uid of a keypair that an account we want to sign a transaction
|
||||
## for belongs to. If we're just doing an authentication for a logged in user, then default key uid is always the key
|
||||
|
|
|
@ -2,18 +2,10 @@ type
|
|||
CreatingAccountNewSeedPhraseState* = ref object of State
|
||||
paths: seq[string]
|
||||
addresses: seq[string]
|
||||
addingAccountsToWalletDone: bool
|
||||
addingAccountsToWalletOk: bool
|
||||
addingMigratedKeypairDone: bool
|
||||
addingMigratedKeypairOk: bool
|
||||
|
||||
proc newCreatingAccountNewSeedPhraseState*(flowType: FlowType, backState: State): CreatingAccountNewSeedPhraseState =
|
||||
result = CreatingAccountNewSeedPhraseState()
|
||||
result.setup(flowType, StateType.CreatingAccountNewSeedPhrase, backState)
|
||||
result.addingAccountsToWalletDone = false
|
||||
result.addingAccountsToWalletOk = false
|
||||
result.addingMigratedKeypairDone = false
|
||||
result.addingMigratedKeypairOk = false
|
||||
|
||||
proc delete*(self: CreatingAccountNewSeedPhraseState) =
|
||||
self.State.delete
|
||||
|
@ -26,17 +18,28 @@ proc resolvePaths(self: CreatingAccountNewSeedPhraseState, controller: Controlle
|
|||
self.paths.add(account.getPath())
|
||||
i.inc
|
||||
|
||||
proc resolveAddressesForPaths(self: CreatingAccountNewSeedPhraseState, controller: Controller) =
|
||||
proc findIndexForPath(self: CreatingAccountNewSeedPhraseState, path: string): int =
|
||||
var ind = -1
|
||||
for p in self.paths:
|
||||
ind.inc
|
||||
if p == path:
|
||||
return ind
|
||||
return ind
|
||||
|
||||
proc resolveAddresses(self: CreatingAccountNewSeedPhraseState, controller: Controller, keycardEvent: KeycardEvent): bool =
|
||||
if keycardEvent.generatedWalletAccounts.len != self.paths.len:
|
||||
return false
|
||||
let kpForPRocessing = controller.getKeyPairForProcessing()
|
||||
let generatedAccount = controller.generateAccountsFromSeedPhrase(controller.getSeedPhrase(), self.paths)
|
||||
for account in kpForPRocessing.getAccountsModel().getItems():
|
||||
if not generatedAccount.derivedAccounts.derivations.hasKey(account.getPath()):
|
||||
return
|
||||
kpForPRocessing.setDerivedFrom(generatedAccount.address)
|
||||
let accDetails = generatedAccount.derivedAccounts.derivations[account.getPath()]
|
||||
account.setAddress(accDetails.address)
|
||||
account.setPubKey(accDetails.publicKey)
|
||||
self.addresses.add(accDetails.address)
|
||||
let index = self.findIndexForPath(account.getPath())
|
||||
if index == -1:
|
||||
## should never be here
|
||||
return false
|
||||
kpForPRocessing.setDerivedFrom(keycardEvent.masterKeyAddress)
|
||||
account.setAddress(keycardEvent.generatedWalletAccounts[index].address)
|
||||
account.setPubKey(keycardEvent.generatedWalletAccounts[index].publicKey)
|
||||
self.addresses.add(keycardEvent.generatedWalletAccounts[index].address)
|
||||
return true
|
||||
|
||||
proc addAccountsToWallet(self: CreatingAccountNewSeedPhraseState, controller: Controller): bool =
|
||||
let kpForPRocessing = controller.getKeyPairForProcessing()
|
||||
|
@ -68,32 +71,18 @@ proc runStoreMetadataFlow(self: CreatingAccountNewSeedPhraseState, controller: C
|
|||
|
||||
method executePrePrimaryStateCommand*(self: CreatingAccountNewSeedPhraseState, controller: Controller) =
|
||||
if self.flowType == FlowType.SetupNewKeycardNewSeedPhrase:
|
||||
if not self.addingAccountsToWalletDone:
|
||||
self.addingAccountsToWalletDone = true
|
||||
self.resolvePaths(controller)
|
||||
self.resolveAddressesForPaths(controller)
|
||||
if self.paths.len != self.addresses.len:
|
||||
return
|
||||
self.addingAccountsToWalletOk = self.addAccountsToWallet(controller)
|
||||
if self.addingAccountsToWalletOk:
|
||||
self.doMigration(controller)
|
||||
self.resolvePaths(controller)
|
||||
controller.runDeriveAccountFlow(bip44Paths = self.paths, controller.getPin())
|
||||
|
||||
method executePreSecondaryStateCommand*(self: CreatingAccountNewSeedPhraseState, controller: Controller) =
|
||||
## Secondary action is called after each async action during migration process.
|
||||
if not self.addingMigratedKeypairDone:
|
||||
self.addingMigratedKeypairDone = true
|
||||
self.addingMigratedKeypairOk = controller.getAddingMigratedKeypairSuccess()
|
||||
if self.addingMigratedKeypairOk:
|
||||
self.runStoreMetadataFlow(controller)
|
||||
|
||||
method getNextPrimaryState*(self: CreatingAccountNewSeedPhraseState, controller: Controller): State =
|
||||
## Secondary action is called after each async action during migration process, in this case after `addMigratedKeyPair`.
|
||||
if self.flowType == FlowType.SetupNewKeycardNewSeedPhrase:
|
||||
if self.addingAccountsToWalletDone and not self.addingAccountsToWalletOk:
|
||||
return createState(StateType.CreatingAccountNewSeedPhraseFailure, self.flowType, nil)
|
||||
if controller.getAddingMigratedKeypairSuccess():
|
||||
self.runStoreMetadataFlow(controller)
|
||||
|
||||
method getNextSecondaryState*(self: CreatingAccountNewSeedPhraseState, controller: Controller): State =
|
||||
if self.flowType == FlowType.SetupNewKeycardNewSeedPhrase:
|
||||
if self.addingMigratedKeypairDone and not self.addingMigratedKeypairOk:
|
||||
if not controller.getAddingMigratedKeypairSuccess():
|
||||
return createState(StateType.CreatingAccountNewSeedPhraseFailure, self.flowType, nil)
|
||||
|
||||
method resolveKeycardNextState*(self: CreatingAccountNewSeedPhraseState, keycardFlowType: string, keycardEvent: KeycardEvent,
|
||||
|
@ -102,6 +91,17 @@ method resolveKeycardNextState*(self: CreatingAccountNewSeedPhraseState, keycard
|
|||
if not state.isNil:
|
||||
return state
|
||||
if self.flowType == FlowType.SetupNewKeycardNewSeedPhrase:
|
||||
if keycardFlowType == ResponseTypeValueKeycardFlowResult and
|
||||
keycardEvent.error.len == 0:
|
||||
return createState(StateType.CreatingAccountNewSeedPhraseSuccess, self.flowType, nil)
|
||||
if controller.getCurrentKeycardServiceFlow() == KCSFlowType.ExportPublic:
|
||||
if keycardFlowType == ResponseTypeValueKeycardFlowResult and
|
||||
keycardEvent.error.len == 0:
|
||||
if not self.resolveAddresses(controller, keycardEvent):
|
||||
return createState(StateType.CreatingAccountNewSeedPhraseFailure, self.flowType, nil)
|
||||
if not self.addAccountsToWallet(controller):
|
||||
return createState(StateType.CreatingAccountNewSeedPhraseFailure, self.flowType, nil)
|
||||
self.doMigration(controller)
|
||||
return nil # returning nil, cause we need to remain in this state
|
||||
if controller.getCurrentKeycardServiceFlow() == KCSFlowType.StoreMetadata:
|
||||
if keycardFlowType == ResponseTypeValueKeycardFlowResult and
|
||||
keycardEvent.error.len == 0:
|
||||
return createState(StateType.CreatingAccountNewSeedPhraseSuccess, self.flowType, nil)
|
||||
return createState(StateType.CreatingAccountNewSeedPhraseSuccess, self.flowType, nil)
|
|
@ -42,6 +42,7 @@ type
|
|||
pukRetries*: int
|
||||
cardMetadata*: CardMetadata
|
||||
generatedWalletAccount*: GeneratedWalletAccount
|
||||
generatedWalletAccounts*: seq[GeneratedWalletAccount]
|
||||
txSignature*: TransactionSignature
|
||||
eip1581Key*: KeyDetails
|
||||
encryptionKey*: KeyDetails
|
||||
|
@ -127,8 +128,12 @@ proc toKeycardEvent(jsonObj: JsonNode): KeycardEvent =
|
|||
if(jsonObj.getProp(ResponseParamCardMeta, obj)):
|
||||
result.cardMetadata = toCardMetadata(obj)
|
||||
|
||||
if(jsonObj.getProp(ResponseParamExportedKey, obj)):
|
||||
result.generatedWalletAccount = toGeneratedWalletAccount(obj)
|
||||
if jsonObj.getProp(ResponseParamExportedKey, obj):
|
||||
if obj.kind == JArray:
|
||||
for o in obj:
|
||||
result.generatedWalletAccounts.add(toGeneratedWalletAccount(o))
|
||||
else:
|
||||
result.generatedWalletAccount = toGeneratedWalletAccount(obj)
|
||||
|
||||
if(jsonObj.getProp(ResponseParamTXSignature, obj)):
|
||||
result.txSignature = toTransactionSignature(obj)
|
|
@ -242,6 +242,8 @@ QtObject:
|
|||
self.startFlow(payload)
|
||||
|
||||
proc startExportPublicFlow*(self: Service, path: string, exportMasterAddr = false, exportPrivateAddr = false, pin = "") =
|
||||
## Exports addresses for passed `path`. Result of this flow sets instance of `GeneratedWalletAccount` under
|
||||
## `generatedWalletAccount` property in `KeycardEvent`.
|
||||
if exportPrivateAddr and not path.startsWith(DefaultEIP1581Path):
|
||||
error "in order to export private address path must not be outside of eip1581 tree"
|
||||
return
|
||||
|
@ -258,6 +260,28 @@ QtObject:
|
|||
self.currentFlow = KCSFlowType.ExportPublic
|
||||
self.startFlow(payload)
|
||||
|
||||
proc startExportPublicFlow*(self: Service, paths: seq[string], exportMasterAddr = false, exportPrivateAddr = false, pin = "") =
|
||||
## Exports addresses for passed `path`. Result of this flow sets array of `GeneratedWalletAccount` under
|
||||
## `generatedWalletAccounts` property in `KeycardEvent`. The order of keys set in `generatedWalletAccounts` array
|
||||
## mathch the order of `paths` sent to this flow.
|
||||
if exportPrivateAddr:
|
||||
for p in paths:
|
||||
if not p.startsWith(DefaultEIP1581Path):
|
||||
error "one of paths in the list refers to a private address path which is not in eip1581 tree"
|
||||
return
|
||||
|
||||
var payload = %* {
|
||||
RequestParamBIP44Path: DefaultBIP44Path,
|
||||
RequestParamExportMasterAddress: exportMasterAddr,
|
||||
RequestParamExportPrivate: exportPrivateAddr
|
||||
}
|
||||
if paths.len > 0:
|
||||
payload[RequestParamBIP44Path] = %* paths
|
||||
if pin.len > 0:
|
||||
payload[RequestParamPIN] = %* pin
|
||||
self.currentFlow = KCSFlowType.ExportPublic
|
||||
self.startFlow(payload)
|
||||
|
||||
proc startStoreMetadataFlow*(self: Service, cardName: string, pin: string, walletPaths: seq[string]) =
|
||||
var name = cardName
|
||||
if cardName.len > CardNameLength:
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit e4fef0fb362ca5e48292d916c83c8aaefa7ac6fa
|
||||
Subproject commit b50cfe22ac3802d508e34b0561095c7100f6efa8
|
Loading…
Reference in New Issue