a402
Version:
Decentralized Infrastructure to buy and sell any internet native resources on Aptos
220 lines (167 loc) • 5.25 kB
Markdown
# A402 SDK - Monetize Your Express APIs with Aptos
Turn any Express API into a payable service with automatic blockchain payments on Aptos.
## How It Works
```mermaid
sequenceDiagram
participant User
participant API
participant A402SDK
participant Supabase
participant Aptos
User->>API: Request with API Key
API->>A402SDK: protect() middleware
A402SDK->>Supabase: Get resource info from URL
A402SDK->>A402SDK: Decode API key → Get signer
A402SDK->>Supabase: Get private key for signer
A402SDK->>Aptos: Make smart contract payment
Aptos->>A402SDK: Transaction hash
A402SDK->>Aptos: Verify payment
A402SDK->>API: Continue (payment info attached)
API->>User: Protected content
```
## Quick Start
### 1. Install the SDK
```bash
npm install a402
# or
yarn add a402
```
### 2. Setup Your Express Server
```typescript
import express from "express";
import { createA402Middleware } from "a402";
import { Network } from "@aptos-labs/ts-sdk";
const app = express();
// Initialize a402
const a402 = createA402Middleware({
network: Network.TESTNET,
contractAddress: "0x...", // Your a402 contract
supabaseUrl: "https://...supabase.co",
supabaseKey: "your-supabase-key",
});
// Protect any endpoint - just add the middleware!
app.post(
"/api/chat",
a402.protect(), // That's it!
async (req, res) => {
// This code only runs after payment is verified
res.json({ message: "Hello from paid API!" });
}
);
```
### 3. Database Setup
Your Supabase needs two tables:
**resources table:**
```sql
CREATE TABLE resources (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
url TEXT UNIQUE NOT NULL, -- e.g., '/api/chat'
price DECIMAL NOT NULL, -- e.g., 0.01
currency TEXT DEFAULT 'APT',
owner TEXT NOT NULL,
created_at TIMESTAMPTZ DEFAULT NOW()
);
```
**buyers table:**
```sql
CREATE TABLE buyers (
address TEXT PRIMARY KEY, -- User's Aptos address
private_key TEXT NOT NULL, -- Backend-generated private key
backend_address TEXT NOT NULL, -- Address of backend account
created_at TIMESTAMPTZ DEFAULT NOW()
);
```
### 4. User Flow
**Step 1: User generates API key**
```javascript
// In your dashboard
const signature = await wallet.signMessage("Generate a402 API key");
const response = await fetch("/a402/generate-key", {
method: "POST",
body: JSON.stringify({
userAddress: wallet.address,
signature,
message: "Generate a402 API key",
}),
});
const { apiKey } = await response.json();
```
**Step 2: User calls protected API**
```javascript
// API key in header
const response = await fetch("/api/chat", {
method: "POST",
headers: {
Authorization: `A402 ${apiKey}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ message: "Hello!" }),
});
```
## Key Features
### 🔑 API Key = Payment Proxy
- Users sign once to generate API key
- Backend handles all payments automatically
- No need for users to sign transactions
### 💰 Smart Contract Integration
- Payments go to your a402 smart contract
- On-chain verification of every payment
- Resource-based payment tracking
### 🛡️ Automatic Protection
- Just add `a402.protect()` to any endpoint
- SDK handles all payment logic
- Clean separation of concerns
### 📊 Built-in Dashboard Routes
```typescript
const routes = a402.getDashboardRoutes();
app.post("/a402/generate-key", routes.generateKey);
app.get("/a402/balance/:address", routes.getBalance);
```
## Advanced Usage
### Access Payment Info in Your Endpoint
```typescript
app.post("/api/premium", a402.protect(), async (req: A402Request, res) => {
// Access payment details
console.log(`User: ${req.a402.user.address}`);
console.log(`Paid: ${req.a402.payment.amount} APT`);
console.log(`TX: ${req.a402.payment.txHash}`);
// Your logic here
res.json({ data: "Premium content!" });
});
```
### Different Pricing Tiers
Just create different resources in your database:
```sql
INSERT INTO resources (url, price, currency) VALUES
('/api/basic', 0.01, 'APT'),
('/api/premium', 0.05, 'APT'),
('/api/enterprise', 0.5, 'APT');
```
## Environment Variables
```bash
# Required
A402_CONTRACT_ADDRESS=0x... # Your a402 smart contract
SUPABASE_URL=https://... # Your Supabase URL
SUPABASE_KEY=sk-... # Your Supabase service key
# Optional
APTOS_NODE_URL=https://... # Custom Aptos node
NETWORK=testnet # or mainnet
```
## Error Handling
The SDK returns appropriate HTTP status codes:
- `402 Payment Required` - No API key provided
- `401 Unauthorized` - Invalid API key
- `404 Not Found` - URL not registered as resource
- `500 Internal Error` - Payment processing failed
## Security Considerations
1. **Private Key Storage**: Backend-generated keys are only for payments
2. **API Key Security**: Treat API keys like passwords
3. **Signature Verification**: Ensures only wallet owner can generate keys
4. **On-chain Verification**: Every payment is verified on Aptos
## Complete Example
See `/examples/express-server.ts` for a full OpenAI API wrapper with:
- Basic chat endpoint (0.01 APT)
- Premium GPT-4 endpoint (0.05 APT)
- Image generation endpoint (0.1 APT)
## License
MIT