diff --git a/lib/index.ts b/lib/index.ts index f71512d1..22982603 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -2,22 +2,74 @@ import * as fs from "fs"; import * as handlebars from "handlebars"; import * as path from "path"; +const numberTypes = [ + "int", + "int8", + "int16", + "int128", + "int256", + "uint", + "uint8", + "uint16", + "uint128", + "uint256", +]; +const addressTypes = ["address"]; +const boolTypes = ["bool"]; +const bytesTypes = ["bytes32"]; +const allTypes = [...numberTypes, ...addressTypes, ...boolTypes, ...bytesTypes]; + +const capitalizeFirstChar = (input: string): string => { + if (input.length === 0) { + return input; + } + + const firstChar = input.charAt(0).toUpperCase(); + const restOfTheString = input.slice(1); + + return firstChar + restOfTheString; +}; + const prepareData = (args: any) => { 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"; + let t = i.split(":")[1]; + if (t === undefined) { + return "bytes32"; + } + if (!allTypes.includes(t)) { + throw new Error( + `Invalid type "${t}", must be one of ${allTypes.join(", ")}` + ); + } return t; }); const pairs = names.map((v: string, i: string) => [v, types[i]]); const contractName = sanitizeSolidityFunctionName(args.name); + const casts = pairs.map((p: any) => { + const n = capitalizeFirstChar(p[0]); + const type = p[1]; + + if (numberTypes.includes(type)) { + return [n, `hre.ethers.BigNumber.from(args.${p[0]})`]; + } + + if (addressTypes.includes(type)) { + return [n, `hre.ethers.utils.getAddress(args.${p[0]})`]; + } + + if (boolTypes.includes(type)) { + return [n, `JSON.parse(args.${p[0]})`]; + } + + // Default case is "bytes32" and other unexpected cases. + return [n, `hre.ethers.utils.toUtf8Bytes(args.${p[0]})`]; + }); return { args, - arguments: { names, pairs, types }, + arguments: { casts, names, pairs, types }, contractName, contractNameUnderscore: camelToUnderscoreUpper(contractName), }; diff --git a/package.json b/package.json index dc577357..bcc6cdea 100644 --- a/package.json +++ b/package.json @@ -77,7 +77,7 @@ "@nomiclabs/hardhat-ethers": "^2.2.3", "@openzeppelin/contracts": "^4.9.2", "@uniswap/v2-periphery": "^1.1.0-beta.0", - "@zetachain/faucet-cli": "^2.0.1-beta.2", + "@zetachain/faucet-cli": "^2.0.2-athens3.1", "@zetachain/networks": "^2.3.0-athens3", "@zetachain/protocol-contracts": "^2.0.1", "axios": "^1.4.0", diff --git a/tasks/messaging.ts b/tasks/messaging.ts index 41208d94..d795dbe6 100644 --- a/tasks/messaging.ts +++ b/tasks/messaging.ts @@ -6,7 +6,7 @@ import * as path from "path"; import { processTemplates } from "../lib"; const main = async (args: any, hre: HardhatRuntimeEnvironment) => { - processTemplates("messaging", args); + await processTemplates("messaging", args); const configPath = path.resolve(process.cwd(), "hardhat.config.ts"); let hardhatConfigContents = fs.readFileSync(configPath, "utf8"); diff --git a/templates/messaging/tasks/interact.ts.hbs b/templates/messaging/tasks/interact.ts.hbs index e7bb025e..da83e6d2 100644 --- a/templates/messaging/tasks/interact.ts.hbs +++ b/templates/messaging/tasks/interact.ts.hbs @@ -1,6 +1,7 @@ import { task } from "hardhat/config"; import { HardhatRuntimeEnvironment } from "hardhat/types"; import { parseEther } from "@ethersproject/units"; +import { trackCCTX } from "@zetachain/toolkit/helpers"; const contractName = "{{contractName}}"; @@ -11,21 +12,29 @@ const main = async (args: any, hre: HardhatRuntimeEnvironment) => { const factory = await hre.ethers.getContractFactory(contractName); const contract = factory.attach(args.contract); + const destination = hre.config.networks[args.destination]?.chainId; + if (destination === undefined) { + throw new Error(`${args.destination} is not a valid destination chain`); + } + + {{#each arguments.casts}}const param{{this.[0]}} = {{this.[1]}}; + {{/each}} + const tx = await contract .connect(signer) - .sendMessage(args.destination, { value: parseEther(args.amount) }); + .sendMessage(destination, {{#each arguments.casts}} param{{this.[0]}}, {{/each}} { value: parseEther(args.amount) }); const receipt = await tx.wait(); 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://athens3.explorer.zetachain.com/cc/tx/${receipt.transactionHash} `); + await trackCCTX(tx.hash); }; task("interact", "Sends a message from one chain to another.", main) .addParam("contract", "Contract address") .addParam("amount", "Token amount to send") - .addParam("destination", "Destination chain ID (integer)"); + .addParam("destination", "Destination chain") + {{#each arguments.pairs}} + .addParam("{{this.[0]}}", "{{this.[1]}}") + {{/each}} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index c4096ae3..281ad3c2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1383,16 +1383,15 @@ resolved "https://registry.yarnpkg.com/@zetachain/addresses/-/addresses-0.0.10.tgz#12174031f29b801ebc97fd7098f4f2aa4577d5e2" integrity sha512-G4OqEdAQwHrXP1YoNtEyFUCU4Nv3UQy9OCcv9Xn3g395EjLz3EqZQVHUcxsjZ5OkLMSJG08enWvCNuBINfAZEg== -"@zetachain/faucet-cli@^2.0.1-beta.2": - version "2.0.1-beta.2" - resolved "https://registry.yarnpkg.com/@zetachain/faucet-cli/-/faucet-cli-2.0.1-beta.2.tgz#32c143d849163844037f7bf0602355d557f11353" - integrity sha512-d9nlW5lHquWVZmSwJ+VuGB/TlkaMiP7J0arorKyDt3Rw6hjQ3twaGTlK+nOTqJAxo2gwyGNrZVECmX6dWBY7rw== +"@zetachain/faucet-cli@^2.0.2-athens3.1": + version "2.0.2-athens3.1" + resolved "https://registry.yarnpkg.com/@zetachain/faucet-cli/-/faucet-cli-2.0.2-athens3.1.tgz#e4d2224097b7620f46ec9a985b45625d350340e3" + integrity sha512-BDtpQF7XpYc49BQsPRfi6kcRBKjs2UESPzzK7jTcjRRxsFjMQ9tLnY3cx65U/WjFaS2O0APE4vo96j6lQry7PQ== dependencies: commander "10.0.1" figlet "1.6.0" got "11.8.5" launchdarkly-node-client-sdk "3.0.2" - readline "1.3.0" typescript "5.0.4" zod "3.19.1" @@ -6276,11 +6275,6 @@ readdirp@~3.6.0: dependencies: picomatch "^2.2.1" -readline@1.3.0, readline@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/readline/-/readline-1.3.0.tgz#c580d77ef2cfc8752b132498060dc9793a7ac01c" - integrity sha512-k2d6ACCkiNYz222Fs/iNze30rRJ1iIicW7JuX/7/cozvih6YCkFZH+J6mAFDVgv0dRBaAyr4jDqC95R2y4IADg== - rechoir@^0.6.2: version "0.6.2" resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384"