diff --git a/client/src/Checks.tsx b/client/src/Checks.tsx index 7de3a88..b5ed3fc 100644 --- a/client/src/Checks.tsx +++ b/client/src/Checks.tsx @@ -1,7 +1,7 @@ -import { useAccount, useConnect, useProvider } from "@starknet-react/core"; +import { useAccount, useConnect, useReadContract } from "@starknet-react/core"; import NotEnough from "@/components/not-enough"; import { useEffect, useState } from "react"; -import { AccountInterface, Contract } from "starknet"; +import { nft_abi } from "@/abi" const SmallScreenWarning = () => (
@@ -14,33 +14,16 @@ const SmallScreenWarning = () => ( ); export default function Checks({ children }: { children: React.ReactNode }) { - const { account, address, isConnected } = useAccount(); + const { address, isConnected } = useAccount(); const { connect, connectors } = useConnect(); - const { provider } = useProvider(); - const [amountOfTokens, setAmountOfTokens] = useState(); - useEffect(() => { - const fetchData = async () => { - if (!isConnected) { - connect({ connector: connectors[0] }); - } - const contract_address = - "0x00c489b121fdc7bf7aa71167d603de7d41184576b6ed1bae87dd7b448c4ac8cf"; - const { abi } = await provider.getClassAt(contract_address); - const contract = new Contract(abi, contract_address, provider); - contract.connect(account as AccountInterface); - const contract_call = contract.populate("balance_of", [ - address?.toString() || "", - ]); - const data = await contract.balance_of(contract_call.calldata); - setAmountOfTokens(Number(data)); - }; - fetchData(); - }, [account, address, connect, connectors, isConnected, provider]); - const isEnough = Math.round(amountOfTokens || 0) >= 1; - console.log({ - amountOfTokens, - isEnough, + const nft_contract_address = "0x00c489b121fdc7bf7aa71167d603de7d41184576b6ed1bae87dd7b448c4ac8cf"; + const { data: nft_data, refetch } = useReadContract({ + abi: nft_abi, + functionName: "balance_of", + address: nft_contract_address, + args: [address || ""] }); + const isEnough = Math.round(Number(nft_data) || 0) >= 1; const [isSmallScreen, setIsSmallScreen] = useState(false); useEffect(() => { @@ -55,10 +38,10 @@ export default function Checks({ children }: { children: React.ReactNode }) { return () => { window.removeEventListener("resize", handleResize); }; - }, []); + }, [connect, connectors, isConnected]); return (
- {isConnected && !isEnough && } + {isConnected && !isEnough && } {isSmallScreen && } {children}
diff --git a/client/src/abi.ts b/client/src/abi.ts new file mode 100644 index 0000000..5133e11 --- /dev/null +++ b/client/src/abi.ts @@ -0,0 +1,675 @@ +export const nft_abi = [ + { + "type": "impl", + "name": "IMancalaPass", + "interface_name": "mancala_pass::IMancalaPass" + }, + { + "type": "interface", + "name": "mancala_pass::IMancalaPass", + "items": [ + { + "type": "function", + "name": "mint_pass", + "inputs": [ + { + "name": "recipient", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [], + "state_mutability": "external" + } + ] + }, + { + "type": "function", + "name": "pause", + "inputs": [], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "unpause", + "inputs": [], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "impl", + "name": "ERC721MixinImpl", + "interface_name": "openzeppelin_token::erc721::interface::ERC721ABI" + }, + { + "type": "struct", + "name": "core::integer::u256", + "members": [ + { + "name": "low", + "type": "core::integer::u128" + }, + { + "name": "high", + "type": "core::integer::u128" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "enum", + "name": "core::bool", + "variants": [ + { + "name": "False", + "type": "()" + }, + { + "name": "True", + "type": "()" + } + ] + }, + { + "type": "struct", + "name": "core::byte_array::ByteArray", + "members": [ + { + "name": "data", + "type": "core::array::Array::" + }, + { + "name": "pending_word", + "type": "core::felt252" + }, + { + "name": "pending_word_len", + "type": "core::integer::u32" + } + ] + }, + { + "type": "interface", + "name": "openzeppelin_token::erc721::interface::ERC721ABI", + "items": [ + { + "type": "function", + "name": "balance_of", + "inputs": [ + { + "name": "account", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [ + { + "type": "core::integer::u256" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "owner_of", + "inputs": [ + { + "name": "token_id", + "type": "core::integer::u256" + } + ], + "outputs": [ + { + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "safe_transfer_from", + "inputs": [ + { + "name": "from", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "to", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "token_id", + "type": "core::integer::u256" + }, + { + "name": "data", + "type": "core::array::Span::" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "transfer_from", + "inputs": [ + { + "name": "from", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "to", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "token_id", + "type": "core::integer::u256" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "approve", + "inputs": [ + { + "name": "to", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "token_id", + "type": "core::integer::u256" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "set_approval_for_all", + "inputs": [ + { + "name": "operator", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "approved", + "type": "core::bool" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "get_approved", + "inputs": [ + { + "name": "token_id", + "type": "core::integer::u256" + } + ], + "outputs": [ + { + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "is_approved_for_all", + "inputs": [ + { + "name": "owner", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "operator", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [ + { + "type": "core::bool" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "supports_interface", + "inputs": [ + { + "name": "interface_id", + "type": "core::felt252" + } + ], + "outputs": [ + { + "type": "core::bool" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "name", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "symbol", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "token_uri", + "inputs": [ + { + "name": "token_id", + "type": "core::integer::u256" + } + ], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "balanceOf", + "inputs": [ + { + "name": "account", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [ + { + "type": "core::integer::u256" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "ownerOf", + "inputs": [ + { + "name": "tokenId", + "type": "core::integer::u256" + } + ], + "outputs": [ + { + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "safeTransferFrom", + "inputs": [ + { + "name": "from", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "to", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "tokenId", + "type": "core::integer::u256" + }, + { + "name": "data", + "type": "core::array::Span::" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "transferFrom", + "inputs": [ + { + "name": "from", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "to", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "tokenId", + "type": "core::integer::u256" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "setApprovalForAll", + "inputs": [ + { + "name": "operator", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "approved", + "type": "core::bool" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "getApproved", + "inputs": [ + { + "name": "tokenId", + "type": "core::integer::u256" + } + ], + "outputs": [ + { + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "isApprovedForAll", + "inputs": [ + { + "name": "owner", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "operator", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [ + { + "type": "core::bool" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "tokenURI", + "inputs": [ + { + "name": "tokenId", + "type": "core::integer::u256" + } + ], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + } + ] + }, + { + "type": "constructor", + "name": "constructor", + "inputs": [ + { + "name": "recipient", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "owner", + "type": "core::starknet::contract_address::ContractAddress" + } + ] + }, + { + "type": "event", + "name": "openzeppelin_token::erc721::erc721::ERC721Component::Transfer", + "kind": "struct", + "members": [ + { + "name": "from", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "key" + }, + { + "name": "to", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "key" + }, + { + "name": "token_id", + "type": "core::integer::u256", + "kind": "key" + } + ] + }, + { + "type": "event", + "name": "openzeppelin_token::erc721::erc721::ERC721Component::Approval", + "kind": "struct", + "members": [ + { + "name": "owner", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "key" + }, + { + "name": "approved", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "key" + }, + { + "name": "token_id", + "type": "core::integer::u256", + "kind": "key" + } + ] + }, + { + "type": "event", + "name": "openzeppelin_token::erc721::erc721::ERC721Component::ApprovalForAll", + "kind": "struct", + "members": [ + { + "name": "owner", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "key" + }, + { + "name": "operator", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "key" + }, + { + "name": "approved", + "type": "core::bool", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "openzeppelin_token::erc721::erc721::ERC721Component::Event", + "kind": "enum", + "variants": [ + { + "name": "Transfer", + "type": "openzeppelin_token::erc721::erc721::ERC721Component::Transfer", + "kind": "nested" + }, + { + "name": "Approval", + "type": "openzeppelin_token::erc721::erc721::ERC721Component::Approval", + "kind": "nested" + }, + { + "name": "ApprovalForAll", + "type": "openzeppelin_token::erc721::erc721::ERC721Component::ApprovalForAll", + "kind": "nested" + } + ] + }, + { + "type": "event", + "name": "openzeppelin_introspection::src5::SRC5Component::Event", + "kind": "enum", + "variants": [] + }, + { + "type": "event", + "name": "openzeppelin_access::ownable::ownable::OwnableComponent::OwnershipTransferred", + "kind": "struct", + "members": [ + { + "name": "previous_owner", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "key" + }, + { + "name": "new_owner", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "key" + } + ] + }, + { + "type": "event", + "name": "openzeppelin_access::ownable::ownable::OwnableComponent::OwnershipTransferStarted", + "kind": "struct", + "members": [ + { + "name": "previous_owner", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "key" + }, + { + "name": "new_owner", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "key" + } + ] + }, + { + "type": "event", + "name": "openzeppelin_access::ownable::ownable::OwnableComponent::Event", + "kind": "enum", + "variants": [ + { + "name": "OwnershipTransferred", + "type": "openzeppelin_access::ownable::ownable::OwnableComponent::OwnershipTransferred", + "kind": "nested" + }, + { + "name": "OwnershipTransferStarted", + "type": "openzeppelin_access::ownable::ownable::OwnableComponent::OwnershipTransferStarted", + "kind": "nested" + } + ] + }, + { + "type": "event", + "name": "openzeppelin_security::pausable::PausableComponent::Paused", + "kind": "struct", + "members": [ + { + "name": "account", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "openzeppelin_security::pausable::PausableComponent::Unpaused", + "kind": "struct", + "members": [ + { + "name": "account", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "openzeppelin_security::pausable::PausableComponent::Event", + "kind": "enum", + "variants": [ + { + "name": "Paused", + "type": "openzeppelin_security::pausable::PausableComponent::Paused", + "kind": "nested" + }, + { + "name": "Unpaused", + "type": "openzeppelin_security::pausable::PausableComponent::Unpaused", + "kind": "nested" + } + ] + }, + { + "type": "event", + "name": "mancala_pass::MancalaPass::Event", + "kind": "enum", + "variants": [ + { + "name": "ERC721Event", + "type": "openzeppelin_token::erc721::erc721::ERC721Component::Event", + "kind": "flat" + }, + { + "name": "SRC5Event", + "type": "openzeppelin_introspection::src5::SRC5Component::Event", + "kind": "flat" + }, + { + "name": "OwnableEvent", + "type": "openzeppelin_access::ownable::ownable::OwnableComponent::Event", + "kind": "flat" + }, + { + "name": "PausableEvent", + "type": "openzeppelin_security::pausable::PausableComponent::Event", + "kind": "flat" + } + ] + } +] as const; diff --git a/client/src/components/not-enough.tsx b/client/src/components/not-enough.tsx index c7bafb8..267f833 100644 --- a/client/src/components/not-enough.tsx +++ b/client/src/components/not-enough.tsx @@ -1,11 +1,35 @@ import { Dialog } from "@material-tailwind/react"; -import { useState } from "react"; +import { useEffect, useState } from "react"; import { Button } from "./ui/button"; -import { BellIcon } from "@heroicons/react/24/solid"; +import MintIcon from "./ui/svgs/mint"; +import { useAccount, useContract, useSendTransaction } from "@starknet-react/core"; +import { nft_abi } from "@/abi" -export default function NotEnough({ isEnough }: { isEnough: boolean }) { +export default function NotEnough({ isEnough, refetch }: { isEnough: boolean, refetch: any }) { const [open, setOpen] = useState(!isEnough); const handleOpen = () => setOpen(open); + const nft_contract_address = "0x00c489b121fdc7bf7aa71167d603de7d41184576b6ed1bae87dd7b448c4ac8cf"; + const { address } = useAccount(); + const { contract } = useContract({ + abi: nft_abi, + address: nft_contract_address, + }); + const { data: mint_response, send } = useSendTransaction({ + calls: contract && address + ? [contract.populate("mint_pass", [address])] + : undefined, + }); + + const handleMint = () => { + setOpen(true); + send(); + } + + useEffect(() => { + if (mint_response?.transaction_hash) { + refetch(); + } + }, [mint_response, refetch]); return (

Missing Token

- This Game is currently available to the general public, Input an - email address to be notified when available to all users + Mancala game access for Pass holders! Mint your free testnet Pass to play now.

-
diff --git a/client/src/components/ui/svgs/mint.tsx b/client/src/components/ui/svgs/mint.tsx new file mode 100644 index 0000000..d0fc2b7 --- /dev/null +++ b/client/src/components/ui/svgs/mint.tsx @@ -0,0 +1,24 @@ +export default function MintIcon() { + return( + + + + + + ) +} \ No newline at end of file