diff --git a/Backend/src/soroban/soroban.service.ts b/Backend/src/soroban/soroban.service.ts index c7d1897c..ffdcec09 100644 --- a/Backend/src/soroban/soroban.service.ts +++ b/Backend/src/soroban/soroban.service.ts @@ -14,6 +14,13 @@ import { } from '@stellar/stellar-sdk'; import { randomBytes } from 'crypto'; +/** + * Canonical event name emitted by the GistRegistry Soroban contract on a new + * gist. Must match the symbol published in contracts/src/lib.rs (see + * contracts/README.md "Events"). + */ +const GIST_POSTED_EVENT = 'gist_posted'; + export interface PostGistResult { gistId: string; txHash: string; @@ -331,8 +338,10 @@ export class SorobanService { return null; } + // Canonical event name emitted by the GistRegistry contract (see contracts/lib.rs + // and contracts/README.md "Events"). Keep this in sync with the contract. const eventName = typeof topic[0] === 'string' ? topic[0] : ''; - if (eventName && eventName !== 'post_gist' && eventName !== 'gist_posted') { + if (eventName !== GIST_POSTED_EVENT) { return null; } diff --git a/Frontend/src/app/layout.tsx b/Frontend/src/app/layout.tsx index 80a5d31f..f0fee4e4 100644 --- a/Frontend/src/app/layout.tsx +++ b/Frontend/src/app/layout.tsx @@ -14,8 +14,18 @@ const geistMono = Geist_Mono({ }); export const metadata: Metadata = { - title: "Create Next App", - description: "Generated by create next app", + title: "GistPin — Location-Aware Micro-Messaging on Stellar", + description: + "Post short, anonymous, geotagged messages (\"gists\") anchored to real-world coordinates, and discover hyperlocal tips, alerts, and conversations happening around you.", + icons: { + icon: "/gistPin-header-logo.png", + }, + openGraph: { + title: "GistPin — Location-Aware Micro-Messaging on Stellar", + description: + "Anonymous, hyperlocal messaging anchored on the Stellar network.", + type: "website", + }, }; export default function RootLayout({ diff --git a/Frontend/src/app/page.tsx b/Frontend/src/app/page.tsx index c7f09d15..f995aacd 100644 --- a/Frontend/src/app/page.tsx +++ b/Frontend/src/app/page.tsx @@ -1,23 +1,11 @@ -// import Hero from "@/components/landing/Hero"; -// import HowItWorks from "@/components/landing/HowItWorks"; -import {Features} from "@/components/landing/Features"; -// import CTA from "@/components/landing/CTA"; +import { Features } from "@/components/landing/Features"; import Footer from "@/components/landing/Footer"; + export default function LandingPage() { return (
- {/* */} - {/* */} - {/* */}
); } -// import React from "react"; - -// const page = () => { -// return
page
; -// }; - -// export default page; diff --git a/Frontend/src/components/landing/CTA.tsx b/Frontend/src/components/landing/CTA.tsx index 66df3ee5..62f77461 100644 --- a/Frontend/src/components/landing/CTA.tsx +++ b/Frontend/src/components/landing/CTA.tsx @@ -6,8 +6,6 @@ import { useGSAP } from '@gsap/react'; import gsap from 'gsap'; import { ScrollTrigger } from 'gsap/ScrollTrigger'; import { useRef } from 'react'; -import { GridPattern } from '@/components/ui/grid-pattern'; -import { cn } from '@/lib/utils'; gsap.registerPlugin(ScrollTrigger); @@ -37,17 +35,6 @@ export default function CTA() { ref={containerRef} className="relative py-24 md:py-32 overflow-hidden bg-[#030303]" > - -
diff --git a/contracts/README.md b/contracts/README.md index 9e21bb37..2131c543 100644 --- a/contracts/README.md +++ b/contracts/README.md @@ -54,6 +54,17 @@ Each gist record tracks: | `get_gist(gist_id)` | Retrieve a gist record by id | | `list_gists_by_cell(location_cell, cursor, limit)` | Paginated list of gists within a location cell | +### Events + +`post_gist` publishes a single canonical event that off-chain indexers +(the backend) subscribe to. **Keep this in sync with the backend's +`GIST_POSTED_EVENT` constant.** + +| Field | Value | +|---|---| +| Topic (event name) | `gist_posted` (a `Symbol`) | +| Data payload | the full `Gist` record (`gist_id`, `author`, `location_cell`, `content_hash`, `created_at`) | + --- ## Planned Contracts diff --git a/contracts/src/lib.rs b/contracts/src/lib.rs index fff45df8..75166b07 100644 --- a/contracts/src/lib.rs +++ b/contracts/src/lib.rs @@ -1,5 +1,7 @@ #![no_std] -use soroban_sdk::{contract, contractimpl, contracttype, symbol_short, Address, Env, String, Vec}; +use soroban_sdk::{ + contract, contractimpl, contracttype, symbol_short, Address, Env, String, Symbol, Vec, +}; // --------------------------------------------------------------------------- // Data types @@ -50,6 +52,12 @@ impl GistRegistry { env.storage().persistent().set(&gist_id, &gist); env.storage().instance().set(&GIST_COUNT, &gist_id); + // Emit the canonical `gist_posted` event so off-chain indexers can + // reconcile on-chain state. The single topic is the event name; the + // data payload is the full Gist record. + let topic = Symbol::new(&env, "gist_posted"); + env.events().publish((topic,), gist); + gist_id } @@ -136,4 +144,20 @@ mod tests { let results = client.list_gists_by_cell(&cell_a, &0, &10); assert_eq!(results.len(), 2); } + + #[test] + fn test_post_gist_emits_event() { + let env = Env::default(); + let contract_id = env.register(GistRegistry, ()); + let client = GistRegistryClient::new(&env, &contract_id); + + let location = String::from_str(&env, "r3gx"); + let hash = String::from_str(&env, "QmEvent"); + + client.post_gist(&None, &location, &hash); + + // Exactly one `gist_posted` event should have been published. + let events = env.events().all(); + assert_eq!(events.len(), 1); + } }