@metamask/assets-controllers 74.1.1 → 74.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -1
- package/dist/selectors/stringify-balance.cjs +30 -1
- package/dist/selectors/stringify-balance.cjs.map +1 -1
- package/dist/selectors/stringify-balance.d.cts +15 -0
- package/dist/selectors/stringify-balance.d.cts.map +1 -1
- package/dist/selectors/stringify-balance.d.mts +15 -0
- package/dist/selectors/stringify-balance.d.mts.map +1 -1
- package/dist/selectors/stringify-balance.mjs +28 -0
- package/dist/selectors/stringify-balance.mjs.map +1 -1
- package/dist/selectors/token-selectors.cjs +12 -3
- package/dist/selectors/token-selectors.cjs.map +1 -1
- package/dist/selectors/token-selectors.d.cts +1 -0
- package/dist/selectors/token-selectors.d.cts.map +1 -1
- package/dist/selectors/token-selectors.d.mts +1 -0
- package/dist/selectors/token-selectors.d.mts.map +1 -1
- package/dist/selectors/token-selectors.mjs +13 -4
- package/dist/selectors/token-selectors.mjs.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [74.2.0]
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- Add `rawBalance` to the result of `selectAssetsBySelectedAccountGroup` ([#6398](https://github.com/MetaMask/core/pull/6398))
|
|
15
|
+
|
|
10
16
|
## [74.1.1]
|
|
11
17
|
|
|
12
18
|
### Changed
|
|
@@ -1926,7 +1932,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
1926
1932
|
|
|
1927
1933
|
- Use Ethers for AssetsContractController ([#845](https://github.com/MetaMask/core/pull/845))
|
|
1928
1934
|
|
|
1929
|
-
[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@74.
|
|
1935
|
+
[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@74.2.0...HEAD
|
|
1936
|
+
[74.2.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@74.1.1...@metamask/assets-controllers@74.2.0
|
|
1930
1937
|
[74.1.1]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@74.1.0...@metamask/assets-controllers@74.1.1
|
|
1931
1938
|
[74.1.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@74.0.0...@metamask/assets-controllers@74.1.0
|
|
1932
1939
|
[74.0.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@73.3.0...@metamask/assets-controllers@74.0.0
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
// From https://github.com/MetaMask/eth-token-tracker/blob/main/lib/util.js
|
|
3
3
|
// Ensures backwards compatibility with display formatting.
|
|
4
4
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
-
exports.stringifyBalanceWithDecimals = void 0;
|
|
5
|
+
exports.parseBalanceWithDecimals = exports.stringifyBalanceWithDecimals = void 0;
|
|
6
|
+
const utils_1 = require("@metamask/utils");
|
|
6
7
|
/**
|
|
7
8
|
* @param balance - The balance to stringify as a decimal string
|
|
8
9
|
* @param decimals - The number of decimals of the balance
|
|
@@ -40,4 +41,32 @@ function stringifyBalanceWithDecimals(balance, decimals, balanceDecimals = 5) {
|
|
|
40
41
|
return `${whole}.${fractional}`;
|
|
41
42
|
}
|
|
42
43
|
exports.stringifyBalanceWithDecimals = stringifyBalanceWithDecimals;
|
|
44
|
+
/**
|
|
45
|
+
* Converts a decimal string representation back to a Hex balance.
|
|
46
|
+
* This is the inverse operation of stringifyBalanceWithDecimals.
|
|
47
|
+
*
|
|
48
|
+
* @param balanceString - The decimal string representation (e.g., "123.456")
|
|
49
|
+
* @param decimals - The number of decimals to apply (shifts decimal point right)
|
|
50
|
+
* @returns The balance as a Hex string
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* parseBalanceWithDecimals("123.456", 18) // Returns '0x6B14BD1E6EEA00000'
|
|
54
|
+
* parseBalanceWithDecimals("0.001", 18) // Returns '0x38D7EA4C68000'
|
|
55
|
+
* parseBalanceWithDecimals("123", 18) // Returns '0x6AAF7C8516D0C0000'
|
|
56
|
+
*/
|
|
57
|
+
function parseBalanceWithDecimals(balanceString, decimals) {
|
|
58
|
+
// Allows: "123", "123.456", "0.123", but not: "-123", "123.", "abc", "12.34.56"
|
|
59
|
+
if (!/^\d+(\.\d+)?$/u.test(balanceString)) {
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
const [integerPart, fractionalPart = ''] = balanceString.split('.');
|
|
63
|
+
if (decimals === 0) {
|
|
64
|
+
return (0, utils_1.bigIntToHex)(BigInt(integerPart));
|
|
65
|
+
}
|
|
66
|
+
if (fractionalPart.length >= decimals) {
|
|
67
|
+
return (0, utils_1.bigIntToHex)(BigInt(`${integerPart}${fractionalPart.slice(0, decimals)}`));
|
|
68
|
+
}
|
|
69
|
+
return (0, utils_1.bigIntToHex)(BigInt(`${integerPart}${fractionalPart}${'0'.repeat(decimals - fractionalPart.length)}`));
|
|
70
|
+
}
|
|
71
|
+
exports.parseBalanceWithDecimals = parseBalanceWithDecimals;
|
|
43
72
|
//# sourceMappingURL=stringify-balance.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stringify-balance.cjs","sourceRoot":"","sources":["../../src/selectors/stringify-balance.ts"],"names":[],"mappings":";AAAA,2EAA2E;AAC3E,2DAA2D;;;AAE3D;;;;;GAKG;AACH,SAAgB,4BAA4B,CAC1C,OAAe,EACf,QAAgB,EAChB,eAAe,GAAG,CAAC;IAEnB,IAAI,OAAO,KAAK,EAAE,IAAI,QAAQ,KAAK,CAAC,EAAE;QACpC,OAAO,OAAO,CAAC,QAAQ,EAAE,CAAC;KAC3B;IAED,IAAI,GAAG,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAC7B,IAAI,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC;IACrB,IAAI,YAAY,GAAG,GAAG,GAAG,QAAQ,CAAC;IAClC,IAAI,MAAM,GAAG,EAAE,CAAC;IAEhB,IAAI,YAAY,IAAI,CAAC,EAAE;QACrB,OAAO,MAAM,CAAC,MAAM,IAAI,YAAY,GAAG,CAAC,CAAC,EAAE;YACzC,MAAM,IAAI,GAAG,CAAC;YACd,GAAG,IAAI,CAAC,CAAC;SACV;QACD,GAAG,GAAG,MAAM,GAAG,GAAG,CAAC;QACnB,YAAY,GAAG,CAAC,CAAC;KAClB;IAED,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,GAAG,QAAQ,CAAC,CAAC;IAE3C,IAAI,eAAe,KAAK,CAAC,EAAE;QACzB,OAAO,KAAK,CAAC;KACd;IAED,MAAM,UAAU,GAAG,GAAG,CAAC,KAAK,CAAC,YAAY,EAAE,YAAY,GAAG,eAAe,CAAC,CAAC;IAC3E,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE;QAC3B,IAAI,iBAAiB,GAAG,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACpE,IAAI,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE;YAChC,iBAAiB,GAAG,IAAI,iBAAiB,EAAE,CAAC;SAC7C;QACD,OAAO,GAAG,KAAK,GAAG,iBAAiB,EAAE,CAAC;KACvC;IACD,OAAO,GAAG,KAAK,IAAI,UAAU,EAAE,CAAC;AAClC,CAAC;AAtCD,oEAsCC","sourcesContent":["// From https://github.com/MetaMask/eth-token-tracker/blob/main/lib/util.js\n// Ensures backwards compatibility with display formatting.\n\n/**\n * @param balance - The balance to stringify as a decimal string\n * @param decimals - The number of decimals of the balance\n * @param balanceDecimals - The number of decimals to display\n * @returns The stringified balance with the specified number of decimals\n */\nexport function stringifyBalanceWithDecimals(\n balance: bigint,\n decimals: number,\n balanceDecimals = 5,\n) {\n if (balance === 0n || decimals === 0) {\n return balance.toString();\n }\n\n let bal = balance.toString();\n let len = bal.length;\n let decimalIndex = len - decimals;\n let prefix = '';\n\n if (decimalIndex <= 0) {\n while (prefix.length <= decimalIndex * -1) {\n prefix += '0';\n len += 1;\n }\n bal = prefix + bal;\n decimalIndex = 1;\n }\n\n const whole = bal.slice(0, len - decimals);\n\n if (balanceDecimals === 0) {\n return whole;\n }\n\n const fractional = bal.slice(decimalIndex, decimalIndex + balanceDecimals);\n if (/0+$/u.test(fractional)) {\n let withOnlySigZeroes = bal.slice(decimalIndex).replace(/0+$/u, '');\n if (withOnlySigZeroes.length > 0) {\n withOnlySigZeroes = `.${withOnlySigZeroes}`;\n }\n return `${whole}${withOnlySigZeroes}`;\n }\n return `${whole}.${fractional}`;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"stringify-balance.cjs","sourceRoot":"","sources":["../../src/selectors/stringify-balance.ts"],"names":[],"mappings":";AAAA,2EAA2E;AAC3E,2DAA2D;;;AAE3D,2CAAwD;AAExD;;;;;GAKG;AACH,SAAgB,4BAA4B,CAC1C,OAAe,EACf,QAAgB,EAChB,eAAe,GAAG,CAAC;IAEnB,IAAI,OAAO,KAAK,EAAE,IAAI,QAAQ,KAAK,CAAC,EAAE;QACpC,OAAO,OAAO,CAAC,QAAQ,EAAE,CAAC;KAC3B;IAED,IAAI,GAAG,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAC7B,IAAI,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC;IACrB,IAAI,YAAY,GAAG,GAAG,GAAG,QAAQ,CAAC;IAClC,IAAI,MAAM,GAAG,EAAE,CAAC;IAEhB,IAAI,YAAY,IAAI,CAAC,EAAE;QACrB,OAAO,MAAM,CAAC,MAAM,IAAI,YAAY,GAAG,CAAC,CAAC,EAAE;YACzC,MAAM,IAAI,GAAG,CAAC;YACd,GAAG,IAAI,CAAC,CAAC;SACV;QACD,GAAG,GAAG,MAAM,GAAG,GAAG,CAAC;QACnB,YAAY,GAAG,CAAC,CAAC;KAClB;IAED,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,GAAG,QAAQ,CAAC,CAAC;IAE3C,IAAI,eAAe,KAAK,CAAC,EAAE;QACzB,OAAO,KAAK,CAAC;KACd;IAED,MAAM,UAAU,GAAG,GAAG,CAAC,KAAK,CAAC,YAAY,EAAE,YAAY,GAAG,eAAe,CAAC,CAAC;IAC3E,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE;QAC3B,IAAI,iBAAiB,GAAG,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACpE,IAAI,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE;YAChC,iBAAiB,GAAG,IAAI,iBAAiB,EAAE,CAAC;SAC7C;QACD,OAAO,GAAG,KAAK,GAAG,iBAAiB,EAAE,CAAC;KACvC;IACD,OAAO,GAAG,KAAK,IAAI,UAAU,EAAE,CAAC;AAClC,CAAC;AAtCD,oEAsCC;AAED;;;;;;;;;;;;GAYG;AACH,SAAgB,wBAAwB,CACtC,aAAqB,EACrB,QAAgB;IAEhB,gFAAgF;IAChF,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE;QACzC,OAAO,SAAS,CAAC;KAClB;IAED,MAAM,CAAC,WAAW,EAAE,cAAc,GAAG,EAAE,CAAC,GAAG,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAEpE,IAAI,QAAQ,KAAK,CAAC,EAAE;QAClB,OAAO,IAAA,mBAAW,EAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC;KACzC;IAED,IAAI,cAAc,CAAC,MAAM,IAAI,QAAQ,EAAE;QACrC,OAAO,IAAA,mBAAW,EAChB,MAAM,CAAC,GAAG,WAAW,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,EAAE,CAAC,CAC7D,CAAC;KACH;IAED,OAAO,IAAA,mBAAW,EAChB,MAAM,CACJ,GAAG,WAAW,GAAG,cAAc,GAAG,GAAG,CAAC,MAAM,CAC1C,QAAQ,GAAG,cAAc,CAAC,MAAM,CACjC,EAAE,CACJ,CACF,CAAC;AACJ,CAAC;AA5BD,4DA4BC","sourcesContent":["// From https://github.com/MetaMask/eth-token-tracker/blob/main/lib/util.js\n// Ensures backwards compatibility with display formatting.\n\nimport { bigIntToHex, type Hex } from '@metamask/utils';\n\n/**\n * @param balance - The balance to stringify as a decimal string\n * @param decimals - The number of decimals of the balance\n * @param balanceDecimals - The number of decimals to display\n * @returns The stringified balance with the specified number of decimals\n */\nexport function stringifyBalanceWithDecimals(\n balance: bigint,\n decimals: number,\n balanceDecimals = 5,\n) {\n if (balance === 0n || decimals === 0) {\n return balance.toString();\n }\n\n let bal = balance.toString();\n let len = bal.length;\n let decimalIndex = len - decimals;\n let prefix = '';\n\n if (decimalIndex <= 0) {\n while (prefix.length <= decimalIndex * -1) {\n prefix += '0';\n len += 1;\n }\n bal = prefix + bal;\n decimalIndex = 1;\n }\n\n const whole = bal.slice(0, len - decimals);\n\n if (balanceDecimals === 0) {\n return whole;\n }\n\n const fractional = bal.slice(decimalIndex, decimalIndex + balanceDecimals);\n if (/0+$/u.test(fractional)) {\n let withOnlySigZeroes = bal.slice(decimalIndex).replace(/0+$/u, '');\n if (withOnlySigZeroes.length > 0) {\n withOnlySigZeroes = `.${withOnlySigZeroes}`;\n }\n return `${whole}${withOnlySigZeroes}`;\n }\n return `${whole}.${fractional}`;\n}\n\n/**\n * Converts a decimal string representation back to a Hex balance.\n * This is the inverse operation of stringifyBalanceWithDecimals.\n *\n * @param balanceString - The decimal string representation (e.g., \"123.456\")\n * @param decimals - The number of decimals to apply (shifts decimal point right)\n * @returns The balance as a Hex string\n *\n * @example\n * parseBalanceWithDecimals(\"123.456\", 18) // Returns '0x6B14BD1E6EEA00000'\n * parseBalanceWithDecimals(\"0.001\", 18) // Returns '0x38D7EA4C68000'\n * parseBalanceWithDecimals(\"123\", 18) // Returns '0x6AAF7C8516D0C0000'\n */\nexport function parseBalanceWithDecimals(\n balanceString: string,\n decimals: number,\n): Hex | undefined {\n // Allows: \"123\", \"123.456\", \"0.123\", but not: \"-123\", \"123.\", \"abc\", \"12.34.56\"\n if (!/^\\d+(\\.\\d+)?$/u.test(balanceString)) {\n return undefined;\n }\n\n const [integerPart, fractionalPart = ''] = balanceString.split('.');\n\n if (decimals === 0) {\n return bigIntToHex(BigInt(integerPart));\n }\n\n if (fractionalPart.length >= decimals) {\n return bigIntToHex(\n BigInt(`${integerPart}${fractionalPart.slice(0, decimals)}`),\n );\n }\n\n return bigIntToHex(\n BigInt(\n `${integerPart}${fractionalPart}${'0'.repeat(\n decimals - fractionalPart.length,\n )}`,\n ),\n );\n}\n"]}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type Hex } from "@metamask/utils";
|
|
1
2
|
/**
|
|
2
3
|
* @param balance - The balance to stringify as a decimal string
|
|
3
4
|
* @param decimals - The number of decimals of the balance
|
|
@@ -5,4 +6,18 @@
|
|
|
5
6
|
* @returns The stringified balance with the specified number of decimals
|
|
6
7
|
*/
|
|
7
8
|
export declare function stringifyBalanceWithDecimals(balance: bigint, decimals: number, balanceDecimals?: number): string;
|
|
9
|
+
/**
|
|
10
|
+
* Converts a decimal string representation back to a Hex balance.
|
|
11
|
+
* This is the inverse operation of stringifyBalanceWithDecimals.
|
|
12
|
+
*
|
|
13
|
+
* @param balanceString - The decimal string representation (e.g., "123.456")
|
|
14
|
+
* @param decimals - The number of decimals to apply (shifts decimal point right)
|
|
15
|
+
* @returns The balance as a Hex string
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* parseBalanceWithDecimals("123.456", 18) // Returns '0x6B14BD1E6EEA00000'
|
|
19
|
+
* parseBalanceWithDecimals("0.001", 18) // Returns '0x38D7EA4C68000'
|
|
20
|
+
* parseBalanceWithDecimals("123", 18) // Returns '0x6AAF7C8516D0C0000'
|
|
21
|
+
*/
|
|
22
|
+
export declare function parseBalanceWithDecimals(balanceString: string, decimals: number): Hex | undefined;
|
|
8
23
|
//# sourceMappingURL=stringify-balance.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stringify-balance.d.cts","sourceRoot":"","sources":["../../src/selectors/stringify-balance.ts"],"names":[],"mappings":"AAGA;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,eAAe,SAAI,UAmCpB"}
|
|
1
|
+
{"version":3,"file":"stringify-balance.d.cts","sourceRoot":"","sources":["../../src/selectors/stringify-balance.ts"],"names":[],"mappings":"AAGA,OAAO,EAAe,KAAK,GAAG,EAAE,wBAAwB;AAExD;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,eAAe,SAAI,UAmCpB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,wBAAwB,CACtC,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,GACf,GAAG,GAAG,SAAS,CAyBjB"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type Hex } from "@metamask/utils";
|
|
1
2
|
/**
|
|
2
3
|
* @param balance - The balance to stringify as a decimal string
|
|
3
4
|
* @param decimals - The number of decimals of the balance
|
|
@@ -5,4 +6,18 @@
|
|
|
5
6
|
* @returns The stringified balance with the specified number of decimals
|
|
6
7
|
*/
|
|
7
8
|
export declare function stringifyBalanceWithDecimals(balance: bigint, decimals: number, balanceDecimals?: number): string;
|
|
9
|
+
/**
|
|
10
|
+
* Converts a decimal string representation back to a Hex balance.
|
|
11
|
+
* This is the inverse operation of stringifyBalanceWithDecimals.
|
|
12
|
+
*
|
|
13
|
+
* @param balanceString - The decimal string representation (e.g., "123.456")
|
|
14
|
+
* @param decimals - The number of decimals to apply (shifts decimal point right)
|
|
15
|
+
* @returns The balance as a Hex string
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* parseBalanceWithDecimals("123.456", 18) // Returns '0x6B14BD1E6EEA00000'
|
|
19
|
+
* parseBalanceWithDecimals("0.001", 18) // Returns '0x38D7EA4C68000'
|
|
20
|
+
* parseBalanceWithDecimals("123", 18) // Returns '0x6AAF7C8516D0C0000'
|
|
21
|
+
*/
|
|
22
|
+
export declare function parseBalanceWithDecimals(balanceString: string, decimals: number): Hex | undefined;
|
|
8
23
|
//# sourceMappingURL=stringify-balance.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stringify-balance.d.mts","sourceRoot":"","sources":["../../src/selectors/stringify-balance.ts"],"names":[],"mappings":"AAGA;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,eAAe,SAAI,UAmCpB"}
|
|
1
|
+
{"version":3,"file":"stringify-balance.d.mts","sourceRoot":"","sources":["../../src/selectors/stringify-balance.ts"],"names":[],"mappings":"AAGA,OAAO,EAAe,KAAK,GAAG,EAAE,wBAAwB;AAExD;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,eAAe,SAAI,UAmCpB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,wBAAwB,CACtC,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,GACf,GAAG,GAAG,SAAS,CAyBjB"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// From https://github.com/MetaMask/eth-token-tracker/blob/main/lib/util.js
|
|
2
2
|
// Ensures backwards compatibility with display formatting.
|
|
3
|
+
import { bigIntToHex } from "@metamask/utils";
|
|
3
4
|
/**
|
|
4
5
|
* @param balance - The balance to stringify as a decimal string
|
|
5
6
|
* @param decimals - The number of decimals of the balance
|
|
@@ -36,4 +37,31 @@ export function stringifyBalanceWithDecimals(balance, decimals, balanceDecimals
|
|
|
36
37
|
}
|
|
37
38
|
return `${whole}.${fractional}`;
|
|
38
39
|
}
|
|
40
|
+
/**
|
|
41
|
+
* Converts a decimal string representation back to a Hex balance.
|
|
42
|
+
* This is the inverse operation of stringifyBalanceWithDecimals.
|
|
43
|
+
*
|
|
44
|
+
* @param balanceString - The decimal string representation (e.g., "123.456")
|
|
45
|
+
* @param decimals - The number of decimals to apply (shifts decimal point right)
|
|
46
|
+
* @returns The balance as a Hex string
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* parseBalanceWithDecimals("123.456", 18) // Returns '0x6B14BD1E6EEA00000'
|
|
50
|
+
* parseBalanceWithDecimals("0.001", 18) // Returns '0x38D7EA4C68000'
|
|
51
|
+
* parseBalanceWithDecimals("123", 18) // Returns '0x6AAF7C8516D0C0000'
|
|
52
|
+
*/
|
|
53
|
+
export function parseBalanceWithDecimals(balanceString, decimals) {
|
|
54
|
+
// Allows: "123", "123.456", "0.123", but not: "-123", "123.", "abc", "12.34.56"
|
|
55
|
+
if (!/^\d+(\.\d+)?$/u.test(balanceString)) {
|
|
56
|
+
return undefined;
|
|
57
|
+
}
|
|
58
|
+
const [integerPart, fractionalPart = ''] = balanceString.split('.');
|
|
59
|
+
if (decimals === 0) {
|
|
60
|
+
return bigIntToHex(BigInt(integerPart));
|
|
61
|
+
}
|
|
62
|
+
if (fractionalPart.length >= decimals) {
|
|
63
|
+
return bigIntToHex(BigInt(`${integerPart}${fractionalPart.slice(0, decimals)}`));
|
|
64
|
+
}
|
|
65
|
+
return bigIntToHex(BigInt(`${integerPart}${fractionalPart}${'0'.repeat(decimals - fractionalPart.length)}`));
|
|
66
|
+
}
|
|
39
67
|
//# sourceMappingURL=stringify-balance.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stringify-balance.mjs","sourceRoot":"","sources":["../../src/selectors/stringify-balance.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,2DAA2D;AAE3D;;;;;GAKG;AACH,MAAM,UAAU,4BAA4B,CAC1C,OAAe,EACf,QAAgB,EAChB,eAAe,GAAG,CAAC;IAEnB,IAAI,OAAO,KAAK,EAAE,IAAI,QAAQ,KAAK,CAAC,EAAE;QACpC,OAAO,OAAO,CAAC,QAAQ,EAAE,CAAC;KAC3B;IAED,IAAI,GAAG,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAC7B,IAAI,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC;IACrB,IAAI,YAAY,GAAG,GAAG,GAAG,QAAQ,CAAC;IAClC,IAAI,MAAM,GAAG,EAAE,CAAC;IAEhB,IAAI,YAAY,IAAI,CAAC,EAAE;QACrB,OAAO,MAAM,CAAC,MAAM,IAAI,YAAY,GAAG,CAAC,CAAC,EAAE;YACzC,MAAM,IAAI,GAAG,CAAC;YACd,GAAG,IAAI,CAAC,CAAC;SACV;QACD,GAAG,GAAG,MAAM,GAAG,GAAG,CAAC;QACnB,YAAY,GAAG,CAAC,CAAC;KAClB;IAED,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,GAAG,QAAQ,CAAC,CAAC;IAE3C,IAAI,eAAe,KAAK,CAAC,EAAE;QACzB,OAAO,KAAK,CAAC;KACd;IAED,MAAM,UAAU,GAAG,GAAG,CAAC,KAAK,CAAC,YAAY,EAAE,YAAY,GAAG,eAAe,CAAC,CAAC;IAC3E,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE;QAC3B,IAAI,iBAAiB,GAAG,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACpE,IAAI,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE;YAChC,iBAAiB,GAAG,IAAI,iBAAiB,EAAE,CAAC;SAC7C;QACD,OAAO,GAAG,KAAK,GAAG,iBAAiB,EAAE,CAAC;KACvC;IACD,OAAO,GAAG,KAAK,IAAI,UAAU,EAAE,CAAC;AAClC,CAAC","sourcesContent":["// From https://github.com/MetaMask/eth-token-tracker/blob/main/lib/util.js\n// Ensures backwards compatibility with display formatting.\n\n/**\n * @param balance - The balance to stringify as a decimal string\n * @param decimals - The number of decimals of the balance\n * @param balanceDecimals - The number of decimals to display\n * @returns The stringified balance with the specified number of decimals\n */\nexport function stringifyBalanceWithDecimals(\n balance: bigint,\n decimals: number,\n balanceDecimals = 5,\n) {\n if (balance === 0n || decimals === 0) {\n return balance.toString();\n }\n\n let bal = balance.toString();\n let len = bal.length;\n let decimalIndex = len - decimals;\n let prefix = '';\n\n if (decimalIndex <= 0) {\n while (prefix.length <= decimalIndex * -1) {\n prefix += '0';\n len += 1;\n }\n bal = prefix + bal;\n decimalIndex = 1;\n }\n\n const whole = bal.slice(0, len - decimals);\n\n if (balanceDecimals === 0) {\n return whole;\n }\n\n const fractional = bal.slice(decimalIndex, decimalIndex + balanceDecimals);\n if (/0+$/u.test(fractional)) {\n let withOnlySigZeroes = bal.slice(decimalIndex).replace(/0+$/u, '');\n if (withOnlySigZeroes.length > 0) {\n withOnlySigZeroes = `.${withOnlySigZeroes}`;\n }\n return `${whole}${withOnlySigZeroes}`;\n }\n return `${whole}.${fractional}`;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"stringify-balance.mjs","sourceRoot":"","sources":["../../src/selectors/stringify-balance.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,2DAA2D;AAE3D,OAAO,EAAE,WAAW,EAAY,wBAAwB;AAExD;;;;;GAKG;AACH,MAAM,UAAU,4BAA4B,CAC1C,OAAe,EACf,QAAgB,EAChB,eAAe,GAAG,CAAC;IAEnB,IAAI,OAAO,KAAK,EAAE,IAAI,QAAQ,KAAK,CAAC,EAAE;QACpC,OAAO,OAAO,CAAC,QAAQ,EAAE,CAAC;KAC3B;IAED,IAAI,GAAG,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAC7B,IAAI,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC;IACrB,IAAI,YAAY,GAAG,GAAG,GAAG,QAAQ,CAAC;IAClC,IAAI,MAAM,GAAG,EAAE,CAAC;IAEhB,IAAI,YAAY,IAAI,CAAC,EAAE;QACrB,OAAO,MAAM,CAAC,MAAM,IAAI,YAAY,GAAG,CAAC,CAAC,EAAE;YACzC,MAAM,IAAI,GAAG,CAAC;YACd,GAAG,IAAI,CAAC,CAAC;SACV;QACD,GAAG,GAAG,MAAM,GAAG,GAAG,CAAC;QACnB,YAAY,GAAG,CAAC,CAAC;KAClB;IAED,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,GAAG,QAAQ,CAAC,CAAC;IAE3C,IAAI,eAAe,KAAK,CAAC,EAAE;QACzB,OAAO,KAAK,CAAC;KACd;IAED,MAAM,UAAU,GAAG,GAAG,CAAC,KAAK,CAAC,YAAY,EAAE,YAAY,GAAG,eAAe,CAAC,CAAC;IAC3E,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE;QAC3B,IAAI,iBAAiB,GAAG,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACpE,IAAI,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE;YAChC,iBAAiB,GAAG,IAAI,iBAAiB,EAAE,CAAC;SAC7C;QACD,OAAO,GAAG,KAAK,GAAG,iBAAiB,EAAE,CAAC;KACvC;IACD,OAAO,GAAG,KAAK,IAAI,UAAU,EAAE,CAAC;AAClC,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,wBAAwB,CACtC,aAAqB,EACrB,QAAgB;IAEhB,gFAAgF;IAChF,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE;QACzC,OAAO,SAAS,CAAC;KAClB;IAED,MAAM,CAAC,WAAW,EAAE,cAAc,GAAG,EAAE,CAAC,GAAG,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAEpE,IAAI,QAAQ,KAAK,CAAC,EAAE;QAClB,OAAO,WAAW,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC;KACzC;IAED,IAAI,cAAc,CAAC,MAAM,IAAI,QAAQ,EAAE;QACrC,OAAO,WAAW,CAChB,MAAM,CAAC,GAAG,WAAW,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,EAAE,CAAC,CAC7D,CAAC;KACH;IAED,OAAO,WAAW,CAChB,MAAM,CACJ,GAAG,WAAW,GAAG,cAAc,GAAG,GAAG,CAAC,MAAM,CAC1C,QAAQ,GAAG,cAAc,CAAC,MAAM,CACjC,EAAE,CACJ,CACF,CAAC;AACJ,CAAC","sourcesContent":["// From https://github.com/MetaMask/eth-token-tracker/blob/main/lib/util.js\n// Ensures backwards compatibility with display formatting.\n\nimport { bigIntToHex, type Hex } from '@metamask/utils';\n\n/**\n * @param balance - The balance to stringify as a decimal string\n * @param decimals - The number of decimals of the balance\n * @param balanceDecimals - The number of decimals to display\n * @returns The stringified balance with the specified number of decimals\n */\nexport function stringifyBalanceWithDecimals(\n balance: bigint,\n decimals: number,\n balanceDecimals = 5,\n) {\n if (balance === 0n || decimals === 0) {\n return balance.toString();\n }\n\n let bal = balance.toString();\n let len = bal.length;\n let decimalIndex = len - decimals;\n let prefix = '';\n\n if (decimalIndex <= 0) {\n while (prefix.length <= decimalIndex * -1) {\n prefix += '0';\n len += 1;\n }\n bal = prefix + bal;\n decimalIndex = 1;\n }\n\n const whole = bal.slice(0, len - decimals);\n\n if (balanceDecimals === 0) {\n return whole;\n }\n\n const fractional = bal.slice(decimalIndex, decimalIndex + balanceDecimals);\n if (/0+$/u.test(fractional)) {\n let withOnlySigZeroes = bal.slice(decimalIndex).replace(/0+$/u, '');\n if (withOnlySigZeroes.length > 0) {\n withOnlySigZeroes = `.${withOnlySigZeroes}`;\n }\n return `${whole}${withOnlySigZeroes}`;\n }\n return `${whole}.${fractional}`;\n}\n\n/**\n * Converts a decimal string representation back to a Hex balance.\n * This is the inverse operation of stringifyBalanceWithDecimals.\n *\n * @param balanceString - The decimal string representation (e.g., \"123.456\")\n * @param decimals - The number of decimals to apply (shifts decimal point right)\n * @returns The balance as a Hex string\n *\n * @example\n * parseBalanceWithDecimals(\"123.456\", 18) // Returns '0x6B14BD1E6EEA00000'\n * parseBalanceWithDecimals(\"0.001\", 18) // Returns '0x38D7EA4C68000'\n * parseBalanceWithDecimals(\"123\", 18) // Returns '0x6AAF7C8516D0C0000'\n */\nexport function parseBalanceWithDecimals(\n balanceString: string,\n decimals: number,\n): Hex | undefined {\n // Allows: \"123\", \"123.456\", \"0.123\", but not: \"-123\", \"123.\", \"abc\", \"12.34.56\"\n if (!/^\\d+(\\.\\d+)?$/u.test(balanceString)) {\n return undefined;\n }\n\n const [integerPart, fractionalPart = ''] = balanceString.split('.');\n\n if (decimals === 0) {\n return bigIntToHex(BigInt(integerPart));\n }\n\n if (fractionalPart.length >= decimals) {\n return bigIntToHex(\n BigInt(`${integerPart}${fractionalPart.slice(0, decimals)}`),\n );\n }\n\n return bigIntToHex(\n BigInt(\n `${integerPart}${fractionalPart}${'0'.repeat(\n decimals - fractionalPart.length,\n )}`,\n ),\n );\n}\n"]}
|
|
@@ -49,6 +49,7 @@ const selectAllEvmAccountNativeBalances = createAssetListSelector([
|
|
|
49
49
|
groupAssets[accountGroupId] ?? (groupAssets[accountGroupId] = {});
|
|
50
50
|
(_a = groupAssets[accountGroupId])[chainId] ?? (_a[chainId] = []);
|
|
51
51
|
const groupChainAssets = groupAssets[accountGroupId][chainId];
|
|
52
|
+
// If a native balance is missing, we still want to show it as 0
|
|
52
53
|
const rawBalance = accountBalance.balance || '0x0';
|
|
53
54
|
const nativeCurrency = networkConfigurationsByChainId[chainId]?.nativeCurrency || 'NATIVE';
|
|
54
55
|
const nativeToken = {
|
|
@@ -70,6 +71,7 @@ const selectAllEvmAccountNativeBalances = createAssetListSelector([
|
|
|
70
71
|
symbol: nativeToken.symbol,
|
|
71
72
|
accountId,
|
|
72
73
|
decimals: nativeToken.decimals,
|
|
74
|
+
rawBalance,
|
|
73
75
|
balance: (0, stringify_balance_1.stringifyBalanceWithDecimals)((0, utils_1.hexToBigInt)(rawBalance), nativeToken.decimals),
|
|
74
76
|
fiat: fiatData
|
|
75
77
|
? {
|
|
@@ -125,6 +127,7 @@ const selectAllEvmAssets = createAssetListSelector([
|
|
|
125
127
|
symbol: token.symbol,
|
|
126
128
|
accountId,
|
|
127
129
|
decimals: token.decimals,
|
|
130
|
+
rawBalance,
|
|
128
131
|
balance: (0, stringify_balance_1.stringifyBalanceWithDecimals)((0, utils_1.hexToBigInt)(rawBalance), token.decimals),
|
|
129
132
|
fiat: fiatData
|
|
130
133
|
? {
|
|
@@ -172,7 +175,13 @@ const selectAllMultichainAssets = createAssetListSelector([
|
|
|
172
175
|
(_a = groupAssets[accountGroupId])[chainId] ?? (_a[chainId] = []);
|
|
173
176
|
const groupChainAssets = groupAssets[accountGroupId][chainId];
|
|
174
177
|
const balance = multichainBalances[accountId]?.[assetId];
|
|
175
|
-
|
|
178
|
+
const decimals = assetMetadata.units.find((unit) => unit.name === assetMetadata.name &&
|
|
179
|
+
unit.symbol === assetMetadata.symbol)?.decimals;
|
|
180
|
+
if (!balance || decimals === undefined) {
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
const rawBalance = (0, stringify_balance_1.parseBalanceWithDecimals)(balance.amount, decimals);
|
|
184
|
+
if (!rawBalance) {
|
|
176
185
|
continue;
|
|
177
186
|
}
|
|
178
187
|
const fiatData = getFiatBalanceForMultichainAsset(balance, multichainConversionRates, assetId);
|
|
@@ -185,8 +194,8 @@ const selectAllMultichainAssets = createAssetListSelector([
|
|
|
185
194
|
name: assetMetadata.name ?? assetMetadata.symbol ?? asset,
|
|
186
195
|
symbol: assetMetadata.symbol ?? asset,
|
|
187
196
|
accountId,
|
|
188
|
-
decimals
|
|
189
|
-
|
|
197
|
+
decimals,
|
|
198
|
+
rawBalance,
|
|
190
199
|
balance: balance.amount,
|
|
191
200
|
fiat: fiatData
|
|
192
201
|
? {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"token-selectors.cjs","sourceRoot":"","sources":["../../src/selectors/token-selectors.ts"],"names":[],"mappings":";;;AAGA,iEAAiE;AAGjE,2CAA4E;AAC5E,uCAA0C;AAE1C,+DAAmE;AAKnE,qEAA0E;AAa1E,2GAA2G;AAC3G,MAAM,2BAA2B,GAAG;IAClC,kDAAkD;IAClD,oDAAoD;CACrD,CAAC;AAiEF,MAAM,uBAAuB,GAAG,yBAAc,CAAC,SAAS,EAAkB,CAAC;AAE3E,MAAM,0BAA0B,GAAG,uBAAuB,CACxD,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,EACjE,CAAC,WAAW,EAAE,gBAAgB,EAAE,EAAE;IAChC,MAAM,WAAW,GAOb,EAAE,CAAC;IACP,KAAK,MAAM,EAAE,MAAM,EAAE,IAAI,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE;QAC3D,KAAK,MAAM,EAAE,EAAE,EAAE,cAAc,EAAE,QAAQ,EAAE,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE;YACpE,KAAK,MAAM,SAAS,IAAI,QAAQ,EAAE;gBAChC,MAAM,eAAe,GAAG,gBAAgB,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;gBAE7D,WAAW;gBACT,gFAAgF;gBAChF,eAAe,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;oBACvC,CAAC,CAAC,eAAe,CAAC,OAAO;oBACzB,CAAC,CAAC,SAAS,CACd,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,eAAe,CAAC,IAAI,EAAE,SAAS,EAAE,CAAC;aAC/D;SACF;KACF;IAED,OAAO,WAAW,CAAC;AACrB,CAAC,CACF,CAAC;AAEF,mGAAmG;AACnG,MAAM,iCAAiC,GAAG,uBAAuB,CAC/D;IACE,0BAA0B;IAC1B,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,iBAAiB;IAClC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,UAAU;IAC3B,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,aAAa;IAC9B,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,eAAe;IAChC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,8BAA8B;CAChD,EACD,CACE,WAAW,EACX,iBAAiB,EACjB,UAAU,EACV,aAAa,EACb,eAAe,EACf,8BAA8B,EAC9B,EAAE;;IACF,MAAM,WAAW,GAAyB,EAAE,CAAC;IAE7C,KAAK,MAAM,CAAC,OAAO,EAAE,aAAa,CAAC,IAAI,MAAM,CAAC,OAAO,CACnD,iBAAiB,CAC+B,EAAE;QAClD,KAAK,MAAM,CAAC,cAAc,EAAE,cAAc,CAAC,IAAI,MAAM,CAAC,OAAO,CAC3D,aAAa,CACd,EAAE;YACD,MAAM,OAAO,GAAG,WAAW,CAAC,cAAc,CAAC,WAAW,EAAE,CAAC,CAAC;YAC1D,IAAI,CAAC,OAAO,EAAE;gBACZ,SAAS;aACV;YAED,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC;YAEpD,WAAW,CAAC,cAAc,MAA1B,WAAW,CAAC,cAAc,IAAM,EAAE,EAAC;YACnC,MAAA,WAAW,CAAC,cAAc,CAAC,EAAC,OAAO,SAAP,OAAO,IAAM,EAAE,EAAC;YAC5C,MAAM,gBAAgB,GAAG,WAAW,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC,CAAC;YAE9D,MAAM,UAAU,GAAG,cAAc,CAAC,OAAO,IAAI,KAAK,CAAC;YAEnD,MAAM,cAAc,GAClB,8BAA8B,CAAC,OAAO,CAAC,EAAE,cAAc,IAAI,QAAQ,CAAC;YAEtE,MAAM,WAAW,GAAG;gBAClB,OAAO,EAAE,IAAA,iCAAqB,EAAC,OAAO,CAAC;gBACvC,QAAQ,EAAE,EAAE;gBACZ,IAAI,EAAE,cAAc,KAAK,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,cAAc;gBAC5D,MAAM,EAAE,cAAc;gBACtB,uDAAuD;gBACvD,KAAK,EAAE,EAAE;aACV,CAAC;YAEF,MAAM,QAAQ,GAAG,yBAAyB,CACxC,UAAU,EACV,WAAW,CAAC,QAAQ,EACpB,UAAU,EACV,aAAa,EACb,OAAO,EACP,WAAW,CAAC,OAAO,CACpB,CAAC;YAEF,gBAAgB,CAAC,IAAI,CAAC;gBACpB,IAAI,EAAE,IAAsB;gBAC5B,OAAO,EAAE,WAAW,CAAC,OAAO;gBAC5B,QAAQ,EAAE,IAAI;gBACd,OAAO,EAAE,WAAW,CAAC,OAAO;gBAC5B,KAAK,EAAE,WAAW,CAAC,KAAK;gBACxB,IAAI,EAAE,WAAW,CAAC,IAAI;gBACtB,MAAM,EAAE,WAAW,CAAC,MAAM;gBAC1B,SAAS;gBACT,QAAQ,EAAE,WAAW,CAAC,QAAQ;gBAC9B,OAAO,EAAE,IAAA,gDAA4B,EACnC,IAAA,mBAAW,EAAC,UAAU,CAAC,EACvB,WAAW,CAAC,QAAQ,CACrB;gBACD,IAAI,EAAE,QAAQ;oBACZ,CAAC,CAAC;wBACE,OAAO,EAAE,QAAQ,CAAC,OAAO;wBACzB,QAAQ,EAAE,eAAe;wBACzB,cAAc,EAAE,QAAQ,CAAC,cAAc;qBACxC;oBACH,CAAC,CAAC,SAAS;gBACb,OAAO;aACR,CAAC,CAAC;SACJ;KACF;IAED,OAAO,WAAW,CAAC;AACrB,CAAC,CACF,CAAC;AAEF,MAAM,kBAAkB,GAAG,uBAAuB,CAChD;IACE,0BAA0B;IAC1B,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,SAAS;IAC1B,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,gBAAgB;IACjC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,aAAa;IAC9B,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,UAAU;IAC3B,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,aAAa;IAC9B,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,eAAe;CACjC,EACD,CACE,WAAW,EACX,SAAS,EACT,gBAAgB,EAChB,aAAa,EACb,UAAU,EACV,aAAa,EACb,eAAe,EACf,EAAE;;IACF,MAAM,WAAW,GAAyB,EAAE,CAAC;IAE7C,KAAK,MAAM,CAAC,OAAO,EAAE,WAAW,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,CAG1D,EAAE;QACH,KAAK,MAAM,CAAC,cAAc,EAAE,aAAa,CAAC,IAAI,MAAM,CAAC,OAAO,CAC1D,WAAW,CACQ,EAAE;YACrB,KAAK,MAAM,KAAK,IAAI,aAAa,EAAE;gBACjC,MAAM,YAAY,GAAG,KAAK,CAAC,OAAc,CAAC;gBAC1C,MAAM,OAAO,GAAG,WAAW,CAAC,cAAc,CAAC,CAAC;gBAC5C,IAAI,CAAC,OAAO,EAAE;oBACZ,SAAS;iBACV;gBAED,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC;gBAEpD,IACE,gBAAgB,CAAC,OAAO,CAAC,EAAE,CAAC,cAAc,CAAC,EAAE,QAAQ,CAAC,YAAY,CAAC,EACnE;oBACA,SAAS;iBACV;gBAED,MAAM,UAAU,GACd,aAAa,CAAC,cAAc,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC;gBAE3D,IAAI,CAAC,UAAU,EAAE;oBACf,SAAS;iBACV;gBAED,WAAW,CAAC,cAAc,MAA1B,WAAW,CAAC,cAAc,IAAM,EAAE,EAAC;gBACnC,MAAA,WAAW,CAAC,cAAc,CAAC,EAAC,OAAO,SAAP,OAAO,IAAM,EAAE,EAAC;gBAC5C,MAAM,gBAAgB,GAAG,WAAW,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC,CAAC;gBAE9D,MAAM,QAAQ,GAAG,yBAAyB,CACxC,UAAU,EACV,KAAK,CAAC,QAAQ,EACd,UAAU,EACV,aAAa,EACb,OAAO,EACP,YAAY,CACb,CAAC;gBAEF,gBAAgB,CAAC,IAAI,CAAC;oBACpB,IAAI,EAAE,IAAsB;oBAC5B,OAAO,EAAE,YAAY;oBACrB,QAAQ,EAAE,KAAK;oBACf,OAAO,EAAE,YAAY;oBACrB,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,EAAE;oBACxB,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,MAAM;oBAChC,MAAM,EAAE,KAAK,CAAC,MAAM;oBACpB,SAAS;oBACT,QAAQ,EAAE,KAAK,CAAC,QAAQ;oBACxB,OAAO,EAAE,IAAA,gDAA4B,EACnC,IAAA,mBAAW,EAAC,UAAU,CAAC,EACvB,KAAK,CAAC,QAAQ,CACf;oBACD,IAAI,EAAE,QAAQ;wBACZ,CAAC,CAAC;4BACE,OAAO,EAAE,QAAQ,CAAC,OAAO;4BACzB,QAAQ,EAAE,eAAe;4BACzB,cAAc,EAAE,QAAQ,CAAC,cAAc;yBACxC;wBACH,CAAC,CAAC,SAAS;oBACb,OAAO;iBACR,CAAC,CAAC;aACJ;SACF;KACF;IAED,OAAO,WAAW,CAAC;AACrB,CAAC,CACF,CAAC;AAEF,MAAM,yBAAyB,GAAG,uBAAuB,CACvD;IACE,0BAA0B;IAC1B,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,cAAc;IAC/B,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,cAAc;IAC/B,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ;IACzB,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,eAAe;IAChC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,eAAe;CACjC,EACD,CACE,WAAW,EACX,gBAAgB,EAChB,wBAAwB,EACxB,kBAAkB,EAClB,yBAAyB,EACzB,eAAe,EACf,EAAE;;IACF,MAAM,WAAW,GAAyB,EAAE,CAAC;IAE7C,KAAK,MAAM,CAAC,SAAS,EAAE,aAAa,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,EAAE;QACzE,KAAK,MAAM,OAAO,IAAI,aAAa,EAAE;YACnC,IAAI,SAAgD,CAAC;YACrD,IAAI;gBACF,SAAS,GAAG,IAAA,0BAAkB,EAAC,OAAO,CAAC,CAAC;aACzC;YAAC,MAAM;gBACN,6FAA6F;gBAC7F,SAAS;aACV;YAED,MAAM,EAAE,OAAO,EAAE,GAAG,SAAS,CAAC;YAC9B,MAAM,KAAK,GAAG,GAAG,SAAS,CAAC,cAAc,IAAI,SAAS,CAAC,cAAc,EAAE,CAAC;YAExE,MAAM,OAAO,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC;YACvC,MAAM,aAAa,GAAG,wBAAwB,CAAC,OAAO,CAAC,CAAC;YACxD,IAAI,CAAC,OAAO,IAAI,CAAC,aAAa,EAAE;gBAC9B,SAAS;aACV;YAED,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;YAEzC,WAAW,CAAC,cAAc,MAA1B,WAAW,CAAC,cAAc,IAAM,EAAE,EAAC;YACnC,MAAA,WAAW,CAAC,cAAc,CAAC,EAAC,OAAO,SAAP,OAAO,IAAM,EAAE,EAAC;YAC5C,MAAM,gBAAgB,GAAG,WAAW,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC,CAAC;YAE9D,MAAM,OAAO,GAKG,kBAAkB,CAAC,SAAS,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC;YAEzD,IAAI,CAAC,OAAO,EAAE;gBACZ,SAAS;aACV;YAED,MAAM,QAAQ,GAAG,gCAAgC,CAC/C,OAAO,EACP,yBAAyB,EACzB,OAAO,CACR,CAAC;YAEF,gGAAgG;YAChG,gBAAgB,CAAC,IAAI,CAAC;gBACpB,IAAI,EAAE,IAA6B;gBACnC,OAAO;gBACP,QAAQ,EAAE,2BAA2B,CAAC,QAAQ,CAAC,OAAO,CAAC;gBACvD,KAAK,EAAE,aAAa,CAAC,OAAO;gBAC5B,IAAI,EAAE,aAAa,CAAC,IAAI,IAAI,aAAa,CAAC,MAAM,IAAI,KAAK;gBACzD,MAAM,EAAE,aAAa,CAAC,MAAM,IAAI,KAAK;gBACrC,SAAS;gBACT,QAAQ,EACN,aAAa,CAAC,KAAK,CAAC,IAAI,CACtB,CAAC,IAAI,EAAE,EAAE,CACP,IAAI,CAAC,IAAI,KAAK,aAAa,CAAC,IAAI;oBAChC,IAAI,CAAC,MAAM,KAAK,aAAa,CAAC,MAAM,CACvC,EAAE,QAAQ,IAAI,CAAC;gBAClB,OAAO,EAAE,OAAO,CAAC,MAAM;gBACvB,IAAI,EAAE,QAAQ;oBACZ,CAAC,CAAC;wBACE,OAAO,EAAE,QAAQ,CAAC,OAAO;wBACzB,QAAQ,EAAE,eAAe;wBACzB,cAAc,EAAE,QAAQ,CAAC,cAAc;qBACxC;oBACH,CAAC,CAAC,SAAS;gBACb,OAAO;aACR,CAAC,CAAC;SACJ;KACF;IAED,OAAO,WAAW,CAAC;AACrB,CAAC,CACF,CAAC;AAEF,MAAM,eAAe,GAAG,uBAAuB,CAC7C;IACE,kBAAkB;IAClB,yBAAyB;IACzB,iCAAiC;CAClC,EACD,CAAC,SAAS,EAAE,gBAAgB,EAAE,wBAAwB,EAAE,EAAE;IACxD,MAAM,WAAW,GAAyB,EAAE,CAAC;IAE7C,WAAW,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;IAEpC,WAAW,CAAC,WAAW,EAAE,gBAAgB,CAAC,CAAC;IAE3C,WAAW,CAAC,WAAW,EAAE,wBAAwB,CAAC,CAAC;IAEnD,OAAO,WAAW,CAAC;AACrB,CAAC,CACF,CAAC;AAEW,QAAA,kCAAkC,GAAG,uBAAuB,CACvE,CAAC,eAAe,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,EAC/C,CAAC,WAAW,EAAE,WAAW,EAAE,EAAE;IAC3B,MAAM,EAAE,oBAAoB,EAAE,GAAG,WAAW,CAAC;IAC7C,IAAI,CAAC,oBAAoB,EAAE;QACzB,OAAO,EAAE,CAAC;KACX;IACD,OAAO,WAAW,CAAC,oBAAoB,CAAC,IAAI,EAAE,CAAC;AACjD,CAAC,CACF,CAAC;AAEF,6HAA6H;AAC7H;;;;;GAKG;AACH,SAAS,WAAW,CAClB,cAAoC,EACpC,SAA+B;IAE/B,KAAK,MAAM,CAAC,cAAc,EAAE,aAAa,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,CAGnE,EAAE;QACH,MAAM,0BAA0B,GAAG,cAAc,CAAC,cAAc,CAAC,CAAC;QAElE,IAAI,CAAC,0BAA0B,EAAE;YAC/B,cAAc,CAAC,cAAc,CAAC,GAAG,EAAE,CAAC;YACpC,KAAK,MAAM,CAAC,OAAO,EAAE,WAAW,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE;gBAClE,cAAc,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,WAAW,CAAC,CAAC;aAC5D;SACF;aAAM;YACL,KAAK,MAAM,CAAC,OAAO,EAAE,WAAW,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE;gBAClE,0BAA0B,CAAC,OAAO,MAAlC,0BAA0B,CAAC,OAAO,IAAM,EAAE,EAAC;gBAC3C,0BAA0B,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,CAAC;aAC1D;SACF;KACF;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,yBAAyB,CAChC,UAAe,EACf,QAAgB,EAChB,UAAmD,EACnD,aAAiD,EACjD,OAAY,EACZ,YAAiB;IAEjB,MAAM,eAAe,GAAG,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC;IAE5D,IAAI,CAAC,eAAe,EAAE;QACpB,OAAO,SAAS,CAAC;KAClB;IAED,MAAM,YAAY,GAAG,aAAa,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;IAE7D,IAAI,CAAC,YAAY,EAAE,cAAc,EAAE;QACjC,OAAO,SAAS,CAAC;KAClB;IAED,MAAM,WAAW,GACf,CAAC,IAAA,sCAAmB,EAAC,UAAU,CAAC,GAAG,EAAE,IAAI,QAAQ,CAAC;QAClD,eAAe,CAAC,KAAK;QACrB,YAAY,CAAC,cAAc,CAAC;IAE9B,OAAO;QACL,OAAO,EAAE,WAAW;QACpB,cAAc,EAAE,YAAY,CAAC,cAAc;KAC5C,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,gCAAgC,CACvC,OAAyC,EACzC,yBAAkF,EAClF,OAAkD;IAElD,MAAM,eAAe,GAAG,yBAAyB,CAAC,OAAO,CAAC,CAAC;IAE3D,IAAI,CAAC,eAAe,EAAE,IAAI,EAAE;QAC1B,OAAO,SAAS,CAAC;KAClB;IAED,OAAO;QACL,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,eAAe,CAAC,IAAI,CAAC;QAC9D,cAAc,EAAE,MAAM,CAAC,eAAe,CAAC,IAAI,CAAC;KAC7C,CAAC;AACJ,CAAC","sourcesContent":["import type { AccountGroupId } from '@metamask/account-api';\nimport type { AccountTreeControllerState } from '@metamask/account-tree-controller';\nimport type { AccountsControllerState } from '@metamask/accounts-controller';\nimport { convertHexToDecimal } from '@metamask/controller-utils';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\nimport type { NetworkState } from '@metamask/network-controller';\nimport { hexToBigInt, parseCaipAssetType, type Hex } from '@metamask/utils';\nimport { createSelector } from 'reselect';\n\nimport { stringifyBalanceWithDecimals } from './stringify-balance';\nimport type { CurrencyRateState } from '../CurrencyRateController';\nimport type { MultichainAssetsControllerState } from '../MultichainAssetsController';\nimport type { MultichainAssetsRatesControllerState } from '../MultichainAssetsRatesController';\nimport type { MultichainBalancesControllerState } from '../MultichainBalancesController';\nimport { getNativeTokenAddress } from '../token-prices-service/codefi-v2';\nimport type { TokenBalancesControllerState } from '../TokenBalancesController';\nimport type { Token, TokenRatesControllerState } from '../TokenRatesController';\nimport type { TokensControllerState } from '../TokensController';\n\ntype AssetsByAccountGroup = {\n [accountGroupId: AccountGroupId]: AccountGroupAssets;\n};\n\nexport type AccountGroupAssets = {\n [network: string]: Asset[];\n};\n\n// If this gets out of hand with other chains, we should probably have a permanent object that defines them\nconst MULTICHAIN_NATIVE_ASSET_IDS = [\n `bip122:000000000019d6689c085ae165831e93/slip44:0`,\n `solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp/slip44:501`,\n];\n\ntype EvmAccountType = Extract<InternalAccount['type'], `eip155:${string}`>;\ntype MultichainAccountType = Exclude<\n InternalAccount['type'],\n `eip155:${string}`\n>;\n\nexport type Asset = (\n | {\n type: EvmAccountType;\n assetId: Hex; // This is also the address for EVM tokens\n address: Hex;\n chainId: Hex;\n }\n | {\n type: MultichainAccountType;\n assetId: `${string}:${string}/${string}:${string}`;\n chainId: `${string}:${string}`;\n }\n) & {\n accountId: string;\n image: string;\n name: string;\n symbol: string;\n decimals: number;\n isNative: boolean;\n balance: string;\n fiat:\n | {\n balance: number;\n currency: string;\n conversionRate: number;\n }\n | undefined;\n};\n\nexport type AssetListState = {\n accountTree: AccountTreeControllerState['accountTree'];\n internalAccounts: AccountsControllerState['internalAccounts'];\n allTokens: TokensControllerState['allTokens'];\n allIgnoredTokens: TokensControllerState['allIgnoredTokens'];\n tokenBalances: TokenBalancesControllerState['tokenBalances'];\n marketData: TokenRatesControllerState['marketData'];\n currencyRates: CurrencyRateState['currencyRates'];\n accountsAssets: MultichainAssetsControllerState['accountsAssets'];\n assetsMetadata: MultichainAssetsControllerState['assetsMetadata'];\n balances: MultichainBalancesControllerState['balances'];\n conversionRates: MultichainAssetsRatesControllerState['conversionRates'];\n currentCurrency: CurrencyRateState['currentCurrency'];\n networkConfigurationsByChainId: NetworkState['networkConfigurationsByChainId'];\n // This is the state from AccountTrackerController. The state is different on mobile and extension\n // accountsByChainId with a balance is the only field that both clients have in common\n // This field could be removed once TokenBalancesController returns native balances\n accountsByChainId: Record<\n Hex,\n Record<\n Hex,\n {\n balance: Hex | null;\n }\n >\n >;\n};\n\nconst createAssetListSelector = createSelector.withTypes<AssetListState>();\n\nconst selectAccountsToGroupIdMap = createAssetListSelector(\n [(state) => state.accountTree, (state) => state.internalAccounts],\n (accountTree, internalAccounts) => {\n const accountsMap: Record<\n string,\n {\n accountGroupId: AccountGroupId;\n type: InternalAccount['type'];\n accountId: string;\n }\n > = {};\n for (const { groups } of Object.values(accountTree.wallets)) {\n for (const { id: accountGroupId, accounts } of Object.values(groups)) {\n for (const accountId of accounts) {\n const internalAccount = internalAccounts.accounts[accountId];\n\n accountsMap[\n // TODO: We would not need internalAccounts if evmTokens state had the accountId\n internalAccount.type.startsWith('eip155')\n ? internalAccount.address\n : accountId\n ] = { accountGroupId, type: internalAccount.type, accountId };\n }\n }\n }\n\n return accountsMap;\n },\n);\n\n// TODO: This selector will not be needed once the native balances are part of the evm tokens state\nconst selectAllEvmAccountNativeBalances = createAssetListSelector(\n [\n selectAccountsToGroupIdMap,\n (state) => state.accountsByChainId,\n (state) => state.marketData,\n (state) => state.currencyRates,\n (state) => state.currentCurrency,\n (state) => state.networkConfigurationsByChainId,\n ],\n (\n accountsMap,\n accountsByChainId,\n marketData,\n currencyRates,\n currentCurrency,\n networkConfigurationsByChainId,\n ) => {\n const groupAssets: AssetsByAccountGroup = {};\n\n for (const [chainId, chainAccounts] of Object.entries(\n accountsByChainId,\n ) as [Hex, Record<Hex, { balance: Hex | null }>][]) {\n for (const [accountAddress, accountBalance] of Object.entries(\n chainAccounts,\n )) {\n const account = accountsMap[accountAddress.toLowerCase()];\n if (!account) {\n continue;\n }\n\n const { accountGroupId, type, accountId } = account;\n\n groupAssets[accountGroupId] ??= {};\n groupAssets[accountGroupId][chainId] ??= [];\n const groupChainAssets = groupAssets[accountGroupId][chainId];\n\n const rawBalance = accountBalance.balance || '0x0';\n\n const nativeCurrency =\n networkConfigurationsByChainId[chainId]?.nativeCurrency || 'NATIVE';\n\n const nativeToken = {\n address: getNativeTokenAddress(chainId),\n decimals: 18,\n name: nativeCurrency === 'ETH' ? 'Ethereum' : nativeCurrency,\n symbol: nativeCurrency,\n // This field need to be filled at client level for now\n image: '',\n };\n\n const fiatData = getFiatBalanceForEvmToken(\n rawBalance,\n nativeToken.decimals,\n marketData,\n currencyRates,\n chainId,\n nativeToken.address,\n );\n\n groupChainAssets.push({\n type: type as EvmAccountType,\n assetId: nativeToken.address,\n isNative: true,\n address: nativeToken.address,\n image: nativeToken.image,\n name: nativeToken.name,\n symbol: nativeToken.symbol,\n accountId,\n decimals: nativeToken.decimals,\n balance: stringifyBalanceWithDecimals(\n hexToBigInt(rawBalance),\n nativeToken.decimals,\n ),\n fiat: fiatData\n ? {\n balance: fiatData.balance,\n currency: currentCurrency,\n conversionRate: fiatData.conversionRate,\n }\n : undefined,\n chainId,\n });\n }\n }\n\n return groupAssets;\n },\n);\n\nconst selectAllEvmAssets = createAssetListSelector(\n [\n selectAccountsToGroupIdMap,\n (state) => state.allTokens,\n (state) => state.allIgnoredTokens,\n (state) => state.tokenBalances,\n (state) => state.marketData,\n (state) => state.currencyRates,\n (state) => state.currentCurrency,\n ],\n (\n accountsMap,\n evmTokens,\n ignoredEvmTokens,\n tokenBalances,\n marketData,\n currencyRates,\n currentCurrency,\n ) => {\n const groupAssets: AssetsByAccountGroup = {};\n\n for (const [chainId, chainTokens] of Object.entries(evmTokens) as [\n Hex,\n { [key: string]: Token[] },\n ][]) {\n for (const [accountAddress, addressTokens] of Object.entries(\n chainTokens,\n ) as [Hex, Token[]][]) {\n for (const token of addressTokens) {\n const tokenAddress = token.address as Hex;\n const account = accountsMap[accountAddress];\n if (!account) {\n continue;\n }\n\n const { accountGroupId, type, accountId } = account;\n\n if (\n ignoredEvmTokens[chainId]?.[accountAddress]?.includes(tokenAddress)\n ) {\n continue;\n }\n\n const rawBalance =\n tokenBalances[accountAddress]?.[chainId]?.[tokenAddress];\n\n if (!rawBalance) {\n continue;\n }\n\n groupAssets[accountGroupId] ??= {};\n groupAssets[accountGroupId][chainId] ??= [];\n const groupChainAssets = groupAssets[accountGroupId][chainId];\n\n const fiatData = getFiatBalanceForEvmToken(\n rawBalance,\n token.decimals,\n marketData,\n currencyRates,\n chainId,\n tokenAddress,\n );\n\n groupChainAssets.push({\n type: type as EvmAccountType,\n assetId: tokenAddress,\n isNative: false,\n address: tokenAddress,\n image: token.image ?? '',\n name: token.name ?? token.symbol,\n symbol: token.symbol,\n accountId,\n decimals: token.decimals,\n balance: stringifyBalanceWithDecimals(\n hexToBigInt(rawBalance),\n token.decimals,\n ),\n fiat: fiatData\n ? {\n balance: fiatData.balance,\n currency: currentCurrency,\n conversionRate: fiatData.conversionRate,\n }\n : undefined,\n chainId,\n });\n }\n }\n }\n\n return groupAssets;\n },\n);\n\nconst selectAllMultichainAssets = createAssetListSelector(\n [\n selectAccountsToGroupIdMap,\n (state) => state.accountsAssets,\n (state) => state.assetsMetadata,\n (state) => state.balances,\n (state) => state.conversionRates,\n (state) => state.currentCurrency,\n ],\n (\n accountsMap,\n multichainTokens,\n multichainAssetsMetadata,\n multichainBalances,\n multichainConversionRates,\n currentCurrency,\n ) => {\n const groupAssets: AssetsByAccountGroup = {};\n\n for (const [accountId, accountAssets] of Object.entries(multichainTokens)) {\n for (const assetId of accountAssets) {\n let caipAsset: ReturnType<typeof parseCaipAssetType>;\n try {\n caipAsset = parseCaipAssetType(assetId);\n } catch {\n // TODO: We should log this error when we have the ability to inject a logger from the client\n continue;\n }\n\n const { chainId } = caipAsset;\n const asset = `${caipAsset.assetNamespace}:${caipAsset.assetReference}`;\n\n const account = accountsMap[accountId];\n const assetMetadata = multichainAssetsMetadata[assetId];\n if (!account || !assetMetadata) {\n continue;\n }\n\n const { accountGroupId, type } = account;\n\n groupAssets[accountGroupId] ??= {};\n groupAssets[accountGroupId][chainId] ??= [];\n const groupChainAssets = groupAssets[accountGroupId][chainId];\n\n const balance:\n | {\n amount: string;\n unit: string;\n }\n | undefined = multichainBalances[accountId]?.[assetId];\n\n if (!balance) {\n continue;\n }\n\n const fiatData = getFiatBalanceForMultichainAsset(\n balance,\n multichainConversionRates,\n assetId,\n );\n\n // TODO: We shouldn't have to rely on fallbacks for name and symbol, they should not be optional\n groupChainAssets.push({\n type: type as MultichainAccountType,\n assetId,\n isNative: MULTICHAIN_NATIVE_ASSET_IDS.includes(assetId),\n image: assetMetadata.iconUrl,\n name: assetMetadata.name ?? assetMetadata.symbol ?? asset,\n symbol: assetMetadata.symbol ?? asset,\n accountId,\n decimals:\n assetMetadata.units.find(\n (unit) =>\n unit.name === assetMetadata.name &&\n unit.symbol === assetMetadata.symbol,\n )?.decimals ?? 0,\n balance: balance.amount,\n fiat: fiatData\n ? {\n balance: fiatData.balance,\n currency: currentCurrency,\n conversionRate: fiatData.conversionRate,\n }\n : undefined,\n chainId,\n });\n }\n }\n\n return groupAssets;\n },\n);\n\nconst selectAllAssets = createAssetListSelector(\n [\n selectAllEvmAssets,\n selectAllMultichainAssets,\n selectAllEvmAccountNativeBalances,\n ],\n (evmAssets, multichainAssets, evmAccountNativeBalances) => {\n const groupAssets: AssetsByAccountGroup = {};\n\n mergeAssets(groupAssets, evmAssets);\n\n mergeAssets(groupAssets, multichainAssets);\n\n mergeAssets(groupAssets, evmAccountNativeBalances);\n\n return groupAssets;\n },\n);\n\nexport const selectAssetsBySelectedAccountGroup = createAssetListSelector(\n [selectAllAssets, (state) => state.accountTree],\n (groupAssets, accountTree) => {\n const { selectedAccountGroup } = accountTree;\n if (!selectedAccountGroup) {\n return {};\n }\n return groupAssets[selectedAccountGroup] || {};\n },\n);\n\n// TODO: Once native assets are part of the evm tokens state, this function can be simplified as chains will always be unique\n/**\n * Merges the new assets into the existing assets\n *\n * @param existingAssets - The existing assets\n * @param newAssets - The new assets\n */\nfunction mergeAssets(\n existingAssets: AssetsByAccountGroup,\n newAssets: AssetsByAccountGroup,\n) {\n for (const [accountGroupId, accountAssets] of Object.entries(newAssets) as [\n AccountGroupId,\n AccountGroupAssets,\n ][]) {\n const existingAccountGroupAssets = existingAssets[accountGroupId];\n\n if (!existingAccountGroupAssets) {\n existingAssets[accountGroupId] = {};\n for (const [network, chainAssets] of Object.entries(accountAssets)) {\n existingAssets[accountGroupId][network] = [...chainAssets];\n }\n } else {\n for (const [network, chainAssets] of Object.entries(accountAssets)) {\n existingAccountGroupAssets[network] ??= [];\n existingAccountGroupAssets[network].push(...chainAssets);\n }\n }\n }\n}\n\n/**\n * @param rawBalance - The balance of the token\n * @param decimals - The decimals of the token\n * @param marketData - The market data for the token\n * @param currencyRates - The currency rates for the token\n * @param chainId - The chain id of the token\n * @param tokenAddress - The address of the token\n * @returns The price and currency of the token in the current currency. Returns undefined if the asset is not found in the market data or currency rates.\n */\nfunction getFiatBalanceForEvmToken(\n rawBalance: Hex,\n decimals: number,\n marketData: TokenRatesControllerState['marketData'],\n currencyRates: CurrencyRateState['currencyRates'],\n chainId: Hex,\n tokenAddress: Hex,\n) {\n const tokenMarketData = marketData[chainId]?.[tokenAddress];\n\n if (!tokenMarketData) {\n return undefined;\n }\n\n const currencyRate = currencyRates[tokenMarketData.currency];\n\n if (!currencyRate?.conversionRate) {\n return undefined;\n }\n\n const fiatBalance =\n (convertHexToDecimal(rawBalance) / 10 ** decimals) *\n tokenMarketData.price *\n currencyRate.conversionRate;\n\n return {\n balance: fiatBalance,\n conversionRate: currencyRate.conversionRate,\n };\n}\n\n/**\n * @param balance - The balance of the asset, in the format { amount: string; unit: string }\n * @param balance.amount - The amount of the balance\n * @param balance.unit - The unit of the balance\n * @param multichainConversionRates - The conversion rates for the multichain asset\n * @param assetId - The asset id of the asset\n * @returns The price and currency of the token in the current currency. Returns undefined if the asset is not found in the conversion rates.\n */\nfunction getFiatBalanceForMultichainAsset(\n balance: { amount: string; unit: string },\n multichainConversionRates: MultichainAssetsRatesControllerState['conversionRates'],\n assetId: `${string}:${string}/${string}:${string}`,\n) {\n const assetMarketData = multichainConversionRates[assetId];\n\n if (!assetMarketData?.rate) {\n return undefined;\n }\n\n return {\n balance: Number(balance.amount) * Number(assetMarketData.rate),\n conversionRate: Number(assetMarketData.rate),\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"token-selectors.cjs","sourceRoot":"","sources":["../../src/selectors/token-selectors.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AccountGroupId } from '@metamask/account-api';\nimport type { AccountTreeControllerState } from '@metamask/account-tree-controller';\nimport type { AccountsControllerState } from '@metamask/accounts-controller';\nimport { convertHexToDecimal } from '@metamask/controller-utils';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\nimport type { NetworkState } from '@metamask/network-controller';\nimport { hexToBigInt, parseCaipAssetType, type Hex } from '@metamask/utils';\nimport { createSelector } from 'reselect';\n\nimport {\n parseBalanceWithDecimals,\n stringifyBalanceWithDecimals,\n} from './stringify-balance';\nimport type { CurrencyRateState } from '../CurrencyRateController';\nimport type { MultichainAssetsControllerState } from '../MultichainAssetsController';\nimport type { MultichainAssetsRatesControllerState } from '../MultichainAssetsRatesController';\nimport type { MultichainBalancesControllerState } from '../MultichainBalancesController';\nimport { getNativeTokenAddress } from '../token-prices-service/codefi-v2';\nimport type { TokenBalancesControllerState } from '../TokenBalancesController';\nimport type { Token, TokenRatesControllerState } from '../TokenRatesController';\nimport type { TokensControllerState } from '../TokensController';\n\ntype AssetsByAccountGroup = {\n [accountGroupId: AccountGroupId]: AccountGroupAssets;\n};\n\nexport type AccountGroupAssets = {\n [network: string]: Asset[];\n};\n\n// If this gets out of hand with other chains, we should probably have a permanent object that defines them\nconst MULTICHAIN_NATIVE_ASSET_IDS = [\n `bip122:000000000019d6689c085ae165831e93/slip44:0`,\n `solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp/slip44:501`,\n];\n\ntype EvmAccountType = Extract<InternalAccount['type'], `eip155:${string}`>;\ntype MultichainAccountType = Exclude<\n InternalAccount['type'],\n `eip155:${string}`\n>;\n\nexport type Asset = (\n | {\n type: EvmAccountType;\n assetId: Hex; // This is also the address for EVM tokens\n address: Hex;\n chainId: Hex;\n }\n | {\n type: MultichainAccountType;\n assetId: `${string}:${string}/${string}:${string}`;\n chainId: `${string}:${string}`;\n }\n) & {\n accountId: string;\n image: string;\n name: string;\n symbol: string;\n decimals: number;\n isNative: boolean;\n rawBalance: Hex;\n balance: string;\n fiat:\n | {\n balance: number;\n currency: string;\n conversionRate: number;\n }\n | undefined;\n};\n\nexport type AssetListState = {\n accountTree: AccountTreeControllerState['accountTree'];\n internalAccounts: AccountsControllerState['internalAccounts'];\n allTokens: TokensControllerState['allTokens'];\n allIgnoredTokens: TokensControllerState['allIgnoredTokens'];\n tokenBalances: TokenBalancesControllerState['tokenBalances'];\n marketData: TokenRatesControllerState['marketData'];\n currencyRates: CurrencyRateState['currencyRates'];\n accountsAssets: MultichainAssetsControllerState['accountsAssets'];\n assetsMetadata: MultichainAssetsControllerState['assetsMetadata'];\n balances: MultichainBalancesControllerState['balances'];\n conversionRates: MultichainAssetsRatesControllerState['conversionRates'];\n currentCurrency: CurrencyRateState['currentCurrency'];\n networkConfigurationsByChainId: NetworkState['networkConfigurationsByChainId'];\n // This is the state from AccountTrackerController. The state is different on mobile and extension\n // accountsByChainId with a balance is the only field that both clients have in common\n // This field could be removed once TokenBalancesController returns native balances\n accountsByChainId: Record<\n Hex,\n Record<\n Hex,\n {\n balance: Hex | null;\n }\n >\n >;\n};\n\nconst createAssetListSelector = createSelector.withTypes<AssetListState>();\n\nconst selectAccountsToGroupIdMap = createAssetListSelector(\n [(state) => state.accountTree, (state) => state.internalAccounts],\n (accountTree, internalAccounts) => {\n const accountsMap: Record<\n string,\n {\n accountGroupId: AccountGroupId;\n type: InternalAccount['type'];\n accountId: string;\n }\n > = {};\n for (const { groups } of Object.values(accountTree.wallets)) {\n for (const { id: accountGroupId, accounts } of Object.values(groups)) {\n for (const accountId of accounts) {\n const internalAccount = internalAccounts.accounts[accountId];\n\n accountsMap[\n // TODO: We would not need internalAccounts if evmTokens state had the accountId\n internalAccount.type.startsWith('eip155')\n ? internalAccount.address\n : accountId\n ] = { accountGroupId, type: internalAccount.type, accountId };\n }\n }\n }\n\n return accountsMap;\n },\n);\n\n// TODO: This selector will not be needed once the native balances are part of the evm tokens state\nconst selectAllEvmAccountNativeBalances = createAssetListSelector(\n [\n selectAccountsToGroupIdMap,\n (state) => state.accountsByChainId,\n (state) => state.marketData,\n (state) => state.currencyRates,\n (state) => state.currentCurrency,\n (state) => state.networkConfigurationsByChainId,\n ],\n (\n accountsMap,\n accountsByChainId,\n marketData,\n currencyRates,\n currentCurrency,\n networkConfigurationsByChainId,\n ) => {\n const groupAssets: AssetsByAccountGroup = {};\n\n for (const [chainId, chainAccounts] of Object.entries(\n accountsByChainId,\n ) as [Hex, Record<Hex, { balance: Hex | null }>][]) {\n for (const [accountAddress, accountBalance] of Object.entries(\n chainAccounts,\n )) {\n const account = accountsMap[accountAddress.toLowerCase()];\n if (!account) {\n continue;\n }\n\n const { accountGroupId, type, accountId } = account;\n\n groupAssets[accountGroupId] ??= {};\n groupAssets[accountGroupId][chainId] ??= [];\n const groupChainAssets = groupAssets[accountGroupId][chainId];\n\n // If a native balance is missing, we still want to show it as 0\n const rawBalance = accountBalance.balance || '0x0';\n\n const nativeCurrency =\n networkConfigurationsByChainId[chainId]?.nativeCurrency || 'NATIVE';\n\n const nativeToken = {\n address: getNativeTokenAddress(chainId),\n decimals: 18,\n name: nativeCurrency === 'ETH' ? 'Ethereum' : nativeCurrency,\n symbol: nativeCurrency,\n // This field need to be filled at client level for now\n image: '',\n };\n\n const fiatData = getFiatBalanceForEvmToken(\n rawBalance,\n nativeToken.decimals,\n marketData,\n currencyRates,\n chainId,\n nativeToken.address,\n );\n\n groupChainAssets.push({\n type: type as EvmAccountType,\n assetId: nativeToken.address,\n isNative: true,\n address: nativeToken.address,\n image: nativeToken.image,\n name: nativeToken.name,\n symbol: nativeToken.symbol,\n accountId,\n decimals: nativeToken.decimals,\n rawBalance,\n balance: stringifyBalanceWithDecimals(\n hexToBigInt(rawBalance),\n nativeToken.decimals,\n ),\n fiat: fiatData\n ? {\n balance: fiatData.balance,\n currency: currentCurrency,\n conversionRate: fiatData.conversionRate,\n }\n : undefined,\n chainId,\n });\n }\n }\n\n return groupAssets;\n },\n);\n\nconst selectAllEvmAssets = createAssetListSelector(\n [\n selectAccountsToGroupIdMap,\n (state) => state.allTokens,\n (state) => state.allIgnoredTokens,\n (state) => state.tokenBalances,\n (state) => state.marketData,\n (state) => state.currencyRates,\n (state) => state.currentCurrency,\n ],\n (\n accountsMap,\n evmTokens,\n ignoredEvmTokens,\n tokenBalances,\n marketData,\n currencyRates,\n currentCurrency,\n ) => {\n const groupAssets: AssetsByAccountGroup = {};\n\n for (const [chainId, chainTokens] of Object.entries(evmTokens) as [\n Hex,\n { [key: string]: Token[] },\n ][]) {\n for (const [accountAddress, addressTokens] of Object.entries(\n chainTokens,\n ) as [Hex, Token[]][]) {\n for (const token of addressTokens) {\n const tokenAddress = token.address as Hex;\n const account = accountsMap[accountAddress];\n if (!account) {\n continue;\n }\n\n const { accountGroupId, type, accountId } = account;\n\n if (\n ignoredEvmTokens[chainId]?.[accountAddress]?.includes(tokenAddress)\n ) {\n continue;\n }\n\n const rawBalance =\n tokenBalances[accountAddress]?.[chainId]?.[tokenAddress];\n\n if (!rawBalance) {\n continue;\n }\n\n groupAssets[accountGroupId] ??= {};\n groupAssets[accountGroupId][chainId] ??= [];\n const groupChainAssets = groupAssets[accountGroupId][chainId];\n\n const fiatData = getFiatBalanceForEvmToken(\n rawBalance,\n token.decimals,\n marketData,\n currencyRates,\n chainId,\n tokenAddress,\n );\n\n groupChainAssets.push({\n type: type as EvmAccountType,\n assetId: tokenAddress,\n isNative: false,\n address: tokenAddress,\n image: token.image ?? '',\n name: token.name ?? token.symbol,\n symbol: token.symbol,\n accountId,\n decimals: token.decimals,\n rawBalance,\n balance: stringifyBalanceWithDecimals(\n hexToBigInt(rawBalance),\n token.decimals,\n ),\n fiat: fiatData\n ? {\n balance: fiatData.balance,\n currency: currentCurrency,\n conversionRate: fiatData.conversionRate,\n }\n : undefined,\n chainId,\n });\n }\n }\n }\n\n return groupAssets;\n },\n);\n\nconst selectAllMultichainAssets = createAssetListSelector(\n [\n selectAccountsToGroupIdMap,\n (state) => state.accountsAssets,\n (state) => state.assetsMetadata,\n (state) => state.balances,\n (state) => state.conversionRates,\n (state) => state.currentCurrency,\n ],\n (\n accountsMap,\n multichainTokens,\n multichainAssetsMetadata,\n multichainBalances,\n multichainConversionRates,\n currentCurrency,\n ) => {\n const groupAssets: AssetsByAccountGroup = {};\n\n for (const [accountId, accountAssets] of Object.entries(multichainTokens)) {\n for (const assetId of accountAssets) {\n let caipAsset: ReturnType<typeof parseCaipAssetType>;\n try {\n caipAsset = parseCaipAssetType(assetId);\n } catch {\n // TODO: We should log this error when we have the ability to inject a logger from the client\n continue;\n }\n\n const { chainId } = caipAsset;\n const asset = `${caipAsset.assetNamespace}:${caipAsset.assetReference}`;\n\n const account = accountsMap[accountId];\n const assetMetadata = multichainAssetsMetadata[assetId];\n if (!account || !assetMetadata) {\n continue;\n }\n\n const { accountGroupId, type } = account;\n\n groupAssets[accountGroupId] ??= {};\n groupAssets[accountGroupId][chainId] ??= [];\n const groupChainAssets = groupAssets[accountGroupId][chainId];\n\n const balance:\n | {\n amount: string;\n unit: string;\n }\n | undefined = multichainBalances[accountId]?.[assetId];\n\n const decimals = assetMetadata.units.find(\n (unit) =>\n unit.name === assetMetadata.name &&\n unit.symbol === assetMetadata.symbol,\n )?.decimals;\n\n if (!balance || decimals === undefined) {\n continue;\n }\n\n const rawBalance = parseBalanceWithDecimals(balance.amount, decimals);\n\n if (!rawBalance) {\n continue;\n }\n\n const fiatData = getFiatBalanceForMultichainAsset(\n balance,\n multichainConversionRates,\n assetId,\n );\n\n // TODO: We shouldn't have to rely on fallbacks for name and symbol, they should not be optional\n groupChainAssets.push({\n type: type as MultichainAccountType,\n assetId,\n isNative: MULTICHAIN_NATIVE_ASSET_IDS.includes(assetId),\n image: assetMetadata.iconUrl,\n name: assetMetadata.name ?? assetMetadata.symbol ?? asset,\n symbol: assetMetadata.symbol ?? asset,\n accountId,\n decimals,\n rawBalance,\n balance: balance.amount,\n fiat: fiatData\n ? {\n balance: fiatData.balance,\n currency: currentCurrency,\n conversionRate: fiatData.conversionRate,\n }\n : undefined,\n chainId,\n });\n }\n }\n\n return groupAssets;\n },\n);\n\nconst selectAllAssets = createAssetListSelector(\n [\n selectAllEvmAssets,\n selectAllMultichainAssets,\n selectAllEvmAccountNativeBalances,\n ],\n (evmAssets, multichainAssets, evmAccountNativeBalances) => {\n const groupAssets: AssetsByAccountGroup = {};\n\n mergeAssets(groupAssets, evmAssets);\n\n mergeAssets(groupAssets, multichainAssets);\n\n mergeAssets(groupAssets, evmAccountNativeBalances);\n\n return groupAssets;\n },\n);\n\nexport const selectAssetsBySelectedAccountGroup = createAssetListSelector(\n [selectAllAssets, (state) => state.accountTree],\n (groupAssets, accountTree) => {\n const { selectedAccountGroup } = accountTree;\n if (!selectedAccountGroup) {\n return {};\n }\n return groupAssets[selectedAccountGroup] || {};\n },\n);\n\n// TODO: Once native assets are part of the evm tokens state, this function can be simplified as chains will always be unique\n/**\n * Merges the new assets into the existing assets\n *\n * @param existingAssets - The existing assets\n * @param newAssets - The new assets\n */\nfunction mergeAssets(\n existingAssets: AssetsByAccountGroup,\n newAssets: AssetsByAccountGroup,\n) {\n for (const [accountGroupId, accountAssets] of Object.entries(newAssets) as [\n AccountGroupId,\n AccountGroupAssets,\n ][]) {\n const existingAccountGroupAssets = existingAssets[accountGroupId];\n\n if (!existingAccountGroupAssets) {\n existingAssets[accountGroupId] = {};\n for (const [network, chainAssets] of Object.entries(accountAssets)) {\n existingAssets[accountGroupId][network] = [...chainAssets];\n }\n } else {\n for (const [network, chainAssets] of Object.entries(accountAssets)) {\n existingAccountGroupAssets[network] ??= [];\n existingAccountGroupAssets[network].push(...chainAssets);\n }\n }\n }\n}\n\n/**\n * @param rawBalance - The balance of the token\n * @param decimals - The decimals of the token\n * @param marketData - The market data for the token\n * @param currencyRates - The currency rates for the token\n * @param chainId - The chain id of the token\n * @param tokenAddress - The address of the token\n * @returns The price and currency of the token in the current currency. Returns undefined if the asset is not found in the market data or currency rates.\n */\nfunction getFiatBalanceForEvmToken(\n rawBalance: Hex,\n decimals: number,\n marketData: TokenRatesControllerState['marketData'],\n currencyRates: CurrencyRateState['currencyRates'],\n chainId: Hex,\n tokenAddress: Hex,\n) {\n const tokenMarketData = marketData[chainId]?.[tokenAddress];\n\n if (!tokenMarketData) {\n return undefined;\n }\n\n const currencyRate = currencyRates[tokenMarketData.currency];\n\n if (!currencyRate?.conversionRate) {\n return undefined;\n }\n\n const fiatBalance =\n (convertHexToDecimal(rawBalance) / 10 ** decimals) *\n tokenMarketData.price *\n currencyRate.conversionRate;\n\n return {\n balance: fiatBalance,\n conversionRate: currencyRate.conversionRate,\n };\n}\n\n/**\n * @param balance - The balance of the asset, in the format { amount: string; unit: string }\n * @param balance.amount - The amount of the balance\n * @param balance.unit - The unit of the balance\n * @param multichainConversionRates - The conversion rates for the multichain asset\n * @param assetId - The asset id of the asset\n * @returns The price and currency of the token in the current currency. Returns undefined if the asset is not found in the conversion rates.\n */\nfunction getFiatBalanceForMultichainAsset(\n balance: { amount: string; unit: string },\n multichainConversionRates: MultichainAssetsRatesControllerState['conversionRates'],\n assetId: `${string}:${string}/${string}:${string}`,\n) {\n const assetMarketData = multichainConversionRates[assetId];\n\n if (!assetMarketData?.rate) {\n return undefined;\n }\n\n return {\n balance: Number(balance.amount) * Number(assetMarketData.rate),\n conversionRate: Number(assetMarketData.rate),\n };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"token-selectors.d.cts","sourceRoot":"","sources":["../../src/selectors/token-selectors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,8BAA8B;AAC5D,OAAO,KAAK,EAAE,0BAA0B,EAAE,0CAA0C;AACpF,OAAO,KAAK,EAAE,uBAAuB,EAAE,sCAAsC;AAE7E,OAAO,KAAK,EAAE,eAAe,EAAE,uCAAuC;AACtE,OAAO,KAAK,EAAE,YAAY,EAAE,qCAAqC;AACjE,OAAO,EAAmC,KAAK,GAAG,EAAE,wBAAwB;
|
|
1
|
+
{"version":3,"file":"token-selectors.d.cts","sourceRoot":"","sources":["../../src/selectors/token-selectors.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"token-selectors.d.mts","sourceRoot":"","sources":["../../src/selectors/token-selectors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,8BAA8B;AAC5D,OAAO,KAAK,EAAE,0BAA0B,EAAE,0CAA0C;AACpF,OAAO,KAAK,EAAE,uBAAuB,EAAE,sCAAsC;AAE7E,OAAO,KAAK,EAAE,eAAe,EAAE,uCAAuC;AACtE,OAAO,KAAK,EAAE,YAAY,EAAE,qCAAqC;AACjE,OAAO,EAAmC,KAAK,GAAG,EAAE,wBAAwB;
|
|
1
|
+
{"version":3,"file":"token-selectors.d.mts","sourceRoot":"","sources":["../../src/selectors/token-selectors.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { convertHexToDecimal } from "@metamask/controller-utils";
|
|
2
2
|
import { hexToBigInt, parseCaipAssetType } from "@metamask/utils";
|
|
3
3
|
import { createSelector } from "reselect";
|
|
4
|
-
import { stringifyBalanceWithDecimals } from "./stringify-balance.mjs";
|
|
4
|
+
import { parseBalanceWithDecimals, stringifyBalanceWithDecimals } from "./stringify-balance.mjs";
|
|
5
5
|
import { getNativeTokenAddress } from "../token-prices-service/codefi-v2.mjs";
|
|
6
6
|
// If this gets out of hand with other chains, we should probably have a permanent object that defines them
|
|
7
7
|
const MULTICHAIN_NATIVE_ASSET_IDS = [
|
|
@@ -46,6 +46,7 @@ const selectAllEvmAccountNativeBalances = createAssetListSelector([
|
|
|
46
46
|
groupAssets[accountGroupId] ?? (groupAssets[accountGroupId] = {});
|
|
47
47
|
(_a = groupAssets[accountGroupId])[chainId] ?? (_a[chainId] = []);
|
|
48
48
|
const groupChainAssets = groupAssets[accountGroupId][chainId];
|
|
49
|
+
// If a native balance is missing, we still want to show it as 0
|
|
49
50
|
const rawBalance = accountBalance.balance || '0x0';
|
|
50
51
|
const nativeCurrency = networkConfigurationsByChainId[chainId]?.nativeCurrency || 'NATIVE';
|
|
51
52
|
const nativeToken = {
|
|
@@ -67,6 +68,7 @@ const selectAllEvmAccountNativeBalances = createAssetListSelector([
|
|
|
67
68
|
symbol: nativeToken.symbol,
|
|
68
69
|
accountId,
|
|
69
70
|
decimals: nativeToken.decimals,
|
|
71
|
+
rawBalance,
|
|
70
72
|
balance: stringifyBalanceWithDecimals(hexToBigInt(rawBalance), nativeToken.decimals),
|
|
71
73
|
fiat: fiatData
|
|
72
74
|
? {
|
|
@@ -122,6 +124,7 @@ const selectAllEvmAssets = createAssetListSelector([
|
|
|
122
124
|
symbol: token.symbol,
|
|
123
125
|
accountId,
|
|
124
126
|
decimals: token.decimals,
|
|
127
|
+
rawBalance,
|
|
125
128
|
balance: stringifyBalanceWithDecimals(hexToBigInt(rawBalance), token.decimals),
|
|
126
129
|
fiat: fiatData
|
|
127
130
|
? {
|
|
@@ -169,7 +172,13 @@ const selectAllMultichainAssets = createAssetListSelector([
|
|
|
169
172
|
(_a = groupAssets[accountGroupId])[chainId] ?? (_a[chainId] = []);
|
|
170
173
|
const groupChainAssets = groupAssets[accountGroupId][chainId];
|
|
171
174
|
const balance = multichainBalances[accountId]?.[assetId];
|
|
172
|
-
|
|
175
|
+
const decimals = assetMetadata.units.find((unit) => unit.name === assetMetadata.name &&
|
|
176
|
+
unit.symbol === assetMetadata.symbol)?.decimals;
|
|
177
|
+
if (!balance || decimals === undefined) {
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
const rawBalance = parseBalanceWithDecimals(balance.amount, decimals);
|
|
181
|
+
if (!rawBalance) {
|
|
173
182
|
continue;
|
|
174
183
|
}
|
|
175
184
|
const fiatData = getFiatBalanceForMultichainAsset(balance, multichainConversionRates, assetId);
|
|
@@ -182,8 +191,8 @@ const selectAllMultichainAssets = createAssetListSelector([
|
|
|
182
191
|
name: assetMetadata.name ?? assetMetadata.symbol ?? asset,
|
|
183
192
|
symbol: assetMetadata.symbol ?? asset,
|
|
184
193
|
accountId,
|
|
185
|
-
decimals
|
|
186
|
-
|
|
194
|
+
decimals,
|
|
195
|
+
rawBalance,
|
|
187
196
|
balance: balance.amount,
|
|
188
197
|
fiat: fiatData
|
|
189
198
|
? {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"token-selectors.mjs","sourceRoot":"","sources":["../../src/selectors/token-selectors.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AccountGroupId } from '@metamask/account-api';\nimport type { AccountTreeControllerState } from '@metamask/account-tree-controller';\nimport type { AccountsControllerState } from '@metamask/accounts-controller';\nimport { convertHexToDecimal } from '@metamask/controller-utils';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\nimport type { NetworkState } from '@metamask/network-controller';\nimport { hexToBigInt, parseCaipAssetType, type Hex } from '@metamask/utils';\nimport { createSelector } from 'reselect';\n\nimport { stringifyBalanceWithDecimals } from './stringify-balance';\nimport type { CurrencyRateState } from '../CurrencyRateController';\nimport type { MultichainAssetsControllerState } from '../MultichainAssetsController';\nimport type { MultichainAssetsRatesControllerState } from '../MultichainAssetsRatesController';\nimport type { MultichainBalancesControllerState } from '../MultichainBalancesController';\nimport { getNativeTokenAddress } from '../token-prices-service/codefi-v2';\nimport type { TokenBalancesControllerState } from '../TokenBalancesController';\nimport type { Token, TokenRatesControllerState } from '../TokenRatesController';\nimport type { TokensControllerState } from '../TokensController';\n\ntype AssetsByAccountGroup = {\n [accountGroupId: AccountGroupId]: AccountGroupAssets;\n};\n\nexport type AccountGroupAssets = {\n [network: string]: Asset[];\n};\n\n// If this gets out of hand with other chains, we should probably have a permanent object that defines them\nconst MULTICHAIN_NATIVE_ASSET_IDS = [\n `bip122:000000000019d6689c085ae165831e93/slip44:0`,\n `solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp/slip44:501`,\n];\n\ntype EvmAccountType = Extract<InternalAccount['type'], `eip155:${string}`>;\ntype MultichainAccountType = Exclude<\n InternalAccount['type'],\n `eip155:${string}`\n>;\n\nexport type Asset = (\n | {\n type: EvmAccountType;\n assetId: Hex; // This is also the address for EVM tokens\n address: Hex;\n chainId: Hex;\n }\n | {\n type: MultichainAccountType;\n assetId: `${string}:${string}/${string}:${string}`;\n chainId: `${string}:${string}`;\n }\n) & {\n accountId: string;\n image: string;\n name: string;\n symbol: string;\n decimals: number;\n isNative: boolean;\n balance: string;\n fiat:\n | {\n balance: number;\n currency: string;\n conversionRate: number;\n }\n | undefined;\n};\n\nexport type AssetListState = {\n accountTree: AccountTreeControllerState['accountTree'];\n internalAccounts: AccountsControllerState['internalAccounts'];\n allTokens: TokensControllerState['allTokens'];\n allIgnoredTokens: TokensControllerState['allIgnoredTokens'];\n tokenBalances: TokenBalancesControllerState['tokenBalances'];\n marketData: TokenRatesControllerState['marketData'];\n currencyRates: CurrencyRateState['currencyRates'];\n accountsAssets: MultichainAssetsControllerState['accountsAssets'];\n assetsMetadata: MultichainAssetsControllerState['assetsMetadata'];\n balances: MultichainBalancesControllerState['balances'];\n conversionRates: MultichainAssetsRatesControllerState['conversionRates'];\n currentCurrency: CurrencyRateState['currentCurrency'];\n networkConfigurationsByChainId: NetworkState['networkConfigurationsByChainId'];\n // This is the state from AccountTrackerController. The state is different on mobile and extension\n // accountsByChainId with a balance is the only field that both clients have in common\n // This field could be removed once TokenBalancesController returns native balances\n accountsByChainId: Record<\n Hex,\n Record<\n Hex,\n {\n balance: Hex | null;\n }\n >\n >;\n};\n\nconst createAssetListSelector = createSelector.withTypes<AssetListState>();\n\nconst selectAccountsToGroupIdMap = createAssetListSelector(\n [(state) => state.accountTree, (state) => state.internalAccounts],\n (accountTree, internalAccounts) => {\n const accountsMap: Record<\n string,\n {\n accountGroupId: AccountGroupId;\n type: InternalAccount['type'];\n accountId: string;\n }\n > = {};\n for (const { groups } of Object.values(accountTree.wallets)) {\n for (const { id: accountGroupId, accounts } of Object.values(groups)) {\n for (const accountId of accounts) {\n const internalAccount = internalAccounts.accounts[accountId];\n\n accountsMap[\n // TODO: We would not need internalAccounts if evmTokens state had the accountId\n internalAccount.type.startsWith('eip155')\n ? internalAccount.address\n : accountId\n ] = { accountGroupId, type: internalAccount.type, accountId };\n }\n }\n }\n\n return accountsMap;\n },\n);\n\n// TODO: This selector will not be needed once the native balances are part of the evm tokens state\nconst selectAllEvmAccountNativeBalances = createAssetListSelector(\n [\n selectAccountsToGroupIdMap,\n (state) => state.accountsByChainId,\n (state) => state.marketData,\n (state) => state.currencyRates,\n (state) => state.currentCurrency,\n (state) => state.networkConfigurationsByChainId,\n ],\n (\n accountsMap,\n accountsByChainId,\n marketData,\n currencyRates,\n currentCurrency,\n networkConfigurationsByChainId,\n ) => {\n const groupAssets: AssetsByAccountGroup = {};\n\n for (const [chainId, chainAccounts] of Object.entries(\n accountsByChainId,\n ) as [Hex, Record<Hex, { balance: Hex | null }>][]) {\n for (const [accountAddress, accountBalance] of Object.entries(\n chainAccounts,\n )) {\n const account = accountsMap[accountAddress.toLowerCase()];\n if (!account) {\n continue;\n }\n\n const { accountGroupId, type, accountId } = account;\n\n groupAssets[accountGroupId] ??= {};\n groupAssets[accountGroupId][chainId] ??= [];\n const groupChainAssets = groupAssets[accountGroupId][chainId];\n\n const rawBalance = accountBalance.balance || '0x0';\n\n const nativeCurrency =\n networkConfigurationsByChainId[chainId]?.nativeCurrency || 'NATIVE';\n\n const nativeToken = {\n address: getNativeTokenAddress(chainId),\n decimals: 18,\n name: nativeCurrency === 'ETH' ? 'Ethereum' : nativeCurrency,\n symbol: nativeCurrency,\n // This field need to be filled at client level for now\n image: '',\n };\n\n const fiatData = getFiatBalanceForEvmToken(\n rawBalance,\n nativeToken.decimals,\n marketData,\n currencyRates,\n chainId,\n nativeToken.address,\n );\n\n groupChainAssets.push({\n type: type as EvmAccountType,\n assetId: nativeToken.address,\n isNative: true,\n address: nativeToken.address,\n image: nativeToken.image,\n name: nativeToken.name,\n symbol: nativeToken.symbol,\n accountId,\n decimals: nativeToken.decimals,\n balance: stringifyBalanceWithDecimals(\n hexToBigInt(rawBalance),\n nativeToken.decimals,\n ),\n fiat: fiatData\n ? {\n balance: fiatData.balance,\n currency: currentCurrency,\n conversionRate: fiatData.conversionRate,\n }\n : undefined,\n chainId,\n });\n }\n }\n\n return groupAssets;\n },\n);\n\nconst selectAllEvmAssets = createAssetListSelector(\n [\n selectAccountsToGroupIdMap,\n (state) => state.allTokens,\n (state) => state.allIgnoredTokens,\n (state) => state.tokenBalances,\n (state) => state.marketData,\n (state) => state.currencyRates,\n (state) => state.currentCurrency,\n ],\n (\n accountsMap,\n evmTokens,\n ignoredEvmTokens,\n tokenBalances,\n marketData,\n currencyRates,\n currentCurrency,\n ) => {\n const groupAssets: AssetsByAccountGroup = {};\n\n for (const [chainId, chainTokens] of Object.entries(evmTokens) as [\n Hex,\n { [key: string]: Token[] },\n ][]) {\n for (const [accountAddress, addressTokens] of Object.entries(\n chainTokens,\n ) as [Hex, Token[]][]) {\n for (const token of addressTokens) {\n const tokenAddress = token.address as Hex;\n const account = accountsMap[accountAddress];\n if (!account) {\n continue;\n }\n\n const { accountGroupId, type, accountId } = account;\n\n if (\n ignoredEvmTokens[chainId]?.[accountAddress]?.includes(tokenAddress)\n ) {\n continue;\n }\n\n const rawBalance =\n tokenBalances[accountAddress]?.[chainId]?.[tokenAddress];\n\n if (!rawBalance) {\n continue;\n }\n\n groupAssets[accountGroupId] ??= {};\n groupAssets[accountGroupId][chainId] ??= [];\n const groupChainAssets = groupAssets[accountGroupId][chainId];\n\n const fiatData = getFiatBalanceForEvmToken(\n rawBalance,\n token.decimals,\n marketData,\n currencyRates,\n chainId,\n tokenAddress,\n );\n\n groupChainAssets.push({\n type: type as EvmAccountType,\n assetId: tokenAddress,\n isNative: false,\n address: tokenAddress,\n image: token.image ?? '',\n name: token.name ?? token.symbol,\n symbol: token.symbol,\n accountId,\n decimals: token.decimals,\n balance: stringifyBalanceWithDecimals(\n hexToBigInt(rawBalance),\n token.decimals,\n ),\n fiat: fiatData\n ? {\n balance: fiatData.balance,\n currency: currentCurrency,\n conversionRate: fiatData.conversionRate,\n }\n : undefined,\n chainId,\n });\n }\n }\n }\n\n return groupAssets;\n },\n);\n\nconst selectAllMultichainAssets = createAssetListSelector(\n [\n selectAccountsToGroupIdMap,\n (state) => state.accountsAssets,\n (state) => state.assetsMetadata,\n (state) => state.balances,\n (state) => state.conversionRates,\n (state) => state.currentCurrency,\n ],\n (\n accountsMap,\n multichainTokens,\n multichainAssetsMetadata,\n multichainBalances,\n multichainConversionRates,\n currentCurrency,\n ) => {\n const groupAssets: AssetsByAccountGroup = {};\n\n for (const [accountId, accountAssets] of Object.entries(multichainTokens)) {\n for (const assetId of accountAssets) {\n let caipAsset: ReturnType<typeof parseCaipAssetType>;\n try {\n caipAsset = parseCaipAssetType(assetId);\n } catch {\n // TODO: We should log this error when we have the ability to inject a logger from the client\n continue;\n }\n\n const { chainId } = caipAsset;\n const asset = `${caipAsset.assetNamespace}:${caipAsset.assetReference}`;\n\n const account = accountsMap[accountId];\n const assetMetadata = multichainAssetsMetadata[assetId];\n if (!account || !assetMetadata) {\n continue;\n }\n\n const { accountGroupId, type } = account;\n\n groupAssets[accountGroupId] ??= {};\n groupAssets[accountGroupId][chainId] ??= [];\n const groupChainAssets = groupAssets[accountGroupId][chainId];\n\n const balance:\n | {\n amount: string;\n unit: string;\n }\n | undefined = multichainBalances[accountId]?.[assetId];\n\n if (!balance) {\n continue;\n }\n\n const fiatData = getFiatBalanceForMultichainAsset(\n balance,\n multichainConversionRates,\n assetId,\n );\n\n // TODO: We shouldn't have to rely on fallbacks for name and symbol, they should not be optional\n groupChainAssets.push({\n type: type as MultichainAccountType,\n assetId,\n isNative: MULTICHAIN_NATIVE_ASSET_IDS.includes(assetId),\n image: assetMetadata.iconUrl,\n name: assetMetadata.name ?? assetMetadata.symbol ?? asset,\n symbol: assetMetadata.symbol ?? asset,\n accountId,\n decimals:\n assetMetadata.units.find(\n (unit) =>\n unit.name === assetMetadata.name &&\n unit.symbol === assetMetadata.symbol,\n )?.decimals ?? 0,\n balance: balance.amount,\n fiat: fiatData\n ? {\n balance: fiatData.balance,\n currency: currentCurrency,\n conversionRate: fiatData.conversionRate,\n }\n : undefined,\n chainId,\n });\n }\n }\n\n return groupAssets;\n },\n);\n\nconst selectAllAssets = createAssetListSelector(\n [\n selectAllEvmAssets,\n selectAllMultichainAssets,\n selectAllEvmAccountNativeBalances,\n ],\n (evmAssets, multichainAssets, evmAccountNativeBalances) => {\n const groupAssets: AssetsByAccountGroup = {};\n\n mergeAssets(groupAssets, evmAssets);\n\n mergeAssets(groupAssets, multichainAssets);\n\n mergeAssets(groupAssets, evmAccountNativeBalances);\n\n return groupAssets;\n },\n);\n\nexport const selectAssetsBySelectedAccountGroup = createAssetListSelector(\n [selectAllAssets, (state) => state.accountTree],\n (groupAssets, accountTree) => {\n const { selectedAccountGroup } = accountTree;\n if (!selectedAccountGroup) {\n return {};\n }\n return groupAssets[selectedAccountGroup] || {};\n },\n);\n\n// TODO: Once native assets are part of the evm tokens state, this function can be simplified as chains will always be unique\n/**\n * Merges the new assets into the existing assets\n *\n * @param existingAssets - The existing assets\n * @param newAssets - The new assets\n */\nfunction mergeAssets(\n existingAssets: AssetsByAccountGroup,\n newAssets: AssetsByAccountGroup,\n) {\n for (const [accountGroupId, accountAssets] of Object.entries(newAssets) as [\n AccountGroupId,\n AccountGroupAssets,\n ][]) {\n const existingAccountGroupAssets = existingAssets[accountGroupId];\n\n if (!existingAccountGroupAssets) {\n existingAssets[accountGroupId] = {};\n for (const [network, chainAssets] of Object.entries(accountAssets)) {\n existingAssets[accountGroupId][network] = [...chainAssets];\n }\n } else {\n for (const [network, chainAssets] of Object.entries(accountAssets)) {\n existingAccountGroupAssets[network] ??= [];\n existingAccountGroupAssets[network].push(...chainAssets);\n }\n }\n }\n}\n\n/**\n * @param rawBalance - The balance of the token\n * @param decimals - The decimals of the token\n * @param marketData - The market data for the token\n * @param currencyRates - The currency rates for the token\n * @param chainId - The chain id of the token\n * @param tokenAddress - The address of the token\n * @returns The price and currency of the token in the current currency. Returns undefined if the asset is not found in the market data or currency rates.\n */\nfunction getFiatBalanceForEvmToken(\n rawBalance: Hex,\n decimals: number,\n marketData: TokenRatesControllerState['marketData'],\n currencyRates: CurrencyRateState['currencyRates'],\n chainId: Hex,\n tokenAddress: Hex,\n) {\n const tokenMarketData = marketData[chainId]?.[tokenAddress];\n\n if (!tokenMarketData) {\n return undefined;\n }\n\n const currencyRate = currencyRates[tokenMarketData.currency];\n\n if (!currencyRate?.conversionRate) {\n return undefined;\n }\n\n const fiatBalance =\n (convertHexToDecimal(rawBalance) / 10 ** decimals) *\n tokenMarketData.price *\n currencyRate.conversionRate;\n\n return {\n balance: fiatBalance,\n conversionRate: currencyRate.conversionRate,\n };\n}\n\n/**\n * @param balance - The balance of the asset, in the format { amount: string; unit: string }\n * @param balance.amount - The amount of the balance\n * @param balance.unit - The unit of the balance\n * @param multichainConversionRates - The conversion rates for the multichain asset\n * @param assetId - The asset id of the asset\n * @returns The price and currency of the token in the current currency. Returns undefined if the asset is not found in the conversion rates.\n */\nfunction getFiatBalanceForMultichainAsset(\n balance: { amount: string; unit: string },\n multichainConversionRates: MultichainAssetsRatesControllerState['conversionRates'],\n assetId: `${string}:${string}/${string}:${string}`,\n) {\n const assetMarketData = multichainConversionRates[assetId];\n\n if (!assetMarketData?.rate) {\n return undefined;\n }\n\n return {\n balance: Number(balance.amount) * Number(assetMarketData.rate),\n conversionRate: Number(assetMarketData.rate),\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"token-selectors.mjs","sourceRoot":"","sources":["../../src/selectors/token-selectors.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AccountGroupId } from '@metamask/account-api';\nimport type { AccountTreeControllerState } from '@metamask/account-tree-controller';\nimport type { AccountsControllerState } from '@metamask/accounts-controller';\nimport { convertHexToDecimal } from '@metamask/controller-utils';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\nimport type { NetworkState } from '@metamask/network-controller';\nimport { hexToBigInt, parseCaipAssetType, type Hex } from '@metamask/utils';\nimport { createSelector } from 'reselect';\n\nimport {\n parseBalanceWithDecimals,\n stringifyBalanceWithDecimals,\n} from './stringify-balance';\nimport type { CurrencyRateState } from '../CurrencyRateController';\nimport type { MultichainAssetsControllerState } from '../MultichainAssetsController';\nimport type { MultichainAssetsRatesControllerState } from '../MultichainAssetsRatesController';\nimport type { MultichainBalancesControllerState } from '../MultichainBalancesController';\nimport { getNativeTokenAddress } from '../token-prices-service/codefi-v2';\nimport type { TokenBalancesControllerState } from '../TokenBalancesController';\nimport type { Token, TokenRatesControllerState } from '../TokenRatesController';\nimport type { TokensControllerState } from '../TokensController';\n\ntype AssetsByAccountGroup = {\n [accountGroupId: AccountGroupId]: AccountGroupAssets;\n};\n\nexport type AccountGroupAssets = {\n [network: string]: Asset[];\n};\n\n// If this gets out of hand with other chains, we should probably have a permanent object that defines them\nconst MULTICHAIN_NATIVE_ASSET_IDS = [\n `bip122:000000000019d6689c085ae165831e93/slip44:0`,\n `solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp/slip44:501`,\n];\n\ntype EvmAccountType = Extract<InternalAccount['type'], `eip155:${string}`>;\ntype MultichainAccountType = Exclude<\n InternalAccount['type'],\n `eip155:${string}`\n>;\n\nexport type Asset = (\n | {\n type: EvmAccountType;\n assetId: Hex; // This is also the address for EVM tokens\n address: Hex;\n chainId: Hex;\n }\n | {\n type: MultichainAccountType;\n assetId: `${string}:${string}/${string}:${string}`;\n chainId: `${string}:${string}`;\n }\n) & {\n accountId: string;\n image: string;\n name: string;\n symbol: string;\n decimals: number;\n isNative: boolean;\n rawBalance: Hex;\n balance: string;\n fiat:\n | {\n balance: number;\n currency: string;\n conversionRate: number;\n }\n | undefined;\n};\n\nexport type AssetListState = {\n accountTree: AccountTreeControllerState['accountTree'];\n internalAccounts: AccountsControllerState['internalAccounts'];\n allTokens: TokensControllerState['allTokens'];\n allIgnoredTokens: TokensControllerState['allIgnoredTokens'];\n tokenBalances: TokenBalancesControllerState['tokenBalances'];\n marketData: TokenRatesControllerState['marketData'];\n currencyRates: CurrencyRateState['currencyRates'];\n accountsAssets: MultichainAssetsControllerState['accountsAssets'];\n assetsMetadata: MultichainAssetsControllerState['assetsMetadata'];\n balances: MultichainBalancesControllerState['balances'];\n conversionRates: MultichainAssetsRatesControllerState['conversionRates'];\n currentCurrency: CurrencyRateState['currentCurrency'];\n networkConfigurationsByChainId: NetworkState['networkConfigurationsByChainId'];\n // This is the state from AccountTrackerController. The state is different on mobile and extension\n // accountsByChainId with a balance is the only field that both clients have in common\n // This field could be removed once TokenBalancesController returns native balances\n accountsByChainId: Record<\n Hex,\n Record<\n Hex,\n {\n balance: Hex | null;\n }\n >\n >;\n};\n\nconst createAssetListSelector = createSelector.withTypes<AssetListState>();\n\nconst selectAccountsToGroupIdMap = createAssetListSelector(\n [(state) => state.accountTree, (state) => state.internalAccounts],\n (accountTree, internalAccounts) => {\n const accountsMap: Record<\n string,\n {\n accountGroupId: AccountGroupId;\n type: InternalAccount['type'];\n accountId: string;\n }\n > = {};\n for (const { groups } of Object.values(accountTree.wallets)) {\n for (const { id: accountGroupId, accounts } of Object.values(groups)) {\n for (const accountId of accounts) {\n const internalAccount = internalAccounts.accounts[accountId];\n\n accountsMap[\n // TODO: We would not need internalAccounts if evmTokens state had the accountId\n internalAccount.type.startsWith('eip155')\n ? internalAccount.address\n : accountId\n ] = { accountGroupId, type: internalAccount.type, accountId };\n }\n }\n }\n\n return accountsMap;\n },\n);\n\n// TODO: This selector will not be needed once the native balances are part of the evm tokens state\nconst selectAllEvmAccountNativeBalances = createAssetListSelector(\n [\n selectAccountsToGroupIdMap,\n (state) => state.accountsByChainId,\n (state) => state.marketData,\n (state) => state.currencyRates,\n (state) => state.currentCurrency,\n (state) => state.networkConfigurationsByChainId,\n ],\n (\n accountsMap,\n accountsByChainId,\n marketData,\n currencyRates,\n currentCurrency,\n networkConfigurationsByChainId,\n ) => {\n const groupAssets: AssetsByAccountGroup = {};\n\n for (const [chainId, chainAccounts] of Object.entries(\n accountsByChainId,\n ) as [Hex, Record<Hex, { balance: Hex | null }>][]) {\n for (const [accountAddress, accountBalance] of Object.entries(\n chainAccounts,\n )) {\n const account = accountsMap[accountAddress.toLowerCase()];\n if (!account) {\n continue;\n }\n\n const { accountGroupId, type, accountId } = account;\n\n groupAssets[accountGroupId] ??= {};\n groupAssets[accountGroupId][chainId] ??= [];\n const groupChainAssets = groupAssets[accountGroupId][chainId];\n\n // If a native balance is missing, we still want to show it as 0\n const rawBalance = accountBalance.balance || '0x0';\n\n const nativeCurrency =\n networkConfigurationsByChainId[chainId]?.nativeCurrency || 'NATIVE';\n\n const nativeToken = {\n address: getNativeTokenAddress(chainId),\n decimals: 18,\n name: nativeCurrency === 'ETH' ? 'Ethereum' : nativeCurrency,\n symbol: nativeCurrency,\n // This field need to be filled at client level for now\n image: '',\n };\n\n const fiatData = getFiatBalanceForEvmToken(\n rawBalance,\n nativeToken.decimals,\n marketData,\n currencyRates,\n chainId,\n nativeToken.address,\n );\n\n groupChainAssets.push({\n type: type as EvmAccountType,\n assetId: nativeToken.address,\n isNative: true,\n address: nativeToken.address,\n image: nativeToken.image,\n name: nativeToken.name,\n symbol: nativeToken.symbol,\n accountId,\n decimals: nativeToken.decimals,\n rawBalance,\n balance: stringifyBalanceWithDecimals(\n hexToBigInt(rawBalance),\n nativeToken.decimals,\n ),\n fiat: fiatData\n ? {\n balance: fiatData.balance,\n currency: currentCurrency,\n conversionRate: fiatData.conversionRate,\n }\n : undefined,\n chainId,\n });\n }\n }\n\n return groupAssets;\n },\n);\n\nconst selectAllEvmAssets = createAssetListSelector(\n [\n selectAccountsToGroupIdMap,\n (state) => state.allTokens,\n (state) => state.allIgnoredTokens,\n (state) => state.tokenBalances,\n (state) => state.marketData,\n (state) => state.currencyRates,\n (state) => state.currentCurrency,\n ],\n (\n accountsMap,\n evmTokens,\n ignoredEvmTokens,\n tokenBalances,\n marketData,\n currencyRates,\n currentCurrency,\n ) => {\n const groupAssets: AssetsByAccountGroup = {};\n\n for (const [chainId, chainTokens] of Object.entries(evmTokens) as [\n Hex,\n { [key: string]: Token[] },\n ][]) {\n for (const [accountAddress, addressTokens] of Object.entries(\n chainTokens,\n ) as [Hex, Token[]][]) {\n for (const token of addressTokens) {\n const tokenAddress = token.address as Hex;\n const account = accountsMap[accountAddress];\n if (!account) {\n continue;\n }\n\n const { accountGroupId, type, accountId } = account;\n\n if (\n ignoredEvmTokens[chainId]?.[accountAddress]?.includes(tokenAddress)\n ) {\n continue;\n }\n\n const rawBalance =\n tokenBalances[accountAddress]?.[chainId]?.[tokenAddress];\n\n if (!rawBalance) {\n continue;\n }\n\n groupAssets[accountGroupId] ??= {};\n groupAssets[accountGroupId][chainId] ??= [];\n const groupChainAssets = groupAssets[accountGroupId][chainId];\n\n const fiatData = getFiatBalanceForEvmToken(\n rawBalance,\n token.decimals,\n marketData,\n currencyRates,\n chainId,\n tokenAddress,\n );\n\n groupChainAssets.push({\n type: type as EvmAccountType,\n assetId: tokenAddress,\n isNative: false,\n address: tokenAddress,\n image: token.image ?? '',\n name: token.name ?? token.symbol,\n symbol: token.symbol,\n accountId,\n decimals: token.decimals,\n rawBalance,\n balance: stringifyBalanceWithDecimals(\n hexToBigInt(rawBalance),\n token.decimals,\n ),\n fiat: fiatData\n ? {\n balance: fiatData.balance,\n currency: currentCurrency,\n conversionRate: fiatData.conversionRate,\n }\n : undefined,\n chainId,\n });\n }\n }\n }\n\n return groupAssets;\n },\n);\n\nconst selectAllMultichainAssets = createAssetListSelector(\n [\n selectAccountsToGroupIdMap,\n (state) => state.accountsAssets,\n (state) => state.assetsMetadata,\n (state) => state.balances,\n (state) => state.conversionRates,\n (state) => state.currentCurrency,\n ],\n (\n accountsMap,\n multichainTokens,\n multichainAssetsMetadata,\n multichainBalances,\n multichainConversionRates,\n currentCurrency,\n ) => {\n const groupAssets: AssetsByAccountGroup = {};\n\n for (const [accountId, accountAssets] of Object.entries(multichainTokens)) {\n for (const assetId of accountAssets) {\n let caipAsset: ReturnType<typeof parseCaipAssetType>;\n try {\n caipAsset = parseCaipAssetType(assetId);\n } catch {\n // TODO: We should log this error when we have the ability to inject a logger from the client\n continue;\n }\n\n const { chainId } = caipAsset;\n const asset = `${caipAsset.assetNamespace}:${caipAsset.assetReference}`;\n\n const account = accountsMap[accountId];\n const assetMetadata = multichainAssetsMetadata[assetId];\n if (!account || !assetMetadata) {\n continue;\n }\n\n const { accountGroupId, type } = account;\n\n groupAssets[accountGroupId] ??= {};\n groupAssets[accountGroupId][chainId] ??= [];\n const groupChainAssets = groupAssets[accountGroupId][chainId];\n\n const balance:\n | {\n amount: string;\n unit: string;\n }\n | undefined = multichainBalances[accountId]?.[assetId];\n\n const decimals = assetMetadata.units.find(\n (unit) =>\n unit.name === assetMetadata.name &&\n unit.symbol === assetMetadata.symbol,\n )?.decimals;\n\n if (!balance || decimals === undefined) {\n continue;\n }\n\n const rawBalance = parseBalanceWithDecimals(balance.amount, decimals);\n\n if (!rawBalance) {\n continue;\n }\n\n const fiatData = getFiatBalanceForMultichainAsset(\n balance,\n multichainConversionRates,\n assetId,\n );\n\n // TODO: We shouldn't have to rely on fallbacks for name and symbol, they should not be optional\n groupChainAssets.push({\n type: type as MultichainAccountType,\n assetId,\n isNative: MULTICHAIN_NATIVE_ASSET_IDS.includes(assetId),\n image: assetMetadata.iconUrl,\n name: assetMetadata.name ?? assetMetadata.symbol ?? asset,\n symbol: assetMetadata.symbol ?? asset,\n accountId,\n decimals,\n rawBalance,\n balance: balance.amount,\n fiat: fiatData\n ? {\n balance: fiatData.balance,\n currency: currentCurrency,\n conversionRate: fiatData.conversionRate,\n }\n : undefined,\n chainId,\n });\n }\n }\n\n return groupAssets;\n },\n);\n\nconst selectAllAssets = createAssetListSelector(\n [\n selectAllEvmAssets,\n selectAllMultichainAssets,\n selectAllEvmAccountNativeBalances,\n ],\n (evmAssets, multichainAssets, evmAccountNativeBalances) => {\n const groupAssets: AssetsByAccountGroup = {};\n\n mergeAssets(groupAssets, evmAssets);\n\n mergeAssets(groupAssets, multichainAssets);\n\n mergeAssets(groupAssets, evmAccountNativeBalances);\n\n return groupAssets;\n },\n);\n\nexport const selectAssetsBySelectedAccountGroup = createAssetListSelector(\n [selectAllAssets, (state) => state.accountTree],\n (groupAssets, accountTree) => {\n const { selectedAccountGroup } = accountTree;\n if (!selectedAccountGroup) {\n return {};\n }\n return groupAssets[selectedAccountGroup] || {};\n },\n);\n\n// TODO: Once native assets are part of the evm tokens state, this function can be simplified as chains will always be unique\n/**\n * Merges the new assets into the existing assets\n *\n * @param existingAssets - The existing assets\n * @param newAssets - The new assets\n */\nfunction mergeAssets(\n existingAssets: AssetsByAccountGroup,\n newAssets: AssetsByAccountGroup,\n) {\n for (const [accountGroupId, accountAssets] of Object.entries(newAssets) as [\n AccountGroupId,\n AccountGroupAssets,\n ][]) {\n const existingAccountGroupAssets = existingAssets[accountGroupId];\n\n if (!existingAccountGroupAssets) {\n existingAssets[accountGroupId] = {};\n for (const [network, chainAssets] of Object.entries(accountAssets)) {\n existingAssets[accountGroupId][network] = [...chainAssets];\n }\n } else {\n for (const [network, chainAssets] of Object.entries(accountAssets)) {\n existingAccountGroupAssets[network] ??= [];\n existingAccountGroupAssets[network].push(...chainAssets);\n }\n }\n }\n}\n\n/**\n * @param rawBalance - The balance of the token\n * @param decimals - The decimals of the token\n * @param marketData - The market data for the token\n * @param currencyRates - The currency rates for the token\n * @param chainId - The chain id of the token\n * @param tokenAddress - The address of the token\n * @returns The price and currency of the token in the current currency. Returns undefined if the asset is not found in the market data or currency rates.\n */\nfunction getFiatBalanceForEvmToken(\n rawBalance: Hex,\n decimals: number,\n marketData: TokenRatesControllerState['marketData'],\n currencyRates: CurrencyRateState['currencyRates'],\n chainId: Hex,\n tokenAddress: Hex,\n) {\n const tokenMarketData = marketData[chainId]?.[tokenAddress];\n\n if (!tokenMarketData) {\n return undefined;\n }\n\n const currencyRate = currencyRates[tokenMarketData.currency];\n\n if (!currencyRate?.conversionRate) {\n return undefined;\n }\n\n const fiatBalance =\n (convertHexToDecimal(rawBalance) / 10 ** decimals) *\n tokenMarketData.price *\n currencyRate.conversionRate;\n\n return {\n balance: fiatBalance,\n conversionRate: currencyRate.conversionRate,\n };\n}\n\n/**\n * @param balance - The balance of the asset, in the format { amount: string; unit: string }\n * @param balance.amount - The amount of the balance\n * @param balance.unit - The unit of the balance\n * @param multichainConversionRates - The conversion rates for the multichain asset\n * @param assetId - The asset id of the asset\n * @returns The price and currency of the token in the current currency. Returns undefined if the asset is not found in the conversion rates.\n */\nfunction getFiatBalanceForMultichainAsset(\n balance: { amount: string; unit: string },\n multichainConversionRates: MultichainAssetsRatesControllerState['conversionRates'],\n assetId: `${string}:${string}/${string}:${string}`,\n) {\n const assetMarketData = multichainConversionRates[assetId];\n\n if (!assetMarketData?.rate) {\n return undefined;\n }\n\n return {\n balance: Number(balance.amount) * Number(assetMarketData.rate),\n conversionRate: Number(assetMarketData.rate),\n };\n}\n"]}
|
package/package.json
CHANGED