mirror of
https://github.com/status-im/status-keycard-go.git
synced 2025-02-14 15:26:35 +00:00
* feat: KeycardContextV2 * feat: ApplicationInfoV2 with string version * feat: rpc service * feat: http server for the session API * feat: ensure api mutual exclusivity * chore: go mod tidy
86 lines
1.8 KiB
Go
86 lines
1.8 KiB
Go
package main
|
|
|
|
import "C"
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"net/http/httptest"
|
|
|
|
"github.com/gorilla/rpc"
|
|
"github.com/pkg/errors"
|
|
"go.uber.org/zap"
|
|
|
|
"github.com/status-im/status-keycard-go/pkg/session"
|
|
)
|
|
|
|
var (
|
|
globalRPCServer *rpc.Server
|
|
)
|
|
|
|
func marshalError(err error) *C.char {
|
|
response := struct {
|
|
Error string `json:"error"`
|
|
}{
|
|
Error: "",
|
|
}
|
|
if err != nil {
|
|
response.Error = err.Error()
|
|
}
|
|
responseBytes, _ := json.Marshal(response)
|
|
return C.CString(string(responseBytes))
|
|
}
|
|
|
|
//export KeycardInitializeRPC
|
|
func KeycardInitializeRPC() *C.char {
|
|
if err := checkAPIMutualExclusion(sessionAPI); err != nil {
|
|
return marshalError(err)
|
|
}
|
|
|
|
// TEMP: Replace with logging to a file, take the path as an argument
|
|
logger, err := zap.NewDevelopment()
|
|
if err != nil {
|
|
fmt.Printf("failed to initialize log: %v\n", err)
|
|
}
|
|
zap.ReplaceGlobals(logger)
|
|
|
|
rpcServer, err := session.CreateRPCServer()
|
|
if err != nil {
|
|
return marshalError(err)
|
|
}
|
|
globalRPCServer = rpcServer
|
|
logger.Info("RPC server initialized")
|
|
return marshalError(nil)
|
|
}
|
|
|
|
//export KeycardCallRPC
|
|
func KeycardCallRPC(payload *C.char) *C.char {
|
|
if globalRPCServer == nil {
|
|
return marshalError(errors.New("RPC server not initialized"))
|
|
}
|
|
|
|
payloadBytes := []byte(C.GoString(payload))
|
|
|
|
// Create a fake HTTP request
|
|
req := httptest.NewRequest("POST", "/rpc", bytes.NewBuffer(payloadBytes))
|
|
req.Header.Set("Content-Type", "application/json")
|
|
|
|
// Create a fake HTTP response writer
|
|
rr := httptest.NewRecorder()
|
|
|
|
// Call the server's ServeHTTP method
|
|
globalRPCServer.ServeHTTP(rr, req)
|
|
|
|
// Read and return the response body
|
|
resp := rr.Result()
|
|
defer resp.Body.Close()
|
|
|
|
body, err := io.ReadAll(resp.Body)
|
|
if err != nil {
|
|
return marshalError(errors.Wrap(err, "internal error reading response body"))
|
|
}
|
|
|
|
return C.CString(string(body))
|
|
}
|