Code Generation
Introduction
Official SDKs are available for Go. For Python, JavaScript/TypeScript, C#, Rust, Java, and other gRPC-capable languages, you can use protobuf code generation to build a VeilNet client that starts and controls the Anchor subprocess via gRPC. This guide walks you through generating client code and using it in your application.
Overview
VeilNet Conflux runs as a subprocess (the Anchor binary) that your application manages. Your app:
- Downloads the platform-specific Anchor binary from the conflux repository.
- Starts the binary as a subprocess.
- Connects to its gRPC server (typically on a local Unix socket or TCP port).
- Sends
StartAnchorwith your registration token so the Anchor joins the VeilNet overlay. - Manages taints and lifecycle with
AddTaint,RemoveTaint,StopAnchor, and related RPCs.
Note: The proto definitions and Anchor service are the same ones used by the Go SDK. Code generation gives you the same capabilities in any language that supports gRPC.
Prerequisites
- Registration token from VeilNet management console or the Guardian API.
- Proto file: veilnet.proto from the veil-net/conflux repository.
- Anchor binary for your platform (see Anchor binaries).
Anchor Binaries
Download the appropriate binary for your OS and architecture from conflux/anchor/bin:
| Platform | Architecture | Binary |
|---|---|---|
| Linux | AMD64 | anchor-linux-amd64 |
| Linux | ARM64 | anchor-linux-arm64 |
| macOS | AMD64 | anchor-darwin-amd64 |
| macOS | ARM64 (Apple Silicon) | anchor-darwin-arm64 |
| Windows | AMD64 | anchor-windows-amd64.exe |
After downloading, make the binary executable (Linux/macOS) and run it. The Anchor typically listens on a gRPC endpoint (port or Unix socket) that your application connects to.
Warning: The Anchor binary needs network administrator privileges to create a virtual network interface (TUN). On Linux, run with
sudoor equivalent.
Proto Definitions
The proto file defines the Anchor gRPC service and all message types. Key definitions:
Anchor gRPC Service
service Anchor {
rpc StartAnchor(StartAnchorRequest) returns (google.protobuf.Empty);
rpc StartAnchorWithFD(StartAnchorWithFDRequest) returns (google.protobuf.Empty);
rpc StopAnchor(google.protobuf.Empty) returns (google.protobuf.Empty);
rpc AddTaint(AddTaintRequest) returns (google.protobuf.Empty);
rpc RemoveTaint(RemoveTaintRequest) returns (google.protobuf.Empty);
rpc GetInfo(google.protobuf.Empty) returns (GetInfoResponse);
rpc GetRealmInfo(google.protobuf.Empty) returns (GetRealmInfoResponse);
rpc GetVeilInfo(google.protobuf.Empty) returns (GetVeilInfoResponse);
rpc GetTracerConfig(google.protobuf.Empty) returns (TracerConfig);
}
Main Request/Response Messages
| Message | Purpose |
|---|---|
StartAnchorRequest | Start the Anchor with guardian_url, anchor_token, optional ip, rift, portal, tracer |
AddTaintRequest | Add a taint label (e.g. web, api) for access control |
RemoveTaintRequest | Remove a taint label |
GetInfoResponse | Node id, tag, uid, cidr, rift, portal, public |
GetRealmInfoResponse | realm, realm_id, subnet |
GetVeilInfoResponse | veil_host, veil_port, region |
For the full proto schema, see veilnet.proto in the conflux repository.
Python
Step 1: Generate gRPC Client Code
Install the protobuf compiler and gRPC tools:
pip install grpcio grpcio-tools
Download the proto file and generate Python code:
curl -o veilnet.proto https://raw.githubusercontent.com/veil-net/conflux/main/veilnet.proto
python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. veilnet.proto
This creates veilnet_pb2.py (messages) and veilnet_pb2_grpc.py (service stubs). You will need google.protobuf; install it if needed:
pip install protobuf
Note: The proto imports
google/protobuf/empty.proto. Ensure the protoc-Ipath includes the standard protobuf includes (e.g. viapip install protobufand using the correct include path for your environment).
If grpc_tools.protoc cannot find google/protobuf/empty.proto, install the protobuf package and add its include path:
pip install protobuf
python -m grpc_tools.protoc -I. -I$(python -c "import google.protobuf; print(google.protobuf.__path__[0])") --python_out=. --grpc_python_out=. veilnet.proto
Step 2: Download and Start the Anchor Binary
import subprocess
import platform
import sys
def get_anchor_binary():
"""Return the Anchor binary filename for current platform."""
system = platform.system().lower()
machine = platform.machine().lower()
if system == 'darwin':
arch = 'arm64' if machine in ('arm64', 'aarch64') else 'amd64'
return f'anchor-darwin-{arch}'
if system == 'linux':
arch = 'arm64' if machine in ('arm64', 'aarch64') else 'amd64'
return f'anchor-linux-{arch}'
if system == 'windows':
return 'anchor-windows-amd64.exe'
raise RuntimeError(f'Unsupported platform: {system}')
def start_anchor_process(anchor_path, args=None):
"""Start the Anchor binary as a subprocess."""
cmd = [anchor_path] + (args or [])
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
return proc
Step 3: Connect and Call the Anchor gRPC Service
import grpc
# Import your generated modules
# from veilnet_pb2 import StartAnchorRequest, AddTaintRequest
# from veilnet_pb2_grpc import AnchorStub
def main():
# Anchor gRPC server listens on 127.0.0.1:1993 by default
channel = grpc.insecure_channel('127.0.0.1:1993')
stub = AnchorStub(channel)
# Start the Anchor with your registration token
request = StartAnchorRequest(
guardian_url='https://guardian.veilnet.app',
anchor_token='your-registration-token',
ip='', # Optional: leave empty for auto-assign
rift=False,
portal=False,
)
stub.StartAnchor(request)
# Add taint for access control
stub.AddTaint(AddTaintRequest(taint='web'))
# Get node info
info = stub.GetInfo(Empty())
print(f'VeilNet IP: {info.cidr}')
# When done: call stub.StopAnchor(Empty()) before terminating the subprocess
Replace your-registration-token with a token from your VeilNet console or Guardian API.
JavaScript / TypeScript
Step 1: Install Dependencies
npm install @grpc/grpc-js @grpc/proto-loader
Step 2: Load Proto and Create Client
Use @grpc/proto-loader to load the proto at runtime (no separate code generation step):
const grpc = require('@grpc/grpc-js');
const protoLoader = require('@grpc/proto-loader');
const path = require('path');
const packageDefinition = protoLoader.loadSync('veilnet.proto', {
keepCase: true,
longs: String,
enums: String,
defaults: true,
oneofs: true,
});
const proto = grpc.loadPackageDefinition(packageDefinition).veilnet;
const client = new proto.Anchor('127.0.0.1:1993', grpc.credentials.createInsecure());
Step 3: Call the Anchor RPCs
// Start the Anchor
client.StartAnchor({
guardian_url: 'https://guardian.veilnet.app',
anchor_token: process.env.ANCHOR_TOKEN || 'your-registration-token',
ip: '',
rift: false,
portal: false,
}, (err, response) => {
if (err) {
console.error(err);
return;
}
console.log('Anchor started');
});
// Add taint
client.AddTaint({ taint: 'api' }, (err) => {
if (err) console.error(err);
});
// Get info
client.GetInfo({}, (err, info) => {
if (err) console.error(err);
else console.log('Node CIDR:', info.cidr);
});
With TypeScript
For better type safety, generate TypeScript definitions:
npm install -D grpc_tools_node_protoc_ts
# Or use protoc with protoc-gen-ts plugin
Alternatively, keep using @grpc/proto-loader and add manual type definitions for the loaded proto.
C# / .NET
Step 1: Create Project and Add Packages
dotnet new console -n VeilNetClient
cd VeilNetClient
dotnet add package Grpc.Net.Client
dotnet add package Google.Protobuf
dotnet add package Grpc.Tools
Step 2: Add Proto Reference
Download the proto and create a Protos folder:
mkdir -p Protos
curl -o Protos/veilnet.proto https://raw.githubusercontent.com/veil-net/conflux/main/veilnet.proto
Add the Google.Protobuf.Tools package or ensure google/protobuf/empty.proto is available. Edit your .csproj:
<ItemGroup>
<Protobuf Include="Protos\veilnet.proto" GrpcServices="Client" ProtoRoot="Protos" />
</ItemGroup>
If the build fails on import "google/protobuf/empty.proto", add the Protobuf include path (e.g. from Google.Protobuf.Tools) or create Protos/google/protobuf/empty.proto from the protobuf repository.
Step 3: Connect and Call the Anchor Service
using Grpc.Net.Client;
using Grpc.Core;
// After building, use the generated client
// var channel = GrpcChannel.ForAddress("http://127.0.0.1:1993");
// var client = new Anchor.AnchorClient(channel);
// await client.StartAnchorAsync(new StartAnchorRequest
// {
// GuardianUrl = "https://guardian.veilnet.app",
// AnchorToken = "your-registration-token",
// Ip = "",
// Rift = false,
// Portal = false,
// });
// await client.AddTaintAsync(new AddTaintRequest { Taint = "web" });
// var info = await client.GetInfoAsync(new Empty());
// Console.WriteLine($"VeilNet IP: {info.Cidr}");
// When done: await client.StopAnchorAsync(new Empty());
Rust
Step 1: Add Dependencies
Add to Cargo.toml:
[dependencies]
tonic = "0.12"
prost = "0.13"
[build-dependencies]
tonic-build = "0.12"
Step 2: Generate Client in build.rs
// build.rs
fn main() -> Result<(), Box<dyn std::error::Error>> {
tonic_build::configure()
.build_server(false)
.compile(&["veilnet.proto"], &["."])?;
Ok(())
}
Download the proto and ensure google/protobuf/empty.proto is available (e.g. from protobuf crate or prost-build includes).
Step 3: Use the Generated Client
use tonic::transport::Channel;
// let channel = Channel::from_static("http://127.0.0.1:1993").connect().await?;
// let mut client = anchor_client::AnchorClient::new(channel);
// client.start_anchor(StartAnchorRequest {
// guardian_url: "https://guardian.veilnet.app".into(),
// anchor_token: "your-registration-token".into(),
// ip: String::new(),
// rift: false,
// portal: false,
// tracer: None,
// }).await?;
// client.add_taint(AddTaintRequest { taint: "web".into() }).await?;
// let info = client.get_info(Empty {}).await?;
// println!("VeilNet IP: {}", info.into_inner().cidr);
// When done: client.stop_anchor(Empty {}).await?;
Java
Step 1: Add Maven Dependencies
<dependencies>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty-shaded</artifactId>
<version>1.60.0</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>1.60.0</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>1.60.0</version>
</dependency>
</dependencies>
<build>
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.7.1</version>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.6.1</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:3.25.1:exe:${os.detected.classifier}</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.60.0:exe:${os.detected.classifier}</pluginArtifact>
<protoSourceRoot>${project.basedir}/src/main/proto</protoSourceRoot>
</configuration>
<executions>
<execution>
<goals><goal>compile</goal></goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Step 2: Place Proto and Generate
Put veilnet.proto in src/main/proto/. Ensure google/protobuf/empty.proto is available (add protoc-gen-grpc-java include path or a google/protobuf directory).
mvn compile
Step 3: Use the Generated Client
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import io.grpc.StatusRuntimeException;
// ManagedChannel channel = ManagedChannelBuilder
// .forTarget("127.0.0.1:1993")
// .usePlaintext()
// .build();
// AnchorGrpc.AnchorBlockingStub stub = AnchorGrpc.newBlockingStub(channel);
// stub.startAnchor(StartAnchorRequest.newBuilder()
// .setGuardianUrl("https://guardian.veilnet.app")
// .setAnchorToken("your-registration-token")
// .setIp("")
// .setRift(false)
// .setPortal(false)
// .build());
// stub.addTaint(AddTaintRequest.newBuilder().setTaint("web").build());
// GetInfoResponse info = stub.getInfo(Empty.getDefaultInstance());
// System.out.println("VeilNet IP: " + info.getCidr());
// When done: stub.stopAnchor(Empty.getDefaultInstance());
Typical Workflow
- Get credentials – Registration token from console.veilnet.app or Guardian API.
- Start Anchor binary – Run the platform-specific binary; it will create the TUN interface and start the gRPC server.
- Connect and call
StartAnchor– Passguardian_url,anchor_token, and optionalip,rift,portal. - Add taints – Use
AddTaintto set labels likeweb,api,databasefor access control. - Use the VeilNet IP – Call
GetInfoto getcidr; bind your app to that address for incoming traffic, or use it as the source for outbound VeilNet traffic. - Shutdown – Call
StopAnchorvia gRPC first, then terminate the subprocess. Do not kill the subprocess before callingStopAnchor.
Warning: Always call
StopAnchorbefore killing the Anchor subprocess. This allows the Anchor to shut down gracefully and clean up network resources. Killing the subprocess without callingStopAnchorfirst may leave the TUN interface and network state in an inconsistent state.
Note: Taints control which nodes can communicate. Two nodes can talk only if one node's taints are a subset or superset of the other's. See Taint-based access control for details.
Reference: Anchor gRPC API
| RPC | Request | Response |
|---|---|---|
StartAnchor | StartAnchorRequest | Empty |
StartAnchorWithFD | StartAnchorWithFDRequest | Empty |
StopAnchor | Empty | Empty |
AddTaint | AddTaintRequest | Empty |
RemoveTaint | RemoveTaintRequest | Empty |
GetInfo | Empty | GetInfoResponse |
GetRealmInfo | Empty | GetRealmInfoResponse |
GetVeilInfo | Empty | GetVeilInfoResponse |
GetTracerConfig | Empty | TracerConfig |
Resources
- Proto file: veilnet.proto
- Anchor binaries: conflux/anchor/bin
- Conflux repository: github.com/veil-net/conflux
- Taint access control: Taint documentation
- Go SDK reference: Quick Start (same concepts apply)
