forked from status-im/status-go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
handlers.go
152 lines (126 loc) · 3.97 KB
/
handlers.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
package jail
import (
"github.com/robertkrimen/otto"
"github.com/status-im/status-go/geth/node"
)
const (
EventLocalStorageSet = "local_storage.set"
EventSendMessage = "jail.send_message"
EventShowSuggestions = "jail.show_suggestions"
LocalStorageMaxDataLen = 256
)
// registerHandlers augments and transforms a given jail cell's underlying VM,
// by adding and replacing method handlers.
func registerHandlers(jail *Jail, vm *otto.Otto, chatID string) (err error) {
jeth, err := vm.Get("jeth")
if err != nil {
return err
}
registerHandler := jeth.Object().Set
// register send handler
if err = registerHandler("send", makeSendHandler(jail, chatID)); err != nil {
return err
}
// register sendAsync handler
if err = registerHandler("sendAsync", makeSendHandler(jail, chatID)); err != nil {
return err
}
// register isConnected handler
if err = registerHandler("isConnected", makeJethIsConnectedHandler(jail)); err != nil {
return err
}
// define localStorage
if err = vm.Set("localStorage", struct{}{}); err != nil {
return
}
// register localStorage.set handler
localStorage, err := vm.Get("localStorage")
if err != nil {
return
}
if err = localStorage.Object().Set("set", makeLocalStorageSetHandler(chatID)); err != nil {
return
}
return nil
}
// makeSendHandler returns jeth.send() and jeth.sendAsync() handler
func makeSendHandler(jail *Jail, chatID string) func(call otto.FunctionCall) (response otto.Value) {
return func(call otto.FunctionCall) (response otto.Value) {
return jail.Send(chatID, call)
}
}
// makeJethIsConnectedHandler returns jeth.isConnected() handler
func makeJethIsConnectedHandler(jail *Jail) func(call otto.FunctionCall) (response otto.Value) {
return func(call otto.FunctionCall) otto.Value {
client, err := jail.requestManager.RPCClient()
if err != nil {
return newErrorResponse(call, -32603, err.Error(), nil)
}
var netListeningResult bool
if err := client.Call(&netListeningResult, "net_listening"); err != nil {
return newErrorResponse(call, -32603, err.Error(), nil)
}
if !netListeningResult {
return newErrorResponse(call, -32603, node.ErrNoRunningNode.Error(), nil)
}
return newResultResponse(call, true)
}
}
// LocalStorageSetEvent is a signal sent whenever local storage Set method is called
type LocalStorageSetEvent struct {
ChatID string `json:"chat_id"`
Data string `json:"data"`
}
// makeLocalStorageSetHandler returns localStorage.set() handler
func makeLocalStorageSetHandler(chatID string) func(call otto.FunctionCall) (response otto.Value) {
return func(call otto.FunctionCall) otto.Value {
data := call.Argument(0).String()
if len(data) > LocalStorageMaxDataLen { // cap input string
data = data[:LocalStorageMaxDataLen]
}
node.SendSignal(node.SignalEnvelope{
Type: EventLocalStorageSet,
Event: LocalStorageSetEvent{
ChatID: chatID,
Data: data,
},
})
return newResultResponse(call, true)
}
}
// SendMessageEvent wraps Jail send signals
type SendMessageEvent struct {
ChatID string `json:"chat_id"`
Message string `json:"message"`
}
func makeSendMessageHandler(chatID string) func(call otto.FunctionCall) (response otto.Value) {
return func(call otto.FunctionCall) otto.Value {
message := call.Argument(0).String()
node.SendSignal(node.SignalEnvelope{
Type: EventSendMessage,
Event: SendMessageEvent{
ChatID: chatID,
Message: message,
},
})
return newResultResponse(call, true)
}
}
// ShowSuggestionsEvent wraps Jail show suggestion signals
type ShowSuggestionsEvent struct {
ChatID string `json:"chat_id"`
Markup string `json:"markup"`
}
func makeShowSuggestionsHandler(chatID string) func(call otto.FunctionCall) (response otto.Value) {
return func(call otto.FunctionCall) otto.Value {
suggestionsMarkup := call.Argument(0).String()
node.SendSignal(node.SignalEnvelope{
Type: EventShowSuggestions,
Event: ShowSuggestionsEvent{
ChatID: chatID,
Markup: suggestionsMarkup,
},
})
return newResultResponse(call, true)
}
}