Go to file
Mathias Beaulieu-Duncan cefcd23cd2 Update CI pipeline to use refresh token for pub.dev auth
Uses PUB_DEV_REFRESH_TOKEN secret to authenticate with pub.dev.
The refresh token is long-lived and auto-renews the access token.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 06:28:12 -04:00
.gitea/workflows Update CI pipeline to use refresh token for pub.dev auth 2026-03-14 06:28:12 -04:00
ios Prepare for pub.dev publishing with Gitea release pipeline 2026-03-14 06:13:35 -04:00
lib Rename package to tsnet_flutter for pub.dev publishing under Svrnty 2026-03-14 06:10:34 -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 Initial commit: embedded Tailscale tsnet Flutter plugin for remote heater access 2026-03-14 05:13:55 -04:00
CHANGELOG.md Prepare for pub.dev publishing with Gitea release pipeline 2026-03-14 06:13:35 -04:00
LICENSE Rename package to tsnet_flutter for pub.dev publishing under Svrnty 2026-03-14 06:10:34 -04:00
pubspec.lock Initial commit: embedded Tailscale tsnet Flutter plugin for remote heater access 2026-03-14 05:13:55 -04:00
pubspec.yaml Rename package to tsnet_flutter for pub.dev publishing under Svrnty 2026-03-14 06:10:34 -04:00
README.md Prepare for pub.dev publishing with Gitea release pipeline 2026-03-14 06:13:35 -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
iOS Supported (arm64 device + simulator)
Android Planned

Requirements

Building from source

The pre-built xcframework is included in the package. To rebuild from Go source:

# Prerequisites: Go 1.23+, Xcode
./build_go.sh

License

BSD-3-Clause. See LICENSE.