Skip to content

Commit 67ad692

Browse files
Merge pull request #166 from moleculeprotocol/feature/hubs-90-read-ipnft-ipfs-metadata-during-subgraph-indexing
HUBS-90 adds metadata templates to the subgraph
2 parents 94bd697 + 2b386c9 commit 67ad692

File tree

5 files changed

+74
-10
lines changed

5 files changed

+74
-10
lines changed

subgraph/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
"build:sepolia": "graph codegen && graph build --network sepolia",
99
"build:mainnet": "graph codegen && graph build --network mainnet",
1010
"deploy:local": "graph deploy --node http://localhost:8020/ --ipfs http://localhost:5001 moleculeprotocol/ipnft-subgraph",
11-
"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",
12-
"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",
11+
"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",
12+
"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",
1313
"create:local": "graph create --node http://localhost:8020/ moleculeprotocol/ipnft-subgraph",
1414
"remove:local": "graph remove --node http://localhost:8020/ moleculeprotocol/ipnft-subgraph",
1515
"test": "graph test"

subgraph/schema.graphql

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,16 @@ type Ipnft @entity {
77
listings: [Listing!] @derivedFrom(field: "ipnft")
88
readers: [CanRead!] @derivedFrom(field: "ipnft")
99
ipts: [IPT!] @derivedFrom(field: "ipnft")
10+
metadata: IpnftMetadata
11+
updatedAtTimestamp: BigInt
12+
}
13+
14+
type IpnftMetadata @entity {
15+
id: ID!
16+
name: String!
17+
image: String!
18+
description: String!
19+
externalURL: String!
1020
}
1121

1222
type IPT @entity {

subgraph/src/ipnftMapping.ts

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
11
import {
22
Address,
3+
BigInt,
34
ByteArray,
45
crypto,
56
ethereum,
67
log,
78
store
89
} from '@graphprotocol/graph-ts'
910
import {
11+
IPNFT as IPNFTContract,
1012
IPNFTMinted as IPNFTMintedEvent,
11-
Reserved as ReservedEvent,
12-
ReadAccessGranted as ReadAccessGrantedEvent,
13-
Transfer as TransferEvent,
1413
MetadataUpdate as MetadataUpdateEvent,
15-
IPNFT as IPNFTContract
14+
ReadAccessGranted as ReadAccessGrantedEvent,
15+
Reserved as ReservedEvent,
16+
Transfer as TransferEvent
1617
} from '../generated/IPNFT/IPNFT'
17-
import { Ipnft, Reservation, CanRead } from '../generated/schema'
18+
import { IpnftMetadata as IpnftMetadataTemplate } from '../generated/templates'
19+
import { CanRead, Ipnft, Reservation } from '../generated/schema'
1820

1921
export function handleTransfer(event: TransferEvent): void {
2022
if (event.params.to == Address.zero()) {
@@ -73,15 +75,29 @@ export function handleReservation(event: ReservedEvent): void {
7375
reservation.save()
7476
}
7577

78+
function updateIpnftMetadata(ipnft: Ipnft, uri: string, timestamp: BigInt): void {
79+
let ipfsLocation = uri.replace('ipfs://', '');
80+
if (!ipfsLocation || ipfsLocation == uri) {
81+
log.error("Invalid URI format for tokenId {}: {}", [ipnft.id, uri])
82+
return
83+
}
84+
85+
ipnft.tokenURI = uri
86+
ipnft.metadata = ipfsLocation
87+
ipnft.updatedAtTimestamp = timestamp
88+
IpnftMetadataTemplate.create(ipfsLocation)
89+
}
90+
7691
//the underlying parameter arrays are misaligned, hence we cannot cast or unify both events
7792
export function handleMint(event: IPNFTMintedEvent): void {
7893
let ipnft = new Ipnft(event.params.tokenId.toString())
7994
ipnft.owner = event.params.owner
80-
ipnft.tokenURI = event.params.tokenURI
8195
ipnft.createdAt = event.block.timestamp
8296
ipnft.symbol = event.params.symbol
97+
updateIpnftMetadata(ipnft, event.params.tokenURI, event.block.timestamp)
8398
store.remove('Reservation', event.params.tokenId.toString())
8499
ipnft.save()
100+
85101
}
86102

87103
export function handleMetadataUpdated(event: MetadataUpdateEvent): void {
@@ -94,8 +110,11 @@ export function handleMetadataUpdated(event: MetadataUpdateEvent): void {
94110
//erc4906 is not emitting the new url, we must query it ourselves
95111
let _ipnftContract = IPNFTContract.bind(event.params._event.address);
96112
let newUri = _ipnftContract.tokenURI(event.params._tokenId)
97-
98-
ipnft.tokenURI = newUri
113+
if (!newUri || newUri == "") {
114+
log.debug("no new uri found for token, likely just minted {}", [event.params._tokenId.toString()])
115+
return
116+
}
117+
updateIpnftMetadata(ipnft, newUri, event.block.timestamp)
99118
ipnft.save()
100119
}
101120

subgraph/src/metadataMapping.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { json, Bytes, dataSource } from '@graphprotocol/graph-ts'
2+
import { IpnftMetadata } from '../generated/schema'
3+
4+
export function handleMetadata(content: Bytes): void {
5+
const value = json.fromBytes(content).toObject()
6+
if (value) {
7+
const image = value.get('image')
8+
const name = value.get('name')
9+
const description = value.get('description')
10+
const externalURL = value.get('external_url')
11+
12+
if (name && image && description && externalURL) {
13+
let ipnftMetadata = new IpnftMetadata(dataSource.stringParam())
14+
ipnftMetadata.name = name.toString()
15+
ipnftMetadata.image = image.toString()
16+
ipnftMetadata.externalURL = externalURL.toString()
17+
ipnftMetadata.description = description.toString()
18+
ipnftMetadata.save()
19+
}
20+
21+
}
22+
}

subgraph/subgraph.yaml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,3 +228,16 @@ templates:
228228
handler: handleScheduled
229229
- event: ScheduleReleased(indexed bytes32,indexed address,uint256)
230230
handler: handleReleased
231+
- name: IpnftMetadata
232+
kind: file/ipfs
233+
mapping:
234+
apiVersion: 0.0.7
235+
language: wasm/assemblyscript
236+
file: ./src/metadataMapping.ts
237+
handler: handleMetadata
238+
entities:
239+
- IpnftMetadata
240+
abis:
241+
- name: IPNFT
242+
file: ./abis/IPNFT.json
243+
network: foundry

0 commit comments

Comments
 (0)