Skip to content

Commit 175470e

Browse files
authored
Merge branch 'main' into SOL-277-solana-banner
2 parents 5a45599 + ce70789 commit 175470e

File tree

11 files changed

+170
-37
lines changed

11 files changed

+170
-37
lines changed

.github/workflows/e2e-chrome.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@ on:
44
workflow_call:
55

66
jobs:
7-
test-e2e-chrome:
7+
test-e2e-chrome-browserify:
88
uses: ./.github/workflows/run-e2e.yml
99
strategy:
1010
fail-fast: false
1111
matrix:
1212
index:
1313
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
1414
with:
15-
test-suite-name: test-e2e-chrome
15+
test-suite-name: test-e2e-chrome-browserify
1616
build-artifact: prep-build-test-browserify-chrome
1717
build-command: yarn build:test
1818
test-command: yarn test:e2e:chrome
@@ -72,7 +72,7 @@ jobs:
7272

7373
test-e2e-chrome-report:
7474
needs:
75-
- test-e2e-chrome
75+
- test-e2e-chrome-browserify
7676
- test-e2e-chrome-webpack
7777
- test-e2e-chrome-multiple-providers
7878
- test-e2e-chrome-rpc

.github/workflows/e2e-firefox.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@ on:
44
workflow_call:
55

66
jobs:
7-
test-e2e-firefox:
7+
test-e2e-firefox-browserify:
88
uses: ./.github/workflows/run-e2e.yml
99
strategy:
1010
fail-fast: false
1111
matrix:
1212
index:
1313
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
1414
with:
15-
test-suite-name: test-e2e-firefox
15+
test-suite-name: test-e2e-firefox-browserify
1616
build-command: yarn build:test:mv2
1717
test-command: yarn test:e2e:firefox
1818
matrix-index: ${{ matrix.index }}
@@ -33,7 +33,7 @@ jobs:
3333

3434
test-e2e-firefox-report:
3535
needs:
36-
- test-e2e-firefox
36+
- test-e2e-firefox-browserify
3737
- test-e2e-firefox-flask
3838
runs-on: ubuntu-latest
3939
if: ${{ !cancelled() }}

.yarnrc.yml

+7-1
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,14 @@ npmAuditIgnoreAdvisories:
5555
- 1102472
5656

5757
# Issue: Issue: Babel has inefficient RexExp complexity in generated code with .replace when transpiling named capturing groups
58-
# We are ignoring this on March 12, 2025 to unblock CI, we will follow with a proper fix or confirmation this does not affect our users
58+
# We are ignoring this on March 12, 2025 and April 24, 2025 to unblock CI, we will follow with a proper fix or confirmation this does not affect our users
5959
- 1103026
60+
- 1104001
61+
62+
# Issue: ses's global contour bindings leak into Compartment lexical scope
63+
# URL: https://github.com/advisories/GHSA-h9w6-f932-gq62
64+
# We are ignoring this on April 24, 2025 as it does not affect the codebase.
65+
- 1103932
6066

6167
# Temp fix for https://github.com/MetaMask/metamask-extension/pull/16920 for the sake of 11.7.1 hotfix
6268
# This will be removed in this ticket https://github.com/MetaMask/metamask-extension/issues/22299

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1717
### Fixed
1818
- Fix NFT removal on different networks ([#32102](https://github.com/MetaMask/metamask-extension/pull/32102))
1919
- Fix exchange rate lookups on Solana Swap page to prevent crashing when values are undefined ([#32114](https://github.com/MetaMask/metamask-extension/pull/32114))
20+
- updates display decimals in Bridge experience 'More Quotes' section ([#32080](https://github.com/MetaMask/metamask-extension/pull/32080))
2021
- Add Multichain API analytics support ([#32013](https://github.com/MetaMask/metamask-extension/pull/32013))
2122

2223
## [12.15.2]

app/scripts/migrations/154.test.ts

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { migrate, version } from './154';
2+
3+
const oldVersion = 153;
4+
5+
describe(`migration #${version}`, () => {
6+
it('updates the version metadata', async () => {
7+
const oldStorage = {
8+
meta: { version: oldVersion },
9+
data: {},
10+
};
11+
const newStorage = await migrate(oldStorage);
12+
expect(newStorage.meta).toStrictEqual({ version });
13+
});
14+
15+
describe(`migration #${version}`, () => {
16+
it('removes the QueuedRequestController from the state', async () => {
17+
const oldStorage = {
18+
meta: { version: oldVersion },
19+
data: {
20+
QueuedRequestController: {
21+
queuedRequestCount: 0,
22+
},
23+
},
24+
};
25+
const expectedData = {};
26+
const newStorage = await migrate(oldStorage);
27+
28+
expect(newStorage.data).toStrictEqual(expectedData);
29+
});
30+
31+
it('does nothing to other state params', async () => {
32+
const oldStorage = {
33+
meta: { version: oldVersion },
34+
data: {
35+
OtherController: {
36+
someParam: 0,
37+
},
38+
},
39+
};
40+
41+
const expectedData = {
42+
OtherController: {
43+
someParam: 0,
44+
},
45+
};
46+
47+
const newStorage = await migrate(oldStorage);
48+
49+
expect(newStorage.data).toStrictEqual(expectedData);
50+
});
51+
});
52+
});

app/scripts/migrations/154.ts

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { cloneDeep } from 'lodash';
2+
3+
type VersionedData = {
4+
meta: { version: number };
5+
data: Record<string, unknown>;
6+
};
7+
8+
export const version = 154;
9+
10+
/**
11+
* This migration deletes the QueuedRequestController from the state.
12+
*
13+
* @param originalVersionedData - Versioned MetaMask extension state, exactly
14+
* what we persist to dist.
15+
* @param originalVersionedData.meta - State metadata.
16+
* @param originalVersionedData.meta.version - The current state version.
17+
* @param originalVersionedData.data - The persisted MetaMask state, keyed by
18+
* controller.
19+
* @returns Updated versioned MetaMask extension state.
20+
*/
21+
export async function migrate(
22+
originalVersionedData: VersionedData,
23+
): Promise<VersionedData> {
24+
const versionedData = cloneDeep(originalVersionedData);
25+
versionedData.meta.version = version;
26+
transformState(versionedData.data);
27+
return versionedData;
28+
}
29+
30+
function transformState(state: Record<string, unknown>) {
31+
delete state?.QueuedRequestController;
32+
}

app/scripts/migrations/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ const migrations = [
181181
require('./152'),
182182
require('./152.1'),
183183
require('./153'),
184+
require('./154'),
184185
];
185186

186187
export default migrations;

shared/constants/metametrics.ts

-1
Original file line numberDiff line numberDiff line change
@@ -929,7 +929,6 @@ export enum MetaMetricsEventAccountType {
929929

930930
export enum QueueType {
931931
NavigationHeader = 'navigation_header',
932-
QueueController = 'queue_controller',
933932
}
934933

935934
export enum MetaMetricsEventAccountImportType {

ui/pages/bridge/prepare/prepare-bridge-page.tsx

+66-24
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,10 @@ import { useDestinationAccount } from '../hooks/useDestinationAccount';
124124
import { Toast, ToastContainer } from '../../../components/multichain';
125125
import { MultichainNetworks } from '../../../../shared/constants/multichain/networks';
126126
import { useIsTxSubmittable } from '../../../hooks/bridge/useIsTxSubmittable';
127+
import {
128+
fetchAssetMetadata,
129+
toAssetId,
130+
} from '../../../../shared/lib/asset-utils';
127131
import { BridgeInputGroup } from './bridge-input-group';
128132
import { BridgeCTAButton } from './bridge-cta-button';
129133
import { DestinationAccountPicker } from './components/destination-account-picker';
@@ -138,10 +142,6 @@ const PrepareBridgePage = () => {
138142

139143
const fromToken = useSelector(getFromToken);
140144
const fromTokens = useSelector(getTokenList) as TokenListMap;
141-
const isFromTokensLoading = useMemo(
142-
() => Object.keys(fromTokens).length === 0,
143-
[fromTokens],
144-
);
145145

146146
const toToken = useSelector(getToToken) as TmpBridgeToken;
147147

@@ -150,6 +150,14 @@ const PrepareBridgePage = () => {
150150
const fromChain = useSelector(getFromChain);
151151
const toChain = useSelector(getToChain);
152152

153+
const isFromTokensLoading = useMemo(() => {
154+
// This is an EVM token list. Solana tokens should not trigger loading state.
155+
if (fromChain && isSolanaChainId(fromChain.chainId)) {
156+
return false;
157+
}
158+
return Object.keys(fromTokens).length === 0;
159+
}, [fromTokens, fromChain]);
160+
153161
const fromAmount = useSelector(getFromAmount);
154162
const fromAmountInCurrency = useSelector(getFromAmountInCurrency);
155163

@@ -416,34 +424,68 @@ const PrepareBridgePage = () => {
416424
});
417425
};
418426

419-
// fromTokens is for EVM chains so it's ok to lowercase the token address
420-
const matchedToken = fromTokens[tokenAddressFromUrl.toLowerCase()];
427+
const handleToken = async () => {
428+
if (isSolanaChainId(fromChain.chainId)) {
429+
const tokenAddress = tokenAddressFromUrl;
430+
const assetId = toAssetId(
431+
tokenAddress,
432+
formatChainIdToCaip(fromChain.chainId),
433+
);
434+
if (!assetId) {
435+
removeTokenFromUrl();
436+
return;
437+
}
438+
439+
const tokenMetadata = await fetchAssetMetadata(
440+
tokenAddress,
441+
fromChain.chainId,
442+
);
443+
if (!tokenMetadata) {
444+
removeTokenFromUrl();
445+
return;
446+
}
421447

422-
switch (tokenAddressFromUrl) {
423-
case fromToken?.address:
424-
// If the token is already set, remove the query param
425-
removeTokenFromUrl();
426-
break;
427-
case matchedToken?.address:
428-
case matchedToken?.address
429-
? toChecksumAddress(matchedToken.address)
430-
: undefined: {
431-
// If there is a match, set it as the fromToken
432448
dispatch(
433449
setFromToken({
434-
...matchedToken,
435-
image: matchedToken.iconUrl,
450+
...tokenMetadata,
436451
chainId: fromChain.chainId,
452+
image: tokenMetadata.image || '',
437453
}),
438454
);
439455
removeTokenFromUrl();
440-
break;
456+
return;
441457
}
442-
default:
443-
// Otherwise remove query param
444-
removeTokenFromUrl();
445-
break;
446-
}
458+
459+
const matchedToken = fromTokens[tokenAddressFromUrl.toLowerCase()];
460+
461+
switch (tokenAddressFromUrl) {
462+
case fromToken?.address:
463+
// If the token is already set, remove the query param
464+
removeTokenFromUrl();
465+
break;
466+
case matchedToken?.address:
467+
case matchedToken?.address
468+
? toChecksumAddress(matchedToken.address)
469+
: undefined: {
470+
// If there is a match, set it as the fromToken
471+
dispatch(
472+
setFromToken({
473+
...matchedToken,
474+
image: matchedToken.iconUrl,
475+
chainId: fromChain.chainId,
476+
}),
477+
);
478+
removeTokenFromUrl();
479+
break;
480+
}
481+
default:
482+
// Otherwise remove query param
483+
removeTokenFromUrl();
484+
break;
485+
}
486+
};
487+
488+
handleToken();
447489
}, [fromChain, fromToken, fromTokens, search, isFromTokensLoading]);
448490

449491
// Set the default destination token and slippage for swaps

ui/pages/bridge/quotes/__snapshots__/bridge-quotes-modal.test.tsx.snap

+2-2
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ exports[`BridgeQuotesModal should render the modal 1`] = `
111111
<p
112112
class="mm-box mm-text mm-text--body-xs-medium mm-box--color-text-alternative"
113113
>
114-
$14 total cost
114+
$14.00 total cost
115115
</p>
116116
<p
117117
class="mm-box mm-text mm-text--body-xs-medium mm-box--color-text-alternative"
@@ -147,7 +147,7 @@ exports[`BridgeQuotesModal should render the modal 1`] = `
147147
<p
148148
class="mm-box mm-text mm-text--body-xs-medium mm-box--color-text-alternative"
149149
>
150-
$14 total cost
150+
$14.00 total cost
151151
</p>
152152
<p
153153
class="mm-box mm-text mm-text--body-xs-medium mm-box--color-text-alternative"

ui/pages/bridge/quotes/bridge-quotes-modal.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ export const BridgeQuotesModal = ({
207207
<Column>
208208
<Text variant={TextVariant.bodyMd}>
209209
{cost.valueInCurrency &&
210-
formatCurrencyAmount(cost.valueInCurrency, currency, 0)}
210+
formatCurrencyAmount(cost.valueInCurrency, currency, 2)}
211211
</Text>
212212
{[
213213
totalNetworkFee?.valueInCurrency &&
@@ -218,7 +218,7 @@ export const BridgeQuotesModal = ({
218218
sentAmount.valueInCurrency,
219219
),
220220
currency,
221-
0,
221+
2,
222222
),
223223
])
224224
: t('quotedTotalCost', [
@@ -232,7 +232,7 @@ export const BridgeQuotesModal = ({
232232
formatCurrencyAmount(
233233
toTokenAmount.valueInCurrency,
234234
currency,
235-
0,
235+
2,
236236
) ??
237237
formatTokenAmount(
238238
locale,

0 commit comments

Comments
 (0)