create-ponder 0.5.0-next.3 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/index.js +53 -18
- package/package.json +1 -1
- package/templates/empty/package.json +1 -0
- package/templates/empty/ponder-env.d.ts +1 -0
- package/templates/empty/ponder.config.ts +1 -1
- package/templates/empty/src/api/index.ts +5 -0
- package/templates/etherscan/package.json +1 -0
- package/templates/etherscan/ponder-env.d.ts +1 -0
- package/templates/feature-api-functions/abis/erc20ABI.ts +147 -0
- package/templates/{feature-callTrace → feature-api-functions}/package.json +2 -1
- package/templates/{feature-callTrace → feature-api-functions}/ponder-env.d.ts +2 -1
- package/templates/feature-api-functions/ponder.config.ts +21 -0
- package/templates/feature-api-functions/ponder.schema.ts +50 -0
- package/templates/feature-api-functions/src/api/index.ts +47 -0
- package/templates/feature-blocks/package.json +1 -0
- package/templates/feature-blocks/ponder-env.d.ts +1 -0
- package/templates/feature-call-traces/package.json +1 -0
- package/templates/feature-call-traces/ponder-env.d.ts +1 -0
- package/templates/feature-factory/package.json +1 -0
- package/templates/feature-factory/ponder-env.d.ts +1 -0
- package/templates/feature-filter/package.json +1 -0
- package/templates/feature-filter/ponder-env.d.ts +1 -0
- package/templates/feature-multichain/package.json +1 -0
- package/templates/feature-multichain/ponder-env.d.ts +1 -0
- package/templates/feature-proxy/package.json +1 -0
- package/templates/feature-proxy/ponder-env.d.ts +1 -0
- package/templates/feature-read-contract/package.json +1 -0
- package/templates/feature-read-contract/ponder-env.d.ts +1 -0
- package/templates/project-friendtech/package.json +1 -0
- package/templates/project-friendtech/ponder-env.d.ts +1 -0
- package/templates/project-uniswap-v3-flash/package.json +1 -0
- package/templates/project-uniswap-v3-flash/ponder-env.d.ts +1 -0
- package/templates/reference-erc1155/package.json +1 -0
- package/templates/reference-erc1155/ponder-env.d.ts +1 -0
- package/templates/reference-erc20/package.json +1 -1
- package/templates/reference-erc20/ponder-env.d.ts +1 -0
- package/templates/reference-erc4626/package.json +1 -0
- package/templates/reference-erc4626/ponder-env.d.ts +1 -0
- package/templates/reference-erc721/package.json +1 -0
- package/templates/reference-erc721/ponder-env.d.ts +1 -0
- package/templates/subgraph/package.json +1 -0
- package/templates/subgraph/ponder-env.d.ts +1 -0
- package/templates/feature-callTrace/ponder.config.ts +0 -22
- package/templates/feature-callTrace/ponder.schema.ts +0 -11
- package/templates/feature-callTrace/src/index.ts +0 -33
- package/templates/reference-erc20/sqlite/ponder.db +0 -0
- package/templates/reference-erc20/sqlite/ponder_cache.db +0 -0
- package/templates/reference-erc20/sqlite/ponder_sync.db +0 -0
- package/templates/reference-erc20/src/api/index.ts +0 -26
- package/templates/reference-erc20/src/server/index.ts +0 -20
- /package/templates/{feature-callTrace → feature-api-functions}/_dot_env.local +0 -0
- /package/templates/{feature-callTrace → feature-api-functions}/_dot_eslintrc.json +0 -0
- /package/templates/{feature-callTrace → feature-api-functions}/_dot_gitignore +0 -0
- /package/templates/{reference-erc20/src/indexing → feature-api-functions/src}/index.ts +0 -0
- /package/templates/{feature-callTrace → feature-api-functions}/tsconfig.json +0 -0
package/README.md
CHANGED
|
@@ -33,7 +33,7 @@ Join [Ponder's telegram chat](https://t.me/ponder_sh) for support, feedback, and
|
|
|
33
33
|
|
|
34
34
|
### 1. Run `create-ponder`
|
|
35
35
|
|
|
36
|
-
You will be asked for a project name, and if you are using a [template](https://ponder.sh/api-reference/create-ponder#templates) (recommended). Then, the CLI will create a project directory, install dependencies, and initialize a git repository.
|
|
36
|
+
You will be asked for a project name, and if you are using a [template](https://ponder.sh/docs/api-reference/create-ponder#templates) (recommended). Then, the CLI will create a project directory, install dependencies, and initialize a git repository.
|
|
37
37
|
|
|
38
38
|
```bash
|
|
39
39
|
npm init ponder@latest
|
|
@@ -128,7 +128,7 @@ ponder.on("BaseRegistrar:NameRegistered", async ({ event, context }) => {
|
|
|
128
128
|
});
|
|
129
129
|
```
|
|
130
130
|
|
|
131
|
-
See the [create & update records](https://ponder.sh/docs/
|
|
131
|
+
See the [create & update records](https://ponder.sh/docs/indexing/create-update-records) docs for a detailed guide on writing indexing functions.
|
|
132
132
|
|
|
133
133
|
### 6. Query the GraphQL API
|
|
134
134
|
|
package/dist/index.js
CHANGED
|
@@ -16,7 +16,7 @@ import { default as prompts } from "prompts";
|
|
|
16
16
|
// package.json
|
|
17
17
|
var package_default = {
|
|
18
18
|
name: "create-ponder",
|
|
19
|
-
version: "0.5.
|
|
19
|
+
version: "0.5.1",
|
|
20
20
|
type: "module",
|
|
21
21
|
description: "A CLI tool to create Ponder apps",
|
|
22
22
|
license: "MIT",
|
|
@@ -484,8 +484,6 @@ var chainIdByGraphNetwork = {
|
|
|
484
484
|
fantom: 250,
|
|
485
485
|
"fantom-testnet": 4002,
|
|
486
486
|
bsc: 56,
|
|
487
|
-
chapel: -1,
|
|
488
|
-
clover: 0,
|
|
489
487
|
avalanche: 43114,
|
|
490
488
|
fuji: 43113,
|
|
491
489
|
celo: 42220,
|
|
@@ -493,7 +491,6 @@ var chainIdByGraphNetwork = {
|
|
|
493
491
|
fuse: 122,
|
|
494
492
|
moonbeam: 1284,
|
|
495
493
|
moonriver: 1285,
|
|
496
|
-
mbase: -1,
|
|
497
494
|
base: 8453,
|
|
498
495
|
"base-sepolia": 84532,
|
|
499
496
|
"arbitrum-one": 42161,
|
|
@@ -504,7 +501,7 @@ var chainIdByGraphNetwork = {
|
|
|
504
501
|
"aurora-testnet": 1313161555
|
|
505
502
|
};
|
|
506
503
|
var getGraphProtocolChainId = (networkName) => {
|
|
507
|
-
return chainIdByGraphNetwork[networkName];
|
|
504
|
+
return chainIdByGraphNetwork[networkName] ?? 0;
|
|
508
505
|
};
|
|
509
506
|
var subgraphYamlFileNames = ["subgraph.yaml"].concat(
|
|
510
507
|
Object.keys(chainIdByGraphNetwork).map((n) => `subgraph-${n}.yaml`)
|
|
@@ -516,17 +513,33 @@ var validateGraphProtocolSource = (source) => {
|
|
|
516
513
|
};
|
|
517
514
|
|
|
518
515
|
// src/subgraph.ts
|
|
519
|
-
var
|
|
520
|
-
|
|
516
|
+
var subgraphProviders = [
|
|
517
|
+
{
|
|
518
|
+
id: "thegraph",
|
|
519
|
+
name: "The Graph",
|
|
520
|
+
getUrl: (cid) => `https://ipfs.network.thegraph.com/api/v0/cat?arg=${cid}`
|
|
521
|
+
},
|
|
522
|
+
{
|
|
523
|
+
id: "satsuma",
|
|
524
|
+
name: "Alchemy Subgraph (Satsuma)",
|
|
525
|
+
getUrl: (cid) => `https://ipfs.satsuma.xyz/ipfs/${cid}`
|
|
526
|
+
}
|
|
527
|
+
];
|
|
528
|
+
var fetchIpfsFile = async (cid, subgraphProvider) => {
|
|
529
|
+
const url = subgraphProvider.getUrl(cid);
|
|
521
530
|
const response = await fetch(url);
|
|
522
531
|
const contentRaw = await response.text();
|
|
523
532
|
return contentRaw;
|
|
524
533
|
};
|
|
525
534
|
var fromSubgraphId = async ({
|
|
526
535
|
rootDir,
|
|
527
|
-
subgraphId
|
|
536
|
+
subgraphId,
|
|
537
|
+
subgraphProvider = "thegraph"
|
|
528
538
|
}) => {
|
|
529
|
-
const
|
|
539
|
+
const provider = subgraphProviders.find((p) => p.id === subgraphProvider);
|
|
540
|
+
if (!provider)
|
|
541
|
+
throw new Error(`Unknown subgraph provider: ${subgraphProvider}`);
|
|
542
|
+
const manifestRaw = await fetchIpfsFile(subgraphId, provider);
|
|
530
543
|
const manifest = parse(manifestRaw);
|
|
531
544
|
const contracts = {};
|
|
532
545
|
manifest.dataSources.forEach((d) => {
|
|
@@ -545,7 +558,7 @@ var fromSubgraphId = async ({
|
|
|
545
558
|
const abis = {};
|
|
546
559
|
await Promise.all(
|
|
547
560
|
abiFiles.map(async (abi) => {
|
|
548
|
-
const abiContent = await fetchIpfsFile(abi.file["/"].slice(6));
|
|
561
|
+
const abiContent = await fetchIpfsFile(abi.file["/"].slice(6), provider);
|
|
549
562
|
const abiPath = path3.join(rootDir, `./abis/${abi.name}Abi.ts`);
|
|
550
563
|
writeFileSync2(
|
|
551
564
|
abiPath,
|
|
@@ -562,10 +575,6 @@ var fromSubgraphId = async ({
|
|
|
562
575
|
const ponderContracts = dataSources.map((sourceInvalid) => {
|
|
563
576
|
const source = validateGraphProtocolSource(sourceInvalid);
|
|
564
577
|
const network = source.network || "mainnet";
|
|
565
|
-
const chainId = getGraphProtocolChainId(network);
|
|
566
|
-
if (!chainId || chainId === -1) {
|
|
567
|
-
throw new Error(`Unhandled network name: ${network}`);
|
|
568
|
-
}
|
|
569
578
|
const abiRelativePath = `./abis/${source.source.abi}Abi.ts`;
|
|
570
579
|
return {
|
|
571
580
|
name: source.name,
|
|
@@ -582,10 +591,11 @@ var fromSubgraphId = async ({
|
|
|
582
591
|
const contractsObject = {};
|
|
583
592
|
const networksObject = {};
|
|
584
593
|
ponderContracts.forEach((pc) => {
|
|
594
|
+
const chainId = getGraphProtocolChainId(pc.network);
|
|
585
595
|
contractsObject[pc.name] = pc;
|
|
586
596
|
networksObject[pc.network] = {
|
|
587
|
-
chainId
|
|
588
|
-
transport: `http(process.env.PONDER_RPC_URL_${
|
|
597
|
+
chainId,
|
|
598
|
+
transport: `http(process.env.PONDER_RPC_URL_${chainId})`
|
|
589
599
|
};
|
|
590
600
|
contractsObject[pc.name].name = void 0;
|
|
591
601
|
});
|
|
@@ -626,6 +636,11 @@ var templates = [
|
|
|
626
636
|
title: "Feature - Custom event filter",
|
|
627
637
|
description: "A Ponder app using an event filter"
|
|
628
638
|
},
|
|
639
|
+
{
|
|
640
|
+
id: "feature-api-functions",
|
|
641
|
+
title: "Feature - Custom api functions",
|
|
642
|
+
description: "A Ponder app using a custom api functions"
|
|
643
|
+
},
|
|
629
644
|
{
|
|
630
645
|
id: "feature-blocks",
|
|
631
646
|
title: "Feature - Block filter",
|
|
@@ -776,7 +791,20 @@ async function run({
|
|
|
776
791
|
}
|
|
777
792
|
}
|
|
778
793
|
let subgraph = options.subgraph;
|
|
794
|
+
let subgraphProvider = options.subgraphProvider;
|
|
779
795
|
if (templateMeta.id === "subgraph") {
|
|
796
|
+
if (subgraphProvider === void 0) {
|
|
797
|
+
const result = await prompts({
|
|
798
|
+
name: "subgraphProvider",
|
|
799
|
+
message: "Which provider is the subgraph deployed to?",
|
|
800
|
+
type: "select",
|
|
801
|
+
choices: subgraphProviders.map(({ id, name }) => ({
|
|
802
|
+
title: name,
|
|
803
|
+
value: id
|
|
804
|
+
}))
|
|
805
|
+
});
|
|
806
|
+
subgraphProvider = result.subgraphProvider;
|
|
807
|
+
}
|
|
780
808
|
if (!subgraph) {
|
|
781
809
|
const result = await prompts({
|
|
782
810
|
type: "text",
|
|
@@ -811,7 +839,11 @@ async function run({
|
|
|
811
839
|
}
|
|
812
840
|
if (templateMeta.id === "subgraph") {
|
|
813
841
|
const result = await oraPromise(
|
|
814
|
-
fromSubgraphId({
|
|
842
|
+
fromSubgraphId({
|
|
843
|
+
rootDir: projectPath,
|
|
844
|
+
subgraphId: subgraph,
|
|
845
|
+
subgraphProvider
|
|
846
|
+
}),
|
|
815
847
|
{
|
|
816
848
|
text: "Fetching subgraph metadata. This may take a few seconds.",
|
|
817
849
|
failText: "Failed to fetch subgraph metadata.",
|
|
@@ -967,7 +999,10 @@ async function run({
|
|
|
967
999
|
const cli = cac(package_default.name).version(package_default.version).usage(`${pico5.green("<directory>")} [options]`).option(
|
|
968
1000
|
"-t, --template [id]",
|
|
969
1001
|
`Use a template. Options: ${templates.map(({ id }) => id).join(", ")}`
|
|
970
|
-
).option("--etherscan [url]", "Use the Etherscan template").option("--subgraph [id]", "Use the subgraph template").option(
|
|
1002
|
+
).option("--etherscan [url]", "Use the Etherscan template").option("--subgraph [id]", "Use the subgraph template").option(
|
|
1003
|
+
"--subgraph-provider [provider]",
|
|
1004
|
+
`Specify the subgraph provider. Options: ${subgraphProviders.map(({ id }) => id).join(", ")}`
|
|
1005
|
+
).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(
|
|
971
1006
|
"--etherscan-api-key [key]",
|
|
972
1007
|
"Etherscan API key for Etherscan template"
|
|
973
1008
|
).help();
|
package/package.json
CHANGED
|
@@ -21,6 +21,7 @@ declare module "@/generated" {
|
|
|
21
21
|
schema,
|
|
22
22
|
name
|
|
23
23
|
>;
|
|
24
|
+
export type ApiContext = Virtual.Drizzle<schema>;
|
|
24
25
|
export type IndexingFunctionArgs<name extends EventNames = EventNames> =
|
|
25
26
|
Virtual.IndexingFunctionArgs<config, schema, name>;
|
|
26
27
|
export type Schema = Virtual.Schema<schema>;
|
|
@@ -21,6 +21,7 @@ declare module "@/generated" {
|
|
|
21
21
|
schema,
|
|
22
22
|
name
|
|
23
23
|
>;
|
|
24
|
+
export type ApiContext = Virtual.Drizzle<schema>;
|
|
24
25
|
export type IndexingFunctionArgs<name extends EventNames = EventNames> =
|
|
25
26
|
Virtual.IndexingFunctionArgs<config, schema, name>;
|
|
26
27
|
export type Schema = Virtual.Schema<schema>;
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
export const erc20ABI = [
|
|
2
|
+
{
|
|
3
|
+
stateMutability: "view",
|
|
4
|
+
type: "function",
|
|
5
|
+
inputs: [],
|
|
6
|
+
name: "DOMAIN_SEPARATOR",
|
|
7
|
+
outputs: [{ name: "", internalType: "bytes32", type: "bytes32" }],
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
stateMutability: "view",
|
|
11
|
+
type: "function",
|
|
12
|
+
inputs: [
|
|
13
|
+
{ name: "", internalType: "address", type: "address" },
|
|
14
|
+
{ name: "", internalType: "address", type: "address" },
|
|
15
|
+
],
|
|
16
|
+
name: "allowance",
|
|
17
|
+
outputs: [{ name: "", internalType: "uint256", type: "uint256" }],
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
stateMutability: "nonpayable",
|
|
21
|
+
type: "function",
|
|
22
|
+
inputs: [
|
|
23
|
+
{ name: "spender", internalType: "address", type: "address" },
|
|
24
|
+
{ name: "amount", internalType: "uint256", type: "uint256" },
|
|
25
|
+
],
|
|
26
|
+
name: "approve",
|
|
27
|
+
outputs: [{ name: "", internalType: "bool", type: "bool" }],
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
stateMutability: "view",
|
|
31
|
+
type: "function",
|
|
32
|
+
inputs: [{ name: "", internalType: "address", type: "address" }],
|
|
33
|
+
name: "balanceOf",
|
|
34
|
+
outputs: [{ name: "", internalType: "uint256", type: "uint256" }],
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
stateMutability: "view",
|
|
38
|
+
type: "function",
|
|
39
|
+
inputs: [],
|
|
40
|
+
name: "decimals",
|
|
41
|
+
outputs: [{ name: "", internalType: "uint8", type: "uint8" }],
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
stateMutability: "view",
|
|
45
|
+
type: "function",
|
|
46
|
+
inputs: [],
|
|
47
|
+
name: "name",
|
|
48
|
+
outputs: [{ name: "", internalType: "string", type: "string" }],
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
stateMutability: "view",
|
|
52
|
+
type: "function",
|
|
53
|
+
inputs: [{ name: "", internalType: "address", type: "address" }],
|
|
54
|
+
name: "nonces",
|
|
55
|
+
outputs: [{ name: "", internalType: "uint256", type: "uint256" }],
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
stateMutability: "nonpayable",
|
|
59
|
+
type: "function",
|
|
60
|
+
inputs: [
|
|
61
|
+
{ name: "owner", internalType: "address", type: "address" },
|
|
62
|
+
{ name: "spender", internalType: "address", type: "address" },
|
|
63
|
+
{ name: "value", internalType: "uint256", type: "uint256" },
|
|
64
|
+
{ name: "deadline", internalType: "uint256", type: "uint256" },
|
|
65
|
+
{ name: "v", internalType: "uint8", type: "uint8" },
|
|
66
|
+
{ name: "r", internalType: "bytes32", type: "bytes32" },
|
|
67
|
+
{ name: "s", internalType: "bytes32", type: "bytes32" },
|
|
68
|
+
],
|
|
69
|
+
name: "permit",
|
|
70
|
+
outputs: [],
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
stateMutability: "view",
|
|
74
|
+
type: "function",
|
|
75
|
+
inputs: [],
|
|
76
|
+
name: "symbol",
|
|
77
|
+
outputs: [{ name: "", internalType: "string", type: "string" }],
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
stateMutability: "view",
|
|
81
|
+
type: "function",
|
|
82
|
+
inputs: [],
|
|
83
|
+
name: "totalSupply",
|
|
84
|
+
outputs: [{ name: "", internalType: "uint256", type: "uint256" }],
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
stateMutability: "nonpayable",
|
|
88
|
+
type: "function",
|
|
89
|
+
inputs: [
|
|
90
|
+
{ name: "to", internalType: "address", type: "address" },
|
|
91
|
+
{ name: "amount", internalType: "uint256", type: "uint256" },
|
|
92
|
+
],
|
|
93
|
+
name: "transfer",
|
|
94
|
+
outputs: [{ name: "", internalType: "bool", type: "bool" }],
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
stateMutability: "nonpayable",
|
|
98
|
+
type: "function",
|
|
99
|
+
inputs: [
|
|
100
|
+
{ name: "from", internalType: "address", type: "address" },
|
|
101
|
+
{ name: "to", internalType: "address", type: "address" },
|
|
102
|
+
{ name: "amount", internalType: "uint256", type: "uint256" },
|
|
103
|
+
],
|
|
104
|
+
name: "transferFrom",
|
|
105
|
+
outputs: [{ name: "", internalType: "bool", type: "bool" }],
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
type: "event",
|
|
109
|
+
anonymous: false,
|
|
110
|
+
inputs: [
|
|
111
|
+
{
|
|
112
|
+
name: "owner",
|
|
113
|
+
internalType: "address",
|
|
114
|
+
type: "address",
|
|
115
|
+
indexed: true,
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
name: "spender",
|
|
119
|
+
internalType: "address",
|
|
120
|
+
type: "address",
|
|
121
|
+
indexed: true,
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
name: "amount",
|
|
125
|
+
internalType: "uint256",
|
|
126
|
+
type: "uint256",
|
|
127
|
+
indexed: false,
|
|
128
|
+
},
|
|
129
|
+
],
|
|
130
|
+
name: "Approval",
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
type: "event",
|
|
134
|
+
anonymous: false,
|
|
135
|
+
inputs: [
|
|
136
|
+
{ name: "from", internalType: "address", type: "address", indexed: true },
|
|
137
|
+
{ name: "to", internalType: "address", type: "address", indexed: true },
|
|
138
|
+
{
|
|
139
|
+
name: "amount",
|
|
140
|
+
internalType: "uint256",
|
|
141
|
+
type: "uint256",
|
|
142
|
+
indexed: false,
|
|
143
|
+
},
|
|
144
|
+
],
|
|
145
|
+
name: "Transfer",
|
|
146
|
+
},
|
|
147
|
+
] as const;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"name": "ponder-examples-feature-
|
|
2
|
+
"name": "ponder-examples-feature-api-functions",
|
|
3
3
|
"private": true,
|
|
4
4
|
"type": "module",
|
|
5
5
|
"scripts": {
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
14
|
"@ponder/core": "workspace:*",
|
|
15
|
+
"hono": "^4.5.0",
|
|
15
16
|
"viem": "^1.19.9"
|
|
16
17
|
},
|
|
17
18
|
"devDependencies": {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// This file enables type checking and editor autocomplete for this Ponder project.
|
|
2
2
|
// After upgrading, you may find that changes have been made to this file.
|
|
3
3
|
// If this happens, please commit the changes. Do not manually edit this file.
|
|
4
|
-
// See https://ponder.sh/docs/
|
|
4
|
+
// See https://ponder.sh/docs/getting-started/installation#typescript for more information.
|
|
5
5
|
|
|
6
6
|
declare module "@/generated" {
|
|
7
7
|
import type { Virtual } from "@ponder/core";
|
|
@@ -21,6 +21,7 @@ declare module "@/generated" {
|
|
|
21
21
|
schema,
|
|
22
22
|
name
|
|
23
23
|
>;
|
|
24
|
+
export type ApiContext = Virtual.Drizzle<schema>;
|
|
24
25
|
export type IndexingFunctionArgs<name extends EventNames = EventNames> =
|
|
25
26
|
Virtual.IndexingFunctionArgs<config, schema, name>;
|
|
26
27
|
export type Schema = Virtual.Schema<schema>;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { createConfig } from "@ponder/core";
|
|
2
|
+
import { http } from "viem";
|
|
3
|
+
import { erc20ABI } from "./abis/erc20ABI";
|
|
4
|
+
|
|
5
|
+
export default createConfig({
|
|
6
|
+
networks: {
|
|
7
|
+
mainnet: {
|
|
8
|
+
chainId: 1,
|
|
9
|
+
transport: http(process.env.PONDER_RPC_URL_1),
|
|
10
|
+
},
|
|
11
|
+
},
|
|
12
|
+
contracts: {
|
|
13
|
+
ERC20: {
|
|
14
|
+
network: "mainnet",
|
|
15
|
+
abi: erc20ABI,
|
|
16
|
+
address: "0x32353A6C91143bfd6C7d363B546e62a9A2489A20",
|
|
17
|
+
startBlock: 13142655,
|
|
18
|
+
endBlock: 13150000,
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
});
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { createSchema } from "@ponder/core";
|
|
2
|
+
|
|
3
|
+
export default createSchema((p) => ({
|
|
4
|
+
Account: p.createTable({
|
|
5
|
+
id: p.hex(),
|
|
6
|
+
balance: p.bigint(),
|
|
7
|
+
isOwner: p.boolean(),
|
|
8
|
+
|
|
9
|
+
allowances: p.many("Allowance.ownerId"),
|
|
10
|
+
approvalOwnerEvents: p.many("ApprovalEvent.ownerId"),
|
|
11
|
+
approvalSpenderEvents: p.many("ApprovalEvent.spenderId"),
|
|
12
|
+
transferFromEvents: p.many("TransferEvent.fromId"),
|
|
13
|
+
transferToEvents: p.many("TransferEvent.toId"),
|
|
14
|
+
}),
|
|
15
|
+
Allowance: p.createTable({
|
|
16
|
+
id: p.string(),
|
|
17
|
+
amount: p.bigint(),
|
|
18
|
+
|
|
19
|
+
ownerId: p.hex().references("Account.id"),
|
|
20
|
+
spenderId: p.hex().references("Account.id"),
|
|
21
|
+
|
|
22
|
+
owner: p.one("ownerId"),
|
|
23
|
+
spender: p.one("spenderId"),
|
|
24
|
+
}),
|
|
25
|
+
TransferEvent: p.createTable(
|
|
26
|
+
{
|
|
27
|
+
id: p.string(),
|
|
28
|
+
amount: p.bigint(),
|
|
29
|
+
timestamp: p.int(),
|
|
30
|
+
|
|
31
|
+
fromId: p.hex().references("Account.id"),
|
|
32
|
+
toId: p.hex().references("Account.id"),
|
|
33
|
+
|
|
34
|
+
from: p.one("fromId"),
|
|
35
|
+
to: p.one("toId"),
|
|
36
|
+
},
|
|
37
|
+
{ fromIdIndex: p.index("fromId") },
|
|
38
|
+
),
|
|
39
|
+
ApprovalEvent: p.createTable({
|
|
40
|
+
id: p.string(),
|
|
41
|
+
amount: p.bigint(),
|
|
42
|
+
timestamp: p.int(),
|
|
43
|
+
|
|
44
|
+
ownerId: p.hex().references("Account.id"),
|
|
45
|
+
spenderId: p.hex().references("Account.id"),
|
|
46
|
+
|
|
47
|
+
owner: p.one("ownerId"),
|
|
48
|
+
spender: p.one("spenderId"),
|
|
49
|
+
}),
|
|
50
|
+
}));
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { ponder } from "@/generated";
|
|
2
|
+
import { count, desc, eq, graphql, or, replaceBigInts } from "@ponder/core";
|
|
3
|
+
import { formatEther, getAddress } from "viem";
|
|
4
|
+
|
|
5
|
+
ponder.use("/graphql", graphql());
|
|
6
|
+
|
|
7
|
+
ponder.get("/count", async (c) => {
|
|
8
|
+
const result = await c.db
|
|
9
|
+
.select({ count: count() })
|
|
10
|
+
.from(c.tables.TransferEvent);
|
|
11
|
+
|
|
12
|
+
if (result.length === 0) return c.text("0");
|
|
13
|
+
return c.text(String(result[0]!.count));
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
ponder.get("/count/:address", async (c) => {
|
|
17
|
+
const account = getAddress(c.req.param("address"));
|
|
18
|
+
const { TransferEvent } = c.tables;
|
|
19
|
+
|
|
20
|
+
const result = await c.db
|
|
21
|
+
.select({ count: count() })
|
|
22
|
+
.from(c.tables.TransferEvent)
|
|
23
|
+
.where(
|
|
24
|
+
or(eq(TransferEvent.fromId, account), eq(TransferEvent.toId, account)),
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
if (result.length === 0) return c.text("0");
|
|
28
|
+
return c.text(String(result[0]!.count));
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
ponder.get("/whale-transfers", async (c) => {
|
|
32
|
+
const { TransferEvent, Account } = c.tables;
|
|
33
|
+
|
|
34
|
+
// Top 10 transfers from whale accounts
|
|
35
|
+
const result = await c.db
|
|
36
|
+
.select({
|
|
37
|
+
amount: TransferEvent.amount,
|
|
38
|
+
senderBalance: Account.balance,
|
|
39
|
+
})
|
|
40
|
+
.from(TransferEvent)
|
|
41
|
+
.innerJoin(Account, eq(TransferEvent.fromId, Account.id))
|
|
42
|
+
.orderBy(desc(Account.balance))
|
|
43
|
+
.limit(10);
|
|
44
|
+
|
|
45
|
+
if (result.length === 0) return c.text("Not found", 500);
|
|
46
|
+
return c.json(replaceBigInts(result, (b) => formatEther(b)));
|
|
47
|
+
});
|
|
@@ -21,6 +21,7 @@ declare module "@/generated" {
|
|
|
21
21
|
schema,
|
|
22
22
|
name
|
|
23
23
|
>;
|
|
24
|
+
export type ApiContext = Virtual.Drizzle<schema>;
|
|
24
25
|
export type IndexingFunctionArgs<name extends EventNames = EventNames> =
|
|
25
26
|
Virtual.IndexingFunctionArgs<config, schema, name>;
|
|
26
27
|
export type Schema = Virtual.Schema<schema>;
|
|
@@ -21,6 +21,7 @@ declare module "@/generated" {
|
|
|
21
21
|
schema,
|
|
22
22
|
name
|
|
23
23
|
>;
|
|
24
|
+
export type ApiContext = Virtual.Drizzle<schema>;
|
|
24
25
|
export type IndexingFunctionArgs<name extends EventNames = EventNames> =
|
|
25
26
|
Virtual.IndexingFunctionArgs<config, schema, name>;
|
|
26
27
|
export type Schema = Virtual.Schema<schema>;
|
|
@@ -21,6 +21,7 @@ declare module "@/generated" {
|
|
|
21
21
|
schema,
|
|
22
22
|
name
|
|
23
23
|
>;
|
|
24
|
+
export type ApiContext = Virtual.Drizzle<schema>;
|
|
24
25
|
export type IndexingFunctionArgs<name extends EventNames = EventNames> =
|
|
25
26
|
Virtual.IndexingFunctionArgs<config, schema, name>;
|
|
26
27
|
export type Schema = Virtual.Schema<schema>;
|
|
@@ -21,6 +21,7 @@ declare module "@/generated" {
|
|
|
21
21
|
schema,
|
|
22
22
|
name
|
|
23
23
|
>;
|
|
24
|
+
export type ApiContext = Virtual.Drizzle<schema>;
|
|
24
25
|
export type IndexingFunctionArgs<name extends EventNames = EventNames> =
|
|
25
26
|
Virtual.IndexingFunctionArgs<config, schema, name>;
|
|
26
27
|
export type Schema = Virtual.Schema<schema>;
|
|
@@ -21,6 +21,7 @@ declare module "@/generated" {
|
|
|
21
21
|
schema,
|
|
22
22
|
name
|
|
23
23
|
>;
|
|
24
|
+
export type ApiContext = Virtual.Drizzle<schema>;
|
|
24
25
|
export type IndexingFunctionArgs<name extends EventNames = EventNames> =
|
|
25
26
|
Virtual.IndexingFunctionArgs<config, schema, name>;
|
|
26
27
|
export type Schema = Virtual.Schema<schema>;
|
|
@@ -21,6 +21,7 @@ declare module "@/generated" {
|
|
|
21
21
|
schema,
|
|
22
22
|
name
|
|
23
23
|
>;
|
|
24
|
+
export type ApiContext = Virtual.Drizzle<schema>;
|
|
24
25
|
export type IndexingFunctionArgs<name extends EventNames = EventNames> =
|
|
25
26
|
Virtual.IndexingFunctionArgs<config, schema, name>;
|
|
26
27
|
export type Schema = Virtual.Schema<schema>;
|
|
@@ -21,6 +21,7 @@ declare module "@/generated" {
|
|
|
21
21
|
schema,
|
|
22
22
|
name
|
|
23
23
|
>;
|
|
24
|
+
export type ApiContext = Virtual.Drizzle<schema>;
|
|
24
25
|
export type IndexingFunctionArgs<name extends EventNames = EventNames> =
|
|
25
26
|
Virtual.IndexingFunctionArgs<config, schema, name>;
|
|
26
27
|
export type Schema = Virtual.Schema<schema>;
|
|
@@ -21,6 +21,7 @@ declare module "@/generated" {
|
|
|
21
21
|
schema,
|
|
22
22
|
name
|
|
23
23
|
>;
|
|
24
|
+
export type ApiContext = Virtual.Drizzle<schema>;
|
|
24
25
|
export type IndexingFunctionArgs<name extends EventNames = EventNames> =
|
|
25
26
|
Virtual.IndexingFunctionArgs<config, schema, name>;
|
|
26
27
|
export type Schema = Virtual.Schema<schema>;
|
|
@@ -21,6 +21,7 @@ declare module "@/generated" {
|
|
|
21
21
|
schema,
|
|
22
22
|
name
|
|
23
23
|
>;
|
|
24
|
+
export type ApiContext = Virtual.Drizzle<schema>;
|
|
24
25
|
export type IndexingFunctionArgs<name extends EventNames = EventNames> =
|
|
25
26
|
Virtual.IndexingFunctionArgs<config, schema, name>;
|
|
26
27
|
export type Schema = Virtual.Schema<schema>;
|
|
@@ -21,6 +21,7 @@ declare module "@/generated" {
|
|
|
21
21
|
schema,
|
|
22
22
|
name
|
|
23
23
|
>;
|
|
24
|
+
export type ApiContext = Virtual.Drizzle<schema>;
|
|
24
25
|
export type IndexingFunctionArgs<name extends EventNames = EventNames> =
|
|
25
26
|
Virtual.IndexingFunctionArgs<config, schema, name>;
|
|
26
27
|
export type Schema = Virtual.Schema<schema>;
|
|
@@ -21,6 +21,7 @@ declare module "@/generated" {
|
|
|
21
21
|
schema,
|
|
22
22
|
name
|
|
23
23
|
>;
|
|
24
|
+
export type ApiContext = Virtual.Drizzle<schema>;
|
|
24
25
|
export type IndexingFunctionArgs<name extends EventNames = EventNames> =
|
|
25
26
|
Virtual.IndexingFunctionArgs<config, schema, name>;
|
|
26
27
|
export type Schema = Virtual.Schema<schema>;
|
|
@@ -21,6 +21,7 @@ declare module "@/generated" {
|
|
|
21
21
|
schema,
|
|
22
22
|
name
|
|
23
23
|
>;
|
|
24
|
+
export type ApiContext = Virtual.Drizzle<schema>;
|
|
24
25
|
export type IndexingFunctionArgs<name extends EventNames = EventNames> =
|
|
25
26
|
Virtual.IndexingFunctionArgs<config, schema, name>;
|
|
26
27
|
export type Schema = Virtual.Schema<schema>;
|
|
@@ -21,6 +21,7 @@ declare module "@/generated" {
|
|
|
21
21
|
schema,
|
|
22
22
|
name
|
|
23
23
|
>;
|
|
24
|
+
export type ApiContext = Virtual.Drizzle<schema>;
|
|
24
25
|
export type IndexingFunctionArgs<name extends EventNames = EventNames> =
|
|
25
26
|
Virtual.IndexingFunctionArgs<config, schema, name>;
|
|
26
27
|
export type Schema = Virtual.Schema<schema>;
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { createConfig } from "@ponder/core";
|
|
2
|
-
import { http, Abi, multicall3Abi } from "viem";
|
|
3
|
-
import { mainnet } from "viem/chains";
|
|
4
|
-
|
|
5
|
-
export default createConfig({
|
|
6
|
-
networks: {
|
|
7
|
-
mainnet: {
|
|
8
|
-
chainId: 1,
|
|
9
|
-
transport: http(process.env.PONDER_RPC_URL_1),
|
|
10
|
-
},
|
|
11
|
-
},
|
|
12
|
-
contracts: {
|
|
13
|
-
multicall3: {
|
|
14
|
-
network: "mainnet",
|
|
15
|
-
abi: multicall3Abi,
|
|
16
|
-
address: mainnet.contracts.multicall3.address,
|
|
17
|
-
startBlock: 19_800_000,
|
|
18
|
-
includeFunctionCalls: true,
|
|
19
|
-
maxBlockRange: 25,
|
|
20
|
-
},
|
|
21
|
-
},
|
|
22
|
-
});
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { ponder } from "@/generated";
|
|
2
|
-
|
|
3
|
-
ponder.on("multicall3.aggregate3()", async ({ event, context }) => {
|
|
4
|
-
await context.db.multicalls.upsert({
|
|
5
|
-
id: event.trace.from,
|
|
6
|
-
create: {
|
|
7
|
-
gasUsed: event.trace.gasUsed,
|
|
8
|
-
bytes: event.args[0].reduce<number>(
|
|
9
|
-
(acc, cur) => acc + Math.ceil((cur.callData.length - 2) / 8),
|
|
10
|
-
0,
|
|
11
|
-
),
|
|
12
|
-
successfulCalls: event.result.filter(({ success }) => success === true)
|
|
13
|
-
.length,
|
|
14
|
-
failedCalls: event.result.filter(({ success }) => success === false)
|
|
15
|
-
.length,
|
|
16
|
-
},
|
|
17
|
-
update: ({ current }) => ({
|
|
18
|
-
gasUsed: current.gasUsed + event.trace.gasUsed,
|
|
19
|
-
bytes:
|
|
20
|
-
current.bytes +
|
|
21
|
-
event.args[0].reduce<number>(
|
|
22
|
-
(acc, cur) => acc + Math.ceil((cur.callData.length - 2) / 8),
|
|
23
|
-
0,
|
|
24
|
-
),
|
|
25
|
-
successfulCalls:
|
|
26
|
-
current.successfulCalls +
|
|
27
|
-
event.result.filter(({ success }) => success === true).length,
|
|
28
|
-
failedCalls:
|
|
29
|
-
current.failedCalls +
|
|
30
|
-
event.result.filter(({ success }) => success === false).length,
|
|
31
|
-
}),
|
|
32
|
-
});
|
|
33
|
-
});
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { ponder } from "@/generated";
|
|
2
|
-
import { graphql, sql } from "@ponder/core";
|
|
3
|
-
|
|
4
|
-
// write file
|
|
5
|
-
ponder.use("/graphql", graphql());
|
|
6
|
-
|
|
7
|
-
ponder.get("/router", async (c) => {
|
|
8
|
-
const db = c.get("db");
|
|
9
|
-
|
|
10
|
-
// await db.query(`UPDATE "Account" SET "isOwner" = 1`);
|
|
11
|
-
// if (Math.random() > 0.5) {
|
|
12
|
-
// throw new Error("kyle");
|
|
13
|
-
// }
|
|
14
|
-
|
|
15
|
-
const v = 1;
|
|
16
|
-
|
|
17
|
-
const account = await db.query<{ balance: bigint }>(
|
|
18
|
-
sql`SELECT * FROM "Account" LIMIT ${v}`,
|
|
19
|
-
);
|
|
20
|
-
|
|
21
|
-
if (account.rows.length === 0) {
|
|
22
|
-
return c.text("Not Found!");
|
|
23
|
-
} else {
|
|
24
|
-
return c.text(`Balance: ${account.rows[0]!.balance.toString()}`);
|
|
25
|
-
}
|
|
26
|
-
});
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { ponder } from "@/generated";
|
|
2
|
-
import { graphql } from "@ponder/core";
|
|
3
|
-
|
|
4
|
-
ponder.use("/graphql", graphql());
|
|
5
|
-
|
|
6
|
-
ponder.get("/router", async (c) => {
|
|
7
|
-
const db = c.get("db");
|
|
8
|
-
|
|
9
|
-
// await db.query(`UPDATE "Account" SET "isOwner" = 1`);
|
|
10
|
-
|
|
11
|
-
const account = await db.query<{ balance: bigint }>(
|
|
12
|
-
`SELECT * FROM "Account" LIMIT 1`,
|
|
13
|
-
);
|
|
14
|
-
|
|
15
|
-
if (account.rows.length === 0) {
|
|
16
|
-
return c.text("Not Found!");
|
|
17
|
-
} else {
|
|
18
|
-
return c.text(`Balance: ${account.rows[0]!.balance.toString()}`);
|
|
19
|
-
}
|
|
20
|
-
});
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|