Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
DEPRACATED: changenow.io now maintains a python library that provides this functionality and is kept up to date with API changes. It can be found here https://gitlab.com/changenow-s-library-catalogue/changenow-api-python and it is recommended to use this library rather than mine.

This repository will no longer be maintained.

# cnio-api-py
This library passes requests to the changenow.io API located at https://changenow.io/api/v1 (version hardcoded for now)
Every API endpoint must be called using a PHP style http_build_query, and returns a JSON object
Expand All @@ -7,4 +11,4 @@ a query url to the api looks like this:
"https://changenow.io/api/v1/endpoint/param1/param2?<query_param_1>=<value>&<query_param_2>=<value>..."
Read the docs at https://changenow.io/api/docs for more information.

This module depends on requests, socketio and aiohttp.
This module depends on requests, json and logging Python modules from the standard library.
115 changes: 88 additions & 27 deletions cnio_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,61 +9,135 @@
https://changenow.io/api/v1/<endpoint>/<param1>/<param2>?<query_param_1>=<value>&<query_param_2>=<value>...
Read the docs at https://changenow.io/api/docs for more information.
'''

import json
import requests
#import socketio
#from aiohttp import web
import logging

class cnio():
def __init__(self):
self.key = str()
self.api = "https://changenow.io/api/v1/"

def currencies(self, active):
def _get(self, url, headers=None, data=None, params=None):
req = requests.get(url, headers=headers, data=data, params=params)
if req.status_code not in [200, 201]:
logging.error('get(%s) failed(%d)' % (url, req.status_code))
if req.text is not None:
logging.error('req: %s' % req.text)
raise Exception('request.get() failed(%s)' % req.text)
raise Exception(
'request.get() failed(status_code:%d)' % req.status_code)
return json.loads(req.text)

def _post(self, url, headers=None, data=None):
req = requests.post(url, headers=headers, data=data)
if req.status_code not in [200, 201]:
logging.error('post(%s) failed(%d)' % (url, req.status_code))
if req.text is not None:
raise Exception('request.post() failed(%s)' % req.text)
raise Exception(
'request.post() failed(status_code:%d)' % req.status_code)
return json.loads(req.text)

def get_pair(self):
endpoint = str('/market-info/available-pairs/')
endpoint = str(self.api + endpoint)
return self._get(url=endpoint)

def currencies(self, active, fixed_rate):
# this method returns the list of supported currencies
# use optional param "active" to get only currently active currencies. This should be provided as a bool value
query = str("?active=" + str(active))
# Both params should be provided as a bool value
query = str("?active=" + str(active) + "&fixedRate=" + str(fixed_rate))
endpoint = "currencies"
endpoint = str(self.api + endpoint + query)
return requests.get(url=endpoint).content
return self._get(url=endpoint)

def currencies_to(self, ticker, fixed_rate):
# this method returns a list of currencies that have trade pairs with the provided currency ticker
# query param "fixed_rate" should be provided as a bool value
query = str("?fixedRate=" + str(fixed_rate))
endpoint = str("currencies-to/" + ticker)
endpoint = str(self.api + endpoint + query)
return self._get(url=endpoint)

def specific_currency_info(self, ticker):
# this method returns information on a specific currency
endpoint = str("currencies/" + ticker)
endpoint = str(self.api + endpoint)
return self._get(url=endpoint)

def min_amount(self, send, receive):
# this method returns the minimum amount required to make an exchange.
# you MUST provide the currency pair that you are looking to trade
endpoint = str("min-amount/" + send + "_" + receive)
endpoint = str(self.api + endpoint)
return requests.get(endpoint).content
return self._get(endpoint)

def est_exchange_rate(self, send_amount, send, receive):
# this method returns the amount of <recieve> currency you will get for the provided amount of <send> currency
# you MUST provide the amount you intend to send, the currency to be sent and the currency to be recieved
endpoint = str("exchange-amount/" + str(send_amount) + "/" + send + "_" + receive)
endpoint = str(self.api + endpoint)
return requests.get(endpoint).content
return self._get(endpoint)

def isitscam(self, url):
# this endpoint just checks if the provided crypto site URL is valid or some type of scam
# I am not sure how accurate the returned information will be
endpoint = str("scam-check/" + url)
endpoint = str(self.api + endpoint)
return requests.get(endpoint).content
return self._get(endpoint)

# use this method to set an API key to work with for the duration of the instance
# call it before calling any methods that require an API key
def api_key(self, key):
self.key = key

# ALL OF THE FOLLOWING ENDPOINTS REQUIRE PROVISION OF AN API KEY
def create_transaction(self, send_amount, send, receive, addr, extra_id=""):
# THE FOLLOWING ARE STANDARD FLOW (VARIABLE RATE NO LIMIT) API ENDPOINTS
def create_transaction(self, send_amount, send, receive, addr, extra_id="", refund_address=""):
# this endpoint creates a transaction
# You must provide quite a bit of information. namely, send currency, recieve currency
# the address you want the recieve currency sent to, the amount you will send,
# and an "extra ID" for currencies that need it (eg. transaction ID for XMP)
query = str("?from=" + send + "&to=" + receive + "&address=" + addr +
"&amount=" + str(send_amount) + "&extraId=" + extra_id)
"&amount=" + str(send_amount) + "&extraId=" + extra_id + "&refundAddress=" + refund_address)
endpoint = str("transactions/" + self.key)
endpoint = str(self.api + endpoint + query)
return requests.post(endpoint).content
return self._post(endpoint)

# THE FOLLOWING ARE THE FIXED RATE API ENDPOINTS
def available_fixed_markets(self):
# this method returns the available keypairs that can be exchanged at a fixed rate
endpoint = str("market-info/fixed-rate/" + self.key)
endpoint = str(self.api + endpoint)
return self._get(endpoint)

def estimate_fixed_rate_exchange_amount(self, send_amount, send, receive):
# this method returns the amount of <recieve> currency you will get for the provided amount of <send> currency
# you MUST provide the amount you intend to send, the currency to be sent and the currency to be recieved
query = str("?api_key=" + self.key)
endpoint = str("exchange-amount/fixed_rate/" + str(send_amount) + "/" + send + "_" + receive)
endpoint = str(self.api + endpoint + query)
return self._get(endpoint)

def create_fixed_rate_transaction(self, send_amount, send, receive, addr, extra_id="", refund_address=""):
# this endpoint creates a transaction
# You must provide quite a bit of information. namely, send currency, recieve currency
# the address you want the recieve currency sent to, the amount you will send,
# and an "extra ID" for currencies that need it (eg. transaction ID for XMP)
query = str("?from=" + send + "&to=" + receive + "&address=" + addr +
"&amount=" + str(send_amount) + "&extraId=" + extra_id + "&refundAddress=" + refund_address)
endpoint = str("transactions/fixed_rate/" + self.key)
endpoint = str(self.api + endpoint + query)
return self._post(endpoint)

# THE FOLLOWING CAN BE USED FOR VARIABLE AND FIXED RATE TRANSACTIONS
def get_transaction_status(self, cnio_transaction_id):
# this method returns the transaction status of a transaction. A transaction id
# from list_transactions() or create_transaction() MUST be provided.
endpoint = str("transactions/" + cnio_transaction_id + "/" + self.key)
endpoint = str(self.api + endpoint)
return self._get(endpoint)

def list_transactions(self, send="", receive="", status="", limit="", offset=""):
# this method returns a list of <limit> transactions that were started using the API key
Expand All @@ -75,21 +149,8 @@ def list_transactions(self, send="", receive="", status="", limit="", offset="")
query = str("?from=" + send + "&to=" + receive + "&status=" + status + "&limit=" + limit + "&offset=" + offset)
endpoint = str("transactions/" + self.key)
endpoint = str(self.api + endpoint + query)
return requests.get(endpoint).content
return self._get(endpoint)

def get_transaction_status(self, cnio_transaction_id):
# this method returns the transaction status of a transaction. A transaction id
# from list_transactions() or create_transaction() MUST be provided.
endpoint = str("transactions/" + cnio_transaction_id + "/" + self.key)
endpoint = str(self.api + endpoint)
return requests.get(endpoint).content

'''
def live_tx_updates_socketio(self):
# this method interfaces with the socket.io websockets endpoint and gets live transaction updates
# you are probably going to need to call this on a separate thread
# TODO: implement sockets.io connection and data subscription
'''

if __name__ != '__main__':
cnio()
15 changes: 7 additions & 8 deletions test.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import cnio_api
import json
import time

cnio = cnio_api.cnio()
Expand All @@ -23,9 +22,14 @@
print(cnio.min_amount("BTC", "ETH"))
print("===")
#
print(cnio.currencies(active=True))
print(cnio.currencies(active=True, fixed_rate=False))
print("===")
#
print(cnio.currencies_to(ticker="btc", fixed_rate=False))
print("===")
#
print(cnio.specific_currency_info(ticker="btc"))
#
print(cnio.est_exchange_rate("1","BTC","ETH"))
print("===")
#
Expand All @@ -41,12 +45,7 @@
print(transactions_list)

print("===")
transactions_list = str(transactions_list).replace("b'[","")
transactions_list = transactions_list.replace("]'","")
transactions_list = transactions_list.replace("},{","} , {")
transactions_list = transactions_list.split(" , ")

for i in transactions_list:
i = json.loads(i)
#
print(cnio.get_transaction_status(i["id"]))
time.sleep(1)