Skip to content

Commit

Permalink
Merge branch 'develop' into use-with-keyring
Browse files Browse the repository at this point in the history
  • Loading branch information
mikesposito authored Jul 12, 2024
2 parents 7958f65 + b585a99 commit 2baee85
Show file tree
Hide file tree
Showing 158 changed files with 11,609 additions and 3,629 deletions.
9 changes: 7 additions & 2 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,10 @@
# those changes on build, release and publishing outcomes.

* @MetaMask/extension-devs
**/snaps/** @MetaMask/snaps-devs
development/ @MetaMask/extension-devs @kumavis
lavamoat/ @MetaMask/extension-devs @MetaMask/supply-chain @MetaMask/snaps-devs

# The offscreen.ts script file that is included in the offscreedocument html
# The offscreen.ts script file that is included in the offscreen document html
# file is responsible, at present, for loading the snaps execution environment
# for MV3. Any changes to this file should require at least one member of the
# snaps development team to review and approve the changes.
Expand Down Expand Up @@ -84,3 +83,9 @@ ui/components/component-library @MetaMask/design-system-engineers
# Slack handle: @accounts-team-devs | Slack channel: #metamask-accounts-team

app/scripts/lib/snap-keyring @MetaMask/accounts-engineers

# Snaps
**/snaps/** @MetaMask/snaps-devs
shared/constants/permissions.ts @MetaMask/snaps-devs
ui/helpers/utils/permission.js @MetaMask/snaps-devs
ui/hooks/useTransactionInsights.js @MetaMask/snaps-devs
20 changes: 20 additions & 0 deletions .github/workflows/run-integration-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: Run integration tests

on:
push:
branches: [develop, master]
pull_request:
types: [opened,reopened,synchronize]

jobs:
test-integration:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup environment
uses: ./.github/actions/setup-environment

- name: test:integration:coverage
run: yarn test:integration:coverage
8 changes: 5 additions & 3 deletions .github/workflows/update-attributions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ jobs:
-f content='+1'
env:
COMMENT_ID: ${{ github.event.comment.id }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ secrets.LAVAMOAT_UPDATE_TOKEN }}
REPO: ${{ github.repository }}

prepare:
Expand Down Expand Up @@ -146,6 +146,8 @@ jobs:
git config --global user.email 'metamaskbot@users.noreply.github.com'
git commit -am "Update Attributions"
git push
env:
GITHUB_TOKEN: ${{ secrets.LAVAMOAT_UPDATE_TOKEN }}
- name: Post comment
run: |
if [[ $HAS_CHANGES == 'true' ]]
Expand All @@ -156,7 +158,7 @@ jobs:
fi
env:
HAS_CHANGES: ${{ steps.attributions-changes.outputs.HAS_CHANGES }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ secrets.LAVAMOAT_UPDATE_TOKEN }}
PR_NUMBER: ${{ github.event.issue.number }}

check-status:
Expand Down Expand Up @@ -192,6 +194,6 @@ jobs:
gh pr comment "${PR_NUMBER}" --body "Attributions update failed. You can [review the logs or retry the attributions update here](${ACTION_RUN_URL})"
fi
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ secrets.LAVAMOAT_UPDATE_TOKEN }}
PR_NUMBER: ${{ github.event.issue.number }}
ACTION_RUN_URL: "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
3 changes: 3 additions & 0 deletions .storybook/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ module.exports = {
config.resolve.alias['../../../../store/actions'] = require.resolve(
'../ui/__mocks__/actions.js',
);
config.resolve.alias['../../../../../../store/actions'] = require.resolve(
'../ui/__mocks__/actions.js',
);
config.resolve.fallback = {
child_process: false,
constants: false,
Expand Down
16 changes: 16 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,22 @@
"program": "${workspaceFolder}/node_modules/jest/bin/jest"
}
},
{
"type": "node",
"request": "launch",
"name": "Jest Integration: current file",
"program": "${workspaceFolder}/node_modules/.bin/jest",
"args": [
"${fileBasenameNoExtension}",
"--config",
"jest.integration.config.js"
],
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen",
"windows": {
"program": "${workspaceFolder}/node_modules/jest/bin/jest"
}
},
{
"type": "node",
"request": "launch",
Expand Down
2,630 changes: 0 additions & 2,630 deletions .yarn/patches/@metamask-gas-fee-controller-npm-15.1.2-db4d2976aa.patch

This file was deleted.

20 changes: 19 additions & 1 deletion app/_locales/en/messages.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions app/scripts/controllers/permissions/caveat-mutators.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { CaveatMutatorOperation } from '@metamask/permission-controller';
import { toChecksumAddress } from 'ethereumjs-util';
import { CaveatTypes } from '../../../../shared/constants/permissions';
import { normalizeSafeAddress } from '../../lib/multichain/address';

/**
* Factories that construct caveat mutator functions that are passed to
Expand All @@ -27,9 +27,9 @@ export const CaveatMutatorFactories = {
* account permissions.
*/
function removeAccount(targetAccount, existingAccounts) {
const checkSumTargetAccount = toChecksumAddress(targetAccount);
const checkSumTargetAccount = normalizeSafeAddress(targetAccount);
const newAccounts = existingAccounts.filter(
(address) => toChecksumAddress(address) !== checkSumTargetAccount,
(address) => normalizeSafeAddress(address) !== checkSumTargetAccount,
);

if (newAccounts.length === existingAccounts.length) {
Expand Down
44 changes: 35 additions & 9 deletions app/scripts/controllers/permissions/caveat-mutators.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,66 @@ import { CaveatMutatorOperation } from '@metamask/permission-controller';
import { CaveatTypes } from '../../../../shared/constants/permissions';
import { CaveatMutatorFactories } from './caveat-mutators';

const address1 = '0xbf16f7f5db8ae6af2512399bace3101debbde7fc';
const address2 = '0xb6d5abeca51bfc3d53d00afed06b17eeea32ecdf';
const nonEvmAddress = 'bc1qdkwac3em6mvlur4fatn2g4q050f4kkqadrsmnp';

describe('caveat mutators', () => {
describe('restrictReturnedAccounts', () => {
const { removeAccount } =
CaveatMutatorFactories[CaveatTypes.restrictReturnedAccounts];

describe('removeAccount', () => {
it('returns the no-op operation if the target account is not permitted', () => {
expect(removeAccount('0x2', ['0x1'])).toStrictEqual({
expect(removeAccount(address2, [address1])).toStrictEqual({
operation: CaveatMutatorOperation.noop,
});
});

it('returns the update operation and a new value if the target account is permitted', () => {
expect(removeAccount('0x2', ['0x1', '0x2'])).toStrictEqual({
expect(removeAccount(address2, [address1, address2])).toStrictEqual({
operation: CaveatMutatorOperation.updateValue,
value: ['0x1'],
value: [address1],
});
});

it('returns the revoke permission operation the target account is the only permitted account', () => {
expect(removeAccount('0x1', ['0x1'])).toStrictEqual({
expect(removeAccount(address1, [address1])).toStrictEqual({
operation: CaveatMutatorOperation.revokePermission,
});
});

it('returns the revoke permission operation even if the target account is a checksummed address', () => {
expect(
removeAccount('0x95222290DD7278Aa3Ddd389Cc1E1d165CC4BAee5', [
'0x95222290dd7278aa3ddd389cc1e1d165cc4baee5',
]),
).toStrictEqual({
const address3 = '0x95222290dd7278aa3ddd389cc1e1d165cc4baee5';
const checksummedAddress3 =
'0x95222290dd7278AA3DDd389cc1E1d165Cc4BaeE5';
expect(removeAccount(checksummedAddress3, [address3])).toStrictEqual({
operation: CaveatMutatorOperation.revokePermission,
});
});

describe('Multichain behaviour', () => {
it('returns the no-op operation if the target account is not permitted', () => {
expect(removeAccount(address2, [nonEvmAddress])).toStrictEqual({
operation: CaveatMutatorOperation.noop,
});
});

it('can revoke permission for non-EVM addresses', () => {
expect(removeAccount(nonEvmAddress, [nonEvmAddress])).toStrictEqual({
operation: CaveatMutatorOperation.revokePermission,
});
});

it('returns the update operation and a new value if the target non-EVM account is permitted', () => {
expect(
removeAccount(nonEvmAddress, [address1, nonEvmAddress]),
).toStrictEqual({
operation: CaveatMutatorOperation.updateValue,
value: [address1],
});
});
});
});
});
});
13 changes: 13 additions & 0 deletions app/scripts/controllers/preferences.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ export default class PreferencesController {
useRequestQueue: true,
openSeaEnabled: true, // todo set this to true
securityAlertsEnabled: true,
bitcoinSupportEnabled: false,
///: BEGIN:ONLY_INCLUDE_IF(keyring-snaps)
addSnapAccountEnabled: false,
///: END:ONLY_INCLUDE_IF
Expand Down Expand Up @@ -290,6 +291,18 @@ export default class PreferencesController {
}
///: END:ONLY_INCLUDE_IF

/**
* Setter for the `bitcoinSupportEnabled` property.
*
* @param {boolean} bitcoinSupportEnabled - Whether or not the user wants to
* enable the "Add a new Bitcoin account" button.
*/
setBitcoinSupportEnabled(bitcoinSupportEnabled) {
this.store.updateState({
bitcoinSupportEnabled,
});
}

/**
* Setter for the `useExternalNameSources` property
*
Expand Down
20 changes: 20 additions & 0 deletions app/scripts/controllers/preferences.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -560,4 +560,24 @@ describe('preferences controller', () => {
).toStrictEqual(false);
});
});

describe('setBitcoinSupportEnabled', () => {
it('has the default value as false', () => {
expect(
preferencesController.store.getState().bitcoinSupportEnabled,
).toStrictEqual(false);
});

it('sets the bitcoinSupportEnabled property in state to true and then false', () => {
preferencesController.setBitcoinSupportEnabled(true);
expect(
preferencesController.store.getState().bitcoinSupportEnabled,
).toStrictEqual(true);

preferencesController.setBitcoinSupportEnabled(false);
expect(
preferencesController.store.getState().bitcoinSupportEnabled,
).toStrictEqual(false);
});
});
});
1 change: 1 addition & 0 deletions app/scripts/lib/ppom/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { SecurityAlertSource } from '../../../../shared/constants/security-provider';

export type SecurityAlertResponse = {
block?: number;
description?: string;
features?: string[];
providerRequestsCount?: Record<string, number>;
Expand Down
1 change: 1 addition & 0 deletions app/scripts/lib/setupSentry.js
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,7 @@ export const SENTRY_UI_STATE = {
welcomeScreenSeen: true,
confirmationExchangeRates: true,
useSafeChainsListValidation: true,
bitcoinSupportEnabled: false,
///: BEGIN:ONLY_INCLUDE_IF(keyring-snaps)
addSnapAccountEnabled: false,
snapsAddSnapAccountModalDismissed: false,
Expand Down
25 changes: 25 additions & 0 deletions app/scripts/lib/snap-keyring/bitcoin-wallet-snap.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { SnapId } from '@metamask/snaps-sdk';
import { Sender } from '@metamask/keyring-api';
import { HandlerType } from '@metamask/snaps-utils';
import { Json, JsonRpcRequest } from '@metamask/utils';
// This dependency is still installed as part of the `package.json`, however
// the Snap is being pre-installed only for Flask build (for the moment).
import BitcoinWalletSnap from '@metamask/bitcoin-wallet-snap/dist/preinstalled-snap.json';
import { handleSnapRequest } from '../../../../ui/store/actions';

export const BITCOIN_WALLET_SNAP_ID: SnapId =
BitcoinWalletSnap.snapId as SnapId;

export class BitcoinWalletSnapSender implements Sender {
send = async (request: JsonRpcRequest): Promise<Json> => {
// We assume the caller of this module is aware of this. If we try to use this module
// without having the pre-installed Snap, this will likely throw an error in
// the `handleSnapRequest` action.
return (await handleSnapRequest({
origin: 'metamask',
snapId: BITCOIN_WALLET_SNAP_ID,
handler: HandlerType.OnKeyringRequest,
request,
})) as Json;
};
}
1 change: 1 addition & 0 deletions app/scripts/lib/snap-keyring/keyring-snaps-permissions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const PORTFOLIO_ORIGINS: string[] = [
'https://portfolio.metamask.io',
///: BEGIN:ONLY_INCLUDE_IF(build-flask)
'https://dev.portfolio.metamask.io',
'https://stage.portfolio.metamask.io',
'https://ramps-dev.portfolio.metamask.io',
///: END:ONLY_INCLUDE_IF
];
Expand Down
Loading

0 comments on commit 2baee85

Please sign in to comment.