Files
mfahampshire a70e68c7bd Max/smolmix docs (#6716)
* Smolmix documentation

* Add smolmix docs: landing page, tutorials, and developer page links

* Add Exit Gateway services page (NR vs IPR) and link from existing docs

* Update auto-generated command and API outputs

* Reorg of tutorials and architecture pages

* License information + remove TODO from docs.rs visibile comment + reorg
readme

* Add versions file for doc-wide versioning

* Relative -> absolute links

* Relative -> absolute links

* Update license + add old tutorial code as examples

* Streamline smolmix docs

* Clippy

* Clean up doc comments

* Last pass

* Add larger file download to list

* set new versions

* Clippy

* Remove blake pin from docs + add version range to root Cargo.toml

* Format example logging

* Remove crate blocked component

* Loose whitespace

* Add doc verification script for inline mdx

* Formatting

* Components regen

* Reorg + tighten text

* Voicing cohesion pass + remove bloated examples

* Voicing cont.

* Reduce max download size

* Small suggested clarifications

* Max/docs voicing consistency (#6769)

* Reduce max download size

* voicing consistency across docs

* New landing order w smolmix

* Tweaks

* Final tweaks
2026-05-13 11:19:44 +00:00

106 lines
3.4 KiB
Plaintext

---
title: "FFI Bindings: Go and C/C++"
description: "Use the Nym SDK from Go and C/C++ via FFI bindings. Covers mixnet messaging, anonymous replies, and TcpProxy lifecycle from non-Rust languages."
schemaType: "TechArticle"
section: "Developers"
lastUpdated: "2026-03-15"
---
# FFI Bindings
import { Callout } from 'nextra/components'
The SDK exposes FFI bindings for Go and C/C++. The source lives in [`sdk/ffi`](https://github.com/nymtech/nym/tree/develop/sdk/ffi):
```
ffi
├── cpp # C/C++ bindings (manual C FFI)
├── go # Go bindings (via uniffi-bindgen-go)
└── shared # Shared Rust implementation
```
Core logic lives in `shared/` and is imported into language-specific wrappers. The shared layer handles thread safety and runs client operations on blocking threads on the Rust side of the FFI boundary.
## What's exposed
**Mixnet** (Go and C/C++): ephemeral and persistent client creation, sending messages, anonymous replies via SURBs, listening for incoming messages.
**TcpProxy** (Go only): client and server creation and lifecycle.
<Callout type="warning">
The TcpProxy module is deprecated. For new projects, use the [Stream module](./stream) instead.
</Callout>
**Client Pool and Stream** have no standalone FFI bindings yet. The TcpProxy bindings use the Client Pool internally.
## Quick example (Go)
```go
// Initialise an ephemeral client
bindings.InitEphemeral()
// Get our Nym address
addr, _ := bindings.GetSelfAddress()
// Send a message through the Mixnet
bindings.SendMessage(addr, "hello from Go")
// Listen for incoming messages
msg, _ := bindings.ListenForIncoming()
fmt.Println("Received:", msg.Message)
// Reply anonymously via SURBs
bindings.Reply(msg.Sender, "reply from Go")
```
## Quick example (C++)
The C++ bindings use callbacks for return values and a `ReceivedMessage` struct for incoming data:
```cpp
extern "C" {
struct ReceivedMessage {
const uint8_t* message;
size_t size;
const char* sender_tag;
};
void init_logging();
char init_ephemeral();
char get_self_address(void (*callback)(const char*));
char send_message(const char*, const char*);
char listen_for_incoming(void (*callback)(ReceivedMessage));
char reply(const char*, const char*);
}
// Get address via callback
char addr[134];
void on_address(const char* s) { strcpy(addr, s); }
// Receive message via callback
char sender_tag[22];
void on_message(ReceivedMessage msg) {
std::cout << "Received: " << msg.message << std::endl;
strcpy(sender_tag, msg.sender_tag);
}
int main() {
init_ephemeral();
get_self_address(on_address);
send_message(addr, "hello from C++");
listen_for_incoming(on_message);
reply(sender_tag, "reply from C++");
}
```
## Building
Each language has a `build.sh` script that compiles the Rust shared library and generates bindings. See the README in each directory for prerequisites.
## Examples and source
- [Go mixnet example](https://github.com/nymtech/nym/blob/develop/sdk/ffi/go/example.go): init, send, receive, SURB reply
- [Go TcpProxy example](https://github.com/nymtech/nym/blob/develop/sdk/ffi/go/proxy_example.go): proxy client and server with TCP echo
- [C++ example](https://github.com/nymtech/nym/blob/develop/sdk/ffi/cpp/src/main.cpp): same flow using Boost threads
- [`sdk/ffi` source](https://github.com/nymtech/nym/tree/develop/sdk/ffi): full source and build scripts