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: CAIP Multichain (New) #27782

Draft
wants to merge 426 commits into
base: caip25-permission-migration
Choose a base branch
from

Conversation

jiexi
Copy link
Contributor

@jiexi jiexi commented Oct 10, 2024

Description

This branch is the feature branch for CAIP-25, CAIP-27, CAIP stream bifurcation. TODO better PR desc.

Open in GitHub Codespaces

Related issues

Related: MetaMask/core#4813
Upstream: #27847

See: https://github.com/MetaMask/MetaMask-planning/issues/2360
See: MetaMask/test-dapp#324

Manual testing steps

yarn start:flask

Replace EXTENSION_ID with your local extension ID

// Setup
const EXTENSION_ID = 'nonfpcflonapegmnfeafnddgdniflbnk';
const extensionPort = chrome.runtime.connect(EXTENSION_ID)
extensionPort.onMessage.addListener((msg) => {
    // format wallet_notify events nicely so that we can read them more easily later
    if (msg.data.method === 'wallet_notify') {
        console.log('wallet_notify:', {
            scope: msg.data.params.scope,
            method: msg.data.params.notification.method,
            subscription: msg.data.params.notification.params.subscription,
            number: msg.data.params.notification.params.result.number
        })
        return;
    }
    console.log(msg.data)
})


// Initial Connection
extensionPort.postMessage({
    type: 'caip-x',
    data: {
        "jsonrpc": "2.0",
        method: 'wallet_createSession',
        params: {
            requiredScopes: {
            },
            optionalScopes: {
                'eip155:1': {
                    methods: [
                        'eth_blockNumber',
                        'eth_gasPrice',
                        'eth_getTransactionCount'
                    ],
                    notifications: [],
                    accounts: []
                }
            },
        },
    }
})


extensionPort.postMessage({
    type: 'caip-x',
    data: {
        "jsonrpc": "2.0",
        method: 'wallet_invokeMethod',
        params: {
            scope: 'eip155:1',
            request: {
                "method": "eth_blockNumber",
                "params": [],
            }
        }
    }
})

extensionPort.postMessage({
    type: 'caip-x',
    data: {
        "jsonrpc": "2.0",
        method: 'wallet_invokeMethod',
        params: {
            scope: 'eip155:1',
            request: {
                "method": "eth_gasPrice",
                "params": [],
            }
        }
    }
})

extensionPort.postMessage({
    type: 'caip-x',
    data: {
        "jsonrpc": "2.0",
        method: 'wallet_invokeMethod',
        params: {
            scope: 'eip155:1',
            request: {
                "method": "eth_getTransactionCount",
                "params": ["0x5bA08AF1bc30f17272178bDcACA1C74e94955cF4", "latest"],
            }
        }
    }
})

// Not very interesting, let’s do this on Sepolia where I have some tx

extensionPort.postMessage({
    type: 'caip-x',
    data: {
        "jsonrpc": "2.0",
        method: 'wallet_invokeMethod',
        params: {
            scope: 'eip155:11155111',
            request: {
                "method": "eth_getTransactionCount",
                "params": ["0x5bA08AF1bc30f17272178bDcACA1C74e94955cF4", "latest"],
            }
        }
    }
})


// Oh no, an error. Let’s fix that
extensionPort.postMessage({
    type: 'caip-x',
    data: {
        "jsonrpc": "2.0",
        method: 'wallet_createSession',
        params: {
            requiredScopes: {
            },
            optionalScopes: {
                'eip155:1': {
                    methods: [
                        'eth_blockNumber',
                        'eth_gasPrice',
                        'eth_getTransactionCount'
                    ],
                    notifications: [],
                    accounts: []
                },
                'eip155:11155111': {
                    methods: [
                        'eth_blockNumber',
                        'eth_gasPrice',
                        'eth_getTransactionCount'
                    ],
                    notifications: [],
                    accounts: []
                }
            },
        },
    }
})

// And try again
extensionPort.postMessage({
    type: 'caip-x',
    data: {
        "jsonrpc": "2.0",
        method: 'wallet_invokeMethod',
        params: {
            scope: 'eip155:11155111',
            request: {
                "method": "eth_getTransactionCount",
                "params": ["0x5bA08AF1bc30f17272178bDcACA1C74e94955cF4", "latest"],
            }
        }
    }
})

// What if I want even more chains and methods and subscriptions and preselected accounts?
extensionPort.postMessage({
    type: 'caip-x',
    data: {
        "jsonrpc": "2.0",
        method: 'wallet_createSession',
        params: {
            requiredScopes: {
            },
            optionalScopes: {
                'eip155:1': {
                    methods: [
                        'eth_blockNumber',
                        'eth_gasPrice',
                        'eth_getTransactionCount',
                        'eth_sendTransaction', 
                        'eth_subscribe'
                    ],
                    notifications: ['eth_subscription'],
                    accounts: []
                },
                'eip155:11155111': {
                    methods: [
                        'eth_blockNumber',
                        'eth_gasPrice',
                        'eth_getTransactionCount',
                        'eth_sendTransaction', 
                        'eth_subscribe'
                    ],
                    notifications: ['eth_subscription'],
                    accounts: ['eip155:11155111:0x5bA08AF1bc30f17272178bDcACA1C74e94955cF4', 'eip155:11155111:0xEe166a3eec4796DeC6A1D314e7485a52bBe68e4d']
                },
                'eip155:59144': {
                    methods: [
                        'eth_estimateGas',
                    ],
                    notifications: [],
                    accounts: []
                },
            },
        },
    }
})










// What if I want to deny some requested chains and add extras?
// Rerun above, Remove Linea, add Linea Sepolia. Show how the added chains get the full permission set


// My dapp that just loaded / I forgot what my permissions look like / I want to check what my permissions currently look like.
extensionPort.postMessage({
    type: 'caip-x',
    data: {
        "jsonrpc": "2.0",
        method: 'wallet_getSession',
        params:{}
    }
})

// What if the user modifies the permission outside of my dapp? How will I know without checking wallet_getSession frequently?
// Modify permission in page. Check for wallet_sessionChanged event


// What if I want to disconnect from the session entirely?
extensionPort.postMessage({
    type: 'caip-x',
    data: {
        "jsonrpc": "2.0",
        method: 'wallet_revokeSession',
        params:{}
    }
})


// Let’s send some transactions! On sepolia and linea sepolia

extensionPort.postMessage({
    type: 'caip-x',
    data: {
        "jsonrpc": "2.0",
        method: 'wallet_createSession',
        params: {
            requiredScopes: {
            },
            optionalScopes: {
                'eip155:1': {
                    methods: [
                        'eth_sendTransaction', 
                        'eth_subscribe'
                    ],
                    notifications: ['eth_subscription'],
                    accounts: []
                },
                'eip155:11155111': {
                    methods: [
                        'eth_sendTransaction', 
                        'eth_subscribe'
                    ],
                    notifications: ['eth_subscription'],
                    accounts: ['eip155:11155111:0x5bA08AF1bc30f17272178bDcACA1C74e94955cF4', 'eip155:11155111:0xEe166a3eec4796DeC6A1D314e7485a52bBe68e4d']
                },
                'eip155:59141': {
                    methods: [
                        'eth_sendTransaction',
                    ],
                    notifications: [],
                    accounts: []
                },
            },
        },
    }
})


extensionPort.postMessage({
    type: 'caip-x',
    data: {
        "jsonrpc": "2.0",
        method: 'wallet_invokeMethod',
        params: {
            scope: 'eip155:11155111',
            request: {
                "method": "eth_sendTransaction",
                 "params": [
                  {
                    from: "0x5bA08AF1bc30f17272178bDcACA1C74e94955cF4",
                    to: "0x0000000000000000000000000000000000000000",
                    gas: "0x76c0",
                    value: "0x2bdbb64bc09000",
                    data: "0x",
                  }
                ],
            }
        }
    }
})


extensionPort.postMessage({
    type: 'caip-x',
    data: {
        "jsonrpc": "2.0",
        method: 'wallet_invokeMethod',
        params: {
            scope: 'eip155:59141',
            request: {
                "method": "eth_sendTransaction",
                 "params": [
                  {
                    from: "0x5bA08AF1bc30f17272178bDcACA1C74e94955cF4",
                    to: "0x0000000000000000000000000000000000000000",
                    gas: "0x76c0",
                    value: "0x2bdbb64bc09000",
                    data: "0x",
                  }
                ],
            }
        }
    }
})

// You can even be receive eth subscriptions events on multiple chains at the same time, previously impossible.
extensionPort.postMessage({
    type: 'caip-x',
    data: {
        "jsonrpc": "2.0",
        method: 'wallet_invokeMethod',
        params: {
            scope: 'eip155:1',
            request: {
                "method": "eth_subscribe",
                 "params": [
                     "newHeads"
                ],
            }
        }
    }
})



extensionPort.postMessage({
    type: 'caip-x',
    data: {
        "jsonrpc": "2.0",
        method: 'wallet_invokeMethod',
        params: {
            scope: 'eip155:11155111',
            request: {
                "method": "eth_subscribe",
                 "params": [
                     "newHeads"
                ],
            }
        }
    }
})

Locked Wallet Behavior

  • wallet_getSession returns full session with all accounts
  • wallet_revokeSession works as usual
  • wallet_createSession prompts for unlock
  • wallet_invokeMethod on signature methods fails with method or accounts not authorized
  • wallet_invokeMethod on non-signature methods work as usual
  • wallet_sessionChanged not being fired when locked and revokeSession is called (TODO need to fix this). Is being fired when unlocked and revokeSession is called.

Wallet Onboarding Behavior (fresh install, not setup yet)

  • wallet_createSession causes wallet setup screen to be shown instead
  • all other methods work as expected
    • wallet_getSession returns no session since there is none
    • wallet_invokeMethod fails for everything since there is no active session

Screenshots/Recordings

Before

After

Pre-merge author checklist

  • I’ve followed MetaMask Coding Standards.
  • I've completed the PR template to the best of my ability
  • I’ve included tests if applicable
  • I’ve documented my code using JSDoc format if applicable
  • I’ve applied the right labels on the PR (see labeling guidelines). Not required for external contributors.

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.

jiexi and others added 30 commits August 20, 2024 14:29
# Conflicts:
#	lavamoat/browserify/beta/policy.json
#	lavamoat/browserify/flask/policy.json
#	lavamoat/browserify/main/policy.json
#	lavamoat/browserify/mmi/policy.json
This reverts commit bbbf8e5.
# Conflicts:
#	lavamoat/browserify/beta/policy.json
#	lavamoat/browserify/flask/policy.json
#	lavamoat/browserify/main/policy.json
#	lavamoat/browserify/mmi/policy.json
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

Misc cleanup. Removing `KnownCaipNamespace` is still not possible
because `@metamask/util` does not have a `Wallet` enum value

[![Open in GitHub
Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/26724?quickstart=1)

## **Related issues**

See: MetaMask/MetaMask-planning#3050

## **Manual testing steps**

1. Go to this page...
2.
3.

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->

### **After**

<!-- [screenshots/recordings] -->

## **Pre-merge author checklist**

- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I’ve included tests if applicable
- [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **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.
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

* Add metrics to `provider_authorize`
* Add jsdoc to `removeScope()`

[![Open in GitHub
Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/26699?quickstart=1)

## **Related issues**

See: MetaMask/MetaMask-planning#3049

## **Manual testing steps**

1. Go to this page...
2.
3.

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->

### **After**

<!-- [screenshots/recordings] -->

## **Pre-merge author checklist**

- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I’ve included tests if applicable
- [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **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.
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

Test cleanup chores

[![Open in GitHub
Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/26698?quickstart=1)

## **Related issues**

See: MetaMask/MetaMask-planning#3046

## **Manual testing steps**

1. Go to this page...
2.
3.

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->

### **After**

<!-- [screenshots/recordings] -->

## **Pre-merge author checklist**

- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I’ve included tests if applicable
- [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **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.
@jiexi
Copy link
Contributor Author

jiexi commented Dec 18, 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 [3222176]
Page Load Metrics (1689 ± 129 ms)
PlatformPageMetricMin (ms)Max (ms)Average (ms)StandardDeviation (ms)MarginOfError (ms)
ChromeHomefirstPaint33721511541466224
domContentLoaded136421391671262126
load137221541689268129
domInteractive25182433517
backgroundConnect106923168
firstReactRender15100483517
getState486262713
initialActions04010
loadScripts98816531241227109
setupStore688252613
uiStartup152728442085373179
Bundle size diffs [🚨 Warning! Bundle size has increased!]
  • background: 95.75 KiB (1.74%)
  • ui: 590 Bytes (0.01%)
  • common: 398.16 KiB (4.96%)

@metamaskbot
Copy link
Collaborator

Builds ready [3222176]
Page Load Metrics (1789 ± 93 ms)
PlatformPageMetricMin (ms)Max (ms)Average (ms)StandardDeviation (ms)MarginOfError (ms)
ChromeHomefirstPaint15262208180320598
domContentLoaded14822199175619694
load15382216178919393
domInteractive22174453316
backgroundConnect984422412
firstReactRender17101493115
getState487202210
initialActions00000
loadScripts10571676131217584
setupStore685202613
uiStartup181925342128239115
Bundle size diffs [🚨 Warning! Bundle size has increased!]
  • background: 95.75 KiB (1.74%)
  • ui: 590 Bytes (0.01%)
  • common: 398.16 KiB (4.96%)

@metamaskbot
Copy link
Collaborator

Builds ready [6662dd3]
Page Load Metrics (1821 ± 67 ms)
PlatformPageMetricMin (ms)Max (ms)Average (ms)StandardDeviation (ms)MarginOfError (ms)
ChromeHomefirstPaint15662046182513967
domContentLoaded15272001179313665
load15682044182114067
domInteractive25180513416
backgroundConnect1575342010
firstReactRender1697413015
getState587282814
initialActions01000
loadScripts11291581135111354
setupStore785272713
uiStartup180327872217335161
Bundle size diffs [🚨 Warning! Bundle size has increased!]
  • background: 95.75 KiB (1.74%)
  • ui: 590 Bytes (0.01%)
  • common: 398.16 KiB (4.96%)

Comment on lines +3158 to +3159
Object.entries(this.connections[origin]).forEach(
([_, { tabId }]) => {
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
Object.entries(this.connections[origin]).forEach(
([_, { tabId }]) => {
Object.values(this.connections[origin]).forEach(
({ tabId }) => {

seems like Object.entries is not necessary here since you are only using the value inside the loop and never the _ key.

@jiexi jiexi force-pushed the jl/caip-multichain-migrate-core branch from 939d897 to 069a8a7 Compare December 19, 2024 20:43
@metamaskbot
Copy link
Collaborator

Builds ready [0048c4d]
Page Load Metrics (1586 ± 49 ms)
PlatformPageMetricMin (ms)Max (ms)Average (ms)StandardDeviation (ms)MarginOfError (ms)
ChromeHomefirstPaint14071783157610953
domContentLoaded1397170115459947
load14081788158610349
domInteractive197433157
backgroundConnect14104482512
firstReactRender15100493718
getState592182411
initialActions01000
loadScripts1014129111388842
setupStore687182512
uiStartup165924131963250120
Bundle size diffs [🚨 Warning! Bundle size has increased!]
  • background: 90.55 KiB (1.61%)
  • ui: 691 Bytes (0.01%)
  • common: 340.55 KiB (4.08%)

@metamaskbot
Copy link
Collaborator

Builds ready [f478911]
Page Load Metrics (1537 ± 31 ms)
PlatformPageMetricMin (ms)Max (ms)Average (ms)StandardDeviation (ms)MarginOfError (ms)
ChromeHomefirstPaint1426168915346933
domContentLoaded1419166815096732
load1427168815376431
domInteractive226932126
backgroundConnect1085302110
firstReactRender15101433316
getState46516199
initialActions01000
loadScripts999124910906531
setupStore67513189
uiStartup16502161185417082
Bundle size diffs [🚨 Warning! Bundle size has increased!]
  • background: 90.55 KiB (1.61%)
  • ui: 691 Bytes (0.01%)
  • common: 340.56 KiB (4.06%)

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.

5 participants