diff --git a/bfxapi/models/__init__.py b/bfxapi/models/__init__.py index 13fc713..4da024e 100644 --- a/bfxapi/models/__init__.py +++ b/bfxapi/models/__init__.py @@ -13,5 +13,8 @@ from .funding_loan import FundingLoan from .funding_offer import FundingOffer from .funding_credit import FundingCredit from .notification import Notification +from .transfer import Transfer +from .deposit_address import DepositAddress +from .withdraw import Withdraw NAME = 'models' diff --git a/bfxapi/models/deposit_address.py b/bfxapi/models/deposit_address.py new file mode 100644 index 0000000..02497de --- /dev/null +++ b/bfxapi/models/deposit_address.py @@ -0,0 +1,42 @@ +""" +Module used to describe a DepositAddress object +""" + +class DepositModel: + """ + Enum used to index the location of each value in a raw array + """ + METHOD = 1 + CURRENCY = 2 + ADDRESS = 4 + +class DepositAddress: + """ + [None, 'BITCOIN', 'BTC', None, '38zsUkv8q2aiXK9qsZVwepXjWeh3jKvvZw'] + + METHOD string Protocol used for funds transfer + SYMBOL string Currency symbol + ADDRESS string Deposit address for funds transfer + """ + + def __init__(self, method, currency, address): + self.method = method + self.currency = currency + self.address = address + + @staticmethod + def from_raw_deposit_address(raw_add): + """ + Parse a raw deposit object into a DepositAddress object + + @return DepositAddress + """ + method = raw_add[DepositModel.METHOD] + currency = raw_add[DepositModel.CURRENCY] + address = raw_add[DepositModel.ADDRESS] + return DepositAddress(method, currency, address) + + def __str__(self): + ''' Allow us to print the Transfer object in a pretty format ''' + text = "DepositAddress <{} method={} currency={}>" + return text.format(self.address, self.method, self.currency) diff --git a/bfxapi/models/notification.py b/bfxapi/models/notification.py index 91bd6dd..84d91b5 100644 --- a/bfxapi/models/notification.py +++ b/bfxapi/models/notification.py @@ -4,6 +4,9 @@ Module used to describe all of the different notification data types from .order import Order from .funding_offer import FundingOffer +from .transfer import Transfer +from .deposit_address import DepositAddress +from .withdraw import Withdraw class NotificationModal: """ @@ -34,8 +37,10 @@ class NotificationTypes: ORDER_UPDATED_REQ = "ou-req" FUNDING_OFFER_NEW = "fon-req" FUNDING_OFFER_CANCEL = "foc-req" + ACCOUNT_TRANSFER = "acc_tf" + ACCOUNT_DEPOSIT = "acc_dep" + ACCOUNT_WITHDRAW_REQ = "acc_wd-req" # uca ? - # acc_tf ? # pm-req ? @@ -70,11 +75,11 @@ class Notification: return False @staticmethod - def from_raw_order(raw_notification): + def from_raw_notification(raw_notification): """ - Parse a raw order object into an Order object + Parse a raw notification object into an Order object - @return Order + @return Notification """ mts = raw_notification[NotificationModal.MTS] notify_type = raw_notification[NotificationModal.TYPE] @@ -100,6 +105,12 @@ class Notification: basic.notify_info = FundingOffer.from_raw_offer(basic.notify_info) elif basic.notify_type == NotificationTypes.FUNDING_OFFER_CANCEL: basic.notify_info = FundingOffer.from_raw_offer(basic.notify_info) + elif basic.notify_type == NotificationTypes.ACCOUNT_TRANSFER: + basic.notify_info = Transfer.from_raw_transfer(basic.notify_info) + elif basic.notify_type == NotificationTypes.ACCOUNT_DEPOSIT: + basic.notify_info = DepositAddress.from_raw_deposit_address(basic.notify_info) + elif basic.notify_type == NotificationTypes.ACCOUNT_WITHDRAW_REQ: + basic.notify_info = Withdraw.from_raw_withdraw(basic.notify_info) return basic def __str__(self): diff --git a/bfxapi/models/transfer.py b/bfxapi/models/transfer.py new file mode 100644 index 0000000..c6db63e --- /dev/null +++ b/bfxapi/models/transfer.py @@ -0,0 +1,53 @@ +""" +Module used to describe a transfer object +""" + +class TransferModel: + """ + Enum used to index the location of each value in a raw array + """ + MTS = 0 + W_FROM = 1 + W_TO = 2 + C_FROM = 4 + C_TO = 5 + AMOUNT = 7 + +class Transfer: + """ + MTS int Millisecond Time Stamp of the update + WALLET_FROM string Wallet name (exchange, margin, funding) + WALLET_TO string Wallet name (exchange, margin, funding) + CURRENCY_FROM string Currency (BTC, etc) + CURRENCY_TO string Currency (BTC, etc) + AMOUNT string Amount of funds to transfer + """ + + def __init__(self, mts, wallet_from, wallet_to, currency_from, currency_to, amount): + self.mts = mts + self.wallet_from = wallet_from + self.wallet_to = wallet_to + self.currency_from = currency_from + self.currency_to = currency_to + self.amount = amount + + @staticmethod + def from_raw_transfer(raw_transfer): + """ + Parse a raw transfer object into a Transfer object + + @return Transfer + """ + mts = raw_transfer[TransferModel.MTS] + wallet_from = raw_transfer[TransferModel.W_FROM] + wallet_to = raw_transfer[TransferModel.W_TO] + currency_from = raw_transfer[TransferModel.C_FROM] + currency_to = raw_transfer[TransferModel.C_TO] + amount = raw_transfer[TransferModel.AMOUNT] + return Transfer(mts, wallet_from, wallet_to, currency_from, currency_to, amount) + + def __str__(self): + ''' Allow us to print the Transfer object in a pretty format ''' + text = "Transfer <{} from {} ({}) to {} ({}) mts={}>" + return text.format(self.amount, self.wallet_from, self.currency_from, + self.wallet_to, self.currency_to, self.mts) diff --git a/bfxapi/models/withdraw.py b/bfxapi/models/withdraw.py new file mode 100644 index 0000000..9412d3f --- /dev/null +++ b/bfxapi/models/withdraw.py @@ -0,0 +1,51 @@ +""" +Module used to describe a withdraw object +""" + +class WithdrawModel: + """ + Enum used to index the location of each value in a raw array + """ + ID = 0 + METHOD = 2 + WALLET = 4 + AMOUNT = 5 + FEE = 7 + +class Withdraw: + """ + [13063236, None, 'tetheruse', None, 'exchange', 5, None, None, 0.00135] + + MTS int Millisecond Time Stamp of the update + WALLET_FROM string Wallet name (exchange, margin, funding) + WALLET_TO string Wallet name (exchange, margin, funding) + CURRENCY_FROM string Currency (BTC, etc) + CURRENCY_TO string Currency (BTC, etc) + AMOUNT string Amount of funds to transfer + """ + + def __init__(self, w_id, method, wallet, amount, fee=0): + self.id = w_id + self.method = method + self.wallet = wallet + self.amount = amount + self.fee = fee + + @staticmethod + def from_raw_withdraw(raw_withdraw): + """ + Parse a raw withdraw object into a Withdraw object + + @return Withdraw + """ + w_id = raw_withdraw[WithdrawModel.ID] + method = raw_withdraw[WithdrawModel.METHOD] + wallet = raw_withdraw[WithdrawModel.WALLET] + amount = raw_withdraw[WithdrawModel.AMOUNT] + return Withdraw(w_id, method, wallet, amount) + + def __str__(self): + ''' Allow us to print the Transfer object in a pretty format ''' + text = "Withdraw " + return text.format(self.id, self.wallet, self.method, self.amount, + self.fee) diff --git a/bfxapi/rest/bfx_rest.py b/bfxapi/rest/bfx_rest.py index 9d66fea..0333208 100644 --- a/bfxapi/rest/bfx_rest.py +++ b/bfxapi/rest/bfx_rest.py @@ -373,7 +373,7 @@ class BfxRest: payload['flags'] = flags endpoint = "auth/w/funding/offer/submit" raw_notification = await self.post(endpoint, payload) - return Notification.from_raw_order(raw_notification) + return Notification.from_raw_notification(raw_notification) async def submit_cancel_funding_offer(self, fundingId): """ @@ -383,7 +383,68 @@ class BfxRest: """ endpoint = "auth/w/funding/offer/cancel" raw_notification = await self.post(endpoint, { 'id': fundingId }) - return Notification.from_raw_order(raw_notification) + return Notification.from_raw_notification(raw_notification) + + async def submit_wallet_transfer(self, from_wallet, to_wallet, from_currency, to_currency, amount): + """ + Transfer funds between wallets + + @param from_wallet string: wallet name to transfer from i.e margin, exchange + @param to_wallet string: wallet name to transfer to i.e margin, exchange + @param from_currency string: currency symbol to tranfer from i.e BTC, USD + @param to_currency string: currency symbol to transfer to i.e BTC, USD + @param amount float: amount of funds to transfer + """ + endpoint = "auth/w/transfer" + payload = { + "from": from_wallet, + "to": to_wallet, + "currency": from_currency, + "currency_to": to_currency, + "amount": str(amount), + } + raw_transfer = await self.post(endpoint, payload) + return Notification.from_raw_notification(raw_transfer) + + async def get_wallet_deposit_address(self, wallet, method, renew=0): + """ + Get the deposit address for the given wallet and protocol + + @param wallet string: wallet name i.e margin, exchange + @param method string: transfer protocol i.e bitcoin + """ + endpoint = "auth/w/deposit/address" + payload = { + "wallet": wallet, + "method": method, + "op_renew": renew, + } + raw_deposit = await self.post(endpoint, payload) + return Notification.from_raw_notification(raw_deposit) + + async def create_wallet_deposit_address(self, wallet, method): + """ + Creates a new deposit address for the given wallet and protocol. + Previously generated addresses remain linked. + + @param wallet string: wallet name i.e margin, exchange + @param method string: transfer protocol i.e bitcoin + """ + return await self.get_wallet_deposit_address(wallet, method, renew=1) + + async def submit_wallet_withdraw(self, wallet, method, amount, address): + """ + `/v2/auth/w/withdraw` (params: `wallet`, `method`, `amount`, `address + """ + endpoint = "auth/w/withdraw" + payload = { + "wallet": wallet, + "method": method, + "amount": str(amount), + "address": str(address) + } + raw_deposit = await self.post(endpoint, payload) + return Notification.from_raw_notification(raw_deposit) # async def submit_close_funding(self, id, type): # """