commit 33d28157f5e7ef07b6218298eac8921bc88ddc92
Author: root <root@hub.scroll.pub> Date: 2025-01-16 23:27:09 +0000 Subject: Initial commit diff --git a/api.js b/api.js new file mode 100644 index 0000000..f6ef3ce --- /dev/null +++ b/api.js @@ -0,0 +1,30 @@ +export default async function handler(req, res) { + if (req.method !== 'POST') { + return res.status(405).json({ error: 'Method not allowed' }); + } + + try { + const { amount, trustedData } = req.body; + const { fid } = trustedData.messageBytes; + + // Here you would integrate with your preferred payment solution + // For example, using Base, Optimism, or other L2 solutions + + return res.status(200).json({ + version: 'vNext', + image: { + src: 'https://sendframehub.pro/images/success.png', + aspectRatio: '1.91:1' + }, + buttons: [ + { + label: 'SEND MORE', + action: 'post' + } + ] + }); + } catch (error) { + console.error('Frame API error:', error); + return res.status(500).json({ error: 'Internal server error' }); + } +} diff --git a/frame.scroll b/frame.scroll new file mode 100644 index 0000000..3eac3e8 --- /dev/null +++ b/frame.scroll @@ -0,0 +1,21 @@ +main + class frameContainer + div + class frameContent + h1 Send Funds + class frameTitle + div + class inputGroup + label Amount (ETH) + for amount + input + type number + id amount + placeholder 0.05 + min 0.001 + step 0.001 + div + class frameActionArea + button Send + class frameButton + data-action post diff --git a/head.scroll b/head.scroll new file mode 100644 index 0000000..813a4b1 --- /dev/null +++ b/head.scroll @@ -0,0 +1,16 @@ +metaTags +meta + name viewport + content width=device-width, initial-scale=1.0 + +replaceNodejs + module.exports = {JSONCONTENTS: JSON.stringify(JSON.parse(require("fs").readFileSync("meta.json")))} + +<meta name="fc:frame" content='JSONCONTENTS' /> + +meta + name fc:frame:image + content https://sendframehub.pro/images/send-frame.png +meta + name fc:frame:post_url + content https://sendframehub.pro/api/frame diff --git a/index.scroll b/index.scroll new file mode 100644 index 0000000..16a12b6 --- /dev/null +++ b/index.scroll @@ -0,0 +1,8 @@ +buildHtml +baseUrl https://sendframehub.pro +import head.scroll +title Send Funds to Friends +description A simple and secure way to send funds to your Farcaster friends +style.css +frame.scroll +script.js diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..a053115 --- /dev/null +++ b/manifest.json @@ -0,0 +1,16 @@ +{ + "version": "vNext", + "name": "Send Funds", + "description": "Send funds to your Farcaster friends securely", + "image": { + "src": "https://sendframehub.pro/images/send-frame.png", + "aspectRatio": "1.91:1" + }, + "buttons": [ + { + "label": "SEND", + "action": "post" + } + ], + "postUrl": "https://sendframehub.pro/api" +} diff --git a/meta.json b/meta.json new file mode 100644 index 0000000..3981122 --- /dev/null +++ b/meta.json @@ -0,0 +1,14 @@ +{ + "version": "next", + "imageUrl": "https://sendframehub.pro/images/send-frame.png", + "button": { + "title": "Send Funds", + "action": { + "type": "launch_frame", + "name": "Send Funds Frame", + "url": "https://sendframehub.pro", + "splashImageUrl": "https://sendframehub.pro/images/splash.png", + "splashBackgroundColor": "#0a0a0a" + } + } +} diff --git a/prompt.json b/prompt.json new file mode 100644 index 0000000..ee7759c --- /dev/null +++ b/prompt.json @@ -0,0 +1,20 @@ +{ + "id": "msg_016xRSPnq5suMmdasUMpbLar", + "type": "message", + "role": "assistant", + "model": "claude-3-5-sonnet-20241022", + "content": [ + { + "type": "text", + "text": "I'll help create a WarpCast Frame for sending money to friends. Let's make it sleek and user-friendly.\n\n---domain---\nsendframehub.pro\n\n---index.scroll---\nbuildHtml\nbaseUrl https://sendframehub.pro\nimport head.scroll\ntitle Send Funds to Friends\ndescription A simple and secure way to send funds to your Farcaster friends\nstyle.css\nframe.scroll\nscript.js\n\n---head.scroll---\nmetaTags\nmeta\n name viewport\n content width=device-width, initial-scale=1.0\n\nreplaceNodejs\n module.exports = {JSONCONTENTS: JSON.stringify(JSON.parse(require(\"fs\").readFileSync(\"meta.json\")))}\n\n<meta name=\"fc:frame\" content='JSONCONTENTS' />\n\nmeta\n name fc:frame:image\n content https://sendframehub.pro/images/send-frame.png\nmeta\n name fc:frame:post_url\n content https://sendframehub.pro/api/frame\n\n---frame.scroll---\nmain\n class frameContainer\n div\n class frameContent\n h1 Send Funds\n class frameTitle\n div\n class inputGroup\n label Amount (ETH)\n for amount\n input\n type number\n id amount\n placeholder 0.05\n min 0.001\n step 0.001\n div\n class frameActionArea\n button Send\n class frameButton\n data-action post\n\n---style.css---\n:root {\n --frame-bg: #0a0a0a;\n --frame-text: #ffffff;\n --frame-accent: #6366f1;\n --frame-input-bg: rgba(255, 255, 255, 0.1);\n --frame-radius: 16px;\n --frame-shadow: 0 8px 32px rgba(99, 102, 241, 0.15);\n}\n\n* {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n}\n\nbody {\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n background: var(--frame-bg);\n color: var(--frame-text);\n min-height: 100vh;\n display: flex;\n flex-direction: column;\n}\n\n.frameContainer {\n width: 100%;\n max-width: 500px;\n margin: 0 auto;\n padding: 24px;\n}\n\n.frameContent {\n background: linear-gradient(145deg, rgba(255, 255, 255, 0.08), rgba(255, 255, 255, 0.03));\n border-radius: var(--frame-radius);\n padding: 32px;\n backdrop-filter: blur(12px);\n border: 1px solid rgba(255, 255, 255, 0.1);\n box-shadow: var(--frame-shadow);\n}\n\n.frameTitle {\n font-size: 28px;\n font-weight: 700;\n margin-bottom: 24px;\n text-align: center;\n background: linear-gradient(135deg, #6366f1, #8b5cf6);\n -webkit-background-clip: text;\n -webkit-text-fill-color: transparent;\n}\n\n.inputGroup {\n margin-bottom: 24px;\n}\n\n.inputGroup label {\n display: block;\n margin-bottom: 8px;\n font-size: 14px;\n color: rgba(255, 255, 255, 0.8);\n}\n\n.inputGroup input {\n width: 100%;\n background: var(--frame-input-bg);\n border: 1px solid rgba(255, 255, 255, 0.1);\n border-radius: calc(var(--frame-radius) / 2);\n padding: 12px 16px;\n color: var(--frame-text);\n font-size: 16px;\n transition: all 0.3s ease;\n}\n\n.inputGroup input:focus {\n outline: none;\n border-color: var(--frame-accent);\n box-shadow: 0 0 0 2px rgba(99, 102, 241, 0.2);\n}\n\n.frameActionArea {\n display: flex;\n justify-content: center;\n margin-top: 24px;\n}\n\n.frameButton {\n background: linear-gradient(135deg, #6366f1, #8b5cf6);\n color: var(--frame-text);\n border: none;\n padding: 14px 32px;\n border-radius: var(--frame-radius);\n font-size: 16px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.3s ease;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.frameButton:hover {\n transform: translateY(-2px);\n box-shadow: 0 6px 20px rgba(99, 102, 241, 0.3);\n}\n\n@media (max-width: 480px) {\n .frameContainer {\n padding: 16px;\n }\n \n .frameContent {\n padding: 24px;\n }\n \n .frameTitle {\n font-size: 24px;\n }\n}\n\n---script.js---\nconst initializeFrame = async () => {\n try {\n const frameContext = await window.frames.getContext();\n console.log('Frame context:', frameContext);\n\n const amountInput = document.querySelector('#amount');\n const sendButton = document.querySelector('.frameButton');\n\n sendButton.addEventListener('click', async () => {\n try {\n const amount = amountInput.value;\n if (!amount || amount <= 0) {\n alert('Please enter a valid amount');\n return;\n }\n\n await window.frames.postMessage({\n action: 'post',\n amount: amount\n });\n } catch (error) {\n console.error('Frame action error:', error);\n }\n });\n\n await window.frames.ready();\n } catch (error) {\n console.error('Frame initialization error:', error);\n }\n};\n\ndocument.addEventListener('DOMContentLoaded', initializeFrame);\n\n---manifest.json---\n{\n \"version\": \"vNext\",\n \"name\": \"Send Funds\",\n \"description\": \"Send funds to your Farcaster friends securely\",\n \"image\": {\n \"src\": \"https://sendframehub.pro/images/send-frame.png\",\n \"aspectRatio\": \"1.91:1\"\n },\n \"buttons\": [\n {\n \"label\": \"SEND\",\n \"action\": \"post\"\n }\n ],\n \"postUrl\": \"https://sendframehub.pro/api\"\n}\n\n---meta.json---\n{\n \"version\": \"next\",\n \"imageUrl\": \"https://sendframehub.pro/images/send-frame.png\",\n \"button\": {\n \"title\": \"Send Funds\",\n \"action\": {\n \"type\": \"launch_frame\",\n \"name\": \"Send Funds Frame\",\n \"url\": \"https://sendframehub.pro\",\n \"splashImageUrl\": \"https://sendframehub.pro/images/splash.png\",\n \"splashBackgroundColor\": \"#0a0a0a\"\n }\n }\n}\n\n---api.js---\nexport default async function handler(req, res) {\n if (req.method !== 'POST') {\n return res.status(405).json({ error: 'Method not allowed' });\n }\n\n try {\n const { amount, trustedData } = req.body;\n const { fid } = trustedData.messageBytes;\n\n // Here you would integrate with your preferred payment solution\n // For example, using Base, Optimism, or other L2 solutions\n\n return res.status(200).json({\n version: 'vNext',\n image: {\n src: 'https://sendframehub.pro/images/success.png',\n aspectRatio: '1.91:1'\n },\n buttons: [\n {\n label: 'SEND MORE',\n action: 'post'\n }\n ]\n });\n } catch (error) {\n console.error('Frame API error:', error);\n return res.status(500).json({ error: 'Internal server error' });\n }\n}\n\n---end---\n\nThis Frame implementation creates a sleek, modern interface for sending funds to Farcaster friends. Key features include:\n\n1. Beautiful gradient design with glass-morphism effects\n2. Responsive input field for entering ETH amount\n3. Smooth animations and transitions\n4. Error handling and validation\n5. Clean, semantic HTML structure\n6. Accessibility considerations\n7. Mobile-first responsive design\n\nThe design uses a modern dark theme with purple/indigo accents, creating a professional and trustworthy feeling that's appropriate for financial transactions. The UI is intentionally simple to reduce friction in the sending process.\n\nNote that you'd need to:\n1. Add actual payment processing logic in the API handler\n2. Create and host the required images (send-frame.png, success.png, splash.png)\n3. Set up proper security measures for handling transactions\n4. Implement proper error handling and transaction confirmation flows" + } + ], + "stop_reason": "end_turn", + "stop_sequence": null, + "usage": { + "input_tokens": 2297, + "cache_creation_input_tokens": 0, + "cache_read_input_tokens": 0, + "output_tokens": 2339 + } +} \ No newline at end of file diff --git a/readme.scroll b/readme.scroll new file mode 100644 index 0000000..63f325e --- /dev/null +++ b/readme.scroll @@ -0,0 +1,3 @@ +# sendframehub.pro.framehub.pro + +frame generated by Claude from prompt: build me a frame for sending my friends money on warpcast \ No newline at end of file diff --git a/script.js b/script.js new file mode 100644 index 0000000..ef8f69b --- /dev/null +++ b/script.js @@ -0,0 +1,32 @@ +const initializeFrame = async () => { + try { + const frameContext = await window.frames.getContext(); + console.log('Frame context:', frameContext); + + const amountInput = document.querySelector('#amount'); + const sendButton = document.querySelector('.frameButton'); + + sendButton.addEventListener('click', async () => { + try { + const amount = amountInput.value; + if (!amount || amount <= 0) { + alert('Please enter a valid amount'); + return; + } + + await window.frames.postMessage({ + action: 'post', + amount: amount + }); + } catch (error) { + console.error('Frame action error:', error); + } + }); + + await window.frames.ready(); + } catch (error) { + console.error('Frame initialization error:', error); + } +}; + +document.addEventListener('DOMContentLoaded', initializeFrame); diff --git a/style.css b/style.css new file mode 100644 index 0000000..baff676 --- /dev/null +++ b/style.css @@ -0,0 +1,116 @@ +:root { + --frame-bg: #0a0a0a; + --frame-text: #ffffff; + --frame-accent: #6366f1; + --frame-input-bg: rgba(255, 255, 255, 0.1); + --frame-radius: 16px; + --frame-shadow: 0 8px 32px rgba(99, 102, 241, 0.15); +} + +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; + background: var(--frame-bg); + color: var(--frame-text); + min-height: 100vh; + display: flex; + flex-direction: column; +} + +.frameContainer { + width: 100%; + max-width: 500px; + margin: 0 auto; + padding: 24px; +} + +.frameContent { + background: linear-gradient(145deg, rgba(255, 255, 255, 0.08), rgba(255, 255, 255, 0.03)); + border-radius: var(--frame-radius); + padding: 32px; + backdrop-filter: blur(12px); + border: 1px solid rgba(255, 255, 255, 0.1); + box-shadow: var(--frame-shadow); +} + +.frameTitle { + font-size: 28px; + font-weight: 700; + margin-bottom: 24px; + text-align: center; + background: linear-gradient(135deg, #6366f1, #8b5cf6); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; +} + +.inputGroup { + margin-bottom: 24px; +} + +.inputGroup label { + display: block; + margin-bottom: 8px; + font-size: 14px; + color: rgba(255, 255, 255, 0.8); +} + +.inputGroup input { + width: 100%; + background: var(--frame-input-bg); + border: 1px solid rgba(255, 255, 255, 0.1); + border-radius: calc(var(--frame-radius) / 2); + padding: 12px 16px; + color: var(--frame-text); + font-size: 16px; + transition: all 0.3s ease; +} + +.inputGroup input:focus { + outline: none; + border-color: var(--frame-accent); + box-shadow: 0 0 0 2px rgba(99, 102, 241, 0.2); +} + +.frameActionArea { + display: flex; + justify-content: center; + margin-top: 24px; +} + +.frameButton { + background: linear-gradient(135deg, #6366f1, #8b5cf6); + color: var(--frame-text); + border: none; + padding: 14px 32px; + border-radius: var(--frame-radius); + font-size: 16px; + font-weight: 600; + cursor: pointer; + transition: all 0.3s ease; + text-transform: uppercase; + letter-spacing: 0.5px; +} + +.frameButton:hover { + transform: translateY(-2px); + box-shadow: 0 6px 20px rgba(99, 102, 241, 0.3); +} + +@media (max-width: 480px) { + .frameContainer { + padding: 16px; + } + + .frameContent { + padding: 24px; + } + + .frameTitle { + font-size: 24px; + } +}