Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get balances API endpoint #9

Open
olemis opened this issue Feb 24, 2019 · 0 comments
Open

Get balances API endpoint #9

olemis opened this issue Feb 24, 2019 · 0 comments
Assignees

Comments

@olemis
Copy link
Contributor

olemis commented Feb 24, 2019

[GET] /api/balances?take=integer&[continuation=string]

Should return balances of the observed wallets with non zero balances. Wallets balance observation is enabled by the [POST] /api/balances/{address}/observation and disabled by the [DELETE] /api/balances/{address}/observation.

Amount of the returned balances should not exceed take . Optional continuation contains context of the previous request, to let Blockchain.Api resume reading of the balances from the previous position. If continuation is empty, balances should be read from the beginning.

Response:

{
  
{
 // Flag, which indicates that the address is valid
“isValid”: boolean,
  // Continuation token, that
    // can be used to continue data reading
    // from the current position.
    // Should be null or empty string if no more data
    // to read.
    “continuation”: “string”,
    // Current batch of the items
    // Should be empty array if there are no items
    “items”:
    [
{
 // Wallet address
“address”: “string”,
 // Asset ID , defaults to SKY
“assetId”: “string”,
            // Balance is integer as string, aligned
            // to the asset accuracy. Actual value can be
            // calculated as
            // x = sourceBalance * (10 ^ asset.Accuracy)
            “balance”: “string”,
// Incremental ID of the moment, when balance
// is updated. It should be the same sequence
// as for block in the
// [GET] /api/transactions/broadcast/* responses
// In other words , block number/height.
            “block”: integer64
        }
] }

Since there are no constraints on tokens returned for continuation , some performance improvements should be obtained by returning the last address itself as continuation token for pagination. Should be stored in Redis index .

Python implementation

@api.route('/balances', methods=['GET'])
def get_balances():
    """
    Get balances of addresses in observation list
    """

    update_index() 
    
    take = request.args.get('take')
    if take is None:
        take = app_config.DEFAULT_LIST_LENGTH
    else:
        take = max(int(take), app_config.DEFAULT_LIST_LENGTH)
    
    continuation = request.args.get('continuation')  #Holds the continuation address previously sent to client
    if continuation is None:
        continuation = ""    
    
    #Get address list from mongodb
    addresses = get_addresses_balance_observation()  
    
    items = []
    
    #define search boundaries
    start_index = 0 if continuation == "" or continuation not in addresses else addresses.index(continuation)
    total_items = take if take != 0 else len(addresses)   
    
    blockheight = get_indexed_blockheight()
    if 'error' in blockheight:
        return make_response(jsonify(build_error(blockheight["error"])), blockheight["status"])
    
    while len(items) < total_items and start_index < len(addresses):
        item = {}
        
        #Get balance from index        
        balance = get_indexed_balance(addresses[start_index])        
        if 'error' in balance: #If there is an error in balance, continue with the next address
            start_index += 1
            continue
     
        #Generate output response
        item['address'] = addresses[start_index]
        item['assetId'] = app_config.SKYCOIN_FIBER_ASSET
        item['balance'] = str(balance['balance'])  #TODO: Asset accuracy. Find endpoint for that
        item['block'] = blockheight['blockheight']
        if balance['balance'] != 0:
            items.append(item)
        
        start_index += 1

    #Add continuation address
    if start_index < len(addresses): #Still data to read        
        #If it is the first call and need continuation create the token
        if continuation == "" and take != 0 and take < len(addresses):
            continuation = addresses[start_index]
    else:
        continuation = ""

    response = {"continuation": continuation, "items": items}
        

return jsonify(response)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants