@blu1606/create-walrus-app 2.0.0 → 2.1.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.
@@ -2,6 +2,7 @@ import { logger } from '../utils/logger.js';
2
2
  import { installDependencies } from './package-manager.js';
3
3
  import { validateProject } from './validator.js';
4
4
  import { displaySuccess, displayError } from './messages.js';
5
+ import { setupWalrusDeploy } from './walrus-deploy.js';
5
6
  export async function runPostInstall(options) {
6
7
  const { context, projectPath, skipInstall = false, skipValidation = false, } = options;
7
8
  const result = {
@@ -30,6 +31,10 @@ export async function runPostInstall(options) {
30
31
  validationResult.errors.forEach((err) => logger.warn(` - ${err}`));
31
32
  }
32
33
  }
34
+ // Step 3: Setup Walrus deployment (interactive prompt)
35
+ if (result.installed) {
36
+ await setupWalrusDeploy(projectPath, context);
37
+ }
33
38
  // Display success message
34
39
  displaySuccess(context);
35
40
  return result;
@@ -0,0 +1,6 @@
1
+ import type { Context } from '../types.js';
2
+ /**
3
+ * Prompts user to setup Walrus Sites deployment
4
+ * Runs setup-walrus-deploy.sh script if user confirms
5
+ */
6
+ export declare function setupWalrusDeploy(projectPath: string, _context: Context): Promise<void>;
@@ -0,0 +1,77 @@
1
+ import prompts from 'prompts';
2
+ import { spawn } from 'cross-spawn';
3
+ import { join } from 'node:path';
4
+ import { existsSync, chmodSync } from 'node:fs';
5
+ import { logger } from '../utils/logger.js';
6
+ /**
7
+ * Prompts user to setup Walrus Sites deployment
8
+ * Runs setup-walrus-deploy.sh script if user confirms
9
+ */
10
+ export async function setupWalrusDeploy(projectPath, _context) {
11
+ try {
12
+ const isInteractive = Boolean(process.stdin.isTTY);
13
+ // Skip in non-interactive mode
14
+ if (!isInteractive) {
15
+ return;
16
+ }
17
+ console.log(''); // Newline for better spacing
18
+ const response = await prompts({
19
+ type: 'confirm',
20
+ name: 'setup',
21
+ message: 'Setup Walrus Sites deployment? (testnet)',
22
+ initial: false,
23
+ }, {
24
+ onCancel: () => {
25
+ logger.info('Skipping Walrus deployment setup');
26
+ return false;
27
+ },
28
+ });
29
+ if (!response.setup) {
30
+ logger.info('You can setup later by running: pnpm setup-walrus-deploy');
31
+ return;
32
+ }
33
+ // Run the setup script
34
+ const scriptPath = join(projectPath, 'scripts', 'setup-walrus-deploy.sh');
35
+ if (!existsSync(scriptPath)) {
36
+ logger.warn('⚠️ setup-walrus-deploy.sh not found in project scripts/');
37
+ return;
38
+ }
39
+ // Make script executable (Unix/macOS)
40
+ try {
41
+ chmodSync(scriptPath, 0o755);
42
+ }
43
+ catch (error) {
44
+ // Ignore on Windows
45
+ }
46
+ logger.info('🦭 Running Walrus deployment setup...\n');
47
+ // Execute setup script
48
+ const child = spawn('bash', [scriptPath, projectPath], {
49
+ cwd: projectPath,
50
+ stdio: 'inherit', // Show output in real-time
51
+ shell: true,
52
+ });
53
+ await new Promise((resolve, reject) => {
54
+ child.on('close', (code) => {
55
+ if (code === 0) {
56
+ logger.success('\n✅ Walrus deployment setup complete!');
57
+ resolve();
58
+ }
59
+ else {
60
+ logger.warn(`\n⚠️ Setup exited with code ${code}. You can retry with: pnpm setup-walrus-deploy`);
61
+ resolve(); // Don't fail the whole installation
62
+ }
63
+ });
64
+ child.on('error', (error) => {
65
+ logger.error(`Setup script error: ${error.message}`);
66
+ reject(error);
67
+ });
68
+ });
69
+ }
70
+ catch (error) {
71
+ // Non-fatal: log and continue
72
+ logger.warn('⚠️ Walrus deployment setup skipped due to error');
73
+ if (error instanceof Error) {
74
+ logger.warn(error.message);
75
+ }
76
+ }
77
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blu1606/create-walrus-app",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "description": "Interactive CLI for scaffolding Walrus applications",
5
5
  "type": "module",
6
6
  "bin": {
@@ -45,3 +45,63 @@ The gallery maintains a local index in localStorage:
45
45
  "lastModified": 1705449600000
46
46
  }
47
47
  ```
48
+
49
+ ## Deploy to Walrus Sites
50
+
51
+ ### First-time Setup
52
+
53
+ ```bash
54
+ pnpm setup-walrus-deploy
55
+ ```
56
+
57
+ This will automatically:
58
+ - Install Bun (if not already installed)
59
+ - Download site-builder binary for your OS
60
+ - Clone Walrus Sites portal to `~/.walrus/portal`
61
+ - Add deployment scripts to package.json
62
+
63
+ ### Configure SUI Private Key
64
+
65
+ Edit the portal configuration:
66
+
67
+ **Linux/macOS:**
68
+ ```bash
69
+ nano ~/.walrus/portal/.env
70
+ ```
71
+
72
+ **Windows:**
73
+ ```bash
74
+ notepad %USERPROFILE%\.walrus\portal\.env
75
+ ```
76
+
77
+ Add your private key:
78
+ ```env
79
+ SUI_PRIVATE_KEY=0x...
80
+ WALRUS_NETWORK=testnet
81
+ ```
82
+
83
+ ### Build & Deploy
84
+
85
+ ```bash
86
+ # Build production bundle
87
+ pnpm build
88
+
89
+ # Deploy to Walrus Sites (testnet, 10 epochs)
90
+ pnpm deploy:walrus
91
+ ```
92
+
93
+ ### Preview Locally
94
+
95
+ ```bash
96
+ pnpm walrus:portal
97
+ ```
98
+
99
+ This starts the local portal server to preview your deployed site.
100
+
101
+ ## Available Scripts
102
+
103
+ - `pnpm dev` - Start development server
104
+ - `pnpm build` - Build for production
105
+ - `pnpm setup-walrus-deploy` - One-time deployment setup
106
+ - `pnpm deploy:walrus` - Deploy to Walrus Sites
107
+ - `pnpm walrus:portal` - Start local portal preview
@@ -9,7 +9,8 @@
9
9
  "dev": "vite",
10
10
  "lint": "eslint . --ext .ts,.tsx",
11
11
  "preview": "vite preview",
12
- "type-check": "tsc --noEmit"
12
+ "type-check": "tsc --noEmit",
13
+ "setup-walrus-deploy": "bash scripts/setup-walrus-deploy.sh"
13
14
  },
14
15
  "dependencies": {
15
16
  "@mysten/dapp-kit": "^0.14.0",
@@ -0,0 +1,286 @@
1
+ #!/bin/bash
2
+ # setup-walrus-deploy.sh - Zero-config Walrus Sites deployment setup (testnet)
3
+ # Auto-installs dependencies, downloads tools, clones portal
4
+ # Supports: Linux, macOS, Windows (Git Bash/WSL)
5
+
6
+ set -e # Exit on error
7
+
8
+ echo "🦭 Walrus Sites Zero-Config Setup (testnet)"
9
+ echo ""
10
+
11
+ # ============================================================================
12
+ # 1. Detect OS & Architecture
13
+ # ============================================================================
14
+ detect_os() {
15
+ OS=$(uname -s | tr '[:upper:]' '[:lower:]')
16
+ ARCH=$(uname -m)
17
+
18
+ case "$OS" in
19
+ linux*) OS_TYPE="linux" ;;
20
+ darwin*) OS_TYPE="macos" ;;
21
+ mingw*|msys*|cygwin*) OS_TYPE="windows" ;;
22
+ *)
23
+ echo "❌ Unsupported OS: $OS"
24
+ exit 1
25
+ ;;
26
+ esac
27
+
28
+ echo "✅ Detected: $OS_TYPE ($ARCH)"
29
+ }
30
+
31
+ # ============================================================================
32
+ # 2. Auto-install Bun (if not exists)
33
+ # ============================================================================
34
+ setup_bun() {
35
+ if command -v bun &>/dev/null; then
36
+ echo "✅ Bun already installed: $(bun --version)"
37
+ return 0
38
+ fi
39
+
40
+ echo "📥 Installing Bun..."
41
+ if [ "$OS_TYPE" = "windows" ]; then
42
+ # Windows (PowerShell install via Git Bash)
43
+ powershell -c "irm bun.sh/install.ps1 | iex"
44
+ else
45
+ # Linux/macOS
46
+ curl -fsSL https://bun.sh/install | bash
47
+ fi
48
+
49
+ # Add to PATH for current session
50
+ if [ "$OS_TYPE" = "windows" ]; then
51
+ export PATH="$USERPROFILE/.bun/bin:$PATH"
52
+ else
53
+ export BUN_INSTALL="$HOME/.bun"
54
+ export PATH="$BUN_INSTALL/bin:$PATH"
55
+ fi
56
+
57
+ # Verify installation
58
+ if command -v bun &>/dev/null; then
59
+ echo "✅ Bun installed: $(bun --version)"
60
+ else
61
+ echo "⚠️ Bun installed but not in PATH. Restart terminal or run:"
62
+ echo " export PATH=\"\$HOME/.bun/bin:\$PATH\""
63
+ fi
64
+ }
65
+
66
+ # ============================================================================
67
+ # 3. Download site-builder binary (if not exists)
68
+ # ============================================================================
69
+ setup_site_builder() {
70
+ # Set install directory based on OS
71
+ if [ "$OS_TYPE" = "windows" ]; then
72
+ WALRUS_BIN="$USERPROFILE/.walrus/bin"
73
+ SITE_BUILDER="$WALRUS_BIN/site-builder.exe"
74
+ else
75
+ WALRUS_BIN="$HOME/.walrus/bin"
76
+ SITE_BUILDER="$WALRUS_BIN/site-builder"
77
+ fi
78
+
79
+ # Check if already exists
80
+ if [ -f "$SITE_BUILDER" ]; then
81
+ echo "✅ site-builder already exists: $SITE_BUILDER"
82
+ chmod +x "$SITE_BUILDER" 2>/dev/null || true
83
+ return 0
84
+ fi
85
+
86
+ echo "📥 Downloading site-builder for $OS_TYPE..."
87
+ mkdir -p "$WALRUS_BIN"
88
+
89
+ # Select binary based on OS
90
+ case "$OS_TYPE" in
91
+ linux) BINARY_NAME="site-builder-linux" ;;
92
+ macos) BINARY_NAME="site-builder-macos" ;;
93
+ windows) BINARY_NAME="site-builder-windows.exe" ;;
94
+ esac
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
103
+
104
+ chmod +x "$SITE_BUILDER"
105
+ echo "✅ site-builder installed: $SITE_BUILDER"
106
+
107
+ # Add to PATH hint (won't persist after script)
108
+ if [ "$OS_TYPE" = "windows" ]; then
109
+ export PATH="$USERPROFILE/.walrus/bin:$PATH"
110
+ else
111
+ export PATH="$HOME/.walrus/bin:$PATH"
112
+ fi
113
+ }
114
+
115
+ # ============================================================================
116
+ # 4. Clone Walrus Portal (if not exists)
117
+ # ============================================================================
118
+ setup_portal() {
119
+ if [ "$OS_TYPE" = "windows" ]; then
120
+ PORTAL_DIR="$USERPROFILE/.walrus/portal"
121
+ else
122
+ PORTAL_DIR="$HOME/.walrus/portal"
123
+ fi
124
+
125
+ if [ -d "$PORTAL_DIR" ]; then
126
+ echo "✅ Portal already exists: $PORTAL_DIR"
127
+ echo " Updating..."
128
+ cd "$PORTAL_DIR"
129
+ git pull --quiet || echo "⚠️ Git pull failed (may be offline)"
130
+ else
131
+ echo "📂 Cloning Walrus Sites portal..."
132
+ mkdir -p "$(dirname "$PORTAL_DIR")"
133
+
134
+ # Clone with depth=1 for faster download
135
+ if ! git clone --depth=1 https://github.com/MystenLabs/walrus-sites.git "$PORTAL_DIR"; then
136
+ echo "❌ Failed to clone portal repository"
137
+ exit 1
138
+ fi
139
+
140
+ cd "$PORTAL_DIR"
141
+ echo "✅ Portal cloned to: $PORTAL_DIR"
142
+ fi
143
+
144
+ # Setup .env if not exists
145
+ if [ ! -f ".env" ]; then
146
+ if [ -f ".env.example" ]; then
147
+ cp .env.example .env
148
+ echo "✅ Created .env from .env.example"
149
+ else
150
+ # Create minimal .env
151
+ cat > .env << 'EOF'
152
+ # Walrus Portal Configuration (Testnet)
153
+ WALRUS_NETWORK=testnet
154
+ SUI_PRIVATE_KEY=
155
+
156
+ # Optional: Uncomment to customize
157
+ # PORTAL_PORT=3000
158
+ EOF
159
+ echo "✅ Created .env template"
160
+ fi
161
+
162
+ echo ""
163
+ echo "⚠️ ACTION REQUIRED:"
164
+ echo " Edit $PORTAL_DIR/.env"
165
+ echo " Add your SUI_PRIVATE_KEY=0x..."
166
+ echo ""
167
+ else
168
+ echo "✅ .env already configured"
169
+ fi
170
+
171
+ # Install portal dependencies
172
+ echo "📦 Installing portal dependencies..."
173
+ if ! bun install --silent; then
174
+ echo "❌ Bun install failed"
175
+ exit 1
176
+ fi
177
+
178
+ echo "✅ Portal dependencies installed"
179
+ }
180
+
181
+ # ============================================================================
182
+ # 5. Add npm scripts to project package.json
183
+ # ============================================================================
184
+ add_project_scripts() {
185
+ PROJECT_DIR="${1:-.}" # Default to current directory
186
+ cd "$PROJECT_DIR" || { echo "❌ Invalid project directory"; exit 1; }
187
+
188
+ if [ ! -f "package.json" ]; then
189
+ echo "❌ No package.json found in $PROJECT_DIR"
190
+ exit 1
191
+ fi
192
+
193
+ echo "📝 Adding Walrus deploy scripts to package.json..."
194
+
195
+ # Use Node.js to safely modify package.json (guaranteed to exist in Node projects)
196
+ node -e "
197
+ const fs = require('fs');
198
+ const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
199
+
200
+ pkg.scripts = pkg.scripts || {};
201
+
202
+ // Add scripts (only if not already exists)
203
+ if (!pkg.scripts['setup-walrus-deploy']) {
204
+ pkg.scripts['setup-walrus-deploy'] = 'bash scripts/setup-walrus-deploy.sh';
205
+ }
206
+
207
+ if (!pkg.scripts['deploy:walrus']) {
208
+ const siteBuilderPath = process.platform === 'win32'
209
+ ? '%USERPROFILE%/.walrus/bin/site-builder.exe'
210
+ : '~/.walrus/bin/site-builder';
211
+ pkg.scripts['deploy:walrus'] = siteBuilderPath + ' --context=testnet deploy ./dist --epochs 10';
212
+ }
213
+
214
+ if (!pkg.scripts['walrus:portal']) {
215
+ const portalPath = process.platform === 'win32'
216
+ ? 'cd %USERPROFILE%/.walrus/portal'
217
+ : 'cd ~/.walrus/portal';
218
+ pkg.scripts['walrus:portal'] = portalPath + ' && bun run server';
219
+ }
220
+
221
+ fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\\n');
222
+ " || {
223
+ echo "❌ Failed to update package.json"
224
+ exit 1
225
+ }
226
+
227
+ echo "✅ Scripts added to package.json:"
228
+ echo " - setup-walrus-deploy"
229
+ echo " - deploy:walrus"
230
+ echo " - walrus:portal"
231
+ }
232
+
233
+ # ============================================================================
234
+ # Main Execution
235
+ # ============================================================================
236
+ main() {
237
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
238
+
239
+ # Trap errors
240
+ trap 'echo "❌ Setup failed at line $LINENO"' ERR
241
+
242
+ # Prerequisites check
243
+ if ! command -v git &>/dev/null; then
244
+ echo "❌ Git not found. Install: https://git-scm.com"
245
+ exit 1
246
+ fi
247
+
248
+ if ! command -v node &>/dev/null; then
249
+ echo "❌ Node.js not found. Install: https://nodejs.org"
250
+ exit 1
251
+ fi
252
+
253
+ # Run setup steps
254
+ detect_os
255
+ setup_bun
256
+ setup_site_builder
257
+ setup_portal
258
+ add_project_scripts "$@"
259
+
260
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
261
+ echo ""
262
+ echo "🎉 Setup Complete!"
263
+ echo ""
264
+ echo "Next Steps:"
265
+ echo " 1. Configure your SUI private key:"
266
+ if [ "$OS_TYPE" = "windows" ]; then
267
+ echo " notepad %USERPROFILE%\\.walrus\\portal\\.env"
268
+ else
269
+ echo " nano ~/.walrus/portal/.env"
270
+ fi
271
+ echo " Add: SUI_PRIVATE_KEY=0x..."
272
+ echo ""
273
+ echo " 2. Build your project:"
274
+ echo " pnpm build"
275
+ echo ""
276
+ echo " 3. Deploy to Walrus Sites:"
277
+ echo " pnpm deploy:walrus"
278
+ echo ""
279
+ echo " 4. (Optional) Preview locally:"
280
+ echo " pnpm walrus:portal"
281
+ echo ""
282
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
283
+ }
284
+
285
+ # Run main with all script arguments
286
+ main "$@"
@@ -22,3 +22,63 @@ This is a Simple Upload Walrus application.
22
22
  - `UploadForm.tsx` - File upload UI
23
23
  - `FilePreview.tsx` - Download UI
24
24
  - `App.tsx` - Main app layout
25
+
26
+ ## Deploy to Walrus Sites
27
+
28
+ ### First-time Setup
29
+
30
+ ```bash
31
+ pnpm setup-walrus-deploy
32
+ ```
33
+
34
+ This will automatically:
35
+ - Install Bun (if not already installed)
36
+ - Download site-builder binary for your OS
37
+ - Clone Walrus Sites portal to `~/.walrus/portal`
38
+ - Add deployment scripts to package.json
39
+
40
+ ### Configure SUI Private Key
41
+
42
+ Edit the portal configuration:
43
+
44
+ **Linux/macOS:**
45
+ ```bash
46
+ nano ~/.walrus/portal/.env
47
+ ```
48
+
49
+ **Windows:**
50
+ ```bash
51
+ notepad %USERPROFILE%\.walrus\portal\.env
52
+ ```
53
+
54
+ Add your private key:
55
+ ```env
56
+ SUI_PRIVATE_KEY=0x...
57
+ WALRUS_NETWORK=testnet
58
+ ```
59
+
60
+ ### Build & Deploy
61
+
62
+ ```bash
63
+ # Build production bundle
64
+ pnpm build
65
+
66
+ # Deploy to Walrus Sites (testnet, 10 epochs)
67
+ pnpm deploy:walrus
68
+ ```
69
+
70
+ ### Preview Locally
71
+
72
+ ```bash
73
+ pnpm walrus:portal
74
+ ```
75
+
76
+ This starts the local portal server to preview your deployed site.
77
+
78
+ ## Available Scripts
79
+
80
+ - `pnpm dev` - Start development server
81
+ - `pnpm build` - Build for production
82
+ - `pnpm setup-walrus-deploy` - One-time deployment setup
83
+ - `pnpm deploy:walrus` - Deploy to Walrus Sites
84
+ - `pnpm walrus:portal` - Start local portal preview
@@ -9,7 +9,8 @@
9
9
  "dev": "vite",
10
10
  "lint": "eslint . --ext .ts,.tsx",
11
11
  "preview": "vite preview",
12
- "type-check": "tsc --noEmit"
12
+ "type-check": "tsc --noEmit",
13
+ "setup-walrus-deploy": "bash scripts/setup-walrus-deploy.sh"
13
14
  },
14
15
  "dependencies": {
15
16
  "@mysten/dapp-kit": "^0.14.0",
@@ -0,0 +1,286 @@
1
+ #!/bin/bash
2
+ # setup-walrus-deploy.sh - Zero-config Walrus Sites deployment setup (testnet)
3
+ # Auto-installs dependencies, downloads tools, clones portal
4
+ # Supports: Linux, macOS, Windows (Git Bash/WSL)
5
+
6
+ set -e # Exit on error
7
+
8
+ echo "🦭 Walrus Sites Zero-Config Setup (testnet)"
9
+ echo ""
10
+
11
+ # ============================================================================
12
+ # 1. Detect OS & Architecture
13
+ # ============================================================================
14
+ detect_os() {
15
+ OS=$(uname -s | tr '[:upper:]' '[:lower:]')
16
+ ARCH=$(uname -m)
17
+
18
+ case "$OS" in
19
+ linux*) OS_TYPE="linux" ;;
20
+ darwin*) OS_TYPE="macos" ;;
21
+ mingw*|msys*|cygwin*) OS_TYPE="windows" ;;
22
+ *)
23
+ echo "❌ Unsupported OS: $OS"
24
+ exit 1
25
+ ;;
26
+ esac
27
+
28
+ echo "✅ Detected: $OS_TYPE ($ARCH)"
29
+ }
30
+
31
+ # ============================================================================
32
+ # 2. Auto-install Bun (if not exists)
33
+ # ============================================================================
34
+ setup_bun() {
35
+ if command -v bun &>/dev/null; then
36
+ echo "✅ Bun already installed: $(bun --version)"
37
+ return 0
38
+ fi
39
+
40
+ echo "📥 Installing Bun..."
41
+ if [ "$OS_TYPE" = "windows" ]; then
42
+ # Windows (PowerShell install via Git Bash)
43
+ powershell -c "irm bun.sh/install.ps1 | iex"
44
+ else
45
+ # Linux/macOS
46
+ curl -fsSL https://bun.sh/install | bash
47
+ fi
48
+
49
+ # Add to PATH for current session
50
+ if [ "$OS_TYPE" = "windows" ]; then
51
+ export PATH="$USERPROFILE/.bun/bin:$PATH"
52
+ else
53
+ export BUN_INSTALL="$HOME/.bun"
54
+ export PATH="$BUN_INSTALL/bin:$PATH"
55
+ fi
56
+
57
+ # Verify installation
58
+ if command -v bun &>/dev/null; then
59
+ echo "✅ Bun installed: $(bun --version)"
60
+ else
61
+ echo "⚠️ Bun installed but not in PATH. Restart terminal or run:"
62
+ echo " export PATH=\"\$HOME/.bun/bin:\$PATH\""
63
+ fi
64
+ }
65
+
66
+ # ============================================================================
67
+ # 3. Download site-builder binary (if not exists)
68
+ # ============================================================================
69
+ setup_site_builder() {
70
+ # Set install directory based on OS
71
+ if [ "$OS_TYPE" = "windows" ]; then
72
+ WALRUS_BIN="$USERPROFILE/.walrus/bin"
73
+ SITE_BUILDER="$WALRUS_BIN/site-builder.exe"
74
+ else
75
+ WALRUS_BIN="$HOME/.walrus/bin"
76
+ SITE_BUILDER="$WALRUS_BIN/site-builder"
77
+ fi
78
+
79
+ # Check if already exists
80
+ if [ -f "$SITE_BUILDER" ]; then
81
+ echo "✅ site-builder already exists: $SITE_BUILDER"
82
+ chmod +x "$SITE_BUILDER" 2>/dev/null || true
83
+ return 0
84
+ fi
85
+
86
+ echo "📥 Downloading site-builder for $OS_TYPE..."
87
+ mkdir -p "$WALRUS_BIN"
88
+
89
+ # Select binary based on OS
90
+ case "$OS_TYPE" in
91
+ linux) BINARY_NAME="site-builder-linux" ;;
92
+ macos) BINARY_NAME="site-builder-macos" ;;
93
+ windows) BINARY_NAME="site-builder-windows.exe" ;;
94
+ esac
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
103
+
104
+ chmod +x "$SITE_BUILDER"
105
+ echo "✅ site-builder installed: $SITE_BUILDER"
106
+
107
+ # Add to PATH hint (won't persist after script)
108
+ if [ "$OS_TYPE" = "windows" ]; then
109
+ export PATH="$USERPROFILE/.walrus/bin:$PATH"
110
+ else
111
+ export PATH="$HOME/.walrus/bin:$PATH"
112
+ fi
113
+ }
114
+
115
+ # ============================================================================
116
+ # 4. Clone Walrus Portal (if not exists)
117
+ # ============================================================================
118
+ setup_portal() {
119
+ if [ "$OS_TYPE" = "windows" ]; then
120
+ PORTAL_DIR="$USERPROFILE/.walrus/portal"
121
+ else
122
+ PORTAL_DIR="$HOME/.walrus/portal"
123
+ fi
124
+
125
+ if [ -d "$PORTAL_DIR" ]; then
126
+ echo "✅ Portal already exists: $PORTAL_DIR"
127
+ echo " Updating..."
128
+ cd "$PORTAL_DIR"
129
+ git pull --quiet || echo "⚠️ Git pull failed (may be offline)"
130
+ else
131
+ echo "📂 Cloning Walrus Sites portal..."
132
+ mkdir -p "$(dirname "$PORTAL_DIR")"
133
+
134
+ # Clone with depth=1 for faster download
135
+ if ! git clone --depth=1 https://github.com/MystenLabs/walrus-sites.git "$PORTAL_DIR"; then
136
+ echo "❌ Failed to clone portal repository"
137
+ exit 1
138
+ fi
139
+
140
+ cd "$PORTAL_DIR"
141
+ echo "✅ Portal cloned to: $PORTAL_DIR"
142
+ fi
143
+
144
+ # Setup .env if not exists
145
+ if [ ! -f ".env" ]; then
146
+ if [ -f ".env.example" ]; then
147
+ cp .env.example .env
148
+ echo "✅ Created .env from .env.example"
149
+ else
150
+ # Create minimal .env
151
+ cat > .env << 'EOF'
152
+ # Walrus Portal Configuration (Testnet)
153
+ WALRUS_NETWORK=testnet
154
+ SUI_PRIVATE_KEY=
155
+
156
+ # Optional: Uncomment to customize
157
+ # PORTAL_PORT=3000
158
+ EOF
159
+ echo "✅ Created .env template"
160
+ fi
161
+
162
+ echo ""
163
+ echo "⚠️ ACTION REQUIRED:"
164
+ echo " Edit $PORTAL_DIR/.env"
165
+ echo " Add your SUI_PRIVATE_KEY=0x..."
166
+ echo ""
167
+ else
168
+ echo "✅ .env already configured"
169
+ fi
170
+
171
+ # Install portal dependencies
172
+ echo "📦 Installing portal dependencies..."
173
+ if ! bun install --silent; then
174
+ echo "❌ Bun install failed"
175
+ exit 1
176
+ fi
177
+
178
+ echo "✅ Portal dependencies installed"
179
+ }
180
+
181
+ # ============================================================================
182
+ # 5. Add npm scripts to project package.json
183
+ # ============================================================================
184
+ add_project_scripts() {
185
+ PROJECT_DIR="${1:-.}" # Default to current directory
186
+ cd "$PROJECT_DIR" || { echo "❌ Invalid project directory"; exit 1; }
187
+
188
+ if [ ! -f "package.json" ]; then
189
+ echo "❌ No package.json found in $PROJECT_DIR"
190
+ exit 1
191
+ fi
192
+
193
+ echo "📝 Adding Walrus deploy scripts to package.json..."
194
+
195
+ # Use Node.js to safely modify package.json (guaranteed to exist in Node projects)
196
+ node -e "
197
+ const fs = require('fs');
198
+ const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
199
+
200
+ pkg.scripts = pkg.scripts || {};
201
+
202
+ // Add scripts (only if not already exists)
203
+ if (!pkg.scripts['setup-walrus-deploy']) {
204
+ pkg.scripts['setup-walrus-deploy'] = 'bash scripts/setup-walrus-deploy.sh';
205
+ }
206
+
207
+ if (!pkg.scripts['deploy:walrus']) {
208
+ const siteBuilderPath = process.platform === 'win32'
209
+ ? '%USERPROFILE%/.walrus/bin/site-builder.exe'
210
+ : '~/.walrus/bin/site-builder';
211
+ pkg.scripts['deploy:walrus'] = siteBuilderPath + ' --context=testnet deploy ./dist --epochs 10';
212
+ }
213
+
214
+ if (!pkg.scripts['walrus:portal']) {
215
+ const portalPath = process.platform === 'win32'
216
+ ? 'cd %USERPROFILE%/.walrus/portal'
217
+ : 'cd ~/.walrus/portal';
218
+ pkg.scripts['walrus:portal'] = portalPath + ' && bun run server';
219
+ }
220
+
221
+ fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\\n');
222
+ " || {
223
+ echo "❌ Failed to update package.json"
224
+ exit 1
225
+ }
226
+
227
+ echo "✅ Scripts added to package.json:"
228
+ echo " - setup-walrus-deploy"
229
+ echo " - deploy:walrus"
230
+ echo " - walrus:portal"
231
+ }
232
+
233
+ # ============================================================================
234
+ # Main Execution
235
+ # ============================================================================
236
+ main() {
237
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
238
+
239
+ # Trap errors
240
+ trap 'echo "❌ Setup failed at line $LINENO"' ERR
241
+
242
+ # Prerequisites check
243
+ if ! command -v git &>/dev/null; then
244
+ echo "❌ Git not found. Install: https://git-scm.com"
245
+ exit 1
246
+ fi
247
+
248
+ if ! command -v node &>/dev/null; then
249
+ echo "❌ Node.js not found. Install: https://nodejs.org"
250
+ exit 1
251
+ fi
252
+
253
+ # Run setup steps
254
+ detect_os
255
+ setup_bun
256
+ setup_site_builder
257
+ setup_portal
258
+ add_project_scripts "$@"
259
+
260
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
261
+ echo ""
262
+ echo "🎉 Setup Complete!"
263
+ echo ""
264
+ echo "Next Steps:"
265
+ echo " 1. Configure your SUI private key:"
266
+ if [ "$OS_TYPE" = "windows" ]; then
267
+ echo " notepad %USERPROFILE%\\.walrus\\portal\\.env"
268
+ else
269
+ echo " nano ~/.walrus/portal/.env"
270
+ fi
271
+ echo " Add: SUI_PRIVATE_KEY=0x..."
272
+ echo ""
273
+ echo " 2. Build your project:"
274
+ echo " pnpm build"
275
+ echo ""
276
+ echo " 3. Deploy to Walrus Sites:"
277
+ echo " pnpm deploy:walrus"
278
+ echo ""
279
+ echo " 4. (Optional) Preview locally:"
280
+ echo " pnpm walrus:portal"
281
+ echo ""
282
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
283
+ }
284
+
285
+ # Run main with all script arguments
286
+ main "$@"