Skip to content

Commit

Permalink
fix: show h instead of apostrophe in taproot xpub to be consistent wi…
Browse files Browse the repository at this point in the history
…th firmware
  • Loading branch information
peter-sanderson committed Dec 20, 2024
1 parent ea0831a commit 42b5a9e
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 16 deletions.
45 changes: 30 additions & 15 deletions packages/connect/src/device/resolveDescriptorForTaproot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,41 @@ interface Params {
publicKey: Messages.PublicKey;
}

export type ConvertTaprootXpubProps = {
xpub: string;
direction: 'h-to-apostrophe' | 'apostrophe-to-h';
};

export const convertTaprootXpub = ({ xpub, direction }: ConvertTaprootXpubProps) => {
const find = direction === 'h-to-apostrophe' ? 'h' : "'";
const replace = direction === 'h-to-apostrophe' ? "'" : 'h';

// This is here to keep backwards compatibility, suite and blockbooks are still using `'` over `h`
const openingSquareBracketSplit = xpub.split('[');
if (openingSquareBracketSplit.length === 2) {
const [beforeOpeningBracket, afterOpeningBracket] = openingSquareBracketSplit;

const closingSquareBracketSplit = afterOpeningBracket.split(']');
if (closingSquareBracketSplit.length === 2) {
const [path, afterClosingBracket] = closingSquareBracketSplit;

const correctedPath = path.replace(new RegExp(find, 'g'), replace); // .replaceAll()

return `${beforeOpeningBracket}[${correctedPath}]${afterClosingBracket}`;
}
}

return null;
};

export const resolveDescriptorForTaproot = ({ response, publicKey }: Params) => {
if (publicKey.descriptor !== null && publicKey.descriptor !== undefined) {
const [xpub, checksum] = publicKey.descriptor.split('#');

// This is here to keep backwards compatibility, suite and blockbooks are still using `'` over `h`
const openingSquareBracketSplit = xpub.split('[');
if (openingSquareBracketSplit.length === 2) {
const [beforeOpeningBracket, afterOpeningBracket] = openingSquareBracketSplit;

const closingSquareBracketSplit = afterOpeningBracket.split(']');
if (closingSquareBracketSplit.length === 2) {
const [path, afterClosingBracket] = closingSquareBracketSplit;

const correctedPath = path.replace(/h/g, "'"); // .replaceAll()
const correctedXpub = convertTaprootXpub({ xpub, direction: 'h-to-apostrophe' });

return {
xpub: `${beforeOpeningBracket}[${correctedPath}]${afterClosingBracket}`,
checksum,
};
}
if (correctedXpub !== null) {
return { xpub: correctedXpub, checksum };
}
}

Expand Down
1 change: 1 addition & 0 deletions packages/connect/src/exports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ export * from './events';
export * from './types';

export { parseConnectSettings } from './data/connectSettings';
export { convertTaprootXpub } from './device/resolveDescriptorForTaproot';
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { selectSelectedDevice } from '@suite-common/wallet-core';
import { convertTaprootXpub } from '@trezor/connect';

import { Translation } from 'src/components/suite';
import { showXpub } from 'src/actions/wallet/publicKeyActions';
Expand Down Expand Up @@ -26,6 +27,13 @@ export const ConfirmXpubModal = (
? `${account.descriptor}#${account.descriptorChecksum}`
: account.descriptor;

// Suite internally uses apostrophe, but FW uses 'h' for taproot descriptors
// and we want to show it correctly to the user
const xpubWithReplacedApostropheWithH = convertTaprootXpub({
xpub,
direction: 'apostrophe-to-h',
});

return (
<ConfirmValueModal
account={account}
Expand All @@ -46,7 +54,7 @@ export const ConfirmXpubModal = (
confirmStepLabel={<Translation id="TR_XPUB_MATCH" />}
validateOnDevice={showXpub}
copyButtonText={<Translation id="TR_XPUB_MODAL_CLIPBOARD" />}
value={xpub}
value={xpubWithReplacedApostropheWithH}
displayMode={DisplayMode.PAGINATED_TEXT}
{...props}
/>
Expand Down

0 comments on commit 42b5a9e

Please sign in to comment.