diff options
Diffstat (limited to 'xmrpayclnt.go')
| -rw-r--r-- | xmrpayclnt.go | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/xmrpayclnt.go b/xmrpayclnt.go new file mode 100644 index 0000000..5d865bf --- /dev/null +++ b/xmrpayclnt.go @@ -0,0 +1,95 @@ +// Package xmrpayclnt is a client library for the MoneroPay v2 HTTP API. +// +// All amounts are in piconero. +package xmrpayclnt + +import ( + "bytes" + "context" + "encoding/json" + "log" + "net/http" + "net/url" + "os" + + "git.samanthony.xyz/jttp" + + "gitlab.com/moneropay/moneropay/v2/pkg/model" +) + +const ( + balancePath = "/balance" + healthPath = "/health" + receivePath = "/receive" +) + +var lg = log.New(os.Stderr, "xmrpayclnt: ", log.LstdFlags) + +type Client struct { + c *jttp.Client + endpoint *url.URL +} + +// New creates a client that will connect to the moneropay server at +// endpoint. +func New(endpoint *url.URL) *Client { + return &Client{jttp.NewClient(&http.Client{}), endpoint} +} + +// Balance returns the entire wallet balance. +func (c *Client) Balance(ctx context.Context) (model.BalanceResponse, error) { + url := c.endpoint.JoinPath(balancePath) + req, err := http.NewRequestWithContext(ctx, http.MethodGet, url.String(), nil) + if err != nil { + return model.BalanceResponse{}, err + } + var bal model.BalanceResponse + err = c.c.Do(req, http.StatusOK, &bal) + return bal, err +} + +// Health returns true if all required services are up. +func (c *Client) Health(ctx context.Context) (bool, error) { + url := c.endpoint.JoinPath(healthPath) + req, err := http.NewRequestWithContext(ctx, http.MethodGet, url.String(), nil) + if err != nil { + return false, err + } + var health model.HealthResponse + err = c.c.Do(req, http.StatusOK, &health) + return err == nil, err +} + +// Receive creates a subaddress for incoming transfers. +func (c *Client) Receive(ctx context.Context, amount uint64, description string) (model.ReceivePostResponse, error) { + return c.postReceive(ctx, amount, description, "") +} + +func (c *Client) ReceiveWithCallback(ctx context.Context, amount uint64, description string, ch *CallbackHandler) (model.ReceivePostResponse, Callback, error) { + cb := ch.listen() + if resp, err := c.postReceive(ctx, amount, description, cb.url.String()); err == nil { + return resp, cb, nil + } else { + cb.Close() + return resp, Callback{}, err + } +} + +func (c *Client) postReceive(ctx context.Context, amount uint64, description string, callbackUrl string) (model.ReceivePostResponse, error) { + var resp model.ReceivePostResponse + + body := new(bytes.Buffer) + enc := json.NewEncoder(body) + err := enc.Encode(model.ReceivePostRequest{amount, callbackUrl, description}) + if err != nil { + return resp, err + } + + url := c.endpoint.JoinPath(receivePath) + req, err := http.NewRequestWithContext(ctx, http.MethodPost, url.String(), body) + if err != nil { + return resp, err + } + err = c.c.Do(req, http.StatusOK, &resp) + return resp, err +} |