diff --git a/src/main/java/io/zksync/methods/response/ZksProtocolVersion.java b/src/main/java/io/zksync/methods/response/ZksProtocolVersion.java new file mode 100644 index 0000000..6812b08 --- /dev/null +++ b/src/main/java/io/zksync/methods/response/ZksProtocolVersion.java @@ -0,0 +1,7 @@ +package io.zksync.methods.response; + +import io.zksync.protocol.core.ProtocolVersion; +import org.web3j.protocol.core.Response; + +public class ZksProtocolVersion extends Response { +} diff --git a/src/main/java/io/zksync/protocol/JsonRpc2_0ZkSync.java b/src/main/java/io/zksync/protocol/JsonRpc2_0ZkSync.java index b1ec5dd..7f31730 100755 --- a/src/main/java/io/zksync/protocol/JsonRpc2_0ZkSync.java +++ b/src/main/java/io/zksync/protocol/JsonRpc2_0ZkSync.java @@ -9,15 +9,14 @@ import io.zksync.methods.request.Transaction; import io.zksync.methods.response.*; import io.zksync.protocol.core.BridgeAddresses; +import io.zksync.protocol.core.ProtocolVersion; import io.zksync.transaction.type.TransactionOptions; import io.zksync.transaction.type.TransferTransaction; import io.zksync.transaction.type.WithdrawTransaction; import io.zksync.utils.TransactionStatus; import io.zksync.utils.WalletUtils; import io.zksync.utils.ZkSyncAddresses; -import io.zksync.wrappers.ERC20; -import io.zksync.wrappers.IEthToken; -import io.zksync.wrappers.IL2Bridge; +import io.zksync.wrappers.*; import org.jetbrains.annotations.Nullable; import org.web3j.abi.FunctionEncoder; import org.web3j.abi.TypeReference; @@ -188,6 +187,10 @@ public Request estimateGasL1(Transaction transaction) { } public String l2TokenAddress(String tokenAddress){ + return l2TokenAddress(tokenAddress, null); + } + + public String l2TokenAddress(String tokenAddress, @Nullable String bridgeAddress){ if (tokenAddress.equalsIgnoreCase(ZkSyncAddresses.LEGACY_ETH_ADDRESS)){ tokenAddress = ZkSyncAddresses.ETH_ADDRESS_IN_CONTRACTS; } @@ -198,12 +201,53 @@ public String l2TokenAddress(String tokenAddress){ } BridgeAddresses bridgeAddresses = zksGetBridgeContracts().sendAsync().join().getResult(); + bridgeAddress = bridgeAddress != null ? bridgeAddress : bridgeAddresses.getL2SharedDefaultBridge(); BigInteger gas = ethGasPrice().sendAsync().join().getGasPrice(); - IL2Bridge shared = IL2Bridge.load(bridgeAddresses.getL2SharedDefaultBridge(), this, WalletUtils.createRandomCredentials(), gas, gas); + IL2SharedBridge shared = IL2SharedBridge.load(bridgeAddress, this, WalletUtils.createRandomCredentials(), gas, gas); return shared.l2TokenAddress(tokenAddress).sendAsync().join(); } + /** + * Return the protocol version + * + * Calls the {@link ... zks_getProtocolVersion} JSON-RPC method. + * + * @param id Specific version ID. + * + * @example + * + * import { Provider, types } from "zksync-ethers"; + * + * const provider = Provider.getDefaultProvider(types.Network.Sepolia); + * console.log(`Protocol version: ${await provider.getProtocolVersion()}`); + */ + public Request getProtocolVersion(int id){ + return new Request<>( + "zks_getProtocolVersion", + Collections.singletonList(id), + web3jService, + ZksProtocolVersion.class); + } + + /** + * Returns true if passed bridge address is legacy and false if its shared bridge. + ** + * @param address The bridge address. + */ + public RemoteCall isL2BridgeLegacy(String address) { + BigInteger gas = ethGasPrice().sendAsync().join().getGasPrice(); + IL2SharedBridge shared = IL2SharedBridge.load(address, this, WalletUtils.createRandomCredentials(), gas, gas); + return new RemoteCall<>(() -> { + try { + shared.l1SharedBridge().send(); + return true; + } catch (Exception e) { + return false; + } + }); + } + public Request estimateL1ToL2Execute(String contractAddress, byte[] calldata, String caller, @Nullable BigInteger l2GasLimit, @Nullable BigInteger l2Value, @Nullable byte[][] factoryDeps, @Nullable BigInteger operatorTip, @Nullable BigInteger gasPerPubDataByte, @Nullable String refoundRecepient) { if (gasPerPubDataByte == null){ gasPerPubDataByte = BigInteger.valueOf(800); diff --git a/src/main/java/io/zksync/protocol/ZkSync.java b/src/main/java/io/zksync/protocol/ZkSync.java index 6105e71..a14695c 100755 --- a/src/main/java/io/zksync/protocol/ZkSync.java +++ b/src/main/java/io/zksync/protocol/ZkSync.java @@ -8,6 +8,7 @@ import org.web3j.protocol.Web3j; import org.web3j.protocol.Web3jService; import org.web3j.protocol.core.DefaultBlockParameter; +import org.web3j.protocol.core.RemoteCall; import org.web3j.protocol.core.RemoteFunctionCall; import org.web3j.protocol.core.Request; import org.web3j.protocol.core.methods.request.EthFilter; @@ -197,6 +198,19 @@ Request zksGetBlockByNumber( */ String l2TokenAddress(String tokenAddress); + /** + * Returns the L2 token address equivalent for a L1 token address as they are not necessarily equal. + * The ETH address is set to the zero address. + * + * Only works for tokens bridged on default zkSync Era bridges. + * + * @param tokenAddress The address of the token on L1. + * @param customBridge The address of the token on L1. + */ + String l2TokenAddress(String tokenAddress, @Nullable String customBridge); + + public RemoteCall isL2BridgeLegacy(String address); + Request estimateL1ToL2Execute(String contractAddress, byte[] calldata, String caller, @Nullable BigInteger l2GasLimit, @Nullable BigInteger l2Value, @Nullable byte[][] factoryDeps, @Nullable BigInteger operatorTip, @Nullable BigInteger gasPerPubDataByte, @Nullable String refoundRecepient); Transaction getWithdrawTransaction(WithdrawTransaction tx, ContractGasProvider gasProvider, TransactionManager transactionManager) throws Exception; diff --git a/src/main/java/io/zksync/protocol/core/BaseSystemContracts.java b/src/main/java/io/zksync/protocol/core/BaseSystemContracts.java new file mode 100644 index 0000000..dca6411 --- /dev/null +++ b/src/main/java/io/zksync/protocol/core/BaseSystemContracts.java @@ -0,0 +1,11 @@ +package io.zksync.protocol.core; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor +@Getter +public class BaseSystemContracts { + private String bootloader; + private String defaultAa; +} diff --git a/src/main/java/io/zksync/protocol/core/Params.java b/src/main/java/io/zksync/protocol/core/Params.java new file mode 100644 index 0000000..d8187bc --- /dev/null +++ b/src/main/java/io/zksync/protocol/core/Params.java @@ -0,0 +1,12 @@ +package io.zksync.protocol.core; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class Params { + private String recursionNodeLevelVkHash; + private String recursionLeafLevelVkHash; + private String recursionCircuitsSetVksHash; +} diff --git a/src/main/java/io/zksync/protocol/core/ProtocolVersion.java b/src/main/java/io/zksync/protocol/core/ProtocolVersion.java new file mode 100644 index 0000000..cfbab7a --- /dev/null +++ b/src/main/java/io/zksync/protocol/core/ProtocolVersion.java @@ -0,0 +1,21 @@ +package io.zksync.protocol.core; + +import org.web3j.protocol.core.Response; + +public class ProtocolVersion { + /** Protocol version ID. */ + private int versionId; + + /** Unix timestamp of the version's activation. */ + private long timestamp; + + /** Contains the hashes of various verification keys used in the protocol. */ + private VerificationKeysHashes verificationKeysHashes; + + /** Addresses of the base system contracts. */ + private BaseSystemContracts baseSystemContracts; + + /** Hash of the transaction used for the system upgrade, if any. */ + private String l2SystemUpgradeTxHash; +} + diff --git a/src/main/java/io/zksync/protocol/core/VerificationKeysHashes.java b/src/main/java/io/zksync/protocol/core/VerificationKeysHashes.java new file mode 100644 index 0000000..014dfb3 --- /dev/null +++ b/src/main/java/io/zksync/protocol/core/VerificationKeysHashes.java @@ -0,0 +1,12 @@ +package io.zksync.protocol.core; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor +@Getter +public class VerificationKeysHashes { + private Params params; + private String recursionSchedulerLevelVkHash; +} +