Skip to content

Commit

Permalink
feat(v3): migration into v3 dependencies (#234)
Browse files Browse the repository at this point in the history
  • Loading branch information
metalboyrick authored Aug 9, 2024
1 parent e7a8a94 commit 795d887
Show file tree
Hide file tree
Showing 10 changed files with 490 additions and 282 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export const DisplayVariable = ({
isLoading,
isFetching,
refetch,
error,
} = useReadContract({
address: contractAddress,
functionName: abiFunction.name,
Expand All @@ -42,6 +43,14 @@ export const DisplayVariable = ({
const { resolvedTheme } = useTheme();
const isDarkMode = resolvedTheme === "dark";

// error logging
useEffect(() => {
if (error) {
console.error(error?.message);
console.error(error.stack);
}
}, [error]);

useEffect(() => {
refetch();
}, [refetch, refreshDisplayVariables]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,22 @@ export const ReadOnlyFunctionForm = ({
const [formErrorMessage, setFormErrorMessage] = useState<string | null>(null);
const lastForm = useRef(form);

const { isFetching, data, refetch } = useReadContract({
const { isFetching, data, refetch, error } = useReadContract({
address: contractAddress,
functionName: abiFunction.name,
abi: [...abi],
args: inputValue ? inputValue.flat(Infinity) : [],
args: inputValue || [],
enabled: false,
blockIdentifier: "pending" as BlockNumber,
});

useEffect(() => {
if (error) {
console.error(error?.message);
console.error(error.stack);
}
}, [error]);

const transformedFunction = transformAbiFunction(abiFunction);
const inputElements = transformedFunction.inputs.map((input, inputIndex) => {
const key = getFunctionInputKey(abiFunction.name, input, inputIndex);
Expand All @@ -59,7 +66,8 @@ export const ReadOnlyFunctionForm = ({
});

const handleRead = () => {
const newInputValue = getParsedContractFunctionArgs(form, false);
const newInputValue = getParsedContractFunctionArgs(form, false, true);

if (JSON.stringify(form) !== JSON.stringify(lastForm.current)) {
setInputValue(newInputValue);
lastForm.current = form;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@ export const WriteOnlyFunctionForm = ({
abiFunction,
onChange,
contractAddress,
}: // inheritedFrom,
WriteOnlyFunctionFormProps) => {
}: WriteOnlyFunctionFormProps) => {
const [form, setForm] = useState<Record<string, any>>(() =>
getInitialFormState(abiFunction),
);
Expand All @@ -67,19 +66,28 @@ WriteOnlyFunctionFormProps) => {
data: result,
isPending: isLoading,
sendAsync,
send,
error,
} = useSendTransaction({
calls: [
{
contractAddress,
entrypoint: abiFunction.name,

// use infinity to completely flatten array from n dimensions to 1 dimension
// writing in starknet next still needs rawArgs parsing, use v2 parsing
calldata: getParsedContractFunctionArgs(form, false).flat(Infinity),
},
],
});

// side effect for error logging
useEffect(() => {
if (error) {
console.error(error?.message);
console.error(error.stack);
}
}, [error]);

const handleWrite = async () => {
if (sendAsync) {
try {
Expand Down
62 changes: 3 additions & 59 deletions packages/nextjs/app/debug/_components/contract/utilsContract.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
AbiFunction,
AbiParameter,
AbiStruct,
deepParseValues,
parseParamWithType,
} from "~~/utils/scaffold-stark/contract";
/**
Expand All @@ -17,15 +18,6 @@ const getFunctionInputKey = (
return functionName + "_" + name + "_" + input.type;
};

const isJsonString = (str: string) => {
try {
JSON.parse(str);
return true;
} catch (e) {
return false;
}
};

const getInitialTupleFormState = (abiParameter: AbiStruct | AbiEnum) => {
const initialForm: Record<string, any> = {};

Expand Down Expand Up @@ -53,64 +45,17 @@ const getInitialFormState = (abiFunction: AbiFunction) => {
return initialForm;
};

const deepParseValues = (
value: any,
isRead: boolean,
keyAndType?: any,
): any => {
if (keyAndType) {
return parseParamWithType(keyAndType, value, isRead);
}
if (typeof value === "string") {
if (isJsonString(value)) {
const parsed = JSON.parse(value);
return deepParseValues(parsed, isRead);
} else {
// It's a string but not a JSON string, return as is
return value;
}
} else if (Array.isArray(value)) {
// If it's an array, recursively parse each element
return value.map((element) => deepParseValues(element, isRead));
} else if (typeof value === "object" && value !== null) {
// If it's an object, recursively parse each value
return Object.entries(value).reduce((acc: any, [key, val]) => {
acc[key] = deepParseValues(val, isRead);
return acc;
}, {});
}

// Handle boolean values represented as strings
if (
value === "true" ||
value === "1" ||
value === "0x1" ||
value === "0x01" ||
value === "0x0001"
) {
return true;
} else if (
value === "false" ||
value === "0" ||
value === "0x0" ||
value === "0x00" ||
value === "0x0000"
) {
return false;
}

return value;
};
/**
* parses form input with array support
*/
const getParsedContractFunctionArgs = (
form: Record<string, any>,
isRead: boolean,
isReadArgsParsing?: boolean,
) => {
return Object.keys(form).map((key) => {
const valueOfArg = form[key];
return deepParseValues(valueOfArg, isRead, key);
return deepParseValues(valueOfArg, isRead, key, isReadArgsParsing);
});
};

Expand All @@ -131,7 +76,6 @@ const transformAbiFunction = (abiFunction: AbiFunction): AbiFunction => {

export {
getFunctionInputKey,
isJsonString,
getInitialFormState,
getInitialTupleFormState,
getParsedContractFunctionArgs,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
parseParamWithType,
} from "~~/utils/scaffold-stark/contract";
import {
isCairoByteArray,
isCairoContractAddress,
isCairoTuple,
parseGenericType,
Expand Down Expand Up @@ -76,6 +77,11 @@ export const displayTxResult = (
return parsedParam;
}

// use quotation for byte arrays to prevent confusion
if (isCairoByteArray(type)) {
return `"${parsedParam.toString()}"`;
}

return isCairoContractAddress(type) &&
validateChecksumAddress(parsedParam) &&
!asText ? (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,14 @@ export const useScaffoldMultiWriteContract = <
contractAddress: contract?.address,
entrypoint: functionName,
calldata:
abiFunction && unParsedArgs
? parseFunctionParams(abiFunction, unParsedArgs, false).flat()
abiFunction && unParsedArgs && contract
? parseFunctionParams({
abiFunction,
isRead: false,
inputs: unParsedArgs as any[],
isReadArgsParsing: false,
abi: contract.abi,
}).flat()
: [],
};
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,7 @@ export const useScaffoldReadContract = <
args && (!Array.isArray(args) || !args.some((arg) => arg === undefined)),
blockIdentifier: "pending" as BlockNumber,
...(readConfig as any),
}) as Omit<ReturnType<typeof useReadContract>, "data" | "refetch"> & {
}) as Omit<ReturnType<typeof useReadContract>, "data"> & {
data: AbiFunctionOutputs<ContractAbi, TFunctionName> | undefined;
// refetch: (options?: {
// throwOnError: boolean;
// cancelRefetch: boolean;
// }) => Promise<AbiFunctionOutputs<ContractAbi, TFunctionName>>;
};
};
25 changes: 19 additions & 6 deletions packages/nextjs/hooks/scaffold-stark/useScaffoldWriteContract.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useMemo } from "react";
import { useEffect, useMemo } from "react";
import { useTargetNetwork } from "./useTargetNetwork";
import {
useDeployedContractInfo,
Expand Down Expand Up @@ -46,11 +46,18 @@ export const useScaffoldWriteContract = <
);

const parsedParams = useMemo(() => {
if (args && abiFunction) {
return parseFunctionParams(abiFunction, args as any[], false).flat();
if (args && abiFunction && deployedContractData) {
const parsed = parseFunctionParams({
abiFunction,
abi: deployedContractData.abi,
inputs: args as any[],
isRead: false,
isReadArgsParsing: false,
}).flat(Infinity);
return parsed;
}
return [];
}, [args, abiFunction]);
}, [args, abiFunction, deployedContractData]);

const wagmiContractWrite = useSendTransaction({
calls: deployedContractData
Expand Down Expand Up @@ -85,8 +92,14 @@ export const useScaffoldWriteContract = <
}

let newParsedParams =
newArgs && abiFunction
? parseFunctionParams(abiFunction, newArgs as any[], false).flat()
newArgs && abiFunction && deployedContractData
? parseFunctionParams({
abiFunction,
abi: deployedContractData.abi,
inputs: args as any[],
isRead: false,
isReadArgsParsing: false,
}).flat(Infinity)
: parsedParams;
const newCalls = [
{
Expand Down
9 changes: 9 additions & 0 deletions packages/nextjs/utils/scaffold-stark/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,12 @@ export function isAddress(address: string): address is Address {
export function feltToHex(feltBigInt: bigint) {
return `0x${feltBigInt.toString(16)}`;
}

export function isJsonString(str: string) {
try {
JSON.parse(str);
return true;
} catch (e) {
return false;
}
}
Loading

0 comments on commit 795d887

Please sign in to comment.