Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix readme + archive #174

Merged
merged 1 commit into from
Jan 17, 2025
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
23 changes: 16 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,25 @@
# Message Kit

A set of tools for AI developers to build on top of [XMTP](https://xmtp.org)
![Status](https://img.shields.io/badge/Deprecated-brown)

> Try XMTP using [xmtp.chat](https://xmtp.chat)
> [!CAUTION]
> This project has not been maintained since 2024. It has been deprecated in favor of the [xmtp-agents](https://github.com/ephemeraHQ/xmtp-agents) project.

A set of tools for AI developers to build on top of [XMTP](https://xmtp.org)
yarn
- [`message-kit`](/packages/message-kit): A kit for quickly building messaging apps
- [`create-message-kit`](/packages/create-message-kit): A CLI for creating new apps easily
- [`docs`](/packages/docs): Documentation for MessageKit
- [`agent-starter`](/packages/agent-starter/): An node js wrapper for AI agents around the [node-sdk](https://github.com/xmtp/xmtp-js/tree/main/sdks/node-sdk)
- [`gated-group`](/packages/gated-group): A gated group quickstart built on agent-starter

- [`base-links ⚠️`](/packages/base-links): A suite of coinbase wallet usdc links
- [`framework ⚠️`](/packages/framework): A kit for quickly building messaging apps
- [`cli ⚠️`](/packages/cli): A CLI for creating new apps easily
### Plugins

- [`xmtp`](/packages/xmtp/): An xmtp node js wrapper for AI agents.
- [`xmtp-e2ee`](/packages/xmtp-e2ee/): A js wrapper for AI agents.

### Other

- [`client`](/packages/client): A simple E2EE encrypted agent inbox
- [`baselinks`](/packages/baselinks): A suite of coinbase wallet usdc links

## Contributing

Expand Down
30 changes: 30 additions & 0 deletions packages/client/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Dependencies
node_modules
.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions

# Build outputs
.next
dist
out
build

# Environment files
.env
.env.local
.env.development
.env.test
.env.production

# System files
.DS_Store

# Cache and logs
.turbo
.vocs
.vercel
7 changes: 7 additions & 0 deletions packages/client/.yarnrc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
compressionLevel: mixed

enableGlobalCache: false

enableTelemetry: false

nodeLinker: node-modules
3 changes: 3 additions & 0 deletions packages/client/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Baselinks

See [Baselinks](https://message-kit.org/plugins/baselinks) in MessageKit
4 changes: 4 additions & 0 deletions packages/client/next.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/** @type {import('next').NextConfig} */
const nextConfig = {};

module.exports = nextConfig;
32 changes: 32 additions & 0 deletions packages/client/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"name": "client",
"version": "0.1.0",
"private": true,
"scripts": {
"build": "next build ",
"dev": "next dev",
"lint": "next lint",
"start": "next start"
},
"dependencies": {
"@farcaster/frame-sdk": "0.0.10",
"@types/next": "^9.0.0",
"cheerio": "^1.0.0",
"geist": "^1.3.1",
"next": "^15.0.3",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"viem": "^2.21.45",
"xmtp-e2ee": "workspace:*"
},
"devDependencies": {
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"typescript": "^5"
},
"packageManager": "[email protected]",
"engines": {
"node": ">=20"
}
}
Binary file added packages/client/public/fonts/GeistMonoVF.woff
Binary file not shown.
Binary file added packages/client/public/fonts/GeistVF.woff
Binary file not shown.
Binary file added packages/client/public/fonts/Inter-Regular.ttf
Binary file not shown.
Binary file added packages/client/public/fonts/Inter-SemiBold.ttf
Binary file not shown.
Binary file added packages/client/public/hero.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added packages/client/public/messagekit-logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
74 changes: 74 additions & 0 deletions packages/client/src/app/api/og/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { NextResponse } from "next/server";
import * as cheerio from 'cheerio';

export async function GET(request: Request) {
try {
const { searchParams } = new URL(request.url);
const url = searchParams.get("url");

if (!url) {
return NextResponse.json(
{ error: "URL parameter is required" },
{ status: 400 },
);
}

console.log("Fetching OG data for URL:", url);

const response = await fetch(url, {
headers: {
"user-agent": "bot",
},
});

if (!response.ok) {
throw new Error(`Failed to fetch: ${response.status}`);
}

const html = await response.text();
const $ = cheerio.load(html);

// Extract meta tags using cheerio
const getMetaContent = (property: string) => {
return (
$(`meta[property="${property}"]`).attr('content') ||
$(`meta[name="${property}"]`).attr('content')
);
};

const ogData = {
title:
getMetaContent("og:title") ||
getMetaContent("twitter:title") ||
$('title').text() ||
url,
description:
getMetaContent("og:description") ||
getMetaContent("twitter:description") ||
getMetaContent("description") ||
"",
image:
getMetaContent("og:image") ||
getMetaContent("twitter:image") ||
"",
url,
siteName: getMetaContent("og:site_name") || "",
};

console.log("Extracted OG data:", ogData);

return NextResponse.json(ogData);
} catch (error) {
console.error("Error in OG route:", error);
return NextResponse.json(
{
error:
error instanceof Error ? error.message : "Failed to fetch OG data",
},
{ status: 500 },
);
}
}

export const runtime = "edge";
export const dynamic = "force-dynamic";
Binary file added packages/client/src/app/favicon.ico
Binary file not shown.
Binary file added packages/client/src/app/fonts/GeistMonoVF.woff
Binary file not shown.
Binary file added packages/client/src/app/fonts/GeistVF.woff
Binary file not shown.
31 changes: 31 additions & 0 deletions packages/client/src/app/globals.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
:root {
--background: #ffffff;
--foreground: #000000;
--accent: #ef4444;
}

@media (prefers-color-scheme: dark) {
:root {
--background: #ffffff;
--accent: #ef4444;
--foreground: #000000;
}
}

html,
body {
max-width: 100vw;
overflow-x: hidden;
margin: 0;
padding: 0;
height: 100vh;
}

body {
color: var(--foreground);
background: var(--background);
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen,
Ubuntu, Cantarell, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
13 changes: 13 additions & 0 deletions packages/client/src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import "./globals.css";

export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html>
<body>{children}</body>
</html>
);
}
96 changes: 96 additions & 0 deletions packages/client/src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
"use client";
import React, { Suspense, useEffect, useState } from "react";
import { useSearchParams } from "next/navigation";
import sdk, { type FrameContext } from "@farcaster/frame-sdk";
import { getUserInfo, type UserInfo } from "@/app/utils/resolver";
import Chat from "../components/Chat";

export default function Home(): JSX.Element {
return (
<Suspense fallback={<div>Loading...</div>}>
<HomeContent />
</Suspense>
);
}

function HomeContent(): JSX.Element {
const searchParams = useSearchParams();
const address = searchParams.get("address") ?? "paymentagent.eth";
console.log("address", address);
const [user, setUser] = useState<UserInfo | null>(null);
const [loading, setLoading] = useState(true);

useEffect(() => {
const fetchUserInfo = async () => {
try {
console.log("Fetching user info for address:", address);
const userInfo = await getUserInfo(address as string);
console.log("Fetched user info:", userInfo);

setUser(userInfo ?? null);
} catch (error) {
console.error("Error fetching user info:", error);
} finally {
setLoading(false);
}
};
fetchUserInfo();
}, [address]);

if (loading) {
return <div>Loading...</div>;
}

if (!user) {
return <div>User not found</div>;
}

return (
<FrameHTML user={user}>
<Suspense fallback={<div>Loading...</div>}>
<ChatContent user={user} />
</Suspense>
</FrameHTML>
);
}

// Create a wrapper component that will render the full HTML
function FrameHTML({
children,
user,
}: {
children: React.ReactNode;
user: UserInfo;
}) {
return <>{children}</>;
}

function ChatContent({ user }: { user: UserInfo }): JSX.Element {
const [isSDKLoaded, setIsSDKLoaded] = useState(false);
const [context, setContext] = useState<FrameContext>();

useEffect(() => {
const initFrame = async () => {
setContext(await sdk.context);
sdk.actions.ready();
};

if (sdk && !isSDKLoaded) {
setIsSDKLoaded(true);
initFrame();
}
}, [isSDKLoaded]);

return (
<div
style={{
display: "flex",
justifyContent: "center",
alignItems: "center",
height: "100vh",
width: "100%",
}}>
<Chat user={user} />
</div>
);
}
Loading
Loading