Files
nym/sdk/ffi/go/example.go
mx 60fa5cfeb8 Max/rust sdk stream abstraction (#4743)
* add TcpProxyClient and TcpProxyServer abstractions to SDK 
* add single connection example
* add multi-connection example 
* add simple echo server to `tools/`: used for multi-connection example 
* update FFI toml files: switched to local imports 
* add proxy bindings to `ffi/shared`
* add proxy bindings and example to `ffi/go` 
* add note to `ffi/cpp` about lack of Proxy bindings for the moment
2024-09-24 09:29:46 +00:00

84 lines
3.1 KiB
Go

package main
import (
"fmt"
"nymffi/go-nym/bindings"
"time"
)
/*
Flow showing:
- setting up Nym client logging
- creating an ephemeral Nym client (no key storage / persistent address - this will come in a future iteration)
- getting its [Nym address](https://nymtech.net/docs/clients/addressing-system.html)
- using that address to send a message to yourself via the Mixnet
- listen for and parse the incoming message for the `sender_tag` used for [anonymous replies with SURBs] (https://nymtech.net/docs/architecture/traffic-flow.html#private-replies-using-surbs)
- send a reply to yourself using SURBs
*/
func main() {
// initialise Nym client logging - this is quite verbose but very informative
bindings.InitLogging()
// initialise an ephemeral client - aka one without specified keystore
err := bindings.InitEphemeral()
if err != nil {
fmt.Println(err)
return
}
// get our client's address
str, err2 := bindings.GetSelfAddress()
if err2 != nil {
fmt.Println("(Go) Error:", err2)
return
}
fmt.Println("(Go) response:")
fmt.Println(str)
// send a message through the mixnet - in this case to ourselves using the value from GetSelfAddress
err3 := bindings.SendMessage(str, "helloworld")
if err3 != nil {
fmt.Println("(Go) Error:", err3)
return
}
// listen out for incoming messages: in the future the client can be split into a listening and a sending client,
// allowing for this to run as a persistent process in its own thread and not have to block but instead be running
// concurrently
//
// assuming a data type like so:
// type IncomingMessage struct {
// Message string
// SenderTag vec<u8>
// }
incomingMessage, err4 := bindings.ListenForIncoming()
if err4 != nil {
fmt.Println("(Go) Error:", err4)
return
}
fmt.Println("(Go) incoming message: ", incomingMessage.Message, " from: ", incomingMessage.Sender)
// we can just use the byte array we parsed from the incoming message to reply with: this is a
// byte representation of the sender_tag used for Single Use Reply Blocks (SURBs)
//
// replying to incoming message (from ourselves) with SURBs - note that sending a message to a recipient and
// replying to an incoming are different functions: replying relies on parsing the incoming sender_tag on the Rust
// side and creating an AnonymousSenderTag type, instead of the Recipient type which relies on a nym address
//
// you will see in the client logs that there are requests for more SURBs that we send to ourselves to
// be able to fit the full reply message in there. In a future iteration of this code we can also expose
// a send() which allows for developers to dictate the number of SURBs to send along with their outgoing message
fmt.Println("(Go) replying to received message")
err5 := bindings.Reply(incomingMessage.Sender, "replyworld")
if err5 != nil {
fmt.Println("(Go) Error:", err5)
return
}
// sleep so that the nym client processes can catch up - in reality you'd have another process
// running to keep logging going, so this is only necessary for this reference
time.Sleep(30 * time.Second)
fmt.Println("(Go) end go example")
}