forked from mito-systems/sol-mem-gen
Add check for phantom wallet before throwing error #1
6
.env.example
Normal file
6
.env.example
Normal file
@ -0,0 +1,6 @@
|
||||
FAL_AI_KEY=
|
||||
|
||||
NEXT_PUBLIC_MTM_TOKEN_MINT=97RggLo3zV5kFGYW4yoQTxr4Xkz4Vg2WPHzNYXXWpump
|
||||
NEXT_PUBLIC_PAYMENT_RECEIVER_ADDRESS=FFDx3SdAEeXrp6BTmStB4BDHpctGsaasZq4FFcowRobY
|
||||
NEXT_PUBLIC_SOLANA_RPC_URL=https://young-radial-orb.solana-mainnet.quiknode.pro/67612b364664616c29514e551bf5de38447ca3d4
|
||||
NEXT_PUBLIC_SOLANA_WEBSOCKET_URL=wss://young-radial-orb.solana-mainnet.quiknode.pro/67612b364664616c29514e551bf5de38447ca3d4
|
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
node_modules
|
||||
.next
|
||||
|
||||
.env
|
@ -15,7 +15,7 @@ const Page: React.FC = (): React.ReactElement => {
|
||||
type: null
|
||||
})
|
||||
|
||||
const handleConnect = async (walletType: WalletType): Promise<void> => {
|
||||
const handleConnect = async (walletType: WalletType): Promise<void> => {
|
||||
try {
|
||||
const newWalletState = await connectWallet(walletType)
|
||||
setWalletState(newWalletState)
|
||||
@ -29,11 +29,13 @@ const Page: React.FC = (): React.ReactElement => {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const handleFluxGeneration = (modelId: string, cost: number) => {
|
||||
return async (prompt: string): Promise<FluxGenerationResult> => {
|
||||
if (!walletState.connected || !walletState.publicKey || !window.solflare) {
|
||||
return { error: 'Wallet not connected' }
|
||||
const type = walletState.type;
|
||||
if (!walletState.connected || !walletState.publicKey ||
|
||||
(type === 'phantom' && !window.phantom) ||
|
||||
(type === 'solflare' && !window.solflare)) {
|
||||
return { error: 'Wallet not connected' }
|
||||
}
|
||||
|
||||
// Process payment first
|
||||
@ -63,7 +65,7 @@ const Page: React.FC = (): React.ReactElement => {
|
||||
<p className="text-gray-400 text-lg mb-8">
|
||||
Use MTM to generate memes
|
||||
</p>
|
||||
|
||||
|
||||
<WalletHeader
|
||||
walletState={walletState}
|
||||
onConnect={handleConnect}
|
||||
@ -82,7 +84,7 @@ const Page: React.FC = (): React.ReactElement => {
|
||||
onGenerate={handleFluxGeneration(model.modelId, model.cost)}
|
||||
/>
|
||||
))}
|
||||
|
||||
|
||||
{/* Coming Soon Card */}
|
||||
<div className="relative bg-gray-800/50 backdrop-blur-lg rounded-2xl shadow-xl border border-gray-700/50 overflow-hidden group">
|
||||
<div className="absolute inset-0 bg-gradient-to-br from-yellow-500/10 to-orange-500/10 opacity-50"></div>
|
||||
@ -98,12 +100,11 @@ const Page: React.FC = (): React.ReactElement => {
|
||||
<span className="text-orange-300 text-sm">TBD</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-6">
|
||||
<button
|
||||
disabled
|
||||
className="w-full bg-gradient-to-r from-yellow-500/50 to-orange-500/50
|
||||
text-white/50 font-semibold py-4 px-6 rounded-xl
|
||||
className="w-full bg-gradient-to-r from-yellow-500/50 to-orange-500/50
|
||||
text-white/50 font-semibold py-4 px-6 rounded-xl
|
||||
cursor-not-allowed opacity-50"
|
||||
>
|
||||
Coming Soon
|
||||
|
@ -43,7 +43,7 @@ const AIServiceCard: React.FC<AIServiceCardProps> = ({
|
||||
|
||||
try {
|
||||
const result = await onGenerate(inputText)
|
||||
|
||||
|
||||
if (result.error) {
|
||||
setGenerationState({
|
||||
...generationState,
|
||||
@ -91,8 +91,8 @@ const AIServiceCard: React.FC<AIServiceCardProps> = ({
|
||||
onChange={(e) => setInputText(e.target.value)}
|
||||
placeholder="Enter your prompt here..."
|
||||
disabled={!isWalletConnected}
|
||||
className="w-full bg-gray-900/50 text-gray-100 border border-gray-700 rounded-xl p-4
|
||||
placeholder-gray-500 focus:border-green-500 focus:ring-2 focus:ring-green-500/20
|
||||
className="w-full bg-gray-900/50 text-gray-100 border border-gray-700 rounded-xl p-4
|
||||
placeholder-gray-500 focus:border-green-500 focus:ring-2 focus:ring-green-500/20
|
||||
focus:outline-none min-h-[120px] transition-all duration-200
|
||||
disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
rows={4}
|
||||
@ -100,9 +100,9 @@ const AIServiceCard: React.FC<AIServiceCardProps> = ({
|
||||
<button
|
||||
onClick={handleGenerate}
|
||||
disabled={!isWalletConnected || generationState.loading || !inputText}
|
||||
className="w-full bg-gradient-to-r from-green-500 to-emerald-500 hover:from-green-600
|
||||
hover:to-emerald-600 text-white font-semibold py-4 px-6 rounded-xl
|
||||
transition-all duration-200 shadow-lg hover:shadow-green-500/25
|
||||
className="w-full bg-gradient-to-r from-green-500 to-emerald-500 hover:from-green-600
|
||||
hover:to-emerald-600 text-white font-semibold py-4 px-6 rounded-xl
|
||||
transition-all duration-200 shadow-lg hover:shadow-green-500/25
|
||||
disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:shadow-none"
|
||||
>
|
||||
{generationState.loading ? 'Processing...' : `Pay ${tokenCost} MTM & Generate`}
|
||||
|
@ -16,13 +16,13 @@ export const FLUX_MODELS: FluxModelConfig[] = [
|
||||
modelId: "fal-ai/flux/schnell",
|
||||
name: "Schnell",
|
||||
description: "Fast meme generator",
|
||||
cost: 300
|
||||
cost: 300
|
||||
},
|
||||
{
|
||||
modelId: "fal-ai/recraft-v3",
|
||||
name: "Recraft",
|
||||
description: "Advanced meme generator",
|
||||
cost: 400
|
||||
cost: 400
|
||||
},
|
||||
{
|
||||
modelId: "fal-ai/stable-diffusion-v35-large",
|
||||
|
@ -1,17 +1,16 @@
|
||||
import { Connection, PublicKey, Transaction, SystemProgram } from '@solana/web3.js'
|
||||
import {
|
||||
TOKEN_PROGRAM_ID,
|
||||
createTransferInstruction,
|
||||
getAssociatedTokenAddress,
|
||||
import {
|
||||
TOKEN_PROGRAM_ID,
|
||||
createTransferInstruction,
|
||||
createAssociatedTokenAccountInstruction,
|
||||
ASSOCIATED_TOKEN_PROGRAM_ID
|
||||
} from '@solana/spl-token'
|
||||
import { WalletType } from './types'
|
||||
|
||||
const MTM_TOKEN_MINT: string = '97RggLo3zV5kFGYW4yoQTxr4Xkz4Vg2WPHzNYXXWpump'
|
||||
const PAYMENT_RECEIVER_ADDRESS: string = 'FFDx3SdAEeXrp6BTmStB4BDHpctGsaasZq4FFcowRobY'
|
||||
const SOLANA_RPC_URL: string = 'https://young-radial-orb.solana-mainnet.quiknode.pro/67612b364664616c29514e551bf5de38447ca3d4'
|
||||
const SOLANA_WEBSOCKET_URL: string = 'wss://young-radial-orb.solana-mainnet.quiknode.pro/67612b364664616c29514e551bf5de38447ca3d4'
|
||||
const MTM_TOKEN_MINT = process.env.NEXT_PUBLIC_MTM_TOKEN_MINT;
|
||||
const PAYMENT_RECEIVER_ADDRESS = process.env.NEXT_PUBLIC_PAYMENT_RECEIVER_ADDRESS;
|
||||
const SOLANA_RPC_URL = process.env.NEXT_PUBLIC_SOLANA_RPC_URL;
|
||||
const SOLANA_WEBSOCKET_URL = process.env.NEXT_PUBLIC_SOLANA_WEBSOCKET_URL;
|
||||
|
||||
const connection = new Connection(
|
||||
SOLANA_RPC_URL,
|
||||
@ -52,7 +51,7 @@ export async function processMTMPayment(
|
||||
): Promise<PaymentResult> {
|
||||
try {
|
||||
let wallet: WalletAdapter | null = null;
|
||||
|
||||
|
||||
if (walletType === 'phantom') {
|
||||
wallet = window.phantom?.solana || null;
|
||||
} else if (walletType === 'solflare') {
|
||||
@ -150,8 +149,8 @@ export async function processMTMPayment(
|
||||
return { success: true }
|
||||
} catch (error) {
|
||||
console.error('Payment error:', error)
|
||||
return {
|
||||
success: false,
|
||||
return {
|
||||
success: false,
|
||||
error: error instanceof Error ? error.message : 'Payment failed'
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user