Skip to content

Commit 2e7c1ab

Browse files
committed
demo-app lint
1 parent e2ff24f commit 2e7c1ab

File tree

8 files changed

+64
-87
lines changed

8 files changed

+64
-87
lines changed

sdk/examples/demo-app/next.config.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
const path = require('path');
1+
import path from 'path';
2+
import { fileURLToPath } from 'url';
3+
4+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
25

36
/** @type {import('next').NextConfig} */
47
const nextConfig = {
@@ -9,4 +12,4 @@ const nextConfig = {
912
},
1013
};
1114

12-
module.exports = nextConfig;
15+
export default nextConfig;

sdk/examples/demo-app/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"name": "demo-app",
33
"version": "0.1.0",
44
"private": true,
5+
"type": "module",
56
"scripts": {
67
"dev": "next dev --turbopack --port 3001",
78
"build": "next build --turbopack",

sdk/examples/demo-app/src/components/ConfigurationPanel.tsx

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use client';
22

3-
import { useState, useEffect } from 'react';
3+
import { useState, useEffect, useCallback } from 'react';
44
import { CheckCircle, AlertCircle, Settings, Globe, Database } from 'lucide-react';
55

66
interface ConfigurationPanelProps {
@@ -53,7 +53,7 @@ export function ConfigurationPanel({
5353
const [customHeaders, setCustomHeaders] = useState('');
5454

5555
// Test MSP connection
56-
const testMspConnection = async () => {
56+
const testMspConnection = useCallback(async () => {
5757
if (!environmentReady) {
5858
setMspStatus('error');
5959
return false;
@@ -68,7 +68,7 @@ export function ConfigurationPanel({
6868
} as RequestInit);
6969

7070
if (response.ok) {
71-
const health = await response.json();
71+
await response.json(); // Verify response is valid JSON
7272
setMspStatus('connected');
7373
return true;
7474
} else {
@@ -80,10 +80,10 @@ export function ConfigurationPanel({
8080
setMspStatus('error');
8181
return false;
8282
}
83-
};
83+
}, [mspConfig, environmentReady]);
8484

8585
// Test blockchain connection
86-
const testBlockchainConnection = async () => {
86+
const testBlockchainConnection = useCallback(async () => {
8787
if (!environmentReady) {
8888
setBlockchainStatus('error');
8989
return false;
@@ -135,18 +135,18 @@ export function ConfigurationPanel({
135135
setBlockchainStatus('error');
136136
return false;
137137
}
138-
};
138+
}, [blockchainConfig, environmentReady]);
139139

140140
// Test all connections
141-
const testConnections = async () => {
141+
const testConnections = useCallback(async () => {
142142
const [mspOk, blockchainOk] = await Promise.all([
143143
testMspConnection(),
144144
testBlockchainConnection()
145145
]);
146146

147147
const allValid = mspOk && blockchainOk;
148148
onConfigurationValid(allValid);
149-
};
149+
}, [onConfigurationValid, testMspConnection, testBlockchainConnection]);
150150

151151
// Parse custom headers
152152
const parseCustomHeaders = (headersString: string): Record<string, string> => {
@@ -171,7 +171,7 @@ export function ConfigurationPanel({
171171
const timeoutId = setTimeout(testConnections, 1000);
172172
return () => clearTimeout(timeoutId);
173173
}
174-
}, [mspConfig, blockchainConfig, environmentReady]);
174+
}, [mspConfig, blockchainConfig, environmentReady, testConnections]);
175175

176176
const getStatusIcon = (status: 'checking' | 'connected' | 'error') => {
177177
switch (status) {

sdk/examples/demo-app/src/components/EnvironmentSetup.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use client';
22

3-
import { useState, useEffect } from 'react';
3+
import { useState, useEffect, useCallback } from 'react';
44
import { Play, Square, RefreshCcw } from 'lucide-react';
55

66
interface EnvironmentSetupProps {
@@ -109,7 +109,7 @@ export function EnvironmentSetup({ onEnvironmentReady, environmentReady }: Envir
109109
return { ...service, status: 'error' };
110110
};
111111

112-
const checkAllServices = async () => {
112+
const checkAllServices = useCallback(async () => {
113113
setIsChecking(true);
114114

115115
const updatedServices = await Promise.all(
@@ -122,14 +122,14 @@ export function EnvironmentSetup({ onEnvironmentReady, environmentReady }: Envir
122122
onEnvironmentReady(allRunning);
123123

124124
setIsChecking(false);
125-
};
125+
}, [services, onEnvironmentReady]);
126126

127127
useEffect(() => {
128128
checkAllServices();
129129
// Check services every 30 seconds
130130
const interval = setInterval(checkAllServices, 30000);
131131
return () => clearInterval(interval);
132-
}, []);
132+
}, [checkAllServices]);
133133

134134
const getStatusColor = (status: ServiceStatus['status']) => {
135135
switch (status) {

sdk/examples/demo-app/src/components/FileManager.tsx

Lines changed: 20 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
'use client';
22

3-
import { useState, useRef, useCallback, useEffect } from 'react';
4-
import { Upload, Download, File, Folder, Hash, Info, X, CheckCircle, AlertCircle, Plus, Database, ArrowLeft } from 'lucide-react';
5-
import { type WalletClient, type PublicClient, formatEther } from 'viem';
3+
import { useState, useRef, useCallback } from 'react';
4+
import { Upload, Download, File, Folder, Hash, X, CheckCircle, AlertCircle, Plus, Database, ArrowLeft } from 'lucide-react';
5+
import { type WalletClient, type PublicClient } from 'viem';
66
import { FileManager as StorageHubFileManager, initWasm, StorageHubClient, ReplicationLevel } from '@storagehub-sdk/core';
7-
import { MspClient, type UploadReceipt, type DownloadResult, type Bucket, type FileListResponse, type FileTree, type DownloadOptions } from '@storagehub-sdk/msp-client';
7+
import { MspClient, type UploadReceipt, type Bucket, type FileTree } from '@storagehub-sdk/msp-client';
88
import { TypeRegistry } from '@polkadot/types';
99
import type { AccountId20, H256 } from '@polkadot/types/interfaces';
1010

@@ -59,7 +59,7 @@ interface FileDownloadState {
5959
downloadError: string | null;
6060
}
6161

62-
export function FileManager({ walletClient, publicClient, walletAddress, mspClient, storageHubClient }: FileManagerProps) {
62+
export function FileManager({ publicClient, walletAddress, mspClient, storageHubClient }: FileManagerProps) {
6363
const fileInputRef = useRef<HTMLInputElement>(null);
6464

6565
const [uploadState, setUploadState] = useState<FileUploadState>({
@@ -93,7 +93,6 @@ export function FileManager({ walletClient, publicClient, walletAddress, mspClie
9393

9494
const [buckets, setBuckets] = useState<Bucket[]>([]);
9595
const [selectedBucketId, setSelectedBucketId] = useState<string>('');
96-
const [walletBalance, setWalletBalance] = useState<string | null>(null);
9796
const [isLoadingBuckets, setIsLoadingBuckets] = useState<boolean>(false);
9897

9998
// File Browser State
@@ -112,21 +111,6 @@ export function FileManager({ walletClient, publicClient, walletAddress, mspClie
112111
downloadError: null,
113112
});
114113

115-
// Get wallet balance
116-
useEffect(() => {
117-
const getBalance = async () => {
118-
if (publicClient && walletAddress) {
119-
try {
120-
const balance = await publicClient.getBalance({ address: walletAddress as `0x${string}` });
121-
setWalletBalance(formatEther(balance));
122-
} catch (error) {
123-
console.error('Failed to get balance:', error);
124-
}
125-
}
126-
};
127-
getBalance();
128-
}, [publicClient, walletAddress]);
129-
130114
// File selection handler
131115
const handleFileSelect = useCallback(async (file: File) => {
132116
setUploadState(prev => ({
@@ -224,7 +208,7 @@ export function FileManager({ walletClient, publicClient, walletAddress, mspClie
224208
} else {
225209
throw new Error('Bucket creation transaction failed');
226210
}
227-
} catch (error: any) {
211+
} catch (error: unknown) {
228212
console.error('Bucket creation failed:', error);
229213
setBucketState(prev => ({
230214
...prev,
@@ -245,20 +229,20 @@ export function FileManager({ walletClient, publicClient, walletAddress, mspClie
245229

246230
try {
247231

248-
let bucketList: any[] = [];
232+
let bucketList: Bucket[] = [];
249233
try {
250234
bucketList = await mspClient.buckets.listBuckets();
251-
} catch (sdkError: any) {
252-
console.error('❌ Failed to load buckets:', sdkError?.message || sdkError);
235+
} catch (sdkError: unknown) {
236+
console.error('❌ Failed to load buckets:', sdkError instanceof Error ? sdkError.message : sdkError);
253237
bucketList = []; // Fallback to empty array
254238
}
255239

256240
// Replace all buckets with the fresh list from MSP backend
257241
const freshBuckets = bucketList || [];
258242
setBuckets(freshBuckets);
259243

260-
} catch (error: any) {
261-
console.error('❌ Failed to refresh buckets:', error?.message || error);
244+
} catch (error: unknown) {
245+
console.error('❌ Failed to refresh buckets:', error instanceof Error ? error.message : error);
262246
} finally {
263247
setIsLoadingBuckets(false);
264248
}
@@ -308,7 +292,7 @@ export function FileManager({ walletClient, publicClient, walletAddress, mspClie
308292

309293
console.log(`📁 Loaded ${extractedFiles.length} files`);
310294

311-
} catch (error: any) {
295+
} catch (error: unknown) {
312296
console.error('❌ Failed to load files:', error);
313297
setFileBrowserState(prev => ({
314298
...prev,
@@ -385,9 +369,8 @@ export function FileManager({ walletClient, publicClient, walletAddress, mspClie
385369
}
386370

387371
const bucketIdH256 = registry.createType("H256", bucketIdForH256) as H256;
388-
const fileKey = await fileManager.computeFileKey(owner, bucketIdH256, fileLocation);
389-
390-
372+
// File key is computed by the MSP backend during upload
373+
await fileManager.computeFileKey(owner, bucketIdH256, fileLocation);
391374

392375
setUploadState(prev => ({ ...prev, uploadProgress: 25 }));
393376

@@ -413,8 +396,8 @@ export function FileManager({ walletClient, publicClient, walletAddress, mspClie
413396
0 // replicas (used only when ReplicationLevel = Custom, like sdk-precompiles)
414397
// No gas options - let it estimate naturally like sdk-precompiles
415398
);
416-
} catch (error: any) {
417-
console.error('❌ Storage request failed:', error?.message || error);
399+
} catch (error: unknown) {
400+
console.error('❌ Storage request failed:', error instanceof Error ? error.message : error);
418401
throw error;
419402
}
420403

@@ -451,8 +434,8 @@ export function FileManager({ walletClient, publicClient, walletAddress, mspClie
451434
fileLocation // location parameter like sdk-precompiles
452435
);
453436

454-
} catch (error: any) {
455-
console.error('❌ MSP upload failed:', error?.message || error);
437+
} catch (error: unknown) {
438+
console.error('❌ MSP upload failed:', error instanceof Error ? error.message : error);
456439
throw error;
457440
}
458441

@@ -465,7 +448,7 @@ export function FileManager({ walletClient, publicClient, walletAddress, mspClie
465448
uploadProgress: 100
466449
}));
467450

468-
} catch (error: any) {
451+
} catch (error: unknown) {
469452
console.error('Upload failed:', error);
470453
setUploadState(prev => ({
471454
...prev,
@@ -803,7 +786,7 @@ export function FileManager({ walletClient, publicClient, walletAddress, mspClie
803786

804787
console.log('✅ File download completed:', file.name);
805788

806-
} catch (error: any) {
789+
} catch (error: unknown) {
807790
console.error('❌ Download failed:', error);
808791
setDownloadState(prev => ({
809792
...prev,

sdk/examples/demo-app/src/components/OnePageDemo.tsx

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use client';
22

3-
import { useState, useCallback, useEffect } from 'react';
3+
import { useState, useCallback, useMemo, useEffect } from 'react';
44
import { Settings, Wallet, Database, CheckCircle, AlertCircle, ExternalLink } from 'lucide-react';
55
import { createWalletClient, createPublicClient, custom, formatEther, getAddress, type WalletClient, type PublicClient } from 'viem';
66
import { StorageHubClient } from '@storagehub-sdk/core';
@@ -31,12 +31,12 @@ export function OnePageDemo() {
3131
const [mspError, setMspError] = useState<string | null>(null);
3232

3333
// Define the StorageHub chain configuration
34-
const storageHubChain = {
34+
const storageHubChain = useMemo(() => ({
3535
id: config.chainId,
3636
name: 'StorageHub Solochain EVM',
3737
nativeCurrency: { name: 'StorageHub', symbol: 'SH', decimals: 18 },
3838
rpcUrls: { default: { http: [config.rpcUrl] } },
39-
};
39+
}), [config.chainId, config.rpcUrl]);
4040

4141
// Check if MetaMask is available (client-side only to avoid hydration mismatch)
4242
const [isMetaMaskAvailable, setIsMetaMaskAvailable] = useState<boolean | null>(null);
@@ -90,9 +90,9 @@ export function OnePageDemo() {
9090
params: [{ chainId: `0x${config.chainId.toString(16)}` }],
9191
});
9292
console.log('✅ Network switched successfully');
93-
} catch (switchError: any) {
93+
} catch (switchError: unknown) {
9494
// If chain doesn't exist, add it
95-
if (switchError.code === 4902) {
95+
if (switchError && typeof switchError === 'object' && 'code' in switchError && (switchError as { code: number }).code === 4902) {
9696
console.log('🔄 Network not found, adding StorageHub network...');
9797
await window.ethereum!.request({
9898
method: 'wallet_addEthereumChain',
@@ -156,19 +156,20 @@ export function OnePageDemo() {
156156
balance: formattedBalance
157157
});
158158

159-
} catch (error: any) {
159+
} catch (error: unknown) {
160160
console.error('❌ Wallet connection failed:', error);
161161

162162
// Provide more specific error messages
163163
let errorMessage = 'Failed to connect wallet';
164-
if (error.message?.includes('User rejected')) {
164+
const errorMsg = error && typeof error === 'object' && 'message' in error ? (error as { message: string }).message : '';
165+
if (errorMsg.includes('User rejected')) {
165166
errorMessage = 'Connection cancelled by user';
166-
} else if (error.message?.includes('network')) {
167+
} else if (errorMsg.includes('network')) {
167168
errorMessage = 'Network configuration error. Please check your MetaMask settings.';
168-
} else if (error.message?.includes('JSON-RPC')) {
169+
} else if (errorMsg.includes('JSON-RPC')) {
169170
errorMessage = 'RPC connection error. Please ensure the StorageHub node is running.';
170-
} else if (error.message) {
171-
errorMessage = error.message;
171+
} else if (errorMsg) {
172+
errorMessage = errorMsg;
172173
}
173174

174175
setWalletError(errorMessage);
@@ -188,8 +189,6 @@ export function OnePageDemo() {
188189
// Create MSP client
189190
const mspClient = await MspClient.connect({ baseUrl: config.mspUrl });
190191

191-
let authToken: string;
192-
193192
if (config.mockAuth) {
194193
// MOCK AUTHENTICATION PATH
195194
const mockAddress = '0xf24FF3a9CF04c71Dbc94D0b566f7A27B94566cac'; // Address that has buckets
@@ -198,7 +197,8 @@ export function OnePageDemo() {
198197
console.log('- Mock Address (with buckets):', mockAddress);
199198
console.log('- Mock mode enabled, skipping SIWE flow');
200199

201-
authToken = generateMockJWT(mockAddress); // Use mock address instead of wallet address
200+
const mockToken = generateMockJWT(mockAddress); // Use mock address instead of wallet address
201+
mspClient.setToken(mockToken);
202202
console.log('✅ Mock JWT generated for address with existing buckets');
203203

204204
} else {
@@ -216,13 +216,9 @@ export function OnePageDemo() {
216216

217217
// Note: authenticateSIWE handles token management internally
218218
// No need to extract token manually
219-
authToken = 'authenticated'; // Placeholder since token is managed internally
220219
}
221220

222-
// Set the token (only needed for mock auth, real auth handles it internally)
223-
if (config.mockAuth) {
224-
// mspClient.setToken(authToken);
225-
}
221+
// Token management is handled internally by the SDK
226222
console.log(`✅ MSP client authenticated successfully (${config.mockAuth ? 'Mock' : 'Real'} auth)`);
227223

228224
// Create StorageHub client

sdk/examples/demo-app/src/components/StorageHubDemo.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
'use client';
22

3-
import { useState, useEffect } from 'react';
3+
import { useState } from 'react';
44
import { type WalletClient, type PublicClient } from 'viem';
5-
import { Upload, Download, Info, Settings } from 'lucide-react';
5+
import { Upload, Info, Settings } from 'lucide-react';
66
import { MspClient } from '@storagehub-sdk/msp-client';
77
import { StorageHubClient } from '@storagehub-sdk/core';
88
import { FileManager } from './FileManager';
@@ -195,7 +195,7 @@ export function StorageHubDemo({ walletClient, publicClient, walletAddress }: St
195195
<li>• Viem clients connected to StorageHub blockchain</li>
196196
<li>• MSP backend authenticated and ready</li>
197197
<li>• File upload/download functionality available</li>
198-
<li>• Switch to "File Management" tab to start</li>
198+
<li>• Switch to &quot;File Management&quot; tab to start</li>
199199
</ul>
200200
</div>
201201
)}

0 commit comments

Comments
 (0)