A pure Go implementation of the Tox Messenger core protocol.
toxcore-go is a clean, idiomatic Go implementation of the Tox protocol, designed for simplicity, security, and performance. It provides a comprehensive, CGo-free implementation with C binding annotations for cross-language compatibility.
Key features:
- Pure Go implementation with no CGo dependencies
- Comprehensive implementation of the Tox protocol
- Clean API design with proper Go idioms
- C binding annotations for cross-language use
- Robust error handling and concurrency patterns
go get github.com/opd-ai/toxcore
package main
import (
"fmt"
"log"
"time"
"github.com/opd-ai/toxcore"
)
func main() {
// Create a new Tox instance
options := toxcore.NewOptions()
options.UDPEnabled = true
tox, err := toxcore.New(options)
if err != nil {
log.Fatal(err)
}
defer tox.Kill()
// Print our Tox ID
fmt.Println("My Tox ID:", tox.SelfGetAddress())
// Set up callbacks
tox.OnFriendRequest(func(publicKey [32]byte, message string) {
fmt.Printf("Friend request: %s\n", message)
// Automatically accept friend requests
friendID, err := tox.AddFriend(publicKey)
if err != nil {
fmt.Printf("Error accepting friend request: %v\n", err)
} else {
fmt.Printf("Accepted friend request. Friend ID: %d\n", friendID)
}
})
tox.OnFriendMessage(func(friendID uint32, message string) {
fmt.Printf("Message from friend %d: %s\n", friendID, message)
// Echo the message back
tox.SendFriendMessage(friendID, "You said: "+message)
})
// Connect to a bootstrap node
err = tox.Bootstrap("node.tox.biribiri.org", 33445, "F404ABAA1C99A9D37D61AB54898F56793E1DEF8BD46B1038B9D822E8460FAB67")
if err != nil {
log.Printf("Warning: Bootstrap failed: %v", err)
}
// Main loop
fmt.Println("Running Tox...")
for tox.IsRunning() {
tox.Iterate()
time.Sleep(tox.IterationInterval())
}
}
toxcore-go can be used from C code via the provided C bindings:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "toxcore.h"
void friend_request_callback(uint8_t* public_key, const char* message, void* user_data) {
printf("Friend request received: %s\n", message);
// Accept the friend request
uint32_t friend_id;
TOX_ERR_FRIEND_ADD err;
friend_id = tox_friend_add_norequest(tox, public_key, &err);
if (err != TOX_ERR_FRIEND_ADD_OK) {
printf("Error accepting friend request: %d\n", err);
} else {
printf("Friend added with ID: %u\n", friend_id);
}
}
void friend_message_callback(uint32_t friend_id, TOX_MESSAGE_TYPE type,
const uint8_t* message, size_t length, void* user_data) {
char* msg = malloc(length + 1);
memcpy(msg, message, length);
msg[length] = '\0';
printf("Message from friend %u: %s\n", friend_id, msg);
// Echo the message back
tox_friend_send_message(tox, friend_id, type, message, length, NULL);
free(msg);
}
int main() {
// Create a new Tox instance
struct Tox_Options options;
tox_options_default(&options);
TOX_ERR_NEW err;
Tox* tox = tox_new(&options, &err);
if (err != TOX_ERR_NEW_OK) {
printf("Error creating Tox instance: %d\n", err);
return 1;
}
// Register callbacks
tox_callback_friend_request(tox, friend_request_callback, NULL);
tox_callback_friend_message(tox, friend_message_callback, NULL);
// Print our Tox ID
uint8_t tox_id[TOX_ADDRESS_SIZE];
tox_self_get_address(tox, tox_id);
char id_str[TOX_ADDRESS_SIZE*2 + 1];
for (int i = 0; i < TOX_ADDRESS_SIZE; i++) {
sprintf(id_str + i*2, "%02X", tox_id[i]);
}
id_str[TOX_ADDRESS_SIZE*2] = '\0';
printf("My Tox ID: %s\n", id_str);
// Bootstrap
uint8_t bootstrap_pub_key[TOX_PUBLIC_KEY_SIZE];
hex_string_to_bin("F404ABAA1C99A9D37D61AB54898F56793E1DEF8BD46B1038B9D822E8460FAB67", bootstrap_pub_key);
tox_bootstrap(tox, "node.tox.biribiri.org", 33445, bootstrap_pub_key, NULL);
// Main loop
printf("Running Tox...\n");
while (1) {
tox_iterate(tox, NULL);
uint32_t interval = tox_iteration_interval(tox);
usleep(interval * 1000);
}
tox_kill(tox);
return 0;
}
toxcore-go differs from the original C implementation in several ways:
- Language and Style: Pure Go implementation with idiomatic Go patterns and error handling.
- Memory Management: Uses Go's garbage collection instead of manual memory management.
- Concurrency: Leverages Go's goroutines and channels for concurrent operations.
- API Design: Cleaner, more consistent API following Go conventions.
- Simplicity: Focused on clean, maintainable code with modern design patterns.
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature
) - Commit your changes (
git commit -m 'Add some amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Open a Pull Request
This project is licensed under the GPL-3.0 License - see the LICENSE file for details.