
Research
Two Malicious Rust Crates Impersonate Popular Logger to Steal Wallet Keys
Socket uncovers malicious Rust crates impersonating fast_log to steal Solana and Ethereum wallet keys from source code.
@coinbase/onchainkit
Advanced tools
<source media="(prefers-color-scheme: dark)" srcset="./docs/logo-v-0-5.png"> </
OnchainKit is a collection of tools to build world-class onchain apps with CSS, React, and Typescript.
Add OnchainKit to your project, install the required packages.
# Use Yarn
yarn add @coinbase/onchainkit
# Use NPM
npm install @coinbase/onchainkit
# Use PNPM
pnpm add @coinbase/onchainkit
OnchainKit is divided into various theme utilities and components that are available for your use:
A Frame transforms any cast into an interactive app.
Creating a frame is easy: select an image and add clickable buttons. When a button is clicked, you receive a callback and can send another image with more buttons. To learn more, check out "Farcaster Frames Official Documentation".
React component:
<FrameMetadata />
: This component renders all the Frame metadata elements in one place.Typescript utilities:
getFrameHtmlResponse()
: Retrieves the Frame HTML for your HTTP responses.getFrameMessage()
: Retrieves a valid Frame message from the Frame Signature Packet.getFrameMetadata()
: Retrieves valid Frame metadata for your initial HTML page with Next.js App Routing.<FrameMetadata />
This component is utilized for incorporating Frame metadata elements into the React page.
Note: If you are using Next.js with App routing, it is recommended to use getFrameMetadata
instead.
export default function HomePage() {
return (
...
<FrameMetadata
buttons={[
{
label: 'Tell me the story',
},
{
label: 'Redirect to cute dog pictures',
action: 'post_redirect',
},
]}
image="https://zizzamia.xyz/park-1.png"
input={{
text: 'Tell me a boat story',
}}
post_url="https://zizzamia.xyz/api/frame"
/>
...
);
}
@Props
type Button = {
label: string;
action?: 'post' | 'post_redirect';
};
type InputMetadata = {
text: string;
};
type FrameMetadataType = {
// A list of strings which are the label for the buttons in the frame (max 4 buttons).
buttons?: [Button, ...Button[]];
// An image which must be smaller than 10MB and should have an aspect ratio of 1.91:1
image: string;
// The text input to use for the Frame.
input?: InputMetadata;
// A valid POST URL to send the Signature Packet to.
post_url?: string;
// A period in seconds at which the app should expect the image to update.
refresh_period?: number;
};
@Returns
<meta name="fc:frame" content="vNext" />
<meta name="fc:frame:button:1" content="Tell me the story" />
<meta name="fc:frame:button:2" content="Redirect to cute dog pictures" />
<meta name="fc:frame:button:2:action" content="post_redirect" />
<meta name="fc:frame:image" content="https://zizzamia.xyz/park-1.png" />
<meta name="fc:frame:input:text" content="Tell me a boat story" />
<meta name="fc:frame:post_url" content="https://zizzamia.xyz/api/frame" />
When you need to send an HTML Frame Response, the getFrameHtmlResponse
method is here to assist you.
It generates a valid HTML string response with a frame and utilizes FrameMetadata
types for page metadata. This eliminates the need to manually create server-side HTML strings.
// Step 1. import getFrameHtmlResponse from @coinbase/onchainkit
import { getFrameHtmlResponse } from '@coinbase/onchainkit';
import { NextRequest, NextResponse } from 'next/server';
async function getResponse(req: NextRequest): Promise<NextResponse> {
// Step 2. Build your Frame logic
...
return new NextResponse(
// Step 3. Use getFrameHtmlResponse to create a Frame response
getFrameHtmlResponse({
buttons: [
{
label: `We love BOAT`,
},
],
image:'https://build-onchain-apps.vercel.app/release/v-0-17.png',
post_url: 'https://build-onchain-apps.vercel.app/api/frame',
}),
);
}
export async function POST(req: NextRequest): Promise<Response> {
return getResponse(req);
}
@Param
type Button = {
label: string;
action?: 'post' | 'post_redirect';
};
type InputMetadata = {
text: string;
};
type FrameMetadataType = {
// A list of strings which are the label for the buttons in the frame (max 4 buttons).
buttons?: [Button, ...Button[]];
// An image which must be smaller than 10MB and should have an aspect ratio of 1.91:1
image: string;
// The text input to use for the Frame.
input?: InputMetadata;
// A valid POST URL to send the Signature Packet to.
post_url?: string;
// A period in seconds at which the app should expect the image to update.
refresh_period?: number;
};
@Returns
type FrameHTMLResponse = string;
When a user interacts with your Frame, you receive a JSON message called the "Frame Signature Packet". Decode and validate this message using the getFrameMessage
function.
You can also use getFrameMessage
to access useful information such as:
Note that if the message
is not valid, it will be undefined.
// Step 1. import getFrameMessage from @coinbase/onchainkit
import { FrameRequest, getFrameMessage } from '@coinbase/onchainkit';
import { NextRequest, NextResponse } from 'next/server';
async function getResponse(req: NextRequest): Promise<NextResponse> {
// Step 2. Read the body from the Next Request
const body: FrameRequest = await req.json();
// Step 3. Validate the message
const { isValid, message } = await getFrameMessage(body , {
neynarApiKey: 'NEYNAR_ONCHAIN_KIT'
});
// Step 4. Determine the experience based on the validity of the message
if (isValid) {
// the message is valid
} else {
// sorry, the message is not valid and it will be undefined
}
...
}
export async function POST(req: NextRequest): Promise<Response> {
return getResponse(req);
}
@Param
// The Frame Signature Packet body
type FrameMessage = {
body: FrameRequest;
messageOptions?: FrameMessageOptions;
};
type FrameMessageOptions =
| {
// The API key to use for validation. Default: NEYNAR_ONCHAIN_KIT
neynarApiKey?: string;
// Whether to cast the reaction context. Default: true
castReactionContext?: boolean;
// Whether to follow the context. Default: true
followContext?: boolean;
}
| undefined;
@Returns
type Promise<FrameValidationResponse>;
type FrameValidationResponse =
| { isValid: true; message: FrameValidationData }
| { isValid: false; message: undefined };
interface FrameValidationData {
button: number; // Number of the button clicked
following: boolean; // Indicates if the viewer clicking the frame follows the cast author
input: string; // Text input from the viewer typing in the frame
interactor: {
fid: number; // Viewer Farcaster ID
custody_address: string; // Viewer custody address
verified_accounts: string[]; // Viewer account addresses
};
liked: boolean; // Indicates if the viewer clicking the frame liked the cast
raw: NeynarFrameValidationInternalModel;
recasted: boolean; // Indicates if the viewer clicking the frame recasted the cast
valid: boolean; // Indicates if the frame is valid
}
With Next.js App routing, use the getFrameMetadata()
inside your page.ts
to get the metadata need it for your Frame.
// Step 1. import getFrameMetadata from @coinbase/onchainkit
import { getFrameMetadata } from '@coinbase/onchainkit';
import type { Metadata } from 'next';
import HomePage from './home';
// Step 2. Use getFrameMetadata to shape your Frame metadata
const frameMetadata = getFrameMetadata({
buttons: [
{
label: 'We love BOAT',
},
],
image: 'https://build-onchain-apps.vercel.app/release/v-0-17.png',
post_url: 'https://build-onchain-apps.vercel.app/api/frame',
});
// Step 3. Add your metadata in the Next.js metadata utility
export const metadata: Metadata = {
manifest: '/manifest.json',
other: {
...frameMetadata
},
};
export default function Page() {
return <HomePage />;
}
@Param
type Button = {
label: string;
action?: 'post' | 'post_redirect';
};
type InputMetadata = {
text: string;
};
type FrameMetadataType = {
// A list of strings which are the label for the buttons in the frame (max 4 buttons).
buttons?: [Button, ...Button[]];
// An image which must be smaller than 10MB and should have an aspect ratio of 1.91:1
image: string;
// The text input to use for the Frame.
input?: InputMetadata;
// A valid POST URL to send the Signature Packet to.
post_url?: string;
// A period in seconds at which the app should expect the image to update.
refresh_period?: number;
};
@Returns
type FrameMetadataResponse = Record<string, string>;
The Name
component is used to display ENS names associated with Ethereum addresses. When an ENS name is not available, it defaults to showing a truncated version of the address.
import { Name } from '@coinbase/onchainkit';
<Name address="0x1234567890abcdef1234567890abcdef12345678" sliced={false} />;
@Props
type UseName = {
// Ethereum address to be resolved from ENS.
address: Address;
// Optional CSS class for custom styling.
className?: string;
// Determines if the address should be sliced when no ENS name is available.
sliced?: boolean;
// Additional HTML attributes for the span element.
props?: React.HTMLAttributes<HTMLSpanElement>;
};
OnchainKit is all about community; for any questions, feel free to:
![]() Leonardo Zizzamia |
![]() Rob Polak |
![]() Alvaro Raminelli |
![]() Taylor Caldwell |
![]() Chris Nascone |
![]() Wesley Pickett |
This project is licensed under the MIT License - see the LICENSE.md file for details
FAQs
Unknown package
The npm package @coinbase/onchainkit receives a total of 10,638 weekly downloads. As such, @coinbase/onchainkit popularity was classified as popular.
We found that @coinbase/onchainkit demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Socket uncovers malicious Rust crates impersonating fast_log to steal Solana and Ethereum wallet keys from source code.
Research
A malicious package uses a QR code as steganography in an innovative technique.
Research
/Security News
Socket identified 80 fake candidates targeting engineering roles, including suspected North Korean operators, exposing the new reality of hiring as a security function.