diff --git a/api/knowhere/lib/type.d.ts b/api/knowhere/lib/type.d.ts index c44c654..1eca270 100644 --- a/api/knowhere/lib/type.d.ts +++ b/api/knowhere/lib/type.d.ts @@ -80,6 +80,11 @@ export interface TokensInfo { tokens: string[]; } +interface Skills { + skill_type?: string; + value?: number; +} + export interface NftInfo { tokenId?: string; nftContract?: string; @@ -89,5 +94,8 @@ export interface NftInfo { collectionName?: string; marketplace?: string; symbol?: string; + class?: string; + rarity?: string; + skills?: Skills[]; attributes?: Attributes[]; } diff --git a/api/randomearth/lib/formatMantleNftInfo.ts b/api/randomearth/lib/formatMantleNftInfo.ts index e6c29e2..77f3d0b 100644 --- a/api/randomearth/lib/formatMantleNftInfo.ts +++ b/api/randomearth/lib/formatMantleNftInfo.ts @@ -5,7 +5,7 @@ import { MantleData, NftInfo } from "../../knowhere/lib/type"; const MARKETPLACE = "RandomEarth"; -const getNftId = (idInfo: string) => { +export const getNftId = (idInfo: string) => { const id = idInfo.slice(3, idInfo.length - 1); return id; }; diff --git a/api/tfloki/index.ts b/api/tfloki/index.ts index ed2b45a..a91ab9b 100644 --- a/api/tfloki/index.ts +++ b/api/tfloki/index.ts @@ -32,9 +32,35 @@ const typeDefs = gql` apr: String! } + type NftAttributes { + display_type: String + trait_type: String + value: String + } + + type Skills { + skill_type: String + value: Int + } + + type TerraFlokiNft { + tokenId: String + nftContract: String + name: String + description: String + image: String + collectionName: String + marketplace: String + class: String + rarity: String + skills: [Skills] + attributes: [NftAttributes] + } + type TFlokiAccount { tflokiHoldings: TFlokiHolding flokiPool: FlokiPool + nfts: [TerraFlokiNft] } extend type Assets @key(fields: "address") { diff --git a/api/tfloki/lib/constants.ts b/api/tfloki/lib/constants.ts index 83d71ae..c6503d5 100644 --- a/api/tfloki/lib/constants.ts +++ b/api/tfloki/lib/constants.ts @@ -1 +1,17 @@ export const TFLOKI_API = "https://api.terrafloki.io/"; + +export const NFTCollections = [ + { + nftContract: "terra1yuna9m4v0xcv5je8q5ymk8chrr7xf8ytvzqf4x", + name: "TFloki Genesis", + symbol: "TFGEN", + }, +]; + +export const CollectionsByContract = { + terra1yuna9m4v0xcv5je8q5ymk8chrr7xf8ytvzqf4x: { + nftContract: "terra1yuna9m4v0xcv5je8q5ymk8chrr7xf8ytvzqf4x", + name: "TFloki Genesis", + symbol: "TFGEN", + }, +}; diff --git a/api/tfloki/lib/getTflokiNfts.ts b/api/tfloki/lib/getTflokiNfts.ts new file mode 100644 index 0000000..3330227 --- /dev/null +++ b/api/tfloki/lib/getTflokiNfts.ts @@ -0,0 +1,75 @@ +import { wasmStoreRequest } from "@contco/terra-utilities"; +import { TokensInfo } from "../../knowhere/lib/type"; +import { fetchNftInfo } from "../../randomearth/lib/fetchNftInfo"; +import { getNftId } from "../../randomearth/lib/formatMantleNftInfo"; +import { NFTCollections, CollectionsByContract } from "./constants"; + +import { NFTCollection } from "./type"; +import { MantleNftInfoResult } from "../../randomearth/lib/type"; +import { MantleData, NftInfo } from "../../knowhere/lib/type"; + +const LIMIT = 1000; +const MARKETPLACE = "TerraFloki"; + +export const getTflokiImageUrl = (token_uri: string) => { + const imageUrl = "https://terrafloki.io/flokis/" + token_uri + ".gif"; + return imageUrl; +}; + +export const formatMantleNftInfo = ( + mantleNftInfoList: MantleNftInfoResult[] +) => { + const nftData = mantleNftInfoList.reduce( + (nftData: NftInfo[], mantleNftInfo: MantleNftInfoResult) => { + const nftIds = Object.keys(mantleNftInfo.result); + const nftResult = Object.values(mantleNftInfo.result); + const formatNftInfo = nftResult.map( + (nftResult: MantleData, index: number) => { + const result = JSON.parse(nftResult.Result); + return { + tokenId: getNftId(nftIds[index]), + description: result?.extension?.description, + name: result?.extension?.name, + image: getTflokiImageUrl(result?.token_uri), + attributes: result?.extension?.attributes, + nftContract: mantleNftInfo.nftContract, + collectionName: + CollectionsByContract[mantleNftInfo.nftContract].name, + symbol: CollectionsByContract[mantleNftInfo.nftContract].symbol, + class: result?.extension?.class, + rarity: result?.extension?.rarity, + skills: result?.extension?.skills, + marketplace: MARKETPLACE, + }; + } + ); + return [...nftData, ...formatNftInfo]; + }, + [] + ); + return nftData; +}; + +const getTokensInfo = async (address: string) => { + const tokenIdsListPromise = NFTCollections.map( + async (collection: NFTCollection) => { + const tokens = await wasmStoreRequest(collection.nftContract, { + tokens: { owner: address, limit: LIMIT }, + }); + return { nftContract: collection.nftContract, ...tokens }; + } + ); + const tokensInfo: TokensInfo[] = await Promise.all(tokenIdsListPromise); + return tokensInfo; +}; + +export const getTFlokiNfts = async (address: string) => { + try { + const tokensInfoList = await getTokensInfo(address); + const nftsInfo = await fetchNftInfo(tokensInfoList); + const nftInfo = formatMantleNftInfo(nftsInfo); + return nftInfo; + } catch (err) { + return []; + } +}; diff --git a/api/tfloki/lib/index.ts b/api/tfloki/lib/index.ts index 5bc7ab8..cd60f32 100644 --- a/api/tfloki/lib/index.ts +++ b/api/tfloki/lib/index.ts @@ -1,6 +1,7 @@ import { getPoolInfo, getPrice } from "@contco/terra-utilities"; import { fetchPoolApr } from "./calculateApr"; import { TFLOKI_CONTRACTS } from "./contracts"; +import { getTFlokiNfts } from "./getTflokiNfts"; import { fetchHoldings, getHoldings } from "./holdings"; import { fetchAvailableLp, fetchStakedLp, getFlokiPool } from "./lp"; @@ -11,12 +12,13 @@ const fetchData = (address: string) => { fetchAvailableLp(address), fetchStakedLp(address), fetchPoolApr(), + getTFlokiNfts(address), ]); return result; }; export const getTFlokiAccount = async (address: string) => { - const [holdingsInfo, poolInfo, availableLp, stakedLp, poolApr] = + const [holdingsInfo, poolInfo, availableLp, stakedLp, poolApr, nfts] = await fetchData(address); const tflokiPrice = getPrice(poolInfo); const userHoldings = getHoldings(holdingsInfo, tflokiPrice); @@ -27,6 +29,6 @@ export const getTFlokiAccount = async (address: string) => { tflokiPrice, poolApr ); - const tflokiAccount = { tflokiHoldings: userHoldings, flokiPool }; + const tflokiAccount = { tflokiHoldings: userHoldings, flokiPool, nfts }; return tflokiAccount; }; diff --git a/api/tfloki/lib/type.d.ts b/api/tfloki/lib/type.d.ts new file mode 100644 index 0000000..8053cf0 --- /dev/null +++ b/api/tfloki/lib/type.d.ts @@ -0,0 +1,5 @@ +export interface NFTCollection { + nftContract: string; + name: string; + symbol: string; +} diff --git a/tefi-gateway/supergraph.graphql b/tefi-gateway/supergraph.graphql index 7edf517..ffd8a5d 100644 --- a/tefi-gateway/supergraph.graphql +++ b/tefi-gateway/supergraph.graphql @@ -591,6 +591,11 @@ type Reward { staked: String } +type Skills { + skill_type: String + value: Int +} + type SpecFarms { apy: String! farm: String! @@ -691,6 +696,7 @@ type StarTerraPools { type TFlokiAccount { flokiPool: FlokiPool + nfts: [TerraFlokiNft] tflokiHoldings: TFlokiHolding } @@ -749,6 +755,20 @@ type TWDPool { totalLpUstValue: String! } +type TerraFlokiNft { + attributes: [NftAttributes] + class: String + collectionName: String + description: String + image: String + marketplace: String + name: String + nftContract: String + rarity: String + skills: [Skills] + tokenId: String +} + type Time { claimableTime: String requestedTime: String