@blu1606/create-walrus-app 2.1.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/dist/context.js +1 -0
  2. package/dist/generator/layers.js +3 -0
  3. package/dist/index.js +1 -0
  4. package/dist/prompts.js +17 -0
  5. package/dist/types.d.ts +1 -0
  6. package/package.json +1 -1
  7. package/presets/react-mysten-gallery/scripts/setup-walrus-deploy.sh +17 -21
  8. package/presets/react-mysten-simple-upload-enoki/.env.example +40 -0
  9. package/presets/react-mysten-simple-upload-enoki/.gitkeep +4 -0
  10. package/presets/react-mysten-simple-upload-enoki/README.md +332 -0
  11. package/presets/react-mysten-simple-upload-enoki/index.html +13 -0
  12. package/presets/react-mysten-simple-upload-enoki/package.json +37 -0
  13. package/presets/react-mysten-simple-upload-enoki/scripts/setup-walrus-deploy.sh +286 -0
  14. package/presets/react-mysten-simple-upload-enoki/src/App.tsx +27 -0
  15. package/presets/react-mysten-simple-upload-enoki/src/components/features/enoki-auth-button.tsx +29 -0
  16. package/presets/react-mysten-simple-upload-enoki/src/components/features/file-preview.tsx +73 -0
  17. package/presets/react-mysten-simple-upload-enoki/src/components/features/upload-form.tsx +61 -0
  18. package/presets/react-mysten-simple-upload-enoki/src/components/features/wallet-connect.tsx +38 -0
  19. package/presets/react-mysten-simple-upload-enoki/src/components/layout/app-layout.tsx +21 -0
  20. package/presets/react-mysten-simple-upload-enoki/src/hooks/use-download.ts +24 -0
  21. package/presets/react-mysten-simple-upload-enoki/src/hooks/use-enoki-auth.ts +52 -0
  22. package/presets/react-mysten-simple-upload-enoki/src/hooks/use-upload.ts +45 -0
  23. package/presets/react-mysten-simple-upload-enoki/src/hooks/use-wallet.ts +32 -0
  24. package/presets/react-mysten-simple-upload-enoki/src/index.css +322 -0
  25. package/presets/react-mysten-simple-upload-enoki/src/index.ts +24 -0
  26. package/presets/react-mysten-simple-upload-enoki/src/lib/enoki/constants.ts +23 -0
  27. package/presets/react-mysten-simple-upload-enoki/src/lib/enoki/index.ts +6 -0
  28. package/presets/react-mysten-simple-upload-enoki/src/lib/enoki/storage-adapter.ts +31 -0
  29. package/presets/react-mysten-simple-upload-enoki/src/lib/walrus/adapter.ts +197 -0
  30. package/presets/react-mysten-simple-upload-enoki/src/lib/walrus/client.ts +87 -0
  31. package/presets/react-mysten-simple-upload-enoki/src/lib/walrus/index.ts +4 -0
  32. package/presets/react-mysten-simple-upload-enoki/src/lib/walrus/types.ts +92 -0
  33. package/presets/react-mysten-simple-upload-enoki/src/main.tsx +19 -0
  34. package/presets/react-mysten-simple-upload-enoki/src/providers/EnokiProvider.tsx +23 -0
  35. package/presets/react-mysten-simple-upload-enoki/src/providers/QueryProvider.tsx +18 -0
  36. package/presets/react-mysten-simple-upload-enoki/src/providers/WalletProvider.tsx +52 -0
  37. package/presets/react-mysten-simple-upload-enoki/src/providers/index.ts +7 -0
  38. package/presets/react-mysten-simple-upload-enoki/src/utils/env.ts +41 -0
  39. package/presets/react-mysten-simple-upload-enoki/src/utils/mime-type.ts +97 -0
  40. package/presets/react-mysten-simple-upload-enoki/tsconfig.json +39 -0
  41. package/presets/react-mysten-simple-upload-enoki/tsconfig.node.json +10 -0
  42. package/presets/react-mysten-simple-upload-enoki/vite.config.ts +19 -0
package/dist/context.js CHANGED
@@ -39,6 +39,7 @@ export function buildContext(args, promptResults) {
39
39
  // Temporarily disabled until templates are implemented
40
40
  analytics: false, // Boolean(merged.analytics),
41
41
  tailwind: false, // Boolean(merged.tailwind),
42
+ useZkLogin: Boolean(merged.useZkLogin),
42
43
  packageManager: packageManager,
43
44
  };
44
45
  }
@@ -30,6 +30,9 @@ export function getPresetName(context) {
30
30
  if (context.analytics) {
31
31
  optionalFeatures.push('analytics');
32
32
  }
33
+ if (context.useZkLogin) {
34
+ optionalFeatures.push('enoki');
35
+ }
33
36
  if (context.tailwind) {
34
37
  optionalFeatures.push('tailwind');
35
38
  }
package/dist/index.js CHANGED
@@ -26,6 +26,7 @@ program
26
26
  // TODO: Re-enable when templates are implemented
27
27
  // .option('--analytics', 'Include Blockberry analytics', false)
28
28
  // .option('--no-tailwind', 'Exclude Tailwind CSS')
29
+ .option('--use-zk-login', 'Use zkLogin (Enoki) authentication', false)
29
30
  .option('--skip-install', 'Skip dependency installation', false)
30
31
  .option('--skip-git', '[DEPRECATED] No longer used - git initialization removed', false)
31
32
  .option('--skip-validation', 'Skip project validation', false)
package/dist/prompts.js CHANGED
@@ -86,6 +86,23 @@ export async function runPrompts(initial = {}) {
86
86
  message: 'Include Tailwind CSS?',
87
87
  initial: false, // Changed to false to prevent layer lookup
88
88
  },
89
+ {
90
+ type: (prev, answers) => {
91
+ // Only show zkLogin prompt for mysten SDK with simple-upload or gallery
92
+ const sdk = initial.sdk || answers.sdk;
93
+ const useCase = answers.useCase;
94
+ if (sdk !== 'mysten')
95
+ return null;
96
+ if (!['simple-upload', 'gallery'].includes(useCase))
97
+ return null;
98
+ if (initial.useZkLogin !== undefined)
99
+ return null;
100
+ return 'confirm';
101
+ },
102
+ name: 'useZkLogin',
103
+ message: 'Use zkLogin (Enoki) authentication? (Web2 login with Google/Apple)',
104
+ initial: false,
105
+ },
89
106
  {
90
107
  type: initial.packageManager ? null : 'select',
91
108
  name: 'packageManager',
package/dist/types.d.ts CHANGED
@@ -10,6 +10,7 @@ export interface Context {
10
10
  useCase: UseCase;
11
11
  analytics: boolean;
12
12
  tailwind: boolean;
13
+ useZkLogin: boolean;
13
14
  packageManager: PackageManager;
14
15
  }
15
16
  export interface ValidationResult {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blu1606/create-walrus-app",
3
- "version": "2.1.0",
3
+ "version": "2.2.0",
4
4
  "description": "Interactive CLI for scaffolding Walrus applications",
5
5
  "type": "module",
6
6
  "bin": {
@@ -69,10 +69,10 @@ setup_bun() {
69
69
  setup_site_builder() {
70
70
  # Set install directory based on OS
71
71
  if [ "$OS_TYPE" = "windows" ]; then
72
- WALRUS_BIN="$USERPROFILE/.walrus/bin"
72
+ WALRUS_BIN="$USERPROFILE/bin"
73
73
  SITE_BUILDER="$WALRUS_BIN/site-builder.exe"
74
74
  else
75
- WALRUS_BIN="$HOME/.walrus/bin"
75
+ WALRUS_BIN="$HOME/bin"
76
76
  SITE_BUILDER="$WALRUS_BIN/site-builder"
77
77
  fi
78
78
 
@@ -93,22 +93,18 @@ setup_site_builder() {
93
93
  windows) BINARY_NAME="site-builder-windows.exe" ;;
94
94
  esac
95
95
 
96
- DOWNLOAD_URL="https://github.com/MystenLabs/walrus-sites/releases/latest/download/$BINARY_NAME"
97
-
98
- # Download with retry
99
- if ! curl -fsSL -o "$SITE_BUILDER" "$DOWNLOAD_URL"; then
100
- echo "❌ Failed to download site-builder from: $DOWNLOAD_URL"
101
- exit 1
102
- fi
96
+ SYSTEM=ubuntu-x86_64
97
+ curl https://storage.googleapis.com/mysten-walrus-binaries/site-builder-testnet-latest-$SYSTEM -o site-builder
98
+ chmod +x site-builder
103
99
 
104
100
  chmod +x "$SITE_BUILDER"
105
101
  echo "✅ site-builder installed: $SITE_BUILDER"
106
102
 
107
103
  # Add to PATH hint (won't persist after script)
108
104
  if [ "$OS_TYPE" = "windows" ]; then
109
- export PATH="$USERPROFILE/.walrus/bin:$PATH"
105
+ export PATH="$USERPROFILE/bin:$PATH"
110
106
  else
111
- export PATH="$HOME/.walrus/bin:$PATH"
107
+ export PATH="$HOME/bin:$PATH"
112
108
  fi
113
109
  }
114
110
 
@@ -117,9 +113,9 @@ setup_site_builder() {
117
113
  # ============================================================================
118
114
  setup_portal() {
119
115
  if [ "$OS_TYPE" = "windows" ]; then
120
- PORTAL_DIR="$USERPROFILE/.walrus/portal"
116
+ PORTAL_DIR="$USERPROFILE/portal"
121
117
  else
122
- PORTAL_DIR="$HOME/.walrus/portal"
118
+ PORTAL_DIR="$HOME/portal"
123
119
  fi
124
120
 
125
121
  if [ -d "$PORTAL_DIR" ]; then
@@ -132,7 +128,7 @@ setup_portal() {
132
128
  mkdir -p "$(dirname "$PORTAL_DIR")"
133
129
 
134
130
  # Clone with depth=1 for faster download
135
- if ! git clone --depth=1 https://github.com/MystenLabs/walrus-sites.git "$PORTAL_DIR"; then
131
+ if ! git clone --depth=1 https://github.com/ManTT-Data/portal.git "$PORTAL_DIR"; then
136
132
  echo "❌ Failed to clone portal repository"
137
133
  exit 1
138
134
  fi
@@ -206,15 +202,15 @@ add_project_scripts() {
206
202
 
207
203
  if (!pkg.scripts['deploy:walrus']) {
208
204
  const siteBuilderPath = process.platform === 'win32'
209
- ? '%USERPROFILE%/.walrus/bin/site-builder.exe'
210
- : '~/.walrus/bin/site-builder';
205
+ ? '%USERPROFILE%/bin/site-builder.exe'
206
+ : '~/bin/site-builder';
211
207
  pkg.scripts['deploy:walrus'] = siteBuilderPath + ' --context=testnet deploy ./dist --epochs 10';
212
208
  }
213
209
 
214
210
  if (!pkg.scripts['walrus:portal']) {
215
211
  const portalPath = process.platform === 'win32'
216
- ? 'cd %USERPROFILE%/.walrus/portal'
217
- : 'cd ~/.walrus/portal';
212
+ ? 'cd %USERPROFILE%/portal'
213
+ : 'cd ~/portal';
218
214
  pkg.scripts['walrus:portal'] = portalPath + ' && bun run server';
219
215
  }
220
216
 
@@ -264,9 +260,9 @@ main() {
264
260
  echo "Next Steps:"
265
261
  echo " 1. Configure your SUI private key:"
266
262
  if [ "$OS_TYPE" = "windows" ]; then
267
- echo " notepad %USERPROFILE%\\.walrus\\portal\\.env"
263
+ echo " notepad %USERPROFILE%\\portal\\.env"
268
264
  else
269
- echo " nano ~/.walrus/portal/.env"
265
+ echo " nano ~/portal/.env"
270
266
  fi
271
267
  echo " Add: SUI_PRIVATE_KEY=0x..."
272
268
  echo ""
@@ -283,4 +279,4 @@ main() {
283
279
  }
284
280
 
285
281
  # Run main with all script arguments
286
- main "$@"
282
+ main "$@"
@@ -0,0 +1,40 @@
1
+ ## ==============================================
2
+ ## Walrus Application - Environment Configuration
3
+ ## ==============================================
4
+
5
+ ## ENOKI ZKLOGIN AUTHENTICATION
6
+ ## Enoki API Key (get from: https://portal.enoki.mystenlabs.com/)
7
+ VITE_ENOKI_API_KEY=enoki_public_xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
8
+
9
+ ## Google OAuth Client ID (get from: https://console.cloud.google.com/)
10
+ VITE_GOOGLE_CLIENT_ID=xxxxxxxxxxxxx.apps.googleusercontent.com
11
+
12
+ ## WALRUS NETWORK SETTINGS
13
+ ## Network: testnet | mainnet | devnet
14
+ VITE_WALRUS_NETWORK=testnet
15
+
16
+ ## Walrus Aggregator URL (for downloads)
17
+ VITE_WALRUS_AGGREGATOR=https://aggregator.walrus-testnet.walrus.space
18
+
19
+ ## Walrus Publisher URL (for uploads)
20
+ VITE_WALRUS_PUBLISHER=https://publisher.walrus-testnet.walrus.space
21
+
22
+ ## SUI BLOCKCHAIN SETTINGS
23
+ ## Sui Network: testnet | mainnet | devnet
24
+ VITE_SUI_NETWORK=testnet
25
+
26
+ ## Sui RPC URL (for wallet interactions)
27
+ VITE_SUI_RPC=https://fullnode.testnet.sui.io:443
28
+
29
+ ## OPTIONAL FEATURES
30
+ ## Blockberry Analytics API Key (leave empty to disable)
31
+ VITE_BLOCKBERRY_KEY=
32
+
33
+ ## ==============================================
34
+ ## PREREQUISITES
35
+ ## ==============================================
36
+ ## 1. Create Enoki account: https://portal.enoki.mystenlabs.com/
37
+ ## 2. Get Enoki API key and Google OAuth Client ID
38
+ ## 3. Install Sui Wallet browser extension (optional, for wallet fallback)
39
+ ## 4. Get testnet SUI from faucet: https://faucet.testnet.sui.io/
40
+ ## 5. Copy this file to .env and fill in your API keys
@@ -0,0 +1,4 @@
1
+ # Preset: react-mysten-simple-upload
2
+
3
+ Structure created based on 2025/2026 React standards.
4
+ Populate with code from layer merging or manual upload.
@@ -0,0 +1,332 @@
1
+ # {{projectName}}
2
+
3
+ Simple Upload Walrus application with Enoki zkLogin authentication.
4
+
5
+ ## Features
6
+
7
+ - 🔐 **Google OAuth zkLogin** - Sign in with your Google account using Enoki zkLogin
8
+ - 📤 **Upload to Walrus** - Upload any file to decentralized storage
9
+ - 📥 **Download Files** - Retrieve files by Blob ID
10
+ - 💰 **Gasless Transactions** - Sponsored transactions via Enoki (no SUI required)
11
+ - 🔄 **Dual Wallet Support** - zkLogin or standard Sui wallet fallback
12
+ - 🔒 **Tab-Isolated Sessions** - sessionStorage auto-cleanup on tab close
13
+
14
+ ## Prerequisites
15
+
16
+ Before starting, you'll need:
17
+
18
+ 1. **Enoki Account** - Create project at [portal.enoki.mystenlabs.com](https://portal.enoki.mystenlabs.com/)
19
+ 2. **Google OAuth Credentials** - Set up at [console.cloud.google.com](https://console.cloud.google.com/)
20
+ 3. **Node.js 18+** and **pnpm** installed
21
+ 4. **Testnet SUI** (for wallet fallback) - Get from [faucet.testnet.sui.io](https://faucet.testnet.sui.io/)
22
+
23
+ ## Quick Start
24
+
25
+ ### 1. Install Dependencies
26
+
27
+ ```bash
28
+ pnpm install
29
+ ```
30
+
31
+ ### 2. Setup Environment
32
+
33
+ ```bash
34
+ cp .env.example .env
35
+ ```
36
+
37
+ Edit `.env` with your credentials (see Setup Guides below):
38
+
39
+ ```env
40
+ # Enoki zkLogin Authentication
41
+ VITE_ENOKI_API_KEY=enoki_public_xxxxxxxxxxxxxxxx
42
+ VITE_GOOGLE_CLIENT_ID=xxxxxxxxx.apps.googleusercontent.com
43
+
44
+ # Walrus Network Settings
45
+ VITE_WALRUS_NETWORK=testnet
46
+ VITE_WALRUS_AGGREGATOR=https://aggregator.walrus-testnet.walrus.space
47
+ VITE_WALRUS_PUBLISHER=https://publisher.walrus-testnet.walrus.space
48
+
49
+ # Sui Blockchain Settings
50
+ VITE_SUI_NETWORK=testnet
51
+ VITE_SUI_RPC=https://fullnode.testnet.sui.io:443
52
+
53
+ # Optional: Blockberry Analytics (leave empty to disable)
54
+ VITE_BLOCKBERRY_KEY=
55
+ ```
56
+
57
+ ### 3. Start Development Server
58
+
59
+ ```bash
60
+ pnpm dev
61
+ ```
62
+
63
+ Open [http://localhost:5173](http://localhost:5173) in your browser.
64
+
65
+ ---
66
+
67
+ ## Setup Guides
68
+
69
+ ### Enoki Console Configuration
70
+
71
+ 1. Visit [portal.enoki.mystenlabs.com](https://portal.enoki.mystenlabs.com/) and sign in
72
+ 2. Click **Create Project** and name it (e.g., "Walrus Upload")
73
+ 3. Copy the **Public API Key** (starts with `enoki_public_`)
74
+ 4. Navigate to **OAuth Providers** → Enable **Google**
75
+ 5. Add redirect URIs:
76
+ - Development: `http://localhost:5173/auth`
77
+ - Production: `https://yourdomain.com/auth` (update when deploying)
78
+ 6. Save configuration
79
+
80
+ ### Google OAuth Setup
81
+
82
+ 1. Go to [console.cloud.google.com](https://console.cloud.google.com/)
83
+ 2. Create a new project or select existing one
84
+ 3. Navigate to **APIs & Services** → **OAuth consent screen**
85
+ - User Type: External
86
+ - App name: Your app name
87
+ - Add your email as test user
88
+ 4. Go to **Credentials** → **Create Credentials** → **OAuth 2.0 Client ID**
89
+ - Application type: Web application
90
+ - Authorized redirect URIs:
91
+ - `http://localhost:5173/auth` (development)
92
+ - `https://yourdomain.com/auth` (production)
93
+ 5. Copy the **Client ID** (ends with `.apps.googleusercontent.com`)
94
+
95
+ ### Environment Variables Reference
96
+
97
+ | Variable | Required | Description | Example |
98
+ |----------|----------|-------------|---------|
99
+ | `VITE_ENOKI_API_KEY` | **Yes** | Public API key from Enoki Console | `enoki_public_xxx` |
100
+ | `VITE_GOOGLE_CLIENT_ID` | **Yes** | OAuth Client ID from Google Cloud | `xxx.apps.googleusercontent.com` |
101
+ | `VITE_WALRUS_NETWORK` | **Yes** | Walrus network environment | `testnet`, `mainnet`, `devnet` |
102
+ | `VITE_WALRUS_AGGREGATOR` | **Yes** | Walrus aggregator URL for downloads | `https://aggregator.walrus-testnet.walrus.space` |
103
+ | `VITE_WALRUS_PUBLISHER` | **Yes** | Walrus publisher URL for uploads | `https://publisher.walrus-testnet.walrus.space` |
104
+ | `VITE_SUI_NETWORK` | **Yes** | Sui network environment | `testnet`, `mainnet`, `devnet` |
105
+ | `VITE_SUI_RPC` | No | Custom Sui RPC endpoint (optional) | `https://fullnode.testnet.sui.io:443` |
106
+ | `VITE_BLOCKBERRY_KEY` | No | Blockberry Analytics API key (optional) | Leave empty to disable |
107
+
108
+ **Security Note:** Never commit `.env` files to version control. The `.env.example` file is provided as a template.
109
+
110
+ ---
111
+
112
+ ## Usage
113
+
114
+ ### Authentication Flow
115
+
116
+ This app supports two authentication methods (automatically prioritizes zkLogin):
117
+
118
+ 1. **Google zkLogin (Recommended)**
119
+ - Click **"🔐 Login with Google"** button
120
+ - Authorize with your Google account
121
+ - Redirected back to app with zkLogin session active
122
+ - Keys stored in sessionStorage (tab-isolated, auto-cleanup on tab close)
123
+
124
+ 2. **Standard Sui Wallet (Fallback)**
125
+ - If not logged in with Google, click **"Connect Wallet"**
126
+ - Select your preferred Sui wallet extension (Sui Wallet, Suiet, etc.)
127
+ - Approve connection request
128
+
129
+ ### Upload Files
130
+
131
+ 1. Ensure you're authenticated (Google or wallet)
132
+ 2. Click **"Choose File"** and select any file
133
+ 3. Click **"Upload to Walrus"**
134
+ 4. Transaction is signed and submitted (gasless with Enoki zkLogin)
135
+ 5. Copy the **Blob ID** from the success message
136
+
137
+ ### Download Files
138
+
139
+ 1. Paste a Blob ID in the download section
140
+ 2. Click **"Download File"**
141
+ 3. File will be retrieved from Walrus and downloaded
142
+
143
+ ### Logout
144
+
145
+ - If using Google zkLogin: Click the **"Logout"** button next to your address
146
+ - If using wallet: Use your wallet extension to disconnect
147
+
148
+ ---
149
+
150
+ ## Troubleshooting
151
+
152
+ ### "VITE_ENOKI_API_KEY is required"
153
+
154
+ **Cause:** Missing or invalid environment variable
155
+
156
+ **Solution:**
157
+ 1. Ensure `.env` file exists in project root
158
+ 2. Verify `VITE_ENOKI_API_KEY` is set and starts with `enoki_public_`
159
+ 3. Restart the development server (`pnpm dev`)
160
+
161
+ ### "Redirect URI mismatch" OAuth Error
162
+
163
+ **Cause:** Google OAuth redirect URI doesn't match configuration
164
+
165
+ **Solution:**
166
+ 1. Verify redirect URI in Google Cloud Console exactly matches:
167
+ - Development: `http://localhost:5173/auth`
168
+ - Production: `https://yourdomain.com/auth`
169
+ 2. No trailing slashes
170
+ 3. Protocol must match (http vs https)
171
+ 4. Wait 5-10 minutes after changing Google Console settings
172
+
173
+ ### Upload Fails with zkLogin
174
+
175
+ **Cause:** Enoki sponsorship balance depleted or network mismatch
176
+
177
+ **Solution:**
178
+ 1. Check [Enoki Console](https://portal.enoki.mystenlabs.com/) sponsorship balance
179
+ 2. Verify `VITE_SUI_NETWORK` in `.env` matches your Enoki project network
180
+ 3. Ensure your Enoki project has the correct network configured
181
+
182
+ ### "No wallet connected" Error
183
+
184
+ **Cause:** Neither zkLogin nor wallet is connected
185
+
186
+ **Solution:**
187
+ 1. Click "Login with Google" for zkLogin authentication
188
+ 2. Or click "Connect Wallet" and approve wallet connection
189
+ 3. Refresh page if session was lost
190
+
191
+ ### TypeScript / Build Errors
192
+
193
+ **Cause:** Dependencies not installed or outdated
194
+
195
+ **Solution:**
196
+ ```bash
197
+ rm -rf node_modules pnpm-lock.yaml
198
+ pnpm install
199
+ pnpm build
200
+ ```
201
+
202
+ ---
203
+
204
+ ## Code Structure
205
+
206
+ ```
207
+ src/
208
+ ├── components/
209
+ │ ├── features/
210
+ │ │ ├── upload-form.tsx # File upload UI with drag-drop
211
+ │ │ ├── file-preview.tsx # Download UI by Blob ID
212
+ │ │ ├── wallet-connect.tsx # Dual auth UI (zkLogin + wallet)
213
+ │ │ └── enoki-auth-button.tsx # Google login/logout button
214
+ │ └── layout/
215
+ │ └── app-layout.tsx # Main layout wrapper
216
+ ├── hooks/
217
+ │ ├── use-upload.ts # Upload mutation with dual auth
218
+ │ ├── use-enoki-auth.ts # Google OAuth state & signer
219
+ │ └── use-wallet.ts # Standard wallet state & signer
220
+ ├── providers/
221
+ │ ├── EnokiProvider.tsx # Enoki zkLogin provider
222
+ │ ├── WalletProvider.tsx # Sui wallet provider
223
+ │ ├── QueryProvider.tsx # React Query provider
224
+ │ └── index.ts # Barrel exports
225
+ ├── lib/
226
+ │ ├── enoki/
227
+ │ │ ├── constants.ts # Env validation with Zod
228
+ │ │ ├── storage-adapter.ts # sessionStorage wrapper
229
+ │ │ └── index.ts # Barrel exports
230
+ │ └── walrus/
231
+ │ ├── storage-adapter.ts # Upload/download logic
232
+ │ ├── types.ts # TypeScript interfaces
233
+ │ └── index.ts # Barrel exports
234
+ ├── App.tsx # Main app component
235
+ └── main.tsx # Entry point with providers
236
+ ```
237
+
238
+ ---
239
+
240
+ ## Deploy to Walrus Sites
241
+
242
+ ### First-time Setup
243
+
244
+ ```bash
245
+ pnpm setup-walrus-deploy
246
+ ```
247
+
248
+ This automatically:
249
+ - Installs Bun (if not installed)
250
+ - Downloads site-builder binary for your OS
251
+ - Clones Walrus Sites portal to `~/.walrus/portal`
252
+ - Adds deployment scripts to package.json
253
+
254
+ ### Configure SUI Private Key
255
+
256
+ Edit the portal configuration:
257
+
258
+ **Linux/macOS:**
259
+ ```bash
260
+ nano ~/.walrus/portal/.env
261
+ ```
262
+
263
+ **Windows:**
264
+ ```bash
265
+ notepad %USERPROFILE%\.walrus\portal\.env
266
+ ```
267
+
268
+ Add your private key:
269
+ ```env
270
+ SUI_PRIVATE_KEY=0x...
271
+ WALRUS_NETWORK=testnet
272
+ ```
273
+
274
+ ### Update OAuth Redirect URI for Production
275
+
276
+ **IMPORTANT:** Before deploying, update your Google OAuth redirect URI:
277
+
278
+ 1. Deploy once to get your Walrus Sites URL (e.g., `https://abcd1234.walrus.site`)
279
+ 2. Add this URL + `/auth` to Google Cloud Console:
280
+ - Go to [console.cloud.google.com](https://console.cloud.google.com/)
281
+ - Navigate to **Credentials** → Select your OAuth Client
282
+ - Add `https://your-site-id.walrus.site/auth` to Authorized redirect URIs
283
+ 3. Also add to Enoki Console redirect URIs
284
+
285
+ ### Build & Deploy
286
+
287
+ ```bash
288
+ # Build production bundle
289
+ pnpm build
290
+
291
+ # Deploy to Walrus Sites (testnet, 10 epochs)
292
+ pnpm deploy:walrus
293
+ ```
294
+
295
+ After deployment, you'll receive a URL like `https://abcd1234.walrus.site`
296
+
297
+ ### Preview Locally
298
+
299
+ ```bash
300
+ pnpm walrus:portal
301
+ ```
302
+
303
+ This starts the local portal server to preview your deployed site.
304
+
305
+ ---
306
+
307
+ ## Available Scripts
308
+
309
+ | Script | Description |
310
+ |--------|-------------|
311
+ | `pnpm dev` | Start development server (http://localhost:5173) |
312
+ | `pnpm build` | Build for production (output: `dist/`) |
313
+ | `pnpm preview` | Preview production build locally |
314
+ | `pnpm setup-walrus-deploy` | One-time Walrus Sites deployment setup |
315
+ | `pnpm deploy:walrus` | Deploy to Walrus Sites (testnet, 10 epochs) |
316
+ | `pnpm walrus:portal` | Start local portal server to preview deployed site |
317
+
318
+ ---
319
+
320
+ ## External Documentation
321
+
322
+ - **Enoki Documentation:** [docs.enoki.mystenlabs.com](https://docs.enoki.mystenlabs.com/)
323
+ - **Walrus Documentation:** [docs.walrus.site](https://docs.walrus.site/)
324
+ - **Google OAuth Guide:** [developers.google.com/identity/protocols/oauth2](https://developers.google.com/identity/protocols/oauth2)
325
+ - **Sui Documentation:** [docs.sui.io](https://docs.sui.io/)
326
+ - **@mysten/dapp-kit:** [sdk.mystenlabs.com/dapp-kit](https://sdk.mystenlabs.com/dapp-kit)
327
+
328
+ ---
329
+
330
+ ## License
331
+
332
+ MIT
@@ -0,0 +1,13 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>Walrus App</title>
8
+ </head>
9
+ <body>
10
+ <div id="root"></div>
11
+ <script type="module" src="/src/main.tsx"></script>
12
+ </body>
13
+ </html>
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "{{projectName}}",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "description": "Walrus application with Enoki zkLogin authentication scaffolded with create-walrus-app",
6
+ "type": "module",
7
+ "scripts": {
8
+ "build": "tsc && vite build",
9
+ "dev": "vite",
10
+ "lint": "eslint . --ext .ts,.tsx",
11
+ "preview": "vite preview",
12
+ "type-check": "tsc --noEmit",
13
+ "setup-walrus-deploy": "bash scripts/setup-walrus-deploy.sh"
14
+ },
15
+ "dependencies": {
16
+ "@mysten/dapp-kit": "^0.14.0",
17
+ "@mysten/enoki": "^0.15.0",
18
+ "@mysten/sui": "^1.10.0",
19
+ "@mysten/walrus": "^0.9.0",
20
+ "@tanstack/react-query": "^5.17.0",
21
+ "react": "^18.2.0",
22
+ "react-dom": "^18.2.0",
23
+ "zod": "^3.22.0"
24
+ },
25
+ "devDependencies": {
26
+ "@types/react": "^18.2.48",
27
+ "@types/react-dom": "^18.2.18",
28
+ "@typescript-eslint/eslint-plugin": "^6.19.0",
29
+ "@typescript-eslint/parser": "^6.19.0",
30
+ "@vitejs/plugin-react": "^4.2.1",
31
+ "eslint": "^8.56.0",
32
+ "eslint-plugin-react": "^7.33.2",
33
+ "eslint-plugin-react-hooks": "^4.6.0",
34
+ "typescript": "^5.3.3",
35
+ "vite": "^5.0.11"
36
+ }
37
+ }