I need to correct my previous guide on creating Farcaster mini apps using various smart contract providers. It turns out I was wrong about Manifold - it's definitely possible to integrate it successfully!
After gaining a LOT more experience with smart contracts and getting some encouragement from Horsefacts, I revisited everything and figured it out. I sincerely apologize for incorrectly stating that Manifold couldn't be used for this purpose!!!
The solution I'm sharing has been tested only with ERC-1155 tokens
I haven't tested with ERC-721 tokens - this may require modifications to the Manifold contract or other significant changes
I've prepared examples for both ETH-only mints and combined USDC+ETH fee mints
Ready to see how it works? I've created a demo Replit that demonstrates the mint in action.
Click the button below to get access to the Repl and let me show you how to do it!
Open the config.ts file in your Replit editor. This is where you'll make all your changes!
This section defines how your NFT is displayed.
// Inside config.ts
export const mintMetadata = {
name: "YOUR NFT NAME", // <-- EDIT THIS
description: "YOUR NFT DESCRIPTION", // <-- EDIT THIS
imageUrl: "/your_nft_image.png", // <-- EDIT THIS (path to your image in the public folder, or a full URL)
creator: {
name: "YOUR CREATOR NAME", // <-- EDIT THIS
fid: 12345, // Your Farcaster FID (optional) // <-- EDIT THIS
profileImageUrl: "YOUR_PROFILE_IMAGE_URL", // (optional) // <-- EDIT THIS
},
chain: "Base", // Or "Ethereum", "Polygon", etc. Ensure it matches `base` import below if using Base.
priceUsdc: "1.0", // <-- **CRITICAL: Set the USDC price of your mint (e.g., "1.0" for 1 USDC)**
manifoldFeeEth: "0.0005", // <-- **CRITICAL: Set the ETH fee (e.g., Manifold's platform fee)**
startsAt: null, // Optional: ISO date string for start time, or null
endsAt: null, // Optional: ISO date string for end time, or null
isMinting: true,
} as const;Update name, description, imageUrl, and creator details.
IMPORTANT: set priceUsdc to the exact USDC amount for one mint. If this doesn't match what the smart contract expects, it won't mint!
IMPORTANT: set manifoldFeeEth to the exact ETH fee required per mint. If this doesn't match what the smart contract expects, it won't mint!
This is the most critical part for interacting with your specific Manifold claim.
// Inside config.ts
export const contractConfig = {
// Address of the MANIFOLD LAZYPAYABLECLAIM contract
address: "0x26BBEA7803DcAc346D5F5f135b57Cf2c752A02bE" as Address,
chain: base, // This should match the chain in mintMetadata and your wagmi/viem setup.
// e.g., import { mainnet } from "viem/chains"; and use `mainnet` if on Ethereum.
// Address of the Creator Contract (the NFT contract Manifold will mint on)
creatorContractAddress: "0xYOUR_CREATOR_NFT_CONTRACT_ADDRESS" as Address, // <-- **CRITICAL: REPLACE THIS**
// The instanceId for your specific claim on the Manifold contract
instanceId: 1, // <-- **CRITICAL: REPLACE with your actual claim instanceId**
// Your mint's token ID.
mintIndex: 1, // <-- **CRITICAL: REPLACE if different**
abi: [ /* ... ABI for Manifold mint and getClaim ... */ ] as const, // Usually no change needed if using the standard Manifold ABI
} as const;
chain: Ensure this (e.g., base) matches the chain your claim is on.
creatorContractAddress: Replace 0xYOUR_CREATOR_NFT_CONTRACT_ADDRESS with the address of the underlying NFT contract that Manifold will mint tokens on for this claim.
instanceId: Replace 1 with the correct instanceId of your claim. You find this on your Manifold dashboard for the specific claim.
mintIndex: Replace 1 if your desired token ID within the claim is not the first one.
// Inside config.ts
export const embedConfig = {
version: "next",
imageUrl: "https://YOUR_REPLIT_URL/nft_image_for_frame.png", // <-- EDIT THIS (URL to image for frame preview)
button: {
title: "Mint",
action: {
type: "launch_frame",
name: "NFT Mint",
url: "https://YOUR_REPLIT_URL/", // <-- EDIT THIS (URL that serves the minting frame/app)
},
},
} as const;Update imageUrl to a publicly accessible URL for the image shown in the Farcaster frame cast.
Update url in action to the URL of your Replit app that serves the minting interface.
Ensure your Replit is running by pressing the Run button.
Open your app using the dev URL in the Farcaster Developer tools.
Attempt the mint. It should first ask for USDC approval and then, after approval, the button should change to "Mint NFT". Clicking it again should initiate the mint transaction.
"User Rejected" Errors: Double-check every address and ID in
contractConfig. Ensure your wallet is on the correct network and has enough USDC (for the price) and ETH (for the Manifold fee + gas for two transactions).Console Logs: Open your browser's developer console. The
CollectButton.tsxhas console.log statements that can help you trace the process.Block Explorer: Use Basescan or another block explorer to check the status of your approval and mint transactions if they are submitted. Verify the cost and erc-20 token for your claim by trying a test transaction from your wallet.
When adapting the frontend for a Manifold claim priced only in ETH versus one priced in USDC with an additional ETH fee, the main changes revolve around how payments and approvals are handled.
I've included ethonly_mintconfig.ts and ethonly_connectbutton.ts in the Repl.
Copy these files into config.ts and connectButton.tsx. Update the values in config.ts accordingly.
USDC + ETH Fee Version:
mintMetadataincludespriceUsdcandmanifoldFeeEthseparately.Requires a
usdcContractConfigsection with the USDC token's address, ABI (forapproveandallowance), and decimals.The main
configexport includesusdcContract.
ETH-Only Version:
mintMetadataincludes a singlepriceEthwhich represents the total cost of the mint (including any platform fees if the claim is configured that way on Manifold). THIS IS VERY IMPORTANT.No
usdcContractConfigis needed.The main
configexport does not includeusdcContract.The
contractConfig.abifor the Manifold claim contract can often remain the same. The Manifold contract itself determines how to interpret the payment based on its on-chain setup (i.e., if it's configured for ETH payment, it expectsmsg.value; if for ERC20, it expects an approval and then usestransferFrom). WhengetClaim()is called for an ETH-only claim, theerc20field in the returned claim data should beaddress(0)(the zero address), and thecostfield should represent the ETH price in wei.
USDC + ETH Fee Version:
Two-Step Process:
Approve: Checks USDC allowance. If insufficient, it calls the
approvefunction on the USDC contract, asking the user to allow the Manifold claim contract to spend their USDC. ThisCollectButton.tsxversion usesMAX_UINT256for the approval amount.Mint: Once approved, it calls the
mintfunction on the Manifold claim contract. Thevaluesent with this transaction is only themanifoldFeeEth. The Manifold contract then internally uses the prior approval to pull thepriceUsdcfrom the user's wallet.
State Management: More complex state is needed to track
needsApproval,isCheckingOrProcessingAllowance, and thecurrentAction(approve or mint).Hooks: Uses
usePublicClientto read allowance.
ETH-Only Version:
One-Step Process:
Mint: Directly calls the
mintfunction on the Manifold claim contract. Thevaluesent with this transaction is the totalpriceEth(converted to wei).
State Management: Simpler state, as there's no approval flow to manage.
Hooks: No need for
usePublicClientfor allowance checks.Props: The component takes a single
priceEthprop.
USDC + ETH Fee Version: Users might encounter two separate wallet transaction prompts: one for approving USDC spend (if it's their first time or previous approval was insufficient/revoked) and a second for the actual mint.
ETH-Only Version: Users encounter a single wallet transaction prompt for the mint, which includes the total ETH cost.
That's it! By carefully updating these configuration values, you should be able to use the provided frontend components for your Manifold 1155s.
