Files
nym/sdk/ffi/go/example.go
T
mx ae6c80f0cd FFI share lib + initial uniffi-bindgen-go implementation (#4394)
* fixed rebase conflict with cargo.lock

* shared cleanup

* moved returncode to shared

* first pass at Go binding structure

* minor cleanup

* working on custom type udl

* trying to get LDFLAG script working

* commit before changing alias -> proper types

* converted CCallbacks from aliases to Struct

* cleanup comments

* temp

* push to share

* cleanup

* trait Lift not implemented for *const i8 issue

* test of refactor:
* move c-specific var casting out of shared/ into cpp/
* error returning in go/ over ffi boundary with uniffi

*  _internal functions ffi wrapper agnostic
* moved lang-specific type conversions to cpp / go bindings and out of
  shared
* got send_message working in c/c++ & go
* split out c/c++-specific types to mod

* cont. with making _internal fns lang agnostic
* working on final fn for C and shared (listening for incoming messages)

* fixed return err on listen_for_incoming

* got full example run running again after shared/ refactor

* removed unused struct

* code comments

* got first runthrough of go example code

* script cleanup

* clean up readme instructions

* clippy

* removed unused imports

* rustfmt

* Update sdk/ffi/go/README.md with link to example file

Co-authored-by: Mark Sinclair <14054343+mmsinclair@users.noreply.github.com>

* updated readme with extra build and usage info

* renamed binding outer directory for nicer path
* moved example file from ffi/main.go -> ./example.go

* updated README with new example file name

---------

Co-authored-by: mfahampshire <mfahampshire@pm.me>
Co-authored-by: Mark Sinclair <14054343+mmsinclair@users.noreply.github.com>
2024-03-18 15:15:59 +01:00

75 lines
2.5 KiB
Go

package main
import (
"fmt"
"nymffi/go-nym/bindings"
"time"
)
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")
}