From 05a2fbb1b14caf869d790f64778786f05ce7bd19 Mon Sep 17 00:00:00 2001 From: Stefan Adolf Date: Thu, 16 Jan 2025 15:05:13 +0100 Subject: [PATCH] fixes structural traversal adds ipfs reading / conversion tests Signed-off-by: Stefan Adolf --- subgraph/.gitignore | 3 + subgraph/package.json | 4 +- subgraph/src/metadataMapping.ts | 9 +-- subgraph/tests/fixtures/ipnft_1.json | 83 ++++++++++++++++++++++++++++ subgraph/tests/metadata.test.ts | 28 ++++++++++ 5 files changed, 121 insertions(+), 6 deletions(-) create mode 100644 subgraph/tests/fixtures/ipnft_1.json create mode 100644 subgraph/tests/metadata.test.ts diff --git a/subgraph/.gitignore b/subgraph/.gitignore index 08ba03fa..8c64fe53 100644 --- a/subgraph/.gitignore +++ b/subgraph/.gitignore @@ -2,3 +2,6 @@ node_modules build/ generated + +tests/.bin +.latest.json \ No newline at end of file diff --git a/subgraph/package.json b/subgraph/package.json index 40d91ef0..f291044d 100644 --- a/subgraph/package.json +++ b/subgraph/package.json @@ -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.3.1-dev.8 --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.3.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.3.1-dev.9 --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.3.1-dev.9 --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" diff --git a/subgraph/src/metadataMapping.ts b/subgraph/src/metadataMapping.ts index 390a1f25..dbcbc9f4 100644 --- a/subgraph/src/metadataMapping.ts +++ b/subgraph/src/metadataMapping.ts @@ -16,12 +16,12 @@ export function handleMetadata(content: Bytes): void { ipnftMetadata.image = image.toString() ipnftMetadata.externalURL = externalURL.toString() ipnftMetadata.description = description.toString() - + ipnftMetadata.save() } else { log.info("[handlemetadata] name, image, description, external_url not found", []) } - + let _properties = value.get('properties') if (_properties) { let properties = _properties.toObject() @@ -61,14 +61,15 @@ export function handleMetadata(content: Bytes): void { } } - let _funding_amount = properties.get('funding_amount') + let _funding_amount = projectDetails.get('funding_amount') + if (_funding_amount) { let funding_amount = _funding_amount.toObject() let _fundingAmount_value = funding_amount.get('value') let _fundingAmount_decimals = funding_amount.get('decimals') let _fundingAmount_currency = funding_amount.get('currency') let _fundingAmount_currencyType = funding_amount.get('currency_type') - + if (_fundingAmount_value && _fundingAmount_decimals && _fundingAmount_currency && _fundingAmount_currencyType) { // on json metadata this can be a decimal value. I'm using a string to store as there's imo no f64 compatible decimal type on the schema scalar types // https://thegraph.com/docs/en/subgraphs/developing/creating/ql-schema/#built-in-scalar-types diff --git a/subgraph/tests/fixtures/ipnft_1.json b/subgraph/tests/fixtures/ipnft_1.json new file mode 100644 index 00000000..aef85306 --- /dev/null +++ b/subgraph/tests/fixtures/ipnft_1.json @@ -0,0 +1,83 @@ +{ + "schema_version": "0.0.1", + "name": "Our awesome test IP-NFT", + "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua...", + "image": "ipfs://bafkreih5d2453qzkprn35zm4gj5ff6ezroevnaaygxqlwcbqq2tg7ebbe4", + "external_url": "https://testnet.mint.molecule.to/ipnft/76", + "terms_signature": "0x1f030b9f1a91d74610cb296aa87f12b2207d2b336766fffad8c53b825f1bee7d30f3665076102fe635dd3664d564ae1e5e746794b58e8861feafacfa6767ea491b", + "properties": { + "type": "IP-NFT", + "initial_symbol": "AWSOME", + "agreements": [ + { + "type": "Research Agreement", + "url": "ipfs://bafkreigqttkfe2vsgddhy4ohf3qs3eyacdz2vwindo33y7jefox3377yqq", + "mime_type": "application/pdf", + "content_hash": "bagaaiera7ftqs3jmnoph3zgq67bgjrszlqtxkk5ygadgjvnihukrqioipndq", + "encryption": { + "protocol": "lit", + "encrypted_sym_key": "dff20fe5fc6aace9669a2afc25745350208825c073c6b8e280dbf02ca772747288e3f0ea122cb89dd9531331bf828819f98c24aa675966c236159c75461a182759d1f3fc9322932cb69ed7f4c125685362137b28fac26069a0fe6a304c8dd28a64ab484b7f610d608232c9104f155b38344fc79992a2a1afabf8137395e1c4f40000000000000020990610adf31cab49dddf73c9466772c96d9c85e48fc6bf8a29da685b204b6cb03ea6509ddf117ae3a52ee637d450e08b", + "access_control_conditions": [ + { + "conditionType": "evmContract", + "contractAddress": "0x152B444e60C526fe4434C721561a077269FcF61a", + "chain": "sepolia", + "functionName": "canRead", + "functionParams": [":userAddress", "76"], + "functionAbi": { + "inputs": [ + { + "internalType": "address", + "name": "reader", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "canRead", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + "returnValueTest": { + "key": "", + "comparator": "=", + "value": "true" + } + } + ] + } + }, + { + "type": "Assignment Agreement", + "url": "ipfs://bafkreihzm4ew2ldltz66juhxyjsmmwk4e52sxobqazsnlkb5cumcdsd3i4", + "mime_type": "application/pdf", + "content_hash": "bagaaiera7ftqs3jmnoph3zgq67bgjrszlqtxkk5ygadgjvnihukrqioipndq" + } + ], + "project_details": { + "industry": "Space Exploration", + "organization": "NASA", + "topic": "Wormholes", + "funding_amount": { + "value": 1234.5678, + "decimals": 2, + "currency": "USD", + "currency_type": "ISO4217" + }, + "research_lead": { + "name": "Carl Sagan", + "email": "carl@example.com" + } + } + } +} diff --git a/subgraph/tests/metadata.test.ts b/subgraph/tests/metadata.test.ts new file mode 100644 index 00000000..38bc4ebf --- /dev/null +++ b/subgraph/tests/metadata.test.ts @@ -0,0 +1,28 @@ +import { ipfs } from "@graphprotocol/graph-ts" +import { assert, describe, mockIpfsFile, test } from 'matchstick-as/assembly/index' +import { handleMetadata } from '../src/metadataMapping' + +const IPNFT_METADATA = "IpnftMetadata" + +describe('Metadata', () => { + //https://thegraph.com/docs/en/subgraphs/developing/creating/unit-testing-framework/#mocking-ipfs-files-from-matchstick-041 + + test('reads ipnft metadata', () => { + + mockIpfsFile('ipfsCatBaseIpnft', 'tests/fixtures/ipnft_1.json') + + let rawData = ipfs.cat("ipfsCatBaseIpnft") + if (!rawData) { + throw new Error("Failed to fetch ipfs data") + } + + handleMetadata(rawData) + assert.entityCount(IPNFT_METADATA, 1) + assert.fieldEquals(IPNFT_METADATA, '', 'topic', 'Wormholes') + assert.fieldEquals(IPNFT_METADATA, '', 'fundingAmount_value', '1234.5678') + assert.fieldEquals(IPNFT_METADATA, '', 'fundingAmount_currency', 'USD') + + //logStore() + }) +}) +