diff --git a/testing/testclient/testclient.go b/testing/testclient/testclient.go index 54cdafa..199ff8f 100644 --- a/testing/testclient/testclient.go +++ b/testing/testclient/testclient.go @@ -5,8 +5,13 @@ package main import ( "flag" "io/ioutil" + "math/big" + "github.com/celer-network/agent-pay/celersdk" + "github.com/celer-network/agent-pay/common" + "github.com/celer-network/agent-pay/ctype" "github.com/celer-network/agent-pay/webapi" + "github.com/celer-network/goutils/eth" "github.com/celer-network/goutils/log" ) @@ -29,6 +34,27 @@ func main() { log.Fatal(err) } log.Infoln("start testclient on port", *grpcPort, "using ks", *ksPath) + if *extSigner { + addr, priv, err := eth.GetAddrPrivKeyFromKeystore(string(ksBytes), "") + if err != nil { + log.Fatal(err) + } + p := common.Bytes2Profile(cfg) + signer, err := eth.NewSigner(priv, big.NewInt(p.ChainId)) + if err != nil { + log.Fatal(err) + } + webapi.NewInternalApiServerWithExternalSigner( + -1, + *grpcPort, + "http://localhost:*", + ctype.Addr2Hex(addr), + *dataPath, + string(cfg[:]), + &testExternalSigner{Signer: signer}, + nil).Start() + return + } webapi.NewInternalApiServer( -1, *grpcPort, @@ -36,6 +62,19 @@ func main() { string(ksBytes[:]), "", *dataPath, - string(cfg[:]), - *extSigner).Start() + string(cfg[:])).Start() +} + +type testExternalSigner struct { + eth.Signer +} + +func (es *testExternalSigner) OnSignMessage(reqid int, msg []byte) { + res, _ := es.SignEthMessage(msg) + celersdk.PublishSignedResult(reqid, res) +} + +func (es *testExternalSigner) OnSignTransaction(reqid int, rawtx []byte) { + res, _ := es.SignEthTransaction(rawtx) + celersdk.PublishSignedResult(reqid, res) } diff --git a/webapi/api_server.go b/webapi/api_server.go index 486fb06..999e3cb 100644 --- a/webapi/api_server.go +++ b/webapi/api_server.go @@ -7,7 +7,6 @@ import ( "encoding/json" "errors" "fmt" - "math/big" "net" "net/http" "strconv" @@ -17,12 +16,10 @@ import ( "github.com/celer-network/agent-pay/celersdk" "github.com/celer-network/agent-pay/celersdkintf" - "github.com/celer-network/agent-pay/common" "github.com/celer-network/agent-pay/ctype" "github.com/celer-network/agent-pay/entity" msgrpc "github.com/celer-network/agent-pay/rpc" "github.com/celer-network/agent-pay/webapi/rpc" - "github.com/celer-network/goutils/eth" "github.com/celer-network/goutils/log" "github.com/improbable-eng/grpc-web/go/grpcweb" "github.com/rs/cors" @@ -44,23 +41,6 @@ type ApiServer struct { appSessionMapLock sync.Mutex } -// implement celersdk.ExternalSignerCallback interface -// also embed eth.Signer so celersdk.ExternalSignerManager can tell the difference and -// avoid double hash -type extSigner struct { - eth.Signer -} - -func (es *extSigner) OnSignMessage(reqid int, msg []byte) { - res, _ := es.SignEthMessage(msg) - celersdk.PublishSignedResult(reqid, res) -} - -func (es *extSigner) OnSignTransaction(reqid int, rawtx []byte) { - res, _ := es.SignEthTransaction(rawtx) - celersdk.PublishSignedResult(reqid, res) -} - func NewApiServer( webPort int, grpcPort int, @@ -68,8 +48,34 @@ func NewApiServer( keystore string, password string, dataPath string, + config string) *ApiServer { + return newApiServerWithClientInit(webPort, grpcPort, allowedOrigins, func(callbackImpl *callbackImpl) { + go celersdk.InitClient( + &celersdk.Account{Keystore: keystore, Password: password}, + config, + dataPath, + callbackImpl) + }) +} + +func NewApiServerWithExternalSigner( + webPort int, + grpcPort int, + allowedOrigins string, + addr string, + dataPath string, config string, - useExtSigner bool) *ApiServer { + signcb celersdk.ExternalSignerCallback) *ApiServer { + return newApiServerWithClientInit(webPort, grpcPort, allowedOrigins, func(callbackImpl *callbackImpl) { + go celersdk.InitClientWithSigner(addr, config, dataPath, callbackImpl, signcb) + }) +} + +func newApiServerWithClientInit( + webPort int, + grpcPort int, + allowedOrigins string, + initClient func(*callbackImpl)) *ApiServer { callbackImpl := NewCallbackImpl() s := &ApiServer{ webPort: webPort, @@ -78,24 +84,7 @@ func NewApiServer( callbackImpl: callbackImpl, appSessionMap: make(map[string]*celersdk.AppSession), } - if !useExtSigner { - go celersdk.InitClient( - &celersdk.Account{Keystore: keystore, Password: password}, - config, - dataPath, - callbackImpl) - } else { // exercise external signer code path - addr, priv, err := eth.GetAddrPrivKeyFromKeystore(keystore, password) - if err != nil { - log.Fatal(err) - } - p := common.Bytes2Profile([]byte(config)) - signer, err := eth.NewSigner(priv, big.NewInt(p.ChainId)) - if err != nil { - log.Fatal(err) - } - go celersdk.InitClientWithSigner(ctype.Addr2Hex(addr), config, dataPath, callbackImpl, &extSigner{signer}) - } + initClient(callbackImpl) select { case client := <-callbackImpl.clientReady: diff --git a/webapi/cmd/main.go b/webapi/cmd/main.go index a82d46d..bca7040 100644 --- a/webapi/cmd/main.go +++ b/webapi/cmd/main.go @@ -73,5 +73,5 @@ func main() { string(ksBytes[:]), ksPasswordStr, *dataPath, - string(cfg[:]), false).Start() + string(cfg[:])).Start() } diff --git a/webapi/internal_api_server.go b/webapi/internal_api_server.go index 0bbabef..d11e4f4 100644 --- a/webapi/internal_api_server.go +++ b/webapi/internal_api_server.go @@ -14,6 +14,7 @@ import ( type InternalApiServer struct { *ApiServer + register func(*grpc.Server) } func NewInternalApiServer( @@ -23,14 +24,29 @@ func NewInternalApiServer( keystore string, password string, dataPath string, + config string) *InternalApiServer { + apiServer := NewApiServer(webPort, grpcPort, allowedOrigins, keystore, password, dataPath, config) + return &InternalApiServer{ApiServer: apiServer} +} + +func NewInternalApiServerWithExternalSigner( + webPort int, + grpcPort int, + allowedOrigins string, + addr string, + dataPath string, config string, - extSigner bool) *InternalApiServer { - apiServer := NewApiServer(webPort, grpcPort, allowedOrigins, keystore, password, dataPath, config, extSigner) - return &InternalApiServer{apiServer} + cb celersdk.ExternalSignerCallback, + register func(*grpc.Server)) *InternalApiServer { + apiServer := NewApiServerWithExternalSigner(webPort, grpcPort, allowedOrigins, addr, dataPath, config, cb) + return &InternalApiServer{ApiServer: apiServer, register: register} } func (s *InternalApiServer) Start() { gs := grpc.NewServer() + if s.register != nil { + s.register(gs) + } rpc.RegisterWebApiServer(gs, s.ApiServer) rpc.RegisterInternalWebApiServer(gs, s) s.ApiServer.serve(gs)