-
Notifications
You must be signed in to change notification settings - Fork 2
/
main.go
148 lines (132 loc) · 3.96 KB
/
main.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
package main
import (
"context"
"fmt"
"io/ioutil"
"net/http"
"os"
"strings"
"github.com/metadium/go-delegator/metaresolver"
"github.com/metadium/go-delegator/crypto"
_ "github.com/metadium/go-delegator/ipfs"
"github.com/metadium/go-delegator/json"
"github.com/metadium/go-delegator/log"
"github.com/metadium/go-delegator/metaservice"
"github.com/metadium/go-delegator/rpc"
"github.com/aws/aws-lambda-go/events"
"github.com/aws/aws-lambda-go/lambda"
"github.com/fvbock/endless"
)
const (
// ParamFuncName is a name indicating function's
ParamFuncName = "func"
// Targetnet indicates target network
Targetnet = rpc.Testnet
)
func handler(req json.RPCRequest) (body string, statusCode int) {
//log.Info("request:", req.String())
var resp json.RPCResponse
var err error
if metaresolver.Contains(req.Method) {
// Forward RPC request to metaservice function (v3)
resp, err = metaresolver.Forward(req)
} else if metaservice.Contains(req.Method) {
// Forward RPC request to metaservice function (v2)
resp, err = metaservice.Forward(req)
} else {
// Forward RPC request to Ether node
var respBody string
if respBody, err = rpc.GetInstance().DoRPC(req); err == nil {
// Relay a response from the node
resp = json.GetRPCResponseFromJSON(respBody)
}
}
statusCode = 200
if err != nil {
// In case of server-side RPC fail
log.Error(err.Error())
resp.Error = &json.RPCError{
Code: -1,
Message: err.Error(),
}
statusCode = 400
}
body = resp.String()
return
}
// lambdaHandler handles APIGatewayProxyRequest as JSON-RPC request
func lambdaHandler(ctx context.Context, request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
// Validate RPC request
req := json.GetRPCRequestFromJSON(request.Body)
if method := request.QueryStringParameters[ParamFuncName]; method != "" {
req.Method = method
} else if method := request.PathParameters[ParamFuncName]; method != "" {
req.Method = method
}
respBody, statusCode := handler(req)
return events.APIGatewayProxyResponse{Body: respBody, StatusCode: statusCode}, nil
}
// httpHandler handles http.Request as JSON-RPC request
func httpHandler(w http.ResponseWriter, r *http.Request) {
b, err := ioutil.ReadAll(r.Body)
defer r.Body.Close()
if err != nil {
http.Error(w, err.Error(), 500)
return
}
log.Info("request:", r.RemoteAddr, string(b))
req := json.GetRPCRequestFromJSON(string(b))
respBody, statusCode := handler(req)
log.Info("response:", r.RemoteAddr, statusCode, respBody)
w.WriteHeader(statusCode)
w.Write([]byte(respBody))
}
func help() {
fmt.Println("USAGE")
fmt.Println(" Option 1. key path only as argument")
fmt.Println(" $> proxy [path]")
fmt.Println(" Option 2. key path and passphrase as argument")
fmt.Println(" $> .proxy [path] [passphrase]")
fmt.Println(" Option 3. key path and passphrase as environment variable")
fmt.Println(" $> export KEY_PATH=[path]")
fmt.Println(" $> export KEY_PASSPHRASE=[passphrase]")
fmt.Println(" $> proxy")
}
func init() {
rpc.NetType = Targetnet
// Initialize Crypto with arguments
var path, passphrase string
if path = os.Getenv(crypto.Path); path != "" {
passphrase = os.Getenv(crypto.Passphrase)
os.Setenv(crypto.Path, "")
os.Setenv(crypto.Passphrase, "")
} else if len(os.Args) > 1 && !strings.HasPrefix(os.Args[1], "-") && os.Args[1] != "help" {
path = os.Args[1]
if len(os.Args) > 2 && !strings.HasPrefix(os.Args[2], "-") {
passphrase = os.Args[2]
} else {
fmt.Printf("Passphrase: ")
fmt.Scanln(&passphrase)
}
} else {
help()
log.Panic("Please refer above help")
}
go func() {
crypto.PathChan <- path
crypto.PassphraseChan <- passphrase
}()
crypto.GetInstance()
}
func main() {
log.Info("Server starting...")
if os.Getenv(crypto.IsAwsLambda) != "" {
log.Info("Ready to start Lambda")
lambda.Start(lambdaHandler)
} else {
log.Info("Ready to start HTTP/HTTPS")
h := http.NewServeMux()
h.HandleFunc("/", httpHandler)
endless.ListenAndServe(":8545", h)
}
}