create-ponder 0.0.78 → 0.0.79
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/dist/bin/create-ponder.d.ts +3 -0
- package/dist/bin/create-ponder.d.ts.map +1 -0
- package/dist/bin/create-ponder.js +105 -0
- package/dist/bin/create-ponder.js.map +1 -0
- package/dist/common.d.ts +23 -0
- package/dist/common.d.ts.map +1 -0
- package/dist/common.js +11 -0
- package/dist/common.js.map +1 -0
- package/dist/helpers/getEtherscanChainId.d.ts +6 -0
- package/dist/helpers/getEtherscanChainId.d.ts.map +1 -0
- package/dist/helpers/getEtherscanChainId.js +75 -0
- package/dist/helpers/getEtherscanChainId.js.map +1 -0
- package/dist/helpers/getGraphProtocolChainId.d.ts +3 -0
- package/dist/helpers/getGraphProtocolChainId.d.ts.map +1 -0
- package/dist/helpers/getGraphProtocolChainId.js +42 -0
- package/dist/helpers/getGraphProtocolChainId.js.map +1 -0
- package/dist/helpers/getPackageManager.d.ts +2 -0
- package/dist/helpers/getPackageManager.d.ts.map +1 -0
- package/dist/helpers/getPackageManager.js +18 -0
- package/dist/helpers/getPackageManager.js.map +1 -0
- package/dist/helpers/git.d.ts +2 -0
- package/dist/helpers/git.d.ts.map +1 -0
- package/dist/helpers/git.js +56 -0
- package/dist/helpers/git.js.map +1 -0
- package/dist/helpers/validateGraphProtocolSource.d.ts +28 -0
- package/dist/helpers/validateGraphProtocolSource.d.ts.map +1 -0
- package/dist/helpers/validateGraphProtocolSource.js +8 -0
- package/dist/helpers/validateGraphProtocolSource.js.map +1 -0
- package/dist/helpers/wait.d.ts +2 -0
- package/dist/helpers/wait.d.ts.map +1 -0
- package/dist/helpers/wait.js +6 -0
- package/dist/helpers/wait.js.map +1 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +168 -0
- package/dist/index.js.map +1 -0
- package/dist/templates/basic.d.ts +5 -0
- package/dist/templates/basic.d.ts.map +1 -0
- package/dist/templates/basic.js +57 -0
- package/dist/templates/basic.js.map +1 -0
- package/dist/templates/etherscan.d.ts +7 -0
- package/dist/templates/etherscan.d.ts.map +1 -0
- package/dist/templates/etherscan.js +199 -0
- package/dist/templates/etherscan.js.map +1 -0
- package/dist/templates/subgraphId.d.ts +6 -0
- package/dist/templates/subgraphId.d.ts.map +1 -0
- package/dist/templates/subgraphId.js +76 -0
- package/dist/templates/subgraphId.js.map +1 -0
- package/dist/templates/subgraphRepo.d.ts +6 -0
- package/dist/templates/subgraphRepo.d.ts.map +1 -0
- package/dist/templates/subgraphRepo.js +86 -0
- package/dist/templates/subgraphRepo.js.map +1 -0
- package/package.json +15 -11
- package/src/bin/create-ponder.ts +127 -0
- package/src/common.ts +27 -0
- package/src/helpers/getEtherscanChainId.ts +74 -0
- package/src/helpers/getGraphProtocolChainId.ts +41 -0
- package/src/helpers/getPackageManager.ts +11 -0
- package/src/helpers/git.ts +51 -0
- package/src/helpers/validateGraphProtocolSource.ts +42 -0
- package/src/helpers/wait.ts +2 -0
- package/src/index.ts +244 -0
- package/src/templates/basic.ts +60 -0
- package/src/templates/etherscan.ts +276 -0
- package/src/templates/subgraphId.ts +97 -0
- package/src/templates/subgraphRepo.ts +116 -0
- package/dist/create-ponder.d.ts +0 -1
- package/dist/create-ponder.js +0 -937
- package/dist/create-ponder.js.map +0 -1
- package/dist/create-ponder.mjs +0 -914
- package/dist/create-ponder.mjs.map +0 -1
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.fromSubgraphRepo = void 0;
|
|
7
|
+
const node_fs_1 = require("node:fs");
|
|
8
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
9
|
+
const prettier_1 = __importDefault(require("prettier"));
|
|
10
|
+
const yaml_1 = require("yaml");
|
|
11
|
+
const getGraphProtocolChainId_1 = require("../helpers/getGraphProtocolChainId");
|
|
12
|
+
const validateGraphProtocolSource_1 = require("../helpers/validateGraphProtocolSource");
|
|
13
|
+
const fromSubgraphRepo = ({ rootDir, subgraphPath, }) => {
|
|
14
|
+
const subgraphRootDir = node_path_1.default.resolve(subgraphPath);
|
|
15
|
+
const ponderNetworks = [];
|
|
16
|
+
let ponderContracts = [];
|
|
17
|
+
// If the `--from-subgraph` option was passed, parse subgraph files
|
|
18
|
+
const subgraphRootDirPath = node_path_1.default.resolve(subgraphRootDir);
|
|
19
|
+
// Read and parse the subgraph YAML file.
|
|
20
|
+
let subgraphYamlRaw = "";
|
|
21
|
+
for (const subgraphYamlFileName of getGraphProtocolChainId_1.subgraphYamlFileNames) {
|
|
22
|
+
try {
|
|
23
|
+
subgraphYamlRaw = (0, node_fs_1.readFileSync)(node_path_1.default.join(subgraphRootDirPath, subgraphYamlFileName), {
|
|
24
|
+
encoding: "utf-8",
|
|
25
|
+
});
|
|
26
|
+
break;
|
|
27
|
+
}
|
|
28
|
+
catch (e) {
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
if (subgraphYamlRaw === "") {
|
|
33
|
+
throw new Error(`subgraph.yaml file not found`);
|
|
34
|
+
}
|
|
35
|
+
const subgraphYaml = (0, yaml_1.parse)(subgraphYamlRaw);
|
|
36
|
+
// Copy over the schema.graphql file.
|
|
37
|
+
const schemaRaw = (0, node_fs_1.readFileSync)(node_path_1.default.join(subgraphRootDirPath, subgraphYaml.schema.file), {
|
|
38
|
+
encoding: "utf-8",
|
|
39
|
+
});
|
|
40
|
+
const schemaCleaned = schemaRaw
|
|
41
|
+
.replaceAll(": ID!", ": String!")
|
|
42
|
+
.replaceAll("BigDecimal", "Float");
|
|
43
|
+
(0, node_fs_1.writeFileSync)(node_path_1.default.join(rootDir, "schema.graphql"), prettier_1.default.format(schemaCleaned, { parser: "graphql" }));
|
|
44
|
+
// Build the ponder sources. Also copy over the ABI files for each source.
|
|
45
|
+
ponderContracts = subgraphYaml.dataSources
|
|
46
|
+
.map(validateGraphProtocolSource_1.validateGraphProtocolSource)
|
|
47
|
+
.map((source) => {
|
|
48
|
+
const abiPath = source.mapping.abis.find((abi) => abi.name === source.name)?.file;
|
|
49
|
+
if (!abiPath) {
|
|
50
|
+
throw new Error(`ABI path not found for source: ${source.name}`);
|
|
51
|
+
}
|
|
52
|
+
const network = source.network || "mainnet";
|
|
53
|
+
const chainId = (0, getGraphProtocolChainId_1.getGraphProtocolChainId)(network);
|
|
54
|
+
if (!chainId || chainId === -1) {
|
|
55
|
+
throw new Error(`Unhandled network name: ${network}`);
|
|
56
|
+
}
|
|
57
|
+
if (!ponderNetworks.map((n) => n.name).includes(network)) {
|
|
58
|
+
ponderNetworks.push({
|
|
59
|
+
name: network,
|
|
60
|
+
chainId: chainId,
|
|
61
|
+
rpcUrl: `process.env.PONDER_RPC_URL_${chainId}`,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
// Copy the ABI file.
|
|
65
|
+
const abiAbsolutePath = node_path_1.default.join(subgraphRootDirPath, abiPath);
|
|
66
|
+
const abiFileName = node_path_1.default.basename(abiPath);
|
|
67
|
+
const ponderAbiRelativePath = `./abis/${abiFileName}`;
|
|
68
|
+
const ponderAbiAbsolutePath = node_path_1.default.join(rootDir, ponderAbiRelativePath);
|
|
69
|
+
(0, node_fs_1.copyFileSync)(abiAbsolutePath, ponderAbiAbsolutePath);
|
|
70
|
+
return {
|
|
71
|
+
name: source.name,
|
|
72
|
+
network: network,
|
|
73
|
+
address: source.source.address,
|
|
74
|
+
abi: ponderAbiRelativePath,
|
|
75
|
+
startBlock: source.source.startBlock,
|
|
76
|
+
};
|
|
77
|
+
});
|
|
78
|
+
// Build the partial ponder config.
|
|
79
|
+
const config = {
|
|
80
|
+
networks: ponderNetworks,
|
|
81
|
+
contracts: ponderContracts,
|
|
82
|
+
};
|
|
83
|
+
return config;
|
|
84
|
+
};
|
|
85
|
+
exports.fromSubgraphRepo = fromSubgraphRepo;
|
|
86
|
+
//# sourceMappingURL=subgraphRepo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subgraphRepo.js","sourceRoot":"","sources":["../../src/templates/subgraphRepo.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-ponder",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.0.79",
|
|
4
|
+
"description": "A CLI tool to create Ponder apps",
|
|
5
5
|
"license": "MIT",
|
|
6
|
-
"author": "olias.eth",
|
|
7
6
|
"files": [
|
|
8
|
-
"dist"
|
|
7
|
+
"dist",
|
|
8
|
+
"src/**/*.ts",
|
|
9
|
+
"!src/**/*.test.ts"
|
|
9
10
|
],
|
|
10
11
|
"bin": {
|
|
11
|
-
"
|
|
12
|
+
"ponder": "./dist/bin/create-ponder.js"
|
|
12
13
|
},
|
|
13
14
|
"dependencies": {
|
|
14
15
|
"cac": "^6.7.14",
|
|
@@ -18,7 +19,6 @@
|
|
|
18
19
|
"picocolors": "^1.0.0",
|
|
19
20
|
"prettier": "^2.6.2",
|
|
20
21
|
"prompts": "^2.4.2",
|
|
21
|
-
"rimraf": "^5.0.1",
|
|
22
22
|
"yaml": "^2.1.1"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
@@ -27,15 +27,19 @@
|
|
|
27
27
|
"@types/prettier": "^2.7.1",
|
|
28
28
|
"@types/prompts": "^2.4.2",
|
|
29
29
|
"abitype": "^0.6.7",
|
|
30
|
-
"
|
|
31
|
-
"
|
|
30
|
+
"concurrently": "^8.2.0",
|
|
31
|
+
"rimraf": "^5.0.1",
|
|
32
|
+
"tsc-alias": "^1.8.2",
|
|
33
|
+
"typescript": "^5.1.3",
|
|
32
34
|
"vitest": "^0.29.2",
|
|
33
|
-
"@ponder/core": "0.0.
|
|
35
|
+
"@ponder/core": "0.0.79"
|
|
34
36
|
},
|
|
35
37
|
"scripts": {
|
|
36
|
-
"build": "
|
|
38
|
+
"build": "pnpm clean && tsc --project tsconfig.build.json && tsc-alias --project tsconfig.build.json",
|
|
39
|
+
"build:watch": "concurrently \"tsc --project tsconfig.build.json --watch\" \"tsc-alias --project tsconfig.build.json --watch\"",
|
|
40
|
+
"clean": "rimraf ./dist",
|
|
37
41
|
"test": "export $(grep -v '^#' .env.local | xargs) && vitest --no-threads",
|
|
38
42
|
"test:ci": "vitest --no-threads",
|
|
39
|
-
"typecheck": "tsc --noEmit"
|
|
43
|
+
"typecheck": "tsc --project tsconfig.json --noEmit"
|
|
40
44
|
}
|
|
41
45
|
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { cac } from "cac";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import prompts from "prompts";
|
|
5
|
+
|
|
6
|
+
import { CreatePonderOptions, Template, TemplateKind } from "@/common";
|
|
7
|
+
import { run } from "@/index";
|
|
8
|
+
|
|
9
|
+
// NOTE: This is a workaround for tsconfig `rootDir` nonsense.
|
|
10
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
11
|
+
// @ts-ignore
|
|
12
|
+
import packageJson from "../../package.json";
|
|
13
|
+
|
|
14
|
+
const createPonder = async () => {
|
|
15
|
+
const cli = cac(packageJson.name)
|
|
16
|
+
.version(packageJson.version)
|
|
17
|
+
.usage("[options]")
|
|
18
|
+
.help()
|
|
19
|
+
.option("--dir [path]", "Path to directory for generated project")
|
|
20
|
+
.option("--from-subgraph-id [id]", "Subgraph deployment ID")
|
|
21
|
+
.option("--from-subgraph-repo [path]", "Path to subgraph repository")
|
|
22
|
+
.option("--from-etherscan [url]", "Link to etherscan contract page")
|
|
23
|
+
.option("--etherscan-api-key [key]", "Etherscan API key");
|
|
24
|
+
|
|
25
|
+
const parsed = cli.parse(process.argv);
|
|
26
|
+
|
|
27
|
+
const options = parsed.options as {
|
|
28
|
+
help?: boolean;
|
|
29
|
+
dir?: string;
|
|
30
|
+
fromSubgraphId?: string;
|
|
31
|
+
fromSubgraphRepo?: string;
|
|
32
|
+
fromEtherscan?: string;
|
|
33
|
+
etherscanApiKey?: string;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
if (options.help) {
|
|
37
|
+
process.exit(0);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const { fromEtherscan, fromSubgraphId, fromSubgraphRepo } = options;
|
|
41
|
+
|
|
42
|
+
// Validate CLI options.
|
|
43
|
+
if (
|
|
44
|
+
(fromSubgraphId && fromSubgraphRepo) ||
|
|
45
|
+
(fromSubgraphId && fromEtherscan) ||
|
|
46
|
+
(fromSubgraphRepo && fromEtherscan)
|
|
47
|
+
) {
|
|
48
|
+
throw new Error(
|
|
49
|
+
`Cannot specify more than one "--from" option:\n --from-subgraph\n --from-etherscan-id\n --from-etherscan-repo`
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const { projectName } = await prompts({
|
|
54
|
+
type: "text",
|
|
55
|
+
name: "projectName",
|
|
56
|
+
message: "What is your project named?",
|
|
57
|
+
initial: "my-app",
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
// Get template from options if provided.
|
|
61
|
+
let template: Template | undefined = undefined;
|
|
62
|
+
if (fromEtherscan) {
|
|
63
|
+
template = { kind: TemplateKind.ETHERSCAN, link: fromEtherscan };
|
|
64
|
+
}
|
|
65
|
+
if (fromSubgraphId) {
|
|
66
|
+
template = { kind: TemplateKind.SUBGRAPH_ID, id: fromSubgraphId };
|
|
67
|
+
}
|
|
68
|
+
if (fromSubgraphRepo) {
|
|
69
|
+
template = { kind: TemplateKind.SUBGRAPH_REPO, path: fromSubgraphRepo };
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Get template from prompts if not provided.
|
|
73
|
+
if (!fromSubgraphId && !fromSubgraphRepo && !fromEtherscan) {
|
|
74
|
+
const { template: templateKind } = await prompts({
|
|
75
|
+
type: "select",
|
|
76
|
+
name: "template",
|
|
77
|
+
message: "Would you like to use a template for this project?",
|
|
78
|
+
choices: [
|
|
79
|
+
{ title: "None" },
|
|
80
|
+
{ title: "Etherscan contract link" },
|
|
81
|
+
{ title: "Subgraph ID" },
|
|
82
|
+
{ title: "Subgraph repository" },
|
|
83
|
+
],
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
if (templateKind === TemplateKind.ETHERSCAN) {
|
|
87
|
+
const { link } = await prompts({
|
|
88
|
+
type: "text",
|
|
89
|
+
name: "link",
|
|
90
|
+
message: "Enter an Etherscan contract link",
|
|
91
|
+
initial: "https://etherscan.io/address/0x97...",
|
|
92
|
+
});
|
|
93
|
+
template = { kind: TemplateKind.ETHERSCAN, link };
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (templateKind === TemplateKind.SUBGRAPH_ID) {
|
|
97
|
+
const { id } = await prompts({
|
|
98
|
+
type: "text",
|
|
99
|
+
name: "id",
|
|
100
|
+
message: "Enter a subgraph deployment ID",
|
|
101
|
+
initial: "QmNus...",
|
|
102
|
+
});
|
|
103
|
+
template = { kind: TemplateKind.SUBGRAPH_ID, id };
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (templateKind === TemplateKind.SUBGRAPH_REPO) {
|
|
107
|
+
const { path } = await prompts({
|
|
108
|
+
type: "text",
|
|
109
|
+
name: "path",
|
|
110
|
+
message: "Enter a path to a subgraph repository",
|
|
111
|
+
initial: "../subgraph",
|
|
112
|
+
});
|
|
113
|
+
template = { kind: TemplateKind.SUBGRAPH_REPO, path };
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const validatedOptions: CreatePonderOptions = {
|
|
118
|
+
projectName,
|
|
119
|
+
rootDir: path.resolve(".", options.dir ? options.dir : projectName),
|
|
120
|
+
template,
|
|
121
|
+
etherscanApiKey: options.etherscanApiKey,
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
await run(validatedOptions);
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
createPonder();
|
package/src/common.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export enum TemplateKind {
|
|
2
|
+
NONE,
|
|
3
|
+
ETHERSCAN,
|
|
4
|
+
SUBGRAPH_ID,
|
|
5
|
+
SUBGRAPH_REPO,
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export type Template =
|
|
9
|
+
| {
|
|
10
|
+
kind: TemplateKind.ETHERSCAN;
|
|
11
|
+
link: string;
|
|
12
|
+
}
|
|
13
|
+
| {
|
|
14
|
+
kind: TemplateKind.SUBGRAPH_ID;
|
|
15
|
+
id: string;
|
|
16
|
+
}
|
|
17
|
+
| {
|
|
18
|
+
kind: TemplateKind.SUBGRAPH_REPO;
|
|
19
|
+
path: string;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export interface CreatePonderOptions {
|
|
23
|
+
rootDir: string;
|
|
24
|
+
projectName: string;
|
|
25
|
+
template?: Template;
|
|
26
|
+
etherscanApiKey?: string;
|
|
27
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
const networkByEtherscanHostname: Record<
|
|
2
|
+
string,
|
|
3
|
+
{ name: string; chainId: number; apiUrl: string } | undefined
|
|
4
|
+
> = {
|
|
5
|
+
"etherscan.io": {
|
|
6
|
+
name: "mainnet",
|
|
7
|
+
chainId: 1,
|
|
8
|
+
apiUrl: "https://api.etherscan.io/api",
|
|
9
|
+
},
|
|
10
|
+
"ropsten.etherscan.io": {
|
|
11
|
+
name: "ropsten",
|
|
12
|
+
chainId: 3,
|
|
13
|
+
apiUrl: "https://api-ropsten.etherscan.io/api",
|
|
14
|
+
},
|
|
15
|
+
"rinkeby.etherscan.io": {
|
|
16
|
+
name: "rinkeby",
|
|
17
|
+
chainId: 4,
|
|
18
|
+
apiUrl: "https://api-rinkeby.etherscan.io/api",
|
|
19
|
+
},
|
|
20
|
+
"goerli.etherscan.io": {
|
|
21
|
+
name: "goerli",
|
|
22
|
+
chainId: 5,
|
|
23
|
+
apiUrl: "https://api-goerli.etherscan.io/api",
|
|
24
|
+
},
|
|
25
|
+
"kovan.etherscan.io": {
|
|
26
|
+
name: "kovan",
|
|
27
|
+
chainId: 42,
|
|
28
|
+
apiUrl: "https://api-kovan.etherscan.io/api",
|
|
29
|
+
},
|
|
30
|
+
"sepolia.etherscan.io": {
|
|
31
|
+
name: "sepolia",
|
|
32
|
+
chainId: 11155111,
|
|
33
|
+
apiUrl: "https://api-sepolia.etherscan.io/api",
|
|
34
|
+
},
|
|
35
|
+
"optimistic.etherscan.io": {
|
|
36
|
+
name: "optimism",
|
|
37
|
+
chainId: 10,
|
|
38
|
+
apiUrl: "https://api-optimistic.etherscan.io/api",
|
|
39
|
+
},
|
|
40
|
+
"goerli-optimism.etherscan.io": {
|
|
41
|
+
name: "optimism-goerli",
|
|
42
|
+
chainId: 420,
|
|
43
|
+
apiUrl: "https://api-goerli-optimistic.etherscan.io/api",
|
|
44
|
+
},
|
|
45
|
+
"polygonscan.com": {
|
|
46
|
+
name: "polygon",
|
|
47
|
+
chainId: 137,
|
|
48
|
+
apiUrl: "https://api.polygonscan.com/api",
|
|
49
|
+
},
|
|
50
|
+
"mumbai.polygonscan.com": {
|
|
51
|
+
name: "polygon-mumbai",
|
|
52
|
+
chainId: 80001,
|
|
53
|
+
apiUrl: "https://api-testnet.polygonscan.com/api",
|
|
54
|
+
},
|
|
55
|
+
"arbiscan.io": {
|
|
56
|
+
name: "arbitrum",
|
|
57
|
+
chainId: 42161,
|
|
58
|
+
apiUrl: "https://api.arbiscan.io/api",
|
|
59
|
+
},
|
|
60
|
+
"goerli.arbiscan.io": {
|
|
61
|
+
name: "arbitrum-goerli",
|
|
62
|
+
chainId: 421613,
|
|
63
|
+
apiUrl: "https://api-goerli.arbiscan.io/api",
|
|
64
|
+
},
|
|
65
|
+
"explorer.zora.energy": {
|
|
66
|
+
name: "zora",
|
|
67
|
+
chainId: 7777777,
|
|
68
|
+
apiUrl: "https://explorer.zora.energy/api",
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
export const getNetworkByEtherscanHostname = (hostname: string) => {
|
|
73
|
+
return networkByEtherscanHostname[hostname];
|
|
74
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// https://github.com/graphprotocol/graph-cli/blob/main/src/protocols/index.js#L40
|
|
2
|
+
// https://chainlist.org/
|
|
3
|
+
const chainIdByGraphNetwork: Record<string, number | undefined> = {
|
|
4
|
+
mainnet: 1,
|
|
5
|
+
kovan: 42,
|
|
6
|
+
rinkeby: 4,
|
|
7
|
+
ropsten: 3,
|
|
8
|
+
goerli: 5,
|
|
9
|
+
"poa-core": 99,
|
|
10
|
+
"poa-sokol": 77,
|
|
11
|
+
xdai: 100,
|
|
12
|
+
matic: 137,
|
|
13
|
+
mumbai: 80001,
|
|
14
|
+
fantom: 250,
|
|
15
|
+
"fantom-testnet": 4002,
|
|
16
|
+
bsc: 56,
|
|
17
|
+
chapel: -1,
|
|
18
|
+
clover: 0,
|
|
19
|
+
avalanche: 43114,
|
|
20
|
+
fuji: 43113,
|
|
21
|
+
celo: 42220,
|
|
22
|
+
"celo-alfajores": 44787,
|
|
23
|
+
fuse: 122,
|
|
24
|
+
moonbeam: 1284,
|
|
25
|
+
moonriver: 1285,
|
|
26
|
+
mbase: -1,
|
|
27
|
+
"arbitrum-one": 42161,
|
|
28
|
+
"arbitrum-rinkeby": 421611,
|
|
29
|
+
optimism: 10,
|
|
30
|
+
"optimism-kovan": 69,
|
|
31
|
+
aurora: 1313161554,
|
|
32
|
+
"aurora-testnet": 1313161555,
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export const getGraphProtocolChainId = (networkName: string) => {
|
|
36
|
+
return chainIdByGraphNetwork[networkName];
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export const subgraphYamlFileNames = ["subgraph.yaml"].concat(
|
|
40
|
+
Object.keys(chainIdByGraphNetwork).map((n) => `subgraph-${n}.yaml`)
|
|
41
|
+
);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { detect } from "detect-package-manager";
|
|
2
|
+
|
|
3
|
+
export function getPackageManager() {
|
|
4
|
+
const userAgent = process.env.npm_config_user_agent;
|
|
5
|
+
if (userAgent) {
|
|
6
|
+
if (userAgent.includes("pnpm")) return "pnpm";
|
|
7
|
+
if (userAgent.includes("npm")) return "npm";
|
|
8
|
+
if (userAgent.includes("yarn")) return "yarn";
|
|
9
|
+
}
|
|
10
|
+
return detect();
|
|
11
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/* eslint-disable no-empty */
|
|
2
|
+
import { execSync } from "child_process";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import rimraf from "rimraf";
|
|
5
|
+
|
|
6
|
+
// File adapted from next.js
|
|
7
|
+
// https://github.dev/vercel/next.js/blob/9ad1f321b7902542acd2be041fb2f15f023a0ed9/packages/create-next-app/helpers/git.ts
|
|
8
|
+
|
|
9
|
+
function isInGitRepository(): boolean {
|
|
10
|
+
try {
|
|
11
|
+
execSync("git rev-parse --is-inside-work-tree", { stdio: "ignore" });
|
|
12
|
+
return true;
|
|
13
|
+
} catch (_) {}
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function isInMercurialRepository(): boolean {
|
|
18
|
+
try {
|
|
19
|
+
execSync("hg --cwd . root", { stdio: "ignore" });
|
|
20
|
+
return true;
|
|
21
|
+
} catch (_) {}
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function tryGitInit(root: string): boolean {
|
|
26
|
+
let didInit = false;
|
|
27
|
+
try {
|
|
28
|
+
execSync("git --version", { stdio: "ignore" });
|
|
29
|
+
if (isInGitRepository() || isInMercurialRepository()) {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
execSync("git init", { stdio: "ignore" });
|
|
34
|
+
didInit = true;
|
|
35
|
+
|
|
36
|
+
execSync("git checkout -b main", { stdio: "ignore" });
|
|
37
|
+
|
|
38
|
+
execSync("git add -A", { stdio: "ignore" });
|
|
39
|
+
execSync('git commit -m "chore: initial commit from create-ponder"', {
|
|
40
|
+
stdio: "ignore",
|
|
41
|
+
});
|
|
42
|
+
return true;
|
|
43
|
+
} catch (e) {
|
|
44
|
+
if (didInit) {
|
|
45
|
+
try {
|
|
46
|
+
rimraf.sync(path.join(root, ".git"));
|
|
47
|
+
} catch (_) {}
|
|
48
|
+
}
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// https://github.com/graphprotocol/graph-node/blob/master/docs/subgraph-manifest.md
|
|
2
|
+
export type GraphSource = {
|
|
3
|
+
kind: string; // Should be "ethereum"
|
|
4
|
+
name: string;
|
|
5
|
+
network: string;
|
|
6
|
+
source: {
|
|
7
|
+
address: string;
|
|
8
|
+
abi: string; // Keys into dataSource.mapping.abis
|
|
9
|
+
startBlock?: number;
|
|
10
|
+
};
|
|
11
|
+
mapping: {
|
|
12
|
+
kind: string; // Should be "ethereum/events"
|
|
13
|
+
apiVersion: string;
|
|
14
|
+
language: string; // Should be "wasm/assemblyscript"
|
|
15
|
+
entities: string[]; // Corresponds to entities by name defined in schema.graphql
|
|
16
|
+
abis: {
|
|
17
|
+
name: string;
|
|
18
|
+
file: any;
|
|
19
|
+
}[];
|
|
20
|
+
eventHandlers?: {
|
|
21
|
+
event: string;
|
|
22
|
+
handler: string;
|
|
23
|
+
topic0?: string;
|
|
24
|
+
}[];
|
|
25
|
+
// NOTE: Not planning to support callHandlers or blockHandlers.
|
|
26
|
+
// callHandlers?: {
|
|
27
|
+
// function: string;
|
|
28
|
+
// handler: string;
|
|
29
|
+
// }[];
|
|
30
|
+
// blockHandlers?: {
|
|
31
|
+
// handler: string;
|
|
32
|
+
// filter?: {
|
|
33
|
+
// kind: string;
|
|
34
|
+
// };
|
|
35
|
+
// }[];
|
|
36
|
+
file: string; // relative path to file that contains handlers for this source
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export const validateGraphProtocolSource = (source: unknown): GraphSource => {
|
|
41
|
+
return source as GraphSource;
|
|
42
|
+
};
|