Source code for Tribler.Core.Modules.restapi.wallets_endpoint

import json

from twisted.internet.defer import DeferredList
from twisted.web import http
from twisted.web import resource
from twisted.web.server import NOT_DONE_YET


[docs]class WalletsEndpoint(resource.Resource): """ This class represents the root endpoint of the wallets resource. """ def __init__(self, session): resource.Resource.__init__(self) self.session = session
[docs] def render_GET(self, request): """ .. http:get:: /wallets A GET request to this endpoint will return information about all available wallets in Tribler. This includes information about the address, a human-readable wallet name and the balance. **Example request**: .. sourcecode:: none curl -X GET http://localhost:8085/wallets **Example response**: .. sourcecode:: javascript { "wallets": [{ "created": True, "name": "Bitcoin", "unlocked": True, "precision": 8, "min_unit": 100000, "address": "17AVS7n3zgBjPq1JT4uVmEXdcX3vgB2wAh", "balance": { "available": 0.000126, "pending": 0.0, "currency": "BTC" } }, ...] } """ wallets = {} balance_deferreds = [] for wallet_id in self.session.lm.wallets.iterkeys(): wallet = self.session.lm.wallets[wallet_id] wallets[wallet_id] = { 'created': wallet.created, 'unlocked': wallet.unlocked, 'address': wallet.get_address(), 'name': wallet.get_name(), 'precision': wallet.precision(), 'min_unit': wallet.min_unit() } balance_deferreds.append(wallet.get_balance().addCallback( lambda balance, wid=wallet_id: (wid, balance))) def on_received_balances(balances): for _, balance_info in balances: wallets[balance_info[0]]['balance'] = balance_info[1] request.write(json.dumps({"wallets": wallets})) request.finish() balance_deferred_list = DeferredList(balance_deferreds) balance_deferred_list.addCallback(on_received_balances) return NOT_DONE_YET
def getChild(self, path, request): return WalletEndpoint(self.session, path)
[docs]class WalletEndpoint(resource.Resource): """ This class represents the endpoint for a single wallet. """ def __init__(self, session, identifier): resource.Resource.__init__(self) self.session = session self.identifier = identifier.upper() child_handler_dict = {"balance": WalletBalanceEndpoint, "transactions": WalletTransactionsEndpoint, "transfer": WalletTransferEndpoint} for path, child_cls in child_handler_dict.iteritems(): self.putChild(path, child_cls(self.session, self.identifier))
[docs] def render_PUT(self, request): """ .. http:put:: /wallets/(string:wallet identifier) A request to this endpoint will create a new wallet. **Example request**: .. sourcecode:: none curl -X PUT http://localhost:8085/wallets/BTC **Example response**: .. sourcecode:: javascript { "created": True } """ if self.session.lm.wallets[self.identifier].created: request.setResponseCode(http.BAD_REQUEST) return json.dumps({"error": "this wallet already exists"}) def on_wallet_created(_): request.write(json.dumps({"created": True})) request.finish() self.session.lm.wallets[self.identifier].create_wallet().addCallback(on_wallet_created) return NOT_DONE_YET
[docs]class WalletBalanceEndpoint(resource.Resource): """ This class handles requests regarding the balance in a wallet. """ def __init__(self, session, identifier): resource.Resource.__init__(self) self.session = session self.identifier = identifier
[docs] def render_GET(self, request): """ .. http:get:: /wallets/(string:wallet identifier)/balance A GET request to this endpoint will return balance information of a specific wallet. **Example request**: .. sourcecode:: none curl -X GET http://localhost:8085/wallets/BTC/balance **Example response**: .. sourcecode:: javascript { "balance": { "available": 0.000126, "pending": 0.0, "currency": "BTC" } } """ def on_balance(balance): request.write(json.dumps({"balance": balance})) request.finish() self.session.lm.wallets[self.identifier].get_balance().addCallback(on_balance) return NOT_DONE_YET
[docs]class WalletTransactionsEndpoint(resource.Resource): """ This class handles requests regarding the transactions of a wallet. """ def __init__(self, session, identifier): resource.Resource.__init__(self) self.session = session self.identifier = identifier
[docs] def render_GET(self, request): """ .. http:get:: /wallets/(string:wallet identifier)/transactions A GET request to this endpoint will return past transactions of a specific wallet. **Example request**: .. sourcecode:: none curl -X GET http://localhost:8085/wallets/BTC/transactions **Example response**: .. sourcecode:: javascript { "transactions": [{ "currency": "BTC", "to": "17AVS7n3zgBjPq1JT4uVmEXdcX3vgB2wAh", "outgoing": false, "from": "", "description": "", "timestamp": "1489673696", "fee_amount": 0.0, "amount": 0.00395598, "id": "6f6c40d034d69c5113ad8cb3710c172955f84787b9313ede1c39cac85eeaaffe" }, ...] } """ def on_transactions(transactions): request.write(json.dumps({"transactions": transactions})) request.finish() self.session.lm.wallets[self.identifier].get_transactions().addCallback(on_transactions) return NOT_DONE_YET
[docs]class WalletTransferEndpoint(resource.Resource): """ This class handles requests regarding transferring money by a wallet. """ def __init__(self, session, identifier): resource.Resource.__init__(self) self.session = session self.identifier = identifier
[docs] def render_POST(self, request): """ .. http:post:: /wallets/(string:wallet identifier)/transfer A POST request to this endpoint will transfer some units from a wallet to another address. **Example request**: .. sourcecode:: none curl -X POST http://localhost:8085/wallets/BTC/transfer --data "amount=0.3&destination=mpC1DDgSP4PKc5HxJzQ5w9q6CGLBEQuLsN" **Example response**: .. sourcecode:: javascript { "txid": "abcd" } """ parameters = http.parse_qs(request.content.read(), 1) if self.identifier != "BTC" and self.identifier != "TBTC": request.setResponseCode(http.BAD_REQUEST) return json.dumps({"error": "currently, currency transfers using the API is only supported for Bitcoin"}) wallet = self.session.lm.wallets[self.identifier] if not wallet.created: request.setResponseCode(http.BAD_REQUEST) return json.dumps({"error": "this wallet is not created"}) if 'amount' not in parameters or 'destination' not in parameters: request.setResponseCode(http.BAD_REQUEST) return json.dumps({"error": "an amount and a destination address are required"}) def on_transferred(txid): request.write(json.dumps({"txid": txid})) request.finish() def on_transfer_error(error): request.setResponseCode(http.INTERNAL_SERVER_ERROR) request.write(json.dumps({"txid": "", "error": error.getErrorMessage()})) request.finish() wallet.transfer(parameters['amount'][0], parameters['destination'][0]).addCallback(on_transferred)\ .addErrback(on_transfer_error) return NOT_DONE_YET