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
package/dist/create-ponder.js
DELETED
|
@@ -1,937 +0,0 @@
|
|
|
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
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
19
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
20
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
21
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
22
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
23
|
-
mod
|
|
24
|
-
));
|
|
25
|
-
|
|
26
|
-
// src/bin/create-ponder.ts
|
|
27
|
-
var import_cac = require("cac");
|
|
28
|
-
var import_node_path6 = __toESM(require("path"));
|
|
29
|
-
var import_prompts = __toESM(require("prompts"));
|
|
30
|
-
|
|
31
|
-
// src/index.ts
|
|
32
|
-
var import_node_child_process = require("child_process");
|
|
33
|
-
var import_node_fs5 = require("fs");
|
|
34
|
-
var import_node_path5 = __toESM(require("path"));
|
|
35
|
-
var import_picocolors = __toESM(require("picocolors"));
|
|
36
|
-
var import_prettier5 = __toESM(require("prettier"));
|
|
37
|
-
|
|
38
|
-
// src/helpers/getPackageManager.ts
|
|
39
|
-
var import_detect_package_manager = require("detect-package-manager");
|
|
40
|
-
function getPackageManager() {
|
|
41
|
-
const userAgent = process.env.npm_config_user_agent;
|
|
42
|
-
if (userAgent) {
|
|
43
|
-
if (userAgent.includes("pnpm"))
|
|
44
|
-
return "pnpm";
|
|
45
|
-
if (userAgent.includes("npm"))
|
|
46
|
-
return "npm";
|
|
47
|
-
if (userAgent.includes("yarn"))
|
|
48
|
-
return "yarn";
|
|
49
|
-
}
|
|
50
|
-
return (0, import_detect_package_manager.detect)();
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
// src/helpers/git.ts
|
|
54
|
-
var import_child_process = require("child_process");
|
|
55
|
-
var import_path = __toESM(require("path"));
|
|
56
|
-
var import_rimraf = __toESM(require("rimraf"));
|
|
57
|
-
function isInGitRepository() {
|
|
58
|
-
try {
|
|
59
|
-
(0, import_child_process.execSync)("git rev-parse --is-inside-work-tree", { stdio: "ignore" });
|
|
60
|
-
return true;
|
|
61
|
-
} catch (_) {
|
|
62
|
-
}
|
|
63
|
-
return false;
|
|
64
|
-
}
|
|
65
|
-
function isInMercurialRepository() {
|
|
66
|
-
try {
|
|
67
|
-
(0, import_child_process.execSync)("hg --cwd . root", { stdio: "ignore" });
|
|
68
|
-
return true;
|
|
69
|
-
} catch (_) {
|
|
70
|
-
}
|
|
71
|
-
return false;
|
|
72
|
-
}
|
|
73
|
-
function tryGitInit(root) {
|
|
74
|
-
let didInit = false;
|
|
75
|
-
try {
|
|
76
|
-
(0, import_child_process.execSync)("git --version", { stdio: "ignore" });
|
|
77
|
-
if (isInGitRepository() || isInMercurialRepository()) {
|
|
78
|
-
return false;
|
|
79
|
-
}
|
|
80
|
-
(0, import_child_process.execSync)("git init", { stdio: "ignore" });
|
|
81
|
-
didInit = true;
|
|
82
|
-
(0, import_child_process.execSync)("git checkout -b main", { stdio: "ignore" });
|
|
83
|
-
(0, import_child_process.execSync)("git add -A", { stdio: "ignore" });
|
|
84
|
-
(0, import_child_process.execSync)('git commit -m "chore: initial commit from create-ponder"', {
|
|
85
|
-
stdio: "ignore"
|
|
86
|
-
});
|
|
87
|
-
return true;
|
|
88
|
-
} catch (e) {
|
|
89
|
-
if (didInit) {
|
|
90
|
-
try {
|
|
91
|
-
import_rimraf.default.sync(import_path.default.join(root, ".git"));
|
|
92
|
-
} catch (_) {
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
return false;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
// src/templates/basic.ts
|
|
100
|
-
var import_node_fs = require("fs");
|
|
101
|
-
var import_node_path = __toESM(require("path"));
|
|
102
|
-
var import_prettier = __toESM(require("prettier"));
|
|
103
|
-
var fromBasic = ({ rootDir }) => {
|
|
104
|
-
const abiFileContents = `[]`;
|
|
105
|
-
const abiRelativePath = "./abis/ExampleContract.json";
|
|
106
|
-
const abiAbsolutePath = import_node_path.default.join(rootDir, abiRelativePath);
|
|
107
|
-
(0, import_node_fs.writeFileSync)(abiAbsolutePath, abiFileContents);
|
|
108
|
-
const schemaGraphqlFileContents = `
|
|
109
|
-
# The entity types defined below map to database tables.
|
|
110
|
-
# The functions you write as event handlers inside the \`src/\` directory are responsible for creating and updating records in those tables.
|
|
111
|
-
# Your schema will be more flexible and powerful if it accurately models the logical relationships in your application's domain.
|
|
112
|
-
# Visit the [documentation](https://ponder.sh/guides/design-your-schema) or the [\`examples/\`](https://github.com/0xOlias/ponder/tree/main/examples) directory for further guidance on designing your schema.
|
|
113
|
-
|
|
114
|
-
type ExampleToken @entity {
|
|
115
|
-
id: String!
|
|
116
|
-
tokenId: Int!
|
|
117
|
-
trait: TokenTrait!
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
enum TokenTrait {
|
|
121
|
-
GOOD
|
|
122
|
-
BAD
|
|
123
|
-
}
|
|
124
|
-
`;
|
|
125
|
-
const ponderSchemaFilePath = import_node_path.default.join(rootDir, "schema.graphql");
|
|
126
|
-
(0, import_node_fs.writeFileSync)(
|
|
127
|
-
ponderSchemaFilePath,
|
|
128
|
-
import_prettier.default.format(schemaGraphqlFileContents, { parser: "graphql" })
|
|
129
|
-
);
|
|
130
|
-
const config = {
|
|
131
|
-
networks: [
|
|
132
|
-
{
|
|
133
|
-
name: "mainnet",
|
|
134
|
-
chainId: 1,
|
|
135
|
-
rpcUrl: `process.env.PONDER_RPC_URL_1`
|
|
136
|
-
}
|
|
137
|
-
],
|
|
138
|
-
contracts: [
|
|
139
|
-
{
|
|
140
|
-
name: "ExampleContract",
|
|
141
|
-
network: "mainnet",
|
|
142
|
-
address: "0x0",
|
|
143
|
-
abi: abiRelativePath,
|
|
144
|
-
startBlock: 1234567
|
|
145
|
-
}
|
|
146
|
-
]
|
|
147
|
-
};
|
|
148
|
-
return config;
|
|
149
|
-
};
|
|
150
|
-
|
|
151
|
-
// src/templates/etherscan.ts
|
|
152
|
-
var import_node_fs2 = require("fs");
|
|
153
|
-
var import_node_path2 = __toESM(require("path"));
|
|
154
|
-
var import_node_fetch = __toESM(require("node-fetch"));
|
|
155
|
-
var import_prettier2 = __toESM(require("prettier"));
|
|
156
|
-
|
|
157
|
-
// src/helpers/getEtherscanChainId.ts
|
|
158
|
-
var networkByEtherscanHostname = {
|
|
159
|
-
"etherscan.io": {
|
|
160
|
-
name: "mainnet",
|
|
161
|
-
chainId: 1,
|
|
162
|
-
apiUrl: "https://api.etherscan.io/api"
|
|
163
|
-
},
|
|
164
|
-
"ropsten.etherscan.io": {
|
|
165
|
-
name: "ropsten",
|
|
166
|
-
chainId: 3,
|
|
167
|
-
apiUrl: "https://api-ropsten.etherscan.io/api"
|
|
168
|
-
},
|
|
169
|
-
"rinkeby.etherscan.io": {
|
|
170
|
-
name: "rinkeby",
|
|
171
|
-
chainId: 4,
|
|
172
|
-
apiUrl: "https://api-rinkeby.etherscan.io/api"
|
|
173
|
-
},
|
|
174
|
-
"goerli.etherscan.io": {
|
|
175
|
-
name: "goerli",
|
|
176
|
-
chainId: 5,
|
|
177
|
-
apiUrl: "https://api-goerli.etherscan.io/api"
|
|
178
|
-
},
|
|
179
|
-
"kovan.etherscan.io": {
|
|
180
|
-
name: "kovan",
|
|
181
|
-
chainId: 42,
|
|
182
|
-
apiUrl: "https://api-kovan.etherscan.io/api"
|
|
183
|
-
},
|
|
184
|
-
"sepolia.etherscan.io": {
|
|
185
|
-
name: "sepolia",
|
|
186
|
-
chainId: 11155111,
|
|
187
|
-
apiUrl: "https://api-sepolia.etherscan.io/api"
|
|
188
|
-
},
|
|
189
|
-
"optimistic.etherscan.io": {
|
|
190
|
-
name: "optimism",
|
|
191
|
-
chainId: 10,
|
|
192
|
-
apiUrl: "https://api-optimistic.etherscan.io/api"
|
|
193
|
-
},
|
|
194
|
-
"goerli-optimism.etherscan.io": {
|
|
195
|
-
name: "optimism-goerli",
|
|
196
|
-
chainId: 420,
|
|
197
|
-
apiUrl: "https://api-goerli-optimistic.etherscan.io/api"
|
|
198
|
-
},
|
|
199
|
-
"polygonscan.com": {
|
|
200
|
-
name: "polygon",
|
|
201
|
-
chainId: 137,
|
|
202
|
-
apiUrl: "https://api.polygonscan.com/api"
|
|
203
|
-
},
|
|
204
|
-
"mumbai.polygonscan.com": {
|
|
205
|
-
name: "polygon-mumbai",
|
|
206
|
-
chainId: 80001,
|
|
207
|
-
apiUrl: "https://api-testnet.polygonscan.com/api"
|
|
208
|
-
},
|
|
209
|
-
"arbiscan.io": {
|
|
210
|
-
name: "arbitrum",
|
|
211
|
-
chainId: 42161,
|
|
212
|
-
apiUrl: "https://api.arbiscan.io/api"
|
|
213
|
-
},
|
|
214
|
-
"goerli.arbiscan.io": {
|
|
215
|
-
name: "arbitrum-goerli",
|
|
216
|
-
chainId: 421613,
|
|
217
|
-
apiUrl: "https://api-goerli.arbiscan.io/api"
|
|
218
|
-
},
|
|
219
|
-
"explorer.zora.energy": {
|
|
220
|
-
name: "zora",
|
|
221
|
-
chainId: 7777777,
|
|
222
|
-
apiUrl: "https://explorer.zora.energy/api"
|
|
223
|
-
}
|
|
224
|
-
};
|
|
225
|
-
var getNetworkByEtherscanHostname = (hostname) => {
|
|
226
|
-
return networkByEtherscanHostname[hostname];
|
|
227
|
-
};
|
|
228
|
-
|
|
229
|
-
// src/helpers/wait.ts
|
|
230
|
-
var wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
231
|
-
|
|
232
|
-
// src/templates/etherscan.ts
|
|
233
|
-
var fromEtherscan = async ({
|
|
234
|
-
rootDir,
|
|
235
|
-
etherscanLink,
|
|
236
|
-
etherscanApiKey
|
|
237
|
-
}) => {
|
|
238
|
-
const apiKey = etherscanApiKey || process.env.ETHERSCAN_API_KEY;
|
|
239
|
-
const url = new URL(etherscanLink);
|
|
240
|
-
const network = getNetworkByEtherscanHostname(url.hostname);
|
|
241
|
-
if (!network) {
|
|
242
|
-
throw new Error(`Unrecognized etherscan hostname: ${url.hostname}`);
|
|
243
|
-
}
|
|
244
|
-
const { name, chainId, apiUrl } = network;
|
|
245
|
-
const contractAddress = url.pathname.slice(1).split("/")[1];
|
|
246
|
-
let blockNumber = void 0;
|
|
247
|
-
try {
|
|
248
|
-
const txHash = await getContractCreationTxn(
|
|
249
|
-
contractAddress,
|
|
250
|
-
apiUrl,
|
|
251
|
-
apiKey
|
|
252
|
-
);
|
|
253
|
-
if (!apiKey) {
|
|
254
|
-
console.log("\n(1/n) Waiting 5 seconds for Etherscan API rate limit");
|
|
255
|
-
await wait(5e3);
|
|
256
|
-
}
|
|
257
|
-
const contractCreationBlockNumber = await getTxBlockNumber(
|
|
258
|
-
txHash,
|
|
259
|
-
apiUrl,
|
|
260
|
-
apiKey
|
|
261
|
-
);
|
|
262
|
-
blockNumber = contractCreationBlockNumber;
|
|
263
|
-
} catch (error) {
|
|
264
|
-
}
|
|
265
|
-
if (!apiKey) {
|
|
266
|
-
console.log("(2/n) Waiting 5 seconds for Etherscan API rate limit");
|
|
267
|
-
await wait(5e3);
|
|
268
|
-
}
|
|
269
|
-
const abis = [];
|
|
270
|
-
const { abi, contractName } = await getContractAbiAndName(
|
|
271
|
-
contractAddress,
|
|
272
|
-
apiUrl,
|
|
273
|
-
apiKey
|
|
274
|
-
);
|
|
275
|
-
abis.push({ abi, contractName });
|
|
276
|
-
if (JSON.parse(abi).find(
|
|
277
|
-
(item) => item.type === "event" && item.name === "Upgraded" && item.inputs[0].name === "implementation"
|
|
278
|
-
)) {
|
|
279
|
-
console.log(
|
|
280
|
-
"Detected EIP-1967 proxy, fetching implementation contract ABIs"
|
|
281
|
-
);
|
|
282
|
-
if (!apiKey) {
|
|
283
|
-
console.log("(3/n) Waiting 5 seconds for Etherscan API rate limit");
|
|
284
|
-
await wait(5e3);
|
|
285
|
-
}
|
|
286
|
-
const { implAddresses } = await getProxyImplementationAddresses({
|
|
287
|
-
contractAddress,
|
|
288
|
-
apiUrl,
|
|
289
|
-
fromBlock: blockNumber,
|
|
290
|
-
apiKey
|
|
291
|
-
});
|
|
292
|
-
for (const [index, implAddress] of implAddresses.entries()) {
|
|
293
|
-
console.log(`Fetching ABI for implementation contract: ${implAddress}`);
|
|
294
|
-
if (!apiKey) {
|
|
295
|
-
console.log(
|
|
296
|
-
`(${4 + index}/${4 + implAddresses.length - 1}) Waiting 5 seconds for Etherscan API rate limit`
|
|
297
|
-
);
|
|
298
|
-
await wait(5e3);
|
|
299
|
-
}
|
|
300
|
-
const { abi: abi2, contractName: contractName2 } = await getContractAbiAndName(
|
|
301
|
-
implAddress,
|
|
302
|
-
apiUrl,
|
|
303
|
-
apiKey
|
|
304
|
-
);
|
|
305
|
-
abis.push({
|
|
306
|
-
abi: abi2,
|
|
307
|
-
contractName: `${contractName2}_${implAddress.slice(0, 6)}`
|
|
308
|
-
});
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
let abiConfig;
|
|
312
|
-
abis.forEach(({ abi: abi2, contractName: contractName2 }) => {
|
|
313
|
-
const abiRelativePath = `./abis/${contractName2}.json`;
|
|
314
|
-
const abiAbsolutePath = import_node_path2.default.join(rootDir, abiRelativePath);
|
|
315
|
-
(0, import_node_fs2.writeFileSync)(abiAbsolutePath, import_prettier2.default.format(abi2, { parser: "json" }));
|
|
316
|
-
if (abis.length === 1) {
|
|
317
|
-
abiConfig = abiRelativePath;
|
|
318
|
-
} else {
|
|
319
|
-
abiConfig ||= [];
|
|
320
|
-
abiConfig.push(abiRelativePath);
|
|
321
|
-
}
|
|
322
|
-
});
|
|
323
|
-
const schemaGraphqlFileContents = `
|
|
324
|
-
type ExampleEntity @entity {
|
|
325
|
-
id: String!
|
|
326
|
-
name: String!
|
|
327
|
-
}
|
|
328
|
-
`;
|
|
329
|
-
const ponderSchemaFilePath = import_node_path2.default.join(rootDir, "schema.graphql");
|
|
330
|
-
(0, import_node_fs2.writeFileSync)(
|
|
331
|
-
ponderSchemaFilePath,
|
|
332
|
-
import_prettier2.default.format(schemaGraphqlFileContents, { parser: "graphql" })
|
|
333
|
-
);
|
|
334
|
-
const config = {
|
|
335
|
-
networks: [
|
|
336
|
-
{
|
|
337
|
-
name,
|
|
338
|
-
chainId,
|
|
339
|
-
rpcUrl: `process.env.PONDER_RPC_URL_${chainId}`
|
|
340
|
-
}
|
|
341
|
-
],
|
|
342
|
-
contracts: [
|
|
343
|
-
{
|
|
344
|
-
name: contractName,
|
|
345
|
-
network: name,
|
|
346
|
-
abi: abiConfig,
|
|
347
|
-
address: contractAddress,
|
|
348
|
-
startBlock: blockNumber ?? void 0
|
|
349
|
-
}
|
|
350
|
-
]
|
|
351
|
-
};
|
|
352
|
-
return config;
|
|
353
|
-
};
|
|
354
|
-
var fetchEtherscan = async (url) => {
|
|
355
|
-
const maxRetries = 5;
|
|
356
|
-
let retryCount = 0;
|
|
357
|
-
while (retryCount <= maxRetries) {
|
|
358
|
-
try {
|
|
359
|
-
const response = await (0, import_node_fetch.default)(url);
|
|
360
|
-
const data = await response.json();
|
|
361
|
-
if (data.status === "0") {
|
|
362
|
-
throw new Error(`Etherscan API error: ${data.result}`);
|
|
363
|
-
}
|
|
364
|
-
return data;
|
|
365
|
-
} catch (error) {
|
|
366
|
-
retryCount++;
|
|
367
|
-
if (retryCount > maxRetries) {
|
|
368
|
-
throw new Error(`Max retries reached: ${error.message}`);
|
|
369
|
-
}
|
|
370
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
};
|
|
374
|
-
var getContractCreationTxn = async (contractAddress, apiUrl, apiKey) => {
|
|
375
|
-
const searchParams = new URLSearchParams({
|
|
376
|
-
module: "contract",
|
|
377
|
-
action: "getcontractcreation",
|
|
378
|
-
contractaddresses: contractAddress
|
|
379
|
-
});
|
|
380
|
-
if (apiKey)
|
|
381
|
-
searchParams.append("apikey", apiKey);
|
|
382
|
-
const data = await fetchEtherscan(`${apiUrl}?${searchParams.toString()}`);
|
|
383
|
-
return data.result[0].txHash;
|
|
384
|
-
};
|
|
385
|
-
var getTxBlockNumber = async (txHash, apiUrl, apiKey) => {
|
|
386
|
-
const searchParams = new URLSearchParams({
|
|
387
|
-
module: "proxy",
|
|
388
|
-
action: "eth_getTransactionByHash",
|
|
389
|
-
txhash: txHash
|
|
390
|
-
});
|
|
391
|
-
if (apiKey)
|
|
392
|
-
searchParams.append("apikey", apiKey);
|
|
393
|
-
const data = await fetchEtherscan(`${apiUrl}?${searchParams.toString()}`);
|
|
394
|
-
const hexBlockNumber = data.result.blockNumber;
|
|
395
|
-
return parseInt(hexBlockNumber.slice(2), 16);
|
|
396
|
-
};
|
|
397
|
-
var getContractAbiAndName = async (contractAddress, apiUrl, apiKey) => {
|
|
398
|
-
const searchParams = new URLSearchParams({
|
|
399
|
-
module: "contract",
|
|
400
|
-
action: "getsourcecode",
|
|
401
|
-
address: contractAddress
|
|
402
|
-
});
|
|
403
|
-
if (apiKey)
|
|
404
|
-
searchParams.append("apikey", apiKey);
|
|
405
|
-
const data = await fetchEtherscan(`${apiUrl}?${searchParams.toString()}`);
|
|
406
|
-
const abi = data.result[0].ABI;
|
|
407
|
-
const contractName = data.result[0].ContractName;
|
|
408
|
-
return { abi, contractName };
|
|
409
|
-
};
|
|
410
|
-
var getProxyImplementationAddresses = async ({
|
|
411
|
-
contractAddress,
|
|
412
|
-
apiUrl,
|
|
413
|
-
fromBlock,
|
|
414
|
-
apiKey
|
|
415
|
-
}) => {
|
|
416
|
-
const searchParams = new URLSearchParams({
|
|
417
|
-
module: "logs",
|
|
418
|
-
action: "getLogs",
|
|
419
|
-
address: contractAddress,
|
|
420
|
-
fromBlock: fromBlock ? String(fromBlock) : "0",
|
|
421
|
-
toBlock: "latest",
|
|
422
|
-
topic0: "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b"
|
|
423
|
-
});
|
|
424
|
-
if (apiKey)
|
|
425
|
-
searchParams.append("apikey", apiKey);
|
|
426
|
-
const data = await fetchEtherscan(`${apiUrl}?${searchParams.toString()}`);
|
|
427
|
-
const logs = data.result;
|
|
428
|
-
const implAddresses = logs.map((log) => {
|
|
429
|
-
if (log.topics[0] && log.topics[1]) {
|
|
430
|
-
return `0x${log.topics[1].slice(26)}`;
|
|
431
|
-
} else {
|
|
432
|
-
return `0x${log.data.slice(26)}`;
|
|
433
|
-
}
|
|
434
|
-
});
|
|
435
|
-
return { implAddresses };
|
|
436
|
-
};
|
|
437
|
-
|
|
438
|
-
// src/templates/subgraphId.ts
|
|
439
|
-
var import_node_fs3 = require("fs");
|
|
440
|
-
var import_node_path3 = __toESM(require("path"));
|
|
441
|
-
var import_node_fetch2 = __toESM(require("node-fetch"));
|
|
442
|
-
var import_prettier3 = __toESM(require("prettier"));
|
|
443
|
-
var import_yaml = require("yaml");
|
|
444
|
-
|
|
445
|
-
// src/helpers/getGraphProtocolChainId.ts
|
|
446
|
-
var chainIdByGraphNetwork = {
|
|
447
|
-
mainnet: 1,
|
|
448
|
-
kovan: 42,
|
|
449
|
-
rinkeby: 4,
|
|
450
|
-
ropsten: 3,
|
|
451
|
-
goerli: 5,
|
|
452
|
-
"poa-core": 99,
|
|
453
|
-
"poa-sokol": 77,
|
|
454
|
-
xdai: 100,
|
|
455
|
-
matic: 137,
|
|
456
|
-
mumbai: 80001,
|
|
457
|
-
fantom: 250,
|
|
458
|
-
"fantom-testnet": 4002,
|
|
459
|
-
bsc: 56,
|
|
460
|
-
chapel: -1,
|
|
461
|
-
clover: 0,
|
|
462
|
-
avalanche: 43114,
|
|
463
|
-
fuji: 43113,
|
|
464
|
-
celo: 42220,
|
|
465
|
-
"celo-alfajores": 44787,
|
|
466
|
-
fuse: 122,
|
|
467
|
-
moonbeam: 1284,
|
|
468
|
-
moonriver: 1285,
|
|
469
|
-
mbase: -1,
|
|
470
|
-
"arbitrum-one": 42161,
|
|
471
|
-
"arbitrum-rinkeby": 421611,
|
|
472
|
-
optimism: 10,
|
|
473
|
-
"optimism-kovan": 69,
|
|
474
|
-
aurora: 1313161554,
|
|
475
|
-
"aurora-testnet": 1313161555
|
|
476
|
-
};
|
|
477
|
-
var getGraphProtocolChainId = (networkName) => {
|
|
478
|
-
return chainIdByGraphNetwork[networkName];
|
|
479
|
-
};
|
|
480
|
-
var subgraphYamlFileNames = ["subgraph.yaml"].concat(
|
|
481
|
-
Object.keys(chainIdByGraphNetwork).map((n) => `subgraph-${n}.yaml`)
|
|
482
|
-
);
|
|
483
|
-
|
|
484
|
-
// src/helpers/validateGraphProtocolSource.ts
|
|
485
|
-
var validateGraphProtocolSource = (source) => {
|
|
486
|
-
return source;
|
|
487
|
-
};
|
|
488
|
-
|
|
489
|
-
// src/templates/subgraphId.ts
|
|
490
|
-
var fetchIpfsFile = async (cid) => {
|
|
491
|
-
const url = `https://ipfs.network.thegraph.com/api/v0/cat?arg=${cid}`;
|
|
492
|
-
const response = await (0, import_node_fetch2.default)(url);
|
|
493
|
-
const contentRaw = await response.text();
|
|
494
|
-
return contentRaw;
|
|
495
|
-
};
|
|
496
|
-
var fromSubgraphId = async ({
|
|
497
|
-
rootDir,
|
|
498
|
-
subgraphId
|
|
499
|
-
}) => {
|
|
500
|
-
const ponderNetworks = [];
|
|
501
|
-
let ponderContracts = [];
|
|
502
|
-
const manifestRaw = await fetchIpfsFile(subgraphId);
|
|
503
|
-
const manifest = (0, import_yaml.parse)(manifestRaw);
|
|
504
|
-
const schemaCid = manifest.schema.file["/"].slice(6);
|
|
505
|
-
const schemaRaw = await fetchIpfsFile(schemaCid);
|
|
506
|
-
const schemaCleaned = schemaRaw.replaceAll(": ID!", ": String!").replaceAll("BigDecimal", "Float");
|
|
507
|
-
const ponderSchemaFilePath = import_node_path3.default.join(rootDir, "schema.graphql");
|
|
508
|
-
(0, import_node_fs3.writeFileSync)(
|
|
509
|
-
ponderSchemaFilePath,
|
|
510
|
-
import_prettier3.default.format(schemaCleaned, { parser: "graphql" })
|
|
511
|
-
);
|
|
512
|
-
const dataSources = manifest.dataSources.map(
|
|
513
|
-
validateGraphProtocolSource
|
|
514
|
-
);
|
|
515
|
-
const abiFiles = dataSources.map((source) => source.mapping.abis).flat().filter(
|
|
516
|
-
(source, idx, arr) => arr.findIndex((s) => s.name === source.name) === idx
|
|
517
|
-
);
|
|
518
|
-
await Promise.all(
|
|
519
|
-
abiFiles.map(async (abi) => {
|
|
520
|
-
const abiContent = await fetchIpfsFile(abi.file["/"].slice(6));
|
|
521
|
-
const abiPath = import_node_path3.default.join(rootDir, `./abis/${abi.name}.json`);
|
|
522
|
-
(0, import_node_fs3.writeFileSync)(abiPath, import_prettier3.default.format(abiContent, { parser: "json" }));
|
|
523
|
-
})
|
|
524
|
-
);
|
|
525
|
-
ponderContracts = dataSources.map((source) => {
|
|
526
|
-
const network = source.network || "mainnet";
|
|
527
|
-
const chainId = getGraphProtocolChainId(network);
|
|
528
|
-
if (!chainId || chainId === -1) {
|
|
529
|
-
throw new Error(`Unhandled network name: ${network}`);
|
|
530
|
-
}
|
|
531
|
-
if (!ponderNetworks.map((n) => n.name).includes(network)) {
|
|
532
|
-
ponderNetworks.push({
|
|
533
|
-
name: network,
|
|
534
|
-
chainId,
|
|
535
|
-
rpcUrl: `process.env.PONDER_RPC_URL_${chainId}`
|
|
536
|
-
});
|
|
537
|
-
}
|
|
538
|
-
const abiRelativePath = `./abis/${source.source.abi}.json`;
|
|
539
|
-
return {
|
|
540
|
-
name: source.name,
|
|
541
|
-
network,
|
|
542
|
-
address: source.source.address,
|
|
543
|
-
abi: abiRelativePath,
|
|
544
|
-
startBlock: source.source.startBlock
|
|
545
|
-
};
|
|
546
|
-
});
|
|
547
|
-
const config = {
|
|
548
|
-
networks: ponderNetworks,
|
|
549
|
-
contracts: ponderContracts
|
|
550
|
-
};
|
|
551
|
-
return config;
|
|
552
|
-
};
|
|
553
|
-
|
|
554
|
-
// src/templates/subgraphRepo.ts
|
|
555
|
-
var import_node_fs4 = require("fs");
|
|
556
|
-
var import_node_path4 = __toESM(require("path"));
|
|
557
|
-
var import_prettier4 = __toESM(require("prettier"));
|
|
558
|
-
var import_yaml2 = require("yaml");
|
|
559
|
-
var fromSubgraphRepo = ({
|
|
560
|
-
rootDir,
|
|
561
|
-
subgraphPath
|
|
562
|
-
}) => {
|
|
563
|
-
const subgraphRootDir = import_node_path4.default.resolve(subgraphPath);
|
|
564
|
-
const ponderNetworks = [];
|
|
565
|
-
let ponderContracts = [];
|
|
566
|
-
const subgraphRootDirPath = import_node_path4.default.resolve(subgraphRootDir);
|
|
567
|
-
let subgraphYamlRaw = "";
|
|
568
|
-
for (const subgraphYamlFileName of subgraphYamlFileNames) {
|
|
569
|
-
try {
|
|
570
|
-
subgraphYamlRaw = (0, import_node_fs4.readFileSync)(
|
|
571
|
-
import_node_path4.default.join(subgraphRootDirPath, subgraphYamlFileName),
|
|
572
|
-
{
|
|
573
|
-
encoding: "utf-8"
|
|
574
|
-
}
|
|
575
|
-
);
|
|
576
|
-
break;
|
|
577
|
-
} catch (e) {
|
|
578
|
-
continue;
|
|
579
|
-
}
|
|
580
|
-
}
|
|
581
|
-
if (subgraphYamlRaw === "") {
|
|
582
|
-
throw new Error(`subgraph.yaml file not found`);
|
|
583
|
-
}
|
|
584
|
-
const subgraphYaml = (0, import_yaml2.parse)(subgraphYamlRaw);
|
|
585
|
-
const schemaRaw = (0, import_node_fs4.readFileSync)(
|
|
586
|
-
import_node_path4.default.join(subgraphRootDirPath, subgraphYaml.schema.file),
|
|
587
|
-
{
|
|
588
|
-
encoding: "utf-8"
|
|
589
|
-
}
|
|
590
|
-
);
|
|
591
|
-
const schemaCleaned = schemaRaw.replaceAll(": ID!", ": String!").replaceAll("BigDecimal", "Float");
|
|
592
|
-
(0, import_node_fs4.writeFileSync)(
|
|
593
|
-
import_node_path4.default.join(rootDir, "schema.graphql"),
|
|
594
|
-
import_prettier4.default.format(schemaCleaned, { parser: "graphql" })
|
|
595
|
-
);
|
|
596
|
-
ponderContracts = subgraphYaml.dataSources.map(validateGraphProtocolSource).map((source) => {
|
|
597
|
-
const abiPath = source.mapping.abis.find(
|
|
598
|
-
(abi) => abi.name === source.name
|
|
599
|
-
)?.file;
|
|
600
|
-
if (!abiPath) {
|
|
601
|
-
throw new Error(`ABI path not found for source: ${source.name}`);
|
|
602
|
-
}
|
|
603
|
-
const network = source.network || "mainnet";
|
|
604
|
-
const chainId = getGraphProtocolChainId(network);
|
|
605
|
-
if (!chainId || chainId === -1) {
|
|
606
|
-
throw new Error(`Unhandled network name: ${network}`);
|
|
607
|
-
}
|
|
608
|
-
if (!ponderNetworks.map((n) => n.name).includes(network)) {
|
|
609
|
-
ponderNetworks.push({
|
|
610
|
-
name: network,
|
|
611
|
-
chainId,
|
|
612
|
-
rpcUrl: `process.env.PONDER_RPC_URL_${chainId}`
|
|
613
|
-
});
|
|
614
|
-
}
|
|
615
|
-
const abiAbsolutePath = import_node_path4.default.join(subgraphRootDirPath, abiPath);
|
|
616
|
-
const abiFileName = import_node_path4.default.basename(abiPath);
|
|
617
|
-
const ponderAbiRelativePath = `./abis/${abiFileName}`;
|
|
618
|
-
const ponderAbiAbsolutePath = import_node_path4.default.join(rootDir, ponderAbiRelativePath);
|
|
619
|
-
(0, import_node_fs4.copyFileSync)(abiAbsolutePath, ponderAbiAbsolutePath);
|
|
620
|
-
return {
|
|
621
|
-
name: source.name,
|
|
622
|
-
network,
|
|
623
|
-
address: source.source.address,
|
|
624
|
-
abi: ponderAbiRelativePath,
|
|
625
|
-
startBlock: source.source.startBlock
|
|
626
|
-
};
|
|
627
|
-
});
|
|
628
|
-
const config = {
|
|
629
|
-
networks: ponderNetworks,
|
|
630
|
-
contracts: ponderContracts
|
|
631
|
-
};
|
|
632
|
-
return config;
|
|
633
|
-
};
|
|
634
|
-
|
|
635
|
-
// src/index.ts
|
|
636
|
-
var run = async (options, overrides = {}) => {
|
|
637
|
-
const { rootDir } = options;
|
|
638
|
-
(0, import_node_fs5.mkdirSync)(import_node_path5.default.join(rootDir, "abis"), { recursive: true });
|
|
639
|
-
(0, import_node_fs5.mkdirSync)(import_node_path5.default.join(rootDir, "src"), { recursive: true });
|
|
640
|
-
let config;
|
|
641
|
-
console.log(
|
|
642
|
-
`
|
|
643
|
-
Creating a new Ponder app in ${import_picocolors.default.bold(import_picocolors.default.green(rootDir))}.`
|
|
644
|
-
);
|
|
645
|
-
switch (options.template?.kind) {
|
|
646
|
-
case 1 /* ETHERSCAN */: {
|
|
647
|
-
console.log(`
|
|
648
|
-
Using ${import_picocolors.default.cyan("Etherscan contract link")} template.`);
|
|
649
|
-
config = await fromEtherscan({
|
|
650
|
-
rootDir,
|
|
651
|
-
etherscanLink: options.template.link,
|
|
652
|
-
etherscanApiKey: options.etherscanApiKey
|
|
653
|
-
});
|
|
654
|
-
break;
|
|
655
|
-
}
|
|
656
|
-
case 2 /* SUBGRAPH_ID */: {
|
|
657
|
-
console.log(`
|
|
658
|
-
Using ${import_picocolors.default.cyan("Subgraph ID")} template.`);
|
|
659
|
-
config = await fromSubgraphId({
|
|
660
|
-
rootDir,
|
|
661
|
-
subgraphId: options.template.id
|
|
662
|
-
});
|
|
663
|
-
break;
|
|
664
|
-
}
|
|
665
|
-
case 3 /* SUBGRAPH_REPO */: {
|
|
666
|
-
console.log(`
|
|
667
|
-
Using ${import_picocolors.default.cyan("Subgraph repository")} template.`);
|
|
668
|
-
config = fromSubgraphRepo({
|
|
669
|
-
rootDir,
|
|
670
|
-
subgraphPath: options.template.path
|
|
671
|
-
});
|
|
672
|
-
break;
|
|
673
|
-
}
|
|
674
|
-
default: {
|
|
675
|
-
config = fromBasic({ rootDir });
|
|
676
|
-
break;
|
|
677
|
-
}
|
|
678
|
-
}
|
|
679
|
-
config.contracts.forEach((contract) => {
|
|
680
|
-
let abi;
|
|
681
|
-
if (Array.isArray(contract.abi)) {
|
|
682
|
-
const abiString = (0, import_node_fs5.readFileSync)(import_node_path5.default.join(rootDir, contract.abi[1]), {
|
|
683
|
-
encoding: "utf-8"
|
|
684
|
-
});
|
|
685
|
-
abi = JSON.parse(abiString);
|
|
686
|
-
} else {
|
|
687
|
-
const abiString = (0, import_node_fs5.readFileSync)(import_node_path5.default.join(rootDir, contract.abi), {
|
|
688
|
-
encoding: "utf-8"
|
|
689
|
-
});
|
|
690
|
-
abi = JSON.parse(abiString);
|
|
691
|
-
}
|
|
692
|
-
const abiEvents = abi.filter(
|
|
693
|
-
(item) => item.type === "event"
|
|
694
|
-
);
|
|
695
|
-
const eventNamesToWrite = abiEvents.map((event) => event.name).slice(0, 2);
|
|
696
|
-
const handlerFileContents = `
|
|
697
|
-
import { ponder } from '@/generated'
|
|
698
|
-
|
|
699
|
-
${eventNamesToWrite.map(
|
|
700
|
-
(eventName) => `
|
|
701
|
-
ponder.on("${contract.name}:${eventName}", async ({ event, context }) => {
|
|
702
|
-
console.log(event.params)
|
|
703
|
-
})`
|
|
704
|
-
).join("\n")}
|
|
705
|
-
`;
|
|
706
|
-
(0, import_node_fs5.writeFileSync)(
|
|
707
|
-
import_node_path5.default.join(rootDir, `./src/${contract.name}.ts`),
|
|
708
|
-
import_prettier5.default.format(handlerFileContents, { parser: "typescript" })
|
|
709
|
-
);
|
|
710
|
-
});
|
|
711
|
-
const finalConfig = `
|
|
712
|
-
import type { Config } from "@ponder/core";
|
|
713
|
-
|
|
714
|
-
export const config: Config = {
|
|
715
|
-
networks: ${JSON.stringify(config.networks).replaceAll(
|
|
716
|
-
/"process.env.PONDER_RPC_URL_(.*?)"/g,
|
|
717
|
-
"process.env.PONDER_RPC_URL_$1"
|
|
718
|
-
)},
|
|
719
|
-
contracts: ${JSON.stringify(config.contracts)},
|
|
720
|
-
};
|
|
721
|
-
`;
|
|
722
|
-
(0, import_node_fs5.writeFileSync)(
|
|
723
|
-
import_node_path5.default.join(rootDir, "ponder.config.ts"),
|
|
724
|
-
import_prettier5.default.format(finalConfig, { parser: "babel" })
|
|
725
|
-
);
|
|
726
|
-
const uniqueChainIds = Array.from(
|
|
727
|
-
new Set(config.networks.map((n) => n.chainId))
|
|
728
|
-
);
|
|
729
|
-
const envLocal = `${uniqueChainIds.map(
|
|
730
|
-
(chainId) => `PONDER_RPC_URL_${chainId}=""
|
|
731
|
-
`
|
|
732
|
-
)}`;
|
|
733
|
-
(0, import_node_fs5.writeFileSync)(import_node_path5.default.join(rootDir, ".env.local"), envLocal);
|
|
734
|
-
const packageJson = `
|
|
735
|
-
{
|
|
736
|
-
"private": true,
|
|
737
|
-
"scripts": {
|
|
738
|
-
"dev": "ponder dev",
|
|
739
|
-
"start": "ponder start",
|
|
740
|
-
"codegen": "ponder codegen"
|
|
741
|
-
},
|
|
742
|
-
"dependencies": {
|
|
743
|
-
"@ponder/core": "latest"
|
|
744
|
-
},
|
|
745
|
-
"devDependencies": {
|
|
746
|
-
"@types/node": "^18.11.18",
|
|
747
|
-
"abitype": "^0.8.11",
|
|
748
|
-
"typescript": "^5.1.3",
|
|
749
|
-
"viem": "^1.2.6"
|
|
750
|
-
}
|
|
751
|
-
}
|
|
752
|
-
`;
|
|
753
|
-
(0, import_node_fs5.writeFileSync)(
|
|
754
|
-
import_node_path5.default.join(rootDir, "package.json"),
|
|
755
|
-
import_prettier5.default.format(packageJson, { parser: "json" })
|
|
756
|
-
);
|
|
757
|
-
const tsConfig = `
|
|
758
|
-
{
|
|
759
|
-
"compilerOptions": {
|
|
760
|
-
"target": "ESNext",
|
|
761
|
-
"module": "ESNext",
|
|
762
|
-
"moduleResolution": "node",
|
|
763
|
-
"resolveJsonModule": true,
|
|
764
|
-
"esModuleInterop": true,
|
|
765
|
-
"strict": true,
|
|
766
|
-
"rootDir": ".",
|
|
767
|
-
"paths": {
|
|
768
|
-
"@/generated": ["./generated/index.ts"]
|
|
769
|
-
}
|
|
770
|
-
},
|
|
771
|
-
"include": ["./**/*.ts"],
|
|
772
|
-
"exclude": ["node_modules"]
|
|
773
|
-
}
|
|
774
|
-
`;
|
|
775
|
-
(0, import_node_fs5.writeFileSync)(
|
|
776
|
-
import_node_path5.default.join(rootDir, "tsconfig.json"),
|
|
777
|
-
import_prettier5.default.format(tsConfig, { parser: "json" })
|
|
778
|
-
);
|
|
779
|
-
(0, import_node_fs5.writeFileSync)(
|
|
780
|
-
import_node_path5.default.join(rootDir, ".gitignore"),
|
|
781
|
-
`node_modules/
|
|
782
|
-
.DS_Store
|
|
783
|
-
|
|
784
|
-
.env.local
|
|
785
|
-
.ponder/
|
|
786
|
-
generated/`
|
|
787
|
-
);
|
|
788
|
-
const packageManager = await getPackageManager();
|
|
789
|
-
console.log(import_picocolors.default.bold(`
|
|
790
|
-
Installing with ${packageManager}.`));
|
|
791
|
-
const installCommand = overrides.installCommand ? overrides.installCommand : `${packageManager} ${packageManager === "npm" ? "--quiet" : "--silent"} install`;
|
|
792
|
-
(0, import_node_child_process.execSync)(installCommand, {
|
|
793
|
-
cwd: rootDir,
|
|
794
|
-
stdio: "inherit"
|
|
795
|
-
});
|
|
796
|
-
process.chdir(rootDir);
|
|
797
|
-
tryGitInit(rootDir);
|
|
798
|
-
console.log(`
|
|
799
|
-
Initialized a git repository.`);
|
|
800
|
-
const runCommand = `${packageManager === "npm" ? `npm --quiet run` : `${packageManager} --silent`} codegen`;
|
|
801
|
-
(0, import_node_child_process.execSync)(runCommand, {
|
|
802
|
-
cwd: rootDir,
|
|
803
|
-
stdio: "inherit"
|
|
804
|
-
});
|
|
805
|
-
console.log(`
|
|
806
|
-
Generated types.`);
|
|
807
|
-
console.log(
|
|
808
|
-
import_picocolors.default.green("\nSuccess! ") + `Created ${options.projectName} at ${rootDir}`
|
|
809
|
-
);
|
|
810
|
-
};
|
|
811
|
-
|
|
812
|
-
// package.json
|
|
813
|
-
var package_default = {
|
|
814
|
-
name: "create-ponder",
|
|
815
|
-
version: "0.0.78",
|
|
816
|
-
description: "Tool to bootstrap a Ponder project",
|
|
817
|
-
license: "MIT",
|
|
818
|
-
author: "olias.eth",
|
|
819
|
-
files: [
|
|
820
|
-
"dist"
|
|
821
|
-
],
|
|
822
|
-
bin: {
|
|
823
|
-
"create-ponder": "dist/create-ponder.js"
|
|
824
|
-
},
|
|
825
|
-
scripts: {
|
|
826
|
-
build: "tsup-node",
|
|
827
|
-
test: "export $(grep -v '^#' .env.local | xargs) && vitest --no-threads",
|
|
828
|
-
"test:ci": "vitest --no-threads",
|
|
829
|
-
typecheck: "tsc --noEmit"
|
|
830
|
-
},
|
|
831
|
-
dependencies: {
|
|
832
|
-
cac: "^6.7.14",
|
|
833
|
-
"detect-package-manager": "^2.0.1",
|
|
834
|
-
execa: "5",
|
|
835
|
-
"node-fetch": "^2.6.7",
|
|
836
|
-
picocolors: "^1.0.0",
|
|
837
|
-
prettier: "^2.6.2",
|
|
838
|
-
prompts: "^2.4.2",
|
|
839
|
-
rimraf: "^5.0.1",
|
|
840
|
-
yaml: "^2.1.1"
|
|
841
|
-
},
|
|
842
|
-
devDependencies: {
|
|
843
|
-
"@ponder/core": "workspace:*",
|
|
844
|
-
"@types/node": "^18.7.8",
|
|
845
|
-
"@types/node-fetch": "2",
|
|
846
|
-
"@types/prettier": "^2.7.1",
|
|
847
|
-
"@types/prompts": "^2.4.2",
|
|
848
|
-
abitype: "^0.6.7",
|
|
849
|
-
tsup: "^6.6.3",
|
|
850
|
-
typescript: "^4.5.5",
|
|
851
|
-
vitest: "^0.29.2"
|
|
852
|
-
}
|
|
853
|
-
};
|
|
854
|
-
|
|
855
|
-
// src/bin/create-ponder.ts
|
|
856
|
-
var createPonder = async () => {
|
|
857
|
-
const cli = (0, import_cac.cac)(package_default.name).version(package_default.version).usage("[options]").help().option("--dir [path]", "Path to directory for generated project").option("--from-subgraph-id [id]", "Subgraph deployment ID").option("--from-subgraph-repo [path]", "Path to subgraph repository").option("--from-etherscan [url]", "Link to etherscan contract page").option("--etherscan-api-key [key]", "Etherscan API key");
|
|
858
|
-
const parsed = cli.parse(process.argv);
|
|
859
|
-
const options = parsed.options;
|
|
860
|
-
if (options.help) {
|
|
861
|
-
process.exit(0);
|
|
862
|
-
}
|
|
863
|
-
const { fromEtherscan: fromEtherscan2, fromSubgraphId: fromSubgraphId2, fromSubgraphRepo: fromSubgraphRepo2 } = options;
|
|
864
|
-
if (fromSubgraphId2 && fromSubgraphRepo2 || fromSubgraphId2 && fromEtherscan2 || fromSubgraphRepo2 && fromEtherscan2) {
|
|
865
|
-
throw new Error(
|
|
866
|
-
`Cannot specify more than one "--from" option:
|
|
867
|
-
--from-subgraph
|
|
868
|
-
--from-etherscan-id
|
|
869
|
-
--from-etherscan-repo`
|
|
870
|
-
);
|
|
871
|
-
}
|
|
872
|
-
const { projectName } = await (0, import_prompts.default)({
|
|
873
|
-
type: "text",
|
|
874
|
-
name: "projectName",
|
|
875
|
-
message: "What is your project named?",
|
|
876
|
-
initial: "my-app"
|
|
877
|
-
});
|
|
878
|
-
let template = void 0;
|
|
879
|
-
if (fromEtherscan2) {
|
|
880
|
-
template = { kind: 1 /* ETHERSCAN */, link: fromEtherscan2 };
|
|
881
|
-
}
|
|
882
|
-
if (fromSubgraphId2) {
|
|
883
|
-
template = { kind: 2 /* SUBGRAPH_ID */, id: fromSubgraphId2 };
|
|
884
|
-
}
|
|
885
|
-
if (fromSubgraphRepo2) {
|
|
886
|
-
template = { kind: 3 /* SUBGRAPH_REPO */, path: fromSubgraphRepo2 };
|
|
887
|
-
}
|
|
888
|
-
if (!fromSubgraphId2 && !fromSubgraphRepo2 && !fromEtherscan2) {
|
|
889
|
-
const { template: templateKind } = await (0, import_prompts.default)({
|
|
890
|
-
type: "select",
|
|
891
|
-
name: "template",
|
|
892
|
-
message: "Would you like to use a template for this project?",
|
|
893
|
-
choices: [
|
|
894
|
-
{ title: "None" },
|
|
895
|
-
{ title: "Etherscan contract link" },
|
|
896
|
-
{ title: "Subgraph ID" },
|
|
897
|
-
{ title: "Subgraph repository" }
|
|
898
|
-
]
|
|
899
|
-
});
|
|
900
|
-
if (templateKind === 1 /* ETHERSCAN */) {
|
|
901
|
-
const { link } = await (0, import_prompts.default)({
|
|
902
|
-
type: "text",
|
|
903
|
-
name: "link",
|
|
904
|
-
message: "Enter an Etherscan contract link",
|
|
905
|
-
initial: "https://etherscan.io/address/0x97..."
|
|
906
|
-
});
|
|
907
|
-
template = { kind: 1 /* ETHERSCAN */, link };
|
|
908
|
-
}
|
|
909
|
-
if (templateKind === 2 /* SUBGRAPH_ID */) {
|
|
910
|
-
const { id } = await (0, import_prompts.default)({
|
|
911
|
-
type: "text",
|
|
912
|
-
name: "id",
|
|
913
|
-
message: "Enter a subgraph deployment ID",
|
|
914
|
-
initial: "QmNus..."
|
|
915
|
-
});
|
|
916
|
-
template = { kind: 2 /* SUBGRAPH_ID */, id };
|
|
917
|
-
}
|
|
918
|
-
if (templateKind === 3 /* SUBGRAPH_REPO */) {
|
|
919
|
-
const { path: path8 } = await (0, import_prompts.default)({
|
|
920
|
-
type: "text",
|
|
921
|
-
name: "path",
|
|
922
|
-
message: "Enter a path to a subgraph repository",
|
|
923
|
-
initial: "../subgraph"
|
|
924
|
-
});
|
|
925
|
-
template = { kind: 3 /* SUBGRAPH_REPO */, path: path8 };
|
|
926
|
-
}
|
|
927
|
-
}
|
|
928
|
-
const validatedOptions = {
|
|
929
|
-
projectName,
|
|
930
|
-
rootDir: import_node_path6.default.resolve(".", options.dir ? options.dir : projectName),
|
|
931
|
-
template,
|
|
932
|
-
etherscanApiKey: options.etherscanApiKey
|
|
933
|
-
};
|
|
934
|
-
await run(validatedOptions);
|
|
935
|
-
};
|
|
936
|
-
createPonder();
|
|
937
|
-
//# sourceMappingURL=create-ponder.js.map
|