Skip to content

Commit

Permalink
stash
Browse files Browse the repository at this point in the history
  • Loading branch information
MajorLift committed Jul 31, 2024
1 parent 50472d0 commit 4abc716
Show file tree
Hide file tree
Showing 16 changed files with 99 additions and 66 deletions.
25 changes: 14 additions & 11 deletions app/scripts/lib/accounts/BalancesController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -224,9 +224,10 @@ export class BalancesController extends BaseController<
* @param accountId - The account ID.
*/
#getAccount(accountId: string): InternalAccount {
const account: InternalAccount = this.#listMultichainAccounts().find(
(multichainAccount) => multichainAccount.id === accountId,
);
const account: InternalAccount | undefined =
this.#listMultichainAccounts().find(
(multichainAccount) => multichainAccount.id === accountId,
);

if (!account) {
throw new Error(`Unknown account: ${accountId}`);
Expand All @@ -247,13 +248,15 @@ export class BalancesController extends BaseController<
const account = this.#getAccount(accountId);
const partialState: BalancesControllerState = { balances: {} };

partialState.balances[account.id] = await this.#getBalances(
account.id,
account.metadata.snap.id,
isBtcMainnetAddress(account.address)
? BTC_MAINNET_ASSETS
: BTC_TESTNET_ASSETS,
);
if (account.metadata.snap) {
partialState.balances[account.id] = await this.#getBalances(
account.id,
account.metadata.snap.id,
isBtcMainnetAddress(account.address)
? BTC_MAINNET_ASSETS
: BTC_TESTNET_ASSETS,
);
}

this.update((state: Draft<BalancesControllerState>) => ({
...state,
Expand Down Expand Up @@ -292,7 +295,7 @@ export class BalancesController extends BaseController<
return (
!isEvmAccountType(account.type) &&
// Non-EVM accounts are backed by a Snap for now
account.metadata.snap
account.metadata.snap !== undefined
);
}

Expand Down
52 changes: 29 additions & 23 deletions app/scripts/lib/createDupeReqFilterStream.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import OurReadableStream from 'readable-stream';
import ReadableStream2 from 'readable-stream-2';
import ReadableStream3 from 'readable-stream-3';

import type { JsonRpcRequest } from '@metamask/utils';
import { JsonRpcNotification, type JsonRpcRequest } from '@metamask/utils';
import createDupeReqFilterStream, {
THREE_MINUTES,
} from './createDupeReqFilterStream';
Expand All @@ -26,7 +26,7 @@ function createTestStream(output: JsonRpcRequest[] = [], S = Transform) {
}

function runStreamTest(
requests: JsonRpcRequest[] = [],
requests: (JsonRpcRequest | JsonRpcNotification)[] = [],
advanceTimersTime = 10,
S = Transform,
) {
Expand All @@ -52,13 +52,13 @@ describe('createDupeReqFilterStream', () => {

it('lets through requests with ids being seen for the first time', async () => {
const requests = [
{ id: 1, method: 'foo' },
{ id: 2, method: 'bar' },
{ id: 1, method: 'foo', jsonrpc: '2.0' as const },
{ id: 2, method: 'bar', jsonrpc: '2.0' as const },
];

const expectedOutput = [
{ id: 1, method: 'foo' },
{ id: 2, method: 'bar' },
{ id: 1, method: 'foo', jsonrpc: '2.0' },
{ id: 2, method: 'bar', jsonrpc: '2.0' },
];

const output = await runStreamTest(requests);
Expand All @@ -67,42 +67,48 @@ describe('createDupeReqFilterStream', () => {

it('does not let through the request if the id has been seen before', async () => {
const requests = [
{ id: 1, method: 'foo' },
{ id: 1, method: 'foo' }, // duplicate
{ id: 1, method: 'foo', jsonrpc: '2.0' as const },
{ id: 1, method: 'foo', jsonrpc: '2.0' as const }, // duplicate
];

const expectedOutput = [{ id: 1, method: 'foo' }];
const expectedOutput = [{ id: 1, method: 'foo', jsonrpc: '2.0' }];

const output = await runStreamTest(requests);
expect(output).toEqual(expectedOutput);
});

it("lets through requests if they don't have an id", async () => {
const requests = [{ method: 'notify1' }, { method: 'notify2' }];
const requests = [
{ method: 'notify1', jsonrpc: '2.0' as const },
{ method: 'notify2', jsonrpc: '2.0' as const },
];

const expectedOutput = [{ method: 'notify1' }, { method: 'notify2' }];
const expectedOutput = [
{ method: 'notify1', jsonrpc: '2.0' },
{ method: 'notify2', jsonrpc: '2.0' },
];

const output = await runStreamTest(requests);
expect(output).toEqual(expectedOutput);
});

it('handles a mix of request types', async () => {
const requests = [
{ id: 1, method: 'foo' },
{ method: 'notify1' },
{ id: 1, method: 'foo' },
{ id: 2, method: 'bar' },
{ method: 'notify2' },
{ id: 2, method: 'bar' },
{ id: 3, method: 'baz' },
{ id: 1, method: 'foo', jsonrpc: '2.0' as const },
{ method: 'notify1', jsonrpc: '2.0' as const },
{ id: 1, method: 'foo', jsonrpc: '2.0' as const },
{ id: 2, method: 'bar', jsonrpc: '2.0' as const },
{ method: 'notify2', jsonrpc: '2.0' as const },
{ id: 2, method: 'bar', jsonrpc: '2.0' as const },
{ id: 3, method: 'baz', jsonrpc: '2.0' as const },
];

const expectedOutput = [
{ id: 1, method: 'foo' },
{ method: 'notify1' },
{ id: 2, method: 'bar' },
{ method: 'notify2' },
{ id: 3, method: 'baz' },
{ id: 1, method: 'foo', jsonrpc: '2.0' },
{ method: 'notify1', jsonrpc: '2.0' },
{ id: 2, method: 'bar', jsonrpc: '2.0' },
{ method: 'notify2', jsonrpc: '2.0' },
{ id: 3, method: 'baz', jsonrpc: '2.0' },
];

const output = await runStreamTest(requests);
Expand Down
3 changes: 2 additions & 1 deletion app/scripts/lib/createDupeReqFilterStream.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ export default function createDupeReqFilterStream() {
transform(chunk: JsonRpcRequest, _, cb) {
// JSON-RPC notifications have no ids; our only recourse is to let them through.
const hasNoId = chunk.id === undefined;
const requestNotYetSeen = seenRequestIds.add(chunk.id);
const requestNotYetSeen =
chunk.id !== null && seenRequestIds.add(chunk.id);

if (hasNoId || requestNotYetSeen) {
cb(null, chunk);
Expand Down
10 changes: 7 additions & 3 deletions app/scripts/lib/ppom/ppom-middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,9 @@ export function createPPOMMiddleware<
) => void,
) {
return async (
req: JsonRpcRequest<Params>,
req: JsonRpcRequest<Params> & {
securityAlertResponse: SecurityAlertResponse;
},
_res: JsonRpcResponse<Result>,
next: () => void,
) => {
Expand All @@ -80,13 +82,15 @@ export function createPPOMMiddleware<
return;
}

const { isSIWEMessage } = detectSIWE({ data: req?.params?.[0] });
const data =
(Array.isArray(req.params) ? req.params[0] : req.params) ?? {};
const { isSIWEMessage } = detectSIWE({ data });
if (isSIWEMessage) {
return;
}

if (req.method === MESSAGE_TYPE.ETH_SEND_TRANSACTION) {
const { to: toAddress } = req?.params?.[0] ?? {};
const { to: toAddress } = data;
const internalAccounts = accountsController.listAccounts();
const isToInternalAccount = internalAccounts.some(
({ address }) => address?.toLowerCase() === toAddress?.toLowerCase(),
Expand Down
13 changes: 10 additions & 3 deletions app/scripts/lib/ppom/ppom-util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ const SECURITY_ALERT_RESPONSE_ERROR = {
reason: BlockaidReason.errored,
};

type PPOMRequest = Exclude<JsonRpcRequest, 'method' | 'params'> & {
method: typeof METHOD_SEND_TRANSACTION;
params: [TransactionParams];
};

export async function validateRequestWithPPOM({
ppomController,
request,
Expand Down Expand Up @@ -129,12 +134,14 @@ export async function isChainSupported(chainId: Hex): Promise<boolean> {
return supportedChainIds.includes(chainId);
}

function normalizePPOMRequest(request: JsonRpcRequest): JsonRpcRequest {
function normalizePPOMRequest(
request: JsonRpcRequest,
): PPOMRequest | typeof request {
if (request.method !== METHOD_SEND_TRANSACTION) {
return request;
}

const transactionParams = (request.params?.[0] || {}) as TransactionParams;
const transactionParams = request.params[0] ?? {};
const normalizedParams = normalizeTransactionParams(transactionParams);

return {
Expand Down Expand Up @@ -210,7 +217,7 @@ async function validateWithController(
async function validateWithAPI(
ppomController: PPOMController,
chainId: string,
request: JsonRpcRequest,
request: PPOMRequest,
): Promise<SecurityAlertResponse> {
try {
const response = await validateWithSecurityAlertsAPI(chainId, request);
Expand Down
4 changes: 4 additions & 0 deletions app/scripts/lib/snap-keyring/snap-keyring.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ const mockInternalAccount = {
name: mockSnapName,
},
name: accountNameSuggestion,
keyring: {
type: '',
},
importTime: 0,
},
};

Expand Down
9 changes: 5 additions & 4 deletions app/scripts/lib/transaction/util.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,7 @@ describe('Transaction Utils', () => {
expect(validateRequestWithPPOMMock).toHaveBeenCalledTimes(0);
});

it('send to users own acccount', async () => {
it('send to users own account', async () => {
const sendRequest = {
...request,
transactionParams: {
Expand All @@ -484,9 +484,10 @@ describe('Transaction Utils', () => {
...sendRequest,
securityAlertsEnabled: false,
chainId: '0x1',
internalAccounts: {
address: INTERNAL_ACCOUNT_ADDRESS,
} as InternalAccount,
internalAccounts: [
// @ts-expect-error Passing incomplete account type for mocking purposes
{ address: INTERNAL_ACCOUNT_ADDRESS },
],
});

expect(
Expand Down
7 changes: 4 additions & 3 deletions app/scripts/lib/transaction/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -264,11 +264,12 @@ async function validateSecurity(request: AddTransactionRequest) {
params: [
{
from,
to,
value,
data,
to: to ?? '',
value: value ?? '',
data: data ?? '',
},
],
jsonrpc: '2.0' as const,
};

const securityAlertId = generateSecurityAlertId();
Expand Down
1 change: 1 addition & 0 deletions app/scripts/migrations/105.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ function expectedInternalAccount(
type: 'HD Key Tree',
},
lastSelected: lastSelected ? expect.any(Number) : undefined,
importTime: Date.now(),
},
options: {},
methods: ETH_EOA_METHODS,
Expand Down
1 change: 1 addition & 0 deletions app/scripts/migrations/105.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ function createInternalAccountsForAccountsController(
// initial updateAccounts call.
type: 'HD Key Tree',
},
importTime: Date.now(),
},
methods: ETH_EOA_METHODS,
type: EthAccountType.Eoa,
Expand Down
14 changes: 7 additions & 7 deletions app/scripts/migrations/119.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,13 @@ function transformState(state: Record<string, any>) {
.accounts,
).length > 0
) {
Object.values(accountsController.internalAccounts.accounts).forEach(
(internalAccount: InternalAccount) => {
if (!internalAccount.metadata?.importTime) {
internalAccount.metadata.importTime = Date.now();
}
},
);
Object.values<InternalAccount>(
accountsController.internalAccounts.accounts,
).forEach((internalAccount) => {
if (!internalAccount.metadata?.importTime) {
internalAccount.metadata.importTime = Date.now();
}
});
}

return {
Expand Down
3 changes: 2 additions & 1 deletion app/scripts/snaps/preinstalled-snaps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import MessageSigningSnap from '@metamask/message-signing-snap/dist/preinstalled
import BitcoinWalletSnap from '@metamask/bitcoin-wallet-snap/dist/preinstalled-snap.json';
///: END:ONLY_INCLUDE_IF

const PREINSTALLED_SNAPS: readonly PreinstalledSnap[] = Object.freeze([
const PREINSTALLED_SNAPS = Object.freeze<PreinstalledSnap[]>([
MessageSigningSnap as PreinstalledSnap,
///: BEGIN:ONLY_INCLUDE_IF(build-flask)
// @ts-expect-error Type 'string' is not comparable to type '{ [brand]: unique symbol; }'.ts(2352)
BitcoinWalletSnap as PreinstalledSnap,
///: END:ONLY_INCLUDE_IF
]);
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/tests/api-usage/account-tracker-api-usage.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ async function getAllInfuraJsonRpcRequests(
);

for (const r of seenProviderRequests) {
const json = await r.body.getJson();
const json = (await r.body.getJson()) as JsonRpcRequest | undefined;
if (json !== undefined) {
allInfuraJsonRpcRequests.push(json);
}
Expand Down
5 changes: 2 additions & 3 deletions ui/contexts/snaps/snap-interface.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,8 @@ export const SnapInterfaceContextProvider: FunctionComponent<
params: {
event: {
type: event,
// TODO: Allow null in the types and simplify this
...(name !== undefined && name !== null ? { name } : {}),
...(value !== undefined && value !== null ? { value } : {}),
name,
value,
},
id: interfaceId,
context,
Expand Down
1 change: 1 addition & 0 deletions ui/hooks/useMultichainSelector.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ describe('useMultichainSelector', () => {
});

it('uses selectedAccount if account is not provided', () => {
// @ts-expect-error Intentionally passing in invalid input for testing purposes
const { result } = renderUseMultichainHook(getMultichainIsEvm, null);

expect(result.current).toBe(true);
Expand Down
15 changes: 9 additions & 6 deletions ui/selectors/accounts.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ describe('Accounts Selectors', () => {
...MOCK_STATE.metamask,
internalAccounts: {
selectedAccount: MOCK_ACCOUNT_EOA.id,
accounts: [MOCK_ACCOUNT_EOA],
accounts: { mock_account_eoa: MOCK_ACCOUNT_EOA },
},
},
};
Expand All @@ -118,10 +118,11 @@ describe('Accounts Selectors', () => {
...MOCK_STATE.metamask,
internalAccounts: {
selectedAccount: MOCK_ACCOUNT_BIP122_P2WPKH.id,
accounts: [
MOCK_ACCOUNT_BIP122_P2WPKH,
MOCK_ACCOUNT_BIP122_P2WPKH_TESTNET,
],
accounts: {
mock_account_bip122_pwpkh: MOCK_ACCOUNT_BIP122_P2WPKH,
mock_account_bip122_p2wpkh_testnet:
MOCK_ACCOUNT_BIP122_P2WPKH_TESTNET,
},
},
},
};
Expand All @@ -136,7 +137,9 @@ describe('Accounts Selectors', () => {
...MOCK_STATE.metamask,
internalAccounts: {
selectedAccount: MOCK_ACCOUNT_BIP122_P2WPKH.id,
accounts: [MOCK_ACCOUNT_BIP122_P2WPKH],
accounts: {
mock_account_bip122_p2wpkh: MOCK_ACCOUNT_BIP122_P2WPKH,
},
},
},
};
Expand Down

0 comments on commit 4abc716

Please sign in to comment.