Skip to content

Commit

Permalink
improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
avkos committed Oct 1, 2024
1 parent fdf8eb3 commit e8fcd72
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 61 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "web3-plugin-zksync",
"version": "1.0.7",
"version": "1.0.8",
"description": "web3.js plugin for ZkSync",
"main": "lib/index.js",
"types": "lib/index.d.ts",
Expand Down
50 changes: 34 additions & 16 deletions src/contract-factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
import type { DeploymentType, TransactionRequest } from './types';
import { AccountAbstractionVersion } from './types';
import type { ZKsyncWallet } from './zksync-wallet';
import { SmartAccount } from './smart-account';

interface CustomData {
factoryDeps?: (string | { object: string })[];
Expand All @@ -38,7 +39,7 @@ export class ContractFactory<Abi extends ContractAbi> extends Web3Context {
*/
readonly bytecode!: string;

readonly zkWallet: ZKsyncWallet;
readonly zkWallet: ZKsyncWallet | SmartAccount;

/** The deployment type that is currently in use. */
readonly deploymentType: DeploymentType;
Expand All @@ -55,7 +56,7 @@ export class ContractFactory<Abi extends ContractAbi> extends Web3Context {
constructor(
abi: Abi,
bytecode: web3Types.Bytes,
zkWallet: ZKsyncWallet,
zkWallet: ZKsyncWallet | SmartAccount,
deploymentType?: DeploymentType,
) {
super(zkWallet.provider);
Expand Down Expand Up @@ -89,16 +90,29 @@ export class ContractFactory<Abi extends ContractAbi> extends Web3Context {
bytecodeHash: web3Types.Bytes,
constructorCalldata: web3Types.Bytes,
): string {
const contractDeploymentArgs = [salt, web3Utils.bytesToHex(bytecodeHash), constructorCalldata];
const accountDeploymentArgs = [...contractDeploymentArgs, AccountAbstractionVersion.Version1];
const contractDeploymentArgs = [
salt,
web3Utils.bytesToHex(bytecodeHash),
constructorCalldata,
];
const accountDeploymentArgs = [
...contractDeploymentArgs,
AccountAbstractionVersion.Version1,
];

switch (this.deploymentType) {
case 'create':
return ContractDeployerContract.methods.create(...contractDeploymentArgs).encodeABI();
return ContractDeployerContract.methods
.create(...contractDeploymentArgs)
.encodeABI();
case 'createAccount':
return ContractDeployerContract.methods.createAccount(...accountDeploymentArgs).encodeABI();
return ContractDeployerContract.methods
.createAccount(...accountDeploymentArgs)
.encodeABI();
case 'create2':
return ContractDeployerContract.methods.create2(...contractDeploymentArgs).encodeABI();
return ContractDeployerContract.methods
.create2(...contractDeploymentArgs)
.encodeABI();
case 'create2Account':
return ContractDeployerContract.methods
.create2Account(...accountDeploymentArgs)
Expand All @@ -123,7 +137,10 @@ export class ContractFactory<Abi extends ContractAbi> extends Web3Context {
throw new Error('Salt is required for CREATE2 deployment!');
}

if (!overrides.customData.salt.startsWith('0x') || overrides.customData.salt.length !== 66) {
if (
!overrides.customData.salt.startsWith('0x') ||
overrides.customData.salt.length !== 66
) {
throw new Error('Invalid salt provided!');
}
}
Expand All @@ -146,14 +163,15 @@ export class ContractFactory<Abi extends ContractAbi> extends Web3Context {
let constructorArgs: any[];

// The overrides will be popped out in this call:
const txRequest: web3Types.TransactionCall & { customData?: any } = this.contractToBeDeployed
.deploy({
data: this.bytecode,
arguments: args,
})
.populateTransaction({
from: this.zkWallet.getAddress() ?? this.defaultAccount ?? undefined,
});
const txRequest: web3Types.TransactionCall & { customData?: any } =
this.contractToBeDeployed
.deploy({
data: this.bytecode,
arguments: args,
})
.populateTransaction({
from: this.zkWallet.getAddress() ?? this.defaultAccount ?? undefined,
});

this.checkOverrides(overrides);
let overridesCopy: Overrides = overrides ?? {
Expand Down
107 changes: 68 additions & 39 deletions src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { ECDSASmartAccount, MultisigECDSASmartAccount, SmartAccount } from './sm

interface ZKsyncWalletConstructor {
new (privateKey: string): ZKsyncWallet;
createRandom: () => ZKsyncWallet;
}
interface ZKsyncAccountConstructor {
new (signer: SmartAccountSigner): SmartAccount;
Expand Down Expand Up @@ -90,10 +91,14 @@ export class ZKsyncPlugin extends Web3PluginBase {
* const PRIVATE_KEY = "<WALLET_PRIVATE_KEY>";
* const zkWallet = new web3.ZKsync.ZkWallet(PRIVATE_KEY);
*/
// the wallet type in this class is different from the parent class. So, they should have different names.

// @ts-ignore - Initialized in the initWallet method which called in the constructor
Wallet: ZKsyncWalletConstructor;
// @ts-ignore - Initialized in the initWallet method which called in the constructor
SmartAccount: ZKsyncAccountConstructor;
// @ts-ignore - Initialized in the initWallet method which called in the constructor
ECDSASmartAccount: ZKsyncECDSASmartAccountConstructor;
// @ts-ignore - Initialized in the initWallet method which called in the constructor
MultisigECDSASmartAccount: ZKsyncMultisigECDSASmartAccountConstructor;
/**
* Create a new ZKsync plugin for the provided L2 network
Expand All @@ -107,7 +112,10 @@ export class ZKsyncPlugin extends Web3PluginBase {
| Web3ZKsyncL2,
) {
super(
providerOrContextL2 as string | web3Types.SupportedProviders<any> | Web3ContextInitOptions,
providerOrContextL2 as
| string
| web3Types.SupportedProviders<any>
| Web3ContextInitOptions,
);
if (providerOrContextL2 instanceof Web3ZKsyncL2) {
this.L2 = providerOrContextL2;
Expand All @@ -118,32 +126,6 @@ export class ZKsyncPlugin extends Web3PluginBase {
this._l2BridgeContracts = {};
this._erc20Contracts = {};

const self = this;
class ZKsyncWalletWithFullContext extends ZKsyncWallet {
constructor(privateKey: string) {
super(privateKey, self.L2, self.L1);
}
}
class ZKsyncAccountWithFullContext extends SmartAccount {
constructor(signer: SmartAccountSigner) {
super(signer, self.L2);
}
}
class ZKsyncECDSASmartAccountWithFullContext {
static create(address: string, secret: string): SmartAccount {
return ECDSASmartAccount.create(address, secret, self.L2);
}
}
class ZKsyncMultisigECDSASmartAccountWithFullContext extends MultisigECDSASmartAccount {
static create(address: string, secret: string[]): SmartAccount {
return MultisigECDSASmartAccount.create(address, secret, self.L2);
}
}

this.Wallet = ZKsyncWalletWithFullContext;
this.SmartAccount = ZKsyncAccountWithFullContext;
this.ECDSASmartAccount = ZKsyncECDSASmartAccountWithFullContext;
this.MultisigECDSASmartAccount = ZKsyncMultisigECDSASmartAccountWithFullContext;
this.initWallet();
}

Expand All @@ -158,8 +140,12 @@ export class ZKsyncPlugin extends Web3PluginBase {
);
}

const { mainContract, bridgehubContractAddress, l1SharedDefaultBridge, l2SharedDefaultBridge } =
await this.ContractsAddresses;
const {
mainContract,
bridgehubContractAddress,
l1SharedDefaultBridge,
l2SharedDefaultBridge,
} = await this.ContractsAddresses;

const contractsCollection: ZKSyncContractsCollection = {
Generic: {
Expand All @@ -177,8 +163,16 @@ export class ZKsyncPlugin extends Web3PluginBase {
constants.CONTRACT_DEPLOYER_ADDRESS,
this.L2,
),
L1MessengerContract: new Contract(IL1MessengerABI, constants.L1_MESSENGER_ADDRESS, this.L2),
NonceHolderContract: new Contract(INonceHolderABI, constants.NONCE_HOLDER_ADDRESS, this.L2),
L1MessengerContract: new Contract(
IL1MessengerABI,
constants.L1_MESSENGER_ADDRESS,
this.L2,
),
NonceHolderContract: new Contract(
INonceHolderABI,
constants.NONCE_HOLDER_ADDRESS,
this.L2,
),
L2BridgeContract: new Contract(IL2BridgeABI, l2SharedDefaultBridge, this.L2),
},
};
Expand Down Expand Up @@ -217,21 +211,44 @@ export class ZKsyncPlugin extends Web3PluginBase {

private initWallet() {
const self = this;
class ZKSyncWalletWithFullContext extends ZKsyncWallet {
class ZKsyncWalletWithFullContext extends ZKsyncWallet {
constructor(privateKey: string) {
super(privateKey, self.L2, self.L1);
}
static override createRandom() {
return ZKsyncWallet.createRandom(self.L2, self.L1);
}
}
class ZKsyncAccountWithFullContext extends SmartAccount {
constructor(signer: SmartAccountSigner) {
super(signer, self.L2);
}
}
class ZKsyncECDSASmartAccountWithFullContext {
static create(address: string, secret: string): SmartAccount {
return ECDSASmartAccount.create(address, secret, self.L2);
}
}
class ZKsyncMultisigECDSASmartAccountWithFullContext extends MultisigECDSASmartAccount {
static create(address: string, secret: string[]): SmartAccount {
return MultisigECDSASmartAccount.create(address, secret, self.L2);
}
}

this.Wallet = ZKSyncWalletWithFullContext;
this.SmartAccount = ZKsyncAccountWithFullContext;
this.ECDSASmartAccount = ZKsyncECDSASmartAccountWithFullContext;
this.MultisigECDSASmartAccount = ZKsyncMultisigECDSASmartAccountWithFullContext;
this.Wallet = ZKsyncWalletWithFullContext;
}

/**
* Get RPC methods instance
*/
get rpc(): RpcMethods {
if (!this._rpc) {
this._rpc = new RpcMethods(this.L2.requestManager as unknown as Web3RequestManager<unknown>);
this._rpc = new RpcMethods(
this.L2.requestManager as unknown as Web3RequestManager<unknown>,
);
}
return this._rpc;
}
Expand All @@ -246,8 +263,16 @@ export class ZKsyncPlugin extends Web3PluginBase {
* For example, if the L1 or L2 providers were changed from testnet to mainnet, this method should be called.
*/
public updateProviders(
contextL1: Web3ZKsyncL1 | web3Types.SupportedProviders<any> | Web3ContextInitOptions | string,
contextL2: Web3ZKsyncL2 | web3Types.SupportedProviders<any> | Web3ContextInitOptions | string,
contextL1:
| Web3ZKsyncL1
| web3Types.SupportedProviders<any>
| Web3ContextInitOptions
| string,
contextL2:
| Web3ZKsyncL2
| web3Types.SupportedProviders<any>
| Web3ContextInitOptions
| string,
) {
this.L1 = contextL1 instanceof Web3ZKsyncL1 ? contextL1 : new Web3ZKsyncL1(contextL1);
this.L2 = contextL2 instanceof Web3ZKsyncL2 ? contextL2 : new Web3ZKsyncL2(contextL2);
Expand Down Expand Up @@ -294,7 +319,9 @@ export class ZKsyncPlugin extends Web3PluginBase {
return l1Token;
}
} catch (e) {
throw new Error(`Error getting L1 address for token ${token}. ${JSON.stringify(e)}`);
throw new Error(
`Error getting L1 address for token ${token}. ${JSON.stringify(e)}`,
);
}
}

Expand All @@ -320,7 +347,9 @@ export class ZKsyncPlugin extends Web3PluginBase {
return l2WethToken;
}
} catch (e) {
throw new Error(`Error getting L2 address for token ${token}. ${JSON.stringify(e)}`);
throw new Error(
`Error getting L2 address for token ${token}. ${JSON.stringify(e)}`,
);
}
}

Expand Down
3 changes: 3 additions & 0 deletions src/web3zksync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -241,4 +241,7 @@ export class Web3ZkSync extends Web3.Web3 {
async sendRawTransaction(signedTx: string) {
return ethRpcMethods.sendRawTransaction(this.requestManager, signedTx);
}
async sendTransaction(tx: TransactionRequest) {
return this.eth.sendTransaction(tx as Transaction);
}
}
9 changes: 4 additions & 5 deletions src/zksync-wallet.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { Web3Account } from 'web3-eth-accounts';
import { privateKeyToAccount, create as createAccount } from 'web3-eth-accounts';
import type * as web3Types from 'web3-types';
import type { Web3ZKsyncL2 } from './web3zksync-l2';
import { Web3ZKsyncL2 } from './web3zksync-l2';
import type { Web3ZKsyncL1 } from './web3zksync-l1';
import { AdapterL1, AdapterL2 } from './adapters';
import {
Expand Down Expand Up @@ -58,7 +58,8 @@ class Adapters extends AdapterL1 {
* Capabilities for integrating, creating, and managing ZKsync wallets.
*/
export class ZKsyncWallet extends Adapters {
provider?: Web3ZKsyncL2;
// @ts-ignore - Property 'provider' assigned in the connect method which called in the constructor.
provider: Web3ZKsyncL2;
providerL1?: Web3ZKsyncL1;
public account: Web3Account;
/**
Expand Down Expand Up @@ -92,9 +93,7 @@ export class ZKsyncWallet extends Adapters {
super();

this.account = privateKeyToAccount(privateKey);
if (providerL2) {
this.connect(providerL2);
}
this.connect(providerL2 ?? new Web3ZKsyncL2());
if (providerL1) {
this.connectToL1(providerL1);
}
Expand Down

0 comments on commit e8fcd72

Please sign in to comment.