Skip to content

Commit

Permalink
Merge pull request #21 from Quantum3-Labs/core-hooks
Browse files Browse the repository at this point in the history
Core hooks
  • Loading branch information
jrcarlos2000 authored Apr 2, 2024
2 parents 1acc44c + 4ce4ee9 commit de48cef
Show file tree
Hide file tree
Showing 22 changed files with 4,643 additions and 5,836 deletions.
36 changes: 34 additions & 2 deletions packages/nextjs/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,32 @@

import Link from "next/link";
import type { NextPage } from "next";
// import { useAccount } from "wagmi";
import { BugAntIcon, MagnifyingGlassIcon } from "@heroicons/react/24/outline";
import { useScaffoldContract } from "~~/hooks/scaffold-stark/useScaffoldContract";
import { useScaffoldContractRead } from "~~/hooks/scaffold-stark/useScaffoldContractRead";
import { useScaffoldContractWrite } from "~~/hooks/scaffold-stark/useScaffoldContractWrite";
import { Button } from "@radix-ui/themes";
import ConnectModal from "~~/components/wallet/ConnectModal";
import { useAccount } from "@starknet-react/core";
// import { Address } from "~~/components/scaffold-eth";

const Home: NextPage = () => {
// const { address: connectedAddress } = useAccount();
const { address: connectedAddress } = useAccount();
const { data } = useScaffoldContractRead({
contractName: "HelloStarknet",
functionName: "get_balance6",
});

console.log("connected address", connectedAddress);
console.log(data);

const { writeAsync } = useScaffoldContractWrite({
contractName: "HelloStarknet",
functionName: "increase_balance",
args: [1],
});

// console.log(data, isLoading);
return (
<>
<div className="flex items-center flex-col flex-grow pt-10">
Expand Down Expand Up @@ -63,6 +82,19 @@ const Home: NextPage = () => {
</div>
</div>
</div>
{/* <ConnectModal
isOpen={true}
onClose={() => {
writeAsync();
}}
></ConnectModal> */}
<Button
onClick={() => {
writeAsync();
}}
>
HI
</Button>
</div>
</>
);
Expand Down
3 changes: 1 addition & 2 deletions packages/nextjs/components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,7 @@ export const Header = () => {
</ul>
</div>
<div className="navbar-end flex-grow mr-4">
<div />
<div />
<div>HERE BUTTON</div>
</div>
</div>
);
Expand Down
3 changes: 2 additions & 1 deletion packages/nextjs/components/ScaffoldStarkAppWithProviders.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
import { Header } from "~~/components/Header";
import { Footer } from "~~/components/Footer";
import { ProgressBar } from "~~/components/scaffold-stark/ProgressBar";
import { appChains } from "~~/services/web3/connectors";

const ScaffoldStarkApp = ({ children }: { children: React.ReactNode }) => {
return (
Expand Down Expand Up @@ -54,7 +55,7 @@ export const ScaffoldStarkAppWithProviders = ({

return (
<StarknetConfig
chains={[sepolia]}
chains={appChains}
provider={publicProvider()}
connectors={connectors}
explorer={starkscan}
Expand Down
118 changes: 117 additions & 1 deletion packages/nextjs/contracts/deployedContracts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,122 @@
* You should not edit it manually or your changes might be overwritten.
*/

const deployedContracts = {} as const;
const deployedContracts = {
sepolia: {
HelloStarknet: {
address:
"0x019e3fe8c9e16411863110c0f6e073ab09f0a5d94ada04e983e4cb3c5ee1da6e",
abi: [
{
type: "impl",
name: "HelloStarknetImpl",
interface_name: "contracts::helloStarknet::IHelloStarknet",
},
{
type: "interface",
name: "contracts::helloStarknet::IHelloStarknet",
items: [
{
type: "function",
name: "increase_balance",
inputs: [
{
name: "amount",
type: "core::felt252",
},
],
outputs: [],
state_mutability: "external",
},
{
type: "function",
name: "get_balance",
inputs: [],
outputs: [
{
type: "core::felt252",
},
],
state_mutability: "view",
},
{
type: "function",
name: "get_balance6",
inputs: [],
outputs: [
{
type: "core::felt252",
},
],
state_mutability: "view",
},
],
},
{
type: "event",
name: "contracts::helloStarknet::HelloStarknet::Event",
kind: "enum",
variants: [],
},
],
},
SimpleStorage: {
address:
"0x067266f2db0c239cdcd546283ce52186a7b57c2016ef0263dfa4003b52dcecd2",
abi: [
{
type: "impl",
name: "SimpleStorageImpl",
interface_name: "contracts::simpleStorage::ISimpleStorage",
},
{
type: "interface",
name: "contracts::simpleStorage::ISimpleStorage",
items: [
{
type: "function",
name: "get_name",
inputs: [],
outputs: [
{
type: "core::felt252",
},
],
state_mutability: "view",
},
{
type: "function",
name: "set_name",
inputs: [
{
name: "name",
type: "core::felt252",
},
],
outputs: [],
state_mutability: "external",
},
],
},
{
type: "constructor",
name: "constructor",
inputs: [
{
name: "name",
type: "core::felt252",
},
],
},
{
type: "event",
name: "contracts::simpleStorage::SimpleStorage::Event",
kind: "enum",
variants: [],
},
],
},
},
} as const;

export default deployedContracts;
1 change: 1 addition & 0 deletions packages/nextjs/hooks/scaffold-stark/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from "./useOutsideClick";
export * from "./useDeployedContractInfo";
62 changes: 62 additions & 0 deletions packages/nextjs/hooks/scaffold-stark/useDeployedContractInfo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { useEffect, useState, useMemo } from "react";
import { useTargetNetwork } from "./useTargetNetwork";
import { useIsMounted } from "usehooks-ts";
import {
ContractCodeStatus,
ContractName,
Contract,
contracts,
} from "~~/utils/scaffold-stark/contract";
import { useProvider } from "@starknet-react/core";
import { BlockIdentifier, RpcProvider } from "starknet";

export const useDeployedContractInfo = <TContractName extends ContractName>(
contractName: TContractName
) => {
const isMounted = useIsMounted();
const { targetNetwork } = useTargetNetwork();
const deployedContract = contracts?.[targetNetwork.network]?.[
contractName as ContractName
] as Contract<TContractName>;
const [status, setStatus] = useState<ContractCodeStatus>(
ContractCodeStatus.LOADING
);
const publicNodeUrl = targetNetwork.rpcUrls.public.http[0];

// Use useMemo to memoize the publicClient object
const publicClient = useMemo(() => {
return new RpcProvider({
nodeUrl: publicNodeUrl,
});
}, [publicNodeUrl]);

useEffect(() => {
const checkContractDeployment = async () => {
if (!deployedContract) {
setStatus(ContractCodeStatus.NOT_FOUND);
return;
}
const contractClasHash = await publicClient.getClassAt(
deployedContract.address,
"Pending" as BlockIdentifier
);

if (!isMounted()) {
return;
}
// If contract code is `0x` => no contract deployed on that address
if (contractClasHash == undefined) {
setStatus(ContractCodeStatus.NOT_FOUND);
return;
}
setStatus(ContractCodeStatus.DEPLOYED);
};

checkContractDeployment();
}, [isMounted, contractName, deployedContract, publicClient]);

return {
data: status === ContractCodeStatus.DEPLOYED ? deployedContract : undefined,
isLoading: status === ContractCodeStatus.LOADING,
};
};
38 changes: 38 additions & 0 deletions packages/nextjs/hooks/scaffold-stark/useScaffoldContract.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { useMemo } from "react";
import { useDeployedContractInfo } from "~~/hooks/scaffold-stark";
import { ContractName } from "~~/utils/scaffold-stark/contract";
import { useTargetNetwork } from "./useTargetNetwork";
import { Contract, RpcProvider } from "starknet";
import { useAccount } from "@starknet-react/core";

export const useScaffoldContract = <TContractName extends ContractName>({
contractName,
}: {
contractName: TContractName;
}) => {
const { data: deployedContractData, isLoading: deployedContractLoading } =
useDeployedContractInfo(contractName);

const { targetNetwork } = useTargetNetwork();
const { account } = useAccount();
const publicNodeUrl = targetNetwork.rpcUrls.public.http[0];

const publicClient = useMemo(() => {
return new RpcProvider({
nodeUrl: publicNodeUrl,
});
}, [publicNodeUrl]);
let contract = undefined;
if (deployedContractData) {
contract = new Contract(
[...deployedContractData.abi],
deployedContractData.address,
account || publicClient
);
}

return {
data: contract,
isLoading: deployedContractLoading,
};
};
46 changes: 46 additions & 0 deletions packages/nextjs/hooks/scaffold-stark/useScaffoldContractRead.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { useTargetNetwork } from "./useTargetNetwork";
import { useContractRead } from "@starknet-react/core";
import { ExtractAbiFunctionNames } from "abi-wan-kanabi/dist/kanabi";
import { BlockIdentifier, BlockTag } from "starknet";
import { useDeployedContractInfo } from "~~/hooks/scaffold-stark";
import {
AbiFunctionOutputs,
ContractAbi,
ContractName,
ExtractAbiFunctionNamesScaffold,
UseScaffoldReadConfig,
} from "~~/utils/scaffold-stark/contract";

export const useScaffoldContractRead = <
TContractName extends ContractName,
TFunctionName extends ExtractAbiFunctionNamesScaffold<
ContractAbi<TContractName>,
"view"
>
>({
contractName,
functionName,
args,
...readConfig
}: UseScaffoldReadConfig<TContractName, TFunctionName>) => {
const { data: deployedContract } = useDeployedContractInfo(contractName);
const { targetNetwork } = useTargetNetwork();

return useContractRead({
chainId: targetNetwork.id,
functionName,
address: deployedContract?.address,
abi: deployedContract?.abi,
watch: true,
args,
enabled: !Array.isArray(args) || !args.some((arg) => arg === undefined),
blockIdentifier: "pending" as BlockIdentifier,
...(readConfig as any),
}) as Omit<ReturnType<typeof useContractRead>, "data" | "refetch"> & {
data: AbiFunctionOutputs<ContractAbi, TFunctionName> | undefined;
// refetch: (options?: {
// throwOnError: boolean;
// cancelRefetch: boolean;
// }) => Promise<AbiFunctionOutputs<ContractAbi, TFunctionName>>;
};
};
Loading

0 comments on commit de48cef

Please sign in to comment.