From 75e9d8bb56169107248abbb4ea3fee8bcd279ff9 Mon Sep 17 00:00:00 2001 From: Sabrina Ferguson Date: Wed, 14 Aug 2024 10:39:38 -0400 Subject: [PATCH] fix: parse array args correctly --- src/commands/contract/encode.ts | 35 ++++++++++++++-------- src/commands/contract/read.ts | 35 ++++++++++++++-------- src/commands/contract/utils/formatters.ts | 15 ++++++++++ src/commands/contract/write.ts | 36 +++++++++++++++-------- 4 files changed, 84 insertions(+), 37 deletions(-) diff --git a/src/commands/contract/encode.ts b/src/commands/contract/encode.ts index b689db0a..f4daecd9 100644 --- a/src/commands/contract/encode.ts +++ b/src/commands/contract/encode.ts @@ -4,7 +4,7 @@ import inquirer from "inquirer"; import Program from "./command.js"; import { abiOption, argumentsOption, methodOption } from "./common/options.js"; -import { encodeData, encodeParam, getFragmentFromSignature, getInputsFromSignature } from "./utils/formatters.js"; +import { encodeData, formatArgs, getFragmentFromSignature, getInputsFromSignature } from "./utils/formatters.js"; import { readAbiFromFile, askAbiMethod, formatMethodString } from "./utils/helpers.js"; import { logFullCommandFromOptions, optionNameToParam } from "../../utils/helpers.js"; import Logger from "../../utils/logger.js"; @@ -15,7 +15,7 @@ import type { DistinctQuestion } from "inquirer"; type EncodeOptions = { method?: string; - arguments?: string[]; + arguments?: Array; abi?: string; }; @@ -82,16 +82,26 @@ const askArguments = async (method: string, options: EncodeOptions) => { message: name, name: index.toString(), type: "input", - validate: (value: string) => { - try { - encodeParam(input, value); // throws if invalid - return true; - } catch (error) { - return `${chalk.redBright( - "Failed to encode provided argument: " + (error instanceof Error ? error.message : error) - )}`; - } - }, + // filter: (value: string) => { + // if (input.baseType === "array") { + // return value + // .replace(/\[|\]/g, "") + // .split(",") + // .map((element) => element.trim()); + // } else { + // return value; + // } + // }, + // validate: (value: string) => { + // try { + // encodeParam(input, value); // throws if invalid + // return true; + // } catch (error) { + // return `${chalk.redBright( + // "Failed to encode provided argument: " + (error instanceof Error ? error.message : error) + // )}`; + // } + // }, }); }); @@ -113,6 +123,7 @@ export const handler = async (options: EncodeOptions, context: Command) => { await askMethod(abi, options); await askArguments(options.method!, options); + options.arguments = formatArgs(options.method!, options.arguments!); const data = encodeData(options.method!, options.arguments!); Logger.info(""); Logger.info(chalk.greenBright("✔ Encoded data: ") + data); diff --git a/src/commands/contract/read.ts b/src/commands/contract/read.ts index 2ad0764c..360e5c69 100644 --- a/src/commands/contract/read.ts +++ b/src/commands/contract/read.ts @@ -16,7 +16,7 @@ import { import { decodeData, encodeData, - encodeParam, + formatArgs, getFragmentFromSignature, getInputValues, getInputsFromSignature, @@ -48,7 +48,7 @@ const decodeSkipOption = new Option("--decode-skip", "Skip decoding response"); type CallOptions = DefaultTransactionOptions & { contract?: string; method?: string; - arguments?: string[]; + arguments?: Array; data?: string; outputTypes: string[]; from?: string; @@ -123,16 +123,26 @@ const askArguments = async (method: string, options: CallOptions) => { message: name, name: index.toString(), type: "input", - validate: (value: string) => { - try { - encodeParam(input, value); // throws if invalid - return true; - } catch (error) { - return `${chalk.redBright( - "Failed to encode provided argument: " + (error instanceof Error ? error.message : error) - )}`; - } - }, + // filter: (value: string) => { + // if (input.baseType === "array") { + // return value + // .replace(/\[|\]/g, "") + // .split(",") + // .map((element) => element.trim()); + // } else { + // return value; + // } + // }, + // validate: (value: string) => { + // try { + // encodeParam(input, value); // throws if invalid + // return true; + // } catch (error) { + // return `${chalk.redBright( + // "Failed to encode provided argument: " + (error instanceof Error ? error.message : error) + // )}`; + // } + // }, }); }); @@ -230,6 +240,7 @@ export const handler = async (options: CallOptions, context: Command) => { if (!options.data) { await askArguments(options.method!, options); } + options.arguments = formatArgs(options.method!, options.arguments!); const transaction: TransactionRequest = { to: contractInfo.address, diff --git a/src/commands/contract/utils/formatters.ts b/src/commands/contract/utils/formatters.ts index d5d35ede..affe6d1b 100644 --- a/src/commands/contract/utils/formatters.ts +++ b/src/commands/contract/utils/formatters.ts @@ -58,3 +58,18 @@ export const getMethodsFromAbi = (abi: ABI, type: "read" | "write"): ethers.util return contractInterface.fragments as ethers.utils.FunctionFragment[]; } }; + +export const formatArgs = (method: string, args: Array) => { + const inputs = getInputsFromSignature(method); + + return args.map((arg, index) => { + const input = inputs[index]; + if (input.baseType === "array") { + return (arg as string) + .replace(/\[|\]/g, "") + .split(",") + .map((element) => element.trim()); + } + return arg; + }); +}; diff --git a/src/commands/contract/write.ts b/src/commands/contract/write.ts index 6b42b5fa..c8ac58a6 100644 --- a/src/commands/contract/write.ts +++ b/src/commands/contract/write.ts @@ -13,7 +13,7 @@ import { methodOption, showTransactionInfoOption, } from "./common/options.js"; -import { encodeData, encodeParam, getFragmentFromSignature, getInputsFromSignature } from "./utils/formatters.js"; +import { encodeData, formatArgs, getFragmentFromSignature, getInputsFromSignature } from "./utils/formatters.js"; import { checkIfMethodExists, getContractInfoWithLoader, @@ -39,7 +39,7 @@ const valueOption = new Option("--value ", "Ether value to send wi type WriteOptions = DefaultTransactionOptions & { contract?: string; method?: string; - arguments?: string[]; + arguments?: Array; value?: string; data?: string; abi?: string; @@ -109,16 +109,26 @@ const askArguments = async (method: string, options: WriteOptions) => { message: name, name: index.toString(), type: "input", - validate: (value: string) => { - try { - encodeParam(input, value); // throws if invalid - return true; - } catch (error) { - return `${chalk.redBright( - "Failed to encode provided argument: " + (error instanceof Error ? error.message : error) - )}`; - } - }, + // filter: (value: string) => { + // if (input.baseType === "array") { + // return value + // .replace(/\[|\]/g, "") + // .split(",") + // .map((element) => element.trim()); + // } else { + // return value; + // } + // }, + // validate: (value: string) => { + // try { + // encodeParam(input, value); // throws if invalid + // return true; + // } catch (error) { + // return `${chalk.redBright( + // "Failed to encode provided argument: " + (error instanceof Error ? error.message : error) + // )}`; + // } + // }, }); }); @@ -183,6 +193,7 @@ export const handler = async (options: WriteOptions, context: Command) => { if (!options.data) { await askArguments(options.method!, options); } + options.arguments = formatArgs(options.method!, options.arguments!); const { privateKey }: { privateKey: string } = await inquirer.prompt( [ @@ -202,7 +213,6 @@ export const handler = async (options: WriteOptions, context: Command) => { options ); const senderWallet = getL2Wallet(options.privateKey || privateKey, provider); - const transaction: TransactionRequest = { from: senderWallet.address, to: contractInfo.address,