);
}
const whyLightningItems = [
{
icon: ShieldCheckIcon,
title: "Stay in Control",
description:
"Set spending limits per agent. You decide how much it can spend and when budgets reset — no surprise bills.",
},
{
icon: EyeOffIcon,
title: "Private by Default",
description:
"No credit cards or personal info shared with merchants. Your agent pays over lightning — fast, direct, and private.",
},
{
icon: ZapIcon,
title: "Instant Access to Paid Services",
description:
"Your agent can access 1,000+ paid APIs instantly — gift cards, domains, hosting, AI models, and more.",
},
];
function getInspirationCategories(hasChannelManagement: boolean): {
label: string;
icon: LucideIcon;
prompts: string[];
skill?: { prompt: string; skillName: string; url: string };
}[] {
return [
{
label: "Wallet",
icon: ZapIcon,
prompts: [
"send $5 to hub@getalby.com for coffee",
"how much is $10 in sats right now?",
"make an invoice for 50,000 sats",
],
},
{
label: "Shopping",
icon: ShoppingBagIcon,
prompts: [
"buy a $25 Netflix gift card on bitrefill.com",
"get me an eSIM with 5GB of data for my trip to Portugal on bitrefill.com",
"what gift cards are available in the US on bitrefill.com?",
],
skill: {
prompt:
"Run `npx -y skills add bitrefill/agents -y` to install the Bitrefill Skill",
skillName: "Bitrefill Skill",
url: "https://bitrefill.com/agents",
},
},
{
label: "Creative",
icon: SparklesIcon,
prompts: [
"generate a watercolor painting of a mountain cabin at sunset on ppq.ai",
"generate a cool bitcoin logo on ppq.ai and print it on a t-shirt on unhuman.store",
"create a logo for my coffee shop using ppq.ai image generation",
],
},
{
label: "Services",
icon: LayersIcon,
prompts: [
"search podcasts for discussions about bitcoin scaling",
"set up an anonymous email address on lnemail.net",
"buy the domain my-awesome-project.dev on unhuman.domains",
"spin up a VPS with 2 cores and 4GB RAM on lnvps.net",
],
},
{
label: "Automation",
icon: RepeatIcon,
prompts: [
"read payouts.csv and send 1,000 sats to each lightning address",
"calculate how much I spent this month and break it down by day",
"export all my transactions from the last 12 months as a CSV",
],
},
{
label: "Build Apps",
icon: HammerIcon,
prompts: [
"build an AI image generator that charges 500 sats per image",
"create a file converter that charges 50 sats per conversion",
"build a blog where readers unlock articles for 50 sats each",
],
skill: {
prompt:
"Run `npx -y skills add getAlby/builder-skill -y` to install the Builder Skill",
skillName: "Builder Skill",
url: "https://github.com/getAlby/builder-skill",
},
},
{
label: "Alby Hub",
icon: BoxIcon,
prompts: [
"create a sub-wallet for my mum",
"setup a new alby hub on my VPS",
"give me an on-chain deposit address",
"create a new app connection with a 21,000 sat monthly budget",
"list all my app connections and their budgets",
"make a read-only connection I can share with my accountant",
'revoke the connection called "old laptop"',
...(hasChannelManagement
? [
"open a channel with 2M sats to ACINQ's node",
"show me my channels and their balances",
"what's my node's connection info?",
]
: []),
],
skill: {
prompt:
"Run `npx -y skills add getAlby/hub-skill -y` to install the Alby Hub Skill",
skillName: "Alby Hub Skill",
url: "https://github.com/getAlby/hub-skill",
},
},
];
}
function RotatingPrompt({ prompts }: { prompts: string[] }) {
const [index, setIndex] = React.useState(0);
const [charCount, setCharCount] = React.useState(0);
const [isTyping, setIsTyping] = React.useState(true);
const currentPrompt = prompts[index];
// Reset when prompts change (tab switch)
React.useEffect(() => {
setIndex(0);
setCharCount(0);
setIsTyping(true);
}, [prompts]);
// Typing effect — advance characters
React.useEffect(() => {
if (!isTyping) {
return;
}
if (charCount >= currentPrompt.length) {
setIsTyping(false);
return;
}
const timeout = setTimeout(() => {
setCharCount((c) => c + 1);
}, 30);
return () => clearTimeout(timeout);
}, [charCount, currentPrompt, isTyping]);
// Pause then rotate to next prompt
React.useEffect(() => {
if (isTyping) {
return;
}
const pause = setTimeout(() => {
setIndex((i) => (i + 1) % prompts.length);
setCharCount(0);
setIsTyping(true);
}, 3000);
return () => clearTimeout(pause);
}, [isTyping, prompts]);
return (
);
}
function InspirationPrompts() {
const { hasChannelManagement } = useInfo();
const inspirationCategories =
getInspirationCategories(!!hasChannelManagement);
return (