Skip to content

Commit 1876f50

Browse files
committed
Finishing up project
1 parent 5590b69 commit 1876f50

File tree

20 files changed

+728
-664
lines changed

20 files changed

+728
-664
lines changed

frontend/next.config.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,18 @@ import type { NextConfig } from "next";
22

33
const nextConfig: NextConfig = {
44
/* config options here */
5-
env: {
6-
NEXT_PUBLIC_APP_NAME: process.env.NEXT_PUBLIC_APP_NAME,
7-
NEXT_PUBLIC_APPKIT_PROJECT_ID:
8-
process.env.NEXT_PUBLIC_APPKIT_PROJECT_ID,
5+
// env: {
6+
// NEXT_PUBLIC_APP_NAME: process.env.NEXT_PUBLIC_APP_NAME,
7+
// NEXT_PUBLIC_APPKIT_PROJECT_ID:
8+
// process.env.NEXT_PUBLIC_APPKIT_PROJECT_ID,
9+
// },
10+
images: {
11+
remotePatterns: [
12+
{
13+
protocol: "https",
14+
hostname: "**",
15+
},
16+
],
917
},
1018
};
1119

frontend/package.json

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,28 +9,28 @@
99
"lint": "next lint"
1010
},
1111
"dependencies": {
12-
"@farcaster/frame-sdk": "^0.0.31",
12+
"@farcaster/frame-sdk": "^0.0.34",
1313
"@polkadot-onboard/core": "^1.1.0",
1414
"@polkadot-onboard/injected-wallets": "^1.1.0",
1515
"@polkadot-onboard/react": "^1.1.0",
1616
"@polkadot-onboard/wallet-connect": "^1.1.0",
17-
"@polkadot/api": "^15.9.1",
18-
"@polkadot/util-crypto": "^13.4.3",
19-
"next": "15.2.1",
17+
"@polkadot/api": "^15.9.2",
18+
"@polkadot/util-crypto": "^13.4.4",
19+
"next": "15.3.0",
2020
"react": "^19.0.0",
2121
"react-dom": "^19.0.0",
2222
"react-hot-toast": "^2.5.2"
2323
},
2424
"devDependencies": {
2525
"@eslint/eslintrc": "^3",
26-
"@polkadot/typegen": "^15.9.1",
27-
"@tailwindcss/postcss": "^4",
28-
"@types/node": "^20",
29-
"@types/react": "^19",
26+
"@polkadot/typegen": "^15.9.2",
27+
"@tailwindcss/postcss": "^4.1.4",
28+
"@types/node": "^22.14.1",
29+
"@types/react": "^19.1.2",
3030
"@types/react-dom": "^19",
3131
"eslint": "^9",
32-
"eslint-config-next": "15.2.1",
33-
"tailwindcss": "^4",
32+
"eslint-config-next": "15.3.0",
33+
"tailwindcss": "^4.1.4",
3434
"ts-node": "^10.9.2",
3535
"typescript": "^5"
3636
}
Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,11 @@
11
{
2-
"accountAssociation": {
3-
"header": "eyJmaWQiOjQwMDcxMywidHlwZSI6ImN1c3RvZHkiLCJrZXkiOiIweDFkNDAxYTUyMzcxOWM1OGFhN2JhYTIzYjYxNTg3YzEyMGJkZDgxY2YifQ",
4-
"payload": "eyJkb21haW4iOiJsb2NhbGhvc3Q6MzAwMCJ9",
5-
"signature": ""
6-
},
72
"frame": {
83
"name": "Polkadot NFT Demo",
94
"version": "1",
10-
"iconUrl": "http://localhost:3000/icon.png",
11-
"homeUrl": "http://localhost:3000",
12-
"imageUrl": "http://localhost:3000/image.png",
5+
"iconUrl": "logo.png",
6+
"homeUrl": "https://polkadot-nft-farcaster-frames-demo.rxshri99.live/",
7+
"imageUrl": "https://polkadot-nft-farcaster-frames-demo.rxshri99.live/logo.png",
138
"buttonTitle": "Polkadot NFT",
14-
"splashImageUrl": "http://localhost:3000/splash.png",
15-
"splashBackgroundColor": "#000",
16-
"webhookUrl": "http://localhost:3000/api/webhook"
9+
"splashBackgroundColor": "#f5f5f5"
1710
}
1811
}

frontend/public/logo.png

178 KB
Loading

frontend/src/app/api/cast-details/route.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ export async function GET(request: Request) {
44

55
const NEYNAR_API_KEY = process.env.NEYNAR_API_KEY || "";
66
const NEYNAR_API_URL =
7-
process.env.NEYNAR_API_URL || "https://api.neynar.com/v2/farcaster/";
7+
process.env.NEXT_PUBLIC_NEYNAR_API_URL ||
8+
"https://api.neynar.com/v2/farcaster/";
89

910
try {
1011
if (!castHash) {

frontend/src/app/api/check-engagement/route.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ export async function GET(request: Request) {
55

66
const NEYNAR_API_KEY = process.env.NEYNAR_API_KEY || "";
77
const NEYNAR_API_URL =
8-
process.env.NEYNAR_API_URL || "https://api.neynar.com/v2/farcaster/";
8+
process.env.NEXT_PUBLIC_NEYNAR_API_URL ||
9+
"https://api.neynar.com/v2/farcaster/";
910

1011
try {
1112
if (!fid || !castHash) {

frontend/src/app/api/verify-user/route.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ export async function GET(request: Request) {
44

55
const NEYNAR_API_KEY = process.env.NEYNAR_API_KEY || "";
66
const NEYNAR_API_URL =
7-
process.env.NEYNAR_API_URL || "https://api.neynar.com/v2/farcaster/";
7+
process.env.NEXT_PUBLIC_NEYNAR_API_URL ||
8+
"https://api.neynar.com/v2/farcaster/";
89

910
try {
1011
if (!fid) {

frontend/src/app/page.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { useWallet } from "../contexts/WalletContext";
1010
import sdk from "@farcaster/frame-sdk";
1111
import { FrameContext } from "../types/farcaster";
1212
import { verifyUser } from "../utils/farcaster";
13+
import Image from "next/image";
1314

1415
const Demo = dynamic(
1516
() => import("../components/Demo").then((mod) => mod.Demo),
@@ -33,7 +34,9 @@ export default function Home() {
3334
setUserContext(context as unknown as FrameContext);
3435

3536
if (context?.user?.fid) {
36-
await verifyUser(context.user.fid);
37+
await verifyUser(
38+
context.user.fid as unknown as string
39+
);
3740
}
3841
} catch (error) {
3942
console.error("Error loading user context:", error);
@@ -60,12 +63,15 @@ export default function Home() {
6063
) : userContext?.user ? (
6164
<div className="flex items-center space-x-2 bg-gray-100 p-2 rounded-lg transition-all hover:bg-gray-200">
6265
{userContext.user.pfpUrl ? (
63-
<img
66+
<Image
6467
src={
6568
userContext
6669
.user
6770
.pfpUrl
6871
}
72+
width={0}
73+
height={0}
74+
sizes="100vw"
6975
alt="Profile"
7076
className="w-8 h-8 rounded-full border-2 border-indigo-300"
7177
/>

frontend/src/components/ArtistDashboard.tsx

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
import React, { useState, useEffect } from "react";
22
import { ApiPromise } from "@polkadot/api";
33
import type { InjectedAccountWithMeta } from "@polkadot/extension-inject/types";
4-
import type { Signer } from "@polkadot/api/types";
4+
import type { Signer } from "@polkadot/rpc-augment/node_modules/@polkadot/types/types/extrinsic";
55
import { Button } from "./ui/components/Button";
66
import { CollectionManager } from "./CollectionManager";
77
import toast from "react-hot-toast";
88

99
interface ArtistDashboardProps {
1010
api: ApiPromise;
1111
account: InjectedAccountWithMeta;
12-
signer: Signer;
12+
signer: Signer | unknown;
1313
}
1414

1515
export const ArtistDashboard: React.FC<ArtistDashboardProps> = ({
@@ -22,6 +22,7 @@ export const ArtistDashboard: React.FC<ArtistDashboardProps> = ({
2222

2323
useEffect(() => {
2424
checkArtistStatus();
25+
// eslint-disable-next-line react-hooks/exhaustive-deps
2526
}, [api, account]);
2627

2728
const checkArtistStatus = async () => {
@@ -64,8 +65,10 @@ export const ArtistDashboard: React.FC<ArtistDashboardProps> = ({
6465
}
6566
}
6667
);
67-
} catch (error) {
68-
toast.error("Failed to register as artist:" + error);
68+
} catch (error: unknown) {
69+
const errorMessage =
70+
error instanceof Error ? error.message : String(error);
71+
toast.error("Failed to register as artist: " + errorMessage);
6972
} finally {
7073
setIsLoading(false);
7174
}
@@ -96,7 +99,11 @@ export const ArtistDashboard: React.FC<ArtistDashboardProps> = ({
9699
<h1 className="text-2xl sm:text-3xl font-bold mb-6 sm:mb-8 text-gray-900">
97100
Artist Dashboard
98101
</h1>
99-
<CollectionManager api={api} account={account} signer={signer} />
102+
<CollectionManager
103+
api={api}
104+
account={account}
105+
signer={signer as unknown}
106+
/>
100107
</div>
101108
);
102109
};

frontend/src/components/CollectionManager.tsx

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
import React, { useState, useEffect } from "react";
22
import { ApiPromise } from "@polkadot/api";
33
import type { InjectedAccountWithMeta } from "@polkadot/extension-inject/types";
4-
import type { Signer } from "@polkadot/types/types";
54
import { Button } from "./ui/components/Button";
65
import { decodeMetadata } from "../utils/utils";
76
import { CreateCollectionModal } from "./ui/modals/CreateCollectionModal";
87
import { CreateNFTModal } from "./ui/modals/CreateNFTModal";
98
import toast from "react-hot-toast";
9+
import Image from "next/image";
10+
import { Signer } from "@polkadot/api/types";
1011

1112
interface CollectionManagerProps {
1213
api: ApiPromise;
1314
account: InjectedAccountWithMeta;
14-
signer: Signer;
15+
signer: Signer | unknown;
1516
}
1617

1718
interface Collection {
@@ -67,12 +68,14 @@ export const CollectionManager: React.FC<CollectionManagerProps> = ({
6768

6869
useEffect(() => {
6970
loadCollections();
71+
// eslint-disable-next-line react-hooks/exhaustive-deps
7072
}, [api, account]);
7173

7274
useEffect(() => {
7375
if (selectedCollection) {
7476
loadNFTs(selectedCollection.id);
7577
}
78+
// eslint-disable-next-line react-hooks/exhaustive-deps
7679
}, [selectedCollection]);
7780

7881
const loadCollections = async () => {
@@ -122,7 +125,9 @@ export const CollectionManager: React.FC<CollectionManagerProps> = ({
122125
);
123126
setCollections(formattedCollections);
124127
} catch (error) {
125-
toast.error("Failed to load collections:", error);
128+
const errorMessage =
129+
error instanceof Error ? error.message : String(error);
130+
toast.error("Failed to load collections: " + errorMessage);
126131
setError("Failed to load collections");
127132
}
128133
};
@@ -173,8 +178,13 @@ export const CollectionManager: React.FC<CollectionManagerProps> = ({
173178
isSold: nftData.isSold,
174179
};
175180
} catch (error) {
181+
const errorMessage =
182+
error instanceof Error
183+
? error.message
184+
: String(error);
176185
toast.error(
177-
`Error loading NFT ${itemId}: ` + error
186+
`Error loading NFT ${itemId}: ` +
187+
errorMessage
178188
);
179189
return null;
180190
}
@@ -211,7 +221,9 @@ export const CollectionManager: React.FC<CollectionManagerProps> = ({
211221
}
212222
);
213223
} catch (error) {
214-
toast.error("Failed to burn NFT: " + error);
224+
const errorMessage =
225+
error instanceof Error ? error.message : String(error);
226+
toast.error("Failed to burn NFT: " + errorMessage);
215227
setError("Failed to burn NFT");
216228
}
217229
};
@@ -242,7 +254,9 @@ export const CollectionManager: React.FC<CollectionManagerProps> = ({
242254
}
243255
});
244256
} catch (error) {
245-
toast.error("Failed to transfer NFT: " + error);
257+
const errorMessage =
258+
error instanceof Error ? error.message : String(error);
259+
toast.error("Failed to transfer NFT: " + errorMessage);
246260
setError("Failed to transfer NFT");
247261
}
248262
};
@@ -302,7 +316,6 @@ export const CollectionManager: React.FC<CollectionManagerProps> = ({
302316
</div>
303317
</div>
304318

305-
{/* NFTs in Selected Collection */}
306319
<div className="bg-white rounded-lg shadow-lg p-4 sm:p-6">
307320
<div className="flex flex-col sm:flex-row justify-between items-start sm:items-center mb-4 sm:mb-6">
308321
<h2 className="text-xl sm:text-2xl font-bold text-gray-800 mb-4 sm:mb-0">
@@ -353,7 +366,14 @@ export const CollectionManager: React.FC<CollectionManagerProps> = ({
353366
</p>
354367
{nft.metadata
355368
.image && (
356-
<img
369+
<Image
370+
width={
371+
0
372+
}
373+
height={
374+
0
375+
}
376+
sizes="100vw"
357377
src={
358378
nft
359379
.metadata
@@ -447,7 +467,7 @@ export const CollectionManager: React.FC<CollectionManagerProps> = ({
447467
<CreateCollectionModal
448468
api={api}
449469
account={account}
450-
signer={signer}
470+
signer={signer as unknown}
451471
isOpen={isCreateCollectionModalOpen}
452472
onClose={() => setIsCreateCollectionModalOpen(false)}
453473
onSuccess={loadCollections}
@@ -457,7 +477,7 @@ export const CollectionManager: React.FC<CollectionManagerProps> = ({
457477
<CreateNFTModal
458478
api={api}
459479
account={account}
460-
signer={signer}
480+
signer={signer as unknown}
461481
collectionId={selectedCollection.id}
462482
isOpen={isCreateNFTModalOpen}
463483
onClose={() => setIsCreateNFTModalOpen(false)}

0 commit comments

Comments
 (0)