Skip to content
Closed
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
diff --git a/dist/TokenBalancesController.cjs b/dist/TokenBalancesController.cjs
index 9c91f20ce150a49fc9c914ca25cc6885e8800f34..075edb48321640a2abed5b038fbcb2e17661071e 100644
--- a/dist/TokenBalancesController.cjs
+++ b/dist/TokenBalancesController.cjs
@@ -123,7 +123,7 @@ class TokenBalancesController extends (0, polling_controller_1.StaticIntervalPol
return this.messenger.call('NetworkController:getNetworkClientById', networkClientId);
});
_TokenBalancesController_createAccountsApiFetcher.set(this, () => {
- const originalFetcher = new api_balance_fetcher_1.AccountsApiBalanceFetcher(__classPrivateFieldGet(this, _TokenBalancesController_platform, "f"), __classPrivateFieldGet(this, _TokenBalancesController_getProvider, "f"));
+ const originalFetcher = new api_balance_fetcher_1.AccountsApiBalanceFetcher(__classPrivateFieldGet(this, _TokenBalancesController_platform, "f"), __classPrivateFieldGet(this, _TokenBalancesController_getProvider, "f"), () => this.state.tokenBalances);
return {
// Dynamically check allowExternalServices() at call time, not just at construction time
supports: (chainId) => __classPrivateFieldGet(this, _TokenBalancesController_allowExternalServices, "f").call(this) &&
diff --git a/dist/multi-chain-accounts-service/api-balance-fetcher.cjs b/dist/multi-chain-accounts-service/api-balance-fetcher.cjs
index 50d8ee9fb47ecc6e08f6322095e7689b8e3bd5a7..bc6da747274e5ebdc7b8ae052ae7ff7b88d2988d 100644
--- a/dist/multi-chain-accounts-service/api-balance-fetcher.cjs
+++ b/dist/multi-chain-accounts-service/api-balance-fetcher.cjs
@@ -13,7 +13,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
-var _AccountsApiBalanceFetcher_instances, _AccountsApiBalanceFetcher_platform, _AccountsApiBalanceFetcher_getProvider, _AccountsApiBalanceFetcher_fetchStakedBalances, _AccountsApiBalanceFetcher_fetchBalances;
+var _AccountsApiBalanceFetcher_instances, _AccountsApiBalanceFetcher_platform, _AccountsApiBalanceFetcher_getProvider, _AccountsApiBalanceFetcher_getUserTokens, _AccountsApiBalanceFetcher_fetchStakedBalances, _AccountsApiBalanceFetcher_fetchBalances;
Object.defineProperty(exports, "__esModule", { value: true });
exports.AccountsApiBalanceFetcher = void 0;
const contracts_1 = require("@ethersproject/contracts");
@@ -31,12 +31,14 @@ const ACCOUNTS_API_TIMEOUT_MS = 10000;
const checksum = (addr) => (0, controller_utils_1.toChecksumHexAddress)(addr);
const toCaipAccount = (chainId, account) => (0, assetsUtil_1.accountAddressToCaipReference)(chainId, account);
class AccountsApiBalanceFetcher {
- constructor(platform = 'extension', getProvider) {
+ constructor(platform = 'extension', getProvider, getUserTokens) {
_AccountsApiBalanceFetcher_instances.add(this);
_AccountsApiBalanceFetcher_platform.set(this, 'extension');
_AccountsApiBalanceFetcher_getProvider.set(this, void 0);
+ _AccountsApiBalanceFetcher_getUserTokens.set(this, void 0);
__classPrivateFieldSet(this, _AccountsApiBalanceFetcher_platform, platform, "f");
__classPrivateFieldSet(this, _AccountsApiBalanceFetcher_getProvider, getProvider, "f");
+ __classPrivateFieldSet(this, _AccountsApiBalanceFetcher_getUserTokens, getUserTokens, "f");
}
supports(chainId) {
return constants_1.SUPPORTED_NETWORKS_ACCOUNTS_API_V4.includes(chainId);
@@ -91,7 +93,8 @@ class AccountsApiBalanceFetcher {
});
// Ensure native token entries exist for all addresses on all requested chains
const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
- const nativeBalancesFromAPI = new Map(); // key: `${address}-${chainId}`
+ const nativeBalancesFromAPI = new Map(); // key: `${accountAddress}-${chainId}`
+ const nonNativeBalancesFromAPI = new Map(); // key: `${accountAddress}-${tokenAddress}-${chainId}`
// Process regular API balances
if (apiResponse.balances) {
const apiBalances = apiResponse.balances.flatMap((b) => {
@@ -127,6 +130,9 @@ class AccountsApiBalanceFetcher {
if (token === ZERO_ADDRESS && value !== undefined) {
nativeBalancesFromAPI.set(`${finalAccount}-${chainId}`, value);
}
+ if (token !== ZERO_ADDRESS && value !== undefined) {
+ nonNativeBalancesFromAPI.set(`${finalAccount.toLowerCase()}-${token.toLowerCase()}-${chainId}`, value);
+ }
return [
{
success: value !== undefined,
@@ -156,6 +162,29 @@ class AccountsApiBalanceFetcher {
}
});
});
+ // Add zero erc-20 balance entries for addresses that API didn't return
+ if (__classPrivateFieldGet(this, _AccountsApiBalanceFetcher_getUserTokens, "f")) {
+ const userTokens = __classPrivateFieldGet(this, _AccountsApiBalanceFetcher_getUserTokens, "f").call(this);
+ Object.entries(userTokens).forEach(([account, chains]) => {
+ Object.entries(chains).forEach(([chainId, tokens]) => {
+ Object.entries(tokens).forEach(([tokenAddress]) => {
+ const tokenLowerCase = tokenAddress.toLowerCase();
+ const key = `${account.toLowerCase()}-${tokenLowerCase}-${chainId}`;
+ const isERC = tokenAddress !== ZERO_ADDRESS;
+ const existingBalance = nonNativeBalancesFromAPI.get(key);
+ if (isERC && !existingBalance) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Truthiness check instead of Map.has() for balance existence

Low Severity

The check !existingBalance uses truthiness to determine whether the API returned a balance for a token, but nonNativeBalancesFromAPI.get(key) returns the stored value, not a boolean. If a balance value is ever falsy (e.g., numeric 0 instead of a BN object), the check passes incorrectly and a duplicate zero-balance entry gets pushed into results. Using !nonNativeBalancesFromAPI.has(key) would correctly test for key existence regardless of the stored value's truthiness.

Additional Locations (1)

Fix in Cursor Fix in Web

+ results.push({
+ success: true,
+ value: new bn_js_1.default('0'),
+ account: account,
+ token: tokenLowerCase,
+ chainId: chainId,
+ });
+ }
+ });
+ });
+ });
+ }
// Add staked balances
results.push(...stakedBalances);
return {
@@ -165,7 +194,7 @@ class AccountsApiBalanceFetcher {
}
}
exports.AccountsApiBalanceFetcher = AccountsApiBalanceFetcher;
-_AccountsApiBalanceFetcher_platform = new WeakMap(), _AccountsApiBalanceFetcher_getProvider = new WeakMap(), _AccountsApiBalanceFetcher_instances = new WeakSet(), _AccountsApiBalanceFetcher_fetchStakedBalances = async function _AccountsApiBalanceFetcher_fetchStakedBalances(addrs) {
+_AccountsApiBalanceFetcher_platform = new WeakMap(), _AccountsApiBalanceFetcher_getProvider = new WeakMap(), _AccountsApiBalanceFetcher_getUserTokens = new WeakMap(), _AccountsApiBalanceFetcher_instances = new WeakSet(), _AccountsApiBalanceFetcher_fetchStakedBalances = async function _AccountsApiBalanceFetcher_fetchStakedBalances(addrs) {
// Return empty array if no provider is available for blockchain calls
if (!__classPrivateFieldGet(this, _AccountsApiBalanceFetcher_getProvider, "f")) {
return [];
2 changes: 1 addition & 1 deletion android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ android {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionName "7.64.1"
versionCode 3667
versionCode 3698
testBuildType System.getProperty('testBuildType', 'debug')
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
manifestPlaceholders.MM_BRANCH_KEY_TEST = "$System.env.MM_BRANCH_KEY_TEST"
Expand Down
2 changes: 1 addition & 1 deletion app/constants/ota.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import otaConfig from '../../ota.config.js';
* Reset to v0 when releasing a new native build
* We keep this OTA_VERSION here to because changes in ota.config.js will affect the fingerprint and break the workflow in Github Actions
*/
export const OTA_VERSION: string = 'v0';
export const OTA_VERSION: string = 'v1';
export const RUNTIME_VERSION = otaConfig.RUNTIME_VERSION;
export const PROJECT_ID = otaConfig.PROJECT_ID;
export const UPDATE_URL = otaConfig.UPDATE_URL;
Expand Down
4 changes: 2 additions & 2 deletions bitrise.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3472,13 +3472,13 @@ app:
VERSION_NAME: 7.64.1
- opts:
is_expand: false
VERSION_NUMBER: 3667
VERSION_NUMBER: 3698
- opts:
is_expand: false
FLASK_VERSION_NAME: 7.64.1
- opts:
is_expand: false
FLASK_VERSION_NUMBER: 3667
FLASK_VERSION_NUMBER: 3698
- opts:
is_expand: false
ANDROID_APK_LINK: ''
Expand Down
12 changes: 6 additions & 6 deletions ios/MetaMask.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -1281,7 +1281,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 3667;
CURRENT_PROJECT_VERSION = 3698;
DEAD_CODE_STRIPPING = YES;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = 48XVW22RCG;
Expand Down Expand Up @@ -1350,7 +1350,7 @@
CODE_SIGN_ENTITLEMENTS = MetaMask/MetaMask.entitlements;
CODE_SIGN_IDENTITY = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 3667;
CURRENT_PROJECT_VERSION = 3698;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = 48XVW22RCG;
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 48XVW22RCG;
Expand Down Expand Up @@ -1416,7 +1416,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 3667;
CURRENT_PROJECT_VERSION = 3698;
DEAD_CODE_STRIPPING = YES;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = 48XVW22RCG;
Expand Down Expand Up @@ -1483,7 +1483,7 @@
CODE_SIGN_ENTITLEMENTS = MetaMask/MetaMask.entitlements;
CODE_SIGN_IDENTITY = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 3667;
CURRENT_PROJECT_VERSION = 3698;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = 48XVW22RCG;
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 48XVW22RCG;
Expand Down Expand Up @@ -1646,7 +1646,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 3667;
CURRENT_PROJECT_VERSION = 3698;
DEAD_CODE_STRIPPING = YES;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = 48XVW22RCG;
Expand Down Expand Up @@ -1716,7 +1716,7 @@
CODE_SIGN_ENTITLEMENTS = MetaMask/MetaMask.entitlements;
CODE_SIGN_IDENTITY = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 3667;
CURRENT_PROJECT_VERSION = 3698;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = 48XVW22RCG;
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 48XVW22RCG;
Expand Down
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,9 @@
"qs": "6.14.1",
"@playwright/test": "^1.57.0",
"@metamask/transaction-controller@npm:^61.0.0": "patch:@metamask/transaction-controller@npm%3A62.9.0#~/.yarn/patches/@metamask-transaction-controller-npm-62.9.0-5c8f871530.patch",
"@metamask/transaction-controller@npm:^62.9.2": "patch:@metamask/transaction-controller@npm%3A62.9.0#~/.yarn/patches/@metamask-transaction-controller-npm-62.9.0-5c8f871530.patch"
"@metamask/transaction-controller@npm:^62.9.2": "patch:@metamask/transaction-controller@npm%3A62.9.0#~/.yarn/patches/@metamask-transaction-controller-npm-62.9.0-5c8f871530.patch",
"@metamask/assets-controllers@npm:^96.0.0": "patch:@metamask/assets-controllers@npm%3A98.0.0#~/.yarn/patches/@metamask-assets-controllers-npm-98.0.0-ebc0dfef4f.patch",
"@metamask/assets-controllers@npm:^97.0.0": "patch:@metamask/assets-controllers@npm%3A98.0.0#~/.yarn/patches/@metamask-assets-controllers-npm-98.0.0-ebc0dfef4f.patch"
},
"dependencies": {
"@config-plugins/detox": "^9.0.0",
Expand All @@ -205,7 +207,7 @@
"@metamask/analytics-controller": "^1.0.0",
"@metamask/app-metadata-controller": "^2.0.0",
"@metamask/approval-controller": "^8.0.0",
"@metamask/assets-controllers": "^98.0.0",
"@metamask/assets-controllers": "patch:@metamask/assets-controllers@npm%3A98.0.0#~/.yarn/patches/@metamask-assets-controllers-npm-98.0.0-ebc0dfef4f.patch",
"@metamask/base-controller": "^9.0.0",
"@metamask/bitcoin-wallet-snap": "^1.9.0",
"@metamask/bridge-controller": "^64.8.0",
Expand Down
71 changes: 9 additions & 62 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7424,63 +7424,9 @@ __metadata:
languageName: node
linkType: hard

"@metamask/assets-controllers@npm:^96.0.0":
version: 96.0.0
resolution: "@metamask/assets-controllers@npm:96.0.0"
dependencies:
"@ethereumjs/util": "npm:^9.1.0"
"@ethersproject/abi": "npm:^5.7.0"
"@ethersproject/address": "npm:^5.7.0"
"@ethersproject/bignumber": "npm:^5.7.0"
"@ethersproject/contracts": "npm:^5.7.0"
"@ethersproject/providers": "npm:^5.7.0"
"@metamask/abi-utils": "npm:^2.0.3"
"@metamask/account-tree-controller": "npm:^4.0.0"
"@metamask/accounts-controller": "npm:^35.0.2"
"@metamask/approval-controller": "npm:^8.0.0"
"@metamask/base-controller": "npm:^9.0.0"
"@metamask/contract-metadata": "npm:^2.4.0"
"@metamask/controller-utils": "npm:^11.18.0"
"@metamask/core-backend": "npm:^5.0.0"
"@metamask/eth-query": "npm:^4.0.0"
"@metamask/keyring-api": "npm:^21.0.0"
"@metamask/keyring-controller": "npm:^25.0.0"
"@metamask/messenger": "npm:^0.3.0"
"@metamask/metamask-eth-abis": "npm:^3.1.1"
"@metamask/multichain-account-service": "npm:^5.1.0"
"@metamask/network-controller": "npm:^29.0.0"
"@metamask/permission-controller": "npm:^12.2.0"
"@metamask/phishing-controller": "npm:^16.1.0"
"@metamask/polling-controller": "npm:^16.0.2"
"@metamask/preferences-controller": "npm:^22.0.0"
"@metamask/profile-sync-controller": "npm:^27.0.0"
"@metamask/rpc-errors": "npm:^7.0.2"
"@metamask/snaps-controllers": "npm:^17.2.0"
"@metamask/snaps-sdk": "npm:^10.3.0"
"@metamask/snaps-utils": "npm:^11.7.0"
"@metamask/transaction-controller": "npm:^62.9.2"
"@metamask/utils": "npm:^11.9.0"
"@types/bn.js": "npm:^5.1.5"
"@types/uuid": "npm:^8.3.0"
async-mutex: "npm:^0.5.0"
bitcoin-address-validation: "npm:^2.2.3"
bn.js: "npm:^5.2.1"
immer: "npm:^9.0.6"
lodash: "npm:^4.17.21"
multiformats: "npm:^9.9.0"
reselect: "npm:^5.1.1"
single-call-balance-checker-abi: "npm:^1.0.0"
uuid: "npm:^8.3.2"
peerDependencies:
"@metamask/providers": ^22.0.0
webextension-polyfill: ^0.10.0 || ^0.11.0 || ^0.12.0
checksum: 10/c5cf7363972b2f267ba96a925fd74eaee3eebde8bf470af7d4c49589b33b34fc9b8574289e4592cbce13e941201893d2ad20018da0dada8025317db0ce33df0f
languageName: node
linkType: hard

"@metamask/assets-controllers@npm:^97.0.0":
version: 97.0.0
resolution: "@metamask/assets-controllers@npm:97.0.0"
"@metamask/assets-controllers@npm:98.0.0":
version: 98.0.0
resolution: "@metamask/assets-controllers@npm:98.0.0"
dependencies:
"@ethereumjs/util": "npm:^9.1.0"
"@ethersproject/abi": "npm:^5.7.0"
Expand Down Expand Up @@ -7513,6 +7459,7 @@ __metadata:
"@metamask/snaps-controllers": "npm:^17.2.0"
"@metamask/snaps-sdk": "npm:^10.3.0"
"@metamask/snaps-utils": "npm:^11.7.0"
"@metamask/storage-service": "npm:^0.0.1"
"@metamask/transaction-controller": "npm:^62.9.2"
"@metamask/utils": "npm:^11.9.0"
"@types/bn.js": "npm:^5.1.5"
Expand All @@ -7529,13 +7476,13 @@ __metadata:
peerDependencies:
"@metamask/providers": ^22.0.0
webextension-polyfill: ^0.10.0 || ^0.11.0 || ^0.12.0
checksum: 10/44f6adc0f3263a17c2be49aff7c558f0478c41f8c0318c03db5706451284ccf56c5534d56366c6504538e89eda8aa86669310467a170276f28875c17bcbd6367
checksum: 10/a2a3564ae4cb5349a134c40844db62db43d8aefa7ac00c8d6a31ace63573b6ea2a77988e1daae7719a99a79736f4dee3af7886d85829cd2efd68dd55b55fb5f6
languageName: node
linkType: hard

"@metamask/assets-controllers@npm:^98.0.0":
"@metamask/assets-controllers@patch:@metamask/assets-controllers@npm%3A98.0.0#~/.yarn/patches/@metamask-assets-controllers-npm-98.0.0-ebc0dfef4f.patch":
version: 98.0.0
resolution: "@metamask/assets-controllers@npm:98.0.0"
resolution: "@metamask/assets-controllers@patch:@metamask/assets-controllers@npm%3A98.0.0#~/.yarn/patches/@metamask-assets-controllers-npm-98.0.0-ebc0dfef4f.patch::version=98.0.0&hash=a57226"
dependencies:
"@ethereumjs/util": "npm:^9.1.0"
"@ethersproject/abi": "npm:^5.7.0"
Expand Down Expand Up @@ -7585,7 +7532,7 @@ __metadata:
peerDependencies:
"@metamask/providers": ^22.0.0
webextension-polyfill: ^0.10.0 || ^0.11.0 || ^0.12.0
checksum: 10/a2a3564ae4cb5349a134c40844db62db43d8aefa7ac00c8d6a31ace63573b6ea2a77988e1daae7719a99a79736f4dee3af7886d85829cd2efd68dd55b55fb5f6
checksum: 10/70d7682d77ac4c340ccb5131a71d1c597da04b0417abfd983bb97303c301ee581970ade8c549dae86c2214d3a630227c97699c5a1baa15472c431095e51c5eba
languageName: node
linkType: hard

Expand Down Expand Up @@ -34682,7 +34629,7 @@ __metadata:
"@metamask/analytics-controller": "npm:^1.0.0"
"@metamask/app-metadata-controller": "npm:^2.0.0"
"@metamask/approval-controller": "npm:^8.0.0"
"@metamask/assets-controllers": "npm:^98.0.0"
"@metamask/assets-controllers": "patch:@metamask/assets-controllers@npm%3A98.0.0#~/.yarn/patches/@metamask-assets-controllers-npm-98.0.0-ebc0dfef4f.patch"
"@metamask/auto-changelog": "npm:^5.3.0"
"@metamask/base-controller": "npm:^9.0.0"
"@metamask/bitcoin-wallet-snap": "npm:^1.9.0"
Expand Down
Loading