-
Notifications
You must be signed in to change notification settings - Fork 0
/
mapping.ts
155 lines (143 loc) · 5.23 KB
/
mapping.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
import { Bytes, ipfs, json, JSONValueKind, log } from "@graphprotocol/graph-ts";
import { NewHash } from "../generated/Contract/Contract";
import { Channel, Transaction } from "../generated/schema";
import { computeHash, serializeTransaction } from "./hash-utils";
/**
* Handle a NewHash event
*/
export function handleNewHash(event: NewHash): void {
let ipfsHash = event.params.hash;
let transactionId = event.transaction.hash.toHex();
let blockNumberString = event.block.number.toString();
log.info("Retrieving and parsing IPFS hash {}, transaction ID {}, block {}", [
ipfsHash,
transactionId,
blockNumberString,
]);
let data = ipfs.cat(ipfsHash);
if (!data) {
log.warning(
"Could not retrieve IPFS hash {} from transaction ID {}, block {}",
[ipfsHash, transactionId, blockNumberString],
);
return;
}
let jsonValue = json.try_fromBytes(data as Bytes);
if (!jsonValue.isOk) {
log.warning(
"Parsing failed for IPFS hash {} from transaction ID {}, block {}",
[ipfsHash, transactionId, blockNumberString],
);
return;
}
if (jsonValue.value.kind !== JSONValueKind.OBJECT) {
log.warning(
"Invalid JSON in IPFS hash {} from transaction ID {}, block {}",
[ipfsHash, transactionId, blockNumberString],
);
return;
}
let doc = jsonValue.value.toObject();
let blockNumber = event.block.number.toI32();
let blockTimestamp = event.block.timestamp.toI32();
let address = event.address;
let feesParameters = event.params.feesParameters;
if (!doc.isSet("header") || !doc.isSet("transactions")) {
log.warning(
"No header or transactions field in IPFS hash {} from transaction ID {}, block {}",
[ipfsHash, transactionId, blockNumberString],
);
return;
}
let header = doc.get("header")!.toObject();
if (!header.isSet("channelIds") || !header.isSet("topics")) {
log.warning(
"No header.channelIds or header.topics in IPFS hash {} from transaction ID {}, block {}",
[ipfsHash, transactionId, blockNumberString],
);
return;
}
let channelIds = header.get("channelIds")!.toObject().entries;
let topics = header.get("topics")!.toObject();
let transactions = doc.get("transactions")!.toArray();
for (let txIndex = 0; txIndex < channelIds.length; ++txIndex) {
let channelId = channelIds[txIndex].key;
let index = channelIds[txIndex].value.toArray()[0].toBigInt().toI32();
log.info(
"Parsing channelId {} for IPFS hash {} from transaction ID {}, block {}",
[channelId, ipfsHash, transactionId, blockNumberString],
);
let entityId = ipfsHash + "-" + index.toString();
let entity = new Transaction(entityId);
let channel = Channel.load(channelId);
if (!channel) {
log.debug("new channel {}", [channelId]);
channel = new Channel(channelId);
channel.topics = [];
}
let transaction = transactions[index].toObject();
entity.channel = channelId;
let topicList: string[] = [];
let channelTopicList = channel.topics;
if (topics.isSet(channelId)) {
let topicsJsonVal = topics.get(channelId)!.toArray();
for (let i = 0; i < topicsJsonVal.length; ++i) {
let topic = topicsJsonVal[i].toString();
topicList.push(topic);
if (!channel.topics.includes(topic)) {
channelTopicList.push(topic);
}
}
}
channelTopicList.sort();
channel.topics = channelTopicList;
entity.hash = ipfsHash;
entity.channelId = channelId;
entity.blockNumber = blockNumber;
entity.blockTimestamp = blockTimestamp;
entity.smartContractAddress = address.toHex();
entity.transactionHash = transactionId;
entity.topics = topicList;
entity.size = feesParameters.toHex();
if (transaction.isSet("encryptedData")) {
let encData = transaction.getEntry("encryptedData")!.value;
entity.encryptedData = encData.toString();
// only the create action contains encryption information
if (transaction.isSet("encryptionMethod")) {
entity.encryptionMethod = transaction
.get("encryptionMethod")!
.toString();
}
if (transaction.isSet("keys")) {
let keys = transaction.get("keys")!.toObject().entries;
// keys are stored in 2 arrays for simplicity of DB model
let publicKeys: string[] = [];
let encryptedKeys: string[] = [];
for (let i = 0; i < keys.length; ++i) {
publicKeys.push(keys[i].key);
encryptedKeys.push(keys[i].value.toString());
}
entity.publicKeys = publicKeys;
entity.encryptedKeys = encryptedKeys;
}
} else if (transaction.isSet("data")) {
let data = transaction.getEntry("data")!.value;
if (data.kind !== JSONValueKind.STRING) {
log.warning(
"Invalid data field in IPFS hash {} from transaction ID {}, block {}",
[ipfsHash, transactionId, blockNumberString],
);
return;
}
entity.data = data.toString();
} else {
log.warning(
"Neither data or encryptedData found in IPFS hash {} from transaction ID {}, block {}",
[ipfsHash, transactionId, blockNumberString],
);
}
entity.dataHash = computeHash(serializeTransaction(entity));
entity.save();
channel.save();
}
}