Quangnguyen711 commited on
Commit
2dff984
·
verified ·
1 Parent(s): 4039830

affter upload I didn't see anything

Browse files
Files changed (6) hide show
  1. README.md +8 -5
  2. components/file-card.js +145 -0
  3. components/navbar.js +70 -0
  4. index.html +85 -19
  5. script.js +135 -0
  6. style.css +44 -18
README.md CHANGED
@@ -1,10 +1,13 @@
1
  ---
2
- title: Solguardian Smart Contract Shield
3
- emoji: 🐨
4
- colorFrom: green
5
- colorTo: red
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
1
  ---
2
+ title: SolGuardian - Smart Contract Shield 🛡️
3
+ colorFrom: blue
4
+ colorTo: yellow
5
+ emoji: 🐳
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite-v3
10
  ---
11
 
12
+ # Welcome to your new DeepSite project!
13
+ This project was created with [DeepSite](https://huggingface.co/deepsite).
components/file-card.js ADDED
@@ -0,0 +1,145 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ class CustomFileCard extends HTMLElement {
2
+ static get observedAttributes() {
3
+ return ['status'];
4
+ }
5
+
6
+ constructor() {
7
+ super();
8
+ this.attachShadow({ mode: 'open' });
9
+ }
10
+
11
+ connectedCallback() {
12
+ this.render();
13
+ }
14
+
15
+ attributeChangedCallback(name, oldValue, newValue) {
16
+ if (name === 'status') {
17
+ this.render();
18
+ }
19
+ }
20
+
21
+ render() {
22
+ const name = this.getAttribute('name') || 'Untitled';
23
+ const status = this.getAttribute('status') || 'pending';
24
+
25
+ let statusText, statusColor, icon;
26
+
27
+ switch(status) {
28
+ case 'pending':
29
+ statusText = 'Analyzing...';
30
+ statusColor = 'bg-yellow-500';
31
+ icon = 'clock';
32
+ break;
33
+ case 'safe':
34
+ statusText = 'Secure';
35
+ statusColor = 'bg-green-500';
36
+ icon = 'check-circle';
37
+ break;
38
+ case 'vulnerable':
39
+ statusText = 'Vulnerable';
40
+ statusColor = 'bg-red-500';
41
+ icon = 'alert-triangle';
42
+ break;
43
+ case 'error':
44
+ statusText = 'Error';
45
+ statusColor = 'bg-gray-500';
46
+ icon = 'x-circle';
47
+ break;
48
+ default:
49
+ statusText = 'Unknown';
50
+ statusColor = 'bg-gray-500';
51
+ icon = 'help-circle';
52
+ }
53
+
54
+ this.shadowRoot.innerHTML = `
55
+ <style>
56
+ .card {
57
+ background-color: white;
58
+ border-radius: 0.75rem;
59
+ overflow: hidden;
60
+ box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
61
+ transition: all 0.3s ease;
62
+ }
63
+ .card:hover {
64
+ transform: translateY(-2px);
65
+ box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
66
+ }
67
+ .card-header {
68
+ padding: 1.5rem;
69
+ border-bottom: 1px solid #e5e7eb;
70
+ }
71
+ .card-title {
72
+ font-size: 1.25rem;
73
+ font-weight: 600;
74
+ color: #1f2937;
75
+ margin-bottom: 0.5rem;
76
+ white-space: nowrap;
77
+ overflow: hidden;
78
+ text-overflow: ellipsis;
79
+ }
80
+ .card-body {
81
+ padding: 1.5rem;
82
+ display: flex;
83
+ flex-direction: column;
84
+ align-items: center;
85
+ }
86
+ .status {
87
+ display: inline-flex;
88
+ align-items: center;
89
+ padding: 0.25rem 0.75rem;
90
+ border-radius: 9999px;
91
+ font-size: 0.875rem;
92
+ font-weight: 500;
93
+ color: white;
94
+ }
95
+ .icon {
96
+ width: 3rem;
97
+ height: 3rem;
98
+ margin-bottom: 1rem;
99
+ }
100
+ .progress-bar {
101
+ width: 100%;
102
+ height: 0.5rem;
103
+ background-color: #e5e7eb;
104
+ border-radius: 0.25rem;
105
+ overflow: hidden;
106
+ margin-top: 1rem;
107
+ }
108
+ .progress {
109
+ height: 100%;
110
+ background-color: #3b82f6;
111
+ width: ${status === 'pending' ? '50%' : '100%'};
112
+ animation: ${status === 'pending' ? 'pulse 2s infinite' : 'none'};
113
+ }
114
+ @keyframes pulse {
115
+ 0% { opacity: 0.6; }
116
+ 50% { opacity: 1; }
117
+ 100% { opacity: 0.6; }
118
+ }
119
+ </style>
120
+
121
+ <div class="card">
122
+ <div class="card-header">
123
+ <h3 class="card-title">${name}</h3>
124
+ <div class="status ${statusColor}">
125
+ <i data-feather="${icon}" class="mr-1" width="14" height="14"></i>
126
+ ${statusText}
127
+ </div>
128
+ </div>
129
+ <div class="card-body">
130
+ <i data-feather="${icon === 'clock' ? 'code' : icon}" class="icon" width="48" height="48"></i>
131
+ <div class="progress-bar">
132
+ <div class="progress"></div>
133
+ </div>
134
+ </div>
135
+ </div>
136
+ `;
137
+
138
+ // Replace feather icons
139
+ if (this.shadowRoot.querySelector('[data-feather]')) {
140
+ feather.replace();
141
+ }
142
+ }
143
+ }
144
+
145
+ customElements.define('custom-file-card', CustomFileCard);
components/navbar.js ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ class CustomNavbar extends HTMLElement {
2
+ connectedCallback() {
3
+ this.attachShadow({ mode: 'open' });
4
+ this.shadowRoot.innerHTML = `
5
+ <style>
6
+ nav {
7
+ background-color: white;
8
+ box-shadow: 0 2px 4px rgba(0,0,0,0.1);
9
+ padding: 1rem 2rem;
10
+ }
11
+ .container {
12
+ display: flex;
13
+ justify-content: space-between;
14
+ align-items: center;
15
+ max-width: 1200px;
16
+ margin: 0 auto;
17
+ }
18
+ .logo {
19
+ display: flex;
20
+ align-items: center;
21
+ font-weight: 700;
22
+ font-size: 1.5rem;
23
+ color: #1e40af;
24
+ text-decoration: none;
25
+ }
26
+ .logo-icon {
27
+ margin-right: 0.5rem;
28
+ }
29
+ .nav-links {
30
+ display: flex;
31
+ gap: 1.5rem;
32
+ }
33
+ .nav-link {
34
+ color: #4b5563;
35
+ text-decoration: none;
36
+ font-weight: 500;
37
+ transition: color 0.2s;
38
+ }
39
+ .nav-link:hover {
40
+ color: #1e40af;
41
+ }
42
+ @media (max-width: 768px) {
43
+ .container {
44
+ flex-direction: column;
45
+ gap: 1rem;
46
+ }
47
+ .nav-links {
48
+ width: 100%;
49
+ justify-content: space-around;
50
+ }
51
+ }
52
+ </style>
53
+ <nav>
54
+ <div class="container">
55
+ <a href="index.html" class="logo">
56
+ <i data-feather="shield" class="logo-icon"></i>
57
+ SolGuardian
58
+ </a>
59
+ <div class="nav-links">
60
+ <a href="index.html" class="nav-link">Home</a>
61
+ <a href="#" class="nav-link">Documentation</a>
62
+ <a href="#" class="nav-link">About</a>
63
+ </div>
64
+ </div>
65
+ </nav>
66
+ `;
67
+ }
68
+ }
69
+
70
+ customElements.define('custom-navbar', CustomNavbar);
index.html CHANGED
@@ -1,19 +1,85 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>SolGuardian - Smart Contract Analysis</title>
7
+ <link rel="stylesheet" href="style.css">
8
+ <script src="https://cdn.tailwindcss.com"></script>
9
+ <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
10
+ <script src="https://unpkg.com/feather-icons"></script>
11
+ <script src="https://cdn.jsdelivr.net/npm/three@0.132.2/build/three.min.js"></script>
12
+ <script src="https://cdn.jsdelivr.net/npm/three@0.132.2/examples/js/controls/OrbitControls.js"></script>
13
+ <script src="https://cdn.jsdelivr.net/npm/d3@7"></script>
14
+ <script src="components/navbar.js"></script>
15
+ <script src="components/file-card.js"></script>
16
+ </head>
17
+ <body class="bg-gray-100 min-h-screen">
18
+ <custom-navbar></custom-navbar>
19
+
20
+ <main class="container mx-auto px-4 py-8">
21
+ <div class="text-center mb-12">
22
+ <h1 class="text-4xl font-bold text-gray-800 mb-4">Smart Contract Vulnerability Scanner</h1>
23
+ <p class="text-xl text-gray-600 max-w-3xl mx-auto">Upload your Solidity files to detect vulnerabilities with AI-powered analysis</p>
24
+ </div>
25
+
26
+ <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6" id="file-container">
27
+ <!-- File cards will be added here dynamically -->
28
+
29
+ <!-- Add new file card -->
30
+ <div class="bg-white rounded-xl shadow-md overflow-hidden hover:shadow-lg transition-shadow duration-300 cursor-pointer" id="add-file-card">
31
+ <div class="p-8 flex flex-col items-center justify-center h-full">
32
+ <i data-feather="plus" class="w-16 h-16 text-blue-500 mb-4"></i>
33
+ <h3 class="text-xl font-semibold text-gray-800">Add New Contract</h3>
34
+ </div>
35
+ </div>
36
+ </div>
37
+
38
+ <!-- File upload modal -->
39
+ <div id="upload-modal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center hidden z-50">
40
+ <div class="bg-white rounded-xl p-8 w-full max-w-md">
41
+ <div class="flex justify-between items-center mb-6">
42
+ <h3 class="text-2xl font-bold text-gray-800">Upload Solidity File</h3>
43
+ <button id="close-modal" class="text-gray-500 hover:text-gray-700">
44
+ <i data-feather="x"></i>
45
+ </button>
46
+ </div>
47
+
48
+ <form id="upload-form" class="space-y-6">
49
+ <div>
50
+ <label for="file-name" class="block text-sm font-medium text-gray-700 mb-1">Project Name</label>
51
+ <input type="text" id="file-name" required class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
52
+ </div>
53
+
54
+ <div>
55
+ <label for="file-upload" class="block text-sm font-medium text-gray-700 mb-1">Solidity File</label>
56
+ <div class="mt-1 flex justify-center px-6 pt-5 pb-6 border-2 border-gray-300 border-dashed rounded-lg">
57
+ <div class="space-y-1 text-center">
58
+ <div class="flex text-sm text-gray-600">
59
+ <label for="file-upload" class="relative cursor-pointer bg-white rounded-md font-medium text-blue-600 hover:text-blue-500 focus-within:outline-none">
60
+ <span>Upload a file</span>
61
+ <input id="file-upload" name="file-upload" type="file" accept=".sol" class="sr-only" required>
62
+ </label>
63
+ <p class="pl-1">or drag and drop</p>
64
+ </div>
65
+ <p class="text-xs text-gray-500">.sol files only</p>
66
+ </div>
67
+ </div>
68
+ </div>
69
+
70
+ <button type="submit" class="w-full bg-blue-600 text-white py-3 px-4 rounded-lg hover:bg-blue-700 transition-colors duration-300 flex items-center justify-center">
71
+ <i data-feather="upload" class="mr-2"></i>
72
+ Analyze Contract
73
+ </button>
74
+ </form>
75
+ </div>
76
+ </div>
77
+ </main>
78
+
79
+ <script src="script.js"></script>
80
+ <script>
81
+ feather.replace();
82
+ </script>
83
+ <script src="https://huggingface.co/deepsite/deepsite-badge.js"></script>
84
+ </body>
85
+ </html>
script.js ADDED
@@ -0,0 +1,135 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ // Load previously uploaded files when page loads
3
+ function loadSavedFiles() {
4
+ const files = JSON.parse(localStorage.getItem('uploadedFiles') || '[]');
5
+ const fileContainer = document.getElementById('file-container');
6
+
7
+ // Clear existing cards except the add button
8
+ const existingCards = document.querySelectorAll('custom-file-card');
9
+ existingCards.forEach(card => card.remove());
10
+
11
+ // Recreate cards from localStorage
12
+ files.forEach(file => {
13
+ const card = document.createElement('custom-file-card');
14
+ card.setAttribute('name', file.name);
15
+ card.setAttribute('status', file.status);
16
+ fileContainer.insertBefore(card, addFileCard);
17
+ });
18
+ }
19
+
20
+ document.addEventListener('DOMContentLoaded', function() {
21
+ // Load any previously uploaded files
22
+ loadSavedFiles();
23
+ // Initialize modal functionality
24
+ const addFileCard = document.getElementById('add-file-card');
25
+ const uploadModal = document.getElementById('upload-modal');
26
+ const closeModal = document.getElementById('close-modal');
27
+ const uploadForm = document.getElementById('upload-form');
28
+
29
+ // Open modal when add file card is clicked
30
+ addFileCard.addEventListener('click', () => {
31
+ uploadModal.classList.remove('hidden');
32
+ });
33
+
34
+ // Close modal
35
+ closeModal.addEventListener('click', () => {
36
+ uploadModal.classList.add('hidden');
37
+ });
38
+
39
+ // Handle file upload
40
+ uploadForm.addEventListener('submit', async (e) => {
41
+ e.preventDefault();
42
+
43
+ const fileName = document.getElementById('file-name').value;
44
+ const fileInput = document.getElementById('file-upload');
45
+ const file = fileInput.files[0];
46
+
47
+ if (!file || !fileName) return;
48
+
49
+ // Create a new file card immediately
50
+ createFileCard(fileName, 'pending');
51
+
52
+ // Close modal
53
+ uploadModal.classList.add('hidden');
54
+ // Simulate API call with mock response
55
+ try {
56
+ // Show loading state
57
+ updateFileCardStatus(fileName, 'pending');
58
+
59
+ // Simulate API delay
60
+ await new Promise(resolve => setTimeout(resolve, 2000));
61
+
62
+ // Generate mock response
63
+ const mockResponse = {
64
+ node: 'detect_vulnerability_src',
65
+ output: {
66
+ predicted_class: Math.random() > 0.5 ? 1 : 0, // Random vulnerability
67
+ confidence_score: (Math.random() * 0.5 + 0.5).toFixed(2) // Random confidence 0.5-1.0
68
+ }
69
+ };
70
+
71
+ // Process the mock response
72
+ processAnalysisData(fileName, mockResponse);
73
+ } catch (error) {
74
+ console.error('Error:', error);
75
+ updateFileCardStatus(fileName, 'error');
76
+
77
+ // Show error message to user
78
+ alert('Analysis failed. Please try again.');
79
+ }
80
+
81
+ // Reset form
82
+ uploadForm.reset();
83
+ });
84
+ // Function to create a new file card
85
+ function createFileCard(name, status) {
86
+ const fileContainer = document.getElementById('file-container');
87
+ const card = document.createElement('custom-file-card');
88
+ card.setAttribute('name', name);
89
+ card.setAttribute('status', status);
90
+ fileContainer.insertBefore(card, addFileCard);
91
+
92
+ // Store the file info in localStorage
93
+ const files = JSON.parse(localStorage.getItem('uploadedFiles') || '[]');
94
+ files.push({ name, status });
95
+ localStorage.setItem('uploadedFiles', JSON.stringify(files));
96
+ }
97
+ // Function to update file card status
98
+ function updateFileCardStatus(name, status) {
99
+ const cards = document.querySelectorAll('custom-file-card');
100
+ for (const card of cards) {
101
+ if (card.getAttribute('name') === name) {
102
+ card.setAttribute('status', status);
103
+
104
+ // Update the file status in localStorage
105
+ const files = JSON.parse(localStorage.getItem('uploadedFiles') || '[]');
106
+ const fileIndex = files.findIndex(f => f.name === name);
107
+ if (fileIndex !== -1) {
108
+ files[fileIndex].status = status;
109
+ localStorage.setItem('uploadedFiles', JSON.stringify(files));
110
+ }
111
+ break;
112
+ }
113
+ }
114
+ }
115
+ // Process analysis data from API
116
+ function processAnalysisData(fileName, data) {
117
+ if (data.node === 'detect_vulnerability_src') {
118
+ const isVulnerable = data.output.predicted_class === 1;
119
+ updateFileCardStatus(fileName, isVulnerable ? 'vulnerable' : 'safe');
120
+
121
+ // Store analysis data for later use in the analysis page
122
+ localStorage.setItem(`analysis_${fileName}`, JSON.stringify({
123
+ isVulnerable,
124
+ confidence: data.output.confidence_score
125
+ }));
126
+
127
+ // Redirect to analysis page if vulnerable
128
+ if (isVulnerable) {
129
+ setTimeout(() => {
130
+ window.location.href = `analysis.html?file=${encodeURIComponent(fileName)}`;
131
+ }, 1500);
132
+ }
133
+ }
134
+ }
135
+ });
style.css CHANGED
@@ -1,28 +1,54 @@
 
 
1
  body {
2
- padding: 2rem;
3
- font-family: -apple-system, BlinkMacSystemFont, "Arial", sans-serif;
 
 
 
 
 
 
 
 
 
 
4
  }
5
 
6
- h1 {
7
- font-size: 16px;
8
- margin-top: 0;
 
9
  }
10
 
11
- p {
12
- color: rgb(107, 114, 128);
13
- font-size: 15px;
14
- margin-bottom: 10px;
15
- margin-top: 5px;
16
  }
17
 
18
- .card {
19
- max-width: 620px;
20
- margin: 0 auto;
21
- padding: 16px;
22
- border: 1px solid lightgray;
23
- border-radius: 16px;
24
  }
25
 
26
- .card p:last-child {
27
- margin-bottom: 0;
28
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
2
+
3
  body {
4
+ font-family: 'Inter', sans-serif;
5
+ }
6
+
7
+ /* Animation for vulnerability graph nodes */
8
+ @keyframes pulse-red {
9
+ 0% { transform: scale(1); }
10
+ 50% { transform: scale(1.05); }
11
+ 100% { transform: scale(1); }
12
+ }
13
+
14
+ .vulnerable-node {
15
+ animation: pulse-red 2s infinite;
16
  }
17
 
18
+ /* Custom scrollbar */
19
+ ::-webkit-scrollbar {
20
+ width: 8px;
21
+ height: 8px;
22
  }
23
 
24
+ ::-webkit-scrollbar-track {
25
+ background: #f1f1f1;
26
+ border-radius: 10px;
 
 
27
  }
28
 
29
+ ::-webkit-scrollbar-thumb {
30
+ background: #888;
31
+ border-radius: 10px;
 
 
 
32
  }
33
 
34
+ ::-webkit-scrollbar-thumb:hover {
35
+ background: #555;
36
  }
37
+
38
+ /* Transition effects */
39
+ .fade-enter-active, .fade-leave-active {
40
+ transition: opacity 0.3s;
41
+ }
42
+ .fade-enter, .fade-leave-to {
43
+ opacity: 0;
44
+ }
45
+
46
+ /* 3D graph container */
47
+ .graph-container {
48
+ width: 100%;
49
+ height: 500px;
50
+ background: #f8fafc;
51
+ border-radius: 12px;
52
+ overflow: hidden;
53
+ position: relative;
54
+ }