Skip to content

Commit 653df84

Browse files
committed
feat: better-list-metadata-handling
1 parent 85ed0ad commit 653df84

File tree

9 files changed

+190
-56
lines changed

9 files changed

+190
-56
lines changed

contracts/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ Refresh the list of deployed contracts by running `./scripts/generateDeployments
1616

1717
#### Arbitrum Sepolia
1818

19-
- [CurateFactory](https://sepolia.arbiscan.io/address/0x5D03d22229899cd7Af84a3F0f9c39B24F51c8E21)
20-
- [CurateV2](https://sepolia.arbiscan.io/address/0x091Ba21a03aab5b4cfee5A770667cc53EF2cB1bc)
21-
- [CurateView](https://sepolia.arbiscan.io/address/0x7152126B8F9f9A9Bd20A37072D198F59773E61dA)
19+
- [CurateFactory](https://sepolia.arbiscan.io/address/0xcfd2315053763f6ae964f721e8a6Ea44286a9baF)
20+
- [CurateV2](https://sepolia.arbiscan.io/address/0xd9ea52247FeBd2258823Ff9f4fC49C9cD53fe8de)
21+
- [CurateView](https://sepolia.arbiscan.io/address/0x2532DBf9a2877C1FDd8286f8f9ef51b76184604F)
2222

2323
#### Sepolia
2424

contracts/deployments/arbitrumSepoliaDevnet/CurateFactory.json

Lines changed: 18 additions & 18 deletions
Large diffs are not rendered by default.

contracts/deployments/arbitrumSepoliaDevnet/CurateV2.json

Lines changed: 52 additions & 14 deletions
Large diffs are not rendered by default.

contracts/deployments/arbitrumSepoliaDevnet/CurateView.json

Lines changed: 13 additions & 13 deletions
Large diffs are not rendered by default.

contracts/src/CurateV2.sol

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,10 @@ contract CurateV2 is IArbitrableV2 {
132132
/// @param _connectedList The address of the connected Curate.
133133
event ConnectedListSet(address indexed _connectedList);
134134

135+
/// @dev Emitted when the list metadata ipfs uri is updated.
136+
/// @param _listMetadata Ipfs uri to list metadata.
137+
event ListMetadataSet(string _listMetadata);
138+
135139
// ************************************* //
136140
// * Initializer * //
137141
// ************************************* //
@@ -247,6 +251,12 @@ contract CurateV2 is IArbitrableV2 {
247251
emit ConnectedListSet(_connectedList);
248252
}
249253

254+
/// @dev Update list metadata ipfs uri.
255+
/// @param _listMetadata Ipfs uri to list metadata
256+
function changeListMetadata(string calldata _listMetadata) external onlyGovernor {
257+
emit ListMetadataSet(_listMetadata);
258+
}
259+
250260
/// @dev Change the address of the relay contract.
251261
/// @param _relayerContract The new address of the relay contract.
252262
function changeRelayerContract(address _relayerContract) external onlyGovernor {

subgraph/schema.graphql

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,24 @@ type Registry @entity {
5050
connectedList: Bytes
5151
"The address that registered the curate"
5252
registerer: User!
53-
"Registry metadata"
53+
"Registry's Title"
5454
title: String
55+
"Registry's description"
5556
description: String
57+
"A link to registry's logo."
5658
logoURI: String
59+
"A link to file describing registry's policy."
5760
policyURI: String
61+
"Field to identify if a list is a 'List of Lists.'"
62+
isListOfLists: Boolean
63+
"Item name for a item in registry."
64+
itemName: String
65+
"Plural item name for items in registry."
66+
itemNamePlural: String
67+
"Ipfs uri pointing to file containing the list metadata."
5868
metadataURI: String!
69+
"The parsed data describing the fields in Registry."
70+
fieldProps: [FieldProp!]! @derivedFrom(field: "registry")
5971
}
6072

6173
type Item @entity {
@@ -121,6 +133,15 @@ type ItemProp @entity {
121133
item: Item!
122134
}
123135

136+
type FieldProp @entity {
137+
id: ID!
138+
type: String!
139+
label: String!
140+
description: String!
141+
isIdentifier: Boolean!
142+
registry: Registry!
143+
}
144+
124145
type Request @entity {
125146
"The item ID (which is the keccak256 hash of its data)."
126147
id: ID!

subgraph/src/Curate.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@ import {
1010
Curate,
1111
DisputeRequest,
1212
ConnectedListSet,
13+
ListMetadataSet,
1314
} from "../generated/templates/Curate/Curate";
1415
import { ItemStatus, ONE, ZERO, getFinalRuling, getStatus } from "./utils";
1516
import { createRequestFromEvent } from "./entities/Request";
1617
import { createItemFromEvent } from "./entities/Item";
1718
import { ensureUser } from "./entities/User";
19+
import { updateRegistryMetadata } from "./CurateFactory";
1820

1921
// Items on a List can be in 1 of 4 states:
2022
// - (0) Absent: The item is not registered on the List and there are no pending requests.
@@ -132,6 +134,19 @@ export function handleConnectedListSet(event: ConnectedListSet): void {
132134
registry.save();
133135
}
134136

137+
export function handleListMetadataSet(event: ListMetadataSet): void {
138+
let registry = Registry.load(event.address.toHexString());
139+
if (!registry) {
140+
log.error(`Registry {} not found.`, [event.address.toHexString()]);
141+
return;
142+
}
143+
registry.metadataURI = event.params._listMetadata;
144+
145+
updateRegistryMetadata(registry.id, event.params._listMetadata);
146+
147+
registry.save();
148+
}
149+
135150
export function handleRuling(event: Ruling): void {
136151
let curate = Curate.bind(event.address);
137152
let itemID = curate.arbitratorDisputeIDToItemID(event.params._arbitrator, event.params._disputeID);

subgraph/src/CurateFactory.ts

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
/* eslint-disable prefer-const */
22
import { Bytes, ipfs, json, log } from "@graphprotocol/graph-ts";
33
import { NewList } from "../generated/CurateFactory/CurateFactory";
4-
import { Registry, User } from "../generated/schema";
4+
import { FieldProp, Registry, User } from "../generated/schema";
55
import { Curate } from "../generated/templates";
66
import { ensureCounter } from "./entities/Counters";
77
import { ensureUser } from "./entities/User";
8-
import { JSONValueToMaybeString, ONE } from "./utils";
8+
import { JSONValueToBool, JSONValueToMaybeString, ONE } from "./utils";
99

1010
export function handleNewCurate(event: NewList): void {
1111
Curate.create(event.params._address);
@@ -20,9 +20,24 @@ export function handleNewCurate(event: NewList): void {
2020
registry.registerer = ensureUser(event.transaction.from.toHexString()).id;
2121
registry.metadataURI = event.params._listMetadata;
2222

23-
let jsonStr = ipfs.cat(registry.metadataURI);
23+
counter.save();
24+
registry.save();
25+
updateRegistryMetadata(registry.id, event.params._listMetadata);
26+
}
27+
28+
export function updateRegistryMetadata(registryID: string, metadataURI: string): void {
29+
let registry = Registry.load(registryID);
30+
31+
if (!registry) {
32+
log.error(`Registry {} not found.`, [registryID]);
33+
return;
34+
}
35+
36+
registry.metadataURI = metadataURI;
37+
38+
let jsonStr = ipfs.cat(metadataURI);
2439
if (!jsonStr) {
25-
log.error("Failed to fetch registry metadata #{} JSON: {}", [registry.id, registry.metadataURI]);
40+
log.error("Failed to fetch registry metadata #{} JSON: {}", [registry.id, metadataURI]);
2641
registry.save();
2742
return;
2843
}
@@ -45,7 +60,40 @@ export function handleNewCurate(event: NewList): void {
4560
registry.description = JSONValueToMaybeString(jsonObj.get("description"));
4661
registry.logoURI = JSONValueToMaybeString(jsonObj.get("logoURI"));
4762
registry.policyURI = JSONValueToMaybeString(jsonObj.get("policyURI"));
63+
registry.itemName = JSONValueToMaybeString(jsonObj.get("itemName"));
64+
registry.itemNamePlural = JSONValueToMaybeString(jsonObj.get("itemNamePlural"));
65+
registry.isListOfLists = JSONValueToBool(jsonObj.get("isListOfLists"));
66+
67+
let columnsValue = jsonObj.get("columns");
68+
if (!columnsValue) {
69+
log.error(`Error getting column values for registry {}`, [registryID]);
70+
registry.save();
71+
return;
72+
}
73+
let columns = columnsValue.toArray();
74+
75+
for (let i = 0; i < columns.length; i++) {
76+
let col = columns[i];
77+
let colObj = col.toObject();
78+
79+
let label = colObj.get("label");
80+
81+
let checkedLabel = label ? label.toString() : "missing-label".concat(i.toString());
82+
83+
let description = colObj.get("description");
84+
let _type = colObj.get("type");
85+
let isIdentifier = colObj.get("isIdentifier");
86+
let fieldPropId = registryID + "@" + checkedLabel;
87+
let fieldProp = new FieldProp(fieldPropId);
88+
89+
fieldProp.type = JSONValueToMaybeString(_type);
90+
fieldProp.label = JSONValueToMaybeString(label);
91+
fieldProp.description = JSONValueToMaybeString(description);
92+
fieldProp.isIdentifier = JSONValueToBool(isIdentifier);
93+
fieldProp.registry = registry.id;
94+
95+
fieldProp.save();
96+
}
4897

49-
counter.save();
5098
registry.save();
5199
}

subgraph/subgraph.yaml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ dataSources:
1111
name: CurateFactory
1212
network: arbitrum-sepolia
1313
source:
14-
address: "0xF5B335323e1b8c219A9e0bF798a2bFf8325e1cE1"
14+
address: "0xcfd2315053763f6ae964f721e8a6Ea44286a9baF"
1515
abi: CurateFactory
16-
startBlock: 23023734
16+
startBlock: 23394953
1717
mapping:
1818
kind: ethereum/events
1919
apiVersion: 0.0.6
@@ -57,4 +57,6 @@ templates:
5757
handler: handleRuling
5858
- event: ConnectedListSet(indexed address)
5959
handler: handleConnectedListSet
60+
- event: ListMetadataSet(string)
61+
handler: handleListMetadataSet
6062
file: ./src/Curate.ts

0 commit comments

Comments
 (0)