mirror of
https://github.com/Such-Software/smirk-website.git
synced 2026-10-17 05:51:28 +02:00
add ToS to website
This commit is contained in:
@@ -26,6 +26,10 @@ export default function RootLayout({
|
||||
Privacy Policy
|
||||
</a>
|
||||
<span className="text-zinc-700">•</span>
|
||||
<a href="/terms" className="hover:text-[#fbeb0a] transition-colors">
|
||||
Terms of Service
|
||||
</a>
|
||||
<span className="text-zinc-700">•</span>
|
||||
<span>
|
||||
Made & Hosted by{" "}
|
||||
<a
|
||||
|
||||
+70
-90
@@ -6,7 +6,7 @@ import Link from 'next/link';
|
||||
import {
|
||||
getMe,
|
||||
getLinkedSocials,
|
||||
registerSocial,
|
||||
initiateLink,
|
||||
unlinkSocial,
|
||||
getMyUsername,
|
||||
setUsername,
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
type LinkedSocial,
|
||||
} from '@/lib/api';
|
||||
|
||||
type LinkStep = 'idle' | 'entering' | 'verifying';
|
||||
type LinkStep = 'idle' | 'linking' | 'waiting';
|
||||
|
||||
export default function SettingsPage() {
|
||||
const [user, setUser] = useState<MeResponse | null>(null);
|
||||
@@ -31,10 +31,9 @@ export default function SettingsPage() {
|
||||
|
||||
// Telegram linking state
|
||||
const [linkStep, setLinkStep] = useState<LinkStep>('idle');
|
||||
const [telegramUsername, setTelegramUsername] = useState('');
|
||||
const [verificationCode, setVerificationCode] = useState<string | null>(null);
|
||||
const [botLink, setBotLink] = useState<string | null>(null);
|
||||
const [deepLink, setDeepLink] = useState<string | null>(null);
|
||||
const [linkError, setLinkError] = useState<string | null>(null);
|
||||
const [polling, setPolling] = useState(false);
|
||||
|
||||
const token = typeof window !== 'undefined' ? localStorage.getItem('smirk_token') : null;
|
||||
|
||||
@@ -81,25 +80,51 @@ export default function SettingsPage() {
|
||||
}
|
||||
};
|
||||
|
||||
const handleStartLink = () => {
|
||||
setLinkStep('entering');
|
||||
const handleStartLink = async () => {
|
||||
if (!token) return;
|
||||
setLinkStep('linking');
|
||||
setLinkError(null);
|
||||
};
|
||||
|
||||
const handleSubmitUsername = async () => {
|
||||
if (!token || !telegramUsername.trim()) return;
|
||||
|
||||
setLinkError(null);
|
||||
try {
|
||||
const result = await registerSocial(token, 'telegram', telegramUsername.trim());
|
||||
setVerificationCode(result.verification_code);
|
||||
setBotLink(result.bot_link);
|
||||
setLinkStep('verifying');
|
||||
const result = await initiateLink(token, 'telegram');
|
||||
setDeepLink(result.deep_link);
|
||||
setLinkStep('waiting');
|
||||
// Start polling for verification
|
||||
startPolling();
|
||||
} catch (err) {
|
||||
setLinkError(err instanceof Error ? err.message : 'Failed to start verification');
|
||||
setLinkError(err instanceof Error ? err.message : 'Failed to initiate link');
|
||||
setLinkStep('idle');
|
||||
}
|
||||
};
|
||||
|
||||
const startPolling = () => {
|
||||
if (polling) return;
|
||||
setPolling(true);
|
||||
};
|
||||
|
||||
// Polling effect for verification status
|
||||
useEffect(() => {
|
||||
if (!polling || !token) return;
|
||||
|
||||
const interval = setInterval(async () => {
|
||||
try {
|
||||
const socialsData = await getLinkedSocials(token);
|
||||
setSocials(socialsData.socials);
|
||||
const telegram = socialsData.socials.find((s) => s.platform === 'telegram');
|
||||
if (telegram?.verified) {
|
||||
// Success! Stop polling and reset state
|
||||
setPolling(false);
|
||||
setLinkStep('idle');
|
||||
setDeepLink(null);
|
||||
}
|
||||
} catch {
|
||||
// Ignore polling errors, keep trying
|
||||
}
|
||||
}, 3000); // Poll every 3 seconds
|
||||
|
||||
return () => clearInterval(interval);
|
||||
}, [polling, token]);
|
||||
|
||||
const handleUnlink = async (platform: string) => {
|
||||
if (!token) return;
|
||||
if (!confirm(`Unlink ${platform}?`)) return;
|
||||
@@ -114,27 +139,9 @@ export default function SettingsPage() {
|
||||
|
||||
const handleCancelLink = () => {
|
||||
setLinkStep('idle');
|
||||
setTelegramUsername('');
|
||||
setVerificationCode(null);
|
||||
setBotLink(null);
|
||||
setDeepLink(null);
|
||||
setLinkError(null);
|
||||
};
|
||||
|
||||
const handleVerificationDone = async () => {
|
||||
if (!token) return;
|
||||
// Refresh socials to check if verified
|
||||
try {
|
||||
const socialsData = await getLinkedSocials(token);
|
||||
setSocials(socialsData.socials);
|
||||
const telegram = socialsData.socials.find((s) => s.platform === 'telegram');
|
||||
if (telegram?.verified) {
|
||||
handleCancelLink();
|
||||
} else {
|
||||
setLinkError('Verification not complete. Send the code to the bot and try again.');
|
||||
}
|
||||
} catch {
|
||||
setLinkError('Failed to check verification status');
|
||||
}
|
||||
setPolling(false);
|
||||
};
|
||||
|
||||
if (loading) {
|
||||
@@ -271,9 +278,11 @@ export default function SettingsPage() {
|
||||
<div>
|
||||
<p className="font-medium">Telegram</p>
|
||||
{telegramSocial?.verified ? (
|
||||
<p className="text-sm text-green-400">@{telegramSocial.username}</p>
|
||||
<p className="text-sm text-green-400">
|
||||
{telegramSocial.username ? `@${telegramSocial.username}` : telegramSocial.display_name || 'Linked'}
|
||||
</p>
|
||||
) : telegramSocial?.pending_verification ? (
|
||||
<p className="text-sm text-yellow-400">Pending: @{telegramSocial.username}</p>
|
||||
<p className="text-sm text-yellow-400">Verification pending</p>
|
||||
) : (
|
||||
<p className="text-sm text-zinc-500">Not linked</p>
|
||||
)}
|
||||
@@ -298,68 +307,33 @@ export default function SettingsPage() {
|
||||
</div>
|
||||
|
||||
{/* Link flow UI */}
|
||||
{linkStep === 'entering' && (
|
||||
{linkStep === 'linking' && (
|
||||
<div className="mt-4 pt-4 border-t border-zinc-800">
|
||||
<label className="block text-sm text-zinc-400 mb-2">
|
||||
Enter your Telegram username
|
||||
</label>
|
||||
<div className="flex gap-2">
|
||||
<input
|
||||
type="text"
|
||||
value={telegramUsername}
|
||||
onChange={(e) => setTelegramUsername(e.target.value)}
|
||||
placeholder="@username"
|
||||
className="flex-1 px-3 py-2 bg-zinc-800 border border-zinc-700 rounded-lg text-white placeholder:text-zinc-500 focus:outline-none focus:border-[#fbeb0a]"
|
||||
/>
|
||||
<button
|
||||
onClick={handleSubmitUsername}
|
||||
disabled={!telegramUsername.trim()}
|
||||
className="px-4 py-2 bg-[#fbeb0a] text-black font-medium rounded-lg hover:bg-[#d4c708] disabled:opacity-50"
|
||||
>
|
||||
Next
|
||||
</button>
|
||||
<button
|
||||
onClick={handleCancelLink}
|
||||
className="px-4 py-2 border border-zinc-700 rounded-lg hover:border-zinc-500"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="animate-spin w-5 h-5 border-2 border-[#fbeb0a] border-t-transparent rounded-full" />
|
||||
<span className="text-zinc-400">Setting up link...</span>
|
||||
</div>
|
||||
{linkError && <p className="mt-2 text-sm text-red-400">{linkError}</p>}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{linkStep === 'verifying' && verificationCode && (
|
||||
{linkStep === 'waiting' && deepLink && (
|
||||
<div className="mt-4 pt-4 border-t border-zinc-800">
|
||||
<div className="bg-zinc-800 rounded-lg p-4 mb-4">
|
||||
<p className="text-sm text-zinc-400 mb-2">Your verification code:</p>
|
||||
<p className="text-2xl font-mono font-bold text-[#fbeb0a]">{verificationCode}</p>
|
||||
</div>
|
||||
<p className="text-sm text-zinc-400 mb-4">
|
||||
Click the button below to open Telegram and link your account automatically:
|
||||
</p>
|
||||
|
||||
<ol className="text-sm text-zinc-400 space-y-2 mb-4">
|
||||
<li>
|
||||
1. Open{' '}
|
||||
<div className="flex gap-2 mb-4">
|
||||
<a
|
||||
href={botLink || 'https://t.me/smirk_wallet_bot'}
|
||||
href={deepLink}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-[#0088cc] hover:underline"
|
||||
className="flex items-center gap-2 px-4 py-2 bg-[#0088cc] text-white font-medium rounded-lg hover:bg-[#0077b3]"
|
||||
>
|
||||
@smirk_wallet_bot
|
||||
</a>{' '}
|
||||
on Telegram
|
||||
</li>
|
||||
<li>2. Send: <code className="bg-zinc-700 px-2 py-0.5 rounded">/verify {verificationCode}</code></li>
|
||||
<li>3. Click "I've verified" below</li>
|
||||
</ol>
|
||||
|
||||
<div className="flex gap-2">
|
||||
<button
|
||||
onClick={handleVerificationDone}
|
||||
className="px-4 py-2 bg-[#fbeb0a] text-black font-medium rounded-lg hover:bg-[#d4c708]"
|
||||
>
|
||||
I've verified
|
||||
</button>
|
||||
<svg className="w-5 h-5" viewBox="0 0 24 24" fill="currentColor">
|
||||
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm4.64 6.8c-.15 1.58-.8 5.42-1.13 7.19-.14.75-.42 1-.68 1.03-.58.05-1.02-.38-1.58-.75-.88-.58-1.38-.94-2.23-1.5-.99-.65-.35-1.01.22-1.59.15-.15 2.71-2.48 2.76-2.69a.2.2 0 00-.05-.18c-.06-.05-.14-.03-.21-.02-.09.02-1.49.95-4.22 2.79-.4.27-.76.41-1.08.4-.36-.01-1.04-.2-1.55-.37-.63-.2-1.12-.31-1.08-.66.02-.18.27-.36.74-.55 2.92-1.27 4.86-2.11 5.83-2.51 2.78-1.16 3.35-1.36 3.73-1.36.08 0 .27.02.39.12.1.08.13.19.14.27-.01.06.01.24 0 .38z" />
|
||||
</svg>
|
||||
Open Telegram
|
||||
</a>
|
||||
<button
|
||||
onClick={handleCancelLink}
|
||||
className="px-4 py-2 border border-zinc-700 rounded-lg hover:border-zinc-500"
|
||||
@@ -367,6 +341,12 @@ export default function SettingsPage() {
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-2 text-sm text-zinc-500">
|
||||
<div className="animate-spin w-4 h-4 border-2 border-zinc-500 border-t-transparent rounded-full" />
|
||||
<span>Waiting for verification...</span>
|
||||
</div>
|
||||
|
||||
{linkError && <p className="mt-2 text-sm text-red-400">{linkError}</p>}
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -0,0 +1,302 @@
|
||||
'use client';
|
||||
|
||||
import Image from 'next/image';
|
||||
import Link from 'next/link';
|
||||
|
||||
export default function Terms() {
|
||||
return (
|
||||
<div className="min-h-screen flex flex-col items-center p-8">
|
||||
{/* Header */}
|
||||
<div className="mb-8 flex flex-col items-center">
|
||||
<Link href="/" className="logo-glow mb-4">
|
||||
<Image
|
||||
src="/logo.svg"
|
||||
alt="Smirk"
|
||||
width={80}
|
||||
height={80}
|
||||
priority
|
||||
/>
|
||||
</Link>
|
||||
<h1 className="creepster-text text-3xl">Terms of Service</h1>
|
||||
</div>
|
||||
|
||||
{/* Content */}
|
||||
<div className="max-w-2xl w-full bg-zinc-900/50 rounded-2xl p-8 space-y-8">
|
||||
<p className="text-zinc-400 text-sm">
|
||||
Last Updated: January 31, 2026
|
||||
</p>
|
||||
|
||||
<p className="text-zinc-300 text-lg leading-relaxed">
|
||||
BY ACCESSING OR USING SMIRK WALLET, YOU AGREE TO BE BOUND BY THESE TERMS OF SERVICE.
|
||||
IF YOU DO NOT AGREE, DO NOT USE OUR SERVICES.
|
||||
</p>
|
||||
|
||||
{/* Section 1 */}
|
||||
<section>
|
||||
<h2 className="text-xl font-bold text-[#fbeb0a] mb-4">1. Eligibility</h2>
|
||||
<p className="text-zinc-300 mb-4">
|
||||
You represent and warrant that you:
|
||||
</p>
|
||||
<ul className="space-y-2 text-zinc-400 ml-4 list-disc list-inside">
|
||||
<li>Are of legal age to form a binding contract in your jurisdiction</li>
|
||||
<li>Have not previously been suspended or removed from using our Services</li>
|
||||
<li>Have full power and authority to enter into this agreement</li>
|
||||
<li>Will not use these services in violation of any applicable laws</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
{/* Section 2 */}
|
||||
<section>
|
||||
<h2 className="text-xl font-bold text-[#fbeb0a] mb-4">2. Account & Wallet Security</h2>
|
||||
<p className="text-zinc-300 mb-4">
|
||||
When you create a Smirk wallet, you agree to:
|
||||
</p>
|
||||
<ul className="space-y-3 text-zinc-400">
|
||||
<li>
|
||||
<strong className="text-white">Secure Your Recovery Phrase:</strong> You are solely
|
||||
responsible for backing up and protecting your 24-word recovery phrase (mnemonic).
|
||||
This phrase is the only way to recover your wallet.
|
||||
</li>
|
||||
<li>
|
||||
<strong className="text-white">Password Protection:</strong> Maintain the security
|
||||
of your wallet password and restrict access to your devices.
|
||||
</li>
|
||||
<li>
|
||||
<strong className="text-white">Promptly Report Issues:</strong> Notify us if you
|
||||
discover or suspect any security breaches related to your account.
|
||||
</li>
|
||||
<li>
|
||||
<strong className="text-white">Accept Responsibility:</strong> Take responsibility
|
||||
for all activities that occur under your wallet, including any authorized or
|
||||
unauthorized access.
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
{/* Section 3 */}
|
||||
<section>
|
||||
<h2 className="text-xl font-bold text-[#fbeb0a] mb-4">3. Description of Services</h2>
|
||||
|
||||
<h3 className="text-lg font-semibold text-white mt-6 mb-3">3.1 Non-Custodial Wallet</h3>
|
||||
<p className="text-zinc-400 mb-4">
|
||||
Smirk is a <strong className="text-white">non-custodial</strong> multi-cryptocurrency
|
||||
wallet supporting Bitcoin (BTC), Litecoin (LTC), Monero (XMR), Wownero (WOW), and
|
||||
Grin (GRIN). Your private spend keys are generated and stored locally on your device.
|
||||
They are never transmitted to our servers. We cannot access, freeze, or seize your funds.
|
||||
</p>
|
||||
|
||||
<h3 className="text-lg font-semibold text-white mt-6 mb-3">3.2 Social Tipping</h3>
|
||||
<p className="text-zinc-400 mb-4">
|
||||
Smirk enables you to send cryptocurrency tips to users on social platforms (Telegram,
|
||||
Discord, etc.) and via public tip links. Tips are encrypted and can only be claimed
|
||||
by the intended recipient (or anyone with the link for public tips).
|
||||
</p>
|
||||
|
||||
<h3 className="text-lg font-semibold text-white mt-6 mb-3">3.3 No Recovery Phrase Retrieval</h3>
|
||||
<p className="text-zinc-400 mb-4">
|
||||
Our Services do not store your recovery phrase or unencrypted private keys. Therefore,
|
||||
we cannot assist you with recovery phrase retrieval.
|
||||
</p>
|
||||
<div className="bg-zinc-800/50 rounded-xl p-4 text-zinc-300">
|
||||
<strong className="text-[#fbeb0a]">WARNING:</strong> IF YOU LOSE YOUR RECOVERY PHRASE,
|
||||
YOU WILL PERMANENTLY LOSE ACCESS TO YOUR FUNDS. THERE IS NO WAY TO RECOVER THEM.
|
||||
</div>
|
||||
|
||||
<h3 className="text-lg font-semibold text-white mt-6 mb-3">3.4 Transaction Processing</h3>
|
||||
<p className="text-zinc-400 mb-4">
|
||||
All cryptocurrency transactions are processed by their respective decentralized
|
||||
networks (Bitcoin, Litecoin, Monero, Wownero, Grin). We do not control these networks
|
||||
and cannot guarantee transaction speed, confirmation, or reversal. Once a transaction
|
||||
is broadcast, it cannot be cancelled or modified.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* Section 4 */}
|
||||
<section>
|
||||
<h2 className="text-xl font-bold text-[#fbeb0a] mb-4">4. Fees</h2>
|
||||
<ul className="space-y-3 text-zinc-400">
|
||||
<li>
|
||||
<strong className="text-white">Service Fees:</strong> Access to Smirk wallet is
|
||||
currently free. We may introduce fees for certain services in the future.
|
||||
</li>
|
||||
<li>
|
||||
<strong className="text-white">Network Fees:</strong> All cryptocurrency transactions
|
||||
require network fees (miner fees) paid to the respective blockchain network. These
|
||||
fees are not collected by Smirk and are displayed before you confirm any transaction.
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
{/* Section 5 */}
|
||||
<section>
|
||||
<h2 className="text-xl font-bold text-[#fbeb0a] mb-4">5. Acceptable Use</h2>
|
||||
<p className="text-zinc-300 mb-4">You agree that you will NOT:</p>
|
||||
<ul className="space-y-2 text-zinc-400 ml-4 list-disc list-inside">
|
||||
<li>Use our Services to engage in illegal activities including fraud, money laundering,
|
||||
or terrorist financing</li>
|
||||
<li>Attempt to interfere with, disrupt, or overburden our Services</li>
|
||||
<li>Use automated means (bots, scrapers) to access our Services without permission</li>
|
||||
<li>Attempt to circumvent any security measures or access controls</li>
|
||||
<li>Introduce viruses, malware, or other harmful code</li>
|
||||
<li>Impersonate others or provide false information</li>
|
||||
<li>Use our Services to harass, abuse, or harm others</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
{/* Section 6 */}
|
||||
<section>
|
||||
<h2 className="text-xl font-bold text-[#fbeb0a] mb-4">6. Taxes</h2>
|
||||
<p className="text-zinc-400">
|
||||
It is your sole responsibility to determine what taxes apply to your cryptocurrency
|
||||
transactions and to report and remit the correct tax to the appropriate tax authority.
|
||||
Smirk is not responsible for determining, collecting, reporting, or remitting any
|
||||
taxes arising from your use of our Services.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* Section 7 */}
|
||||
<section>
|
||||
<h2 className="text-xl font-bold text-[#fbeb0a] mb-4">7. Assumption of Risk</h2>
|
||||
<p className="text-zinc-300 mb-4">
|
||||
You acknowledge and agree that there are risks associated with using cryptocurrency
|
||||
and Internet-based services, including but not limited to:
|
||||
</p>
|
||||
<ul className="space-y-2 text-zinc-400 ml-4 list-disc list-inside">
|
||||
<li>Price volatility and potential loss of value</li>
|
||||
<li>Risk of hardware, software, and Internet connection failures</li>
|
||||
<li>Risk of malicious software or phishing attacks</li>
|
||||
<li>Risk of unauthorized access to your devices or accounts</li>
|
||||
<li>Irreversibility of cryptocurrency transactions</li>
|
||||
<li>Regulatory changes that may affect cryptocurrency use</li>
|
||||
</ul>
|
||||
<p className="text-zinc-400 mt-4">
|
||||
Smirk is not responsible for any losses arising from forgotten recovery phrases,
|
||||
incorrect addresses, server failures, phishing attacks, or any other unauthorized
|
||||
third-party activities.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* Section 8 */}
|
||||
<section>
|
||||
<h2 className="text-xl font-bold text-[#fbeb0a] mb-4">8. Discontinuance of Services</h2>
|
||||
<p className="text-zinc-400">
|
||||
We may, in our sole discretion and without liability to you, modify or discontinue
|
||||
any portion of our Services at any time. You are solely responsible for maintaining
|
||||
a backup of your recovery phrase outside of the Services. If you have your recovery
|
||||
phrase, you can always access your funds using any compatible wallet software, even
|
||||
if Smirk discontinues its Services.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* Section 9 */}
|
||||
<section>
|
||||
<h2 className="text-xl font-bold text-[#fbeb0a] mb-4">9. Disclaimer of Warranties</h2>
|
||||
<p className="text-zinc-400 uppercase text-sm leading-relaxed">
|
||||
OUR SERVICES ARE PROVIDED ON AN "AS IS" AND "AS AVAILABLE" BASIS.
|
||||
TO THE MAXIMUM EXTENT PERMITTED BY LAW, WE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED,
|
||||
INCLUDING WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
|
||||
NON-INFRINGEMENT. WE DO NOT WARRANT THAT OUR SERVICES WILL BE UNINTERRUPTED,
|
||||
ERROR-FREE, OR SECURE.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* Section 10 */}
|
||||
<section>
|
||||
<h2 className="text-xl font-bold text-[#fbeb0a] mb-4">10. Limitation of Liability</h2>
|
||||
<p className="text-zinc-400 uppercase text-sm leading-relaxed">
|
||||
TO THE MAXIMUM EXTENT PERMITTED BY LAW, SMIRK AND ITS DIRECTORS, EMPLOYEES, AND
|
||||
AGENTS SHALL NOT BE LIABLE FOR ANY INDIRECT, INCIDENTAL, SPECIAL, CONSEQUENTIAL,
|
||||
OR PUNITIVE DAMAGES, INCLUDING BUT NOT LIMITED TO LOSS OF PROFITS, DATA, OR FUNDS,
|
||||
ARISING FROM YOUR USE OF OR INABILITY TO USE OUR SERVICES.
|
||||
</p>
|
||||
<p className="text-zinc-400 uppercase text-sm leading-relaxed mt-4">
|
||||
IN NO EVENT SHALL OUR AGGREGATE LIABILITY EXCEED ONE HUNDRED DOLLARS ($100 USD).
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* Section 11 */}
|
||||
<section>
|
||||
<h2 className="text-xl font-bold text-[#fbeb0a] mb-4">11. Indemnification</h2>
|
||||
<p className="text-zinc-400">
|
||||
You agree to defend, indemnify, and hold harmless Smirk and its officers, directors,
|
||||
employees, and agents from any claims, damages, losses, or expenses arising from:
|
||||
(a) your use of our Services; (b) your violation of these Terms; (c) your violation
|
||||
of any rights of any third party; or (d) any content you submit through our Services.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* Section 12 */}
|
||||
<section>
|
||||
<h2 className="text-xl font-bold text-[#fbeb0a] mb-4">12. Privacy</h2>
|
||||
<p className="text-zinc-400">
|
||||
Please refer to our{' '}
|
||||
<Link href="/privacy" className="text-[#fbeb0a] hover:underline">
|
||||
Privacy Policy
|
||||
</Link>
|
||||
{' '}for information about how we collect, use, and protect your information.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* Section 13 */}
|
||||
<section>
|
||||
<h2 className="text-xl font-bold text-[#fbeb0a] mb-4">13. Modifications to Terms</h2>
|
||||
<p className="text-zinc-400">
|
||||
We reserve the right to modify these Terms at any time. We will provide notice of
|
||||
material changes by updating the "Last Updated" date at the top of these Terms.
|
||||
Your continued use of our Services after any changes constitutes your acceptance of
|
||||
the new Terms.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* Section 14 */}
|
||||
<section>
|
||||
<h2 className="text-xl font-bold text-[#fbeb0a] mb-4">14. Governing Law</h2>
|
||||
<p className="text-zinc-400">
|
||||
These Terms shall be governed by and construed in accordance with the laws of the
|
||||
jurisdiction where Smirk operates, without regard to conflict of law principles.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* Section 15 */}
|
||||
<section>
|
||||
<h2 className="text-xl font-bold text-[#fbeb0a] mb-4">15. Severability</h2>
|
||||
<p className="text-zinc-400">
|
||||
If any provision of these Terms is found to be invalid or unenforceable, the remaining
|
||||
provisions shall remain in full force and effect.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* Quick Summary */}
|
||||
<section className="border border-zinc-700 rounded-xl p-6">
|
||||
<h2 className="text-lg font-bold text-white mb-4">Quick Summary</h2>
|
||||
<ul className="space-y-2 text-zinc-400">
|
||||
<li><strong className="text-[#fbeb0a]">Non-Custodial:</strong> You control your keys. We cannot access or recover your funds.</li>
|
||||
<li><strong className="text-[#fbeb0a]">Your Responsibility:</strong> Back up your recovery phrase. Losing it means losing your funds forever.</li>
|
||||
<li><strong className="text-[#fbeb0a]">Irreversible:</strong> Cryptocurrency transactions cannot be cancelled or reversed.</li>
|
||||
<li><strong className="text-[#fbeb0a]">No Guarantees:</strong> We provide the service as-is. Use at your own risk.</li>
|
||||
<li><strong className="text-[#fbeb0a]">Be Legal:</strong> Don't use Smirk for illegal activities.</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
{/* Contact */}
|
||||
<section className="bg-zinc-800/50 rounded-xl p-6">
|
||||
<h2 className="text-lg font-bold text-[#fbeb0a] mb-4">Questions?</h2>
|
||||
<p className="text-zinc-300">
|
||||
If you have questions about these Terms of Service, please contact us through our
|
||||
official channels or at the support email provided in the extension.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* Back link */}
|
||||
<div className="pt-4 text-center">
|
||||
<Link
|
||||
href="/"
|
||||
className="text-[#fbeb0a] hover:underline"
|
||||
>
|
||||
← Back to Smirk
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
+36
-1
@@ -87,12 +87,20 @@ export interface RegisterSocialResponse {
|
||||
|
||||
export interface LinkedSocial {
|
||||
platform: string;
|
||||
username: string;
|
||||
username: string | null;
|
||||
display_name: string | null;
|
||||
platform_user_id: string | null;
|
||||
verified: boolean;
|
||||
verified_at: string | null;
|
||||
pending_verification: boolean;
|
||||
}
|
||||
|
||||
export interface InitiateLinkResponse {
|
||||
deep_link: string;
|
||||
code: string;
|
||||
expires_at: string;
|
||||
}
|
||||
|
||||
export interface LinkedSocialsResponse {
|
||||
socials: LinkedSocial[];
|
||||
}
|
||||
@@ -119,6 +127,33 @@ export async function registerSocial(
|
||||
return res.json();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiate social link via deep link flow.
|
||||
*
|
||||
* Returns a deep link that opens the bot. User clicks the link,
|
||||
* bot extracts their info automatically, no manual username entry.
|
||||
*/
|
||||
export async function initiateLink(
|
||||
token: string,
|
||||
platform: string
|
||||
): Promise<InitiateLinkResponse> {
|
||||
const res = await fetch(`${API_URL}/api/v1/socials/initiate-link`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
body: JSON.stringify({ platform }),
|
||||
});
|
||||
|
||||
if (!res.ok) {
|
||||
const data = await res.json().catch(() => ({}));
|
||||
throw new Error(data.error || 'Failed to initiate link');
|
||||
}
|
||||
|
||||
return res.json();
|
||||
}
|
||||
|
||||
export async function getLinkedSocials(token: string): Promise<LinkedSocialsResponse> {
|
||||
const res = await fetch(`${API_URL}/api/v1/socials/me`, {
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
|
||||
Reference in New Issue
Block a user