//////////////////////////////////////////////////////////////////////////////// // Copyright © 2020 xx network SEZC // // // // Use of this source code is governed by a license that can be found in the // // LICENSE file // //////////////////////////////////////////////////////////////////////////////// //go:build js && wasm package wasm import ( "gitlab.com/elixxir/client/bindings" "syscall/js" ) // Connection wraps the [bindings.Connection] object so its methods can be // wrapped to be Javascript compatible. type Connection struct { c *bindings.Connection } // newConnectJS creates a new Javascript compatible object // (map[string]interface{}) that matches the Connection structure. func newConnectJS(api *bindings.Connection) map[string]interface{} { c := Connection{api} connection := map[string]interface{}{ // connect.go "GetID": js.FuncOf(c.GetID), "SendE2E": js.FuncOf(c.SendE2E), "Close": js.FuncOf(c.Close), "GetPartner": js.FuncOf(c.GetPartner), "RegisterListener": js.FuncOf(c.RegisterListener), } return connection } // GetID returns the ID for this [bindings.Connection] in the connectionTracker. // // Returns: // - int of the ID func (c *Connection) GetID(js.Value, []js.Value) interface{} { return c.c.GetId() } // Connect performs auth key negotiation with the given recipient and returns a // Connection object for the newly created [partner.Manager]. // // This function is to be used sender-side and will block until the // [partner.Manager] is confirmed. // // Parameters: // - args[0] - ID of the E2E object in the E2E tracker (int). // - args[1] - marshalled recipient [contact.Contact] (Uint8Array). // - args[3] - JSON of [xxdk.E2EParams] (Uint8Array). // // Returns: // - Javascript representation of the Connection object // - throws a TypeError if creating loading the parameters or connecting fails func (c *Cmix) Connect(_ js.Value, args []js.Value) interface{} { recipientContact := CopyBytesToGo(args[1]) e2eParamsJSON := CopyBytesToGo(args[2]) api, err := c.api.Connect(args[0].Int(), recipientContact, e2eParamsJSON) if err != nil { Throw(TypeError, err.Error()) return nil } return newConnectJS(api) } // SendE2E is a wrapper for sending specifically to the Connection's // [partner.Manager]. // // Returns: // - []byte - the JSON marshalled bytes of the E2ESendReport object, which can // be passed into WaitForRoundResult to see if the send succeeded. // // Parameters: // - args[0] - message type from [catalog.MessageType] (int) // - args[1] - message payload (Uint8Array) // // Returns: // - JSON of [bindings.E2ESendReport], which can be passed into // cmix.WaitForRoundResult to see if the send succeeded (Uint8Array) // - throws a TypeError if sending fails func (c *Connection) SendE2E(_ js.Value, args []js.Value) interface{} { sendReport, err := c.c.SendE2E(args[0].Int(), CopyBytesToGo(args[1])) if err != nil { Throw(TypeError, err.Error()) return nil } return CopyBytesToJS(sendReport) } // Close deletes this Connection's partner.Manager and releases resources. // // Returns: // - throws a TypeError if closing fails func (c *Connection) Close(js.Value, []js.Value) interface{} { err := c.c.Close() if err != nil { Throw(TypeError, err.Error()) return nil } return nil } // GetPartner returns the partner.Manager for this Connection. // // Returns: // - bytes of the partner's [id.ID] (Uint8Array) func (c *Connection) GetPartner(js.Value, []js.Value) interface{} { return CopyBytesToJS(c.c.GetPartner()) } // listener adheres to the [bindings.Listener] interface. type listener struct { hear func(args ...interface{}) js.Value name func(args ...interface{}) js.Value } func (l *listener) Hear(item []byte) { l.hear(CopyBytesToJS(item)) } func (l *listener) Name() string { return l.name().String() } // RegisterListener is used for E2E reception and allows for reading data sent // from the partner.Manager. // // Parameters: // - args[0] - message type from [catalog.MessageType] (int) // - args[1] - Javascript object that has functions that implement the // [bindings.Listener] interface // // Returns: // - throws a TypeError is registering the listener fails func (c *Connection) RegisterListener(_ js.Value, args []js.Value) interface{} { err := c.c.RegisterListener(args[0].Int(), &listener{args[1].Get("Hear").Invoke, args[1].Get("Name").Invoke}) if err != nil { Throw(TypeError, err.Error()) return nil } return nil }