Skip to content

Commit 5829816

Browse files
v4.1.4 (#1410)
* Added dynamic gas station price based using API (#1404) * Added dynamic gas station metadata fetch * Log * Refactor * revert * Refactor * Revert latestblock * Added chain id check * Fix * Fixed sdk-core imports (#1405) * Added dynamic gas station metadata fetch * Log * Refactor * revert * Refactor * Revert latestblock * Added chain id check * Fix * Fixed sdk-core imports * CHANGELOG * Added account cleanup on login (#1408) * Added account cleanup on login * CHANGELOG * v4.1.4 (#1409) * Fixed tests * Clear address * Added clear at web wallet login --------- Co-authored-by: Radu Mojic <radu.mojic@multiversx.com>
2 parents 5523c30 + 55ebd09 commit 5829816

36 files changed

Lines changed: 200 additions & 61 deletions

CHANGELOG.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10-
## [[v4.1.3](https://github.com/multiversx/mx-sdk-dapp/pull/1407)] - 2025-04-15
10+
## [[v4.1.4](https://github.com/multiversx/mx-sdk-dapp/pull/1409)] - 2025-05-07
11+
12+
- [Added account cleanup on login](https://github.com/multiversx/mx-sdk-dapp/pull/1408)
13+
- [Fixed sdk-core imports](https://github.com/multiversx/mx-sdk-dapp/pull/1405)
14+
- [Added dynamic gas station metadata fetch](https://github.com/multiversx/mx-sdk-dapp/pull/1404)
15+
16+
## [[v4.1.3](https://github.com/multiversx/mx-sdk-dapp/pull/1407)] - 2025-05-06
1117

1218
- [Update WalletConnect Provider](https://github.com/multiversx/mx-sdk-dapp/pull/1407)
1319

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@multiversx/sdk-dapp",
3-
"version": "4.1.3",
3+
"version": "4.1.4",
44
"description": "A library to hold the main logic for a dapp on the MultiversX blockchain",
55
"author": "MultiversX",
66
"license": "GPL-3.0-or-later",

src/UI/SignTransactionsModals/SignWithDeviceModal/components/SignStepBody.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React from 'react';
2-
import { Address } from '@multiversx/sdk-core/out';
2+
import { Address } from '@multiversx/sdk-core';
33
import classNames from 'classnames';
44

55
import { withStyles, WithStylesImportType } from 'hocs/withStyles';

src/UI/SignTransactionsModals/SignWithDeviceModal/components/components/ConfirmFee/components/GasDetails/gasDetails.types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Transaction } from '@multiversx/sdk-core/out';
1+
import { Transaction } from '@multiversx/sdk-core';
22

33
import { WithStylesImportType } from 'hocs/useStyles';
44
import { UseSignTransactionsWithDeviceReturnType } from 'hooks';

src/UI/SignTransactionsModals/SignWithDeviceModal/components/components/ConfirmFee/components/GasDetails/helpers/getGasPriceDetails.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Transaction } from '@multiversx/sdk-core/out';
1+
import { Transaction } from '@multiversx/sdk-core';
22
import BigNumber from 'bignumber.js';
33
import { recommendGasPrice } from 'hooks/transactions/helpers/recommendGasPrice';
44
import { NetworkType } from 'types/network.types';

src/UI/SignTransactionsModals/SignWithDeviceModal/components/components/ConfirmFee/components/GasDetails/helpers/tests/getGasPriceDetails.test.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Transaction } from '@multiversx/sdk-core/out';
1+
import { Transaction } from '@multiversx/sdk-core';
22
import { testAddress } from '__mocks__';
33
import { getGasPriceDetails } from '../getGasPriceDetails';
44

@@ -18,20 +18,20 @@ describe('getGasPriceDetails', () => {
1818
it('should return the correct gas price details', () => {
1919
const gasPriceDetails = getGasPriceDetails({
2020
shard: 1,
21-
gasStationMetadata: [
22-
{
21+
gasStationMetadata: {
22+
0: {
2323
fast: 11_760_000,
2424
faster: 19_287_760
2525
},
26-
{
26+
1: {
2727
fast: 11_760_000,
2828
faster: 19_287_760
2929
},
30-
{
30+
2: {
3131
fast: 11_760_000,
3232
faster: 19_287_760
3333
}
34-
],
34+
},
3535
transaction: secondTx,
3636
initialGasPrice: 1_000_000_000
3737
});

src/UI/ledger/LedgerLoginContainer/AddressRow/AddressRow.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React from 'react';
2-
import { Address, AddressComputer } from '@multiversx/sdk-core/out';
2+
import { Address, AddressComputer } from '@multiversx/sdk-core';
33
import classNames from 'classnames';
44

55
import ShardLogo from 'assets/icons/shard-icon.svg';
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import axios from 'axios';
2+
import { getCleanApiAddress } from 'apiCalls/utils';
3+
import { BaseNetworkType } from 'types/network.types';
4+
5+
interface IGasStationApiResponse {
6+
lastBlock: number;
7+
fast: number;
8+
faster: number;
9+
}
10+
11+
const GAS_STATION_ENDPOINT = 'transactions/ppu';
12+
13+
export async function getGasStationMetadataFromApi(
14+
shard: number
15+
): Promise<BaseNetworkType['gasStationMetadata'] | null> {
16+
const apiAddress = getCleanApiAddress();
17+
const gasStationUrl = `${apiAddress}/${GAS_STATION_ENDPOINT}/${shard}`;
18+
19+
try {
20+
const { data } = await axios.get<IGasStationApiResponse>(gasStationUrl);
21+
22+
if (data) {
23+
return {
24+
[shard]: {
25+
lastBlock: data.lastBlock,
26+
fast: data.fast,
27+
faster: data.faster
28+
}
29+
};
30+
}
31+
return null;
32+
} catch (err) {
33+
console.error(
34+
'Error fetching gas station metadata from:',
35+
gasStationUrl,
36+
err
37+
);
38+
return null;
39+
}
40+
}

src/apiCalls/configuration/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
export * from './getServerConfigurationForEnvironment';
22
export * from './getServerConfiguration';
33
export * from './getNetworkConfig';
4+
export * from './getGasStationMetadata';
45
export * from './getApiAddressForChainId';
56
export * from './getEnvironmentForChainId';
67
export * from './useGetNetworkConfigFromApi';

src/components/ProviderInitializer/ProviderInitializer.tsx

Lines changed: 75 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1-
import { useEffect, useRef } from 'react';
1+
import { useEffect, useRef, useState } from 'react';
22

3-
import { getNetworkConfigFromApi, useGetAccountFromApi } from 'apiCalls';
3+
import {
4+
getNetworkConfigFromApi,
5+
getGasStationMetadataFromApi,
6+
useGetAccountFromApi
7+
} from 'apiCalls';
48
import {
59
DEVNET_CHAIN_ID,
610
MAINNET_CHAIN_ID,
@@ -46,6 +50,7 @@ import {
4650
} from 'reduxStore/slices';
4751
import { decodeNativeAuthToken } from 'services/nativeAuth/helpers';
4852
import { LoginMethodsEnum } from 'types/enums.types';
53+
import { NetworkType, ApiNetworkConfigType } from 'types/network.types';
4954
import {
5055
getAddress,
5156
getLatestNonce,
@@ -67,7 +72,6 @@ import {
6772
handleGuardianWarning
6873
} from './helpers';
6974
import { useSetLedgerProvider } from './hooks';
70-
7175
let initalizingLedger = false;
7276

7377
export function ProviderInitializer() {
@@ -85,6 +89,7 @@ export function ProviderInitializer() {
8589
const tokenLogin = useSelector(tokenLoginSelector);
8690
const userAccount = useSelector(accountSelector);
8791
const nativeAuthConfig = tokenLogin?.nativeAuthConfig;
92+
const [lastChainId, setLastChainId] = useState<string>(chainID);
8893

8994
const loginService = useLoginService(
9095
nativeAuthConfig ? nativeAuthConfig : false
@@ -136,6 +141,51 @@ export function ProviderInitializer() {
136141
}
137142
}, [isLoggedIn, userAccount]);
138143

144+
useEffect(() => {
145+
checkGasMetadata();
146+
}, [
147+
userAccount.shard,
148+
userAccount.address,
149+
isLoggedIn,
150+
lastChainId,
151+
chainID
152+
]);
153+
154+
async function checkGasMetadata() {
155+
const hasAccountShard = isLoggedIn && userAccount.shard != null;
156+
157+
if (!hasAccountShard) {
158+
return;
159+
}
160+
161+
const shard = Number(userAccount.shard);
162+
const fetchedGasMetadata = await getGasStationMetadataFromApi(shard);
163+
164+
if (!fetchedGasMetadata?.[shard]?.lastBlock) {
165+
return;
166+
}
167+
168+
const hasDifferentGasStationMetadata =
169+
!network.gasStationMetadata ||
170+
!network.gasStationMetadata[shard] ||
171+
network.gasStationMetadata[shard].lastBlock !==
172+
fetchedGasMetadata[shard].lastBlock;
173+
174+
const hasDifferentChainId = lastChainId !== chainID;
175+
176+
if (hasDifferentChainId) {
177+
setLastChainId(chainID);
178+
}
179+
180+
if (hasDifferentGasStationMetadata || hasDifferentChainId) {
181+
dispatch(
182+
updateNetworkConfig({
183+
gasStationMetadata: fetchedGasMetadata
184+
})
185+
);
186+
}
187+
}
188+
139189
// We need to get the roundDuration for networks that do not support websocket (e.g. sovereign)
140190
// The round duration is used for polling interval
141191
async function refreshNetworkConfig() {
@@ -146,30 +196,37 @@ export function ProviderInitializer() {
146196
) &&
147197
!network.roundDuration;
148198

149-
const shouldGetConfig =
199+
const shouldGetBaseConfig =
150200
!network.chainId || needsRoundDurationForPollingInterval;
151201

152-
if (!shouldGetConfig) {
202+
if (!shouldGetBaseConfig) {
153203
return;
154204
}
155205

156206
try {
157-
const networkConfig = await getNetworkConfigFromApi();
158-
const hasDifferentNetworkConfig =
159-
networkConfig &&
160-
(network.chainId !== networkConfig.erd_chain_id ||
161-
network.roundDuration !== networkConfig.erd_round_duration);
207+
const fetchedNetworkConfig = await getNetworkConfigFromApi();
162208

163-
if (hasDifferentNetworkConfig) {
164-
dispatch(
165-
updateNetworkConfig({
166-
chainId: networkConfig.erd_chain_id,
167-
roundDuration: networkConfig.erd_round_duration
168-
})
169-
);
209+
const updates: Partial<NetworkType> = {};
210+
211+
if (fetchedNetworkConfig) {
212+
const networkConfigResult =
213+
fetchedNetworkConfig as ApiNetworkConfigType;
214+
215+
const hasDifferentNetworkConfig =
216+
network.chainId !== networkConfigResult.erd_chain_id ||
217+
network.roundDuration !== networkConfigResult.erd_round_duration;
218+
219+
if (hasDifferentNetworkConfig) {
220+
updates.chainId = networkConfigResult.erd_chain_id;
221+
updates.roundDuration = networkConfigResult.erd_round_duration;
222+
}
223+
}
224+
225+
if (Object.keys(updates).length > 0) {
226+
dispatch(updateNetworkConfig(updates));
170227
}
171228
} catch (err) {
172-
console.error('failed refreshing chainId ', err);
229+
console.error('Failed refreshing network config:', err);
173230
}
174231
}
175232

0 commit comments

Comments
 (0)