Go to file
Mathias Beaulieu-Duncan f070bcdb86 Add Android and Linux platform support (local gRPC working, tsnet WIP)
- Android: Dart FFI → Go c-shared (.so) in jniLibs (arm64-v8a + x86_64)
- Linux: Dart FFI → Go c-shared (.so) via Docker cross-compilation (amd64)
- Dart API: TsnetFlutter uses MethodChannel on iOS/macOS, FFI on Android/Linux
- Add ffi package dependency for native function bindings
- Build script: ./build_go.sh [ios|macos|android|linux|apple|all]
- Android RegisterInterfaceGetter to bypass netlink CAP_NET_ADMIN restriction
- Make TailscaleStart() idempotent and add GODEBUG=netdns=go for Android

Known: Android tsnet tunnel blocked by Go stdlib net.Interfaces() netlink
call — local gRPC works, Tailscale fallback needs libtailscale integration.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 07:49:11 -04:00
.gitea/workflows Update CI pipeline to use refresh token for pub.dev auth 2026-03-14 06:28:12 -04:00
android Add Android and Linux platform support (local gRPC working, tsnet WIP) 2026-03-14 07:49:11 -04:00
ios Add Android and Linux platform support (local gRPC working, tsnet WIP) 2026-03-14 07:49:11 -04:00
lib Add Android and Linux platform support (local gRPC working, tsnet WIP) 2026-03-14 07:49:11 -04:00
linux Add Android and Linux platform support (local gRPC working, tsnet WIP) 2026-03-14 07:49:11 -04:00
macos Add macOS support, idempotent start(), bump to 0.2.0 2026-03-14 07:11:01 -04:00
test Initial commit: embedded Tailscale tsnet Flutter plugin for remote heater access 2026-03-14 05:13:55 -04:00
.gitignore Initial commit: embedded Tailscale tsnet Flutter plugin for remote heater access 2026-03-14 05:13:55 -04:00
.pubignore Prepare for pub.dev publishing with Gitea release pipeline 2026-03-14 06:13:35 -04:00
build_go.sh Add Android and Linux platform support (local gRPC working, tsnet WIP) 2026-03-14 07:49:11 -04:00
CHANGELOG.md Add macOS support, idempotent start(), bump to 0.2.0 2026-03-14 07:11:01 -04:00
LICENSE Rename package to tsnet_flutter for pub.dev publishing under Svrnty 2026-03-14 06:10:34 -04:00
pubspec.lock Add Android and Linux platform support (local gRPC working, tsnet WIP) 2026-03-14 07:49:11 -04:00
pubspec.yaml Add Android and Linux platform support (local gRPC working, tsnet WIP) 2026-03-14 07:49:11 -04:00
README.md Add macOS support, idempotent start(), bump to 0.2.0 2026-03-14 07:11:01 -04:00

tsnet_flutter

Embed Tailscale's 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

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:

<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

Building from source

The pre-built xcframeworks are included in the package. To rebuild from Go source:

# 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.