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

feat: cache by metadigest #3

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Binary file modified .cache/cache.db
Binary file not shown.
2 changes: 1 addition & 1 deletion config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ contracts:
- event: ProxyCreation(address proxy, address masterCopy)
- event: ERC20WrapperDeployed(address indexed avatar, address indexed erc20Wrapper, uint8 circlesType)
- name: StandardTreasury
handler: src/event_handlers/hubV2.ts
handler: src/event_handlers/standardTreasury.ts
events:
- event: CreateVault(address indexed group, address indexed vault)
- event: GroupMintSingle(address indexed group, uint256 indexed id, uint256 value, bytes userData)
Expand Down
5 changes: 3 additions & 2 deletions schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ enum AvatarType {
Invite
RegisterGroup
RegisterOrganization
Unknown
}

type AvatarBalance {
Expand Down Expand Up @@ -94,8 +95,6 @@ type Avatar {
tokenId: String
# v2 wrapped token id
wrappedTokenId: String
# groups only
name: String
# IPFS CID of the avatar's profile
cidV0: String
# balances of all tokens
Expand All @@ -113,6 +112,8 @@ type Profile {
id: ID!
name: String!
description: String
# groups only
symbol: String
previewImageUrl: String
imageUrl: String
}
Expand Down
17 changes: 10 additions & 7 deletions src/cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const db = new sqlite3.Database(".cache/cache.db");

export class ProfileCache {
static async init() {
const cache = new ProfileCache("cache");
const cache = new ProfileCache("cache_v2");
await cache.createTableIfNotExists();
return cache;
}
Expand All @@ -21,6 +21,7 @@ export class ProfileCache {
const query = `
CREATE TABLE IF NOT EXISTS ${this.key} (
id TEXT PRIMARY KEY,
cidV0 TEXT,
data TEXT
)
`;
Expand All @@ -36,26 +37,28 @@ export class ProfileCache {
});
}

public read(id: string): Promise<Metadata | null> {
public read(id: string): Promise<{ cidV0: string; data: Metadata } | null> {
return new Promise((resolve, reject) => {
const query = `SELECT data FROM ${this.key} WHERE id = ?`;
const query = `SELECT data, cidV0 FROM ${this.key} WHERE id = ?`;
db.get(query, [id], (err, row: any) => {
if (err) {
console.error("Error executing query:", err);
reject(err);
} else {
resolve(row ? JSON.parse(row.data) : null);
resolve(
row ? { cidV0: row.cidV0, data: JSON.parse(row.data) } : null
);
}
});
});
}

public async add(id: string, metadata: Metadata) {
const query = `INSERT INTO ${this.key} (id, data) VALUES (?, ?)`;
public async add(id: string, cidV0: string, metadata: Metadata) {
const query = `INSERT INTO ${this.key} (id, cidV0, data) VALUES (?, ?, ?)`;
const data = JSON.stringify(metadata);

return new Promise<void>((resolve, reject) => {
db.run(query, [id, data], (err) => {
db.run(query, [id, cidV0, data], (err) => {
if (err) {
console.error("Error executing query:", err);
reject(err);
Expand Down
2 changes: 0 additions & 2 deletions src/event_handlers/hubV1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ Hub.OrganizationSignup.handler(async ({ event, context }) => {
logIndex: event.logIndex,
tokenId: undefined,
cidV0: undefined,
name: undefined,
transactionIndex: event.transaction.transactionIndex,
wrappedTokenId: undefined,
balance: 0n,
Expand Down Expand Up @@ -64,7 +63,6 @@ Hub.Signup.handler(async ({ event, context }) => {
logIndex: event.logIndex,
tokenId: event.params.token,
cidV0: undefined,
name: undefined,
transactionIndex: event.transaction.transactionIndex,
wrappedTokenId: undefined,
balance: avatarBalance?.balance || 0n,
Expand Down
216 changes: 99 additions & 117 deletions src/event_handlers/hubV2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,13 @@ import {
HubV2_TransferSingle_eventArgs,
HubV2_TransferBatch_eventArgs,
WrapperERC20Personal_Transfer_eventArgs,
StandardTreasury,
NameRegistry,
SafeAccount,
} from "generated";
import {
toBytes,
bytesToBigInt,
zeroAddress,
parseEther,
Address,
} from "viem";
import { toBytes, bytesToBigInt, zeroAddress, parseEther } from "viem";
import { incrementStats } from "../incrementStats";
import { TransferType_t } from "generated/src/db/Enums.gen";
import { getProfileMetadataFromIpfs, uint8ArrayToCidV0 } from "../utils";
import { getProfileMetadataFromIpfs } from "../utils";
import { Profile } from "../types";

function makeAvatarBalanceEntityId(avatarId: string, tokenId: string) {
Expand Down Expand Up @@ -89,7 +82,6 @@ HubV2.RegisterHuman.handler(async ({ event, context }) => {
logIndex: event.logIndex,
tokenId: bytesToBigInt(toBytes(event.params.avatar)).toString(),
cidV0: undefined,
name: undefined,
transactionIndex: event.transaction.transactionIndex,
wrappedTokenId: undefined,
balance: 0n,
Expand Down Expand Up @@ -141,7 +133,6 @@ HubV2.RegisterOrganization.handler(async ({ event, context }) => {
logIndex: event.logIndex,
tokenId: bytesToBigInt(toBytes(event.params.organization)).toString(),
cidV0: undefined,
name: event.params.name,
transactionIndex: event.transaction.transactionIndex,
wrappedTokenId: undefined,
balance: 0n,
Expand All @@ -153,33 +144,68 @@ HubV2.RegisterOrganization.handler(async ({ event, context }) => {
};

context.Avatar.set(avatarEntity);

context.Profile.set({
id: event.params.organization,
description: "",
previewImageUrl: "",
imageUrl: "",
name: event.params.name,
symbol: "",
});
await incrementStats(context, "signups");
});

HubV2.RegisterGroup.handler(async ({ event, context }) => {
const avatarEntity: Avatar = {
const avatar = await context.Avatar.get(event.params.group);
if (!avatar) {
const avatarEntity: Avatar = {
id: event.params.group,
avatarType: "RegisterGroup",
blockNumber: event.block.number,
timestamp: event.block.timestamp,
transactionHash: event.transaction.hash,
invitedBy: undefined,
version: 2,
logIndex: event.logIndex,
tokenId: bytesToBigInt(toBytes(event.params.group)).toString(),
cidV0: undefined,
transactionIndex: event.transaction.transactionIndex,
wrappedTokenId: undefined,
balance: 0n,
lastMint: undefined,
mintEndPeriod: undefined,
lastDemurrageUpdate: undefined,
trustedByN: 0,
profile_id: event.params.group,
};

context.Avatar.set(avatarEntity);
} else {
context.Avatar.set({
...avatar,
avatarType: "RegisterGroup",
blockNumber: event.block.number,
timestamp: event.block.timestamp,
transactionHash: event.transaction.hash,
transactionIndex: event.transaction.transactionIndex,
});
}

const profile = (await context.Profile.get(event.params.group)) || {
id: event.params.group,
avatarType: "RegisterGroup",
blockNumber: event.block.number,
timestamp: event.block.timestamp,
transactionHash: event.transaction.hash,
invitedBy: undefined,
version: 2,
logIndex: event.logIndex,
tokenId: bytesToBigInt(toBytes(event.params.group)).toString(),
cidV0: undefined,
name: event.params.name,
transactionIndex: event.transaction.transactionIndex,
wrappedTokenId: undefined,
balance: 0n,
lastMint: undefined,
mintEndPeriod: undefined,
lastDemurrageUpdate: undefined,
trustedByN: 0,
profile_id: event.params.group,
name: "name not found",
description: "",
previewImageUrl: "",
imageUrl: "",
};

context.Avatar.set(avatarEntity);
context.Profile.set({
...profile,
name: event.params.name,
symbol: event.params.symbol,
});

await incrementStats(context, "signups");
});

Expand All @@ -194,99 +220,56 @@ HubV2.PersonalMint.handler(async ({ event, context }) => {
}
});

StandardTreasury.CreateVault.handler(async ({ event, context }) => {
// TODO: Implement handler here
});

StandardTreasury.GroupMintSingle.handler(async ({ event, context }) => {
const avatar = await context.Avatar.get(event.params.group);
if (avatar) {
const balanceId = makeAvatarBalanceEntityId(
event.params.group,
event.params.id.toString()
);
const avatarBalance = await context.AvatarBalance.get(balanceId);
if (avatarBalance) {
context.AvatarBalance.set({
...avatarBalance,
balance: avatarBalance.balance + event.params.value,
});
} else {
context.AvatarBalance.set({
id: makeAvatarBalanceEntityId(
event.params.group,
event.params.id.toString()
),
token_id: event.params.id.toString(),
avatar_id: event.params.group,
balance: event.params.value,
inflationaryValue: 0n,
isWrapped: false,
lastCalculated: 0,
version: 2,
});
}
}
});

StandardTreasury.GroupMintBatch.handler(async ({ event, context }) => {
// TODO: Implement handler here
});

StandardTreasury.GroupRedeem.handler(async ({ event, context }) => {
// TODO: Implement handler here
});

StandardTreasury.GroupRedeemCollateralBurn.handler(
async ({ event, context }) => {
// TODO: Implement handler here
}
);

StandardTreasury.GroupRedeemCollateralReturn.handler(
async ({ event, context }) => {
// TODO: Implement handler here
}
);

// TODO: missing envent to redeeem from group

NameRegistry.UpdateMetadataDigest.handler(async ({ event, context }) => {
const avatar = await context.Avatar.get(event.params.avatar);
if (avatar) {
const cidV0Formatted = uint8ArrayToCidV0(
Uint8Array.from(
Buffer.from(
event.params.metadataDigest.slice(
2,
event.params.metadataDigest.length
),
"hex"
)
)
let profileMetadata: { cidV0: string; data: Profile | null } | null = null;
try {
profileMetadata = await getProfileMetadataFromIpfs(
event.params.metadataDigest
);
} catch (_) {}

let profileMetadata: Profile | null = null;
try {
profileMetadata = await getProfileMetadataFromIpfs(
cidV0Formatted,
avatar.id as Address
);
} catch (_) {}

context.Profile.set({
id: avatar.id,
name: profileMetadata?.name || "name not found",
description: profileMetadata?.description || "",
previewImageUrl: profileMetadata?.previewImageUrl || "",
imageUrl: profileMetadata?.imageUrl || "",
const avatar = await context.Avatar.get(event.params.avatar);
if (!avatar) {
// register group emits metadata event update before the register group event
context.Avatar.set({
id: event.params.avatar,
avatarType: "Unknown",
blockNumber: event.block.number,
timestamp: event.block.timestamp,
transactionHash: event.transaction.hash,
invitedBy: undefined,
version: 2,
logIndex: event.logIndex,
tokenId: bytesToBigInt(toBytes(event.params.avatar)).toString(),
cidV0: profileMetadata?.cidV0,
transactionIndex: event.transaction.transactionIndex,
wrappedTokenId: undefined,
balance: 0n,
lastMint: undefined,
mintEndPeriod: undefined,
lastDemurrageUpdate: undefined,
trustedByN: 0,
profile_id: event.params.avatar,
});

} else {
context.Avatar.set({
...avatar,
cidV0: cidV0Formatted,
cidV0: profileMetadata?.cidV0,
});
}

const currentProfile = (await context.Profile.get(event.params.avatar)) || {
id: event.params.avatar,
name: "name not found",
symbol: "",
description: "",
previewImageUrl: "",
imageUrl: "",
};
context.Profile.set({
...currentProfile,
...profileMetadata?.data,
});
});

// ###############
Expand Down Expand Up @@ -608,7 +591,6 @@ HubV2.Trust.handler(async ({ event, context }) => {
logIndex: event.logIndex,
tokenId: undefined,
cidV0: undefined,
name: undefined,
transactionIndex: event.transaction.transactionIndex,
wrappedTokenId: undefined,
balance: 0n,
Expand Down
Loading