mirror of
https://github.com/Quad4-Software/Reticulum-Go
synced 2026-08-29 23:48:44 -04:00
291 lines
9.9 KiB
Text
291 lines
9.9 KiB
Text
Binding scaffold for Reticulum-Go
|
|
=================================
|
|
|
|
Use this file to add a new language binding under bindings/<lang>/.
|
|
It is language-neutral. Follow an existing binding for idioms.
|
|
|
|
Choose one integration path (or both, as Dart does)
|
|
---------------------------------------------------
|
|
|
|
1. librns (in-process)
|
|
- Link or load the shared library built by task build-librns
|
|
- Authoritative C ABI: include/rns.h (copy also under bin/rns.h after build)
|
|
- Artifacts: bin/librns.so (Linux), bin/darwin/*/librns.dylib, bin/windows/amd64/librns.dll
|
|
- Best when the app embeds the stack in the same process
|
|
|
|
2. Control API (out-of-process)
|
|
- Talk HTTP and WebSocket to a running reticulum-go daemon
|
|
- Authoritative docs: docs/en/control-api.md
|
|
- Types and wire shapes: pkg/controlapi/protocol.go
|
|
- Best when the app stays outside the Go process
|
|
|
|
Do not invent a third wire protocol. Prefer peer destinations and links for
|
|
application traffic. The Control API is a local front end, not the mesh.
|
|
|
|
Reference bindings already in tree
|
|
----------------------------------
|
|
|
|
bindings/odin librns wrappers (foreign import) ABI 1.5 reference
|
|
bindings/zig librns wrappers (@extern)
|
|
bindings/cpp librns wrappers (C++ RAII)
|
|
bindings/dart librns FFI plus Control API client
|
|
bindings/rust librns wrappers (safe Rust over extern)
|
|
bindings/python librns wrappers (ctypes)
|
|
bindings/lua librns wrappers (LuaJIT FFI)
|
|
bindings/swift librns wrappers (SwiftPM)
|
|
bindings/java librns wrappers (JNA)
|
|
bindings/kotlin librns wrappers (Kotlin over Java JNA)
|
|
bindings/c C ABI examples only (include/rns.h)
|
|
|
|
Each binding keeps demos under bindings/<lang>/examples/{smoke,page-fetch,pageserver}
|
|
where applicable. Go-only samples stay under examples/.
|
|
|
|
Read docs/en/librns.md and docs/en/control-api.md before coding.
|
|
For product design constraints on the Control API, read the Architecture notes
|
|
in docs/en/control-api.md.
|
|
|
|
Suggested directory layout
|
|
--------------------------
|
|
|
|
bindings/<lang>/
|
|
Makefile or native build file
|
|
<package>/ or src/
|
|
raw ABI or HTTP client layer (thin)
|
|
errors
|
|
types / hashes / constants
|
|
identity
|
|
node
|
|
destination
|
|
link
|
|
path
|
|
event
|
|
util (string and buffer helpers)
|
|
tests/
|
|
optional example/
|
|
|
|
Keep a thin raw layer that mirrors include/rns.h or the Control API routes.
|
|
Put idiomatic ownership and Result/error types above that layer.
|
|
|
|
librns module map (required surface)
|
|
------------------------------------
|
|
|
|
Mirror these C entry points. Names may be idiomatic in the host language.
|
|
Handles are opaque uint64. Destroy before process exit.
|
|
|
|
Version and errors
|
|
rns_version
|
|
rns_last_error
|
|
RNS_API_VERSION string must match the header you compiled or loaded against
|
|
Error codes: OK, INVALID_ARG, INVALID_HANDLE, NOT_FOUND, STATE, IO,
|
|
INTERNAL, TIMEOUT, TRUNCATED
|
|
|
|
Node
|
|
rns_node_create (empty config path means in-memory defaults, share_instance off)
|
|
rns_node_start / rns_node_stop / rns_node_destroy
|
|
rns_node_set_identity
|
|
rns_node_pause / rns_node_resume
|
|
rns_node_refresh_paths
|
|
|
|
Identity
|
|
rns_identity_generate / rns_identity_load / rns_identity_save
|
|
rns_identity_destroy
|
|
rns_identity_hash (32 hex chars)
|
|
rns_identity_hash_bytes / rns_identity_public_key / rns_identity_from_public_key
|
|
rns_identity_sign / rns_identity_verify
|
|
|
|
RSG / RSM
|
|
rns_rsg_create / rns_rsg_validate / rns_rsg_sign_file / rns_rsg_verify_file
|
|
rns_rsm_verify
|
|
|
|
Destination
|
|
rns_destination_create (app name required, optional aspects, accepts_links)
|
|
rns_destination_enable_ratchets / rns_destination_enforce_ratchets
|
|
rns_destination_announce
|
|
rns_destination_hash (16 bytes, RNS_HASH_LEN)
|
|
rns_destination_destroy
|
|
rns_destination_register_request_handler
|
|
|
|
Path and link
|
|
rns_path_request
|
|
rns_path_table
|
|
rns_interfaces
|
|
rns_link_open / rns_link_send / rns_link_send_resource / rns_link_close
|
|
rns_link_id
|
|
rns_link_request
|
|
rns_request_respond / rns_request_respond_file
|
|
|
|
Events
|
|
rns_event_poll (caller owns app_data buffer capacity)
|
|
rns_set_event_callback (optional, same queue as poll)
|
|
Prefer one consumer style at a time (poll or callback, not both)
|
|
|
|
Event kinds
|
|
ANNOUNCE
|
|
LINK_ESTABLISHED / LINK_FAILED / LINK_DATA / LINK_CLOSED
|
|
REQUEST_INCOMING / REQUEST_RESPONSE / REQUEST_FAILED
|
|
RESOURCE_STARTED / RESOURCE_CONCLUDED
|
|
DESTINATION_DATA
|
|
|
|
ABI rules that bindings must preserve
|
|
-------------------------------------
|
|
|
|
- Never hold Go pointers across the ABI. Always copy bytes.
|
|
- Paths are operator-chosen. Reject empty paths and embedded NUL where the C API does.
|
|
- Incoming request handlers block the link until respond or timeout (about 30s).
|
|
- Event queue is bounded and drops oldest on overflow.
|
|
- Set app_data and app_data_cap before poll for variable payloads.
|
|
- Truncation flags on path, error_message, and app_data must be visible to callers.
|
|
|
|
Typical librns flow
|
|
-------------------
|
|
|
|
node_create("")
|
|
identity_generate or identity_load
|
|
node_set_identity
|
|
node_start
|
|
destination_create(..., accepts_links=true)
|
|
destination_register_request_handler(dest, "/ping")
|
|
destination_announce
|
|
peer: poll -> ANNOUNCE
|
|
peer: link_open(dest_hash)
|
|
poll -> LINK_ESTABLISHED
|
|
link_send / LINK_DATA
|
|
link_request / REQUEST_RESPONSE
|
|
link_close / LINK_CLOSED
|
|
node_stop
|
|
node_destroy
|
|
|
|
Control API module map (if building a daemon client)
|
|
----------------------------------------------------
|
|
|
|
Auth
|
|
Authorization: Bearer <hex rpc_key> on every /v1 route
|
|
Default host 127.0.0.1 port 37430 (config may change)
|
|
|
|
HTTP
|
|
GET /v1/health
|
|
GET /v1/status
|
|
GET /v1/paths
|
|
POST /v1/sessions
|
|
DELETE /v1/sessions/{id}
|
|
POST /v1/sessions/{id}/destinations
|
|
POST /v1/sessions/{id}/destinations/{hash}/announce
|
|
POST /v1/sessions/{id}/destinations/{hash}/requests
|
|
DELETE /v1/sessions/{id}/destinations/{hash}/requests?path=
|
|
POST /v1/sessions/{id}/path/request
|
|
GET /v1/sessions/{id}/events (WebSocket upgrade)
|
|
POST /v1/lifecycle/resume
|
|
POST /v1/lifecycle/pause
|
|
POST /v1/lifecycle/refresh-paths
|
|
|
|
WebSocket server -> client event types
|
|
announce
|
|
link.established / link.failed / link.data / link.closed / link.remote_identified
|
|
request.incoming / request.response / request.failed
|
|
resource.started / resource.concluded
|
|
command.error
|
|
|
|
WebSocket client -> server command types
|
|
subscribe_announces
|
|
link.open / link.send / link.close / link.request / link.send_resource / link.identify
|
|
request.respond
|
|
|
|
Binary fields use hex or base64 as documented in pkg/controlapi/protocol.go.
|
|
WebSocket event delivery is best-effort. A full outbox drops events.
|
|
Browser clients often cannot set Authorization on WebSocket upgrades.
|
|
|
|
Typical Control API flow
|
|
------------------------
|
|
|
|
POST /v1/sessions
|
|
POST /v1/sessions/{id}/destinations
|
|
POST /v1/sessions/{id}/destinations/{hash}/announce
|
|
GET /v1/sessions/{id}/events (WebSocket)
|
|
subscribe_announces
|
|
link.open after path exists
|
|
link.send / request.respond as needed
|
|
|
|
Idiomatic wrapper checklist
|
|
---------------------------
|
|
|
|
- Map error codes to host Result / exception / error union types
|
|
- Own handles with destroy on drop / finalizer / defer (language-appropriate)
|
|
- Disallow copy of handle owners unless the language makes sharing explicit
|
|
- Expose Hash as fixed 16-byte value, not free-form string, at the idiomatic layer
|
|
- Hex helpers at the boundary only
|
|
- Document library load order if dynamic: argument, env (e.g. RNS_LIB_PATH), then defaults under bin/
|
|
- Call version() early and compare to the ABI the binding was written against
|
|
|
|
Tests to include
|
|
----------------
|
|
|
|
Minimum
|
|
version string non-empty
|
|
node create / start / stop / destroy
|
|
identity generate and hash length
|
|
destination create and hash length
|
|
event poll timeout returns TIMEOUT (librns)
|
|
|
|
Stronger (match existing bindings where feasible)
|
|
link open / send / close over local UDP or Auto config
|
|
request register / incoming / respond
|
|
path table snapshot
|
|
callback vs poll mutual exclusion behavior
|
|
|
|
Build and smoke
|
|
---------------
|
|
|
|
From repository root:
|
|
|
|
task build-librns
|
|
make -C bindings/c/examples/smoke
|
|
./bindings/c/examples/smoke/librns-smoke
|
|
|
|
Add a bindings/<lang> Makefile (or equivalent) with at least:
|
|
test
|
|
examples
|
|
optional smoke
|
|
|
|
Wire CI using scripts/ci/run-<lang>-bindings.sh and
|
|
scripts/ci/run-binding-examples.sh (jobs in .github/workflows/ci.yml).
|
|
|
|
What not to put in a binding
|
|
----------------------------
|
|
|
|
- A reimplementation of the wire protocol
|
|
- Public Control API exposure guidance that fights loopback-first security notes
|
|
- Large file transfer via base64 link.send_resource when rncp or in-process is available
|
|
- New ABI symbols without growing include/rns.h and RNS_API_VERSION
|
|
|
|
Acceptance criteria for a new binding
|
|
-------------------------------------
|
|
|
|
See bindings/README.md "Correctness and interop" for the full bar.
|
|
|
|
1. Lives under bindings/<lang>/
|
|
2. Thin raw layer matches include/rns.h and/or Control API /v1
|
|
3. Idiomatic layer covers node, identity, destination, link, path, events, errors
|
|
4. Ownership of handles is safe for the host language
|
|
5. Tests run via make or the language package tool from that directory
|
|
6. Examples under bindings/<lang>/examples/ build (smoke at minimum)
|
|
7. CI script scripts/ci/run-<lang>-bindings.sh wired from Task and ci.yml
|
|
8. Interop verified against Go (pkg/node / pkg/librns) and Python RNS for any
|
|
mesh-visible surface (announce, path, link, request, resource, pageserver)
|
|
9. Short note added under the matching section of docs/en/librns.md and/or
|
|
docs/en/control-api.md when the binding is ready to advertise
|
|
|
|
FFI-only unit tests without a real librns build or peer check are not enough.
|
|
|
|
Authoritative sources (read these, do not guess)
|
|
------------------------------------------------
|
|
|
|
include/rns.h
|
|
docs/en/librns.md
|
|
docs/en/control-api.md
|
|
pkg/controlapi/protocol.go
|
|
bindings/c/examples/smoke
|
|
examples/control-client/client.py
|
|
bindings/odin , bindings/zig , bindings/cpp , bindings/dart ,
|
|
bindings/rust , bindings/python , bindings/lua , bindings/swift ,
|
|
bindings/java , bindings/kotlin
|
|
)
|