Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions subgraph/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
"build:sepolia": "graph codegen && graph build --network sepolia",
"build:mainnet": "graph codegen && graph build --network mainnet",
"deploy:local": "graph deploy --node http://localhost:8020/ --ipfs http://localhost:5001 moleculeprotocol/ipnft-subgraph",
"deploy:sepolia": "env-cmd -x -f ../.env graph deploy ip-nft-sepolia --version-label 1.2.0 --node https://subgraphs.alchemy.com/api/subgraphs/deploy --ipfs https://ipfs.satsuma.xyz --deploy-key \\$SATSUMA_DEPLOY_KEY",
"deploy:mainnet": "env-cmd -x -f ../.env graph deploy ip-nft-mainnet --version-label 1.2.0 --node https://subgraphs.alchemy.com/api/subgraphs/deploy --ipfs https://ipfs.satsuma.xyz --deploy-key \\$SATSUMA_DEPLOY_KEY",
"deploy:sepolia": "env-cmd -x -f ../.env graph deploy ip-nft-sepolia --version-label 1.2.1 --node https://subgraphs.alchemy.com/api/subgraphs/deploy --ipfs https://ipfs.satsuma.xyz --deploy-key \\$SATSUMA_DEPLOY_KEY",
"deploy:mainnet": "env-cmd -x -f ../.env graph deploy ip-nft-mainnet --version-label 1.2.1 --node https://subgraphs.alchemy.com/api/subgraphs/deploy --ipfs https://ipfs.satsuma.xyz --deploy-key \\$SATSUMA_DEPLOY_KEY",
"create:local": "graph create --node http://localhost:8020/ moleculeprotocol/ipnft-subgraph",
"remove:local": "graph remove --node http://localhost:8020/ moleculeprotocol/ipnft-subgraph",
"test": "graph test"
Expand Down
10 changes: 10 additions & 0 deletions subgraph/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,16 @@ type Ipnft @entity {
listings: [Listing!] @derivedFrom(field: "ipnft")
readers: [CanRead!] @derivedFrom(field: "ipnft")
ipts: [IPT!] @derivedFrom(field: "ipnft")
metadata: IpnftMetadata
updatedAtTimestamp: BigInt
}

type IpnftMetadata @entity {
id: ID!
name: String!
image: String!
description: String!
externalURL: String!
}

type IPT @entity {
Expand Down
35 changes: 27 additions & 8 deletions subgraph/src/ipnftMapping.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
import {
Address,
BigInt,
ByteArray,
crypto,
ethereum,
log,
store
} from '@graphprotocol/graph-ts'
import {
IPNFT as IPNFTContract,
IPNFTMinted as IPNFTMintedEvent,
Reserved as ReservedEvent,
ReadAccessGranted as ReadAccessGrantedEvent,
Transfer as TransferEvent,
MetadataUpdate as MetadataUpdateEvent,
IPNFT as IPNFTContract
ReadAccessGranted as ReadAccessGrantedEvent,
Reserved as ReservedEvent,
Transfer as TransferEvent
} from '../generated/IPNFT/IPNFT'
import { Ipnft, Reservation, CanRead } from '../generated/schema'
import { IpnftMetadata as IpnftMetadataTemplate } from '../generated/templates'
import { CanRead, Ipnft, Reservation } from '../generated/schema'

export function handleTransfer(event: TransferEvent): void {
if (event.params.to == Address.zero()) {
Expand Down Expand Up @@ -73,15 +75,29 @@ export function handleReservation(event: ReservedEvent): void {
reservation.save()
}

function updateIpnftMetadata(ipnft: Ipnft, uri: string, timestamp: BigInt): void {
let ipfsLocation = uri.replace('ipfs://', '');
if (!ipfsLocation || ipfsLocation == uri) {
log.error("Invalid URI format for tokenId {}: {}", [ipnft.id, uri])
return
}

ipnft.tokenURI = uri
ipnft.metadata = ipfsLocation
ipnft.updatedAtTimestamp = timestamp
IpnftMetadataTemplate.create(ipfsLocation)
}

//the underlying parameter arrays are misaligned, hence we cannot cast or unify both events
export function handleMint(event: IPNFTMintedEvent): void {
let ipnft = new Ipnft(event.params.tokenId.toString())
ipnft.owner = event.params.owner
ipnft.tokenURI = event.params.tokenURI
ipnft.createdAt = event.block.timestamp
ipnft.symbol = event.params.symbol
updateIpnftMetadata(ipnft, event.params.tokenURI, event.block.timestamp)
store.remove('Reservation', event.params.tokenId.toString())
ipnft.save()

}

export function handleMetadataUpdated(event: MetadataUpdateEvent): void {
Expand All @@ -94,8 +110,11 @@ export function handleMetadataUpdated(event: MetadataUpdateEvent): void {
//erc4906 is not emitting the new url, we must query it ourselves
let _ipnftContract = IPNFTContract.bind(event.params._event.address);
let newUri = _ipnftContract.tokenURI(event.params._tokenId)

ipnft.tokenURI = newUri
if (!newUri || newUri == "") {
log.debug("no new uri found for token, likely just minted {}", [event.params._tokenId.toString()])
return
}
updateIpnftMetadata(ipnft, newUri, event.block.timestamp)
ipnft.save()
}

22 changes: 22 additions & 0 deletions subgraph/src/metadataMapping.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { json, Bytes, dataSource } from '@graphprotocol/graph-ts'
import { IpnftMetadata } from '../generated/schema'

export function handleMetadata(content: Bytes): void {
const value = json.fromBytes(content).toObject()
if (value) {
const image = value.get('image')
const name = value.get('name')
const description = value.get('description')
const externalURL = value.get('external_url')

if (name && image && description && externalURL) {
let ipnftMetadata = new IpnftMetadata(dataSource.stringParam())
ipnftMetadata.name = name.toString()
ipnftMetadata.image = image.toString()
ipnftMetadata.externalURL = externalURL.toString()
ipnftMetadata.description = description.toString()
ipnftMetadata.save()
}

}
}
13 changes: 13 additions & 0 deletions subgraph/subgraph.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -228,3 +228,16 @@ templates:
handler: handleScheduled
- event: ScheduleReleased(indexed bytes32,indexed address,uint256)
handler: handleReleased
- name: IpnftMetadata
kind: file/ipfs
mapping:
apiVersion: 0.0.7
language: wasm/assemblyscript
file: ./src/metadataMapping.ts
handler: handleMetadata
entities:
- IpnftMetadata
abis:
- name: IPNFT
file: ./abis/IPNFT.json
network: foundry