Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 39 additions & 2 deletions ui/hooks/useMultichainAccountsIntroModal.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { lt as semverLt } from 'semver';
import { lt as semverLt, coerce as semverCoerce } from 'semver';

// Test the core logic independently of React hooks
describe('BIP-44 Banner Logic', () => {
Expand All @@ -16,7 +16,17 @@ describe('BIP-44 Banner Logic', () => {
const isUpgradeFromLowerThanBip44Version = Boolean(
lastUpdatedFromVersion &&
typeof lastUpdatedFromVersion === 'string' &&
semverLt(lastUpdatedFromVersion, BIP44_ACCOUNTS_INTRODUCTION_VERSION),
(() => {
try {
const coercedVersion = semverCoerce(lastUpdatedFromVersion);
return (
coercedVersion &&
semverLt(coercedVersion, BIP44_ACCOUNTS_INTRODUCTION_VERSION)
);
} catch {
return false;
}
})(),
);

return (
Expand Down Expand Up @@ -171,5 +181,32 @@ describe('BIP-44 Banner Logic', () => {
);
expect(result).toBe(false);
});

it('handles invalid semver version like 13.9.0.150 (4-part version)', () => {
// This tests the bug fix for extensions with non-standard version formats
const result = shouldShowBip44Banner(
true,
true,
false,
Date.now(),
'13.9.0.150', // Invalid semver - 4 parts
true,
);
// Should gracefully handle and return false (coerced to 13.9.0 which is >= 13.5.0)
expect(result).toBe(false);
});

it('handles invalid semver for older version like 13.4.0.100', () => {
const result = shouldShowBip44Banner(
true,
true,
false,
Date.now(),
'13.4.0.100', // Invalid semver - 4 parts, but coerces to 13.4.0
true,
);
// Should coerce to 13.4.0 and show banner
expect(result).toBe(true);
});
});
});
16 changes: 14 additions & 2 deletions ui/hooks/useMultichainAccountsIntroModal.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useState, useEffect } from 'react';
import { lt as semverLt } from 'semver';
import { lt as semverLt, coerce as semverCoerce } from 'semver';
import { useAppSelector } from '../store/store';
import { getIsMultichainAccountsState2Enabled } from '../selectors/multichain-accounts/feature-flags';
import { getLastUpdatedFromVersion } from '../selectors/selectors';
Expand Down Expand Up @@ -40,10 +40,22 @@ export function useMultichainAccountsIntroModal(
const isMainWalletArea = location.pathname === DEFAULT_ROUTE;

// Check if this is an upgrade from a version lower than BIP-44 introduction version
// Extension versions may not be valid semver therefore we coerce them first
const isUpgradeFromLowerThanBip44Version = Boolean(
lastUpdatedFromVersion &&
typeof lastUpdatedFromVersion === 'string' &&
semverLt(lastUpdatedFromVersion, BIP44_ACCOUNTS_INTRODUCTION_VERSION),
(() => {
try {
const coercedVersion = semverCoerce(lastUpdatedFromVersion);
return (
coercedVersion &&
semverLt(coercedVersion, BIP44_ACCOUNTS_INTRODUCTION_VERSION)
);
} catch {
// If version can't be parsed, assume it's not from an old version
return false;
}
})(),
);

// Show modal only for upgrades from versions < BIP-44 introduction version
Expand Down
Loading