| 
									
										
										
										
											2015-03-15 13:21:54 +07:00
										 |  |  | package rpc | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"encoding/json" | 
					
						
							| 
									
										
										
										
											2015-05-11 01:24:40 +02:00
										 |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2015-05-25 02:27:37 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-20 13:22:01 +01:00
										 |  |  | 	"github.com/ethereum/go-ethereum/jsre" | 
					
						
							|  |  |  | 	"github.com/robertkrimen/otto" | 
					
						
							| 
									
										
										
										
											2015-03-15 13:21:54 +07:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type Jeth struct { | 
					
						
							|  |  |  | 	ethApi *EthereumApi | 
					
						
							| 
									
										
										
										
											2015-03-20 13:22:01 +01:00
										 |  |  | 	re     *jsre.JSRE | 
					
						
							| 
									
										
										
										
											2015-03-15 13:21:54 +07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-25 02:27:37 +02:00
										 |  |  | func NewJeth(ethApi *EthereumApi, re *jsre.JSRE) *Jeth { | 
					
						
							|  |  |  | 	return &Jeth{ethApi, re} | 
					
						
							| 
									
										
										
										
											2015-03-15 13:21:54 +07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-22 02:31:59 +02:00
										 |  |  | func (self *Jeth) err(call otto.FunctionCall, code int, msg string, id interface{}) (response otto.Value) { | 
					
						
							| 
									
										
										
										
											2015-03-15 13:21:54 +07:00
										 |  |  | 	rpcerr := &RpcErrorObject{code, msg} | 
					
						
							| 
									
										
										
										
											2015-04-22 02:31:59 +02:00
										 |  |  | 	call.Otto.Set("ret_jsonrpc", jsonrpcver) | 
					
						
							|  |  |  | 	call.Otto.Set("ret_id", id) | 
					
						
							|  |  |  | 	call.Otto.Set("ret_error", rpcerr) | 
					
						
							|  |  |  | 	response, _ = call.Otto.Run(` | 
					
						
							| 
									
										
										
										
											2015-03-20 13:22:01 +01:00
										 |  |  | 		ret_response = { jsonrpc: ret_jsonrpc, id: ret_id, error: ret_error }; | 
					
						
							|  |  |  | 	`) | 
					
						
							|  |  |  | 	return | 
					
						
							| 
									
										
										
										
											2015-03-15 13:21:54 +07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *Jeth) Send(call otto.FunctionCall) (response otto.Value) { | 
					
						
							|  |  |  | 	reqif, err := call.Argument(0).Export() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2015-04-22 02:31:59 +02:00
										 |  |  | 		return self.err(call, -32700, err.Error(), nil) | 
					
						
							| 
									
										
										
										
											2015-03-15 13:21:54 +07:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	jsonreq, err := json.Marshal(reqif) | 
					
						
							| 
									
										
										
										
											2015-04-22 02:31:59 +02:00
										 |  |  | 	var reqs []RpcRequest | 
					
						
							|  |  |  | 	batch := true | 
					
						
							|  |  |  | 	err = json.Unmarshal(jsonreq, &reqs) | 
					
						
							| 
									
										
										
										
											2015-03-15 13:21:54 +07:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2015-04-22 02:31:59 +02:00
										 |  |  | 		reqs = make([]RpcRequest, 1) | 
					
						
							|  |  |  | 		err = json.Unmarshal(jsonreq, &reqs[0]) | 
					
						
							|  |  |  | 		batch = false | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	call.Otto.Set("response_len", len(reqs)) | 
					
						
							|  |  |  | 	call.Otto.Run("var ret_response = new Array(response_len);") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for i, req := range reqs { | 
					
						
							|  |  |  | 		var respif interface{} | 
					
						
							|  |  |  | 		err = self.ethApi.GetRequestReply(&req, &respif) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							| 
									
										
										
										
											2015-05-11 01:24:40 +02:00
										 |  |  | 			fmt.Println("Error response:", err) | 
					
						
							| 
									
										
										
										
											2015-04-22 02:31:59 +02:00
										 |  |  | 			return self.err(call, -32603, err.Error(), req.Id) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		call.Otto.Set("ret_jsonrpc", jsonrpcver) | 
					
						
							|  |  |  | 		call.Otto.Set("ret_id", req.Id) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		res, _ := json.Marshal(respif) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		call.Otto.Set("ret_result", string(res)) | 
					
						
							|  |  |  | 		call.Otto.Set("response_idx", i) | 
					
						
							|  |  |  | 		response, err = call.Otto.Run(` | 
					
						
							|  |  |  | 		ret_response[response_idx] = { jsonrpc: ret_jsonrpc, id: ret_id, result: JSON.parse(ret_result) }; | 
					
						
							|  |  |  | 		`) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if !batch { | 
					
						
							|  |  |  | 		call.Otto.Run("ret_response = ret_response[0];") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if call.Argument(1).IsObject() { | 
					
						
							|  |  |  | 		call.Otto.Set("callback", call.Argument(1)) | 
					
						
							|  |  |  | 		call.Otto.Run(` | 
					
						
							|  |  |  | 	    if (Object.prototype.toString.call(callback) == '[object Function]') { | 
					
						
							|  |  |  | 			callback(null, ret_response); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		`) | 
					
						
							| 
									
										
										
										
											2015-03-15 13:21:54 +07:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-03-24 23:50:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-15 13:21:54 +07:00
										 |  |  | 	return | 
					
						
							|  |  |  | } |