134 lines
3.5 KiB
Go
134 lines
3.5 KiB
Go
package jail
|
|
|
|
import (
|
|
"os"
|
|
|
|
"github.com/robertkrimen/otto"
|
|
"github.com/status-im/status-go/geth/common"
|
|
"github.com/status-im/status-go/geth/jail/console"
|
|
"github.com/status-im/status-go/geth/node"
|
|
"github.com/status-im/status-go/geth/signal"
|
|
)
|
|
|
|
// signals
|
|
const (
|
|
EventSignal = "jail.signal"
|
|
|
|
// EventConsoleLog defines the event type for the console.log call.
|
|
eventConsoleLog = "vm.console.log"
|
|
)
|
|
|
|
// registerHandlers augments and transforms a given jail cell's underlying VM,
|
|
// by adding and replacing method handlers.
|
|
func registerHandlers(jail *Jail, cell common.JailCell, chatID string) error {
|
|
jeth, err := cell.Get("jeth")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
registerHandler := jeth.Object().Set
|
|
|
|
if err = registerHandler("console", map[string]interface{}{
|
|
"log": func(fn otto.FunctionCall) otto.Value {
|
|
return console.Write(fn, os.Stdout, eventConsoleLog)
|
|
},
|
|
}); err != nil {
|
|
return err
|
|
}
|
|
|
|
// register send handler
|
|
if err = registerHandler("send", makeSendHandler(jail)); err != nil {
|
|
return err
|
|
}
|
|
|
|
// register sendAsync handler
|
|
if err = registerHandler("sendAsync", makeAsyncSendHandler(jail, cell)); err != nil {
|
|
return err
|
|
}
|
|
|
|
// register isConnected handler
|
|
if err = registerHandler("isConnected", makeJethIsConnectedHandler(jail, cell)); err != nil {
|
|
return err
|
|
}
|
|
|
|
// register sendMessage/showSuggestions handlers
|
|
if err = cell.Set("statusSignals", struct{}{}); err != nil {
|
|
return err
|
|
}
|
|
statusSignals, err := cell.Get("statusSignals")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
registerHandler = statusSignals.Object().Set
|
|
|
|
return registerHandler("sendSignal", makeSignalHandler(chatID))
|
|
}
|
|
|
|
// makeAsyncSendHandler returns jeth.sendAsync() handler.
|
|
func makeAsyncSendHandler(jail *Jail, cellInt common.JailCell) func(call otto.FunctionCall) otto.Value {
|
|
// FIXME(tiabc): Get rid of this.
|
|
cell := cellInt.(*Cell)
|
|
return func(call otto.FunctionCall) otto.Value {
|
|
go func() {
|
|
response := jail.Send(call)
|
|
|
|
callback := call.Argument(1)
|
|
if callback.Class() == "Function" {
|
|
// run callback asyncronously with args (error, response)
|
|
err := otto.NullValue()
|
|
cell.CallAsync(callback, err, response)
|
|
}
|
|
}()
|
|
return otto.UndefinedValue()
|
|
}
|
|
}
|
|
|
|
// makeSendHandler returns jeth.send() and jeth.sendAsync() handler
|
|
func makeSendHandler(jail *Jail) func(call otto.FunctionCall) otto.Value {
|
|
return func(call otto.FunctionCall) otto.Value {
|
|
return jail.Send(call)
|
|
}
|
|
}
|
|
|
|
// makeJethIsConnectedHandler returns jeth.isConnected() handler
|
|
func makeJethIsConnectedHandler(jail *Jail, cellInt common.JailCell) func(call otto.FunctionCall) (response otto.Value) {
|
|
// FIXME(tiabc): Get rid of this.
|
|
cell := cellInt.(*Cell)
|
|
return func(call otto.FunctionCall) otto.Value {
|
|
client := jail.nodeManager.RPCClient()
|
|
|
|
var netListeningResult bool
|
|
if err := client.Call(&netListeningResult, "net_listening"); err != nil {
|
|
return newErrorResponseOtto(cell.VM, err.Error(), nil)
|
|
}
|
|
|
|
if !netListeningResult {
|
|
return newErrorResponseOtto(cell.VM, node.ErrNoRunningNode.Error(), nil)
|
|
}
|
|
|
|
return newResultResponse(call.Otto, true)
|
|
}
|
|
}
|
|
|
|
// SignalEvent wraps Jail send signals
|
|
type SignalEvent struct {
|
|
ChatID string `json:"chat_id"`
|
|
Data string `json:"data"`
|
|
}
|
|
|
|
func makeSignalHandler(chatID string) func(call otto.FunctionCall) otto.Value {
|
|
return func(call otto.FunctionCall) otto.Value {
|
|
message := call.Argument(0).String()
|
|
|
|
signal.Send(signal.Envelope{
|
|
Type: EventSignal,
|
|
Event: SignalEvent{
|
|
ChatID: chatID,
|
|
Data: message,
|
|
},
|
|
})
|
|
|
|
return newResultResponse(call.Otto, true)
|
|
}
|
|
}
|