Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Migrate eth_accounts and permittedChains to CAIP-25 endowment #27847

Open
wants to merge 330 commits into
base: main
Choose a base branch
from

Conversation

jiexi
Copy link
Contributor

@jiexi jiexi commented Oct 14, 2024

Description

This PR replaces the replaces the internal eth_accounts and endowment:permittedChains permission structure with a CAIP-25 endowment. It adds adapter logic to translate to and from the new internal CAIP-25 permissions. This change should be transparent to wallet users and to dapps except for one two cases, see below. This change is required in order to support CAIP-25 and CAIP-27 requests in a follow-up PR that enables the Multichain API.

Open in GitHub Codespaces

Related issues

Related: MetaMask/core#4784

Manual testing steps

There should be no user or dapp facing difference in behavior except:

  • When calling wallet_revokePermissions and specifying either eth_accounts or endowment:permitted-chains, the entire CAIP-25 permission will be revoked. It will appear to the dapp as if both eth_accounts and endowment:permitted-chains were revoked.
  • When calling wallet_getPermissions for a permitted dapp when the wallet is locked, eth_accounts should be returned in addition to endowment:permitted-chains. Currently there is a regression on main where only endowment:permitted-chains gets returned when the wallet is locked.
await window.ethereum.request({
 "method": "wallet_revokePermissions",
 "params": [
  {
    eth_accounts: {}
  }
],
});

await window.ethereum.request({
 "method": "wallet_revokePermissions",
 "params": [
  {
    'endowment:permitted-chains': {}
  }
],
});

await window.ethereum.request({
 "method": "wallet_getPermissions",
 "params": [],
});

Locked Wallet Behavior with dapp connected

Other than the two noted items below, this behavior matches that in main

  • eth_accounts returns []
  • wallet_getPermissions returns permissions incl eth_accounts
  • wallet_revokePermissions works as usual and revokes eth_accounts and revoke permitted-chains together
    • Note this fixes a regression in main where eth_accounts and permitted-chains aren't revoked as a pair if either is revoked
  • eth_requestAccounts prompts for unlock, after unlock returns accounts if any are permitted, otherwise shows connection prompt
  • wallet_requestPermissions prompts for unlock
  • signature methods fails with method or accounts not authorized
  • non-signature methods work as usual
  • accountsChanged empty array on lock. no event after revokePermissions which makes sense since the dapp was told empty array on lock and now it's actually empty array so no changes have occurred as far as the dapp should be concerned.
  • CHANGED: for dapps that were granted chain permissions via the wallet_addEthereum or wallet_switchEthereumChain flows without account permissions, these permissions will be removed with this migration. We think this ok because:
    • This is a very uncommon scenario for dapps to request chain switches without account permissions.
    • These permissions can be regained very trivially with subsequent chain switch requests.

Screenshots/Recordings

Before

After

Pre-merge author checklist

Pre-merge reviewer checklist

  • I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed).
  • I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots.

Copy link
Contributor

CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes.

Copy link

socket-security bot commented Oct 14, 2024

New, updated, and removed dependencies detected. Learn more about Socket for GitHub ↗︎

Package New capabilities Transitives Size Publisher
npm/@metamask/[email protected] 🔁 npm/@metamask/[email protected] None 0 270 kB metamaskbot
npm/@metamask/[email protected] None 0 318 kB metamaskbot
npm/@open-rpc/[email protected] 🔁 npm/@open-rpc/[email protected] None 0 38.4 kB belfordz

🚮 Removed packages: npm/@json-schema-spec/[email protected], npm/@json-schema-tools/[email protected]

View full report↗︎

Copy link

socket-security bot commented Oct 14, 2024

👍 Dependency issues cleared. Learn more about Socket for GitHub ↗︎

This PR previously contained dependency changes with security issues that have been resolved, removed, or ignored.

View full report↗︎

@jiexi
Copy link
Contributor Author

jiexi commented Oct 14, 2024

@metamask-bot update-policies

@jiexi
Copy link
Contributor Author

jiexi commented Oct 15, 2024

@metamaskbot update-policies

@metamaskbot
Copy link
Collaborator

Policies updated.
👀 Please review the diff for suspicious new powers.

🧠 Learn how: https://lavamoat.github.io/guides/policy-diff/#what-to-look-for-when-reviewing-a-policy-diff

@jiexi
Copy link
Contributor Author

jiexi commented Oct 15, 2024

@metamaskbot update-policies

@metamaskbot
Copy link
Collaborator

Policies updated.
👀 Please review the diff for suspicious new powers.

🧠 Learn how: https://lavamoat.github.io/guides/policy-diff/#what-to-look-for-when-reviewing-a-policy-diff

@jiexi
Copy link
Contributor Author

jiexi commented Oct 15, 2024

@SocketSecurity ignore npm/@metamask/[email protected]

i know that mcmire guy

@jiexi
Copy link
Contributor Author

jiexi commented Oct 15, 2024

@SocketSecurity ignore npm/@metamask/[email protected]

i still know that mcmire fellow

@jiexi
Copy link
Contributor Author

jiexi commented Oct 15, 2024

@SocketSecurity ignore npm/@metamask/[email protected]

the fetch isn't new, but even then it's fine because it fetches caller supplied url

@jiexi
Copy link
Contributor Author

jiexi commented Oct 15, 2024

@metamaskbot update-policies

@metamaskbot
Copy link
Collaborator

Policies updated.
👀 Please review the diff for suspicious new powers.

🧠 Learn how: https://lavamoat.github.io/guides/policy-diff/#what-to-look-for-when-reviewing-a-policy-diff

@jiexi
Copy link
Contributor Author

jiexi commented Oct 16, 2024

@metamaskbot update-policies

@metamaskbot
Copy link
Collaborator

Policies updated.
👀 Please review the diff for suspicious new powers.

🧠 Learn how: https://lavamoat.github.io/guides/policy-diff/#what-to-look-for-when-reviewing-a-policy-diff

Copy link

@jiexi
Copy link
Contributor Author

jiexi commented Oct 17, 2024

@metamaskbot update-policies

@metamaskbot
Copy link
Collaborator

Policies updated.
👀 Please review the diff for suspicious new powers.

🧠 Learn how: https://lavamoat.github.io/guides/policy-diff/#what-to-look-for-when-reviewing-a-policy-diff

@metamaskbot
Copy link
Collaborator

Builds ready [29d2381]
Page Load Metrics (1566 ± 46 ms)
PlatformPageMetricMin (ms)Max (ms)Average (ms)StandardDeviation (ms)MarginOfError (ms)
ChromeHomefirstPaint13691741157210450
domContentLoaded1361169415448943
load1370170315669646
domInteractive198937199
backgroundConnect55823168
firstReactRender15100473115
getState596222713
initialActions01000
loadScripts984124811368641
setupStore680192211
uiStartup155623301892225108
Bundle size diffs [🚨 Warning! Bundle size has increased!]
  • background: 15.13 KiB (0.26%)
  • ui: 691 Bytes (0.01%)
  • common: 132.64 KiB (1.57%)

app/scripts/metamask-controller.js Show resolved Hide resolved
app/scripts/metamask-controller.js Show resolved Hide resolved
app/scripts/migrations/138.ts Show resolved Hide resolved
app/scripts/migrations/138.ts Show resolved Hide resolved
app/scripts/migrations/138.ts Outdated Show resolved Hide resolved
app/scripts/migrations/138.ts Show resolved Hide resolved
app/scripts/migrations/138.ts Outdated Show resolved Hide resolved
app/scripts/migrations/138.ts Show resolved Hide resolved
app/scripts/migrations/138.ts Outdated Show resolved Hide resolved
@metamaskbot
Copy link
Collaborator

Builds ready [2f0a4e5]
Page Load Metrics (1637 ± 74 ms)
PlatformPageMetricMin (ms)Max (ms)Average (ms)StandardDeviation (ms)MarginOfError (ms)
ChromeHomefirstPaint32419611579323155
domContentLoaded13981951160615273
load14011960163715474
domInteractive19164423216
backgroundConnect578322411
firstReactRender15100322512
getState4371094
initialActions01000
loadScripts10131560121013565
setupStore656182010
uiStartup16752255186917483
Bundle size diffs [🚨 Warning! Bundle size has increased!]
  • background: 16.22 KiB (0.28%)
  • ui: 691 Bytes (0.01%)
  • common: 132.64 KiB (1.57%)

app/scripts/migrations/138.test.ts Outdated Show resolved Hide resolved
ui/ducks/bridge/selectors.ts Outdated Show resolved Hide resolved
@@ -60,7 +60,7 @@ export const EditAccountsModal: React.FC<EditAccountsModalProps> = ({

useEffect(() => {
setSelectedAccountAddresses(defaultSelectedAccountAddresses);
}, [defaultSelectedAccountAddresses]);
}, [JSON.stringify(defaultSelectedAccountAddresses)]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this being stringified? Both here and in edit-networks-modal, I see the same change made in both places

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this change can be moved into main. It's because this component can sometimes rerender while you're using it and your checkboxes get overwritten with the default selected again

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: I think this can be made separately against main as well

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: The changes here and in switch-custom-network can probably be reverted (I think they were needed for the previous version of withPermissionControllerConnectedToTestDapp)

.sort();

assert.deepStrictEqual(grantedPermissionNames, [
'endowment:permitted-chains',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Recording something we discussed on a call: We should verify whether the order has changed here

'0xbee150bdc171c7d4190891e78234f791a3ac7b24',
'0xa5c5293e124d04e2f85e8553851001fd2f192647',
'0xb9504634e5788208933b51ae7440b478bfadf865',
'eip155:1337:0xbee150bdc171c7d4190891e78234f791a3ac7b24',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These prefixes don't need to be here, they're added by the migration

@@ -1257,16 +1252,16 @@ class FixtureBuilder {
},
],
date: 1708029792962,
id: 'oKXoF_MNlffiR2u1Y3mDE',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Maybe we can revert these re-order changes to minimize the diff

@@ -657,6 +643,11 @@ class FixtureBuilder {
lastSelected: 1665507800000,
name: 'Account 2',
},
[ERC_4337_ACCOUNT]: {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curious why this was added

await new TestDapp(driver).openTestDappPage();

await driver.findClickableElement({ text: 'Connect', tag: 'button' });
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: I see that the changes here are different than the prior file, despite the changes being similar in nature. The previous file uses connectAccount on the test dapp instance rather than running these connect steps one by one. Worth considering which approach we prefer, if they are indeed equivalent.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants