github.com/bitfinexcom/bitfinex-api-go@v0.0.0-20210608095005-9e0b26f200fb/v2/rest/invoice.go (about)

     1  package rest
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"path"
     7  	"strconv"
     8  	"strings"
     9  
    10  	"github.com/bitfinexcom/bitfinex-api-go/pkg/models/common"
    11  	"github.com/bitfinexcom/bitfinex-api-go/pkg/models/invoice"
    12  )
    13  
    14  // InvoiceService manages Invoice endpoint
    15  type InvoiceService struct {
    16  	requestFactory
    17  	Synchronous
    18  }
    19  
    20  // DepositInvoiceRequest - data structure for constructing deposit invoice request payload
    21  type DepositInvoiceRequest struct {
    22  	Currency string `json:"currency,omitempty"`
    23  	Wallet   string `json:"wallet,omitempty"`
    24  	Amount   string `json:"amount,omitempty"`
    25  }
    26  
    27  var validCurrencies = map[string]struct {
    28  	name string
    29  	min  float64
    30  	max  float64
    31  }{
    32  	"LNX": {
    33  		name: "Bitcoin Lightning Network",
    34  		min:  0.000001,
    35  		max:  0.02,
    36  	},
    37  }
    38  
    39  func validCurrency(currency string) error {
    40  	if _, ok := validCurrencies[currency]; !ok {
    41  		var sb strings.Builder
    42  		sb.WriteString(currency)
    43  		sb.WriteString(" is not supported currency. Supported currencies: [")
    44  
    45  		for sc := range validCurrencies {
    46  			sb.WriteString(fmt.Sprintf(" %s(%s) ", sc, validCurrencies[sc].name))
    47  		}
    48  
    49  		sb.WriteString("]")
    50  
    51  		return fmt.Errorf(sb.String())
    52  	}
    53  
    54  	return nil
    55  }
    56  
    57  func validAmount(currency, amount string) error {
    58  	f, err := strconv.ParseFloat(amount, 64)
    59  	if err != nil {
    60  		return err
    61  	}
    62  
    63  	if f < validCurrencies[currency].min {
    64  		return fmt.Errorf(
    65  			"Minimum allowed amount for %s is %f. Got: %f",
    66  			currency,
    67  			validCurrencies[currency].min,
    68  			f,
    69  		)
    70  	}
    71  
    72  	if f > validCurrencies[currency].max {
    73  		return fmt.Errorf(
    74  			"Maximum allowed amount for %s is %f. Got: %f",
    75  			currency,
    76  			validCurrencies[currency].max,
    77  			f,
    78  		)
    79  	}
    80  
    81  	return nil
    82  }
    83  
    84  // GenerateInvoice generates a Lightning Network deposit invoice
    85  // Accepts DepositInvoiceRequest type as argument
    86  // https://docs.bitfinex.com/reference#rest-auth-deposit-invoice
    87  func (is *InvoiceService) GenerateInvoice(payload DepositInvoiceRequest) (*invoice.Invoice, error) {
    88  	if err := validCurrency(payload.Currency); err != nil {
    89  		return nil, err
    90  	}
    91  
    92  	if err := validAmount(payload.Currency, payload.Amount); err != nil {
    93  		return nil, err
    94  	}
    95  
    96  	pldBytes, err := json.Marshal(payload)
    97  	if err != nil {
    98  		return nil, err
    99  	}
   100  
   101  	req, err := is.NewAuthenticatedRequestWithBytes(
   102  		common.PermissionWrite,
   103  		path.Join("deposit", "invoice"),
   104  		pldBytes,
   105  	)
   106  	if err != nil {
   107  		return nil, err
   108  	}
   109  
   110  	raw, err := is.Request(req)
   111  	if err != nil {
   112  		return nil, err
   113  	}
   114  
   115  	invc, err := invoice.NewFromRaw(raw)
   116  	if err != nil {
   117  		return nil, err
   118  	}
   119  
   120  	return invc, nil
   121  }