create-ponder 0.1.7 → 0.1.9

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 CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/index.ts
4
- import { writeFileSync as writeFileSync2 } from "node:fs";
5
- import path3 from "node:path";
4
+ import { writeFileSync as writeFileSync3 } from "node:fs";
5
+ import path4 from "node:path";
6
6
  import { fileURLToPath } from "node:url";
7
7
  import { cac } from "cac";
8
8
  import cpy from "cpy";
@@ -10,13 +10,13 @@ import { execa } from "execa";
10
10
  import fs2 from "fs-extra";
11
11
  import { oraPromise } from "ora";
12
12
  import pico5 from "picocolors";
13
- import prettier2 from "prettier";
13
+ import prettier3 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.7",
19
+ version: "0.1.9",
20
20
  type: "module",
21
21
  description: "A CLI tool to create Ponder apps",
22
22
  license: "MIT",
@@ -48,7 +48,8 @@ var package_default = {
48
48
  prompts: "^2.4.2",
49
49
  "update-check": "^1.5.4",
50
50
  "validate-npm-package-name": "^5.0.0",
51
- viem: "^2.0.10"
51
+ viem: "^2.0.10",
52
+ yaml: "^2.3.4"
52
53
  },
53
54
  devDependencies: {
54
55
  "@types/fs-extra": "^11.0.4",
@@ -92,6 +93,7 @@ var fromEtherscan = async ({
92
93
  etherscanLink,
93
94
  etherscanApiKey
94
95
  }) => {
96
+ const warnings = [];
95
97
  const apiKey = etherscanApiKey || process.env.ETHERSCAN_API_KEY;
96
98
  const explorerUrl = new URL(etherscanLink);
97
99
  const chainExplorer = chainExplorerByHostname[explorerUrl.hostname];
@@ -167,6 +169,12 @@ var fromEtherscan = async ({
167
169
  if (!apiKey)
168
170
  await wait(5e3);
169
171
  const { abi, contractName: implContractName } = await getContractAbiAndName(implAddress, apiUrl, apiKey);
172
+ if (typeof abi !== "string") {
173
+ warnings.push(
174
+ `Unable to fetch ABI for implementation contract ${implAddress}. Please see the proxy contract documentation for more details: https://ponder.sh/docs/guides/add-contracts#multiple-abis`
175
+ );
176
+ continue;
177
+ }
170
178
  contractName = implContractName;
171
179
  abis.push({
172
180
  abi: JSON.parse(abi),
@@ -187,9 +195,7 @@ var fromEtherscan = async ({
187
195
  abiAbsolutePath,
188
196
  await prettier.format(
189
197
  `export const ${contractName2}Abi = ${JSON.stringify(abi)} as const`,
190
- {
191
- parser: "typescript"
192
- }
198
+ { parser: "typescript" }
193
199
  )
194
200
  );
195
201
  if (abis.length === 1) {
@@ -225,7 +231,7 @@ var fromEtherscan = async ({
225
231
  }
226
232
  }
227
233
  };
228
- return config;
234
+ return { config, warnings };
229
235
  };
230
236
  var fetchEtherscan = async (url) => {
231
237
  const maxRetries = 5;
@@ -420,6 +426,143 @@ var ValidationError = class extends Error {
420
426
  }
421
427
  };
422
428
 
429
+ // src/subgraph.ts
430
+ import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync2 } from "node:fs";
431
+ import path3 from "node:path";
432
+ import prettier2 from "prettier";
433
+ import { parse } from "yaml";
434
+
435
+ // src/helpers/getGraphProtocolChainId.ts
436
+ var chainIdByGraphNetwork = {
437
+ mainnet: 1,
438
+ kovan: 42,
439
+ rinkeby: 4,
440
+ ropsten: 3,
441
+ goerli: 5,
442
+ "poa-core": 99,
443
+ "poa-sokol": 77,
444
+ xdai: 100,
445
+ matic: 137,
446
+ mumbai: 80001,
447
+ fantom: 250,
448
+ "fantom-testnet": 4002,
449
+ bsc: 56,
450
+ chapel: -1,
451
+ clover: 0,
452
+ avalanche: 43114,
453
+ fuji: 43113,
454
+ celo: 42220,
455
+ "celo-alfajores": 44787,
456
+ fuse: 122,
457
+ moonbeam: 1284,
458
+ moonriver: 1285,
459
+ mbase: -1,
460
+ "arbitrum-one": 42161,
461
+ "arbitrum-rinkeby": 421611,
462
+ optimism: 10,
463
+ "optimism-kovan": 69,
464
+ aurora: 1313161554,
465
+ "aurora-testnet": 1313161555
466
+ };
467
+ var getGraphProtocolChainId = (networkName) => {
468
+ return chainIdByGraphNetwork[networkName];
469
+ };
470
+ var subgraphYamlFileNames = ["subgraph.yaml"].concat(
471
+ Object.keys(chainIdByGraphNetwork).map((n) => `subgraph-${n}.yaml`)
472
+ );
473
+
474
+ // src/helpers/validateGraphProtocolSource.ts
475
+ var validateGraphProtocolSource = (source) => {
476
+ return source;
477
+ };
478
+
479
+ // src/subgraph.ts
480
+ var fetchIpfsFile = async (cid) => {
481
+ const url = `https://ipfs.network.thegraph.com/api/v0/cat?arg=${cid}`;
482
+ const response = await fetch(url);
483
+ const contentRaw = await response.text();
484
+ return contentRaw;
485
+ };
486
+ var fromSubgraphId = async ({
487
+ rootDir,
488
+ subgraphId
489
+ }) => {
490
+ const manifestRaw = await fetchIpfsFile(subgraphId);
491
+ const manifest = parse(manifestRaw);
492
+ const contracts = {};
493
+ manifest.dataSources.forEach((d) => {
494
+ contracts[d.name] = {
495
+ network: d.network,
496
+ address: d.source.address,
497
+ startBlock: d.source.startBlock
498
+ };
499
+ });
500
+ const dataSources = manifest.dataSources;
501
+ mkdirSync2(path3.join(rootDir, "abis"), { recursive: true });
502
+ mkdirSync2(path3.join(rootDir, "src"), { recursive: true });
503
+ const abiFiles = dataSources.flatMap((source) => validateGraphProtocolSource(source).mapping.abis).filter(
504
+ (source, idx, arr) => arr.findIndex((s) => s.name === source.name) === idx
505
+ );
506
+ const abis = {};
507
+ await Promise.all(
508
+ abiFiles.map(async (abi) => {
509
+ const abiContent = await fetchIpfsFile(abi.file["/"].slice(6));
510
+ const abiPath = path3.join(rootDir, `./abis/${abi.name}Abi.ts`);
511
+ writeFileSync2(
512
+ abiPath,
513
+ await prettier2.format(
514
+ `export const ${abi.name}Abi = ${abiContent} as const`,
515
+ { parser: "typescript" }
516
+ )
517
+ );
518
+ abis[abi.name] = JSON.parse(abiContent);
519
+ })
520
+ );
521
+ const ponderContracts = dataSources.map((sourceInvalid) => {
522
+ const source = validateGraphProtocolSource(sourceInvalid);
523
+ const network = source.network || "mainnet";
524
+ const chainId = getGraphProtocolChainId(network);
525
+ if (!chainId || chainId === -1) {
526
+ throw new Error(`Unhandled network name: ${network}`);
527
+ }
528
+ const abiRelativePath = `./abis/${source.source.abi}Abi.ts`;
529
+ return {
530
+ name: source.name,
531
+ network,
532
+ address: source.source.address,
533
+ abi: {
534
+ abi: abis[source.source.abi],
535
+ dir: abiRelativePath,
536
+ name: `${source.source.abi}Abi`
537
+ },
538
+ startBlock: source.source.startBlock
539
+ };
540
+ });
541
+ const contractsObject = {};
542
+ const networksObject = {};
543
+ ponderContracts.forEach((pc) => {
544
+ contractsObject[pc.name] = pc;
545
+ networksObject[pc.network] = {
546
+ chainId: getGraphProtocolChainId(pc.network),
547
+ transport: `http(process.env.PONDER_RPC_URL_${getGraphProtocolChainId(
548
+ pc.network
549
+ )})`
550
+ };
551
+ contractsObject[pc.name].name = void 0;
552
+ });
553
+ const config = {
554
+ networks: networksObject,
555
+ contracts: contractsObject
556
+ };
557
+ const warnings = [];
558
+ if (manifest.templates?.length > 0) {
559
+ warnings.push(
560
+ "Factory contract detected. Please see the factory contract documentation for more details: https://ponder.sh/docs/guides/add-contracts#factory-contracts"
561
+ );
562
+ }
563
+ return { config, warnings };
564
+ };
565
+
423
566
  // src/index.ts
424
567
  var log2 = console.log;
425
568
  var templates = [
@@ -427,7 +570,12 @@ var templates = [
427
570
  {
428
571
  id: "etherscan",
429
572
  title: "Etherscan contract link",
430
- description: "Bootstrap from an Etherscan contract link"
573
+ description: "Create from an Etherscan contract link"
574
+ },
575
+ {
576
+ id: "subgraph",
577
+ title: "Subgraph ID",
578
+ description: "Create from a deployed subgraph"
431
579
  },
432
580
  {
433
581
  id: "feature-factory",
@@ -481,6 +629,7 @@ async function run({
481
629
  }) {
482
630
  if (options.help)
483
631
  return;
632
+ const warnings = [];
484
633
  log2();
485
634
  log2(
486
635
  `Welcome to ${pico5.bold(
@@ -489,7 +638,7 @@ async function run({
489
638
  );
490
639
  log2();
491
640
  const __dirname = fileURLToPath(new URL(".", import.meta.url));
492
- const templatesPath = path3.join(__dirname, "..", "templates");
641
+ const templatesPath = path4.join(__dirname, "..", "templates");
493
642
  let templateId = options.template || options.t;
494
643
  let templateValidation = await validateTemplateName({
495
644
  isNameRequired: false,
@@ -530,8 +679,10 @@ async function run({
530
679
  });
531
680
  if (!nameValidation.valid)
532
681
  throw new ValidationError(nameValidation);
533
- if (options.etherscanContractLink && !templateId)
682
+ if (options.etherscan && !templateId)
534
683
  templateId = "etherscan";
684
+ if (options.subgraph && !templateId)
685
+ templateId = "subgraph";
535
686
  if (!templateId) {
536
687
  templateId = (await prompts({
537
688
  name: "templateId",
@@ -553,27 +704,42 @@ async function run({
553
704
  if (!templateValidation.valid)
554
705
  throw new ValidationError(templateValidation);
555
706
  let config;
556
- const targetPath = path3.join(process.cwd(), projectPath);
557
- let link = void 0;
707
+ const targetPath = path4.join(process.cwd(), projectPath);
708
+ let url = options.etherscan;
558
709
  if (templateMeta.id === "etherscan") {
559
- link = options.etherscanContractLink;
560
- if (!link) {
710
+ if (!url) {
561
711
  const result = await prompts({
562
712
  type: "text",
563
- name: "link",
564
- message: "Enter a block explorer contract link",
713
+ name: "url",
714
+ message: "Enter a block explorer contract url",
565
715
  initial: "https://etherscan.io/address/0x97..."
566
716
  });
567
- link = result.link;
717
+ url = result.url;
718
+ }
719
+ }
720
+ let subgraph = options.subgraph;
721
+ if (templateMeta.id === "subgraph") {
722
+ if (!subgraph) {
723
+ const result = await prompts({
724
+ type: "text",
725
+ name: "id",
726
+ message: "Enter a subgraph ID",
727
+ initial: "Qmb3hd2hYd2nWFgcmRswykF1dUBSrDUrinYCgN1dmE1tNy"
728
+ });
729
+ subgraph = result.id;
730
+ }
731
+ if (!subgraph) {
732
+ log2(pico5.red("No subgraph ID provided."));
733
+ process.exit(0);
568
734
  }
569
735
  }
570
736
  log2();
571
737
  if (templateMeta.id === "etherscan") {
572
- const host = new URL(link).host;
573
- config = await oraPromise(
738
+ const host = new URL(url).host;
739
+ const result = await oraPromise(
574
740
  fromEtherscan({
575
741
  rootDir: targetPath,
576
- etherscanLink: link,
742
+ etherscanLink: url,
577
743
  etherscanApiKey: options.etherscanApiKey
578
744
  }),
579
745
  {
@@ -584,9 +750,23 @@ async function run({
584
750
  successText: `Fetched contract metadata from ${pico5.bold(host)}.`
585
751
  }
586
752
  );
753
+ config = result.config;
754
+ warnings.push(...result.warnings);
587
755
  }
588
- const templatePath = path3.join(templatesPath, templateMeta.id);
589
- await cpy(path3.join(templatePath, "**", "*"), targetPath, {
756
+ if (templateMeta.id === "subgraph") {
757
+ const result = await oraPromise(
758
+ fromSubgraphId({ rootDir: targetPath, subgraphId: subgraph }),
759
+ {
760
+ text: "Fetching subgraph metadata. This may take a few seconds.",
761
+ failText: "Failed to fetch subgraph metadata.",
762
+ successText: `Fetched subgraph metadata for ${pico5.bold(subgraph)}.`
763
+ }
764
+ );
765
+ config = result.config;
766
+ warnings.push(...result.warnings);
767
+ }
768
+ const templatePath = path4.join(templatesPath, templateMeta.id);
769
+ await cpy(path4.join(templatePath, "**", "*"), targetPath, {
590
770
  rename: (name) => name.replace(/^_dot_/, ".")
591
771
  });
592
772
  if (config) {
@@ -594,7 +774,9 @@ async function run({
594
774
  import { createConfig${Object.values(config.contracts).some((c) => Array.isArray(c.abi)) ? ", mergeAbis" : ""} } from "@ponder/core";
595
775
  import { http } from "viem";
596
776
 
597
- ${Object.values(config.contracts).flatMap((c) => c.abi).map(
777
+ ${Object.values(config.contracts).flatMap((c) => c.abi).filter(
778
+ (tag, index, array) => array.findIndex((t) => t.dir === tag.dir) === index
779
+ ).map(
598
780
  (abi) => `import {${abi.name}} from "${abi.dir.slice(
599
781
  0,
600
782
  abi.dir.length - 3
@@ -620,14 +802,14 @@ async function run({
620
802
  ).replaceAll(/"abi":"(.*?)"/g, "abi:$1")},
621
803
  });
622
804
  `;
623
- writeFileSync2(
624
- path3.join(targetPath, "ponder.config.ts"),
625
- await prettier2.format(configContent, { parser: "typescript" })
805
+ writeFileSync3(
806
+ path4.join(targetPath, "ponder.config.ts"),
807
+ await prettier3.format(configContent, { parser: "typescript" })
626
808
  );
627
809
  for (const [name, contract] of Object.entries(config.contracts)) {
628
810
  const abi = Array.isArray(contract.abi) ? contract.abi[1].abi : contract.abi.abi;
629
811
  const abiEvents = abi.filter(
630
- (item) => item.type === "event"
812
+ (item) => item.type === "event" && !item.anonymous
631
813
  );
632
814
  const eventNamesToWrite = abiEvents.map((event) => event.name).slice(0, 2);
633
815
  const indexingFunctionFileContents = `
@@ -640,20 +822,20 @@ async function run({
640
822
  })`
641
823
  ).join("\n")}
642
824
  `;
643
- writeFileSync2(
644
- path3.join(targetPath, `./src/${name}.ts`),
645
- await prettier2.format(indexingFunctionFileContents, {
825
+ writeFileSync3(
826
+ path4.join(targetPath, `./src/${name}.ts`),
827
+ await prettier3.format(indexingFunctionFileContents, {
646
828
  parser: "typescript"
647
829
  })
648
830
  );
649
831
  }
650
832
  }
651
- const packageJson = await fs2.readJSON(path3.join(targetPath, "package.json"));
833
+ const packageJson = await fs2.readJSON(path4.join(targetPath, "package.json"));
652
834
  packageJson.name = projectName;
653
835
  packageJson.dependencies["@ponder/core"] = `^${package_default.version}`;
654
836
  packageJson.devDependencies["eslint-config-ponder"] = `^${package_default.version}`;
655
837
  await fs2.writeFile(
656
- path3.join(targetPath, "package.json"),
838
+ path4.join(targetPath, "package.json"),
657
839
  JSON.stringify(packageJson, null, 2)
658
840
  );
659
841
  const packageManager = getPackageManager({ options });
@@ -704,13 +886,17 @@ async function run({
704
886
  }
705
887
  );
706
888
  }
889
+ for (const warning of warnings) {
890
+ log2();
891
+ log2(pico5.yellow(warning));
892
+ }
707
893
  log2();
708
894
  log2("\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015\u2015");
709
895
  log2();
710
896
  log2(
711
897
  `${pico5.green("Success!")} Created ${pico5.bold(
712
898
  projectName
713
- )} at ${pico5.green(path3.resolve(projectPath))}`
899
+ )} at ${pico5.green(path4.resolve(projectPath))}`
714
900
  );
715
901
  log2();
716
902
  log2(
@@ -727,10 +913,13 @@ async function run({
727
913
  log2();
728
914
  }
729
915
  (async () => {
730
- const cli = cac(package_default.name).version(package_default.version).usage(`${pico5.green("<project-directory>")} [options]`).option(
731
- "-t, --template [name]",
732
- `A template to bootstrap with. Available: ${templates.map(({ id }) => id).join(", ")}`
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();
916
+ const cli = cac(package_default.name).version(package_default.version).usage(`${pico5.green("<directory>")} [options]`).option(
917
+ "-t, --template [id]",
918
+ `Use a template. Options: ${templates.map(({ id }) => id).join(", ")}`
919
+ ).option("--etherscan [url]", "Use the Etherscan template").option("--subgraph [id]", "Use the subgraph template").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(
920
+ "--etherscan-api-key [key]",
921
+ "Etherscan API key for Etherscan template"
922
+ ).help();
734
923
  const _nodeVersion = process.version.split(".");
735
924
  const nodeVersion = [
736
925
  Number(_nodeVersion[0].slice(1)),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-ponder",
3
- "version": "0.1.7",
3
+ "version": "0.1.9",
4
4
  "type": "module",
5
5
  "description": "A CLI tool to create Ponder apps",
6
6
  "license": "MIT",
@@ -27,7 +27,8 @@
27
27
  "prompts": "^2.4.2",
28
28
  "update-check": "^1.5.4",
29
29
  "validate-npm-package-name": "^5.0.0",
30
- "viem": "^2.0.10"
30
+ "viem": "^2.0.10",
31
+ "yaml": "^2.3.4"
31
32
  },
32
33
  "devDependencies": {
33
34
  "@types/fs-extra": "^11.0.4",
@@ -1,4 +1,6 @@
1
- // This file is required for type inference and generated by Ponder.
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.
2
4
  // See https://ponder.sh/docs/guides/typescript for more information.
3
5
 
4
6
  declare module "@/generated" {
@@ -1,4 +1,6 @@
1
- // This file is required for type inference and generated by Ponder.
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.
2
4
  // See https://ponder.sh/docs/guides/typescript for more information.
3
5
 
4
6
  declare module "@/generated" {
@@ -1,4 +1,6 @@
1
- // This file is required for type inference and generated by Ponder.
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.
2
4
  // See https://ponder.sh/docs/guides/typescript for more information.
3
5
 
4
6
  declare module "@/generated" {
@@ -1,4 +1,6 @@
1
- // This file is required for type inference and generated by Ponder.
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.
2
4
  // See https://ponder.sh/docs/guides/typescript for more information.
3
5
 
4
6
  declare module "@/generated" {
@@ -1,4 +1,6 @@
1
- // This file is required for type inference and generated by Ponder.
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.
2
4
  // See https://ponder.sh/docs/guides/typescript for more information.
3
5
 
4
6
  declare module "@/generated" {
@@ -1,4 +1,6 @@
1
- // This file is required for type inference and generated by Ponder.
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.
2
4
  // See https://ponder.sh/docs/guides/typescript for more information.
3
5
 
4
6
  declare module "@/generated" {
@@ -1,4 +1,6 @@
1
- // This file is required for type inference and generated by Ponder.
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.
2
4
  // See https://ponder.sh/docs/guides/typescript for more information.
3
5
 
4
6
  declare module "@/generated" {
@@ -1,4 +1,6 @@
1
- // This file is required for type inference and generated by Ponder.
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.
2
4
  // See https://ponder.sh/docs/guides/typescript for more information.
3
5
 
4
6
  declare module "@/generated" {
@@ -1,4 +1,6 @@
1
- // This file is required for type inference and generated by Ponder.
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.
2
4
  // See https://ponder.sh/docs/guides/typescript for more information.
3
5
 
4
6
  declare module "@/generated" {
@@ -0,0 +1,5 @@
1
+ # Mainnet RPC URL used for fetching blockchain data. Alchemy is recommended.
2
+ PONDER_RPC_URL_1=
3
+
4
+ # (Optional) Postgres database URL. If not provided, SQLite will be used.
5
+ DATABASE_URL=
@@ -0,0 +1,3 @@
1
+ {
2
+ "extends": "ponder"
3
+ }
@@ -0,0 +1,18 @@
1
+ # Dependencies
2
+ /node_modules
3
+
4
+ # Debug
5
+ npm-debug.log*
6
+ yarn-debug.log*
7
+ yarn-error.log*
8
+ .pnpm-debug.log*
9
+
10
+ # Misc
11
+ .DS_Store
12
+
13
+ # Env files
14
+ .env*.local
15
+
16
+ # Ponder
17
+ /generated/
18
+ /.ponder/
@@ -0,0 +1,26 @@
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
+ "codegen": "ponder codegen",
10
+ "lint": "eslint .",
11
+ "typecheck": "tsc"
12
+ },
13
+ "dependencies": {
14
+ "@ponder/core": "^0.0.95",
15
+ "viem": "^1.19.3"
16
+ },
17
+ "devDependencies": {
18
+ "@types/node": "^20.9.0",
19
+ "eslint": "^8.53.0",
20
+ "eslint-config-ponder": "^0.0.95",
21
+ "typescript": "^5.2.2"
22
+ },
23
+ "engines": {
24
+ "node": ">=18.14"
25
+ }
26
+ }
@@ -0,0 +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
+
6
+ declare module "@/generated" {
7
+ import type {
8
+ PonderContext,
9
+ PonderEvent,
10
+ PonderEventNames,
11
+ PonderApp,
12
+ } from "@ponder/core";
13
+
14
+ type Config = typeof import("./ponder.config.ts").default;
15
+ type Schema = typeof import("./ponder.schema.ts").default;
16
+
17
+ export const ponder: PonderApp<Config, Schema>;
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
+ };
32
+ }
@@ -0,0 +1,8 @@
1
+ import { createSchema } from "@ponder/core";
2
+
3
+ export default createSchema((p) => ({
4
+ Example: p.createTable({
5
+ id: p.string(),
6
+ name: p.string().optional(),
7
+ }),
8
+ }));
@@ -0,0 +1,26 @@
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
+ }