CoinTerm - cryptocurrency solution for payment kiosks.

We are a cryptocurrency exchange platform.

Agent is a kiosk network owner. We set up a contract between agent and exchange.
Agent holds a deposit on the exchange to cover the deals.

Customer chooses a cryptocurrency(Bitcoin, Litecoin, Ethereum, Zcash), sees the current price, deposits cash, then chooses the resulting payment method - either private key printed on the receipt, or sending the cryptocurrency to a wallet address scanned by QR-reader.

To print out a private key on the receipt, agent gets or generates a pair (private key and address), to which cryptocurrency is sent to, and then prints a private key as a plain text and QR code on the customer’s receipt.

Exchange sends the cryptocurrency to this wallet.

Exchange can fix the rate for 5 minute for a customer convenience.
Kiosk is regularly sending a request to the exchange which recalculates the rate and gives a response.
Rate is calculated as a best offer in the orderbook or last_price + exchange trade fee + agent fee + subagent fee.

To complete the deal, kiosk receives a rate from the exchange:

  1. If the received rate is better than fixed, the deal is completed with a calculated rate.
  2. If the received rate is either outdated or random, then exchange is evaluating the rate against market price in the orderbook:
    2.1 if the deal might be completed with this rate, then it is done
    2.2 if not then error is generated. Rate should be fixed against, or another rate should be generated.

Single deposit can be shared by multiple kiosks.

Kiosks may face connection issues, thus request-response mode is used. Websocket and rest-api are used as transport protocols.

Each request handles a token, call name and parameters.
Token is generated in the personal interface: Profile -> Tokens.

Calls available:

pairs

Get a list of cryptocurrencies available (get trade pairs)

Parameter * Type Description
currency 0 string return a list with a named currency

example:

curl \
    -s -H "Content-Type: application/json" -X POST \
    -d '{ "token":"fixed:0tLqBR6B7D5FqI0wbK27EaWz2Ta0T1vyPEcwEuqtIQQ", "call":"pairs", "currency": "eur" }' \
    https://bitlish.com/api/v1 | python -m json.tool;
{
    "btceur": {
        "currency_id": "eur",
        "id": "btceur",
        "item_id": "btc",
        "name": "BTC/EUR"
    },
    "etheur": {
        "currency_id": "eur",
        "id": "etheur",
        "item_id": "eth",
        "name": "ETH/EUR"
    },
    "ltceur": {
        "currency_id": "eur",
        "id": "ltceur",
        "item_id": "ltc",
        "name": "LTC/EUR"
    },
    "zeceur": {
        "currency_id": "eur",
        "id": "zeceur",
        "item_id": "zec",
        "name": "ZEC/EUR"
    }
}

term_rate

Get a rate

Parameter * Type Description
pair_id 1 string get rate

example:

curl \
    -s -H "Content-Type: application/json" -X POST \
    -d '{ "token":"fixed:0tLqBR6B7D5FqI0wbK27EaWz2Ta0T1vyPEcwEuqtIQQ", "call":"term_rate", "pair_id": "btceur" }' \
    https://bitlish.com/api/v1 | python -m json.tool;
{
    "expire": "1476948550", # time to live for a fixed rate
    "now": "1476948548",    # current server time
    "pair_id": "btceur",    # trade pair
    "sell": "298.5",        # sell rate
    "buy": "321.6",         # buy rate       
}

term_buy

Execute a buy order

Uniquess of a label is checked, thus there is an option to make a call with the same label and be sure withdrawal won’t be duplicated.

Parameter * Type Descripti
amount 0 Num amount of coins to buy
volume 0 Num amount of fiat money to buy
address 1 Str withdrawal address
price 1 Num buy rate
pair_id 1 Str trade pair
mark 0 Str random unique identifier

example:

curl \
    -s -H "Content-Type: application/json" -X POST \
    -d '{ "token":"fixed:myIuuL4ZevoAEwXf7kRDqgiO6DmGb84GePWuiAR4T1o", "call":"term_buy", "pair_id": "btceur", "price":"321.6", "volume":"300", "mark"
:"test", "address":"my9Ga4wWoA2CRxDcSJJvJAetRqMMchH35z" }' \
    https://bitlish.com/api/v1 | python -m json.tool;                                                                                                                                
{
    "pair_id": "btceur",    # trade pair
    "dir": "buy",           # order direction
    "price": "321.6",       # rate
    "amount": "0.93283582", # amount of cryptocurrency (coins)
    "volume": "300",        # amount of fiat money (currency)
    "mark": "test",         # random unique identifier
    "from": "eur",          # debited currency
    "to": "btc",            # credited currency
    "recv": "0.93283582",   # income  ( debited amount )
    "send": "300",          # outcome ( credited amount, sent to the address )
    "ts": "1476973082",     # deal time
    "repeated_reply": "1"   # mark non-unique - respond with the details of the previous deal with the same mark
}

term_convert

Make a conversion - buy or sell the neccessary amount of coins.

While making a buy deal, you should mention the neccessary amount of coins with a price amount*price, and make a withdrawal to your address.

While making a sell deal, you mention the neccessary amount of coins to sell, and credited sum equal to amount*price is withdrawn according to the withdraw parameters you mention.

Uniquess of a label is checked, thus there is an option to make a call with the same label and be sure withdrawal won’t be duplicated.

Paramete * Type Descriptio
amount 0 Num amount of coins to buy/sell
volume 0 Num amount of fiat money to buy
dir 1 Str order direction buy or sell
price 1 Num buy rate. can be fixed beforehand usingterm_rate
pair_id 1 Str trade pair i.e. btcusd etc.
mark 0 Str random unique identifier
withdraw 1 Hash withdraw parameters.depends on payment method. pls check withdraw call description

response is equal to term_buy

example:

curl \
    -s -H "Content-Type: application/json" -X POST \
    -d '{ "token":"fixed:myIuuL4ZevoAEwXf7kRDqgiO6DmGb84GePWuiAR4T1o", "call":"term_convert", "pair_id": "btceur", "dir":"buy", "price":"321.6", "volume":"300", "mark":"testx", "withdraw": { "account":"my9Ga4wWoA2CRxDcSJJvJAetRqMMchH35z", "payment_method": "bitcoin" } }' \
    https://bitlish.com/api/v1/ | python -m json.tool;                                                                 
{
    "amount": "0.93283582",
    "dir": "buy",
    "from": "eur",
    "mark": "testx",
    "pair_id": "btceur",
    "price": "321.6",
    "recv": "0.93283582",
    "send": "300",
    "to": "btc",
    "ts": "1476974584",
    "volume": "300",
    "repeated_reply": "1"
}

get_addr_with_pkey

Agent uses this call when he needs to get a private key and address for the withdrawal. After getting a repsonse, address is used as a withdrwal address, and private key is printed on a receipt as plain text and QR code.QR code allows to easily get the coins using mobile crypto wallets. Don’t forget private key is strictly confidential thus agent is responsible to keep it secret.

curl \
    -s -H "Content-Type: application/json" -X POST \
    -d '{ "token":"fixed:myIuuL4ZevoAEwXf7kRDqgiO6DmGb84GePWuiAR4T1o", "call":"get_addr_with_pkey", "currency": "btc"}' \
    https://bitlish.com/api/v1/ | python -m json.tool;                                                                 
{
    "address":"15yJoKLRfzMd4Ce25rrqUPjwpTdSNBHKDj",
    "pkey":"L3dxa6Ta3UocXUJEfmEBFrLwT7WK5QJ1LQurr26BZxZk3CR6yrxY",
    "wallet_id":"1486474874422327"
}

send_to_login

Top-up an account to the user with named mobile number or email.
This call is used for top-up of a user account on exchange.

Параметр * Тип Описание
login 1 Str phone number or email of a registered exchange user
amount 1 Num amount to be credited
currency 1 Str currency
curl \
    -s -H "Content-Type: application/json" -X POST \
    -d '{ "token":"fixed:myIuuL4ZevoAEwXf7kRDqgiO6DmGb84GePWuiAR4T1o", "call":"send_to_login", "currency": "eur", "amount": 10, "login": "+7123456789" }' \
    https://bitlish.com/api/v1/ | python -m json.tool
{
    "amount": "10.0000000000000000",
    "currency": "eur"
}

All successful calls return HTTP code 200.
Error generates a HTTP code different from 200. Error description is inside the response:

# curl -s -H "Content-Type: application/json" -X POST -d '{ "token":"fixed:V0tjx0191o9lAalNtieoJW9sH2FVV9FQ/f2aup+gF9g", "call":"term_buy", "pair_id": "btceur", "price":"321.6", "volume":"300", "mark": "test"
, "address": "zzz" }' https://bitlish.com/api/v1/ | python -m json.tool;                                                                                                                                                                         
{
    "errcode": "Bitlish::Err::BadArgs", # error type
    "msg": "Invalid %s",                # error description, formatted
    "args": [ "account" ],              # argument to be used in "sprintf" function for localisation
    "path": [ "account" ],              # which field in the argument is invalid (path in the structure) 
    "text": "Bitlish::Err::BadArgs: account: 'Invalid account' \n" # combined error code text
}

Error codes:

  • Bitlish::Err::AlreadyExists - transaction with this label is already registered, but information about it is not available (otherwise the same info is returned)
  • Bitlish::Err::NoPerm - no access, cointerm api is disabled
  • Bitlish::Err::BadArgs - arguments are invalid - check the other fields in the response
  • Bitlish::Err::NoWay - rate cannot be calculated
  • Bitlish::Err::NotFound - rate with this price is not registered or outdated, and cannot be fixed now with the same conditions