Skip to content

Commit

Permalink
Merge branch 'standard-header' into decentralized-staking
Browse files Browse the repository at this point in the history
  • Loading branch information
karlavasquez8 committed Apr 24, 2024
2 parents 8a2d236 + 875625d commit 0c9817c
Show file tree
Hide file tree
Showing 52 changed files with 3,072 additions and 436 deletions.
8 changes: 4 additions & 4 deletions .yarnrc.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
compressionLevel: mixed

enableColors: true

enableGlobalCache: false

nmHoistingLimits: workspaces

nodeLinker: node-modules

plugins:
- path: .yarn/plugins/@yarnpkg/plugin-typescript.cjs
spec: "@yarnpkg/plugin-typescript"

yarnPath: .yarn/releases/yarn-3.2.3.cjs
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -232,10 +232,10 @@ For production-grade applications, it's recommended to obtain your own API keys

Run the `yarn verify --network your_network` command to verify your contracts on etherscan 🛰

👉 Search this address on Etherscan to get the URL you submit to 🏃‍♀️[SpeedRunEthereum.com](https://speedrunstark.com).
👉 Search this address on Etherscan to get the URL you submit to 🏃‍♀️[SpeedRunEthereum.com](https://speedrunethereum.com).

---

> 🏃 Head to your next challenge [here](https://speedrunstark.com).
> 🏃 Head to your next challenge [here](https://speedrunethereum.com).
> 💬 Problems, questions, comments on the stack? Post them to the [🏗 scaffold-eth developers chat](https://t.me/joinchat/F7nCRK3kI93PoCOk)
12 changes: 12 additions & 0 deletions packages/nextjs/app/api/ipfs/add/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { ipfsClient } from "~~/utils/simpleNFT/ipfs";

export async function POST(request: Request) {
try {
const body = await request.json();
const res = await ipfsClient.add(JSON.stringify(body));
return Response.json(res);
} catch (error) {
console.log("Error adding to ipfs", error);
return Response.json({ error: "Error adding to ipfs" });
}
}
12 changes: 12 additions & 0 deletions packages/nextjs/app/api/ipfs/get-metadata/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { getNFTMetadataFromIPFS } from "~~/utils/simpleNFT/ipfs";

export async function POST(request: Request) {
try {
const { ipfsHash } = await request.json();
const res = await getNFTMetadataFromIPFS(ipfsHash);
return Response.json(res);
} catch (error) {
console.log("Error getting metadata from ipfs", error);
return Response.json({ error: "Error getting metadata from ipfs" });
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
ContractName,
GenericContract,
InheritedFunctions,
getFunctionsByStateMutability,
} from "~~/utils/scaffold-stark/contract";
import { ReadOnlyFunctionForm } from "./ReadOnlyFunctionForm";

Expand All @@ -17,36 +18,19 @@ export const ContractReadMethods = ({
return null;
}

const functionsToDisplay = ((deployedContractData.abi || []) as Abi)
.reduce((acc, part) => {
if (part.type === "function") {
acc.push(part);
} else if (part.type === "interface" && Array.isArray(part.items)) {
part.items.forEach((item) => {
if (item.type === "function") {
acc.push(item);
}
});
}
return acc;
}, [] as AbiFunction[])
const functionsToDisplay = getFunctionsByStateMutability(
(deployedContractData.abi || []) as Abi,
"view",
)
.filter((fn) => {
const isQueryableWithParams =
fn.state_mutability === "view" && fn.inputs.length > 0;
const isQueryableWithParams = fn.inputs.length > 0;
return isQueryableWithParams;
})
.map((fn) => {
return {
fn,
// inheritedFrom: (
// (deployedContractData as GenericContract)
// ?.inheritedFunctions as InheritedFunctions
// )?.[fn.name],
};
});
// .sort((a, b) =>
// b.inheritedFrom ? b.inheritedFrom.localeCompare(a.inheritedFrom) : 1
// );
if (!functionsToDisplay.length) {
return <>No read methods</>;
}
Expand All @@ -58,7 +42,6 @@ export const ContractReadMethods = ({
contractAddress={deployedContractData.address}
abiFunction={fn}
key={fn.name}
// inheritedFrom={inheritedFrom}
/>
))}
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
ContractName,
GenericContract,
InheritedFunctions,
getFunctionsByStateMutability,
} from "~~/utils/scaffold-stark/contract";
import { DisplayVariable } from "./DisplayVariable";

Expand All @@ -19,37 +20,19 @@ export const ContractVariables = ({
return null;
}

const functionsToDisplay = ((deployedContractData.abi || []) as Abi)
.reduce((acc, part) => {
if (part.type === "function") {
acc.push(part);
} else if (part.type === "interface" && Array.isArray(part.items)) {
part.items.forEach((item) => {
if (item.type === "function") {
acc.push(item);
}
});
}
return acc;
}, [] as AbiFunction[])
const functionsToDisplay = getFunctionsByStateMutability(
(deployedContractData.abi || []) as Abi,
"view",
)
.filter((fn) => {
const isQueryableWithNoParams =
fn.state_mutability === "view" && fn.inputs.length === 0;
return isQueryableWithNoParams;
const isQueryableWithParams = fn.inputs.length === 0;
return isQueryableWithParams;
})
.map((fn) => {
return {
fn,
// inheritedFrom: (
// (deployedContractData as GenericContract)
// ?.inheritedFunctions as InheritedFunctions
// )?.[fn.name],
};
});
// .sort((a, b) =>
// b.inheritedFrom ? b.inheritedFrom.localeCompare(a.inheritedFrom) : 1
// );

if (!functionsToDisplay.length) {
return <>No contract variables</>;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
ContractName,
GenericContract,
InheritedFunctions,
getFunctionsByStateMutability,
} from "~~/utils/scaffold-stark/contract";

export const ContractWriteMethods = ({
Expand All @@ -19,35 +20,14 @@ export const ContractWriteMethods = ({
return null;
}

const functionsToDisplay = ((deployedContractData.abi || []) as Abi)
.reduce((acc, part) => {
if (part.type === "function") {
acc.push(part);
} else if (part.type === "interface" && Array.isArray(part.items)) {
part.items.forEach((item) => {
if (item.type === "function") {
acc.push(item);
}
});
}
return acc;
}, [] as AbiFunction[])
.filter((fn) => {
const isWriteableFunction = fn.state_mutability == "external";
return isWriteableFunction;
})
.map((fn) => {
return {
fn,
// inheritedFrom: (
// (deployedContractData as GenericContract)
// ?.inheritedFunctions as InheritedFunctions
// )?.[fn.name],
};
});
// .sort((a, b) =>
// b.inheritedFrom ? b.inheritedFrom.localeCompare(a.inheritedFrom) : 1
// );
const functionsToDisplay = getFunctionsByStateMutability(
(deployedContractData.abi || []) as Abi,
"external",
).map((fn) => {
return {
fn,
};
});

if (!functionsToDisplay.length) {
return <>No write methods</>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export const DisplayVariable = ({
}: DisplayVariableProps) => {
const {
data: result,
isLoading,
isFetching,
refetch,
} = useContractRead({
Expand All @@ -52,7 +53,7 @@ export const DisplayVariable = ({
className="btn btn-ghost btn-xs"
onClick={async () => await refetch()}
>
{isFetching ? (
{!isLoading && isFetching ? (
<span className="loading loading-spinner loading-xs"></span>
) : (
<ArrowPathIcon
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@ export const ReadOnlyFunctionForm = ({
const [form, setForm] = useState<Record<string, any>>(() =>
getInitialFormState(abiFunction),
);
const [result, setResult] = useState<unknown>();
const [inputValue, setInputValue] = useState<any>();

const { isLoading, isFetching, refetch } = useContractRead({
const { isLoading, isFetching, data } = useContractRead({
address: contractAddress,
functionName: abiFunction.name,
abi: [...abi],
args: getParsedContractFunctionArgs(form),
args: inputValue,
enabled: false, // TODO : notify when failed - add error
blockIdentifier: "pending" as BlockNumber,
});
Expand All @@ -49,7 +49,7 @@ export const ReadOnlyFunctionForm = ({
<ContractInput
key={key}
setForm={(updatedFormValue) => {
setResult(undefined);
setInputValue(undefined);
setForm(updatedFormValue);
}}
form={form}
Expand All @@ -68,20 +68,19 @@ export const ReadOnlyFunctionForm = ({
{inputElements}
<div className="flex justify-between gap-2 flex-wrap">
<div className="flex-grow w-4/5">
{result !== null && result !== undefined && (
{data !== null && data !== undefined && (
<div className="bg-secondary rounded-3xl text-sm px-4 py-1.5 break-words">
<p className="font-bold m-0 mb-1">Result:</p>
<pre className="whitespace-pre-wrap break-words">
{displayTxResult(result, false, abiFunction?.outputs)}
{displayTxResult(data, false, abiFunction?.outputs)}
</pre>
</div>
)}
</div>
<button
className="btn btn-secondary btn-sm"
onClick={async () => {
const { data } = await refetch();
setResult(data);
setInputValue(getParsedContractFunctionArgs(form));
}}
disabled={!isLoading && isFetching}
>
Expand Down
13 changes: 6 additions & 7 deletions packages/nextjs/app/debug/_components/contract/utilsContract.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { AbiFunction, AbiParameter } from "~~/utils/scaffold-stark/contract";
import {
AbiFunction,
AbiParameter,
parseParamWithType,
} from "~~/utils/scaffold-stark/contract";
import { uint256 } from "starknet";
import { byteArray } from "starknet-dev";
/**
Expand Down Expand Up @@ -35,12 +39,7 @@ const getInitialFormState = (abiFunction: AbiFunction) => {
// Recursive function to deeply parse JSON strings, correctly handling nested arrays and encoded JSON strings
const deepParseValues = (value: any, keyAndType?: any): any => {
if (keyAndType) {
if (keyAndType.includes("core::integer::u256")) {
return uint256.bnToUint256(value);
}
if (keyAndType.includes("core::byte_array::ByteArray")) {
return byteArray.byteArrayFromString(value);
}
return parseParamWithType(keyAndType, value);
}
if (typeof value === "string") {
if (isJsonString(value)) {
Expand Down
84 changes: 84 additions & 0 deletions packages/nextjs/app/ipfsDownload/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
"use client";

import { lazy, useEffect, useState } from "react";
import type { NextPage } from "next";
import { notification } from "~~/utils/scaffold-stark/notification";
import { getMetadataFromIPFS } from "~~/utils/simpleNFT/ipfs-fetch";

const LazyReactJson = lazy(() => import("react-json-view"));

const IpfsDownload: NextPage = () => {
const [yourJSON, setYourJSON] = useState({});
const [ipfsPath, setIpfsPath] = useState("");
const [loading, setLoading] = useState(false);
const [mounted, setMounted] = useState(false);
useEffect(() => {
setMounted(true);
}, []);

const handleIpfsDownload = async () => {
setLoading(true);
const notificationId = notification.loading("Getting data from IPFS");
try {
const metaData = await getMetadataFromIPFS(ipfsPath);
notification.remove(notificationId);
notification.success("Downloaded from IPFS");

setYourJSON(metaData);
} catch (error) {
notification.remove(notificationId);
notification.error("Error downloading from IPFS");
console.log(error);
} finally {
setLoading(false);
}
};

return (
<>
<div className="flex items-center flex-col flex-grow pt-10">
<h1 className="text-center mb-4">
<span className="block text-4xl font-bold">Download from IPFS</span>
</h1>
<div
className={`flex border-2 border-accent/95 bg-base-200 rounded-full text-accent w-96`}
>
<input
className="input input-ghost focus:outline-none focus:bg-transparent focus:text-secondary-content h-[2.2rem] min-h-[2.2rem] px-4 border w-full font-medium placeholder:text-accent/50 text-secondary-content/75"
placeholder="IPFS CID"
value={ipfsPath}
onChange={(e) => setIpfsPath(e.target.value)}
autoComplete="off"
/>
</div>
<button
className={`btn btn-secondary my-6 ${loading ? "loading" : ""}`}
disabled={loading}
onClick={handleIpfsDownload}
>
Download from IPFS
</button>

{mounted && (
<LazyReactJson
style={{ padding: "1rem", borderRadius: "0.75rem" }}
src={yourJSON}
theme="solarized"
enableClipboard={false}
onEdit={(edit) => {
setYourJSON(edit.updated_src);
}}
onAdd={(add) => {
setYourJSON(add.updated_src);
}}
onDelete={(del) => {
setYourJSON(del.updated_src);
}}
/>
)}
</div>
</>
);
};

export default IpfsDownload;
Loading

0 comments on commit 0c9817c

Please sign in to comment.