Skip to content

Instantly share code, notes, and snippets.

@korrio
Created November 8, 2021 03:32
Show Gist options
  • Save korrio/6935cb4f28e835af5b3d3dc6322c24a2 to your computer and use it in GitHub Desktop.
Save korrio/6935cb4f28e835af5b3d3dc6322c24a2 to your computer and use it in GitHub Desktop.
useVonderNFT.ts
import { useWeb3React } from "@web3-react/core";
import { BigNumber, Contract, ethers } from "ethers";
import { useCallback, useEffect, useMemo, useState } from "react";
import { useContract } from "./contracts/useContract";
import {
IVonderBabyBoomer,
VonderCharacter,
VonderElement,
VonderGeneration,
} from "types/Vonder";
import { batchPromise } from "utils/batchPromise";
import { gql, useQuery } from "@apollo/client";
import { ChainId } from "constants/contracts";
export type Address = string;
interface IVonderResponse {
tokenURI: string;
}
interface IVonderInfoResponse {
tokenId: BigNumber;
tokenName: string;
tokenURI: string;
mintedBy: Address;
currentOwner: Address;
previousOwner: Address;
price: BigNumber;
numberOfTransfers: BigNumber;
forSale: boolean;
characterType: number;
element: number;
}
export const useVonderNFT = () => {
const vonderNFTGenXContract = useContract("VONDER_NFT");
const { account, chainId } = useWeb3React();
const [isLoadingVonders, setIsLoadingVonders] = useState(false);
const [ownedVonders, setOwnedVonders] = useState<IVonderBabyBoomer[]>([]);
const getNFT = async (
tokenId: BigNumber | string
): Promise<IVonderBabyBoomer> => {
const vonderResponse: IVonderInfoResponse = await vonderNFTGenXContract.allCryptoNFTs(
tokenId
);
const numbers: number[] = await vonderNFTGenXContract.getLotteryNumbers(
tokenId
);
const vonder: IVonderBabyBoomer = {
id: vonderResponse.tokenId.toNumber(),
name: vonderResponse.tokenName,
numbers,
generation: 2,
element: vonderResponse.element as VonderElement,
charType: vonderResponse.characterType as VonderCharacter,
};
return vonder;
};
const getOwnedVonderFromContract = async (contract: Contract) => {
const vonderCount: number = await contract.balanceOf(account);
const indices = Array.from({ length: vonderCount }, (_, index) => index);
const vonders = await batchPromise(indices, async (index) => {
const tokenId: BigNumber = await contract.tokenOfOwnerByIndex(
account,
index
);
const vonder = await getNFT(tokenId);
return vonder;
});
return vonders;
};
const getOwnedVonders = useCallback(async (): Promise<any[]> => {
if (!account || !vonderNFTGenXContract) {
return [];
}
setIsLoadingVonders(true);
const vondersFromContract = await batchPromise(
[{ contract: vonderNFTGenXContract }],
async ({ contract }) => {
return getOwnedVonderFromContract(contract);
}
);
setIsLoadingVonders(false);
setOwnedVonders(vondersFromContract.flat());
}, [account, chainId]);
// TODO: Use subgraph entirely to get information of owned tokens
useQuery(
gql`
query OwnedVonders($account: ID!) {
account(id: $account) {
tokens {
identifier
owner {
id
}
approval {
id
}
uri
}
}
}
`,
{
variables: { account },
skip: chainId !== ChainId.BKC_MAINNET,
onCompleted: (ownedVondersData) => {
if (!ownedVondersData?.account) {
getOwnedVonders()
return
}
const vondersFromSubgraph = ownedVondersData.account.tokens.map(
({ identifier, uri }) => {
return {
id: identifier,
url: uri,
numbers: [1, 1, 1, 1],
element: VonderElement.FIRE,
charType: 1,
generation: VonderGeneration.GEN_X,
};
}
);
setOwnedVonders(vondersFromSubgraph);
},
}
);
useEffect(() => {
if (chainId !== ChainId.BKC_MAINNET) {
getOwnedVonders()
}
}, [chainId, account])
return {
getNFT,
ownedVonders,
isLoadingVonders,
};
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment