Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
0eff976
feat: add mocks and evm check to accounts controller
montelaidev Apr 26, 2024
83250ef
feat: add mocks and util function for non evm
montelaidev Apr 26, 2024
fafd322
fix: update NftDetectionController to use selectedInternalId instead …
montelaidev Apr 26, 2024
61ace68
fix: update NftController to use selectedAccountId instead of selecte…
montelaidev Apr 26, 2024
c866813
fix: use selectedAccount action
montelaidev Apr 29, 2024
6ee9a62
fix: listeners in NftDetectionController
montelaidev Apr 29, 2024
4c30c69
feat: add mocks and evm check to accounts controller
montelaidev Apr 26, 2024
c0cde1b
feat: add mocks and util function for non evm
montelaidev Apr 26, 2024
a9ec2a0
fix: remove getIdentites and getSelectedAddress from AccountTrackerCo…
montelaidev Apr 29, 2024
23aeaa0
fix: update selectedAddress args in token controllers
montelaidev Apr 24, 2024
42133c0
fix: udpate TokenBalancesController to use InternalAccount instead of…
montelaidev Apr 25, 2024
e291bdb
fix: update TokenBalances test to reach 100% coverage
montelaidev Apr 25, 2024
9b8a1eb
fix: update token controllers
montelaidev Apr 26, 2024
6c0595d
feat: add tests to util and mocks
montelaidev Apr 29, 2024
cb17e99
fix: remove nonevm check during selectedAccountChange
montelaidev Apr 29, 2024
f5f6c11
feat: add mocks and evm check to accounts controller
montelaidev Apr 26, 2024
5967095
feat: add mocks and util function for non evm
montelaidev Apr 26, 2024
0e5df33
fix: imports
montelaidev May 2, 2024
9dd7c8d
Merge branch 'fix/ap381/update-account-tracker-to-use-selectedAccount…
montelaidev May 2, 2024
1c9e453
Merge branch 'fix/ap381/update-tokens-controllers-to-use-internal-acc…
montelaidev May 2, 2024
0b8cbed
Merge branch 'fix/ap381/update-nft-controllers-to-use-internal-accoun…
montelaidev May 2, 2024
6e656f6
Merge branch 'fix/ap381/update-transaction-controllers-to-use-selecte…
montelaidev May 2, 2024
a7089c5
fix: peer dep version
montelaidev May 2, 2024
cff6cd9
Merge remote-tracking branch 'origin/main' into fix/ap381/update-cont…
montelaidev May 3, 2024
8cee6a6
fix: update to keyring-api 6.1
montelaidev May 6, 2024
eb5191e
chore(deps): bump keyring api version to 6.1.0
montelaidev May 14, 2024
f916816
fix: type error
montelaidev May 14, 2024
a1db071
temp: add skip lib check for snaps sdk type error
montelaidev May 14, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions packages/accounts-controller/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@
"dependencies": {
"@ethereumjs/util": "^8.1.0",
"@metamask/base-controller": "^5.0.2",
"@metamask/eth-snap-keyring": "^4.0.0",
"@metamask/keyring-api": "^6.0.0",
"@metamask/snaps-sdk": "^4.0.1",
"@metamask/snaps-utils": "^7.1.0",
"@metamask/eth-snap-keyring": "^4.1.0",
"@metamask/keyring-api": "^6.1.0",
"@metamask/snaps-sdk": "^4.1.0",
"@metamask/snaps-utils": "^7.3.0",
"@metamask/utils": "^8.3.0",
"deepmerge": "^4.2.2",
"ethereum-cryptography": "^2.1.2",
Expand Down
14 changes: 10 additions & 4 deletions packages/accounts-controller/src/AccountsController.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,8 @@ class MockNormalAccountUUID {
* @param props.keyringType - The type of the keyring associated with the account.
* @param props.snapId - The id of the snap.
* @param props.snapEnabled - The status of the snap
* @param props.lastSelected - The last selected time of the account.
* @param props.importTime - The import time of the account.
* @returns The `InternalAccount` object created from the normal account properties.
*/
function createExpectedInternalAccount({
Expand All @@ -154,13 +156,17 @@ function createExpectedInternalAccount({
keyringType,
snapId,
snapEnabled = true,
importTime,
lastSelected,
}: {
id: string;
name: string;
address: string;
keyringType: string;
snapId?: string;
snapEnabled?: boolean;
importTime?: number;
lastSelected?: number;
}): InternalAccount {
const account: InternalAccount = {
id,
Expand All @@ -171,10 +177,8 @@ function createExpectedInternalAccount({
metadata: {
name,
keyring: { type: keyringType },
importTime: expect.any(Number),
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
lastSelected: undefined,
importTime: importTime || expect.any(Number),
lastSelected: lastSelected || undefined,
},
};

Expand Down Expand Up @@ -703,6 +707,8 @@ describe('AccountsController', () => {
name: 'Custom Name',
address: mockAccount2.address,
keyringType: KeyringTypes.hd,
importTime: 1955565967656,
lastSelected: 1955565967656,
});

const mockNewKeyringState = {
Expand Down
80 changes: 63 additions & 17 deletions packages/accounts-controller/src/AccountsController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const controllerName = 'AccountsController';
export type AccountsControllerState = {
internalAccounts: {
accounts: Record<string, InternalAccount>;
selectedAccount: string; // id of the selected account
selectedAccount: string;
};
};

Expand Down Expand Up @@ -75,6 +75,11 @@ export type AccountsControllerGetAccountAction = {
handler: AccountsController['getAccount'];
};

export type AccountsControllerGetAccountExpectAction = {
type: `${typeof controllerName}:getAccountExpect`;
handler: AccountsController['getAccountExpect'];
};

export type AllowedActions =
| KeyringControllerGetKeyringForAccountAction
| KeyringControllerGetKeyringsByTypeAction
Expand All @@ -88,7 +93,8 @@ export type AccountsControllerActions =
| AccountsControllerUpdateAccountsAction
| AccountsControllerGetAccountByAddressAction
| AccountsControllerGetSelectedAccountAction
| AccountsControllerGetAccountAction;
| AccountsControllerGetAccountAction
| AccountsControllerGetAccountExpectAction;

export type AccountsControllerChangeEvent = ControllerStateChangeEvent<
typeof controllerName,
Expand Down Expand Up @@ -302,7 +308,21 @@ export class AccountsController extends BaseController<
...account,
metadata: { ...account.metadata, name: accountName },
};
currentState.internalAccounts.accounts[accountId] = internalAccount;

// deep clone of old state to get around Type instantiation is excessively deep and possibly infinite.
const oldState = JSON.parse(JSON.stringify(currentState));

const newState: AccountsControllerState = {
internalAccounts: {
...oldState.internalAccounts,
accounts: {
...oldState.internalAccounts.accounts,
[accountId]: internalAccount,
},
},
};

return newState;
});
}

Expand Down Expand Up @@ -363,8 +383,15 @@ export class AccountsController extends BaseController<
}, {} as Record<string, InternalAccount>);

this.update((currentState: Draft<AccountsControllerState>) => {
(currentState as AccountsControllerState).internalAccounts.accounts =
accounts;
const newState: AccountsControllerState = {
...currentState,
internalAccounts: {
selectedAccount: currentState.internalAccounts.selectedAccount,
accounts,
},
};

return newState;
});
}

Expand All @@ -375,9 +402,11 @@ export class AccountsController extends BaseController<
*/
loadBackup(backup: AccountsControllerState): void {
if (backup.internalAccounts) {
this.update((currentState: Draft<AccountsControllerState>) => {
(currentState as AccountsControllerState).internalAccounts =
backup.internalAccounts;
this.update(() => {
const newState: AccountsControllerState = {
internalAccounts: backup.internalAccounts,
};
return newState;
});
}
}
Expand Down Expand Up @@ -761,17 +790,29 @@ export class AccountsController extends BaseController<
const accountName = `${accountPrefix} ${indexToUse}`;

this.update((currentState: Draft<AccountsControllerState>) => {
(currentState as AccountsControllerState).internalAccounts.accounts[
newAccount.id
] = {
...newAccount,
metadata: {
...newAccount.metadata,
name: accountName,
importTime: Date.now(),
lastSelected: Date.now(),
// deep clone of old state to get around Type instantiation is excessively deep and possibly infinite.
const oldState = JSON.parse(JSON.stringify(currentState));

const newState: AccountsControllerState = {
...oldState,
internalAccounts: {
...oldState.internalAccounts,
accounts: {
...oldState.internalAccounts.accounts,
[newAccount.id]: {
...newAccount,
metadata: {
...newAccount.metadata,
name: accountName,
importTime: Date.now(),
lastSelected: Date.now(),
},
},
},
},
};

return newState;
});

this.setSelectedAccount(newAccount.id);
Expand Down Expand Up @@ -840,5 +881,10 @@ export class AccountsController extends BaseController<
`AccountsController:getAccount`,
this.getAccount.bind(this),
);

this.messagingSystem.registerActionHandler(
`AccountsController:getAccountExpect`,
this.getAccountExpect.bind(this),
);
}
}
2 changes: 2 additions & 0 deletions packages/accounts-controller/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export type {
AccountsControllerGetSelectedAccountAction,
AccountsControllerGetAccountByAddressAction,
AccountsControllerGetAccountAction,
AccountsControllerGetAccountExpectAction,
AccountsControllerActions,
AccountsControllerChangeEvent,
AccountsControllerSelectedAccountChangeEvent,
Expand All @@ -16,3 +17,4 @@ export type {
} from './AccountsController';
export { AccountsController } from './AccountsController';
export { keyringTypeToName, getUUIDFromAddressOfNormalAccount } from './utils';
export { createMockInternalAccount } from './tests/mocks';
77 changes: 77 additions & 0 deletions packages/accounts-controller/src/tests/mocks.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { BtcAccountType, EthAccountType } from '@metamask/keyring-api';

import { createMockInternalAccount } from './mocks';

describe('createMockInternalAccount', () => {
it('should create a mock internal account', () => {
const account = createMockInternalAccount();
expect(account).toStrictEqual({
id: expect.any(String),
address: expect.any(String),
type: expect.any(String),
options: expect.any(Object),
methods: expect.any(Array),
metadata: {
name: expect.any(String),
keyring: { type: expect.any(String) },
importTime: expect.any(Number),
lastSelected: expect.any(Number),
snap: undefined,
},
});
});

it('should create a mock internal account with custom values', () => {
const customSnap = {
id: '1',
enabled: true,
name: 'Snap 1',
};
const account = createMockInternalAccount({
id: '1',
address: '0x123',
type: EthAccountType.Erc4337,
name: 'Custom Account',
snap: customSnap,
});
expect(account).toStrictEqual({
id: '1',
address: '0x123',
type: EthAccountType.Erc4337,
options: expect.any(Object),
methods: expect.any(Array),
metadata: {
name: 'Custom Account',
keyring: { type: expect.any(String) },
importTime: expect.any(Number),
lastSelected: expect.any(Number),
snap: customSnap,
},
});
});

it('should create a nonevm account', () => {
const account = createMockInternalAccount({ type: BtcAccountType.P2wpkh });
expect(account).toStrictEqual({
id: expect.any(String),
address: expect.any(String),
type: BtcAccountType.P2wpkh,
options: expect.any(Object),
methods: expect.any(Array),
metadata: {
name: expect.any(String),
keyring: { type: expect.any(String) },
importTime: expect.any(Number),
lastSelected: expect.any(Number),
snap: undefined,
},
});
});

it('will throw if an unknown account type was passed', () => {
// @ts-expect-error testing unknown account type
expect(() => createMockInternalAccount({ type: 'unknown' })).toThrow(
'Unknown account type: unknown',
);
});
});
79 changes: 79 additions & 0 deletions packages/accounts-controller/src/tests/mocks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import type {
InternalAccount,
InternalAccountType,
} from '@metamask/keyring-api';
import {
BtcAccountType,
BtcMethod,
EthAccountType,
EthErc4337Method,
EthMethod,
} from '@metamask/keyring-api';
import { KeyringTypes } from '@metamask/keyring-controller';
import { v4 } from 'uuid';

export const createMockInternalAccount = ({
id = v4(),
address = '0x2990079bcdee240329a520d2444386fc119da21a',
type = EthAccountType.Eoa,
name = 'Account 1',
keyringType = KeyringTypes.hd,
snap,
importTime = Date.now(),
lastSelected = Date.now(),
}: {
id?: string;
address?: string;
type?: InternalAccountType;
name?: string;
keyringType?: KeyringTypes;
snap?: {
id: string;
enabled: boolean;
name: string;
};
importTime?: number;
lastSelected?: number;
} = {}): InternalAccount => {
let methods;

switch (type) {
case EthAccountType.Eoa:
methods = [
EthMethod.PersonalSign,
EthMethod.Sign,
EthMethod.SignTransaction,
EthMethod.SignTypedDataV1,
EthMethod.SignTypedDataV3,
EthMethod.SignTypedDataV4,
];
break;
case EthAccountType.Erc4337:
methods = [
EthErc4337Method.PatchUserOperation,
EthErc4337Method.PrepareUserOperation,
EthErc4337Method.SignUserOperation,
];
break;
case BtcAccountType.P2wpkh:
methods = [BtcMethod.SendMany];
break;
default:
throw new Error(`Unknown account type: ${type as string}`);
}

return {
id,
address,
options: {},
methods,
type,
metadata: {
name,
keyring: { type: keyringType },
importTime,
lastSelected,
snap: snap && snap,
},
} as InternalAccount;
};
2 changes: 1 addition & 1 deletion packages/assets-controllers/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
"@metamask/contract-metadata": "^2.4.0",
"@metamask/controller-utils": "^9.1.0",
"@metamask/eth-query": "^4.0.0",
"@metamask/keyring-api": "^6.1.0",
"@metamask/keyring-controller": "^16.0.0",
"@metamask/metamask-eth-abis": "^3.1.1",
"@metamask/network-controller": "^18.1.0",
Expand All @@ -73,7 +74,6 @@
"devDependencies": {
"@metamask/auto-changelog": "^3.4.4",
"@metamask/ethjs-provider-http": "^0.3.0",
"@metamask/keyring-api": "^6.0.0",
"@types/jest": "^27.4.1",
"@types/lodash": "^4.14.191",
"@types/node": "^16.18.54",
Expand Down
Loading