@settlemint/solidity-token-erc721-generative-art
Version:
Smart contract set to build an ERC721 token with generated art in SettleMint
101 lines (88 loc) • 3.6 kB
text/typescript
import {
Address,
Bytes,
ipfs,
json,
JSONValueKind,
} from '@graphprotocol/graph-ts';
import { IERC721 } from '@openzeppelin/subgraphs/generated/erc721/IERC721';
import { ERC721Contract } from '@openzeppelin/subgraphs/generated/schema';
import {
ERC721Token,
ERC721TokenAttribute,
ERC721TokenMetadata,
} from '../../generated/schema';
export function fetchERC721TokenIpfsMetadata(
contractId: string,
tokenId: string,
refresh: boolean
): ERC721TokenMetadata {
let metadata = ERC721TokenMetadata.load(tokenId);
const contract = ERC721Contract.load(Bytes.fromHexString(contractId));
const token = ERC721Token.load(tokenId);
if (
(metadata == null || refresh) &&
contract !== null &&
contract.supportsMetadata &&
token != null
) {
metadata = new ERC721TokenMetadata(tokenId);
token.metadata = metadata.id;
const erc721 = IERC721.bind(Address.fromString(contract.id.toHex()));
const try_tokenURI = erc721.try_tokenURI(token.identifier);
const uri = try_tokenURI.reverted ? '' : try_tokenURI.value;
if (uri.includes('ipfs://')) {
const ipfsHash = uri.replace('ipfs://', '');
const tokenURIBytes = ipfs.cat(ipfsHash);
if (tokenURIBytes) {
const tokenURIContent = json.try_fromBytes(tokenURIBytes);
if (
tokenURIContent.isOk &&
tokenURIContent.value.kind == JSONValueKind.OBJECT
) {
const tokenMetadata = tokenURIContent.value.toObject();
const name = tokenMetadata.get('name');
metadata.name = name ? name.toString() : null;
const description = tokenMetadata.get('description');
metadata.description = description ? description.toString() : null;
const image = tokenMetadata.get('image');
metadata.image = image ? image.toString() : null;
const attributes = tokenMetadata.get('attributes');
if (attributes && attributes.kind == JSONValueKind.ARRAY) {
const attributesArray = attributes.toArray();
for (let i = 0; i < attributesArray.length; i++) {
const attributeId = metadata.id.concat('/').concat(i.toString());
let attribute = ERC721TokenAttribute.load(attributeId);
if (
attribute == null &&
attributesArray[i].kind == JSONValueKind.OBJECT
) {
const attributeData = attributesArray[i].toObject();
attribute = new ERC721TokenAttribute(attributeId);
attribute.metadata = metadata.id;
const traitType = attributeData.get('trait_type');
attribute.traitType = traitType ? traitType.toString() : '';
const value = attributeData.get('value');
if (value && value.kind == JSONValueKind.STRING) {
attribute.value = value ? value.toString() : '';
} else if (value && value.kind == JSONValueKind.NUMBER) {
attribute.value = value ? value.toBigInt().toString() : '';
}
const maxValue = attributeData.get('max_value');
attribute.maxValue = maxValue ? maxValue.toBigInt() : null;
const displayType = attributeData.get('display_type');
attribute.displayType = displayType
? displayType.toString()
: null;
attribute.save();
}
}
}
}
}
}
metadata.save();
token.save();
}
return metadata as ERC721TokenMetadata;
}