From bb662ac70c7946c74a929874cf0195aa8bb357c8 Mon Sep 17 00:00:00 2001 From: bigben-7 Date: Thu, 23 Jul 2026 20:38:43 +0100 Subject: [PATCH 1/4] fix(frontend): set real app metadata (was Create Next App default) Replace the scaffold title/description with GistPin's real metadata, add a favicon (the header logo) and basic OpenGraph tags. Fixes #870 Co-Authored-By: Claude Opus 4.8 --- Frontend/src/app/layout.tsx | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) 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({ From 0ec2e9d6772c1f0dc3bcdae56f2929e6665a3cd6 Mon Sep 17 00:00:00 2001 From: bigben-7 Date: Thu, 23 Jul 2026 20:38:43 +0100 Subject: [PATCH 2/4] fix(backend): match the canonical gist_posted Soroban event name The event filter loosely accepted both 'post_gist' and 'gist_posted' (and even an empty name). Pin it to the single canonical event name emitted by the contract via a shared GIST_POSTED_EVENT constant, documented against the contract. Fixes #871 Co-Authored-By: Claude Opus 4.8 --- Backend/src/soroban/soroban.service.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) 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; } From 864d014b54b9a836f6e6af53408cea2e628baac9 Mon Sep 17 00:00:00 2001 From: bigben-7 Date: Thu, 23 Jul 2026 20:38:43 +0100 Subject: [PATCH 3/4] fix(frontend): resolve half-wired landing page Remove the commented-out Hero/HowItWorks/CTA imports and dead code from page.tsx so it matches what actually renders (Features + Footer), and drop the import + usage of the non-existent grid-pattern component from CTA.tsx so the file is internally consistent. Fixes #872 Co-Authored-By: Claude Opus 4.8 --- Frontend/src/app/page.tsx | 16 ++-------------- Frontend/src/components/landing/CTA.tsx | 13 ------------- 2 files changed, 2 insertions(+), 27 deletions(-) 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]" > - -
From 641572beec9d017adee2869a3fd1011819e0beff Mon Sep 17 00:00:00 2001 From: bigben-7 Date: Thu, 23 Jul 2026 20:38:43 +0100 Subject: [PATCH 4/4] feat(contracts): emit canonical gist_posted event on post_gist MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit post_gist now publishes a single 'gist_posted' event (topic = event name, data = the full Gist record) so the backend indexer can reconcile on-chain state. Documents the event schema in the contract README and adds a test asserting the event is emitted. Note: compile-checked by inspection only — cargo/soroban toolchain is not available in this environment. Fixes #873 Co-Authored-By: Claude Opus 4.8 --- contracts/README.md | 11 +++++++++++ contracts/src/lib.rs | 26 +++++++++++++++++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) 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); + } }