Skip to content
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
11 changes: 10 additions & 1 deletion Backend/src/soroban/soroban.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}

Expand Down
14 changes: 12 additions & 2 deletions Frontend/src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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({
Expand Down
16 changes: 2 additions & 14 deletions Frontend/src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<div className="bg-[#111827] text-gray-200">
{/* <Hero /> */}
{/* <HowItWorks /> */}
<Features />
{/* <CTA /> */}
<Footer />
</div>
);
}
// import React from "react";

// const page = () => {
// return <div>page</div>;
// };

// export default page;
13 changes: 0 additions & 13 deletions Frontend/src/components/landing/CTA.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -37,17 +35,6 @@ export default function CTA() {
ref={containerRef}
className="relative py-24 md:py-32 overflow-hidden bg-[#030303]"
>
<GridPattern
width={30}
height={30}
x={-1}
y={-1}
className={cn(
'fill-purple-500/10 stroke-purple-500/20',
'[mask-image:radial-gradient(500px_circle_at_center,white,transparent)]'
)}
/>

<div className="max-w-3xl px-4 mx-auto text-center glowing-card-container">
<div className="glow-layer"></div>

Expand Down
11 changes: 11 additions & 0 deletions contracts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
26 changes: 25 additions & 1 deletion contracts/src/lib.rs
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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
}

Expand Down Expand Up @@ -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);
}
}
Loading