Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

accounts + native transfers #1210

Merged
merged 61 commits into from
Nov 26, 2024
Merged
Show file tree
Hide file tree
Changes from 57 commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
2daf668
start new filter impl
kyscott18 Nov 1, 2024
35d5d00
debug rpc types
kyscott18 Oct 30, 2024
3cfd157
withLog
kyscott18 Oct 30, 2024
f987047
add debug helper functions
kyscott18 Nov 1, 2024
cc5a3f6
syncTrace in sync-historical added with filter matching
khaidarkairbek Nov 2, 2024
1a61820
syncTrace filtering modified, blockwise processing added
khaidarkairbek Nov 3, 2024
d15808d
sync-realtime: added tx/transfer factories
khaidarkairbek Nov 3, 2024
600304d
sync: fragments and encoding for transaction/transfer filters
khaidarkairbek Nov 3, 2024
b318ead
sync-realtime: transaction/trasfer filter added
khaidarkairbek Nov 3, 2024
0ab76da
sync-realtime: handleBlock is modified for new filters
khaidarkairbek Nov 3, 2024
57bfc82
sync-realtime: fetchBlockEventData changed to debug and new filters f…
khaidarkairbek Nov 3, 2024
3f3f82d
update historical sync
kyscott18 Nov 4, 2024
06b9060
build checkpoint for traces
kyscott18 Nov 4, 2024
3d944f0
record failed traces
kyscott18 Nov 4, 2024
479be95
implement insert traces db method
kyscott18 Nov 4, 2024
6681242
.
kyscott18 Nov 5, 2024
41412e6
cleanup realtime
kyscott18 Nov 5, 2024
edbbea0
corrections: minor changes
khaidarkairbek Nov 8, 2024
51e87df
sync-historical: traceCache added
khaidarkairbek Nov 8, 2024
a7052f3
sync-realtime: trace traversal added in fetchBlockEventData and handl…
kyscott18 Nov 10, 2024
e7dcfbb
sync: buildEvents and decodeEvents modfied
khaidarkairbek Nov 9, 2024
5640a6a
fix debug type
kyscott18 Nov 10, 2024
537f795
Merge branch 'v0.8' into accounts
kyscott18 Nov 11, 2024
5293137
new filter types
kyscott18 Nov 11, 2024
abaeae8
Merge branch 'accounts' of https://github.com/0xOlias/ponder into acc…
kyscott18 Nov 11, 2024
735d587
decodeEvents + buildEvents
kyscott18 Nov 11, 2024
e266901
Merge branch 'v0.8' into accounts
kyscott18 Nov 13, 2024
269c1d4
sync-historical: transaction filter
khaidarkairbek Nov 14, 2024
fa48e6a
getEvents
kyscott18 Nov 16, 2024
5e23f17
Merge branch 'accounts' of https://github.com/0xOlias/ponder into acc…
kyscott18 Nov 16, 2024
a9c9d69
account sources
kyscott18 Nov 16, 2024
ad82daa
accounts config
kyscott18 Nov 16, 2024
c600555
sync-realtime: fetchBlockEventData and handleBlock modified to handle…
khaidarkairbek Nov 17, 2024
9a60456
cleanup realtime logs
kyscott18 Nov 18, 2024
f5ba161
minor fix
khaidarkairbek Nov 18, 2024
b4ca245
build accounts
kyscott18 Nov 18, 2024
6f29077
start historical sync tests
kyscott18 Nov 18, 2024
a85ae63
update sync tests
kyscott18 Nov 19, 2024
b12eacc
sync: handle factory address
khaidarkairbek Nov 19, 2024
f0fb96f
cleanup
kyscott18 Nov 19, 2024
c9f4ed9
Merge branch 'accounts' of https://github.com/0xOlias/ponder into acc…
kyscott18 Nov 19, 2024
c9a40aa
fix transport tests
kyscott18 Nov 19, 2024
3b4cd1f
realtime sync tests
kyscott18 Nov 19, 2024
04c934e
fix typecheck
kyscott18 Nov 19, 2024
0ca8af0
account specific test
kyscott18 Nov 20, 2024
0c97911
accounts example
kyscott18 Nov 20, 2024
7c2cfa4
fix virtual types
kyscott18 Nov 20, 2024
587e3de
cleanup sync
kyscott18 Nov 20, 2024
ecb3482
note
kyscott18 Nov 20, 2024
c9f5e1a
transaction includeReverted
kyscott18 Nov 20, 2024
aae6b18
cleanup
kyscott18 Nov 20, 2024
5bef6b0
fix: config
kyscott18 Nov 22, 2024
ec42276
sync: factory filter
khaidarkairbek Nov 22, 2024
017466c
sync: factory filter cont.
khaidarkairbek Nov 22, 2024
597a65f
set
kyscott18 Nov 23, 2024
74c0246
feature-accounts
kyscott18 Nov 23, 2024
36631a7
cleanup
kyscott18 Nov 23, 2024
8d6b189
trace type
kyscott18 Nov 25, 2024
731d2bb
nits
kyscott18 Nov 25, 2024
dc78175
fix
kyscott18 Nov 26, 2024
1e249e2
cleanup
kyscott18 Nov 26, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .changeset/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"fixed": [["@ponder/core", "create-ponder", "eslint-config-ponder"]],
"ignore": [
"@ponder/common",
"ponder-examples-accounts",
"ponder-examples-feature-blocks",
"ponder-examples-feature-factory",
"ponder-examples-feature-filter",
Expand Down
5 changes: 5 additions & 0 deletions examples/feature-accounts/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Mainnet RPC URL used for fetching blockchain data. Alchemy is recommended.
PONDER_RPC_URL_1=https://eth-mainnet.g.alchemy.com/v2/...

# (Optional) Postgres database URL. If not provided, SQLite will be used.
DATABASE_URL=
3 changes: 3 additions & 0 deletions examples/feature-accounts/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "ponder"
}
18 changes: 18 additions & 0 deletions examples/feature-accounts/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Dependencies
/node_modules

# Debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*

# Misc
.DS_Store

# Env files
.env*.local

# Ponder
/generated/
/.ponder/
27 changes: 27 additions & 0 deletions examples/feature-accounts/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"name": "ponder-examples-feature-accounts",
"private": true,
"type": "module",
"scripts": {
"dev": "ponder dev",
"start": "ponder start",
"codegen": "ponder codegen",
"serve": "ponder serve",
"lint": "eslint .",
"typecheck": "tsc"
},
"dependencies": {
"@ponder/core": "workspace:*",
"hono": "^4.5.0",
"viem": "^2.21.3"
},
"devDependencies": {
"@types/node": "^20.10.0",
"eslint": "^8.54.0",
"eslint-config-ponder": "workspace:*",
"typescript": "^5.3.2"
},
"engines": {
"node": ">=18.14"
}
}
27 changes: 27 additions & 0 deletions examples/feature-accounts/ponder-env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// This file enables type checking and editor autocomplete for this Ponder project.
// After upgrading, you may find that changes have been made to this file.
// If this happens, please commit the changes. Do not manually edit this file.
// See https://ponder.sh/docs/getting-started/installation#typescript for more information.

declare module "@/generated" {
import type { Virtual } from "@ponder/core";

type config = typeof import("./ponder.config.ts").default;
type schema = typeof import("./ponder.schema.ts");

export const ponder: Virtual.Registry<config, schema>;

export type EventNames = Virtual.EventNames<config>;
export type Event<name extends EventNames = EventNames> = Virtual.Event<
config,
name
>;
export type Context<name extends EventNames = EventNames> = Virtual.Context<
config,
schema,
name
>;
export type ApiContext = Virtual.ApiContext<schema>;
export type IndexingFunctionArgs<name extends EventNames = EventNames> =
Virtual.IndexingFunctionArgs<config, schema, name>;
}
22 changes: 22 additions & 0 deletions examples/feature-accounts/ponder.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { createConfig } from "@ponder/core";
import { http, createPublicClient } from "viem";

const latestBlockMainnet = await createPublicClient({
transport: http(process.env.PONDER_RPC_URL_1),
}).getBlock();

export default createConfig({
networks: {
mainnet: {
chainId: 1,
transport: http(process.env.PONDER_RPC_URL_1),
},
},
accounts: {
BeaverBuilder: {
network: "mainnet",
startBlock: Number(latestBlockMainnet.number) - 100,
address: "0x95222290DD7278Aa3Ddd389Cc1E1d165CC4BAfe5",
},
},
});
7 changes: 7 additions & 0 deletions examples/feature-accounts/ponder.schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { onchainTable } from "@ponder/core";

export const transactionEvents = onchainTable("transaction_events", (t) => ({
to: t.hex().primaryKey(),
value: t.bigint().notNull(),
data: t.hex().notNull(),
}));
22 changes: 22 additions & 0 deletions examples/feature-accounts/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { ponder } from "@/generated";
import * as schema from "../ponder.schema";

ponder.on("BeaverBuilder:transaction:from", async ({ event, context }) => {
if (event.transaction.to === null) return;

await context.db
.insert(schema.transactionEvents)
.values({
to: event.transaction.to,
value: event.transaction.value,
data: event.transaction.input,
})
.onConflictDoUpdate((row) => ({
value: row.value + event.transaction.value,
data: event.transaction.input,
}));
});

ponder.on("BeaverBuilder:transfer:to", async ({ event }) => {
console.log("sent", event.transfer);
});
26 changes: 26 additions & 0 deletions examples/feature-accounts/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"compilerOptions": {
// Type checking
"strict": true,
"noUncheckedIndexedAccess": true,

// Interop constraints
"verbatimModuleSyntax": false,
"esModuleInterop": true,
"isolatedModules": true,
"allowSyntheticDefaultImports": true,
"resolveJsonModule": true,

// Language and environment
"moduleResolution": "bundler",
"module": "ESNext",
"noEmit": true,
"lib": ["ES2022"],
"target": "ES2022",

// Skip type checking for node modules
"skipLibCheck": true
},
"include": ["./**/*.ts"],
"exclude": ["node_modules"]
}
6 changes: 0 additions & 6 deletions packages/core/src/_test/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,3 @@ export const ACCOUNTS = [

// Named accounts
export const [ALICE, BOB] = ACCOUNTS;

// Deployed contract addresses.
export const CONTRACTS = {
erc20Address: "0x5fbdb2315678afecb367f032d93f642f64180aa3",
factoryAddress: "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512",
} as const;
53 changes: 25 additions & 28 deletions packages/core/src/_test/e2e/erc20/erc20.test.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
import path from "node:path";
import { ALICE, BOB } from "@/_test/constants.js";
import { ALICE } from "@/_test/constants.js";
import {
setupAnvil,
setupCommon,
setupIsolatedDatabase,
} from "@/_test/setup.js";
import { simulate } from "@/_test/simulate.js";
import { deployErc20, mintErc20 } from "@/_test/simulate.js";
import {
getFreePort,
postGraphql,
waitForIndexedBlock,
} from "@/_test/utils.js";
import { serve } from "@/bin/commands/serve.js";
import { start } from "@/bin/commands/start.js";
import { range } from "@/utils/range.js";
import { rimrafSync } from "rimraf";
import { zeroAddress } from "viem";
import { parseEther, zeroAddress } from "viem";
import { beforeEach, describe, expect, test } from "vitest";

const rootDir = path.join(".", "src", "_test", "e2e", "erc20");
Expand All @@ -35,7 +34,7 @@ const cliOptions = {
logFormat: "pretty",
};

test("erc20", async (context) => {
test("erc20", async () => {
const port = await getFreePort();

const cleanup = await start({
Expand All @@ -46,12 +45,16 @@ test("erc20", async (context) => {
},
});

await simulate({
erc20Address: context.erc20.address,
factoryAddress: context.factory.address,
const { address } = await deployErc20({ sender: ALICE });

await mintErc20({
erc20: address,
to: ALICE,
amount: parseEther("1"),
sender: ALICE,
});

await waitForIndexedBlock(port, "mainnet", 8);
await waitForIndexedBlock(port, "mainnet", 2);

const response = await postGraphql(
port,
Expand All @@ -67,19 +70,16 @@ test("erc20", async (context) => {

expect(response.status).toBe(200);
const body = (await response.json()) as any;

expect(body.errors).toBe(undefined);
const accounts = body.data.accounts.items;
expect(accounts[0]).toMatchObject({
address: zeroAddress,
balance: (-2 * 10 ** 18).toString(),
balance: (-1 * 10 ** 18).toString(),
});
expect(accounts[1]).toMatchObject({
address: BOB.toLowerCase(),
balance: (2 * 10 ** 18).toString(),
});
expect(accounts[2]).toMatchObject({
address: ALICE.toLowerCase(),
balance: "0",
balance: (10 ** 18).toString(),
});

await cleanup();
Expand All @@ -89,7 +89,7 @@ const isPglite = !!process.env.DATABASE_URL;

// Fix this once it's easier to have per-command kill functions in Ponder.ts.
describe.skipIf(isPglite)("postgres database", () => {
test.todo("ponder serve", async (context) => {
test.todo("ponder serve", async () => {
const startPort = await getFreePort();

const cleanupStart = await start({
Expand All @@ -100,13 +100,14 @@ describe.skipIf(isPglite)("postgres database", () => {
},
});

for (const _ in range(0, 3)) {
await simulate({
erc20Address: context.erc20.address,
factoryAddress: context.factory.address,
});
}
const { address } = await deployErc20({ sender: ALICE });

await mintErc20({
erc20: address,
to: ALICE,
amount: parseEther("1"),
sender: ALICE,
});
const servePort = await getFreePort();

const cleanupServe = await serve({
Expand Down Expand Up @@ -137,15 +138,11 @@ describe.skipIf(isPglite)("postgres database", () => {
expect(accounts).toHaveLength(3);
expect(accounts[0]).toMatchObject({
address: zeroAddress,
balance: (-4 * 10 ** 18).toString(),
balance: (-1 * 10 ** 18).toString(),
});
expect(accounts[1]).toMatchObject({
address: BOB.toLowerCase(),
balance: (4 * 10 ** 18).toString(),
});
expect(accounts[2]).toMatchObject({
address: ALICE.toLowerCase(),
balance: "0",
balance: (10 ** 18).toString(),
});

await cleanupServe();
Expand Down
8 changes: 1 addition & 7 deletions packages/core/src/_test/e2e/erc20/ponder.config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { http } from "viem";

import { createConfig } from "../../../config/config.js";
import { CONTRACTS } from "../../constants.js";
import { erc20ABI } from "../../generated.js";

const poolId = Number(process.env.VITEST_POOL_ID ?? 1);
Expand Down Expand Up @@ -29,11 +27,7 @@ export default createConfig({
Erc20: {
network: "mainnet",
abi: erc20ABI,
address: CONTRACTS.erc20Address,
filter: {
event:
"Transfer(address indexed from, address indexed to, uint256 amount)",
},
address: "0x5fbdb2315678afecb367f032d93f642f64180aa3",
},
},
});
33 changes: 27 additions & 6 deletions packages/core/src/_test/e2e/factory/factory.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import {
setupCommon,
setupIsolatedDatabase,
} from "@/_test/setup.js";
import { simulatePairSwap } from "@/_test/simulate.js";
import { deployFactory } from "@/_test/simulate.js";
import { createPair } from "@/_test/simulate.js";
import { swapPair } from "@/_test/simulate.js";
import {
getFreePort,
postGraphql,
Expand All @@ -32,7 +34,7 @@ const cliOptions = {
logFormat: "pretty",
};

test("factory", async (context) => {
test("factory", async () => {
const port = await getFreePort();

const cleanup = await start({
Expand All @@ -43,7 +45,20 @@ test("factory", async (context) => {
},
});

await waitForIndexedBlock(port, "mainnet", 5);
const { address } = await deployFactory({ sender: ALICE });
const { result: pair } = await createPair({
factory: address,
sender: ALICE,
});
await swapPair({
pair,
amount0Out: 1n,
amount1Out: 1n,
to: ALICE,
sender: ALICE,
});

await waitForIndexedBlock(port, "mainnet", 3);

let response = await postGraphql(
port,
Expand All @@ -69,12 +84,18 @@ test("factory", async (context) => {
id: expect.any(String),
from: ALICE.toLowerCase(),
to: ALICE.toLowerCase(),
pair: context.factory.pair.toLowerCase(),
pair,
});

await simulatePairSwap(context.factory.pair);
await swapPair({
pair,
amount0Out: 1n,
amount1Out: 1n,
to: ALICE,
sender: ALICE,
});

await waitForIndexedBlock(port, "mainnet", 6);
await waitForIndexedBlock(port, "mainnet", 4);

response = await postGraphql(
port,
Expand Down
Loading
Loading