func (ps *PaymentService) getPaymentAddr(req *msg.OcReq) (*msg.OcResp, error) { if len(req.Args) > 1 { return msg.NewRespError(msg.INVALID_ARGUMENTS), nil } reqCurrency := string(msg.BTC) if len(req.Args) == 1 { reqCurrency = strings.ToUpper(req.Args[0]) } p, err := peer.NewPeerFromReq(req, ps.BitcoindConf) if err != nil { return msg.NewRespError(msg.SERVER_ERROR), nil } switch reqCurrency { case string(msg.BTC): if ps.BitcoindConf == nil { return msg.NewRespError(msg.SERVER_ERROR), nil } // TODO(ortutay): smarter handling to map request ID to address btcAddr, err := p.PaymentAddr(ADDRS_PER_ID, ps.BitcoindConf) if err != nil { return msg.NewRespError(msg.SERVER_ERROR), nil } payAddr := msg.PaymentAddr{Currency: msg.BTC, Addr: btcAddr} return msg.NewRespOk([]byte(payAddr.String())), nil default: return msg.NewRespError(msg.CURRENCY_UNSUPPORTED), nil } }
func (ps *PaymentService) balance(req *msg.OcReq) (*msg.OcResp, error) { p, err := peer.NewPeerFromReq(req, ps.BitcoindConf) if err != nil { return msg.NewRespError(msg.SERVER_ERROR), nil } balance, err := p.Balance(0, ps.BitcoindConf) if err != nil { return msg.NewRespError(msg.SERVER_ERROR), nil } maxBalanceConf, err := ps.Conf.PolicyForCmd(conf.MAX_BALANCE) if err != nil { // TODO(ortutay): handle more configuration around max balance panic(err) } maxBalance := maxBalanceConf.Args[0].(*msg.PaymentValue) btcAddr, err := p.PaymentAddr(ADDRS_PER_ID, ps.BitcoindConf) if err != nil { return msg.NewRespError(msg.SERVER_ERROR), nil } resp := BalanceResponse{ Balance: balance, MaxBalance: maxBalance, Addr: btcAddr, } body, err := json.Marshal(&resp) if err != nil { return msg.NewRespError(msg.SERVER_ERROR), nil } return msg.NewRespOk(body), nil }
func (s *Server) Serve(listener net.Listener) error { conn, err := listener.Accept() if err != nil { return err } go (func(conn net.Conn) { println("get req") req, err := msg.ReadOcReq(bufio.NewReader(conn)) defer conn.Close() defer fmt.Fprintf(conn, "\n") if err != nil { msg.NewRespError(msg.BAD_REQUEST).Write(conn) return } fmt.Printf("Got request: %v\n", req) // TODO(ortutay): implement additional request validation // - validate sigs // - check nonce // - check service available // - check method available p, err := peer.NewPeerFromReq(req, s.BtcConf) if err != nil { log.Printf("error generating peer: %v\n", err) if err == peer.INVALID_SIGNATURE { msg.NewRespError(msg.INVALID_SIGNATURE).Write(conn) } else if err == peer.COIN_REUSE { msg.NewRespError(msg.COIN_REUSE).Write(conn) } else { msg.NewRespError(msg.SERVER_ERROR).Write(conn) } return } // TODO(ortutay): more configuration options around allowed balance balanceDueResp := s.checkBalance(p) if balanceDueResp != nil && req.Service != "payment" { balanceDueResp.Write(conn) return } if ok, status := s.isAllowedByPolicy(p, req); !ok { if status == msg.OK { panic("expected error status") } fmt.Printf("not allowed: %v %v\n", ok, status) msg.NewRespError(status).Write(conn) return } fmt.Printf("passing off to handler...\n") resp, err := s.Handler.Handle(req) if err != nil || resp == nil { fmt.Printf("server error: %v\n", err) msg.NewRespError(msg.SERVER_ERROR).Write(conn) } else { fmt.Printf("sending response: %v\n", resp) resp.Write(conn) } return })(conn) return nil }