2026-02-27 10:18:23 +00:00
# @push.rocks/smartvpn
2026-03-29 17:04:27 +00:00
A high-performance VPN solution with a **TypeScript control plane ** and a **Rust data plane daemon ** . Enterprise-ready client authentication, triple transport support (WebSocket + QUIC + WireGuard), and a typed hub API for managing clients from code.
2026-02-27 10:18:23 +00:00
2026-03-29 17:04:27 +00:00
🔐 **Noise IK ** mutual authentication — per-client X25519 keypairs, server-side registry
2026-03-29 15:25:22 +00:00
🚀 **Triple transport ** : WebSocket (Cloudflare-friendly), raw **QUIC ** (datagrams), and **WireGuard ** (standard protocol)
2026-03-29 17:04:27 +00:00
🛡️ **ACL engine ** — deny-overrides-allow IP filtering, aligned with SmartProxy conventions
2026-03-29 17:40:55 +00:00
🔀 **PROXY protocol v2 ** — real client IPs behind reverse proxies (HAProxy, SmartProxy, Cloudflare Spectrum)
2026-03-29 17:04:27 +00:00
📊 **Adaptive QoS ** : per-client rate limiting, priority queues, connection quality tracking
🔄 **Hub API ** : one `createClient()` call generates keys, assigns IP, returns both SmartVPN + WireGuard configs
📡 **Real-time telemetry ** : RTT, jitter, loss ratio, link health — all via typed APIs
2026-03-30 06:52:20 +00:00
🌐 **Unified forwarding pipeline ** : all transports share the same engine — TUN (kernel), userspace NAT (no root), or testing mode
2026-03-19 21:53:30 +00:00
2026-02-27 10:18:23 +00:00
## Issue Reporting and Security
For reporting bugs, issues, or security vulnerabilities, please visit [community.foss.global/ ](https://community.foss.global/ ). This is the central community hub for all issue reporting. Developers who sign and comply with our contribution agreement and go through identification can also get a [code.foss.global/ ](https://code.foss.global/ ) account to submit Pull Requests directly.
2026-03-29 17:04:27 +00:00
## Install 📦
2026-02-27 10:18:23 +00:00
```bash
pnpm install @push .rocks/smartvpn
2026-03-29 17:04:27 +00:00
# or
npm install @push .rocks/smartvpn
2026-02-27 10:18:23 +00:00
```
2026-03-29 17:04:27 +00:00
The package ships with pre-compiled Rust binaries for **linux/amd64 ** and **linux/arm64 ** . No Rust toolchain required at runtime.
## Architecture 🏗️
2026-02-27 10:18:23 +00:00
```
2026-03-29 17:04:27 +00:00
┌──────────────────────────────┐ JSON-lines IPC ┌───────────────────────────────┐
│ TypeScript Control Plane │ ◄─────────────────────► │ Rust Data Plane Daemon │
│ │ stdio or Unix sock │ │
│ VpnServer / VpnClient │ │ Noise IK handshake │
│ Typed IPC commands │ │ XChaCha20-Poly1305 │
│ Config validation │ │ WS + QUIC + WireGuard │
│ Hub: client management │ │ TUN device, IP pool, NAT │
│ WireGuard .conf generation │ │ Rate limiting, ACLs, QoS │
└──────────────────────────────┘ └───────────────────────────────┘
2026-02-27 10:18:23 +00:00
```
2026-03-29 17:04:27 +00:00
**Split-plane design** — TypeScript handles orchestration, config, and DX; Rust handles every hot-path byte with zero-copy async I/O (tokio, mimalloc).
2026-02-27 10:18:23 +00:00
2026-03-29 17:04:27 +00:00
## Quick Start 🚀
2026-02-27 10:18:23 +00:00
2026-03-29 17:04:27 +00:00
### 1. Start a VPN Server (Hub)
2026-02-27 10:18:23 +00:00
```typescript
2026-03-29 17:04:27 +00:00
import { VpnServer } from '@push .rocks/smartvpn';
2026-02-27 10:18:23 +00:00
2026-03-29 17:04:27 +00:00
const server = new VpnServer({ transport: { transport: 'stdio' } });
await server.start({
listenAddr: '0.0.0.0:443',
privateKey: '<server-noise-private-key-base64>',
publicKey: '<server-noise-public-key-base64>',
subnet: '10.8.0.0/24',
2026-03-30 06:52:20 +00:00
transportMode: 'all', // WebSocket + QUIC + WireGuard simultaneously (default)
2026-03-29 23:41:31 +00:00
forwardingMode: 'tun', // 'tun' (kernel), 'socket' (userspace NAT), or 'testing'
2026-03-30 06:52:20 +00:00
wgPrivateKey: '<server-wg-private-key-base64>', // required for WireGuard transport
2026-03-29 17:04:27 +00:00
enableNat: true,
2026-02-27 10:18:23 +00:00
dns: ['1.1.1.1', '8.8.8.8'],
});
```
2026-03-29 17:04:27 +00:00
### 2. Create a Client (One Call = Everything)
2026-03-19 21:53:30 +00:00
```typescript
2026-03-29 17:04:27 +00:00
const bundle = await server.createClient({
clientId: 'alice-laptop',
tags: ['engineering'],
security: {
destinationAllowList: ['10.0.0.0/8'], // can only reach internal network
destinationBlockList: ['10.0.0.99'], // except this host
rateLimit: { bytesPerSec: 10_000_000, burstBytes: 20_000_000 },
},
2026-03-19 21:53:30 +00:00
});
2026-03-29 17:04:27 +00:00
// bundle.smartvpnConfig → typed IVpnClientConfig, ready to use
// bundle.wireguardConfig → standard WireGuard .conf string
// bundle.secrets → { noisePrivateKey, wgPrivateKey } — shown ONCE
2026-03-19 21:53:30 +00:00
```
2026-03-29 17:04:27 +00:00
### 3. Connect a Client
2026-03-29 15:25:22 +00:00
```typescript
import { VpnClient } from '@push .rocks/smartvpn';
2026-03-29 17:04:27 +00:00
const client = new VpnClient({ transport: { transport: 'stdio' } });
await client.start();
2026-03-29 15:25:22 +00:00
2026-03-29 17:04:27 +00:00
const { assignedIp } = await client.connect(bundle.smartvpnConfig);
console.log(`Connected! VPN IP: ${assignedIp}` );
2026-03-29 15:25:22 +00:00
```
2026-03-29 17:04:27 +00:00
## Features ✨
2026-02-27 10:18:23 +00:00
2026-03-29 17:04:27 +00:00
### 🔐 Enterprise Authentication (Noise IK)
2026-02-27 10:18:23 +00:00
2026-03-29 17:04:27 +00:00
Every client authenticates with a **Noise IK handshake ** (`Noise_IK_25519_ChaChaPoly_BLAKE2s` ). The server verifies the client's static public key against its registry — unauthorized clients are rejected before any data flows.
2026-02-27 10:18:23 +00:00
2026-03-29 17:04:27 +00:00
- Per-client X25519 keypair generated server-side
- Client registry with enable/disable, expiry, tags
- Key rotation with `rotateClientKey()` — generates new keys, returns fresh config bundle, disconnects old session
2026-03-15 18:16:15 +00:00
2026-03-29 17:04:27 +00:00
### 🌐 Triple Transport
2026-02-27 10:18:23 +00:00
2026-03-29 17:04:27 +00:00
| Transport | Protocol | Best For |
|-----------|----------|----------|
| **WebSocket ** | TLS over TCP | Firewall-friendly, Cloudflare compatible |
| **QUIC ** | UDP (via quinn) | Low latency, datagram support for IP packets |
| **WireGuard ** | UDP (via boringtun) | Standard WG clients (iOS, Android, wg-quick) |
2026-02-27 10:18:23 +00:00
2026-03-30 06:52:20 +00:00
The server runs **all three simultaneously ** by default with `transportMode: 'all'` . All transports share the same unified forwarding pipeline (`ForwardingEngine` ), IP pool, client registry, and stats — so WireGuard peers get the same userspace NAT, rate limiting, and monitoring as WS/QUIC clients. Clients auto-negotiate with `transport: 'auto'` (tries QUIC first, falls back to WS).
2026-03-15 18:16:15 +00:00
2026-03-29 17:04:27 +00:00
### 🛡️ ACL Engine (SmartProxy-Aligned)
2026-02-27 10:18:23 +00:00
2026-03-29 17:04:27 +00:00
Security policies per client, using the same `ipAllowList` / `ipBlockList` naming convention as `@push.rocks/smartproxy` :
2026-02-27 10:18:23 +00:00
2026-03-29 17:04:27 +00:00
```typescript
security: {
ipAllowList: ['192.168.1.0/24'], // source IPs allowed to connect
ipBlockList: ['192.168.1.100'], // deny overrides allow
destinationAllowList: ['10.0.0.0/8'], // VPN destinations permitted
destinationBlockList: ['10.0.0.99'], // deny overrides allow
maxConnections: 5,
rateLimit: { bytesPerSec: 1_000_000, burstBytes: 2_000_000 },
}
2026-02-27 10:18:23 +00:00
```
2026-03-29 17:04:27 +00:00
Supports exact IPs, CIDR, wildcards (`192.168.1.*` ), and ranges (`1.1.1.1-1.1.1.100` ).
2026-03-29 15:25:22 +00:00
2026-03-29 17:40:55 +00:00
### 🔀 PROXY Protocol v2
When the VPN server sits behind a reverse proxy, enable PROXY protocol v2 to receive the **real client IP ** instead of the proxy's address. This makes `ipAllowList` / `ipBlockList` ACLs work correctly through load balancers.
```typescript
await server.start({
// ... other config ...
proxyProtocol: true, // parse PP v2 headers on WS connections
connectionIpBlockList: ['198.51.100.0/24'], // server-wide block list (pre-handshake)
});
```
**Two-phase ACL with real IPs:**
| Phase | When | What Happens |
|-------|------|-------------|
| **Pre-handshake ** | After TCP accept | Server-level `connectionIpBlockList` rejects known-bad IPs — zero crypto cost |
| **Post-handshake ** | After Noise IK identifies client | Per-client `ipAllowList` / `ipBlockList` checked against real source IP |
- Parses the PP v2 binary header from raw TCP before WebSocket upgrade
- 5-second timeout protects against stalling attacks
- LOCAL command (proxy health checks) handled gracefully
- IPv4 and IPv6 addresses supported
- `remoteAddr` field on `IVpnClientInfo` exposes the real client IP for monitoring
- **Security**: must be `false` (default) when accepting direct connections — only enable behind a trusted proxy
2026-03-29 23:41:31 +00:00
### 📦 Packet Forwarding Modes
SmartVPN supports three forwarding modes, configurable per-server and per-client:
| Mode | Flag | Description | Root Required |
|------|------|-------------|---------------|
| **TUN ** | `'tun'` | Kernel TUN device — real packet forwarding with system routing | ✅ Yes |
| **Userspace NAT ** | `'socket'` | Userspace TCP/UDP proxy via `connect(2)` — no TUN, no root needed | ❌ No |
| **Testing ** | `'testing'` | Monitoring only — packets are counted but not forwarded | ❌ No |
```typescript
// Server with userspace NAT (no root required)
await server.start({
// ...
forwardingMode: 'socket',
enableNat: true,
});
// Client with TUN device
const { assignedIp } = await client.connect({
// ...
forwardingMode: 'tun',
});
```
The userspace NAT mode extracts destination IP/port from IP packets, opens a real socket to the destination, and relays data — supporting both TCP streams and UDP datagrams without requiring `CAP_NET_ADMIN` or root privileges.
2026-03-29 17:04:27 +00:00
### 📊 Telemetry & QoS
2026-03-29 15:25:22 +00:00
2026-03-29 17:04:27 +00:00
- **Connection quality**: Smoothed RTT, jitter, min/max RTT, loss ratio, link health (`healthy` / `degraded` / `critical` )
- **Adaptive keepalives**: Interval adjusts based on link health (60s → 30s → 10s)
- **Per-client rate limiting**: Token bucket with configurable bytes/sec and burst
- **Dead-peer detection**: 180s inactivity timeout
- **MTU management**: Automatic overhead calculation (IP+TCP+WS+Noise = 79 bytes)
2026-03-29 15:25:22 +00:00
2026-03-29 17:04:27 +00:00
### 🔄 Hub Client Management
2026-03-29 15:25:22 +00:00
2026-03-29 17:04:27 +00:00
The server acts as a **hub ** — one API to manage all clients:
```typescript
// Create (generates keys, assigns IP, returns config bundle)
const bundle = await server.createClient({ clientId: 'bob-phone' });
// Read
const entry = await server.getClient('bob-phone');
const all = await server.listRegisteredClients();
2026-03-29 15:25:22 +00:00
2026-03-29 17:04:27 +00:00
// Update (ACLs, tags, description, rate limits...)
await server.updateClient('bob-phone', {
security: { destinationAllowList: ['0.0.0.0/0'] },
tags: ['mobile', 'field-ops'],
2026-03-29 15:25:22 +00:00
});
2026-03-29 17:04:27 +00:00
// Enable / Disable
await server.disableClient('bob-phone'); // disconnects + blocks reconnection
await server.enableClient('bob-phone');
// Key rotation
const newBundle = await server.rotateClientKey('bob-phone');
2026-03-29 15:25:22 +00:00
2026-03-29 17:04:27 +00:00
// Export config (without secrets)
const wgConf = await server.exportClientConfig('bob-phone', 'wireguard');
2026-03-29 15:25:22 +00:00
2026-03-29 17:04:27 +00:00
// Remove
await server.removeClient('bob-phone');
2026-03-29 15:25:22 +00:00
```
2026-03-29 17:04:27 +00:00
### 📝 WireGuard Config Generation
2026-03-29 15:25:22 +00:00
2026-03-29 17:04:27 +00:00
Generate standard `.conf` files for any WireGuard client:
2026-03-29 15:25:22 +00:00
```typescript
import { WgConfigGenerator } from '@push .rocks/smartvpn';
2026-03-29 17:04:27 +00:00
const conf = WgConfigGenerator.generateClientConfig({
privateKey: '<client-wg-private-key>',
2026-03-29 15:25:22 +00:00
address: '10.8.0.2/24',
2026-03-29 17:04:27 +00:00
dns: ['1.1.1.1'],
2026-03-29 15:25:22 +00:00
peer: {
2026-03-29 17:04:27 +00:00
publicKey: '<server-wg-public-key>',
2026-03-29 15:25:22 +00:00
endpoint: 'vpn.example.com:51820',
2026-03-29 17:04:27 +00:00
allowedIps: ['0.0.0.0/0'],
2026-03-29 15:25:22 +00:00
persistentKeepalive: 25,
},
});
2026-03-29 17:04:27 +00:00
// → standard WireGuard .conf compatible with wg-quick, iOS, Android
2026-03-29 15:25:22 +00:00
```
2026-03-29 17:04:27 +00:00
### 🖥️ System Service Installation
2026-02-27 10:18:23 +00:00
```typescript
import { VpnInstaller } from '@push .rocks/smartvpn';
2026-03-29 17:04:27 +00:00
const unit = VpnInstaller.generateServiceUnit({
2026-02-27 10:18:23 +00:00
mode: 'server',
2026-03-29 17:04:27 +00:00
configPath: '/etc/smartvpn/server.json',
2026-02-27 10:18:23 +00:00
});
2026-03-29 17:04:27 +00:00
// unit.platform → 'linux' | 'macos'
// unit.content → systemd unit file or launchd plist
// unit.installPath → /etc/systemd/system/smartvpn-server.service
2026-03-19 21:53:30 +00:00
```
2026-03-29 17:04:27 +00:00
## API Reference 📖
### Classes
| Class | Description |
|-------|-------------|
| `VpnServer` | Manages the Rust daemon in server mode. Hub methods for client CRUD. |
| `VpnClient` | Manages the Rust daemon in client mode. Connect, disconnect, telemetry. |
| `VpnBridge<T>` | Low-level typed IPC bridge (stdio or Unix socket). |
| `VpnConfig` | Static config validation and file I/O. |
| `VpnInstaller` | Generates systemd/launchd service files. |
| `WgConfigGenerator` | Generates standard WireGuard `.conf` files. |
### Key Interfaces
| Interface | Purpose |
|-----------|---------|
2026-03-29 23:41:31 +00:00
| `IVpnServerConfig` | Server configuration (listen addr, keys, subnet, transport mode, forwarding mode, clients, proxy protocol) |
| `IVpnClientConfig` | Client configuration (server URL, keys, transport, forwarding mode, WG options) |
2026-03-29 17:04:27 +00:00
| `IClientEntry` | Server-side client definition (ID, keys, security, priority, tags, expiry) |
| `IClientSecurity` | Per-client ACLs and rate limits (SmartProxy-aligned naming) |
| `IClientRateLimit` | Rate limiting config (bytesPerSec, burstBytes) |
| `IClientConfigBundle` | Full config bundle returned by `createClient()` |
2026-03-29 17:40:55 +00:00
| `IVpnClientInfo` | Connected client info (IP, stats, authenticated key, remote addr) |
2026-03-29 17:04:27 +00:00
| `IVpnConnectionQuality` | RTT, jitter, loss ratio, link health |
| `IVpnKeypair` | Base64-encoded public/private key pair |
### Server IPC Commands
| Command | Description |
|---------|-------------|
| `start` / `stop` | Start/stop the VPN listener |
| `createClient` | Generate keys, assign IP, return config bundle |
| `removeClient` / `getClient` / `listRegisteredClients` | Client registry CRUD |
| `updateClient` / `enableClient` / `disableClient` | Modify client state |
| `rotateClientKey` | Fresh keypairs + new config bundle |
| `exportClientConfig` | Re-export as SmartVPN config or WireGuard `.conf` |
| `listClients` / `disconnectClient` | Manage live connections |
| `setClientRateLimit` / `removeClientRateLimit` | Runtime rate limit adjustments |
| `getStatus` / `getStatistics` / `getClientTelemetry` | Monitoring |
| `generateKeypair` / `generateWgKeypair` / `generateClientKeypair` | Key generation |
| `addWgPeer` / `removeWgPeer` / `listWgPeers` | WireGuard peer management |
### Client IPC Commands
| Command | Description |
|---------|-------------|
| `connect` / `disconnect` | Manage the tunnel |
| `getStatus` / `getStatistics` | Connection state and traffic stats |
| `getConnectionQuality` | RTT, jitter, loss, link health |
| `getMtuInfo` | MTU and overhead details |
## Transport Modes 🔀
### Server Configuration
2026-03-19 21:53:30 +00:00
```typescript
2026-03-30 06:52:20 +00:00
// All transports simultaneously (default) — WS + QUIC + WireGuard
{ transportMode: 'all', listenAddr: '0.0.0.0:443', wgPrivateKey: '...', wgListenPort: 51820 }
// WS + QUIC only (backward compat)
{ transportMode: 'both', listenAddr: '0.0.0.0:443', quicListenAddr: '0.0.0.0:4433' }
2026-03-29 17:04:27 +00:00
// WebSocket only
{ transportMode: 'websocket', listenAddr: '0.0.0.0:443' }
2026-03-19 21:53:30 +00:00
2026-03-29 17:04:27 +00:00
// QUIC only
{ transportMode: 'quic', listenAddr: '0.0.0.0:443' }
2026-03-19 21:53:30 +00:00
2026-03-30 06:52:20 +00:00
// WireGuard only
{ transportMode: 'wireguard', wgPrivateKey: '...', wgListenPort: 51820, wgPeers: [...] }
2026-03-15 18:16:15 +00:00
```
2026-03-30 06:52:20 +00:00
All transport modes share the same `forwardingMode` — WireGuard peers can use `'socket'` (userspace NAT) just like WS/QUIC clients.
2026-03-29 17:04:27 +00:00
### Client Configuration
2026-03-19 21:53:30 +00:00
```typescript
2026-03-29 17:04:27 +00:00
// Auto (tries QUIC first, falls back to WS)
{ transport: 'auto', serverUrl: 'wss://vpn.example.com' }
2026-02-27 10:18:23 +00:00
2026-03-29 17:04:27 +00:00
// Explicit QUIC with certificate pinning
{ transport: 'quic', serverUrl: '1.2.3.4:4433', serverCertHash: '<sha256-base64>' }
2026-02-27 10:18:23 +00:00
2026-03-29 17:04:27 +00:00
// WireGuard
{ transport: 'wireguard', wgPrivateKey: '...', wgEndpoint: 'vpn.example.com:51820', ... }
2026-02-27 10:18:23 +00:00
```
2026-03-29 17:04:27 +00:00
## Cryptography 🔑
2026-02-27 10:18:23 +00:00
2026-03-29 17:04:27 +00:00
| Layer | Algorithm | Purpose |
|-------|-----------|---------|
| **Handshake ** | Noise IK (X25519 + ChaChaPoly + BLAKE2s) | Mutual authentication + key exchange |
| **Transport ** | Noise transport state (ChaChaPoly) | All post-handshake data encryption |
| **Additional ** | XChaCha20-Poly1305 | Extended nonce space for data-at-rest |
| **WireGuard ** | X25519 + ChaCha20-Poly1305 (via boringtun) | Standard WireGuard crypto |
2026-03-19 21:53:30 +00:00
2026-03-29 17:04:27 +00:00
## Binary Protocol 📡
2026-03-29 15:25:22 +00:00
2026-03-29 17:04:27 +00:00
All frames use `[type:1B][length:4B][payload:NB]` with a 64KB max payload:
2026-02-27 10:18:23 +00:00
2026-03-29 17:04:27 +00:00
| Type | Hex | Direction | Description |
|------|-----|-----------|-------------|
| HandshakeInit | `0x01` | Client → Server | Noise IK first message |
| HandshakeResp | `0x02` | Server → Client | Noise IK response |
| IpPacket | `0x10` | Bidirectional | Encrypted tunnel data |
| Keepalive | `0x20` | Client → Server | App-level keepalive (not WS ping) |
| KeepaliveAck | `0x21` | Server → Client | Keepalive response with RTT payload |
| Disconnect | `0x3F` | Bidirectional | Graceful disconnect |
2026-02-27 10:18:23 +00:00
2026-03-29 17:04:27 +00:00
## Development 🛠️
2026-02-27 10:18:23 +00:00
```bash
# Install dependencies
pnpm install
2026-03-29 17:04:27 +00:00
# Build (TypeScript + Rust cross-compile)
2026-02-27 10:18:23 +00:00
pnpm build
2026-03-29 23:41:31 +00:00
# Run all tests (79 TS + 132 Rust = 211 tests)
2026-02-27 10:18:23 +00:00
pnpm test
2026-03-29 17:04:27 +00:00
# Run Rust tests directly
cd rust && cargo test
2026-03-15 18:16:15 +00:00
2026-03-29 17:04:27 +00:00
# Run a specific TS test
tstest test/test.flowcontrol.node.ts --verbose
```
2026-03-15 18:16:15 +00:00
2026-03-29 17:04:27 +00:00
### Project Structure
2026-02-27 10:18:23 +00:00
```
2026-03-29 17:04:27 +00:00
smartvpn/
├── ts/ # TypeScript control plane
│ ├── index.ts # All exports
│ ├── smartvpn.interfaces.ts # Interfaces, types, IPC command maps
│ ├── smartvpn.classes.vpnserver.ts
│ ├── smartvpn.classes.vpnclient.ts
│ ├── smartvpn.classes.vpnbridge.ts
│ ├── smartvpn.classes.vpnconfig.ts
│ ├── smartvpn.classes.vpninstaller.ts
│ └── smartvpn.classes.wgconfig.ts
├── rust/ # Rust data plane daemon
│ └── src/
│ ├── main.rs # CLI entry point
│ ├── server.rs # VPN server + hub methods
│ ├── client.rs # VPN client
│ ├── crypto.rs # Noise IK + XChaCha20
│ ├── client_registry.rs # Client database
│ ├── acl.rs # ACL engine
2026-03-29 17:40:55 +00:00
│ ├── proxy_protocol.rs # PROXY protocol v2 parser
2026-03-29 17:04:27 +00:00
│ ├── management.rs # JSON-lines IPC
│ ├── transport.rs # WebSocket transport
│ ├── quic_transport.rs # QUIC transport
│ ├── wireguard.rs # WireGuard (boringtun)
│ ├── codec.rs # Binary frame protocol
│ ├── keepalive.rs # Adaptive keepalives
│ ├── ratelimit.rs # Token bucket
2026-03-29 23:41:31 +00:00
│ ├── userspace_nat.rs # Userspace TCP/UDP NAT proxy
2026-03-29 17:04:27 +00:00
│ └── ... # tunnel, network, telemetry, qos, mtu, reconnect
├── test/ # 9 test files (79 tests)
├── dist_ts/ # Compiled TypeScript
└── dist_rust/ # Cross-compiled binaries (linux amd64 + arm64)
```
2026-02-27 10:18:23 +00:00
## License and Legal Information
2026-03-30 06:52:20 +00:00
This repository contains open-source code licensed under the MIT License. A copy of the license can be found in the [license ](./license.md ) file.
2026-02-27 10:18:23 +00:00
**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.
### Trademarks
This project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH or third parties, and are not included within the scope of the MIT license granted herein.
Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines or the guidelines of the respective third-party owners, and any usage must be approved in writing. Third-party trademarks used herein are the property of their respective owners and used only in a descriptive manner, e.g. for an implementation of an API or similar.
### Company Information
2026-03-29 17:04:27 +00:00
Task Venture Capital GmbH
2026-02-27 10:18:23 +00:00
Registered at District Court Bremen HRB 35230 HB, Germany
For any legal inquiries or further information, please contact us via email at hello@task .vc.
By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.