create-ponder 0.15.18 → 0.16.0
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/dist/index.js +60 -557
- package/package.json +2 -1
- package/templates/etherscan/_dot_env.local +0 -5
- package/templates/etherscan/_dot_eslintrc.json +0 -3
- package/templates/etherscan/_dot_gitignore +0 -18
- package/templates/etherscan/package.json +0 -28
- package/templates/etherscan/ponder-env.d.ts +0 -15
- package/templates/etherscan/ponder.schema.ts +0 -6
- package/templates/etherscan/tsconfig.json +0 -26
- package/templates/subgraph/_dot_env.local +0 -5
- package/templates/subgraph/_dot_eslintrc.json +0 -3
- package/templates/subgraph/_dot_gitignore +0 -18
- package/templates/subgraph/package.json +0 -28
- package/templates/subgraph/ponder-env.d.ts +0 -15
- package/templates/subgraph/ponder.schema.ts +0 -6
- package/templates/subgraph/tsconfig.json +0 -26
package/dist/index.js
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/index.ts
|
|
4
|
-
import { mkdirSync
|
|
5
|
-
import
|
|
4
|
+
import { mkdirSync, writeFileSync } from "node:fs";
|
|
5
|
+
import path2 from "node:path";
|
|
6
6
|
import { fileURLToPath } from "node:url";
|
|
7
7
|
import { cac } from "cac";
|
|
8
8
|
import cpy from "cpy";
|
|
9
9
|
import { execa } from "execa";
|
|
10
10
|
import fs from "fs-extra";
|
|
11
11
|
import { oraPromise } from "ora";
|
|
12
|
-
import
|
|
13
|
-
import
|
|
12
|
+
import pico4 from "picocolors";
|
|
13
|
+
import prettier from "prettier";
|
|
14
14
|
import { default as prompts } from "prompts";
|
|
15
15
|
|
|
16
16
|
// package.json
|
|
17
17
|
var package_default = {
|
|
18
18
|
name: "create-ponder",
|
|
19
|
-
version: "0.
|
|
19
|
+
version: "0.16.0",
|
|
20
20
|
type: "module",
|
|
21
21
|
description: "A CLI tool to create Ponder apps",
|
|
22
22
|
license: "MIT",
|
|
@@ -32,6 +32,7 @@ var package_default = {
|
|
|
32
32
|
scripts: {
|
|
33
33
|
build: "tsup",
|
|
34
34
|
test: "vitest run",
|
|
35
|
+
"test:bun": "bun test",
|
|
35
36
|
typecheck: "tsc --noEmit"
|
|
36
37
|
},
|
|
37
38
|
dependencies: {
|
|
@@ -64,274 +65,8 @@ var package_default = {
|
|
|
64
65
|
}
|
|
65
66
|
};
|
|
66
67
|
|
|
67
|
-
// src/etherscan.ts
|
|
68
|
-
import { mkdirSync, writeFileSync } from "node:fs";
|
|
69
|
-
import path from "node:path";
|
|
70
|
-
|
|
71
|
-
// src/helpers/wait.ts
|
|
72
|
-
var wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
73
|
-
|
|
74
|
-
// src/etherscan.ts
|
|
75
|
-
import pico from "picocolors";
|
|
76
|
-
import prettier from "prettier";
|
|
77
|
-
import * as chains from "viem/chains";
|
|
78
|
-
var chainExplorerByHostname = {};
|
|
79
|
-
for (const [name, chain] of Object.entries(chains)) {
|
|
80
|
-
for (const explorer of Object.values(chain.blockExplorers ?? {})) {
|
|
81
|
-
const hostname = new URL(explorer.url).hostname;
|
|
82
|
-
chainExplorerByHostname[hostname] = {
|
|
83
|
-
name,
|
|
84
|
-
id: chain.id,
|
|
85
|
-
explorer
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
var fromEtherscan = async ({
|
|
90
|
-
rootDir,
|
|
91
|
-
etherscanLink,
|
|
92
|
-
etherscanApiKey
|
|
93
|
-
}) => {
|
|
94
|
-
const warnings = [];
|
|
95
|
-
const apiKey = etherscanApiKey || process.env.ETHERSCAN_API_KEY;
|
|
96
|
-
const explorerUrl = new URL(etherscanLink);
|
|
97
|
-
const chainExplorer = chainExplorerByHostname[explorerUrl.hostname];
|
|
98
|
-
if (!chainExplorer)
|
|
99
|
-
throw new Error(
|
|
100
|
-
`Block explorer (${explorerUrl.hostname}) is not present in viem/chains.`
|
|
101
|
-
);
|
|
102
|
-
const name = chainExplorer.name;
|
|
103
|
-
const chainId = chainExplorer.id;
|
|
104
|
-
const apiUrl = chainExplorer.explorer.apiUrl;
|
|
105
|
-
if (!apiUrl)
|
|
106
|
-
throw new Error(
|
|
107
|
-
`${pico.red("\u2717")} Block explorer (${explorerUrl.hostname}) does not have a API URL registered in viem/chains.`
|
|
108
|
-
);
|
|
109
|
-
const pathComponents = explorerUrl.pathname.slice(1).split("/");
|
|
110
|
-
const contractAddress = pathComponents[1];
|
|
111
|
-
if (pathComponents[0] !== "address" || !(typeof contractAddress === "string") || !contractAddress.startsWith("0x")) {
|
|
112
|
-
throw new Error(
|
|
113
|
-
`${pico.red("\u2717")} Invalid block explorer URL (${explorerUrl.href}). Expected path "/address/<contract-address>".`
|
|
114
|
-
);
|
|
115
|
-
}
|
|
116
|
-
const abiResult = await getContractAbiAndName(
|
|
117
|
-
contractAddress,
|
|
118
|
-
apiUrl,
|
|
119
|
-
apiKey
|
|
120
|
-
);
|
|
121
|
-
warnings.push(...abiResult.warnings);
|
|
122
|
-
const baseAbi = abiResult.abi;
|
|
123
|
-
let contractName = abiResult.contractName;
|
|
124
|
-
const abis = [
|
|
125
|
-
{ abi: baseAbi, contractName }
|
|
126
|
-
];
|
|
127
|
-
let blockNumber = void 0;
|
|
128
|
-
try {
|
|
129
|
-
if (!apiKey)
|
|
130
|
-
await wait(5e3);
|
|
131
|
-
const txHash = await getContractCreationTxn(
|
|
132
|
-
contractAddress,
|
|
133
|
-
apiUrl,
|
|
134
|
-
apiKey
|
|
135
|
-
);
|
|
136
|
-
if (!apiKey)
|
|
137
|
-
await wait(5e3);
|
|
138
|
-
const contractCreationBlockNumber = await getTxBlockNumber(
|
|
139
|
-
txHash,
|
|
140
|
-
apiUrl,
|
|
141
|
-
apiKey
|
|
142
|
-
);
|
|
143
|
-
blockNumber = contractCreationBlockNumber;
|
|
144
|
-
} catch (e) {
|
|
145
|
-
const error = e;
|
|
146
|
-
warnings.push(
|
|
147
|
-
`Unable to fetch contract deployment block number from block explorer. Error: ${error.message}`
|
|
148
|
-
);
|
|
149
|
-
}
|
|
150
|
-
if (baseAbi.find(
|
|
151
|
-
(item) => item.type === "event" && item.name === "Upgraded" && item.inputs[0].name === "implementation"
|
|
152
|
-
)) {
|
|
153
|
-
if (!apiKey)
|
|
154
|
-
await wait(5e3);
|
|
155
|
-
const { implAddresses } = await getProxyImplementationAddresses({
|
|
156
|
-
contractAddress,
|
|
157
|
-
apiUrl,
|
|
158
|
-
fromBlock: blockNumber,
|
|
159
|
-
apiKey
|
|
160
|
-
});
|
|
161
|
-
for (const implAddress of implAddresses) {
|
|
162
|
-
if (!apiKey)
|
|
163
|
-
await wait(5e3);
|
|
164
|
-
const abiResult2 = await getContractAbiAndName(
|
|
165
|
-
implAddress,
|
|
166
|
-
apiUrl,
|
|
167
|
-
apiKey
|
|
168
|
-
);
|
|
169
|
-
warnings.push(...abiResult2.warnings);
|
|
170
|
-
abis.push({
|
|
171
|
-
abi: abiResult2.abi,
|
|
172
|
-
contractName: `${abiResult2.contractName}_${implAddress.slice(0, 6)}`
|
|
173
|
-
});
|
|
174
|
-
contractName = abiResult2.contractName;
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
mkdirSync(path.join(rootDir, "abis"), { recursive: true });
|
|
178
|
-
mkdirSync(path.join(rootDir, "src"), { recursive: true });
|
|
179
|
-
let abiConfig;
|
|
180
|
-
for (const { abi, contractName: contractName2 } of abis) {
|
|
181
|
-
const abiRelativePath = `./abis/${contractName2}Abi.ts`;
|
|
182
|
-
const abiAbsolutePath = path.join(
|
|
183
|
-
path.resolve(".", rootDir),
|
|
184
|
-
abiRelativePath
|
|
185
|
-
);
|
|
186
|
-
writeFileSync(
|
|
187
|
-
abiAbsolutePath,
|
|
188
|
-
await prettier.format(
|
|
189
|
-
`export const ${contractName2}Abi = ${JSON.stringify(abi)} as const`,
|
|
190
|
-
{
|
|
191
|
-
parser: "typescript"
|
|
192
|
-
}
|
|
193
|
-
)
|
|
194
|
-
);
|
|
195
|
-
if (abis.length === 1) {
|
|
196
|
-
abiConfig = {
|
|
197
|
-
abi,
|
|
198
|
-
dir: abiRelativePath,
|
|
199
|
-
name: `${contractName2}Abi`
|
|
200
|
-
};
|
|
201
|
-
} else {
|
|
202
|
-
if (abiConfig === void 0) {
|
|
203
|
-
abiConfig = [];
|
|
204
|
-
}
|
|
205
|
-
abiConfig.push({
|
|
206
|
-
abi,
|
|
207
|
-
name: `${contractName2}Abi`,
|
|
208
|
-
dir: abiRelativePath
|
|
209
|
-
});
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
const config = {
|
|
213
|
-
chains: {
|
|
214
|
-
[name]: {
|
|
215
|
-
id: chainId,
|
|
216
|
-
rpc: `http(process.env.PONDER_RPC_URL_${chainId})`
|
|
217
|
-
}
|
|
218
|
-
},
|
|
219
|
-
contracts: {
|
|
220
|
-
[contractName]: {
|
|
221
|
-
abi: abiConfig,
|
|
222
|
-
address: contractAddress,
|
|
223
|
-
chain: name,
|
|
224
|
-
startBlock: blockNumber ?? void 0
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
};
|
|
228
|
-
return { config, warnings };
|
|
229
|
-
};
|
|
230
|
-
var fetchEtherscan = async (url) => {
|
|
231
|
-
const maxRetries = 5;
|
|
232
|
-
let retryCount = 0;
|
|
233
|
-
while (retryCount <= maxRetries) {
|
|
234
|
-
try {
|
|
235
|
-
const response = await fetch(url);
|
|
236
|
-
const data = await response.json();
|
|
237
|
-
return data;
|
|
238
|
-
} catch (error) {
|
|
239
|
-
retryCount++;
|
|
240
|
-
if (retryCount > maxRetries) {
|
|
241
|
-
throw new Error(`Max retries reached: ${error.message}`);
|
|
242
|
-
}
|
|
243
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
};
|
|
247
|
-
var getContractCreationTxn = async (contractAddress, apiUrl, apiKey) => {
|
|
248
|
-
const searchParams = new URLSearchParams({
|
|
249
|
-
module: "contract",
|
|
250
|
-
action: "getcontractcreation",
|
|
251
|
-
contractaddresses: contractAddress
|
|
252
|
-
});
|
|
253
|
-
if (apiKey)
|
|
254
|
-
searchParams.append("apikey", apiKey);
|
|
255
|
-
const data = await fetchEtherscan(`${apiUrl}?${searchParams.toString()}`);
|
|
256
|
-
return data.result[0].txHash;
|
|
257
|
-
};
|
|
258
|
-
var getTxBlockNumber = async (txHash, apiUrl, apiKey) => {
|
|
259
|
-
const searchParams = new URLSearchParams({
|
|
260
|
-
module: "proxy",
|
|
261
|
-
action: "eth_getTransactionByHash",
|
|
262
|
-
txhash: txHash
|
|
263
|
-
});
|
|
264
|
-
if (apiKey)
|
|
265
|
-
searchParams.append("apikey", apiKey);
|
|
266
|
-
const data = await fetchEtherscan(`${apiUrl}?${searchParams.toString()}`);
|
|
267
|
-
const hexBlockNumber = data.result.blockNumber;
|
|
268
|
-
return Number.parseInt(hexBlockNumber.slice(2), 16);
|
|
269
|
-
};
|
|
270
|
-
var getContractAbiAndName = async (contractAddress, apiUrl, apiKey) => {
|
|
271
|
-
const searchParams = new URLSearchParams({
|
|
272
|
-
module: "contract",
|
|
273
|
-
action: "getsourcecode",
|
|
274
|
-
address: contractAddress
|
|
275
|
-
});
|
|
276
|
-
if (apiKey)
|
|
277
|
-
searchParams.append("apikey", apiKey);
|
|
278
|
-
const warnings = [];
|
|
279
|
-
let abi;
|
|
280
|
-
let contractName;
|
|
281
|
-
try {
|
|
282
|
-
const data = await fetchEtherscan(`${apiUrl}?${searchParams.toString()}`);
|
|
283
|
-
const rawAbi = data.result[0].ABI;
|
|
284
|
-
if (rawAbi === "Contract source code not verified") {
|
|
285
|
-
warnings.push(
|
|
286
|
-
`Contract ${contractAddress} is unverified or has an empty ABI.`
|
|
287
|
-
);
|
|
288
|
-
abi = [];
|
|
289
|
-
} else {
|
|
290
|
-
abi = JSON.parse(rawAbi);
|
|
291
|
-
}
|
|
292
|
-
contractName = data.result[0].ContractName ?? "";
|
|
293
|
-
if (contractName === "")
|
|
294
|
-
contractName = "UnverifiedContract";
|
|
295
|
-
} catch (e) {
|
|
296
|
-
const error = e;
|
|
297
|
-
warnings.push(
|
|
298
|
-
`Failed to fetch ABI for contract ${contractAddress}. Marking as unverified. Error: ${error.message}`
|
|
299
|
-
);
|
|
300
|
-
abi = [];
|
|
301
|
-
contractName = "UnverifiedContract";
|
|
302
|
-
}
|
|
303
|
-
return { abi, contractName, warnings };
|
|
304
|
-
};
|
|
305
|
-
var getProxyImplementationAddresses = async ({
|
|
306
|
-
contractAddress,
|
|
307
|
-
apiUrl,
|
|
308
|
-
fromBlock,
|
|
309
|
-
apiKey
|
|
310
|
-
}) => {
|
|
311
|
-
const searchParams = new URLSearchParams({
|
|
312
|
-
module: "logs",
|
|
313
|
-
action: "getLogs",
|
|
314
|
-
address: contractAddress,
|
|
315
|
-
fromBlock: fromBlock ? String(fromBlock) : "0",
|
|
316
|
-
toBlock: "latest",
|
|
317
|
-
topic0: "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b"
|
|
318
|
-
});
|
|
319
|
-
if (apiKey)
|
|
320
|
-
searchParams.append("apikey", apiKey);
|
|
321
|
-
const data = await fetchEtherscan(`${apiUrl}?${searchParams.toString()}`);
|
|
322
|
-
const logs = data.result;
|
|
323
|
-
const implAddresses = logs.map((log3) => {
|
|
324
|
-
if (log3.topics[0] && log3.topics[1]) {
|
|
325
|
-
return `0x${log3.topics[1].slice(26)}`;
|
|
326
|
-
} else {
|
|
327
|
-
return `0x${log3.data.slice(26)}`;
|
|
328
|
-
}
|
|
329
|
-
});
|
|
330
|
-
return { implAddresses };
|
|
331
|
-
};
|
|
332
|
-
|
|
333
68
|
// src/helpers/getPackageManager.ts
|
|
334
|
-
import
|
|
69
|
+
import pico from "picocolors";
|
|
335
70
|
var getPackageManager = ({
|
|
336
71
|
options
|
|
337
72
|
}) => {
|
|
@@ -356,7 +91,7 @@ var getPackageManager = ({
|
|
|
356
91
|
if (userAgent.includes("yarn"))
|
|
357
92
|
return "yarn";
|
|
358
93
|
}
|
|
359
|
-
throw new Error(
|
|
94
|
+
throw new Error(pico.red("Undetectable package manager"));
|
|
360
95
|
};
|
|
361
96
|
|
|
362
97
|
// src/helpers/mergeAbis.ts
|
|
@@ -375,7 +110,7 @@ var mergeAbis = (abis) => {
|
|
|
375
110
|
};
|
|
376
111
|
|
|
377
112
|
// src/helpers/notifyUpdate.ts
|
|
378
|
-
import
|
|
113
|
+
import pico2 from "picocolors";
|
|
379
114
|
import checkForUpdate from "update-check";
|
|
380
115
|
var log = console.log;
|
|
381
116
|
async function notifyUpdate({ options }) {
|
|
@@ -385,11 +120,11 @@ async function notifyUpdate({ options }) {
|
|
|
385
120
|
const packageManager = getPackageManager({ options });
|
|
386
121
|
const updateMessage = packageManager === "bun" ? "bun install --global create-ponder" : packageManager === "pnpm" ? "pnpm add -g create-ponder" : packageManager === "npm" ? "npm install -g create-ponder" : "yarn global add create-ponder";
|
|
387
122
|
log(
|
|
388
|
-
|
|
389
|
-
`${
|
|
123
|
+
pico2.bold(
|
|
124
|
+
`${pico2.yellow(
|
|
390
125
|
"A new version of `create-ponder` is available!"
|
|
391
126
|
)}
|
|
392
|
-
You can update by running: ${
|
|
127
|
+
You can update by running: ${pico2.cyan(updateMessage)}
|
|
393
128
|
`
|
|
394
129
|
)
|
|
395
130
|
);
|
|
@@ -400,9 +135,9 @@ You can update by running: ${pico3.cyan(updateMessage)}
|
|
|
400
135
|
}
|
|
401
136
|
|
|
402
137
|
// src/helpers/validate.ts
|
|
403
|
-
import
|
|
138
|
+
import path from "node:path";
|
|
404
139
|
import { pathExists } from "fs-extra";
|
|
405
|
-
import
|
|
140
|
+
import pico3 from "picocolors";
|
|
406
141
|
import validatePackageName from "validate-npm-package-name";
|
|
407
142
|
async function validateProjectName({
|
|
408
143
|
projectName
|
|
@@ -429,7 +164,7 @@ async function validateProjectPath({
|
|
|
429
164
|
if (await pathExists(projectPath))
|
|
430
165
|
return {
|
|
431
166
|
valid: false,
|
|
432
|
-
message: `\u{1F648} the directory "${
|
|
167
|
+
message: `\u{1F648} the directory "${path.relative(process.cwd(), projectPath)}" already exists.`,
|
|
433
168
|
problems: "\u{1F449} choose another name or delete the directory."
|
|
434
169
|
};
|
|
435
170
|
return {
|
|
@@ -458,179 +193,14 @@ async function validateTemplateName({
|
|
|
458
193
|
var ValidationError = class extends Error {
|
|
459
194
|
name = "ValidationError";
|
|
460
195
|
constructor(validation) {
|
|
461
|
-
super([
|
|
196
|
+
super([pico3.red(validation.message), validation.problems].join("\n"));
|
|
462
197
|
}
|
|
463
198
|
};
|
|
464
199
|
|
|
465
|
-
// src/subgraph.ts
|
|
466
|
-
import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
467
|
-
import path3 from "node:path";
|
|
468
|
-
import prettier2 from "prettier";
|
|
469
|
-
import { parse } from "yaml";
|
|
470
|
-
|
|
471
|
-
// src/helpers/getGraphProtocolChainId.ts
|
|
472
|
-
var chainIdByGraphNetwork = {
|
|
473
|
-
mainnet: 1,
|
|
474
|
-
kovan: 42,
|
|
475
|
-
rinkeby: 4,
|
|
476
|
-
ropsten: 3,
|
|
477
|
-
goerli: 5,
|
|
478
|
-
sepolia: 11155111,
|
|
479
|
-
"poa-core": 99,
|
|
480
|
-
"poa-sokol": 77,
|
|
481
|
-
xdai: 100,
|
|
482
|
-
matic: 137,
|
|
483
|
-
mumbai: 80001,
|
|
484
|
-
fantom: 250,
|
|
485
|
-
"fantom-testnet": 4002,
|
|
486
|
-
bsc: 56,
|
|
487
|
-
avalanche: 43114,
|
|
488
|
-
fuji: 43113,
|
|
489
|
-
celo: 42220,
|
|
490
|
-
"celo-alfajores": 44787,
|
|
491
|
-
fuse: 122,
|
|
492
|
-
moonbeam: 1284,
|
|
493
|
-
moonriver: 1285,
|
|
494
|
-
base: 8453,
|
|
495
|
-
"base-sepolia": 84532,
|
|
496
|
-
"arbitrum-one": 42161,
|
|
497
|
-
"arbitrum-sepolia": 421614,
|
|
498
|
-
optimism: 10,
|
|
499
|
-
"optimism-sepolia": 11155420,
|
|
500
|
-
aurora: 1313161554,
|
|
501
|
-
"aurora-testnet": 1313161555
|
|
502
|
-
};
|
|
503
|
-
var getGraphProtocolChainId = (networkName) => {
|
|
504
|
-
return chainIdByGraphNetwork[networkName] ?? 0;
|
|
505
|
-
};
|
|
506
|
-
var subgraphYamlFileNames = ["subgraph.yaml"].concat(
|
|
507
|
-
Object.keys(chainIdByGraphNetwork).map((n) => `subgraph-${n}.yaml`)
|
|
508
|
-
);
|
|
509
|
-
|
|
510
|
-
// src/helpers/validateGraphProtocolSource.ts
|
|
511
|
-
var validateGraphProtocolSource = (source) => {
|
|
512
|
-
return source;
|
|
513
|
-
};
|
|
514
|
-
|
|
515
|
-
// src/subgraph.ts
|
|
516
|
-
var subgraphProviders = [
|
|
517
|
-
{
|
|
518
|
-
id: "thegraph",
|
|
519
|
-
name: "The Graph",
|
|
520
|
-
// Used to be https://ipfs.network.thegraph.com/api/v0/cat?arg=${cid}
|
|
521
|
-
// Also used to accept GET requests for some reason
|
|
522
|
-
fetchIpfs: async (cid) => {
|
|
523
|
-
const response = await fetch(
|
|
524
|
-
`https://api.thegraph.com/ipfs/api/v0/cat?arg=${cid}`,
|
|
525
|
-
{ method: "POST" }
|
|
526
|
-
);
|
|
527
|
-
return await response.text();
|
|
528
|
-
}
|
|
529
|
-
},
|
|
530
|
-
{
|
|
531
|
-
id: "satsuma",
|
|
532
|
-
name: "Alchemy Subgraph (Satsuma)",
|
|
533
|
-
fetchIpfs: async (cid) => {
|
|
534
|
-
const response = await fetch(`https://ipfs.satsuma.xyz/ipfs/${cid}`);
|
|
535
|
-
return await response.text();
|
|
536
|
-
}
|
|
537
|
-
}
|
|
538
|
-
];
|
|
539
|
-
var fromSubgraphId = async ({
|
|
540
|
-
rootDir,
|
|
541
|
-
subgraphId,
|
|
542
|
-
subgraphProvider
|
|
543
|
-
}) => {
|
|
544
|
-
const provider = subgraphProviders.find((p) => p.id === subgraphProvider);
|
|
545
|
-
if (!provider)
|
|
546
|
-
throw new Error(`Unknown subgraph provider: ${subgraphProvider}`);
|
|
547
|
-
const manifestRaw = await provider.fetchIpfs(subgraphId);
|
|
548
|
-
const manifest = parse(manifestRaw);
|
|
549
|
-
const contracts = {};
|
|
550
|
-
manifest.dataSources.forEach((d) => {
|
|
551
|
-
contracts[d.name] = {
|
|
552
|
-
chain: d.network,
|
|
553
|
-
address: d.source.address,
|
|
554
|
-
startBlock: d.source.startBlock
|
|
555
|
-
};
|
|
556
|
-
});
|
|
557
|
-
const dataSources = manifest.dataSources;
|
|
558
|
-
mkdirSync2(path3.join(rootDir, "abis"), { recursive: true });
|
|
559
|
-
mkdirSync2(path3.join(rootDir, "src"), { recursive: true });
|
|
560
|
-
const abiFiles = dataSources.flatMap((source) => validateGraphProtocolSource(source).mapping.abis).filter(
|
|
561
|
-
(source, idx, arr) => arr.findIndex((s) => s.name === source.name) === idx
|
|
562
|
-
);
|
|
563
|
-
const abis = {};
|
|
564
|
-
await Promise.all(
|
|
565
|
-
abiFiles.map(async (abi) => {
|
|
566
|
-
const abiContent = await provider.fetchIpfs(abi.file["/"].slice(6));
|
|
567
|
-
const abiPath = path3.join(rootDir, `./abis/${abi.name}Abi.ts`);
|
|
568
|
-
writeFileSync2(
|
|
569
|
-
abiPath,
|
|
570
|
-
await prettier2.format(
|
|
571
|
-
`export const ${abi.name}Abi = ${abiContent} as const`,
|
|
572
|
-
{
|
|
573
|
-
parser: "typescript"
|
|
574
|
-
}
|
|
575
|
-
)
|
|
576
|
-
);
|
|
577
|
-
abis[abi.name] = JSON.parse(abiContent);
|
|
578
|
-
})
|
|
579
|
-
);
|
|
580
|
-
const ponderContracts = dataSources.map((sourceInvalid) => {
|
|
581
|
-
const source = validateGraphProtocolSource(sourceInvalid);
|
|
582
|
-
const chain = source.network || "mainnet";
|
|
583
|
-
const abiRelativePath = `./abis/${source.source.abi}Abi.ts`;
|
|
584
|
-
return {
|
|
585
|
-
name: source.name,
|
|
586
|
-
chain,
|
|
587
|
-
address: source.source.address,
|
|
588
|
-
abi: {
|
|
589
|
-
abi: abis[source.source.abi],
|
|
590
|
-
dir: abiRelativePath,
|
|
591
|
-
name: `${source.source.abi}Abi`
|
|
592
|
-
},
|
|
593
|
-
startBlock: source.source.startBlock
|
|
594
|
-
};
|
|
595
|
-
});
|
|
596
|
-
const contractsObject = {};
|
|
597
|
-
const chainsObject = {};
|
|
598
|
-
ponderContracts.forEach((pc) => {
|
|
599
|
-
const chainId = getGraphProtocolChainId(pc.chain);
|
|
600
|
-
contractsObject[pc.name] = pc;
|
|
601
|
-
chainsObject[pc.chain] = {
|
|
602
|
-
id: chainId,
|
|
603
|
-
rpc: `process.env.PONDER_RPC_URL_${chainId}!`
|
|
604
|
-
};
|
|
605
|
-
contractsObject[pc.name].name = void 0;
|
|
606
|
-
});
|
|
607
|
-
const config = {
|
|
608
|
-
chains: chainsObject,
|
|
609
|
-
contracts: contractsObject
|
|
610
|
-
};
|
|
611
|
-
const warnings = [];
|
|
612
|
-
if (manifest.templates?.length > 0) {
|
|
613
|
-
warnings.push(
|
|
614
|
-
"Factory contract detected. Please see the factory contract documentation for more details: https://ponder.sh/docs/indexing/read-contracts#factory-contracts"
|
|
615
|
-
);
|
|
616
|
-
}
|
|
617
|
-
return { config, warnings };
|
|
618
|
-
};
|
|
619
|
-
|
|
620
200
|
// src/index.ts
|
|
621
201
|
var log2 = console.log;
|
|
622
202
|
var templates = [
|
|
623
203
|
{ id: "empty", title: "Default", description: "A blank-slate Ponder app" },
|
|
624
|
-
{
|
|
625
|
-
id: "etherscan",
|
|
626
|
-
title: "Etherscan contract link",
|
|
627
|
-
description: "Create from an Etherscan contract link"
|
|
628
|
-
},
|
|
629
|
-
{
|
|
630
|
-
id: "subgraph",
|
|
631
|
-
title: "Subgraph ID",
|
|
632
|
-
description: "Create from a deployed subgraph"
|
|
633
|
-
},
|
|
634
204
|
{
|
|
635
205
|
id: "feature-factory",
|
|
636
206
|
title: "Feature - Factory contract",
|
|
@@ -716,13 +286,13 @@ async function run({
|
|
|
716
286
|
const warnings = [];
|
|
717
287
|
log2();
|
|
718
288
|
log2(
|
|
719
|
-
`Welcome to ${
|
|
720
|
-
|
|
289
|
+
`Welcome to ${pico4.bold(
|
|
290
|
+
pico4.blue("create-ponder")
|
|
721
291
|
)} \u2013 the quickest way to get started with Ponder!`
|
|
722
292
|
);
|
|
723
293
|
log2();
|
|
724
294
|
const __dirname = fileURLToPath(new URL(".", import.meta.url));
|
|
725
|
-
const templatesPath =
|
|
295
|
+
const templatesPath = path2.join(__dirname, "..", "templates");
|
|
726
296
|
let templateId = options.template || options.t;
|
|
727
297
|
let templateValidation = await validateTemplateName({
|
|
728
298
|
isNameRequired: false,
|
|
@@ -735,14 +305,14 @@ async function run({
|
|
|
735
305
|
let projectPath;
|
|
736
306
|
if (args[0]) {
|
|
737
307
|
projectPath = args[0].trim();
|
|
738
|
-
if (!
|
|
739
|
-
projectPath =
|
|
740
|
-
const splitPath = projectPath.split(
|
|
308
|
+
if (!path2.isAbsolute(projectPath))
|
|
309
|
+
projectPath = path2.resolve(projectPath);
|
|
310
|
+
const splitPath = projectPath.split(path2.sep);
|
|
741
311
|
projectName = splitPath[splitPath.length - 1]?.trim() || "";
|
|
742
312
|
const nameValidation = await validateProjectName({ projectName });
|
|
743
313
|
if (!nameValidation.valid)
|
|
744
314
|
throw new ValidationError(nameValidation);
|
|
745
|
-
log2(
|
|
315
|
+
log2(pico4.green("\u2714"), pico4.bold("Using project name:"), projectName);
|
|
746
316
|
} else {
|
|
747
317
|
const res = await prompts({
|
|
748
318
|
initial: "my-app",
|
|
@@ -757,12 +327,12 @@ async function run({
|
|
|
757
327
|
}
|
|
758
328
|
});
|
|
759
329
|
projectName = res.projectName?.trim();
|
|
760
|
-
projectPath =
|
|
330
|
+
projectPath = path2.resolve(projectName);
|
|
761
331
|
}
|
|
762
332
|
const pathValidation = await validateProjectPath({ projectPath });
|
|
763
333
|
if (!pathValidation.valid)
|
|
764
334
|
throw new ValidationError(pathValidation);
|
|
765
|
-
|
|
335
|
+
mkdirSync(projectPath, { recursive: true });
|
|
766
336
|
if (options.etherscan && !templateId)
|
|
767
337
|
templateId = "etherscan";
|
|
768
338
|
if (options.subgraph && !templateId)
|
|
@@ -788,83 +358,9 @@ async function run({
|
|
|
788
358
|
if (!templateValidation.valid)
|
|
789
359
|
throw new ValidationError(templateValidation);
|
|
790
360
|
let config;
|
|
791
|
-
let url = options.etherscan;
|
|
792
|
-
if (templateMeta.id === "etherscan") {
|
|
793
|
-
if (!url) {
|
|
794
|
-
const result = await prompts({
|
|
795
|
-
type: "text",
|
|
796
|
-
name: "url",
|
|
797
|
-
message: "Enter a block explorer contract url",
|
|
798
|
-
initial: "https://etherscan.io/address/0x97..."
|
|
799
|
-
});
|
|
800
|
-
url = result.url;
|
|
801
|
-
}
|
|
802
|
-
}
|
|
803
|
-
let subgraph = options.subgraph;
|
|
804
|
-
let subgraphProvider = options.subgraphProvider;
|
|
805
|
-
if (templateMeta.id === "subgraph") {
|
|
806
|
-
if (subgraphProvider === void 0) {
|
|
807
|
-
const result = await prompts({
|
|
808
|
-
name: "subgraphProvider",
|
|
809
|
-
message: "Which provider is the subgraph deployed to?",
|
|
810
|
-
type: "select",
|
|
811
|
-
choices: subgraphProviders.map(({ id, name }) => ({
|
|
812
|
-
title: name,
|
|
813
|
-
value: id
|
|
814
|
-
}))
|
|
815
|
-
});
|
|
816
|
-
subgraphProvider = result.subgraphProvider;
|
|
817
|
-
}
|
|
818
|
-
if (!subgraph) {
|
|
819
|
-
const result = await prompts({
|
|
820
|
-
type: "text",
|
|
821
|
-
name: "id",
|
|
822
|
-
message: "Enter a subgraph Deployment ID",
|
|
823
|
-
initial: "Qmb3hd2hYd2nWFgcmRswykF1dUBSrDUrinYCgN1dmE1tNy"
|
|
824
|
-
});
|
|
825
|
-
subgraph = result.id;
|
|
826
|
-
}
|
|
827
|
-
if (!subgraph) {
|
|
828
|
-
log2(pico5.red("No subgraph Deployment ID provided."));
|
|
829
|
-
process.exit(0);
|
|
830
|
-
}
|
|
831
|
-
}
|
|
832
361
|
log2();
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
const result = await oraPromise(
|
|
836
|
-
fromEtherscan({
|
|
837
|
-
rootDir: projectPath,
|
|
838
|
-
etherscanLink: url,
|
|
839
|
-
etherscanApiKey: options.etherscanApiKey
|
|
840
|
-
}),
|
|
841
|
-
{
|
|
842
|
-
text: `Fetching contract metadata from ${pico5.bold(host)}. This may take a few seconds.`,
|
|
843
|
-
failText: "Failed to fetch contract metadata.",
|
|
844
|
-
successText: `Fetched contract metadata from ${pico5.bold(host)}.`
|
|
845
|
-
}
|
|
846
|
-
);
|
|
847
|
-
config = result.config;
|
|
848
|
-
warnings.push(...result.warnings);
|
|
849
|
-
}
|
|
850
|
-
if (templateMeta.id === "subgraph") {
|
|
851
|
-
const result = await oraPromise(
|
|
852
|
-
fromSubgraphId({
|
|
853
|
-
rootDir: projectPath,
|
|
854
|
-
subgraphId: subgraph,
|
|
855
|
-
subgraphProvider
|
|
856
|
-
}),
|
|
857
|
-
{
|
|
858
|
-
text: "Fetching subgraph metadata. This may take a few seconds.",
|
|
859
|
-
failText: "Failed to fetch subgraph metadata.",
|
|
860
|
-
successText: `Fetched subgraph metadata for ${pico5.bold(subgraph)}.`
|
|
861
|
-
}
|
|
862
|
-
);
|
|
863
|
-
config = result.config;
|
|
864
|
-
warnings.push(...result.warnings);
|
|
865
|
-
}
|
|
866
|
-
const templatePath = path4.join(templatesPath, templateMeta.id);
|
|
867
|
-
await cpy(path4.join(templatePath, "**", "*"), projectPath, {
|
|
362
|
+
const templatePath = path2.join(templatesPath, templateMeta.id);
|
|
363
|
+
await cpy(path2.join(templatePath, "**", "*"), projectPath, {
|
|
868
364
|
rename: (name) => name.replace(/^_dot_/, ".")
|
|
869
365
|
});
|
|
870
366
|
if (config) {
|
|
@@ -896,9 +392,9 @@ async function run({
|
|
|
896
392
|
).replaceAll(/"abi":"(.*?)"/g, "abi:$1")},
|
|
897
393
|
});
|
|
898
394
|
`;
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
await
|
|
395
|
+
writeFileSync(
|
|
396
|
+
path2.join(projectPath, "ponder.config.ts"),
|
|
397
|
+
await prettier.format(configContent, { parser: "typescript" })
|
|
902
398
|
);
|
|
903
399
|
for (const [name, contract] of Object.entries(config.contracts)) {
|
|
904
400
|
const abi = Array.isArray(contract.abi) ? mergeAbis(contract.abi.map((a) => a.abi)) : contract.abi.abi;
|
|
@@ -916,20 +412,23 @@ async function run({
|
|
|
916
412
|
})`
|
|
917
413
|
).join("\n")}
|
|
918
414
|
`;
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
await
|
|
415
|
+
writeFileSync(
|
|
416
|
+
path2.join(projectPath, "src", `${name}.ts`),
|
|
417
|
+
await prettier.format(indexingFunctionFileContents, {
|
|
922
418
|
parser: "typescript"
|
|
923
419
|
})
|
|
924
420
|
);
|
|
925
421
|
}
|
|
926
422
|
}
|
|
927
|
-
const packageJson = await fs.readJSON(
|
|
423
|
+
const packageJson = await fs.readJSON(path2.join(projectPath, "package.json"));
|
|
928
424
|
packageJson.name = projectName;
|
|
929
425
|
packageJson.dependencies.ponder = `^${package_default.version}`;
|
|
930
426
|
packageJson.devDependencies["eslint-config-ponder"] = `^${package_default.version}`;
|
|
427
|
+
if ("bun" in process.versions) {
|
|
428
|
+
packageJson.scripts = addBunFlagToScripts(packageJson.scripts ?? {});
|
|
429
|
+
}
|
|
931
430
|
await fs.writeFile(
|
|
932
|
-
|
|
431
|
+
path2.join(projectPath, "package.json"),
|
|
933
432
|
JSON.stringify(packageJson, null, 2)
|
|
934
433
|
);
|
|
935
434
|
const packageManager = getPackageManager({ options });
|
|
@@ -951,9 +450,9 @@ async function run({
|
|
|
951
450
|
}
|
|
952
451
|
}),
|
|
953
452
|
{
|
|
954
|
-
text: `Installing packages with ${
|
|
453
|
+
text: `Installing packages with ${pico4.bold(packageManager)}. This may take a few seconds.`,
|
|
955
454
|
failText: "Failed to install packages.",
|
|
956
|
-
successText: `Installed packages with ${
|
|
455
|
+
successText: `Installed packages with ${pico4.bold(packageManager)}.`
|
|
957
456
|
}
|
|
958
457
|
);
|
|
959
458
|
}
|
|
@@ -982,22 +481,22 @@ async function run({
|
|
|
982
481
|
}
|
|
983
482
|
log2();
|
|
984
483
|
for (const warning of warnings) {
|
|
985
|
-
log2(`${
|
|
484
|
+
log2(`${pico4.yellow("\u26A0")} ${warning}`);
|
|
986
485
|
}
|
|
987
486
|
log2();
|
|
988
487
|
log2("\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015");
|
|
989
488
|
log2();
|
|
990
489
|
log2(
|
|
991
|
-
`${
|
|
992
|
-
|
|
490
|
+
`${pico4.green("Success!")} Created ${pico4.bold(projectName)} at ${pico4.green(
|
|
491
|
+
path2.resolve(projectPath)
|
|
993
492
|
)}`
|
|
994
493
|
);
|
|
995
494
|
log2();
|
|
996
495
|
log2(
|
|
997
|
-
`To start your app, run ${
|
|
998
|
-
|
|
999
|
-
)} and then ${
|
|
1000
|
-
|
|
496
|
+
`To start your app, run ${pico4.bold(
|
|
497
|
+
pico4.cyan(`cd ${path2.relative(process.cwd(), projectPath)}`)
|
|
498
|
+
)} and then ${pico4.bold(
|
|
499
|
+
pico4.cyan(
|
|
1001
500
|
`${packageManager}${packageManager === "npm" || packageManager === "bun" ? " run" : ""} dev`
|
|
1002
501
|
)
|
|
1003
502
|
)}`
|
|
@@ -1006,16 +505,20 @@ async function run({
|
|
|
1006
505
|
log2("\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015");
|
|
1007
506
|
log2();
|
|
1008
507
|
}
|
|
508
|
+
function addBunFlagToScripts(scripts) {
|
|
509
|
+
const ret = {};
|
|
510
|
+
for (const [k, v] of Object.entries(scripts)) {
|
|
511
|
+
if (v.startsWith("ponder"))
|
|
512
|
+
ret[k] = `bun --bun ${v}`;
|
|
513
|
+
else
|
|
514
|
+
ret[k] = v;
|
|
515
|
+
}
|
|
516
|
+
return ret;
|
|
517
|
+
}
|
|
1009
518
|
(async () => {
|
|
1010
|
-
const cli = cac(package_default.name).version(package_default.version).usage(`${
|
|
519
|
+
const cli = cac(package_default.name).version(package_default.version).usage(`${pico4.green("<directory>")} [options]`).option(
|
|
1011
520
|
"-t, --template [id]",
|
|
1012
521
|
`Use a template. Options: ${templates.map(({ id }) => id).join(", ")}`
|
|
1013
|
-
).option("--etherscan [url]", "Use the Etherscan template").option(
|
|
1014
|
-
"--etherscan-api-key [key]",
|
|
1015
|
-
"Etherscan API key for Etherscan template"
|
|
1016
|
-
).option("--subgraph [id]", "Use the subgraph template").option(
|
|
1017
|
-
"--subgraph-provider [provider]",
|
|
1018
|
-
`Specify the subgraph provider. Options: ${subgraphProviders.map(({ id }) => id).join(", ")}`
|
|
1019
522
|
).option("--npm", "Use npm as your package manager").option("--pnpm", "Use pnpm as your package manager").option("--yarn", "Use yarn as your package manager").option("--skip-git", "Skip initializing a git repository").option("--skip-install", "Skip installing packages").help();
|
|
1020
523
|
const _nodeVersion = process.version.split(".");
|
|
1021
524
|
const nodeVersion = [
|
|
@@ -1025,7 +528,7 @@ async function run({
|
|
|
1025
528
|
];
|
|
1026
529
|
if (nodeVersion[0] < 18 || nodeVersion[0] === 18 && nodeVersion[1] < 14)
|
|
1027
530
|
throw new Error(
|
|
1028
|
-
|
|
531
|
+
pico4.red(
|
|
1029
532
|
`Node version:${process.version} does not meet the >=18.14 requirement`
|
|
1030
533
|
)
|
|
1031
534
|
);
|
|
@@ -1036,7 +539,7 @@ async function run({
|
|
|
1036
539
|
await notifyUpdate({ options });
|
|
1037
540
|
} catch (error) {
|
|
1038
541
|
log2(
|
|
1039
|
-
error instanceof ValidationError ? error.message :
|
|
542
|
+
error instanceof ValidationError ? error.message : pico4.red(error.message)
|
|
1040
543
|
);
|
|
1041
544
|
log2();
|
|
1042
545
|
await notifyUpdate({ options });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-ponder",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A CLI tool to create Ponder apps",
|
|
6
6
|
"license": "MIT",
|
|
@@ -47,6 +47,7 @@
|
|
|
47
47
|
"scripts": {
|
|
48
48
|
"build": "tsup",
|
|
49
49
|
"test": "vitest run",
|
|
50
|
+
"test:bun": "bun test",
|
|
50
51
|
"typecheck": "tsc --noEmit"
|
|
51
52
|
}
|
|
52
53
|
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "ponder-etherscan",
|
|
3
|
-
"version": "0.0.1",
|
|
4
|
-
"private": true,
|
|
5
|
-
"type": "module",
|
|
6
|
-
"scripts": {
|
|
7
|
-
"dev": "ponder dev",
|
|
8
|
-
"start": "ponder start",
|
|
9
|
-
"db": "ponder db",
|
|
10
|
-
"codegen": "ponder codegen",
|
|
11
|
-
"lint": "eslint .",
|
|
12
|
-
"typecheck": "tsc"
|
|
13
|
-
},
|
|
14
|
-
"dependencies": {
|
|
15
|
-
"ponder": "^0.0.95",
|
|
16
|
-
"hono": "^4.5.0",
|
|
17
|
-
"viem": "^2.21.3"
|
|
18
|
-
},
|
|
19
|
-
"devDependencies": {
|
|
20
|
-
"@types/node": "^20.9.0",
|
|
21
|
-
"eslint": "^8.53.0",
|
|
22
|
-
"eslint-config-ponder": "^0.0.95",
|
|
23
|
-
"typescript": "^5.2.2"
|
|
24
|
-
},
|
|
25
|
-
"engines": {
|
|
26
|
-
"node": ">=18.14"
|
|
27
|
-
}
|
|
28
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
/// <reference types="ponder/virtual" />
|
|
2
|
-
|
|
3
|
-
declare module "ponder:internal" {
|
|
4
|
-
const config: typeof import("./ponder.config.ts");
|
|
5
|
-
const schema: typeof import("./ponder.schema.ts");
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
declare module "ponder:schema" {
|
|
9
|
-
export * from "./ponder.schema.ts";
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
// This file enables type checking and editor autocomplete for this Ponder project.
|
|
13
|
-
// After upgrading, you may find that changes have been made to this file.
|
|
14
|
-
// If this happens, please commit the changes. Do not manually edit this file.
|
|
15
|
-
// See https://ponder.sh/docs/requirements#typescript for more information.
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
// Type checking
|
|
4
|
-
"strict": true,
|
|
5
|
-
"noUncheckedIndexedAccess": true,
|
|
6
|
-
|
|
7
|
-
// Interop constraints
|
|
8
|
-
"verbatimModuleSyntax": false,
|
|
9
|
-
"esModuleInterop": true,
|
|
10
|
-
"isolatedModules": true,
|
|
11
|
-
"allowSyntheticDefaultImports": true,
|
|
12
|
-
"resolveJsonModule": true,
|
|
13
|
-
|
|
14
|
-
// Language and environment
|
|
15
|
-
"moduleResolution": "bundler",
|
|
16
|
-
"module": "ESNext",
|
|
17
|
-
"noEmit": true,
|
|
18
|
-
"lib": ["ES2022"],
|
|
19
|
-
"target": "ES2022",
|
|
20
|
-
|
|
21
|
-
// Skip type checking for node modules
|
|
22
|
-
"skipLibCheck": true
|
|
23
|
-
},
|
|
24
|
-
"include": ["./**/*.ts"],
|
|
25
|
-
"exclude": ["node_modules"]
|
|
26
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "ponder-etherscan",
|
|
3
|
-
"version": "0.0.1",
|
|
4
|
-
"private": true,
|
|
5
|
-
"type": "module",
|
|
6
|
-
"scripts": {
|
|
7
|
-
"dev": "ponder dev",
|
|
8
|
-
"start": "ponder start",
|
|
9
|
-
"db": "ponder db",
|
|
10
|
-
"codegen": "ponder codegen",
|
|
11
|
-
"lint": "eslint .",
|
|
12
|
-
"typecheck": "tsc"
|
|
13
|
-
},
|
|
14
|
-
"dependencies": {
|
|
15
|
-
"ponder": "^0.0.95",
|
|
16
|
-
"hono": "^4.5.0",
|
|
17
|
-
"viem": "^2.21.3"
|
|
18
|
-
},
|
|
19
|
-
"devDependencies": {
|
|
20
|
-
"@types/node": "^20.9.0",
|
|
21
|
-
"eslint": "^8.53.0",
|
|
22
|
-
"eslint-config-ponder": "^0.0.95",
|
|
23
|
-
"typescript": "^5.2.2"
|
|
24
|
-
},
|
|
25
|
-
"engines": {
|
|
26
|
-
"node": ">=18.14"
|
|
27
|
-
}
|
|
28
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
/// <reference types="ponder/virtual" />
|
|
2
|
-
|
|
3
|
-
declare module "ponder:internal" {
|
|
4
|
-
const config: typeof import("./ponder.config.ts");
|
|
5
|
-
const schema: typeof import("./ponder.schema.ts");
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
declare module "ponder:schema" {
|
|
9
|
-
export * from "./ponder.schema.ts";
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
// This file enables type checking and editor autocomplete for this Ponder project.
|
|
13
|
-
// After upgrading, you may find that changes have been made to this file.
|
|
14
|
-
// If this happens, please commit the changes. Do not manually edit this file.
|
|
15
|
-
// See https://ponder.sh/docs/requirements#typescript for more information.
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
// Type checking
|
|
4
|
-
"strict": true,
|
|
5
|
-
"noUncheckedIndexedAccess": true,
|
|
6
|
-
|
|
7
|
-
// Interop constraints
|
|
8
|
-
"verbatimModuleSyntax": false,
|
|
9
|
-
"esModuleInterop": true,
|
|
10
|
-
"isolatedModules": true,
|
|
11
|
-
"allowSyntheticDefaultImports": true,
|
|
12
|
-
"resolveJsonModule": true,
|
|
13
|
-
|
|
14
|
-
// Language and environment
|
|
15
|
-
"moduleResolution": "bundler",
|
|
16
|
-
"module": "ESNext",
|
|
17
|
-
"noEmit": true,
|
|
18
|
-
"lib": ["ES2022"],
|
|
19
|
-
"target": "ES2022",
|
|
20
|
-
|
|
21
|
-
// Skip type checking for node modules
|
|
22
|
-
"skipLibCheck": true
|
|
23
|
-
},
|
|
24
|
-
"include": ["./**/*.ts"],
|
|
25
|
-
"exclude": ["node_modules"]
|
|
26
|
-
}
|