Skip to content

Commit e41dde7

Browse files
committed
initial commit
0 parents  commit e41dde7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+28477
-0
lines changed

.env.sample

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Palchemy Environment Variables Sample
2+
# Copy this file to .env.local and fill in your actual values
3+
4+
# ===========================================
5+
# Alchemy Configuration
6+
# ===========================================
7+
# Get these from: https://dashboard.alchemy.com/apps
8+
# Create an app with Arbitrum Sepolia network
9+
NEXT_PUBLIC_ALCHEMY_API_KEY=your_alchemy_api_key_here
10+
11+
# Get this from: https://dashboard.alchemy.com/services/gas-manager/configuration
12+
# Create a gas sponsorship policy for Arbitrum Sepolia
13+
NEXT_PUBLIC_ALCHEMY_POLICY_ID=your_alchemy_gas_policy_id_here
14+
15+
# ===========================================
16+
# Turnkey Configuration
17+
# ===========================================
18+
# Get these from: https://app.turnkey.com/
19+
# Used for secure escrow wallet management
20+
21+
# Your Turnkey organization ID (found in dashboard)
22+
TURNKEY_ORGANIZATION_ID=your_turnkey_organization_id_here
23+
24+
# API key pair for Turnkey (generate in dashboard)
25+
# IMPORTANT: Store private key securely - it cannot be recovered
26+
TURNKEY_API_PUBLIC_KEY=your_turnkey_public_key_here
27+
TURNKEY_API_PRIVATE_KEY=your_turnkey_private_key_here
28+
29+
# ===========================================
30+
# Setup Instructions
31+
# ===========================================
32+
# 1. Copy this file: cp .env.sample .env.local
33+
# 2. Get Alchemy API key from: https://dashboard.alchemy.com/apps
34+
# 3. Create gas policy at: https://dashboard.alchemy.com/services/gas-manager/configuration
35+
# 4. Set up Turnkey organization at: https://app.turnkey.com/
36+
# 5. Generate Turnkey API keys in your organization dashboard
37+
# 6. Replace all placeholder values with your actual credentials
38+
# 7. Never commit .env.local to version control

.gitignore

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2+
3+
# dependencies
4+
/node_modules
5+
/.pnp
6+
.pnp.js
7+
.yarn/install-state.gz
8+
9+
# testing
10+
/coverage
11+
12+
# next.js
13+
/.next/
14+
/out/
15+
16+
# production
17+
/build
18+
19+
# misc
20+
.DS_Store
21+
*.pem
22+
23+
# debug
24+
npm-debug.log*
25+
yarn-debug.log*
26+
yarn-error.log*
27+
28+
# local env files
29+
.env*.local
30+
.env
31+
32+
# vercel
33+
.vercel
34+
35+
# typescript
36+
*.tsbuildinfo
37+
next-env.d.ts

README.md

Lines changed: 228 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,228 @@
1+
# Palchemy
2+
3+
A cryptocurrency payment platform that makes sending and receiving crypto as easy as sending an email. Built with Alchemy Account Kit smart wallets and Turnkey's secure infrastructure.
4+
5+
## ✨ Features
6+
7+
- **Email-like payments**: Send crypto to anyone with just an email address
8+
- **No wallet required**: Recipients can claim payments without existing crypto wallets
9+
- **Smart wallet integration**: Email, passkey & social login using Account Kit
10+
- **Secure escrow system**: Temporary escrow wallets using Turnkey infrastructure
11+
- **Gasless transactions**: Sponsored transactions for seamless user experience
12+
- **Blockchain transparency**: All transactions verifiable on Arbitrum Sepolia
13+
- **Modern UI**: TailwindCSS + shadcn/ui components, React Query, TypeScript
14+
15+
## 🌐 Network
16+
17+
This application runs on **Arbitrum Sepolia** testnet.
18+
19+
## 🚀 Getting Started
20+
21+
### 1. Clone and Install
22+
23+
```bash
24+
git clone <repository-url>
25+
cd palchemy-demo
26+
npm install
27+
```
28+
29+
### 2. Environment Configuration
30+
31+
Create a `.env.local` file in the root directory and add the following environment variables:
32+
33+
```bash
34+
# Alchemy Configuration
35+
NEXT_PUBLIC_ALCHEMY_API_KEY=your_alchemy_api_key
36+
NEXT_PUBLIC_ALCHEMY_POLICY_ID=your_alchemy_gas_policy_id
37+
38+
# Turnkey Configuration
39+
TURNKEY_API_PUBLIC_KEY=your_turnkey_public_key
40+
TURNKEY_API_PRIVATE_KEY=your_turnkey_private_key
41+
TURNKEY_ORGANIZATION_ID=your_turnkey_organization_id
42+
```
43+
44+
#### Required API Keys
45+
46+
| Variable | Purpose | How to Get |
47+
| ------------------------------- | ------------------------------------------------ | ----------------------------------------------------------------------------------------- |
48+
| `NEXT_PUBLIC_ALCHEMY_API_KEY` | Alchemy API key for blockchain interactions | Create an app in [Alchemy Dashboard](https://dashboard.alchemy.com/apps) |
49+
| `NEXT_PUBLIC_ALCHEMY_POLICY_ID` | Gas sponsorship policy for free transactions | Set up in [Gas Manager](https://dashboard.alchemy.com/services/gas-manager/configuration) |
50+
| `TURNKEY_API_PUBLIC_KEY` | Turnkey public key for escrow wallet management | Generated in [Turnkey Dashboard](https://app.turnkey.com/) |
51+
| `TURNKEY_API_PRIVATE_KEY` | Turnkey private key for escrow wallet management | Generated with public key in Turnkey Dashboard |
52+
| `TURNKEY_ORGANIZATION_ID` | Your Turnkey organization identifier | Found in [Turnkey Dashboard](https://app.turnkey.com/) |
53+
54+
### 3. Alchemy Setup
55+
56+
1. **Create an Alchemy Account**: Sign up at [alchemy.com](https://www.alchemy.com/)
57+
2. **Create a New App**:
58+
- Go to [Alchemy Dashboard](https://dashboard.alchemy.com/apps)
59+
- Click "Create App"
60+
- Choose "Arbitrum Sepolia" as the network
61+
- Copy your API key
62+
3. **Set up Smart Wallets**:
63+
- Navigate to [Smart Wallets Configuration](https://dashboard.alchemy.com/services/smart-wallets/configuration)
64+
- Enable email, passkey, and social login methods
65+
4. **Configure Gas Sponsorship**:
66+
- Go to [Gas Manager](https://dashboard.alchemy.com/services/gas-manager/configuration)
67+
- Create a new policy for Arbitrum Sepolia
68+
- Copy the Policy ID
69+
70+
### 4. Turnkey Setup
71+
72+
1. **Create a Turnkey Account**: Sign up at [turnkey.com](https://www.turnkey.com/)
73+
2. **Set up Organization**:
74+
- Complete the organization setup in [Turnkey Dashboard](https://app.turnkey.com/)
75+
- Note your Organization ID
76+
3. **Generate API Keys**:
77+
- In the Turnkey dashboard, create a new API key pair
78+
- Download both the public and private keys
79+
- **Important**: Store the private key securely - it cannot be recovered
80+
81+
### 5. Run the Application
82+
83+
```bash
84+
npm run dev
85+
```
86+
87+
Open [http://localhost:3000](http://localhost:3000) to start using Palchemy!
88+
89+
## 🗂 Project Layout
90+
91+
```
92+
app/
93+
├── api/turnkey/ # Turnkey API routes for escrow management
94+
├── claim/[token]/ # Claim page for payment recipients
95+
├── components/ # React components
96+
├── hooks/ # Custom React hooks
97+
└── page.tsx # Main payment interface
98+
99+
components/ui/ # shadcn/ui primitives
100+
lib/
101+
├── alchemy.ts # Alchemy SDK configuration
102+
├── turnkey.ts # Turnkey escrow management
103+
├── constants.ts # Contract addresses and ABIs
104+
└── types/ # TypeScript type definitions
105+
106+
config.ts # Account Kit + Gas Sponsorship setup
107+
```
108+
109+
## 🏗️ How Palchemy Works
110+
111+
### Payment Flow
112+
113+
1. **Sender Login**: User authenticates via email, passkey, or social login using Account Kit
114+
2. **Payment Creation**:
115+
- User enters recipient email and amount
116+
- Palchemy creates a secure escrow wallet using Turnkey
117+
- Funds are transferred to the escrow wallet
118+
3. **Claim Link Generation**: A secure claim link is generated with encrypted payment data
119+
4. **Recipient Experience**:
120+
- Recipient clicks the claim link
121+
- They can see payment details and escrow wallet on blockchain
122+
- After login, funds transfer to their new smart wallet
123+
- Escrow wallet is securely deleted
124+
125+
### Key Technologies
126+
127+
- **Account Kit**: Provides smart wallets with social login
128+
- **Turnkey**: Secure key management for temporary escrow wallets
129+
- **Arbitrum Sepolia**: Layer 2 network for fast, cheap transactions
130+
- **Gas Sponsorship**: Palchemy covers transaction fees for smooth UX
131+
132+
## 🚀 Usage
133+
134+
1. **Send a Payment**:
135+
136+
- Log in to Palchemy at [http://localhost:3000](http://localhost:3000)
137+
- Enter recipient email and amount
138+
- Click "Continue" to create escrow and generate claim link
139+
- Share the claim link with your recipient
140+
141+
2. **Receive a Payment**:
142+
- Click the claim link you received
143+
- View payment details and verify escrow on blockchain
144+
- Log in to create/access your smart wallet
145+
- Claim the payment to transfer funds to your wallet
146+
147+
## 🔧 Development
148+
149+
### Available Scripts
150+
151+
```bash
152+
npm run dev # Start development server
153+
npm run build # Production build
154+
npm run start # Run production build
155+
npm run lint # Lint code
156+
```
157+
158+
### Testing
159+
160+
To test the payment flow:
161+
162+
1. Create a payment with a test email
163+
2. Copy the generated claim link
164+
3. Open the claim link in an incognito window
165+
4. Complete the claim process
166+
167+
## 📚 Documentation & Resources
168+
169+
- [Alchemy Account Kit Documentation](https://www.alchemy.com/docs/wallets/react/overview)
170+
- [Turnkey Documentation](https://docs.turnkey.com/)
171+
- [Arbitrum Sepolia Explorer](https://sepolia.arbiscan.io/)
172+
173+
## 🔒 Security
174+
175+
### ⚠️ **CRITICAL SECURITY WARNING FOR PRODUCTION USE**
176+
177+
**This demo application is designed for educational purposes and contains intentional security simplifications to demonstrate the payment flow transparently. DO NOT use this pattern in production without implementing proper security measures.**
178+
179+
### 🚨 **Claim Link Security Issues (DEMO ONLY)**
180+
181+
**The current implementation has intentional security vulnerabilities for educational clarity:**
182+
183+
- **Sensitive data exposure**: Claim links contain unencrypted private keys, wallet addresses, and transaction details in the URL
184+
- **Clear text transmission**: All sensitive information is transmitted in the clear through URLs
185+
- **No access control**: Anyone with the claim link can view and potentially claim the payment
186+
- **Browser history exposure**: Sensitive data persists in browser history, server logs, and referrer headers
187+
- **Network exposure**: URLs with sensitive data can be logged by proxies, CDNs, and network infrastructure
188+
189+
### 🔐 **Production Security Requirements**
190+
191+
For a production cryptocurrency payment system, you **MUST** implement:
192+
193+
#### **Secure Claim Link Architecture:**
194+
195+
- **Server-side session management**: Store sensitive data server-side with secure session tokens
196+
- **Database encryption**: Encrypt all sensitive data at rest using industry-standard encryption
197+
- **Access control**: Implement proper authentication and authorization for claim access
198+
- **HTTPS everywhere**: Ensure all communication is encrypted in transit
199+
- **Token expiration**: Implement time-limited access tokens with automatic expiration
200+
- **Rate limiting**: Prevent brute force attacks on claim endpoints
201+
202+
#### **Key Management:**
203+
204+
- **Hardware Security Modules (HSMs)**: Use HSMs for private key generation and storage
205+
- **Key rotation**: Implement regular key rotation policies
206+
- **Minimal privilege**: Limit key access to only necessary operations
207+
- **Audit logging**: Comprehensive logging of all key operations
208+
209+
#### **Additional Security Measures:**
210+
211+
- **Multi-factor authentication**: Require MFA for sensitive operations
212+
- **IP allowlisting**: Restrict access based on IP addresses where appropriate
213+
- **Fraud detection**: Implement real-time fraud monitoring and alerts
214+
- **Compliance**: Ensure compliance with relevant financial regulations (AML/KYC)
215+
- **Security audits**: Regular security audits and penetration testing
216+
- **Incident response**: Comprehensive incident response procedures
217+
218+
### 🏗️ **Infrastructure Security**
219+
220+
- All escrow wallets are managed by Turnkey's secure infrastructure
221+
- Private keys are never exposed to the application frontend
222+
- All transactions are verifiable on the Arbitrum Sepolia blockchain
223+
- Escrow wallets are automatically deleted after successful claims
224+
- **Production requirement**: Implement proper secret management and environment isolation
225+
226+
## 🛂 License
227+
228+
MIT
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { NextRequest, NextResponse } from "next/server";
2+
import { createEscrowOrganization } from "@/lib/turnkey";
3+
import { CreateEscrowRequest, CreateEscrowResponse } from "@/lib/types/turnkey";
4+
5+
export async function POST(request: NextRequest) {
6+
try {
7+
const body: CreateEscrowRequest = await request.json();
8+
9+
// Call your Turnkey helper function
10+
const escrowOrganization: CreateEscrowResponse =
11+
await createEscrowOrganization(body);
12+
13+
return NextResponse.json({
14+
success: true,
15+
data: escrowOrganization,
16+
});
17+
} catch (error) {
18+
return NextResponse.json(
19+
{ success: false, error: "Failed to create escrow organization" },
20+
{ status: 500 }
21+
);
22+
}
23+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { NextRequest, NextResponse } from "next/server";
2+
import { transferFunds } from "@/lib/turnkey";
3+
import {
4+
TransferAndCleanupRequest,
5+
TransferAndCleanupResponse,
6+
} from "@/lib/types/turnkey";
7+
8+
export async function POST(request: NextRequest) {
9+
try {
10+
const body: TransferAndCleanupRequest = await request.json();
11+
12+
// Step 1: Transfer funds using private API key authorization
13+
const transferResult = await transferFunds(body);
14+
15+
const result: TransferAndCleanupResponse = {
16+
transferHash: transferResult.hash,
17+
organizationId: body.organizationId,
18+
transferAmount: body.amount,
19+
recipientAddress: body.recipientAddress,
20+
organizationDeleted: true,
21+
};
22+
23+
return NextResponse.json({
24+
success: true,
25+
data: result,
26+
});
27+
} catch (error) {
28+
return NextResponse.json(
29+
{
30+
success: false,
31+
error: "Failed to transfer funds and cleanup organization",
32+
},
33+
{ status: 500 }
34+
);
35+
}
36+
}

app/claim/page.tsx

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
"use client";
2+
3+
import { useSearchParams } from "next/navigation";
4+
import ClaimHeader from "../components/claim-header";
5+
import PaymentClaimCard from "../components/payment-claim-card";
6+
7+
export default function ClaimPage() {
8+
const searchParams = useSearchParams();
9+
const token = searchParams.get("token") || "";
10+
11+
return (
12+
<div className="min-h-screen bg-gray-50">
13+
<ClaimHeader />
14+
<main className="container mx-auto px-4 py-8">
15+
<div className="max-w-2xl mx-auto">
16+
<PaymentClaimCard token={token} />
17+
</div>
18+
</main>
19+
</div>
20+
);
21+
}

0 commit comments

Comments
 (0)