Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
90 commits
Select commit Hold shift + click to select a range
b0f22ca
Todo list replaced
builderio-bot Sep 16, 2025
739af71
Use env-driven addresses and WalletConnect optional config; read Base…
builderio-bot Sep 16, 2025
3e799aa
Load contract addresses from Vite env vars
builderio-bot Sep 16, 2025
0b2f616
Fix ESLint errors: replace empty interfaces and require in tailwind c…
builderio-bot Sep 16, 2025
e443afa
Fix ESLint errors: replace empty interfaces and require usage
builderio-bot Sep 16, 2025
7c92651
Add types and ESM plugin import to tailwind config
builderio-bot Sep 16, 2025
e1865db
Update ConnectWallet UI per user request
builderio-bot Sep 16, 2025
c464217
Add missing imports and OKX connector
builderio-bot Sep 16, 2025
6f043a8
Add okxWallet to connectors list
builderio-bot Sep 16, 2025
cbd52eb
Clean connectors array (filter undefined)
builderio-bot Sep 16, 2025
eaf2d88
Type connectors array to avoid any
builderio-bot Sep 16, 2025
f151695
Fix connectors typing cast
builderio-bot Sep 16, 2025
34920a3
Remove duplicate import in wagmi.ts
builderio-bot Sep 16, 2025
0ae3a28
Remove okxWallet import and usage
builderio-bot Sep 16, 2025
8c0edf8
Remove okxWallet usage in connectors array
builderio-bot Sep 16, 2025
f73b056
Remove OKX from preferred wallets in ConnectWallet
builderio-bot Sep 16, 2025
4146953
Add usePosts hook
builderio-bot Sep 16, 2025
71de65b
Add useComments hook
builderio-bot Sep 16, 2025
0300b48
Add useFollow hook
builderio-bot Sep 16, 2025
f7562a0
Wire Feed to use on-chain posts (usePosts) with fallback
builderio-bot Sep 16, 2025
17d92c4
Update CreatePost to await onPost if it returns a Promise
builderio-bot Sep 16, 2025
0b5f768
Replace any with unknown and safer casts in usePosts
builderio-bot Sep 16, 2025
daa8ad6
Use unknown for error types and other any occurrences in usePosts
builderio-bot Sep 16, 2025
0d91907
Replace other any casts in usePosts
builderio-bot Sep 16, 2025
0746b69
Replace any in like/unlike write calls
builderio-bot Sep 16, 2025
fd93fbb
Replace any in unlikePost write call and catch
builderio-bot Sep 16, 2025
17e5e65
Type-safety fixes in useComments
builderio-bot Sep 16, 2025
7929118
Replace any usage in readContract calls in useComments
builderio-bot Sep 16, 2025
ae24f9c
Replace error catches in useComments
builderio-bot Sep 16, 2025
b920446
Fix types and imports in useFollow
builderio-bot Sep 16, 2025
526be24
Remove any cast usage in Feed and adjust Post timestamp type
builderio-bot Sep 16, 2025
814424d
Remove any casts in Feed mapping and sorting
builderio-bot Sep 16, 2025
8562540
Make sorting type-safe in Feed
builderio-bot Sep 16, 2025
11b91da
Avoid any in CreatePost promise check
builderio-bot Sep 16, 2025
18670f1
Use abitype Abi and typed tuples to remove any in usePosts
builderio-bot Sep 16, 2025
d595c7c
Replace abi casts and raw handling in usePosts
builderio-bot Sep 16, 2025
12dd187
Use Abi type in write calls and adjust error handlers in usePosts
builderio-bot Sep 16, 2025
86be4ab
Update likePost write call abi typing and error type
builderio-bot Sep 16, 2025
089d8d3
Update unlikePost abi typing
builderio-bot Sep 16, 2025
a1a6699
Use Abi type in useComments
builderio-bot Sep 16, 2025
1a35228
Use Abi type in useComments read calls and typed tuple
builderio-bot Sep 16, 2025
0e7d480
Fix remaining any occurrences
builderio-bot Sep 16, 2025
10ef20e
Use Abi type in useFollow read/write calls
builderio-bot Sep 16, 2025
3a012b9
Add QA on-chain check script
builderio-bot Sep 16, 2025
2679d84
Convert QA script to ESM
builderio-bot Sep 16, 2025
a178f61
Fix ethers import usage in QA script
builderio-bot Sep 16, 2025
51cd9e4
Fallback to mock mode in usePosts when on-chain calls fail
builderio-bot Sep 16, 2025
29a34ea
Set mock fallback on fetch error and handle createPost fallback
builderio-bot Sep 16, 2025
8ff939c
Fallback createPost when on-chain fails or in mock mode
builderio-bot Sep 16, 2025
65992ae
Fallback like/unlike handling when in mock mode
builderio-bot Sep 16, 2025
f0aca75
Fallback unlike handling when in mock mode
builderio-bot Sep 16, 2025
11cd5bb
Replace ABIs with provided ABIs and keep env addresses
builderio-bot Sep 16, 2025
f167a47
Update useComments to use addComment/getCommentsForPost
builderio-bot Sep 16, 2025
741d9a4
Update useFollow to use followerCount/isFollowing/followingCount
builderio-bot Sep 16, 2025
8e640ba
Update useProfile to read on-chain profile
builderio-bot Sep 16, 2025
a4501b7
Fix any casts in useFollow and move mock posts to module scope; add deps
builderio-bot Sep 16, 2025
e6b6b72
Fix useFollow and usePosts deps and casts
builderio-bot Sep 16, 2025
0b45b01
Update createPost deps in usePosts
builderio-bot Sep 16, 2025
f2673b5
Replace any cast occurrences in useFollow counts
builderio-bot Sep 16, 2025
9c99588
Fallback to posts(index) when getAllPosts missing
builderio-bot Sep 16, 2025
b7450ae
Ensure wallet switches to Base Mainnet on connect
builderio-bot Sep 16, 2025
3ec4979
Add network hooks imports and base chain
builderio-bot Sep 16, 2025
068c565
Import base chain
builderio-bot Sep 16, 2025
8f14750
Add Base network switch logic
builderio-bot Sep 16, 2025
29d4b98
Remove duplicate Button imports and ensure single import
builderio-bot Sep 16, 2025
24b115d
Replace network-hook usage with window.ethereum-based checks
builderio-bot Sep 16, 2025
c2c3caf
Fix effect dependencies
builderio-bot Sep 16, 2025
1c76ee3
Open wallet popup when creating post if not connected
builderio-bot Sep 16, 2025
0630dc6
Add useConnect variables
builderio-bot Sep 16, 2025
719abff
Trigger wallet popup when creating post if not connected (precise rep…
builderio-bot Sep 16, 2025
68af8e8
Add useState import to CreatePost
builderio-bot Sep 16, 2025
49e13e8
Add react imports to Feed
builderio-bot Sep 16, 2025
d07ac17
Update createPost dependencies
builderio-bot Sep 16, 2025
a06c6cb
Remove duplicate react import in Feed
builderio-bot Sep 16, 2025
d4a006b
Add react import to Feed
builderio-bot Sep 16, 2025
b1393b4
Normalize React imports in Feed
builderio-bot Sep 16, 2025
1c27b28
Normalize React import in CreatePost
builderio-bot Sep 16, 2025
6eacbba
Normalize React import in ConnectWallet
builderio-bot Sep 16, 2025
4a36249
Add useLocation import to NotFound and normalize react import
builderio-bot Sep 16, 2025
b20b159
Normalize Feed react imports - remove duplicate
builderio-bot Sep 16, 2025
11bbb76
Add missing React imports to several files
builderio-bot Sep 16, 2025
6287578
Add React import to PostCard
builderio-bot Sep 16, 2025
37ddb89
Add React import to Dashboard
builderio-bot Sep 16, 2025
8dd6f95
Add React import to Index page
builderio-bot Sep 16, 2025
e18f8ba
Remove duplicate useState-only imports
builderio-bot Sep 16, 2025
0b87a55
Remove duplicate useState-only imports from PostCard
builderio-bot Sep 16, 2025
0faeb2c
Remove duplicate useState-only imports from CreatePost
builderio-bot Sep 16, 2025
58e66eb
Remove duplicate useState-only import from Index
builderio-bot Sep 16, 2025
b65389f
Fallback to mock when Posts contract not configured
builderio-bot Sep 16, 2025
5cba610
Merge pull request #1 from cryptoxbr1/ai_main_ac9dc7e1edaa
cryptoxbr1 Sep 16, 2025
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
Binary file modified bun.lockb
100644 → 100755
Binary file not shown.
48 changes: 48 additions & 0 deletions scripts/qa-onchain-check.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#!/usr/bin/env node
import { JsonRpcProvider, Contract } from 'ethers';

async function main() {
const rpc = process.env.VITE_BASE_RPC || process.env.BASE_RPC || 'https://mainnet.base.org';
const postsAddr = process.env.VITE_BASELINE_POSTS || process.env.BASELINE_POSTS;

console.log('Using RPC:', rpc);
console.log('Posts contract address:', postsAddr);

if (!postsAddr) {
console.error('No Posts contract address provided in env VITE_BASELINE_POSTS');
process.exit(2);
}

const provider = new JsonRpcProvider(rpc);

const POSTS_ABI = [
'function getAllPosts() view returns (uint256[])',
'function getPost(uint256) view returns (uint256 id, address author, string content, uint256 timestamp, uint256 likesCount, uint256 commentsCount, bool exists)'
];
Comment on lines +18 to +21
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

ABI mismatch with deployed contract schema (getPost shape) and missing getAllPosts definition.

Your local ABI expects getPost to return 7 fields (incl. likes/comments/existence), but src/lib/contracts.ts defines getPost as (Post tuple, uint256) and does not expose commentsCount/exists. Also, POSTS_ABI there does not include getAllPosts, yet the script calls it. This will revert at runtime. Align the ABI and stop calling non-existent functions.

Apply this minimal ABI fix (align to tuple + likeCount) and switch to events-based discovery (PostCreated) rather than getAllPosts:

-  const POSTS_ABI = [
-    'function getAllPosts() view returns (uint256[])',
-    'function getPost(uint256) view returns (uint256 id, address author, string content, uint256 timestamp, uint256 likesCount, uint256 commentsCount, bool exists)'
-  ];
+  const POSTS_ABI = [
+    'event PostCreated(uint256 indexed id, address indexed author, string content, uint256 timestamp)',
+    'function getPost(uint256) view returns ((uint256 id, address author, string content, uint256 timestamp), uint256)',
+    'function likeCounts(uint256) view returns (uint256)'
+  ];
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const POSTS_ABI = [
'function getAllPosts() view returns (uint256[])',
'function getPost(uint256) view returns (uint256 id, address author, string content, uint256 timestamp, uint256 likesCount, uint256 commentsCount, bool exists)'
];
const POSTS_ABI = [
'event PostCreated(uint256 indexed id, address indexed author, string content, uint256 timestamp)',
'function getPost(uint256) view returns ((uint256 id, address author, string content, uint256 timestamp), uint256)',
'function likeCounts(uint256) view returns (uint256)'
];
🤖 Prompt for AI Agents
In scripts/qa-onchain-check.js around lines 18 to 21, the hardcoded POSTS_ABI is
out of sync with the deployed contract: it declares getPost returning 7 fields
and includes getAllPosts (which the deployed contract/ src/lib/contracts.ts does
not expose). Replace the ABI entries so getPost matches the contract tuple
signature used in src/lib/contracts.ts (Post tuple plus uint256 likeCount) —
remove commentsCount and exists — and remove/stop calling getAllPosts; instead
implement discovery by filtering the PostCreated event from the contract
(queryFilter or provider.getLogs) to enumerate posts and then call getPost for
each returned id. Ensure the ABI only contains the actual functions/events used
(getPost and the PostCreated event) to avoid runtime reverts.


try {
const contract = new Contract(postsAddr, POSTS_ABI, provider);
console.log('Calling getAllPosts...');
const ids = await contract.getAllPosts();
console.log('Received ids length:', ids.length);
if (ids.length > 0) {
const first = ids[0];
console.log('Fetching first post id:', first.toString());
const post = await contract.getPost(first);
console.log('Post:', {
id: post.id.toString(),
author: post.author,
content: (post.content || '').slice(0, 120),
timestamp: post.timestamp.toString(),
likes: (post.likesCount?.toString?.() || post[4]?.toString?.())
});
} else {
console.log('No posts found on-chain (getAllPosts returned empty array).');
}
Comment on lines +23 to +41
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Replace getAllPosts call with event scan to enumerate post ids.

Since the ABI doesn’t include getAllPosts, query PostCreated logs to grab recent post IDs and then read a post via getPost.

-    const contract = new Contract(postsAddr, POSTS_ABI, provider);
-    console.log('Calling getAllPosts...');
-    const ids = await contract.getAllPosts();
-    console.log('Received ids length:', ids.length);
-    if (ids.length > 0) {
-      const first = ids[0];
-      console.log('Fetching first post id:', first.toString());
-      const post = await contract.getPost(first);
-      console.log('Post:', {
-        id: post.id.toString(),
-        author: post.author,
-        content: (post.content || '').slice(0, 120),
-        timestamp: post.timestamp.toString(),
-        likes: (post.likesCount?.toString?.() || post[4]?.toString?.())
-      });
-    } else {
-      console.log('No posts found on-chain (getAllPosts returned empty array).');
-    }
+    const contract = new Contract(postsAddr, POSTS_ABI, provider);
+    console.log('Scanning PostCreated logs...');
+    const topic0 = (await import('ethers')).id('PostCreated(uint256,address,string,uint256)');
+    const logs = await provider.getLogs({ address: postsAddr, topics: [topic0], fromBlock: 0, toBlock: 'latest' });
+    console.log('Found PostCreated logs:', logs.length);
+    if (logs.length > 0) {
+      const last = logs[logs.length - 1];
+      const idHex = last.topics[1]; // indexed id
+      const postId = BigInt(idHex);
+      console.log('Fetching latest post id:', postId.toString());
+      const [post, likeCount] = await contract.getPost(postId);
+      console.log('Post:', {
+        id: post.id.toString(),
+        author: post.author,
+        content: (post.content || '').slice(0, 120),
+        timestamp: post.timestamp.toString(),
+        likes: likeCount?.toString?.()
+      });
+    } else {
+      console.log('No posts found on-chain (no PostCreated logs).');
+    }

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In scripts/qa-onchain-check.js around lines 23 to 41, the code calls a
non-existent getAllPosts ABI method; replace that with a log scan for
PostCreated events and decode those logs to enumerate post IDs. Use the provider
to getLogs with a filter for the posts contract address and the PostCreated
event signature (via the POSTS_ABI) for a recent block range, decode each log
with an ethers Interface to extract the post ID list, then if any IDs exist call
contract.getPost(firstId) as before; ensure you handle the case of no logs found
and surface clear console messages and any decode errors.

} catch (err) {
console.error('On-chain checks failed:', (err && err.message) || err);
process.exit(1);
}
}

main();
109 changes: 80 additions & 29 deletions src/components/ConnectWallet.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { Button } from "@/components/ui/button";
import { Card } from "@/components/ui/card";
import { Button } from "@/components/ui/button";

import { useConnect, useAccount } from "wagmi";
import { Wallet, Shield, Zap, ChevronRight } from "lucide-react";
import { useEffect } from "react";
import { base } from 'wagmi/chains';
import React, { useEffect } from "react";
import heroImage from "@/assets/baseline-hero.jpg";

interface ConnectWalletProps {
Expand All @@ -12,13 +14,55 @@ interface ConnectWalletProps {
const ConnectWallet = ({ onConnect }: ConnectWalletProps) => {
const { connectors, connect } = useConnect();
const { isConnected } = useAccount();
const baseRpc = (import.meta.env.VITE_BASE_RPC as string | undefined) ?? 'https://mainnet.base.org';
Comment on lines 15 to +17
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Await connection properly; use connectAsync for error handling.

connect isn’t awaited; errors won’t be caught. Use connectAsync and await it.

-  const { connectors, connect } = useConnect();
+  const { connectors, connectAsync } = useConnect();
-                  try {
-                    connect({ connector: target });
-                  } catch (err) {
+                  try {
+                    await connectAsync({ connector: target });
+                  } catch (err) {
                     console.error('Connect failed', err);
                     try { (await import('sonner')).toast.error('Failed to connect wallet'); } catch { console.warn('No sonner available'); }
                   }

Also applies to: 110-132

🤖 Prompt for AI Agents
In src/components/ConnectWallet.tsx around lines 15-17 (and also apply same
change to lines 110-132), the component uses the non-async connect function so
connection attempts aren’t awaited and thrown errors can’t be handled; replace
usages of connect with connectAsync and await the call inside an async handler,
wrap the await in a try/catch to handle and log/display errors, and ensure any
subsequent logic that depends on the connection awaits the connectAsync result
before proceeding.


useEffect(() => {
if (isConnected) {
onConnect();
}
}, [isConnected, onConnect]);

useEffect(() => {
if (!isConnected) return;

const ensureBase = async () => {
try {
const ethereum = (window as any).ethereum;
if (!ethereum?.request) {
try { (await import('sonner')).toast.error('No Ethereum provider available to switch networks'); } catch { /* ignore */ }
return;
}

const currentChainHex = await ethereum.request({ method: 'eth_chainId' }) as string;
const currentChainId = parseInt(currentChainHex, 16);
if (currentChainId === base.id) return;

await ethereum.request({
method: 'wallet_addEthereumChain',
params: [{
chainId: '0x' + base.id.toString(16),
chainName: 'Base Mainnet',
rpcUrls: [baseRpc],
nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
blockExplorerUrls: ['https://base.blockscout.com/'],
}],
});

await ethereum.request({
method: 'wallet_switchEthereumChain',
params: [{ chainId: '0x' + base.id.toString(16) }],
});

try { (await import('sonner')).toast.success('Switched to Base Mainnet'); } catch { /* ignore */ }
} catch (err) {
console.error('Network switch failed', err);
try { (await import('sonner')).toast.error('Please switch your wallet to Base Mainnet'); } catch { /* ignore */ }
}
};

ensureBase();
}, [isConnected, baseRpc]);

const wallets = [];

return (
Expand All @@ -34,7 +78,7 @@ const ConnectWallet = ({ onConnect }: ConnectWalletProps) => {
{/* Header */}
<div className="text-center mb-8">
<div className="inline-flex items-center justify-center w-16 h-16 bg-gradient-primary rounded-2xl mb-4 shadow-medium">
<span className="text-2xl">⚡</span>
<span className="text-3xl font-bold text-primary-foreground">B</span>
</div>
<h1 className="text-4xl font-bold mb-2">
Welcome to <span className="gradient-text">BaseLine</span>
Expand All @@ -61,26 +105,40 @@ const ConnectWallet = ({ onConnect }: ConnectWalletProps) => {

<Card className="p-6 card-glow glass-effect">
<h3 className="text-xl font-semibold mb-4 text-center">Connect Your Wallet</h3>

<div className="space-y-3">
{connectors.map((connector) => (
<Button
key={connector.uid}
variant="default"
size="lg"
className="w-full justify-between group btn-gradient"
onClick={() => connect({ connector })}
disabled={!connector.ready}
>
<div className="flex items-center gap-3">
<Wallet className="w-5 h-5" />
<div className="text-left">
<div className="font-semibold">{connector.name}</div>
<div className="text-sm opacity-80">Connect with {connector.name}</div>
</div>
<Button
variant="default"
size="lg"
className="w-full justify-center group btn-gradient"
onClick={async () => {
// Preferred wallet order
const preferred = ["MetaMask", "Coinbase Wallet"];
const findPreferred = connectors.find((c) => preferred.some((p) => c.name.toLowerCase().includes(p.toLowerCase())));
const fallback = connectors.find((c) => c.ready) || connectors[0];
const target = findPreferred || fallback;
if (!target) {
// show fallback message
try { (await import('sonner')).toast.error('No wallet connectors available'); } catch { console.warn('No sonner available'); }
return;
}

try {
connect({ connector: target });
} catch (err) {
console.error('Connect failed', err);
try { (await import('sonner')).toast.error('Failed to connect wallet'); } catch { console.warn('No sonner available'); }
}
}}
>
<div className="flex items-center gap-3">
<Wallet className="w-5 h-5" />
<div className="text-left">
<div className="font-semibold">Connect Wallet</div>
<div className="text-sm opacity-80">MetaMask · Coinbase Wallet · OKX</div>
</div>
<ChevronRight className="w-5 h-5 group-hover:translate-x-1 transition-transform" />
</Button>
))}
</div>
</Button>
</div>

<div className="mt-6 text-center">
Expand All @@ -90,17 +148,10 @@ const ConnectWallet = ({ onConnect }: ConnectWalletProps) => {
</div>
</Card>

{/* Network Info */}
<div className="mt-6 text-center">
<div className="inline-flex items-center gap-2 px-3 py-1 bg-accent/50 rounded-full text-sm glass-effect">
<div className="connection-dot"></div>
<span>Base Mainnet (Chain ID: 8453)</span>
</div>
</div>
</div>
</div>
</div>
);
};

export default ConnectWallet;
export default ConnectWallet;
26 changes: 18 additions & 8 deletions src/components/CreatePost.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useState } from "react";
import React, { useState } from "react";
import { Button } from "@/components/ui/button";
import { Card } from "@/components/ui/card";
import { Textarea } from "@/components/ui/textarea";
Expand Down Expand Up @@ -33,13 +33,23 @@ const CreatePost = ({ onPost }: CreatePostProps) => {

const handlePost = async () => {
if (!content.trim() || isPosting) return;

setIsPosting(true);
await new Promise(resolve => setTimeout(resolve, 1000)); // Simulate blockchain tx
onPost(content);
setContent("");
setCharCount(0);
setIsPosting(false);
try {
const res = onPost ? onPost(content) : null;
if (res && typeof (res as { then?: unknown }).then === 'function') {
await res as Promise<unknown>;
} else {
// fallback simulated tx
await new Promise(resolve => setTimeout(resolve, 1000));
}
setContent("");
setCharCount(0);
} catch (err) {
console.error('Post failed', err);
} finally {
setIsPosting(false);
}
};

const getCharCountColor = () => {
Expand Down Expand Up @@ -133,4 +143,4 @@ const CreatePost = ({ onPost }: CreatePostProps) => {
);
};

export default CreatePost;
export default CreatePost;
4 changes: 2 additions & 2 deletions src/components/Dashboard.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useState } from "react";
import React, { useState } from "react";
import Sidebar from "./Sidebar";
import Feed from "./Feed";
import RightPanel from "./RightPanel";
Expand Down Expand Up @@ -43,4 +43,4 @@ const Dashboard = ({ onDisconnect }: DashboardProps) => {
);
};

export default Dashboard;
export default Dashboard;
Loading