Skip to content

Commit d4b57d7

Browse files
Add test folder
1 parent 5143ac5 commit d4b57d7

28 files changed

+9434
-0
lines changed

test/.gitignore

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

test/README.md

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
# Seal + Walrus Demo Application
2+
3+
This Next.js application demonstrates the integration of Seal (decentralized secrets management) and Walrus (decentralized storage) to create a secure content platform.
4+
5+
## Features Implemented
6+
7+
### 1. **Encrypted Article Storage**
8+
- Articles are encrypted using Seal's Identity-Based Encryption (IBE)
9+
- Support for both text content and images
10+
- Images are encrypted separately and linked to articles
11+
- Encrypted data is stored on Walrus decentralized storage
12+
- Only the encrypted blob ID is stored locally
13+
14+
### 2. **Access Control**
15+
- Public articles: Anyone can decrypt and read using demo allowlist
16+
- Restricted articles: Only allowlisted addresses can access
17+
- Admin functionality to create and manage allowlists
18+
- Demo allowlist pre-deployed for testing
19+
20+
### 3. **Wallet Integration**
21+
- Connect with Sui wallets (Sui Wallet, Suiet, etc.)
22+
- Session key management for reduced wallet interactions
23+
- Personal message signing for authentication
24+
25+
### 4. **Rich Content Support**
26+
- Text articles with titles and content
27+
- Optional image uploads (max 10MB)
28+
- Image preview before submission
29+
- Encrypted image storage and retrieval
30+
31+
## Architecture
32+
33+
### Data Flow
34+
1. **Writing Articles**:
35+
- User writes article content
36+
- Content is encrypted using Seal with a unique ID
37+
- Encrypted data is uploaded to Walrus
38+
- Metadata (blob ID, access info) stored locally
39+
40+
2. **Reading Articles**:
41+
- Download encrypted data from Walrus
42+
- Create session key and get user signature
43+
- Build approval transaction for Move contract
44+
- Decrypt content using Seal client
45+
46+
### Key Components
47+
48+
- **WriteArticle**: Handles article creation and encryption
49+
- **ArticleList**: Displays articles and handles decryption
50+
- **AdminPanel**: Manages allowlists (admin only)
51+
- **seal.ts**: Seal encryption/decryption utilities
52+
- **storage.ts**: Local storage management
53+
54+
## Setup Instructions
55+
56+
1. **Move Contracts Already Deployed**:
57+
- Package ID: `0x9c2e3762ca1c5bd01f8adfc5de004e47bcc028441cdedb2c010a908e864233e8`
58+
- Demo Allowlist: `0xd7722daf6e0bdef36345ab97d7fb3e0e13d44aed7eeac06ac4bc72a6c6ea2a99`
59+
- All constants are pre-configured in `constants.ts`
60+
61+
2. **Run the Application**:
62+
```bash
63+
npm run dev
64+
```
65+
Access at http://localhost:3001
66+
67+
## Key Features
68+
69+
### Payment System
70+
- **Article Posting Fee**: 1 SUI (1,000,000,000 MIST) per article
71+
- Fee is transferred to admin wallet on submission
72+
- Transaction must be signed before article encryption/upload
73+
74+
### Transaction Flow
75+
1. User writes article and clicks submit
76+
2. Wallet prompts to sign transaction (1 SUI payment)
77+
3. Upon successful payment:
78+
- Article is encrypted using Seal
79+
- Encrypted data uploaded to Walrus
80+
- Metadata saved locally
81+
4. If transaction fails, no article is posted
82+
83+
## Current Limitations
84+
85+
1. **Allowlist Management**: Adding addresses to allowlist requires Cap object tracking (not fully implemented).
86+
2. **Public Access**: Uses a simplified approval mechanism for demo purposes.
87+
3. **Error Handling**: Basic error handling - production app would need more robust error management.
88+
4. **Local Storage**: Article metadata stored in browser localStorage - production would use a backend.
89+
90+
## Security Considerations
91+
92+
- Never expose master keys
93+
- Session keys have limited TTL (10 minutes)
94+
- Encrypted data is stored on Walrus, only metadata stored locally
95+
- Access control enforced by on-chain Move contracts
96+
97+
## Next Steps
98+
99+
1. Deploy and integrate actual Move contracts
100+
2. Implement subscription-based access control
101+
3. Add Cap object management for allowlist administration
102+
4. Implement server-side metadata storage
103+
5. Add support for multiple key server configurations
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
'use client';
2+
3+
import { useState, useEffect } from 'react';
4+
import { useCurrentAccount, useSuiClient } from '@mysten/dapp-kit';
5+
import { ADMIN_ADDRESS } from '../constants';
6+
7+
export default function AdminDashboard() {
8+
const [balance, setBalance] = useState<string>('0');
9+
const [isLoading, setIsLoading] = useState(true);
10+
const [transactionCount, setTransactionCount] = useState(0);
11+
12+
const currentAccount = useCurrentAccount();
13+
const suiClient = useSuiClient();
14+
15+
useEffect(() => {
16+
const fetchAdminBalance = async () => {
17+
try {
18+
// Get balance for admin address
19+
const balanceResult = await suiClient.getBalance({
20+
owner: ADMIN_ADDRESS,
21+
});
22+
23+
// Convert from MIST to SUI (divide by 10^9)
24+
const suiBalance = (BigInt(balanceResult.totalBalance) / BigInt(1000000000)).toString();
25+
setBalance(suiBalance);
26+
27+
// Get recent transactions (this is a simplified version)
28+
// In a real app, you'd filter for specific transaction types
29+
const txns = await suiClient.queryTransactionBlocks({
30+
filter: {
31+
ToAddress: ADMIN_ADDRESS,
32+
},
33+
limit: 50,
34+
});
35+
36+
setTransactionCount(txns.data.length);
37+
} catch (error) {
38+
console.error('Error fetching admin data:', error);
39+
} finally {
40+
setIsLoading(false);
41+
}
42+
};
43+
44+
fetchAdminBalance();
45+
46+
// Refresh every 30 seconds
47+
const interval = setInterval(fetchAdminBalance, 30000);
48+
return () => clearInterval(interval);
49+
}, [suiClient]);
50+
51+
// Only show admin dashboard if current user is admin
52+
const isAdmin = currentAccount?.address === ADMIN_ADDRESS;
53+
54+
if (!isAdmin) {
55+
return (
56+
<div className="w-full max-w-4xl mx-auto p-6 bg-zinc-800 rounded-lg">
57+
<h2 className="text-2xl font-bold text-white mb-4">Admin Dashboard</h2>
58+
<p className="text-gray-400">You must be logged in as admin to view this dashboard.</p>
59+
</div>
60+
);
61+
}
62+
63+
return (
64+
<div className="w-full max-w-4xl mx-auto p-6 bg-zinc-800 rounded-lg">
65+
<h2 className="text-2xl font-bold text-white mb-6">Admin Dashboard</h2>
66+
67+
{isLoading ? (
68+
<p className="text-gray-400">Loading admin data...</p>
69+
) : (
70+
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
71+
<div className="bg-zinc-700 p-6 rounded-lg">
72+
<h3 className="text-lg font-semibold text-gray-300 mb-2">Total Balance</h3>
73+
<p className="text-3xl font-bold text-white">{balance} SUI</p>
74+
<p className="text-sm text-gray-400 mt-1">Admin wallet balance</p>
75+
</div>
76+
77+
<div className="bg-zinc-700 p-6 rounded-lg">
78+
<h3 className="text-lg font-semibold text-gray-300 mb-2">Recent Payments</h3>
79+
<p className="text-3xl font-bold text-white">{transactionCount}</p>
80+
<p className="text-sm text-gray-400 mt-1">Transactions to admin wallet</p>
81+
</div>
82+
83+
<div className="bg-zinc-700 p-6 rounded-lg col-span-1 md:col-span-2">
84+
<h3 className="text-lg font-semibold text-gray-300 mb-2">Admin Wallet</h3>
85+
<p className="text-sm text-gray-400 break-all font-mono">{ADMIN_ADDRESS}</p>
86+
</div>
87+
88+
<div className="bg-blue-600 p-6 rounded-lg col-span-1 md:col-span-2">
89+
<h3 className="text-lg font-semibold text-white mb-2">Article Posting Fee</h3>
90+
<p className="text-2xl font-bold text-white">1 SUI per article</p>
91+
<p className="text-sm text-gray-200 mt-1">All article posting fees are transferred to the admin wallet</p>
92+
</div>
93+
</div>
94+
)}
95+
</div>
96+
);
97+
}

0 commit comments

Comments
 (0)