create-ponder 0.0.1
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/README.md +1 -0
- package/dist/bin/create-ponder +42 -0
- package/dist/fromBasic.js +102 -0
- package/dist/fromEtherscan.js +168 -0
- package/dist/fromSubgraph.js +145 -0
- package/dist/helpers/detectPackageManager.js +109 -0
- package/dist/helpers/getEtherscanChainId.js +51 -0
- package/dist/helpers/getGraphProtocolChainId.js +71 -0
- package/dist/helpers/getPackageManager.js +54 -0
- package/dist/helpers/validateGraphProtocolSource.js +35 -0
- package/dist/index.js +281 -0
- package/package.json +43 -0
package/README.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Go to [docs on GitHub](https://github.com/0xOlias/ponder#readme)
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
18
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
19
|
+
mod
|
|
20
|
+
));
|
|
21
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
22
|
+
var create_ponder_exports = {};
|
|
23
|
+
module.exports = __toCommonJS(create_ponder_exports);
|
|
24
|
+
var import_commander = require("commander");
|
|
25
|
+
var import_node_path = __toESM(require("node:path"));
|
|
26
|
+
const program = new import_commander.Command();
|
|
27
|
+
program.description("Create a Ponder project").option("--dir <string>", "Path to directory for generated Ponder project").option("--from-subgraph <string>", "Path to subgraph directory").option("--from-etherscan <string>", "Link to etherscan contract page").option("--etherscan-api-key <string>", "Etherscan API key");
|
|
28
|
+
program.parse();
|
|
29
|
+
const options = program.opts();
|
|
30
|
+
if (options.fromSubgraph && options.fromEtherscan) {
|
|
31
|
+
throw new Error(`Cannot specify more than one "--from" option:
|
|
32
|
+
--from-subgraph
|
|
33
|
+
--from-etherscan
|
|
34
|
+
`);
|
|
35
|
+
}
|
|
36
|
+
const validatedOptions = {
|
|
37
|
+
ponderRootDir: import_node_path.default.resolve(options.dir ? options.dir : "ponder"),
|
|
38
|
+
fromSubgraph: options.fromSubgraph,
|
|
39
|
+
fromEtherscan: options.fromEtherscan,
|
|
40
|
+
etherscanApiKey: options.etherscanApiKey
|
|
41
|
+
};
|
|
42
|
+
require("../index").run(validatedOptions);
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if ((from && typeof from === "object") || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, {
|
|
17
|
+
get: () => from[key],
|
|
18
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable,
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
return to;
|
|
22
|
+
};
|
|
23
|
+
var __toESM = (mod, isNodeMode, target) => (
|
|
24
|
+
(target = mod != null ? __create(__getProtoOf(mod)) : {}),
|
|
25
|
+
__copyProps(
|
|
26
|
+
isNodeMode || !mod || !mod.__esModule
|
|
27
|
+
? __defProp(target, "default", { value: mod, enumerable: true })
|
|
28
|
+
: target,
|
|
29
|
+
mod
|
|
30
|
+
)
|
|
31
|
+
);
|
|
32
|
+
var __toCommonJS = (mod) =>
|
|
33
|
+
__copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
34
|
+
var fromBasic_exports = {};
|
|
35
|
+
__export(fromBasic_exports, {
|
|
36
|
+
fromBasic: () => fromBasic,
|
|
37
|
+
});
|
|
38
|
+
module.exports = __toCommonJS(fromBasic_exports);
|
|
39
|
+
var import_node_fs = require("node:fs");
|
|
40
|
+
var import_node_path = __toESM(require("node:path"));
|
|
41
|
+
var import_prettier = __toESM(require("prettier"));
|
|
42
|
+
const fromBasic = (options) => {
|
|
43
|
+
const { ponderRootDir } = options;
|
|
44
|
+
const abiFileContents = `[]`;
|
|
45
|
+
const abiRelativePath = "./abis/ExampleContract.json";
|
|
46
|
+
const abiAbsolutePath = import_node_path.default.join(
|
|
47
|
+
ponderRootDir,
|
|
48
|
+
abiRelativePath
|
|
49
|
+
);
|
|
50
|
+
(0, import_node_fs.writeFileSync)(abiAbsolutePath, abiFileContents);
|
|
51
|
+
const schemaGraphqlFileContents = `
|
|
52
|
+
type ExampleToken @entity {
|
|
53
|
+
id: ID!
|
|
54
|
+
tokenId: Int!
|
|
55
|
+
trait: TokenTrait!
|
|
56
|
+
}
|
|
57
|
+
enum TokenTrait {
|
|
58
|
+
GOOD
|
|
59
|
+
BAD
|
|
60
|
+
}
|
|
61
|
+
`;
|
|
62
|
+
const ponderSchemaFilePath = import_node_path.default.join(
|
|
63
|
+
ponderRootDir,
|
|
64
|
+
"schema.graphql"
|
|
65
|
+
);
|
|
66
|
+
(0, import_node_fs.writeFileSync)(
|
|
67
|
+
ponderSchemaFilePath,
|
|
68
|
+
import_prettier.default.format(schemaGraphqlFileContents, {
|
|
69
|
+
parser: "graphql",
|
|
70
|
+
})
|
|
71
|
+
);
|
|
72
|
+
const ponderConfig = {
|
|
73
|
+
plugins: ["graphqlPlugin()"],
|
|
74
|
+
database: {
|
|
75
|
+
kind: "sqlite",
|
|
76
|
+
},
|
|
77
|
+
networks: [
|
|
78
|
+
{
|
|
79
|
+
kind: "evm",
|
|
80
|
+
name: "mainnet",
|
|
81
|
+
chainId: 1,
|
|
82
|
+
rpcUrl: `process.env.PONDER_RPC_URL_1`,
|
|
83
|
+
},
|
|
84
|
+
],
|
|
85
|
+
sources: [
|
|
86
|
+
{
|
|
87
|
+
kind: "evm",
|
|
88
|
+
name: "ExampleContract",
|
|
89
|
+
network: "mainnet",
|
|
90
|
+
address: "0x0",
|
|
91
|
+
abi: abiRelativePath,
|
|
92
|
+
startBlock: 1234567,
|
|
93
|
+
},
|
|
94
|
+
],
|
|
95
|
+
};
|
|
96
|
+
return ponderConfig;
|
|
97
|
+
};
|
|
98
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
99
|
+
0 &&
|
|
100
|
+
(module.exports = {
|
|
101
|
+
fromBasic,
|
|
102
|
+
});
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if ((from && typeof from === "object") || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, {
|
|
17
|
+
get: () => from[key],
|
|
18
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable,
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
return to;
|
|
22
|
+
};
|
|
23
|
+
var __toESM = (mod, isNodeMode, target) => (
|
|
24
|
+
(target = mod != null ? __create(__getProtoOf(mod)) : {}),
|
|
25
|
+
__copyProps(
|
|
26
|
+
isNodeMode || !mod || !mod.__esModule
|
|
27
|
+
? __defProp(target, "default", { value: mod, enumerable: true })
|
|
28
|
+
: target,
|
|
29
|
+
mod
|
|
30
|
+
)
|
|
31
|
+
);
|
|
32
|
+
var __toCommonJS = (mod) =>
|
|
33
|
+
__copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
34
|
+
var fromEtherscan_exports = {};
|
|
35
|
+
__export(fromEtherscan_exports, {
|
|
36
|
+
fromEtherscan: () => fromEtherscan,
|
|
37
|
+
});
|
|
38
|
+
module.exports = __toCommonJS(fromEtherscan_exports);
|
|
39
|
+
var import_node_fs = require("node:fs");
|
|
40
|
+
var import_node_path = __toESM(require("node:path"));
|
|
41
|
+
var import_node_fetch = __toESM(require("node-fetch"));
|
|
42
|
+
var import_prettier = __toESM(require("prettier"));
|
|
43
|
+
var import_getEtherscanChainId = require("./helpers/getEtherscanChainId");
|
|
44
|
+
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
45
|
+
const fromEtherscan = async (options) => {
|
|
46
|
+
const { ponderRootDir } = options;
|
|
47
|
+
if (!options.fromEtherscan) {
|
|
48
|
+
throw new Error(`Internal error: fromEtherscan undefined`);
|
|
49
|
+
}
|
|
50
|
+
const apiKey = options.etherscanApiKey || process.env.ETHERSCAN_API_KEY;
|
|
51
|
+
const url = new URL(options.fromEtherscan);
|
|
52
|
+
const network = (0, import_getEtherscanChainId.getNetworkByEtherscanHostname)(
|
|
53
|
+
url.hostname
|
|
54
|
+
);
|
|
55
|
+
if (!network) {
|
|
56
|
+
throw new Error(`Unrecognized etherscan hostname: ${url.hostname}`);
|
|
57
|
+
}
|
|
58
|
+
const apiUrl = `https://api.${url.hostname}/api`;
|
|
59
|
+
const contractAddress = url.pathname.slice(1).split("/")[1];
|
|
60
|
+
const txHash = await getContractCreationTxn(contractAddress, apiUrl, apiKey);
|
|
61
|
+
if (!apiKey) {
|
|
62
|
+
console.log("(1/2) Waiting 5 seconds for Etherscan API rate limit");
|
|
63
|
+
await delay(5e3);
|
|
64
|
+
}
|
|
65
|
+
const blockNumber = await getTxBlockNumber(txHash, apiUrl, apiKey);
|
|
66
|
+
if (!apiKey) {
|
|
67
|
+
console.log("(2/2) Waiting 5 seconds for Etherscan API rate limit");
|
|
68
|
+
await delay(5e3);
|
|
69
|
+
}
|
|
70
|
+
const { abi, contractName } = await getContractAbiAndName(
|
|
71
|
+
contractAddress,
|
|
72
|
+
apiUrl,
|
|
73
|
+
apiKey
|
|
74
|
+
);
|
|
75
|
+
const abiRelativePath = `./abis/${contractName}.json`;
|
|
76
|
+
const abiAbsolutePath = import_node_path.default.join(
|
|
77
|
+
ponderRootDir,
|
|
78
|
+
abiRelativePath
|
|
79
|
+
);
|
|
80
|
+
(0, import_node_fs.writeFileSync)(abiAbsolutePath, abi);
|
|
81
|
+
const schemaGraphqlFileContents = `
|
|
82
|
+
type ExampleEntity @entity {
|
|
83
|
+
id: ID!
|
|
84
|
+
name: String!
|
|
85
|
+
}
|
|
86
|
+
`;
|
|
87
|
+
const ponderSchemaFilePath = import_node_path.default.join(
|
|
88
|
+
ponderRootDir,
|
|
89
|
+
"schema.graphql"
|
|
90
|
+
);
|
|
91
|
+
(0, import_node_fs.writeFileSync)(
|
|
92
|
+
ponderSchemaFilePath,
|
|
93
|
+
import_prettier.default.format(schemaGraphqlFileContents, {
|
|
94
|
+
parser: "graphql",
|
|
95
|
+
})
|
|
96
|
+
);
|
|
97
|
+
const ponderConfig = {
|
|
98
|
+
plugins: ["graphqlPlugin()"],
|
|
99
|
+
database: {
|
|
100
|
+
kind: "sqlite",
|
|
101
|
+
},
|
|
102
|
+
networks: [
|
|
103
|
+
{
|
|
104
|
+
kind: "evm",
|
|
105
|
+
name: network.name,
|
|
106
|
+
chainId: network.chainId,
|
|
107
|
+
rpcUrl: `process.env.PONDER_RPC_URL_${network.chainId}`,
|
|
108
|
+
},
|
|
109
|
+
],
|
|
110
|
+
sources: [
|
|
111
|
+
{
|
|
112
|
+
kind: "evm",
|
|
113
|
+
name: contractName,
|
|
114
|
+
network: network.name,
|
|
115
|
+
abi: abiRelativePath,
|
|
116
|
+
address: contractAddress,
|
|
117
|
+
startBlock: blockNumber,
|
|
118
|
+
},
|
|
119
|
+
],
|
|
120
|
+
};
|
|
121
|
+
return ponderConfig;
|
|
122
|
+
};
|
|
123
|
+
const fetchEtherscan = async (url) => {
|
|
124
|
+
const response = await (0, import_node_fetch.default)(url);
|
|
125
|
+
const data = await response.json();
|
|
126
|
+
if (data.status === "0") {
|
|
127
|
+
throw new Error(`Etherscan API error: ${data.result}`);
|
|
128
|
+
}
|
|
129
|
+
return data;
|
|
130
|
+
};
|
|
131
|
+
const getContractCreationTxn = async (contractAddress, apiUrl, apiKey) => {
|
|
132
|
+
const searchParams = new URLSearchParams({
|
|
133
|
+
module: "contract",
|
|
134
|
+
action: "getcontractcreation",
|
|
135
|
+
contractaddresses: contractAddress,
|
|
136
|
+
});
|
|
137
|
+
if (apiKey) searchParams.append("apikey", apiKey);
|
|
138
|
+
const data = await fetchEtherscan(`${apiUrl}?${searchParams.toString()}`);
|
|
139
|
+
return data.result[0].txHash;
|
|
140
|
+
};
|
|
141
|
+
const getTxBlockNumber = async (txHash, apiUrl, apiKey) => {
|
|
142
|
+
const searchParams = new URLSearchParams({
|
|
143
|
+
module: "proxy",
|
|
144
|
+
action: "eth_getTransactionByHash",
|
|
145
|
+
txhash: txHash,
|
|
146
|
+
});
|
|
147
|
+
if (apiKey) searchParams.append("apikey", apiKey);
|
|
148
|
+
const data = await fetchEtherscan(`${apiUrl}?${searchParams.toString()}`);
|
|
149
|
+
const hexBlockNumber = data.result.blockNumber;
|
|
150
|
+
return parseInt(hexBlockNumber.slice(2), 16);
|
|
151
|
+
};
|
|
152
|
+
const getContractAbiAndName = async (contractAddress, apiUrl, apiKey) => {
|
|
153
|
+
const searchParams = new URLSearchParams({
|
|
154
|
+
module: "contract",
|
|
155
|
+
action: "getsourcecode",
|
|
156
|
+
address: contractAddress,
|
|
157
|
+
});
|
|
158
|
+
if (apiKey) searchParams.append("apikey", apiKey);
|
|
159
|
+
const data = await fetchEtherscan(`${apiUrl}?${searchParams.toString()}`);
|
|
160
|
+
const abi = data.result[0].ABI;
|
|
161
|
+
const contractName = data.result[0].ContractName;
|
|
162
|
+
return { abi, contractName };
|
|
163
|
+
};
|
|
164
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
165
|
+
0 &&
|
|
166
|
+
(module.exports = {
|
|
167
|
+
fromEtherscan,
|
|
168
|
+
});
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if ((from && typeof from === "object") || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, {
|
|
17
|
+
get: () => from[key],
|
|
18
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable,
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
return to;
|
|
22
|
+
};
|
|
23
|
+
var __toESM = (mod, isNodeMode, target) => (
|
|
24
|
+
(target = mod != null ? __create(__getProtoOf(mod)) : {}),
|
|
25
|
+
__copyProps(
|
|
26
|
+
isNodeMode || !mod || !mod.__esModule
|
|
27
|
+
? __defProp(target, "default", { value: mod, enumerable: true })
|
|
28
|
+
: target,
|
|
29
|
+
mod
|
|
30
|
+
)
|
|
31
|
+
);
|
|
32
|
+
var __toCommonJS = (mod) =>
|
|
33
|
+
__copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
34
|
+
var fromSubgraph_exports = {};
|
|
35
|
+
__export(fromSubgraph_exports, {
|
|
36
|
+
fromSubgraph: () => fromSubgraph,
|
|
37
|
+
});
|
|
38
|
+
module.exports = __toCommonJS(fromSubgraph_exports);
|
|
39
|
+
var import_node_fs = require("node:fs");
|
|
40
|
+
var import_node_path = __toESM(require("node:path"));
|
|
41
|
+
var import_yaml = require("yaml");
|
|
42
|
+
var import_getGraphProtocolChainId = require("./helpers/getGraphProtocolChainId");
|
|
43
|
+
var import_validateGraphProtocolSource = require("./helpers/validateGraphProtocolSource");
|
|
44
|
+
const fromSubgraph = (options) => {
|
|
45
|
+
if (!options.fromSubgraph) {
|
|
46
|
+
throw new Error(`Internal error: fromSubgraph undefined`);
|
|
47
|
+
}
|
|
48
|
+
const { ponderRootDir } = options;
|
|
49
|
+
const subgraphRootDir = import_node_path.default.resolve(
|
|
50
|
+
options.fromSubgraph
|
|
51
|
+
);
|
|
52
|
+
const ponderNetworks = [];
|
|
53
|
+
let ponderSources = [];
|
|
54
|
+
const subgraphRootDirPath = import_node_path.default.resolve(subgraphRootDir);
|
|
55
|
+
let subgraphYamlRaw = "";
|
|
56
|
+
for (const subgraphYamlFileName of import_getGraphProtocolChainId.subgraphYamlFileNames) {
|
|
57
|
+
try {
|
|
58
|
+
subgraphYamlRaw = (0, import_node_fs.readFileSync)(
|
|
59
|
+
import_node_path.default.join(
|
|
60
|
+
subgraphRootDirPath,
|
|
61
|
+
subgraphYamlFileName
|
|
62
|
+
),
|
|
63
|
+
{
|
|
64
|
+
encoding: "utf-8",
|
|
65
|
+
}
|
|
66
|
+
);
|
|
67
|
+
break;
|
|
68
|
+
} catch (e) {
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (subgraphYamlRaw === "") {
|
|
73
|
+
throw new Error(`subgraph.yaml file not found`);
|
|
74
|
+
}
|
|
75
|
+
const subgraphYaml = (0, import_yaml.parse)(subgraphYamlRaw);
|
|
76
|
+
const subgraphSchemaFilePath = import_node_path.default.join(
|
|
77
|
+
subgraphRootDirPath,
|
|
78
|
+
subgraphYaml.schema.file
|
|
79
|
+
);
|
|
80
|
+
const ponderSchemaFilePath = import_node_path.default.join(
|
|
81
|
+
ponderRootDir,
|
|
82
|
+
"schema.graphql"
|
|
83
|
+
);
|
|
84
|
+
(0, import_node_fs.copyFileSync)(
|
|
85
|
+
subgraphSchemaFilePath,
|
|
86
|
+
ponderSchemaFilePath
|
|
87
|
+
);
|
|
88
|
+
ponderSources = subgraphYaml.dataSources
|
|
89
|
+
.map(import_validateGraphProtocolSource.validateGraphProtocolSource)
|
|
90
|
+
.map((source) => {
|
|
91
|
+
const abiPath = source.mapping.abis.find(
|
|
92
|
+
(abi) => abi.name === source.name
|
|
93
|
+
)?.file;
|
|
94
|
+
if (!abiPath) {
|
|
95
|
+
throw new Error(`ABI path not found for source: ${source.name}`);
|
|
96
|
+
}
|
|
97
|
+
const network = source.network || "mainnet";
|
|
98
|
+
const chainId = (0,
|
|
99
|
+
import_getGraphProtocolChainId.getGraphProtocolChainId)(network);
|
|
100
|
+
if (!chainId || chainId === -1) {
|
|
101
|
+
throw new Error(`Unhandled network name: ${network}`);
|
|
102
|
+
}
|
|
103
|
+
if (!ponderNetworks.map((n) => n.name).includes(network)) {
|
|
104
|
+
ponderNetworks.push({
|
|
105
|
+
kind: "evm",
|
|
106
|
+
name: network,
|
|
107
|
+
chainId,
|
|
108
|
+
rpcUrl: `process.env.PONDER_RPC_URL_${chainId}`,
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
const abiAbsolutePath = import_node_path.default.join(
|
|
112
|
+
subgraphRootDirPath,
|
|
113
|
+
abiPath
|
|
114
|
+
);
|
|
115
|
+
const abiFileName = import_node_path.default.basename(abiPath);
|
|
116
|
+
const ponderAbiRelativePath = `./abis/${abiFileName}`;
|
|
117
|
+
const ponderAbiAbsolutePath = import_node_path.default.join(
|
|
118
|
+
ponderRootDir,
|
|
119
|
+
ponderAbiRelativePath
|
|
120
|
+
);
|
|
121
|
+
(0, import_node_fs.copyFileSync)(abiAbsolutePath, ponderAbiAbsolutePath);
|
|
122
|
+
return {
|
|
123
|
+
kind: "evm",
|
|
124
|
+
name: source.name,
|
|
125
|
+
network,
|
|
126
|
+
address: source.source.address,
|
|
127
|
+
abi: ponderAbiRelativePath,
|
|
128
|
+
startBlock: source.source.startBlock,
|
|
129
|
+
};
|
|
130
|
+
});
|
|
131
|
+
const ponderConfig = {
|
|
132
|
+
plugins: ["graphqlPlugin()"],
|
|
133
|
+
database: {
|
|
134
|
+
kind: "sqlite",
|
|
135
|
+
},
|
|
136
|
+
networks: ponderNetworks,
|
|
137
|
+
sources: ponderSources,
|
|
138
|
+
};
|
|
139
|
+
return ponderConfig;
|
|
140
|
+
};
|
|
141
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
142
|
+
0 &&
|
|
143
|
+
(module.exports = {
|
|
144
|
+
fromSubgraph,
|
|
145
|
+
});
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if ((from && typeof from === "object") || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, {
|
|
17
|
+
get: () => from[key],
|
|
18
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable,
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
return to;
|
|
22
|
+
};
|
|
23
|
+
var __toESM = (mod, isNodeMode, target) => (
|
|
24
|
+
(target = mod != null ? __create(__getProtoOf(mod)) : {}),
|
|
25
|
+
__copyProps(
|
|
26
|
+
isNodeMode || !mod || !mod.__esModule
|
|
27
|
+
? __defProp(target, "default", { value: mod, enumerable: true })
|
|
28
|
+
: target,
|
|
29
|
+
mod
|
|
30
|
+
)
|
|
31
|
+
);
|
|
32
|
+
var __toCommonJS = (mod) =>
|
|
33
|
+
__copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
34
|
+
var detectPackageManager_exports = {};
|
|
35
|
+
__export(detectPackageManager_exports, {
|
|
36
|
+
detect: () => detect,
|
|
37
|
+
});
|
|
38
|
+
module.exports = __toCommonJS(detectPackageManager_exports);
|
|
39
|
+
var import_execa = __toESM(require("execa"));
|
|
40
|
+
var import_fs = require("fs");
|
|
41
|
+
var import_path = require("path");
|
|
42
|
+
async function pathExists(p) {
|
|
43
|
+
try {
|
|
44
|
+
await import_fs.promises.access(p);
|
|
45
|
+
return true;
|
|
46
|
+
} catch {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
const cache = /* @__PURE__ */ new Map();
|
|
51
|
+
function hasGlobalInstallation(pm) {
|
|
52
|
+
const key = `has_global_${pm}`;
|
|
53
|
+
if (cache.has(key)) {
|
|
54
|
+
return Promise.resolve(cache.get(key));
|
|
55
|
+
}
|
|
56
|
+
return (0, import_execa.default)(pm, ["--version"])
|
|
57
|
+
.then((res) => {
|
|
58
|
+
return /^\d+.\d+.\d+$/.test(res.stdout);
|
|
59
|
+
})
|
|
60
|
+
.then((value) => {
|
|
61
|
+
cache.set(key, value);
|
|
62
|
+
return value;
|
|
63
|
+
})
|
|
64
|
+
.catch(() => false);
|
|
65
|
+
}
|
|
66
|
+
function getTypeofLockFile(cwd = ".") {
|
|
67
|
+
const key = `lockfile_${cwd}`;
|
|
68
|
+
if (cache.has(key)) {
|
|
69
|
+
return Promise.resolve(cache.get(key));
|
|
70
|
+
}
|
|
71
|
+
return Promise.all([
|
|
72
|
+
pathExists((0, import_path.resolve)(cwd, "yarn.lock")),
|
|
73
|
+
pathExists((0, import_path.resolve)(cwd, "package-lock.json")),
|
|
74
|
+
pathExists((0, import_path.resolve)(cwd, "pnpm-lock.yaml")),
|
|
75
|
+
]).then(([isYarn, isNpm, isPnpm]) => {
|
|
76
|
+
let value = null;
|
|
77
|
+
if (isYarn) {
|
|
78
|
+
value = "yarn";
|
|
79
|
+
} else if (isPnpm) {
|
|
80
|
+
value = "pnpm";
|
|
81
|
+
} else if (isNpm) {
|
|
82
|
+
value = "npm";
|
|
83
|
+
}
|
|
84
|
+
cache.set(key, value);
|
|
85
|
+
return value;
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
const detect = async ({ cwd } = {}) => {
|
|
89
|
+
const type = await getTypeofLockFile(cwd);
|
|
90
|
+
if (type) {
|
|
91
|
+
return type;
|
|
92
|
+
}
|
|
93
|
+
const [hasYarn, hasPnpm] = await Promise.all([
|
|
94
|
+
hasGlobalInstallation("yarn"),
|
|
95
|
+
hasGlobalInstallation("pnpm"),
|
|
96
|
+
]);
|
|
97
|
+
if (hasPnpm) {
|
|
98
|
+
return "pnpm";
|
|
99
|
+
}
|
|
100
|
+
if (hasYarn) {
|
|
101
|
+
return "yarn";
|
|
102
|
+
}
|
|
103
|
+
return "npm";
|
|
104
|
+
};
|
|
105
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
106
|
+
0 &&
|
|
107
|
+
(module.exports = {
|
|
108
|
+
detect,
|
|
109
|
+
});
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if ((from && typeof from === "object") || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, {
|
|
15
|
+
get: () => from[key],
|
|
16
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable,
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
return to;
|
|
20
|
+
};
|
|
21
|
+
var __toCommonJS = (mod) =>
|
|
22
|
+
__copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
23
|
+
var getEtherscanChainId_exports = {};
|
|
24
|
+
__export(getEtherscanChainId_exports, {
|
|
25
|
+
getNetworkByEtherscanHostname: () => getNetworkByEtherscanHostname,
|
|
26
|
+
});
|
|
27
|
+
module.exports = __toCommonJS(getEtherscanChainId_exports);
|
|
28
|
+
const networkByEtherscanHostname = {
|
|
29
|
+
"etherscan.io": { name: "mainnet", chainId: 1 },
|
|
30
|
+
"ropsten.etherscan.io": { name: "ropsten", chainId: 3 },
|
|
31
|
+
"rinkeby.etherscan.io": { name: "rinkeby", chainId: 4 },
|
|
32
|
+
"goerli.etherscan.io": { name: "goerli", chainId: 5 },
|
|
33
|
+
"kovan.etherscan.io": { name: "kovan", chainId: 42 },
|
|
34
|
+
"sepolia.etherscan.io": { name: "sepolia", chainId: 11155111 },
|
|
35
|
+
"optimistic.etherscan.io": { name: "optimism", chainId: 10 },
|
|
36
|
+
"kovan-optimistic.etherscan.io": { name: "optimism-kovan", chainId: 69 },
|
|
37
|
+
"goerli-optimism.etherscan.io": { name: "optimism-goerli", chainId: 420 },
|
|
38
|
+
"polygonscan.com": { name: "polygon", chainId: 137 },
|
|
39
|
+
"mumbai.polygonscan.com": { name: "polygon-mumbai", chainId: 80001 },
|
|
40
|
+
"arbiscan.io": { name: "arbitrum", chainId: 42161 },
|
|
41
|
+
"testnet.arbiscan.io": { name: "arbitrum-rinkeby", chainId: 421611 },
|
|
42
|
+
"goerli.arbiscan.io": { name: "arbitrum-goerli", chainId: 421613 },
|
|
43
|
+
};
|
|
44
|
+
const getNetworkByEtherscanHostname = (hostname) => {
|
|
45
|
+
return networkByEtherscanHostname[hostname];
|
|
46
|
+
};
|
|
47
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
48
|
+
0 &&
|
|
49
|
+
(module.exports = {
|
|
50
|
+
getNetworkByEtherscanHostname,
|
|
51
|
+
});
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if ((from && typeof from === "object") || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, {
|
|
15
|
+
get: () => from[key],
|
|
16
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable,
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
return to;
|
|
20
|
+
};
|
|
21
|
+
var __toCommonJS = (mod) =>
|
|
22
|
+
__copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
23
|
+
var getGraphProtocolChainId_exports = {};
|
|
24
|
+
__export(getGraphProtocolChainId_exports, {
|
|
25
|
+
getGraphProtocolChainId: () => getGraphProtocolChainId,
|
|
26
|
+
subgraphYamlFileNames: () => subgraphYamlFileNames,
|
|
27
|
+
});
|
|
28
|
+
module.exports = __toCommonJS(getGraphProtocolChainId_exports);
|
|
29
|
+
const chainIdByGraphNetwork = {
|
|
30
|
+
mainnet: 1,
|
|
31
|
+
kovan: 42,
|
|
32
|
+
rinkeby: 4,
|
|
33
|
+
ropsten: 3,
|
|
34
|
+
goerli: 5,
|
|
35
|
+
"poa-core": 99,
|
|
36
|
+
"poa-sokol": 77,
|
|
37
|
+
xdai: 100,
|
|
38
|
+
matic: 137,
|
|
39
|
+
mumbai: 80001,
|
|
40
|
+
fantom: 250,
|
|
41
|
+
"fantom-testnet": 4002,
|
|
42
|
+
bsc: 56,
|
|
43
|
+
chapel: -1,
|
|
44
|
+
clover: 0,
|
|
45
|
+
avalanche: 43114,
|
|
46
|
+
fuji: 43113,
|
|
47
|
+
celo: 42220,
|
|
48
|
+
"celo-alfajores": 44787,
|
|
49
|
+
fuse: 122,
|
|
50
|
+
moonbeam: 1284,
|
|
51
|
+
moonriver: 1285,
|
|
52
|
+
mbase: -1,
|
|
53
|
+
"arbitrum-one": 42161,
|
|
54
|
+
"arbitrum-rinkeby": 421611,
|
|
55
|
+
optimism: 10,
|
|
56
|
+
"optimism-kovan": 69,
|
|
57
|
+
aurora: 1313161554,
|
|
58
|
+
"aurora-testnet": 1313161555,
|
|
59
|
+
};
|
|
60
|
+
const getGraphProtocolChainId = (networkName) => {
|
|
61
|
+
return chainIdByGraphNetwork[networkName];
|
|
62
|
+
};
|
|
63
|
+
const subgraphYamlFileNames = ["subgraph.yaml"].concat(
|
|
64
|
+
Object.keys(chainIdByGraphNetwork).map((n) => `subgraph-${n}.yaml`)
|
|
65
|
+
);
|
|
66
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
67
|
+
0 &&
|
|
68
|
+
(module.exports = {
|
|
69
|
+
getGraphProtocolChainId,
|
|
70
|
+
subgraphYamlFileNames,
|
|
71
|
+
});
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if ((from && typeof from === "object") || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, {
|
|
15
|
+
get: () => from[key],
|
|
16
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable,
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
return to;
|
|
20
|
+
};
|
|
21
|
+
var __toCommonJS = (mod) =>
|
|
22
|
+
__copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
23
|
+
var getPackageManager_exports = {};
|
|
24
|
+
__export(getPackageManager_exports, {
|
|
25
|
+
getPackageManager: () => getPackageManager,
|
|
26
|
+
});
|
|
27
|
+
module.exports = __toCommonJS(getPackageManager_exports);
|
|
28
|
+
var import_child_process = require("child_process");
|
|
29
|
+
function getPackageManager() {
|
|
30
|
+
try {
|
|
31
|
+
const userAgent = process.env.npm_config_user_agent;
|
|
32
|
+
if (userAgent) {
|
|
33
|
+
if (userAgent.startsWith("yarn")) {
|
|
34
|
+
return "yarn";
|
|
35
|
+
} else if (userAgent.startsWith("pnpm")) {
|
|
36
|
+
return "pnpm";
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
try {
|
|
40
|
+
(0, import_child_process.execSync)("yarn --version", { stdio: "ignore" });
|
|
41
|
+
return "yarn";
|
|
42
|
+
} catch {
|
|
43
|
+
(0, import_child_process.execSync)("pnpm --version", { stdio: "ignore" });
|
|
44
|
+
return "pnpm";
|
|
45
|
+
}
|
|
46
|
+
} catch {
|
|
47
|
+
return "npm";
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
51
|
+
0 &&
|
|
52
|
+
(module.exports = {
|
|
53
|
+
getPackageManager,
|
|
54
|
+
});
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if ((from && typeof from === "object") || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, {
|
|
15
|
+
get: () => from[key],
|
|
16
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable,
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
return to;
|
|
20
|
+
};
|
|
21
|
+
var __toCommonJS = (mod) =>
|
|
22
|
+
__copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
23
|
+
var validateGraphProtocolSource_exports = {};
|
|
24
|
+
__export(validateGraphProtocolSource_exports, {
|
|
25
|
+
validateGraphProtocolSource: () => validateGraphProtocolSource,
|
|
26
|
+
});
|
|
27
|
+
module.exports = __toCommonJS(validateGraphProtocolSource_exports);
|
|
28
|
+
const validateGraphProtocolSource = (source) => {
|
|
29
|
+
return source;
|
|
30
|
+
};
|
|
31
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
32
|
+
0 &&
|
|
33
|
+
(module.exports = {
|
|
34
|
+
validateGraphProtocolSource,
|
|
35
|
+
});
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if ((from && typeof from === "object") || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, {
|
|
17
|
+
get: () => from[key],
|
|
18
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable,
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
return to;
|
|
22
|
+
};
|
|
23
|
+
var __toESM = (mod, isNodeMode, target) => (
|
|
24
|
+
(target = mod != null ? __create(__getProtoOf(mod)) : {}),
|
|
25
|
+
__copyProps(
|
|
26
|
+
isNodeMode || !mod || !mod.__esModule
|
|
27
|
+
? __defProp(target, "default", { value: mod, enumerable: true })
|
|
28
|
+
: target,
|
|
29
|
+
mod
|
|
30
|
+
)
|
|
31
|
+
);
|
|
32
|
+
var __toCommonJS = (mod) =>
|
|
33
|
+
__copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
34
|
+
var src_exports = {};
|
|
35
|
+
__export(src_exports, {
|
|
36
|
+
run: () => run,
|
|
37
|
+
});
|
|
38
|
+
module.exports = __toCommonJS(src_exports);
|
|
39
|
+
var import_chalk = __toESM(require("chalk"));
|
|
40
|
+
var import_ethers = require("ethers");
|
|
41
|
+
var import_node_child_process = require("node:child_process");
|
|
42
|
+
var import_node_fs = require("node:fs");
|
|
43
|
+
var import_node_path = __toESM(require("node:path"));
|
|
44
|
+
var import_prettier = __toESM(require("prettier"));
|
|
45
|
+
var import_fromBasic = require("./fromBasic");
|
|
46
|
+
var import_fromEtherscan = require("./fromEtherscan");
|
|
47
|
+
var import_fromSubgraph = require("./fromSubgraph");
|
|
48
|
+
var import_detectPackageManager = require("./helpers/detectPackageManager");
|
|
49
|
+
const run = async (options) => {
|
|
50
|
+
const { ponderRootDir } = options;
|
|
51
|
+
(0, import_node_fs.mkdirSync)(
|
|
52
|
+
import_node_path.default.join(ponderRootDir, "abis"),
|
|
53
|
+
{ recursive: true }
|
|
54
|
+
);
|
|
55
|
+
(0, import_node_fs.mkdirSync)(
|
|
56
|
+
import_node_path.default.join(ponderRootDir, "handlers"),
|
|
57
|
+
{ recursive: true }
|
|
58
|
+
);
|
|
59
|
+
let ponderConfig;
|
|
60
|
+
if (options.fromSubgraph) {
|
|
61
|
+
console.log(
|
|
62
|
+
import_chalk.default.bold.cyanBright("[create-ponder] ") +
|
|
63
|
+
`Bootstrapping from subgraph`
|
|
64
|
+
);
|
|
65
|
+
ponderConfig = (0, import_fromSubgraph.fromSubgraph)(options);
|
|
66
|
+
} else if (options.fromEtherscan) {
|
|
67
|
+
console.log(
|
|
68
|
+
import_chalk.default.bold.cyanBright("[create-ponder] ") +
|
|
69
|
+
`Bootstrapping from Etherscan`
|
|
70
|
+
);
|
|
71
|
+
ponderConfig = await (0, import_fromEtherscan.fromEtherscan)(options);
|
|
72
|
+
} else {
|
|
73
|
+
ponderConfig = (0, import_fromBasic.fromBasic)(options);
|
|
74
|
+
}
|
|
75
|
+
ponderConfig.sources.forEach((source) => {
|
|
76
|
+
const abi = (0, import_node_fs.readFileSync)(
|
|
77
|
+
import_node_path.default.join(ponderRootDir, source.abi),
|
|
78
|
+
{
|
|
79
|
+
encoding: "utf-8",
|
|
80
|
+
}
|
|
81
|
+
);
|
|
82
|
+
const abiInterface = new import_ethers.ethers.utils.Interface(abi);
|
|
83
|
+
const eventNames = Object.keys(abiInterface.events);
|
|
84
|
+
const handlers = eventNames.map((eventName) => {
|
|
85
|
+
const eventBaseName = eventName.split("(")[0];
|
|
86
|
+
const handlerFunctionType = `${eventBaseName}Handler`;
|
|
87
|
+
const handlerFunctionName = `handle${eventBaseName}`;
|
|
88
|
+
return {
|
|
89
|
+
handlerFunctionType,
|
|
90
|
+
handlerFunction: `const ${handlerFunctionName}: ${handlerFunctionType} = async (event, context) => { return }
|
|
91
|
+
`,
|
|
92
|
+
handlerExport: `${eventBaseName}: ${handlerFunctionName}`,
|
|
93
|
+
};
|
|
94
|
+
});
|
|
95
|
+
const handlerFileContents = `
|
|
96
|
+
import { ${handlers.map((h) => h.handlerFunctionType).join(",")} }
|
|
97
|
+
from '../generated/handlers'
|
|
98
|
+
|
|
99
|
+
${handlers.map((h) => h.handlerFunction).join("\n")}
|
|
100
|
+
|
|
101
|
+
export const ${source.name} = {
|
|
102
|
+
${handlers.map((h) => h.handlerExport).join(",")}
|
|
103
|
+
}
|
|
104
|
+
`;
|
|
105
|
+
(0, import_node_fs.writeFileSync)(
|
|
106
|
+
import_node_path.default.join(
|
|
107
|
+
ponderRootDir,
|
|
108
|
+
`./handlers/${source.name}.ts`
|
|
109
|
+
),
|
|
110
|
+
import_prettier.default.format(handlerFileContents, {
|
|
111
|
+
parser: "typescript",
|
|
112
|
+
})
|
|
113
|
+
);
|
|
114
|
+
});
|
|
115
|
+
const handlerIndexFileContents = `
|
|
116
|
+
${ponderConfig.sources
|
|
117
|
+
.map((source) => `import { ${source.name} } from "./${source.name}"`)
|
|
118
|
+
.join("\n")}
|
|
119
|
+
|
|
120
|
+
export default {
|
|
121
|
+
${ponderConfig.sources
|
|
122
|
+
.map((source) => `${source.name}: ${source.name}`)
|
|
123
|
+
.join(",")}
|
|
124
|
+
}
|
|
125
|
+
`;
|
|
126
|
+
(0, import_node_fs.writeFileSync)(
|
|
127
|
+
import_node_path.default.join(ponderRootDir, `./handlers/index.ts`),
|
|
128
|
+
import_prettier.default.format(handlerIndexFileContents, {
|
|
129
|
+
parser: "typescript",
|
|
130
|
+
})
|
|
131
|
+
);
|
|
132
|
+
const finalPonderConfig = `const { graphqlPlugin } = require("@ponder/graphql");
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* @type {import('@ponder/ponder').PonderConfig}
|
|
136
|
+
*/
|
|
137
|
+
const ponderConfig = {
|
|
138
|
+
plugins: [graphqlPlugin()],
|
|
139
|
+
database: {
|
|
140
|
+
kind: "sqlite",
|
|
141
|
+
},
|
|
142
|
+
networks: ${JSON.stringify(ponderConfig.networks).replaceAll(
|
|
143
|
+
/"process.env.PONDER_RPC_URL_(.*?)"/g,
|
|
144
|
+
"process.env.PONDER_RPC_URL_$1"
|
|
145
|
+
)},
|
|
146
|
+
sources: ${JSON.stringify(ponderConfig.sources)},
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
module.exports = ponderConfig;`;
|
|
150
|
+
(0, import_node_fs.writeFileSync)(
|
|
151
|
+
import_node_path.default.join(ponderRootDir, "ponder.config.js"),
|
|
152
|
+
import_prettier.default.format(finalPonderConfig, { parser: "babel" })
|
|
153
|
+
);
|
|
154
|
+
const uniqueChainIds = Array.from(
|
|
155
|
+
new Set(ponderConfig.networks.map((n) => n.chainId))
|
|
156
|
+
);
|
|
157
|
+
const envLocal = `${uniqueChainIds.map(
|
|
158
|
+
(chainId) => `PONDER_RPC_URL_${chainId}=""
|
|
159
|
+
`
|
|
160
|
+
)}`;
|
|
161
|
+
(0, import_node_fs.writeFileSync)(
|
|
162
|
+
import_node_path.default.join(ponderRootDir, ".env.local"),
|
|
163
|
+
envLocal
|
|
164
|
+
);
|
|
165
|
+
const packageJson = `
|
|
166
|
+
{
|
|
167
|
+
"version": "0.1.0",
|
|
168
|
+
"private": true,
|
|
169
|
+
"scripts": {
|
|
170
|
+
"dev": "ponder dev",
|
|
171
|
+
"start": "ponder start",
|
|
172
|
+
"codegen": "ponder codegen"
|
|
173
|
+
},
|
|
174
|
+
"dependencies": {
|
|
175
|
+
"@ponder/ponder": "latest",
|
|
176
|
+
"@ponder/graphql": "latest"
|
|
177
|
+
},
|
|
178
|
+
"devDependencies": {
|
|
179
|
+
"ethers": "^5.6.9"
|
|
180
|
+
},
|
|
181
|
+
"engines": {
|
|
182
|
+
"node": "16",
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
`;
|
|
186
|
+
(0, import_node_fs.writeFileSync)(
|
|
187
|
+
import_node_path.default.join(ponderRootDir, "package.json"),
|
|
188
|
+
import_prettier.default.format(packageJson, { parser: "json" })
|
|
189
|
+
);
|
|
190
|
+
const tsConfig = `
|
|
191
|
+
{
|
|
192
|
+
"compilerOptions": {
|
|
193
|
+
"target": "esnext",
|
|
194
|
+
"module": "esnext",
|
|
195
|
+
"esModuleInterop": true,
|
|
196
|
+
"strict": true,
|
|
197
|
+
"moduleResolution": "node"
|
|
198
|
+
},
|
|
199
|
+
"include": ["./**/*.ts"],
|
|
200
|
+
"exclude": ["node_modules"]
|
|
201
|
+
}
|
|
202
|
+
`;
|
|
203
|
+
(0, import_node_fs.writeFileSync)(
|
|
204
|
+
import_node_path.default.join(ponderRootDir, "tsconfig.json"),
|
|
205
|
+
import_prettier.default.format(tsConfig, { parser: "json" })
|
|
206
|
+
);
|
|
207
|
+
(0, import_node_fs.writeFileSync)(
|
|
208
|
+
import_node_path.default.join(ponderRootDir, ".gitignore"),
|
|
209
|
+
`node_modules/
|
|
210
|
+
.DS_Store
|
|
211
|
+
|
|
212
|
+
.env.local
|
|
213
|
+
.ponder/
|
|
214
|
+
generated/`
|
|
215
|
+
);
|
|
216
|
+
const packageManager = await (0, import_detectPackageManager.detect)();
|
|
217
|
+
const renderYaml = `
|
|
218
|
+
# This file was generated by \`create-ponder\`. You can deploy your Ponder app
|
|
219
|
+
# by signing in to https://render.com, connecting this repository, and clicking Deploy.
|
|
220
|
+
|
|
221
|
+
services:
|
|
222
|
+
- type: web
|
|
223
|
+
name: ponder-app
|
|
224
|
+
env: node
|
|
225
|
+
buildCommand: ${packageManager} install
|
|
226
|
+
startCommand: ${packageManager} run start
|
|
227
|
+
envVars:
|
|
228
|
+
- key: POSTGRES_URL
|
|
229
|
+
fromDatabase:
|
|
230
|
+
name: ponder-db
|
|
231
|
+
property: connectionString
|
|
232
|
+
${ponderConfig.networks
|
|
233
|
+
.map(
|
|
234
|
+
(n) => ` - key: PONDER_RPC_URL_${n.chainId}
|
|
235
|
+
sync: false`
|
|
236
|
+
)
|
|
237
|
+
.join("\n")}
|
|
238
|
+
|
|
239
|
+
databases:
|
|
240
|
+
- name: ponder-db
|
|
241
|
+
postgresMajorVersion: 14
|
|
242
|
+
`;
|
|
243
|
+
(0, import_node_fs.writeFileSync)(
|
|
244
|
+
import_node_path.default.join(ponderRootDir, "render.yaml"),
|
|
245
|
+
import_prettier.default.format(renderYaml, { parser: "yaml" })
|
|
246
|
+
);
|
|
247
|
+
console.log(
|
|
248
|
+
import_chalk.default.bold.cyanBright("[create-ponder] ") +
|
|
249
|
+
`Installing using ${packageManager}`
|
|
250
|
+
);
|
|
251
|
+
(0, import_node_child_process.execSync)(`${packageManager} install`, {
|
|
252
|
+
cwd: ponderRootDir,
|
|
253
|
+
stdio: "inherit",
|
|
254
|
+
});
|
|
255
|
+
console.log(
|
|
256
|
+
import_chalk.default.bold.cyanBright("[create-ponder] ") +
|
|
257
|
+
`Generating types`
|
|
258
|
+
);
|
|
259
|
+
(0, import_node_child_process.execSync)(
|
|
260
|
+
`${packageManager} run --silent codegen`,
|
|
261
|
+
{
|
|
262
|
+
cwd: ponderRootDir,
|
|
263
|
+
stdio: "inherit",
|
|
264
|
+
}
|
|
265
|
+
);
|
|
266
|
+
console.log(
|
|
267
|
+
import_chalk.default.bold.cyanBright("[create-ponder] ") +
|
|
268
|
+
import_chalk.default.bold.greenBright("Done! ") +
|
|
269
|
+
`To get started: ${import_chalk.default.bold.yellowBright(
|
|
270
|
+
`cd ${import_node_path.default.relative(
|
|
271
|
+
".",
|
|
272
|
+
ponderRootDir
|
|
273
|
+
)} && ${packageManager} run dev`
|
|
274
|
+
)}`
|
|
275
|
+
);
|
|
276
|
+
};
|
|
277
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
278
|
+
0 &&
|
|
279
|
+
(module.exports = {
|
|
280
|
+
run,
|
|
281
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "create-ponder",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Tool to bootstrap a Ponder project",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "olias.eth",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist"
|
|
9
|
+
],
|
|
10
|
+
"bin": {
|
|
11
|
+
"create-ponder": "./dist/bin/create-ponder"
|
|
12
|
+
},
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"@ethersproject/abi": "^5.6.4",
|
|
15
|
+
"@ethersproject/providers": "^5.6.8",
|
|
16
|
+
"chalk": "4",
|
|
17
|
+
"commander": "^9.4.0",
|
|
18
|
+
"ethers": "^5.6.9",
|
|
19
|
+
"execa": "5",
|
|
20
|
+
"node-fetch": ">=2.6.7",
|
|
21
|
+
"prettier": "^2.6.2",
|
|
22
|
+
"yaml": "^2.1.1"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"@types/node": "^18.7.8",
|
|
26
|
+
"@types/node-fetch": "2",
|
|
27
|
+
"@types/prettier": "^2.7.1",
|
|
28
|
+
"esbuild": "^0.15.2",
|
|
29
|
+
"tsconfig-replace-paths": "^0.0.11",
|
|
30
|
+
"typescript": "^4.5.5"
|
|
31
|
+
},
|
|
32
|
+
"scripts": {
|
|
33
|
+
"clean": "rm -rf dist",
|
|
34
|
+
"lint": "(tsc || exit 0) && eslint src",
|
|
35
|
+
"format": "prettier src --write",
|
|
36
|
+
"replace-paths": "tsconfig-replace-paths --src src",
|
|
37
|
+
"esbuild": "esbuild `find src \\( -name '*.ts' \\)` --platform=node --format=cjs --outdir=dist && $npm_execpath run replace-paths",
|
|
38
|
+
"build": "$npm_execpath run clean && $npm_execpath run esbuild && mv dist/bin/create-ponder.js dist/bin/create-ponder",
|
|
39
|
+
"format-dist": "prettier dist --write --loglevel warn",
|
|
40
|
+
"prerelease": "$npm_execpath run build && $npm_execpath run format-dist",
|
|
41
|
+
"release": "$npm_execpath run prerelease && VERSION=$($npm_execpath version patch) && $npm_execpath publish && git add ./package.json && git commit -m \"release(create-ponder): $VERSION\""
|
|
42
|
+
}
|
|
43
|
+
}
|