add viewProfile example

This commit is contained in:
Tony D'Addeo 2025-01-06 16:54:40 -06:00 committed by lucas-neynar
parent 7cde86a049
commit 805036bdaf
No known key found for this signature in database
9 changed files with 266 additions and 38 deletions

21
components.json Normal file
View File

@ -0,0 +1,21 @@
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "default",
"rsc": true,
"tsx": true,
"tailwind": {
"config": "tailwind.config.ts",
"css": "src/app/globals.css",
"baseColor": "neutral",
"cssVariables": false,
"prefix": ""
},
"aliases": {
"components": "~/components",
"utils": "~/lib/utils",
"ui": "~/components/ui",
"lib": "~/lib",
"hooks": "~/hooks"
},
"iconLibrary": "lucide"
}

View File

@ -10,17 +10,23 @@
},
"dependencies": {
"@farcaster/auth-kit": "^0.6.0",
"@farcaster/frame-core": "^0.0.19",
"@farcaster/frame-core": "^0.0.22",
"@farcaster/frame-node": "^0.0.7",
"@farcaster/frame-sdk": "^0.0.21",
"@farcaster/frame-sdk": "^0.0.26",
"@farcaster/frame-wagmi-connector": "^0.0.6",
"@radix-ui/react-label": "^2.1.1",
"@tanstack/react-query": "^5.61.0",
"@upstash/redis": "^1.34.3",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"lucide-react": "^0.469.0",
"next": "15.0.3",
"next-auth": "^4.24.11",
"ox": "^0.4.2",
"react": "19.0.0-rc-66855b96-20241106",
"react-dom": "19.0.0-rc-66855b96-20241106",
"tailwind-merge": "^2.6.0",
"tailwindcss-animate": "^1.0.7",
"viem": "^2.21.55",
"wagmi": "^2.14.3"
},

View File

@ -28,3 +28,9 @@ body {
*::-webkit-scrollbar {
display: none;
}
@layer base {
:root {
--radius: 0.5rem;
}
}

View File

@ -1,10 +1,13 @@
"use client";
import { useEffect, useCallback, useState, useMemo } from "react";
import { Input } from "../components/ui/input"
import { signIn, signOut, getCsrfToken } from "next-auth/react";
import sdk, {
AddFrame,
FrameNotificationDetails,
type FrameContext,
SignIn as SignInCore,
type Context,
} from "@farcaster/frame-sdk";
import {
useAccount,
@ -24,14 +27,15 @@ import { truncateAddress } from "~/lib/truncateAddress";
import { base, optimism } from "wagmi/chains";
import { BaseError, UserRejectedRequestError } from "viem";
import { useSession } from "next-auth/react"
import { SignIn as SignInCore } from "@farcaster/frame-core";
import { SignInResult } from "@farcaster/frame-core/dist/actions/signIn";
import { createStore } from 'mipd'
import { Label } from "~/components/ui/label";
export default function Demo(
{ title }: { title?: string } = { title: "Frames v2 Demo" }
) {
const [isSDKLoaded, setIsSDKLoaded] = useState(false);
const [context, setContext] = useState<FrameContext>();
const [context, setContext] = useState<Context.FrameContext>();
const [isContextOpen, setIsContextOpen] = useState(false);
const [txHash, setTxHash] = useState<string | null>(null);
@ -124,9 +128,21 @@ export default function Demo(
console.log("primaryButtonClicked");
});
console.log("Calling ready");
sdk.actions.ready({});
// Set up a MIPD Store, and request Providers.
const store = createStore()
// Subscribe to the MIPD Store.
store.subscribe(providerDetails => {
console.log("PROVIDER DETAILS", providerDetails)
// => [EIP6963ProviderDetail, EIP6963ProviderDetail, ...]
})
};
if (sdk && !isSDKLoaded) {
console.log("Calling load");
setIsSDKLoaded(true);
load();
return () => {
@ -153,7 +169,6 @@ export default function Demo(
const result = await sdk.actions.addFrame();
if (result.added) {
if (result.notificationDetails) {
setNotificationDetails(result.notificationDetails);
}
@ -162,10 +177,15 @@ export default function Demo(
? `Added, got notificaton token ${result.notificationDetails.token} and url ${result.notificationDetails.url}`
: "Added, got no notification details"
);
} else {
setAddFrameResult(`Not added: ${result.reason}`);
}
} catch (error) {
if (error instanceof AddFrame.RejectedByUser) {
setAddFrameResult(`Not added: ${error.message}`);
}
if (error instanceof AddFrame.InvalidDomainManifest) {
setAddFrameResult(`Not added: ${error.message}`);
}
setAddFrameResult(`Error: ${error}`);
}
}, []);
@ -307,6 +327,15 @@ export default function Demo(
<Button onClick={openWarpcastUrl}>Open Warpcast Link</Button>
</div>
<div className="mb-4">
<div className="p-2 bg-gray-100 dark:bg-gray-800 rounded-lg my-2">
<pre className="font-mono text-xs whitespace-pre-wrap break-words max-w-[260px] overflow-x-">
sdk.actions.viewProfile
</pre>
</div>
<ViewProfile />
</div>
<div className="mb-4">
<div className="p-2 bg-gray-100 dark:bg-gray-800 rounded-lg my-2">
<pre className="font-mono text-xs whitespace-pre-wrap break-words max-w-[260px] overflow-x-">
@ -553,7 +582,7 @@ function SendEth() {
function SignIn() {
const [signingIn, setSigningIn] = useState(false);
const [signingOut, setSigningOut] = useState(false);
const [signInResult, setSignInResult] = useState<SignInResult>();
const [signInResult, setSignInResult] = useState<SignInCore.SignInResult>();
const [signInFailure, setSignInFailure] = useState<string>();
const { data: session, status } = useSession()
@ -638,6 +667,33 @@ function SignIn() {
);
}
function ViewProfile() {
const [fid, setFid] = useState('3');
return (
<>
<div>
<Label className="text-xs font-semibold text-gray-500 mb-1" htmlFor="view-profile-fid">Fid</Label>
<Input
id="view-profile-fid"
type="number"
value={fid}
className="mb-2"
onChange={(e) => {
setFid(e.target.value)
}}
step="1"
min="1"
/>
</div>
<Button
onClick={() => { sdk.actions.viewProfile({ fid: parseInt(fid) }) }}
>
View Profile
</Button>
</>
);
}
const renderError = (error: Error | null) => {
if (!error) return null;

View File

@ -0,0 +1,22 @@
import * as React from "react"
import { cn } from "~/lib/utils"
const Input = React.forwardRef<HTMLInputElement, React.ComponentProps<"input">>(
({ className, type, ...props }, ref) => {
return (
<input
type={type}
className={cn(
"flex h-10 w-full rounded-md border border-neutral-200 bg-white px-3 py-2 text-base ring-offset-white file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-neutral-950 placeholder:text-neutral-500 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-neutral-950 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm dark:border-neutral-800 dark:bg-neutral-950 dark:ring-offset-neutral-950 dark:file:text-neutral-50 dark:placeholder:text-neutral-400 dark:focus-visible:ring-neutral-300",
className
)}
ref={ref}
{...props}
/>
)
}
)
Input.displayName = "Input"
export { Input }

View File

@ -0,0 +1,26 @@
"use client"
import * as React from "react"
import * as LabelPrimitive from "@radix-ui/react-label"
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "~/lib/utils"
const labelVariants = cva(
"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
)
const Label = React.forwardRef<
React.ElementRef<typeof LabelPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root> &
VariantProps<typeof labelVariants>
>(({ className, ...props }, ref) => (
<LabelPrimitive.Root
ref={ref}
className={cn(labelVariants(), className)}
{...props}
/>
))
Label.displayName = LabelPrimitive.Root.displayName
export { Label }

6
src/lib/utils.ts Normal file
View File

@ -0,0 +1,6 @@
import { clsx, type ClassValue } from "clsx"
import { twMerge } from "tailwind-merge"
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}

View File

@ -1,6 +1,7 @@
import type { Config } from "tailwindcss";
export default {
darkMode: ["class"],
content: [
"./src/pages/**/*.{js,ts,jsx,tsx,mdx}",
"./src/components/**/*.{js,ts,jsx,tsx,mdx}",
@ -9,10 +10,15 @@ export default {
theme: {
extend: {
colors: {
background: "var(--background)",
foreground: "var(--foreground)",
background: 'var(--background)',
foreground: 'var(--foreground)'
},
borderRadius: {
lg: 'var(--radius)',
md: 'calc(var(--radius) - 2px)',
sm: 'calc(var(--radius) - 4px)'
}
}
},
},
plugins: [],
plugins: [require("tailwindcss-animate")],
} satisfies Config;

103
yarn.lock
View File

@ -134,13 +134,13 @@
qrcode "^1.5.3"
react-remove-scroll "^2.5.7"
"@farcaster/frame-core@0.0.20":
version "0.0.20"
resolved "https://registry.yarnpkg.com/@farcaster/frame-core/-/frame-core-0.0.20.tgz#2e872db2d17b20d12d602510b5dc6dfb39e942b6"
integrity sha512-MMHMy/wSFpCThJKaX+MKGZTZeAPDEMD2uXMsfRlQ/DrLtfWR7R8NuOjoPLGaipmPVNTzIBJm4BJ0+71zitdSGQ==
"@farcaster/frame-core@0.0.24":
version "0.0.24"
resolved "https://registry.yarnpkg.com/@farcaster/frame-core/-/frame-core-0.0.24.tgz#35c2403f561a74b6551e3032d6d57a730c3dc413"
integrity sha512-iO/Jxz6mZBVUoLIY753Id5Yhn6DHBakQkIBXf0mreAcnjPGCMvKx/0xKEM3ns3M801PqoX7VLYO4q+kKxYzQ0A==
dependencies:
ox "^0.4.0"
zod "^3.23.8"
ox "^0.4.4"
zod "^3.24.1"
"@farcaster/frame-core@^0.0.19":
version "0.0.19"
@ -150,6 +150,14 @@
ox "^0.4.0"
zod "^3.23.8"
"@farcaster/frame-core@^0.0.22":
version "0.0.22"
resolved "https://registry.yarnpkg.com/@farcaster/frame-core/-/frame-core-0.0.22.tgz#c5b91f3d7bb27b55873348b1b878472b3e5e5d5d"
integrity sha512-VervdgEXn3wfU+CLFsPMiLiOAXmXY4g+CPAcQ7g1771KW2SdfgLpOmHwvHvGRadfvvZxnPV84h1EwjooSvdsUA==
dependencies:
ox "^0.4.4"
zod "^3.24.1"
"@farcaster/frame-node@^0.0.7":
version "0.0.7"
resolved "https://registry.yarnpkg.com/@farcaster/frame-node/-/frame-node-0.0.7.tgz#cebbafa2f7def65c0800bdcca47ce86096e4bb4c"
@ -158,15 +166,15 @@
"@farcaster/frame-core" "^0.0.19"
ox "^0.4.0"
"@farcaster/frame-sdk@^0.0.21":
version "0.0.21"
resolved "https://registry.yarnpkg.com/@farcaster/frame-sdk/-/frame-sdk-0.0.21.tgz#f5d595003c5e88233cdf63e3793a35c4d6617413"
integrity sha512-FaeHdaIRQP6VqBtnwcrgggWcE+a/0hWzuIpp5NcnfYvo8a1JMpkOXspWFAa3fYfCyl9Dm9QF6jXt+T5tiALsPQ==
"@farcaster/frame-sdk@^0.0.26":
version "0.0.26"
resolved "https://registry.yarnpkg.com/@farcaster/frame-sdk/-/frame-sdk-0.0.26.tgz#2cf5c5e9e8ecdbdbc244e55f41129fc1caa9b88c"
integrity sha512-tOoJcJLXXezjmP0gg/MOU/mCjNdWyL+j99XMylYCovel1etDQjLovGamVex8A6eELryLZ4LElV9AIbxP/i9IfA==
dependencies:
"@farcaster/frame-core" "0.0.20"
"@farcaster/frame-core" "0.0.24"
comlink "^4.4.2"
eventemitter3 "^5.0.1"
ox "^0.4.0"
ox "^0.4.4"
"@farcaster/frame-wagmi-connector@^0.0.6":
version "0.0.6"
@ -856,6 +864,32 @@
resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33"
integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==
"@radix-ui/react-compose-refs@1.1.1":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.1.tgz#6f766faa975f8738269ebb8a23bad4f5a8d2faec"
integrity sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw==
"@radix-ui/react-label@^2.1.1":
version "2.1.1"
resolved "https://registry.yarnpkg.com/@radix-ui/react-label/-/react-label-2.1.1.tgz#f30bd577b26873c638006e4f65761d4c6b80566d"
integrity sha512-UUw5E4e/2+4kFMH7+YxORXGWggtY6sM8WIwh5RZchhLuUg2H1hc98Py+pr8HMz6rdaYrK2t296ZEjYLOCO5uUw==
dependencies:
"@radix-ui/react-primitive" "2.0.1"
"@radix-ui/react-primitive@2.0.1":
version "2.0.1"
resolved "https://registry.yarnpkg.com/@radix-ui/react-primitive/-/react-primitive-2.0.1.tgz#6d9efc550f7520135366f333d1e820cf225fad9e"
integrity sha512-sHCWTtxwNn3L3fH8qAfnF3WbUZycW93SM1j3NFDzXBiz8D6F5UTTy8G1+WFEaiCdvCVRJWj6N2R4Xq6HdiHmDg==
dependencies:
"@radix-ui/react-slot" "1.1.1"
"@radix-ui/react-slot@1.1.1":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@radix-ui/react-slot/-/react-slot-1.1.1.tgz#ab9a0ffae4027db7dc2af503c223c978706affc3"
integrity sha512-RApLLOcINYJA+dMVbOju7MYv1Mb2EBp2nH4HdDzXTSyaR5optlm6Otrz1euW3HbdOR8UmmFK06TD+A9frYWv+g==
dependencies:
"@radix-ui/react-compose-refs" "1.1.1"
"@rtsao/scc@^1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@rtsao/scc/-/scc-1.1.0.tgz#927dd2fae9bc3361403ac2c7a00c32ddce9ad7e8"
@ -1951,6 +1985,13 @@ citty@^0.1.5, citty@^0.1.6:
dependencies:
consola "^3.2.3"
class-variance-authority@^0.7.1:
version "0.7.1"
resolved "https://registry.yarnpkg.com/class-variance-authority/-/class-variance-authority-0.7.1.tgz#4008a798a0e4553a781a57ac5177c9fb5d043787"
integrity sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==
dependencies:
clsx "^2.1.1"
client-only@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/client-only/-/client-only-0.0.1.tgz#38bba5d403c41ab150bff64a95c85013cf73bca1"
@ -1979,6 +2020,11 @@ clsx@^1.2.1:
resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.2.1.tgz#0ddc4a20a549b59c93a4116bb26f5294ca17dc12"
integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==
clsx@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.1.1.tgz#eed397c9fd8bd882bfb18deab7102049a2f32999"
integrity sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==
color-convert@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
@ -3694,6 +3740,11 @@ lru-cache@^6.0.0:
dependencies:
yallist "^4.0.0"
lucide-react@^0.469.0:
version "0.469.0"
resolved "https://registry.yarnpkg.com/lucide-react/-/lucide-react-0.469.0.tgz#f16936ca6521482fef754a7eabb310e6c68e1482"
integrity sha512-28vvUnnKQ/dBwiCQtwJw7QauYnE7yd2Cyp4tTTJpvglX4EMpbflcdBgrgToX2j71B3YvugK/NH3BGUk+E/p/Fw==
media-query-parser@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/media-query-parser/-/media-query-parser-2.0.2.tgz#ff79e56cee92615a304a1c2fa4f2bd056c0a1d29"
@ -4106,6 +4157,19 @@ ox@^0.4.2:
abitype "^1.0.6"
eventemitter3 "5.0.1"
ox@^0.4.4:
version "0.4.4"
resolved "https://registry.yarnpkg.com/ox/-/ox-0.4.4.tgz#9d1757c026406e60097680d98ffedf9e3bc1fa0b"
integrity sha512-oJPEeCDs9iNiPs6J0rTx+Y0KGeCGyCAA3zo94yZhm8G5WpOxrwUtn2Ie/Y8IyARSqqY/j9JTKA3Fc1xs1DvFnw==
dependencies:
"@adraffy/ens-normalize" "^1.10.1"
"@noble/curves" "^1.6.0"
"@noble/hashes" "^1.5.0"
"@scure/bip32" "^1.5.0"
"@scure/bip39" "^1.4.0"
abitype "^1.0.6"
eventemitter3 "5.0.1"
p-limit@^2.2.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1"
@ -5028,6 +5092,16 @@ system-architecture@^0.1.0:
resolved "https://registry.yarnpkg.com/system-architecture/-/system-architecture-0.1.0.tgz#71012b3ac141427d97c67c56bc7921af6bff122d"
integrity sha512-ulAk51I9UVUyJgxlv9M6lFot2WP3e7t8Kz9+IS6D4rVba1tR9kON+Ey69f+1R4Q8cd45Lod6a4IcJIxnzGc/zA==
tailwind-merge@^2.6.0:
version "2.6.0"
resolved "https://registry.yarnpkg.com/tailwind-merge/-/tailwind-merge-2.6.0.tgz#ac5fb7e227910c038d458f396b7400d93a3142d5"
integrity sha512-P+Vu1qXfzediirmHOC3xKGAYeZtPcV9g76X+xg2FD4tYgR71ewMA35Y3sCz3zhiN/dwefRpJX0yBcgwi1fXNQA==
tailwindcss-animate@^1.0.7:
version "1.0.7"
resolved "https://registry.yarnpkg.com/tailwindcss-animate/-/tailwindcss-animate-1.0.7.tgz#318b692c4c42676cc9e67b19b78775742388bef4"
integrity sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==
tailwindcss@^3.4.1:
version "3.4.15"
resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.4.15.tgz#04808bf4bf1424b105047d19e7d4bfab368044a9"
@ -5594,6 +5668,11 @@ zod@^3.23.8:
resolved "https://registry.yarnpkg.com/zod/-/zod-3.24.0.tgz#babb32313f7c5f4a99812feee806d186b4f76bde"
integrity sha512-Hz+wiY8yD0VLA2k/+nsg2Abez674dDGTai33SwNvMPuf9uIrBC9eFgIMQxBBbHFxVXi8W+5nX9DcAh9YNSQm/w==
zod@^3.24.1:
version "3.24.1"
resolved "https://registry.yarnpkg.com/zod/-/zod-3.24.1.tgz#27445c912738c8ad1e9de1bea0359fa44d9d35ee"
integrity sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==
zustand@5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/zustand/-/zustand-5.0.0.tgz#71f8aaecf185592a3ba2743d7516607361899da9"