- macOS plugin: Swift bridge + universal xcframework (arm64 + x86_64) - macOS podspec with direct force_load (no script phase needed — single slice) - Make TailscaleStart() idempotent — return success if already started - Document macOS entitlements (network.client + network.server) - Build script: ./build_go.sh [ios|macos|all] Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
83 lines
2.4 KiB
Markdown
83 lines
2.4 KiB
Markdown
# tsnet_flutter
|
|
|
|
Embed [Tailscale's tsnet](https://pkg.go.dev/tailscale.com/tsnet) in Flutter apps. Provides a userspace WireGuard tunnel with a localhost TCP proxy — **no VPN entitlement needed** on iOS.
|
|
|
|
## How it works
|
|
|
|
```
|
|
Flutter (Dart) → MethodChannel → Swift Plugin → Go static library (tsnet)
|
|
↓
|
|
WireGuard tunnel (userspace)
|
|
↓
|
|
Remote device (100.x.x.x)
|
|
```
|
|
|
|
The Go layer runs a local TCP proxy: your app connects to `localhost:PORT`, and traffic is forwarded through a WireGuard tunnel to the target device's Tailscale IP. Flutter doesn't know about Tailscale — it just sees a localhost port.
|
|
|
|
## Usage
|
|
|
|
```dart
|
|
import 'package:tsnet_flutter/tsnet_flutter.dart';
|
|
|
|
final tsnet = TsnetFlutter();
|
|
|
|
// Join the Tailnet
|
|
await tsnet.start(authKey: 'tskey-auth-...');
|
|
|
|
// Create a local proxy to the remote device
|
|
final localPort = await tsnet.startProxy('100.64.0.5', port: 5050);
|
|
|
|
// Connect your client to the proxy
|
|
yourClient.connect('127.0.0.1', port: localPort);
|
|
|
|
// Clean up
|
|
await tsnet.stopProxy();
|
|
await tsnet.stop();
|
|
```
|
|
|
|
## Platform support
|
|
|
|
| Platform | Status | Min version |
|
|
|----------|--------|-------------|
|
|
| iOS | Supported (arm64 device + simulator) | 14.0 |
|
|
| macOS | Supported (arm64 + x86_64 universal) | 12.0 |
|
|
| Android | Planned | — |
|
|
|
|
## Platform setup
|
|
|
|
### iOS
|
|
|
|
No special entitlements or permissions needed. No VPN entitlement required.
|
|
|
|
### macOS
|
|
|
|
macOS apps run sandboxed. Add these entitlements to both `DebugProfile.entitlements` and `Release.entitlements`:
|
|
|
|
```xml
|
|
<key>com.apple.security.network.client</key>
|
|
<true/>
|
|
<key>com.apple.security.network.server</key>
|
|
<true/>
|
|
```
|
|
|
|
`network.client` allows the app to connect to the localhost proxy and external networks. `network.server` allows the Go layer to open a localhost listener for the proxy.
|
|
|
|
## Requirements
|
|
|
|
- Tailscale auth key (generate at [login.tailscale.com](https://login.tailscale.com/admin/settings/keys))
|
|
|
|
## Building from source
|
|
|
|
The pre-built xcframeworks are included in the package. To rebuild from Go source:
|
|
|
|
```bash
|
|
# Prerequisites: Go 1.23+, Xcode with iOS + macOS SDKs
|
|
./build_go.sh # build all platforms
|
|
./build_go.sh ios # iOS only
|
|
./build_go.sh macos # macOS only
|
|
```
|
|
|
|
## License
|
|
|
|
BSD-3-Clause. See [LICENSE](LICENSE).
|