From 14305690a120eaeacd96452ef256e72d9c5b8fdf Mon Sep 17 00:00:00 2001 From: Corantin Date: Tue, 12 Dec 2023 09:42:29 -0500 Subject: [PATCH] Transaction receipt --- .../{blockexplorer => }/TransactionHash.tsx | 9 +- .../nextjs/components/assets/BitcoinIcon.tsx | 14 + .../{DownloadLogo.tsx => Downloadicon.tsx} | 0 .../blockexplorer/TransactionsTable.tsx | 2 +- .../nextjs/components/blockexplorer/index.tsx | 2 +- .../components/inputs/FileUploaderInput.tsx | 6 +- .../components/scaffold-eth/Address.tsx | 10 +- .../components/scaffold-eth/BlockieAvatar.tsx | 10 +- .../RainbowKitCustomConnectButton.tsx | 414 +++++++++--------- .../nextjs/components/scaffold-eth/index.tsx | 1 - packages/nextjs/constants.ts | 11 + .../nextjs/contracts/externalContracts.ts | 193 +++++++- .../nextjs/hooks/contracts/deed-nft-hooks.ts | 23 +- .../hooks/scaffold-eth/useAutoConnect.ts | 21 +- .../scaffold-eth/useScaffoldContractWrite.ts | 6 +- packages/nextjs/models/auth-token.ts | 2 +- packages/nextjs/models/deed-info.model.ts | 24 +- packages/nextjs/package.json | 4 +- packages/nextjs/pages/_app.tsx | 1 - packages/nextjs/pages/api/deed-info/[id].ts | 15 +- packages/nextjs/pages/api/payment.ts | 15 +- .../nextjs/pages/property-explorer/index.tsx | 1 + .../pages/registration/PaymentInformation.tsx | 169 +++---- packages/nextjs/pages/registration/index.tsx | 165 ++++--- packages/nextjs/services/jwt-util.ts | 10 + packages/nextjs/services/web3/wagmiConfig.tsx | 14 +- .../nextjs/services/web3/wagmiConnectors.tsx | 145 +++--- .../nextjs/utils/scaffold-eth/networks.ts | 70 ++- yarn.lock | 350 +++++---------- 29 files changed, 1004 insertions(+), 703 deletions(-) rename packages/nextjs/components/{blockexplorer => }/TransactionHash.tsx (73%) create mode 100644 packages/nextjs/components/assets/BitcoinIcon.tsx rename packages/nextjs/components/assets/{DownloadLogo.tsx => Downloadicon.tsx} (100%) create mode 100644 packages/nextjs/services/jwt-util.ts diff --git a/packages/nextjs/components/blockexplorer/TransactionHash.tsx b/packages/nextjs/components/TransactionHash.tsx similarity index 73% rename from packages/nextjs/components/blockexplorer/TransactionHash.tsx rename to packages/nextjs/components/TransactionHash.tsx index 5d361516..1fe22a05 100644 --- a/packages/nextjs/components/blockexplorer/TransactionHash.tsx +++ b/packages/nextjs/components/TransactionHash.tsx @@ -1,14 +1,19 @@ -import { useState } from "react"; +import { useMemo, useState } from "react"; import Link from "next/link"; +import { ExternalLinkIcon } from "@dynamic-labs/sdk-react-core"; import { CopyToClipboard } from "react-copy-to-clipboard"; import { CheckCircleIcon, DocumentDuplicateIcon } from "@heroicons/react/24/outline"; +import { getBlockExplorerTxLink } from "~~/utils/scaffold-eth"; export const TransactionHash = ({ hash }: { hash: string }) => { const [addressCopied, setAddressCopied] = useState(false); + const txExplorerLink = useMemo(() => getBlockExplorerTxLink(hash), [hash]); + return (
- + + {hash?.substring(0, 6)}...{hash?.substring(hash.length - 4)} {addressCopied ? ( diff --git a/packages/nextjs/components/assets/BitcoinIcon.tsx b/packages/nextjs/components/assets/BitcoinIcon.tsx new file mode 100644 index 00000000..66e5b6b6 --- /dev/null +++ b/packages/nextjs/components/assets/BitcoinIcon.tsx @@ -0,0 +1,14 @@ +export const BitcoinIcon = ({ width }: { width: number }) => ( + + + +); diff --git a/packages/nextjs/components/assets/DownloadLogo.tsx b/packages/nextjs/components/assets/Downloadicon.tsx similarity index 100% rename from packages/nextjs/components/assets/DownloadLogo.tsx rename to packages/nextjs/components/assets/Downloadicon.tsx diff --git a/packages/nextjs/components/blockexplorer/TransactionsTable.tsx b/packages/nextjs/components/blockexplorer/TransactionsTable.tsx index 4c72ee3e..00c104d1 100644 --- a/packages/nextjs/components/blockexplorer/TransactionsTable.tsx +++ b/packages/nextjs/components/blockexplorer/TransactionsTable.tsx @@ -1,5 +1,5 @@ import { formatEther } from "viem"; -import { TransactionHash } from "~~/components/blockexplorer/TransactionHash"; +import { TransactionHash } from "~~/components/TransactionHash"; import { Address } from "~~/components/scaffold-eth"; import { TransactionWithFunction, getTargetNetwork } from "~~/utils/scaffold-eth"; import { TransactionsTableProps } from "~~/utils/scaffold-eth/"; diff --git a/packages/nextjs/components/blockexplorer/index.tsx b/packages/nextjs/components/blockexplorer/index.tsx index 36afa618..d7a13180 100644 --- a/packages/nextjs/components/blockexplorer/index.tsx +++ b/packages/nextjs/components/blockexplorer/index.tsx @@ -3,5 +3,5 @@ export * from "./AddressCodeTab"; export * from "./AddressStorageTab"; export * from "./PaginationButton"; export * from "./SearchBar"; -export * from "./TransactionHash"; +export * from "../TransactionHash"; export * from "./TransactionsTable"; diff --git a/packages/nextjs/components/inputs/FileUploaderInput.tsx b/packages/nextjs/components/inputs/FileUploaderInput.tsx index 97bf2e7c..bc1d1311 100644 --- a/packages/nextjs/components/inputs/FileUploaderInput.tsx +++ b/packages/nextjs/components/inputs/FileUploaderInput.tsx @@ -1,6 +1,6 @@ import { useEffect, useRef, useState } from "react"; import { useRouter } from "next/router"; -import { DownloadLogo } from "../assets/DownloadLogo"; +import { DownloadLogo } from "../assets/Downloadicon"; import useHttpClient from "~~/hooks/useHttpClient"; import { IpfsFileModel } from "~~/models/ipfs-file.model"; import { LightChangeEvent } from "~~/models/light-change-event"; @@ -35,7 +35,9 @@ export const FileUploaderInput = ({ const { id } = query as { id: string }; useEffect(() => { - if (value) { + if (!value) { + setFiles([]); + } else { if (Array.isArray(value)) { setFiles(value); } else { diff --git a/packages/nextjs/components/scaffold-eth/Address.tsx b/packages/nextjs/components/scaffold-eth/Address.tsx index 6df8453a..b024d08d 100644 --- a/packages/nextjs/components/scaffold-eth/Address.tsx +++ b/packages/nextjs/components/scaffold-eth/Address.tsx @@ -29,8 +29,8 @@ const blockieSizeMap = { * Displays an address (or ENS) with a Blockie image and option to copy address. */ export const Address = ({ address, disableAddressLink, format, size = "base" }: TAddressProps) => { - const [ens, setEns] = useState(); - const [ensAvatar, setEnsAvatar] = useState(); + const [ens, setEns] = useState(); + const [ensAvatar, setEnsAvatar] = useState(); const [addressCopied, setAddressCopied] = useState(false); const { data: fetchedEns } = useEnsName({ @@ -47,11 +47,11 @@ export const Address = ({ address, disableAddressLink, format, size = "base" }: // We need to apply this pattern to avoid Hydration errors. useEffect(() => { - setEns(fetchedEns); + setEns(fetchedEns ?? undefined); }, [fetchedEns]); useEffect(() => { - setEnsAvatar(fetchedEnsAvatar); + setEnsAvatar(fetchedEnsAvatar ?? undefined); }, [fetchedEnsAvatar]); // Skeleton UI @@ -70,7 +70,7 @@ export const Address = ({ address, disableAddressLink, format, size = "base" }: return Wrong address; } - const blockExplorerAddressLink = getBlockExplorerAddressLink(getTargetNetwork(), address); + const blockExplorerAddressLink = getBlockExplorerAddressLink(address); let displayAddress = address?.slice(0, 5) + "..." + address?.slice(-4); if (ens) { diff --git a/packages/nextjs/components/scaffold-eth/BlockieAvatar.tsx b/packages/nextjs/components/scaffold-eth/BlockieAvatar.tsx index 9c1ea4d6..fe5082d0 100644 --- a/packages/nextjs/components/scaffold-eth/BlockieAvatar.tsx +++ b/packages/nextjs/components/scaffold-eth/BlockieAvatar.tsx @@ -1,8 +1,14 @@ -import { AvatarComponent } from "@rainbow-me/rainbowkit"; import { blo } from "blo"; +import { Address } from "viem"; + +interface Props { + address: Address; + ensImage?: string; + size: number; +} // Custom Avatar for RainbowKit -export const BlockieAvatar: AvatarComponent = ({ address, ensImage, size }) => ( +export const BlockieAvatar = ({ address, ensImage, size }: Props) => ( // Don't want to use nextJS Image here (and adding remote patterns for the URL) // eslint-disable-next-line @next/next/no-img-element { - useAutoConnect(); - const networkColor = useNetworkColor(); - const configuredNetwork = getTargetNetwork(); - const { disconnect } = useDisconnect(); - const { switchNetwork } = useSwitchNetwork(); - const [addressCopied, setAddressCopied] = useState(false); +// /** +// * Custom Wagmi Connect Button (watch balance + custom design) +// */ +// export const RainbowKitCustomConnectButton = () => { +// useAutoConnect(); +// const networkColor = useNetworkColor(); +// const configuredNetwork = getTargetNetwork(); +// const { disconnect } = useDisconnect(); +// const { switchNetwork } = useSwitchNetwork(); +// const [addressCopied, setAddressCopied] = useState(false); - return ( - - {({ account, chain, openConnectModal, mounted }) => { - const connected = mounted && account && chain; - const blockExplorerAddressLink = account - ? getBlockExplorerAddressLink(getTargetNetwork(), account.address) - : undefined; +// return ( +// +// {({ account, chain, openConnectModal, mounted }) => { +// const connected = mounted && account && chain; +// const blockExplorerAddressLink = account +// ? getBlockExplorerAddressLink(getTargetNetwork(), account.address) +// : undefined; - return ( - <> - {(() => { - if (!connected) { - return ( - - ); - } +// return ( +// <> +// {(() => { +// if (!connected) { +// return ( +// +// ); +// } - if (chain.unsupported || chain.id !== configuredNetwork.id) { - return ( -
- -
    -
  • - -
  • -
  • - -
  • -
-
- ); - } +// if (chain.unsupported || chain.id !== configuredNetwork.id) { +// return ( +//
+// +//
    +//
  • +// +//
  • +//
  • +// +//
  • +//
+//
+// ); +// } - return ( -
-
- - - {chain.name} - -
-
- -
    -
  • - {addressCopied ? ( -
    -
    - ) : ( - { - setAddressCopied(true); - setTimeout(() => { - setAddressCopied(false); - }, 800); - }} - > -
    -
    -
    - )} -
  • -
  • - -
  • -
  • - -
  • -
  • - -
  • -
-
-
- - -
-
- ); - })()} - - ); - }} -
- ); -}; +// return ( +//
+//
+// +// +// {chain.name} +// +//
+//
+// +//
    +//
  • +// {addressCopied ? ( +//
    +//
    +// ) : ( +// { +// setAddressCopied(true); +// setTimeout(() => { +// setAddressCopied(false); +// }, 800); +// }} +// > +//
    +//
    +//
    +// )} +//
  • +//
  • +// +//
  • +//
  • +// +//
  • +//
  • +// +//
  • +//
+//
+//
+// +// +//
+//
+// ); +// })()} +// +// ); +// }} +//
+// ); +// }; diff --git a/packages/nextjs/components/scaffold-eth/index.tsx b/packages/nextjs/components/scaffold-eth/index.tsx index 5d51ad56..41c87e09 100644 --- a/packages/nextjs/components/scaffold-eth/index.tsx +++ b/packages/nextjs/components/scaffold-eth/index.tsx @@ -5,4 +5,3 @@ export * from "./Contract"; export * from "./Faucet"; export * from "./FaucetButton"; export * from "./Input"; -export * from "./RainbowKitCustomConnectButton"; diff --git a/packages/nextjs/constants.ts b/packages/nextjs/constants.ts index bad1e7b5..1ee2e3f8 100644 --- a/packages/nextjs/constants.ts +++ b/packages/nextjs/constants.ts @@ -168,6 +168,7 @@ export const BlockchainOptions = [ disabled: true, }, ] as const; + export const PaymentOptions = [ { title: "Debit or Credit", @@ -182,6 +183,7 @@ export const PaymentOptions = [ icon: IconPolygon, }, ] as const; + export const WrapperOptions = [ { title: "Nominee Trust", @@ -201,3 +203,12 @@ export const WrapperOptions = [ value: "llc", }, ] as const; + +export const SupportedStableCoin = [ + { + label: "Dai Stablecoin", + symbol: "DAI", + decimals: 18, + value: "0x9D233A907E065855D2A9c7d4B552ea27fB2E5a36", + }, +] as const; diff --git a/packages/nextjs/contracts/externalContracts.ts b/packages/nextjs/contracts/externalContracts.ts index f2872902..95044eb8 100644 --- a/packages/nextjs/contracts/externalContracts.ts +++ b/packages/nextjs/contracts/externalContracts.ts @@ -10,6 +10,197 @@ import { GenericContractsDeclaration } from "~~/utils/scaffold-eth/contract"; * } * } as const; */ -const externalContracts = {} as const; +const externalContracts = { + 5: { + DAI: { + address: "0x9D233A907E065855D2A9c7d4B552ea27fB2E5a36", + abi: [ + { + inputs: [ + { internalType: "string", name: "name", type: "string" }, + { internalType: "string", name: "symbol", type: "string" }, + { internalType: "uint8", name: "decimals", type: "uint8" }, + { internalType: "uint256", name: "initialSupply", type: "uint256" }, + ], + stateMutability: "nonpayable", + type: "constructor", + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: "address", name: "owner", type: "address" }, + { indexed: true, internalType: "address", name: "spender", type: "address" }, + { indexed: false, internalType: "uint256", name: "value", type: "uint256" }, + ], + name: "Approval", + type: "event", + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: "address", name: "previousOwner", type: "address" }, + { indexed: true, internalType: "address", name: "newOwner", type: "address" }, + ], + name: "OwnershipTransferred", + type: "event", + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: "address", name: "from", type: "address" }, + { indexed: true, internalType: "address", name: "to", type: "address" }, + { indexed: false, internalType: "uint256", name: "value", type: "uint256" }, + ], + name: "Transfer", + type: "event", + }, + { + inputs: [ + { internalType: "address", name: "owner", type: "address" }, + { internalType: "address", name: "spender", type: "address" }, + ], + name: "allowance", + outputs: [{ internalType: "uint256", name: "", type: "uint256" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { internalType: "address", name: "spender", type: "address" }, + { internalType: "uint256", name: "amount", type: "uint256" }, + ], + name: "approve", + outputs: [{ internalType: "bool", name: "", type: "bool" }], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [{ internalType: "address", name: "account", type: "address" }], + name: "balanceOf", + outputs: [{ internalType: "uint256", name: "", type: "uint256" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [{ internalType: "uint256", name: "amount", type: "uint256" }], + name: "burn", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { internalType: "address", name: "account", type: "address" }, + { internalType: "uint256", name: "amount", type: "uint256" }, + ], + name: "burnFrom", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "decimals", + outputs: [{ internalType: "uint8", name: "", type: "uint8" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { internalType: "address", name: "spender", type: "address" }, + { internalType: "uint256", name: "subtractedValue", type: "uint256" }, + ], + name: "decreaseAllowance", + outputs: [{ internalType: "bool", name: "", type: "bool" }], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { internalType: "address", name: "spender", type: "address" }, + { internalType: "uint256", name: "addedValue", type: "uint256" }, + ], + name: "increaseAllowance", + outputs: [{ internalType: "bool", name: "", type: "bool" }], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { internalType: "address", name: "to", type: "address" }, + { internalType: "uint256", name: "amount", type: "uint256" }, + ], + name: "mint", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "name", + outputs: [{ internalType: "string", name: "", type: "string" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "owner", + outputs: [{ internalType: "address", name: "", type: "address" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "renounceOwnership", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "symbol", + outputs: [{ internalType: "string", name: "", type: "string" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "totalSupply", + outputs: [{ internalType: "uint256", name: "", type: "uint256" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { internalType: "address", name: "recipient", type: "address" }, + { internalType: "uint256", name: "amount", type: "uint256" }, + ], + name: "transfer", + outputs: [{ internalType: "bool", name: "", type: "bool" }], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { internalType: "address", name: "sender", type: "address" }, + { internalType: "address", name: "recipient", type: "address" }, + { internalType: "uint256", name: "amount", type: "uint256" }, + ], + name: "transferFrom", + outputs: [{ internalType: "bool", name: "", type: "bool" }], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [{ internalType: "address", name: "newOwner", type: "address" }], + name: "transferOwnership", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + ], + }, + }, +} as const; export default externalContracts satisfies GenericContractsDeclaration; diff --git a/packages/nextjs/hooks/contracts/deed-nft-hooks.ts b/packages/nextjs/hooks/contracts/deed-nft-hooks.ts index 3181ddb3..bbb0c43d 100644 --- a/packages/nextjs/hooks/contracts/deed-nft-hooks.ts +++ b/packages/nextjs/hooks/contracts/deed-nft-hooks.ts @@ -12,11 +12,17 @@ import { import logger from "~~/services/logger"; import { indexOfLiteral } from "~~/utils/extract-values"; import { uploadFile, uploadJson } from "~~/utils/ipfs"; -import { notification } from "~~/utils/scaffold-eth"; +import { getTargetNetwork, notification } from "~~/utils/scaffold-eth"; export const useDeedNftMint = (onConfirmed?: (txnReceipt: TransactionReceipt) => void) => { const { primaryWallet } = useDynamicContext(); + const { writeAsync: erc20Transfer } = useScaffoldContractWrite({ + contractName: "DAI", + functionName: "transfer", + args: [] as any, // Will be filled in by write() + }); + const contractWriteHook = useScaffoldContractWrite({ contractName: "DeedNFT", functionName: "mintAsset", @@ -31,6 +37,21 @@ export const useDeedNftMint = (onConfirmed?: (txnReceipt: TransactionReceipt) => } if (data.paymentInformation.paymentType === "crypto") { + const paymentNotif = notification.info("Sending payment..."); + try { + const { deedMintingFee, storageWalletAddress } = getTargetNetwork(); + const txHash = await erc20Transfer({ + args: [storageWalletAddress, deedMintingFee], + }); + if (txHash) { + data.paymentInformation.receipt = txHash; + } + notification.remove(paymentNotif); + } catch (error) { + logger.error({ message: "Error while sending payment", error }); + notification.error("Error while sending payment"); + return; + } } else { // Call api } diff --git a/packages/nextjs/hooks/scaffold-eth/useAutoConnect.ts b/packages/nextjs/hooks/scaffold-eth/useAutoConnect.ts index baf2b110..6b2e0190 100644 --- a/packages/nextjs/hooks/scaffold-eth/useAutoConnect.ts +++ b/packages/nextjs/hooks/scaffold-eth/useAutoConnect.ts @@ -3,10 +3,13 @@ import { useEffectOnce, useLocalStorage, useReadLocalStorage } from "usehooks-ts import { hardhat } from "viem/chains"; import { Connector, useAccount, useConnect } from "wagmi"; import scaffoldConfig from "~~/scaffold.config"; -import { burnerWalletId, defaultBurnerChainId } from "~~/services/web3/wagmi-burner/BurnerConnector"; +import { + burnerWalletId, + defaultBurnerChainId, +} from "~~/services/web3/wagmi-burner/BurnerConnector"; import { getTargetNetwork } from "~~/utils/scaffold-eth"; -const SCAFFOLD_WALLET_STROAGE_KEY = "scaffoldEth2.wallet"; +const SCAFFOLD_WALLET_STORAGE_KEY = "scaffoldEth2.wallet"; const WAGMI_WALLET_STORAGE_KEY = "wagmi.wallet"; // ID of the SAFE connector instance @@ -23,7 +26,9 @@ const getInitialConnector = ( connectors: Connector[], ): { connector: Connector | undefined; chainId?: number } | undefined => { // Look for the SAFE connector instance and connect to it instantly if loaded in SAFE frame - const safeConnectorInstance = connectors.find(connector => connector.id === SAFE_ID && connector.ready); + const safeConnectorInstance = connectors.find( + connector => connector.id === SAFE_ID && connector.ready, + ); if (safeConnectorInstance) { return { connector: safeConnectorInstance }; @@ -58,7 +63,10 @@ const getInitialConnector = ( */ export const useAutoConnect = (): void => { const wagmiWalletValue = useReadLocalStorage(WAGMI_WALLET_STORAGE_KEY); - const [walletId, setWalletId] = useLocalStorage(SCAFFOLD_WALLET_STROAGE_KEY, wagmiWalletValue ?? ""); + const [walletId, setWalletId] = useLocalStorage( + SCAFFOLD_WALLET_STORAGE_KEY, + wagmiWalletValue ?? "", + ); const connectState = useConnect(); const accountState = useAccount(); @@ -78,7 +86,10 @@ export const useAutoConnect = (): void => { const initialConnector = getInitialConnector(walletId, connectState.connectors); if (initialConnector?.connector) { - connectState.connect({ connector: initialConnector.connector, chainId: initialConnector.chainId }); + connectState.connect({ + connector: initialConnector.connector, + chainId: initialConnector.chainId, + }); } }); }; diff --git a/packages/nextjs/hooks/scaffold-eth/useScaffoldContractWrite.ts b/packages/nextjs/hooks/scaffold-eth/useScaffoldContractWrite.ts index ab12cee2..05fcfec3 100644 --- a/packages/nextjs/hooks/scaffold-eth/useScaffoldContractWrite.ts +++ b/packages/nextjs/hooks/scaffold-eth/useScaffoldContractWrite.ts @@ -78,7 +78,7 @@ export const useScaffoldContractWrite = < if (wagmiContractWrite.writeAsync) { try { setIsMining(true); - await writeTx( + const hash = await writeTx( () => wagmiContractWrite.writeAsync({ args: newArgs ?? args, @@ -87,6 +87,7 @@ export const useScaffoldContractWrite = < }), { onBlockConfirmation, blockConfirmations }, ); + return hash; } catch (e: any) { const message = getParsedError(e); notification.error(message); @@ -94,11 +95,12 @@ export const useScaffoldContractWrite = < } finally { setIsMining(false); } + return null; } else { const message = "Contract writer error. Try again."; notification.error(message); logger.error({ message, contract: contractName }); - return; + return null; } }; diff --git a/packages/nextjs/models/auth-token.ts b/packages/nextjs/models/auth-token.ts index eaac7786..63a0b585 100644 --- a/packages/nextjs/models/auth-token.ts +++ b/packages/nextjs/models/auth-token.ts @@ -1,4 +1,4 @@ -import { JwtPayload } from "jwt-decode"; +import { JwtPayload } from "jsonwebtoken"; import { Address } from "viem"; export default interface AuthToken extends JwtPayload { diff --git a/packages/nextjs/models/deed-info.model.ts b/packages/nextjs/models/deed-info.model.ts index b375f1dd..7bb22bf7 100644 --- a/packages/nextjs/models/deed-info.model.ts +++ b/packages/nextjs/models/deed-info.model.ts @@ -9,6 +9,7 @@ import { PropertyTypeOptions, PropertyZoningOptions, StateOptions, + SupportedStableCoin, WrapperOptions, } from "~~/constants"; import { ValueExtractor } from "~~/utils/extract-values"; @@ -53,20 +54,27 @@ export interface OtherInformationModel { export interface PaymentInformationModel { paymentType: ValueExtractor; - cardNumber: string; - cardExpiry: string; - cardCVV: string; - cardholderName: string; + + // -- Fiat only -- + cardNumber?: string; + cardExpiry?: string; + cardCVV?: string; + cardholderName?: string; suffix?: string; - billingAddress: string; - city: string; - state: string; - zip: string; + billingAddress?: string; + city?: string; + state?: string; + zip?: string; + + // -- Crypto only -- + stabeleCoin?: ValueExtractor; + receipt?: string; } export interface DeedInfoModel { id?: number; owner?: Address; + isValidated?: boolean; // 1. Owner Information ownerInformation: OwnerInformationModel; diff --git a/packages/nextjs/package.json b/packages/nextjs/package.json index 68d48b3e..c42ba904 100644 --- a/packages/nextjs/package.json +++ b/packages/nextjs/package.json @@ -28,7 +28,6 @@ "@heroicons/react": "^2.0.11", "@next/font": "^13.5.3", "@pinata/sdk": "^2.1.0", - "@rainbow-me/rainbowkit": "1.1.2", "@uniswap/sdk": "^3.0.3", "@uniswap/sdk-core": "^4.0.1", "@uniswap/v2-sdk": "^3.0.1", @@ -38,7 +37,7 @@ "daisyui": "^3.5.1", "finity-ui": "^0.0.2", "formidable": "^3.5.1", - "jwt-decode": "^4.0.0", + "jsonwebtoken": "^9.0.2", "leaflet": "^1.9.4", "lodash-es": "^4.17.21", "next": "^13.1.6", @@ -65,6 +64,7 @@ "devDependencies": { "@trivago/prettier-plugin-sort-imports": "^4.1.1", "@types/formidable": "^3", + "@types/jsonwebtoken": "^9", "@types/leaflet": "^1.9.4", "@types/lodash-es": "^4", "@types/mime": "^3", diff --git a/packages/nextjs/pages/_app.tsx b/packages/nextjs/pages/_app.tsx index 5abbe248..6f4d3eb1 100644 --- a/packages/nextjs/pages/_app.tsx +++ b/packages/nextjs/pages/_app.tsx @@ -18,7 +18,6 @@ import "~~/styles/globals.scss"; config.autoAddCss = false; const ScaffoldEthApp = ({ Component, pageProps }: AppProps) => { - // This variable is required for initial client side rendering of correct theme for RainbowKit const [isDarkTheme, setIsDarkTheme] = useState(true); const { isDarkMode } = useDarkMode(); diff --git a/packages/nextjs/pages/api/deed-info/[id].ts b/packages/nextjs/pages/api/deed-info/[id].ts index 10393e3a..ca52a47b 100644 --- a/packages/nextjs/pages/api/deed-info/[id].ts +++ b/packages/nextjs/pages/api/deed-info/[id].ts @@ -1,13 +1,14 @@ import axios from "axios"; -import { JwtPayload, jwtDecode } from "jwt-decode"; import { NextApiRequest, NextApiResponse } from "next"; import { Readable } from "stream"; -import { Address, Hex, createPublicClient, getContract, hexToString, http } from "viem"; +import { Hex, createPublicClient, getContract, hexToString, http } from "viem"; import { goerli } from "viem/chains"; import deployedContracts from "~~/contracts/deployedContracts"; +import AuthToken from "~~/models/auth-token"; import { DeedInfoModel } from "~~/models/deed-info.model"; import { IpfsFileModel } from "~~/models/ipfs-file.model"; import scaffoldConfig from "~~/scaffold.config"; +import { jwtDecode } from "~~/services/jwt-util"; // This function handles the API request for fetching the deed information. export default async function handler(req: NextApiRequest, res: NextApiResponse) { @@ -72,7 +73,14 @@ const get = async (req: NextApiRequest, res: NextApiResponse) => { if (!canAccess && jwtToken) { // Decode the JWT token to get the wallet address. - const decoded = jwtDecode(jwtToken); + let decoded: AuthToken; + try { + decoded = jwtDecode(jwtToken); + } catch (error) { + res.status(401).send(`Error: Invalid JWT token`); + return; + } + walletAddress = decoded.verified_credentials[0].address; const isValidator = await contract.read.hasValidatorRole({ account: walletAddress, @@ -104,6 +112,7 @@ const get = async (req: NextApiRequest, res: NextApiResponse) => { const deedInfoMetadata = (await response.json()) as DeedInfoModel; deedInfoMetadata.id = +id; deedInfoMetadata.owner = deedOwner; + deedInfoMetadata.isValidated = deedInfo.isValidated; if (!hash) { // Send the JSON data as the response. diff --git a/packages/nextjs/pages/api/payment.ts b/packages/nextjs/pages/api/payment.ts index 81b092be..9954a212 100644 --- a/packages/nextjs/pages/api/payment.ts +++ b/packages/nextjs/pages/api/payment.ts @@ -1,18 +1,7 @@ -import pinataSDK from "@pinata/sdk"; -import { JwtPayload, jwtDecode } from "jwt-decode"; import { NextApiRequest, NextApiResponse } from "next"; import Stripe from "stripe"; import AuthToken from "~~/models/auth-token"; - -const pinata = new pinataSDK({ pinataJWTKey: process.env.NEXT_PINATA_TOKEN }); -if (!process.env.NEXT_PINATA_TOKEN) throw new Error("Missing NEXT_PINATA_TOKEN env var"); - -export const config = { - api: { - bodyParser: false, - externalResolver: true, - }, -}; +import { jwtDecode } from "~~/services/jwt-util"; export default async function handler(req: NextApiRequest, res: NextApiResponse) { if (req.method === "POST") { @@ -21,7 +10,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse< let email = undefined; const decoded = jwtDecode(jwtToken); email = decoded.email; - const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!); + const stripe = new Stripe(process.env.NEXT_STRIPE_SECRET_KEY!); const paymentIntent = await stripe.paymentIntents.create({ amount: 200, currency: "usd", diff --git a/packages/nextjs/pages/property-explorer/index.tsx b/packages/nextjs/pages/property-explorer/index.tsx index c4cc0e3b..2c15ae8c 100644 --- a/packages/nextjs/pages/property-explorer/index.tsx +++ b/packages/nextjs/pages/property-explorer/index.tsx @@ -63,6 +63,7 @@ const PropertyExplorer: NextPage = () => { }; const loadMoreProperties = async () => { + setProperties([]); setLoading(true); setCurrentPage(prev => prev + 1); const radius = 10; diff --git a/packages/nextjs/pages/registration/PaymentInformation.tsx b/packages/nextjs/pages/registration/PaymentInformation.tsx index dd662ea4..ee681975 100644 --- a/packages/nextjs/pages/registration/PaymentInformation.tsx +++ b/packages/nextjs/pages/registration/PaymentInformation.tsx @@ -1,9 +1,9 @@ -import React from "react"; +import React, { useState } from "react"; import Link from "next/link"; import { RadioBoxesInput } from "~~/components/inputs/RadioBoxesInput"; import { SelectInput } from "~~/components/inputs/SelectInput"; import TextInput from "~~/components/inputs/TextInput"; -import { PaymentOptions, StateOptions } from "~~/constants"; +import { PaymentOptions, StateOptions, SupportedStableCoin } from "~~/constants"; import { DeedInfoModel, PaymentInformationModel } from "~~/models/deed-info.model"; import { LightChangeEvent } from "~~/models/light-change-event"; @@ -45,85 +45,98 @@ const PaymentInformation = ({ value, onChange }: Props) => { onChange={handleChange} />
-
- - - -
-
- - -
-
- - + {value?.paymentType === "fiat" ? ( + <> +
+ + + +
+
+ + +
+
+ + + + +
+ + ) : ( - -
+ )} ); }; diff --git a/packages/nextjs/pages/registration/index.tsx b/packages/nextjs/pages/registration/index.tsx index 3b563e31..06182ce9 100644 --- a/packages/nextjs/pages/registration/index.tsx +++ b/packages/nextjs/pages/registration/index.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useMemo, useState } from "react"; +import React, { useCallback, useEffect, useMemo, useState } from "react"; import Link from "next/link"; import { useRouter } from "next/router"; import OtherInformations from "./OtherInformations"; @@ -8,6 +8,10 @@ import PropertyDetails from "./PropertyDetails"; import { useDynamicContext } from "@dynamic-labs/sdk-react-core"; import { NextPage } from "next"; import { TransactionReceipt } from "viem"; +import { CurrencyDollarIcon } from "@heroicons/react/24/outline"; +import { BitcoinIcon } from "~~/components/assets/BitcoinIcon"; +import { TransactionHash } from "~~/components/blockexplorer"; +import { Address } from "~~/components/scaffold-eth"; import { useIsValidator } from "~~/hooks/contracts/access-manager.hooks"; import { useDeedContract, @@ -58,18 +62,26 @@ const fakeData: DeedInfoModel = { blockchain: "gnosis", wrapper: "llc", }, + paymentInformation: { + paymentType: "crypto", + stabeleCoin: "0x9D233A907E065855D2A9c7d4B552ea27fB2E5a36", + }, }; -const defaultData: DeedInfoModel = { - otherInformation: { - blockchain: "gnosis", - wrapper: "llc", - }, - ownerInformation: { - ownerType: "individual", - }, - propertyDetails: {}, -} as DeedInfoModel; +const defaultData: DeedInfoModel = fakeData; +// const defaultData: DeedInfoModel = { +// otherInformation: { +// blockchain: "gnosis", +// wrapper: "llc", +// }, +// ownerInformation: { +// ownerType: "individual", +// }, +// propertyDetails: {}, +// paymentInformation: { +// paymentType: "fiat", +// }, +// } as DeedInfoModel; type ErrorCode = "notFound" | "unauthorized"; @@ -99,24 +111,26 @@ const RegistrationForm: NextPage = () => { const { authToken, primaryWallet } = useDynamicContext(); const [isLoading, setIsLoading] = useState(true); const [initialData, setInitialData] = useState(); - const [formData, setFormData] = useState(defaultData); + const [deedInfo, setDeedInfo] = useState(defaultData); const [errorCode, setErrorCode] = useState(undefined); const [isOwner, setIsOwner] = useState(false); + const { id: chainId } = getTargetNetwork(); const deedContract = useDeedContract(); const httpClient = useHttpClient(); useEffect(() => { - if (!isReady || !id) return; - deedContract?.read.ownerOf([BigInt(id)]).then(owner => { + if (!isReady || !id || !deedContract || !primaryWallet) return; + deedContract.read.ownerOf([BigInt(id)]).then(owner => { setIsOwner(owner === primaryWallet?.address); }); - }, [primaryWallet, id, isReady]); + }, [primaryWallet, id, isReady, deedContract]); useEffect(() => { setIsLoading(true); if (isReady) { if (id == null) { + setDeedInfo(defaultData); setIsLoading(false); } else { fetchDeedInfo(+id); @@ -125,30 +139,32 @@ const RegistrationForm: NextPage = () => { }, [id, authToken, isReady]); const handleChange = (ev: LightChangeEvent) => { - setFormData((prevState: DeedInfoModel) => ({ ...prevState, [ev.name]: ev.value })); + setDeedInfo((prevState: DeedInfoModel) => ({ ...prevState, [ev.name]: ev.value })); }; - const fetchDeedInfo = async (id: number) => { - const chainId = getTargetNetwork().id; - const resp = await httpClient.get(`/api/deed-info/${id}?chainId=${chainId}`); - setErrorCode(undefined); - if (resp?.status === 200) { - setInitialData(resp.value); - setFormData(resp.value); - } else { - setErrorCode(resp?.status === 404 ? "notFound" : "unauthorized"); - } - setIsLoading(false); - }; + const fetchDeedInfo = useCallback( + async (id: number) => { + const resp = await httpClient.get(`/api/deed-info/${id}?chainId=${chainId}`); + setErrorCode(undefined); + if (resp?.status === 200) { + setInitialData(resp.value); + setDeedInfo(resp.value); + } else { + setErrorCode(resp?.status === 404 ? "notFound" : "unauthorized"); + } + setIsLoading(false); + }, + [id, chainId], + ); const handleSubmit = async () => { if (!validate()) return; if (id) { if (initialData) { - await writeDeedNftUpdateInfoAsync(formData, initialData, +id); + await writeDeedNftUpdateInfoAsync(deedInfo, initialData, +id); } } else { - await writeDeedNftMintAsync(formData); + await writeDeedNftMintAsync(deedInfo); } }; @@ -159,36 +175,36 @@ const RegistrationForm: NextPage = () => { }; const validate = () => { - if (!formData.ownerInformation.ids && !isDev()) { + if (!deedInfo.ownerInformation.ids && !isDev()) { notification.error("Owner Information ids is required", { duration: 3000 }); return false; } - if (!formData.ownerInformation.articleIncorporation && !isDev()) { + if (!deedInfo.ownerInformation.articleIncorporation && !isDev()) { notification.error("Owner Information articleIncorporation is required", { duration: 3000 }); return false; } - if (!formData.propertyDetails.propertyDeedOrTitle && !isDev()) { + if (!deedInfo.propertyDetails.propertyDeedOrTitle && !isDev()) { notification.error("Property details Deed or Title is required", { duration: 3000 }); return false; } - for (const field of Object.values(formData.ownerInformation)) { + for (const field of Object.values(deedInfo.ownerInformation)) { if (field instanceof File && field.size / 1024 > 10000) { notification.error(`${field.name} is too big. Max size is 10mb`, { duration: 3000 }); return false; } } - for (const field of Object.values(formData.propertyDetails)) { + for (const field of Object.values(deedInfo.propertyDetails)) { if (field instanceof File && field.size / 1024 > 10000) { notification.error(`${field.name} is too big. Max size is 10mb`, { duration: 3000 }); return false; } } - for (const field of Object.values(formData.otherInformation)) { + for (const field of Object.values(deedInfo.otherInformation)) { if (field instanceof File && field.size / 1024 > 10000) { notification.error(`${field.name} is too big. Max size is 10mb`); return false; @@ -250,10 +266,10 @@ const RegistrationForm: NextPage = () => {
- - - - + + + +
@@ -267,21 +283,68 @@ const RegistrationForm: NextPage = () => {
- {isValidator && !isOwner && id && ( - - )} - {!id && ( + {id ? ( + <> + {isOwner && ( +
+ Status:{" "} + + {deedInfo.isValidated ? "Verified" : "Waiting for validation"} + +
+ )} + {isValidator && !isOwner && ( + <> +
+
Payment information:
+
    +
  • +
    Type:
    + {deedInfo.paymentInformation.paymentType === "crypto" ? ( +
    + + Crypto +
    + ) : ( +
    + + Fiat +
    + )} +
  • + {deedInfo.paymentInformation.paymentType === "crypto" && ( + <> +
  • +
    Coin:
    +
    +
  • +
  • +
    Transaction:
    + +
  • + + )} +
+
+ + + )} + {isOwner && ( + + )} + + ) : ( )} - {isOwner && id && ( - - )}
diff --git a/packages/nextjs/services/jwt-util.ts b/packages/nextjs/services/jwt-util.ts new file mode 100644 index 00000000..baf31f35 --- /dev/null +++ b/packages/nextjs/services/jwt-util.ts @@ -0,0 +1,10 @@ +import { verify } from "jsonwebtoken"; + +export const jwtDecode = (jwtToken: string): JwtPayload => { + const publicKey = process.env.NEXT_DYNAMIC_PUBLIC_KEY!; + + const decoded = verify(jwtToken, publicKey, { + algorithms: ["RS256"], + }); + return decoded as JwtPayload; +}; diff --git a/packages/nextjs/services/web3/wagmiConfig.tsx b/packages/nextjs/services/web3/wagmiConfig.tsx index 240aea0f..cd672f0a 100644 --- a/packages/nextjs/services/web3/wagmiConfig.tsx +++ b/packages/nextjs/services/web3/wagmiConfig.tsx @@ -1,8 +1,8 @@ -import { createConfig } from "wagmi"; -import { appChains, wagmiConnectors } from "~~/services/web3/wagmiConnectors"; +// import { createConfig } from "wagmi"; +// import { appChains, wagmiConnectors } from "~~/services/web3/wagmiConnectors"; -export const wagmiConfig = createConfig({ - autoConnect: false, - connectors: wagmiConnectors, - publicClient: appChains.publicClient, -}); +// export const wagmiConfig = createConfig({ +// autoConnect: false, +// connectors: wagmiConnectors, +// publicClient: appChains.publicClient, +// }); diff --git a/packages/nextjs/services/web3/wagmiConnectors.tsx b/packages/nextjs/services/web3/wagmiConnectors.tsx index 8d69303b..bb09c29c 100644 --- a/packages/nextjs/services/web3/wagmiConnectors.tsx +++ b/packages/nextjs/services/web3/wagmiConnectors.tsx @@ -1,78 +1,77 @@ -import { connectorsForWallets } from "@rainbow-me/rainbowkit"; -import { - braveWallet, - coinbaseWallet, - ledgerWallet, - metaMaskWallet, - rainbowWallet, - safeWallet, - walletConnectWallet, -} from "@rainbow-me/rainbowkit/wallets"; -import * as chains from "viem/chains"; -import { configureChains } from "wagmi"; -import { alchemyProvider } from "wagmi/providers/alchemy"; -import { publicProvider } from "wagmi/providers/public"; -import scaffoldConfig from "~~/scaffold.config"; -import { burnerWalletConfig } from "~~/services/web3/wagmi-burner/burnerWalletConfig"; -import { getTargetNetwork } from "~~/utils/scaffold-eth"; +// import { +// braveWallet, +// coinbaseWallet, +// ledgerWallet, +// metaMaskWallet, +// rainbowWallet, +// safeWallet, +// walletConnectWallet, +// } from "@rainbow-me/rainbowkit/wallets"; +// import * as chains from "viem/chains"; +// import { configureChains } from "wagmi"; +// import { alchemyProvider } from "wagmi/providers/alchemy"; +// import { publicProvider } from "wagmi/providers/public"; +// import scaffoldConfig from "~~/scaffold.config"; +// import { burnerWalletConfig } from "~~/services/web3/wagmi-burner/burnerWalletConfig"; +// import { getTargetNetwork } from "~~/utils/scaffold-eth"; -const configuredNetwork = getTargetNetwork(); -const { onlyLocalBurnerWallet } = scaffoldConfig; +// const configuredNetwork = getTargetNetwork(); +// const { onlyLocalBurnerWallet } = scaffoldConfig; -// We always want to have mainnet enabled (ENS resolution, ETH price, etc). But only once. -const enabledChains = - configuredNetwork.id === 1 ? [configuredNetwork] : [configuredNetwork, chains.mainnet]; +// // We always want to have mainnet enabled (ENS resolution, ETH price, etc). But only once. +// const enabledChains = +// configuredNetwork.id === 1 ? [configuredNetwork] : [configuredNetwork, chains.mainnet]; -/** - * Chains for the app - */ -export const appChains = configureChains( - enabledChains, - [ - alchemyProvider({ - apiKey: scaffoldConfig.alchemyApiKey, - }), - publicProvider(), - ], - { - // We might not need this checkout https://github.com/scaffold-eth/scaffold-eth-2/pull/45#discussion_r1024496359, will test and remove this before merging - stallTimeout: 3_000, - // Sets pollingInterval if using chain's other than local hardhat chain - ...(configuredNetwork.id !== chains.hardhat.id - ? { - pollingInterval: scaffoldConfig.pollingInterval, - } - : {}), - }, -); +// /** +// * Chains for the app +// */ +// export const appChains = configureChains( +// enabledChains, +// [ +// alchemyProvider({ +// apiKey: scaffoldConfig.alchemyApiKey, +// }), +// publicProvider(), +// ], +// { +// // We might not need this checkout https://github.com/scaffold-eth/scaffold-eth-2/pull/45#discussion_r1024496359, will test and remove this before merging +// stallTimeout: 3_000, +// // Sets pollingInterval if using chain's other than local hardhat chain +// ...(configuredNetwork.id !== chains.hardhat.id +// ? { +// pollingInterval: scaffoldConfig.pollingInterval, +// } +// : {}), +// }, +// ); -const walletsOptions = { - chains: appChains.chains, - projectId: scaffoldConfig.walletConnectProjectId, -}; -const wallets = [ - metaMaskWallet({ ...walletsOptions, shimDisconnect: true }), - walletConnectWallet(walletsOptions), - ledgerWallet(walletsOptions), - braveWallet(walletsOptions), - coinbaseWallet({ ...walletsOptions, appName: "scaffold-eth-2" }), - rainbowWallet(walletsOptions), - ...(configuredNetwork.id === chains.hardhat.id || !onlyLocalBurnerWallet - ? [burnerWalletConfig({ chains: [appChains.chains[0]] })] - : []), - safeWallet({ - ...walletsOptions, - debug: false, - allowedDomains: [/gnosis-safe.io$/, /app.safe.global$/], - }), -]; +// const walletsOptions = { +// chains: appChains.chains, +// projectId: scaffoldConfig.walletConnectProjectId, +// }; +// const wallets = [ +// metaMaskWallet({ ...walletsOptions, shimDisconnect: true }), +// walletConnectWallet(walletsOptions), +// ledgerWallet(walletsOptions), +// braveWallet(walletsOptions), +// coinbaseWallet({ ...walletsOptions, appName: "scaffold-eth-2" }), +// rainbowWallet(walletsOptions), +// ...(configuredNetwork.id === chains.hardhat.id || !onlyLocalBurnerWallet +// ? [burnerWalletConfig({ chains: [appChains.chains[0]] })] +// : []), +// safeWallet({ +// ...walletsOptions, +// debug: false, +// allowedDomains: [/gnosis-safe.io$/, /app.safe.global$/], +// }), +// ]; -/** - * wagmi connectors for the wagmi context - */ -export const wagmiConnectors = connectorsForWallets([ - { - groupName: "Supported Wallets", - wallets, - }, -]); +// /** +// * wagmi connectors for the wagmi context +// */ +// export const wagmiConnectors = connectorsForWallets([ +// { +// groupName: "Supported Wallets", +// wallets, +// }, +// ]); diff --git a/packages/nextjs/utils/scaffold-eth/networks.ts b/packages/nextjs/utils/scaffold-eth/networks.ts index 6b66a1e3..6e84d75a 100644 --- a/packages/nextjs/utils/scaffold-eth/networks.ts +++ b/packages/nextjs/utils/scaffold-eth/networks.ts @@ -6,53 +6,111 @@ export interface TChainAttributes { color: string | [string, string]; // Used to fetch price by providing mainnet token address // for networks having native currency other than ETH - nativeCurrencyTokenAddress?: string; + nativeCurrencyTokenAddress: string; + stableCoinAddress: string; + storageWalletAddress: string; + deedMintingFee: bigint; + blockExplorer?: string; } export const NETWORKS_EXTRA_DATA: Record = { [chains.hardhat.id]: { color: "#b8af0c", + nativeCurrencyTokenAddress: "0x0000000000", + storageWalletAddress: "0x91B0d67D3F47A30FBEeB159E67209Ad6cb2cE22E", + deedMintingFee: BigInt(0), + stableCoinAddress: "0x0000000000", }, [chains.mainnet.id]: { color: "#ff8b9e", + nativeCurrencyTokenAddress: "0x0000000000", + storageWalletAddress: "0x91B0d67D3F47A30FBEeB159E67209Ad6cb2cE22E", + deedMintingFee: BigInt(0), + stableCoinAddress: "0x0000000000", }, [chains.sepolia.id]: { color: ["#5f4bb6", "#87ff65"], + nativeCurrencyTokenAddress: "0x0000000000", + storageWalletAddress: "0x91B0d67D3F47A30FBEeB159E67209Ad6cb2cE22E", + deedMintingFee: BigInt(0), + stableCoinAddress: "0x0000000000", }, [chains.goerli.id]: { color: "#0975F6", + nativeCurrencyTokenAddress: "0xdc31Ee1784292379Fbb2964b3B9C4124D8F89C60", + storageWalletAddress: "0x52e6102B7C22eeC7A68B11Dd71faC7D6D9AEcf50", + deedMintingFee: BigInt(0), + stableCoinAddress: "0xdc31Ee1784292379Fbb2964b3B9C4124D8F89C60", }, [chains.gnosis.id]: { color: "#48a9a6", + nativeCurrencyTokenAddress: "0x0000000000", + storageWalletAddress: "0x91B0d67D3F47A30FBEeB159E67209Ad6cb2cE22E", + deedMintingFee: BigInt(0), + stableCoinAddress: "0x0000000000", }, [chains.polygon.id]: { color: "#2bbdf7", nativeCurrencyTokenAddress: "0x7D1AfA7B718fb893dB30A3aBc0Cfc608AaCfeBB0", + storageWalletAddress: "0x91B0d67D3F47A30FBEeB159E67209Ad6cb2cE22E", + deedMintingFee: BigInt(0), + stableCoinAddress: "0x0000000000", }, [chains.polygonMumbai.id]: { color: "#92D9FA", nativeCurrencyTokenAddress: "0x7D1AfA7B718fb893dB30A3aBc0Cfc608AaCfeBB0", + storageWalletAddress: "0x91B0d67D3F47A30FBEeB159E67209Ad6cb2cE22E", + deedMintingFee: BigInt(0), + stableCoinAddress: "0x0000000000", }, [chains.optimismGoerli.id]: { color: "#f01a37", + nativeCurrencyTokenAddress: "0x0000000000", + storageWalletAddress: "0x91B0d67D3F47A30FBEeB159E67209Ad6cb2cE22E", + deedMintingFee: BigInt(0), + stableCoinAddress: "0x0000000000", }, [chains.optimism.id]: { color: "#f01a37", + nativeCurrencyTokenAddress: "0x0000000000", + storageWalletAddress: "0x91B0d67D3F47A30FBEeB159E67209Ad6cb2cE22E", + deedMintingFee: BigInt(0), + stableCoinAddress: "0x0000000000", }, [chains.arbitrumGoerli.id]: { color: "#28a0f0", + nativeCurrencyTokenAddress: "0x0000000000", + storageWalletAddress: "0x91B0d67D3F47A30FBEeB159E67209Ad6cb2cE22E", + deedMintingFee: BigInt(0), + stableCoinAddress: "0x0000000000", }, [chains.arbitrum.id]: { color: "#28a0f0", + nativeCurrencyTokenAddress: "0x0000000000", + storageWalletAddress: "0x91B0d67D3F47A30FBEeB159E67209Ad6cb2cE22E", + deedMintingFee: BigInt(0), + stableCoinAddress: "0x0000000000", }, [chains.fantom.id]: { color: "#1969ff", + nativeCurrencyTokenAddress: "0x0000000000", + storageWalletAddress: "0x91B0d67D3F47A30FBEeB159E67209Ad6cb2cE22E", + deedMintingFee: BigInt(0), + stableCoinAddress: "0x0000000000", }, [chains.fantomTestnet.id]: { color: "#1969ff", + nativeCurrencyTokenAddress: "0x0000000000", + storageWalletAddress: "0x91B0d67D3F47A30FBEeB159E67209Ad6cb2cE22E", + deedMintingFee: BigInt(0), + stableCoinAddress: "0x0000000000", }, [chains.scrollSepolia.id]: { color: "#fbebd4", + nativeCurrencyTokenAddress: "0x0000000000", + storageWalletAddress: "0x91B0d67D3F47A30FBEeB159E67209Ad6cb2cE22E", + deedMintingFee: BigInt(0), + stableCoinAddress: "0x0000000000", }, }; @@ -62,7 +120,10 @@ export const NETWORKS_EXTRA_DATA: Record = { * @param txnHash * @dev returns empty string if the network is localChain */ -export function getBlockExplorerTxLink(chainId: number, txnHash: string) { +export function getBlockExplorerTxLink(txnHash: string, chainId?: number) { + if (!chainId) { + chainId = getTargetNetwork().id; + } const chainNames = Object.keys(chains); const targetChainArr = chainNames.filter(chainName => { @@ -91,7 +152,10 @@ export function getBlockExplorerTxLink(chainId: number, txnHash: string) { * @param address * @returns block explorer address URL and etherscan URL if block explorer URL is not present for wagmi network */ -export function getBlockExplorerAddressLink(network: chains.Chain, address: string) { +export function getBlockExplorerAddressLink(address: string, network?: chains.Chain) { + if (!network) { + network = getTargetNetwork(); + } const blockExplorerBaseURL = network.blockExplorers?.default?.url; if (network.id === chains.hardhat.id) { return `/blockexplorer/address/${address}`; diff --git a/yarn.lock b/yarn.lock index c36bc7d9..be7532c7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -666,13 +666,6 @@ __metadata: languageName: node linkType: hard -"@emotion/hash@npm:^0.8.0": - version: 0.8.0 - resolution: "@emotion/hash@npm:0.8.0" - checksum: 4b35d88a97e67275c1d990c96d3b0450451d089d1508619488fc0acb882cb1ac91e93246d471346ebd1b5402215941ef4162efe5b51534859b39d8b3a0e3ffaa - languageName: node - linkType: hard - "@eslint-community/eslint-utils@npm:^4.2.0, @eslint-community/eslint-utils@npm:^4.4.0": version: 4.4.0 resolution: "@eslint-community/eslint-utils@npm:4.4.0" @@ -2730,26 +2723,6 @@ __metadata: languageName: node linkType: hard -"@rainbow-me/rainbowkit@npm:1.1.2": - version: 1.1.2 - resolution: "@rainbow-me/rainbowkit@npm:1.1.2" - dependencies: - "@vanilla-extract/css": 1.9.1 - "@vanilla-extract/dynamic": 2.0.2 - "@vanilla-extract/sprinkles": 1.5.0 - clsx: 1.1.1 - i18n-js: ^4.3.2 - qrcode: 1.5.0 - react-remove-scroll: 2.5.4 - peerDependencies: - react: ">=17" - react-dom: ">=17" - viem: ~0.3.19 || ^1.0.0 - wagmi: ~1.0.1 || ~1.1.0 || ~1.2.0 || ~1.3.0 || ~1.4.0 - checksum: 54087b6991b8bd058a653f31f7067f88f9122895d6b11f3280b7b45135ca498b928e11b2b11fdee509d9d919931fe5df03006e29c7af06b4f3927cd1f2d1c431 - languageName: node - linkType: hard - "@react-leaflet/core@npm:^2.1.0": version: 2.1.0 resolution: "@react-leaflet/core@npm:2.1.0" @@ -2899,9 +2872,9 @@ __metadata: "@heroicons/react": ^2.0.11 "@next/font": ^13.5.3 "@pinata/sdk": ^2.1.0 - "@rainbow-me/rainbowkit": 1.1.2 "@trivago/prettier-plugin-sort-imports": ^4.1.1 "@types/formidable": ^3 + "@types/jsonwebtoken": ^9 "@types/leaflet": ^1.9.4 "@types/lodash-es": ^4 "@types/mime": ^3 @@ -2927,7 +2900,7 @@ __metadata: eslint-plugin-prettier: ^4.2.1 finity-ui: ^0.0.2 formidable: ^3.5.1 - jwt-decode: ^4.0.0 + jsonwebtoken: ^9.0.2 leaflet: ^1.9.4 lodash-es: ^4.17.21 next: ^13.1.6 @@ -3733,6 +3706,15 @@ __metadata: languageName: node linkType: hard +"@types/jsonwebtoken@npm:^9": + version: 9.0.5 + resolution: "@types/jsonwebtoken@npm:9.0.5" + dependencies: + "@types/node": "*" + checksum: 07ab6fee602e5bd3fb5c6dfe4ec400769dc20f1d7fce901feecb4c3af5f5f08323b03ea55de3e49b1aa41e171a59008f6f4318738a735588c5268a63eba25337 + languageName: node + linkType: hard + "@types/leaflet@npm:^1.9.4": version: 1.9.4 resolution: "@types/leaflet@npm:1.9.4" @@ -4451,50 +4433,6 @@ __metadata: languageName: node linkType: hard -"@vanilla-extract/css@npm:1.9.1": - version: 1.9.1 - resolution: "@vanilla-extract/css@npm:1.9.1" - dependencies: - "@emotion/hash": ^0.8.0 - "@vanilla-extract/private": ^1.0.3 - ahocorasick: 1.0.2 - chalk: ^4.1.1 - css-what: ^5.0.1 - cssesc: ^3.0.0 - csstype: ^3.0.7 - deep-object-diff: ^1.1.0 - deepmerge: ^4.2.2 - media-query-parser: ^2.0.2 - outdent: ^0.8.0 - checksum: 91127d8e2eaaf521b155a39fb6a93e0fbfe5ddd5a8bdf1c732aba278cfdb9505cba24c755a982bc47682b9ff582a06d11e51e6f8d810404164ba098799ce6800 - languageName: node - linkType: hard - -"@vanilla-extract/dynamic@npm:2.0.2": - version: 2.0.2 - resolution: "@vanilla-extract/dynamic@npm:2.0.2" - dependencies: - "@vanilla-extract/private": ^1.0.3 - checksum: c6f22606bce094a5682c6d842be6d6965b9448f8973eaabdaa7a7438146458c22490c1c63345f08d2226f1c95ac20731835a5140c2c18646b2c1287b65607b84 - languageName: node - linkType: hard - -"@vanilla-extract/private@npm:^1.0.3": - version: 1.0.3 - resolution: "@vanilla-extract/private@npm:1.0.3" - checksum: 866a71ba6804edeb0735684e7723ba78f5cf0bb40d4fb538fe6bf7d73928099e341312337b2a510ac0ce96ff8a4b39eb7f7a5fad0c842532353dd20e7278f29b - languageName: node - linkType: hard - -"@vanilla-extract/sprinkles@npm:1.5.0": - version: 1.5.0 - resolution: "@vanilla-extract/sprinkles@npm:1.5.0" - peerDependencies: - "@vanilla-extract/css": ^1.0.0 - checksum: 522b96afe856a72d76072ab41453edc35117772a6ac829c8a5ad09cddd69152e152b1cbda0b4344d50dbde59d0effa39301beb7acf319ef88f485966c89c80fd - languageName: node - linkType: hard - "@vascosantos/moving-average@npm:^1.1.0": version: 1.1.0 resolution: "@vascosantos/moving-average@npm:1.1.0" @@ -5676,13 +5614,6 @@ __metadata: languageName: node linkType: hard -"ahocorasick@npm:1.0.2": - version: 1.0.2 - resolution: "ahocorasick@npm:1.0.2" - checksum: a13ce4403554ae782cf5e28d468a732acf1fd3d0bff251f5dcfddfa5497b6cc343948d69cd94dfdbe8d4dfdb81e2b34cb1c92079e6301f38b0143d314fb95bd6 - languageName: node - linkType: hard - "ajv-keywords@npm:^3.5.2": version: 3.5.2 resolution: "ajv-keywords@npm:3.5.2" @@ -6344,7 +6275,7 @@ __metadata: languageName: node linkType: hard -"bignumber.js@npm:*, bignumber.js@npm:^9.0.0": +"bignumber.js@npm:^9.0.0": version: 9.1.2 resolution: "bignumber.js@npm:9.1.2" checksum: 582c03af77ec9cb0ebd682a373ee6c66475db94a4325f92299621d544aa4bd45cb45fd60001610e94aef8ae98a0905fa538241d9638d4422d57abbeeac6fadaf @@ -6637,6 +6568,13 @@ __metadata: languageName: node linkType: hard +"buffer-equal-constant-time@npm:1.0.1": + version: 1.0.1 + resolution: "buffer-equal-constant-time@npm:1.0.1" + checksum: 80bb945f5d782a56f374b292770901065bad21420e34936ecbe949e57724b4a13874f735850dd1cc61f078773c4fb5493a41391e7bda40d1fa388d6bd80daaab + languageName: node + linkType: hard + "buffer-fill@npm:^1.0.0": version: 1.0.0 resolution: "buffer-fill@npm:1.0.0" @@ -6916,7 +6854,7 @@ __metadata: languageName: node linkType: hard -"chalk@npm:4.1.2, chalk@npm:^4, chalk@npm:^4.0.0, chalk@npm:^4.0.2, chalk@npm:^4.1.0, chalk@npm:^4.1.1, chalk@npm:^4.1.2": +"chalk@npm:4.1.2, chalk@npm:^4, chalk@npm:^4.0.0, chalk@npm:^4.0.2, chalk@npm:^4.1.0, chalk@npm:^4.1.2": version: 4.1.2 resolution: "chalk@npm:4.1.2" dependencies: @@ -7231,13 +7169,6 @@ __metadata: languageName: node linkType: hard -"clsx@npm:1.1.1": - version: 1.1.1 - resolution: "clsx@npm:1.1.1" - checksum: ff052650329773b9b245177305fc4c4dc3129f7b2be84af4f58dc5defa99538c61d4207be7419405a5f8f3d92007c954f4daba5a7b74e563d5de71c28c830063 - languageName: node - linkType: hard - "clsx@npm:^1.1.0": version: 1.2.1 resolution: "clsx@npm:1.2.1" @@ -7610,13 +7541,6 @@ __metadata: languageName: node linkType: hard -"css-what@npm:^5.0.1": - version: 5.1.0 - resolution: "css-what@npm:5.1.0" - checksum: 0b75d1bac95c885c168573c85744a6c6843d8c33345f54f717218b37ea6296b0e99bb12105930ea170fd4a921990392a7c790c16c585c1d8960c49e2b7ec39f7 - languageName: node - linkType: hard - "cssesc@npm:^3.0.0": version: 3.0.0 resolution: "cssesc@npm:3.0.0" @@ -7626,7 +7550,7 @@ __metadata: languageName: node linkType: hard -"csstype@npm:^3.0.2, csstype@npm:^3.0.7": +"csstype@npm:^3.0.2": version: 3.1.1 resolution: "csstype@npm:3.1.1" checksum: 1f7b4f5fdd955b7444b18ebdddf3f5c699159f13e9cf8ac9027ae4a60ae226aef9bbb14a6e12ca7dba3358b007cee6354b116e720262867c398de6c955ea451d @@ -7811,13 +7735,6 @@ __metadata: languageName: node linkType: hard -"deep-object-diff@npm:^1.1.0": - version: 1.1.7 - resolution: "deep-object-diff@npm:1.1.7" - checksum: 543fb1ae87b138ad260691e6949e72bf7dc144825084b7ad1886bb725d2ace1c19ed1ef1280f1116243e86bf2c6b942f45c670958b1468f644613f28c5dc97ea - languageName: node - linkType: hard - "deepmerge@npm:^2.1.1": version: 2.2.1 resolution: "deepmerge@npm:2.2.1" @@ -7825,13 +7742,6 @@ __metadata: languageName: node linkType: hard -"deepmerge@npm:^4.2.2": - version: 4.2.2 - resolution: "deepmerge@npm:4.2.2" - checksum: a8c43a1ed8d6d1ed2b5bf569fa4c8eb9f0924034baf75d5d406e47e157a451075c4db353efea7b6bcc56ec48116a8ce72fccf867b6e078e7c561904b5897530b - languageName: node - linkType: hard - "defaults@npm:^1.0.3": version: 1.0.4 resolution: "defaults@npm:1.0.4" @@ -8157,6 +8067,15 @@ __metadata: languageName: node linkType: hard +"ecdsa-sig-formatter@npm:1.0.11": + version: 1.0.11 + resolution: "ecdsa-sig-formatter@npm:1.0.11" + dependencies: + safe-buffer: ^5.0.1 + checksum: 207f9ab1c2669b8e65540bce29506134613dd5f122cccf1e6a560f4d63f2732d427d938f8481df175505aad94583bcb32c688737bb39a6df0625f903d6d93c03 + languageName: node + linkType: hard + "edge-runtime@npm:2.0.0": version: 2.0.0 resolution: "edge-runtime@npm:2.0.0" @@ -10271,13 +10190,6 @@ __metadata: languageName: node linkType: hard -"get-nonce@npm:^1.0.0": - version: 1.0.1 - resolution: "get-nonce@npm:1.0.1" - checksum: e2614e43b4694c78277bb61b0f04583d45786881289285c73770b07ded246a98be7e1f78b940c80cbe6f2b07f55f0b724e6db6fd6f1bcbd1e8bdac16521074ed - languageName: node - linkType: hard - "get-package-type@npm:^0.1.0": version: 0.1.0 resolution: "get-package-type@npm:0.1.0" @@ -11137,17 +11049,6 @@ __metadata: languageName: node linkType: hard -"i18n-js@npm:^4.3.2": - version: 4.3.2 - resolution: "i18n-js@npm:4.3.2" - dependencies: - bignumber.js: "*" - lodash: "*" - make-plural: "*" - checksum: 08a051dba75d93447e2021c1feb92f34c9034b5a818957885ea19ac58954d764c848c4deaaf46ada3e15d51f61ad9f7e0bf4ddffa3c765871ff1b26638ca0a8f - languageName: node - linkType: hard - "i18next@npm:^23.4.6": version: 23.7.6 resolution: "i18next@npm:23.7.6" @@ -11380,15 +11281,6 @@ __metadata: languageName: node linkType: hard -"invariant@npm:^2.2.4": - version: 2.2.4 - resolution: "invariant@npm:2.2.4" - dependencies: - loose-envify: ^1.0.0 - checksum: cc3182d793aad82a8d1f0af697b462939cb46066ec48bbf1707c150ad5fad6406137e91a262022c269702e01621f35ef60269f6c0d7fd178487959809acdfb14 - languageName: node - linkType: hard - "io-ts@npm:1.10.4": version: 1.10.4 resolution: "io-ts@npm:1.10.4" @@ -12439,6 +12331,24 @@ __metadata: languageName: node linkType: hard +"jsonwebtoken@npm:^9.0.2": + version: 9.0.2 + resolution: "jsonwebtoken@npm:9.0.2" + dependencies: + jws: ^3.2.2 + lodash.includes: ^4.3.0 + lodash.isboolean: ^3.0.3 + lodash.isinteger: ^4.0.4 + lodash.isnumber: ^3.0.3 + lodash.isplainobject: ^4.0.6 + lodash.isstring: ^4.0.1 + lodash.once: ^4.0.0 + ms: ^2.1.1 + semver: ^7.5.4 + checksum: fc739a6a8b33f1974f9772dca7f8493ca8df4cc31c5a09dcfdb7cff77447dcf22f4236fb2774ef3fe50df0abeb8e1c6f4c41eba82f500a804ab101e2fbc9d61a + languageName: node + linkType: hard + "jsprim@npm:^1.2.2": version: 1.4.2 resolution: "jsprim@npm:1.4.2" @@ -12468,10 +12378,24 @@ __metadata: languageName: node linkType: hard -"jwt-decode@npm:^4.0.0": - version: 4.0.0 - resolution: "jwt-decode@npm:4.0.0" - checksum: 390e2edcb31a92e86c8cbdd1edeea4c0d62acd371f8a8f0a8878e499390c0ecf4c658b365c4e941e4ef37d0170e4ca650aaa49f99a45c0b9695a235b210154b0 +"jwa@npm:^1.4.1": + version: 1.4.1 + resolution: "jwa@npm:1.4.1" + dependencies: + buffer-equal-constant-time: 1.0.1 + ecdsa-sig-formatter: 1.0.11 + safe-buffer: ^5.0.1 + checksum: ff30ea7c2dcc61f3ed2098d868bf89d43701605090c5b21b5544b512843ec6fd9e028381a4dda466cbcdb885c2d1150f7c62e7168394ee07941b4098e1035e2f + languageName: node + linkType: hard + +"jws@npm:^3.2.2": + version: 3.2.2 + resolution: "jws@npm:3.2.2" + dependencies: + jwa: ^1.4.1 + safe-buffer: ^5.0.1 + checksum: f0213fe5b79344c56cd443428d8f65c16bf842dc8cb8f5aed693e1e91d79c20741663ad6eff07a6d2c433d1831acc9814e8d7bada6a0471fbb91d09ceb2bf5c2 languageName: node linkType: hard @@ -12767,6 +12691,20 @@ __metadata: languageName: node linkType: hard +"lodash.includes@npm:^4.3.0": + version: 4.3.0 + resolution: "lodash.includes@npm:4.3.0" + checksum: 71092c130515a67ab3bd928f57f6018434797c94def7f46aafa417771e455ce3a4834889f4267b17887d7f75297dfabd96231bf704fd2b8c5096dc4a913568b6 + languageName: node + linkType: hard + +"lodash.isboolean@npm:^3.0.3": + version: 3.0.3 + resolution: "lodash.isboolean@npm:3.0.3" + checksum: b70068b4a8b8837912b54052557b21fc4774174e3512ed3c5b94621e5aff5eb6c68089d0a386b7e801d679cd105d2e35417978a5e99071750aa2ed90bffd0250 + languageName: node + linkType: hard + "lodash.isequal@npm:4.5.0": version: 4.5.0 resolution: "lodash.isequal@npm:4.5.0" @@ -12774,6 +12712,34 @@ __metadata: languageName: node linkType: hard +"lodash.isinteger@npm:^4.0.4": + version: 4.0.4 + resolution: "lodash.isinteger@npm:4.0.4" + checksum: 6034821b3fc61a2ffc34e7d5644bb50c5fd8f1c0121c554c21ac271911ee0c0502274852845005f8651d51e199ee2e0cfebfe40aaa49c7fe617f603a8a0b1691 + languageName: node + linkType: hard + +"lodash.isnumber@npm:^3.0.3": + version: 3.0.3 + resolution: "lodash.isnumber@npm:3.0.3" + checksum: 913784275b565346255e6ae6a6e30b760a0da70abc29f3e1f409081585875105138cda4a429ff02577e1bc0a7ae2a90e0a3079a37f3a04c3d6c5aaa532f4cab2 + languageName: node + linkType: hard + +"lodash.isplainobject@npm:^4.0.6": + version: 4.0.6 + resolution: "lodash.isplainobject@npm:4.0.6" + checksum: 29c6351f281e0d9a1d58f1a4c8f4400924b4c79f18dfc4613624d7d54784df07efaff97c1ff2659f3e085ecf4fff493300adc4837553104cef2634110b0d5337 + languageName: node + linkType: hard + +"lodash.isstring@npm:^4.0.1": + version: 4.0.1 + resolution: "lodash.isstring@npm:4.0.1" + checksum: eaac87ae9636848af08021083d796e2eea3d02e80082ab8a9955309569cb3a463ce97fd281d7dc119e402b2e7d8c54a23914b15d2fc7fff56461511dc8937ba0 + languageName: node + linkType: hard + "lodash.kebabcase@npm:^4.1.1": version: 4.1.1 resolution: "lodash.kebabcase@npm:4.1.1" @@ -12802,6 +12768,13 @@ __metadata: languageName: node linkType: hard +"lodash.once@npm:^4.0.0": + version: 4.1.1 + resolution: "lodash.once@npm:4.1.1" + checksum: d768fa9f9b4e1dc6453be99b753906f58990e0c45e7b2ca5a3b40a33111e5d17f6edf2f768786e2716af90a8e78f8f91431ab8435f761fef00f9b0c256f6d245 + languageName: node + linkType: hard + "lodash.pad@npm:^4.5.1": version: 4.5.1 resolution: "lodash.pad@npm:4.5.1" @@ -12886,7 +12859,7 @@ __metadata: languageName: node linkType: hard -"lodash@npm:*, lodash@npm:^4.17.11, lodash@npm:^4.17.14, lodash@npm:^4.17.15, lodash@npm:^4.17.19, lodash@npm:^4.17.20, lodash@npm:^4.17.21": +"lodash@npm:^4.17.11, lodash@npm:^4.17.14, lodash@npm:^4.17.15, lodash@npm:^4.17.19, lodash@npm:^4.17.20, lodash@npm:^4.17.21": version: 4.17.21 resolution: "lodash@npm:4.17.21" checksum: eb835a2e51d381e561e508ce932ea50a8e5a68f4ebdd771ea240d3048244a8d13658acbd502cd4829768c56f2e16bdd4340b9ea141297d472517b83868e677f7 @@ -12938,7 +12911,7 @@ __metadata: languageName: node linkType: hard -"loose-envify@npm:^1.0.0, loose-envify@npm:^1.1.0, loose-envify@npm:^1.4.0": +"loose-envify@npm:^1.1.0, loose-envify@npm:^1.4.0": version: 1.4.0 resolution: "loose-envify@npm:1.4.0" dependencies: @@ -13081,13 +13054,6 @@ __metadata: languageName: node linkType: hard -"make-plural@npm:*": - version: 7.3.0 - resolution: "make-plural@npm:7.3.0" - checksum: bb39b4b77533f0d5fb94eec128340b54dda8c1707d6b0a98c148e5d7bc23094e123f88275a61573fa31dc2f5d7352215cee0df523cd69b5d8fcb3969a2bcf8f8 - languageName: node - linkType: hard - "markdown-table@npm:^1.1.3": version: 1.1.3 resolution: "markdown-table@npm:1.1.3" @@ -13131,15 +13097,6 @@ __metadata: languageName: node linkType: hard -"media-query-parser@npm:^2.0.2": - version: 2.0.2 - resolution: "media-query-parser@npm:2.0.2" - dependencies: - "@babel/runtime": ^7.12.5 - checksum: 8ef956d9e63fe6f4041988beda69843b3a6bb48228ea2923a066f6e7c8f7c5dba75fae357318c48a97ed5beae840b8425cb7e727fc1bb77acc65f2005f8945ab - languageName: node - linkType: hard - "memory-level@npm:^1.0.0": version: 1.0.0 resolution: "memory-level@npm:1.0.0" @@ -14540,13 +14497,6 @@ __metadata: languageName: node linkType: hard -"outdent@npm:^0.8.0": - version: 0.8.0 - resolution: "outdent@npm:0.8.0" - checksum: 72b7c1a287674317ea477999ec24e73a9eda21de35eb9429218f4a5bab899e964afaee7508265898118fee5cbee1d79397916b66dd8aeee285cd948ea5b1f562 - languageName: node - linkType: hard - "p-defer@npm:^3.0.0": version: 3.0.0 resolution: "p-defer@npm:3.0.0" @@ -15336,20 +15286,6 @@ __metadata: languageName: node linkType: hard -"qrcode@npm:1.5.0": - version: 1.5.0 - resolution: "qrcode@npm:1.5.0" - dependencies: - dijkstrajs: ^1.0.1 - encode-utf8: ^1.0.3 - pngjs: ^5.0.0 - yargs: ^15.3.1 - bin: - qrcode: bin/qrcode - checksum: a0857713d4390937900a2789d5a065700f7cf78cd760e773bf8524c0e907ff629db19c9bdd4210aac55b8eef53ec1c7bcaa2acf01f340ef049c53098388a45a0 - languageName: node - linkType: hard - "qrcode@npm:1.5.1, qrcode@npm:^1.5.1": version: 1.5.1 resolution: "qrcode@npm:1.5.1" @@ -15647,58 +15583,6 @@ __metadata: languageName: node linkType: hard -"react-remove-scroll-bar@npm:^2.3.3": - version: 2.3.3 - resolution: "react-remove-scroll-bar@npm:2.3.3" - dependencies: - react-style-singleton: ^2.2.1 - tslib: ^2.0.0 - peerDependencies: - "@types/react": ^16.8.0 || ^17.0.0 || ^18.0.0 - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: fc8c70014a473b12d4205071ad79bd3cfc6ded173c6589fe6baca01090729757f1ee9966278f16930f3b58029c6923e06d2e3193dcb878ecdcb4eb293b7b9bf4 - languageName: node - linkType: hard - -"react-remove-scroll@npm:2.5.4": - version: 2.5.4 - resolution: "react-remove-scroll@npm:2.5.4" - dependencies: - react-remove-scroll-bar: ^2.3.3 - react-style-singleton: ^2.2.1 - tslib: ^2.1.0 - use-callback-ref: ^1.3.0 - use-sidecar: ^1.1.2 - peerDependencies: - "@types/react": ^16.8.0 || ^17.0.0 || ^18.0.0 - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 01b0f65542a4c8803ee748b4e6cf2adad66d034e15fb72e8455773b0d7b178ec806b3194d74f412db7064670c45552cc666c04e9fb3b5d466dce5fb48e634825 - languageName: node - linkType: hard - -"react-style-singleton@npm:^2.2.1": - version: 2.2.1 - resolution: "react-style-singleton@npm:2.2.1" - dependencies: - get-nonce: ^1.0.0 - invariant: ^2.2.4 - tslib: ^2.0.0 - peerDependencies: - "@types/react": ^16.8.0 || ^17.0.0 || ^18.0.0 - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 7ee8ef3aab74c7ae1d70ff34a27643d11ba1a8d62d072c767827d9ff9a520905223e567002e0bf6c772929d8ea1c781a3ba0cc4a563e92b1e3dc2eaa817ecbe8 - languageName: node - linkType: hard - "react@npm:^18.2.0": version: 18.2.0 resolution: "react@npm:18.2.0"