forked from FrederikBolding/chainlist
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgatsby-node.js
More file actions
115 lines (104 loc) · 2.95 KB
/
gatsby-node.js
File metadata and controls
115 lines (104 loc) · 2.95 KB
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
const { createRemoteFileNode } = require("gatsby-source-filesystem");
const fetch = require("node-fetch");
const probe = require("probe-image-size");
const { createReadStream } = require("fs");
exports.sourceNodes = async ({
actions,
createNodeId,
createContentDigest,
store,
cache,
reporter,
}) => {
const { createNode } = actions;
const chains = await fetch("https://chainid.network/chains.json").then(
(response) => response.json()
);
const icons = await fetch("https://chainid.network/chain_icons.json").then(
(response) => response.json()
);
async function fetchIcon(name, file) {
const cid = file.url.slice(7);
const wrappedCreateNode = async (node, args) => {
const stream = createReadStream(node.absolutePath);
// Validate image type to prevent issues with invalid images
const imageSize = await probe(stream);
if (imageSize.type !== node.ext.slice(1)) {
throw new Error("Invalid image");
}
return await createNode(node, args);
};
// Try iconsDownload first as it is way faster.
try {
return await createRemoteFileNode({
url: `https://chainid.network/iconsDownload/${cid}`,
createNode: wrappedCreateNode,
createNodeId,
store,
cache,
reporter,
name,
ext: `.${file.format}`,
});
} catch {}
// Fallback to IPFS
try {
return await createRemoteFileNode({
url: `https://ipfs.io/ipfs/${cid}`,
createNode: wrappedCreateNode,
createNodeId,
store,
cache,
reporter,
name,
ext: `.${file.format}`,
});
} catch {}
return null;
}
const iconFiles = await icons.reduce(async (previousPromise, icon) => {
const iconName = icon.name;
const iconFile = icon.icons?.[0];
const result = await fetchIcon(iconName, iconFile);
const acc = await previousPromise;
if (result) {
acc[iconName] = result;
}
return acc;
}, Promise.resolve({}));
chains
// Filter out non HTTP(S) RPC URLs
.map((chain) => ({
...chain,
rpc: chain.rpc.filter(
(rpc) => rpc.startsWith("http://") || rpc.startsWith("https://")
),
}))
.filter((chain) => chain.rpc.length > 0)
.forEach((chain) => {
const icon = chain.icon;
const iconFileId = iconFiles[icon]?.id;
const chainData = { ...chain, icon: iconFileId };
const node = {
...chainData,
parent: null,
children: [],
id: createNodeId(`chain__${chainData.chainId}`),
internal: {
type: "Chain",
content: JSON.stringify(chainData),
contentDigest: createContentDigest(chainData),
},
};
createNode(node);
});
};
exports.createSchemaCustomization = ({ actions }) => {
const { createTypes } = actions;
const typeDefs = `
type Chain implements Node {
icon: File @link(from: "icon")
}
`;
createTypes(typeDefs);
};