mirror of
https://github.com/logos-messaging/logos-messaging-dart-bindings.git
synced 2026-01-05 15:23:12 +00:00
First commit
This commit is contained in:
commit
27de79bda4
7
.gitignore
vendored
Normal file
7
.gitignore
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
# https://dart.dev/guides/libraries/private-files
|
||||
# Created by `dart pub`
|
||||
.dart_tool/
|
||||
|
||||
# Avoid committing pubspec.lock for library packages; see
|
||||
# https://dart.dev/guides/libraries/private-files#pubspeclock.
|
||||
pubspec.lock
|
||||
3
CHANGELOG.md
Normal file
3
CHANGELOG.md
Normal file
@ -0,0 +1,3 @@
|
||||
## 1.0.0
|
||||
|
||||
- Initial version.
|
||||
6
ffigen.yaml
Normal file
6
ffigen.yaml
Normal file
@ -0,0 +1,6 @@
|
||||
name: WakuBindings
|
||||
description: Bindings to Waku C API
|
||||
output: lib/src/waku_ffi.dart
|
||||
headers:
|
||||
entry-points:
|
||||
- native/libwaku.h
|
||||
51
lib/bindings.dart
Normal file
51
lib/bindings.dart
Normal file
@ -0,0 +1,51 @@
|
||||
import 'dart:ffi';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:ffi/ffi.dart';
|
||||
|
||||
class CallbackResult {
|
||||
late int callerRet;
|
||||
late String msg;
|
||||
}
|
||||
|
||||
/// Callback typedef
|
||||
typedef WakuCallBackC = Void Function(
|
||||
Int32 callerRet, Pointer<Utf8> msg, IntPtr len, Pointer<Void> userData);
|
||||
typedef WakuCallBackDart = void Function(
|
||||
int callerRet, Pointer<Utf8> msg, int len, Pointer<Void> userData);
|
||||
|
||||
/// waku_new typedefs
|
||||
typedef WakuNewC = Pointer<Void> Function(Pointer<Utf8> configJson,
|
||||
Pointer<NativeFunction<WakuCallBackC>> callback, Pointer<Void> userData);
|
||||
|
||||
typedef WakuNewDart = Pointer<Void> Function(Pointer<Utf8> configJson,
|
||||
Pointer<NativeFunction<WakuCallBackC>> callback, Pointer<Void> userData);
|
||||
|
||||
/// no params functions typedefs
|
||||
typedef WakuNoParamsC = Pointer<Void> Function(Pointer<Void> ctx,
|
||||
Pointer<NativeFunction<WakuCallBackC>> callback, Pointer<Void> userData);
|
||||
|
||||
typedef WakuNoParamsDart = Pointer<Void> Function(Pointer<Void> ctx,
|
||||
Pointer<NativeFunction<WakuCallBackC>> callback, Pointer<Void> userData);
|
||||
|
||||
/// Load the shared library
|
||||
final DynamicLibrary wakuLib = DynamicLibrary.open(
|
||||
Platform.isMacOS
|
||||
? 'libwaku.dylib'
|
||||
: Platform.isLinux
|
||||
? 'libwaku.so'
|
||||
: 'waku.dll',
|
||||
);
|
||||
|
||||
/// Lookup functions
|
||||
final WakuNewDart waku_new =
|
||||
wakuLib.lookupFunction<WakuNewC, WakuNewDart>('waku_new');
|
||||
|
||||
final WakuNoParamsDart waku_destroy =
|
||||
wakuLib.lookupFunction<WakuNoParamsC, WakuNoParamsDart>('waku_destroy');
|
||||
|
||||
final WakuNoParamsDart waku_start =
|
||||
wakuLib.lookupFunction<WakuNoParamsC, WakuNoParamsDart>('waku_start');
|
||||
|
||||
final WakuNoParamsDart waku_stop =
|
||||
wakuLib.lookupFunction<WakuNoParamsC, WakuNoParamsDart>('waku_stop');
|
||||
102
lib/waku.dart
Normal file
102
lib/waku.dart
Normal file
@ -0,0 +1,102 @@
|
||||
import 'dart:async';
|
||||
import 'dart:ffi';
|
||||
import 'package:ffi/ffi.dart';
|
||||
import 'bindings.dart';
|
||||
|
||||
class Waku {
|
||||
final Pointer<Void> _context;
|
||||
|
||||
Waku._(this._context);
|
||||
|
||||
static Future<Waku> newInstance(String configJson) async {
|
||||
late final NativeCallable<WakuCallBackC> callback;
|
||||
|
||||
final completer = Completer<CallbackResult>();
|
||||
void onCallCompleted(
|
||||
int callerRet, Pointer<Utf8> msg, int len, Pointer<Void> userData) {
|
||||
print("instance is created callback");
|
||||
completer.complete(CallbackResult()
|
||||
..callerRet = callerRet
|
||||
..msg = msg.toDartString(length: len));
|
||||
callback.close();
|
||||
}
|
||||
|
||||
callback = NativeCallable<WakuCallBackC>.listener(onCallCompleted);
|
||||
|
||||
final configPtr = configJson.toNativeUtf8();
|
||||
final context = waku_new(configPtr, callback.nativeFunction, nullptr);
|
||||
|
||||
final callResult = await completer.future;
|
||||
|
||||
malloc.free(configPtr);
|
||||
|
||||
final wakuCompleter = Completer<Waku>();
|
||||
|
||||
if (callResult.callerRet != 0) {
|
||||
print("Could not create instance");
|
||||
wakuCompleter
|
||||
.completeError('Failed to create Waku instance: ${callResult.msg}');
|
||||
} else {
|
||||
wakuCompleter.complete(Waku._(context));
|
||||
}
|
||||
|
||||
return wakuCompleter.future;
|
||||
}
|
||||
|
||||
Future<CallbackResult> destroyInstance() async {
|
||||
late final NativeCallable<WakuCallBackC> callback;
|
||||
|
||||
final completer = Completer<CallbackResult>();
|
||||
void onCallCompleted(
|
||||
int callerRet, Pointer<Utf8> msg, int len, Pointer<Void> userData) {
|
||||
completer.complete(CallbackResult()
|
||||
..callerRet = callerRet
|
||||
..msg = msg.toDartString(length: len));
|
||||
callback.close();
|
||||
}
|
||||
|
||||
callback = NativeCallable<WakuCallBackC>.listener(onCallCompleted);
|
||||
|
||||
waku_destroy(_context, callback.nativeFunction, nullptr);
|
||||
|
||||
return completer.future;
|
||||
}
|
||||
|
||||
Future<CallbackResult> start() async {
|
||||
late final NativeCallable<WakuCallBackC> callback;
|
||||
|
||||
final completer = Completer<CallbackResult>();
|
||||
void onCallCompleted(
|
||||
int callerRet, Pointer<Utf8> msg, int len, Pointer<Void> userData) {
|
||||
completer.complete(CallbackResult()
|
||||
..callerRet = callerRet
|
||||
..msg = msg.toDartString(length: len));
|
||||
callback.close();
|
||||
}
|
||||
|
||||
callback = NativeCallable<WakuCallBackC>.listener(onCallCompleted);
|
||||
|
||||
waku_start(_context, callback.nativeFunction, nullptr);
|
||||
|
||||
return completer.future;
|
||||
}
|
||||
|
||||
Future<CallbackResult> stop() async {
|
||||
late final NativeCallable<WakuCallBackC> callback;
|
||||
|
||||
final completer = Completer<CallbackResult>();
|
||||
void onCallCompleted(
|
||||
int callerRet, Pointer<Utf8> msg, int len, Pointer<Void> userData) {
|
||||
completer.complete(CallbackResult()
|
||||
..callerRet = callerRet
|
||||
..msg = msg.toDartString(length: len));
|
||||
callback.close();
|
||||
}
|
||||
|
||||
callback = NativeCallable<WakuCallBackC>.listener(onCallCompleted);
|
||||
|
||||
waku_stop(_context, callback.nativeFunction, nullptr);
|
||||
|
||||
return completer.future;
|
||||
}
|
||||
}
|
||||
251
native/libwaku.h
Normal file
251
native/libwaku.h
Normal file
@ -0,0 +1,251 @@
|
||||
|
||||
// Generated manually and inspired by the one generated by the Nim Compiler.
|
||||
// In order to see the header file generated by Nim just run `make libwaku`
|
||||
// from the root repo folder and the header should be created in
|
||||
// nimcache/release/libwaku/libwaku.h
|
||||
#ifndef __libwaku__
|
||||
#define __libwaku__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// The possible returned values for the functions that return int
|
||||
#define RET_OK 0
|
||||
#define RET_ERR 1
|
||||
#define RET_MISSING_CALLBACK 2
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef void (*WakuCallBack) (int callerRet, const char* msg, size_t len, void* userData);
|
||||
|
||||
// Creates a new instance of the waku node.
|
||||
// Sets up the waku node from the given configuration.
|
||||
// Returns a pointer to the Context needed by the rest of the API functions.
|
||||
void* waku_new(
|
||||
const char* configJson,
|
||||
WakuCallBack callback,
|
||||
void* userData);
|
||||
|
||||
int waku_start(void* ctx,
|
||||
WakuCallBack callback,
|
||||
void* userData);
|
||||
|
||||
int waku_stop(void* ctx,
|
||||
WakuCallBack callback,
|
||||
void* userData);
|
||||
|
||||
// Destroys an instance of a waku node created with waku_new
|
||||
int waku_destroy(void* ctx,
|
||||
WakuCallBack callback,
|
||||
void* userData);
|
||||
|
||||
int waku_version(void* ctx,
|
||||
WakuCallBack callback,
|
||||
void* userData);
|
||||
|
||||
void waku_set_event_callback(void* ctx,
|
||||
WakuCallBack callback,
|
||||
void* userData);
|
||||
|
||||
int waku_content_topic(void* ctx,
|
||||
const char* appName,
|
||||
unsigned int appVersion,
|
||||
const char* contentTopicName,
|
||||
const char* encoding,
|
||||
WakuCallBack callback,
|
||||
void* userData);
|
||||
|
||||
int waku_pubsub_topic(void* ctx,
|
||||
const char* topicName,
|
||||
WakuCallBack callback,
|
||||
void* userData);
|
||||
|
||||
int waku_default_pubsub_topic(void* ctx,
|
||||
WakuCallBack callback,
|
||||
void* userData);
|
||||
|
||||
int waku_relay_publish(void* ctx,
|
||||
const char* pubSubTopic,
|
||||
const char* jsonWakuMessage,
|
||||
unsigned int timeoutMs,
|
||||
WakuCallBack callback,
|
||||
void* userData);
|
||||
|
||||
int waku_lightpush_publish(void* ctx,
|
||||
const char* pubSubTopic,
|
||||
const char* jsonWakuMessage,
|
||||
WakuCallBack callback,
|
||||
void* userData);
|
||||
|
||||
int waku_relay_subscribe(void* ctx,
|
||||
const char* pubSubTopic,
|
||||
WakuCallBack callback,
|
||||
void* userData);
|
||||
|
||||
int waku_relay_add_protected_shard(void* ctx,
|
||||
int clusterId,
|
||||
int shardId,
|
||||
char* publicKey,
|
||||
WakuCallBack callback,
|
||||
void* userData);
|
||||
|
||||
int waku_relay_unsubscribe(void* ctx,
|
||||
const char* pubSubTopic,
|
||||
WakuCallBack callback,
|
||||
void* userData);
|
||||
|
||||
int waku_filter_subscribe(void* ctx,
|
||||
const char* pubSubTopic,
|
||||
const char* contentTopics,
|
||||
WakuCallBack callback,
|
||||
void* userData);
|
||||
|
||||
int waku_filter_unsubscribe(void* ctx,
|
||||
const char* pubSubTopic,
|
||||
const char* contentTopics,
|
||||
WakuCallBack callback,
|
||||
void* userData);
|
||||
|
||||
int waku_filter_unsubscribe_all(void* ctx,
|
||||
WakuCallBack callback,
|
||||
void* userData);
|
||||
|
||||
int waku_relay_get_num_connected_peers(void* ctx,
|
||||
const char* pubSubTopic,
|
||||
WakuCallBack callback,
|
||||
void* userData);
|
||||
|
||||
int waku_relay_get_connected_peers(void* ctx,
|
||||
const char* pubSubTopic,
|
||||
WakuCallBack callback,
|
||||
void* userData);
|
||||
|
||||
int waku_relay_get_num_peers_in_mesh(void* ctx,
|
||||
const char* pubSubTopic,
|
||||
WakuCallBack callback,
|
||||
void* userData);
|
||||
|
||||
int waku_relay_get_peers_in_mesh(void* ctx,
|
||||
const char* pubSubTopic,
|
||||
WakuCallBack callback,
|
||||
void* userData);
|
||||
|
||||
int waku_store_query(void* ctx,
|
||||
const char* jsonQuery,
|
||||
const char* peerAddr,
|
||||
int timeoutMs,
|
||||
WakuCallBack callback,
|
||||
void* userData);
|
||||
|
||||
int waku_connect(void* ctx,
|
||||
const char* peerMultiAddr,
|
||||
unsigned int timeoutMs,
|
||||
WakuCallBack callback,
|
||||
void* userData);
|
||||
|
||||
int waku_disconnect_peer_by_id(void* ctx,
|
||||
const char* peerId,
|
||||
WakuCallBack callback,
|
||||
void* userData);
|
||||
|
||||
int waku_disconnect_all_peers(void* ctx,
|
||||
WakuCallBack callback,
|
||||
void* userData);
|
||||
|
||||
int waku_dial_peer(void* ctx,
|
||||
const char* peerMultiAddr,
|
||||
const char* protocol,
|
||||
int timeoutMs,
|
||||
WakuCallBack callback,
|
||||
void* userData);
|
||||
|
||||
int waku_dial_peer_by_id(void* ctx,
|
||||
const char* peerId,
|
||||
const char* protocol,
|
||||
int timeoutMs,
|
||||
WakuCallBack callback,
|
||||
void* userData);
|
||||
|
||||
int waku_get_peerids_from_peerstore(void* ctx,
|
||||
WakuCallBack callback,
|
||||
void* userData);
|
||||
|
||||
int waku_get_connected_peers_info(void* ctx,
|
||||
WakuCallBack callback,
|
||||
void* userData);
|
||||
|
||||
int waku_get_peerids_by_protocol(void* ctx,
|
||||
const char* protocol,
|
||||
WakuCallBack callback,
|
||||
void* userData);
|
||||
|
||||
int waku_listen_addresses(void* ctx,
|
||||
WakuCallBack callback,
|
||||
void* userData);
|
||||
|
||||
int waku_get_connected_peers(void* ctx,
|
||||
WakuCallBack callback,
|
||||
void* userData);
|
||||
|
||||
// Returns a list of multiaddress given a url to a DNS discoverable ENR tree
|
||||
// Parameters
|
||||
// char* entTreeUrl: URL containing a discoverable ENR tree
|
||||
// char* nameDnsServer: The nameserver to resolve the ENR tree url.
|
||||
// int timeoutMs: Timeout value in milliseconds to execute the call.
|
||||
int waku_dns_discovery(void* ctx,
|
||||
const char* entTreeUrl,
|
||||
const char* nameDnsServer,
|
||||
int timeoutMs,
|
||||
WakuCallBack callback,
|
||||
void* userData);
|
||||
|
||||
// Updates the bootnode list used for discovering new peers via DiscoveryV5
|
||||
// bootnodes - JSON array containing the bootnode ENRs i.e. `["enr:...", "enr:..."]`
|
||||
int waku_discv5_update_bootnodes(void* ctx,
|
||||
char* bootnodes,
|
||||
WakuCallBack callback,
|
||||
void* userData);
|
||||
|
||||
int waku_start_discv5(void* ctx,
|
||||
WakuCallBack callback,
|
||||
void* userData);
|
||||
|
||||
int waku_stop_discv5(void* ctx,
|
||||
WakuCallBack callback,
|
||||
void* userData);
|
||||
|
||||
// Retrieves the ENR information
|
||||
int waku_get_my_enr(void* ctx,
|
||||
WakuCallBack callback,
|
||||
void* userData);
|
||||
|
||||
int waku_get_my_peerid(void* ctx,
|
||||
WakuCallBack callback,
|
||||
void* userData);
|
||||
|
||||
int waku_get_metrics(void* ctx,
|
||||
WakuCallBack callback,
|
||||
void* userData);
|
||||
|
||||
int waku_peer_exchange_request(void* ctx,
|
||||
int numPeers,
|
||||
WakuCallBack callback,
|
||||
void* userData);
|
||||
|
||||
int waku_ping_peer(void* ctx,
|
||||
const char* peerAddr,
|
||||
int timeoutMs,
|
||||
WakuCallBack callback,
|
||||
void* userData);
|
||||
|
||||
int waku_is_online(void* ctx,
|
||||
WakuCallBack callback,
|
||||
void* userData);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __libwaku__ */
|
||||
BIN
native/libwaku.so
Executable file
BIN
native/libwaku.so
Executable file
Binary file not shown.
14
pubspec.yaml
Normal file
14
pubspec.yaml
Normal file
@ -0,0 +1,14 @@
|
||||
name: waku_dart_bindings
|
||||
description: Dart bindings for Waku C API
|
||||
version: 1.0.0
|
||||
|
||||
environment:
|
||||
sdk: ">3.4.0 <4.0.0"
|
||||
|
||||
dependencies:
|
||||
ffi: ^2.1.0
|
||||
|
||||
dev_dependencies:
|
||||
ffigen: ^19.1.0
|
||||
lints: ^6.0.0
|
||||
test: ^1.26.0
|
||||
27
test/waku_test.dart
Normal file
27
test/waku_test.dart
Normal file
@ -0,0 +1,27 @@
|
||||
import 'package:test/test.dart';
|
||||
import 'package:waku_dart_bindings/waku.dart'; // Your high-level wrapper
|
||||
|
||||
void main() {
|
||||
group('Waku FFI Tests', () {
|
||||
Waku? wakuInstance;
|
||||
|
||||
setUp(() async {
|
||||
// Create a new Waku instance before each test
|
||||
wakuInstance = await Waku.newInstance(
|
||||
'{ "clusterId": 16, "shards": [ 1, 32, 64, 128, 256 ], "numShardsInNetwork": 257 }');
|
||||
});
|
||||
|
||||
tearDown(() {
|
||||
// Optionally: clean up resources if your API exposes a free function
|
||||
// e.g., waku_free(wakuInstance?.context);
|
||||
wakuInstance?.destroyInstance();
|
||||
});
|
||||
|
||||
test('Start and stop waku instance', () async {
|
||||
final startResult = await wakuInstance!.start();
|
||||
expect(startResult.callerRet, 0);
|
||||
final stopResult = await wakuInstance!.stop();
|
||||
expect(stopResult.callerRet, 0);
|
||||
});
|
||||
});
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user