Skip to content

Eip 7702 #5988

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

Merged
merged 56 commits into from
May 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
f08c6ec
update to ethers v6 with eip 7702
yann300 Apr 25, 2025
0b67f36
update ethereumjs to 10.0.0
yann300 Apr 29, 2025
5a5a675
yarn ethers6/ethereumjs10
yann300 Apr 29, 2025
19bb2c5
fix using ethereumjs 10 api
yann300 Apr 29, 2025
9e8da22
fix e2e
yann300 Apr 29, 2025
32e2216
use ethers 6.13.7
yann300 May 1, 2025
15dcf86
merge import and remove console.log
yann300 May 2, 2025
4ae109b
add pectra
yann300 Mar 9, 2025
c45750d
eip 7702
yann300 Mar 10, 2025
b190247
eip7702 use viem
yann300 Apr 24, 2025
80cf76b
add contract designation UI
yann300 Apr 24, 2025
84b3068
use prague for k id
yann300 Apr 28, 2025
c36eb0b
UI for delegation authorization
yann300 Apr 28, 2025
0ef15ea
fix using authorizationList
yann300 Apr 28, 2025
32897f0
fix issues with eip 7702 impl
yann300 May 1, 2025
5ddc25f
Merge remote-tracking branch 'origin/master' into eip_7702
yann300 May 2, 2025
4d97a63
add more tests
yann300 May 5, 2025
a2a0872
fix label
yann300 May 5, 2025
04f8b95
using fix v10
yann300 May 5, 2025
96d0305
fix test
yann300 May 5, 2025
5048538
adding a template
yann300 May 5, 2025
b1778d8
fix test
yann300 May 5, 2025
90935ed
fix logging tx logs
yann300 May 6, 2025
3525620
update README.md
yann300 May 6, 2025
f6879ae
linting
yann300 May 6, 2025
4efa34e
linting & fix debuggin
yann300 May 6, 2025
8ebdea4
linting and labels
yann300 May 6, 2025
7621ddb
bug fix
yann300 May 6, 2025
f2b80e6
enable for vm-mainnet-fork and update label
yann300 May 6, 2025
d7d0755
Merge remote-tracking branch 'origin/master' into eip_7702
yann300 May 6, 2025
b2086d9
add contract instead of import
yann300 May 6, 2025
a94ac89
update label and misc changes
yann300 May 7, 2025
bdb766e
small reset fix
bunsenstraat May 7, 2025
dd933cc
timeouts
bunsenstraat May 7, 2025
a9947f5
force 135
bunsenstraat May 7, 2025
e586dbb
fix script
bunsenstraat May 7, 2025
753b6ea
chrome
bunsenstraat May 7, 2025
8c4e2f9
turn off linux test
bunsenstraat May 7, 2025
9d00c2a
add pause
bunsenstraat May 7, 2025
4f4680e
ethers 6 and misc chanages
yann300 May 7, 2025
5b1d9c8
add matomo
yann300 May 7, 2025
cd26c85
fix label & hide component
yann300 May 7, 2025
259c13f
fix label
yann300 May 7, 2025
d120a3b
use info instead of log, update label
yann300 May 7, 2025
f963ed7
fix tests
yann300 May 7, 2025
fed51c7
improve term deets
Aniket-Engg May 5, 2025
243b37c
fix
Aniket-Engg May 6, 2025
e2c0bc4
rafactor and paymster
Aniket-Engg May 6, 2025
1fff0a0
show correct to address
Aniket-Engg May 6, 2025
71f1960
linting fix
Aniket-Engg May 6, 2025
3ecaff8
add event signature
Aniket-Engg May 7, 2025
90ebc56
update known tx too
Aniket-Engg May 7, 2025
5364a9b
sol and evm
Aniket-Engg May 7, 2025
4803789
fix e2e
Aniket-Engg May 7, 2025
111b6f3
fix test
yann300 May 7, 2025
3f8bcad
Merge remote-tracking branch 'origin/master' into eip_7702
yann300 May 7, 2025
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
1 change: 1 addition & 0 deletions apps/remix-dapp/src/locales/en/udapp.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
"udapp.createSmartAccountDesc4":"Smart Account will by default have a PAYMASTER attached to it to execute GASLESS transactions, only for SEPOLIA testnet. ",
"udapp.createSmartAccountDesc5":"Smart Account creation will require signing of an initial transaction at next step.",
"udapp.continue": "Continue",
"udapp.authorize": "Authorize",
"udapp.createNewAccount": "Create a new account",
"udapp.web3Title": "Creating an account is possible only in Personal mode. Please go to Settings to enable it.",
"udapp.defaultTitle": "Unfortunately it's not possible to create an account using an external wallet ({selectExEnv}).",
Expand Down
2 changes: 1 addition & 1 deletion apps/remix-ide-e2e/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"npm": "^6.14.15"
},
"dependencies": {
"ethers": "^6.13.7",
"ethers": "^6.14.0",
"@openzeppelin/contracts": "^5.0.2",
"@openzeppelin/contracts-upgradeable": "^5.0.2",
"@openzeppelin/upgrades-core": "^1.30.0",
Expand Down
74 changes: 74 additions & 0 deletions apps/remix-ide-e2e/src/tests/eip7702.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
'use strict'

import { NightwatchBrowser } from 'nightwatch'
import init from '../helpers/init'

module.exports = {
'@disabled': true,
before: function (browser: NightwatchBrowser, done: VoidFunction) {
init(browser, done)
},
'Should activate delegation and make a transaction to the authority address #group1': function (browser: NightwatchBrowser) {
let addressDelegate
browser
.clickLaunchIcon('udapp')
.switchEnvironment('vm-pectra')
.addFile('delegate.sol', { content: delegate })
.clickLaunchIcon('solidity')
.setSolidityCompilerVersion('soljson-v0.8.28+commit.7893614a.js')
.clickLaunchIcon('solidity')
.verifyContracts(['TestDelegate'])
.clickLaunchIcon('udapp')
.selectContract('Simple7702Account')
.createContract('')
.perform((done) => {
browser.getAddressAtPosition(0, (address) => {
addressDelegate = address
done()
})
})
.click('[data-id="deployAndRunClearInstances"]')
.perform((done) => {
browser
.click('*[data-id="create-delegation-authorization"]')
.waitForElementVisible('*[data-id="create-delegation-authorization-input"]')
.execute(() => {
(document.querySelector('*[data-id="create-delegation-authorization-input"]') as any).focus()
}, [], () => {})
.setValue('*[data-id="create-delegation-authorization-input"]', addressDelegate)
.perform(() => done())
})
.modalFooterOKClick('udappNotify')
.waitForElementContainsText('*[data-id="terminalJournal"]', 'This account will be running the code located at')
.clickInstance(0)
.clickFunction('entryPoint - call')
.verifyCallReturnValue('0x5B38Da6a701c568545dCfcB03FcB875f56beddC4', ['0:address: 0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108'])
},

'Should keep the delegation status after reloae & switching accounts #group1': function (browser: NightwatchBrowser) {
browser
.refresh()
.clickLaunchIcon('udapp')
.switchEnvironment('vm-pectra')
.waitForElementVisible('*[data-id="delete-delegation"]')
.selectAccount('0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2')
.waitForElementNotPresent('*[data-id="delete-delegation"]')
.selectAccount('0x5B38Da6a701c568545dCfcB03FcB875f56beddC4')
.waitForElementVisible('*[data-id="delete-delegation"]')
},

'Should remove the delegation #group1': function (browser: NightwatchBrowser) {
browser
.waitForElementVisible('*[data-id="delete-delegation"]')
.click('*[data-id="delete-delegation"]')
.modalFooterOKClick('udappNotify')
.waitForElementNotPresent('*[data-id="delete-delegation"]')
.waitForElementContainsText('*[data-id="terminalJournal"]', `Delegation for 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4 removed.`)
.refresh()
.clickLaunchIcon('udapp')
.switchEnvironment('vm-pectra')
.waitForElementNotPresent('*[data-id="delete-delegation"]')
}
}

const delegate = `import "https://github.com/eth-infinitism/account-abstraction/blob/v0.8.0/contracts/accounts/Simple7702Account.sol";`
4 changes: 3 additions & 1 deletion apps/remix-ide/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import { StoragePlugin } from './app/plugins/storage'
import { Layout } from './app/panels/layout'
import { NotificationPlugin } from './app/plugins/notification'
import { Blockchain } from './blockchain/blockchain'
import { MergeVMProvider, LondonVMProvider, BerlinVMProvider, ShanghaiVMProvider, CancunVMProvider } from './app/providers/vm-provider'
import { MergeVMProvider, LondonVMProvider, BerlinVMProvider, ShanghaiVMProvider, CancunVMProvider, PectraVMProvider } from './app/providers/vm-provider'
import { MainnetForkVMProvider } from './app/providers/mainnet-vm-fork-provider'
import { SepoliaForkVMProvider } from './app/providers/sepolia-vm-fork-provider'
import { GoerliForkVMProvider } from './app/providers/goerli-vm-fork-provider'
Expand Down Expand Up @@ -341,6 +341,7 @@ class AppComponent {
const vmProviderGoerliFork = new GoerliForkVMProvider(blockchain)
const vmProviderShanghai = new ShanghaiVMProvider(blockchain)
const vmProviderCancun = new CancunVMProvider(blockchain)
const vmProviderPectra = new PectraVMProvider(blockchain)
const vmProviderMerge = new MergeVMProvider(blockchain)
const vmProviderBerlin = new BerlinVMProvider(blockchain)
const vmProviderLondon = new LondonVMProvider(blockchain)
Expand Down Expand Up @@ -417,6 +418,7 @@ class AppComponent {
storagePlugin,
vmProviderShanghai,
vmProviderCancun,
vmProviderPectra,
vmProviderMerge,
vmProviderBerlin,
vmProviderLondon,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ export const templates = (intl, plugin) => {
name: "Generic",
items: [
{ value: "remixDefault", tagList: ["Solidity"], displayName: intl.formatMessage({ id: 'filePanel.basic' }), description: 'The default project' },
{ value: "blank", displayName: intl.formatMessage({ id: 'filePanel.blank' }), IsArtefact: true, description: 'A blank project' }
{ value: "blank", displayName: intl.formatMessage({ id: 'filePanel.blank' }), IsArtefact: true, description: 'A blank project' },
{ value: "simpleEip7702", displayName: 'Simple EIP 7702', IsArtefact: true, description: 'Pectra upgrade allowing externally owner accounts (EOAs) to run contract code.' },
{ value: "accountAbstraction", displayName: 'Account Abstraction Template', IsArtefact: true, description: 'Experiment with Account Abstraction contracts: (ERC-4337, EIP-7702)' }
]
},
{
Expand Down
18 changes: 18 additions & 0 deletions apps/remix-ide/src/app/providers/vm-provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,24 @@ export class CancunVMProvider extends BasicVMProvider {
}
}

export class PectraVMProvider extends BasicVMProvider {
constructor(blockchain) {
super(
{
name: 'vm-pectra',
displayName: 'Remix VM (Pectra)',
kind: 'provider',
description: 'Remix VM (Pectra)',
methods: ['sendAsync', 'init'],
version: packageJson.version
},
blockchain
)
this.blockchain = blockchain
this.fork = 'prague'
}
}

export class ForkedVMStateProvider extends BasicVMProvider {
nodeUrl?: string
blockNumber?: string
Expand Down
8 changes: 7 additions & 1 deletion apps/remix-ide/src/app/tabs/locales/en/udapp.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
"udapp.createSmartAccountDesc4":"Smart Account will by default have a PAYMASTER attached to it to execute GASLESS transactions, only for SEPOLIA testnet. ",
"udapp.createSmartAccountDesc5":"Smart Account creation will require signing of an initial transaction at next step.",
"udapp.continue": "Continue",
"udapp.authorize": "Authorize",
"udapp.createNewAccount": "Create new account",
"udapp.web3Title": "Creating an account is possible only in Personal mode. Please go to Settings to enable it.",
"udapp.defaultTitle": "Unfortunately it's not possible to create an account using an external wallet ({selectExEnv}).",
Expand Down Expand Up @@ -186,5 +187,10 @@
"udapp.EIP712-3": "In Remix, signing typed data is possible by right clicking (right click / Sign Typed Data) on a JSON file whose content is EIP-712 compatible.",
"udapp.EIP712-create-template": "Create a JSON compliant with EIP-712",
"udapp.EIP712-close": "Close",
"udapp.sign": "Sign"
"udapp.sign": "Sign",

"udapp.createDelegationAuthorization": "Connect EOA to contract code (EIP 7702)",
"udapp.createDelegationTitle": "Connect EOA to contract code (EIP 7702)",
"udapp.removeDelegationTitle": "Remove contract delegation (EIP 7702)",
"udapp.createDelegationDescription": "Authorize a delegation between the current EOA and the contract code at the provided address. The contract must be deployed in the current chain."
}
36 changes: 1 addition & 35 deletions apps/remix-ide/src/app/tabs/web3-provider.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,41 +77,7 @@ export class Web3ProviderModule extends Plugin {
await this.call('compilerArtefacts', 'addResolvedContract', contractAddressStr, data)
}
}, 50)
const provider = this.blockchain.executionContext.getProviderObject()

// a basic in-browser VM state.
const isBasicVMState = provider.config.isVM && !provider.config.isVMStateForked && !provider.config.isRpcForkedState
// a standard fork of an in-browser state.
const isForkedVMState = provider.config.isVM && provider.config.isVMStateForked && !provider.config.isRpcForkedState
// a fork of an in-browser state which derive from a live network.
const isForkedRpcState = provider.config.isVM && provider.config.isVMStateForked && provider.config.isRpcForkedState

if (isBasicVMState || isForkedVMState || isForkedRpcState) {
if (this.blockchain.config.get('settings/save-evm-state')) {
try {
let state = await this.blockchain.executionContext.getStateDetails()
if (provider.config.statePath) {
const stateFileExists = await this.call('fileManager', 'exists', provider.config.statePath)
if (stateFileExists) {
let stateDetails = await this.call('fileManager', 'readFile', provider.config.statePath)
stateDetails = JSON.parse(stateDetails)
state = JSON.parse(state)
state['stateName'] = stateDetails.stateName
state['forkName'] = stateDetails.forkName
state['savingTimestamp'] = stateDetails.savingTimestamp
state = JSON.stringify(state, null, 2)
}
this.call('fileManager', 'writeFile', provider.config.statePath, state)
} else if (isBasicVMState && !isForkedRpcState && !isForkedRpcState) {
// in that case, we store the state only if it is a basic VM.
const provider = this.blockchain.executionContext.getProvider()
this.call('fileManager', 'writeFile', `.states/${provider}/state.json`, state)
}
} catch (e) {
console.error(e)
}
}
}
await this.call('blockchain', 'dumpState')
}
}
resolve(message)
Expand Down
10 changes: 6 additions & 4 deletions apps/remix-ide/src/app/udapp/run-tab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ export class RunTab extends ViewPlugin {
'vm-paris': 'Deploy to the in-browser virtual machine running the Paris fork.',
'vm-london': 'Deploy to the in-browser virtual machine running the London fork.',
'vm-berlin': 'Deploy to the in-browser virtual machine running the Berlin fork.',
'vm-pectra': 'Deploy to the in-browser virtual machine running the Prague fork.',
'vm-mainnet-fork': 'Deploy to a fork of the Ethereum mainnet latest block in the in-browser virtual machine.',
'vm-sepolia-fork': 'Deploy to a fork of the Sepolia testnet latest block in the in-browser virtual machine.',
'vm-custom-fork': 'Deploy to a fork of a custom network in the in-browser virtual machine.',
Expand Down Expand Up @@ -261,14 +262,15 @@ export class RunTab extends ViewPlugin {

// VM
const titleVM = 'Execution environment is local to Remix. Data is only saved to browser memory and will vanish upon reload.'
await addProvider(1, 'vm-cancun', 'Remix VM (Cancun)', { isInjected: false, isVM: true, isRpcForkedState: false, statePath: '.states/vm-cancun/state.json', fork: 'cancun' }, 'settingsVMCancunMode', titleVM)
await addProvider(1, 'vm-pectra', 'Remix VM (Pectra)', { isInjected: false, isVM: true, isRpcForkedState: false, statePath: '.states/vm-pectra/state.json', fork: 'prague' }, 'settingsVMPectraMode', titleVM)
await addProvider(2, 'vm-cancun', 'Remix VM (Cancun)', { isInjected: false, isVM: true, isRpcForkedState: false, statePath: '.states/vm-cancun/state.json', fork: 'cancun' }, 'settingsVMCancunMode', titleVM)
await addProvider(50, 'vm-shanghai', 'Remix VM (Shanghai)', { isInjected: false, isVM: true, isRpcForkedState: false, statePath: '.states/vm-shanghai/state.json', fork: 'shanghai' }, 'settingsVMShanghaiMode', titleVM)
await addProvider(51, 'vm-paris', 'Remix VM (Paris)', { isInjected: false, isVM: true, isRpcForkedState: false, statePath: '.states/vm-paris/state.json', fork: 'paris' }, 'settingsVMParisMode', titleVM)
await addProvider(52, 'vm-london', 'Remix VM (London)', { isInjected: false, isVM: true, isRpcForkedState: false, statePath: '.states/vm-london/state.json', fork: 'london' }, 'settingsVMLondonMode', titleVM)
await addProvider(53, 'vm-berlin', 'Remix VM (Berlin)', { isInjected: false, isVM: true, isRpcForkedState: false, statePath: '.states/vm-berlin/state.json', fork: 'berlin' }, 'settingsVMBerlinMode', titleVM)
await addProvider(2, 'vm-mainnet-fork', 'Remix VM - Mainnet fork', { isInjected: false, isVM: true, isVMStateForked: true, isRpcForkedState: true, fork: 'cancun' }, 'settingsVMMainnetMode', titleVM)
await addProvider(3, 'vm-sepolia-fork', 'Remix VM - Sepolia fork', { isInjected: false, isVM: true, isVMStateForked: true, isRpcForkedState: true, fork: 'cancun' }, 'settingsVMSepoliaMode', titleVM)
await addProvider(4, 'vm-custom-fork', 'Remix VM - Custom fork', { isInjected: false, isVM: true, isVMStateForked: true, isRpcForkedState: true, fork: '' }, 'settingsVMCustomMode', titleVM)
await addProvider(3, 'vm-mainnet-fork', 'Remix VM - Mainnet fork', { isInjected: false, isVM: true, isVMStateForked: true, isRpcForkedState: true, fork: 'cancun' }, 'settingsVMMainnetMode', titleVM)
await addProvider(4, 'vm-sepolia-fork', 'Remix VM - Sepolia fork', { isInjected: false, isVM: true, isVMStateForked: true, isRpcForkedState: true, fork: 'cancun' }, 'settingsVMSepoliaMode', titleVM)
await addProvider(5, 'vm-custom-fork', 'Remix VM - Custom fork', { isInjected: false, isVM: true, isVMStateForked: true, isRpcForkedState: true, fork: '' }, 'settingsVMCustomMode', titleVM)

// Forked VM States
const addFVSProvider = async(stateFilePath, pos) => {
Expand Down
Loading