Farcaster Frames
In this guide, we will create a Frames app that lets users mint an NFT on Zora using DEGEN on Base.
Here's the NFT contract we'll use: 0xb88f2f291d...8755accc9ed9c77ce. The contract has a mintFor
function that allows users to mint by sending ETH to the contract on Zora.
We'll use the Glide to let users pay for the minting using DEGEN on Base.
Setup
We'll use the Frog.fm framework to build a Farcaster Frames app. But, you can use any framework you like. Glide works with the underlying Frames spec.
Steps
1. Create a frog app
If you haven't already, create a Frog app. You can learn more about Frog here.
npm init frog
2. Install Glide & viem
npm install @paywithglide/glide-js viem
3. Create a Glide config
import { createGlideConfig, chains } from "@paywithglide/glide-js";
export const config = createGlideConfig({
projectId: "your project id",
// Lists the chains where payments will be accepted
chains: [chains.base],
});
4. Create the default frame
The default frame shows an image of the NFT and a button to mint the NFT.
The button has a target of /mint
, which we'll use to create the Glide session for minting the NFT.
It also has an action set to /tx-status
, which we'll use to show the transaction status once the user has paid.
app.frame("/", (c) => {
return c.res({
image:
"https://storage.withfabric.xyz/loom/cff20f6d-e485-4271-9f54-47cf53334abd.png",
imageAspectRatio: "1:1",
intents: [
<Button.Transaction target="/mint">Mint with Degen</Button.Transaction>,
],
action: "/tx-status",
});
});
5. Handle the /mint
route
The mint route creates a Glide session to mint the NFT on Zora using DEGEN on Base.
The Glide session contains an unsigned payment transaction for making the payment using DEGEN. This route returns the payment transaction to the user so the Farcaster client can let the user sign and send it.
app.transaction("/mint", async (c) => {
const { address } = c;
const { unsignedTransaction } = await createSession(config, {
chainId: chains.zora.id,
account: address,
paymentCurrency: currencies.degen,
abi: fabricABI,
address: "0xb88f2f291d796de8b44993b8755accc9ed9c77ce",
functionName: "mintFor",
args: [address, 100000000000n],
value: 100000000000n,
});
if (!unsignedTransaction) {
throw new Error("missing unsigned transaction");
}
// Return the payment transaction to the user
return c.send({
chainId: `eip155:${chains.base.id}`,
to: unsignedTransaction.to,
data: unsignedTransaction.input,
value: hexToBigInt(unsignedTransaction.value),
});
});
6. Handle the /tx-status
route
In this route, we'll use the payment transaction hash provided to us by the Farcaster client to get the Glide session status and show the user the status of the transaction.
If the transaction is pending, we'll show a button to refresh the status.
app.frame("/tx-status", async (c) => {
const { transactionId, buttonValue } = c;
// The payment transaction hash is passed with transactionId if the user just completed the payment. If the user hit the "Refresh" button, the transaction hash is passed with buttonValue.
const hash = transactionId || buttonValue;
if (!txHash) {
throw new Error("missing transaction hash");
}
try {
let session = await getSessionByPaymentTransaction(config, {
chainId: chains.base.id,
hash,
});
// Wait for the session to complete. It can take a few seconds
session = await waitForSession(config, session.sessionId);
return c.res({
image: (
<div
style={{
display: "flex",
justifyContent: "center",
fontSize: 64,
marginTop: "200px",
}}
>
Mint complete!
</div>
),
intents: [
<Button.Link
href={`https://explorer.zora.energy/tx/${session.sponsoredTransactionHash}`}
>
View on Zora
</Button.Link>,
],
});
} catch (e) {
// If the session is not found, it means the payment is still pending.
// Let the user know that the payment is pending and show a button to refresh the status.
return c.res({
image: (
<div
style={{
display: "flex",
justifyContent: "center",
fontSize: 44,
marginTop: "200px",
}}
>
Waiting for payment confirmation..
</div>
),
intents: [
<Button value={hash} action="/tx-status">
Refresh
</Button>,
],
});
}
});
Success
You've successfully integrated Glide with Farcaster Frames to let users pay for minting an NFT using DEGEN on Base.