Skip to content

Commit

Permalink
fix: templates (#18)
Browse files Browse the repository at this point in the history
  • Loading branch information
fadeev authored Jul 19, 2023
1 parent 351f10d commit 485471a
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 125 deletions.
71 changes: 3 additions & 68 deletions tasks/omnichain.ts
Original file line number Diff line number Diff line change
@@ -1,77 +1,12 @@
import * as fs from "fs";
import * as handlebars from "handlebars";
import { task } from "hardhat/config";
import { HardhatRuntimeEnvironment } from "hardhat/types";
import * as path from "path";

const sanitizeSolidityFunctionName = (str: string): string => {
// Remove any character that's not alphanumeric or underscore
const cleaned = str.replace(/[^a-zA-Z0-9_]/g, "");

// If the first character is a digit, prepend with an underscore
return cleaned.match(/^\d/) ? `_${cleaned}` : cleaned;
};

const processTemplates = async (
templateDir: string,
outputDir: string,
data: Record<string, unknown>
): Promise<void> => {
try {
templateDir = path.resolve(__dirname, templateDir);

const files = fs.readdirSync(templateDir);

for (const file of files) {
const templatePath = path.join(templateDir, file);

// Compiling filename as a template
const filenameTemplate = handlebars.compile(file);
const filename = filenameTemplate(data);

// Replacing .hbs extension if the file was a handlebars template
const outputPath = path.join(outputDir, filename.replace(".hbs", ""));

fs.mkdirSync(path.dirname(outputPath), { recursive: true });

if (fs.lstatSync(templatePath).isDirectory()) {
// If file is a directory, recursively process it
await processTemplates(templatePath, outputPath, data);
} else if (path.extname(file) === ".hbs") {
const templateContent = fs.readFileSync(templatePath, "utf-8");
const template = handlebars.compile(templateContent);
const outputContent = template(data);
fs.writeFileSync(outputPath, outputContent);
} else {
fs.copyFileSync(templatePath, outputPath);
}
}
} catch (error) {
console.error(`Error processing templates: ${error}`);
}
};
import { processTemplates } from "../lib";

const main = async (args: any, hre: HardhatRuntimeEnvironment) => {
const templateDir = path.resolve(__dirname, "..", "templates", "omnichain");
const outputDir = path.resolve(process.cwd());
const argsList = args.arguments || [];
const names = argsList.map((i: string) => i.split(":")[0]);
const types = argsList.map((i: string) => {
let parts = i.split(":");
// If there's a type and it's not empty, use it; if not, default to "bytes32"
let t =
parts.length > 1 && parts[1].trim() !== "" ? parts[1].trim() : "bytes32";
return t;
});
const pairs = names.map((v: string, i: string) => [v, types[i]]);

const data = {
args,
arguments: { names, pairs, types },
contractName: sanitizeSolidityFunctionName(args.name),
};

processTemplates(templateDir, outputDir, data);
processTemplates("omnichain", args);

const configPath = path.resolve(process.cwd(), "hardhat.config.ts");
let hardhatConfigContents = fs.readFileSync(configPath, "utf8");
Expand All @@ -89,7 +24,7 @@ const main = async (args: any, hre: HardhatRuntimeEnvironment) => {

export const omnichainTask = task(
"omnichain",
"Generate code for an omnichain smart contract",
"Generate code for an omnichain contract",
main
)
.addPositionalParam("name", "Name of the contract")
Expand Down
52 changes: 22 additions & 30 deletions templates/messaging/tasks/deploy.ts.hbs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { getAddress, getChainId } from "@zetachain/addresses";
import { getAddress } from "@zetachain/protocol-contracts";
import { ethers } from "ethers";
import { task } from "hardhat/config";
import { HardhatRuntimeEnvironment } from "hardhat/types";
import { getSupportedNetworks } from "@zetachain/networks";

const contractName = "{{contractName}}";

Expand All @@ -23,7 +24,7 @@ const main = async (args: any, hre: HardhatRuntimeEnvironment) => {
// Initialize a wallet using a network configuration and a private key from
// environment variables.
const initWallet = (hre: HardhatRuntimeEnvironment, networkName: string) => {
const { url } = hre.config.networks[networkName];
const { url } = hre.config.networks[networkName] as any;
const provider = new ethers.providers.JsonRpcProvider(url);
const wallet = new ethers.Wallet(process.env.PRIVATE_KEY as string, provider);

Expand All @@ -38,41 +39,30 @@ const deployContract = async (
networkName: string
) => {
const wallet = initWallet(hre, networkName);
const zetaNetwork = "athens";
const connectorAddress = getAddress({
address: "connector",
networkName,
zetaNetwork,
});
const zetaTokenAddress = getAddress({
address: "zetaToken",
networkName,
zetaNetwork,
});
const zetaTokenConsumerV2 = getAddress({
address: "zetaTokenConsumerUniV2",
networkName,
zetaNetwork,
});
const zetaTokenConsumerV3 = getAddress({
address: "zetaTokenConsumerUniV3",
networkName,
zetaNetwork,
});

const connector = getAddress("connector", networkName as any);
const zetaToken = getAddress("zetaToken", networkName as any);
const zetaTokenConsumerUniV2 = getAddress(
"zetaTokenConsumerUniV2",
networkName as any
);
const zetaTokenConsumerUniV3 = getAddress(
"zetaTokenConsumerUniV3",
networkName as any
);

const { abi, bytecode } = await hre.artifacts.readArtifact(contractName);
const factory = new ethers.ContractFactory(abi, bytecode, wallet);
const contract = await factory.deploy(
connectorAddress,
zetaTokenAddress,
zetaTokenConsumerV2 || zetaTokenConsumerV3
connector,
zetaToken,
zetaTokenConsumerUniV2 || zetaTokenConsumerUniV3
);

await contract.deployed();
console.log(`
🚀 Successfully deployed contract on ${networkName}.
📜 Contract address: ${contract.address}
`);
📜 Contract address: ${contract.address}`);
return contract.address;
};

Expand Down Expand Up @@ -102,7 +92,7 @@ const setInteractors = async (
["address"],
[contracts[counterparty]]
);
const chainId = getChainId(counterparty as any);
const chainId = hre.config.networks[counterparty].chainId;
await (
await contract.setInteractorByChainId(chainId, counterpartyContract)
).wait();
Expand All @@ -114,5 +104,7 @@ const setInteractors = async (

task("deploy", "Deploy the contract", main).addParam(
"networks",
"Comma separated list of networks to deploy to"
`Comma separated list of networks to deploy to (e.g. ${getSupportedNetworks(
"ccm"
)})`
);
6 changes: 3 additions & 3 deletions templates/messaging/tasks/interact.ts.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ const main = async (args: any, hre: HardhatRuntimeEnvironment) => {

const tx = await contract
.connect(signer)
.sendHelloWorld(args.destination, { value: parseEther(args.amount) });
.sendMessage(args.destination, { value: parseEther(args.amount) });

const receipt = await tx.wait();
console.log(`✅ "sendHelloWorld" transaction has been broadcasted to ${hre.network.name}
console.log(`✅ The transaction has been broadcasted to ${hre.network.name}
📝 Transaction hash: ${receipt.transactionHash}

Please, refer to ZetaChain's explorer for updates on the progress of the cross-chain transaction.

🌍 Explorer: https://explorer.zetachain.com/cc/tx/${receipt.transactionHash}
🌍 Explorer: https://athens3.explorer.zetachain.com/cc/tx/${receipt.transactionHash}
`);
};

Expand Down
2 changes: 2 additions & 0 deletions templates/omnichain/contracts/{{contractName}}.sol.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@ contract {{contractName}} is zContract {
uint256 amount,
bytes calldata message
) external virtual override {
{{#if arguments.pairs}}
({{#each arguments.pairs}}{{#if @index}}, {{/if}}{{this.[1]}} {{this.[0]}}{{/each}}) = abi.decode(
message,
({{#each arguments.pairs}}{{#if @index}}, {{/if}}{{this.[1]}}{{/each}})
);
{{/if}}
// TODO: implement the logic
}
}
4 changes: 2 additions & 2 deletions templates/omnichain/tasks/deploy.ts.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ const contractName = "{{contractName}}";
const SYSTEM_CONTRACT = "0x239e96c8f17C85c30100AC26F635Ea15f23E9c67";

const main = async (args: any, hre: HardhatRuntimeEnvironment) => {
if (hre.network.name !== "athens") {
if (hre.network.name !== "zeta_testnet") {
throw new Error(
'🚨 Please use the "athens" network to deploy to ZetaChain.'
'🚨 Please use the "zeta_testnet" network to deploy to ZetaChain.'
);
}

Expand Down
29 changes: 7 additions & 22 deletions templates/omnichain/tasks/interact.ts.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -2,49 +2,34 @@ import { task } from "hardhat/config";
import { HardhatRuntimeEnvironment } from "hardhat/types";
import { parseEther } from "@ethersproject/units";
import { getAddress } from "@zetachain/protocol-contracts";
import { prepareData, trackCCTX } from "@zetachain/toolkit/helpers";

const main = async (args: any, hre: HardhatRuntimeEnvironment) => {
const [signer] = await hre.ethers.getSigners();
console.log(`🔑 Using account: ${signer.address}\n`);

const prepareData = (
contract: string,
typesList: string[],
argsList: string[]
) => {
const abiCoder = hre.ethers.utils.defaultAbiCoder;
const params = abiCoder.encode(typesList, argsList);
return `${contract}${params.slice(2)}`;
};

const network = hre.network.name;
const data = prepareData(
args.contract,
[{{#each arguments.types}}"{{this}}", {{/each}}],
[{{#each arguments.names}}"{{this}}", {{/each}}]
[{{#each arguments.names}}args.{{this}}, {{/each}}]
);
const to = getAddress({
address: "tss",
networkName: network,
zetaNetwork: "athens",
});
const to = getAddress("tss", hre.network.name);
const value = parseEther(args.amount);

const tx = await signer.sendTransaction({ data, to, value });

console.log(`
🚀 Successfully broadcasted a token transfer transaction on ${network} network.
📝 Transaction hash: ${tx.hash}

This transaction has been submitted to ${network}, but it may take some time
for it to be processed on ZetaChain. Please refer to ZetaChain's explorer
for updates on the progress of the cross-chain transaction.

🌍 Explorer: https://explorer.zetachain.com/address/${args.contract}?tab=ccTxs
`);
await trackCCTX(tx.hash);
};

task("interact", "Interact with the contract")
.addParam("contract", "The address of the withdraw contract on ZetaChain")
.addParam("amount", "Amount of tokens to send")
{{#each arguments.names}}
.addParam("{{this}}")
{{/each}}
.setAction(main);

0 comments on commit 485471a

Please sign in to comment.