mirror of https://github.com/status-im/go-waku.git
fix: c api and add some documentation (#219)
This commit is contained in:
parent
290b7663d1
commit
aa6d8c8b58
5
Makefile
5
Makefile
|
@ -83,7 +83,10 @@ build-example-chat-2:
|
|||
build-example-filter2:
|
||||
cd examples/filter2 && $(MAKE)
|
||||
|
||||
build-example: build-example-basic2 build-example-chat-2 build-example-filter2
|
||||
build-example-c-bindings:
|
||||
cd examples/c-bindings && $(MAKE)
|
||||
|
||||
build-example: build-example-basic2 build-example-chat-2 build-example-filter2 build-example-c-bindings
|
||||
|
||||
static-library: ##@cross-compile Build go-waku as static library for current platform
|
||||
mkdir -p ./build/lib
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
*
|
||||
!.gitignore
|
||||
!lib
|
|
@ -0,0 +1,2 @@
|
|||
*
|
||||
!.gitignore
|
|
@ -29,13 +29,13 @@ int main(int argc, char *argv[])
|
|||
|
||||
|
||||
|
||||
response = gowaku_start(nodeID); // Start the node, enabling the waku protocols
|
||||
response = gowaku_start(1); // Start the node, enabling the waku protocols
|
||||
if (isError(response))
|
||||
return 1;
|
||||
|
||||
|
||||
|
||||
response = gowaku_id(nodeID); // Obtain the node peerID
|
||||
response = gowaku_peerid(nodeID); // Obtain the node peerID
|
||||
if (isError(response))
|
||||
return 1;
|
||||
char *nodePeerID = getStrValue(response);
|
||||
|
@ -61,14 +61,15 @@ int main(int argc, char *argv[])
|
|||
int version = 1;
|
||||
while (true){
|
||||
i++;
|
||||
|
||||
response = gowaku_encode_data("Hello World!", ASYMMETRIC, bobPubKey, alicePrivKey, version); // Send a message encrypting it with Bob's PubK, and signing it with Alice PrivK
|
||||
|
||||
char *msg = gowaku_utils_base64_encode("Hello World!");
|
||||
response = gowaku_encode_data(msg, ASYMMETRIC, bobPubKey, alicePrivKey, version); // Send a message encrypting it with Bob's PubK, and signing it with Alice PrivK
|
||||
if (isError(response))
|
||||
return 1;
|
||||
char *encodedData = getStrValue(response);
|
||||
|
||||
|
||||
char *contentTopic = getStrValue(gowaku_content_topic("example", 1, "default", "rfc26"));
|
||||
char *contentTopic = gowaku_content_topic("example", 1, "default", "rfc26");
|
||||
|
||||
|
||||
char wakuMsg[1000];
|
||||
|
@ -100,8 +101,9 @@ void callBack(char *signal)
|
|||
"nodeId":1,
|
||||
"type":"message",
|
||||
"event":{
|
||||
"messageID":"0x6496491e40dbe0b6c3a2198c2426b16301688a2daebc4f57ad7706115eac3ad1",
|
||||
"pubsubTopic":"/waku/2/default-waku/proto",
|
||||
"subscriptionID": ".....",
|
||||
"messageID":"0x6496491e40dbe0b6c3a2198c2426b16301688a2daebc4f57ad7706115eac3ad1",
|
||||
"wakuMessage":{
|
||||
"payload":"BPABASUqWgRkgp73aW/FHIyGtJDYnStvaQvCoX9MdaNsOH39Vet0em6ipZc3lZ7kK9uFFtbJgIWfRaqTxSRjiFOPx88gXt1JeSm2SUwGSz+1gh2xTy0am8tXkc8OWSSjamdkEbXuVgAueLxHOnV3xlGwYt7nx2G5DWYqUu1BXv4yWHPOoiH2yx3fxX0OajgKGBwiMbadRNUuAUFPRM90f+bzG2y22ssHctDV/U6sXOa9ljNgpAx703Q3WIFleSRozto7ByNAdRFwWR0RGGV4l0btJXM7JpnrYcVC24dB0tJ3HVWuD0ZcwOM1zTL0wwc0hTezLHvI+f6bHSzsFGcCWIlc03KSoMjK1XENNL4dtDmSFI1DQCGgq09c2Bc3Je3Ci6XJHu+FP1F1pTnRzevv2WP8FSBJiTXpmJXdm6evB7V1Xxj4QlzQDvmHLRpBOL6PSttxf1Dc0IwC6BfZRN5g0dNmItNlS2pcY1MtZLxD5zpj",
|
||||
"contentTopic":"ABC",
|
||||
|
|
|
@ -0,0 +1,441 @@
|
|||
---
|
||||
slug: #
|
||||
title: #/GOWAKU-BINDINGS
|
||||
name: Go-Waku v2 C Bindings
|
||||
status: draft
|
||||
tags: go-waku
|
||||
editor: Richard Ramos <richard@status.im>
|
||||
contributors:
|
||||
|
||||
---
|
||||
|
||||
This specification describes the API for consuming go-waku when built as a dynamic or static library
|
||||
|
||||
|
||||
# libgowaku.h
|
||||
|
||||
|
||||
## General
|
||||
|
||||
|
||||
### JSONResponse
|
||||
All the API functions return a `JSONResponse` unless specified otherwise. `JSONResponse` is a `char *` whose format depends on whether the function was executed sucessfully or not:
|
||||
```json
|
||||
// On failure:
|
||||
{ "error": "the error message" }
|
||||
|
||||
// On success:
|
||||
{ "result": ... } // result format depends on the function response
|
||||
```
|
||||
|
||||
## Events
|
||||
Asynchronous events require a callback to be registered. An example of an asynchronous event that might be emitted is receiving a message. When an event is emitted, this callback will be triggered receiving a json string with the following format:
|
||||
```json
|
||||
{
|
||||
"nodeId": 0, // go-waku node that emitted the signal
|
||||
"type": "message", // type of signal being emitted. Currently only "message" is available
|
||||
"event": ... // format depends on the type of signal. In the case of "message", a waku message can be expected here
|
||||
}
|
||||
```
|
||||
|
||||
### `extern void gowaku_set_event_callback(void* cb)`
|
||||
Register callback to act as event handler and receive application signals, which are used to react to asyncronous events in waku.
|
||||
|
||||
**Parameters**
|
||||
1. `void* cb`: callback that will be executed when an async event is emitted. The function signature for the callback should be `void myCallback(char* signalJSON)`
|
||||
|
||||
|
||||
## Node management
|
||||
|
||||
### `extern char* gowaku_new(char* configJSON)`
|
||||
Initialize a go-waku node.
|
||||
|
||||
**Parameters**
|
||||
1. `char* configJSON`: JSON string containing the options used to initialize a go-waku node. It can be `NULL` to use defaults. All the keys from the configuration are optional. If a key is `undefined`, or `null`, a default value will be set
|
||||
```json
|
||||
// example config:
|
||||
{
|
||||
"host": "0.0.0.0",
|
||||
"port": 60000,
|
||||
"advertiseAddr": "1.2.3.4",
|
||||
"nodeKey": "0x123...567",
|
||||
"keepAliveInterval": 20,
|
||||
"relay": true,
|
||||
"minPeersToPublish": 0
|
||||
}
|
||||
```
|
||||
- `host` - `String` (optional): Listening IP address. Default `0.0.0.0`
|
||||
- `port` - `Number` (optional): Libp2p TCP listening port. Default `60000`. Use `0` for random
|
||||
- `advertiseAddr` - `String` (optional): External address to advertise to other nodes.
|
||||
- `nodeKey` - `String` (optional): secp256k1 private key in Hex format (`0x123...abc`). Default random
|
||||
- `keepAliveInterval` - `Number` (optional): Interval in seconds for pinging peers to keep the connection alive. Default `20`
|
||||
- `relay` - `Boolean` (optional): Enable relay protocol. Default `true`
|
||||
- `minPeersToPublish` - `Number` (optional). The minimum number of peers required on a topic to allow broadcasting a message. Default `0`
|
||||
|
||||
**Returns**
|
||||
`JSONResponse` with a `result` containing an `int` which represents the `nodeID` which should be used in all calls from this API that require interacting with the node if the function executes successfully. An `error` message otherwise
|
||||
|
||||
---
|
||||
|
||||
### `extern char* gowaku_start(int nodeID)`
|
||||
Initialize a go-waku node mounting all the protocols that were enabled during the waku node initialization.
|
||||
|
||||
**Parameters**
|
||||
1. `int nodeID`: the node identifier obtained from a succesful execution of `gowaku_new`
|
||||
|
||||
---
|
||||
|
||||
### `extern char* gowaku_stop(int nodeID)`
|
||||
Stops a go-waku node
|
||||
|
||||
**Parameters**
|
||||
1. `int nodeID`: the node identifier obtained from a succesful execution of `gowaku_new`
|
||||
|
||||
**Returns**
|
||||
`JSONResponse` containing a null `result` if the function executes successfully. An `error` message otherwise
|
||||
|
||||
---
|
||||
|
||||
### `extern char* gowaku_peerid(int nodeID)`
|
||||
Obtain the peer ID of the go-waku node.
|
||||
|
||||
**Parameters**
|
||||
1. `int nodeID`: the node identifier obtained from a succesful execution of `gowaku_new`
|
||||
|
||||
**Returns**
|
||||
`JSONResponse` containing the peer ID (base58 encoded) if the function executes successfully. An `error` message otherwise
|
||||
|
||||
---
|
||||
|
||||
### `extern char* gowaku_listen_addresses(int nodeID)`
|
||||
Obtain the multiaddresses the wakunode is listening to
|
||||
|
||||
**Parameters**
|
||||
1. `int nodeID`: the node identifier obtained from a succesful execution of `gowaku_new`
|
||||
|
||||
**Returns**
|
||||
`JSONResponse` containing an array of multiaddresses if the function executes successfully. An `error` message otherwise
|
||||
|
||||
|
||||
## Connecting to peers
|
||||
|
||||
### `extern char* gowaku_add_peer(int nodeID, char* address, char* protocolID)`
|
||||
Add node multiaddress and protocol to the wakunode peerstore
|
||||
|
||||
**Parameters**
|
||||
1. `int nodeID`: the node identifier obtained from a succesful execution of `gowaku_new`
|
||||
2. `char* address`: multiaddress of the peer being added
|
||||
3. `char* protocolID`: protocol supported by the peer
|
||||
|
||||
**Returns**
|
||||
`JSONResponse` containing the peer ID (base58 encoded) of the peer that was added if the function executes successfully. An `error` message otherwise
|
||||
|
||||
---
|
||||
|
||||
### `extern char* gowaku_dial_peer(int nodeID, char* address, int ms)`
|
||||
Dial peer at multiaddress.
|
||||
|
||||
**Parameters**
|
||||
1. `int nodeID`: the node identifier obtained from a succesful execution of `gowaku_new`
|
||||
2. `char* address`: multiaddress of the peer being dialed
|
||||
3. `int ms`: max duration in milliseconds this function might take to execute. If the function execution takes longer than this value, the execution will be canceled and an error returned. Use `0` for unlimited duration
|
||||
|
||||
**Returns**
|
||||
`JSONResponse` with a null `result` if the function executes successfully. An `error` message otherwise
|
||||
|
||||
---
|
||||
|
||||
### `extern char* gowaku_dial_peerid(int nodeID, char* id, int ms)`
|
||||
Dial peer using peerID.
|
||||
|
||||
**Parameters**
|
||||
1. `int nodeID`: the node identifier obtained from a succesful execution of `gowaku_new`
|
||||
2. `char* peerID`: peerID to dial. The peer must be already known. It must have been added before with `gowaku_add_peer` or previously dialed with `gowaku_dial_peer`
|
||||
3. `int ms`: max duration in milliseconds this function might take to execute. If the function execution takes longer than this value, the execution will be canceled and an error returned. Use `0` for unlimited duration
|
||||
|
||||
**Returns**
|
||||
`JSONResponse` with a null `result` if the function executes successfully. An `error` message otherwise
|
||||
|
||||
---
|
||||
|
||||
### `extern char* gowaku_close_peer(int nodeID, char* address)`
|
||||
Disconnect a peer using its multiaddress
|
||||
|
||||
**Parameters**
|
||||
1. `int nodeID`: the node identifier obtained from a succesful execution of `gowaku_new`
|
||||
2. `char* address`: multiaddress of the peer being disconnected.
|
||||
|
||||
**Returns**
|
||||
`JSONResponse` with a null `result` if the function executes successfully. An `error` message otherwise
|
||||
|
||||
---
|
||||
|
||||
### `extern char* gowaku_close_peerid(int nodeID, char* id)`
|
||||
Disconnect a peer using its peerID
|
||||
**Parameters**
|
||||
1. `int nodeID`: the node identifier obtained from a succesful execution of `gowaku_new`
|
||||
2. `char* peerID`: peerID to disconnect.
|
||||
|
||||
**Returns**
|
||||
`JSONResponse` with a null `result` if the function executes successfully. An `error` message otherwise
|
||||
|
||||
---
|
||||
|
||||
### `extern char* gowaku_peer_cnt(int nodeID)`
|
||||
Obtain number of connected peers
|
||||
|
||||
**Parameters**
|
||||
1. `int nodeID`: the node identifier obtained from a succesful execution of `gowaku_new`
|
||||
|
||||
**Returns**
|
||||
`JSONResponse` containing an `int` with the number of connected peers. An `error` message otherwise
|
||||
|
||||
---
|
||||
|
||||
### `extern char* gowaku_peers(int nodeID)`
|
||||
Retrieve the list of peers known by the go-waku node
|
||||
|
||||
**Parameters**
|
||||
1. `int nodeID`: the node identifier obtained from a succesful execution of `gowaku_new`
|
||||
|
||||
**Returns**
|
||||
`JSONResponse` containing a list of peers. An `error` message otherwise. The list of peers has this format:
|
||||
```json
|
||||
{
|
||||
"result":[
|
||||
...
|
||||
{
|
||||
"peerID":"16Uiu2HAmJb2e28qLXxT5kZxVUUoJt72EMzNGXB47RedcBafeDCBA",
|
||||
"protocols":[
|
||||
"/ipfs/id/1.0.0",
|
||||
"/vac/waku/relay/2.0.0",
|
||||
"/ipfs/ping/1.0.0",
|
||||
...
|
||||
],
|
||||
"addrs":[
|
||||
"/ip4/1.2.3.4/tcp/30303",
|
||||
...
|
||||
],
|
||||
"connected":true
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Waku Relay
|
||||
|
||||
|
||||
### `extern char* gowaku_content_topic(char* applicationName, unsigned int applicationVersion, char* contentTopicName, char* encoding)`
|
||||
Create a content topic string according to [RFC 23](https://rfc.vac.dev/spec/23/)
|
||||
|
||||
**Parameters**
|
||||
1. `char* applicationName`
|
||||
2. `unsigned int applicationVersion`
|
||||
3. `char* contentTopicName`
|
||||
4. `char* encoding`: depending on the payload, use `proto`, `rlp` or `rfc26`
|
||||
|
||||
**Returns**
|
||||
`char *` containing a content topic formatted according to [RFC 23](https://rfc.vac.dev/spec/23/)
|
||||
```
|
||||
/{application-name}/{version-of-the-application}/{content-topic-name}/{encoding}
|
||||
```
|
||||
|
||||
--
|
||||
|
||||
### `extern char* gowaku_pubsub_topic(char* name, char* encoding)`
|
||||
Create a pubsub topic string according to [RFC 23](https://rfc.vac.dev/spec/23/)
|
||||
|
||||
**Parameters**
|
||||
1. `char* name`
|
||||
2. `char* encoding`: depending on the payload, use `proto`, `rlp` or `rfc26`
|
||||
|
||||
**Returns**
|
||||
`char *` containing a content topic formatted according to [RFC 23](https://rfc.vac.dev/spec/23/)
|
||||
```
|
||||
/waku/2/{topic-name}/{encoding}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `extern char* gowaku_default_pubsub_topic()`
|
||||
Returns the default pubsub topic used for exchanging waku messages defined in [RFC 10](https://rfc.vac.dev/spec/10/)
|
||||
|
||||
**Returns**
|
||||
`char *` containing the default pubsub topic:
|
||||
```
|
||||
/waku/2/default-waku/proto
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `extern char* gowaku_relay_publish(int nodeID, char* messageJSON, char* topic, int ms)`
|
||||
Publish a message using waku relay.
|
||||
|
||||
**Parameters**
|
||||
1. `int nodeID`: the node identifier obtained from a succesful execution of `gowaku_new`
|
||||
2. `char* messageJSON`: json string containing the [Waku Message](https://rfc.vac.dev/spec/14/)
|
||||
```json
|
||||
{
|
||||
"payload":"", // base64 encoded payload. gowaku_utils_base64_encode can be used for this
|
||||
"contentTopic: "...",
|
||||
"version": 1,
|
||||
"timestamp": 1647963508000000000 // Unix timestamp in nanoseconds
|
||||
}
|
||||
```
|
||||
3. `char* topic`: pubsub topic. Set to `NULL` to use the default pubsub topic
|
||||
4. `int ms`: max duration in milliseconds this function might take to execute. If the function execution takes longer than this value, the execution will be canceled and an error returned. Use `0` for unlimited duration
|
||||
|
||||
**Returns**
|
||||
`JSONResponse` containing the message ID. An `error` message otherwise
|
||||
|
||||
---
|
||||
|
||||
### `extern char* gowaku_enough_peers(int nodeID, char* topic)`
|
||||
Determine if there are enough peers to publish a message on a topic.
|
||||
|
||||
**Parameters**
|
||||
1. `int nodeID`: the node identifier obtained from a succesful execution of `gowaku_new`
|
||||
2. `char* topic`: pubsub topic to verify. Use `NULL` to verify the number of peers in the default pubsub topic
|
||||
|
||||
**Returns**
|
||||
`JSONResponse` with a boolean indicating if there are enough peers or not. An `error` message otherwise
|
||||
|
||||
---
|
||||
|
||||
### `extern char* gowaku_relay_subscribe(int nodeID, char* topic)`
|
||||
Subscribe to a WakuRelay topic to receive messages.
|
||||
|
||||
**Parameters**
|
||||
1. `int nodeID`: the node identifier obtained from a succesful execution of `gowaku_new`
|
||||
2. `char* topic`: pubsub topic to subscribe to. Use `NULL` for subscribing to the default pubsub topic
|
||||
|
||||
|
||||
**Returns**
|
||||
`JSONResponse` with a subscription ID. An `error` message otherwise
|
||||
|
||||
**Events**
|
||||
When a message is received, a ``"message"` event` is emitted containing the message, pubsub topic, and nodeID in which the message was received. Here's an example event that could be received:
|
||||
```json
|
||||
{
|
||||
"nodeId":1,
|
||||
"type":"message",
|
||||
"event":{
|
||||
"subscriptionID":"...",
|
||||
"pubsubTopic":"/waku/2/default-waku/proto",
|
||||
"messageID":"0x6496491e40dbe0b6c3a2198c2426b16301688a2daebc4f57ad7706115eac3ad1",
|
||||
"wakuMessage":{
|
||||
"payload":"...", // base64 encoded message. Use gowaku_decode_data to decode
|
||||
"contentTopic":"ABC",
|
||||
"version":1,
|
||||
"timestamp":1647826358000000000 // in nanoseconds
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### `extern char* gowaku_relay_close_subscription(int nodeID, char* subsID)`
|
||||
Closes a waku relay subscription. No more messages will be received from this subscription
|
||||
|
||||
**Parameters**
|
||||
1. `int nodeID`: the node identifier obtained from a succesful execution of `gowaku_new`
|
||||
2. `char* subsID`: subscription ID to close
|
||||
|
||||
**Returns**
|
||||
`JSONResponse` with null `response` if successful. An `error` message otherwise
|
||||
|
||||
---
|
||||
|
||||
### `extern char* gowaku_relay_unsubscribe_from_topic(int nodeID, char* topic)`
|
||||
Closes the pubsub subscription to a pubsub topic. Existing subscriptions will not be closed, but they will stop receiving messages
|
||||
|
||||
**Parameters**
|
||||
1. `int nodeID`: the node identifier obtained from a succesful execution of `gowaku_new`
|
||||
2. `char* topic`: pubsub topic to unsubscribe. Use `NULL` for unsubscribe from the default pubsub topic
|
||||
|
||||
**Returns**
|
||||
`JSONResponse` with null `response` if successful. An `error` message otherwise
|
||||
|
||||
|
||||
|
||||
## Waku Message Utils
|
||||
|
||||
### `extern char* gowaku_encode_data(char* data, char* keyType, char* key, char* signingKey, int version)`
|
||||
Encode a byte array according to [RFC 26](https://rfc.vac.dev/spec/26/). This function can be used to encrypt the payload of a waku message
|
||||
|
||||
**Parameters**
|
||||
1. `char* data`: byte array to encode in base64 format. (gowaku_utils_base64_encode can be used to encode the message)
|
||||
2. `char* keyType`: defines the type of key to use:
|
||||
- `NONE`: no encryption will be applied
|
||||
- `ASYMMETRIC`: encrypt the payload using a secp256k1 public key
|
||||
- `SYMMETRIC`: encrypt the payload using a 32 bit key.
|
||||
3. `char* key`: hex key (`0x123...abc`) used for encrypting the `data`.
|
||||
- When `version` is 0: No encryption is used
|
||||
- When `version` is 1
|
||||
- If using `ASYMMETRIC` encoding, `key` must contain a secp256k1 public key to encrypt the data with
|
||||
- If using `SYMMETRIC` encoding, `key` must contain a 32 bytes symmetric key.
|
||||
4. `char* signingKey`: Hex string containing a secp256k1 private key to sign the encoded message, It's optional. To not sign the message use `NULL` instead.
|
||||
5. `int version`: is used to define the type of payload encryption
|
||||
|
||||
**Returns**
|
||||
`JSONResponse` with the base64 encoded payload. An `error` message otherwise.
|
||||
|
||||
---
|
||||
|
||||
### `extern char* gowaku_decode_data(char* data, char* keyType, char* key, int version)`
|
||||
Decode a byte array according to [RFC 26](https://rfc.vac.dev/spec/26/). This function can be used to decrypt the payload of a waku message
|
||||
|
||||
**Parameters**
|
||||
1. `char* data`: byte array to decode, in base64.
|
||||
2. `char* keyType`: defines the type of key to use:
|
||||
- `NONE`: no encryption was used in the payload
|
||||
- `ASYMMETRIC`: decrypt the payload using a secp256k1 public key
|
||||
- `SYMMETRIC`: decrypt the payload using a 32 bit key.
|
||||
3. `char* key`: hex key (`0x123...abc`) used for decrypting the `data`.
|
||||
- When `version` is 0: No encryption is used
|
||||
- When `version` is 1
|
||||
- If using `ASYMMETRIC` encoding, `key` must contain a secp256k1 private key to decrypt the data
|
||||
- If using `SYMMETRIC` encoding, `key` must contain a 32 bytes symmetric key.
|
||||
4. `int version`: is used to define the type of payload encryption
|
||||
|
||||
**Returns**
|
||||
`JSONResponse` with the decoded payload. An `error` message otherwise. The decoded payload has this format:
|
||||
```json
|
||||
{
|
||||
"result": {
|
||||
"pubkey":"0x04123...abc", // secp256k1 public key
|
||||
"signature":"0x123...abc", // secp256k1 signature
|
||||
"data":"...", // base64 encoded
|
||||
"padding":"..." // base64 encoded
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `extern char* gowaku_utils_base64_encode(char* data)`
|
||||
Encode a byte array to base64 useful for creating the payload of a waku message in the format understood by `gowaku_relay_publish`
|
||||
|
||||
**Parameters**
|
||||
1. `char* data`: byte array to encode
|
||||
|
||||
**Returns**
|
||||
A `char *` containing the base64 encoded byte array
|
||||
|
||||
---
|
||||
|
||||
### `extern char* gowaku_utils_base64_decode(char* data)`
|
||||
Decode a base64 string (useful for reading the payload from waku messages)
|
||||
|
||||
**Parameters**
|
||||
1. `char* data`: base64 encoded byte array to decode
|
||||
|
||||
**Returns**
|
||||
`JSONResponse` with the decoded payload. An `error` message otherwise. The decoded payload has this format:
|
||||
|
||||
|
||||
|
||||
# Copyright
|
||||
|
||||
Copyright and related rights waived via
|
||||
[CC0](https://creativecommons.org/publicdomain/zero/1.0/).
|
|
@ -66,12 +66,14 @@ type WakuConfig struct {
|
|||
NodeKey *string `json:"nodeKey,omitempty"`
|
||||
KeepAliveInterval *int `json:"keepAliveInterval,omitempty"`
|
||||
EnableRelay *bool `json:"relay"`
|
||||
MinPeersToPublish *int `json:"minPeersToPublish`
|
||||
}
|
||||
|
||||
var DefaultHost = "0.0.0.0"
|
||||
var DefaultPort = 60000
|
||||
var DefaultKeepAliveInterval = 20
|
||||
var DefaultEnableRelay = true
|
||||
var DefaultMinPeersToPublish = 0
|
||||
|
||||
func getConfig(configJSON *C.char) (WakuConfig, error) {
|
||||
var config WakuConfig
|
||||
|
@ -102,6 +104,10 @@ func getConfig(configJSON *C.char) (WakuConfig, error) {
|
|||
config.KeepAliveInterval = &DefaultKeepAliveInterval
|
||||
}
|
||||
|
||||
if config.MinPeersToPublish == nil {
|
||||
config.MinPeersToPublish = &DefaultMinPeersToPublish
|
||||
}
|
||||
|
||||
return config, nil
|
||||
}
|
||||
|
||||
|
@ -155,7 +161,7 @@ func gowaku_new(configJSON *C.char) *C.char {
|
|||
}
|
||||
|
||||
if *config.EnableRelay {
|
||||
opts = append(opts, node.WithWakuRelay())
|
||||
opts = append(opts, node.WithWakuRelayAndMinPeers(*config.MinPeersToPublish))
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
|
@ -207,9 +213,9 @@ func gowaku_stop(nodeID C.int) *C.char {
|
|||
return makeJSONResponse(nil)
|
||||
}
|
||||
|
||||
//export gowaku_id
|
||||
//export gowaku_peerid
|
||||
// Obtain the peer ID of the waku node
|
||||
func gowaku_id(nodeID C.int) *C.char {
|
||||
func gowaku_peerid(nodeID C.int) *C.char {
|
||||
mutex.Lock()
|
||||
defer mutex.Unlock()
|
||||
wakuNode, ok := nodes[int(nodeID)]
|
||||
|
@ -279,7 +285,7 @@ func gowaku_dial_peer(nodeID C.int, address *C.char, ms C.int) *C.char {
|
|||
|
||||
//export gowaku_dial_peerid
|
||||
// Dial known peer by peerID. if ms > 0, cancel the function execution if it takes longer than N milliseconds
|
||||
func gowaku_dial_peerid(nodeID C.int, id *C.char, ms C.int) *C.char {
|
||||
func gowaku_dial_peerid(nodeID C.int, peerID *C.char, ms C.int) *C.char {
|
||||
mutex.Lock()
|
||||
defer mutex.Unlock()
|
||||
wakuNode, ok := nodes[int(nodeID)]
|
||||
|
@ -290,7 +296,7 @@ func gowaku_dial_peerid(nodeID C.int, id *C.char, ms C.int) *C.char {
|
|||
var ctx context.Context
|
||||
var cancel context.CancelFunc
|
||||
|
||||
peerID, err := peer.Decode(C.GoString(id))
|
||||
pID, err := peer.Decode(C.GoString(peerID))
|
||||
if err != nil {
|
||||
return makeJSONResponse(err)
|
||||
}
|
||||
|
@ -302,7 +308,7 @@ func gowaku_dial_peerid(nodeID C.int, id *C.char, ms C.int) *C.char {
|
|||
ctx = context.Background()
|
||||
}
|
||||
|
||||
err = wakuNode.DialPeerByID(ctx, peerID)
|
||||
err = wakuNode.DialPeerByID(ctx, pID)
|
||||
return makeJSONResponse(err)
|
||||
}
|
||||
|
||||
|
@ -322,7 +328,7 @@ func gowaku_close_peer(nodeID C.int, address *C.char) *C.char {
|
|||
|
||||
//export gowaku_close_peerid
|
||||
// Close connection to a known peer by peerID
|
||||
func gowaku_close_peerid(nodeID C.int, id *C.char) *C.char {
|
||||
func gowaku_close_peerid(nodeID C.int, peerID *C.char) *C.char {
|
||||
mutex.Lock()
|
||||
defer mutex.Unlock()
|
||||
wakuNode, ok := nodes[int(nodeID)]
|
||||
|
@ -330,12 +336,12 @@ func gowaku_close_peerid(nodeID C.int, id *C.char) *C.char {
|
|||
return makeJSONResponse(ErrWakuNodeNotReady)
|
||||
}
|
||||
|
||||
peerID, err := peer.Decode(C.GoString(id))
|
||||
pID, err := peer.Decode(C.GoString(peerID))
|
||||
if err != nil {
|
||||
return makeJSONResponse(err)
|
||||
}
|
||||
|
||||
err = wakuNode.ClosePeerById(peerID)
|
||||
err = wakuNode.ClosePeerById(pID)
|
||||
return makeJSONResponse(err)
|
||||
}
|
||||
|
||||
|
@ -355,7 +361,7 @@ func gowaku_peer_cnt(nodeID C.int) *C.char {
|
|||
//export gowaku_content_topic
|
||||
// Create a content topic string according to RFC 23
|
||||
func gowaku_content_topic(applicationName *C.char, applicationVersion C.uint, contentTopicName *C.char, encoding *C.char) *C.char {
|
||||
return prepareJSONResponse(protocol.NewContentTopic(C.GoString(applicationName), uint(applicationVersion), C.GoString(contentTopicName), C.GoString(encoding)).String(), nil)
|
||||
return C.CString(protocol.NewContentTopic(C.GoString(applicationName), uint(applicationVersion), C.GoString(contentTopicName), C.GoString(encoding)).String())
|
||||
}
|
||||
|
||||
//export gowaku_pubsub_topic
|
||||
|
@ -367,7 +373,7 @@ func gowaku_pubsub_topic(name *C.char, encoding *C.char) *C.char {
|
|||
//export gowaku_default_pubsub_topic
|
||||
// Get the default pubsub topic used in waku2: /waku/2/default-waku/proto
|
||||
func gowaku_default_pubsub_topic() *C.char {
|
||||
return prepareJSONResponse(protocol.DefaultPubsubTopic().String(), nil)
|
||||
return C.CString(protocol.DefaultPubsubTopic().String())
|
||||
}
|
||||
|
||||
func publish(nodeID int, message string, pubsubTopic string, ms int) (string, error) {
|
||||
|
@ -442,16 +448,18 @@ func gowaku_set_event_callback(cb unsafe.Pointer) {
|
|||
}
|
||||
|
||||
type SubscriptionMsg struct {
|
||||
MessageID string `json:"messageID"`
|
||||
PubsubTopic string `json:"pubsubTopic"`
|
||||
Message *pb.WakuMessage `json:"wakuMessage"`
|
||||
MessageID string `json:"messageID"`
|
||||
SubscriptionID string `json:"subscriptionID"`
|
||||
PubsubTopic string `json:"pubsubTopic"`
|
||||
Message *pb.WakuMessage `json:"wakuMessage"`
|
||||
}
|
||||
|
||||
func toSubscriptionMessage(msg *protocol.Envelope) *SubscriptionMsg {
|
||||
func toSubscriptionMessage(subsID string, msg *protocol.Envelope) *SubscriptionMsg {
|
||||
return &SubscriptionMsg{
|
||||
MessageID: hexutil.Encode(msg.Hash()),
|
||||
PubsubTopic: msg.PubsubTopic(),
|
||||
Message: msg.Message(),
|
||||
SubscriptionID: subsID,
|
||||
MessageID: hexutil.Encode(msg.Hash()),
|
||||
PubsubTopic: msg.PubsubTopic(),
|
||||
Message: msg.Message(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -460,7 +468,7 @@ func toSubscriptionMessage(msg *protocol.Envelope) *SubscriptionMsg {
|
|||
// to the default topic. Returns a json response containing the subscription ID
|
||||
// or an error message. When a message is received, a "message" is emitted containing
|
||||
// the message, pubsub topic, and nodeID in which the message was received
|
||||
func gowaku_relay_subscribe(nodeID int, topic *C.char) *C.char {
|
||||
func gowaku_relay_subscribe(nodeID C.int, topic *C.char) *C.char {
|
||||
mutex.Lock()
|
||||
defer mutex.Unlock()
|
||||
wakuNode, ok := nodes[int(nodeID)]
|
||||
|
@ -483,7 +491,7 @@ func gowaku_relay_subscribe(nodeID int, topic *C.char) *C.char {
|
|||
|
||||
go func() {
|
||||
for envelope := range subscription.C {
|
||||
send(nodeID, "message", toSubscriptionMessage(envelope))
|
||||
send(int(nodeID), "message", toSubscriptionMessage(subsID, envelope))
|
||||
}
|
||||
}()
|
||||
|
||||
|
@ -493,7 +501,7 @@ func gowaku_relay_subscribe(nodeID int, topic *C.char) *C.char {
|
|||
//export gowaku_relay_unsubscribe_from_topic
|
||||
// Closes the pubsub subscription to a pubsub topic. Existing subscriptions
|
||||
// will not be closed, but they will stop receiving messages
|
||||
func gowaku_relay_unsubscribe_from_topic(nodeID int, topic *C.char) *C.char {
|
||||
func gowaku_relay_unsubscribe_from_topic(nodeID C.int, topic *C.char) *C.char {
|
||||
mutex.Lock()
|
||||
defer mutex.Unlock()
|
||||
wakuNode, ok := nodes[int(nodeID)]
|
||||
|
@ -516,7 +524,7 @@ func gowaku_relay_unsubscribe_from_topic(nodeID int, topic *C.char) *C.char {
|
|||
|
||||
//export gowaku_relay_close_subscription
|
||||
// Closes a waku relay subscription
|
||||
func gowaku_relay_close_subscription(nodeID int, subsID *C.char) *C.char {
|
||||
func gowaku_relay_close_subscription(nodeID C.int, subsID *C.char) *C.char {
|
||||
mutex.Lock()
|
||||
defer mutex.Unlock()
|
||||
wakuNode, ok := nodes[int(nodeID)]
|
||||
|
@ -537,8 +545,8 @@ func gowaku_relay_close_subscription(nodeID int, subsID *C.char) *C.char {
|
|||
}
|
||||
|
||||
//export gowaku_peers
|
||||
// Retrieve the list of peers connected to the waku node
|
||||
func gowaku_peers(nodeID int) *C.char {
|
||||
// Retrieve the list of peers known by the waku node
|
||||
func gowaku_peers(nodeID C.int) *C.char {
|
||||
mutex.Lock()
|
||||
defer mutex.Unlock()
|
||||
wakuNode, ok := nodes[int(nodeID)]
|
||||
|
@ -604,8 +612,13 @@ func gowaku_encode_data(data *C.char, keyType *C.char, key *C.char, signingKey *
|
|||
keyInfo.PubKey = *pubK
|
||||
}
|
||||
|
||||
b, err := base64.StdEncoding.DecodeString(C.GoString(data))
|
||||
if err != nil {
|
||||
return makeJSONResponse(err)
|
||||
}
|
||||
|
||||
payload := node.Payload{
|
||||
Data: []byte(C.GoString(data)),
|
||||
Data: b,
|
||||
Key: keyInfo,
|
||||
}
|
||||
|
||||
|
@ -689,7 +702,8 @@ func gowaku_utils_base64_decode(data *C.char) *C.char {
|
|||
// format understood by gowaku_relay_publish)
|
||||
func gowaku_utils_base64_encode(data *C.char) *C.char {
|
||||
str := base64.StdEncoding.EncodeToString([]byte(C.GoString(data)))
|
||||
return prepareJSONResponse(str, nil)
|
||||
return C.CString(string(str))
|
||||
|
||||
}
|
||||
|
||||
// TODO:
|
||||
|
|
|
@ -5,51 +5,29 @@ import (
|
|||
"encoding/json"
|
||||
)
|
||||
|
||||
const (
|
||||
codeUnknown int = iota
|
||||
// special codes
|
||||
codeFailedParseResponse
|
||||
// codeFailedParseParams
|
||||
)
|
||||
|
||||
var errToCodeMap = map[error]int{
|
||||
//transactions.ErrInvalidTxSender: codeErrInvalidTxSender,
|
||||
}
|
||||
|
||||
type jsonrpcSuccessfulResponse struct {
|
||||
type JSONResponse struct {
|
||||
Error *string `json:"error,omitempty"`
|
||||
Result interface{} `json:"result"`
|
||||
}
|
||||
|
||||
type jsonrpcErrorResponse struct {
|
||||
Error jsonError `json:"error"`
|
||||
}
|
||||
|
||||
type jsonError struct {
|
||||
Code int `json:"code,omitempty"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
func prepareJSONResponse(result interface{}, err error) *C.char {
|
||||
code := codeUnknown
|
||||
if c, ok := errToCodeMap[err]; ok {
|
||||
code = c
|
||||
}
|
||||
|
||||
return prepareJSONResponseWithCode(result, err, code)
|
||||
}
|
||||
|
||||
func prepareJSONResponseWithCode(result interface{}, err error, code int) *C.char {
|
||||
if err != nil {
|
||||
errResponse := jsonrpcErrorResponse{
|
||||
Error: jsonError{Code: code, Message: err.Error()},
|
||||
errStr := err.Error()
|
||||
errResponse := JSONResponse{
|
||||
Error: &errStr,
|
||||
}
|
||||
response, _ := json.Marshal(&errResponse)
|
||||
return C.CString(string(response))
|
||||
}
|
||||
|
||||
data, err := json.Marshal(jsonrpcSuccessfulResponse{result})
|
||||
data, err := json.Marshal(JSONResponse{Result: result})
|
||||
if err != nil {
|
||||
return prepareJSONResponseWithCode(nil, err, codeFailedParseResponse)
|
||||
return prepareJSONResponse(nil, err)
|
||||
}
|
||||
return C.CString(string(data))
|
||||
}
|
||||
|
@ -61,7 +39,7 @@ func makeJSONResponse(err error) *C.char {
|
|||
errString = &errStr
|
||||
}
|
||||
|
||||
out := APIResponse{
|
||||
out := JSONResponse{
|
||||
Error: errString,
|
||||
}
|
||||
outBytes, _ := json.Marshal(out)
|
||||
|
|
|
@ -14,6 +14,13 @@ import (
|
|||
"unsafe"
|
||||
)
|
||||
|
||||
// SignalHandler defines a minimal interface
|
||||
// a signal handler needs to implement.
|
||||
//nolint
|
||||
type SignalHandler interface {
|
||||
HandleSignal(string)
|
||||
}
|
||||
|
||||
// SignalHandler is a simple callback function that gets called when any signal is received
|
||||
type MobileSignalHandler func([]byte)
|
||||
|
||||
|
|
|
@ -1,74 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// APIResponse generic response from API.
|
||||
type APIResponse struct {
|
||||
Error *string `json:"error"`
|
||||
}
|
||||
|
||||
// APIDetailedResponse represents a generic response
|
||||
// with possible errors.
|
||||
//nolint
|
||||
type APIDetailedResponse struct {
|
||||
Status bool `json:"status"`
|
||||
Message string `json:"message,omitempty"`
|
||||
FieldErrors []APIFieldError `json:"field_errors,omitempty"`
|
||||
}
|
||||
|
||||
// Error string representation of APIDetailedResponse.
|
||||
//nolint
|
||||
func (r APIDetailedResponse) Error() string {
|
||||
buf := bytes.NewBufferString("")
|
||||
|
||||
for _, err := range r.FieldErrors {
|
||||
buf.WriteString(err.Error() + "\n") // nolint: gas
|
||||
}
|
||||
|
||||
return strings.TrimSpace(buf.String())
|
||||
}
|
||||
|
||||
// APIFieldError represents a set of errors
|
||||
// related to a parameter.
|
||||
//nolint
|
||||
type APIFieldError struct {
|
||||
Parameter string `json:"parameter,omitempty"`
|
||||
Errors []APIError `json:"errors"`
|
||||
}
|
||||
|
||||
// Error string representation of APIFieldError.
|
||||
func (e APIFieldError) Error() string {
|
||||
if len(e.Errors) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
buf := bytes.NewBufferString(fmt.Sprintf("Parameter: %s\n", e.Parameter))
|
||||
|
||||
for _, err := range e.Errors {
|
||||
buf.WriteString(err.Error() + "\n") // nolint: gas
|
||||
}
|
||||
|
||||
return strings.TrimSpace(buf.String())
|
||||
}
|
||||
|
||||
// APIError represents a single error.
|
||||
//nolint
|
||||
type APIError struct {
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
// Error string representation of APIError.
|
||||
func (e APIError) Error() string {
|
||||
return fmt.Sprintf("message=%s", e.Message)
|
||||
}
|
||||
|
||||
// SignalHandler defines a minimal interface
|
||||
// a signal handler needs to implement.
|
||||
//nolint
|
||||
type SignalHandler interface {
|
||||
HandleSignal(string)
|
||||
}
|
|
@ -39,10 +39,10 @@ import (
|
|||
)
|
||||
|
||||
type Peer struct {
|
||||
ID peer.ID
|
||||
Protocols []string
|
||||
Addrs []ma.Multiaddr
|
||||
Connected bool
|
||||
ID peer.ID `json:"peerID"`
|
||||
Protocols []string `json:"protocols"`
|
||||
Addrs []ma.Multiaddr `json:"addrs"`
|
||||
Connected bool `json:"connected"`
|
||||
}
|
||||
|
||||
type storeFactory func(w *WakuNode) store.Store
|
||||
|
|
Loading…
Reference in New Issue