https://github.com/chipi-pay/chipi-sdk-clerk-demo
Create invisible wallets and sign transactions with Chipi-SDK and Clerk
https://github.com/chipi-pay/chipi-sdk-clerk-demo
Last synced: about 2 months ago
JSON representation
Create invisible wallets and sign transactions with Chipi-SDK and Clerk
- Host: GitHub
- URL: https://github.com/chipi-pay/chipi-sdk-clerk-demo
- Owner: chipi-pay
- Created: 2025-02-25T21:14:39.000Z (3 months ago)
- Default Branch: main
- Last Pushed: 2025-04-01T14:56:01.000Z (about 2 months ago)
- Last Synced: 2025-04-01T16:25:32.927Z (about 2 months ago)
- Language: TypeScript
- Homepage: https://chipi-sdk-clerk-demo.vercel.app
- Size: 126 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# 🌟 Invisible wallets and actions with Chipi SDK
![]()
A seamless web3 application for staking STRK tokens using invisible wallets powered by Chipi SDK and Clerk authentication.
## 🚀 Features
- **🔐 Invisible Wallets**: Create and manage StarkNet wallets without exposing private keys
- **💳 Gas-free Transactions**: All transactions are sponsored through Chipi's paymaster
- **🔄 STRK Token Operations**:
- Transfer STRK tokens
- Approve STRK for VESU contract
- Stake STRK into VESU
- **👤 User Authentication**: Secure login and session management with Clerk
- **📱 Responsive Design**: Beautiful UI that works on all devices## 🛠 Tech Stack
- **Frontend**: Next.js 14 with App Router
- **Authentication**: Clerk
- **Blockchain**: StarkNet via Chipi SDK
- **Styling**: Tailwind CSS
- **Language**: TypeScript## 📋 Detailed Setup Guide
### 1. Project Setup
```bash
git clone https://github.com/yourusername/starknet-staking-dapp.git
cd starknet-staking-dapp
npm install
```### 2. Environment Configuration
Create a `.env` file with the following variables:
```env
# Clerk Authentication
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=your_clerk_publishable_key
CLERK_SECRET_KEY=your_clerk_secret_key# Chipi SDK
NEXT_PUBLIC_AVNU_API_KEY=your_avnu_api_key
```### 3. Clerk Configuration and Metadata Setup
#### Types Configuration
Create a new file `src/types/clerk.d.ts` to define the metadata types:
```typescript:src/types/clerk.d.ts
declare namespace Clerk {
interface UserPublicMetadata {
locale?: string;
wallet?: {
account: string;
publicKey: string;
encryptedPrivateKey: string;
};
}interface UserPrivateMetadata {
// Add any private metadata fields here
}interface UserUnsafeMetadata {
// Add any unsafe metadata fields here
}
}
```#### Understanding Clerk Metadata Types
Clerk provides three types of metadata, each with specific use cases:
1. **Public Metadata** (`UserPublicMetadata`)
- Accessible from both frontend and backend
- Can only be modified from the backend
- Used for:
```typescript
{
locale: string; // User's language preference
wallet: {
account: string; // Wallet account details
publicKey: string; // StarkNet public key
encryptedPrivateKey: string; // Encrypted private key
}
}
```
- Location: `src/app/onboarding/_actions.ts` for updates
- Access: Throughout the application using `user.publicMetadata`2. **Private Metadata** (`UserPrivateMetadata`)
- Only accessible from backend routes
- Used for sensitive data
- Example usage in server actions:
```typescript:src/app/api/user/_actions.ts
export async function updateUserPrivateData(userId: string) {
await clerkClient.users.updateUserMetadata(userId, {
privateMetadata: {
// Add private data here
}
});
}
```3. **Unsafe Metadata** (`UserUnsafeMetadata`)
- Accessible and modifiable from both frontend and backend
- Used for non-sensitive temporary data
- Example usage in components:
```typescript:src/app/components/UserPreferences.tsx
const { user } = useUser();
const updatePreferences = async () => {
await user?.update({
unsafeMetadata: {
// Add temporary data here
}
});
};
```#### Metadata Usage in Different Parts of the Application
1. **Server Components and Actions**
```typescript:src/app/onboarding/_actions.ts
import { clerkClient } from "@clerk/nextjs";export async function createWallet(userId: string, walletData: Clerk.UserPublicMetadata['wallet']) {
return await clerkClient.users.updateUserMetadata(userId, {
publicMetadata: {
wallet: walletData
}
});
}
```2. **Client Components**
```typescript:src/app/components/WalletInfo.tsx
'use client';import { useUser } from "@clerk/nextjs";
export function WalletInfo() {
const { user } = useUser();
const wallet = user?.publicMetadata?.wallet;
return (
Public Key: {wallet?.publicKey}
);
}
```3. **Middleware Usage**
```typescript:src/middleware.ts
import { clerkMiddleware } from "@clerk/nextjs/server";
import { NextResponse } from "next/server";// Define public routes that don't require authentication
const isPublicRoute = createRouteMatcher(["/", "/onboarding"])export default clerkMiddleware(async (auth, req) => {
const { userId, sessionClaims } = await auth();// Redirect to sign-in if accessing private route without auth
if (!userId && !isPublicRoute(req)) {
return redirectToSignIn({ returnBackUrl: req.url });
}// Redirect to onboarding if wallet not created
if (userId && !sessionClaims?.metadata?.wallet &&
req.nextUrl.pathname !== "/onboarding") {
return NextResponse.redirect(new URL("/onboarding", req.url));
}return NextResponse.next();
});// Configure middleware matcher
export const config = {
matcher: [
'/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|images|favicon).*)',
'/(api|trpc)(.*)',
],
};
```The middleware handles:
- Route protection
- Authentication checks
- Onboarding flow redirection
- Public route access### 4. Middleware Configuration
The application uses Clerk middleware to protect routes and handle authentication flow. Create or update `src/middleware.ts`:
```typescript
import { clerkMiddleware, createRouteMatcher } from "@clerk/nextjs/server";
import { NextResponse } from "next/server";// Define public routes that don't require authentication
const isPublicRoute = createRouteMatcher(["/", "/onboarding"])export default clerkMiddleware(async (auth, req) => {
const { userId, sessionClaims } = await auth();// Redirect to sign-in if accessing private route without auth
if (!userId && !isPublicRoute(req)) {
return redirectToSignIn({ returnBackUrl: req.url });
}// Redirect to onboarding if wallet not created
if (userId && !sessionClaims?.metadata?.wallet &&
req.nextUrl.pathname !== "/onboarding") {
return NextResponse.redirect(new URL("/onboarding", req.url));
}return NextResponse.next();
});// Configure middleware matcher
export const config = {
matcher: [
'/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|images|favicon).*)',
'/(api|trpc)(.*)',
],
};
```The middleware handles:
- Route protection
- Authentication checks
- Onboarding flow redirection
- Public route access### 5. Project Structure
- `src/middleware.ts`: Route protection and authentication flow
- `src/app/providers.tsx`: ChipiSDK configuration
- `src/app/onboarding/`: Wallet creation flow
- `src/app/dashboard/hooks.tsx`: Token operations### 6. Key Components
#### ChipiProvider (`providers.tsx`)
The ChipiProvider configures the SDK with your API key and network settings:
- Manages StarkNet connection
- Handles transaction sponsoring
- Configures network settings#### Onboarding Flow
The onboarding process includes:
1. User authentication with Clerk
2. PIN selection for wallet encryption
3. Invisible wallet creation
4. Storage of encrypted credentials#### Available Operations (`hooks.tsx`)
- **Transfer**: Send USDC tokens to other addresses
- **Stake**: Stake STRK tokens into VESU contract
- **Approve**: Approve STRK tokens for staking## 🔧 Usage Guide
### Setting Up a New Wallet
1. Sign in using Clerk authentication
2. Complete the onboarding process:
- Set a secure PIN (minimum 6 digits)
- Your StarkNet wallet will be created automatically
- Credentials are encrypted and stored securely### Performing Operations
#### Transfer USDC
- Enter your PIN
- Specify recipient address
- Enter amount
- Confirm transaction#### Stake STRK
- Enter your PIN
- Specify amount to stake
- Contract address is pre-configured
- Confirm transaction#### Approve STRK
- Enter your PIN
- Amount to approve
- VESU contract is pre-configured
- Confirm transaction## 🔐 Security Considerations
- PINs are never stored in plain text
- Private keys are encrypted before storage
- All transactions require PIN verification
- Clerk handles secure authentication
- Gas fees are sponsored through Chipi's paymaster
- Metadata is securely stored in Clerk's infrastructure
- Public metadata is read-only from frontend
- Private keys are always encrypted before storage
- Middleware ensures proper route protection## 🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
## 📄 License
This project is licensed under the MIT License - see the LICENSE file for details