Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
b812186
feat(frontend): add Connect Wallet integration on home page
DevSolex Feb 17, 2026
dbbbf7a
feat(frontend): add Connect Wallet to Navbar
DevSolex Feb 17, 2026
03486f7
feat(frontend): add S-pay contract constants
DevSolex Feb 17, 2026
3c54923
feat(frontend): add contract call helpers with @stacks/transactions
DevSolex Feb 17, 2026
17fad52
feat(frontend): expose callContract via openContractCall in StacksCon…
DevSolex Feb 17, 2026
c1c7d95
feat(frontend): add Navbar to root layout
DevSolex Feb 17, 2026
61eb823
feat(frontend): add useRegisterUser and useVaultDeposit hooks
DevSolex Feb 17, 2026
32032e6
feat(frontend): add buildRegisterMerchantOptions to contract-calls
DevSolex Feb 17, 2026
d861c20
feat(frontend): add useProcessPayment and useRegisterMerchant hooks
DevSolex Feb 17, 2026
39f9fca
feat(frontend): add read-only contract calls with @stacks/transactions
DevSolex Feb 17, 2026
4f28067
feat(frontend): add useUserData hook for get-user-data
DevSolex Feb 17, 2026
ee5049a
feat(frontend): add RegisterUserForm component
DevSolex Feb 17, 2026
f45d816
feat(frontend): add /register page with RegisterUserForm
DevSolex Feb 17, 2026
f157354
feat(frontend): add transferStx via openSTXTransfer from @stacks/connect
DevSolex Feb 17, 2026
6767497
feat(frontend): add Register link to Navbar
DevSolex Feb 17, 2026
faa1e80
feat(frontend): add buildVaultWithdraw and buildMerchantWithdraw
DevSolex Feb 17, 2026
c845355
feat(frontend): add useVaultWithdraw and useMerchantWithdraw hooks
DevSolex Feb 17, 2026
2451f9d
feat(frontend): add useTransferStx hook for openSTXTransfer
DevSolex Feb 17, 2026
fa9b190
feat(frontend): add getProtocolStatus to read-only lib
DevSolex Feb 17, 2026
b2251a3
feat(frontend): add useProtocolStatus hook
DevSolex Feb 17, 2026
8c03905
feat(frontend): add buildReclaimStakeOptions and useReclaimStake
DevSolex Feb 17, 2026
a0203ce
feat(frontend): add PaymentForm using useProcessPayment and buildProc…
DevSolex Feb 17, 2026
044e734
feat(frontend): add /pay page with PaymentForm
DevSolex Feb 17, 2026
663e36c
feat(frontend): add Pay link to Navbar
DevSolex Feb 17, 2026
6cb43ef
feat(frontend): use cvToValue from @stacks/transactions for protocol …
DevSolex Feb 17, 2026
3b40bc4
feat(frontend): add RegisterMerchantForm using useRegisterMerchant
DevSolex Feb 17, 2026
24aa475
feat(frontend): add /merchant/register page
DevSolex Feb 17, 2026
3b42196
feat(frontend): add VaultDepositForm using useVaultDeposit
DevSolex Feb 17, 2026
82862b2
feat(frontend): add /vault page
DevSolex Feb 17, 2026
e963c6f
feat(frontend): add Vault and Merchant links to Navbar
DevSolex Feb 17, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions frontend/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { Metadata } from "next";
import "./globals.css";
import { StacksProvider } from "@/context/StacksContext";
import Navbar from "@/components/Navbar/Navbar";

export const metadata: Metadata = {
title: "S-pay | Premium Stacks Payments",
Expand All @@ -21,6 +22,7 @@ export default function RootLayout({
</head>
<body>
<StacksProvider>
<Navbar />
{children}
</StacksProvider>
</body>
Expand Down
16 changes: 16 additions & 0 deletions frontend/app/merchant/register/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
"use client";

import { RegisterMerchantForm } from "@/components/RegisterMerchantForm/RegisterMerchantForm";
import styles from "./register.module.css";

export default function MerchantRegisterPage() {
return (
<div className={styles.page}>
<h1 className={styles.title}>Register as Merchant</h1>
<p className={styles.subtitle}>
Requires 50 STX verification stake (register-merchant)
</p>
<RegisterMerchantForm />
</div>
);
}
18 changes: 18 additions & 0 deletions frontend/app/merchant/register/register.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
.page {
min-height: 80vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 2rem;
}

.title {
font-size: 2rem;
margin-bottom: 0.5rem;
}

.subtitle {
color: #a0a0aa;
margin-bottom: 2rem;
}
33 changes: 0 additions & 33 deletions frontend/app/page.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -48,39 +48,6 @@
line-height: 1.6;
}

.actions {
display: flex;
gap: 1.5rem;
justify-content: center;
}

.primaryBtn {
background: var(--primary);
color: white;
padding: 1rem 2.5rem;
border-radius: 12px;
font-weight: 600;
transition: var(--transition-smooth);
}

.primaryBtn:hover {
transform: translateY(-2px);
box-shadow: 0 0 20px var(--primary-glow);
}

.secondaryBtn {
border: 1px solid var(--glass-border);
color: var(--foreground);
padding: 1rem 2.5rem;
border-radius: 12px;
font-weight: 600;
transition: var(--transition-smooth);
}

.secondaryBtn:hover {
background: rgba(255, 255, 255, 0.05);
}

@media (max-width: 768px) {
.title {
font-size: 3rem;
Expand Down
17 changes: 3 additions & 14 deletions frontend/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import styles from "./page.module.css";
import { ConnectWallet } from "@/components/ConnectWallet/ConnectWallet";

export default function Home() {
return (
Expand All @@ -10,23 +11,11 @@ export default function Home() {
<span>Powered by Stacks.</span>
</h1>
<p className={styles.description}>
Experience the most premium payment gateway for the Bitcoin ecosystem.
Experience the most premium payment gateway for the Bitcoin ecosystem.
Fast, decentralized, and built for modern commerce.
</p>
<div className={styles.actions}>
<button className={styles.primaryBtn}>Connect Wallet</button>
<button className={styles.secondaryBtn}>Learn More</button>
</div>
<ConnectWallet />
</header>
</div>
);
}
// Final polish 62
// Final polish 63
// Final polish 64
// Final polish 65
// Final polish 66
// Final polish 67
// Final polish 68
// Final polish 69
// Final polish 70
16 changes: 16 additions & 0 deletions frontend/app/pay/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
"use client";

import { PaymentForm } from "@/components/PaymentForm/PaymentForm";
import styles from "./pay.module.css";

export default function PayPage() {
return (
<div className={styles.page}>
<h1 className={styles.title}>Process Payment</h1>
<p className={styles.subtitle}>
Send STX via S-pay protocol (process-payment)
</p>
<PaymentForm />
</div>
);
}
18 changes: 18 additions & 0 deletions frontend/app/pay/pay.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
.page {
min-height: 80vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 2rem;
}

.title {
font-size: 2rem;
margin-bottom: 0.5rem;
}

.subtitle {
color: #a0a0aa;
margin-bottom: 2rem;
}
16 changes: 16 additions & 0 deletions frontend/app/register/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
"use client";

import { RegisterUserForm } from "@/components/RegisterUserForm/RegisterUserForm";
import styles from "./register.module.css";

export default function RegisterPage() {
return (
<div className={styles.page}>
<h1 className={styles.title}>Register as User</h1>
<p className={styles.subtitle}>
Pick a unique username to join S-pay (string-ascii 24 max)
</p>
<RegisterUserForm />
</div>
);
}
18 changes: 18 additions & 0 deletions frontend/app/register/register.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
.page {
min-height: 80vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 2rem;
}

.title {
font-size: 2rem;
margin-bottom: 0.5rem;
}

.subtitle {
color: #a0a0aa;
margin-bottom: 2rem;
}
16 changes: 16 additions & 0 deletions frontend/app/vault/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
"use client";

import { VaultDepositForm } from "@/components/VaultDepositForm/VaultDepositForm";
import styles from "./vault.module.css";

export default function VaultPage() {
return (
<div className={styles.page}>
<h1 className={styles.title}>Vault Deposit</h1>
<p className={styles.subtitle}>
Deposit STX to your S-pay vault (vault-deposit)
</p>
<VaultDepositForm />
</div>
);
}
18 changes: 18 additions & 0 deletions frontend/app/vault/vault.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
.page {
min-height: 80vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 2rem;
}

.title {
font-size: 2rem;
margin-bottom: 0.5rem;
}

.subtitle {
color: #a0a0aa;
margin-bottom: 2rem;
}
42 changes: 42 additions & 0 deletions frontend/components/ConnectWallet/ConnectWallet.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
.actions {
display: flex;
gap: 1.5rem;
justify-content: center;
align-items: center;
}

.address {
font-family: monospace;
font-size: 0.95rem;
color: var(--foreground);
background: rgba(255, 255, 255, 0.05);
padding: 0.5rem 1rem;
border-radius: 8px;
}

.primaryBtn {
background: var(--primary);
color: white;
padding: 1rem 2.5rem;
border-radius: 12px;
font-weight: 600;
transition: var(--transition-smooth);
}

.primaryBtn:hover {
transform: translateY(-2px);
box-shadow: 0 0 20px var(--primary-glow);
}

.secondaryBtn {
border: 1px solid var(--glass-border);
color: var(--foreground);
padding: 1rem 2.5rem;
border-radius: 12px;
font-weight: 600;
transition: var(--transition-smooth);
}

.secondaryBtn:hover {
background: rgba(255, 255, 255, 0.05);
}
29 changes: 29 additions & 0 deletions frontend/components/ConnectWallet/ConnectWallet.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
"use client";

import { useStacks } from "@/context/StacksContext";
import styles from "./ConnectWallet.module.css";

export function ConnectWallet() {
const { userData, handleConnect, handleDisconnect } = useStacks();
const address = userData?.profile?.stxAddress?.mainnet ?? userData?.profile?.stxAddress?.testnet;

return (
<div className={styles.actions}>
{address ? (
<>
<span className={styles.address}>{address.slice(0, 6)}…{address.slice(-4)}</span>
<button className={styles.secondaryBtn} onClick={handleDisconnect}>
Disconnect
</button>
</>
) : (
<>
<button className={styles.primaryBtn} onClick={handleConnect}>
Connect Wallet
</button>
<button className={styles.secondaryBtn}>Learn More</button>
</>
)}
</div>
);
}
15 changes: 15 additions & 0 deletions frontend/components/Navbar/Navbar.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,21 @@
color: var(--foreground);
}

.actions {
display: flex;
align-items: center;
gap: 1rem;
}

.address {
font-family: monospace;
font-size: 0.85rem;
color: var(--foreground);
background: rgba(255, 255, 255, 0.05);
padding: 0.4rem 0.8rem;
border-radius: 8px;
}

.connectBtn {
background: rgba(255, 255, 255, 0.05);
border: 1px solid var(--glass-border);
Expand Down
17 changes: 16 additions & 1 deletion frontend/components/Navbar/Navbar.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,37 @@
"use client";

import Link from "next/link";
import { useStacks } from "@/context/StacksContext";
import styles from "./Navbar.module.css";

export default function Navbar() {
const { userData, handleConnect, handleDisconnect } = useStacks();
const addr = userData?.profile?.stxAddress?.mainnet ?? userData?.profile?.stxAddress?.testnet;

return (
<nav className={styles.navbar}>
<div className={styles.container}>
<Link href="/" className={styles.logo}>
S-pay<span className={styles.dot}>.</span>
</Link>
<div className={styles.links}>
<Link href="/register" className={styles.link}>Register</Link>
<Link href="/pay" className={styles.link}>Pay</Link>
<Link href="/vault" className={styles.link}>Vault</Link>
<Link href="/merchant/register" className={styles.link}>Merchant</Link>
<Link href="/payments" className={styles.link}>Payments</Link>
<Link href="/tokens" className={styles.link}>Tokens</Link>
<Link href="/docs" className={styles.link}>Developers</Link>
</div>
<div className={styles.actions}>
<button className={styles.connectBtn}>Connect</button>
{addr ? (
<>
<span className={styles.address}>{addr.slice(0, 6)}…{addr.slice(-4)}</span>
<button className={styles.connectBtn} onClick={handleDisconnect}>Disconnect</button>
</>
) : (
<button className={styles.connectBtn} onClick={handleConnect}>Connect</button>
)}
</div>
</div>
</nav>
Expand Down
22 changes: 22 additions & 0 deletions frontend/components/PaymentForm/PaymentForm.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
.form {
display: flex;
flex-direction: column;
gap: 0.75rem;
max-width: 400px;
}

.input {
padding: 0.6rem 1rem;
border-radius: 8px;
border: 1px solid var(--glass-border);
background: rgba(255, 255, 255, 0.05);
color: var(--foreground);
}

.btn {
background: var(--primary);
color: white;
padding: 0.75rem;
border-radius: 8px;
font-weight: 600;
}
Loading
Loading