Skip to content

Qr code based hw integration#2280

Open
Maskln wants to merge 22 commits intov2from
qr-code-based-hw-integration
Open

Qr code based hw integration#2280
Maskln wants to merge 22 commits intov2from
qr-code-based-hw-integration

Conversation

@Maskln
Copy link
Copy Markdown
Member

@Maskln Maskln commented Mar 25, 2026

paired with: https://github.com/AmbireTech/ambire-app/pull/6803

Summary

  • QR HW wallet support (base layer): types, interfaces, and extensibility for multiple QR wallets
  • Signer updates: QR-specific state + request/response flow handling
  • Account Picker: QR import flow via QrKeyIterator + new init handler
  • Signatures: added normalizeSignatureHex (supports {r,s,v} + hex)
  • Misc: status wiring + type cleanups for future integrations

@Maskln Maskln requested review from Oxbobby and superKalo March 25, 2026 13:30
@Oxbobby Oxbobby added the enhancement New feature or request label Mar 26, 2026
keyType === 'qr'
? this.keyIterator.parsedAccount?.hdPath ||
this.keyIterator.parsedAccount?.accounts?.[0]?.hdPath
: undefined
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@superKalo I'm not proficient enough here so tagging Kalo for assistance.

I guess I'm wondering why do we have different hd paths for accounts? And is it safe that we're not using an account specific hdPath for qr accounts but defaulting to this.keyIterator.parsedAccount?.hdPath for each one of them?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Yeah, good catch.

The hd path is critical to know, since we calculate the next accounts ourselves from the xpub of the first account we receive from the QR code.

So in this case I'd advice in the key iterator - we make sure the hdPath of the first account exists and if not - to fallback with the standard hd path in there. So on this level (in the AccountPicker) - we should always have the hdPath and throw if missing.

keyType === 'qr' && qrWalletConfig
? qrWalletConfig.hdPathTemplate || this.hdPathTemplate
: this.hdPathTemplate
) as HD_PATH_TEMPLATE_TYPE
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I see we prioritize qrWalletConfig.hdPathTemplate here. What if the user has changed this from the UI?
My questions are:

  1. Is the user allowed to change his hdPathTemplate from the UI
  2. If yes, would be reflected in qrWalletConfig.hdPathTemplate (I don't think so as this happens in setHDPathTemplate)

Imo, it would be better to find a way to use the controller this.hdPathTemplate at all times. Maybe set it initially from the qrWalletConfig and allow the UI to dispatch changes after

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

  1. I think the answer is no - hd path should not be changable in our UI. But we should test with different hd path set on the hardware wallet (e. g. on imToken wallet) or in general - what's the flow other wallets do for different than standard hd path.

@Maskln Maskln requested a review from Oxbobby April 1, 2026 13:15
hdPathTemplate: this.hdPathTemplate as HD_PATH_TEMPLATE_TYPE,
hdPathTemplate: hdPathTemplate,
relativePathTemplate: relativePathTemplate,
originHdPath: originPath,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I don't like this part. It has a lot of noise.

For all external signers we have hdPathTemplate, which is for example: m/44'/60'/0'/0/<account>

So why we need extra 2 props relativePathTemplate (example: 0/{index}) and originHdPath (example: m/44'/60'/0')? Can't we just calculate them based on the hdPathTemplate?

Also, why mixing <account> (that we already use for all) and {index}. They mean the same thing.

Also, it's strange that these two values are only set for QR-based wallets and would be undefined for all others. If they are QR-based specifics only, why don't we name them somehow indicating that (same applies for (masterFingerprint, naming doesn't suggest it's QR-based wallets only and for all others - would be undefined)

hdPathTemplate: keyIterator.walletConfig!.hdPathTemplate,
pageSize: 5,
shouldAddNextAccountAutomatically: false,
shouldSearchForLinkedAccounts: false
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Please add context why searching for linked accounts is disabled. Otherwise, it will get lost in the Slack discussions. Base on memory, it was decided like so for simplicity sake?


qrWalletType?: QrWalletType
qrProtocol?: QrProtocolType
originHdPath?: string // for accounts imported from QR, to store the original path used on the wallet, as some wallets (like Keystone) don't provide the possibility to retrieve the key by xpub, but only by path, so we need to keep track of it in order to be able to retrieve the key later on
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can you give an example how this is different than the combo between the existing hdPathTemplate and the index props?

qrProtocol?: QrProtocolType
originHdPath?: string // for accounts imported from QR, to store the original path used on the wallet, as some wallets (like Keystone) don't provide the possibility to retrieve the key by xpub, but only by path, so we need to keep track of it in order to be able to retrieve the key later on
masterFingerprint?: string // for Ledger, optional for others, as it can be used for additional info but is not required to retrieve the key
relativePathTemplate?: string // QR related
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can you give an example how this is different than the combo between the existing hdPathTemplate and the index props?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants