@metamask-previews/assets-controllers 45.1.1-preview-73fa7bfb → 45.1.1-preview-9e677163
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/dist/AccountTrackerController.d.cts +2 -2
- package/dist/AccountTrackerController.d.mts +2 -2
- package/dist/CurrencyRateController.d.cts +2 -2
- package/dist/CurrencyRateController.d.mts +2 -2
- package/dist/MultichainBalancesController/BalancesTracker.cjs +1 -7
- package/dist/MultichainBalancesController/BalancesTracker.cjs.map +1 -1
- package/dist/MultichainBalancesController/BalancesTracker.d.cts.map +1 -1
- package/dist/MultichainBalancesController/BalancesTracker.d.mts.map +1 -1
- package/dist/MultichainBalancesController/BalancesTracker.mjs +1 -7
- package/dist/MultichainBalancesController/BalancesTracker.mjs.map +1 -1
- package/dist/MultichainBalancesController/MultichainBalancesController.cjs +32 -47
- package/dist/MultichainBalancesController/MultichainBalancesController.cjs.map +1 -1
- package/dist/MultichainBalancesController/MultichainBalancesController.d.cts +2 -1
- package/dist/MultichainBalancesController/MultichainBalancesController.d.cts.map +1 -1
- package/dist/MultichainBalancesController/MultichainBalancesController.d.mts +2 -1
- package/dist/MultichainBalancesController/MultichainBalancesController.d.mts.map +1 -1
- package/dist/MultichainBalancesController/MultichainBalancesController.mjs +33 -48
- package/dist/MultichainBalancesController/MultichainBalancesController.mjs.map +1 -1
- package/dist/MultichainBalancesController/constants.cjs +9 -9
- package/dist/MultichainBalancesController/constants.cjs.map +1 -1
- package/dist/MultichainBalancesController/constants.d.cts +4 -4
- package/dist/MultichainBalancesController/constants.d.cts.map +1 -1
- package/dist/MultichainBalancesController/constants.d.mts +4 -4
- package/dist/MultichainBalancesController/constants.d.mts.map +1 -1
- package/dist/MultichainBalancesController/constants.mjs +8 -8
- package/dist/MultichainBalancesController/constants.mjs.map +1 -1
- package/dist/MultichainBalancesController/utils.cjs +3 -3
- package/dist/MultichainBalancesController/utils.cjs.map +1 -1
- package/dist/MultichainBalancesController/utils.d.cts +1 -1
- package/dist/MultichainBalancesController/utils.d.mts +1 -1
- package/dist/MultichainBalancesController/utils.mjs +1 -1
- package/dist/MultichainBalancesController/utils.mjs.map +1 -1
- package/dist/TokenBalancesController.d.cts +2 -2
- package/dist/TokenBalancesController.d.mts +2 -2
- package/dist/TokenDetectionController.d.cts +2 -2
- package/dist/TokenDetectionController.d.mts +2 -2
- package/dist/TokenListController.d.cts +2 -2
- package/dist/TokenListController.d.mts +2 -2
- package/dist/TokenRatesController.d.cts +2 -2
- package/dist/TokenRatesController.d.mts +2 -2
- package/package.json +1 -1
|
@@ -65,8 +65,8 @@ type AccountTrackerPollingInput = {
|
|
|
65
65
|
networkClientId: NetworkClientId;
|
|
66
66
|
};
|
|
67
67
|
declare const AccountTrackerController_base: (abstract new (...args: any[]) => {
|
|
68
|
-
readonly "__#
|
|
69
|
-
"__#
|
|
68
|
+
readonly "__#13@#intervalIds": Record<string, NodeJS.Timeout>;
|
|
69
|
+
"__#13@#intervalLength": number | undefined;
|
|
70
70
|
setIntervalLength(intervalLength: number): void;
|
|
71
71
|
getIntervalLength(): number | undefined;
|
|
72
72
|
_startPolling(input: AccountTrackerPollingInput): void;
|
|
@@ -65,8 +65,8 @@ type AccountTrackerPollingInput = {
|
|
|
65
65
|
networkClientId: NetworkClientId;
|
|
66
66
|
};
|
|
67
67
|
declare const AccountTrackerController_base: (abstract new (...args: any[]) => {
|
|
68
|
-
readonly "__#
|
|
69
|
-
"__#
|
|
68
|
+
readonly "__#13@#intervalIds": Record<string, NodeJS.Timeout>;
|
|
69
|
+
"__#13@#intervalLength": number | undefined;
|
|
70
70
|
setIntervalLength(intervalLength: number): void;
|
|
71
71
|
getIntervalLength(): number | undefined;
|
|
72
72
|
_startPolling(input: AccountTrackerPollingInput): void;
|
|
@@ -29,8 +29,8 @@ type CurrencyRatePollingInput = {
|
|
|
29
29
|
nativeCurrencies: string[];
|
|
30
30
|
};
|
|
31
31
|
declare const CurrencyRateController_base: (abstract new (...args: any[]) => {
|
|
32
|
-
readonly "__#
|
|
33
|
-
"__#
|
|
32
|
+
readonly "__#13@#intervalIds": Record<string, NodeJS.Timeout>;
|
|
33
|
+
"__#13@#intervalLength": number | undefined;
|
|
34
34
|
setIntervalLength(intervalLength: number): void;
|
|
35
35
|
getIntervalLength(): number | undefined;
|
|
36
36
|
_startPolling(input: CurrencyRatePollingInput): void;
|
|
@@ -29,8 +29,8 @@ type CurrencyRatePollingInput = {
|
|
|
29
29
|
nativeCurrencies: string[];
|
|
30
30
|
};
|
|
31
31
|
declare const CurrencyRateController_base: (abstract new (...args: any[]) => {
|
|
32
|
-
readonly "__#
|
|
33
|
-
"__#
|
|
32
|
+
readonly "__#13@#intervalIds": Record<string, NodeJS.Timeout>;
|
|
33
|
+
"__#13@#intervalLength": number | undefined;
|
|
34
34
|
setIntervalLength(intervalLength: number): void;
|
|
35
35
|
getIntervalLength(): number | undefined;
|
|
36
36
|
_startPolling(input: CurrencyRatePollingInput): void;
|
|
@@ -42,7 +42,7 @@ class BalancesTracker {
|
|
|
42
42
|
* @returns True if the account is being tracker, false otherwise.
|
|
43
43
|
*/
|
|
44
44
|
isTracked(accountId) {
|
|
45
|
-
return
|
|
45
|
+
return accountId in __classPrivateFieldGet(this, _BalancesTracker_balances, "f");
|
|
46
46
|
}
|
|
47
47
|
/**
|
|
48
48
|
* Asserts that an account ID is being tracked.
|
|
@@ -88,20 +88,15 @@ class BalancesTracker {
|
|
|
88
88
|
* @throws If the account ID is not being tracked.
|
|
89
89
|
*/
|
|
90
90
|
async updateBalance(accountId) {
|
|
91
|
-
console.log('MultichainBalancesController - BalancesTracker updateBalance start');
|
|
92
91
|
this.assertBeingTracked(accountId);
|
|
93
|
-
console.log('MultichainBalancesController - BalancesTracker updateBalance', { accountId });
|
|
94
92
|
// We check if the balance is outdated (by comparing to the block time associated
|
|
95
93
|
// with this kind of account).
|
|
96
94
|
//
|
|
97
95
|
// This might not be super accurate, but we could probably compute this differently
|
|
98
96
|
// and try to sync with the "real block time"!
|
|
99
97
|
const info = __classPrivateFieldGet(this, _BalancesTracker_balances, "f")[accountId];
|
|
100
|
-
console.log({ info });
|
|
101
98
|
const isOutdated = Date.now() - info.lastUpdated >= info.blockTime;
|
|
102
|
-
console.log({ isOutdated });
|
|
103
99
|
const hasNoBalanceYet = info.lastUpdated === 0;
|
|
104
|
-
console.log({ hasNoBalanceYet });
|
|
105
100
|
if (hasNoBalanceYet || isOutdated) {
|
|
106
101
|
await __classPrivateFieldGet(this, _BalancesTracker_updateBalance, "f").call(this, accountId);
|
|
107
102
|
__classPrivateFieldGet(this, _BalancesTracker_balances, "f")[accountId].lastUpdated = Date.now();
|
|
@@ -112,7 +107,6 @@ class BalancesTracker {
|
|
|
112
107
|
* is considered outdated).
|
|
113
108
|
*/
|
|
114
109
|
async updateBalances() {
|
|
115
|
-
console.log('MultichainBalancesController - BalancesTracker updateBalances', { balances: __classPrivateFieldGet(this, _BalancesTracker_balances, "f") });
|
|
116
110
|
await Promise.allSettled(Object.keys(__classPrivateFieldGet(this, _BalancesTracker_balances, "f")).map(async (accountId) => {
|
|
117
111
|
await this.updateBalance(accountId);
|
|
118
112
|
}));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BalancesTracker.cjs","sourceRoot":"","sources":["../../src/MultichainBalancesController/BalancesTracker.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,yCAAkC;AAOlC,MAAM,0BAA0B,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,6BAA6B;AAE3E,MAAa,eAAe;IAO1B,YAAY,qBAA2D;QANvE,0CAAgB;QAEhB,iDAAqD;QAErD,oCAAyC,EAAE,EAAC;QAG1C,uBAAA,IAAI,kCAAkB,qBAAqB,MAAA,CAAC;QAE5C,uBAAA,IAAI,2BAAW,IAAI,eAAM,CAAC,IAAI,CAAC,cAAc,EAAE,0BAA0B,CAAC,MAAA,CAAC;IAC7E,CAAC;IAED;;OAEG;IACH,KAAK;QACH,uBAAA,IAAI,+BAAQ,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;IAED;;OAEG;IACH,IAAI;QACF,uBAAA,IAAI,+BAAQ,CAAC,IAAI,EAAE,CAAC;IACtB,CAAC;IAED;;;;;OAKG;IACH,SAAS,CAAC,SAAiB;QACzB,OAAO,
|
|
1
|
+
{"version":3,"file":"BalancesTracker.cjs","sourceRoot":"","sources":["../../src/MultichainBalancesController/BalancesTracker.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,yCAAkC;AAOlC,MAAM,0BAA0B,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,6BAA6B;AAE3E,MAAa,eAAe;IAO1B,YAAY,qBAA2D;QANvE,0CAAgB;QAEhB,iDAAqD;QAErD,oCAAyC,EAAE,EAAC;QAG1C,uBAAA,IAAI,kCAAkB,qBAAqB,MAAA,CAAC;QAE5C,uBAAA,IAAI,2BAAW,IAAI,eAAM,CAAC,IAAI,CAAC,cAAc,EAAE,0BAA0B,CAAC,MAAA,CAAC;IAC7E,CAAC;IAED;;OAEG;IACH,KAAK;QACH,uBAAA,IAAI,+BAAQ,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;IAED;;OAEG;IACH,IAAI;QACF,uBAAA,IAAI,+BAAQ,CAAC,IAAI,EAAE,CAAC;IACtB,CAAC;IAED;;;;;OAKG;IACH,SAAS,CAAC,SAAiB;QACzB,OAAO,SAAS,IAAI,uBAAA,IAAI,iCAAU,CAAC;IACrC,CAAC;IAED;;;;;OAKG;IACH,kBAAkB,CAAC,SAAiB;QAClC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE;YAC9B,MAAM,IAAI,KAAK,CAAC,iCAAiC,SAAS,EAAE,CAAC,CAAC;SAC/D;IACH,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,SAAiB,EAAE,SAAiB;QACxC,0DAA0D;QAC1D,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE;YAC9B,uBAAA,IAAI,iCAAU,CAAC,SAAS,CAAC,GAAG;gBAC1B,WAAW,EAAE,CAAC;gBACd,SAAS;aACV,CAAC;SACH;IACH,CAAC;IAED;;;;;OAKG;IACH,OAAO,CAAC,SAAiB;QACvB,IAAI,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC;QACnC,OAAO,uBAAA,IAAI,iCAAU,CAAC,SAAS,CAAC,CAAC;IACnC,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,aAAa,CAAC,SAAiB;QACnC,IAAI,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC;QAEnC,iFAAiF;QACjF,8BAA8B;QAC9B,EAAE;QACF,mFAAmF;QACnF,8CAA8C;QAC9C,MAAM,IAAI,GAAG,uBAAA,IAAI,iCAAU,CAAC,SAAS,CAAC,CAAC;QACvC,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,SAAS,CAAC;QACnE,MAAM,eAAe,GAAG,IAAI,CAAC,WAAW,KAAK,CAAC,CAAC;QAC/C,IAAI,eAAe,IAAI,UAAU,EAAE;YACjC,MAAM,uBAAA,IAAI,sCAAe,MAAnB,IAAI,EAAgB,SAAS,CAAC,CAAC;YACrC,uBAAA,IAAI,iCAAU,CAAC,SAAS,CAAC,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;SACpD;IACH,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,cAAc;QAClB,MAAM,OAAO,CAAC,UAAU,CACtB,MAAM,CAAC,IAAI,CAAC,uBAAA,IAAI,iCAAU,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE;YAClD,MAAM,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;QACtC,CAAC,CAAC,CACH,CAAC;IACJ,CAAC;CACF;AA/GD,0CA+GC","sourcesContent":["import { Poller } from './Poller';\n\ntype BalanceInfo = {\n lastUpdated: number;\n blockTime: number;\n};\n\nconst BALANCES_TRACKING_INTERVAL = 30 * 1000; // Every 30s in milliseconds.\n\nexport class BalancesTracker {\n #poller: Poller;\n\n #updateBalance: (accountId: string) => Promise<void>;\n\n #balances: Record<string, BalanceInfo> = {};\n\n constructor(updateBalanceCallback: (accountId: string) => Promise<void>) {\n this.#updateBalance = updateBalanceCallback;\n\n this.#poller = new Poller(this.updateBalances, BALANCES_TRACKING_INTERVAL);\n }\n\n /**\n * Starts the tracking process.\n */\n start(): void {\n this.#poller.start();\n }\n\n /**\n * Stops the tracking process.\n */\n stop(): void {\n this.#poller.stop();\n }\n\n /**\n * Checks if an account ID is being tracked.\n *\n * @param accountId - The account ID.\n * @returns True if the account is being tracker, false otherwise.\n */\n isTracked(accountId: string) {\n return accountId in this.#balances;\n }\n\n /**\n * Asserts that an account ID is being tracked.\n *\n * @param accountId - The account ID.\n * @throws If the account ID is not being tracked.\n */\n assertBeingTracked(accountId: string) {\n if (!this.isTracked(accountId)) {\n throw new Error(`Account is not being tracked: ${accountId}`);\n }\n }\n\n /**\n * Starts tracking a new account ID. This method has no effect on already tracked\n * accounts.\n *\n * @param accountId - The account ID.\n * @param blockTime - The block time (used when refreshing the account balances).\n */\n track(accountId: string, blockTime: number) {\n // Do not overwrite current info if already being tracked!\n if (!this.isTracked(accountId)) {\n this.#balances[accountId] = {\n lastUpdated: 0,\n blockTime,\n };\n }\n }\n\n /**\n * Stops tracking a tracked account ID.\n *\n * @param accountId - The account ID.\n * @throws If the account ID is not being tracked.\n */\n untrack(accountId: string) {\n this.assertBeingTracked(accountId);\n delete this.#balances[accountId];\n }\n\n /**\n * Update the balances for a tracked account ID.\n *\n * @param accountId - The account ID.\n * @throws If the account ID is not being tracked.\n */\n async updateBalance(accountId: string) {\n this.assertBeingTracked(accountId);\n\n // We check if the balance is outdated (by comparing to the block time associated\n // with this kind of account).\n //\n // This might not be super accurate, but we could probably compute this differently\n // and try to sync with the \"real block time\"!\n const info = this.#balances[accountId];\n const isOutdated = Date.now() - info.lastUpdated >= info.blockTime;\n const hasNoBalanceYet = info.lastUpdated === 0;\n if (hasNoBalanceYet || isOutdated) {\n await this.#updateBalance(accountId);\n this.#balances[accountId].lastUpdated = Date.now();\n }\n }\n\n /**\n * Update the balances of all tracked accounts (only if the balances\n * is considered outdated).\n */\n async updateBalances() {\n await Promise.allSettled(\n Object.keys(this.#balances).map(async (accountId) => {\n await this.updateBalance(accountId);\n }),\n );\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BalancesTracker.d.cts","sourceRoot":"","sources":["../../src/MultichainBalancesController/BalancesTracker.ts"],"names":[],"mappings":"AASA,qBAAa,eAAe;;gBAOd,qBAAqB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC;IAMvE;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;OAEG;IACH,IAAI,IAAI,IAAI;IAIZ;;;;;OAKG;IACH,SAAS,CAAC,SAAS,EAAE,MAAM;IAI3B;;;;;OAKG;IACH,kBAAkB,CAAC,SAAS,EAAE,MAAM;IAMpC;;;;;;OAMG;IACH,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;IAU1C;;;;;OAKG;IACH,OAAO,CAAC,SAAS,EAAE,MAAM;IAKzB;;;;;OAKG;IACG,aAAa,CAAC,SAAS,EAAE,MAAM;
|
|
1
|
+
{"version":3,"file":"BalancesTracker.d.cts","sourceRoot":"","sources":["../../src/MultichainBalancesController/BalancesTracker.ts"],"names":[],"mappings":"AASA,qBAAa,eAAe;;gBAOd,qBAAqB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC;IAMvE;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;OAEG;IACH,IAAI,IAAI,IAAI;IAIZ;;;;;OAKG;IACH,SAAS,CAAC,SAAS,EAAE,MAAM;IAI3B;;;;;OAKG;IACH,kBAAkB,CAAC,SAAS,EAAE,MAAM;IAMpC;;;;;;OAMG;IACH,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;IAU1C;;;;;OAKG;IACH,OAAO,CAAC,SAAS,EAAE,MAAM;IAKzB;;;;;OAKG;IACG,aAAa,CAAC,SAAS,EAAE,MAAM;IAiBrC;;;OAGG;IACG,cAAc;CAOrB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BalancesTracker.d.mts","sourceRoot":"","sources":["../../src/MultichainBalancesController/BalancesTracker.ts"],"names":[],"mappings":"AASA,qBAAa,eAAe;;gBAOd,qBAAqB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC;IAMvE;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;OAEG;IACH,IAAI,IAAI,IAAI;IAIZ;;;;;OAKG;IACH,SAAS,CAAC,SAAS,EAAE,MAAM;IAI3B;;;;;OAKG;IACH,kBAAkB,CAAC,SAAS,EAAE,MAAM;IAMpC;;;;;;OAMG;IACH,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;IAU1C;;;;;OAKG;IACH,OAAO,CAAC,SAAS,EAAE,MAAM;IAKzB;;;;;OAKG;IACG,aAAa,CAAC,SAAS,EAAE,MAAM;
|
|
1
|
+
{"version":3,"file":"BalancesTracker.d.mts","sourceRoot":"","sources":["../../src/MultichainBalancesController/BalancesTracker.ts"],"names":[],"mappings":"AASA,qBAAa,eAAe;;gBAOd,qBAAqB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC;IAMvE;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;OAEG;IACH,IAAI,IAAI,IAAI;IAIZ;;;;;OAKG;IACH,SAAS,CAAC,SAAS,EAAE,MAAM;IAI3B;;;;;OAKG;IACH,kBAAkB,CAAC,SAAS,EAAE,MAAM;IAMpC;;;;;;OAMG;IACH,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;IAU1C;;;;;OAKG;IACH,OAAO,CAAC,SAAS,EAAE,MAAM;IAKzB;;;;;OAKG;IACG,aAAa,CAAC,SAAS,EAAE,MAAM;IAiBrC;;;OAGG;IACG,cAAc;CAOrB"}
|
|
@@ -39,7 +39,7 @@ export class BalancesTracker {
|
|
|
39
39
|
* @returns True if the account is being tracker, false otherwise.
|
|
40
40
|
*/
|
|
41
41
|
isTracked(accountId) {
|
|
42
|
-
return
|
|
42
|
+
return accountId in __classPrivateFieldGet(this, _BalancesTracker_balances, "f");
|
|
43
43
|
}
|
|
44
44
|
/**
|
|
45
45
|
* Asserts that an account ID is being tracked.
|
|
@@ -85,20 +85,15 @@ export class BalancesTracker {
|
|
|
85
85
|
* @throws If the account ID is not being tracked.
|
|
86
86
|
*/
|
|
87
87
|
async updateBalance(accountId) {
|
|
88
|
-
console.log('MultichainBalancesController - BalancesTracker updateBalance start');
|
|
89
88
|
this.assertBeingTracked(accountId);
|
|
90
|
-
console.log('MultichainBalancesController - BalancesTracker updateBalance', { accountId });
|
|
91
89
|
// We check if the balance is outdated (by comparing to the block time associated
|
|
92
90
|
// with this kind of account).
|
|
93
91
|
//
|
|
94
92
|
// This might not be super accurate, but we could probably compute this differently
|
|
95
93
|
// and try to sync with the "real block time"!
|
|
96
94
|
const info = __classPrivateFieldGet(this, _BalancesTracker_balances, "f")[accountId];
|
|
97
|
-
console.log({ info });
|
|
98
95
|
const isOutdated = Date.now() - info.lastUpdated >= info.blockTime;
|
|
99
|
-
console.log({ isOutdated });
|
|
100
96
|
const hasNoBalanceYet = info.lastUpdated === 0;
|
|
101
|
-
console.log({ hasNoBalanceYet });
|
|
102
97
|
if (hasNoBalanceYet || isOutdated) {
|
|
103
98
|
await __classPrivateFieldGet(this, _BalancesTracker_updateBalance, "f").call(this, accountId);
|
|
104
99
|
__classPrivateFieldGet(this, _BalancesTracker_balances, "f")[accountId].lastUpdated = Date.now();
|
|
@@ -109,7 +104,6 @@ export class BalancesTracker {
|
|
|
109
104
|
* is considered outdated).
|
|
110
105
|
*/
|
|
111
106
|
async updateBalances() {
|
|
112
|
-
console.log('MultichainBalancesController - BalancesTracker updateBalances', { balances: __classPrivateFieldGet(this, _BalancesTracker_balances, "f") });
|
|
113
107
|
await Promise.allSettled(Object.keys(__classPrivateFieldGet(this, _BalancesTracker_balances, "f")).map(async (accountId) => {
|
|
114
108
|
await this.updateBalance(accountId);
|
|
115
109
|
}));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BalancesTracker.mjs","sourceRoot":"","sources":["../../src/MultichainBalancesController/BalancesTracker.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,EAAE,MAAM,EAAE,qBAAiB;AAOlC,MAAM,0BAA0B,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,6BAA6B;AAE3E,MAAM,OAAO,eAAe;IAO1B,YAAY,qBAA2D;QANvE,0CAAgB;QAEhB,iDAAqD;QAErD,oCAAyC,EAAE,EAAC;QAG1C,uBAAA,IAAI,kCAAkB,qBAAqB,MAAA,CAAC;QAE5C,uBAAA,IAAI,2BAAW,IAAI,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE,0BAA0B,CAAC,MAAA,CAAC;IAC7E,CAAC;IAED;;OAEG;IACH,KAAK;QACH,uBAAA,IAAI,+BAAQ,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;IAED;;OAEG;IACH,IAAI;QACF,uBAAA,IAAI,+BAAQ,CAAC,IAAI,EAAE,CAAC;IACtB,CAAC;IAED;;;;;OAKG;IACH,SAAS,CAAC,SAAiB;QACzB,OAAO,
|
|
1
|
+
{"version":3,"file":"BalancesTracker.mjs","sourceRoot":"","sources":["../../src/MultichainBalancesController/BalancesTracker.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,EAAE,MAAM,EAAE,qBAAiB;AAOlC,MAAM,0BAA0B,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,6BAA6B;AAE3E,MAAM,OAAO,eAAe;IAO1B,YAAY,qBAA2D;QANvE,0CAAgB;QAEhB,iDAAqD;QAErD,oCAAyC,EAAE,EAAC;QAG1C,uBAAA,IAAI,kCAAkB,qBAAqB,MAAA,CAAC;QAE5C,uBAAA,IAAI,2BAAW,IAAI,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE,0BAA0B,CAAC,MAAA,CAAC;IAC7E,CAAC;IAED;;OAEG;IACH,KAAK;QACH,uBAAA,IAAI,+BAAQ,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;IAED;;OAEG;IACH,IAAI;QACF,uBAAA,IAAI,+BAAQ,CAAC,IAAI,EAAE,CAAC;IACtB,CAAC;IAED;;;;;OAKG;IACH,SAAS,CAAC,SAAiB;QACzB,OAAO,SAAS,IAAI,uBAAA,IAAI,iCAAU,CAAC;IACrC,CAAC;IAED;;;;;OAKG;IACH,kBAAkB,CAAC,SAAiB;QAClC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE;YAC9B,MAAM,IAAI,KAAK,CAAC,iCAAiC,SAAS,EAAE,CAAC,CAAC;SAC/D;IACH,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,SAAiB,EAAE,SAAiB;QACxC,0DAA0D;QAC1D,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE;YAC9B,uBAAA,IAAI,iCAAU,CAAC,SAAS,CAAC,GAAG;gBAC1B,WAAW,EAAE,CAAC;gBACd,SAAS;aACV,CAAC;SACH;IACH,CAAC;IAED;;;;;OAKG;IACH,OAAO,CAAC,SAAiB;QACvB,IAAI,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC;QACnC,OAAO,uBAAA,IAAI,iCAAU,CAAC,SAAS,CAAC,CAAC;IACnC,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,aAAa,CAAC,SAAiB;QACnC,IAAI,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC;QAEnC,iFAAiF;QACjF,8BAA8B;QAC9B,EAAE;QACF,mFAAmF;QACnF,8CAA8C;QAC9C,MAAM,IAAI,GAAG,uBAAA,IAAI,iCAAU,CAAC,SAAS,CAAC,CAAC;QACvC,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,SAAS,CAAC;QACnE,MAAM,eAAe,GAAG,IAAI,CAAC,WAAW,KAAK,CAAC,CAAC;QAC/C,IAAI,eAAe,IAAI,UAAU,EAAE;YACjC,MAAM,uBAAA,IAAI,sCAAe,MAAnB,IAAI,EAAgB,SAAS,CAAC,CAAC;YACrC,uBAAA,IAAI,iCAAU,CAAC,SAAS,CAAC,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;SACpD;IACH,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,cAAc;QAClB,MAAM,OAAO,CAAC,UAAU,CACtB,MAAM,CAAC,IAAI,CAAC,uBAAA,IAAI,iCAAU,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE;YAClD,MAAM,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;QACtC,CAAC,CAAC,CACH,CAAC;IACJ,CAAC;CACF","sourcesContent":["import { Poller } from './Poller';\n\ntype BalanceInfo = {\n lastUpdated: number;\n blockTime: number;\n};\n\nconst BALANCES_TRACKING_INTERVAL = 30 * 1000; // Every 30s in milliseconds.\n\nexport class BalancesTracker {\n #poller: Poller;\n\n #updateBalance: (accountId: string) => Promise<void>;\n\n #balances: Record<string, BalanceInfo> = {};\n\n constructor(updateBalanceCallback: (accountId: string) => Promise<void>) {\n this.#updateBalance = updateBalanceCallback;\n\n this.#poller = new Poller(this.updateBalances, BALANCES_TRACKING_INTERVAL);\n }\n\n /**\n * Starts the tracking process.\n */\n start(): void {\n this.#poller.start();\n }\n\n /**\n * Stops the tracking process.\n */\n stop(): void {\n this.#poller.stop();\n }\n\n /**\n * Checks if an account ID is being tracked.\n *\n * @param accountId - The account ID.\n * @returns True if the account is being tracker, false otherwise.\n */\n isTracked(accountId: string) {\n return accountId in this.#balances;\n }\n\n /**\n * Asserts that an account ID is being tracked.\n *\n * @param accountId - The account ID.\n * @throws If the account ID is not being tracked.\n */\n assertBeingTracked(accountId: string) {\n if (!this.isTracked(accountId)) {\n throw new Error(`Account is not being tracked: ${accountId}`);\n }\n }\n\n /**\n * Starts tracking a new account ID. This method has no effect on already tracked\n * accounts.\n *\n * @param accountId - The account ID.\n * @param blockTime - The block time (used when refreshing the account balances).\n */\n track(accountId: string, blockTime: number) {\n // Do not overwrite current info if already being tracked!\n if (!this.isTracked(accountId)) {\n this.#balances[accountId] = {\n lastUpdated: 0,\n blockTime,\n };\n }\n }\n\n /**\n * Stops tracking a tracked account ID.\n *\n * @param accountId - The account ID.\n * @throws If the account ID is not being tracked.\n */\n untrack(accountId: string) {\n this.assertBeingTracked(accountId);\n delete this.#balances[accountId];\n }\n\n /**\n * Update the balances for a tracked account ID.\n *\n * @param accountId - The account ID.\n * @throws If the account ID is not being tracked.\n */\n async updateBalance(accountId: string) {\n this.assertBeingTracked(accountId);\n\n // We check if the balance is outdated (by comparing to the block time associated\n // with this kind of account).\n //\n // This might not be super accurate, but we could probably compute this differently\n // and try to sync with the \"real block time\"!\n const info = this.#balances[accountId];\n const isOutdated = Date.now() - info.lastUpdated >= info.blockTime;\n const hasNoBalanceYet = info.lastUpdated === 0;\n if (hasNoBalanceYet || isOutdated) {\n await this.#updateBalance(accountId);\n this.#balances[accountId].lastUpdated = Date.now();\n }\n }\n\n /**\n * Update the balances of all tracked accounts (only if the balances\n * is considered outdated).\n */\n async updateBalances() {\n await Promise.allSettled(\n Object.keys(this.#balances).map(async (accountId) => {\n await this.updateBalance(accountId);\n }),\n );\n }\n}\n"]}
|
|
@@ -10,9 +10,9 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (
|
|
|
10
10
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
11
11
|
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
12
12
|
};
|
|
13
|
-
var _MultichainBalancesController_instances, _MultichainBalancesController_tracker,
|
|
13
|
+
var _MultichainBalancesController_instances, _MultichainBalancesController_tracker, _MultichainBalancesController_getBlockTimeFor, _MultichainBalancesController_listMultichainAccounts, _MultichainBalancesController_listAccounts, _MultichainBalancesController_getAccount, _MultichainBalancesController_updateBalance, _MultichainBalancesController_isNonEvmAccount, _MultichainBalancesController_handleOnAccountAdded, _MultichainBalancesController_handleOnAccountRemoved, _MultichainBalancesController_getBalances, _MultichainBalancesController_getClient;
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.MultichainBalancesController = exports.defaultState = void 0;
|
|
15
|
+
exports.MultichainBalancesController = exports.BTC_BALANCES_UPDATE_TIME = exports.defaultState = void 0;
|
|
16
16
|
const base_controller_1 = require("@metamask/base-controller");
|
|
17
17
|
const keyring_api_1 = require("@metamask/keyring-api");
|
|
18
18
|
const snaps_utils_1 = require("@metamask/snaps-utils");
|
|
@@ -24,18 +24,27 @@ const controllerName = 'MultichainBalancesController';
|
|
|
24
24
|
*/
|
|
25
25
|
exports.defaultState = { balances: {} };
|
|
26
26
|
/**
|
|
27
|
-
* {@link
|
|
27
|
+
* {@link MultichainBalancesController}'s metadata.
|
|
28
28
|
*
|
|
29
29
|
* This allows us to choose if fields of the state should be persisted or not
|
|
30
30
|
* using the `persist` flag; and if they can be sent to Sentry or not, using
|
|
31
31
|
* the `anonymous` flag.
|
|
32
32
|
*/
|
|
33
|
-
const
|
|
33
|
+
const balancesControllerMetadata = {
|
|
34
34
|
balances: {
|
|
35
35
|
persist: true,
|
|
36
36
|
anonymous: false,
|
|
37
37
|
},
|
|
38
38
|
};
|
|
39
|
+
const BTC_AVG_BLOCK_TIME = 10 * 60 * 1000; // 10 minutes in milliseconds
|
|
40
|
+
const SOLANA_AVG_BLOCK_TIME = 400; // 400 milliseconds
|
|
41
|
+
// NOTE: We set an interval of half the average block time to mitigate when our interval
|
|
42
|
+
// is de-synchronized with the actual block time.
|
|
43
|
+
exports.BTC_BALANCES_UPDATE_TIME = BTC_AVG_BLOCK_TIME / 2;
|
|
44
|
+
const BALANCE_CHECK_INTERVALS = {
|
|
45
|
+
[keyring_api_1.BtcAccountType.P2wpkh]: exports.BTC_BALANCES_UPDATE_TIME,
|
|
46
|
+
[keyring_api_1.SolAccountType.DataAccount]: SOLANA_AVG_BLOCK_TIME,
|
|
47
|
+
};
|
|
39
48
|
/**
|
|
40
49
|
* The MultichainBalancesController is responsible for fetching and caching account
|
|
41
50
|
* balances.
|
|
@@ -45,7 +54,7 @@ class MultichainBalancesController extends base_controller_1.BaseController {
|
|
|
45
54
|
super({
|
|
46
55
|
messenger,
|
|
47
56
|
name: controllerName,
|
|
48
|
-
metadata:
|
|
57
|
+
metadata: balancesControllerMetadata,
|
|
49
58
|
state: {
|
|
50
59
|
...exports.defaultState,
|
|
51
60
|
...state,
|
|
@@ -53,14 +62,12 @@ class MultichainBalancesController extends base_controller_1.BaseController {
|
|
|
53
62
|
});
|
|
54
63
|
_MultichainBalancesController_instances.add(this);
|
|
55
64
|
_MultichainBalancesController_tracker.set(this, void 0);
|
|
56
|
-
// As a temporary solution, we are using a map to store the assets
|
|
57
|
-
// that are hardcoded in the module. In the future, this mapping
|
|
58
|
-
// should be dynamic to allow a client to register and unregister assets
|
|
59
|
-
_MultichainBalancesController_networkAssetsMap.set(this, _1.NETWORK_ASSETS_MAP);
|
|
60
65
|
__classPrivateFieldSet(this, _MultichainBalancesController_tracker, new _1.BalancesTracker(async (accountId) => await __classPrivateFieldGet(this, _MultichainBalancesController_instances, "m", _MultichainBalancesController_updateBalance).call(this, accountId)), "f");
|
|
61
66
|
// Register all non-EVM accounts into the tracker
|
|
62
67
|
for (const account of __classPrivateFieldGet(this, _MultichainBalancesController_instances, "m", _MultichainBalancesController_listAccounts).call(this)) {
|
|
63
|
-
__classPrivateFieldGet(this, _MultichainBalancesController_instances, "m",
|
|
68
|
+
if (__classPrivateFieldGet(this, _MultichainBalancesController_instances, "m", _MultichainBalancesController_isNonEvmAccount).call(this, account)) {
|
|
69
|
+
__classPrivateFieldGet(this, _MultichainBalancesController_tracker, "f").track(account.id, __classPrivateFieldGet(this, _MultichainBalancesController_instances, "m", _MultichainBalancesController_getBlockTimeFor).call(this, account));
|
|
70
|
+
}
|
|
64
71
|
}
|
|
65
72
|
this.messagingSystem.subscribe('AccountsController:accountAdded', (account) => __classPrivateFieldGet(this, _MultichainBalancesController_instances, "m", _MultichainBalancesController_handleOnAccountAdded).call(this, account));
|
|
66
73
|
this.messagingSystem.subscribe('AccountsController:accountRemoved', (account) => __classPrivateFieldGet(this, _MultichainBalancesController_instances, "m", _MultichainBalancesController_handleOnAccountRemoved).call(this, account));
|
|
@@ -84,7 +91,6 @@ class MultichainBalancesController extends base_controller_1.BaseController {
|
|
|
84
91
|
* @param accountId - The account ID.
|
|
85
92
|
*/
|
|
86
93
|
async updateBalance(accountId) {
|
|
87
|
-
console.log('MultichainBalancesController updateBalance', { accountId });
|
|
88
94
|
// NOTE: No need to track the account here, since we start tracking those when
|
|
89
95
|
// the "AccountsController:accountAdded" is fired.
|
|
90
96
|
await __classPrivateFieldGet(this, _MultichainBalancesController_tracker, "f").updateBalance(accountId);
|
|
@@ -94,28 +100,21 @@ class MultichainBalancesController extends base_controller_1.BaseController {
|
|
|
94
100
|
* anything, but it updates the state of the controller.
|
|
95
101
|
*/
|
|
96
102
|
async updateBalances() {
|
|
97
|
-
console.log('MultichainBalancesController updateBalances');
|
|
98
103
|
await __classPrivateFieldGet(this, _MultichainBalancesController_tracker, "f").updateBalances();
|
|
99
104
|
}
|
|
100
105
|
}
|
|
101
106
|
exports.MultichainBalancesController = MultichainBalancesController;
|
|
102
|
-
_MultichainBalancesController_tracker = new WeakMap(),
|
|
103
|
-
if (
|
|
104
|
-
|
|
105
|
-
console.log('MultichainBalancesController - early return in #trackAccount', account);
|
|
106
|
-
return;
|
|
107
|
+
_MultichainBalancesController_tracker = new WeakMap(), _MultichainBalancesController_instances = new WeakSet(), _MultichainBalancesController_getBlockTimeFor = function _MultichainBalancesController_getBlockTimeFor(account) {
|
|
108
|
+
if (account.type in BALANCE_CHECK_INTERVALS) {
|
|
109
|
+
return _1.BALANCE_UPDATE_INTERVALS[account.type];
|
|
107
110
|
}
|
|
108
|
-
|
|
109
|
-
// @ts-expect-error - For the moment we are only tracking non-EVM accounts and this is
|
|
110
|
-
// checked with the method `#isNonEvmAccount`. We can ignore this error since
|
|
111
|
-
// eip155:eoa and eip155:erc4337 account type balances are not tracked here.
|
|
112
|
-
_1.BALANCE_UPDATE_INTERVALS[__classPrivateFieldGet(this, _MultichainBalancesController_instances, "m", _MultichainBalancesController_getAccount).call(this, account.id).type];
|
|
113
|
-
__classPrivateFieldGet(this, _MultichainBalancesController_tracker, "f").track(account.id, updateTime);
|
|
111
|
+
throw new Error(`Unsupported account type for balance tracking: ${account.type}`);
|
|
114
112
|
}, _MultichainBalancesController_listMultichainAccounts = function _MultichainBalancesController_listMultichainAccounts() {
|
|
115
113
|
return this.messagingSystem.call('AccountsController:listMultichainAccounts');
|
|
116
114
|
}, _MultichainBalancesController_listAccounts = function _MultichainBalancesController_listAccounts() {
|
|
117
115
|
const accounts = __classPrivateFieldGet(this, _MultichainBalancesController_instances, "m", _MultichainBalancesController_listMultichainAccounts).call(this);
|
|
118
|
-
return accounts.filter((account) =>
|
|
116
|
+
return accounts.filter((account) => account.type === keyring_api_1.SolAccountType.DataAccount ||
|
|
117
|
+
account.type === keyring_api_1.BtcAccountType.P2wpkh);
|
|
119
118
|
}, _MultichainBalancesController_getAccount = function _MultichainBalancesController_getAccount(accountId) {
|
|
120
119
|
const account = __classPrivateFieldGet(this, _MultichainBalancesController_instances, "m", _MultichainBalancesController_listMultichainAccounts).call(this).find((multichainAccount) => multichainAccount.id === accountId);
|
|
121
120
|
if (!account) {
|
|
@@ -134,17 +133,12 @@ _MultichainBalancesController_tracker = new WeakMap(), _MultichainBalancesContro
|
|
|
134
133
|
*/
|
|
135
134
|
async function _MultichainBalancesController_updateBalance(accountId) {
|
|
136
135
|
const account = __classPrivateFieldGet(this, _MultichainBalancesController_instances, "m", _MultichainBalancesController_getAccount).call(this, accountId);
|
|
137
|
-
console.log('MultichainBalancesController updateBalance', { account });
|
|
138
136
|
const partialState = { balances: {} };
|
|
139
|
-
console.log('MultichainBalancesController updateBalance', { partialState });
|
|
140
|
-
const scope = (0, utils_1.getScopeForAddress)(account);
|
|
141
|
-
console.log('MultichainBalancesController updateBalance', { scope });
|
|
142
|
-
const assetsList = __classPrivateFieldGet(this, _MultichainBalancesController_networkAssetsMap, "f")[scope];
|
|
143
|
-
console.log('MultichainBalancesController updateBalance', { assetsList });
|
|
144
137
|
if (account.metadata.snap) {
|
|
145
|
-
|
|
138
|
+
const scope = (0, utils_1.getScopeForAccount)(account);
|
|
139
|
+
const assetTypes = _1.NETWORK_ASSETS_MAP[scope];
|
|
140
|
+
partialState.balances[account.id] = await __classPrivateFieldGet(this, _MultichainBalancesController_instances, "m", _MultichainBalancesController_getBalances).call(this, account.id, account.metadata.snap.id, assetTypes);
|
|
146
141
|
}
|
|
147
|
-
console.log('MultichainBalancesController update state', { partialState });
|
|
148
142
|
this.update((state) => {
|
|
149
143
|
state.balances = {
|
|
150
144
|
...state.balances,
|
|
@@ -162,10 +156,11 @@ async function _MultichainBalancesController_updateBalance(accountId) {
|
|
|
162
156
|
* @param account - The new account being added.
|
|
163
157
|
*/
|
|
164
158
|
async function _MultichainBalancesController_handleOnAccountAdded(account) {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
159
|
+
if (!__classPrivateFieldGet(this, _MultichainBalancesController_instances, "m", _MultichainBalancesController_isNonEvmAccount).call(this, account)) {
|
|
160
|
+
// Nothing to do here for EVM accounts
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
__classPrivateFieldGet(this, _MultichainBalancesController_tracker, "f").track(account.id, __classPrivateFieldGet(this, _MultichainBalancesController_instances, "m", _MultichainBalancesController_getBlockTimeFor).call(this, account));
|
|
169
164
|
// NOTE: Unfortunately, we cannot update the balance right away here, because
|
|
170
165
|
// messenger's events are running synchronously and fetching the balance is
|
|
171
166
|
// asynchronous.
|
|
@@ -180,9 +175,6 @@ async function _MultichainBalancesController_handleOnAccountAdded(account) {
|
|
|
180
175
|
* @param accountId - The account ID being removed.
|
|
181
176
|
*/
|
|
182
177
|
async function _MultichainBalancesController_handleOnAccountRemoved(accountId) {
|
|
183
|
-
console.log('MultichainBalancesController handleOnAccountAdded', {
|
|
184
|
-
accountId,
|
|
185
|
-
});
|
|
186
178
|
if (__classPrivateFieldGet(this, _MultichainBalancesController_tracker, "f").isTracked(accountId)) {
|
|
187
179
|
__classPrivateFieldGet(this, _MultichainBalancesController_tracker, "f").untrack(accountId);
|
|
188
180
|
}
|
|
@@ -202,14 +194,7 @@ async function _MultichainBalancesController_handleOnAccountRemoved(accountId) {
|
|
|
202
194
|
* @returns A map of asset types to balances.
|
|
203
195
|
*/
|
|
204
196
|
async function _MultichainBalancesController_getBalances(accountId, snapId, assetTypes) {
|
|
205
|
-
|
|
206
|
-
accountId,
|
|
207
|
-
snapId,
|
|
208
|
-
assetTypes,
|
|
209
|
-
});
|
|
210
|
-
const keyringClient = __classPrivateFieldGet(this, _MultichainBalancesController_instances, "m", _MultichainBalancesController_getClient).call(this, snapId);
|
|
211
|
-
console.log('MultichainBalancesController', { keyringClient });
|
|
212
|
-
return await keyringClient.getAccountBalances(accountId, assetTypes);
|
|
197
|
+
return await __classPrivateFieldGet(this, _MultichainBalancesController_instances, "m", _MultichainBalancesController_getClient).call(this, snapId).getAccountBalances(accountId, assetTypes);
|
|
213
198
|
}, _MultichainBalancesController_getClient = function _MultichainBalancesController_getClient(snapId) {
|
|
214
199
|
return new keyring_api_1.KeyringClient({
|
|
215
200
|
send: async (request) => (await this.messagingSystem.call('SnapController:handleRequest', {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MultichainBalancesController.cjs","sourceRoot":"","sources":["../../src/MultichainBalancesController/MultichainBalancesController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n AccountsControllerAccountAddedEvent,\n AccountsControllerAccountRemovedEvent,\n AccountsControllerListMultichainAccountsAction,\n} from '@metamask/accounts-controller';\nimport {\n BaseController,\n type ControllerGetStateAction,\n type ControllerStateChangeEvent,\n type RestrictedControllerMessenger,\n} from '@metamask/base-controller';\nimport {\n KeyringClient,\n type Balance,\n type CaipAssetType,\n type InternalAccount,\n isEvmAccountType,\n} from '@metamask/keyring-api';\nimport type { HandleSnapRequest } from '@metamask/snaps-controllers';\nimport type { SnapId } from '@metamask/snaps-sdk';\nimport { HandlerType } from '@metamask/snaps-utils';\nimport type { Json, JsonRpcRequest } from '@metamask/utils';\nimport type { Draft } from 'immer';\n\nimport {\n BalancesTracker,\n BALANCE_UPDATE_INTERVALS,\n NETWORK_ASSETS_MAP,\n} from '.';\nimport { getScopeForAddress } from './utils';\n\nconst controllerName = 'MultichainBalancesController';\n\n/**\n * State used by the {@link MultichainBalancesController} to cache account balances.\n */\nexport type MultichainBalancesControllerState = {\n balances: {\n [account: string]: {\n [asset: string]: {\n amount: string;\n unit: string;\n };\n };\n };\n};\n\n/**\n * Default state of the {@link MultichainBalancesController}.\n */\nexport const defaultState: MultichainBalancesControllerState = { balances: {} };\n\n/**\n * Returns the state of the {@link MultichainBalancesController}.\n */\nexport type MultichainBalancesControllerGetStateAction =\n ControllerGetStateAction<\n typeof controllerName,\n MultichainBalancesControllerState\n >;\n\n/**\n * Updates the balances of all supported accounts in {@link MultichainBalancesController}.\n */\nexport type MultichainBalancesControllerUpdateBalancesAction = {\n type: `${typeof controllerName}:updateBalances`;\n handler: MultichainBalancesController['updateBalances'];\n};\n\n/**\n * Event emitted when the state of the {@link MultichainBalancesController} changes.\n */\nexport type MultichainBalancesControllerStateChange =\n ControllerStateChangeEvent<\n typeof controllerName,\n MultichainBalancesControllerState\n >;\n\n/**\n * Actions exposed by the {@link MultichainBalancesController}.\n */\nexport type MultichainBalancesControllerActions =\n | MultichainBalancesControllerGetStateAction\n | MultichainBalancesControllerUpdateBalancesAction;\n\n/**\n * Events emitted by {@link MultichainBalancesController}.\n */\nexport type MultichainBalancesControllerEvents =\n MultichainBalancesControllerStateChange;\n\n/**\n * Actions that this controller is allowed to call.\n */\nexport type AllowedActions =\n | HandleSnapRequest\n | AccountsControllerListMultichainAccountsAction;\n\n/**\n * Events that this controller is allowed to subscribe.\n */\nexport type AllowedEvents =\n | AccountsControllerAccountAddedEvent\n | AccountsControllerAccountRemovedEvent;\n\n/**\n * Messenger type for the MultichainBalancesController.\n */\nexport type MultichainBalancesControllerMessenger =\n RestrictedControllerMessenger<\n typeof controllerName,\n MultichainBalancesControllerActions | AllowedActions,\n MultichainBalancesControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n >;\n\n/**\n * {@link multichainBalancesController}'s metadata.\n *\n * This allows us to choose if fields of the state should be persisted or not\n * using the `persist` flag; and if they can be sent to Sentry or not, using\n * the `anonymous` flag.\n */\nconst multichainBalancesControllerMetadata = {\n balances: {\n persist: true,\n anonymous: false,\n },\n};\n\n/**\n * The MultichainBalancesController is responsible for fetching and caching account\n * balances.\n */\nexport class MultichainBalancesController extends BaseController<\n typeof controllerName,\n MultichainBalancesControllerState,\n MultichainBalancesControllerMessenger\n> {\n readonly #tracker: BalancesTracker;\n\n // As a temporary solution, we are using a map to store the assets\n // that are hardcoded in the module. In the future, this mapping\n // should be dynamic to allow a client to register and unregister assets\n readonly #networkAssetsMap: Record<string, string[]> = NETWORK_ASSETS_MAP;\n\n constructor({\n messenger,\n state,\n }: {\n messenger: MultichainBalancesControllerMessenger;\n state: MultichainBalancesControllerState;\n }) {\n super({\n messenger,\n name: controllerName,\n metadata: multichainBalancesControllerMetadata,\n state: {\n ...defaultState,\n ...state,\n },\n });\n\n this.#tracker = new BalancesTracker(\n async (accountId: string) => await this.#updateBalance(accountId),\n );\n\n // Register all non-EVM accounts into the tracker\n for (const account of this.#listAccounts()) {\n this.#trackAccount(account);\n }\n\n this.messagingSystem.subscribe(\n 'AccountsController:accountAdded',\n (account) => this.#handleOnAccountAdded(account),\n );\n this.messagingSystem.subscribe(\n 'AccountsController:accountRemoved',\n (account) => this.#handleOnAccountRemoved(account),\n );\n }\n\n /**\n * Starts the polling process.\n */\n start(): void {\n this.#tracker.start();\n }\n\n /**\n * Stops the polling process.\n */\n stop(): void {\n this.#tracker.stop();\n }\n\n /**\n * Tracks an account to get its balances.\n *\n * @param account - The account to track.\n */\n #trackAccount(account: InternalAccount): void {\n if (!this.#isNonEvmAccount(account)) {\n // Nothing to do here for EVM accounts\n console.log(\n 'MultichainBalancesController - early return in #trackAccount',\n account,\n );\n return;\n }\n\n const updateTime =\n // @ts-expect-error - For the moment we are only tracking non-EVM accounts and this is\n // checked with the method `#isNonEvmAccount`. We can ignore this error since\n // eip155:eoa and eip155:erc4337 account type balances are not tracked here.\n BALANCE_UPDATE_INTERVALS[this.#getAccount(account.id).type];\n this.#tracker.track(account.id, updateTime);\n }\n\n /**\n * Lists the multichain accounts coming from the `AccountsController`.\n *\n * @returns A list of multichain accounts.\n */\n #listMultichainAccounts(): InternalAccount[] {\n return this.messagingSystem.call(\n 'AccountsController:listMultichainAccounts',\n );\n }\n\n /**\n * Lists the accounts that we should get balances for.\n *\n * Currently, we only get balances for non-EVM accounts.\n *\n * @returns A list of accounts that we should get balances for.\n */\n #listAccounts(): InternalAccount[] {\n const accounts = this.#listMultichainAccounts();\n\n return accounts.filter((account) => this.#isNonEvmAccount(account));\n }\n\n /**\n * Get a non-EVM account from its ID.\n *\n * @param accountId - The account ID.\n * @returns The non-EVM account.\n */\n #getAccount(accountId: string): InternalAccount {\n const account: InternalAccount | undefined =\n this.#listMultichainAccounts().find(\n (multichainAccount) => multichainAccount.id === accountId,\n );\n\n if (!account) {\n throw new Error(`Unknown account: ${accountId}`);\n }\n if (!this.#isNonEvmAccount(account)) {\n throw new Error(`Account is not a non-EVM account: ${accountId}`);\n }\n return account;\n }\n\n /**\n * Updates the balances of one account. This method doesn't return\n * anything, but it updates the state of the controller.\n *\n * @param accountId - The account ID.\n */\n async #updateBalance(accountId: string) {\n const account = this.#getAccount(accountId);\n console.log('MultichainBalancesController updateBalance', { account });\n const partialState: MultichainBalancesControllerState = { balances: {} };\n console.log('MultichainBalancesController updateBalance', { partialState });\n\n const scope = getScopeForAddress(account);\n console.log('MultichainBalancesController updateBalance', { scope });\n const assetsList = this.#networkAssetsMap[scope];\n console.log('MultichainBalancesController updateBalance', { assetsList });\n\n if (account.metadata.snap) {\n partialState.balances[account.id] = await this.#getBalances(\n account.id,\n account.metadata.snap.id,\n assetsList,\n );\n }\n\n console.log('MultichainBalancesController update state', { partialState });\n this.update((state: Draft<MultichainBalancesControllerState>) => {\n state.balances = {\n ...state.balances,\n ...partialState.balances,\n };\n });\n }\n\n /**\n * Updates the balances of one account. This method doesn't return\n * anything, but it updates the state of the controller.\n *\n * @param accountId - The account ID.\n */\n async updateBalance(accountId: string) {\n console.log('MultichainBalancesController updateBalance', { accountId });\n // NOTE: No need to track the account here, since we start tracking those when\n // the \"AccountsController:accountAdded\" is fired.\n await this.#tracker.updateBalance(accountId);\n }\n\n /**\n * Updates the balances of all supported accounts. This method doesn't return\n * anything, but it updates the state of the controller.\n */\n async updateBalances() {\n console.log('MultichainBalancesController updateBalances');\n await this.#tracker.updateBalances();\n }\n\n /**\n * Checks for non-EVM accounts.\n *\n * @param account - The new account to be checked.\n * @returns True if the account is a non-EVM account, false otherwise.\n */\n #isNonEvmAccount(account: InternalAccount): boolean {\n return (\n !isEvmAccountType(account.type) &&\n // Non-EVM accounts are backed by a Snap for now\n account.metadata.snap !== undefined\n );\n }\n\n /**\n * Handles changes when a new account has been added.\n *\n * @param account - The new account being added.\n */\n async #handleOnAccountAdded(account: InternalAccount) {\n console.log('MultichainBalancesController handleOnAccountAdded', {\n account,\n });\n this.#trackAccount(account);\n // NOTE: Unfortunately, we cannot update the balance right away here, because\n // messenger's events are running synchronously and fetching the balance is\n // asynchronous.\n // Updating the balance here would resume at some point but the event emitter\n // will not `await` this (so we have no real control \"when\" the balance will\n // really be updated), see:\n // - https://github.com/MetaMask/core/blob/v213.0.0/packages/accounts-controller/src/AccountsController.ts#L1036-L1039\n }\n\n /**\n * Handles changes when a new account has been removed.\n *\n * @param accountId - The account ID being removed.\n */\n async #handleOnAccountRemoved(accountId: string) {\n console.log('MultichainBalancesController handleOnAccountAdded', {\n accountId,\n });\n if (this.#tracker.isTracked(accountId)) {\n this.#tracker.untrack(accountId);\n }\n\n if (accountId in this.state.balances) {\n this.update((state: Draft<MultichainBalancesControllerState>) => {\n delete state.balances[accountId];\n return state;\n });\n }\n }\n\n /**\n * Get the balances for an account.\n *\n * @param accountId - ID of the account to get balances for.\n * @param snapId - ID of the Snap which manages the account.\n * @param assetTypes - Array of asset types to get balances for.\n * @returns A map of asset types to balances.\n */\n async #getBalances(\n accountId: string,\n snapId: string,\n assetTypes: CaipAssetType[],\n ): Promise<Record<CaipAssetType, Balance>> {\n console.log('MultichainBalancesController - getBalances', {\n accountId,\n snapId,\n assetTypes,\n });\n const keyringClient = this.#getClient(snapId);\n console.log('MultichainBalancesController', { keyringClient });\n return await keyringClient.getAccountBalances(accountId, assetTypes);\n }\n\n /**\n * Gets a `KeyringClient` for a Snap.\n *\n * @param snapId - ID of the Snap to get the client for.\n * @returns A `KeyringClient` for the Snap.\n */\n #getClient(snapId: string): KeyringClient {\n return new KeyringClient({\n send: async (request: JsonRpcRequest) =>\n (await this.messagingSystem.call('SnapController:handleRequest', {\n snapId: snapId as SnapId,\n origin: 'metamask',\n handler: HandlerType.OnKeyringRequest,\n request,\n })) as Promise<Json>,\n });\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"MultichainBalancesController.cjs","sourceRoot":"","sources":["../../src/MultichainBalancesController/MultichainBalancesController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n AccountsControllerAccountAddedEvent,\n AccountsControllerAccountRemovedEvent,\n AccountsControllerListMultichainAccountsAction,\n} from '@metamask/accounts-controller';\nimport {\n BaseController,\n type ControllerGetStateAction,\n type ControllerStateChangeEvent,\n type RestrictedControllerMessenger,\n} from '@metamask/base-controller';\nimport {\n BtcAccountType,\n KeyringClient,\n type Balance,\n type CaipAssetType,\n type InternalAccount,\n isEvmAccountType,\n SolAccountType,\n} from '@metamask/keyring-api';\nimport type { HandleSnapRequest } from '@metamask/snaps-controllers';\nimport type { SnapId } from '@metamask/snaps-sdk';\nimport { HandlerType } from '@metamask/snaps-utils';\nimport type { Json, JsonRpcRequest } from '@metamask/utils';\nimport type { Draft } from 'immer';\n\nimport {\n BalancesTracker,\n BALANCE_UPDATE_INTERVALS,\n NETWORK_ASSETS_MAP,\n} from '.';\nimport { getScopeForAccount } from './utils';\n\nconst controllerName = 'MultichainBalancesController';\n\n/**\n * State used by the {@link MultichainBalancesController} to cache account balances.\n */\nexport type MultichainBalancesControllerState = {\n balances: {\n [account: string]: {\n [asset: string]: {\n amount: string;\n unit: string;\n };\n };\n };\n};\n\n/**\n * Default state of the {@link MultichainBalancesController}.\n */\nexport const defaultState: MultichainBalancesControllerState = { balances: {} };\n\n/**\n * Returns the state of the {@link MultichainBalancesController}.\n */\nexport type MultichainBalancesControllerGetStateAction =\n ControllerGetStateAction<\n typeof controllerName,\n MultichainBalancesControllerState\n >;\n\n/**\n * Updates the balances of all supported accounts.\n */\nexport type MultichainBalancesControllerUpdateBalancesAction = {\n type: `${typeof controllerName}:updateBalances`;\n handler: MultichainBalancesController['updateBalances'];\n};\n\n/**\n * Event emitted when the state of the {@link MultichainBalancesController} changes.\n */\nexport type MultichainBalancesControllerStateChange =\n ControllerStateChangeEvent<\n typeof controllerName,\n MultichainBalancesControllerState\n >;\n\n/**\n * Actions exposed by the {@link MultichainBalancesController}.\n */\nexport type MultichainBalancesControllerActions =\n | MultichainBalancesControllerGetStateAction\n | MultichainBalancesControllerUpdateBalancesAction;\n\n/**\n * Events emitted by {@link MultichainBalancesController}.\n */\nexport type MultichainBalancesControllerEvents =\n MultichainBalancesControllerStateChange;\n\n/**\n * Actions that this controller is allowed to call.\n */\nexport type AllowedActions =\n | HandleSnapRequest\n | AccountsControllerListMultichainAccountsAction;\n\n/**\n * Events that this controller is allowed to subscribe.\n */\nexport type AllowedEvents =\n | AccountsControllerAccountAddedEvent\n | AccountsControllerAccountRemovedEvent;\n\n/**\n * Messenger type for the MultichainBalancesController.\n */\nexport type MultichainBalancesControllerMessenger =\n RestrictedControllerMessenger<\n typeof controllerName,\n MultichainBalancesControllerActions | AllowedActions,\n MultichainBalancesControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n >;\n\n/**\n * {@link MultichainBalancesController}'s metadata.\n *\n * This allows us to choose if fields of the state should be persisted or not\n * using the `persist` flag; and if they can be sent to Sentry or not, using\n * the `anonymous` flag.\n */\nconst balancesControllerMetadata = {\n balances: {\n persist: true,\n anonymous: false,\n },\n};\n\nconst BTC_AVG_BLOCK_TIME = 10 * 60 * 1000; // 10 minutes in milliseconds\nconst SOLANA_AVG_BLOCK_TIME = 400; // 400 milliseconds\n\n// NOTE: We set an interval of half the average block time to mitigate when our interval\n// is de-synchronized with the actual block time.\nexport const BTC_BALANCES_UPDATE_TIME = BTC_AVG_BLOCK_TIME / 2;\n\nconst BALANCE_CHECK_INTERVALS = {\n [BtcAccountType.P2wpkh]: BTC_BALANCES_UPDATE_TIME,\n [SolAccountType.DataAccount]: SOLANA_AVG_BLOCK_TIME,\n};\n\n/**\n * The MultichainBalancesController is responsible for fetching and caching account\n * balances.\n */\nexport class MultichainBalancesController extends BaseController<\n typeof controllerName,\n MultichainBalancesControllerState,\n MultichainBalancesControllerMessenger\n> {\n #tracker: BalancesTracker;\n\n constructor({\n messenger,\n state,\n }: {\n messenger: MultichainBalancesControllerMessenger;\n state: MultichainBalancesControllerState;\n }) {\n super({\n messenger,\n name: controllerName,\n metadata: balancesControllerMetadata,\n state: {\n ...defaultState,\n ...state,\n },\n });\n\n this.#tracker = new BalancesTracker(\n async (accountId: string) => await this.#updateBalance(accountId),\n );\n\n // Register all non-EVM accounts into the tracker\n for (const account of this.#listAccounts()) {\n if (this.#isNonEvmAccount(account)) {\n this.#tracker.track(account.id, this.#getBlockTimeFor(account));\n }\n }\n\n this.messagingSystem.subscribe(\n 'AccountsController:accountAdded',\n (account) => this.#handleOnAccountAdded(account),\n );\n this.messagingSystem.subscribe(\n 'AccountsController:accountRemoved',\n (account) => this.#handleOnAccountRemoved(account),\n );\n }\n\n /**\n * Starts the polling process.\n */\n start(): void {\n this.#tracker.start();\n }\n\n /**\n * Stops the polling process.\n */\n stop(): void {\n this.#tracker.stop();\n }\n\n /**\n * Gets the block time for a given account.\n *\n * @param account - The account to get the block time for.\n * @returns The block time for the account.\n */\n #getBlockTimeFor(account: InternalAccount): number {\n if (account.type in BALANCE_CHECK_INTERVALS) {\n return BALANCE_UPDATE_INTERVALS[\n account.type as keyof typeof BALANCE_UPDATE_INTERVALS\n ];\n }\n throw new Error(\n `Unsupported account type for balance tracking: ${account.type}`,\n );\n }\n\n /**\n * Lists the multichain accounts coming from the `AccountsController`.\n *\n * @returns A list of multichain accounts.\n */\n #listMultichainAccounts(): InternalAccount[] {\n return this.messagingSystem.call(\n 'AccountsController:listMultichainAccounts',\n );\n }\n\n /**\n * Lists the accounts that we should get balances for.\n *\n * @returns A list of accounts that we should get balances for.\n */\n #listAccounts(): InternalAccount[] {\n const accounts = this.#listMultichainAccounts();\n\n return accounts.filter(\n (account) =>\n account.type === SolAccountType.DataAccount ||\n account.type === BtcAccountType.P2wpkh,\n );\n }\n\n /**\n * Get a non-EVM account from its ID.\n *\n * @param accountId - The account ID.\n * @returns The non-EVM account.\n */\n #getAccount(accountId: string): InternalAccount {\n const account: InternalAccount | undefined =\n this.#listMultichainAccounts().find(\n (multichainAccount) => multichainAccount.id === accountId,\n );\n\n if (!account) {\n throw new Error(`Unknown account: ${accountId}`);\n }\n if (!this.#isNonEvmAccount(account)) {\n throw new Error(`Account is not a non-EVM account: ${accountId}`);\n }\n return account;\n }\n\n /**\n * Updates the balances of one account. This method doesn't return\n * anything, but it updates the state of the controller.\n *\n * @param accountId - The account ID.\n */\n async #updateBalance(accountId: string) {\n const account = this.#getAccount(accountId);\n const partialState: MultichainBalancesControllerState = { balances: {} };\n\n if (account.metadata.snap) {\n const scope = getScopeForAccount(account);\n const assetTypes = NETWORK_ASSETS_MAP[scope];\n\n partialState.balances[account.id] = await this.#getBalances(\n account.id,\n account.metadata.snap.id,\n assetTypes,\n );\n }\n\n this.update((state: Draft<MultichainBalancesControllerState>) => {\n state.balances = {\n ...state.balances,\n ...partialState.balances,\n };\n });\n }\n\n /**\n * Updates the balances of one account. This method doesn't return\n * anything, but it updates the state of the controller.\n *\n * @param accountId - The account ID.\n */\n async updateBalance(accountId: string) {\n // NOTE: No need to track the account here, since we start tracking those when\n // the \"AccountsController:accountAdded\" is fired.\n await this.#tracker.updateBalance(accountId);\n }\n\n /**\n * Updates the balances of all supported accounts. This method doesn't return\n * anything, but it updates the state of the controller.\n */\n async updateBalances() {\n await this.#tracker.updateBalances();\n }\n\n /**\n * Checks for non-EVM accounts.\n *\n * @param account - The new account to be checked.\n * @returns True if the account is a non-EVM account, false otherwise.\n */\n #isNonEvmAccount(account: InternalAccount): boolean {\n return (\n !isEvmAccountType(account.type) &&\n // Non-EVM accounts are backed by a Snap for now\n account.metadata.snap !== undefined\n );\n }\n\n /**\n * Handles changes when a new account has been added.\n *\n * @param account - The new account being added.\n */\n async #handleOnAccountAdded(account: InternalAccount) {\n if (!this.#isNonEvmAccount(account)) {\n // Nothing to do here for EVM accounts\n return;\n }\n\n this.#tracker.track(account.id, this.#getBlockTimeFor(account));\n // NOTE: Unfortunately, we cannot update the balance right away here, because\n // messenger's events are running synchronously and fetching the balance is\n // asynchronous.\n // Updating the balance here would resume at some point but the event emitter\n // will not `await` this (so we have no real control \"when\" the balance will\n // really be updated), see:\n // - https://github.com/MetaMask/core/blob/v213.0.0/packages/accounts-controller/src/AccountsController.ts#L1036-L1039\n }\n\n /**\n * Handles changes when a new account has been removed.\n *\n * @param accountId - The account ID being removed.\n */\n async #handleOnAccountRemoved(accountId: string) {\n if (this.#tracker.isTracked(accountId)) {\n this.#tracker.untrack(accountId);\n }\n\n if (accountId in this.state.balances) {\n this.update((state: Draft<MultichainBalancesControllerState>) => {\n delete state.balances[accountId];\n return state;\n });\n }\n }\n\n /**\n * Get the balances for an account.\n *\n * @param accountId - ID of the account to get balances for.\n * @param snapId - ID of the Snap which manages the account.\n * @param assetTypes - Array of asset types to get balances for.\n * @returns A map of asset types to balances.\n */\n async #getBalances(\n accountId: string,\n snapId: string,\n assetTypes: CaipAssetType[],\n ): Promise<Record<CaipAssetType, Balance>> {\n return await this.#getClient(snapId).getAccountBalances(\n accountId,\n assetTypes,\n );\n }\n\n /**\n * Gets a `KeyringClient` for a Snap.\n *\n * @param snapId - ID of the Snap to get the client for.\n * @returns A `KeyringClient` for the Snap.\n */\n #getClient(snapId: string): KeyringClient {\n return new KeyringClient({\n send: async (request: JsonRpcRequest) =>\n (await this.messagingSystem.call('SnapController:handleRequest', {\n snapId: snapId as SnapId,\n origin: 'metamask',\n handler: HandlerType.OnKeyringRequest,\n request,\n })) as Promise<Json>,\n });\n }\n}\n"]}
|
|
@@ -24,7 +24,7 @@ export declare const defaultState: MultichainBalancesControllerState;
|
|
|
24
24
|
*/
|
|
25
25
|
export type MultichainBalancesControllerGetStateAction = ControllerGetStateAction<typeof controllerName, MultichainBalancesControllerState>;
|
|
26
26
|
/**
|
|
27
|
-
* Updates the balances of all supported accounts
|
|
27
|
+
* Updates the balances of all supported accounts.
|
|
28
28
|
*/
|
|
29
29
|
export type MultichainBalancesControllerUpdateBalancesAction = {
|
|
30
30
|
type: `${typeof controllerName}:updateBalances`;
|
|
@@ -54,6 +54,7 @@ export type AllowedEvents = AccountsControllerAccountAddedEvent | AccountsContro
|
|
|
54
54
|
* Messenger type for the MultichainBalancesController.
|
|
55
55
|
*/
|
|
56
56
|
export type MultichainBalancesControllerMessenger = RestrictedControllerMessenger<typeof controllerName, MultichainBalancesControllerActions | AllowedActions, MultichainBalancesControllerEvents | AllowedEvents, AllowedActions['type'], AllowedEvents['type']>;
|
|
57
|
+
export declare const BTC_BALANCES_UPDATE_TIME: number;
|
|
57
58
|
/**
|
|
58
59
|
* The MultichainBalancesController is responsible for fetching and caching account
|
|
59
60
|
* balances.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MultichainBalancesController.d.cts","sourceRoot":"","sources":["../../src/MultichainBalancesController/MultichainBalancesController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mCAAmC,EACnC,qCAAqC,EACrC,8CAA8C,EAC/C,sCAAsC;AACvC,OAAO,EACL,cAAc,EACd,KAAK,wBAAwB,EAC7B,KAAK,0BAA0B,EAC/B,KAAK,6BAA6B,EACnC,kCAAkC;
|
|
1
|
+
{"version":3,"file":"MultichainBalancesController.d.cts","sourceRoot":"","sources":["../../src/MultichainBalancesController/MultichainBalancesController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mCAAmC,EACnC,qCAAqC,EACrC,8CAA8C,EAC/C,sCAAsC;AACvC,OAAO,EACL,cAAc,EACd,KAAK,wBAAwB,EAC7B,KAAK,0BAA0B,EAC/B,KAAK,6BAA6B,EACnC,kCAAkC;AAUnC,OAAO,KAAK,EAAE,iBAAiB,EAAE,oCAAoC;AAarE,QAAA,MAAM,cAAc,iCAAiC,CAAC;AAEtD;;GAEG;AACH,MAAM,MAAM,iCAAiC,GAAG;IAC9C,QAAQ,EAAE;QACR,CAAC,OAAO,EAAE,MAAM,GAAG;YACjB,CAAC,KAAK,EAAE,MAAM,GAAG;gBACf,MAAM,EAAE,MAAM,CAAC;gBACf,IAAI,EAAE,MAAM,CAAC;aACd,CAAC;SACH,CAAC;KACH,CAAC;CACH,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,YAAY,EAAE,iCAAoD,CAAC;AAEhF;;GAEG;AACH,MAAM,MAAM,0CAA0C,GACpD,wBAAwB,CACtB,OAAO,cAAc,EACrB,iCAAiC,CAClC,CAAC;AAEJ;;GAEG;AACH,MAAM,MAAM,gDAAgD,GAAG;IAC7D,IAAI,EAAE,GAAG,OAAO,cAAc,iBAAiB,CAAC;IAChD,OAAO,EAAE,4BAA4B,CAAC,gBAAgB,CAAC,CAAC;CACzD,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,uCAAuC,GACjD,0BAA0B,CACxB,OAAO,cAAc,EACrB,iCAAiC,CAClC,CAAC;AAEJ;;GAEG;AACH,MAAM,MAAM,mCAAmC,GAC3C,0CAA0C,GAC1C,gDAAgD,CAAC;AAErD;;GAEG;AACH,MAAM,MAAM,kCAAkC,GAC5C,uCAAuC,CAAC;AAE1C;;GAEG;AACH,MAAM,MAAM,cAAc,GACtB,iBAAiB,GACjB,8CAA8C,CAAC;AAEnD;;GAEG;AACH,MAAM,MAAM,aAAa,GACrB,mCAAmC,GACnC,qCAAqC,CAAC;AAE1C;;GAEG;AACH,MAAM,MAAM,qCAAqC,GAC/C,6BAA6B,CAC3B,OAAO,cAAc,EACrB,mCAAmC,GAAG,cAAc,EACpD,kCAAkC,GAAG,aAAa,EAClD,cAAc,CAAC,MAAM,CAAC,EACtB,aAAa,CAAC,MAAM,CAAC,CACtB,CAAC;AAqBJ,eAAO,MAAM,wBAAwB,QAAyB,CAAC;AAO/D;;;GAGG;AACH,qBAAa,4BAA6B,SAAQ,cAAc,CAC9D,OAAO,cAAc,EACrB,iCAAiC,EACjC,qCAAqC,CACtC;;gBAGa,EACV,SAAS,EACT,KAAK,GACN,EAAE;QACD,SAAS,EAAE,qCAAqC,CAAC;QACjD,KAAK,EAAE,iCAAiC,CAAC;KAC1C;IAgCD;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;OAEG;IACH,IAAI,IAAI,IAAI;IAiGZ;;;;;OAKG;IACG,aAAa,CAAC,SAAS,EAAE,MAAM;IAMrC;;;OAGG;IACG,cAAc;CA6FrB"}
|
|
@@ -24,7 +24,7 @@ export declare const defaultState: MultichainBalancesControllerState;
|
|
|
24
24
|
*/
|
|
25
25
|
export type MultichainBalancesControllerGetStateAction = ControllerGetStateAction<typeof controllerName, MultichainBalancesControllerState>;
|
|
26
26
|
/**
|
|
27
|
-
* Updates the balances of all supported accounts
|
|
27
|
+
* Updates the balances of all supported accounts.
|
|
28
28
|
*/
|
|
29
29
|
export type MultichainBalancesControllerUpdateBalancesAction = {
|
|
30
30
|
type: `${typeof controllerName}:updateBalances`;
|
|
@@ -54,6 +54,7 @@ export type AllowedEvents = AccountsControllerAccountAddedEvent | AccountsContro
|
|
|
54
54
|
* Messenger type for the MultichainBalancesController.
|
|
55
55
|
*/
|
|
56
56
|
export type MultichainBalancesControllerMessenger = RestrictedControllerMessenger<typeof controllerName, MultichainBalancesControllerActions | AllowedActions, MultichainBalancesControllerEvents | AllowedEvents, AllowedActions['type'], AllowedEvents['type']>;
|
|
57
|
+
export declare const BTC_BALANCES_UPDATE_TIME: number;
|
|
57
58
|
/**
|
|
58
59
|
* The MultichainBalancesController is responsible for fetching and caching account
|
|
59
60
|
* balances.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MultichainBalancesController.d.mts","sourceRoot":"","sources":["../../src/MultichainBalancesController/MultichainBalancesController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mCAAmC,EACnC,qCAAqC,EACrC,8CAA8C,EAC/C,sCAAsC;AACvC,OAAO,EACL,cAAc,EACd,KAAK,wBAAwB,EAC7B,KAAK,0BAA0B,EAC/B,KAAK,6BAA6B,EACnC,kCAAkC;
|
|
1
|
+
{"version":3,"file":"MultichainBalancesController.d.mts","sourceRoot":"","sources":["../../src/MultichainBalancesController/MultichainBalancesController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mCAAmC,EACnC,qCAAqC,EACrC,8CAA8C,EAC/C,sCAAsC;AACvC,OAAO,EACL,cAAc,EACd,KAAK,wBAAwB,EAC7B,KAAK,0BAA0B,EAC/B,KAAK,6BAA6B,EACnC,kCAAkC;AAUnC,OAAO,KAAK,EAAE,iBAAiB,EAAE,oCAAoC;AAarE,QAAA,MAAM,cAAc,iCAAiC,CAAC;AAEtD;;GAEG;AACH,MAAM,MAAM,iCAAiC,GAAG;IAC9C,QAAQ,EAAE;QACR,CAAC,OAAO,EAAE,MAAM,GAAG;YACjB,CAAC,KAAK,EAAE,MAAM,GAAG;gBACf,MAAM,EAAE,MAAM,CAAC;gBACf,IAAI,EAAE,MAAM,CAAC;aACd,CAAC;SACH,CAAC;KACH,CAAC;CACH,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,YAAY,EAAE,iCAAoD,CAAC;AAEhF;;GAEG;AACH,MAAM,MAAM,0CAA0C,GACpD,wBAAwB,CACtB,OAAO,cAAc,EACrB,iCAAiC,CAClC,CAAC;AAEJ;;GAEG;AACH,MAAM,MAAM,gDAAgD,GAAG;IAC7D,IAAI,EAAE,GAAG,OAAO,cAAc,iBAAiB,CAAC;IAChD,OAAO,EAAE,4BAA4B,CAAC,gBAAgB,CAAC,CAAC;CACzD,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,uCAAuC,GACjD,0BAA0B,CACxB,OAAO,cAAc,EACrB,iCAAiC,CAClC,CAAC;AAEJ;;GAEG;AACH,MAAM,MAAM,mCAAmC,GAC3C,0CAA0C,GAC1C,gDAAgD,CAAC;AAErD;;GAEG;AACH,MAAM,MAAM,kCAAkC,GAC5C,uCAAuC,CAAC;AAE1C;;GAEG;AACH,MAAM,MAAM,cAAc,GACtB,iBAAiB,GACjB,8CAA8C,CAAC;AAEnD;;GAEG;AACH,MAAM,MAAM,aAAa,GACrB,mCAAmC,GACnC,qCAAqC,CAAC;AAE1C;;GAEG;AACH,MAAM,MAAM,qCAAqC,GAC/C,6BAA6B,CAC3B,OAAO,cAAc,EACrB,mCAAmC,GAAG,cAAc,EACpD,kCAAkC,GAAG,aAAa,EAClD,cAAc,CAAC,MAAM,CAAC,EACtB,aAAa,CAAC,MAAM,CAAC,CACtB,CAAC;AAqBJ,eAAO,MAAM,wBAAwB,QAAyB,CAAC;AAO/D;;;GAGG;AACH,qBAAa,4BAA6B,SAAQ,cAAc,CAC9D,OAAO,cAAc,EACrB,iCAAiC,EACjC,qCAAqC,CACtC;;gBAGa,EACV,SAAS,EACT,KAAK,GACN,EAAE;QACD,SAAS,EAAE,qCAAqC,CAAC;QACjD,KAAK,EAAE,iCAAiC,CAAC;KAC1C;IAgCD;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;OAEG;IACH,IAAI,IAAI,IAAI;IAiGZ;;;;;OAKG;IACG,aAAa,CAAC,SAAS,EAAE,MAAM;IAMrC;;;OAGG;IACG,cAAc;CA6FrB"}
|
|
@@ -9,32 +9,41 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (
|
|
|
9
9
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
10
10
|
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
11
11
|
};
|
|
12
|
-
var _MultichainBalancesController_instances, _MultichainBalancesController_tracker,
|
|
12
|
+
var _MultichainBalancesController_instances, _MultichainBalancesController_tracker, _MultichainBalancesController_getBlockTimeFor, _MultichainBalancesController_listMultichainAccounts, _MultichainBalancesController_listAccounts, _MultichainBalancesController_getAccount, _MultichainBalancesController_updateBalance, _MultichainBalancesController_isNonEvmAccount, _MultichainBalancesController_handleOnAccountAdded, _MultichainBalancesController_handleOnAccountRemoved, _MultichainBalancesController_getBalances, _MultichainBalancesController_getClient;
|
|
13
13
|
import { BaseController } from "@metamask/base-controller";
|
|
14
14
|
import { KeyringClient } from "@metamask/keyring-api";
|
|
15
15
|
import $metamaskkeyringapi from "@metamask/keyring-api";
|
|
16
|
-
const { isEvmAccountType } = $metamaskkeyringapi;
|
|
16
|
+
const { BtcAccountType, isEvmAccountType, SolAccountType } = $metamaskkeyringapi;
|
|
17
17
|
import { HandlerType } from "@metamask/snaps-utils";
|
|
18
18
|
import { BalancesTracker, BALANCE_UPDATE_INTERVALS, NETWORK_ASSETS_MAP } from "./index.mjs";
|
|
19
|
-
import {
|
|
19
|
+
import { getScopeForAccount } from "./utils.mjs";
|
|
20
20
|
const controllerName = 'MultichainBalancesController';
|
|
21
21
|
/**
|
|
22
22
|
* Default state of the {@link MultichainBalancesController}.
|
|
23
23
|
*/
|
|
24
24
|
export const defaultState = { balances: {} };
|
|
25
25
|
/**
|
|
26
|
-
* {@link
|
|
26
|
+
* {@link MultichainBalancesController}'s metadata.
|
|
27
27
|
*
|
|
28
28
|
* This allows us to choose if fields of the state should be persisted or not
|
|
29
29
|
* using the `persist` flag; and if they can be sent to Sentry or not, using
|
|
30
30
|
* the `anonymous` flag.
|
|
31
31
|
*/
|
|
32
|
-
const
|
|
32
|
+
const balancesControllerMetadata = {
|
|
33
33
|
balances: {
|
|
34
34
|
persist: true,
|
|
35
35
|
anonymous: false,
|
|
36
36
|
},
|
|
37
37
|
};
|
|
38
|
+
const BTC_AVG_BLOCK_TIME = 10 * 60 * 1000; // 10 minutes in milliseconds
|
|
39
|
+
const SOLANA_AVG_BLOCK_TIME = 400; // 400 milliseconds
|
|
40
|
+
// NOTE: We set an interval of half the average block time to mitigate when our interval
|
|
41
|
+
// is de-synchronized with the actual block time.
|
|
42
|
+
export const BTC_BALANCES_UPDATE_TIME = BTC_AVG_BLOCK_TIME / 2;
|
|
43
|
+
const BALANCE_CHECK_INTERVALS = {
|
|
44
|
+
[BtcAccountType.P2wpkh]: BTC_BALANCES_UPDATE_TIME,
|
|
45
|
+
[SolAccountType.DataAccount]: SOLANA_AVG_BLOCK_TIME,
|
|
46
|
+
};
|
|
38
47
|
/**
|
|
39
48
|
* The MultichainBalancesController is responsible for fetching and caching account
|
|
40
49
|
* balances.
|
|
@@ -44,7 +53,7 @@ export class MultichainBalancesController extends BaseController {
|
|
|
44
53
|
super({
|
|
45
54
|
messenger,
|
|
46
55
|
name: controllerName,
|
|
47
|
-
metadata:
|
|
56
|
+
metadata: balancesControllerMetadata,
|
|
48
57
|
state: {
|
|
49
58
|
...defaultState,
|
|
50
59
|
...state,
|
|
@@ -52,14 +61,12 @@ export class MultichainBalancesController extends BaseController {
|
|
|
52
61
|
});
|
|
53
62
|
_MultichainBalancesController_instances.add(this);
|
|
54
63
|
_MultichainBalancesController_tracker.set(this, void 0);
|
|
55
|
-
// As a temporary solution, we are using a map to store the assets
|
|
56
|
-
// that are hardcoded in the module. In the future, this mapping
|
|
57
|
-
// should be dynamic to allow a client to register and unregister assets
|
|
58
|
-
_MultichainBalancesController_networkAssetsMap.set(this, NETWORK_ASSETS_MAP);
|
|
59
64
|
__classPrivateFieldSet(this, _MultichainBalancesController_tracker, new BalancesTracker(async (accountId) => await __classPrivateFieldGet(this, _MultichainBalancesController_instances, "m", _MultichainBalancesController_updateBalance).call(this, accountId)), "f");
|
|
60
65
|
// Register all non-EVM accounts into the tracker
|
|
61
66
|
for (const account of __classPrivateFieldGet(this, _MultichainBalancesController_instances, "m", _MultichainBalancesController_listAccounts).call(this)) {
|
|
62
|
-
__classPrivateFieldGet(this, _MultichainBalancesController_instances, "m",
|
|
67
|
+
if (__classPrivateFieldGet(this, _MultichainBalancesController_instances, "m", _MultichainBalancesController_isNonEvmAccount).call(this, account)) {
|
|
68
|
+
__classPrivateFieldGet(this, _MultichainBalancesController_tracker, "f").track(account.id, __classPrivateFieldGet(this, _MultichainBalancesController_instances, "m", _MultichainBalancesController_getBlockTimeFor).call(this, account));
|
|
69
|
+
}
|
|
63
70
|
}
|
|
64
71
|
this.messagingSystem.subscribe('AccountsController:accountAdded', (account) => __classPrivateFieldGet(this, _MultichainBalancesController_instances, "m", _MultichainBalancesController_handleOnAccountAdded).call(this, account));
|
|
65
72
|
this.messagingSystem.subscribe('AccountsController:accountRemoved', (account) => __classPrivateFieldGet(this, _MultichainBalancesController_instances, "m", _MultichainBalancesController_handleOnAccountRemoved).call(this, account));
|
|
@@ -83,7 +90,6 @@ export class MultichainBalancesController extends BaseController {
|
|
|
83
90
|
* @param accountId - The account ID.
|
|
84
91
|
*/
|
|
85
92
|
async updateBalance(accountId) {
|
|
86
|
-
console.log('MultichainBalancesController updateBalance', { accountId });
|
|
87
93
|
// NOTE: No need to track the account here, since we start tracking those when
|
|
88
94
|
// the "AccountsController:accountAdded" is fired.
|
|
89
95
|
await __classPrivateFieldGet(this, _MultichainBalancesController_tracker, "f").updateBalance(accountId);
|
|
@@ -93,27 +99,20 @@ export class MultichainBalancesController extends BaseController {
|
|
|
93
99
|
* anything, but it updates the state of the controller.
|
|
94
100
|
*/
|
|
95
101
|
async updateBalances() {
|
|
96
|
-
console.log('MultichainBalancesController updateBalances');
|
|
97
102
|
await __classPrivateFieldGet(this, _MultichainBalancesController_tracker, "f").updateBalances();
|
|
98
103
|
}
|
|
99
104
|
}
|
|
100
|
-
_MultichainBalancesController_tracker = new WeakMap(),
|
|
101
|
-
if (
|
|
102
|
-
|
|
103
|
-
console.log('MultichainBalancesController - early return in #trackAccount', account);
|
|
104
|
-
return;
|
|
105
|
+
_MultichainBalancesController_tracker = new WeakMap(), _MultichainBalancesController_instances = new WeakSet(), _MultichainBalancesController_getBlockTimeFor = function _MultichainBalancesController_getBlockTimeFor(account) {
|
|
106
|
+
if (account.type in BALANCE_CHECK_INTERVALS) {
|
|
107
|
+
return BALANCE_UPDATE_INTERVALS[account.type];
|
|
105
108
|
}
|
|
106
|
-
|
|
107
|
-
// @ts-expect-error - For the moment we are only tracking non-EVM accounts and this is
|
|
108
|
-
// checked with the method `#isNonEvmAccount`. We can ignore this error since
|
|
109
|
-
// eip155:eoa and eip155:erc4337 account type balances are not tracked here.
|
|
110
|
-
BALANCE_UPDATE_INTERVALS[__classPrivateFieldGet(this, _MultichainBalancesController_instances, "m", _MultichainBalancesController_getAccount).call(this, account.id).type];
|
|
111
|
-
__classPrivateFieldGet(this, _MultichainBalancesController_tracker, "f").track(account.id, updateTime);
|
|
109
|
+
throw new Error(`Unsupported account type for balance tracking: ${account.type}`);
|
|
112
110
|
}, _MultichainBalancesController_listMultichainAccounts = function _MultichainBalancesController_listMultichainAccounts() {
|
|
113
111
|
return this.messagingSystem.call('AccountsController:listMultichainAccounts');
|
|
114
112
|
}, _MultichainBalancesController_listAccounts = function _MultichainBalancesController_listAccounts() {
|
|
115
113
|
const accounts = __classPrivateFieldGet(this, _MultichainBalancesController_instances, "m", _MultichainBalancesController_listMultichainAccounts).call(this);
|
|
116
|
-
return accounts.filter((account) =>
|
|
114
|
+
return accounts.filter((account) => account.type === SolAccountType.DataAccount ||
|
|
115
|
+
account.type === BtcAccountType.P2wpkh);
|
|
117
116
|
}, _MultichainBalancesController_getAccount = function _MultichainBalancesController_getAccount(accountId) {
|
|
118
117
|
const account = __classPrivateFieldGet(this, _MultichainBalancesController_instances, "m", _MultichainBalancesController_listMultichainAccounts).call(this).find((multichainAccount) => multichainAccount.id === accountId);
|
|
119
118
|
if (!account) {
|
|
@@ -132,17 +131,12 @@ _MultichainBalancesController_tracker = new WeakMap(), _MultichainBalancesContro
|
|
|
132
131
|
*/
|
|
133
132
|
async function _MultichainBalancesController_updateBalance(accountId) {
|
|
134
133
|
const account = __classPrivateFieldGet(this, _MultichainBalancesController_instances, "m", _MultichainBalancesController_getAccount).call(this, accountId);
|
|
135
|
-
console.log('MultichainBalancesController updateBalance', { account });
|
|
136
134
|
const partialState = { balances: {} };
|
|
137
|
-
console.log('MultichainBalancesController updateBalance', { partialState });
|
|
138
|
-
const scope = getScopeForAddress(account);
|
|
139
|
-
console.log('MultichainBalancesController updateBalance', { scope });
|
|
140
|
-
const assetsList = __classPrivateFieldGet(this, _MultichainBalancesController_networkAssetsMap, "f")[scope];
|
|
141
|
-
console.log('MultichainBalancesController updateBalance', { assetsList });
|
|
142
135
|
if (account.metadata.snap) {
|
|
143
|
-
|
|
136
|
+
const scope = getScopeForAccount(account);
|
|
137
|
+
const assetTypes = NETWORK_ASSETS_MAP[scope];
|
|
138
|
+
partialState.balances[account.id] = await __classPrivateFieldGet(this, _MultichainBalancesController_instances, "m", _MultichainBalancesController_getBalances).call(this, account.id, account.metadata.snap.id, assetTypes);
|
|
144
139
|
}
|
|
145
|
-
console.log('MultichainBalancesController update state', { partialState });
|
|
146
140
|
this.update((state) => {
|
|
147
141
|
state.balances = {
|
|
148
142
|
...state.balances,
|
|
@@ -160,10 +154,11 @@ async function _MultichainBalancesController_updateBalance(accountId) {
|
|
|
160
154
|
* @param account - The new account being added.
|
|
161
155
|
*/
|
|
162
156
|
async function _MultichainBalancesController_handleOnAccountAdded(account) {
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
157
|
+
if (!__classPrivateFieldGet(this, _MultichainBalancesController_instances, "m", _MultichainBalancesController_isNonEvmAccount).call(this, account)) {
|
|
158
|
+
// Nothing to do here for EVM accounts
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
__classPrivateFieldGet(this, _MultichainBalancesController_tracker, "f").track(account.id, __classPrivateFieldGet(this, _MultichainBalancesController_instances, "m", _MultichainBalancesController_getBlockTimeFor).call(this, account));
|
|
167
162
|
// NOTE: Unfortunately, we cannot update the balance right away here, because
|
|
168
163
|
// messenger's events are running synchronously and fetching the balance is
|
|
169
164
|
// asynchronous.
|
|
@@ -178,9 +173,6 @@ async function _MultichainBalancesController_handleOnAccountAdded(account) {
|
|
|
178
173
|
* @param accountId - The account ID being removed.
|
|
179
174
|
*/
|
|
180
175
|
async function _MultichainBalancesController_handleOnAccountRemoved(accountId) {
|
|
181
|
-
console.log('MultichainBalancesController handleOnAccountAdded', {
|
|
182
|
-
accountId,
|
|
183
|
-
});
|
|
184
176
|
if (__classPrivateFieldGet(this, _MultichainBalancesController_tracker, "f").isTracked(accountId)) {
|
|
185
177
|
__classPrivateFieldGet(this, _MultichainBalancesController_tracker, "f").untrack(accountId);
|
|
186
178
|
}
|
|
@@ -200,14 +192,7 @@ async function _MultichainBalancesController_handleOnAccountRemoved(accountId) {
|
|
|
200
192
|
* @returns A map of asset types to balances.
|
|
201
193
|
*/
|
|
202
194
|
async function _MultichainBalancesController_getBalances(accountId, snapId, assetTypes) {
|
|
203
|
-
|
|
204
|
-
accountId,
|
|
205
|
-
snapId,
|
|
206
|
-
assetTypes,
|
|
207
|
-
});
|
|
208
|
-
const keyringClient = __classPrivateFieldGet(this, _MultichainBalancesController_instances, "m", _MultichainBalancesController_getClient).call(this, snapId);
|
|
209
|
-
console.log('MultichainBalancesController', { keyringClient });
|
|
210
|
-
return await keyringClient.getAccountBalances(accountId, assetTypes);
|
|
195
|
+
return await __classPrivateFieldGet(this, _MultichainBalancesController_instances, "m", _MultichainBalancesController_getClient).call(this, snapId).getAccountBalances(accountId, assetTypes);
|
|
211
196
|
}, _MultichainBalancesController_getClient = function _MultichainBalancesController_getClient(snapId) {
|
|
212
197
|
return new KeyringClient({
|
|
213
198
|
send: async (request) => (await this.messagingSystem.call('SnapController:handleRequest', {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MultichainBalancesController.mjs","sourceRoot":"","sources":["../../src/MultichainBalancesController/MultichainBalancesController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n AccountsControllerAccountAddedEvent,\n AccountsControllerAccountRemovedEvent,\n AccountsControllerListMultichainAccountsAction,\n} from '@metamask/accounts-controller';\nimport {\n BaseController,\n type ControllerGetStateAction,\n type ControllerStateChangeEvent,\n type RestrictedControllerMessenger,\n} from '@metamask/base-controller';\nimport {\n KeyringClient,\n type Balance,\n type CaipAssetType,\n type InternalAccount,\n isEvmAccountType,\n} from '@metamask/keyring-api';\nimport type { HandleSnapRequest } from '@metamask/snaps-controllers';\nimport type { SnapId } from '@metamask/snaps-sdk';\nimport { HandlerType } from '@metamask/snaps-utils';\nimport type { Json, JsonRpcRequest } from '@metamask/utils';\nimport type { Draft } from 'immer';\n\nimport {\n BalancesTracker,\n BALANCE_UPDATE_INTERVALS,\n NETWORK_ASSETS_MAP,\n} from '.';\nimport { getScopeForAddress } from './utils';\n\nconst controllerName = 'MultichainBalancesController';\n\n/**\n * State used by the {@link MultichainBalancesController} to cache account balances.\n */\nexport type MultichainBalancesControllerState = {\n balances: {\n [account: string]: {\n [asset: string]: {\n amount: string;\n unit: string;\n };\n };\n };\n};\n\n/**\n * Default state of the {@link MultichainBalancesController}.\n */\nexport const defaultState: MultichainBalancesControllerState = { balances: {} };\n\n/**\n * Returns the state of the {@link MultichainBalancesController}.\n */\nexport type MultichainBalancesControllerGetStateAction =\n ControllerGetStateAction<\n typeof controllerName,\n MultichainBalancesControllerState\n >;\n\n/**\n * Updates the balances of all supported accounts in {@link MultichainBalancesController}.\n */\nexport type MultichainBalancesControllerUpdateBalancesAction = {\n type: `${typeof controllerName}:updateBalances`;\n handler: MultichainBalancesController['updateBalances'];\n};\n\n/**\n * Event emitted when the state of the {@link MultichainBalancesController} changes.\n */\nexport type MultichainBalancesControllerStateChange =\n ControllerStateChangeEvent<\n typeof controllerName,\n MultichainBalancesControllerState\n >;\n\n/**\n * Actions exposed by the {@link MultichainBalancesController}.\n */\nexport type MultichainBalancesControllerActions =\n | MultichainBalancesControllerGetStateAction\n | MultichainBalancesControllerUpdateBalancesAction;\n\n/**\n * Events emitted by {@link MultichainBalancesController}.\n */\nexport type MultichainBalancesControllerEvents =\n MultichainBalancesControllerStateChange;\n\n/**\n * Actions that this controller is allowed to call.\n */\nexport type AllowedActions =\n | HandleSnapRequest\n | AccountsControllerListMultichainAccountsAction;\n\n/**\n * Events that this controller is allowed to subscribe.\n */\nexport type AllowedEvents =\n | AccountsControllerAccountAddedEvent\n | AccountsControllerAccountRemovedEvent;\n\n/**\n * Messenger type for the MultichainBalancesController.\n */\nexport type MultichainBalancesControllerMessenger =\n RestrictedControllerMessenger<\n typeof controllerName,\n MultichainBalancesControllerActions | AllowedActions,\n MultichainBalancesControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n >;\n\n/**\n * {@link multichainBalancesController}'s metadata.\n *\n * This allows us to choose if fields of the state should be persisted or not\n * using the `persist` flag; and if they can be sent to Sentry or not, using\n * the `anonymous` flag.\n */\nconst multichainBalancesControllerMetadata = {\n balances: {\n persist: true,\n anonymous: false,\n },\n};\n\n/**\n * The MultichainBalancesController is responsible for fetching and caching account\n * balances.\n */\nexport class MultichainBalancesController extends BaseController<\n typeof controllerName,\n MultichainBalancesControllerState,\n MultichainBalancesControllerMessenger\n> {\n readonly #tracker: BalancesTracker;\n\n // As a temporary solution, we are using a map to store the assets\n // that are hardcoded in the module. In the future, this mapping\n // should be dynamic to allow a client to register and unregister assets\n readonly #networkAssetsMap: Record<string, string[]> = NETWORK_ASSETS_MAP;\n\n constructor({\n messenger,\n state,\n }: {\n messenger: MultichainBalancesControllerMessenger;\n state: MultichainBalancesControllerState;\n }) {\n super({\n messenger,\n name: controllerName,\n metadata: multichainBalancesControllerMetadata,\n state: {\n ...defaultState,\n ...state,\n },\n });\n\n this.#tracker = new BalancesTracker(\n async (accountId: string) => await this.#updateBalance(accountId),\n );\n\n // Register all non-EVM accounts into the tracker\n for (const account of this.#listAccounts()) {\n this.#trackAccount(account);\n }\n\n this.messagingSystem.subscribe(\n 'AccountsController:accountAdded',\n (account) => this.#handleOnAccountAdded(account),\n );\n this.messagingSystem.subscribe(\n 'AccountsController:accountRemoved',\n (account) => this.#handleOnAccountRemoved(account),\n );\n }\n\n /**\n * Starts the polling process.\n */\n start(): void {\n this.#tracker.start();\n }\n\n /**\n * Stops the polling process.\n */\n stop(): void {\n this.#tracker.stop();\n }\n\n /**\n * Tracks an account to get its balances.\n *\n * @param account - The account to track.\n */\n #trackAccount(account: InternalAccount): void {\n if (!this.#isNonEvmAccount(account)) {\n // Nothing to do here for EVM accounts\n console.log(\n 'MultichainBalancesController - early return in #trackAccount',\n account,\n );\n return;\n }\n\n const updateTime =\n // @ts-expect-error - For the moment we are only tracking non-EVM accounts and this is\n // checked with the method `#isNonEvmAccount`. We can ignore this error since\n // eip155:eoa and eip155:erc4337 account type balances are not tracked here.\n BALANCE_UPDATE_INTERVALS[this.#getAccount(account.id).type];\n this.#tracker.track(account.id, updateTime);\n }\n\n /**\n * Lists the multichain accounts coming from the `AccountsController`.\n *\n * @returns A list of multichain accounts.\n */\n #listMultichainAccounts(): InternalAccount[] {\n return this.messagingSystem.call(\n 'AccountsController:listMultichainAccounts',\n );\n }\n\n /**\n * Lists the accounts that we should get balances for.\n *\n * Currently, we only get balances for non-EVM accounts.\n *\n * @returns A list of accounts that we should get balances for.\n */\n #listAccounts(): InternalAccount[] {\n const accounts = this.#listMultichainAccounts();\n\n return accounts.filter((account) => this.#isNonEvmAccount(account));\n }\n\n /**\n * Get a non-EVM account from its ID.\n *\n * @param accountId - The account ID.\n * @returns The non-EVM account.\n */\n #getAccount(accountId: string): InternalAccount {\n const account: InternalAccount | undefined =\n this.#listMultichainAccounts().find(\n (multichainAccount) => multichainAccount.id === accountId,\n );\n\n if (!account) {\n throw new Error(`Unknown account: ${accountId}`);\n }\n if (!this.#isNonEvmAccount(account)) {\n throw new Error(`Account is not a non-EVM account: ${accountId}`);\n }\n return account;\n }\n\n /**\n * Updates the balances of one account. This method doesn't return\n * anything, but it updates the state of the controller.\n *\n * @param accountId - The account ID.\n */\n async #updateBalance(accountId: string) {\n const account = this.#getAccount(accountId);\n console.log('MultichainBalancesController updateBalance', { account });\n const partialState: MultichainBalancesControllerState = { balances: {} };\n console.log('MultichainBalancesController updateBalance', { partialState });\n\n const scope = getScopeForAddress(account);\n console.log('MultichainBalancesController updateBalance', { scope });\n const assetsList = this.#networkAssetsMap[scope];\n console.log('MultichainBalancesController updateBalance', { assetsList });\n\n if (account.metadata.snap) {\n partialState.balances[account.id] = await this.#getBalances(\n account.id,\n account.metadata.snap.id,\n assetsList,\n );\n }\n\n console.log('MultichainBalancesController update state', { partialState });\n this.update((state: Draft<MultichainBalancesControllerState>) => {\n state.balances = {\n ...state.balances,\n ...partialState.balances,\n };\n });\n }\n\n /**\n * Updates the balances of one account. This method doesn't return\n * anything, but it updates the state of the controller.\n *\n * @param accountId - The account ID.\n */\n async updateBalance(accountId: string) {\n console.log('MultichainBalancesController updateBalance', { accountId });\n // NOTE: No need to track the account here, since we start tracking those when\n // the \"AccountsController:accountAdded\" is fired.\n await this.#tracker.updateBalance(accountId);\n }\n\n /**\n * Updates the balances of all supported accounts. This method doesn't return\n * anything, but it updates the state of the controller.\n */\n async updateBalances() {\n console.log('MultichainBalancesController updateBalances');\n await this.#tracker.updateBalances();\n }\n\n /**\n * Checks for non-EVM accounts.\n *\n * @param account - The new account to be checked.\n * @returns True if the account is a non-EVM account, false otherwise.\n */\n #isNonEvmAccount(account: InternalAccount): boolean {\n return (\n !isEvmAccountType(account.type) &&\n // Non-EVM accounts are backed by a Snap for now\n account.metadata.snap !== undefined\n );\n }\n\n /**\n * Handles changes when a new account has been added.\n *\n * @param account - The new account being added.\n */\n async #handleOnAccountAdded(account: InternalAccount) {\n console.log('MultichainBalancesController handleOnAccountAdded', {\n account,\n });\n this.#trackAccount(account);\n // NOTE: Unfortunately, we cannot update the balance right away here, because\n // messenger's events are running synchronously and fetching the balance is\n // asynchronous.\n // Updating the balance here would resume at some point but the event emitter\n // will not `await` this (so we have no real control \"when\" the balance will\n // really be updated), see:\n // - https://github.com/MetaMask/core/blob/v213.0.0/packages/accounts-controller/src/AccountsController.ts#L1036-L1039\n }\n\n /**\n * Handles changes when a new account has been removed.\n *\n * @param accountId - The account ID being removed.\n */\n async #handleOnAccountRemoved(accountId: string) {\n console.log('MultichainBalancesController handleOnAccountAdded', {\n accountId,\n });\n if (this.#tracker.isTracked(accountId)) {\n this.#tracker.untrack(accountId);\n }\n\n if (accountId in this.state.balances) {\n this.update((state: Draft<MultichainBalancesControllerState>) => {\n delete state.balances[accountId];\n return state;\n });\n }\n }\n\n /**\n * Get the balances for an account.\n *\n * @param accountId - ID of the account to get balances for.\n * @param snapId - ID of the Snap which manages the account.\n * @param assetTypes - Array of asset types to get balances for.\n * @returns A map of asset types to balances.\n */\n async #getBalances(\n accountId: string,\n snapId: string,\n assetTypes: CaipAssetType[],\n ): Promise<Record<CaipAssetType, Balance>> {\n console.log('MultichainBalancesController - getBalances', {\n accountId,\n snapId,\n assetTypes,\n });\n const keyringClient = this.#getClient(snapId);\n console.log('MultichainBalancesController', { keyringClient });\n return await keyringClient.getAccountBalances(accountId, assetTypes);\n }\n\n /**\n * Gets a `KeyringClient` for a Snap.\n *\n * @param snapId - ID of the Snap to get the client for.\n * @returns A `KeyringClient` for the Snap.\n */\n #getClient(snapId: string): KeyringClient {\n return new KeyringClient({\n send: async (request: JsonRpcRequest) =>\n (await this.messagingSystem.call('SnapController:handleRequest', {\n snapId: snapId as SnapId,\n origin: 'metamask',\n handler: HandlerType.OnKeyringRequest,\n request,\n })) as Promise<Json>,\n });\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"MultichainBalancesController.mjs","sourceRoot":"","sources":["../../src/MultichainBalancesController/MultichainBalancesController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n AccountsControllerAccountAddedEvent,\n AccountsControllerAccountRemovedEvent,\n AccountsControllerListMultichainAccountsAction,\n} from '@metamask/accounts-controller';\nimport {\n BaseController,\n type ControllerGetStateAction,\n type ControllerStateChangeEvent,\n type RestrictedControllerMessenger,\n} from '@metamask/base-controller';\nimport {\n BtcAccountType,\n KeyringClient,\n type Balance,\n type CaipAssetType,\n type InternalAccount,\n isEvmAccountType,\n SolAccountType,\n} from '@metamask/keyring-api';\nimport type { HandleSnapRequest } from '@metamask/snaps-controllers';\nimport type { SnapId } from '@metamask/snaps-sdk';\nimport { HandlerType } from '@metamask/snaps-utils';\nimport type { Json, JsonRpcRequest } from '@metamask/utils';\nimport type { Draft } from 'immer';\n\nimport {\n BalancesTracker,\n BALANCE_UPDATE_INTERVALS,\n NETWORK_ASSETS_MAP,\n} from '.';\nimport { getScopeForAccount } from './utils';\n\nconst controllerName = 'MultichainBalancesController';\n\n/**\n * State used by the {@link MultichainBalancesController} to cache account balances.\n */\nexport type MultichainBalancesControllerState = {\n balances: {\n [account: string]: {\n [asset: string]: {\n amount: string;\n unit: string;\n };\n };\n };\n};\n\n/**\n * Default state of the {@link MultichainBalancesController}.\n */\nexport const defaultState: MultichainBalancesControllerState = { balances: {} };\n\n/**\n * Returns the state of the {@link MultichainBalancesController}.\n */\nexport type MultichainBalancesControllerGetStateAction =\n ControllerGetStateAction<\n typeof controllerName,\n MultichainBalancesControllerState\n >;\n\n/**\n * Updates the balances of all supported accounts.\n */\nexport type MultichainBalancesControllerUpdateBalancesAction = {\n type: `${typeof controllerName}:updateBalances`;\n handler: MultichainBalancesController['updateBalances'];\n};\n\n/**\n * Event emitted when the state of the {@link MultichainBalancesController} changes.\n */\nexport type MultichainBalancesControllerStateChange =\n ControllerStateChangeEvent<\n typeof controllerName,\n MultichainBalancesControllerState\n >;\n\n/**\n * Actions exposed by the {@link MultichainBalancesController}.\n */\nexport type MultichainBalancesControllerActions =\n | MultichainBalancesControllerGetStateAction\n | MultichainBalancesControllerUpdateBalancesAction;\n\n/**\n * Events emitted by {@link MultichainBalancesController}.\n */\nexport type MultichainBalancesControllerEvents =\n MultichainBalancesControllerStateChange;\n\n/**\n * Actions that this controller is allowed to call.\n */\nexport type AllowedActions =\n | HandleSnapRequest\n | AccountsControllerListMultichainAccountsAction;\n\n/**\n * Events that this controller is allowed to subscribe.\n */\nexport type AllowedEvents =\n | AccountsControllerAccountAddedEvent\n | AccountsControllerAccountRemovedEvent;\n\n/**\n * Messenger type for the MultichainBalancesController.\n */\nexport type MultichainBalancesControllerMessenger =\n RestrictedControllerMessenger<\n typeof controllerName,\n MultichainBalancesControllerActions | AllowedActions,\n MultichainBalancesControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n >;\n\n/**\n * {@link MultichainBalancesController}'s metadata.\n *\n * This allows us to choose if fields of the state should be persisted or not\n * using the `persist` flag; and if they can be sent to Sentry or not, using\n * the `anonymous` flag.\n */\nconst balancesControllerMetadata = {\n balances: {\n persist: true,\n anonymous: false,\n },\n};\n\nconst BTC_AVG_BLOCK_TIME = 10 * 60 * 1000; // 10 minutes in milliseconds\nconst SOLANA_AVG_BLOCK_TIME = 400; // 400 milliseconds\n\n// NOTE: We set an interval of half the average block time to mitigate when our interval\n// is de-synchronized with the actual block time.\nexport const BTC_BALANCES_UPDATE_TIME = BTC_AVG_BLOCK_TIME / 2;\n\nconst BALANCE_CHECK_INTERVALS = {\n [BtcAccountType.P2wpkh]: BTC_BALANCES_UPDATE_TIME,\n [SolAccountType.DataAccount]: SOLANA_AVG_BLOCK_TIME,\n};\n\n/**\n * The MultichainBalancesController is responsible for fetching and caching account\n * balances.\n */\nexport class MultichainBalancesController extends BaseController<\n typeof controllerName,\n MultichainBalancesControllerState,\n MultichainBalancesControllerMessenger\n> {\n #tracker: BalancesTracker;\n\n constructor({\n messenger,\n state,\n }: {\n messenger: MultichainBalancesControllerMessenger;\n state: MultichainBalancesControllerState;\n }) {\n super({\n messenger,\n name: controllerName,\n metadata: balancesControllerMetadata,\n state: {\n ...defaultState,\n ...state,\n },\n });\n\n this.#tracker = new BalancesTracker(\n async (accountId: string) => await this.#updateBalance(accountId),\n );\n\n // Register all non-EVM accounts into the tracker\n for (const account of this.#listAccounts()) {\n if (this.#isNonEvmAccount(account)) {\n this.#tracker.track(account.id, this.#getBlockTimeFor(account));\n }\n }\n\n this.messagingSystem.subscribe(\n 'AccountsController:accountAdded',\n (account) => this.#handleOnAccountAdded(account),\n );\n this.messagingSystem.subscribe(\n 'AccountsController:accountRemoved',\n (account) => this.#handleOnAccountRemoved(account),\n );\n }\n\n /**\n * Starts the polling process.\n */\n start(): void {\n this.#tracker.start();\n }\n\n /**\n * Stops the polling process.\n */\n stop(): void {\n this.#tracker.stop();\n }\n\n /**\n * Gets the block time for a given account.\n *\n * @param account - The account to get the block time for.\n * @returns The block time for the account.\n */\n #getBlockTimeFor(account: InternalAccount): number {\n if (account.type in BALANCE_CHECK_INTERVALS) {\n return BALANCE_UPDATE_INTERVALS[\n account.type as keyof typeof BALANCE_UPDATE_INTERVALS\n ];\n }\n throw new Error(\n `Unsupported account type for balance tracking: ${account.type}`,\n );\n }\n\n /**\n * Lists the multichain accounts coming from the `AccountsController`.\n *\n * @returns A list of multichain accounts.\n */\n #listMultichainAccounts(): InternalAccount[] {\n return this.messagingSystem.call(\n 'AccountsController:listMultichainAccounts',\n );\n }\n\n /**\n * Lists the accounts that we should get balances for.\n *\n * @returns A list of accounts that we should get balances for.\n */\n #listAccounts(): InternalAccount[] {\n const accounts = this.#listMultichainAccounts();\n\n return accounts.filter(\n (account) =>\n account.type === SolAccountType.DataAccount ||\n account.type === BtcAccountType.P2wpkh,\n );\n }\n\n /**\n * Get a non-EVM account from its ID.\n *\n * @param accountId - The account ID.\n * @returns The non-EVM account.\n */\n #getAccount(accountId: string): InternalAccount {\n const account: InternalAccount | undefined =\n this.#listMultichainAccounts().find(\n (multichainAccount) => multichainAccount.id === accountId,\n );\n\n if (!account) {\n throw new Error(`Unknown account: ${accountId}`);\n }\n if (!this.#isNonEvmAccount(account)) {\n throw new Error(`Account is not a non-EVM account: ${accountId}`);\n }\n return account;\n }\n\n /**\n * Updates the balances of one account. This method doesn't return\n * anything, but it updates the state of the controller.\n *\n * @param accountId - The account ID.\n */\n async #updateBalance(accountId: string) {\n const account = this.#getAccount(accountId);\n const partialState: MultichainBalancesControllerState = { balances: {} };\n\n if (account.metadata.snap) {\n const scope = getScopeForAccount(account);\n const assetTypes = NETWORK_ASSETS_MAP[scope];\n\n partialState.balances[account.id] = await this.#getBalances(\n account.id,\n account.metadata.snap.id,\n assetTypes,\n );\n }\n\n this.update((state: Draft<MultichainBalancesControllerState>) => {\n state.balances = {\n ...state.balances,\n ...partialState.balances,\n };\n });\n }\n\n /**\n * Updates the balances of one account. This method doesn't return\n * anything, but it updates the state of the controller.\n *\n * @param accountId - The account ID.\n */\n async updateBalance(accountId: string) {\n // NOTE: No need to track the account here, since we start tracking those when\n // the \"AccountsController:accountAdded\" is fired.\n await this.#tracker.updateBalance(accountId);\n }\n\n /**\n * Updates the balances of all supported accounts. This method doesn't return\n * anything, but it updates the state of the controller.\n */\n async updateBalances() {\n await this.#tracker.updateBalances();\n }\n\n /**\n * Checks for non-EVM accounts.\n *\n * @param account - The new account to be checked.\n * @returns True if the account is a non-EVM account, false otherwise.\n */\n #isNonEvmAccount(account: InternalAccount): boolean {\n return (\n !isEvmAccountType(account.type) &&\n // Non-EVM accounts are backed by a Snap for now\n account.metadata.snap !== undefined\n );\n }\n\n /**\n * Handles changes when a new account has been added.\n *\n * @param account - The new account being added.\n */\n async #handleOnAccountAdded(account: InternalAccount) {\n if (!this.#isNonEvmAccount(account)) {\n // Nothing to do here for EVM accounts\n return;\n }\n\n this.#tracker.track(account.id, this.#getBlockTimeFor(account));\n // NOTE: Unfortunately, we cannot update the balance right away here, because\n // messenger's events are running synchronously and fetching the balance is\n // asynchronous.\n // Updating the balance here would resume at some point but the event emitter\n // will not `await` this (so we have no real control \"when\" the balance will\n // really be updated), see:\n // - https://github.com/MetaMask/core/blob/v213.0.0/packages/accounts-controller/src/AccountsController.ts#L1036-L1039\n }\n\n /**\n * Handles changes when a new account has been removed.\n *\n * @param accountId - The account ID being removed.\n */\n async #handleOnAccountRemoved(accountId: string) {\n if (this.#tracker.isTracked(accountId)) {\n this.#tracker.untrack(accountId);\n }\n\n if (accountId in this.state.balances) {\n this.update((state: Draft<MultichainBalancesControllerState>) => {\n delete state.balances[accountId];\n return state;\n });\n }\n }\n\n /**\n * Get the balances for an account.\n *\n * @param accountId - ID of the account to get balances for.\n * @param snapId - ID of the Snap which manages the account.\n * @param assetTypes - Array of asset types to get balances for.\n * @returns A map of asset types to balances.\n */\n async #getBalances(\n accountId: string,\n snapId: string,\n assetTypes: CaipAssetType[],\n ): Promise<Record<CaipAssetType, Balance>> {\n return await this.#getClient(snapId).getAccountBalances(\n accountId,\n assetTypes,\n );\n }\n\n /**\n * Gets a `KeyringClient` for a Snap.\n *\n * @param snapId - ID of the Snap to get the client for.\n * @returns A `KeyringClient` for the Snap.\n */\n #getClient(snapId: string): KeyringClient {\n return new KeyringClient({\n send: async (request: JsonRpcRequest) =>\n (await this.messagingSystem.call('SnapController:handleRequest', {\n snapId: snapId as SnapId,\n origin: 'metamask',\n handler: HandlerType.OnKeyringRequest,\n request,\n })) as Promise<Json>,\n });\n }\n}\n"]}
|
|
@@ -1,15 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.NETWORK_ASSETS_MAP = exports.
|
|
3
|
+
exports.NETWORK_ASSETS_MAP = exports.BALANCE_UPDATE_INTERVALS = exports.MultichainNativeAssets = exports.MultichainNetworks = void 0;
|
|
4
4
|
const keyring_api_1 = require("@metamask/keyring-api");
|
|
5
|
-
const BTC_AVG_BLOCK_TIME = 10 * 60 * 1000; // 10 minutes in milliseconds
|
|
6
|
-
const SOLANA_AVG_BLOCK_TIME = 400; // 400 milliseconds
|
|
7
|
-
exports.BALANCE_UPDATE_INTERVALS = {
|
|
8
|
-
// NOTE: We set an interval of half the average block time fot bitcoin
|
|
9
|
-
// to mitigate when our interval is de-synchronized with the actual block time.
|
|
10
|
-
[keyring_api_1.BtcAccountType.P2wpkh]: BTC_AVG_BLOCK_TIME / 2,
|
|
11
|
-
[keyring_api_1.SolAccountType.DataAccount]: SOLANA_AVG_BLOCK_TIME,
|
|
12
|
-
};
|
|
13
5
|
/**
|
|
14
6
|
* The network identifiers for supported networks in CAIP-2 format.
|
|
15
7
|
* Note: This is a temporary workaround until we have a more robust
|
|
@@ -31,6 +23,14 @@ var MultichainNativeAssets;
|
|
|
31
23
|
MultichainNativeAssets["SolanaDevnet"] = "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1/slip44:501";
|
|
32
24
|
MultichainNativeAssets["SolanaTestnet"] = "solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z/slip44:501";
|
|
33
25
|
})(MultichainNativeAssets || (exports.MultichainNativeAssets = MultichainNativeAssets = {}));
|
|
26
|
+
const BTC_AVG_BLOCK_TIME = 10 * 60 * 1000; // 10 minutes in milliseconds
|
|
27
|
+
const SOLANA_AVG_BLOCK_TIME = 400; // 400 milliseconds
|
|
28
|
+
exports.BALANCE_UPDATE_INTERVALS = {
|
|
29
|
+
// NOTE: We set an interval of half the average block time fot bitcoin
|
|
30
|
+
// to mitigate when our interval is de-synchronized with the actual block time.
|
|
31
|
+
[keyring_api_1.BtcAccountType.P2wpkh]: BTC_AVG_BLOCK_TIME / 2,
|
|
32
|
+
[keyring_api_1.SolAccountType.DataAccount]: SOLANA_AVG_BLOCK_TIME,
|
|
33
|
+
};
|
|
34
34
|
/**
|
|
35
35
|
* Maps network identifiers to their corresponding native asset types.
|
|
36
36
|
* Each network is mapped to an array containing its native asset for consistency.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.cjs","sourceRoot":"","sources":["../../src/MultichainBalancesController/constants.ts"],"names":[],"mappings":";;;AAAA,uDAAuE;AAEvE
|
|
1
|
+
{"version":3,"file":"constants.cjs","sourceRoot":"","sources":["../../src/MultichainBalancesController/constants.ts"],"names":[],"mappings":";;;AAAA,uDAAuE;AAEvE;;;;GAIG;AACH,IAAY,kBAMX;AAND,WAAY,kBAAkB;IAC5B,yEAAmD,CAAA;IACnD,gFAA0D,CAAA;IAC1D,wEAAkD,CAAA;IAClD,8EAAwD,CAAA;IACxD,+EAAyD,CAAA;AAC3D,CAAC,EANW,kBAAkB,kCAAlB,kBAAkB,QAM7B;AAED,IAAY,sBAMX;AAND,WAAY,sBAAsB;IAChC,sFAAkD,CAAA;IAClD,6FAAgE,CAAA;IAChE,uFAAkD,CAAA;IAClD,6FAA8D,CAAA;IAC9D,8FAAgE,CAAA;AAClE,CAAC,EANW,sBAAsB,sCAAtB,sBAAsB,QAMjC;AAED,MAAM,kBAAkB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,6BAA6B;AACxE,MAAM,qBAAqB,GAAG,GAAG,CAAC,CAAC,mBAAmB;AAEzC,QAAA,wBAAwB,GAAG;IACtC,sEAAsE;IACtE,+EAA+E;IAC/E,CAAC,4BAAc,CAAC,MAAM,CAAC,EAAE,kBAAkB,GAAG,CAAC;IAC/C,CAAC,4BAAc,CAAC,WAAW,CAAC,EAAE,qBAAqB;CACpD,CAAC;AAEF;;;GAGG;AACU,QAAA,kBAAkB,GAA6C;IAC1E,CAAC,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAC,sBAAsB,CAAC,MAAM,CAAC;IAC5D,CAAC,kBAAkB,CAAC,aAAa,CAAC,EAAE,CAAC,sBAAsB,CAAC,aAAa,CAAC;IAC1E,CAAC,kBAAkB,CAAC,YAAY,CAAC,EAAE,CAAC,sBAAsB,CAAC,YAAY,CAAC;IACxE,CAAC,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAAC,sBAAsB,CAAC,OAAO,CAAC;IAC9D,CAAC,kBAAkB,CAAC,cAAc,CAAC,EAAE,CAAC,sBAAsB,CAAC,cAAc,CAAC;CAC7E,CAAC","sourcesContent":["import { BtcAccountType, SolAccountType } from '@metamask/keyring-api';\n\n/**\n * The network identifiers for supported networks in CAIP-2 format.\n * Note: This is a temporary workaround until we have a more robust\n * solution for network identifiers.\n */\nexport enum MultichainNetworks {\n Bitcoin = 'bip122:000000000019d6689c085ae165831e93',\n BitcoinTestnet = 'bip122:000000000933ea01ad0ee984209779ba',\n Solana = 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp',\n SolanaDevnet = 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1',\n SolanaTestnet = 'solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z',\n}\n\nexport enum MultichainNativeAssets {\n Bitcoin = `${MultichainNetworks.Bitcoin}/slip44:0`,\n BitcoinTestnet = `${MultichainNetworks.BitcoinTestnet}/slip44:0`,\n Solana = `${MultichainNetworks.Solana}/slip44:501`,\n SolanaDevnet = `${MultichainNetworks.SolanaDevnet}/slip44:501`,\n SolanaTestnet = `${MultichainNetworks.SolanaTestnet}/slip44:501`,\n}\n\nconst BTC_AVG_BLOCK_TIME = 10 * 60 * 1000; // 10 minutes in milliseconds\nconst SOLANA_AVG_BLOCK_TIME = 400; // 400 milliseconds\n\nexport const BALANCE_UPDATE_INTERVALS = {\n // NOTE: We set an interval of half the average block time fot bitcoin\n // to mitigate when our interval is de-synchronized with the actual block time.\n [BtcAccountType.P2wpkh]: BTC_AVG_BLOCK_TIME / 2,\n [SolAccountType.DataAccount]: SOLANA_AVG_BLOCK_TIME,\n};\n\n/**\n * Maps network identifiers to their corresponding native asset types.\n * Each network is mapped to an array containing its native asset for consistency.\n */\nexport const NETWORK_ASSETS_MAP: Record<string, MultichainNativeAssets[]> = {\n [MultichainNetworks.Solana]: [MultichainNativeAssets.Solana],\n [MultichainNetworks.SolanaTestnet]: [MultichainNativeAssets.SolanaTestnet],\n [MultichainNetworks.SolanaDevnet]: [MultichainNativeAssets.SolanaDevnet],\n [MultichainNetworks.Bitcoin]: [MultichainNativeAssets.Bitcoin],\n [MultichainNetworks.BitcoinTestnet]: [MultichainNativeAssets.BitcoinTestnet],\n};\n"]}
|
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
export declare const BALANCE_UPDATE_INTERVALS: {
|
|
2
|
-
"bip122:p2wpkh": number;
|
|
3
|
-
"solana:data-account": number;
|
|
4
|
-
};
|
|
5
1
|
/**
|
|
6
2
|
* The network identifiers for supported networks in CAIP-2 format.
|
|
7
3
|
* Note: This is a temporary workaround until we have a more robust
|
|
@@ -21,6 +17,10 @@ export declare enum MultichainNativeAssets {
|
|
|
21
17
|
SolanaDevnet = "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1/slip44:501",
|
|
22
18
|
SolanaTestnet = "solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z/slip44:501"
|
|
23
19
|
}
|
|
20
|
+
export declare const BALANCE_UPDATE_INTERVALS: {
|
|
21
|
+
"bip122:p2wpkh": number;
|
|
22
|
+
"solana:data-account": number;
|
|
23
|
+
};
|
|
24
24
|
/**
|
|
25
25
|
* Maps network identifiers to their corresponding native asset types.
|
|
26
26
|
* Each network is mapped to an array containing its native asset for consistency.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.cts","sourceRoot":"","sources":["../../src/MultichainBalancesController/constants.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"constants.d.cts","sourceRoot":"","sources":["../../src/MultichainBalancesController/constants.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,oBAAY,kBAAkB;IAC5B,OAAO,4CAA4C;IACnD,cAAc,4CAA4C;IAC1D,MAAM,4CAA4C;IAClD,YAAY,4CAA4C;IACxD,aAAa,4CAA4C;CAC1D;AAED,oBAAY,sBAAsB;IAChC,OAAO,qDAA2C;IAClD,cAAc,qDAAkD;IAChE,MAAM,uDAA4C;IAClD,YAAY,uDAAkD;IAC9D,aAAa,uDAAmD;CACjE;AAKD,eAAO,MAAM,wBAAwB;;;CAKpC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,sBAAsB,EAAE,CAMvE,CAAC"}
|
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
export declare const BALANCE_UPDATE_INTERVALS: {
|
|
2
|
-
"bip122:p2wpkh": number;
|
|
3
|
-
"solana:data-account": number;
|
|
4
|
-
};
|
|
5
1
|
/**
|
|
6
2
|
* The network identifiers for supported networks in CAIP-2 format.
|
|
7
3
|
* Note: This is a temporary workaround until we have a more robust
|
|
@@ -21,6 +17,10 @@ export declare enum MultichainNativeAssets {
|
|
|
21
17
|
SolanaDevnet = "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1/slip44:501",
|
|
22
18
|
SolanaTestnet = "solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z/slip44:501"
|
|
23
19
|
}
|
|
20
|
+
export declare const BALANCE_UPDATE_INTERVALS: {
|
|
21
|
+
"bip122:p2wpkh": number;
|
|
22
|
+
"solana:data-account": number;
|
|
23
|
+
};
|
|
24
24
|
/**
|
|
25
25
|
* Maps network identifiers to their corresponding native asset types.
|
|
26
26
|
* Each network is mapped to an array containing its native asset for consistency.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.mts","sourceRoot":"","sources":["../../src/MultichainBalancesController/constants.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"constants.d.mts","sourceRoot":"","sources":["../../src/MultichainBalancesController/constants.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,oBAAY,kBAAkB;IAC5B,OAAO,4CAA4C;IACnD,cAAc,4CAA4C;IAC1D,MAAM,4CAA4C;IAClD,YAAY,4CAA4C;IACxD,aAAa,4CAA4C;CAC1D;AAED,oBAAY,sBAAsB;IAChC,OAAO,qDAA2C;IAClD,cAAc,qDAAkD;IAChE,MAAM,uDAA4C;IAClD,YAAY,uDAAkD;IAC9D,aAAa,uDAAmD;CACjE;AAKD,eAAO,MAAM,wBAAwB;;;CAKpC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,sBAAsB,EAAE,CAMvE,CAAC"}
|
|
@@ -1,13 +1,5 @@
|
|
|
1
1
|
import $metamaskkeyringapi from "@metamask/keyring-api";
|
|
2
2
|
const { BtcAccountType, SolAccountType } = $metamaskkeyringapi;
|
|
3
|
-
const BTC_AVG_BLOCK_TIME = 10 * 60 * 1000; // 10 minutes in milliseconds
|
|
4
|
-
const SOLANA_AVG_BLOCK_TIME = 400; // 400 milliseconds
|
|
5
|
-
export const BALANCE_UPDATE_INTERVALS = {
|
|
6
|
-
// NOTE: We set an interval of half the average block time fot bitcoin
|
|
7
|
-
// to mitigate when our interval is de-synchronized with the actual block time.
|
|
8
|
-
[BtcAccountType.P2wpkh]: BTC_AVG_BLOCK_TIME / 2,
|
|
9
|
-
[SolAccountType.DataAccount]: SOLANA_AVG_BLOCK_TIME,
|
|
10
|
-
};
|
|
11
3
|
/**
|
|
12
4
|
* The network identifiers for supported networks in CAIP-2 format.
|
|
13
5
|
* Note: This is a temporary workaround until we have a more robust
|
|
@@ -29,6 +21,14 @@ export var MultichainNativeAssets;
|
|
|
29
21
|
MultichainNativeAssets["SolanaDevnet"] = "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1/slip44:501";
|
|
30
22
|
MultichainNativeAssets["SolanaTestnet"] = "solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z/slip44:501";
|
|
31
23
|
})(MultichainNativeAssets || (MultichainNativeAssets = {}));
|
|
24
|
+
const BTC_AVG_BLOCK_TIME = 10 * 60 * 1000; // 10 minutes in milliseconds
|
|
25
|
+
const SOLANA_AVG_BLOCK_TIME = 400; // 400 milliseconds
|
|
26
|
+
export const BALANCE_UPDATE_INTERVALS = {
|
|
27
|
+
// NOTE: We set an interval of half the average block time fot bitcoin
|
|
28
|
+
// to mitigate when our interval is de-synchronized with the actual block time.
|
|
29
|
+
[BtcAccountType.P2wpkh]: BTC_AVG_BLOCK_TIME / 2,
|
|
30
|
+
[SolAccountType.DataAccount]: SOLANA_AVG_BLOCK_TIME,
|
|
31
|
+
};
|
|
32
32
|
/**
|
|
33
33
|
* Maps network identifiers to their corresponding native asset types.
|
|
34
34
|
* Each network is mapped to an array containing its native asset for consistency.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.mjs","sourceRoot":"","sources":["../../src/MultichainBalancesController/constants.ts"],"names":[],"mappings":";;AAEA
|
|
1
|
+
{"version":3,"file":"constants.mjs","sourceRoot":"","sources":["../../src/MultichainBalancesController/constants.ts"],"names":[],"mappings":";;AAEA;;;;GAIG;AACH,MAAM,CAAN,IAAY,kBAMX;AAND,WAAY,kBAAkB;IAC5B,yEAAmD,CAAA;IACnD,gFAA0D,CAAA;IAC1D,wEAAkD,CAAA;IAClD,8EAAwD,CAAA;IACxD,+EAAyD,CAAA;AAC3D,CAAC,EANW,kBAAkB,KAAlB,kBAAkB,QAM7B;AAED,MAAM,CAAN,IAAY,sBAMX;AAND,WAAY,sBAAsB;IAChC,sFAAkD,CAAA;IAClD,6FAAgE,CAAA;IAChE,uFAAkD,CAAA;IAClD,6FAA8D,CAAA;IAC9D,8FAAgE,CAAA;AAClE,CAAC,EANW,sBAAsB,KAAtB,sBAAsB,QAMjC;AAED,MAAM,kBAAkB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,6BAA6B;AACxE,MAAM,qBAAqB,GAAG,GAAG,CAAC,CAAC,mBAAmB;AAEtD,MAAM,CAAC,MAAM,wBAAwB,GAAG;IACtC,sEAAsE;IACtE,+EAA+E;IAC/E,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,kBAAkB,GAAG,CAAC;IAC/C,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,qBAAqB;CACpD,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAA6C;IAC1E,CAAC,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAC,sBAAsB,CAAC,MAAM,CAAC;IAC5D,CAAC,kBAAkB,CAAC,aAAa,CAAC,EAAE,CAAC,sBAAsB,CAAC,aAAa,CAAC;IAC1E,CAAC,kBAAkB,CAAC,YAAY,CAAC,EAAE,CAAC,sBAAsB,CAAC,YAAY,CAAC;IACxE,CAAC,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAAC,sBAAsB,CAAC,OAAO,CAAC;IAC9D,CAAC,kBAAkB,CAAC,cAAc,CAAC,EAAE,CAAC,sBAAsB,CAAC,cAAc,CAAC;CAC7E,CAAC","sourcesContent":["import { BtcAccountType, SolAccountType } from '@metamask/keyring-api';\n\n/**\n * The network identifiers for supported networks in CAIP-2 format.\n * Note: This is a temporary workaround until we have a more robust\n * solution for network identifiers.\n */\nexport enum MultichainNetworks {\n Bitcoin = 'bip122:000000000019d6689c085ae165831e93',\n BitcoinTestnet = 'bip122:000000000933ea01ad0ee984209779ba',\n Solana = 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp',\n SolanaDevnet = 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1',\n SolanaTestnet = 'solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z',\n}\n\nexport enum MultichainNativeAssets {\n Bitcoin = `${MultichainNetworks.Bitcoin}/slip44:0`,\n BitcoinTestnet = `${MultichainNetworks.BitcoinTestnet}/slip44:0`,\n Solana = `${MultichainNetworks.Solana}/slip44:501`,\n SolanaDevnet = `${MultichainNetworks.SolanaDevnet}/slip44:501`,\n SolanaTestnet = `${MultichainNetworks.SolanaTestnet}/slip44:501`,\n}\n\nconst BTC_AVG_BLOCK_TIME = 10 * 60 * 1000; // 10 minutes in milliseconds\nconst SOLANA_AVG_BLOCK_TIME = 400; // 400 milliseconds\n\nexport const BALANCE_UPDATE_INTERVALS = {\n // NOTE: We set an interval of half the average block time fot bitcoin\n // to mitigate when our interval is de-synchronized with the actual block time.\n [BtcAccountType.P2wpkh]: BTC_AVG_BLOCK_TIME / 2,\n [SolAccountType.DataAccount]: SOLANA_AVG_BLOCK_TIME,\n};\n\n/**\n * Maps network identifiers to their corresponding native asset types.\n * Each network is mapped to an array containing its native asset for consistency.\n */\nexport const NETWORK_ASSETS_MAP: Record<string, MultichainNativeAssets[]> = {\n [MultichainNetworks.Solana]: [MultichainNativeAssets.Solana],\n [MultichainNetworks.SolanaTestnet]: [MultichainNativeAssets.SolanaTestnet],\n [MultichainNetworks.SolanaDevnet]: [MultichainNativeAssets.SolanaDevnet],\n [MultichainNetworks.Bitcoin]: [MultichainNativeAssets.Bitcoin],\n [MultichainNetworks.BitcoinTestnet]: [MultichainNativeAssets.BitcoinTestnet],\n};\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.getScopeForAccount = exports.getScopeForSolAddress = exports.getScopeForBtcAddress = void 0;
|
|
4
4
|
const keyring_api_1 = require("@metamask/keyring-api");
|
|
5
5
|
const bitcoin_address_validation_1 = require("bitcoin-address-validation");
|
|
6
6
|
const constants_1 = require("./constants.cjs");
|
|
@@ -46,7 +46,7 @@ exports.getScopeForSolAddress = getScopeForSolAddress;
|
|
|
46
46
|
* @param account - The account to get the scope for.
|
|
47
47
|
* @returns The scope for the given account.
|
|
48
48
|
*/
|
|
49
|
-
const
|
|
49
|
+
const getScopeForAccount = (account) => {
|
|
50
50
|
switch (account.type) {
|
|
51
51
|
case keyring_api_1.BtcAccountType.P2wpkh:
|
|
52
52
|
return (0, exports.getScopeForBtcAddress)(account);
|
|
@@ -56,5 +56,5 @@ const getScopeForAddress = (account) => {
|
|
|
56
56
|
throw new Error(`Unsupported non-EVM account type: ${account.type}`);
|
|
57
57
|
}
|
|
58
58
|
};
|
|
59
|
-
exports.
|
|
59
|
+
exports.getScopeForAccount = getScopeForAccount;
|
|
60
60
|
//# sourceMappingURL=utils.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.cjs","sourceRoot":"","sources":["../../src/MultichainBalancesController/utils.ts"],"names":[],"mappings":";;;AACA,uDAAuE;AACvE,2EAA+D;AAE/D,+CAAiD;AAEjD;;;;;;;GAOG;AACI,MAAM,qBAAqB,GAAG,CAAC,OAAwB,EAAU,EAAE;IACxE,IAAI,IAAA,qCAAQ,EAAC,OAAO,CAAC,OAAO,EAAE,oCAAO,CAAC,OAAO,CAAC,EAAE;QAC9C,OAAO,8BAAkB,CAAC,OAAO,CAAC;KACnC;IAED,IAAI,IAAA,qCAAQ,EAAC,OAAO,CAAC,OAAO,EAAE,oCAAO,CAAC,OAAO,CAAC,EAAE;QAC9C,OAAO,8BAAkB,CAAC,cAAc,CAAC;KAC1C;IAED,MAAM,IAAI,KAAK,CAAC,4BAA4B,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;AACjE,CAAC,CAAC;AAVW,QAAA,qBAAqB,yBAUhC;AAEF;;;;;;;GAOG;AACI,MAAM,qBAAqB,GAAG,CAAC,OAAwB,EAAU,EAAE;IACxE,iFAAiF;IACjF,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE;QAC1B,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;KACtD;IACD,OAAO,OAAO,CAAC,OAAO,CAAC,KAAe,CAAC;AACzC,CAAC,CAAC;AANW,QAAA,qBAAqB,yBAMhC;AAEF;;;;;;;GAOG;AACI,MAAM,kBAAkB,GAAG,CAAC,OAAwB,EAAU,EAAE;IACrE,QAAQ,OAAO,CAAC,IAAI,EAAE;QACpB,KAAK,4BAAc,CAAC,MAAM;YACxB,OAAO,IAAA,6BAAqB,EAAC,OAAO,CAAC,CAAC;QACxC,KAAK,4BAAc,CAAC,WAAW;YAC7B,OAAO,IAAA,6BAAqB,EAAC,OAAO,CAAC,CAAC;QACxC;YACE,MAAM,IAAI,KAAK,CAAC,qCAAqC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;KACxE;AACH,CAAC,CAAC;AATW,QAAA,kBAAkB,sBAS7B","sourcesContent":["import type { InternalAccount } from '@metamask/keyring-api';\nimport { BtcAccountType, SolAccountType } from '@metamask/keyring-api';\nimport { validate, Network } from 'bitcoin-address-validation';\n\nimport { MultichainNetworks } from './constants';\n\n/**\n * Gets the scope for a specific and supported Bitcoin account.\n * Note: This is a temporary method and will be replaced by a more robust solution\n * once the new `account.scopes` is available in the `@metamask/keyring-api` module.\n *\n * @param account - Bitcoin account\n * @returns The scope for the given account.\n */\nexport const getScopeForBtcAddress = (account: InternalAccount): string => {\n if (validate(account.address, Network.mainnet)) {\n return MultichainNetworks.Bitcoin;\n }\n\n if (validate(account.address, Network.testnet)) {\n return MultichainNetworks.BitcoinTestnet;\n }\n\n throw new Error(`Invalid Bitcoin address: ${account.address}`);\n};\n\n/**\n * Gets the scope for a specific and supported Solana account.\n * Note: This is a temporary method and will be replaced by a more robust solution\n * once the new `account.scopes` is available in the `keyring-api`.\n *\n * @param account - Solana account\n * @returns The scope for the given account.\n */\nexport const getScopeForSolAddress = (account: InternalAccount): string => {\n // For Solana accounts, we know we have a `scope` on the account's `options` bag.\n if (!account.options.scope) {\n throw new Error('Solana account scope is undefined');\n }\n return account.options.scope as string;\n};\n\n/**\n * Get the scope for a given address.\n * Note: This is a temporary method and will be replaced by a more robust solution\n * once the new `account.scopes` is available in the `keyring-api`.\n *\n * @param account - The account to get the scope for.\n * @returns The scope for the given account.\n */\nexport const
|
|
1
|
+
{"version":3,"file":"utils.cjs","sourceRoot":"","sources":["../../src/MultichainBalancesController/utils.ts"],"names":[],"mappings":";;;AACA,uDAAuE;AACvE,2EAA+D;AAE/D,+CAAiD;AAEjD;;;;;;;GAOG;AACI,MAAM,qBAAqB,GAAG,CAAC,OAAwB,EAAU,EAAE;IACxE,IAAI,IAAA,qCAAQ,EAAC,OAAO,CAAC,OAAO,EAAE,oCAAO,CAAC,OAAO,CAAC,EAAE;QAC9C,OAAO,8BAAkB,CAAC,OAAO,CAAC;KACnC;IAED,IAAI,IAAA,qCAAQ,EAAC,OAAO,CAAC,OAAO,EAAE,oCAAO,CAAC,OAAO,CAAC,EAAE;QAC9C,OAAO,8BAAkB,CAAC,cAAc,CAAC;KAC1C;IAED,MAAM,IAAI,KAAK,CAAC,4BAA4B,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;AACjE,CAAC,CAAC;AAVW,QAAA,qBAAqB,yBAUhC;AAEF;;;;;;;GAOG;AACI,MAAM,qBAAqB,GAAG,CAAC,OAAwB,EAAU,EAAE;IACxE,iFAAiF;IACjF,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE;QAC1B,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;KACtD;IACD,OAAO,OAAO,CAAC,OAAO,CAAC,KAAe,CAAC;AACzC,CAAC,CAAC;AANW,QAAA,qBAAqB,yBAMhC;AAEF;;;;;;;GAOG;AACI,MAAM,kBAAkB,GAAG,CAAC,OAAwB,EAAU,EAAE;IACrE,QAAQ,OAAO,CAAC,IAAI,EAAE;QACpB,KAAK,4BAAc,CAAC,MAAM;YACxB,OAAO,IAAA,6BAAqB,EAAC,OAAO,CAAC,CAAC;QACxC,KAAK,4BAAc,CAAC,WAAW;YAC7B,OAAO,IAAA,6BAAqB,EAAC,OAAO,CAAC,CAAC;QACxC;YACE,MAAM,IAAI,KAAK,CAAC,qCAAqC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;KACxE;AACH,CAAC,CAAC;AATW,QAAA,kBAAkB,sBAS7B","sourcesContent":["import type { InternalAccount } from '@metamask/keyring-api';\nimport { BtcAccountType, SolAccountType } from '@metamask/keyring-api';\nimport { validate, Network } from 'bitcoin-address-validation';\n\nimport { MultichainNetworks } from './constants';\n\n/**\n * Gets the scope for a specific and supported Bitcoin account.\n * Note: This is a temporary method and will be replaced by a more robust solution\n * once the new `account.scopes` is available in the `@metamask/keyring-api` module.\n *\n * @param account - Bitcoin account\n * @returns The scope for the given account.\n */\nexport const getScopeForBtcAddress = (account: InternalAccount): string => {\n if (validate(account.address, Network.mainnet)) {\n return MultichainNetworks.Bitcoin;\n }\n\n if (validate(account.address, Network.testnet)) {\n return MultichainNetworks.BitcoinTestnet;\n }\n\n throw new Error(`Invalid Bitcoin address: ${account.address}`);\n};\n\n/**\n * Gets the scope for a specific and supported Solana account.\n * Note: This is a temporary method and will be replaced by a more robust solution\n * once the new `account.scopes` is available in the `keyring-api`.\n *\n * @param account - Solana account\n * @returns The scope for the given account.\n */\nexport const getScopeForSolAddress = (account: InternalAccount): string => {\n // For Solana accounts, we know we have a `scope` on the account's `options` bag.\n if (!account.options.scope) {\n throw new Error('Solana account scope is undefined');\n }\n return account.options.scope as string;\n};\n\n/**\n * Get the scope for a given address.\n * Note: This is a temporary method and will be replaced by a more robust solution\n * once the new `account.scopes` is available in the `keyring-api`.\n *\n * @param account - The account to get the scope for.\n * @returns The scope for the given account.\n */\nexport const getScopeForAccount = (account: InternalAccount): string => {\n switch (account.type) {\n case BtcAccountType.P2wpkh:\n return getScopeForBtcAddress(account);\n case SolAccountType.DataAccount:\n return getScopeForSolAddress(account);\n default:\n throw new Error(`Unsupported non-EVM account type: ${account.type}`);\n }\n};\n"]}
|
|
@@ -25,5 +25,5 @@ export declare const getScopeForSolAddress: (account: InternalAccount) => string
|
|
|
25
25
|
* @param account - The account to get the scope for.
|
|
26
26
|
* @returns The scope for the given account.
|
|
27
27
|
*/
|
|
28
|
-
export declare const
|
|
28
|
+
export declare const getScopeForAccount: (account: InternalAccount) => string;
|
|
29
29
|
//# sourceMappingURL=utils.d.cts.map
|
|
@@ -25,5 +25,5 @@ export declare const getScopeForSolAddress: (account: InternalAccount) => string
|
|
|
25
25
|
* @param account - The account to get the scope for.
|
|
26
26
|
* @returns The scope for the given account.
|
|
27
27
|
*/
|
|
28
|
-
export declare const
|
|
28
|
+
export declare const getScopeForAccount: (account: InternalAccount) => string;
|
|
29
29
|
//# sourceMappingURL=utils.d.mts.map
|
|
@@ -42,7 +42,7 @@ export const getScopeForSolAddress = (account) => {
|
|
|
42
42
|
* @param account - The account to get the scope for.
|
|
43
43
|
* @returns The scope for the given account.
|
|
44
44
|
*/
|
|
45
|
-
export const
|
|
45
|
+
export const getScopeForAccount = (account) => {
|
|
46
46
|
switch (account.type) {
|
|
47
47
|
case BtcAccountType.P2wpkh:
|
|
48
48
|
return getScopeForBtcAddress(account);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.mjs","sourceRoot":"","sources":["../../src/MultichainBalancesController/utils.ts"],"names":[],"mappings":";;AAEA,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,mCAAmC;AAE/D,OAAO,EAAE,kBAAkB,EAAE,wBAAoB;AAEjD;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,OAAwB,EAAU,EAAE;IACxE,IAAI,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE;QAC9C,OAAO,kBAAkB,CAAC,OAAO,CAAC;KACnC;IAED,IAAI,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE;QAC9C,OAAO,kBAAkB,CAAC,cAAc,CAAC;KAC1C;IAED,MAAM,IAAI,KAAK,CAAC,4BAA4B,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;AACjE,CAAC,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,OAAwB,EAAU,EAAE;IACxE,iFAAiF;IACjF,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE;QAC1B,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;KACtD;IACD,OAAO,OAAO,CAAC,OAAO,CAAC,KAAe,CAAC;AACzC,CAAC,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,OAAwB,EAAU,EAAE;IACrE,QAAQ,OAAO,CAAC,IAAI,EAAE;QACpB,KAAK,cAAc,CAAC,MAAM;YACxB,OAAO,qBAAqB,CAAC,OAAO,CAAC,CAAC;QACxC,KAAK,cAAc,CAAC,WAAW;YAC7B,OAAO,qBAAqB,CAAC,OAAO,CAAC,CAAC;QACxC;YACE,MAAM,IAAI,KAAK,CAAC,qCAAqC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;KACxE;AACH,CAAC,CAAC","sourcesContent":["import type { InternalAccount } from '@metamask/keyring-api';\nimport { BtcAccountType, SolAccountType } from '@metamask/keyring-api';\nimport { validate, Network } from 'bitcoin-address-validation';\n\nimport { MultichainNetworks } from './constants';\n\n/**\n * Gets the scope for a specific and supported Bitcoin account.\n * Note: This is a temporary method and will be replaced by a more robust solution\n * once the new `account.scopes` is available in the `@metamask/keyring-api` module.\n *\n * @param account - Bitcoin account\n * @returns The scope for the given account.\n */\nexport const getScopeForBtcAddress = (account: InternalAccount): string => {\n if (validate(account.address, Network.mainnet)) {\n return MultichainNetworks.Bitcoin;\n }\n\n if (validate(account.address, Network.testnet)) {\n return MultichainNetworks.BitcoinTestnet;\n }\n\n throw new Error(`Invalid Bitcoin address: ${account.address}`);\n};\n\n/**\n * Gets the scope for a specific and supported Solana account.\n * Note: This is a temporary method and will be replaced by a more robust solution\n * once the new `account.scopes` is available in the `keyring-api`.\n *\n * @param account - Solana account\n * @returns The scope for the given account.\n */\nexport const getScopeForSolAddress = (account: InternalAccount): string => {\n // For Solana accounts, we know we have a `scope` on the account's `options` bag.\n if (!account.options.scope) {\n throw new Error('Solana account scope is undefined');\n }\n return account.options.scope as string;\n};\n\n/**\n * Get the scope for a given address.\n * Note: This is a temporary method and will be replaced by a more robust solution\n * once the new `account.scopes` is available in the `keyring-api`.\n *\n * @param account - The account to get the scope for.\n * @returns The scope for the given account.\n */\nexport const
|
|
1
|
+
{"version":3,"file":"utils.mjs","sourceRoot":"","sources":["../../src/MultichainBalancesController/utils.ts"],"names":[],"mappings":";;AAEA,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,mCAAmC;AAE/D,OAAO,EAAE,kBAAkB,EAAE,wBAAoB;AAEjD;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,OAAwB,EAAU,EAAE;IACxE,IAAI,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE;QAC9C,OAAO,kBAAkB,CAAC,OAAO,CAAC;KACnC;IAED,IAAI,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE;QAC9C,OAAO,kBAAkB,CAAC,cAAc,CAAC;KAC1C;IAED,MAAM,IAAI,KAAK,CAAC,4BAA4B,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;AACjE,CAAC,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,OAAwB,EAAU,EAAE;IACxE,iFAAiF;IACjF,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE;QAC1B,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;KACtD;IACD,OAAO,OAAO,CAAC,OAAO,CAAC,KAAe,CAAC;AACzC,CAAC,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,OAAwB,EAAU,EAAE;IACrE,QAAQ,OAAO,CAAC,IAAI,EAAE;QACpB,KAAK,cAAc,CAAC,MAAM;YACxB,OAAO,qBAAqB,CAAC,OAAO,CAAC,CAAC;QACxC,KAAK,cAAc,CAAC,WAAW;YAC7B,OAAO,qBAAqB,CAAC,OAAO,CAAC,CAAC;QACxC;YACE,MAAM,IAAI,KAAK,CAAC,qCAAqC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;KACxE;AACH,CAAC,CAAC","sourcesContent":["import type { InternalAccount } from '@metamask/keyring-api';\nimport { BtcAccountType, SolAccountType } from '@metamask/keyring-api';\nimport { validate, Network } from 'bitcoin-address-validation';\n\nimport { MultichainNetworks } from './constants';\n\n/**\n * Gets the scope for a specific and supported Bitcoin account.\n * Note: This is a temporary method and will be replaced by a more robust solution\n * once the new `account.scopes` is available in the `@metamask/keyring-api` module.\n *\n * @param account - Bitcoin account\n * @returns The scope for the given account.\n */\nexport const getScopeForBtcAddress = (account: InternalAccount): string => {\n if (validate(account.address, Network.mainnet)) {\n return MultichainNetworks.Bitcoin;\n }\n\n if (validate(account.address, Network.testnet)) {\n return MultichainNetworks.BitcoinTestnet;\n }\n\n throw new Error(`Invalid Bitcoin address: ${account.address}`);\n};\n\n/**\n * Gets the scope for a specific and supported Solana account.\n * Note: This is a temporary method and will be replaced by a more robust solution\n * once the new `account.scopes` is available in the `keyring-api`.\n *\n * @param account - Solana account\n * @returns The scope for the given account.\n */\nexport const getScopeForSolAddress = (account: InternalAccount): string => {\n // For Solana accounts, we know we have a `scope` on the account's `options` bag.\n if (!account.options.scope) {\n throw new Error('Solana account scope is undefined');\n }\n return account.options.scope as string;\n};\n\n/**\n * Get the scope for a given address.\n * Note: This is a temporary method and will be replaced by a more robust solution\n * once the new `account.scopes` is available in the `keyring-api`.\n *\n * @param account - The account to get the scope for.\n * @returns The scope for the given account.\n */\nexport const getScopeForAccount = (account: InternalAccount): string => {\n switch (account.type) {\n case BtcAccountType.P2wpkh:\n return getScopeForBtcAddress(account);\n case SolAccountType.DataAccount:\n return getScopeForSolAddress(account);\n default:\n throw new Error(`Unsupported non-EVM account type: ${account.type}`);\n }\n};\n"]}
|
|
@@ -45,8 +45,8 @@ export type TokenBalancesPollingInput = {
|
|
|
45
45
|
chainId: Hex;
|
|
46
46
|
};
|
|
47
47
|
declare const TokenBalancesController_base: (abstract new (...args: any[]) => {
|
|
48
|
-
readonly "__#
|
|
49
|
-
"__#
|
|
48
|
+
readonly "__#13@#intervalIds": Record<string, NodeJS.Timeout>;
|
|
49
|
+
"__#13@#intervalLength": number | undefined;
|
|
50
50
|
setIntervalLength(intervalLength: number): void;
|
|
51
51
|
getIntervalLength(): number | undefined;
|
|
52
52
|
_startPolling(input: TokenBalancesPollingInput): void;
|
|
@@ -45,8 +45,8 @@ export type TokenBalancesPollingInput = {
|
|
|
45
45
|
chainId: Hex;
|
|
46
46
|
};
|
|
47
47
|
declare const TokenBalancesController_base: (abstract new (...args: any[]) => {
|
|
48
|
-
readonly "__#
|
|
49
|
-
"__#
|
|
48
|
+
readonly "__#13@#intervalIds": Record<string, NodeJS.Timeout>;
|
|
49
|
+
"__#13@#intervalLength": number | undefined;
|
|
50
50
|
setIntervalLength(intervalLength: number): void;
|
|
51
51
|
getIntervalLength(): number | undefined;
|
|
52
52
|
_startPolling(input: TokenBalancesPollingInput): void;
|
|
@@ -34,8 +34,8 @@ type TokenDetectionPollingInput = {
|
|
|
34
34
|
address: string;
|
|
35
35
|
};
|
|
36
36
|
declare const TokenDetectionController_base: (abstract new (...args: any[]) => {
|
|
37
|
-
readonly "__#
|
|
38
|
-
"__#
|
|
37
|
+
readonly "__#13@#intervalIds": Record<string, NodeJS.Timeout>;
|
|
38
|
+
"__#13@#intervalLength": number | undefined;
|
|
39
39
|
setIntervalLength(intervalLength: number): void;
|
|
40
40
|
getIntervalLength(): number | undefined;
|
|
41
41
|
_startPolling(input: TokenDetectionPollingInput): void;
|
|
@@ -34,8 +34,8 @@ type TokenDetectionPollingInput = {
|
|
|
34
34
|
address: string;
|
|
35
35
|
};
|
|
36
36
|
declare const TokenDetectionController_base: (abstract new (...args: any[]) => {
|
|
37
|
-
readonly "__#
|
|
38
|
-
"__#
|
|
37
|
+
readonly "__#13@#intervalIds": Record<string, NodeJS.Timeout>;
|
|
38
|
+
"__#13@#intervalLength": number | undefined;
|
|
39
39
|
setIntervalLength(intervalLength: number): void;
|
|
40
40
|
getIntervalLength(): number | undefined;
|
|
41
41
|
_startPolling(input: TokenDetectionPollingInput): void;
|
|
@@ -37,8 +37,8 @@ type TokenListPollingInput = {
|
|
|
37
37
|
chainId: Hex;
|
|
38
38
|
};
|
|
39
39
|
declare const TokenListController_base: (abstract new (...args: any[]) => {
|
|
40
|
-
readonly "__#
|
|
41
|
-
"__#
|
|
40
|
+
readonly "__#13@#intervalIds": Record<string, NodeJS.Timeout>;
|
|
41
|
+
"__#13@#intervalLength": number | undefined;
|
|
42
42
|
setIntervalLength(intervalLength: number): void;
|
|
43
43
|
getIntervalLength(): number | undefined;
|
|
44
44
|
_startPolling(input: TokenListPollingInput): void;
|
|
@@ -37,8 +37,8 @@ type TokenListPollingInput = {
|
|
|
37
37
|
chainId: Hex;
|
|
38
38
|
};
|
|
39
39
|
declare const TokenListController_base: (abstract new (...args: any[]) => {
|
|
40
|
-
readonly "__#
|
|
41
|
-
"__#
|
|
40
|
+
readonly "__#13@#intervalIds": Record<string, NodeJS.Timeout>;
|
|
41
|
+
"__#13@#intervalLength": number | undefined;
|
|
42
42
|
setIntervalLength(intervalLength: number): void;
|
|
43
43
|
getIntervalLength(): number | undefined;
|
|
44
44
|
_startPolling(input: TokenListPollingInput): void;
|
|
@@ -108,8 +108,8 @@ export type TokenRatesPollingInput = {
|
|
|
108
108
|
chainId: Hex;
|
|
109
109
|
};
|
|
110
110
|
declare const TokenRatesController_base: (abstract new (...args: any[]) => {
|
|
111
|
-
readonly "__#
|
|
112
|
-
"__#
|
|
111
|
+
readonly "__#13@#intervalIds": Record<string, NodeJS.Timeout>;
|
|
112
|
+
"__#13@#intervalLength": number | undefined;
|
|
113
113
|
setIntervalLength(intervalLength: number): void;
|
|
114
114
|
getIntervalLength(): number | undefined;
|
|
115
115
|
_startPolling(input: TokenRatesPollingInput): void;
|
|
@@ -108,8 +108,8 @@ export type TokenRatesPollingInput = {
|
|
|
108
108
|
chainId: Hex;
|
|
109
109
|
};
|
|
110
110
|
declare const TokenRatesController_base: (abstract new (...args: any[]) => {
|
|
111
|
-
readonly "__#
|
|
112
|
-
"__#
|
|
111
|
+
readonly "__#13@#intervalIds": Record<string, NodeJS.Timeout>;
|
|
112
|
+
"__#13@#intervalLength": number | undefined;
|
|
113
113
|
setIntervalLength(intervalLength: number): void;
|
|
114
114
|
getIntervalLength(): number | undefined;
|
|
115
115
|
_startPolling(input: TokenRatesPollingInput): void;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@metamask-previews/assets-controllers",
|
|
3
|
-
"version": "45.1.1-preview-
|
|
3
|
+
"version": "45.1.1-preview-9e677163",
|
|
4
4
|
"description": "Controllers which manage interactions involving ERC-20, ERC-721, and ERC-1155 tokens (including NFTs)",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"MetaMask",
|