Skip to content

Commit 3377a06

Browse files
authored
Merge pull request #75 from krishnan05/main
Add per-page SEO metadata, OG tags, and MetaMask SDK web shim
2 parents 9eaff96 + 4b63c82 commit 3377a06

8 files changed

Lines changed: 257 additions & 4 deletions

File tree

next.config.mjs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import path from "path";
2+
13
/** @type {import('next').NextConfig} */
24
const nextConfig = {
35
output: 'export',
@@ -7,6 +9,12 @@ const nextConfig = {
79
},
810
webpack: (config) => {
911
config.resolve.fallback = { fs: false, net: false, tls: false };
12+
config.resolve.alias = {
13+
...(config.resolve.alias || {}),
14+
"@react-native-async-storage/async-storage": path.resolve(
15+
"./src/shims/asyncStorage.ts"
16+
),
17+
};
1018
return config;
1119
},
1220
};

src/app/[pool]/page.tsx

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,39 @@
1+
import type { Metadata } from "next";
12
import { Suspense } from "react";
23
import InteractionClient from "./InteractionClient";
34

5+
export const metadata: Metadata = {
6+
title: "Pool",
7+
description:
8+
"View pool details, pricing, and trade bull and bear positions on Fate Protocol with real-time oracle updates, liquidity metrics, and transparent on-chain execution.",
9+
alternates: {
10+
// TODO: Replace with a dynamic per-pool canonical URL once generateMetadata() is implemented.
11+
canonical: "/pool",
12+
},
13+
openGraph: {
14+
title: "Pool",
15+
description:
16+
"View pool details, pricing, and trade bull and bear positions on Fate Protocol with real-time oracle updates, liquidity metrics, and transparent on-chain execution.",
17+
// TODO: Replace with a dynamic per-pool URL once generateMetadata() is implemented.
18+
url: "/pool",
19+
type: "website",
20+
images: [
21+
{
22+
url: "https://evm.fate.stability.nexus/og-image.png",
23+
width: 1200,
24+
height: 630,
25+
alt: "Fate Protocol - Decentralized Prediction Markets",
26+
},
27+
],
28+
},
29+
twitter: {
30+
title: "Pool",
31+
description:
32+
"View pool details, pricing, and trade bull and bear positions on Fate Protocol with real-time oracle updates, liquidity metrics, and transparent on-chain execution.",
33+
images: ["https://evm.fate.stability.nexus/og-image.png"],
34+
},
35+
};
36+
437
export async function generateStaticParams() {
538
return [
639
{ pool: "pool" }

src/app/createPool/layout.tsx

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import type { Metadata } from "next";
2+
import type { ReactNode } from "react";
3+
4+
export const metadata: Metadata = {
5+
title: "Create Pool",
6+
description:
7+
"Create a new prediction pool with custom parameters, asset selection, and oracle configuration, then deploy on supported chains with transparent fees and on-chain settlement.",
8+
alternates: {
9+
canonical: "/createPool",
10+
},
11+
openGraph: {
12+
title: "Create Pool",
13+
description:
14+
"Create a new prediction pool with custom parameters, asset selection, and oracle configuration, then deploy on supported chains with transparent fees and on-chain settlement.",
15+
url: "/createPool",
16+
type: "website",
17+
images: [
18+
{
19+
url: "https://evm.fate.stability.nexus/og-image.png",
20+
width: 1200,
21+
height: 630,
22+
alt: "Fate Protocol - Decentralized Prediction Markets",
23+
},
24+
],
25+
},
26+
twitter: {
27+
title: "Create Pool",
28+
description:
29+
"Create a new prediction pool with custom parameters, asset selection, and oracle configuration, then deploy on supported chains with transparent fees and on-chain settlement.",
30+
images: ["https://evm.fate.stability.nexus/og-image.png"],
31+
},
32+
};
33+
34+
export default function CreatePoolLayout({
35+
children,
36+
}: {
37+
children: ReactNode;
38+
}) {
39+
return children;
40+
}

src/app/explorePools/layout.tsx

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import type { Metadata } from "next";
2+
import type { ReactNode } from "react";
3+
4+
export const metadata: Metadata = {
5+
title: "Explore Pools",
6+
description:
7+
"Browse prediction pools across supported chains, compare bull and bear markets, and discover real-time opportunities with oracle pricing, liquidity, and performance insights.",
8+
alternates: {
9+
canonical: "/explorePools",
10+
},
11+
openGraph: {
12+
title: "Explore Pools",
13+
description:
14+
"Browse prediction pools across supported chains, compare bull and bear markets, and discover real-time opportunities with oracle pricing, liquidity, and performance insights.",
15+
url: "/explorePools",
16+
type: "website",
17+
images: [
18+
{
19+
url: "https://evm.fate.stability.nexus/og-image.png",
20+
width: 1200,
21+
height: 630,
22+
alt: "Fate Protocol - Decentralized Prediction Markets",
23+
},
24+
],
25+
},
26+
twitter: {
27+
title: "Explore Pools",
28+
description:
29+
"Browse prediction pools across supported chains, compare bull and bear markets, and discover real-time opportunities with oracle pricing, liquidity, and performance insights.",
30+
images: ["https://evm.fate.stability.nexus/og-image.png"],
31+
},
32+
};
33+
34+
export default function ExplorePoolsLayout({
35+
children,
36+
}: {
37+
children: ReactNode;
38+
}) {
39+
return children;
40+
}

src/app/layout.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@ const geistMono = Geist_Mono({
1818
});
1919

2020
export const metadata: Metadata = {
21-
title: "Fate Protocol | Decentralized Prediction Markets & DeFi Trading",
21+
title: {
22+
default: "Fate Protocol",
23+
template: "%s | Fate Protocol",
24+
},
2225
description:
2326
"Trade prediction markets on Fate Protocol - the decentralized platform for perpetual prediction pools. Buy bullCoins and bearCoins to predict price movements across multiple blockchain networks. Advanced DeFi trading with real-time price feeds and automated market making.",
2427
keywords: [
@@ -48,9 +51,6 @@ export const metadata: Metadata = {
4851
telephone: false,
4952
},
5053
metadataBase: new URL("https://evm.fate.stability.nexus"),
51-
alternates: {
52-
canonical: "/",
53-
},
5454
openGraph: {
5555
title: "Fate Protocol | Decentralized Prediction Markets",
5656
description: "Trade prediction markets on Fate Protocol - the decentralized platform for perpetual prediction pools. Buy bullCoins and bearCoins to predict price movements.",

src/app/page.tsx

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,37 @@
1+
import type { Metadata } from "next";
12
import AboutSection from "@/components/Home/About";
23
import Hero from "@/components/Home/Hero";
34

5+
export const metadata: Metadata = {
6+
title: "Decentralized Prediction Markets & DeFi Trading",
7+
description:
8+
"Decentralized perpetual prediction pools for trading price movements across multiple blockchain networks with real-time oracle pricing, automated market making, and transparent on-chain execution.",
9+
alternates: {
10+
canonical: "/",
11+
},
12+
openGraph: {
13+
title: "Decentralized Prediction Markets & DeFi Trading",
14+
description:
15+
"Decentralized perpetual prediction pools for trading price movements across multiple blockchain networks with real-time oracle pricing, automated market making, and transparent on-chain execution.",
16+
url: "/",
17+
type: "website",
18+
images: [
19+
{
20+
url: "https://evm.fate.stability.nexus/og-image.png",
21+
width: 1200,
22+
height: 630,
23+
alt: "Fate Protocol - Decentralized Prediction Markets",
24+
},
25+
],
26+
},
27+
twitter: {
28+
title: "Decentralized Prediction Markets & DeFi Trading",
29+
description:
30+
"Decentralized perpetual prediction pools for trading price movements across multiple blockchain networks with real-time oracle pricing, automated market making, and transparent on-chain execution.",
31+
images: ["https://evm.fate.stability.nexus/og-image.png"],
32+
},
33+
};
34+
435
export default function Home() {
536
return (
637
<>

src/app/portfolio/layout.tsx

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import type { Metadata } from "next";
2+
import type { ReactNode } from "react";
3+
4+
export const metadata: Metadata = {
5+
title: "Portfolio",
6+
description:
7+
"Track your prediction positions, performance, and portfolio analytics across supported chains with real-time pricing, P&L, and historical trade insights.",
8+
alternates: {
9+
canonical: "/portfolio",
10+
},
11+
openGraph: {
12+
title: "Portfolio",
13+
description:
14+
"Track your prediction positions, performance, and portfolio analytics across supported chains with real-time pricing, P&L, and historical trade insights.",
15+
url: "/portfolio",
16+
type: "website",
17+
images: [
18+
{
19+
url: "https://evm.fate.stability.nexus/og-image.png",
20+
width: 1200,
21+
height: 630,
22+
alt: "Fate Protocol - Decentralized Prediction Markets",
23+
},
24+
],
25+
},
26+
twitter: {
27+
title: "Portfolio",
28+
description:
29+
"Track your prediction positions, performance, and portfolio analytics across supported chains with real-time pricing, P&L, and historical trade insights.",
30+
images: ["https://evm.fate.stability.nexus/og-image.png"],
31+
},
32+
};
33+
34+
export default function PortfolioLayout({
35+
children,
36+
}: {
37+
children: ReactNode;
38+
}) {
39+
return children;
40+
}

src/shims/asyncStorage.ts

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
type AsyncStorageLike = {
2+
getItem: (key: string) => Promise<string | null>;
3+
setItem: (key: string, value: string) => Promise<void>;
4+
removeItem: (key: string) => Promise<void>;
5+
};
6+
7+
const memoryStore = new Map<string, string>();
8+
9+
const getStorage = () => {
10+
try {
11+
if (typeof window !== "undefined" && window.localStorage) {
12+
return window.localStorage;
13+
}
14+
} catch {
15+
return null;
16+
}
17+
return null;
18+
};
19+
20+
const AsyncStorage: AsyncStorageLike = {
21+
async getItem(key) {
22+
if (memoryStore.has(key)) {
23+
return memoryStore.get(key) ?? null;
24+
}
25+
const storage = getStorage();
26+
if (storage) {
27+
try {
28+
return storage.getItem(key);
29+
} catch {
30+
return memoryStore.get(key) ?? null;
31+
}
32+
}
33+
return memoryStore.get(key) ?? null;
34+
},
35+
async setItem(key, value) {
36+
const storage = getStorage();
37+
if (storage) {
38+
try {
39+
storage.setItem(key, value);
40+
return;
41+
} catch {
42+
// Fall through to memory store
43+
}
44+
}
45+
memoryStore.set(key, value);
46+
},
47+
async removeItem(key) {
48+
memoryStore.delete(key);
49+
const storage = getStorage();
50+
if (storage) {
51+
try {
52+
storage.removeItem(key);
53+
return;
54+
} catch {
55+
// Fall through to memory store
56+
}
57+
}
58+
},
59+
};
60+
61+
export default AsyncStorage;

0 commit comments

Comments
 (0)