Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
stephancill committed Jan 23, 2025
2 parents e5f2235 + c0c651e commit efaf777
Show file tree
Hide file tree
Showing 36 changed files with 854 additions and 157 deletions.
7 changes: 7 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# docs

## 0.3.13

### Patch Changes

- Updated dependencies [86e03b9]
- [email protected]

## 0.3.12

### Patch Changes
Expand Down
4 changes: 2 additions & 2 deletions docs/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "docs",
"version": "0.3.12",
"version": "0.3.13",
"type": "module",
"private": true,
"scripts": {
Expand All @@ -9,7 +9,7 @@
"preview": "vocs preview"
},
"dependencies": {
"frames.js": "0.21.1",
"frames.js": "0.21.2",
"lucide-react": "^0.372.0",
"next": "14.1.4",
"react": "^18.2.0",
Expand Down
7 changes: 7 additions & 0 deletions packages/debugger/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# @frames.js/debugger

## 0.4.2

### Patch Changes

- 96a5831: feat: view profile dialog
- 86e03b9: feat: support for app key signatures

## 0.4.1

### Patch Changes
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/* eslint-disable @next/next/no-img-element */
import React from "react";
import {
Dialog,
DialogContent,
DialogTitle,
DialogDescription,
} from "@/components/ui/dialog";
import { useQuery } from "@tanstack/react-query";
import { z } from "zod";
import { Loader2Icon, TriangleAlertIcon } from "lucide-react";
import Image from "next/image";

type UserDetails = {
username: string;
pfp_url: string;
profile: {
bio: {
text: string;
};
};
follower_count: number;
following_count: number;
};

type FrameAppDebuggerViewProfileDialogProps = {
fid: number;
onDismiss: () => void;
};

const UserDetailsSchema = z.object({
username: z.string(),
pfp_url: z.string().url(),
profile: z.object({
bio: z.object({
text: z.string(),
}),
}),
follower_count: z.number().int(),
following_count: z.number().int(),
});

async function fetchUser(fid: number): Promise<UserDetails> {
const response = await fetch(`/farcaster/user/${fid}`);

if (!response.ok) {
throw new Error("Network response was not ok");
}

const data = await response.json();

return UserDetailsSchema.parse(data);
}

export function FrameAppDebuggerViewProfileDialog({
fid,
onDismiss,
}: FrameAppDebuggerViewProfileDialogProps) {
const query = useQuery({
queryKey: ["user", fid],
queryFn: () => fetchUser(fid),
});

return (
<Dialog open={true} onOpenChange={onDismiss}>
<DialogContent>
<DialogTitle>Profile Details</DialogTitle>
{query.isLoading && (
<DialogDescription className="flex items-center justify-center">
<Loader2Icon className="animate-spin" />
</DialogDescription>
)}
{query.isError && (
<DialogDescription className="flex flex-col items-center justify-center text-red-500">
<TriangleAlertIcon className="mb-2 w-6 h-6" />
<span className="font-semibold">Unexpected error occurred</span>
</DialogDescription>
)}
{query.isSuccess && (
<DialogDescription className="flex flex-col gap-2 items-center justify-center">
<div className="flex items-center">
<div className="aspect-square h-[80px] w-[80px] rounded-full overflow-hidden">
<img
className="w-full h-full object-contain"
src={query.data.pfp_url}
alt={query.data.username}
width={80}
/>
</div>
</div>
<strong className="text-lg">{query.data.username}</strong>
<div className="grid grid-cols-2 gap-4 text-sm text-gray-500 text-center">
<div>
<strong>{formatCount(query.data.follower_count)}</strong>{" "}
followers
</div>
<div>
<strong>{formatCount(query.data.following_count)}</strong>{" "}
following
</div>
</div>
<span>{query.data.profile.bio.text}</span>
</DialogDescription>
)}
</DialogContent>
</Dialog>
);
}

function formatCount(count: number): string {
if (count < 1000) {
return count.toString();
} else if (count >= 1000 && count < 1000000) {
return (count / 1000).toFixed(1) + "K";
}

return (count / 1000000).toFixed(1) + "M";
}
19 changes: 19 additions & 0 deletions packages/debugger/app/components/frame-app-debugger.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import type { EIP6963ProviderInfo } from "@farcaster/frame-sdk";
import { z } from "zod";
import { Dialog, DialogContent } from "@/components/ui/dialog";
import { useCopyToClipboard } from "../hooks/useCopyToClipboad";
import { FrameAppDebuggerViewProfileDialog } from "./frame-app-debugger-view-profile-dialog";

type TabValues = "events" | "console" | "notifications";

Expand Down Expand Up @@ -153,6 +154,7 @@ export function FrameAppDebugger({
};
}
}, [toast]);
const [viewFidProfile, setViewFidProfile] = useState<number | null>(null);
const frameApp = useFrameAppInIframe({
debug: true,
source: context.parseResult,
Expand Down Expand Up @@ -289,6 +291,11 @@ export function FrameAppDebugger({
});
},
async onSignIn({ nonce, notBefore, expirationTime, frame }) {
console.info("sdk.actions.signIn() called", {
nonce,
notBefore,
expirationTime,
});
let abortTimeout: NodeJS.Timeout | undefined;

try {
Expand Down Expand Up @@ -373,6 +380,10 @@ export function FrameAppDebugger({
setFarcasterSignInAbortControllerURL(null);
}
},
async onViewProfile(params) {
console.info("sdk.actions.viewProfile() called", params);
setViewFidProfile(params.fid);
},
});

return (
Expand Down Expand Up @@ -552,6 +563,14 @@ export function FrameAppDebugger({
) : null}
</div>
</div>
{viewFidProfile !== null && (
<FrameAppDebuggerViewProfileDialog
fid={viewFidProfile}
onDismiss={() => {
setViewFidProfile(null);
}}
/>
)}
</>
);
}
44 changes: 44 additions & 0 deletions packages/debugger/app/farcaster/user/[fid]/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import type { NextRequest } from "next/server";
import { z } from "zod";

const validator = z.object({
fid: z.coerce.number().int().positive(),
});

export async function GET(
_: NextRequest,
{ params }: { params: { fid: string } }
) {
try {
const { fid } = validator.parse(params);

const url = new URL("https://api.neynar.com/v2/farcaster/user/bulk");

url.searchParams.set("fids", fid.toString());

const response = await fetch(url, {
headers: {
accept: "application/json",
"x-api-key": "NEYNAR_FRAMES_JS",
},
});

if (!response.ok) {
if (response.status === 404) {
return Response.json({ error: "User not found" }, { status: 404 });
}

throw new Error(`Unexpected response: ${response.status}`);
}

const data = await response.json();

return Response.json(data.users[0]);
} catch (e) {
if (e instanceof z.ZodError) {
return Response.json({ error: e.errors }, { status: 400 });
}

throw e;
}
}
6 changes: 3 additions & 3 deletions packages/debugger/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"frames.js",
"farcaster"
],
"version": "0.4.1",
"version": "0.4.2",
"bin": {
"frames": "./bin/debugger.js"
},
Expand Down Expand Up @@ -37,7 +37,7 @@
},
"devDependencies": {
"@farcaster/core": "^0.15.6",
"@frames.js/render": "^0.5.1",
"@frames.js/render": "^0.5.2",
"@primer/octicons-react": "^19.9.0",
"@radix-ui/react-accordion": "^1.1.2",
"@radix-ui/react-checkbox": "^1.0.4",
Expand Down Expand Up @@ -69,7 +69,7 @@
"console-feed": "^3.6.0",
"eslint": "^8.56.0",
"eslint-config-next": "^14.1.0",
"frames.js": "^0.21.1",
"frames.js": "^0.21.2",
"lucide-react": "^0.408.0",
"postcss": "^8",
"qrcode.react": "^3.1.0",
Expand Down
6 changes: 6 additions & 0 deletions packages/frames.js/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# frames.js

## 0.21.2

### Patch Changes

- 86e03b9: feat: support for app key signatures

## 0.21.1

### Patch Changes
Expand Down
18 changes: 15 additions & 3 deletions packages/frames.js/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "frames.js",
"version": "0.21.1",
"version": "0.21.2",
"type": "module",
"main": "./dist/index.cjs",
"types": "index.d.cts",
Expand Down Expand Up @@ -187,6 +187,16 @@
"default": "./dist/farcaster-v2/types.cjs"
}
},
"./farcaster-v2/verify": {
"import": {
"types": "./dist/farcaster-v2/verify.d.ts",
"default": "./dist/farcaster-v2/verify.js"
},
"require": {
"types": "./dist/farcaster-v2/verify.d.cts",
"default": "./dist/farcaster-v2/verify.cjs"
}
},
"./core": {
"import": {
"types": "./dist/core/index.d.ts",
Expand Down Expand Up @@ -420,12 +430,14 @@
},
"dependencies": {
"@farcaster/frame-core": "^0.0.24",
"@farcaster/frame-node": "^0.0.13",
"@noble/ed25519": "^2.2.3",
"@noble/hashes": "^1.7.1",
"@vercel/og": "^0.6.3",
"cheerio": "^1.0.0-rc.12",
"ox": "^0.4.4",
"protobufjs": "^7.2.6",
"viem": "^2.7.8",
"type-fest": "^4.28.1",
"viem": "^2.7.8",
"zod": "^3.24.1"
}
}
8 changes: 8 additions & 0 deletions packages/frames.js/src/farcaster-v2/es25519.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { sha512 } from "@noble/hashes/sha512";
import { etc, getPublicKey, sign, verify } from "@noble/ed25519";

if (!etc.sha512Sync) {
etc.sha512Sync = (...m: Uint8Array[]) => sha512(etc.concatBytes(...m));
}

export { getPublicKey, sign, verify };
Loading

0 comments on commit efaf777

Please sign in to comment.