diff --git a/.github/workflows/ci_4337.yml b/.github/workflows/ci_4337.yml index ce63df2b..df4b06f0 100644 --- a/.github/workflows/ci_4337.yml +++ b/.github/workflows/ci_4337.yml @@ -14,9 +14,9 @@ jobs: node-version: 20.x cache: npm cache-dependency-path: package-lock.json - - run: npm ci - - run: npm run build -w modules/4337 && npm run build:ts -w modules/4337 - - run: npm run coverage -w modules/4337 + - run: | + npm ci + npm run coverage -w modules/4337 - name: Coveralls uses: coverallsapp/github-action@master with: @@ -33,7 +33,7 @@ jobs: cache-dependency-path: package-lock.json - run: | npm ci - npm run test:e2e -w modules/4337 + npm run test:4337 -w modules/4337 lint: runs-on: ubuntu-latest steps: @@ -43,6 +43,7 @@ jobs: node-version: 20.x cache: npm cache-dependency-path: package-lock.json - - run: npm ci - - run: npm run lint -w modules/4337 - - run: npm run fmt:check -w modules/4337 + - run: | + npm ci + npm run lint -w modules/4337 + npm run fmt:check -w modules/4337 diff --git a/.github/workflows/ci_4337_gas_metering.yml b/.github/workflows/ci_4337_gas_metering.yml index c9abcb4d..0262192c 100644 --- a/.github/workflows/ci_4337_gas_metering.yml +++ b/.github/workflows/ci_4337_gas_metering.yml @@ -15,7 +15,8 @@ jobs: node-version: 20.x cache: npm cache-dependency-path: package-lock.json - - run: npm ci - - run: npm run fmt:check -w examples/4337-gas-metering - - run: npm run lint -w examples/4337-gas-metering - - run: npm run build -w examples/4337-gas-metering + - run: | + npm ci + npm run fmt:check -w examples/4337-gas-metering + npm run lint -w examples/4337-gas-metering + npm run build -w examples/4337-gas-metering diff --git a/.github/workflows/ci_4337_local_bundler.yml b/.github/workflows/ci_4337_local_bundler.yml new file mode 100644 index 00000000..2e8df3eb --- /dev/null +++ b/.github/workflows/ci_4337_local_bundler.yml @@ -0,0 +1,19 @@ +name: safe-modules-4337-local-bundler +on: + push: + paths: + - 'packages/4337-local-bundler/**' + +jobs: + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 20.x + cache: npm + cache-dependency-path: package-lock.json + - run: | + npm ci + npm run lint diff --git a/.github/workflows/ci_4337_upstream_bundler.yml b/.github/workflows/ci_4337_upstream_bundler.yml index ba60471a..fb337c91 100644 --- a/.github/workflows/ci_4337_upstream_bundler.yml +++ b/.github/workflows/ci_4337_upstream_bundler.yml @@ -1,4 +1,4 @@ -name: 4337 Module End-to-End Tests With Upstream Bundler +name: 4337 End-to-End Tests With Upstream Bundler on: schedule: # * is a special character in YAML so you have to quote this string @@ -7,6 +7,9 @@ on: push: paths: - 'modules/4337/**' + - 'modules/passkey/**' + - 'packages/4337-local-bundler/**' + jobs: e2e-upstream-bundler: @@ -20,4 +23,5 @@ jobs: cache-dependency-path: package-lock.json - run: | npm ci - npm run test:e2e:upstream -w modules/4337 + npm run test:4337:upstream -w modules/4337 + npm run test:4337:upstream -w modules/passkey diff --git a/.github/workflows/ci_passkey_example.yml b/.github/workflows/ci_passkey_example.yml index 9bd7f05c..57ac18d6 100644 --- a/.github/workflows/ci_passkey_example.yml +++ b/.github/workflows/ci_passkey_example.yml @@ -17,10 +17,6 @@ jobs: cache: npm cache-dependency-path: package-lock.json - run: | - npm ci - # Build the 4337 module so the app can use the artifacts - npm run build -w modules/4337 - # Reinstall the dependencies so the 4337 dependency includes artifacts npm ci npm run lint -w examples/4337-passkeys npm run build -w examples/4337-passkeys diff --git a/modules/4337/docker-compose.yaml b/modules/4337/docker-compose.yaml deleted file mode 100644 index fee33d68..00000000 --- a/modules/4337/docker-compose.yaml +++ /dev/null @@ -1,35 +0,0 @@ -version: '3.8' - -services: - geth: - image: docker.io/ethereum/client-go:stable - restart: always - environment: - GETH_DEV: 'true' - GETH_HTTP: 'true' - GETH_HTTP_ADDR: '0.0.0.0' - GETH_HTTP_API: 'personal,eth,net,web3,debug' - GETH_HTTP_VHOSTS: '*' - GETH_RPC_ALLOW_UNPROTECTED_TXS: 'true' - ports: - - 8545:8545 - - bundler: - build: - context: . - dockerfile: docker/bundler/Dockerfile - restart: always - command: ['--auto', '--network=http://geth:8545'] - ports: - - 3000:3000 - - bundler-upstream: - build: - context: . - dockerfile: docker/bundler/Dockerfile - args: - TAG: main - restart: always - command: ['--auto', '--network=http://geth:8545'] - ports: - - 3000:3000 diff --git a/modules/4337/docker/bundler/Dockerfile b/modules/4337/docker/bundler/Dockerfile deleted file mode 100644 index 86b79b9f..00000000 --- a/modules/4337/docker/bundler/Dockerfile +++ /dev/null @@ -1,12 +0,0 @@ -FROM docker.io/library/node:18 - -# v0.7.0 -ARG TAG=26e4f4c -RUN git clone https://github.com/eth-infinitism/bundler /src/bundler -WORKDIR /src/bundler -RUN git checkout ${TAG} -RUN git submodule init && git submodule update - -RUN yarn && yarn preprocess -ENTRYPOINT ["yarn", "bundler"] -CMD [] diff --git a/modules/4337/hardhat.config.ts b/modules/4337/hardhat.config.ts index 08df57c3..b257fd3d 100644 --- a/modules/4337/hardhat.config.ts +++ b/modules/4337/hardhat.config.ts @@ -67,11 +67,11 @@ const userConfig: HardhatUserConfig = { networks: { localhost: { url: 'http://localhost:8545', - tags: ['dev', 'safe'], + tags: ['dev', 'entrypoint', 'safe'], }, hardhat: { gasPrice: 10000000000, - tags: ['test'], + tags: ['test', 'entrypoint', 'safe'], }, mainnet: { ...sharedNetworkConfig, @@ -88,12 +88,12 @@ const userConfig: HardhatUserConfig = { sepolia: { ...sharedNetworkConfig, url: `https://sepolia.infura.io/v3/${INFURA_KEY}`, - tags: ['dev'], + tags: ['dev', 'entrypoint'], }, amoy: { ...sharedNetworkConfig, url: `https://polygon-amoy.infura.io/v3/${INFURA_KEY}`, - tags: ['dev'], + tags: ['dev', 'entrypoint'], }, ...customNetwork, }, diff --git a/modules/4337/package.json b/modules/4337/package.json index 0212efa0..c0283062 100644 --- a/modules/4337/package.json +++ b/modules/4337/package.json @@ -18,9 +18,9 @@ "build:ts": "npx rimraf dist && tsc", "build:sol": "npx rimraf build && hardhat compile", "test": "hardhat test --deploy-fixture", - "test:e2e": "./test/e2e/run.sh", - "test:e2e:upstream": "USE_UPSTREAM_BUNDLER=1 ./test/e2e/run.sh", - "test:all": "npm run test && npm run test:e2e", + "test:4337": "4337-local-bundler-test", + "test:4337:upstream": "USE_UPSTREAM_BUNDLER=1 4337-local-bundler-test", + "test:all": "npm run test && npm run test:4337", "coverage": "hardhat coverage", "codesize": "hardhat codesize", "benchmark": "npm run test benchmark/*.ts", @@ -54,6 +54,7 @@ "@noble/curves": "^1.3.0", "@nomicfoundation/hardhat-toolbox": "^4.0.0", "@openzeppelin/contracts": "^5.0.2", + "@safe-global/safe-4337-local-bundler": "^0.0.0", "@simplewebauthn/server": "9.0.0", "@types/chai": "^4.3.11", "@types/mocha": "^10.0.6", @@ -63,8 +64,8 @@ "debug": "^4.3.4", "dotenv": "^16.4.4", "ethers": "^6.11.1", - "hardhat": "^2.20.1", - "hardhat-deploy": "0.11.45", + "hardhat": "^2.21.0", + "hardhat-deploy": "^0.12.1", "husky": "^9.0.11", "solc": "^0.8.24", "solhint": "^4.1.1", diff --git a/modules/4337/src/deploy/entrypoint.ts b/modules/4337/src/deploy/entrypoint.ts index ff22afb7..39787c57 100644 --- a/modules/4337/src/deploy/entrypoint.ts +++ b/modules/4337/src/deploy/entrypoint.ts @@ -1,25 +1,3 @@ -import EntryPoint from '@account-abstraction/contracts/artifacts/EntryPoint.json' -import { DeployFunction } from 'hardhat-deploy/types' +import { deployEntryPoint } from '@safe-global/safe-4337-local-bundler' -const ENTRY_POINT = process.env.DEPLOYMENT_ENTRY_POINT_ADDRESS - -const deploy: DeployFunction = async ({ deployments, getNamedAccounts, network }) => { - const { deployer } = await getNamedAccounts() - const { deploy } = deployments - - if (network.tags.dev || network.tags.test) { - await deploy('EntryPoint', { - from: deployer, - contract: EntryPoint, - args: [], - log: true, - deterministicDeployment: '0x90d8084deab30c2a37c45e8d47f49f2f7965183cb6990a98943ef94940681de3', - }) - } else if (!ENTRY_POINT) { - throw new Error('DEPLOYMENT_ENTRY_POINT_ADDRESS must be set') - } -} - -deploy.tags = ['entrypoint'] - -export default deploy +export default deployEntryPoint \ No newline at end of file diff --git a/modules/4337/src/deploy/webauthn.ts b/modules/4337/src/deploy/experimental.ts similarity index 75% rename from modules/4337/src/deploy/webauthn.ts rename to modules/4337/src/deploy/experimental.ts index 04f5636a..e8f94b22 100644 --- a/modules/4337/src/deploy/webauthn.ts +++ b/modules/4337/src/deploy/experimental.ts @@ -8,6 +8,8 @@ const deploy: DeployFunction = async ({ deployments, getNamedAccounts, network } const { deployer } = await getNamedAccounts() const { deploy } = deployments + const entryPoint = await deployments.get('EntryPoint') + const p256Verifier = await deploy('P256Verifier', { from: deployer, args: [], @@ -28,6 +30,15 @@ const deploy: DeployFunction = async ({ deployments, getNamedAccounts, network } log: true, deterministicDeployment: true, }) + + await deploy('SafeSignerLaunchpad', { + from: deployer, + args: [entryPoint.address], + log: true, + deterministicDeployment: true, + }) } +deploy.dependencies = ['entrypoint'] + export default deploy diff --git a/modules/4337/src/deploy/libraries.ts b/modules/4337/src/deploy/libraries.ts index c3cfe75d..a840f10d 100644 --- a/modules/4337/src/deploy/libraries.ts +++ b/modules/4337/src/deploy/libraries.ts @@ -12,6 +12,4 @@ const deploy: DeployFunction = async ({ deployments, getNamedAccounts }) => { }) } -deploy.tags = ['libraries'] - export default deploy diff --git a/modules/4337/src/deploy/mock.ts b/modules/4337/src/deploy/mock.ts index 41e71206..3d1f5f94 100644 --- a/modules/4337/src/deploy/mock.ts +++ b/modules/4337/src/deploy/mock.ts @@ -28,6 +28,5 @@ const deploy: DeployFunction = async ({ deployments, getNamedAccounts, network } } deploy.dependencies = ['entrypoint'] -deploy.tags = ['mock'] export default deploy diff --git a/modules/4337/src/deploy/modules.ts b/modules/4337/src/deploy/module.ts similarity index 95% rename from modules/4337/src/deploy/modules.ts rename to modules/4337/src/deploy/module.ts index a46e020a..b4f4b420 100644 --- a/modules/4337/src/deploy/modules.ts +++ b/modules/4337/src/deploy/module.ts @@ -17,6 +17,5 @@ const deploy: DeployFunction = async ({ deployments, getNamedAccounts }) => { } deploy.dependencies = ['entrypoint'] -deploy.tags = ['modules'] export default deploy diff --git a/modules/4337/src/deploy/safe.ts b/modules/4337/src/deploy/safe.ts index b7f0c9c0..cf3ef935 100644 --- a/modules/4337/src/deploy/safe.ts +++ b/modules/4337/src/deploy/safe.ts @@ -1,39 +1,3 @@ -import MultiSend from '@safe-global/safe-contracts/build/artifacts/contracts/libraries/MultiSend.sol/MultiSend.json' -import SafeProxyFactory from '@safe-global/safe-contracts/build/artifacts/contracts/proxies/SafeProxyFactory.sol/SafeProxyFactory.json' -import SafeL2 from '@safe-global/safe-contracts/build/artifacts/contracts/SafeL2.sol/SafeL2.json' -import { DeployFunction } from 'hardhat-deploy/types' +import { deploySafe } from '@safe-global/safe-4337-local-bundler' -const deploy: DeployFunction = async ({ deployments, getNamedAccounts, network }) => { - if (!network.tags.safe && !network.tags.test) { - return - } - - const { deployer } = await getNamedAccounts() - const { deploy } = deployments - - await deploy('MultiSend', { - from: deployer, - contract: MultiSend, - args: [], - log: true, - deterministicDeployment: true, - }) - await deploy('SafeL2', { - from: deployer, - contract: SafeL2, - args: [], - log: true, - deterministicDeployment: true, - }) - await deploy('SafeProxyFactory', { - from: deployer, - contract: SafeProxyFactory, - args: [], - log: true, - deterministicDeployment: true, - }) -} - -deploy.tags = ['safe'] - -export default deploy +export default deploySafe \ No newline at end of file diff --git a/modules/4337/test/e2e/4337NestedSafe.spec.ts b/modules/4337/test/e2e/4337NestedSafe.spec.ts index 6059fdeb..449068ba 100644 --- a/modules/4337/test/e2e/4337NestedSafe.spec.ts +++ b/modules/4337/test/e2e/4337NestedSafe.spec.ts @@ -290,7 +290,7 @@ const buildNestedSafeOp = async ( ) } -describe('E2E - Nested Safes With An Execution Initiated by a Leaf 4337 Safe', () => { +describe('Nested Safes With An Execution Initiated by a Leaf 4337 Safe [@4337]', () => { before(function () { if (network.name !== 'localhost') { this.skip() diff --git a/modules/4337/test/e2e/LocalBundler.spec.ts b/modules/4337/test/e2e/LocalBundler.spec.ts index fef9561d..7c7bdd15 100644 --- a/modules/4337/test/e2e/LocalBundler.spec.ts +++ b/modules/4337/test/e2e/LocalBundler.spec.ts @@ -6,7 +6,7 @@ import { chainId, timestamp } from '../utils/encoding' import { Safe4337 } from '../../src/utils/safe' import { bundlerRpc, prepareAccounts, waitForUserOp } from '../utils/e2e' -describe('E2E - Local Bundler', () => { +describe('Local Bundler [@4337]', () => { before(function () { if (network.name !== 'localhost') { this.skip() diff --git a/modules/4337/test/e2e/SingletonSigners.spec.ts b/modules/4337/test/e2e/SingletonSigners.spec.ts index 134cb76e..d7b97791 100644 --- a/modules/4337/test/e2e/SingletonSigners.spec.ts +++ b/modules/4337/test/e2e/SingletonSigners.spec.ts @@ -8,7 +8,7 @@ import { } from '../../src/utils/userOp' import { bundlerRpc, encodeMultiSendTransactions, prepareAccounts, waitForUserOp } from '../utils/e2e' -describe('E2E - Singleton Signers', () => { +describe('Singleton Signers [@4337]', () => { before(function () { if (network.name !== 'localhost') { this.skip() diff --git a/modules/4337/test/e2e/UniqueSigner.spec.ts b/modules/4337/test/e2e/UniqueSigner.spec.ts index 16a10083..dc923ded 100644 --- a/modules/4337/test/e2e/UniqueSigner.spec.ts +++ b/modules/4337/test/e2e/UniqueSigner.spec.ts @@ -4,7 +4,7 @@ import { bundlerRpc, prepareAccounts, waitForUserOp } from '../utils/e2e' import { chainId } from '../utils/encoding' import { packGasParameters, unpackUserOperation } from '../../src/utils/userOp' -describe('E2E - Unique Signers', () => { +describe('Unique Signers [@4337]', () => { before(function () { if (network.name !== 'localhost') { this.skip() diff --git a/modules/4337/test/e2e/WebAuthnSigner.spec.ts b/modules/4337/test/e2e/WebAuthnSigner.spec.ts index 5f8f3165..bdb51052 100644 --- a/modules/4337/test/e2e/WebAuthnSigner.spec.ts +++ b/modules/4337/test/e2e/WebAuthnSigner.spec.ts @@ -11,7 +11,7 @@ import { } from '../utils/webauthn' import { packGasParameters, unpackUserOperation } from '../../src/utils/userOp' -describe('E2E - WebAuthn Signers', () => { +describe('WebAuthn Signers [@4337]', () => { before(function () { if (network.name !== 'localhost') { this.skip() diff --git a/modules/4337/test/e2e/WebAuthnSingletonSigner.spec.ts b/modules/4337/test/e2e/WebAuthnSingletonSigner.spec.ts index e61ad22f..50eb3d40 100644 --- a/modules/4337/test/e2e/WebAuthnSingletonSigner.spec.ts +++ b/modules/4337/test/e2e/WebAuthnSingletonSigner.spec.ts @@ -15,7 +15,7 @@ import { } from '../../src/utils/userOp' import { buildSignatureBytes } from '../../src/utils/execution' -describe('E2E - WebAuthn Singleton Signers', () => { +describe('WebAuthn Singleton Signers [@4337]', () => { before(function () { if (network.name !== 'localhost') { this.skip() diff --git a/modules/4337/test/e2e/run.sh b/modules/4337/test/e2e/run.sh deleted file mode 100755 index 3a77a328..00000000 --- a/modules/4337/test/e2e/run.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env bash - -DOCKER="${DOCKER:-docker}" - -bundler_container="bundler" -if [[ -n "$USE_UPSTREAM_BUNDLER" ]]; then - bundler_container="bundler-upstream" -fi - -"$DOCKER" compose up -d geth "$bundler_container" - -# wait for containers to start up -SECONDS=0 -until curl -fs http://localhost:8545 >/dev/null && curl -fs http://localhost:3000 >/dev/null; do - if [[ $SECONDS -gt 30 ]]; then - echo "ERROR: timeout waiting for local node and bundler to start" - "$DOCKER" compose logs - exit 1 - fi - sleep 1 -done - -hardhat test --deploy-fixture --network localhost --grep '^E2E - ' -success=$? - -"$DOCKER" compose down - -# exit with the E2E test's exit code -exit $success diff --git a/modules/allowances/package.json b/modules/allowances/package.json index ac00c787..e35e9361 100644 --- a/modules/allowances/package.json +++ b/modules/allowances/package.json @@ -42,8 +42,8 @@ "chai": "^4.2.0", "dotenv": "^16.4.4", "ethers": "^6.11.1", - "hardhat": "^2.20.1", - "hardhat-deploy": "^0.11.45", + "hardhat": "^2.21.0", + "hardhat-deploy": "^0.12.1", "hardhat-gas-reporter": "^1.0.10", "rimraf": "^5.0.5", "solhint": "4.1.1", diff --git a/modules/passkey/docker-compose.yaml b/modules/passkey/docker-compose.yaml deleted file mode 100644 index fee33d68..00000000 --- a/modules/passkey/docker-compose.yaml +++ /dev/null @@ -1,35 +0,0 @@ -version: '3.8' - -services: - geth: - image: docker.io/ethereum/client-go:stable - restart: always - environment: - GETH_DEV: 'true' - GETH_HTTP: 'true' - GETH_HTTP_ADDR: '0.0.0.0' - GETH_HTTP_API: 'personal,eth,net,web3,debug' - GETH_HTTP_VHOSTS: '*' - GETH_RPC_ALLOW_UNPROTECTED_TXS: 'true' - ports: - - 8545:8545 - - bundler: - build: - context: . - dockerfile: docker/bundler/Dockerfile - restart: always - command: ['--auto', '--network=http://geth:8545'] - ports: - - 3000:3000 - - bundler-upstream: - build: - context: . - dockerfile: docker/bundler/Dockerfile - args: - TAG: main - restart: always - command: ['--auto', '--network=http://geth:8545'] - ports: - - 3000:3000 diff --git a/modules/passkey/docker/bundler/Dockerfile b/modules/passkey/docker/bundler/Dockerfile deleted file mode 100644 index 86b79b9f..00000000 --- a/modules/passkey/docker/bundler/Dockerfile +++ /dev/null @@ -1,12 +0,0 @@ -FROM docker.io/library/node:18 - -# v0.7.0 -ARG TAG=26e4f4c -RUN git clone https://github.com/eth-infinitism/bundler /src/bundler -WORKDIR /src/bundler -RUN git checkout ${TAG} -RUN git submodule init && git submodule update - -RUN yarn && yarn preprocess -ENTRYPOINT ["yarn", "bundler"] -CMD [] diff --git a/modules/passkey/hardhat.config.ts b/modules/passkey/hardhat.config.ts index 405a5b7b..7ca87148 100644 --- a/modules/passkey/hardhat.config.ts +++ b/modules/passkey/hardhat.config.ts @@ -15,10 +15,10 @@ const config: HardhatUserConfig = { networks: { localhost: { url: 'http://localhost:8545', - tags: ['dev'], + tags: ['dev', 'entrypoint', 'safe'], }, hardhat: { - tags: ['test'], + tags: ['test', 'entrypoint', 'safe'], }, }, solidity: { diff --git a/modules/passkey/package.json b/modules/passkey/package.json index a52477ed..7eb510bc 100644 --- a/modules/passkey/package.json +++ b/modules/passkey/package.json @@ -37,13 +37,15 @@ "lint:sol": "solhint 'contracts/**/*.sol'", "lint:ts": "eslint .", "test": "hardhat test", - "test:4337": "./test/4337/run.sh" + "test:4337": "4337-local-bundler-test", + "test:4337:upstream": "USE_UPSTREAM_BUNDLER=1 4337-local-bundler-test" }, "devDependencies": { "@account-abstraction/contracts": "^0.7.0", "@noble/curves": "^1.3.0", "@nomicfoundation/hardhat-toolbox": "^4.0.0", "@safe-global/safe-4337": "^0.3.0", + "@safe-global/safe-4337-local-bundler": "^0.0.0", "@simplewebauthn/server": "^9.0.3", "cbor": "^9.0.2", "dotenv": "^16.4.5", diff --git a/modules/passkey/src/deploy/entrypoint.ts b/modules/passkey/src/deploy/entrypoint.ts new file mode 100644 index 00000000..39787c57 --- /dev/null +++ b/modules/passkey/src/deploy/entrypoint.ts @@ -0,0 +1,3 @@ +import { deployEntryPoint } from '@safe-global/safe-4337-local-bundler' + +export default deployEntryPoint \ No newline at end of file diff --git a/modules/passkey/src/deploy/safe.ts b/modules/passkey/src/deploy/safe.ts index 5137033a..cf3ef935 100644 --- a/modules/passkey/src/deploy/safe.ts +++ b/modules/passkey/src/deploy/safe.ts @@ -1,58 +1,3 @@ -import MultiSend from '@safe-global/safe-contracts/build/artifacts/contracts/libraries/MultiSend.sol/MultiSend.json' -import SafeProxyFactory from '@safe-global/safe-contracts/build/artifacts/contracts/proxies/SafeProxyFactory.sol/SafeProxyFactory.json' -import SafeL2 from '@safe-global/safe-contracts/build/artifacts/contracts/SafeL2.sol/SafeL2.json' -import Safe4337Module from '@safe-global/safe-4337/build/artifacts/contracts/Safe4337Module.sol/Safe4337Module.json' -import SafeModuleSetup from '@safe-global/safe-4337/build/artifacts/contracts/SafeModuleSetup.sol/SafeModuleSetup.json' -import { DeployFunction } from 'hardhat-deploy/types' +import { deploySafe } from '@safe-global/safe-4337-local-bundler' -const deploy: DeployFunction = async ({ deployments, getNamedAccounts, network }) => { - if (!network.tags.dev && !network.tags.test) { - return - } - - const { deployer } = await getNamedAccounts() - const { deploy } = deployments - - const entryPoint = await deployments.get('EntryPoint') - - await deploy('MultiSend', { - from: deployer, - contract: MultiSend, - args: [], - log: true, - deterministicDeployment: true, - }) - await deploy('SafeL2', { - from: deployer, - contract: SafeL2, - args: [], - log: true, - deterministicDeployment: true, - }) - await deploy('SafeProxyFactory', { - from: deployer, - contract: SafeProxyFactory, - args: [], - log: true, - deterministicDeployment: true, - }) - await deploy('SafeModuleSetup', { - from: deployer, - contract: SafeModuleSetup, - args: [], - log: true, - deterministicDeployment: true, - }) - await deploy('Safe4337Module', { - from: deployer, - contract: Safe4337Module, - args: [entryPoint.address], - log: true, - deterministicDeployment: true, - }) -} - -deploy.dependencies = ['entrypoint'] -deploy.tags = ['safe'] - -export default deploy +export default deploySafe \ No newline at end of file diff --git a/modules/passkey/src/deploy/safe4337.ts b/modules/passkey/src/deploy/safe4337.ts new file mode 100644 index 00000000..2d2c12e6 --- /dev/null +++ b/modules/passkey/src/deploy/safe4337.ts @@ -0,0 +1,33 @@ +import Safe4337Module from '@safe-global/safe-4337/build/artifacts/contracts/Safe4337Module.sol/Safe4337Module.json' +import SafeModuleSetup from '@safe-global/safe-4337/build/artifacts/contracts/SafeModuleSetup.sol/SafeModuleSetup.json' +import { DeployFunction } from 'hardhat-deploy/types' + +const deploy: DeployFunction = async ({ deployments, getNamedAccounts, network }) => { + if (!network.tags.safe) { + return + } + + const { deployer } = await getNamedAccounts() + const { deploy } = deployments + + const entryPoint = await deployments.get('EntryPoint') + + await deploy('SafeModuleSetup', { + from: deployer, + contract: SafeModuleSetup, + args: [], + log: true, + deterministicDeployment: true, + }) + await deploy('Safe4337Module', { + from: deployer, + contract: Safe4337Module, + args: [entryPoint.address], + log: true, + deterministicDeployment: true, + }) +} + +deploy.dependencies = ['entrypoint'] + +export default deploy \ No newline at end of file diff --git a/modules/passkey/src/deploy/webauthn.ts b/modules/passkey/src/deploy/webauthn.ts index 6fc7f6a0..38dbb51d 100644 --- a/modules/passkey/src/deploy/webauthn.ts +++ b/modules/passkey/src/deploy/webauthn.ts @@ -1,10 +1,6 @@ import { DeployFunction } from 'hardhat-deploy/types' -const deploy: DeployFunction = async ({ deployments, getNamedAccounts, network }) => { - if (!network.tags.dev && !network.tags.test) { - return - } - +const deploy: DeployFunction = async ({ deployments, getNamedAccounts }) => { const { deployer } = await getNamedAccounts() const { deploy } = deployments diff --git a/modules/passkey/test/4337/run.sh b/modules/passkey/test/4337/run.sh deleted file mode 100755 index 943f2a35..00000000 --- a/modules/passkey/test/4337/run.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env bash - -DOCKER="${DOCKER:-docker}" - -bundler_container="bundler" -if [[ -n "$USE_UPSTREAM_BUNDLER" ]]; then - bundler_container="bundler-upstream" -fi - -"$DOCKER" compose up -d geth "$bundler_container" - -# wait for containers to start up -SECONDS=0 -until curl -fs http://localhost:8545 >/dev/null && curl -fs http://localhost:3000 >/dev/null; do - if [[ $SECONDS -gt 30 ]]; then - echo "ERROR: timeout waiting for local node and bundler to start" - "$DOCKER" compose logs - exit 1 - fi - sleep 1 -done - -hardhat test --deploy-fixture --network localhost --grep '@4337' -success=$? - -"$DOCKER" compose down - -# exit with the E2E test's exit code -exit $success diff --git a/package-lock.json b/package-lock.json index fbc5a035..a26ac5fe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -568,6 +568,7 @@ "@noble/curves": "^1.3.0", "@nomicfoundation/hardhat-toolbox": "^4.0.0", "@openzeppelin/contracts": "^5.0.2", + "@safe-global/safe-4337-local-bundler": "^0.0.0", "@simplewebauthn/server": "9.0.0", "@types/chai": "^4.3.11", "@types/mocha": "^10.0.6", @@ -577,8 +578,8 @@ "debug": "^4.3.4", "dotenv": "^16.4.4", "ethers": "^6.11.1", - "hardhat": "^2.20.1", - "hardhat-deploy": "0.11.45", + "hardhat": "^2.21.0", + "hardhat-deploy": "^0.12.1", "husky": "^9.0.11", "solc": "^0.8.24", "solhint": "^4.1.1", @@ -908,8 +909,8 @@ "chai": "^4.2.0", "dotenv": "^16.4.4", "ethers": "^6.11.1", - "hardhat": "^2.20.1", - "hardhat-deploy": "^0.11.45", + "hardhat": "^2.21.0", + "hardhat-deploy": "^0.12.1", "hardhat-gas-reporter": "^1.0.10", "rimraf": "^5.0.5", "solhint": "4.1.1", @@ -1190,6 +1191,7 @@ "@noble/curves": "^1.3.0", "@nomicfoundation/hardhat-toolbox": "^4.0.0", "@safe-global/safe-4337": "^0.3.0", + "@safe-global/safe-4337-local-bundler": "^0.0.0", "@simplewebauthn/server": "^9.0.3", "cbor": "^9.0.2", "dotenv": "^16.4.5", @@ -1204,213 +1206,6 @@ "license": "MIT", "peer": true }, - "modules/passkey/node_modules/@ethersproject/contracts": { - "version": "5.7.0", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abi": "^5.7.0", - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/transactions": "^5.7.0" - } - }, - "modules/passkey/node_modules/@ethersproject/hdnode": { - "version": "5.7.0", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/basex": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/pbkdf2": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/wordlists": "^5.7.0" - } - }, - "modules/passkey/node_modules/@ethersproject/json-wallets": { - "version": "5.7.0", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hdnode": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/pbkdf2": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "aes-js": "3.0.0", - "scrypt-js": "3.0.1" - } - }, - "modules/passkey/node_modules/@ethersproject/json-wallets/node_modules/aes-js": { - "version": "3.0.0", - "dev": true, - "license": "MIT" - }, - "modules/passkey/node_modules/@ethersproject/pbkdf2": { - "version": "5.7.0", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/sha2": "^5.7.0" - } - }, - "modules/passkey/node_modules/@ethersproject/solidity": { - "version": "5.7.0", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "modules/passkey/node_modules/@ethersproject/units": { - "version": "5.7.0", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "modules/passkey/node_modules/@ethersproject/wallet": { - "version": "5.7.0", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/hdnode": "^5.7.0", - "@ethersproject/json-wallets": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/wordlists": "^5.7.0" - } - }, - "modules/passkey/node_modules/@ethersproject/wordlists": { - "version": "5.7.0", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, "modules/passkey/node_modules/@noble/curves": { "version": "1.2.0", "dev": true, @@ -1525,51 +1320,6 @@ "license": "MIT", "peer": true }, - "modules/passkey/node_modules/ansi-styles": { - "version": "4.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "modules/passkey/node_modules/chalk": { - "version": "4.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "modules/passkey/node_modules/color-convert": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "modules/passkey/node_modules/color-name": { - "version": "1.1.4", - "dev": true, - "license": "MIT" - }, "modules/passkey/node_modules/dotenv": { "version": "16.4.5", "dev": true, @@ -1624,109 +1374,11 @@ "node": ">=10" } }, - "modules/passkey/node_modules/hardhat-deploy": { - "version": "0.12.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@ethersproject/abi": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/contracts": "^5.7.0", - "@ethersproject/providers": "^5.7.2", - "@ethersproject/solidity": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/wallet": "^5.7.0", - "@types/qs": "^6.9.7", - "axios": "^0.21.1", - "chalk": "^4.1.2", - "chokidar": "^3.5.2", - "debug": "^4.3.2", - "enquirer": "^2.3.6", - "ethers": "^5.7.0", - "form-data": "^4.0.0", - "fs-extra": "^10.0.0", - "match-all": "^1.2.6", - "murmur-128": "^0.2.1", - "qs": "^6.9.4", - "zksync-ethers": "^5.0.0" - } - }, - "modules/passkey/node_modules/hardhat-deploy/node_modules/ethers": { - "version": "5.7.2", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abi": "5.7.0", - "@ethersproject/abstract-provider": "5.7.0", - "@ethersproject/abstract-signer": "5.7.0", - "@ethersproject/address": "5.7.0", - "@ethersproject/base64": "5.7.0", - "@ethersproject/basex": "5.7.0", - "@ethersproject/bignumber": "5.7.0", - "@ethersproject/bytes": "5.7.0", - "@ethersproject/constants": "5.7.0", - "@ethersproject/contracts": "5.7.0", - "@ethersproject/hash": "5.7.0", - "@ethersproject/hdnode": "5.7.0", - "@ethersproject/json-wallets": "5.7.0", - "@ethersproject/keccak256": "5.7.0", - "@ethersproject/logger": "5.7.0", - "@ethersproject/networks": "5.7.1", - "@ethersproject/pbkdf2": "5.7.0", - "@ethersproject/properties": "5.7.0", - "@ethersproject/providers": "5.7.2", - "@ethersproject/random": "5.7.0", - "@ethersproject/rlp": "5.7.0", - "@ethersproject/sha2": "5.7.0", - "@ethersproject/signing-key": "5.7.0", - "@ethersproject/solidity": "5.7.0", - "@ethersproject/strings": "5.7.0", - "@ethersproject/transactions": "5.7.0", - "@ethersproject/units": "5.7.0", - "@ethersproject/wallet": "5.7.0", - "@ethersproject/web": "5.7.1", - "@ethersproject/wordlists": "5.7.0" - } - }, - "modules/passkey/node_modules/hardhat-deploy/node_modules/fs-extra": { - "version": "10.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "modules/passkey/node_modules/has-flag": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "modules/passkey/node_modules/jsonfile": { "version": "6.1.0", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "universalify": "^2.0.0" }, @@ -1734,17 +1386,6 @@ "graceful-fs": "^4.1.6" } }, - "modules/passkey/node_modules/supports-color": { - "version": "7.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "modules/passkey/node_modules/tslib": { "version": "2.4.0", "dev": true, @@ -1755,6 +1396,7 @@ "version": "2.0.1", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">= 10.0.0" } @@ -3886,6 +3528,10 @@ "resolved": "modules/4337", "link": true }, + "node_modules/@safe-global/safe-4337-local-bundler": { + "resolved": "packages/4337-local-bundler", + "link": true + }, "node_modules/@safe-global/safe-allowance-module": { "resolved": "modules/allowances", "link": true @@ -4480,7 +4126,6 @@ }, "node_modules/@types/qs": { "version": "6.9.11", - "dev": true, "license": "MIT" }, "node_modules/@types/react": { @@ -5552,7 +5197,6 @@ }, "node_modules/ansi-colors": { "version": "4.1.3", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -5842,7 +5486,6 @@ }, "node_modules/axios": { "version": "0.21.4", - "dev": true, "license": "MIT", "dependencies": { "follow-redirects": "^1.14.0" @@ -6137,7 +5780,6 @@ }, "node_modules/call-bind": { "version": "1.0.5", - "dev": true, "license": "MIT", "dependencies": { "function-bind": "^1.1.2", @@ -6803,7 +6445,6 @@ }, "node_modules/define-data-property": { "version": "1.1.1", - "dev": true, "license": "MIT", "dependencies": { "get-intrinsic": "^1.2.1", @@ -6973,7 +6614,6 @@ }, "node_modules/enquirer": { "version": "2.4.1", - "dev": true, "license": "MIT", "dependencies": { "ansi-colors": "^4.1.1", @@ -8985,7 +8625,6 @@ }, "node_modules/fmix": { "version": "0.1.0", - "dev": true, "license": "MIT", "dependencies": { "imul": "^1.0.0" @@ -9082,7 +8721,6 @@ }, "node_modules/function-bind": { "version": "1.1.2", - "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -9130,7 +8768,6 @@ }, "node_modules/get-intrinsic": { "version": "1.2.2", - "dev": true, "license": "MIT", "dependencies": { "function-bind": "^1.1.2", @@ -9327,7 +8964,6 @@ }, "node_modules/gopd": { "version": "1.0.1", - "dev": true, "license": "MIT", "dependencies": { "get-intrinsic": "^1.1.3" @@ -9362,7 +8998,6 @@ }, "node_modules/graceful-fs": { "version": "4.2.11", - "dev": true, "license": "ISC" }, "node_modules/graphemer": { @@ -9407,8 +9042,9 @@ }, "node_modules/hardhat": { "version": "2.21.0", + "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.21.0.tgz", + "integrity": "sha512-8DlJAVJDEVHaV1sh9FLuKLLgCFv9EAJ+M+8IbjSIPgoeNo3ss5L1HgGBMfnI88c7OzMEZkdcuyGoobFeK3Orqw==", "dev": true, - "license": "MIT", "dependencies": { "@ethersproject/abi": "^5.1.2", "@metamask/eth-sig-util": "^4.0.0", @@ -9471,9 +9107,9 @@ } }, "node_modules/hardhat-deploy": { - "version": "0.11.45", - "dev": true, - "license": "MIT", + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/hardhat-deploy/-/hardhat-deploy-0.12.1.tgz", + "integrity": "sha512-ayPJqBCElzPeiwdHUEV0rKQ6NvKStjQAxCqCPlsavQVaxl7uZUHt/d+XbLqglVFqOOpHHs6L9K4W1vxPbsOy5Q==", "dependencies": { "@ethersproject/abi": "^5.7.0", "@ethersproject/abstract-signer": "^5.7.0", @@ -9498,12 +9134,13 @@ "match-all": "^1.2.6", "murmur-128": "^0.2.1", "qs": "^6.9.4", - "zksync-web3": "^0.14.3" + "zksync-ethers": "^5.0.0" } }, "node_modules/hardhat-deploy/node_modules/@ethersproject/contracts": { "version": "5.7.0", - "dev": true, + "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.7.0.tgz", + "integrity": "sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg==", "funding": [ { "type": "individual", @@ -9514,7 +9151,6 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], - "license": "MIT", "dependencies": { "@ethersproject/abi": "^5.7.0", "@ethersproject/abstract-provider": "^5.7.0", @@ -9530,7 +9166,8 @@ }, "node_modules/hardhat-deploy/node_modules/@ethersproject/hdnode": { "version": "5.7.0", - "dev": true, + "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.7.0.tgz", + "integrity": "sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg==", "funding": [ { "type": "individual", @@ -9541,7 +9178,6 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], - "license": "MIT", "dependencies": { "@ethersproject/abstract-signer": "^5.7.0", "@ethersproject/basex": "^5.7.0", @@ -9559,7 +9195,8 @@ }, "node_modules/hardhat-deploy/node_modules/@ethersproject/json-wallets": { "version": "5.7.0", - "dev": true, + "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz", + "integrity": "sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g==", "funding": [ { "type": "individual", @@ -9570,7 +9207,6 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], - "license": "MIT", "dependencies": { "@ethersproject/abstract-signer": "^5.7.0", "@ethersproject/address": "^5.7.0", @@ -9589,7 +9225,8 @@ }, "node_modules/hardhat-deploy/node_modules/@ethersproject/pbkdf2": { "version": "5.7.0", - "dev": true, + "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz", + "integrity": "sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw==", "funding": [ { "type": "individual", @@ -9600,7 +9237,6 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], - "license": "MIT", "dependencies": { "@ethersproject/bytes": "^5.7.0", "@ethersproject/sha2": "^5.7.0" @@ -9608,7 +9244,8 @@ }, "node_modules/hardhat-deploy/node_modules/@ethersproject/solidity": { "version": "5.7.0", - "dev": true, + "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.7.0.tgz", + "integrity": "sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA==", "funding": [ { "type": "individual", @@ -9619,7 +9256,6 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], - "license": "MIT", "dependencies": { "@ethersproject/bignumber": "^5.7.0", "@ethersproject/bytes": "^5.7.0", @@ -9631,7 +9267,8 @@ }, "node_modules/hardhat-deploy/node_modules/@ethersproject/units": { "version": "5.7.0", - "dev": true, + "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.7.0.tgz", + "integrity": "sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg==", "funding": [ { "type": "individual", @@ -9642,7 +9279,6 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], - "license": "MIT", "dependencies": { "@ethersproject/bignumber": "^5.7.0", "@ethersproject/constants": "^5.7.0", @@ -9651,7 +9287,8 @@ }, "node_modules/hardhat-deploy/node_modules/@ethersproject/wallet": { "version": "5.7.0", - "dev": true, + "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.7.0.tgz", + "integrity": "sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA==", "funding": [ { "type": "individual", @@ -9662,7 +9299,6 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], - "license": "MIT", "dependencies": { "@ethersproject/abstract-provider": "^5.7.0", "@ethersproject/abstract-signer": "^5.7.0", @@ -9683,7 +9319,8 @@ }, "node_modules/hardhat-deploy/node_modules/@ethersproject/wordlists": { "version": "5.7.0", - "dev": true, + "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.7.0.tgz", + "integrity": "sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA==", "funding": [ { "type": "individual", @@ -9694,7 +9331,6 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], - "license": "MIT", "dependencies": { "@ethersproject/bytes": "^5.7.0", "@ethersproject/hash": "^5.7.0", @@ -9705,12 +9341,11 @@ }, "node_modules/hardhat-deploy/node_modules/aes-js": { "version": "3.0.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", + "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==" }, "node_modules/hardhat-deploy/node_modules/ansi-styles": { "version": "4.3.0", - "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -9724,7 +9359,6 @@ }, "node_modules/hardhat-deploy/node_modules/chalk": { "version": "4.1.2", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -9739,7 +9373,6 @@ }, "node_modules/hardhat-deploy/node_modules/color-convert": { "version": "2.0.1", - "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -9750,12 +9383,12 @@ }, "node_modules/hardhat-deploy/node_modules/color-name": { "version": "1.1.4", - "dev": true, "license": "MIT" }, "node_modules/hardhat-deploy/node_modules/ethers": { "version": "5.7.2", - "dev": true, + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz", + "integrity": "sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==", "funding": [ { "type": "individual", @@ -9766,7 +9399,6 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], - "license": "MIT", "dependencies": { "@ethersproject/abi": "5.7.0", "@ethersproject/abstract-provider": "5.7.0", @@ -9802,7 +9434,6 @@ }, "node_modules/hardhat-deploy/node_modules/fs-extra": { "version": "10.1.0", - "dev": true, "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", @@ -9815,7 +9446,6 @@ }, "node_modules/hardhat-deploy/node_modules/has-flag": { "version": "4.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -9823,7 +9453,6 @@ }, "node_modules/hardhat-deploy/node_modules/jsonfile": { "version": "6.1.0", - "dev": true, "license": "MIT", "dependencies": { "universalify": "^2.0.0" @@ -9834,7 +9463,6 @@ }, "node_modules/hardhat-deploy/node_modules/supports-color": { "version": "7.2.0", - "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -9845,20 +9473,11 @@ }, "node_modules/hardhat-deploy/node_modules/universalify": { "version": "2.0.1", - "dev": true, "license": "MIT", "engines": { "node": ">= 10.0.0" } }, - "node_modules/hardhat-deploy/node_modules/zksync-web3": { - "version": "0.14.4", - "dev": true, - "license": "MIT", - "peerDependencies": { - "ethers": "^5.7.0" - } - }, "node_modules/hardhat-gas-reporter": { "version": "1.0.10", "dev": true, @@ -9890,7 +9509,6 @@ }, "node_modules/has-property-descriptors": { "version": "1.0.1", - "dev": true, "license": "MIT", "dependencies": { "get-intrinsic": "^1.2.2" @@ -9901,7 +9519,6 @@ }, "node_modules/has-proto": { "version": "1.0.1", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -9912,7 +9529,6 @@ }, "node_modules/has-symbols": { "version": "1.0.3", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -9977,7 +9593,6 @@ }, "node_modules/hasown": { "version": "2.0.0", - "dev": true, "license": "MIT", "dependencies": { "function-bind": "^1.1.2" @@ -10175,7 +9790,6 @@ }, "node_modules/imul": { "version": "1.0.1", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -11070,7 +10684,6 @@ }, "node_modules/match-all": { "version": "1.2.6", - "dev": true, "license": "MIT" }, "node_modules/md5.js": { @@ -11427,7 +11040,6 @@ }, "node_modules/murmur-128": { "version": "0.2.1", - "dev": true, "license": "MIT", "dependencies": { "encode-utf8": "^1.0.2", @@ -11612,7 +11224,6 @@ }, "node_modules/object-inspect": { "version": "1.13.1", - "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -12407,7 +12018,6 @@ }, "node_modules/qs": { "version": "6.11.2", - "dev": true, "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.0.4" @@ -13041,7 +12651,6 @@ }, "node_modules/set-function-length": { "version": "1.1.1", - "dev": true, "license": "MIT", "dependencies": { "define-data-property": "^1.1.1", @@ -13134,7 +12743,6 @@ }, "node_modules/side-channel": { "version": "1.0.4", - "dev": true, "license": "MIT", "dependencies": { "call-bind": "^1.0.0", @@ -15268,7 +14876,6 @@ }, "node_modules/zksync-ethers": { "version": "5.4.0", - "dev": true, "license": "MIT", "dependencies": { "ethers": "~5.7.0" @@ -15279,7 +14886,6 @@ }, "node_modules/zksync-ethers/node_modules/@ethersproject/contracts": { "version": "5.7.0", - "dev": true, "funding": [ { "type": "individual", @@ -15306,7 +14912,6 @@ }, "node_modules/zksync-ethers/node_modules/@ethersproject/hdnode": { "version": "5.7.0", - "dev": true, "funding": [ { "type": "individual", @@ -15335,7 +14940,6 @@ }, "node_modules/zksync-ethers/node_modules/@ethersproject/json-wallets": { "version": "5.7.0", - "dev": true, "funding": [ { "type": "individual", @@ -15365,7 +14969,6 @@ }, "node_modules/zksync-ethers/node_modules/@ethersproject/pbkdf2": { "version": "5.7.0", - "dev": true, "funding": [ { "type": "individual", @@ -15384,7 +14987,6 @@ }, "node_modules/zksync-ethers/node_modules/@ethersproject/solidity": { "version": "5.7.0", - "dev": true, "funding": [ { "type": "individual", @@ -15407,7 +15009,6 @@ }, "node_modules/zksync-ethers/node_modules/@ethersproject/units": { "version": "5.7.0", - "dev": true, "funding": [ { "type": "individual", @@ -15427,7 +15028,6 @@ }, "node_modules/zksync-ethers/node_modules/@ethersproject/wallet": { "version": "5.7.0", - "dev": true, "funding": [ { "type": "individual", @@ -15459,7 +15059,6 @@ }, "node_modules/zksync-ethers/node_modules/@ethersproject/wordlists": { "version": "5.7.0", - "dev": true, "funding": [ { "type": "individual", @@ -15481,12 +15080,10 @@ }, "node_modules/zksync-ethers/node_modules/aes-js": { "version": "3.0.0", - "dev": true, "license": "MIT" }, "node_modules/zksync-ethers/node_modules/ethers": { "version": "5.7.2", - "dev": true, "funding": [ { "type": "individual", @@ -15537,6 +15134,18 @@ "funding": { "url": "https://github.com/sponsors/colinhacks" } + }, + "packages/4337-local-bundler": { + "name": "@safe-global/safe-4337-local-bundler", + "version": "0.0.0", + "hasInstallScript": true, + "license": "LGPL-3.0-only", + "dependencies": { + "hardhat-deploy": "^0.12.1" + }, + "bin": { + "local-bundler-test": "dist/bin/test.js" + } } } } diff --git a/packages/4337-local-bundler/.eslintignore b/packages/4337-local-bundler/.eslintignore new file mode 100644 index 00000000..849ddff3 --- /dev/null +++ b/packages/4337-local-bundler/.eslintignore @@ -0,0 +1 @@ +dist/ diff --git a/packages/4337-local-bundler/.gitignore b/packages/4337-local-bundler/.gitignore new file mode 100644 index 00000000..849ddff3 --- /dev/null +++ b/packages/4337-local-bundler/.gitignore @@ -0,0 +1 @@ +dist/ diff --git a/packages/4337-local-bundler/docker-compose.yaml b/packages/4337-local-bundler/docker-compose.yaml index fee33d68..6ccfae84 100644 --- a/packages/4337-local-bundler/docker-compose.yaml +++ b/packages/4337-local-bundler/docker-compose.yaml @@ -20,6 +20,8 @@ services: dockerfile: docker/bundler/Dockerfile restart: always command: ['--auto', '--network=http://geth:8545'] + environment: + DEBUG: 'aa.exec,aa.exec.cron,aa.events,aa.mempool' ports: - 3000:3000 @@ -31,5 +33,7 @@ services: TAG: main restart: always command: ['--auto', '--network=http://geth:8545'] + environment: + DEBUG: 'aa.exec,aa.exec.cron,aa.events,aa.mempool' ports: - 3000:3000 diff --git a/packages/4337-local-bundler/bundler/Dockerfile b/packages/4337-local-bundler/docker/bundler/Dockerfile similarity index 100% rename from packages/4337-local-bundler/bundler/Dockerfile rename to packages/4337-local-bundler/docker/bundler/Dockerfile diff --git a/packages/4337-local-bundler/package.json b/packages/4337-local-bundler/package.json index 3913e1f2..ceaf6e91 100644 --- a/packages/4337-local-bundler/package.json +++ b/packages/4337-local-bundler/package.json @@ -4,7 +4,19 @@ "private": true, "license": "LGPL-3.0-only", "main": "dist/index.js", - "typings": "dist/index.d.ts", + "types": "dist/index.d.ts", + "bin": { + "4337-local-bundler-test": "dist/bin/test.js" + }, "scripts": { + "build": "npx rimraf dist && tsc && chmod +x dist/bin/*.js", + "lint": "eslint .", + "prepack": "npm run build", + "prepublish": "npm run build", + "postinstall": "npm run build" + }, + "dependencies": { + "hardhat-deploy": "^0.12.1", + "node-fetch": "^2.7.0" } } diff --git a/packages/4337-local-bundler/src/bin/test.ts b/packages/4337-local-bundler/src/bin/test.ts new file mode 100644 index 00000000..d451c64d --- /dev/null +++ b/packages/4337-local-bundler/src/bin/test.ts @@ -0,0 +1,68 @@ +#!/usr/bin/env node + +import childProcess, { SpawnOptions } from 'node:child_process' +import path from 'node:path' + +const { DOCKER, USE_UPSTREAM_BUNDLER } = process.env + +const root = path.join(__dirname, '..', '..') + +const docker = DOCKER || 'docker' +const bundler = USE_UPSTREAM_BUNDLER === '1' ? 'bunlder-upstream' : 'bundler' + +async function exec(command: string, args: string[], options: Omit = {}) { + const process = childProcess.spawn(command, args, { ...options, stdio: 'inherit' }) + await new Promise((resolve, reject) => { + process.on('exit', (code) => { + if (code === 0) { + resolve(undefined) + } else { + reject(new Error(`'${command}' process exited with code ${code}`)) + } + }) + }) +} + +async function checkRpc(...urls: string[]) { + const statuses = await Promise.all( + urls.map(async (url) => { + try { + const response = await fetch(url) + return response.ok + } catch (err) { + return false + } + }), + ) + return statuses.every((ok) => ok) +} + +async function main() { + console.log('==> Starting docker containers...') + await exec(docker, ['compose', 'up', '-d', 'geth', bundler], { cwd: root }) + + console.log('==> Waiting for RPC endpoints') + const start = Date.now() + const timeout = 60 * 1000 + while (!(await checkRpc('http://localhost:8545', 'http://localhost:3000'))) { + if (Date.now() - start > timeout) { + throw new Error('timeout waiting for local node and bundler to start') + } + } + + try { + console.log('==> Running tests') + await exec('hardhat', ['test', '--network', 'localhost', '--grep', '@4337']) + } finally { + console.log('==> Shutting down') + await exec(docker, ['compose', 'down'], { cwd: root }) + } +} + +main().catch((err) => { + console.error('ERROR: ', err) + if (err.stderr) { + console.log(err.stderr) + } + process.exitCode = 1 +}) diff --git a/modules/passkey/src/deploy/4337.ts b/packages/4337-local-bundler/src/deploy/entrypoint.ts similarity index 88% rename from modules/passkey/src/deploy/4337.ts rename to packages/4337-local-bundler/src/deploy/entrypoint.ts index 1b86a7e6..8983b69b 100644 --- a/modules/passkey/src/deploy/4337.ts +++ b/packages/4337-local-bundler/src/deploy/entrypoint.ts @@ -1,7 +1,11 @@ import EntryPoint from '@account-abstraction/contracts/artifacts/EntryPoint.json' import { DeployFunction } from 'hardhat-deploy/types' -const deploy: DeployFunction = async ({ deployments, getNamedAccounts }) => { +const deploy: DeployFunction = async ({ deployments, getNamedAccounts, network }) => { + if (!network.tags.entrypoint) { + return + } + const { deployer } = await getNamedAccounts() const { deploy } = deployments diff --git a/packages/4337-local-bundler/src/deploy/safe.ts b/packages/4337-local-bundler/src/deploy/safe.ts new file mode 100644 index 00000000..1e6749ff --- /dev/null +++ b/packages/4337-local-bundler/src/deploy/safe.ts @@ -0,0 +1,39 @@ +import MultiSend from '@safe-global/safe-contracts/build/artifacts/contracts/libraries/MultiSend.sol/MultiSend.json' +import SafeProxyFactory from '@safe-global/safe-contracts/build/artifacts/contracts/proxies/SafeProxyFactory.sol/SafeProxyFactory.json' +import SafeL2 from '@safe-global/safe-contracts/build/artifacts/contracts/SafeL2.sol/SafeL2.json' +import { DeployFunction } from 'hardhat-deploy/types' + +const deploy: DeployFunction = async ({ deployments, getNamedAccounts, network }) => { + if (!network.tags.safe) { + return + } + + const { deployer } = await getNamedAccounts() + const { deploy } = deployments + + await deploy('MultiSend', { + from: deployer, + contract: MultiSend, + args: [], + log: true, + deterministicDeployment: true, + }) + await deploy('SafeL2', { + from: deployer, + contract: SafeL2, + args: [], + log: true, + deterministicDeployment: true, + }) + await deploy('SafeProxyFactory', { + from: deployer, + contract: SafeProxyFactory, + args: [], + log: true, + deterministicDeployment: true, + }) +} + +deploy.tags = ['safe'] + +export default deploy diff --git a/packages/4337-local-bundler/src/index.ts b/packages/4337-local-bundler/src/index.ts new file mode 100644 index 00000000..3d2da4d3 --- /dev/null +++ b/packages/4337-local-bundler/src/index.ts @@ -0,0 +1,6 @@ +import 'hardhat-deploy' + +import deployEntryPoint from './deploy/entrypoint' +import deploySafe from './deploy/safe' + +export { deployEntryPoint, deploySafe } diff --git a/packages/4337-local-bundler/test.sh b/packages/4337-local-bundler/test.sh deleted file mode 100755 index 943f2a35..00000000 --- a/packages/4337-local-bundler/test.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env bash - -DOCKER="${DOCKER:-docker}" - -bundler_container="bundler" -if [[ -n "$USE_UPSTREAM_BUNDLER" ]]; then - bundler_container="bundler-upstream" -fi - -"$DOCKER" compose up -d geth "$bundler_container" - -# wait for containers to start up -SECONDS=0 -until curl -fs http://localhost:8545 >/dev/null && curl -fs http://localhost:3000 >/dev/null; do - if [[ $SECONDS -gt 30 ]]; then - echo "ERROR: timeout waiting for local node and bundler to start" - "$DOCKER" compose logs - exit 1 - fi - sleep 1 -done - -hardhat test --deploy-fixture --network localhost --grep '@4337' -success=$? - -"$DOCKER" compose down - -# exit with the E2E test's exit code -exit $success diff --git a/packages/4337-local-bundler/tsconfig.json b/packages/4337-local-bundler/tsconfig.json new file mode 100644 index 00000000..0ae3997d --- /dev/null +++ b/packages/4337-local-bundler/tsconfig.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "target": "es2020", + "module": "commonjs", + "declaration": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "outDir": "./dist", + "strict": true, + "skipLibCheck": true, + "resolveJsonModule": true + } +}