diff --git a/package-lock.json b/package-lock.json index ed82ece..28d49b8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,15 +1,16 @@ { "name": "@nilfoundation/hardhat-plugin", - "version": "0.1.8", + "version": "0.1.10", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@nilfoundation/hardhat-plugin", - "version": "0.1.8", + "version": "0.1.10", "license": "ISC", "dependencies": { "@nilfoundation/niljs": "^0.9.0", + "@nomicfoundation/hardhat-ethers": "^3.0.6", "ethers": "^6.12.1", "hardhat": "^2.22.4", "viem": "^2.16.3" @@ -1071,6 +1072,20 @@ "setimmediate": "^1.0.5" } }, + "node_modules/@nomicfoundation/hardhat-ethers": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-ethers/-/hardhat-ethers-3.0.6.tgz", + "integrity": "sha512-/xzkFQAaHQhmIAYOQmvHBPwL+NkwLzT9gRZBsgWUYeV+E6pzXsBQsHfRYbAZ3XEYare+T7S+5Tg/1KDJgepSkA==", + "license": "MIT", + "dependencies": { + "debug": "^4.1.1", + "lodash.isequal": "^4.5.0" + }, + "peerDependencies": { + "ethers": "^6.1.0", + "hardhat": "^2.0.0" + } + }, "node_modules/@nomicfoundation/solidity-analyzer": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.1.tgz", @@ -3407,6 +3422,12 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, + "node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==", + "license": "MIT" + }, "node_modules/log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", diff --git a/package.json b/package.json index 4145492..475fb0c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@nilfoundation/hardhat-plugin", - "version": "0.1.9", + "version": "0.1.10", "description": "Custom Hardhat plugin to enable seamless deployment and interaction with applications within =nil;", "repository": { "type": "git", @@ -25,6 +25,7 @@ "@nilfoundation/niljs": "^0.9.0", "ethers": "^6.12.1", "hardhat": "^2.22.4", + "@nomicfoundation/hardhat-ethers": "^3.0.6", "viem": "^2.16.3" }, "devDependencies": { diff --git a/src/index.ts b/src/index.ts index af46db0..9e336e6 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,15 +3,25 @@ import type { HardhatUserConfig } from "hardhat/types"; import { unifiedInterceptor } from "./interceptors"; import { setupWalletAndClient } from "./setup"; -extendEnvironment(async (hre) => { - const context = await setupWalletAndClient(hre); +extendEnvironment((hre) => { + const originalRequest = hre.network.provider.request.bind( + hre.network.provider, + ); + const originalSend = hre.network.provider.send.bind(hre.network.provider); + const contextPromise = setupWalletAndClient( + hre, + originalRequest, + originalSend, + ); - hre.network.provider.send = (method, params) => { + hre.network.provider.send = async (method, params) => { + const context = await contextPromise; context.isRequest = false; return unifiedInterceptor(method, params || [], context); }; - hre.network.provider.request = (args) => { + hre.network.provider.request = async (args) => { + const context = await contextPromise; context.isRequest = true; const safeParams = Array.isArray(args.params) ? args.params diff --git a/src/setup.ts b/src/setup.ts index 9746430..84cc703 100644 --- a/src/setup.ts +++ b/src/setup.ts @@ -12,6 +12,7 @@ import type { HttpNetworkConfig, NetworkConfig, } from "hardhat/types"; +import { bytesToHex } from "viem"; import type { HandlerContext } from "./context"; import { shardNumber } from "./utils/conversion"; import { ensure0xPrefix } from "./utils/hex"; @@ -32,6 +33,8 @@ function isHttpNetworkConfig( // Function to setup the wallet and client export async function setupWalletAndClient( hre: HardhatRuntimeEnvironment, + originalRequest: any, + originalSend: any, ): Promise { const networkName = "nil"; const networkConfig = hre.config.networks[networkName]; @@ -54,11 +57,25 @@ export async function setupWalletAndClient( throw new Error("No private key configured for the network."); } - const walletAddress = hre.config.walletAddress + const signer = new LocalECDSAKeySigner({ privateKey }); + const pubKey = await signer.getPublicKey(); + + const newWalletSalt = new Uint8Array(32); + let walletAddress = hre.config.walletAddress ? ensure0xPrefix(hre.config.walletAddress) : undefined; if (!walletAddress) { - throw new Error("Wallet address is not configured."); + walletAddress = bytesToHex( + WalletV1.calculateWalletAddress({ + pubKey, + shardId: 1, + salt: newWalletSalt, + }), + ); + + console.log( + `Wallet address not found in configuration.\nGenerated wallet address for current private key: ${walletAddress}`, + ); } // Set up network components @@ -66,9 +83,8 @@ export async function setupWalletAndClient( transport: new HttpTransport({ endpoint: url }), shardId: shardNumber(walletAddress), }); + const faucet = new Faucet(client); - const signer = new LocalECDSAKeySigner({ privateKey }); - const pubKey = await signer.getPublicKey(); const config: WalletV1Config = { pubkey: pubKey, client, @@ -76,12 +92,18 @@ export async function setupWalletAndClient( address: walletAddress, }; const wallet = new WalletV1(config); - const faucet = new Faucet(client); - const originalRequest = hre.network.provider.request.bind( - hre.network.provider, - ); - const originalSend = hre.network.provider.send.bind(hre.network.provider); + const existingWallet = await client.getCode(walletAddress, "latest"); + if (existingWallet.length === 0) { + console.log("Deploying new wallet..."); + + wallet.salt = newWalletSalt; + + await faucet.withdrawToWithRetry(walletAddress, 1_000_000_000n); + await wallet.selfDeploy(); + + console.log("Deployed new wallet."); + } return { hre, diff --git a/src/utils/conversion.ts b/src/utils/conversion.ts index 6be7a26..4956f56 100644 --- a/src/utils/conversion.ts +++ b/src/utils/conversion.ts @@ -6,7 +6,10 @@ export function hexStringToUint8Array(hexString: string): Uint8Array { const byteArray = new Uint8Array(numBytes); for (let i = 0; i < numBytes; i++) { - byteArray[i] = Number.parseInt(cleanHexString.substr(i * 2, 2), 16); + byteArray[i] = Number.parseInt( + cleanHexString.substring(i * 2, i * 2 + 2), + 16, + ); } return byteArray;