mirror of
https://github.com/neynarxyz/create-farcaster-mini-app.git
synced 2025-11-16 08:08:56 -05:00
Merge branch 'main' into mp/alt-sign
This commit is contained in:
commit
45f8b980b9
@ -388,10 +388,9 @@ export async function init(projectName = null, autoAcceptDefaults = false) {
|
|||||||
packageJson.dependencies = {
|
packageJson.dependencies = {
|
||||||
"@farcaster/auth-client": ">=0.3.0 <1.0.0",
|
"@farcaster/auth-client": ">=0.3.0 <1.0.0",
|
||||||
"@farcaster/auth-kit": ">=0.6.0 <1.0.0",
|
"@farcaster/auth-kit": ">=0.6.0 <1.0.0",
|
||||||
"@farcaster/frame-core": ">=0.0.29 <1.0.0",
|
"@farcaster/miniapp-node": ">=0.1.5 <1.0.0",
|
||||||
"@farcaster/frame-node": ">=0.0.18 <1.0.0",
|
"@farcaster/miniapp-sdk": ">=0.1.6 <1.0.0",
|
||||||
"@farcaster/frame-sdk": ">=0.0.31 <1.0.0",
|
"@farcaster/miniapp-wagmi-connector": "^1.0.0",
|
||||||
"@farcaster/frame-wagmi-connector": ">=0.0.19 <1.0.0",
|
|
||||||
"@farcaster/mini-app-solana": ">=0.0.17 <1.0.0",
|
"@farcaster/mini-app-solana": ">=0.0.17 <1.0.0",
|
||||||
"@neynar/react": "^1.2.5",
|
"@neynar/react": "^1.2.5",
|
||||||
"@radix-ui/react-label": "^2.1.1",
|
"@radix-ui/react-label": "^2.1.1",
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@neynar/create-farcaster-mini-app",
|
"name": "@neynar/create-farcaster-mini-app",
|
||||||
"version": "1.5.3",
|
"version": "1.5.6",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"private": false,
|
"private": false,
|
||||||
"access": "public",
|
"access": "public",
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
|
|
||||||
const { execSync } = require('child_process');
|
import { execSync } from 'child_process';
|
||||||
|
|
||||||
// Parse arguments
|
// Parse arguments
|
||||||
const args = process.argv.slice(2);
|
const args = process.argv.slice(2);
|
||||||
|
|||||||
@ -409,6 +409,45 @@ async function setEnvironmentVariables(
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function waitForDeployment(vercelClient, projectId, maxWaitTime = 300000) { // 5 minutes
|
||||||
|
console.log('\n⏳ Waiting for deployment to complete...');
|
||||||
|
const startTime = Date.now();
|
||||||
|
|
||||||
|
while (Date.now() - startTime < maxWaitTime) {
|
||||||
|
try {
|
||||||
|
const deployments = await vercelClient.deployments.list({
|
||||||
|
projectId: projectId,
|
||||||
|
limit: 1
|
||||||
|
});
|
||||||
|
|
||||||
|
if (deployments.deployments?.[0]) {
|
||||||
|
const deployment = deployments.deployments[0];
|
||||||
|
console.log(`📊 Deployment status: ${deployment.state}`);
|
||||||
|
|
||||||
|
if (deployment.state === 'READY') {
|
||||||
|
console.log('✅ Deployment completed successfully!');
|
||||||
|
return deployment;
|
||||||
|
} else if (deployment.state === 'ERROR') {
|
||||||
|
throw new Error(`Deployment failed with state: ${deployment.state}`);
|
||||||
|
} else if (deployment.state === 'CANCELED') {
|
||||||
|
throw new Error('Deployment was canceled');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Still building, wait and check again
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 5000)); // Wait 5 seconds
|
||||||
|
} else {
|
||||||
|
console.log('⏳ No deployment found yet, waiting...');
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 5000));
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.warn('⚠️ Could not check deployment status:', error.message);
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 5000));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error('Deployment timed out after 5 minutes');
|
||||||
|
}
|
||||||
|
|
||||||
async function deployToVercel(useGitHub = false) {
|
async function deployToVercel(useGitHub = false) {
|
||||||
try {
|
try {
|
||||||
console.log("\n🚀 Deploying to Vercel...");
|
console.log("\n🚀 Deploying to Vercel...");
|
||||||
@ -431,25 +470,46 @@ async function deployToVercel(useGitHub = false) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set up Vercel project
|
// Set up Vercel project
|
||||||
console.log("\n📦 Setting up Vercel project...");
|
console.log('\n📦 Setting up Vercel project...');
|
||||||
console.log(
|
console.log('An initial deployment is required to get an assigned domain that can be used in the mini app manifest\n');
|
||||||
"An initial deployment is required to get an assigned domain that can be used in the mini app manifest\n"
|
console.log('\n⚠️ Note: choosing a longer, more unique project name will help avoid conflicts with other existing domains\n');
|
||||||
);
|
|
||||||
console.log(
|
|
||||||
"\n⚠️ Note: choosing a longer, more unique project name will help avoid conflicts with other existing domains\n"
|
|
||||||
);
|
|
||||||
|
|
||||||
execSync("vercel", {
|
// Use spawn instead of execSync for better error handling
|
||||||
|
const { spawn } = await import('child_process');
|
||||||
|
const vercelSetup = spawn('vercel', [], {
|
||||||
cwd: projectRoot,
|
cwd: projectRoot,
|
||||||
stdio: "inherit",
|
stdio: "inherit",
|
||||||
shell: process.platform === "win32",
|
shell: process.platform === "win32",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
await new Promise((resolve, reject) => {
|
||||||
|
vercelSetup.on('close', (code) => {
|
||||||
|
if (code === 0 || code === null) {
|
||||||
|
console.log('✅ Vercel project setup completed');
|
||||||
|
resolve();
|
||||||
|
} else {
|
||||||
|
console.log('⚠️ Vercel setup command completed (this is normal)');
|
||||||
|
resolve(); // Don't reject, as this is often expected
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
vercelSetup.on('error', (error) => {
|
||||||
|
console.log('⚠️ Vercel setup command completed (this is normal)');
|
||||||
|
resolve(); // Don't reject, as this is often expected
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Wait a moment for project files to be written
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
||||||
|
|
||||||
// Load project info
|
// Load project info
|
||||||
const projectJson = JSON.parse(
|
let projectId;
|
||||||
fs.readFileSync(".vercel/project.json", "utf8")
|
try {
|
||||||
);
|
const projectJson = JSON.parse(fs.readFileSync('.vercel/project.json', 'utf8'));
|
||||||
const projectId = projectJson.projectId;
|
projectId = projectJson.projectId;
|
||||||
|
} catch (error) {
|
||||||
|
throw new Error('Failed to load project info. Please ensure the Vercel project was created successfully.');
|
||||||
|
}
|
||||||
|
|
||||||
// Get Vercel token and initialize SDK client
|
// Get Vercel token and initialize SDK client
|
||||||
let vercelClient = null;
|
let vercelClient = null;
|
||||||
@ -489,30 +549,35 @@ async function deployToVercel(useGitHub = false) {
|
|||||||
|
|
||||||
// Fallback to CLI method if SDK failed
|
// Fallback to CLI method if SDK failed
|
||||||
if (!domain) {
|
if (!domain) {
|
||||||
const inspectOutput = execSync(
|
try {
|
||||||
`vercel project inspect ${projectId} 2>&1`,
|
const inspectOutput = execSync(`vercel project inspect ${projectId} 2>&1`, {
|
||||||
{
|
|
||||||
cwd: projectRoot,
|
cwd: projectRoot,
|
||||||
encoding: "utf8",
|
encoding: 'utf8'
|
||||||
}
|
});
|
||||||
);
|
|
||||||
|
|
||||||
const nameMatch = inspectOutput.match(/Name\s+([^\n]+)/);
|
const nameMatch = inspectOutput.match(/Name\s+([^\n]+)/);
|
||||||
if (nameMatch) {
|
if (nameMatch) {
|
||||||
projectName = nameMatch[1].trim();
|
projectName = nameMatch[1].trim();
|
||||||
domain = `${projectName}.vercel.app`;
|
|
||||||
console.log("🌐 Using project name for domain:", domain);
|
|
||||||
} else {
|
|
||||||
const altMatch = inspectOutput.match(/Found Project [^/]+\/([^\n]+)/);
|
|
||||||
if (altMatch) {
|
|
||||||
projectName = altMatch[1].trim();
|
|
||||||
domain = `${projectName}.vercel.app`;
|
domain = `${projectName}.vercel.app`;
|
||||||
console.log("🌐 Using project name for domain:", domain);
|
console.log("🌐 Using project name for domain:", domain);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(
|
const altMatch = inspectOutput.match(/Found Project [^/]+\/([^\n]+)/);
|
||||||
"Could not determine project name from inspection output"
|
if (altMatch) {
|
||||||
);
|
projectName = altMatch[1].trim();
|
||||||
|
domain = `${projectName}.vercel.app`;
|
||||||
|
console.log('🌐 Using project name for domain:', domain);
|
||||||
|
} else {
|
||||||
|
console.warn('⚠️ Could not determine project name from inspection, using fallback');
|
||||||
|
// Use a fallback domain based on project ID
|
||||||
|
domain = `project-${projectId.slice(-8)}.vercel.app`;
|
||||||
|
console.log('🌐 Using fallback domain:', domain);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.warn('⚠️ Could not inspect project, using fallback domain');
|
||||||
|
// Use a fallback domain based on project ID
|
||||||
|
domain = `project-${projectId.slice(-8)}.vercel.app`;
|
||||||
|
console.log('🌐 Using fallback domain:', domain);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -572,27 +637,49 @@ async function deployToVercel(useGitHub = false) {
|
|||||||
console.log("\n📦 Deploying local code directly...");
|
console.log("\n📦 Deploying local code directly...");
|
||||||
}
|
}
|
||||||
|
|
||||||
execSync("vercel deploy --prod", {
|
// Use spawn for better control over the deployment process
|
||||||
|
const vercelDeploy = spawn('vercel', ['deploy', '--prod'], {
|
||||||
cwd: projectRoot,
|
cwd: projectRoot,
|
||||||
stdio: "inherit",
|
stdio: "inherit",
|
||||||
env: process.env,
|
env: process.env,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
await new Promise((resolve, reject) => {
|
||||||
|
vercelDeploy.on('close', (code) => {
|
||||||
|
if (code === 0) {
|
||||||
|
console.log('✅ Vercel deployment command completed');
|
||||||
|
resolve();
|
||||||
|
} else {
|
||||||
|
console.error(`❌ Vercel deployment failed with code: ${code}`);
|
||||||
|
reject(new Error(`Vercel deployment failed with exit code: ${code}`));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
vercelDeploy.on('error', (error) => {
|
||||||
|
console.error('❌ Vercel deployment error:', error.message);
|
||||||
|
reject(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Wait for deployment to actually complete
|
||||||
|
let deployment;
|
||||||
|
if (vercelClient) {
|
||||||
|
try {
|
||||||
|
deployment = await waitForDeployment(vercelClient, projectId);
|
||||||
|
} catch (error) {
|
||||||
|
console.warn('⚠️ Could not verify deployment completion:', error.message);
|
||||||
|
console.log('ℹ️ Proceeding with domain verification...');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Verify actual domain after deployment
|
// Verify actual domain after deployment
|
||||||
console.log("\n🔍 Verifying deployment domain...");
|
console.log("\n🔍 Verifying deployment domain...");
|
||||||
|
|
||||||
let actualDomain = domain;
|
let actualDomain = domain;
|
||||||
if (vercelClient) {
|
if (vercelClient && deployment) {
|
||||||
try {
|
try {
|
||||||
const deployments = await vercelClient.deployments.list({
|
actualDomain = deployment.url || domain;
|
||||||
projectId: projectId,
|
console.log('🌐 Verified actual domain:', actualDomain);
|
||||||
limit: 1,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (deployments.deployments?.[0]?.url) {
|
|
||||||
actualDomain = deployments.deployments[0].url;
|
|
||||||
console.log("🌐 Verified actual domain:", actualDomain);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn(
|
console.warn(
|
||||||
"⚠️ Could not verify domain via SDK, using assumed domain"
|
"⚠️ Could not verify domain via SDK, using assumed domain"
|
||||||
@ -614,26 +701,37 @@ async function deployToVercel(useGitHub = false) {
|
|||||||
NEXT_PUBLIC_URL: `https://${actualDomain}`,
|
NEXT_PUBLIC_URL: `https://${actualDomain}`,
|
||||||
};
|
};
|
||||||
|
|
||||||
const updatedMetadata = await generateFarcasterMetadata(
|
if (miniAppMetadata) {
|
||||||
actualDomain,
|
const updatedMetadata = await generateFarcasterMetadata(actualDomain, fid, await validateSeedPhrase(process.env.SEED_PHRASE), process.env.SEED_PHRASE, webhookUrl);
|
||||||
webhookUrl
|
updatedEnv.MINI_APP_METADATA = updatedMetadata;
|
||||||
);
|
}
|
||||||
updatedEnv.MINI_APP_METADATA = updatedMetadata;
|
|
||||||
|
|
||||||
await setEnvironmentVariables(
|
await setEnvironmentVariables(vercelClient, projectId, updatedEnv, projectRoot);
|
||||||
vercelClient,
|
|
||||||
projectId,
|
|
||||||
updatedEnv,
|
|
||||||
projectRoot
|
|
||||||
);
|
|
||||||
|
|
||||||
console.log("\n📦 Redeploying with correct domain...");
|
console.log('\n📦 Redeploying with correct domain...');
|
||||||
execSync("vercel deploy --prod", {
|
const vercelRedeploy = spawn('vercel', ['deploy', '--prod'], {
|
||||||
cwd: projectRoot,
|
cwd: projectRoot,
|
||||||
stdio: "inherit",
|
stdio: "inherit",
|
||||||
env: process.env,
|
env: process.env,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
await new Promise((resolve, reject) => {
|
||||||
|
vercelRedeploy.on('close', (code) => {
|
||||||
|
if (code === 0) {
|
||||||
|
console.log('✅ Redeployment completed');
|
||||||
|
resolve();
|
||||||
|
} else {
|
||||||
|
console.error(`❌ Redeployment failed with code: ${code}`);
|
||||||
|
reject(new Error(`Redeployment failed with exit code: ${code}`));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
vercelRedeploy.on('error', (error) => {
|
||||||
|
console.error('❌ Redeployment error:', error.message);
|
||||||
|
reject(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
domain = actualDomain;
|
domain = actualDomain;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { notificationDetailsSchema } from "@farcaster/frame-sdk";
|
import { notificationDetailsSchema } from "@farcaster/miniapp-sdk";
|
||||||
import { NextRequest } from "next/server";
|
import { NextRequest } from "next/server";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { setUserNotificationDetails } from "~/lib/kv";
|
import { setUserNotificationDetails } from "~/lib/kv";
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import {
|
|||||||
ParseWebhookEvent,
|
ParseWebhookEvent,
|
||||||
parseWebhookEvent,
|
parseWebhookEvent,
|
||||||
verifyAppKeyWithNeynar,
|
verifyAppKeyWithNeynar,
|
||||||
} from "@farcaster/frame-node";
|
} from "@farcaster/miniapp-node";
|
||||||
import { NextRequest } from "next/server";
|
import { NextRequest } from "next/server";
|
||||||
import { APP_NAME } from "~/lib/constants";
|
import { APP_NAME } from "~/lib/constants";
|
||||||
import {
|
import {
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import React, { createContext, useEffect, useState } from "react";
|
import React, { createContext, useEffect, useState } from "react";
|
||||||
import dynamic from "next/dynamic";
|
import dynamic from "next/dynamic";
|
||||||
import { sdk } from '@farcaster/frame-sdk';
|
import { sdk } from '@farcaster/miniapp-sdk';
|
||||||
|
|
||||||
const FarcasterSolanaProvider = dynamic(
|
const FarcasterSolanaProvider = dynamic(
|
||||||
() => import('@farcaster/mini-app-solana').then(mod => mod.FarcasterSolanaProvider),
|
() => import('@farcaster/mini-app-solana').then(mod => mod.FarcasterSolanaProvider),
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { createConfig, http, WagmiProvider } from "wagmi";
|
import { createConfig, http, WagmiProvider } from "wagmi";
|
||||||
import { base, degen, mainnet, optimism, unichain, celo } from "wagmi/chains";
|
import { base, degen, mainnet, optimism, unichain, celo } from "wagmi/chains";
|
||||||
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
||||||
import { farcasterFrame } from "@farcaster/frame-wagmi-connector";
|
import { farcasterFrame } from "@farcaster/miniapp-wagmi-connector";
|
||||||
import { coinbaseWallet, metaMask } from 'wagmi/connectors';
|
import { coinbaseWallet, metaMask } from 'wagmi/connectors';
|
||||||
import { APP_NAME, APP_ICON_URL, APP_URL } from "~/lib/constants";
|
import { APP_NAME, APP_ICON_URL, APP_URL } from "~/lib/constants";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { APP_NAME } from "~/lib/constants";
|
import { APP_NAME } from "~/lib/constants";
|
||||||
import sdk from "@farcaster/frame-sdk";
|
import sdk from "@farcaster/miniapp-sdk";
|
||||||
import { useMiniApp } from "@neynar/react";
|
import { useMiniApp } from "@neynar/react";
|
||||||
|
|
||||||
type HeaderProps = {
|
type HeaderProps = {
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
import { useCallback, useState, useEffect } from 'react';
|
import { useCallback, useState, useEffect } from 'react';
|
||||||
import { Button } from './Button';
|
import { Button } from './Button';
|
||||||
import { useMiniApp } from '@neynar/react';
|
import { useMiniApp } from '@neynar/react';
|
||||||
import { type ComposeCast } from "@farcaster/frame-sdk";
|
import { type ComposeCast } from "@farcaster/miniapp-sdk";
|
||||||
|
|
||||||
interface EmbedConfig {
|
interface EmbedConfig {
|
||||||
path?: string;
|
path?: string;
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import { useMiniApp } from "@neynar/react";
|
|||||||
import { ShareButton } from "../Share";
|
import { ShareButton } from "../Share";
|
||||||
import { Button } from "../Button";
|
import { Button } from "../Button";
|
||||||
import { SignIn } from "../wallet/SignIn";
|
import { SignIn } from "../wallet/SignIn";
|
||||||
import { type Haptics } from "@farcaster/frame-sdk";
|
import { type Haptics } from "@farcaster/miniapp-sdk";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ActionsTab component handles mini app actions like sharing, notifications, and haptic feedback.
|
* ActionsTab component handles mini app actions like sharing, notifications, and haptic feedback.
|
||||||
|
|||||||
@ -17,7 +17,7 @@ export function HomeTab() {
|
|||||||
<div className="flex items-center justify-center h-[calc(100vh-200px)] px-6">
|
<div className="flex items-center justify-center h-[calc(100vh-200px)] px-6">
|
||||||
<div className="text-center w-full max-w-md mx-auto">
|
<div className="text-center w-full max-w-md mx-auto">
|
||||||
<p className="text-lg mb-2">Put your content here!</p>
|
<p className="text-lg mb-2">Put your content here!</p>
|
||||||
<p className="text-sm text-gray-500">Powered by Neynar 🪐</p>
|
<p className="text-sm text-gray-500 dark:text-gray-400">Powered by Neynar 🪐</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
import { useCallback, useState } from "react";
|
import { useCallback, useState } from "react";
|
||||||
import { signIn, signOut, getCsrfToken } from "next-auth/react";
|
import { signIn, signOut, getCsrfToken } from "next-auth/react";
|
||||||
import sdk, { SignIn as SignInCore } from "@farcaster/frame-sdk";
|
import sdk, { SignIn as SignInCore } from "@farcaster/miniapp-sdk";
|
||||||
import { useSession } from "next-auth/react";
|
import { useSession } from "next-auth/react";
|
||||||
import { Button } from "../Button";
|
import { Button } from "../Button";
|
||||||
|
|
||||||
@ -128,9 +128,9 @@ export function SignIn() {
|
|||||||
|
|
||||||
{/* Session Information */}
|
{/* Session Information */}
|
||||||
{session && (
|
{session && (
|
||||||
<div className="my-2 p-2 text-xs overflow-x-scroll bg-gray-100 rounded-lg font-mono">
|
<div className="my-2 p-2 text-xs overflow-x-scroll bg-gray-100 dark:bg-gray-900 rounded-lg font-mono">
|
||||||
<div className="font-semibold text-gray-500 mb-1">Session</div>
|
<div className="font-semibold text-gray-500 dark:text-gray-300 mb-1">Session</div>
|
||||||
<div className="whitespace-pre">
|
<div className="whitespace-pre text-gray-700 dark:text-gray-200">
|
||||||
{JSON.stringify(session, null, 2)}
|
{JSON.stringify(session, null, 2)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -138,17 +138,17 @@ export function SignIn() {
|
|||||||
|
|
||||||
{/* Error Display */}
|
{/* Error Display */}
|
||||||
{signInFailure && !authState.signingIn && (
|
{signInFailure && !authState.signingIn && (
|
||||||
<div className="my-2 p-2 text-xs overflow-x-scroll bg-gray-100 rounded-lg font-mono">
|
<div className="my-2 p-2 text-xs overflow-x-scroll bg-gray-100 dark:bg-gray-900 rounded-lg font-mono">
|
||||||
<div className="font-semibold text-gray-500 mb-1">SIWF Result</div>
|
<div className="font-semibold text-gray-500 dark:text-gray-300 mb-1">SIWF Result</div>
|
||||||
<div className="whitespace-pre">{signInFailure}</div>
|
<div className="whitespace-pre text-gray-700 dark:text-gray-200">{signInFailure}</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Success Result Display */}
|
{/* Success Result Display */}
|
||||||
{signInResult && !authState.signingIn && (
|
{signInResult && !authState.signingIn && (
|
||||||
<div className="my-2 p-2 text-xs overflow-x-scroll bg-gray-100 rounded-lg font-mono">
|
<div className="my-2 p-2 text-xs overflow-x-scroll bg-gray-100 dark:bg-gray-900 rounded-lg font-mono">
|
||||||
<div className="font-semibold text-gray-500 mb-1">SIWF Result</div>
|
<div className="font-semibold text-gray-500 dark:text-gray-300 mb-1">SIWF Result</div>
|
||||||
<div className="whitespace-pre">
|
<div className="whitespace-pre text-gray-700 dark:text-gray-200">
|
||||||
{JSON.stringify(signInResult, null, 2)}
|
{JSON.stringify(signInResult, null, 2)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { FrameNotificationDetails } from "@farcaster/frame-sdk";
|
import { FrameNotificationDetails } from "@farcaster/miniapp-sdk";
|
||||||
import { Redis } from "@upstash/redis";
|
import { Redis } from "@upstash/redis";
|
||||||
import { APP_NAME } from "./constants";
|
import { APP_NAME } from "./constants";
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import {
|
import {
|
||||||
SendNotificationRequest,
|
SendNotificationRequest,
|
||||||
sendNotificationResponseSchema,
|
sendNotificationResponseSchema,
|
||||||
} from "@farcaster/frame-sdk";
|
} from "@farcaster/miniapp-sdk";
|
||||||
import { getUserNotificationDetails } from "~/lib/kv";
|
import { getUserNotificationDetails } from "~/lib/kv";
|
||||||
import { APP_URL } from "./constants";
|
import { APP_URL } from "./constants";
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user