Deploy Kusama Shield Interface
Requirements:
Clone:
git clone https://codeberg.org/KusamaShield/Interface && cd Interface/
Build wasm:
cargo install wasm-pack
wasm-pack build --target web
rm -rf public/pkg/
cp -r pkg/ public/
Install node packages:
npm install -f
Run locally:

npm run local
Use
npm run devto run it on all public network interfaces
Run a public instance
You should run a public instance! We encourage everyone to do so.
git clone https://codeberg.org/KusamaShield/Interface
cd Interface/ && npm install -f
npm run build
Run:
npm run local
Put Kusama Shield behind a firewall
You are adviced to put the react interface behind a firewall such as:
- nginx + https://github.com/owasp-modsecurity/ModSecurity
- Coraza
Nginx setup example:
Modify vite.config.ts:
import react from '@vitejs/plugin-react'
import { defineConfig } from 'vite'
import path from 'path'
//import { NodeGlobalsPolyfillPlugin } from '@esbuild-plugins/node-globals-polyfill';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
build: {
target: 'esnext',
},
worker: {
format: 'es',
},
// Cross-Origin-Isolation headers enable SharedArrayBuffer, which lets
// snarkjs/ffjavascript use multi-threaded WASM for multiexponentiation.
// Without these, groth16.prove() runs single-threaded (~40s → ~5-10s).
server: {
port: 6666, // Vite listens here (no root needed)
hmr: {
protocol: 'wss',
host: 'changethistoyourwebsite.com',
// REMOVE THIS: port: 443,
clientPort: 443, // Browser connects here through nginx
},
allowedHosts: ['changethistoyourwebsite.com'],
headers: {
'Cross-Origin-Opener-Policy': 'same-origin',
'Cross-Origin-Embedder-Policy': 'require-corp',
},
},
preview: {
headers: {
'Cross-Origin-Opener-Policy': 'same-origin',
'Cross-Origin-Embedder-Policy': 'require-corp',
},
},
assetsInclude: ['**/*.wasm'],
optimizeDeps: {
include: ['dayjs', 'dayjs/plugin/relativeTime', 'dayjs/locale/en'],
},
})
Add it to nginx:
#cat /etc/nginx/sites-available/mywebsite
server {
# listen 80;
server_name mywebsite;
location / {
proxy_pass http://localhost:6666;
# Or serve static files: root /path/to/your/static/files;
# Add other directives as needed.
proxy_http_version 1.1;
# WebSocket support
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/mywebsite/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/mywebsite/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = mywebsite) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
server_name mywebsite;
return 404; # managed by Certbot
access_log /var/log/nginx/xapiaccess.log;
}
Replace mywebsite with my domain and grab a free tls(https) certificate with certbot:
https://certbot.eff.org/instructions
Run with IPFS:
Note: Most ipfs gateways block wasm via the http headers which is a problem for all WASM sites being served over IPFS.
Build project:
npm run build
ipfs add -r dist/