feat: remove localtunnel and recommend ngrok

This commit is contained in:
veganbeef 2025-10-29 17:16:48 -07:00
parent 8d37c83ee8
commit 760d2f28ec
No known key found for this signature in database
5 changed files with 31 additions and 104 deletions

View File

@ -8,7 +8,6 @@ let projectName = null;
let autoAcceptDefaults = false; let autoAcceptDefaults = false;
let apiKey = null; let apiKey = null;
let noWallet = false; let noWallet = false;
let noTunnel = false;
let sponsoredSigner = false; let sponsoredSigner = false;
let seedPhrase = null; let seedPhrase = null;
let returnUrl = null; let returnUrl = null;
@ -54,10 +53,6 @@ if (yIndex !== -1) {
noWallet = true; noWallet = true;
args.splice(i, 1); // Remove the flag args.splice(i, 1); // Remove the flag
i--; // Adjust index since we removed 1 element i--; // Adjust index since we removed 1 element
} else if (arg === '--no-tunnel') {
noTunnel = true;
args.splice(i, 1); // Remove the flag
i--; // Adjust index since we removed 1 element
} else if (arg === '--sponsored-signer') { } else if (arg === '--sponsored-signer') {
sponsoredSigner = true; sponsoredSigner = true;
args.splice(i, 1); // Remove the flag args.splice(i, 1); // Remove the flag
@ -99,7 +94,7 @@ if (autoAcceptDefaults && !projectName) {
process.exit(1); process.exit(1);
} }
init(projectName, autoAcceptDefaults, apiKey, noWallet, noTunnel, sponsoredSigner, seedPhrase, returnUrl).catch((err) => { init(projectName, autoAcceptDefaults, apiKey, noWallet, sponsoredSigner, seedPhrase, returnUrl).catch((err) => {
console.error('Error:', err); console.error('Error:', err);
process.exit(1); process.exit(1);
}); });

View File

@ -68,7 +68,6 @@ export async function init(
autoAcceptDefaults = false, autoAcceptDefaults = false,
apiKey = null, apiKey = null,
noWallet = false, noWallet = false,
noTunnel = false,
sponsoredSigner = false, sponsoredSigner = false,
seedPhrase = null, seedPhrase = null,
returnUrl = null returnUrl = null
@ -251,7 +250,6 @@ export async function init(
tags: [], tags: [],
buttonText: 'Launch Mini App', buttonText: 'Launch Mini App',
useWallet: !noWallet, useWallet: !noWallet,
useTunnel: true,
enableAnalytics: true, enableAnalytics: true,
seedPhrase: seedPhraseValue, seedPhrase: seedPhraseValue,
useSponsoredSigner: useSponsoredSignerValue, useSponsoredSigner: useSponsoredSignerValue,
@ -361,24 +359,6 @@ export async function init(
answers.useWallet = walletAnswer.useWallet; answers.useWallet = walletAnswer.useWallet;
} }
// Ask about localhost vs tunnel
if (noTunnel) {
answers.useTunnel = false;
} else {
const hostingAnswer = await inquirer.prompt([
{
type: 'confirm',
name: 'useTunnel',
message:
'Would you like to test on mobile and/or test the app with Warpcast developer tools?\n' +
`⚠️ ${yellow}${italic}Both mobile testing and the Warpcast debugger require setting up a tunnel to serve your app from localhost to the broader internet.\n${reset}` +
'Configure a tunnel for mobile testing and/or Warpcast developer tools?',
default: true,
},
]);
answers.useTunnel = hostingAnswer.useTunnel;
}
// Ask about Sign In With Neynar (SIWN) - requires seed phrase // Ask about Sign In With Neynar (SIWN) - requires seed phrase
if (seedPhrase) { if (seedPhrase) {
// If --seed-phrase flag is used, validate it // If --seed-phrase flag is used, validate it
@ -546,7 +526,6 @@ export async function init(
"eslint": "^8", "eslint": "^8",
"eslint-config-next": "15.0.3", "eslint-config-next": "15.0.3",
"inquirer": "^10.2.2", "inquirer": "^10.2.2",
"localtunnel": "^2.0.2",
"pino-pretty": "^13.0.0", "pino-pretty": "^13.0.0",
"postcss": "^8", "postcss": "^8",
"tailwindcss": "^3.4.1", "tailwindcss": "^3.4.1",
@ -755,7 +734,6 @@ export async function init(
`\nNEXTAUTH_SECRET="${crypto.randomBytes(32).toString('hex')}"` `\nNEXTAUTH_SECRET="${crypto.randomBytes(32).toString('hex')}"`
); );
} }
fs.appendFileSync(envPath, `\nUSE_TUNNEL="${answers.useTunnel}"`);
if (answers.useSponsoredSigner) { if (answers.useSponsoredSigner) {
fs.appendFileSync(envPath, `\nSPONSOR_SIGNER="true"`); fs.appendFileSync(envPath, `\nSPONSOR_SIGNER="true"`);
} }

34
package-lock.json generated
View File

@ -1,12 +1,12 @@
{ {
"name": "@neynar/create-farcaster-mini-app", "name": "@neynar/create-farcaster-mini-app",
"version": "1.8.13", "version": "1.8.15",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "@neynar/create-farcaster-mini-app", "name": "@neynar/create-farcaster-mini-app",
"version": "1.8.13", "version": "1.8.15",
"dependencies": { "dependencies": {
"dotenv": "^16.4.7", "dotenv": "^16.4.7",
"inquirer": "^12.4.3", "inquirer": "^12.4.3",
@ -614,9 +614,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/@openapitools/openapi-generator-cli": { "node_modules/@openapitools/openapi-generator-cli": {
"version": "2.23.1", "version": "2.25.0",
"resolved": "https://registry.npmjs.org/@openapitools/openapi-generator-cli/-/openapi-generator-cli-2.23.1.tgz", "resolved": "https://registry.npmjs.org/@openapitools/openapi-generator-cli/-/openapi-generator-cli-2.25.0.tgz",
"integrity": "sha512-Kd5EZqzbcIXf6KRlpUrheHMzQNRHsJWzAGrm4ncWCNhnQl+Mh6TsFcqq+hIetgiFCknWBH6cZ2f37SxPxaon4w==", "integrity": "sha512-u/3VAbF8c68AXBgm8nBAdDPLPW/KgrtHz28yemf92zNB0iDZFGdRUX2W80Lzf177g6ctYLz0GIPHCOU0LTJegQ==",
"dev": true, "dev": true,
"hasInstallScript": true, "hasInstallScript": true,
"license": "Apache-2.0", "license": "Apache-2.0",
@ -625,13 +625,13 @@
"@nestjs/common": "11.1.6", "@nestjs/common": "11.1.6",
"@nestjs/core": "11.1.6", "@nestjs/core": "11.1.6",
"@nuxtjs/opencollective": "0.3.2", "@nuxtjs/opencollective": "0.3.2",
"axios": "1.11.0", "axios": "1.12.2",
"chalk": "4.1.2", "chalk": "4.1.2",
"commander": "8.3.0", "commander": "8.3.0",
"compare-versions": "4.1.4", "compare-versions": "6.1.1",
"concurrently": "9.2.1", "concurrently": "9.2.1",
"console.table": "0.10.0", "console.table": "0.10.0",
"fs-extra": "11.3.1", "fs-extra": "11.3.2",
"glob": "11.0.3", "glob": "11.0.3",
"inquirer": "8.2.7", "inquirer": "8.2.7",
"proxy-agent": "6.5.0", "proxy-agent": "6.5.0",
@ -896,9 +896,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/axios": { "node_modules/axios": {
"version": "1.11.0", "version": "1.12.2",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.11.0.tgz", "resolved": "https://registry.npmjs.org/axios/-/axios-1.12.2.tgz",
"integrity": "sha512-1Lx3WLFQWm3ooKDYZD1eXmoGO9fxYQjrycfHFC8P0sCfQVXyROp0p9PFWBehewBOdCwHc+f/b8I0fMto5eSfwA==", "integrity": "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -1153,9 +1153,9 @@
} }
}, },
"node_modules/compare-versions": { "node_modules/compare-versions": {
"version": "4.1.4", "version": "6.1.1",
"resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-4.1.4.tgz", "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-6.1.1.tgz",
"integrity": "sha512-FemMreK9xNyL8gQevsdRMrvO4lFCkQP7qbuktn1q8ndcNk1+0mz7lgE7b/sNvbhVgY4w6tMN1FDp6aADjqw2rw==", "integrity": "sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==",
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
@ -1589,9 +1589,9 @@
} }
}, },
"node_modules/fs-extra": { "node_modules/fs-extra": {
"version": "11.3.1", "version": "11.3.2",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.1.tgz", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.2.tgz",
"integrity": "sha512-eXvGGwZ5CL17ZSwHWd3bbgk7UUpF6IFHtP57NYYakPvHOs8GDgDe5KJI36jIJzDkJ6eJjuzRA8eBQb6SkKue0g==", "integrity": "sha512-Xr9F6z6up6Ws+NjzMCZc6WXg2YFRlrLP9NQDO3VQrWrfiojdhS56TzueT88ze0uBdCTwEIhQ3ptnmKeWGFAe0A==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {

View File

@ -1,6 +1,6 @@
{ {
"name": "@neynar/create-farcaster-mini-app", "name": "@neynar/create-farcaster-mini-app",
"version": "1.8.14", "version": "1.9.0",
"type": "module", "type": "module",
"private": false, "private": false,
"access": "public", "access": "public",

View File

@ -1,4 +1,3 @@
import localtunnel from 'localtunnel';
import { spawn } from 'child_process'; import { spawn } from 'child_process';
import { createServer } from 'net'; import { createServer } from 'net';
import dotenv from 'dotenv'; import dotenv from 'dotenv';
@ -11,7 +10,6 @@ dotenv.config({ path: '.env.local' });
const __dirname = path.dirname(fileURLToPath(import.meta.url)); const __dirname = path.dirname(fileURLToPath(import.meta.url));
const projectRoot = path.resolve(path.normalize(path.join(__dirname, '..'))); const projectRoot = path.resolve(path.normalize(path.join(__dirname, '..')));
let tunnel;
let nextDev; let nextDev;
let isCleaningUp = false; let isCleaningUp = false;
@ -97,52 +95,20 @@ async function startDev() {
process.exit(1); process.exit(1);
} }
const useTunnel = process.env.USE_TUNNEL === 'true'; const miniAppUrl = `http://localhost:${port}`;
let miniAppUrl;
if (useTunnel) {
// Start localtunnel and get URL
tunnel = await localtunnel({ port: port });
let ip;
try {
ip = await fetch('https://ipv4.icanhazip.com').then(res => res.text()).then(ip => ip.trim());
} catch (error) {
console.error('Error getting IP address:', error);
}
miniAppUrl = tunnel.url;
console.log(` console.log(`
🌐 Local tunnel URL: ${tunnel.url} 💻 Your mini app is running at: ${miniAppUrl}
💻 To test on desktop: 🌐 To test with the Farcaster preview tool:
1. Open the localtunnel URL in your browser: ${tunnel.url}
2. Enter your IP address in the password field${ip ? `: ${ip}` : ''} (note that this IP may be incorrect if you are using a VPN)
3. Click "Click to Submit" -- your mini app should now load in the browser
4. Navigate to the Warpcast Mini App Developer Tools: https://warpcast.com/~/developers
5. Enter your mini app URL: ${tunnel.url}
6. Click "Preview" to launch your mini app within Warpcast (note that it may take ~10 seconds to load)
1. Create a free ngrok account at https://ngrok.com/download/mac-os
You will not be able to load your mini app in Warpcast until 2. Download and install ngrok following the instructions
you submit your IP address in the localtunnel password field 3. In a NEW terminal window, run: ngrok http ${port}
4. Copy the forwarding URL (e.g., https://xxxx-xx-xx-xx-xx.ngrok-free.app)
5. Navigate to: https://farcaster.xyz/~/developers/mini-apps/preview
📱 To test in Warpcast mobile app: 6. Enter your ngrok URL and click "Preview" to test your mini app
1. Open Warpcast on your phone `)
2. Go to Settings > Developer > Mini Apps
4. Enter this URL: ${tunnel.url}
5. Click "Preview" (note that it may take ~10 seconds to load)
`);
} else {
miniAppUrl = `http://localhost:${port}`;
console.log(`
💻 To test your mini app:
1. Open the Warpcast Mini App Developer Tools: https://warpcast.com/~/developers
2. Scroll down to the "Preview Mini App" tool
3. Enter this URL: ${miniAppUrl}
4. Click "Preview" to test your mini app (note that it may take ~5 seconds to load the first time)
`);
}
// Start next dev with appropriate configuration // Start next dev with appropriate configuration
const nextBin = path.normalize(path.join(projectRoot, 'node_modules', '.bin', 'next')); const nextBin = path.normalize(path.join(projectRoot, 'node_modules', '.bin', 'next'));
@ -182,15 +148,6 @@ async function startDev() {
} }
} }
if (tunnel) {
try {
await tunnel.close();
console.log('🌐 Tunnel closed');
} catch (e) {
console.log('Note: Tunnel already closed');
}
}
// Force kill any remaining processes on the specified port // Force kill any remaining processes on the specified port
await killProcessOnPort(port); await killProcessOnPort(port);
} catch (error) { } catch (error) {
@ -204,9 +161,6 @@ async function startDev() {
process.on('SIGINT', cleanup); process.on('SIGINT', cleanup);
process.on('SIGTERM', cleanup); process.on('SIGTERM', cleanup);
process.on('exit', cleanup); process.on('exit', cleanup);
if (tunnel) {
tunnel.on('close', cleanup);
}
} }
startDev().catch(console.error); startDev().catch(console.error);