mirror of
https://github.com/aljazceru/bitfinex-api-py.git
synced 2025-12-20 15:24:21 +01:00
@@ -302,13 +302,13 @@ class RestAuthenticatedEndpoints(Middleware):
|
||||
|
||||
return serializers._Notification[DepositAddress](serializers.DepositAddress).parse(*self._POST("auth/w/deposit/address", body=body))
|
||||
|
||||
def generate_deposit_invoice(self, wallet: str, currency: str, amount: Union[Decimal, float, str]) -> Invoice:
|
||||
def generate_deposit_invoice(self, wallet: str, currency: str, amount: Union[Decimal, float, str]) -> LightningNetworkInvoice:
|
||||
body = {
|
||||
"wallet": wallet, "currency": currency,
|
||||
"amount": amount
|
||||
}
|
||||
|
||||
return serializers.Invoice.parse(*self._POST("auth/w/deposit/invoice", body=body))
|
||||
return serializers.LightningNetworkInvoice.parse(*self._POST("auth/w/deposit/invoice", body=body))
|
||||
|
||||
def get_movements(self, currency: Optional[str] = None, start: Optional[str] = None, end: Optional[str] = None, limit: Optional[int] = None) -> List[Movement]:
|
||||
if currency == None:
|
||||
@@ -321,3 +321,21 @@ class RestAuthenticatedEndpoints(Middleware):
|
||||
}
|
||||
|
||||
return [ serializers.Movement.parse(*sub_data) for sub_data in self._POST(endpoint, body=body) ]
|
||||
|
||||
def submit_invoice(self, amount: Union[Decimal, float, str], currency: str, order_id: str,
|
||||
customer_info: CustomerInfo, pay_currencies: List[str], duration: Optional[int] = None,
|
||||
webhook: Optional[str] = None, redirect_url: Optional[str] = None) -> InvoiceSubmission:
|
||||
data = self._POST("auth/w/ext/pay/invoice/create", body={
|
||||
"amount": amount, "currency": currency, "order_id": order_id,
|
||||
"customer_info": customer_info, "pay_currencies": pay_currencies, "duration": duration,
|
||||
"webhook": webhook, "redirect_url": redirect_url
|
||||
})
|
||||
|
||||
if "customer_info" in data and data["customer_info"] != None:
|
||||
data["customer_info"] = CustomerInfo(**data["customer_info"])
|
||||
|
||||
if "invoices" in data and data["invoices"] != None:
|
||||
for index, invoice in enumerate(data["invoices"]):
|
||||
data["invoices"][index] = Invoice(**invoice)
|
||||
|
||||
return InvoiceSubmission(**data)
|
||||
@@ -18,7 +18,7 @@ __serializers__ = [
|
||||
"FundingOffer", "FundingCredit", "FundingLoan",
|
||||
"FundingAutoRenew", "FundingInfo", "Wallet",
|
||||
"Transfer", "Withdrawal", "DepositAddress",
|
||||
"Invoice", "Movement", "SymbolMarginInfo",
|
||||
"LightningNetworkInvoice", "Movement", "SymbolMarginInfo",
|
||||
"BaseMarginInfo", "PositionClaim", "PositionIncreaseInfo",
|
||||
"PositionIncrease", "PositionHistory", "PositionSnapshot",
|
||||
"PositionAudit", "DerivativePositionCollateral", "DerivativePositionCollateralLimits",
|
||||
@@ -581,7 +581,7 @@ DepositAddress = generate_labeler_serializer("DepositAddress", klass=types.Depos
|
||||
"pool_address"
|
||||
])
|
||||
|
||||
Invoice = generate_labeler_serializer("Invoice", klass=types.Invoice, labels=[
|
||||
LightningNetworkInvoice = generate_labeler_serializer("LightningNetworkInvoice", klass=types.LightningNetworkInvoice, labels=[
|
||||
"invoice_hash",
|
||||
"invoice",
|
||||
"_PLACEHOLDER",
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
from typing import Type, Tuple, List, Dict, TypedDict, Union, Optional, Any
|
||||
from typing import Type, Tuple, List, Dict, TypedDict, Union, Optional, Literal, Any
|
||||
|
||||
from dataclasses import dataclass
|
||||
|
||||
from types import SimpleNamespace
|
||||
|
||||
from .. labeler import _Type
|
||||
from .. notification import Notification
|
||||
from ..utils.JSONEncoder import JSON
|
||||
from .. utils.JSONEncoder import JSON
|
||||
|
||||
#region Type hinting for Rest Public Endpoints
|
||||
|
||||
@@ -440,7 +442,7 @@ class DepositAddress(_Type):
|
||||
pool_address: str
|
||||
|
||||
@dataclass
|
||||
class Invoice(_Type):
|
||||
class LightningNetworkInvoice(_Type):
|
||||
invoice_hash: str
|
||||
invoice: str
|
||||
amount: str
|
||||
@@ -562,3 +564,43 @@ class DerivativePositionCollateralLimits(_Type):
|
||||
max_collateral: float
|
||||
|
||||
#endregion
|
||||
|
||||
#region Type hinting for models which are not serializable
|
||||
|
||||
@dataclass
|
||||
class InvoiceSubmission(_Type):
|
||||
id: str
|
||||
t: int
|
||||
type: Literal["ECOMMERCE", "POS"]
|
||||
duration: int
|
||||
amount: float
|
||||
currency: str
|
||||
order_id: str
|
||||
pay_currencies: List[str]
|
||||
webhook: str
|
||||
redirect_url: str
|
||||
status: Literal["CREATED", "PENDING", "COMPLETED", "EXPIRED"]
|
||||
customer_info: Optional["CustomerInfo"]
|
||||
invoices: List["Invoice"]
|
||||
|
||||
class CustomerInfo(SimpleNamespace):
|
||||
nationality: str
|
||||
resid_country: str
|
||||
resid_state: str
|
||||
resid_city: str
|
||||
resid_zip_code: str
|
||||
resid_street: str
|
||||
resid_building_no: str
|
||||
full_name: str
|
||||
email: str
|
||||
tos_accepted: bool
|
||||
|
||||
class Invoice(SimpleNamespace):
|
||||
amount: float
|
||||
currency: str
|
||||
pay_currency: str
|
||||
pool_currency: str
|
||||
address: str
|
||||
ext: JSON
|
||||
|
||||
#endregion
|
||||
@@ -2,16 +2,16 @@ import json
|
||||
from decimal import Decimal
|
||||
from datetime import datetime
|
||||
|
||||
from types import SimpleNamespace
|
||||
|
||||
from typing import Type, List, Dict, Union, Any
|
||||
|
||||
JSON = Union[Dict[str, "JSON"], List["JSON"], bool, int, float, str, Type[None]]
|
||||
|
||||
class JSONEncoder(json.JSONEncoder):
|
||||
def encode(self, obj: JSON) -> str:
|
||||
def _strip(dictionary: Dict) -> Dict:
|
||||
def _strip(dictionary: Dict) -> Dict:
|
||||
return { key: value for key, value in dictionary.items() if value != None}
|
||||
|
||||
def _convert_float_to_str(data: JSON) -> JSON:
|
||||
def _convert_float_to_str(data: JSON) -> JSON:
|
||||
if isinstance(data, float):
|
||||
return format(Decimal(repr(data)), "f")
|
||||
elif isinstance(data, list):
|
||||
@@ -20,15 +20,13 @@ class JSONEncoder(json.JSONEncoder):
|
||||
return _strip({ key: _convert_float_to_str(value) for key, value in data.items() })
|
||||
else: return data
|
||||
|
||||
data = _convert_float_to_str(obj)
|
||||
|
||||
return json.JSONEncoder.encode(self, data)
|
||||
class JSONEncoder(json.JSONEncoder):
|
||||
def encode(self, obj: JSON) -> str:
|
||||
return json.JSONEncoder.encode(self, _convert_float_to_str(obj))
|
||||
|
||||
def default(self, obj: Any) -> Any:
|
||||
if isinstance(obj, Decimal):
|
||||
return format(obj, "f")
|
||||
|
||||
if isinstance(obj, datetime):
|
||||
return str(obj)
|
||||
if isinstance(obj, SimpleNamespace): return _convert_float_to_str(vars(obj))
|
||||
elif isinstance(obj, Decimal): return format(obj, "f")
|
||||
elif isinstance(obj, datetime): return str(obj)
|
||||
|
||||
return json.JSONEncoder.default(self, obj)
|
||||
33
examples/rest/merchant.py
Normal file
33
examples/rest/merchant.py
Normal file
@@ -0,0 +1,33 @@
|
||||
# python -c "import examples.rest.merchant"
|
||||
|
||||
import os
|
||||
|
||||
from bfxapi.client import Client, Constants
|
||||
from bfxapi.rest.types import CustomerInfo
|
||||
|
||||
bfx = Client(
|
||||
REST_HOST=Constants.REST_HOST,
|
||||
API_KEY=os.getenv("BFX_API_KEY"),
|
||||
API_SECRET=os.getenv("BFX_API_SECRET")
|
||||
)
|
||||
|
||||
customer_info: CustomerInfo = CustomerInfo(
|
||||
nationality="GB",
|
||||
resid_country="DE",
|
||||
resid_city="Berlin",
|
||||
resid_zip_code=1,
|
||||
resid_street="Timechain",
|
||||
full_name="Satoshi",
|
||||
email="satoshi3@bitfinex.com",
|
||||
tos_accepted=None,
|
||||
resid_building_no=None
|
||||
)
|
||||
|
||||
print(bfx.rest.auth.submit_invoice(
|
||||
amount=1,
|
||||
currency="USD",
|
||||
duration=864000,
|
||||
order_id="order123",
|
||||
customer_info=customer_info,
|
||||
pay_currencies=["ETH"],
|
||||
))
|
||||
Reference in New Issue
Block a user