mirror of
https://github.com/getwax/wax.git
synced 2026-01-09 15:18:02 -05:00
Merge pull request #229 from getwax/wax-215-add-compression
Add compression to bundler
This commit is contained in:
@@ -7,6 +7,11 @@ type ConfigType = {
|
||||
addFundsEthAmount?: string;
|
||||
deployerSeedPhrase: string;
|
||||
requirePermission?: boolean;
|
||||
externalContracts?: {
|
||||
entryPoint: string;
|
||||
blsSignatureAggregator: string;
|
||||
addressRegistry: string;
|
||||
};
|
||||
};
|
||||
|
||||
export default ConfigType;
|
||||
|
||||
@@ -15,11 +15,24 @@ const config: ConfigType = {
|
||||
rpcUrl: 'http://127.0.0.1:8545',
|
||||
deployerSeedPhrase:
|
||||
'test test test test test test test test test test test junk',
|
||||
|
||||
// Uncomment this with the url of a bundler to enable using an external
|
||||
// bundler (sometimes this is the same as rpcUrl). Otherwise, a bundler will
|
||||
// be simulated inside the library.
|
||||
// bundlerRpcUrl: '',
|
||||
|
||||
requirePermission: false,
|
||||
|
||||
// These contracts will be deployed deterministically by default. However,
|
||||
// if you need to interop with a specific existing deployment, you'll need
|
||||
// to specify the contracts here:
|
||||
// externalContracts: {
|
||||
// entryPoint: '0x...',
|
||||
// blsSignatureAggregator: '0x...',
|
||||
// addressRegistry: '0x...',
|
||||
// }
|
||||
// (Other contracts will still be deterministically deployed, but they
|
||||
// shouldn't be required for interop purposes.)
|
||||
};
|
||||
|
||||
export default config;
|
||||
|
||||
@@ -13,6 +13,7 @@ WaxInPage.addStylesheet();
|
||||
const waxInPage = new WaxInPage({
|
||||
rpcUrl: config.rpcUrl,
|
||||
bundlerRpcUrl: config.bundlerRpcUrl,
|
||||
externalContracts: config.externalContracts,
|
||||
});
|
||||
|
||||
waxInPage.attachGlobals();
|
||||
|
||||
@@ -1,12 +1,34 @@
|
||||
#!/usr/bin/env tsx
|
||||
|
||||
/* eslint-disable no-console */
|
||||
|
||||
import concurrently from 'concurrently';
|
||||
import config from '../demo/config/config.ts';
|
||||
|
||||
const tasks = ['vite'];
|
||||
|
||||
let externalNode: boolean;
|
||||
|
||||
if (config.rpcUrl === 'http://127.0.0.1:8545') {
|
||||
tasks.push('yarn --cwd hardhat hardhat node');
|
||||
try {
|
||||
await fetch(config.rpcUrl);
|
||||
externalNode = true;
|
||||
} catch (e) {
|
||||
if ((e as { code: string }).code !== 'ECONNREFUSED') {
|
||||
throw e;
|
||||
}
|
||||
|
||||
externalNode = false;
|
||||
tasks.push('yarn --cwd hardhat hardhat node');
|
||||
}
|
||||
} else {
|
||||
externalNode = true;
|
||||
}
|
||||
|
||||
if (externalNode) {
|
||||
console.log(`Relying on external node: ${config.rpcUrl}`);
|
||||
} else {
|
||||
console.log('Starting dev node');
|
||||
}
|
||||
|
||||
await concurrently(tasks, { killOthers: 'failure' }).result;
|
||||
|
||||
@@ -130,6 +130,10 @@ const Button = ({
|
||||
return;
|
||||
}
|
||||
|
||||
if ('key' in e && e.key !== 'Enter' && e.key !== ' ') {
|
||||
return;
|
||||
}
|
||||
|
||||
runAsync(async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
|
||||
@@ -13,12 +13,14 @@ import { roundUpPseudoFloat } from './helpers/encodeUtils';
|
||||
|
||||
// We need a UserOperation in order to estimate the gas fields of a
|
||||
// UserOperation, so we use these values as placeholders.
|
||||
const temporaryEstimationGas = '0x012345';
|
||||
const temporaryEstimationGas = '0x01234567';
|
||||
const temporarySignature = [
|
||||
'0x',
|
||||
'123456fe2807660c417ca1a38760342fa70135fcab89a8c7c879a77da8ce7a0b5a3805735e',
|
||||
'95170906b11c6f30dcc74e463e1e6990c68a3998a7271b728b123456',
|
||||
].join('');
|
||||
const verificationGasLimitBuffer = 2000n;
|
||||
const preVerificationGasBuffer = 1000n;
|
||||
|
||||
type StrictUserOperation = {
|
||||
sender: string;
|
||||
@@ -183,9 +185,15 @@ export default class EthereumApi {
|
||||
|
||||
return {
|
||||
...userOp,
|
||||
callGasLimit: roundUpPseudoFloat(userOp.callGasLimit),
|
||||
verificationGasLimit: `0x${roundUpPseudoFloat(
|
||||
BigInt(userOp.verificationGasLimit),
|
||||
).toString(16)}`,
|
||||
preVerificationGas: `0x${roundUpPseudoFloat(
|
||||
BigInt(userOp.preVerificationGas),
|
||||
).toString(16)}`,
|
||||
maxFeePerGas: roundUpPseudoFloat(userOp.maxFeePerGas),
|
||||
maxPriorityFeePerGas: roundUpPseudoFloat(userOp.maxPriorityFeePerGas),
|
||||
callGasLimit: roundUpPseudoFloat(userOp.callGasLimit),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -342,7 +350,7 @@ export default class EthereumApi {
|
||||
callData,
|
||||
callGasLimit: actions.map((a) => BigInt(a.gas)).reduce((a, b) => a + b),
|
||||
verificationGasLimit: temporaryEstimationGas,
|
||||
preVerificationGas: temporaryEstimationGas,
|
||||
preVerificationGas: '0x0',
|
||||
maxFeePerGas,
|
||||
maxPriorityFeePerGas,
|
||||
paymasterAndData: '0x',
|
||||
@@ -360,8 +368,14 @@ export default class EthereumApi {
|
||||
params: [userOp, await contracts.entryPoint.getAddress()],
|
||||
});
|
||||
|
||||
userOp.verificationGasLimit = verificationGasLimit;
|
||||
userOp.preVerificationGas = preVerificationGas;
|
||||
userOp.verificationGasLimit = `0x${(
|
||||
BigInt(verificationGasLimit) + verificationGasLimitBuffer
|
||||
).toString(16)}`;
|
||||
userOp.preVerificationGas = `0x${(
|
||||
BigInt(preVerificationGas) + preVerificationGasBuffer
|
||||
).toString(16)}`;
|
||||
|
||||
userOp = this.#maybeRoundUpPseudoFloats(userOp);
|
||||
|
||||
userOpHash = await this.#calculateUserOpHash(userOp);
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import z from 'zod';
|
||||
|
||||
class JsonRpcError extends Error {
|
||||
code: number;
|
||||
code: number | string;
|
||||
data: unknown;
|
||||
|
||||
constructor({ code, data, message }: RawJsonRpcError) {
|
||||
@@ -17,7 +17,7 @@ class JsonRpcError extends Error {
|
||||
}
|
||||
|
||||
const RawJsonRpcError = z.object({
|
||||
code: z.number().int(),
|
||||
code: z.union([z.number().int(), z.string()]),
|
||||
data: z.unknown(),
|
||||
message: z.string(),
|
||||
});
|
||||
|
||||
@@ -50,6 +50,7 @@ import measureCalldataGas from './measureCalldataGas';
|
||||
import DeterministicDeployer, {
|
||||
DeterministicDeploymentViewer,
|
||||
} from '../lib-ts/deterministic-deployer/DeterministicDeployer';
|
||||
import ConfigType from '../demo/config/ConfigType';
|
||||
|
||||
type Config = {
|
||||
logRequests?: boolean;
|
||||
@@ -58,6 +59,7 @@ type Config = {
|
||||
deployContractsIfNeeded: boolean;
|
||||
ethersPollingInterval?: number;
|
||||
useTopLevelCompression?: boolean;
|
||||
externalContracts?: ConfigType['externalContracts'];
|
||||
};
|
||||
|
||||
const defaultConfig: Config = {
|
||||
@@ -71,6 +73,7 @@ let ethersDefaultPollingInterval = 4000;
|
||||
type ConstructorOptions = {
|
||||
rpcUrl: string;
|
||||
bundlerRpcUrl?: string;
|
||||
externalContracts?: ConfigType['externalContracts'];
|
||||
storage?: WaxStorage;
|
||||
};
|
||||
|
||||
@@ -103,6 +106,7 @@ export default class WaxInPage {
|
||||
constructor({
|
||||
rpcUrl,
|
||||
bundlerRpcUrl,
|
||||
externalContracts,
|
||||
storage = makeLocalWaxStorage(),
|
||||
}: ConstructorOptions) {
|
||||
let bundler: IBundler;
|
||||
@@ -113,6 +117,8 @@ export default class WaxInPage {
|
||||
bundler = new NetworkBundler(bundlerRpcUrl);
|
||||
}
|
||||
|
||||
this.#config.externalContracts =
|
||||
externalContracts ?? this.#config.externalContracts;
|
||||
this.ethereum = new EthereumApi(rpcUrl, this, bundler);
|
||||
this.storage = storage;
|
||||
this.ethersProvider = new ethers.BrowserProvider(this.ethereum);
|
||||
@@ -194,15 +200,48 @@ export default class WaxInPage {
|
||||
chainId,
|
||||
);
|
||||
|
||||
const assumedEntryPoint = viewer.connectAssume(EntryPoint__factory, []);
|
||||
|
||||
const assumedAddressRegistry = viewer.connectAssume(
|
||||
AddressRegistry__factory,
|
||||
[],
|
||||
);
|
||||
const wallet = await this.requestAdminAccount('deploy-contracts');
|
||||
|
||||
const assumedBlsOpen = viewer.connectAssume(BLSOpen__factory, []);
|
||||
|
||||
let assumedEntryPoint: EntryPoint;
|
||||
let assumedAddressRegistry: AddressRegistry;
|
||||
let assumedBlsSignatureAggregator: BLSSignatureAggregator;
|
||||
|
||||
if (this.#config.externalContracts) {
|
||||
assumedEntryPoint = EntryPoint__factory.connect(
|
||||
this.#config.externalContracts.entryPoint,
|
||||
wallet,
|
||||
);
|
||||
|
||||
assumedBlsSignatureAggregator = BLSSignatureAggregator__factory.connect(
|
||||
this.#config.externalContracts.blsSignatureAggregator,
|
||||
wallet,
|
||||
);
|
||||
|
||||
assumedAddressRegistry = AddressRegistry__factory.connect(
|
||||
this.#config.externalContracts.addressRegistry,
|
||||
wallet,
|
||||
);
|
||||
} else {
|
||||
assumedEntryPoint = viewer.connectAssume(EntryPoint__factory, []);
|
||||
|
||||
assumedAddressRegistry = viewer.connectAssume(
|
||||
AddressRegistry__factory,
|
||||
[],
|
||||
);
|
||||
|
||||
assumedBlsSignatureAggregator = viewer.connectAssume(
|
||||
DeterministicDeployer.link(BLSSignatureAggregator__factory, [
|
||||
{
|
||||
'account-abstraction/contracts/samples/bls/lib/BLSOpen.sol:BLSOpen':
|
||||
await assumedBlsOpen.getAddress(),
|
||||
},
|
||||
]),
|
||||
[],
|
||||
);
|
||||
}
|
||||
|
||||
const contracts: Contracts = {
|
||||
greeter: viewer.connectAssume(Greeter__factory, ['']).connect(runner),
|
||||
entryPoint: assumedEntryPoint,
|
||||
@@ -226,15 +265,7 @@ export default class WaxInPage {
|
||||
[],
|
||||
),
|
||||
testToken: viewer.connectAssume(ERC20Mock__factory, []),
|
||||
blsSignatureAggregator: viewer.connectAssume(
|
||||
DeterministicDeployer.link(BLSSignatureAggregator__factory, [
|
||||
{
|
||||
'account-abstraction/contracts/samples/bls/lib/BLSOpen.sol:BLSOpen':
|
||||
await assumedBlsOpen.getAddress(),
|
||||
},
|
||||
]),
|
||||
[],
|
||||
),
|
||||
blsSignatureAggregator: assumedBlsSignatureAggregator,
|
||||
};
|
||||
|
||||
if (this.#contractsDeployed) {
|
||||
@@ -250,19 +281,49 @@ export default class WaxInPage {
|
||||
throw new Error('Contracts not deployed');
|
||||
}
|
||||
|
||||
const wallet = await this.requestAdminAccount('deploy-contracts');
|
||||
|
||||
const factory = await DeterministicDeployer.init(wallet);
|
||||
|
||||
const entryPoint = await factory.connectOrDeploy(EntryPoint__factory, []);
|
||||
|
||||
const addressRegistry = await factory.connectOrDeploy(
|
||||
AddressRegistry__factory,
|
||||
[],
|
||||
);
|
||||
|
||||
const blsOpen = await factory.connectOrDeploy(BLSOpen__factory, []);
|
||||
|
||||
let entryPoint: EntryPoint;
|
||||
let blsSignatureAggregator: BLSSignatureAggregator;
|
||||
let addressRegistry: AddressRegistry;
|
||||
|
||||
if (this.#config.externalContracts) {
|
||||
entryPoint = assumedEntryPoint;
|
||||
blsSignatureAggregator = assumedBlsSignatureAggregator;
|
||||
addressRegistry = assumedAddressRegistry;
|
||||
|
||||
await Promise.all(
|
||||
[entryPoint, blsSignatureAggregator, addressRegistry].map(
|
||||
async (contract) => {
|
||||
if (!(await this.#checkDeployed(await contract.getAddress()))) {
|
||||
throw new Error(
|
||||
`External contract not deployed: ${await contract.getAddress()}`,
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
} else {
|
||||
entryPoint = await factory.connectOrDeploy(EntryPoint__factory, []);
|
||||
|
||||
blsSignatureAggregator = await factory.connectOrDeploy(
|
||||
DeterministicDeployer.link(BLSSignatureAggregator__factory, [
|
||||
{
|
||||
'account-abstraction/contracts/samples/bls/lib/BLSOpen.sol:BLSOpen':
|
||||
await blsOpen.getAddress(),
|
||||
},
|
||||
]),
|
||||
[],
|
||||
);
|
||||
|
||||
addressRegistry = await factory.connectOrDeploy(
|
||||
AddressRegistry__factory,
|
||||
[],
|
||||
);
|
||||
}
|
||||
|
||||
const deployments: {
|
||||
[C in keyof Contracts]: () => Promise<Contracts[C]>;
|
||||
} = {
|
||||
@@ -285,16 +346,7 @@ export default class WaxInPage {
|
||||
safeECDSARecoveryPlugin: () =>
|
||||
factory.connectOrDeploy(SafeECDSARecoveryPlugin__factory, []),
|
||||
testToken: () => factory.connectOrDeploy(ERC20Mock__factory, []),
|
||||
blsSignatureAggregator: async () =>
|
||||
factory.connectOrDeploy(
|
||||
DeterministicDeployer.link(BLSSignatureAggregator__factory, [
|
||||
{
|
||||
'account-abstraction/contracts/samples/bls/lib/BLSOpen.sol:BLSOpen':
|
||||
await blsOpen.getAddress(),
|
||||
},
|
||||
]),
|
||||
[],
|
||||
),
|
||||
blsSignatureAggregator: () => Promise.resolve(blsSignatureAggregator),
|
||||
};
|
||||
|
||||
for (const deployment of Object.values(deployments)) {
|
||||
@@ -306,18 +358,19 @@ export default class WaxInPage {
|
||||
|
||||
async #checkDeployments(contracts: Contracts): Promise<boolean> {
|
||||
const deployFlags = await Promise.all(
|
||||
Object.values(contracts).map(async (contract) => {
|
||||
const existingCode = await this.ethersProvider.getCode(
|
||||
contract.getAddress(),
|
||||
);
|
||||
|
||||
return existingCode !== '0x';
|
||||
}),
|
||||
Object.values(contracts).map(
|
||||
async (contract) =>
|
||||
await this.#checkDeployed(await contract.getAddress()),
|
||||
),
|
||||
);
|
||||
|
||||
return deployFlags.every((flag) => flag);
|
||||
}
|
||||
|
||||
async #checkDeployed(address: string): Promise<boolean> {
|
||||
return (await this.ethersProvider.getCode(address)) !== '0x';
|
||||
}
|
||||
|
||||
async requestAdminAccount(purpose: AdminPurpose): Promise<ethers.Wallet> {
|
||||
if (this.#adminAccount) {
|
||||
return this.#adminAccount;
|
||||
|
||||
@@ -23,7 +23,6 @@ import {
|
||||
hexJoin,
|
||||
hexLen,
|
||||
lookupAddress,
|
||||
roundUpPseudoFloat,
|
||||
} from '../helpers/encodeUtils';
|
||||
import windowDebug from '../../demo/windowDebug';
|
||||
import simulateValidation from '../helpers/simulateValidation';
|
||||
@@ -148,19 +147,13 @@ export default class SimulatedBundler implements IBundler {
|
||||
],
|
||||
});
|
||||
|
||||
let res = {
|
||||
return {
|
||||
preVerificationGas: `0x${(basePreVerificationGas + calldataGas).toString(
|
||||
16,
|
||||
)}`,
|
||||
verificationGasLimit: `0x${verificationGasLimit.toString(16)}`,
|
||||
callGasLimit,
|
||||
};
|
||||
|
||||
if (this.#waxInPage.getConfig('useTopLevelCompression')) {
|
||||
res = SimulatedBundler.roundUpGasEstimate(res);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
async eth_getUserOperationReceipt(
|
||||
@@ -513,21 +506,6 @@ export default class SimulatedBundler implements IBundler {
|
||||
parts.push(encodeBytes(calldata));
|
||||
}
|
||||
}
|
||||
|
||||
static roundUpGasEstimate({
|
||||
preVerificationGas,
|
||||
verificationGasLimit,
|
||||
callGasLimit,
|
||||
}: EthereumRpc.UserOperationGasEstimate): EthereumRpc.UserOperationGasEstimate {
|
||||
const roundUp = (x: string) =>
|
||||
`0x${roundUpPseudoFloat(BigInt(x)).toString(16)}`;
|
||||
|
||||
return {
|
||||
preVerificationGas: roundUp(preVerificationGas),
|
||||
verificationGasLimit: roundUp(verificationGasLimit),
|
||||
callGasLimit: roundUp(callGasLimit),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const decompressAndPerformSelector = ethers.FunctionFragment.getSelector(
|
||||
|
||||
2
packages/plugins/.gitignore
vendored
2
packages/plugins/.gitignore
vendored
@@ -10,3 +10,5 @@ cache
|
||||
cache_hardhat
|
||||
artifacts
|
||||
|
||||
deployedAddresses.backup.json
|
||||
deployedAddresses.json
|
||||
|
||||
@@ -20,7 +20,7 @@ const config: HardhatUserConfig = {
|
||||
settings: {
|
||||
optimizer: {
|
||||
enabled: true,
|
||||
runs: 200,
|
||||
runs: 1_000_000,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import fs from "fs/promises";
|
||||
import { ethers } from "ethers";
|
||||
import DeterministicDeployer from "../lib-ts/deterministic-deployer/DeterministicDeployer";
|
||||
import DeterministicDeployer, {
|
||||
ContractFactoryConstructor,
|
||||
DeployParams,
|
||||
} from "../lib-ts/deterministic-deployer/DeterministicDeployer";
|
||||
import {
|
||||
SimulateTxAccessor__factory,
|
||||
SafeProxyFactory__factory,
|
||||
@@ -13,11 +17,17 @@ import {
|
||||
EntryPoint__factory,
|
||||
BLSSignatureAggregator__factory,
|
||||
BLSOpen__factory,
|
||||
HandleOpsCaller__factory,
|
||||
HandleAggregatedOpsCaller__factory,
|
||||
AddressRegistry__factory,
|
||||
} from "../typechain-types";
|
||||
import makeDevFaster from "../test/e2e/utils/makeDevFaster";
|
||||
import { TokenCallbackHandler__factory } from "../typechain-types/factories/lib/safe-contracts/contracts/handler/TokenCallbackHandler__factory";
|
||||
import bundlerConfig from "./../config/bundler.config.json";
|
||||
|
||||
// 'test '.repeat(11) + 'absent'
|
||||
const testAbsentAddress = "0xe8250207B79D7396631bb3aE38a7b457261ae0B6";
|
||||
|
||||
async function deploy() {
|
||||
const { NODE_URL, MNEMONIC } = process.env;
|
||||
const provider = new ethers.JsonRpcProvider(NODE_URL);
|
||||
@@ -25,63 +35,140 @@ async function deploy() {
|
||||
const hdNode = ethers.HDNodeWallet.fromPhrase(MNEMONIC!);
|
||||
const wallet = new ethers.Wallet(hdNode.privateKey, provider);
|
||||
|
||||
const deployer = await DeterministicDeployer.init(wallet);
|
||||
const recordingDeployer = await RecordingDeployer.init(wallet);
|
||||
|
||||
const contractFactories = [
|
||||
SimulateTxAccessor__factory,
|
||||
TokenCallbackHandler__factory,
|
||||
CompatibilityFallbackHandler__factory,
|
||||
CreateCall__factory,
|
||||
EntryPoint__factory,
|
||||
MultiSend__factory,
|
||||
MultiSendCallOnly__factory,
|
||||
SignMessageLib__factory,
|
||||
BLSOpen__factory,
|
||||
];
|
||||
|
||||
for (const contractFactory of contractFactories) {
|
||||
const contract = await deployer.connectOrDeploy(contractFactory, []);
|
||||
|
||||
const contractName = contractFactory.name.split("_")[0];
|
||||
console.log(`deployed ${contractName} to ${await contract.getAddress()}`);
|
||||
}
|
||||
|
||||
const blsSignatureAggregatorFactory = DeterministicDeployer.link(
|
||||
const linkedAggregator = DeterministicDeployer.link(
|
||||
BLSSignatureAggregator__factory,
|
||||
[
|
||||
{
|
||||
"lib/account-abstraction/contracts/samples/bls/lib/BLSOpen.sol:BLSOpen":
|
||||
deployer.calculateAddress(BLSOpen__factory, []),
|
||||
recordingDeployer.deployer.calculateAddress(BLSOpen__factory, []),
|
||||
},
|
||||
],
|
||||
);
|
||||
const blsSignatureAggregator = await deployer.connectOrDeploy(
|
||||
blsSignatureAggregatorFactory,
|
||||
[bundlerConfig.entryPoint],
|
||||
);
|
||||
console.log(
|
||||
`deployed ${
|
||||
BLSSignatureAggregator__factory.name.split("_")[0]
|
||||
} to ${await blsSignatureAggregator.getAddress()}`,
|
||||
|
||||
const deployments = [
|
||||
["SimulateTxAccessor", SimulateTxAccessor__factory],
|
||||
["TokenCallbackHandler", TokenCallbackHandler__factory],
|
||||
["CompatibilityFallbackHandler", CompatibilityFallbackHandler__factory],
|
||||
["CreateCall", CreateCall__factory],
|
||||
["EntryPoint", EntryPoint__factory],
|
||||
["MultiSend", MultiSend__factory],
|
||||
["MultiSendCallOnly", MultiSendCallOnly__factory],
|
||||
["SignMessageLib", SignMessageLib__factory],
|
||||
["BLSOpen", BLSOpen__factory],
|
||||
["BLSSignatureAggregator", linkedAggregator],
|
||||
["AddressRegistry", AddressRegistry__factory],
|
||||
] as const;
|
||||
|
||||
for (const [name, contractFactory] of deployments) {
|
||||
await recordingDeployer.deploy(name, contractFactory, []);
|
||||
}
|
||||
|
||||
const handleOpsCaller = await recordingDeployer.deploy(
|
||||
"HandleOpsCaller",
|
||||
HandleOpsCaller__factory,
|
||||
[
|
||||
recordingDeployer.deployer.calculateAddress(EntryPoint__factory, []),
|
||||
testAbsentAddress,
|
||||
recordingDeployer.deployer.calculateAddress(AddressRegistry__factory, []),
|
||||
],
|
||||
);
|
||||
|
||||
const safeDeployer = await DeterministicDeployer.initSafeVersion(wallet);
|
||||
const handleAggregatedOpsCaller = await recordingDeployer.deploy(
|
||||
"HandleAggregatedOpsCaller",
|
||||
HandleAggregatedOpsCaller__factory,
|
||||
[
|
||||
recordingDeployer.deployer.calculateAddress(EntryPoint__factory, []),
|
||||
testAbsentAddress,
|
||||
recordingDeployer.deployer.calculateAddress(linkedAggregator, []),
|
||||
recordingDeployer.deployer.calculateAddress(AddressRegistry__factory, []),
|
||||
],
|
||||
);
|
||||
|
||||
void handleOpsCaller;
|
||||
void handleAggregatedOpsCaller;
|
||||
|
||||
const safeContractFactories = [
|
||||
SafeProxyFactory__factory,
|
||||
SafeL2__factory,
|
||||
Safe__factory,
|
||||
];
|
||||
["SafeProxyFactory", SafeProxyFactory__factory],
|
||||
["SafeL2", SafeL2__factory],
|
||||
["Safe", Safe__factory],
|
||||
] as const;
|
||||
|
||||
for (const contractFactory of safeContractFactories) {
|
||||
const contract = await safeDeployer.connectOrDeploy(contractFactory, []);
|
||||
|
||||
const contractName = contractFactory.name.split("_")[0];
|
||||
console.log(`deployed ${contractName} to ${await contract.getAddress()}`);
|
||||
for (const [name, contractFactory] of safeContractFactories) {
|
||||
await recordingDeployer.deployWithSafeDeployer(name, contractFactory, []);
|
||||
}
|
||||
|
||||
await recordingDeployer.finish();
|
||||
}
|
||||
|
||||
deploy().catch((error: Error) => {
|
||||
console.error(error);
|
||||
process.exitCode = 1;
|
||||
});
|
||||
|
||||
class RecordingDeployer {
|
||||
deployments: Record<string, string> = {};
|
||||
|
||||
private constructor(
|
||||
public deployer: DeterministicDeployer,
|
||||
public safeDeployer: DeterministicDeployer,
|
||||
) {}
|
||||
|
||||
static async init(wallet: ethers.Wallet): Promise<RecordingDeployer> {
|
||||
const deployer = await DeterministicDeployer.init(wallet);
|
||||
const safeDeployer = await DeterministicDeployer.initSafeVersion(wallet);
|
||||
|
||||
try {
|
||||
await fs.rename(
|
||||
"deployedAddresses.json",
|
||||
"deployedAddresses.backup.json",
|
||||
);
|
||||
} catch (e) {
|
||||
if ((e as { code: string }).code !== "ENOENT") {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
return new RecordingDeployer(deployer, safeDeployer);
|
||||
}
|
||||
|
||||
async deploy<CFC extends ContractFactoryConstructor>(
|
||||
name: string,
|
||||
factory: CFC,
|
||||
args: DeployParams<CFC>,
|
||||
) {
|
||||
return this.deployImpl(name, factory, args, this.deployer);
|
||||
}
|
||||
|
||||
async deployWithSafeDeployer<CFC extends ContractFactoryConstructor>(
|
||||
name: string,
|
||||
factory: CFC,
|
||||
args: DeployParams<CFC>,
|
||||
) {
|
||||
return this.deployImpl(name, factory, args, this.safeDeployer);
|
||||
}
|
||||
|
||||
private async deployImpl<CFC extends ContractFactoryConstructor>(
|
||||
name: string,
|
||||
factory: CFC,
|
||||
args: DeployParams<CFC>,
|
||||
deployer: DeterministicDeployer,
|
||||
) {
|
||||
const contract = await deployer.connectOrDeploy(factory, args);
|
||||
const address = await contract.getAddress();
|
||||
console.log(`Deployed ${name} to ${address}`);
|
||||
this.deployments[name] = address;
|
||||
|
||||
return contract;
|
||||
}
|
||||
|
||||
async finish() {
|
||||
await fs.writeFile(
|
||||
"deployedAddresses.json",
|
||||
JSON.stringify(this.deployments, null, 2),
|
||||
);
|
||||
|
||||
await fs.rm("deployedAddresses.backup.json", { force: true });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@ SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
||||
set -meuo pipefail
|
||||
|
||||
function cleanup {
|
||||
docker stop $CONTAINER || true
|
||||
jobs -p | xargs kill
|
||||
}
|
||||
|
||||
|
||||
@@ -151,7 +151,7 @@ contract SafeZkEmailRecoveryPlugin_Integration_Test is TestHelper {
|
||||
);
|
||||
emailProof.timestamp = block.timestamp;
|
||||
emailProof
|
||||
.maskedSubject = "Accept guardian request for 0x78cA0A67bF6Cbe8Bf2429f0c7934eE5Dd687a32c";
|
||||
.maskedSubject = "Accept guardian request for 0x5991A2dF15A8F6A256D3Ec51E99254Cd3fb576A9";
|
||||
emailProof.emailNullifier = keccak256(abi.encode("nullifier 1"));
|
||||
emailProof.accountSalt = accountSalt;
|
||||
emailProof.isCodeExist = true;
|
||||
@@ -185,7 +185,7 @@ contract SafeZkEmailRecoveryPlugin_Integration_Test is TestHelper {
|
||||
);
|
||||
emailProof.timestamp = block.timestamp + 1;
|
||||
emailProof
|
||||
.maskedSubject = "Update owner to 0xDdF4497d39b10cf50Af640942cc15233970dA0c2 on account 0x78cA0A67bF6Cbe8Bf2429f0c7934eE5Dd687a32c";
|
||||
.maskedSubject = "Update owner to 0xDdF4497d39b10cf50Af640942cc15233970dA0c2 on account 0x5991A2dF15A8F6A256D3Ec51E99254Cd3fb576A9";
|
||||
emailProof.emailNullifier = keccak256(abi.encode("nullifier 2"));
|
||||
emailProof.accountSalt = accountSalt;
|
||||
require(
|
||||
|
||||
Reference in New Issue
Block a user