Skip to content

Backend Api for My Signals App Copy Trading platform. pay for signals with cryptocurrency and place the signals automatically on your binance account

Notifications You must be signed in to change notification settings

Godhanded/MySignalsApp

Repository files navigation

MySignalsApp_Server

TODO

  • Switch to MainNet

Table Of Contents


MY SIGNALSAPP API-ENDPOINT DOCUMENTATION




Set up the server

Install Dependencies

$ python3 -m venv venv

$ source venv/bin/activate

$ pip install -r requirements.txt

Set up the Database

With Postgres running, create a sigs database:

$ createdb sigs

Run the Server

$ python3 run.py 

Base Uri



hosted for live testing on https://api.mysignals.app/ ....


Error Handling



Errors are returned as JSON objects in the following format with their error code

{
  "error": "error name",
  "message": "error description"
}

The API will return 5 error types, with diffreent descriptions when requests fail;

  • 400: Request unprocessable
  • 403: Forbidden
  • 404: resource not found
  • 422: Bad Request
  • 429: Too Many Requests(rate limiting)
  • 500: Internal server error

Permissions/Roles



There are three roles available, role will be provided at login and base_uri/auth/@me

  • User:["User"]
    • general permissions, regular user
  • Provider:["User","Provider"]
    • signal providers,permissions to upload signals for users to trade
  • Registrar:["User","Registrar]
    • Admin, grant roles and view users

EndPoints




AUTHENTICATION

server side authentication is Used

POST '/auth/register'

  • Register new user,role is set to user and account is marked inactive, sends activation code to user email on success.
  • Request Arguements: JSON object containing
{
  "email":"user email",
  "user_name":"user name",
  "password":"password at least 8 characters",
  "confirm_password":"confirm password",
  "referrers_code":"referal code to register",// "" if no ref code
  "wallet":"User wallet address"
}
  • Returns message ,user name and email
{
    "message": "Success", 
    "user_name": "user_name", 
    "email": "user email"
}


GET '/auth/activate/${token}'

  • Activates user account
  • Request Arguements: token- string token/code
  • Returns: HTML


POST '/auth/login'

  • login user, Server side sessions is used, cookie is sent to client
  • Request Arguements: JSON object containing
{
  "user_name_or_mail":"users username or email address",
  "password":"user password"
}
  • Returns: JSON, permissions of logged in user and if user account is active
 {
    "message": "Success",
    "id":"user id",
    "has_api_keys": true,
    "user_name": "user_name",
    "referral_code":"90jeu378",
    "is_active": true,//boolean- if account is active or not
    "permission": "User",//string 'User' or array of permissions
}

note: "permission":["User","Provider"] or "permission":"User"



POST '/auth/reset_password'

  • Request password reset, reset code sent to user mail if exists
  • Request Arguements: Json object
{
    "email":"user email"
}

Returns:

{
    "message": "Reset password token will be sent to {email} if they exist"
}


POST '/auth/reset_password/${token}'

  • receive sent token and allows password chsnge
  • Request Arguements token-string jwt token and JSON object
{
  "password":"user password",
  "confirm_password":"confirm password"
}
  • Returns:
{"message": "Password changed"}


POST '/auth/logout'

  • Log out user
  • Returns: 'message'
{
    "message": "Success",
}


GET '/auth/@me'

  • gets all data of currenly logged in user
  • Requires logged in
  • Returns: JSON object
{
    "message": "Success",
    "id":"user id",
    "has_api_keys": false,
    "email": "email",
    "referral_code": "90c44000",// users referral code
    "referrals": 0,
    "referrers_wallet": null,//wallet address of referrer
    "wallet": "0xodn",//wallet address of user
    "unread_notifications":1,
    "user_name": "user_name",
    "is_active": false,
    "roles": "['User','Rgistrar']",
    "created_on": "thu 30 june 2021 12:24:07"
}


GET '/auth/notifications' or GET '/auth/notifications?page=${page}'

  • gets all notifications of a user
  • Requires logged in
  • Request Arguements:query parameter page- integer defaults to 1 if not provided
  • Returns: JSON object paginated
{
  "message": "success",
  "notifications": [
    {
      "date_created": "Mon, 15 Jan 2024 17:46:38 GMT",
      "id": 1,
      "message": "test notification",
      "user": "bingoprovider"
    }
  ],
  "pages": 1,
  "status": true,
  "total": 1
}


GET '/auth/notifications/count'

  • gets total number of unread notifications of logged in user
  • Returns: JSON object
{
  "message": "success",
  "status": true,
  "unread_notifications": 1
}


POST '/auth/update_keys'

  • Change api key and secret, Requires logged in
  • Request Arguements: JSON object
{
    "api_key":"key...",
    "api_secret":"secret..."
}

Returns: Json object

{
    "message": "success",
    "id":"user id",
    "has_api_keys": true,
    "user_name": "user_name",
    "is_active": true,
}



PROVIDER ENDPOINTS

ENDPOINTS only accessible to logged in user with Provider role. These are Signal Providers

GET '/provider/signals' or GET '/provider/signals?page=${page}'

  • get all signals uploaded by logged in provider
  • Request Arguements:query parameter page- integer defaults to 1 if not provided
  • Returns: JSON object array of signals, total signals and total number of pages,20 signals max per page
{
    "message": "Success",
    "provider_rating": 0.0,
    "signals": [
        {
            "id": 1,
            "signal": {
                "symbol":"BNBUSDT",
                "side":"BUY",
                "quantity":"0.05",
                "price":"360",
                "stops":{
                    "sl":"350",
                    "tp":"380"
                }
            },
            "short_text":"short message from provider",
            "status": true, //is signal is still valid
            "is_spot": true,// if is spot trade
            "provider": "testprovider", // provider user name
            "provider_wallet": "0x0...",//providers wallet address
            "date_created": "sun 31 march 2020 13:42:00",
        },
        {
            "id": 2,
            "signal": {
                "symbol":"LTCUSDT",
                "side":"SELL",
                "quantity":"1",
                "price":"70.05",
                "stops":{
                    "sl":"73.2",
                    "tp":"60"
                }
            },
            "short_text":"short message from provider",
            "status": false, //old or no longer valid
            "is_spot": false,// futures trade
            "provider": "testprovider", // provider user name
            "provider_wallet": "0x0...",//providers wallet address
            "date_created": "sun 31 march 2020 13:42:00",
        },
    ],
    "total": 5,// total signals from this provider
    "pages": 1,// total number of pages available
}


GET '/provider/spot/pairs'

  • get all available USDT spot trading pairs from binance
  • Returns: JSON object
{
    "message":"success",
    "pairs":[
        "BNBUSDT",
        "ETHUSDT",
        "BTCUSDT"]
}


GET '/provider/futures/pairs'

  • get all available USDT futures trading pairs from binance
  • Returns: JSON object
{
    "message":"success",
    "pairs":[
        "BNBUSDT",
        "ETHUSDT",
        "BTCUSDT"]
}


POST '/provider/spot/new'

  • upload or post new spot trade
  • Request Arguements: JSON object
{
  "symbol":"BNBUSDT",
  "side":"BUY",
  "quantity":"0.5",//type:float
  "price":"336",//type:float
  "tp1":"325",//type:float
  "tp2":"",//float optional
  "tp3":"",//float optional
  "sl":"340",//type:float
  "short_text":"sample short message from provider"
}
  • Returns: JSON object
{
    "message":"success",
    "signal":{
            "id": 1,
            "signal": {
                "symbol":"BNBUSDT",
                "side":"SELL",
                "quantity":"0.5",
                "price":"366",
                "stops":{
                    "sl":"340",
                    "tp":"325"
                }
            },
            "short_text":"short message from provider",
            "status": true, //is signal is still valid
            "is_spot": true,// if is spot trade
            "provider": "testprovider", // provider user name
            "provider_wallet": "0x0...",//providers wallet address
            "date_created": "sun 31 march 2020 13:42:00",
        }
}


POST '/provider/futures/new'

  • upload or post new futures trade
  • Request Arguements: JSON object
{
  "symbol":"BNBUSDT",
  "side":"SELL",
  "quantity":"0.5",//type:float
  "price":"336",//type:float
  "leverage":"3",//type:integer
  "tp1":"325",//type:float required
  "tp2":"",//float optional
  "tp3":"",//float optional
  "sl":"340",//type:float
  "short_text":"sample short message from provider"
}
  • Returns: JSON object
{
    "message":"success",
    "signal":{
            "id": 1,
            "signal": {
                "symbol":"BNBUSDT",
                "side":"SELL",
                "quantity":"0.5",
                "leverage":"5",
                "price":"366",
                "stops":{
                    "sl":"340",
                    "tp":"325"
                }
            },
            "short_text":"short message from provider",
            "status": true, //if signal is still valid
            "is_spot": false,// if is futures trade
            "provider": "testprovider", // provider user name
            "provider_wallet": "0x0...",//providers wallet address
            "date_created": "sun 31 march 2020 13:42:00",
        }
}


POST '/provider/delete/${signal_id}'

  • Provider deletes a signal he has created before
  • Request Arguements: signal_id- integer id of the signal to delete Returns: JSON object
{
    "message":"success",
    "signal_id":1
}


POST '/provider/deactivate/${signal_id}'

  • Provider marks a signal he has created before as no longer valid
  • Request Arguements: signal_id- integer id of the signal to edit Returns: JSON object
{
    "message":"success",
    "signal_id":1
}


POST '/provider/update_wallet'

  • allows provider change wallet address the will be paid with requires user is active
  • Request Arguements: JSON object
{
    "wallet":"0x12..."
}

Returns:JSON object

{
    "message":"wallet changed"
}


GENERAL ENDPOINTS

ENDPOINTS accessible to any logged in user

POST '/spot/trade/${signal_id}'

  • place spot trade on logged in users binance account
  • Request Arguements: signal_id- integer, id of signal to trade and empty JSON body
{ 
  "tp":"0.876",//selected tp:float
  "quoteQty":"10" //AMOUNT USDT TO TRADE
}
  • Returns:JSON object
{
    "message":"success",
    "signal":{
        "symbol":"BNBUSDT",
        "side":"SELL",
        "quantity":"0.5",
        "price":"336",
        "timeInForce": "GTC",
        "type": "LIMIT",
        "tp":"325",
        "sl":"340",
        "newClientOrderId": "bieuhcfu3y478gi88"
    }
}


POST '/futures/trade/${signal_id}'

  • place futures trade on logged in users binance account
  • Request Arguements: signal_id- integer, id of signal to trade and JSON body containig
{ 
  "tp":"0.876",//selected tp:float
  "quoteQty":"10" //AMOUNT USDT TO TRADE
}
  • Returns:JSON object
{
    "message":"success",
    "signal":{
        "symbol":"BNBUSDT",
        "side":"SELL",
        "quantity":"0.5",
        "price":"336",
        "timeInForce": "GTC",
        "type": "LIMIT",
        "tp":"325",
        "sl":"340",
        "leverage":"3",
        "newClientOrderId": "bieuhcfu3y478gi88"
    }
}


GET or POST '/signal/${signal_id}?tx_hash=${tx_hash}'

  • get complete details of a signal, requires logged in

  • Request Arguements: query parameter signal_id- integer,tx_hash - string; id of signal to get;tx hash of payment made to contract

  • Returns: JSON object

{
  "message":"success",
  "signal": {
            "id": 1,
            "signal": {
                "symbol":"BNBUSDT",
                "side":"SELL",
                "quantity":"0.5",
                "price":"366",
                "stops":{
                    "sl":"340",
                    "tp":"325"
                }
            },
            "short_text":"",//short message from provider
            "status": true, //is signal is still valid
            "is_spot": true,// if is spot trade
            "provider": "testprovider", // provider user name
            "provider_wallet": "0x0...",//providers wallet address
            "date_created": "sun 31 march 2020 13:42:00",
        }
}


POST '/signal/rate/${signal_id}'

  • rate a trade that as user has paid for and has taken before
  • Request Arguements: query parameter signal_id- integer, id of signal to rate and JSON object:
{
  "rate":5 // integer between 1 and 5
}
  • Returns: JSON object
{
  "message": "success", 
  "rating": 5
}


GET '/' or GET '?page=${page}'

  • get reduced/summarized form of all active signals(status=true),paginated
  • Request Arguements: page- integer page number, page defaults to 1 if not given
  • Returns:JSON object
{
  "message": "Success",
  "signals":[
    {
      "id": 4,
      "signal": {
          "symbol": "LTCUSDT",
          "side":"SELL",
          "quantity":""
      },
      "is_spot": true,
      "short_text":null,
      "provider":"proider username",
      "provider_wallet": "0x21gh...",
      "provider_rating":4.65,
      "date_created": "Sun 31 march 2020 13:42:00",
    },
    {
      "id": 7,
      "signal": {
          "symbol": "BTCUSDT",
          "side":"BUY",
          "quantity":""
      },
      "is_spot": true,
      "provider":"proider username",
      "short_text":null,
      "provider_wallet": "0x21gh...",
      "provider_rating":4.05,
      "date_created": "Sun 31 march 2020 13:42:00",
    },
    {
      "id": 9,
      "signal": {
          "symbol": "ETHUSDT",
          "side":"SELL",
          "quantity":""
      },
      "is_spot": false,
      "provider":"proider username",
      "short_text":null,
      "provider_wallet": "0x21gh...",
      "provider_rating":3.35,
      "date_created": "Sun 31 march 2020 13:42:00",
    }
  ],
  "total": 40,
  "pages": 3,
}


GET '/mytrades' or GET '/mytrades?page=${page}'

  • get all previously purchased trades of logged in user,paginated
  • Request Arguements: page- integer page number, page defaults to 1 if not given
  • Returns:JSON object
{
  "message": "success",
  "pages": 1,
  "total": 2 ,
  "mytrades": [
    {
      "date_created": "Mon, 27 Nov 2023 00:10:22 GMT",
      "id": 2,
      "is_spot": true,
      "short_text":"", //short message from provider
      "provider": "testprovider", // provider user name
      "provider_wallet": "0x0...",//providers wallet address
      "signal": {
        "price": 336.0,
        "quantity": 0.5,
        "side": "SELL",
        "stops": {
          "sl": 340.0,
          "tp": 325.0
        },
        "symbol": "LTCUSDT"
      },
      "status": true,
      "user_rating": 0 // signal rating given by this logged in user
    },
    {
      "date_created": "Mon, 27 Nov 2023 00:10:07 GMT",
      "id": 1,
      "is_spot": true,
      "short_text":"",//short message from provider
      "provider": "testprovider", // provider user name
      "provider_wallet": "0x0...",//providers wallet address
      "signal": {
        "price": 336.0,
        "quantity": 0.5,
        "side": "SELL",
        "stops": {
          "sl": 340.0,
          "tp": 325.0
        },
        "symbol": "BNBUSDT"
      },
      "status": true,
      "user_rating": 0  // signal rating given by this logged in user
    }
  ],
  "status": true
}


POST '/mytrades/cancel/${id}'

  • cancel a trade that was placed on binance through MySignals
  • Request Arguements: id- integer id of signal to cancel
  • Request Body: Empty Json Object
{}
  • Returns:JSON object
{
    "message": "Successfully Cancelled Signal!",
    "status": true,
    "signal_id": 13,
}




POST '/apply/provider'

  • submit request to become a signal provider
  • Request Arguements: JSON object:
{
  "wallet":"0x40 characters more",
  "experience":"",//providers experience(300 chars max 10 chars min)
  "socials_and_additional":"" //social links and other relevant info(500 chars max 10 chars min)
}
  • Returns:JSON object
{
  "message": "success",
  "status": true
}


#### **REGISTRAR ENPOINTS** >ENDPOINTS only accessible to logged in user with Registrar role. This is The Admin

POST '/registrar/provider/new'

  • Change user role to Provider
  • Request Arguements: JSON object
{
  "email":"user@email.com"
}
  • Returns:JSON object
{
  "message": "success", 
  "provider": "user@email.com"
}


POST '/registrar/registrar/new'

  • Change user role to Registrar
  • Request Arguements:JSON object
{
  "email":"user@email.com"
}
  • Returns:JSON object
{
  "message": "success", 
  "registrar": "user@email.com"
}


POST '/registrar/drop_role'

  • Drop any special role of back to User
  • Request Arguements: JSON object
{
  "email":"user@email.com"
}
  • RETURNS:JSON object
{
  "message": "success", 
  "registrar": "user@email.com"
}


GET '/registrar/role/providers' or GET '/registrar/role/providers?page=${page}'

  • Get all users with Provider role,paginated
  • Request Arguements: page-integer, defaults to 1
  • Returns:JSON object
{
    "message": "success",
    "providers": [],
    "pages": 0,
    "total": 0,
}

or

{
    "message": "success",
    "providers": [
      {
        "id": 4,
        "email": "user@email.com",
        "user_name": "user name",
        "roles": "Provider",
        "is_active": true,
        "wallet": "0x05tg4...",
        "has_api_keys": true,
        "date_created": "Sun 31 march 2020 13:42:00"
      },
      {
        "id": 5,
        "email": "user@email.com",
        "user_name": "user name",
        "roles": "Provider",
        "is_active": false,
        "wallet": "0x05tg4...",
        "has_api_keys": true,
        "date_created": "Sun 31 march 2020 13:42:00"
      }
    ],
    "pages": 1,
    "total": 2
}


GET '/registrar/role/registrars' or GET '/registrar/role/registrars?page=${page}'

  • Get all users with Registrar role,paginated
  • Request Arguements: page-integer, defaults to 1
  • Returns:JSON object
{
    "message": "success",
    "registrars": [],
    "pages": 0,
    "total": 0,
}

or

{
    "message": "success",
    "registrars": [
      {
        "id": 4,
        "email": "user@email.com",
        "user_name": "user name",
        "roles": "Registrars",
        "is_active": true,
        "wallet": "0x05tg4...",
        "has_api_keys": true,
        "date_created": "Sun 31 march 2020 13:42:00"
      },
      {
        "id": 5,
        "email": "user@email.com",
        "user_name": "user name",
        "roles": "Registrar",
        "is_active": false,
        "wallet": "0x05tg4...",
        "has_api_keys": true,
        "date_created": "Sun 31 march 2020 13:42:00"
      }
    ],
    "pages": 1,
    "total": 2
}


GET '/registrar/role/users' or GET '/registrar/role/users?page=${page}'

  • Get all regular users, paginated
  • Request Arguements: page-integer, defaults to 1
  • Returns:JSON object
{
    "message": "success",
    "users": [],
    "pages": 0,
    "total": 0,
}

or

{
    "message": "success",
    "users": [
      {
        "id": 4,
        "email": "user@email.com",
        "user_name": "user name",
        "roles": "User",
        "is_active": true,
        "wallet": "0x05tg4...",
        "has_api_keys": true,
        "date_created": "Sun 31 march 2020 13:42:00"
      },
      {
        "id": 5,
        "email": "user@email.com",
        "user_name": "user name",
        "roles": "User",
        "is_active": false,
        "wallet": "0x05tg4...",
        "has_api_keys": true,
        "date_created": "Sun 31 march 2020 13:42:00"
      }
    ],
    "pages": 1,
    "total": 2
}


GET '/registrar/get/users' or GET '/registrar/get/users?page=${page}'

  • Get all regardless of role, paginated
  • Request Arguements: page-integer, defaults to 1
  • Returns:JSON object
{
    "message": "success",
    "users": [],
    "pages": 0,
    "total": 0,
}

or

{
    "message": "success",
    "users": [
      {
        "id": 4,
        "email": "user@email.com",
        "user_name": "user name",
        "roles": "User",
        "is_active": true,
        "wallet": "0x05tg4...",
        "has_api_keys": true,
        "date_created": "Sun 31 march 2020 13:42:00"
      },
      {
        "id": 5,
        "email": "user@email.com",
        "user_name": "user name",
        "roles": "Provider",
        "is_active": false,
        "wallet": "0x05tg4...",
        "has_api_keys": true,
        "date_created": "Sun 31 march 2020 13:42:00"
      }
    ],
    "pages": 1,
    "total": 2
}

Authors

Acknowledgments

  • Binance-Python-Connector

About

Backend Api for My Signals App Copy Trading platform. pay for signals with cryptocurrency and place the signals automatically on your binance account

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages