### Development: Example API Request Source: https://github.com/quiknode-labs/qn-oss/blob/main/packages/libs/sdk/README.md An example of how to send a request to the SDK's API during development using curl. This assumes the example application is running locally. ```bash curl http://localhost:3333/api/nftsByAddress/0xbc08dadccc79c00587d7e6a75bb68ff5fd30f9e0 ``` -------------------------------- ### Quickstart: Get Block Number Source: https://github.com/quiknode-labs/qn-oss/blob/main/packages/libs/sdk/README.md Demonstrates how to initialize the Core SDK and fetch the current block number from QuickNode's services. Requires Node.js v16 or higher. ```typescript import Core from '@quicknode/sdk/core'; const core = new Core({ endpointUrl: 'replaceme' }); const blockNumber = core.client.getBlockNumber().then((response) => console.log(response)); ``` -------------------------------- ### TokenGate Example Usage Source: https://github.com/quiknode-labs/qn-oss/blob/main/packages/apps/examples/token-gate-example/src/index.html This snippet demonstrates how to use the TokenGate contract. It includes deploying the contract, setting up access control, and verifying token ownership for access. ```javascript const { ethers } = require("hardhat"); const { expect } = require("chai"); describe("TokenGate", function () { let TokenGate; let tokenGate; let owner; let addr1; let addr2; let mockToken; beforeEach(async function () { [owner, addr1, addr2] = await ethers.getSigners(); const MockToken = await ethers.getContractFactory("MockToken"); mockToken = await MockToken.deploy("Mock Token", "MTK"); await mockToken.deployed(); TokenGate = await ethers.getContractFactory("TokenGate"); tokenGate = await TokenGate.deploy(mockToken.address); await tokenGate.deployed(); // Mint tokens to addr1 and addr2 await mockToken.mint(addr1.address, ethers.utils.parseEther("100")); await mockToken.mint(addr2.address, ethers.utils.parseEther("50")); }); it("Should set the correct token address", async function () { expect(await tokenGate.token()).to.equal(mockToken.address); }); it("Should allow owner to set required token balance", async function () { const requiredBalance = ethers.utils.parseEther("75"); await tokenGate.setRequiredTokenBalance(requiredBalance); expect(await tokenGate.requiredTokenBalance()).to.equal(requiredBalance); }); it("Should revert if non-owner sets required token balance", async function () { const requiredBalance = ethers.utils.parseEther("75"); await expect(tokenGate.connect(addr1).setRequiredTokenBalance(requiredBalance)).to.be.revertedWith("Ownable: caller is not the owner"); }); it("Should grant access if user has enough tokens", async function () { const requiredBalance = ethers.utils.parseEther("75"); await tokenGate.setRequiredTokenBalance(requiredBalance); await mockToken.connect(addr1).approve(tokenGate.address, ethers.utils.parseEther("100")); await tokenGate.connect(addr1).grantAccess(); expect(await tokenGate.hasAccess(addr1.address)).to.be.true; }); it("Should revoke access if user does not have enough tokens", async function () { const requiredBalance = ethers.utils.parseEther("75"); await tokenGate.setRequiredTokenBalance(requiredBalance); await mockToken.connect(addr1).approve(tokenGate.address, ethers.utils.parseEther("100")); await tokenGate.connect(addr1).grantAccess(); expect(await tokenGate.hasAccess(addr1.address)).to.be.true; // Transfer tokens away from addr1 await mockToken.connect(addr1).transfer(addr2.address, ethers.utils.parseEther("30")); // Note: The contract checks balance on `hasAccess` call, so no explicit revoke needed if balance drops. // However, if there was a function to explicitly revoke, it would be tested here. expect(await tokenGate.hasAccess(addr1.address)).to.be.false; }); it("Should revert if user does not have enough tokens to grant access", async function () { const requiredBalance = ethers.utils.parseEther("75"); await tokenGate.setRequiredTokenBalance(requiredBalance); await mockToken.connect(addr2).approve(tokenGate.address, ethers.utils.parseEther("50")); // Only 50 tokens await expect(tokenGate.connect(addr2).grantAccess()).to.be.revertedWith("TokenGate: Insufficient token balance"); }); it("Should allow owner to revoke access", async function () { const requiredBalance = ethers.utils.parseEther("75"); await tokenGate.setRequiredTokenBalance(requiredBalance); await mockToken.connect(addr1).approve(tokenGate.address, ethers.utils.parseEther("100")); await tokenGate.connect(addr1).grantAccess(); expect(await tokenGate.hasAccess(addr1.address)).to.be.true; await tokenGate.connect(owner).revokeAccess(addr1.address); expect(await tokenGate.hasAccess(addr1.address)).to.be.false; }); it("Should revert if non-owner revokes access", async function () { const requiredBalance = ethers.utils.parseEther("75"); await tokenGate.setRequiredTokenBalance(requiredBalance); await mockToken.connect(addr1).approve(tokenGate.address, ethers.utils.parseEther("100")); await tokenGate.connect(addr1).grantAccess(); await expect(tokenGate.connect(addr1).revokeAccess(addr1.address)).to.be.revertedWith("Ownable: caller is not the owner"); }); }); // MockToken contract for testing purposes contract("MockToken", function (accounts) { const initialSupply = 1000000; const tokenName = "Mock Token"; const tokenSymbol = "MTK"; it("deployment should assign the total supply to the owner", async function () { const [owner] = await ethers.getSigners(); const MockToken = await ethers.getContractFactory("MockToken"); const mockToken = await MockToken.deploy(tokenName, tokenSymbol); await mockToken.deployed(); const ownerBalance = await mockToken.balanceOf(owner.address); expect(await mockToken.totalSupply()).to.equal(ownerBalance); }); it("should transfer tokens between accounts", async function () { const [owner, addr1] = await ethers.getSigners(); const MockToken = await ethers.getContractFactory("MockToken"); const mockToken = await MockToken.deploy(tokenName, tokenSymbol); await mockToken.deployed(); await mockToken.mint(addr1.address, 100); const addr1Balance = await mockToken.balanceOf(addr1.address); expect(addr1Balance).to.equal(100); const transferAmount = 50; await mockToken.transfer(owner.address, transferAmount); const ownerBalanceAfterTransfer = await mockToken.balanceOf(owner.address); expect(ownerBalanceAfterTransfer).to.equal(transferAmount); const addr1BalanceAfterTransfer = await mockToken.balanceOf(addr1.address); expect(addr1BalanceAfterTransfer).to.equal(addr1Balance.sub(transferAmount)); }); it("should approve and transfer from another account", async function () { const [owner, addr1, addr2] = await ethers.getSigners(); const MockToken = await ethers.getContractFactory("MockToken"); const mockToken = await MockToken.deploy(tokenName, tokenSymbol); await mockToken.deployed(); await mockToken.mint(addr1.address, 100); const transferAmount = 50; await mockToken.connect(addr1).approve(addr2.address, transferAmount); expect(await mockToken.allowance(addr1.address, addr2.address)).to.equal(transferAmount); await mockToken.connect(addr2).transferFrom(addr1.address, owner.address, transferAmount); expect(await mockToken.balanceOf(owner.address)).to.equal(transferAmount); expect(await mockToken.balanceOf(addr1.address)).to.equal(100 - transferAmount); expect(await mockToken.allowance(addr1.address, addr2.address)).to.equal(0); }); }); ``` -------------------------------- ### Installation Source: https://github.com/quiknode-labs/qn-oss/blob/main/packages/libs/ui/nft-react-hooks/README.md Install the @quicknode/icy-nft-hooks package using either yarn or npm. ```bash yarn add @quicknode/icy-nft-hooks ``` ```bash npm install @quicknode/icy-nft-hooks ``` -------------------------------- ### TokenGate Component Setup Source: https://github.com/quiknode-labs/qn-oss/blob/main/packages/libs/ui/token-gate/README.md Shows how to set up the `TokenGate` component with essential props like `buttonPrompt`, `appElement`, `quicknodeUrl`, and `nftContractAddress`. ```jsx ``` -------------------------------- ### TokenGatedRoute for Route Protection Source: https://github.com/quiknode-labs/qn-oss/blob/main/packages/libs/ui/token-gate/README.md Provides an example of using the `useTokenGate` hook with `react-router` to protect specific routes, redirecting unverified users to the homepage. ```jsx import { Navigate } from 'react-router-dom'; import { useTokenGate } from '@quicknode/token-gate'; const TokenGatedRoute = ({ children }: { children: any }) => { const isVerifed = useTokenGate(); if (!isVerifed) { // Navigate back to the homepage return ; } return children; }; // Use the TokenGatedRoute in the Routes } /> ; ``` -------------------------------- ### Use useTokenGate Hook Source: https://github.com/quiknode-labs/qn-oss/blob/main/packages/libs/ui/token-gate/README.md Illustrates how to use the `useTokenGate` hook to get the NFT verification status within your React application. ```javascript import { useTokenGate } from '@quicknode/token-gate'; const isVerified = useTokenGate(); ``` -------------------------------- ### UseNFTBalance Hook Source: https://github.com/quiknode-labs/qn-oss/blob/main/packages/apps/examples/nft-react-hooks/src/index.html A React Hook to fetch and manage an NFT balance for a given wallet address and contract address. It handles loading states and errors. ```javascript import { useState, useEffect } from 'react'; import { getNFTBalance } from '@quiknode/sdk'; function useNFTBalance(walletAddress, contractAddress) { const [balance, setBalance] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { const fetchBalance = async () => { setLoading(true); setError(null); try { const result = await getNFTBalance(walletAddress, contractAddress); setBalance(result); } catch (err) { setError(err); } finally { setLoading(false); } }; if (walletAddress && contractAddress) { fetchBalance(); } }, [walletAddress, contractAddress]); return { balance, loading, error }; } ``` -------------------------------- ### UseNFTMetadata Hook Source: https://github.com/quiknode-labs/qn-oss/blob/main/packages/apps/examples/nft-react-hooks/src/index.html A React Hook to fetch and manage metadata for a specific NFT, identified by its contract address and token ID. It includes loading and error handling. ```typescript import { useState, useEffect } from 'react'; import { getNFTMetadata } from '@quiknode/sdk'; interface NFTMetadata { name: string; description: string; image: string; attributes?: any[]; } function useNFTMetadata(contractAddress: string, tokenId: string): { metadata: NFTMetadata | null; loading: boolean; error: Error | null; } { const [metadata, setMetadata] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { const fetchMetadata = async () => { setLoading(true); setError(null); try { const result = await getNFTMetadata(contractAddress, tokenId); setMetadata(result); } catch (err: any) { setError(err); } finally { setLoading(false); } }; if (contractAddress && tokenId) { fetchMetadata(); } }, [contractAddress, tokenId]); return { metadata, loading, error }; } ``` -------------------------------- ### Linting: Run ESLint Source: https://github.com/quiknode-labs/qn-oss/blob/main/packages/libs/sdk/README.md Command to execute the SDK's linting process using ESLint. ```bash nx lint libs-sdk ``` -------------------------------- ### Testing: Run Jest Tests Source: https://github.com/quiknode-labs/qn-oss/blob/main/packages/libs/sdk/README.md Command to execute the SDK's tests using Jest. API responses are recorded with Polly.js. ```bash nx test libs-sdk ``` -------------------------------- ### Initialize IcyProvider Source: https://github.com/quiknode-labs/qn-oss/blob/main/packages/libs/ui/nft-react-hooks/README.md Wrap your React application with the `IcyProvider` component. An optional `apiKey` can be passed for increased rate limits. ```jsx import { IcyProvider } from '@quicknode/icy-nft-hooks'; function App() { return ...; } ``` ```jsx import { IcyProvider } from '@quicknode/icy-nft-hooks'; function App() { return ...; } ``` -------------------------------- ### Run Lint Source: https://github.com/quiknode-labs/qn-oss/blob/main/packages/libs/util/README.md Executes linting for the libs-util library using ESLint. ```bash nx lint libs-util ``` -------------------------------- ### Rollup Configuration Strategy Source: https://github.com/quiknode-labs/qn-oss/blob/main/tools/build-lib-nft-hooks/README.md Explains the approach to configuring Rollup, highlighting the preference for a data structure config similar to Apollo Client but the necessity of a JS function due to Nx integration. It details the limitations imposed by Nx regarding promises and the inability to return an array of configs directly. ```javascript /* Rollup configuration can be done with either a data structure, or a JS function. JS has limitations: https://www.rollupjs.org/guide/en/#differences-to-the-javascript-api Apollo client uses a data structure config: https://github.com/apollographql/apollo-client/blob/main/config/rollup.config.js It's preferable to copy the apollo technique, but we cannot because we require an initial config from Nx, which can only come through a JS function. Nx does not support a promise from this function, therefore we cannot directly use the rollup API: https://www.rollupjs.org/guide/en/#javascript-api Therefore we cannot return an array of configs from our JS function (which is what apollo does). */ ``` -------------------------------- ### Deployment Scripting Shorthand Source: https://github.com/quiknode-labs/qn-oss/blob/main/packages/libs/ui/nft-react-hooks/README.md Provides shorthand commands for building and serving the NFT hooks library using Yarn. ```bash yarn build:lib:nft:hooks ``` ```bash yarn serve:app:nft:hooks ``` -------------------------------- ### Import TokenGate Component Source: https://github.com/quiknode-labs/qn-oss/blob/main/packages/libs/ui/token-gate/README.md Demonstrates how to import the `TokenGate` component from the `@quicknode/token-gate` library. ```javascript import { TokenGate } from '@quicknode/token-gate'; ``` -------------------------------- ### Workaround for ESM and CommonJS Builds Source: https://github.com/quiknode-labs/qn-oss/blob/main/tools/build-lib-nft-hooks/README.md Details the workaround implemented to build for both ESM and CommonJS formats. This involves executing the build process twice, once for each format, and managing the output files to ensure compatibility. The `build-lib-nft-hooks.bash` script encapsulates this process. ```bash # The workaround is to run the build twice, once each for ESM and CommonJS. # Since Nx clears the package dist folder between builds, we preserve the `main.cjs` file # after the `cjs` build and copy it into the dist folder after running the `esm` format. # The shell script `build-lib-nft-hooks.bash` encapsulates the process. ``` -------------------------------- ### Run Unit Tests Source: https://github.com/quiknode-labs/qn-oss/blob/main/packages/libs/util/README.md Executes unit tests for the libs-util library using Jest. ```bash nx test libs-util ``` -------------------------------- ### QuickNode SDK - GraphQL API Wrapper Source: https://github.com/quiknode-labs/qn-oss/blob/main/README.md A framework-agnostic library designed to wrap QuickNode's GraphQL API. It simplifies interactions with QuickNode services for blockchain developers. ```javascript import { QuickNodeSDK } from '@quicknode/sdk'; const sdk = new QuickNodeSDK('YOUR_QUICKNODE_API_KEY'); async function getBlockNumber() { const response = await sdk.graphql(` query { blockchain { getBlockNumber } } `); console.log(response.data.blockchain.getBlockNumber); } getBlockNumber(); ``` -------------------------------- ### NFT React Hooks - icy.tools API Wrapper Source: https://github.com/quiknode-labs/qn-oss/blob/main/README.md A collection of React hooks that act as a wrapper for the icy.tools GraphQL API. It simplifies fetching and managing NFT-related data within React applications. ```typescript import { useNFTsByOwner } from '@quicknode/ui/nft-react-hooks'; function NftGallery({ ownerAddress }) { const { nfts, loading, error } = useNFTsByOwner(ownerAddress, 'mainnet'); if (loading) return

Loading NFTs...

; if (error) return

Error loading NFTs: {error.message}

; return (

NFTs Owned by {ownerAddress}

    {nfts.map(nft => (
  • {nft.name} - #{nft.tokenId}
  • ))}
); } ``` -------------------------------- ### Run Unit Tests Source: https://github.com/quiknode-labs/qn-oss/blob/main/packages/libs/ui/util/README.md Executes the unit tests for the libs-ui-util library using Jest. This command is typically run within the Nx build system. ```bash nx test libs-ui-util ``` -------------------------------- ### Token Gate - React NFT Ownership Component Source: https://github.com/quiknode-labs/qn-oss/blob/main/README.md A React library that allows developers to conditionally render parts of their application based on a user's NFT ownership. It integrates with blockchain data to manage access. ```javascript import React from 'react'; import { TokenGate } from '@quicknode/ui/token-gate'; function App() { return (

My DApp

Welcome, NFT Holder!

); } ``` -------------------------------- ### Use useWalletNFTs Hook Source: https://github.com/quiknode-labs/qn-oss/blob/main/packages/libs/ui/nft-react-hooks/README.md Fetch NFTs for a given wallet address or ENS name using the `useWalletNFTs` hook. It returns the list of NFTs, loading state, and a validity flag for the search query. ```jsx import { useWalletNFTs } from '@quicknode/icy-nft-hooks'; function WalletComponent({ ensName }: { ensName: string }) { const { nfts } = useWalletNFTs({ ensName }); return (

{ensName}

    {nfts.map((nft) => (
  • {nft.contract.symbol}#{nft.tokenId}

  • ))}
) } ``` -------------------------------- ### API Reference - useWalletNFTs Source: https://github.com/quiknode-labs/qn-oss/blob/main/packages/libs/ui/nft-react-hooks/README.md Fetches NFTs associated with a specific wallet address or ENS name. It supports pagination and returns NFT details, loading status, and search validity. ```ts // Example const { nfts, loading, isSearchValid } = useWalletNFTs({ address: '0x....', ensName: 'vitalk.eth', }); // args: // args: Args interface WalletNFTsQueryAddressVariables extends PaginationArgs { address: string; } interface WalletNFTsQueryENSVariables extends PaginationArgs { ensName: string; } export type WalletNFTsQueryVariables = WalletNFTsQueryAddressVariables | WalletNFTsQueryENSVariables; // returns: // nfts: NFT[] interface NFT { tokenId: string; contract: { address: string; symbol: string; name: string; }; images: { url: string; }[]; } // loading: boolean // isSearchValid: boolean // pageInfo: PageInfo ``` -------------------------------- ### useCollection Hook Usage Source: https://github.com/quiknode-labs/qn-oss/blob/main/packages/libs/ui/nft-react-hooks/README.md Demonstrates how to use the `useCollection` hook to fetch NFT collection data, optionally including statistics. It takes a contract address and a flag to include stats. ```ts const { collections, pageInfo } = useCollection({ contractAddress: '0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D', includeStats: true, }); ``` -------------------------------- ### API Reference - useNFTOwner Source: https://github.com/quiknode-labs/qn-oss/blob/main/packages/libs/ui/nft-react-hooks/README.md Fetches the owner's address and ENS name for a specific NFT, identified by its contract address and token ID. Returns owner details and loading status. ```ts // Example const { owner, loading } = useNFTOwner({ ensName: 'mevcollector.eth', }); // args: // args: Args interface Args { contractAddress: string; tokenId: string; } // returns: // owner: Owner | null interface Owner { address: string; ensName: string | null; } // loading: boolean ``` -------------------------------- ### API Reference - useTrendingCollections Source: https://github.com/quiknode-labs/qn-oss/blob/main/packages/libs/ui/nft-react-hooks/README.md Retrieves trending NFT collections based on specified sorting, direction, and time period. Supports pagination and returns collection data, loading status, and pagination info. ```ts // Example const { collections, pageInfo } = useTrendingCollections({ orderBy: 'SALES', orderDirection: 'DESC', timePeriod: TrendingCollectionsTimePeriod.ONE_HOUR, first: 5, after: cursor, }); // args: // args: Args export interface TrendingCollectionsQueryVariables extends PaginationArgs { orderBy: 'SALES' | 'AVERAGE' | 'VOLUME'; orderDirection: 'DESC' | 'ASC'; timePeriod?: TrendingCollectionsTimePeriod; } export enum TrendingCollectionsTimePeriod { ONE_HOUR = 'ONE_HOUR', TWELVE_HOURS = 'TWELVE_HOURS', ONE_DAY = 'ONE_DAY', SEVEN_DAYS = 'SEVEN_DAYS', } // returns: // collections: Collection[] export interface Collection { address: string; name: string; stats: { totalSales: number; average: number; ceiling: number; floor: number; volume: number; }; symbol: number; } // loading: boolean // pageInfo: PageInfo ``` -------------------------------- ### API Reference - Shared Types Source: https://github.com/quiknode-labs/qn-oss/blob/main/packages/libs/ui/nft-react-hooks/README.md Defines shared types used across various API hooks, including pagination information and arguments. ```ts export interface PageInfo { hasNextPage: boolean; endCursor: string | null; } export interface PaginationArgs { first?: number; after?: string; } ``` -------------------------------- ### useCollection Hook Return Types Source: https://github.com/quiknode-labs/qn-oss/blob/main/packages/libs/ui/nft-react-hooks/README.md Specifies the TypeScript interfaces for the return values of the `useCollection` hook, including the collection data (with or without stats) and the loading state. ```ts export interface Collection { address: string; name: string; symbol: string; unsafeOpenseaBannerImageUrl: string | null; unsafeOpenseaImageUrl: string | null; unsafeOpenseaSlug: string | null; } export interface CollectionWithStats extends Collection { stats: { average: number | null; ceiling: number | null; floor: number | null; totalSales: number; volume: number; }; } // The hook also returns: // loading: boolean - The loading state of the query ``` -------------------------------- ### useCollection Hook Arguments Interface Source: https://github.com/quiknode-labs/qn-oss/blob/main/packages/libs/ui/nft-react-hooks/README.md Defines the TypeScript interfaces for the arguments accepted by the `useCollection` hook. It supports fetching collections with or without additional statistics. ```ts interface WithStatsArgs { address: string; includeStats: true; } interface WithoutStatsArgs { address: string; includeStats?: false; } type Args = WithStatsArgs | WithoutStatsArgs; ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.