create-ponder 0.1.6 → 0.1.7
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 +136 -180
- package/package.json +3 -2
- package/templates/empty/ponder-env.d.ts +25 -3
- package/templates/etherscan/ponder-env.d.ts +25 -3
- package/templates/feature-factory/ponder-env.d.ts +23 -3
- package/templates/feature-filter/ponder-env.d.ts +23 -3
- package/templates/feature-multichain/ponder-env.d.ts +23 -3
- package/templates/feature-proxy/ponder-env.d.ts +23 -3
- package/templates/feature-read-contract/ponder-env.d.ts +23 -3
- package/templates/project-friendtech/ponder-env.d.ts +23 -3
- package/templates/project-uniswap-v3-flash/ponder-env.d.ts +23 -3
- package/templates/reference-erc20/ponder-env.d.ts +23 -3
- package/templates/reference-erc721/ponder-env.d.ts +23 -3
package/dist/index.js
CHANGED
|
@@ -9,14 +9,14 @@ import cpy from "cpy";
|
|
|
9
9
|
import { execa } from "execa";
|
|
10
10
|
import fs2 from "fs-extra";
|
|
11
11
|
import { oraPromise } from "ora";
|
|
12
|
-
import
|
|
12
|
+
import pico5 from "picocolors";
|
|
13
13
|
import prettier2 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.1.
|
|
19
|
+
version: "0.1.7",
|
|
20
20
|
type: "module",
|
|
21
21
|
description: "A CLI tool to create Ponder apps",
|
|
22
22
|
license: "MIT",
|
|
@@ -47,7 +47,8 @@ var package_default = {
|
|
|
47
47
|
prettier: "^3.1.0",
|
|
48
48
|
prompts: "^2.4.2",
|
|
49
49
|
"update-check": "^1.5.4",
|
|
50
|
-
"validate-npm-package-name": "^5.0.0"
|
|
50
|
+
"validate-npm-package-name": "^5.0.0",
|
|
51
|
+
viem: "^2.0.10"
|
|
51
52
|
},
|
|
52
53
|
devDependencies: {
|
|
53
54
|
"@types/fs-extra": "^11.0.4",
|
|
@@ -67,118 +68,82 @@ var package_default = {
|
|
|
67
68
|
// src/etherscan.ts
|
|
68
69
|
import { mkdirSync, writeFileSync } from "node:fs";
|
|
69
70
|
import path from "node:path";
|
|
70
|
-
import prettier from "prettier";
|
|
71
|
-
|
|
72
|
-
// src/helpers/getEtherscanChainId.ts
|
|
73
|
-
var networkByEtherscanHostname = {
|
|
74
|
-
"etherscan.io": {
|
|
75
|
-
name: "mainnet",
|
|
76
|
-
chainId: 1,
|
|
77
|
-
apiUrl: "https://api.etherscan.io/api"
|
|
78
|
-
},
|
|
79
|
-
"ropsten.etherscan.io": {
|
|
80
|
-
name: "ropsten",
|
|
81
|
-
chainId: 3,
|
|
82
|
-
apiUrl: "https://api-ropsten.etherscan.io/api"
|
|
83
|
-
},
|
|
84
|
-
"rinkeby.etherscan.io": {
|
|
85
|
-
name: "rinkeby",
|
|
86
|
-
chainId: 4,
|
|
87
|
-
apiUrl: "https://api-rinkeby.etherscan.io/api"
|
|
88
|
-
},
|
|
89
|
-
"goerli.etherscan.io": {
|
|
90
|
-
name: "goerli",
|
|
91
|
-
chainId: 5,
|
|
92
|
-
apiUrl: "https://api-goerli.etherscan.io/api"
|
|
93
|
-
},
|
|
94
|
-
"kovan.etherscan.io": {
|
|
95
|
-
name: "kovan",
|
|
96
|
-
chainId: 42,
|
|
97
|
-
apiUrl: "https://api-kovan.etherscan.io/api"
|
|
98
|
-
},
|
|
99
|
-
"sepolia.etherscan.io": {
|
|
100
|
-
name: "sepolia",
|
|
101
|
-
chainId: 11155111,
|
|
102
|
-
apiUrl: "https://api-sepolia.etherscan.io/api"
|
|
103
|
-
},
|
|
104
|
-
"optimistic.etherscan.io": {
|
|
105
|
-
name: "optimism",
|
|
106
|
-
chainId: 10,
|
|
107
|
-
apiUrl: "https://api-optimistic.etherscan.io/api"
|
|
108
|
-
},
|
|
109
|
-
"goerli-optimism.etherscan.io": {
|
|
110
|
-
name: "optimism-goerli",
|
|
111
|
-
chainId: 420,
|
|
112
|
-
apiUrl: "https://api-goerli-optimistic.etherscan.io/api"
|
|
113
|
-
},
|
|
114
|
-
"polygonscan.com": {
|
|
115
|
-
name: "polygon",
|
|
116
|
-
chainId: 137,
|
|
117
|
-
apiUrl: "https://api.polygonscan.com/api"
|
|
118
|
-
},
|
|
119
|
-
"mumbai.polygonscan.com": {
|
|
120
|
-
name: "polygon-mumbai",
|
|
121
|
-
chainId: 80001,
|
|
122
|
-
apiUrl: "https://api-testnet.polygonscan.com/api"
|
|
123
|
-
},
|
|
124
|
-
"arbiscan.io": {
|
|
125
|
-
name: "arbitrum",
|
|
126
|
-
chainId: 42161,
|
|
127
|
-
apiUrl: "https://api.arbiscan.io/api"
|
|
128
|
-
},
|
|
129
|
-
"goerli.arbiscan.io": {
|
|
130
|
-
name: "arbitrum-goerli",
|
|
131
|
-
chainId: 421613,
|
|
132
|
-
apiUrl: "https://api-goerli.arbiscan.io/api"
|
|
133
|
-
},
|
|
134
|
-
"explorer.zora.energy": {
|
|
135
|
-
name: "zora",
|
|
136
|
-
chainId: 7777777,
|
|
137
|
-
apiUrl: "https://explorer.zora.energy/api"
|
|
138
|
-
},
|
|
139
|
-
"basescan.org": {
|
|
140
|
-
name: "base",
|
|
141
|
-
chainId: 8453,
|
|
142
|
-
apiUrl: "https://api.basescan.org/api"
|
|
143
|
-
},
|
|
144
|
-
"goerli.basescan.org": {
|
|
145
|
-
name: "base-goerli",
|
|
146
|
-
chainId: 84531,
|
|
147
|
-
apiUrl: "https://api-goerli.basescan.org/api"
|
|
148
|
-
}
|
|
149
|
-
};
|
|
150
|
-
var getNetworkByEtherscanHostname = (hostname) => {
|
|
151
|
-
return networkByEtherscanHostname[hostname];
|
|
152
|
-
};
|
|
153
71
|
|
|
154
72
|
// src/helpers/wait.ts
|
|
155
73
|
var wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
156
74
|
|
|
157
75
|
// src/etherscan.ts
|
|
76
|
+
import pico from "picocolors";
|
|
77
|
+
import prettier from "prettier";
|
|
78
|
+
import * as chains from "viem/chains";
|
|
79
|
+
var chainExplorerByHostname = {};
|
|
80
|
+
for (const [name, chain] of Object.entries(chains)) {
|
|
81
|
+
for (const explorer of Object.values(chain.blockExplorers ?? {})) {
|
|
82
|
+
const hostname = new URL(explorer.url).hostname;
|
|
83
|
+
chainExplorerByHostname[hostname] = {
|
|
84
|
+
name,
|
|
85
|
+
id: chain.id,
|
|
86
|
+
explorer
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
}
|
|
158
90
|
var fromEtherscan = async ({
|
|
159
91
|
rootDir,
|
|
160
92
|
etherscanLink,
|
|
161
93
|
etherscanApiKey
|
|
162
94
|
}) => {
|
|
163
95
|
const apiKey = etherscanApiKey || process.env.ETHERSCAN_API_KEY;
|
|
164
|
-
const
|
|
165
|
-
const
|
|
166
|
-
if (!
|
|
167
|
-
throw new Error(
|
|
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
|
+
let abiResult = void 0;
|
|
117
|
+
try {
|
|
118
|
+
abiResult = await getContractAbiAndName(contractAddress, apiUrl, apiKey);
|
|
119
|
+
} catch (e) {
|
|
120
|
+
const error = e;
|
|
121
|
+
throw new Error(
|
|
122
|
+
`${pico.red("\u2717")} Failed to fetch contract ABI from block explorer API: ${error.message}`
|
|
123
|
+
);
|
|
168
124
|
}
|
|
169
|
-
|
|
170
|
-
|
|
125
|
+
if (typeof abiResult.abi !== "string")
|
|
126
|
+
throw new Error(
|
|
127
|
+
`${pico.red(
|
|
128
|
+
"\u2717"
|
|
129
|
+
)} Invalid ABI returned from block explorer API. Is the contract verified?`
|
|
130
|
+
);
|
|
131
|
+
const baseAbi = JSON.parse(abiResult.abi);
|
|
132
|
+
let contractName = abiResult.contractName;
|
|
133
|
+
const abis = [
|
|
134
|
+
{ abi: baseAbi, contractName }
|
|
135
|
+
];
|
|
171
136
|
let blockNumber = void 0;
|
|
172
137
|
try {
|
|
138
|
+
if (!apiKey)
|
|
139
|
+
await wait(5e3);
|
|
173
140
|
const txHash = await getContractCreationTxn(
|
|
174
141
|
contractAddress,
|
|
175
142
|
apiUrl,
|
|
176
143
|
apiKey
|
|
177
144
|
);
|
|
178
|
-
if (!apiKey)
|
|
179
|
-
console.log("\n(1/n) Waiting 5 seconds for Etherscan API rate limit");
|
|
145
|
+
if (!apiKey)
|
|
180
146
|
await wait(5e3);
|
|
181
|
-
}
|
|
182
147
|
const contractCreationBlockNumber = await getTxBlockNumber(
|
|
183
148
|
txHash,
|
|
184
149
|
apiUrl,
|
|
@@ -187,47 +152,24 @@ var fromEtherscan = async ({
|
|
|
187
152
|
blockNumber = contractCreationBlockNumber;
|
|
188
153
|
} catch (error) {
|
|
189
154
|
}
|
|
190
|
-
if (
|
|
191
|
-
console.log("(2/n) Waiting 5 seconds for Etherscan API rate limit");
|
|
192
|
-
await wait(5e3);
|
|
193
|
-
}
|
|
194
|
-
const abis = [];
|
|
195
|
-
const abiAndName = await getContractAbiAndName(
|
|
196
|
-
contractAddress,
|
|
197
|
-
apiUrl,
|
|
198
|
-
apiKey
|
|
199
|
-
);
|
|
200
|
-
const { abi } = abiAndName;
|
|
201
|
-
let contractName = abiAndName.contractName;
|
|
202
|
-
abis.push({ abi: JSON.parse(abi), contractName });
|
|
203
|
-
if (JSON.parse(abi).find(
|
|
155
|
+
if (baseAbi.find(
|
|
204
156
|
(item) => item.type === "event" && item.name === "Upgraded" && item.inputs[0].name === "implementation"
|
|
205
157
|
)) {
|
|
206
|
-
|
|
207
|
-
"Detected EIP-1967 proxy, fetching implementation contract ABIs"
|
|
208
|
-
);
|
|
209
|
-
if (!apiKey) {
|
|
210
|
-
console.log("(3/n) Waiting 5 seconds for Etherscan API rate limit");
|
|
158
|
+
if (!apiKey)
|
|
211
159
|
await wait(5e3);
|
|
212
|
-
}
|
|
213
160
|
const { implAddresses } = await getProxyImplementationAddresses({
|
|
214
161
|
contractAddress,
|
|
215
162
|
apiUrl,
|
|
216
163
|
fromBlock: blockNumber,
|
|
217
164
|
apiKey
|
|
218
165
|
});
|
|
219
|
-
for (const
|
|
220
|
-
|
|
221
|
-
if (!apiKey) {
|
|
222
|
-
console.log(
|
|
223
|
-
`(${4 + index}/${4 + implAddresses.length - 1}) Waiting 5 seconds for Etherscan API rate limit`
|
|
224
|
-
);
|
|
166
|
+
for (const implAddress of implAddresses) {
|
|
167
|
+
if (!apiKey)
|
|
225
168
|
await wait(5e3);
|
|
226
|
-
}
|
|
227
|
-
const { abi: abi2, contractName: implContractName } = await getContractAbiAndName(implAddress, apiUrl, apiKey);
|
|
169
|
+
const { abi, contractName: implContractName } = await getContractAbiAndName(implAddress, apiUrl, apiKey);
|
|
228
170
|
contractName = implContractName;
|
|
229
171
|
abis.push({
|
|
230
|
-
abi: JSON.parse(
|
|
172
|
+
abi: JSON.parse(abi),
|
|
231
173
|
contractName: `${contractName}_${implAddress.slice(0, 6)}`
|
|
232
174
|
});
|
|
233
175
|
}
|
|
@@ -235,7 +177,7 @@ var fromEtherscan = async ({
|
|
|
235
177
|
mkdirSync(path.join(rootDir, "abis"), { recursive: true });
|
|
236
178
|
mkdirSync(path.join(rootDir, "src"), { recursive: true });
|
|
237
179
|
let abiConfig;
|
|
238
|
-
for (const { abi
|
|
180
|
+
for (const { abi, contractName: contractName2 } of abis) {
|
|
239
181
|
const abiRelativePath = `./abis/${contractName2}Abi.ts`;
|
|
240
182
|
const abiAbsolutePath = path.join(
|
|
241
183
|
path.resolve(".", rootDir),
|
|
@@ -244,7 +186,7 @@ var fromEtherscan = async ({
|
|
|
244
186
|
writeFileSync(
|
|
245
187
|
abiAbsolutePath,
|
|
246
188
|
await prettier.format(
|
|
247
|
-
`export const ${contractName2}Abi = ${JSON.stringify(
|
|
189
|
+
`export const ${contractName2}Abi = ${JSON.stringify(abi)} as const`,
|
|
248
190
|
{
|
|
249
191
|
parser: "typescript"
|
|
250
192
|
}
|
|
@@ -252,7 +194,7 @@ var fromEtherscan = async ({
|
|
|
252
194
|
);
|
|
253
195
|
if (abis.length === 1) {
|
|
254
196
|
abiConfig = {
|
|
255
|
-
abi
|
|
197
|
+
abi,
|
|
256
198
|
dir: abiRelativePath,
|
|
257
199
|
name: `${contractName2}Abi`
|
|
258
200
|
};
|
|
@@ -261,7 +203,7 @@ var fromEtherscan = async ({
|
|
|
261
203
|
abiConfig = [];
|
|
262
204
|
}
|
|
263
205
|
abiConfig.push({
|
|
264
|
-
abi
|
|
206
|
+
abi,
|
|
265
207
|
name: `${contractName2}Abi`,
|
|
266
208
|
dir: abiRelativePath
|
|
267
209
|
});
|
|
@@ -292,9 +234,6 @@ var fetchEtherscan = async (url) => {
|
|
|
292
234
|
try {
|
|
293
235
|
const response = await fetch(url);
|
|
294
236
|
const data = await response.json();
|
|
295
|
-
if (data.status === "0") {
|
|
296
|
-
throw new Error(`Etherscan API error: ${data.result}`);
|
|
297
|
-
}
|
|
298
237
|
return data;
|
|
299
238
|
} catch (error) {
|
|
300
239
|
retryCount++;
|
|
@@ -370,7 +309,7 @@ var getProxyImplementationAddresses = async ({
|
|
|
370
309
|
};
|
|
371
310
|
|
|
372
311
|
// src/helpers/getPackageManager.ts
|
|
373
|
-
import
|
|
312
|
+
import pico2 from "picocolors";
|
|
374
313
|
var getPackageManager = ({
|
|
375
314
|
options
|
|
376
315
|
}) => {
|
|
@@ -395,11 +334,11 @@ var getPackageManager = ({
|
|
|
395
334
|
if (userAgent.includes("yarn"))
|
|
396
335
|
return "yarn";
|
|
397
336
|
}
|
|
398
|
-
throw Error(
|
|
337
|
+
throw Error(pico2.red("Undetectable package manager"));
|
|
399
338
|
};
|
|
400
339
|
|
|
401
340
|
// src/helpers/notifyUpdate.ts
|
|
402
|
-
import
|
|
341
|
+
import pico3 from "picocolors";
|
|
403
342
|
import checkForUpdate from "update-check";
|
|
404
343
|
var log = console.log;
|
|
405
344
|
async function notifyUpdate({ options }) {
|
|
@@ -409,11 +348,11 @@ async function notifyUpdate({ options }) {
|
|
|
409
348
|
const packageManager = getPackageManager({ options });
|
|
410
349
|
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";
|
|
411
350
|
log(
|
|
412
|
-
|
|
413
|
-
`${
|
|
351
|
+
pico3.bold(
|
|
352
|
+
`${pico3.yellow(
|
|
414
353
|
"A new version of `create-ponder` is available!"
|
|
415
354
|
)}
|
|
416
|
-
You can update by running: ${
|
|
355
|
+
You can update by running: ${pico3.cyan(updateMessage)}
|
|
417
356
|
`
|
|
418
357
|
)
|
|
419
358
|
);
|
|
@@ -426,7 +365,7 @@ You can update by running: ${pico2.cyan(updateMessage)}
|
|
|
426
365
|
// src/helpers/validate.ts
|
|
427
366
|
import path2 from "path";
|
|
428
367
|
import fs from "fs-extra";
|
|
429
|
-
import
|
|
368
|
+
import pico4 from "picocolors";
|
|
430
369
|
import validatePackageName from "validate-npm-package-name";
|
|
431
370
|
async function validateProjectName({
|
|
432
371
|
projectName,
|
|
@@ -477,7 +416,7 @@ async function validateTemplateName({
|
|
|
477
416
|
var ValidationError = class extends Error {
|
|
478
417
|
name = "ValidationError";
|
|
479
418
|
constructor(validation) {
|
|
480
|
-
super([
|
|
419
|
+
super([pico4.red(validation.message), validation.problems].join("\n"));
|
|
481
420
|
}
|
|
482
421
|
};
|
|
483
422
|
|
|
@@ -544,8 +483,8 @@ async function run({
|
|
|
544
483
|
return;
|
|
545
484
|
log2();
|
|
546
485
|
log2(
|
|
547
|
-
`Welcome to ${
|
|
548
|
-
|
|
486
|
+
`Welcome to ${pico5.bold(
|
|
487
|
+
pico5.blue("create-ponder")
|
|
549
488
|
)} \u2013 the quickest way to get started with Ponder!`
|
|
550
489
|
);
|
|
551
490
|
log2();
|
|
@@ -565,7 +504,7 @@ async function run({
|
|
|
565
504
|
projectPath = args[0].trim();
|
|
566
505
|
const splitPath = projectPath.split("/");
|
|
567
506
|
projectName = splitPath[splitPath.length - 1]?.trim() || "";
|
|
568
|
-
log2(
|
|
507
|
+
log2(pico5.green("\u2714"), pico5.bold("Using project name:"), projectName);
|
|
569
508
|
} else {
|
|
570
509
|
const res = await prompts({
|
|
571
510
|
initial: "my-app",
|
|
@@ -615,27 +554,37 @@ async function run({
|
|
|
615
554
|
throw new ValidationError(templateValidation);
|
|
616
555
|
let config;
|
|
617
556
|
const targetPath = path3.join(process.cwd(), projectPath);
|
|
557
|
+
let link = void 0;
|
|
618
558
|
if (templateMeta.id === "etherscan") {
|
|
619
|
-
|
|
559
|
+
link = options.etherscanContractLink;
|
|
620
560
|
if (!link) {
|
|
621
561
|
const result = await prompts({
|
|
622
562
|
type: "text",
|
|
623
563
|
name: "link",
|
|
624
|
-
message: "Enter
|
|
564
|
+
message: "Enter a block explorer contract link",
|
|
625
565
|
initial: "https://etherscan.io/address/0x97..."
|
|
626
566
|
});
|
|
627
567
|
link = result.link;
|
|
628
568
|
}
|
|
629
|
-
config = await fromEtherscan({
|
|
630
|
-
rootDir: targetPath,
|
|
631
|
-
etherscanLink: link,
|
|
632
|
-
etherscanApiKey: options.etherscanApiKey
|
|
633
|
-
});
|
|
634
569
|
}
|
|
635
|
-
log2(`Creating a repo at: ${pico4.green(targetPath)}`);
|
|
636
|
-
log2();
|
|
637
|
-
log2(`Using template: ${pico4.bold(templateMeta.title)}`);
|
|
638
570
|
log2();
|
|
571
|
+
if (templateMeta.id === "etherscan") {
|
|
572
|
+
const host = new URL(link).host;
|
|
573
|
+
config = await oraPromise(
|
|
574
|
+
fromEtherscan({
|
|
575
|
+
rootDir: targetPath,
|
|
576
|
+
etherscanLink: link,
|
|
577
|
+
etherscanApiKey: options.etherscanApiKey
|
|
578
|
+
}),
|
|
579
|
+
{
|
|
580
|
+
text: `Fetching contract metadata from ${pico5.bold(
|
|
581
|
+
host
|
|
582
|
+
)}. This may take a few seconds.`,
|
|
583
|
+
failText: "Failed to fetch contract metadata.",
|
|
584
|
+
successText: `Fetched contract metadata from ${pico5.bold(host)}.`
|
|
585
|
+
}
|
|
586
|
+
);
|
|
587
|
+
}
|
|
639
588
|
const templatePath = path3.join(templatesPath, templateMeta.id);
|
|
640
589
|
await cpy(path3.join(templatePath, "**", "*"), targetPath, {
|
|
641
590
|
rename: (name) => name.replace(/^_dot_/, ".")
|
|
@@ -708,8 +657,6 @@ async function run({
|
|
|
708
657
|
JSON.stringify(packageJson, null, 2)
|
|
709
658
|
);
|
|
710
659
|
const packageManager = getPackageManager({ options });
|
|
711
|
-
log2(`Installing with: ${pico4.bold(packageManager)}`);
|
|
712
|
-
log2();
|
|
713
660
|
const installArgs = [
|
|
714
661
|
"install",
|
|
715
662
|
packageManager === "npm" ? "--quiet" : "--silent"
|
|
@@ -727,51 +674,60 @@ async function run({
|
|
|
727
674
|
}
|
|
728
675
|
}),
|
|
729
676
|
{
|
|
730
|
-
text:
|
|
677
|
+
text: `Installing packages with ${pico5.bold(
|
|
678
|
+
packageManager
|
|
679
|
+
)}. This may take a few seconds.`,
|
|
731
680
|
failText: "Failed to install packages.",
|
|
732
|
-
successText:
|
|
681
|
+
successText: `Installed packages with ${pico5.bold(packageManager)}.`
|
|
733
682
|
}
|
|
734
683
|
);
|
|
735
|
-
log2();
|
|
736
684
|
if (!options.skipGit) {
|
|
737
|
-
await
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
685
|
+
await oraPromise(
|
|
686
|
+
async () => {
|
|
687
|
+
await execa("git", ["init"], { cwd: targetPath });
|
|
688
|
+
await execa("git", ["add", "."], { cwd: targetPath });
|
|
689
|
+
await execa(
|
|
690
|
+
"git",
|
|
691
|
+
[
|
|
692
|
+
"commit",
|
|
693
|
+
"--no-verify",
|
|
694
|
+
"--message",
|
|
695
|
+
"chore: initial commit from create-ponder"
|
|
696
|
+
],
|
|
697
|
+
{ cwd: targetPath }
|
|
698
|
+
);
|
|
699
|
+
},
|
|
700
|
+
{
|
|
701
|
+
text: "Initializing git repository.",
|
|
702
|
+
failText: "Failed to initialize git repository.",
|
|
703
|
+
successText: "Initialized git repository."
|
|
704
|
+
}
|
|
748
705
|
);
|
|
749
|
-
log2(pico4.green("\u2714"), "Initialized git repository.");
|
|
750
|
-
log2();
|
|
751
706
|
}
|
|
707
|
+
log2();
|
|
752
708
|
log2("\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015");
|
|
753
709
|
log2();
|
|
754
710
|
log2(
|
|
755
|
-
`${
|
|
711
|
+
`${pico5.green("Success!")} Created ${pico5.bold(
|
|
756
712
|
projectName
|
|
757
|
-
)} at ${
|
|
713
|
+
)} at ${pico5.green(path3.resolve(projectPath))}`
|
|
758
714
|
);
|
|
759
715
|
log2();
|
|
760
716
|
log2(
|
|
761
|
-
`To start your app, run
|
|
762
|
-
|
|
763
|
-
)}
|
|
764
|
-
|
|
717
|
+
`To start your app, run ${pico5.bold(
|
|
718
|
+
pico5.cyan(`cd ${projectPath}`)
|
|
719
|
+
)} and then ${pico5.bold(
|
|
720
|
+
pico5.cyan(
|
|
765
721
|
`${packageManager}${packageManager === "npm" || packageManager === "bun" ? " run" : ""} dev`
|
|
766
722
|
)
|
|
767
|
-
)}
|
|
723
|
+
)}`
|
|
768
724
|
);
|
|
769
725
|
log2();
|
|
770
726
|
log2("\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015");
|
|
771
727
|
log2();
|
|
772
728
|
}
|
|
773
729
|
(async () => {
|
|
774
|
-
const cli = cac(package_default.name).version(package_default.version).usage(`${
|
|
730
|
+
const cli = cac(package_default.name).version(package_default.version).usage(`${pico5.green("<project-directory>")} [options]`).option(
|
|
775
731
|
"-t, --template [name]",
|
|
776
732
|
`A template to bootstrap with. Available: ${templates.map(({ id }) => id).join(", ")}`
|
|
777
733
|
).option("--etherscan-contract-link [link]", "Etherscan contract link").option("--etherscan-api-key [key]", "Etherscan API key").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", "Skips initializing the project as a git repository").help();
|
|
@@ -783,7 +739,7 @@ async function run({
|
|
|
783
739
|
];
|
|
784
740
|
if (nodeVersion[0] < 18 || nodeVersion[0] === 18 && nodeVersion[1] < 14)
|
|
785
741
|
throw Error(
|
|
786
|
-
|
|
742
|
+
pico5.red(
|
|
787
743
|
`Node version:${process.version} does not meet the >=18.14 requirement`
|
|
788
744
|
)
|
|
789
745
|
);
|
|
@@ -794,7 +750,7 @@ async function run({
|
|
|
794
750
|
await notifyUpdate({ options });
|
|
795
751
|
} catch (error) {
|
|
796
752
|
log2(
|
|
797
|
-
error instanceof ValidationError ? error.message :
|
|
753
|
+
error instanceof ValidationError ? error.message : pico5.red(error.message)
|
|
798
754
|
);
|
|
799
755
|
log2();
|
|
800
756
|
await notifyUpdate({ options });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-ponder",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A CLI tool to create Ponder apps",
|
|
6
6
|
"license": "MIT",
|
|
@@ -26,7 +26,8 @@
|
|
|
26
26
|
"prettier": "^3.1.0",
|
|
27
27
|
"prompts": "^2.4.2",
|
|
28
28
|
"update-check": "^1.5.4",
|
|
29
|
-
"validate-npm-package-name": "^5.0.0"
|
|
29
|
+
"validate-npm-package-name": "^5.0.0",
|
|
30
|
+
"viem": "^2.0.10"
|
|
30
31
|
},
|
|
31
32
|
"devDependencies": {
|
|
32
33
|
"@types/fs-extra": "^11.0.4",
|
|
@@ -1,10 +1,32 @@
|
|
|
1
|
+
// This file enables type checking and editor autocomplete for this Ponder project.
|
|
2
|
+
// After upgrading, you may find that changes have been made to this file.
|
|
3
|
+
// If this happens, please commit the changes. Do not manually edit this file.
|
|
4
|
+
// See https://ponder.sh/docs/guides/typescript for more information.
|
|
5
|
+
|
|
1
6
|
declare module "@/generated" {
|
|
2
|
-
import type {
|
|
7
|
+
import type {
|
|
8
|
+
PonderContext,
|
|
9
|
+
PonderEvent,
|
|
10
|
+
PonderEventNames,
|
|
11
|
+
PonderApp,
|
|
12
|
+
} from "@ponder/core";
|
|
3
13
|
|
|
4
14
|
type Config = typeof import("./ponder.config.ts").default;
|
|
5
15
|
type Schema = typeof import("./ponder.schema.ts").default;
|
|
6
16
|
|
|
7
17
|
export const ponder: PonderApp<Config, Schema>;
|
|
8
|
-
|
|
9
|
-
export type
|
|
18
|
+
export type EventNames = PonderEventNames<Config>;
|
|
19
|
+
export type Event<name extends EventNames = EventNames> = PonderEvent<
|
|
20
|
+
Config,
|
|
21
|
+
name
|
|
22
|
+
>;
|
|
23
|
+
export type Context<name extends EventNames = EventNames> = PonderContext<
|
|
24
|
+
Config,
|
|
25
|
+
Schema,
|
|
26
|
+
name
|
|
27
|
+
>;
|
|
28
|
+
export type IndexingFunctionArgs<name extends EventNames = EventNames> = {
|
|
29
|
+
event: Event<name>;
|
|
30
|
+
context: Context<name>;
|
|
31
|
+
};
|
|
10
32
|
}
|
|
@@ -1,10 +1,32 @@
|
|
|
1
|
+
// This file enables type checking and editor autocomplete for this Ponder project.
|
|
2
|
+
// After upgrading, you may find that changes have been made to this file.
|
|
3
|
+
// If this happens, please commit the changes. Do not manually edit this file.
|
|
4
|
+
// See https://ponder.sh/docs/guides/typescript for more information.
|
|
5
|
+
|
|
1
6
|
declare module "@/generated" {
|
|
2
|
-
import type {
|
|
7
|
+
import type {
|
|
8
|
+
PonderContext,
|
|
9
|
+
PonderEvent,
|
|
10
|
+
PonderEventNames,
|
|
11
|
+
PonderApp,
|
|
12
|
+
} from "@ponder/core";
|
|
3
13
|
|
|
4
14
|
type Config = typeof import("./ponder.config.ts").default;
|
|
5
15
|
type Schema = typeof import("./ponder.schema.ts").default;
|
|
6
16
|
|
|
7
17
|
export const ponder: PonderApp<Config, Schema>;
|
|
8
|
-
|
|
9
|
-
export type
|
|
18
|
+
export type EventNames = PonderEventNames<Config>;
|
|
19
|
+
export type Event<name extends EventNames = EventNames> = PonderEvent<
|
|
20
|
+
Config,
|
|
21
|
+
name
|
|
22
|
+
>;
|
|
23
|
+
export type Context<name extends EventNames = EventNames> = PonderContext<
|
|
24
|
+
Config,
|
|
25
|
+
Schema,
|
|
26
|
+
name
|
|
27
|
+
>;
|
|
28
|
+
export type IndexingFunctionArgs<name extends EventNames = EventNames> = {
|
|
29
|
+
event: Event<name>;
|
|
30
|
+
context: Context<name>;
|
|
31
|
+
};
|
|
10
32
|
}
|
|
@@ -1,10 +1,30 @@
|
|
|
1
|
+
// This file is required for type inference and generated by Ponder.
|
|
2
|
+
// See https://ponder.sh/docs/guides/typescript for more information.
|
|
3
|
+
|
|
1
4
|
declare module "@/generated" {
|
|
2
|
-
import type {
|
|
5
|
+
import type {
|
|
6
|
+
PonderContext,
|
|
7
|
+
PonderEvent,
|
|
8
|
+
PonderEventNames,
|
|
9
|
+
PonderApp,
|
|
10
|
+
} from "@ponder/core";
|
|
3
11
|
|
|
4
12
|
type Config = typeof import("./ponder.config.ts").default;
|
|
5
13
|
type Schema = typeof import("./ponder.schema.ts").default;
|
|
6
14
|
|
|
7
15
|
export const ponder: PonderApp<Config, Schema>;
|
|
8
|
-
|
|
9
|
-
export type
|
|
16
|
+
export type EventNames = PonderEventNames<Config>;
|
|
17
|
+
export type Event<name extends EventNames = EventNames> = PonderEvent<
|
|
18
|
+
Config,
|
|
19
|
+
name
|
|
20
|
+
>;
|
|
21
|
+
export type Context<name extends EventNames = EventNames> = PonderContext<
|
|
22
|
+
Config,
|
|
23
|
+
Schema,
|
|
24
|
+
name
|
|
25
|
+
>;
|
|
26
|
+
export type IndexingFunctionArgs<name extends EventNames = EventNames> = {
|
|
27
|
+
event: Event<name>;
|
|
28
|
+
context: Context<name>;
|
|
29
|
+
};
|
|
10
30
|
}
|
|
@@ -1,10 +1,30 @@
|
|
|
1
|
+
// This file is required for type inference and generated by Ponder.
|
|
2
|
+
// See https://ponder.sh/docs/guides/typescript for more information.
|
|
3
|
+
|
|
1
4
|
declare module "@/generated" {
|
|
2
|
-
import type {
|
|
5
|
+
import type {
|
|
6
|
+
PonderContext,
|
|
7
|
+
PonderEvent,
|
|
8
|
+
PonderEventNames,
|
|
9
|
+
PonderApp,
|
|
10
|
+
} from "@ponder/core";
|
|
3
11
|
|
|
4
12
|
type Config = typeof import("./ponder.config.ts").default;
|
|
5
13
|
type Schema = typeof import("./ponder.schema.ts").default;
|
|
6
14
|
|
|
7
15
|
export const ponder: PonderApp<Config, Schema>;
|
|
8
|
-
|
|
9
|
-
export type
|
|
16
|
+
export type EventNames = PonderEventNames<Config>;
|
|
17
|
+
export type Event<name extends EventNames = EventNames> = PonderEvent<
|
|
18
|
+
Config,
|
|
19
|
+
name
|
|
20
|
+
>;
|
|
21
|
+
export type Context<name extends EventNames = EventNames> = PonderContext<
|
|
22
|
+
Config,
|
|
23
|
+
Schema,
|
|
24
|
+
name
|
|
25
|
+
>;
|
|
26
|
+
export type IndexingFunctionArgs<name extends EventNames = EventNames> = {
|
|
27
|
+
event: Event<name>;
|
|
28
|
+
context: Context<name>;
|
|
29
|
+
};
|
|
10
30
|
}
|
|
@@ -1,10 +1,30 @@
|
|
|
1
|
+
// This file is required for type inference and generated by Ponder.
|
|
2
|
+
// See https://ponder.sh/docs/guides/typescript for more information.
|
|
3
|
+
|
|
1
4
|
declare module "@/generated" {
|
|
2
|
-
import type {
|
|
5
|
+
import type {
|
|
6
|
+
PonderContext,
|
|
7
|
+
PonderEvent,
|
|
8
|
+
PonderEventNames,
|
|
9
|
+
PonderApp,
|
|
10
|
+
} from "@ponder/core";
|
|
3
11
|
|
|
4
12
|
type Config = typeof import("./ponder.config.ts").default;
|
|
5
13
|
type Schema = typeof import("./ponder.schema.ts").default;
|
|
6
14
|
|
|
7
15
|
export const ponder: PonderApp<Config, Schema>;
|
|
8
|
-
|
|
9
|
-
export type
|
|
16
|
+
export type EventNames = PonderEventNames<Config>;
|
|
17
|
+
export type Event<name extends EventNames = EventNames> = PonderEvent<
|
|
18
|
+
Config,
|
|
19
|
+
name
|
|
20
|
+
>;
|
|
21
|
+
export type Context<name extends EventNames = EventNames> = PonderContext<
|
|
22
|
+
Config,
|
|
23
|
+
Schema,
|
|
24
|
+
name
|
|
25
|
+
>;
|
|
26
|
+
export type IndexingFunctionArgs<name extends EventNames = EventNames> = {
|
|
27
|
+
event: Event<name>;
|
|
28
|
+
context: Context<name>;
|
|
29
|
+
};
|
|
10
30
|
}
|
|
@@ -1,10 +1,30 @@
|
|
|
1
|
+
// This file is required for type inference and generated by Ponder.
|
|
2
|
+
// See https://ponder.sh/docs/guides/typescript for more information.
|
|
3
|
+
|
|
1
4
|
declare module "@/generated" {
|
|
2
|
-
import type {
|
|
5
|
+
import type {
|
|
6
|
+
PonderContext,
|
|
7
|
+
PonderEvent,
|
|
8
|
+
PonderEventNames,
|
|
9
|
+
PonderApp,
|
|
10
|
+
} from "@ponder/core";
|
|
3
11
|
|
|
4
12
|
type Config = typeof import("./ponder.config.ts").default;
|
|
5
13
|
type Schema = typeof import("./ponder.schema.ts").default;
|
|
6
14
|
|
|
7
15
|
export const ponder: PonderApp<Config, Schema>;
|
|
8
|
-
|
|
9
|
-
export type
|
|
16
|
+
export type EventNames = PonderEventNames<Config>;
|
|
17
|
+
export type Event<name extends EventNames = EventNames> = PonderEvent<
|
|
18
|
+
Config,
|
|
19
|
+
name
|
|
20
|
+
>;
|
|
21
|
+
export type Context<name extends EventNames = EventNames> = PonderContext<
|
|
22
|
+
Config,
|
|
23
|
+
Schema,
|
|
24
|
+
name
|
|
25
|
+
>;
|
|
26
|
+
export type IndexingFunctionArgs<name extends EventNames = EventNames> = {
|
|
27
|
+
event: Event<name>;
|
|
28
|
+
context: Context<name>;
|
|
29
|
+
};
|
|
10
30
|
}
|
|
@@ -1,10 +1,30 @@
|
|
|
1
|
+
// This file is required for type inference and generated by Ponder.
|
|
2
|
+
// See https://ponder.sh/docs/guides/typescript for more information.
|
|
3
|
+
|
|
1
4
|
declare module "@/generated" {
|
|
2
|
-
import type {
|
|
5
|
+
import type {
|
|
6
|
+
PonderContext,
|
|
7
|
+
PonderEvent,
|
|
8
|
+
PonderEventNames,
|
|
9
|
+
PonderApp,
|
|
10
|
+
} from "@ponder/core";
|
|
3
11
|
|
|
4
12
|
type Config = typeof import("./ponder.config.ts").default;
|
|
5
13
|
type Schema = typeof import("./ponder.schema.ts").default;
|
|
6
14
|
|
|
7
15
|
export const ponder: PonderApp<Config, Schema>;
|
|
8
|
-
|
|
9
|
-
export type
|
|
16
|
+
export type EventNames = PonderEventNames<Config>;
|
|
17
|
+
export type Event<name extends EventNames = EventNames> = PonderEvent<
|
|
18
|
+
Config,
|
|
19
|
+
name
|
|
20
|
+
>;
|
|
21
|
+
export type Context<name extends EventNames = EventNames> = PonderContext<
|
|
22
|
+
Config,
|
|
23
|
+
Schema,
|
|
24
|
+
name
|
|
25
|
+
>;
|
|
26
|
+
export type IndexingFunctionArgs<name extends EventNames = EventNames> = {
|
|
27
|
+
event: Event<name>;
|
|
28
|
+
context: Context<name>;
|
|
29
|
+
};
|
|
10
30
|
}
|
|
@@ -1,10 +1,30 @@
|
|
|
1
|
+
// This file is required for type inference and generated by Ponder.
|
|
2
|
+
// See https://ponder.sh/docs/guides/typescript for more information.
|
|
3
|
+
|
|
1
4
|
declare module "@/generated" {
|
|
2
|
-
import type {
|
|
5
|
+
import type {
|
|
6
|
+
PonderContext,
|
|
7
|
+
PonderEvent,
|
|
8
|
+
PonderEventNames,
|
|
9
|
+
PonderApp,
|
|
10
|
+
} from "@ponder/core";
|
|
3
11
|
|
|
4
12
|
type Config = typeof import("./ponder.config.ts").default;
|
|
5
13
|
type Schema = typeof import("./ponder.schema.ts").default;
|
|
6
14
|
|
|
7
15
|
export const ponder: PonderApp<Config, Schema>;
|
|
8
|
-
|
|
9
|
-
export type
|
|
16
|
+
export type EventNames = PonderEventNames<Config>;
|
|
17
|
+
export type Event<name extends EventNames = EventNames> = PonderEvent<
|
|
18
|
+
Config,
|
|
19
|
+
name
|
|
20
|
+
>;
|
|
21
|
+
export type Context<name extends EventNames = EventNames> = PonderContext<
|
|
22
|
+
Config,
|
|
23
|
+
Schema,
|
|
24
|
+
name
|
|
25
|
+
>;
|
|
26
|
+
export type IndexingFunctionArgs<name extends EventNames = EventNames> = {
|
|
27
|
+
event: Event<name>;
|
|
28
|
+
context: Context<name>;
|
|
29
|
+
};
|
|
10
30
|
}
|
|
@@ -1,10 +1,30 @@
|
|
|
1
|
+
// This file is required for type inference and generated by Ponder.
|
|
2
|
+
// See https://ponder.sh/docs/guides/typescript for more information.
|
|
3
|
+
|
|
1
4
|
declare module "@/generated" {
|
|
2
|
-
import type {
|
|
5
|
+
import type {
|
|
6
|
+
PonderContext,
|
|
7
|
+
PonderEvent,
|
|
8
|
+
PonderEventNames,
|
|
9
|
+
PonderApp,
|
|
10
|
+
} from "@ponder/core";
|
|
3
11
|
|
|
4
12
|
type Config = typeof import("./ponder.config.ts").default;
|
|
5
13
|
type Schema = typeof import("./ponder.schema.ts").default;
|
|
6
14
|
|
|
7
15
|
export const ponder: PonderApp<Config, Schema>;
|
|
8
|
-
|
|
9
|
-
export type
|
|
16
|
+
export type EventNames = PonderEventNames<Config>;
|
|
17
|
+
export type Event<name extends EventNames = EventNames> = PonderEvent<
|
|
18
|
+
Config,
|
|
19
|
+
name
|
|
20
|
+
>;
|
|
21
|
+
export type Context<name extends EventNames = EventNames> = PonderContext<
|
|
22
|
+
Config,
|
|
23
|
+
Schema,
|
|
24
|
+
name
|
|
25
|
+
>;
|
|
26
|
+
export type IndexingFunctionArgs<name extends EventNames = EventNames> = {
|
|
27
|
+
event: Event<name>;
|
|
28
|
+
context: Context<name>;
|
|
29
|
+
};
|
|
10
30
|
}
|
|
@@ -1,10 +1,30 @@
|
|
|
1
|
+
// This file is required for type inference and generated by Ponder.
|
|
2
|
+
// See https://ponder.sh/docs/guides/typescript for more information.
|
|
3
|
+
|
|
1
4
|
declare module "@/generated" {
|
|
2
|
-
import type {
|
|
5
|
+
import type {
|
|
6
|
+
PonderContext,
|
|
7
|
+
PonderEvent,
|
|
8
|
+
PonderEventNames,
|
|
9
|
+
PonderApp,
|
|
10
|
+
} from "@ponder/core";
|
|
3
11
|
|
|
4
12
|
type Config = typeof import("./ponder.config.ts").default;
|
|
5
13
|
type Schema = typeof import("./ponder.schema.ts").default;
|
|
6
14
|
|
|
7
15
|
export const ponder: PonderApp<Config, Schema>;
|
|
8
|
-
|
|
9
|
-
export type
|
|
16
|
+
export type EventNames = PonderEventNames<Config>;
|
|
17
|
+
export type Event<name extends EventNames = EventNames> = PonderEvent<
|
|
18
|
+
Config,
|
|
19
|
+
name
|
|
20
|
+
>;
|
|
21
|
+
export type Context<name extends EventNames = EventNames> = PonderContext<
|
|
22
|
+
Config,
|
|
23
|
+
Schema,
|
|
24
|
+
name
|
|
25
|
+
>;
|
|
26
|
+
export type IndexingFunctionArgs<name extends EventNames = EventNames> = {
|
|
27
|
+
event: Event<name>;
|
|
28
|
+
context: Context<name>;
|
|
29
|
+
};
|
|
10
30
|
}
|
|
@@ -1,10 +1,30 @@
|
|
|
1
|
+
// This file is required for type inference and generated by Ponder.
|
|
2
|
+
// See https://ponder.sh/docs/guides/typescript for more information.
|
|
3
|
+
|
|
1
4
|
declare module "@/generated" {
|
|
2
|
-
import type {
|
|
5
|
+
import type {
|
|
6
|
+
PonderContext,
|
|
7
|
+
PonderEvent,
|
|
8
|
+
PonderEventNames,
|
|
9
|
+
PonderApp,
|
|
10
|
+
} from "@ponder/core";
|
|
3
11
|
|
|
4
12
|
type Config = typeof import("./ponder.config.ts").default;
|
|
5
13
|
type Schema = typeof import("./ponder.schema.ts").default;
|
|
6
14
|
|
|
7
15
|
export const ponder: PonderApp<Config, Schema>;
|
|
8
|
-
|
|
9
|
-
export type
|
|
16
|
+
export type EventNames = PonderEventNames<Config>;
|
|
17
|
+
export type Event<name extends EventNames = EventNames> = PonderEvent<
|
|
18
|
+
Config,
|
|
19
|
+
name
|
|
20
|
+
>;
|
|
21
|
+
export type Context<name extends EventNames = EventNames> = PonderContext<
|
|
22
|
+
Config,
|
|
23
|
+
Schema,
|
|
24
|
+
name
|
|
25
|
+
>;
|
|
26
|
+
export type IndexingFunctionArgs<name extends EventNames = EventNames> = {
|
|
27
|
+
event: Event<name>;
|
|
28
|
+
context: Context<name>;
|
|
29
|
+
};
|
|
10
30
|
}
|