Skip to content

Commit

Permalink
Merge branch 'ts-js' of github.com-ikem:ikemHood/chainevents-contract…
Browse files Browse the repository at this point in the history
…s into ts-js
  • Loading branch information
ikemHood committed Dec 1, 2024
2 parents 3cabc00 + e426af4 commit daabae6
Show file tree
Hide file tree
Showing 21 changed files with 672 additions and 34 deletions.
Binary file removed .DS_Store
Binary file not shown.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
target
.snfoundry_cache/
.snfoundry_cache/
.DS_Store
src/.DS_Store
58 changes: 37 additions & 21 deletions Scarb.lock
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ dependencies = [

[[package]]
name = "openzeppelin"
version = "0.15.0"
source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.15.0#f57642960f1c8cffafefb88bfff418eca8510634"
version = "0.17.0"
source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.17.0#bf5d02c25c989ccc24f3ab42ec649617d3f21289"
dependencies = [
"openzeppelin_access",
"openzeppelin_account",
"openzeppelin_finance",
"openzeppelin_governance",
"openzeppelin_introspection",
"openzeppelin_merkle_tree",
"openzeppelin_presets",
"openzeppelin_security",
"openzeppelin_token",
Expand All @@ -27,58 +29,72 @@ dependencies = [

[[package]]
name = "openzeppelin_access"
version = "0.15.0"
source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.15.0#f57642960f1c8cffafefb88bfff418eca8510634"
version = "0.17.0"
source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.17.0#bf5d02c25c989ccc24f3ab42ec649617d3f21289"
dependencies = [
"openzeppelin_introspection",
"openzeppelin_utils",
]

[[package]]
name = "openzeppelin_account"
version = "0.15.0"
source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.15.0#f57642960f1c8cffafefb88bfff418eca8510634"
version = "0.17.0"
source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.17.0#bf5d02c25c989ccc24f3ab42ec649617d3f21289"
dependencies = [
"openzeppelin_introspection",
"openzeppelin_token",
"openzeppelin_utils",
]

[[package]]
name = "openzeppelin_finance"
version = "0.17.0"
source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.17.0#bf5d02c25c989ccc24f3ab42ec649617d3f21289"
dependencies = [
"openzeppelin_access",
"openzeppelin_token",
]

[[package]]
name = "openzeppelin_governance"
version = "0.15.0"
source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.15.0#f57642960f1c8cffafefb88bfff418eca8510634"
version = "0.17.0"
source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.17.0#bf5d02c25c989ccc24f3ab42ec649617d3f21289"
dependencies = [
"openzeppelin_access",
"openzeppelin_introspection",
]

[[package]]
name = "openzeppelin_introspection"
version = "0.15.0"
source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.15.0#f57642960f1c8cffafefb88bfff418eca8510634"
version = "0.17.0"
source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.17.0#bf5d02c25c989ccc24f3ab42ec649617d3f21289"

[[package]]
name = "openzeppelin_merkle_tree"
version = "0.17.0"
source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.17.0#bf5d02c25c989ccc24f3ab42ec649617d3f21289"

[[package]]
name = "openzeppelin_presets"
version = "0.15.0"
source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.15.0#f57642960f1c8cffafefb88bfff418eca8510634"
version = "0.17.0"
source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.17.0#bf5d02c25c989ccc24f3ab42ec649617d3f21289"
dependencies = [
"openzeppelin_access",
"openzeppelin_account",
"openzeppelin_finance",
"openzeppelin_introspection",
"openzeppelin_token",
"openzeppelin_upgrades",
]

[[package]]
name = "openzeppelin_security"
version = "0.15.0"
source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.15.0#f57642960f1c8cffafefb88bfff418eca8510634"
version = "0.17.0"
source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.17.0#bf5d02c25c989ccc24f3ab42ec649617d3f21289"

[[package]]
name = "openzeppelin_token"
version = "0.15.0"
source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.15.0#f57642960f1c8cffafefb88bfff418eca8510634"
version = "0.17.0"
source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.17.0#bf5d02c25c989ccc24f3ab42ec649617d3f21289"
dependencies = [
"openzeppelin_account",
"openzeppelin_governance",
Expand All @@ -87,13 +103,13 @@ dependencies = [

[[package]]
name = "openzeppelin_upgrades"
version = "0.15.0"
source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.15.0#f57642960f1c8cffafefb88bfff418eca8510634"
version = "0.17.0"
source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.17.0#bf5d02c25c989ccc24f3ab42ec649617d3f21289"

[[package]]
name = "openzeppelin_utils"
version = "0.15.0"
source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.15.0#f57642960f1c8cffafefb88bfff418eca8510634"
version = "0.17.0"
source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.17.0#bf5d02c25c989ccc24f3ab42ec649617d3f21289"

[[package]]
name = "snforge_scarb_plugin"
Expand Down
2 changes: 1 addition & 1 deletion Scarb.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ edition = "2023_11"

[dependencies]
starknet = "2.8.2"
openzeppelin = { git = "https://github.com/OpenZeppelin/cairo-contracts.git", tag = "v0.15.0" }
openzeppelin = { git = "https://github.com/OpenZeppelin/cairo-contracts.git", tag = "v0.17.0" }

[dev-dependencies]
snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry", tag = "v0.31.0" }
Expand Down
7 changes: 7 additions & 0 deletions backend/config/events.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const events = {
NewEventAdded: "NewEventAdded", //replace with event identify
RegisteredForEvent: "RegisteredForEvent",
EventAttendanceMark: "EventAttendanceMark",
EndEventRegistration: "EndEventRegistration",
RSVPForEvent: "RSVPForEvent"
};
44 changes: 44 additions & 0 deletions backend/controllers/EventController.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,47 @@ export const viewByEventOwner = async (req, res) => {
return failure(res, err.message, [], 500);
}
};

export const fetchSingleEventDetails = async (req, res) => {
try {
const { event_id } = req.params;

const event = await Event.findByEventId(event_id);

if (!event) {
return failure(res, "Event not found", [], 404);
}

return success(res, "Event details fetched successfully", event, 200);
} catch (err) {
return failure(res, err.message, [], 500);
}
};

export const fetchEventRegistrationAttendeesForOneEvent = async (req, res) => {
try {
const { event_id } = req.params;
const { page = 1, limit = 10 } = req.query;

const event = await Event.findByEventId(event_id);

if (!event) {
return failure(res, "Event not found", [], 404);
}

const registrations = await Event.getRegisteredUsersWithPagination(
event_id,
page,
limit
);

return success(
res,
"Registered attendees fetched successfully",
registrations,
200
);
} catch (err) {
return failure(res, err.message, [], 500);
}
};
131 changes: 131 additions & 0 deletions backend/indexer/handlers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
import {
NewEventAdded,
RegisteredForEvent,
EventAttendanceMark,
EndEventRegistration,
RSVPForEvent
} from "./types";
import { FieldElement, v1alpha2 as starknet } from '@apibara/starknet';
import Event from "../models/Event.js";
import { uint256 } from 'starknet';
import { hexToAscii } from "../utils/tohexAscii.js";

export async function handleNewEventAdded(event: starknet.IEvent) {
const data = event.data!;

const eventDetails: NewEventAdded = {
name: hexToAscii(FieldElement.toHex(data[0]).toString()),
event_id: parseInt(uint256
.uint256ToBN({
low: FieldElement.toBigInt(data[1]),
high: FieldElement.toBigInt(data[2]),
})
.toString()),
location: hexToAscii(FieldElement.toHex(data[3]).toString()),
event_owner: FieldElement.toHex(data[4]).toString()
};

//Debugging purposes
console.log(eventDetails);

const eventExists = await Event.findByEventId(eventDetails.event_id);
if (eventExists) {
console.log("Event already exists");
return;
}
await Event.create(eventDetails);
}

export async function handleRegisteredForEvent(event: starknet.IEvent) {
const data = event.data!;

const registeredForEvent: RegisteredForEvent = {
event_id: parseInt(uint256
.uint256ToBN({
low: FieldElement.toBigInt(data[0]),
high: FieldElement.toBigInt(data[1]),
})
.toString()),
event_name: hexToAscii(FieldElement.toHex(data[2]).toString()),
user_address: FieldElement.toHex(data[3]).toString()
};

console.log(registeredForEvent);

const hasRegistered = await Event.isUserRegistered(registeredForEvent.event_id, registeredForEvent.user_address);
if (hasRegistered) {
console.log("User has already registered");
return;
}
await Event.registerUser(registeredForEvent.event_id, registeredForEvent.user_address);
}

export async function handleEventAttendanceMark(event: starknet.IEvent) {
const data = event.data!;

const eventAttendanceMark: EventAttendanceMark = {
event_id: parseInt(uint256
.uint256ToBN({
low: FieldElement.toBigInt(data[0]),
high: FieldElement.toBigInt(data[1]),
})
.toString()),
user_address: FieldElement.toHex(data[2]).toString()
};

console.log(eventAttendanceMark);

const hasMarkedAttendance = await Event.hasUserAttended(eventAttendanceMark.event_id, eventAttendanceMark.user_address);
if (hasMarkedAttendance) {
console.log("User has already marked attendance");
return;
}
await Event.markAttendance(eventAttendanceMark.event_id, eventAttendanceMark.user_address);
}

export async function handleEndEventRegistration(event: starknet.IEvent) {
const data = event.data!;

const endEventRegistration: EndEventRegistration = {
event_id: parseInt(uint256
.uint256ToBN({
low: FieldElement.toBigInt(data[0]),
high: FieldElement.toBigInt(data[1]),
})
.toString()),
event_name: hexToAscii(FieldElement.toHex(data[2]).toString()),
event_owner: FieldElement.toHex(data[3]).toString()
};

console.log(endEventRegistration);

const eventExists = await Event.findByEventId(endEventRegistration.event_id);
if (!eventExists) {
console.log("Event does not exist");
return;
}
await Event.endRegistration(endEventRegistration.event_id);
}

export async function handleRSVPForEvent(event: starknet.IEvent) {
const data = event.data!;

const rsvpForEvent: RSVPForEvent = {
event_id: parseInt(uint256
.uint256ToBN({
low: FieldElement.toBigInt(data[0]),
high: FieldElement.toBigInt(data[1]),
})
.toString()),
attendee_address: FieldElement.toHex(data[2]).toString()
};

console.log(rsvpForEvent);

const hasRSVPed = await Event.hasUserRSVPed(rsvpForEvent.event_id, rsvpForEvent.attendee_address);
if (hasRSVPed) {
console.log("User has already RSVPed");
return;
}
await Event.addRSVP(rsvpForEvent.event_id, rsvpForEvent.attendee_address);
}
69 changes: 69 additions & 0 deletions backend/indexer/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { StreamClient, v1alpha2 } from '@apibara/protocol';
import {
FieldElement,
Filter,
v1alpha2 as starknet,
StarkNetCursor,
} from '@apibara/starknet';
import { events } from '../config/events';
import {
handleNewEventAdded,
handleRegisteredForEvent,
handleEventAttendanceMark,
handleEndEventRegistration,
handleRSVPForEvent,
} from './handlers';

const client = new StreamClient({
url: process.env.DNA_CLIENT_URL!,
clientOptions: {
'grpc.max_receive_message_length': 100 * 1024 * 1024, // 100MB
},
token: process.env.DNA_TOKEN,
});

// Create filter combining all event handlers
const filter = Filter.create().withHeader({ weak: true });

// Map your events to handlers
const eventHandlers: Record<string, (event: starknet.IEvent) => Promise<void>> = {
[events.NewEventAdded]: handleNewEventAdded,
[events.RegisteredForEvent]: handleRegisteredForEvent,
[events.EventAttendanceMark]: handleEventAttendanceMark,
[events.EndEventRegistration]: handleEndEventRegistration,
[events.RSVPForEvent]: handleRSVPForEvent,
};

// Add all events to filter
Object.keys(eventHandlers).forEach((eventKey) => {
filter.addEvent((event) =>
event.withKeys([FieldElement.fromBigInt(BigInt(eventKey))])
);
});

// Start indexer function
export async function startIndexer() {
client.configure({
filter: filter.encode(),
batchSize: 1,
finality: v1alpha2.DataFinality.DATA_STATUS_FINALIZED,
cursor: StarkNetCursor.createWithBlockNumber(0),
});

for await (const message of client) {
if (message.message === 'data') {
const { data } = message.data!;
for (const item of data) {
const block = starknet.Block.decode(item);
for (const event of block.events) {
if (!event.event) continue;
const eventKey = FieldElement.toHex(event.event.keys![0]);
const handler = eventHandlers[eventKey];
if (handler) {
await handler(event.event);
}
}
}
}
}
}
Loading

0 comments on commit daabae6

Please sign in to comment.