// 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 } // NewTx creates a subaddress for incoming transfers. func (c *Client) NewTx(ctx context.Context, amount uint64, description string) (model.ReceivePostResponse, error) { return c.postReceive(ctx, amount, description, "") } // NewTxWithCallback creates a subaddress and a callback to monitor it. func (c *Client) NewTxWithCallback(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 }