Skip to content

Repository files navigation

🚀 Lazor Turbo Starter

The Ultimate Solana Starter Kit with Passkey Auth & Gasless Transactions

Built with Lazorkit Next.js 14 TypeScript Solana License: MIT


Say goodbye to seed phrases. Say goodbye to gas fees.

This starter kit demonstrates how to build production-ready Solana dApps using Lazorkit SDK — enabling biometric authentication (FaceID, TouchID, Windows Hello) and gasless transactions out of the box.

📖 Documentation · 🎮 Live Demo · 🐛 Report Bug


Lazor Turbo Starter Demo

✨ Why Use This Starter Kit?

Building a Web3 app shouldn't feel like building a spaceship. Lazor Turbo Starter removes the hardest parts:

Traditional Wallet UX With Lazorkit
❌ Users must install browser extensions ✅ Works instantly on any device
❌ Seed phrase management is scary ✅ Biometric auth they already know
❌ Users need SOL for gas fees ✅ Gasless via Paymaster — zero SOL needed
❌ Complex Web3 onboarding ✅ One-tap connection

🎯 What You'll Learn

  1. Passkey Authentication — Replace seed phrases with FaceID/TouchID
  2. Gasless Transactions — Let users transact without owning SOL
  3. Clean Architecture — Production-ready Next.js 14 patterns
  4. Type Safety — Strict TypeScript throughout

🏗️ Project Structure

lazor-turbo-starter/
├── 📄 package.json              # Dependencies & scripts
├── 📄 tailwind.config.ts        # Custom theme & animations
├── 📄 tsconfig.json             # Strict TypeScript config
├── 📄 next.config.js            # Next.js + Web3 optimizations
├── 📄 .env.example              # Environment variables template
│
├── 📁 src/
│   ├── 📁 app/
│   │   ├── 📄 layout.tsx        # Root layout with providers
│   │   ├── 📄 page.tsx          # Landing page UI
│   │   └── 📄 globals.css       # Global styles + animations
│   │
│   ├── 📁 components/
│   │   └── 📄 LazorProvider.tsx # SDK initialization wrapper
│   │
│   └── 📁 hooks/
│       └── 📄 useGaslessTip.ts  # Custom hook for gasless txs
│
└── 📄 README.md                 # You are here! 👋

🚀 Quick Start

Get up and running in under 2 minutes:

Prerequisites

  • Node.js 18+ installed
  • pnpm, npm, or yarn

Installation

# Clone the repository
git clone https://github.com/your-org/lazor-turbo-starter.git

# Navigate to the project
cd lazor-turbo-starter

# Install dependencies
npm install

# Copy environment variables
cp .env.example .env.local

# Start the development server
npm run dev

Open http://localhost:3000 to see your app! 🎉


📖 Tutorials

Tutorial 1: Setting Up Passkey Authentication

Passkeys use the WebAuthn standard to authenticate users using their device's biometrics (FaceID, TouchID, Windows Hello) or a hardware security key.

How It Works

sequenceDiagram
    participant User
    participant Browser
    participant Lazorkit
    participant Solana

    User->>Browser: Click "Connect with FaceID"
    Browser->>User: Biometric prompt (FaceID/TouchID)
    User->>Browser: Authenticate
    Browser->>Lazorkit: WebAuthn credential
    Lazorkit->>Lazorkit: Derive Solana keypair
    Lazorkit->>Solana: Register wallet
    Lazorkit->>Browser: Return wallet address
    Browser->>User: "Connected as 8abc...xyz"
Loading

Step 1: Wrap Your App with the Provider

Create src/components/LazorProvider.tsx:

'use client';

import { LazorkitProvider } from '@lazorkit/react-sdk';
import { ReactNode } from 'react';

const config = {
  rpcUrl: process.env.NEXT_PUBLIC_SOLANA_RPC_URL || 'https://api.devnet.solana.com',
  paymasterUrl: process.env.NEXT_PUBLIC_PAYMASTER_URL || 'https://api.devnet.lazorkit.com/paymaster',
  appName: 'My dApp',
};

export function LazorProvider({ children }: { children: ReactNode }) {
  return (
    <LazorkitProvider
      rpcUrl={config.rpcUrl}
      paymasterUrl={config.paymasterUrl}
      appName={config.appName}
    >
      {children}
    </LazorkitProvider>
  );
}

Step 2: Add the Provider to Your Layout

In src/app/layout.tsx:

import { LazorProvider } from '@/components/LazorProvider';

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        <LazorProvider>
          {children}
        </LazorProvider>
      </body>
    </html>
  );
}

Step 3: Use the Wallet Hook

In any client component:

'use client';

import { useLazorWallet } from '@lazorkit/react-sdk';

export default function ConnectButton() {
  const { loginWithPasskey, address, isConnected } = useLazorWallet();

  if (isConnected) {
    return <p>Connected: {address}</p>;
  }

  return (
    <button onClick={() => loginWithPasskey()}>
      Connect with FaceID
    </button>
  );
}

Tip

The address is a Solana public key derived from the user's passkey. It's unique per app + device combination.


Tutorial 2: Executing a Gasless Transaction

The Paymaster is a service that sponsors transaction fees on behalf of your users. This means:

  • Users don't need SOL to transact
  • Better onboarding for new crypto users
  • You control who gets free transactions

How It Works

sequenceDiagram
    participant User
    participant dApp
    participant Lazorkit
    participant Paymaster
    participant Solana

    User->>dApp: Click "Send Tip"
    dApp->>Lazorkit: Build transaction
    Lazorkit->>Paymaster: Request sponsorship
    Paymaster->>Paymaster: Validate request
    Paymaster->>Lazorkit: Add fee signature
    Lazorkit->>User: Biometric prompt
    User->>Lazorkit: Authenticate
    Lazorkit->>Solana: Submit transaction
    Solana->>dApp: Transaction confirmed
    dApp->>User: "Tip sent! 🎉"
Loading

Step 1: Create a Gasless Transaction Hook

Create src/hooks/useGaslessTip.ts:

'use client';

import { useCallback, useState } from 'react';
import { useLazorWallet } from '@lazorkit/react-sdk';
import { PublicKey, Transaction } from '@solana/web3.js';
import { createTransferInstruction, getAssociatedTokenAddressSync } from '@solana/spl-token';

// USDC Mint on Devnet
const USDC_MINT = new PublicKey('4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU');
const USDC_DECIMALS = 6;

export function useGaslessTip() {
  const [isLoading, setIsLoading] = useState(false);
  const { address, signAndSendTransaction } = useLazorWallet();

  const sendTip = useCallback(async (recipient: string, amount: number) => {
    if (!address) throw new Error('Not connected');

    setIsLoading(true);
    try {
      const senderPubkey = new PublicKey(address);
      const recipientPubkey = new PublicKey(recipient);

      // Get Associated Token Addresses
      const senderATA = getAssociatedTokenAddressSync(USDC_MINT, senderPubkey);
      const recipientATA = getAssociatedTokenAddressSync(USDC_MINT, recipientPubkey);

      // Build transfer instruction
      const instruction = createTransferInstruction(
        senderATA,
        recipientATA,
        senderPubkey,
        BigInt(amount * 10 ** USDC_DECIMALS)
      );

      const tx = new Transaction().add(instruction);

      // ✨ THE MAGIC: paysFee: false triggers Paymaster
      const signature = await signAndSendTransaction(tx, { paysFee: false });

      return signature;
    } finally {
      setIsLoading(false);
    }
  }, [address, signAndSendTransaction]);

  return { sendTip, isLoading };
}

Step 2: Use the Hook in Your UI

'use client';

import { useGaslessTip } from '@/hooks/useGaslessTip';

export default function TipCard() {
  const { sendTip, isLoading } = useGaslessTip();

  const handleTip = async () => {
    try {
      const signature = await sendTip('RECIPIENT_ADDRESS_HERE', 1);
      console.log('Success!', signature);
    } catch (err) {
      console.error('Failed:', err);
    }
  };

  return (
    <button onClick={handleTip} disabled={isLoading}>
      {isLoading ? 'Sending...' : 'Send $1 USDC (Gasless!)'}
    </button>
  );
}

Important

The paysFee: false flag is what makes the transaction gasless. Without it, the user would need SOL for fees.


⚙️ Configuration

Environment Variables

Create a .env.local file in your project root:

# Solana RPC URL
NEXT_PUBLIC_SOLANA_RPC_URL=https://api.devnet.solana.com

# Lazorkit Paymaster URL
NEXT_PUBLIC_PAYMASTER_URL=https://api.devnet.lazorkit.com/paymaster

# Your app name (shown in passkey prompts)
NEXT_PUBLIC_APP_NAME=My Awesome dApp

Switching Networks

Network RPC URL
Devnet https://api.devnet.solana.com
Mainnet https://api.mainnet-beta.solana.com
Custom Your own RPC provider URL

Warning

Make sure to update the USDC mint address when switching to mainnet:

  • Devnet: 4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU
  • Mainnet: EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v

🧪 Testing

# Run the development server
npm run dev

# Build for production
npm run build

# Start production server
npm start

# Lint the code
npm run lint

🎨 Customization

Theming

The project uses Tailwind CSS with custom theme extensions. Edit tailwind.config.ts:

theme: {
  extend: {
    colors: {
      lazor: {
        purple: '#8B5CF6',  // Primary brand color
        pink: '#EC4899',    // Accent color
        dark: '#0F0B1A',    // Background
      },
    },
  },
}

Glassmorphism Components

Use the pre-built .glass-card class for frosted glass effects:

<div className="glass-card p-6">
  Your content here
</div>

📚 API Reference

useLazorWallet Hook

Property Type Description
connect () => Promise<void> Opens passkey authentication
loginWithPasskey () => Promise<void> Alias for connect
address string | null User's Solana wallet address
isConnected boolean Whether user is authenticated
signAndSendTransaction (tx, options?) => Promise<string> Sign and submit a transaction

signAndSendTransaction Options

Option Type Default Description
paysFee boolean true Set to false for gasless transactions

🤝 Contributing

We welcome contributions! Please see our Contributing Guide for details.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.


Built with 💜 for the Lazorkit Hackathon

⬆ Back to Top

About

🔐 Production-ready Next.js 14 starter kit for Solana dApps with Passkey Authentication (FaceID/TouchID) and Gasless Transactions powered by Lazorkit SDK

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages