Skip to content
This repository was archived by the owner on Feb 18, 2025. It is now read-only.

Commit

Permalink
Wallet and contract deploy utils
Browse files Browse the repository at this point in the history
  • Loading branch information
dmtrskv committed Jul 18, 2024
1 parent ab39b1a commit 2b3ce82
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 15 deletions.
25 changes: 23 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
Expand Down
50 changes: 38 additions & 12 deletions src/setup.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
Faucet,
Hex,
HttpTransport,
LocalECDSAKeySigner,
PublicClient,
Expand All @@ -12,9 +13,10 @@ import type {
HttpNetworkConfig,
NetworkConfig,
} from "hardhat/types";
import type { HandlerContext } from "./context";
import { shardNumber } from "./utils/conversion";
import { ensure0xPrefix } from "./utils/hex";
import type {HandlerContext} from "./context";
import {shardNumber, uint8ArrayToHexString} from "./utils/conversion";
import {ensure0xPrefix} from "./utils/hex";
import {generatePrivateKey} from "viem/accounts";

function isStringArray(
accounts: HttpNetworkAccountsConfig,
Expand Down Expand Up @@ -49,26 +51,41 @@ export async function setupWalletAndClient(
throw new Error("Accounts configuration is not an array of strings.");
}

const privateKey = ensure0xPrefix(networkConfig.accounts[0]);
if (!privateKey) {
throw new Error("No private key configured for the network.");
const newWalletSalt = new Uint8Array(32);

let generatedWallet = false;
let privateKey: Hex;
if (networkConfig.accounts[0]) {
privateKey = ensure0xPrefix(networkConfig.accounts[0])
} else {
generatedWallet = true;
privateKey = generatePrivateKey();

console.log(`Private key not found in configuration.\nGenerated new private key: ${privateKey}`);
}

const walletAddress = hre.config.walletAddress
const signer = new LocalECDSAKeySigner({privateKey});
const pubKey = await signer.getPublicKey();

let walletAddress = hre.config.walletAddress
? ensure0xPrefix(hre.config.walletAddress)
: undefined;
if (!walletAddress) {
throw new Error("Wallet address is not configured.");
if (!walletAddress || generatedWallet) {
walletAddress = uint8ArrayToHexString(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
const client = new PublicClient({
transport: new HttpTransport({ endpoint: url }),
transport: new HttpTransport({endpoint: url}),
shardId: shardNumber(walletAddress),
});

const signer = new LocalECDSAKeySigner({ privateKey });
const pubKey = await signer.getPublicKey();
const config: WalletV1Config = {
pubkey: pubKey,
client,
Expand All @@ -78,6 +95,15 @@ export async function setupWalletAndClient(
const wallet = new WalletV1(config);
const faucet = new Faucet(client);

if (generatedWallet) {
wallet.salt = newWalletSalt;

await faucet.withdrawToWithRetry(walletAddress, 100000n);
await wallet.selfDeploy();

console.log(`Deployed new wallet.`);
}

const originalRequest = hre.network.provider.request.bind(
hre.network.provider,
);
Expand Down
9 changes: 8 additions & 1 deletion src/utils/conversion.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import {Hex} from "@nilfoundation/niljs";
import {ensure0xPrefix} from "./hex";

export function hexStringToUint8Array(hexString: string): Uint8Array {
const cleanHexString = hexString.startsWith("0x")
? hexString.slice(2)
Expand All @@ -6,12 +9,16 @@ 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;
}

export function uint8ArrayToHexString(myUint8Arr: Uint8Array): Hex {
return ensure0xPrefix(Buffer.from(myUint8Arr).toString("hex"));
}

export function shardNumber(address: string): number {
let formattedAddress = address;
if (address.startsWith("0x")) {
Expand Down
23 changes: 23 additions & 0 deletions src/utils/deploy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import assert from "node:assert";
import "@nomicfoundation/hardhat-ethers";
import hre from "hardhat";

export async function deployNilContract(
name: string,
args: any[] = [],
) {
const factory = await hre.ethers.getContractFactory(name);
const deployTx = await factory.getDeployTransaction(...args);

assert.ok(factory.runner);
assert.ok(factory.runner.sendTransaction);

const sentTx = await factory.runner.sendTransaction(deployTx);
const txResponse = await sentTx.wait();

if (!txResponse || !txResponse.contractAddress) {
throw new Error("Contract deployment failed");
}

return factory.attach(txResponse.contractAddress);
}

0 comments on commit 2b3ce82

Please sign in to comment.