Skip to content

Commit e1b135c

Browse files
authored
feat(accounts-controller): Add entropySource to new InternalAccount (#5841)
## Explanation `AccountsController:accountAdded` events were missing the `.options.entropySource` property, causing account syncing to misbehave, registering new accounts to the primary SRP instead of the actual SRP used to add the account. We now add the `entropySource` to these new `InternalAccount`s based on the `keyring` that was used to create them. ## References Relates to #5618 Relates to #5725 Relates to #5753
1 parent 1e14fed commit e1b135c

File tree

3 files changed

+51
-6
lines changed

3 files changed

+51
-6
lines changed

packages/accounts-controller/CHANGELOG.md

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

88
## [Unreleased]
99

10+
### Fixed
11+
12+
- Populate `.options.entropySource` for new `InternalAccount`s before publishing `:accountAdded` ([#5841](https://github.com/MetaMask/core/pull/5841))
13+
1014
## [29.0.0]
1115

1216
### Changed

packages/accounts-controller/src/AccountsController.test.ts

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,18 @@ import type {
77
} from '@metamask/keyring-api';
88
import {
99
BtcAccountType,
10+
BtcScope,
1011
EthAccountType,
1112
EthScope,
12-
BtcScope,
1313
} from '@metamask/keyring-api';
1414
import { KeyringTypes } from '@metamask/keyring-controller';
1515
import type { InternalAccount } from '@metamask/keyring-internal-api';
1616
import type { NetworkClientId } from '@metamask/network-controller';
1717
import type { SnapControllerState } from '@metamask/snaps-controllers';
1818
import { SnapStatus } from '@metamask/snaps-utils';
1919
import type { CaipChainId } from '@metamask/utils';
20-
import * as uuid from 'uuid';
2120
import type { V4Options } from 'uuid';
21+
import * as uuid from 'uuid';
2222

2323
import type {
2424
AccountsControllerActions,
@@ -180,6 +180,29 @@ function setLastSelectedAsAny(account: InternalAccount): InternalAccount {
180180
return deepClonedAccount;
181181
}
182182

183+
/**
184+
* Sets the `entropySource` property of the given `account` to the specified
185+
* keyringId value.
186+
*
187+
* @param account - The account to modify.
188+
* @param keyringId - The keyring ID to set as entropySource.
189+
* @returns The modified account.
190+
*/
191+
function populateEntropySource(
192+
account: InternalAccount,
193+
keyringId: string,
194+
): InternalAccount {
195+
return JSON.parse(
196+
JSON.stringify({
197+
...account,
198+
options: {
199+
...account.options,
200+
entropySource: keyringId,
201+
},
202+
}),
203+
) as InternalAccount;
204+
}
205+
183206
/**
184207
* Builds a new instance of the Messenger class for the AccountsController.
185208
*
@@ -621,7 +644,7 @@ describe('AccountsController', () => {
621644

622645
expect(accounts).toStrictEqual([
623646
mockAccount,
624-
setLastSelectedAsAny(mockAccount2),
647+
setLastSelectedAsAny(populateEntropySource(mockAccount2, 'mock-id')),
625648
]);
626649
});
627650

@@ -876,6 +899,9 @@ describe('AccountsController', () => {
876899
name: 'Account 3',
877900
address: mockAccount3.address,
878901
keyringType: KeyringTypes.hd,
902+
options: {
903+
entropySource: 'mock-id',
904+
},
879905
}),
880906
),
881907
]);
@@ -941,7 +967,9 @@ describe('AccountsController', () => {
941967
name: 'Account 3',
942968
address: mockAccount3.address,
943969
keyringType: KeyringTypes.hd,
944-
options: {},
970+
options: {
971+
entropySource: 'mock-id',
972+
},
945973
}),
946974
]);
947975
});
@@ -1044,7 +1072,7 @@ describe('AccountsController', () => {
10441072

10451073
expect(accounts).toStrictEqual([
10461074
mockAccount,
1047-
setLastSelectedAsAny(mockAccount2),
1075+
setLastSelectedAsAny(populateEntropySource(mockAccount2, 'mock-id')),
10481076
]);
10491077
expect(accountsController.getSelectedAccount().id).toBe(mockAccount.id);
10501078
});
@@ -1093,7 +1121,7 @@ describe('AccountsController', () => {
10931121
// 2. AccountsController:stateChange
10941122
3,
10951123
'AccountsController:accountAdded',
1096-
setLastSelectedAsAny(mockAccount2),
1124+
setLastSelectedAsAny(populateEntropySource(mockAccount2, 'mock-id')),
10971125
);
10981126
});
10991127
});
@@ -1407,6 +1435,9 @@ describe('AccountsController', () => {
14071435
name: 'Account 1',
14081436
address: '0x456',
14091437
keyringType: KeyringTypes.hd,
1438+
options: {
1439+
entropySource: 'mock-id',
1440+
},
14101441
});
14111442

14121443
mockUUIDWithNormalAccounts([

packages/accounts-controller/src/AccountsController.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -791,6 +791,7 @@ export class AccountsController extends BaseController<
791791
added: [] as {
792792
address: string;
793793
type: string;
794+
options: InternalAccount['options'];
794795
}[],
795796
updated: [] as InternalAccount[],
796797
removed: [] as InternalAccount[],
@@ -836,6 +837,11 @@ export class AccountsController extends BaseController<
836837
patch.added.push({
837838
address,
838839
type: keyring.type,
840+
// Automatically injects `entropySource` for HD accounts only.
841+
options:
842+
keyring.type === KeyringTypes.hd
843+
? { entropySource: keyring.metadata.id }
844+
: {},
839845
});
840846
}
841847

@@ -902,6 +908,10 @@ export class AccountsController extends BaseController<
902908
importTime: Date.now(),
903909
lastSelected,
904910
},
911+
options: {
912+
...account.options,
913+
...added.options,
914+
},
905915
};
906916

907917
diff.added.push(internalAccounts.accounts[account.id]);

0 commit comments

Comments
 (0)