Skip to content

Commit fc1d5c0

Browse files
committed
feat: add support for accountChanged for Tron network
1 parent 7e037dc commit fc1d5c0

File tree

3 files changed

+379
-3
lines changed

3 files changed

+379
-3
lines changed

app/scripts/metamask-controller.js

Lines changed: 214 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1638,8 +1638,9 @@ export default class MetamaskController extends EventEmitter {
16381638
setupControllerEventSubscriptions() {
16391639
let lastSelectedAddress;
16401640
let lastSelectedSolanaAccountAddress;
1641+
let lastSelectedTronAccountAddress;
16411642

1642-
// this throws if there is no solana account... perhaps we should handle this better at the controller level
1643+
// this throws if there is no solana or Tron account... perhaps we should handle this better at the controller level
16431644
try {
16441645
lastSelectedSolanaAccountAddress =
16451646
this.accountsController.getSelectedMultichainAccount(
@@ -1648,6 +1649,14 @@ export default class MetamaskController extends EventEmitter {
16481649
} catch {
16491650
// noop
16501651
}
1652+
try {
1653+
lastSelectedTronAccountAddress =
1654+
this.accountsController.getSelectedMultichainAccount(
1655+
MultichainNetworks.TRON,
1656+
)?.address;
1657+
} catch {
1658+
// noop
1659+
}
16511660

16521661
this.controllerMessenger.subscribe(
16531662
'PreferencesController:stateChange',
@@ -1943,6 +1952,193 @@ export default class MetamaskController extends EventEmitter {
19431952
},
19441953
);
19451954

1955+
// wallet_notify for tron accountChanged when permission changes
1956+
this.controllerMessenger.subscribe(
1957+
`${this.permissionController.name}:stateChange`,
1958+
async (currentValue, previousValue) => {
1959+
const origins = uniq([...previousValue.keys(), ...currentValue.keys()]);
1960+
origins.forEach((origin) => {
1961+
const previousCaveatValue = previousValue.get(origin);
1962+
const currentCaveatValue = currentValue.get(origin);
1963+
1964+
const previousTronAccountChangedNotificationsEnabled = Boolean(
1965+
previousCaveatValue?.sessionProperties?.[
1966+
KnownSessionProperties.TronAccountChangedNotifications
1967+
],
1968+
);
1969+
const currentTronAccountChangedNotificationsEnabled = Boolean(
1970+
currentCaveatValue?.sessionProperties?.[
1971+
KnownSessionProperties.TronAccountChangedNotifications
1972+
],
1973+
);
1974+
1975+
if (
1976+
!previousTronAccountChangedNotificationsEnabled &&
1977+
!currentTronAccountChangedNotificationsEnabled
1978+
) {
1979+
return;
1980+
}
1981+
1982+
const previousTronCaipAccountIds = previousCaveatValue
1983+
? getPermittedAccountsForScopes(previousCaveatValue, [
1984+
MultichainNetworks.TRON,
1985+
MultichainNetworks.TRON_SHASTA,
1986+
MultichainNetworks.TRON_NILE,
1987+
])
1988+
: [];
1989+
const previousNonUniqueTronHexAccountAddresses =
1990+
previousTronCaipAccountIds.map((caipAccountId) => {
1991+
const { address } = parseCaipAccountId(caipAccountId);
1992+
return address;
1993+
});
1994+
const previousTronHexAccountAddresses = uniq(
1995+
previousNonUniqueTronHexAccountAddresses,
1996+
);
1997+
const [previousSelectedTronAccountAddress] =
1998+
this.sortMultichainAccountsByLastSelected(
1999+
previousTronHexAccountAddresses,
2000+
);
2001+
2002+
const currentTronCaipAccountIds = currentCaveatValue
2003+
? getPermittedAccountsForScopes(currentCaveatValue, [
2004+
MultichainNetworks.TRON,
2005+
MultichainNetworks.TRON_SHASTA,
2006+
MultichainNetworks.TRON_NILE,
2007+
])
2008+
: [];
2009+
const currentNonUniqueTronHexAccountAddresses =
2010+
currentTronCaipAccountIds.map((caipAccountId) => {
2011+
const { address } = parseCaipAccountId(caipAccountId);
2012+
return address;
2013+
});
2014+
const currentTronHexAccountAddresses = uniq(
2015+
currentNonUniqueTronHexAccountAddresses,
2016+
);
2017+
const [currentSelectedTronAccountAddress] =
2018+
this.sortMultichainAccountsByLastSelected(
2019+
currentTronHexAccountAddresses,
2020+
);
2021+
2022+
if (
2023+
previousSelectedTronAccountAddress !==
2024+
currentSelectedTronAccountAddress
2025+
) {
2026+
this._notifyTronAccountChange(
2027+
origin,
2028+
currentSelectedTronAccountAddress
2029+
? [currentSelectedTronAccountAddress]
2030+
: [],
2031+
);
2032+
}
2033+
});
2034+
},
2035+
getAuthorizedScopesByOrigin,
2036+
);
2037+
2038+
// TODO: To be removed when state 2 is fully transitioned.
2039+
// wallet_notify for tron accountChanged when selected account changes
2040+
this.controllerMessenger.subscribe(
2041+
`${this.accountsController.name}:selectedAccountChange`,
2042+
async (account) => {
2043+
if (
2044+
account.type === TrxAccountType.Eoa &&
2045+
account.address !== lastSelectedTronAccountAddress
2046+
) {
2047+
lastSelectedTronAccountAddress = account.address;
2048+
2049+
const originsWithTronAccountChangedNotifications =
2050+
getOriginsWithSessionProperty(
2051+
this.permissionController.state,
2052+
KnownSessionProperties.TronAccountChangedNotifications,
2053+
);
2054+
2055+
// returns a map of origins to permitted tron accounts
2056+
const tronAccounts = getPermittedAccountsForScopesByOrigin(
2057+
this.permissionController.state,
2058+
[
2059+
MultichainNetworks.TRON,
2060+
MultichainNetworks.TRON_SHASTA,
2061+
MultichainNetworks.TRON_NILE,
2062+
],
2063+
);
2064+
2065+
if (tronAccounts.size > 0) {
2066+
for (const [origin, accounts] of tronAccounts.entries()) {
2067+
const parsedTronAddresses = accounts.map((caipAccountId) => {
2068+
const { address } = parseCaipAccountId(caipAccountId);
2069+
return address;
2070+
});
2071+
2072+
if (
2073+
parsedTronAddresses.includes(account.address) &&
2074+
originsWithTronAccountChangedNotifications[origin]
2075+
) {
2076+
this._notifyTronAccountChange(origin, [account.address]);
2077+
}
2078+
}
2079+
}
2080+
}
2081+
},
2082+
);
2083+
2084+
// wallet_notify for tron accountChanged when selected account group changes
2085+
this.controllerMessenger.subscribe(
2086+
`${this.accountTreeController.name}:selectedAccountGroupChange`,
2087+
(groupId) => {
2088+
// TODO: Move this logic to the SnapKeyring directly.
2089+
// Forward selected accounts to the Snap keyring, so each Snaps can fetch those accounts.
2090+
// eslint-disable-next-line no-void
2091+
void this.forwardSelectedAccountGroupToSnapKeyring(
2092+
this.getSnapKeyringIfAvailable(),
2093+
groupId,
2094+
);
2095+
2096+
const [account] =
2097+
this.accountTreeController.getAccountsFromSelectedAccountGroup({
2098+
scopes: [TrxScope.Mainnet],
2099+
});
2100+
if (
2101+
account &&
2102+
account.type === TrxAccountType.Eoa &&
2103+
account.address !== lastSelectedTronAccountAddress
2104+
) {
2105+
lastSelectedTronAccountAddress = account.address;
2106+
2107+
const originsWithTronAccountChangedNotifications =
2108+
getOriginsWithSessionProperty(
2109+
this.permissionController.state,
2110+
KnownSessionProperties.TronAccountChangedNotifications,
2111+
);
2112+
2113+
// returns a map of origins to permitted tron accounts
2114+
const tronAccounts = getPermittedAccountsForScopesByOrigin(
2115+
this.permissionController.state,
2116+
[
2117+
MultichainNetworks.TRON,
2118+
MultichainNetworks.TRON_SHASTA,
2119+
MultichainNetworks.TRON_NILE,
2120+
],
2121+
);
2122+
2123+
if (tronAccounts.size > 0) {
2124+
for (const [origin, accounts] of tronAccounts.entries()) {
2125+
const parsedTronAddresses = accounts.map((caipAccountId) => {
2126+
const { address } = parseCaipAccountId(caipAccountId);
2127+
return address;
2128+
});
2129+
2130+
if (
2131+
parsedTronAddresses.includes(account.address) &&
2132+
originsWithTronAccountChangedNotifications[origin]
2133+
) {
2134+
this._notifyTronAccountChange(origin, [account.address]);
2135+
}
2136+
}
2137+
}
2138+
}
2139+
},
2140+
);
2141+
19462142
// TODO: Move this logic to the SnapKeyring directly.
19472143
// Forward selected accounts to the Snap keyring, so each Snaps can fetch those accounts.
19482144
this.controllerMessenger.subscribe(
@@ -8677,6 +8873,23 @@ export default class MetamaskController extends EventEmitter {
86778873
);
86788874
}
86798875

8876+
async _notifyTronAccountChange(origin, accountAddressArray) {
8877+
this.notifyConnections(
8878+
origin,
8879+
{
8880+
method: MultichainApiNotifications.walletNotify,
8881+
params: {
8882+
scope: MultichainNetworks.TRON,
8883+
notification: {
8884+
method: NOTIFICATION_NAMES.accountsChanged,
8885+
params: accountAddressArray,
8886+
},
8887+
},
8888+
},
8889+
API_TYPE.CAIP_MULTICHAIN,
8890+
);
8891+
}
8892+
86808893
async _notifyChainChange() {
86818894
this.notifyAllConnections(
86828895
async (origin) => ({

0 commit comments

Comments
 (0)