Created
December 6, 2023 19:50
-
-
Save robertjchristian/c98362735ad8132050ab04b095d79d2f to your computer and use it in GitHub Desktop.
Alchemy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"use strict"; | |
import AlchemyInitializer from "./AlchemyInitializer"; | |
import { Alchemy } from "alchemy-sdk"; | |
/** | |
* Class for fetching NFTs minted under a given contract address. | |
*/ | |
class NFTFetcher { | |
private alchemy: Alchemy; | |
private contractAddress: string; | |
/** | |
* Creates an instance of NFTFetcher. | |
*/ | |
constructor(contractAddress: string) { | |
this.contractAddress = contractAddress; | |
// Initialize Alchemy | |
this.alchemy = new AlchemyInitializer().initMatic(); | |
} | |
/** | |
* Private method to parse NFT data from a response. | |
* | |
*/ | |
private parseNfts(res: any) { | |
const nfts: any[] = []; | |
for (let x = 0; x < res.nfts.length; x++) { | |
const nft = res.nfts[x]; | |
const n: any = nft.raw.metadata; | |
// Add additional properties to the NFT object | |
n["tokenId"] = nft.tokenId; | |
n["uri"] = nft.tokenUri; | |
n["media"] = nft.media; | |
nfts.push(n); | |
} | |
return nfts; | |
} | |
/** | |
* Private method to fetch NFTs for a contract with pagination. | |
* | |
*/ | |
private async fetchNFTsForContractPaged( | |
contractAddress: string, | |
pageKey: string | null, | |
omitMetadata = true | |
) { | |
let options: any = { limit: 100, omitMetadata }; | |
if (pageKey) { | |
options["pageKey"] = pageKey; | |
} | |
// Fetch NFTs for the specified contract | |
const nftsForContractResponse = await this.alchemy.nft.getNftsForContract( | |
contractAddress, | |
options | |
); | |
return { | |
nfts: nftsForContractResponse.nfts, | |
pageKey: nftsForContractResponse.pageKey | |
? nftsForContractResponse.pageKey | |
: null, | |
}; | |
} | |
/** | |
* Private method to fetch all NFTs for a contract with pagination. | |
* | |
*/ | |
private async fetchAllNFTsForContractWithPaging( | |
contractAddress: string, | |
omitMetadata: boolean | |
) { | |
let nfts: any[] = []; | |
let i = 0; | |
let pageKey = null; | |
while (true) { | |
const res = await this.fetchNFTsForContractPaged( | |
contractAddress, | |
pageKey, | |
omitMetadata | |
); | |
if (omitMetadata) { | |
// console.log(res.nfts); | |
const tokenIds = res.nfts.map((nft) => nft.tokenId); | |
nfts = nfts.concat(tokenIds); | |
// filter out the contract address from the fetched NFTs | |
const filteredNFTs = nfts.filter((nft: any) => nft !== contractAddress); | |
// return NFT id only | |
nfts = filteredNFTs; | |
// sleep to keep under rate limit (throttle) | |
// reduces "Retrying after error: 429" for large collections | |
await new Promise((resolve) => setTimeout(resolve, 35)); // TODO make this configurable, depends on key | |
} else { | |
// Concatenate the parsed NFTs to the existing array | |
nfts = nfts.concat(this.parseNfts(res)); | |
} | |
// console.log(nfts); | |
// Output pagination information | |
console.log("Page", i++, res.pageKey, res.nfts.length, nfts.length); | |
pageKey = res.pageKey; | |
if (!pageKey) { | |
break; | |
} | |
} | |
return nfts; | |
} | |
/** | |
* Public method to fetch all NFTs for a contract. | |
* | |
*/ | |
async fetchNftsForContract(includeMetadata: boolean = false) { | |
const omitMetadata = !includeMetadata; | |
let nfts = await this.fetchAllNFTsForContractWithPaging( | |
this.contractAddress, | |
omitMetadata | |
); | |
console.log("Finishing up..."); | |
let final: any[] = []; | |
return nfts | |
} | |
} | |
/** | |
* Main function to fetch and log NFTs for a specific contract. (run example) | |
*/ | |
const main = async () => { | |
const startTime = performance.now(); // Record start time | |
const contractAddress = "0x135Fb4Ab7A5d62297682A8286f54719465a6C581"; | |
const nftFetcher = new NFTFetcher(contractAddress); | |
const nfts = await nftFetcher.fetchNftsForContract(false); | |
console.log(nfts); | |
const endTime = performance.now(); // Record end time | |
const elapsedTimeMs = endTime - startTime; // Calculate elapsed time in milliseconds | |
const elapsedTimeMinutes = elapsedTimeMs / 60000; // Convert to minutes | |
console.log( | |
`Completed successfully in ${elapsedTimeMs.toFixed( | |
0 | |
)} ms (${elapsedTimeMinutes.toFixed(2)} minutes)` | |
); | |
}; | |
// Execute the main function and handle any errors | |
main() | |
.then(() => process.exit(0)) | |
.catch((error: Error) => { | |
console.error(error); | |
process.exit(1); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Issues:
Unrelated to GIST: