digitalbitbox, trustedcoin: proxied http client
use common cross-thread HTTP method, which is put in network.py, since that is where the proxy is. TrustedCoin tested successfully, but DigitalBitbox can't be tested completely due to #4903 before this commit, digitalbitbox would not use any proxying
This commit is contained in:
@@ -38,9 +38,12 @@ import traceback
|
|||||||
import dns
|
import dns
|
||||||
import dns.resolver
|
import dns.resolver
|
||||||
from aiorpcx import TaskGroup
|
from aiorpcx import TaskGroup
|
||||||
|
from aiohttp import ClientResponse
|
||||||
|
|
||||||
from . import util
|
from . import util
|
||||||
from .util import PrintError, print_error, log_exceptions, ignore_exceptions, bfh, SilentTaskGroup
|
from .util import (PrintError, print_error, log_exceptions, ignore_exceptions,
|
||||||
|
bfh, SilentTaskGroup, make_aiohttp_session)
|
||||||
|
|
||||||
from .bitcoin import COIN
|
from .bitcoin import COIN
|
||||||
from . import constants
|
from . import constants
|
||||||
from . import blockchain
|
from . import blockchain
|
||||||
@@ -903,3 +906,34 @@ class Network(PrintError):
|
|||||||
await self.interface.group.spawn(self._request_fee_estimates, self.interface)
|
await self.interface.group.spawn(self._request_fee_estimates, self.interface)
|
||||||
|
|
||||||
await asyncio.sleep(0.1)
|
await asyncio.sleep(0.1)
|
||||||
|
|
||||||
|
|
||||||
|
async def _send_http_on_proxy(self, method: str, url: str, params: str = None, body: bytes = None, json: dict = None, headers=None, on_finish=None):
|
||||||
|
async def default_on_finish(resp: ClientResponse):
|
||||||
|
resp.raise_for_status()
|
||||||
|
return await resp.text()
|
||||||
|
if headers is None:
|
||||||
|
headers = {}
|
||||||
|
if on_finish is None:
|
||||||
|
on_finish = default_on_finish
|
||||||
|
async with make_aiohttp_session(self.proxy) as session:
|
||||||
|
if method == 'get':
|
||||||
|
async with session.get(url, params=params, headers=headers) as resp:
|
||||||
|
return await on_finish(resp)
|
||||||
|
elif method == 'post':
|
||||||
|
assert body is not None or json is not None, 'body or json must be supplied if method is post'
|
||||||
|
if body is not None:
|
||||||
|
async with session.post(url, data=body, headers=headers) as resp:
|
||||||
|
return await on_finish(resp)
|
||||||
|
elif json is not None:
|
||||||
|
async with session.post(url, json=json, headers=headers) as resp:
|
||||||
|
return await on_finish(resp)
|
||||||
|
else:
|
||||||
|
assert False
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def send_http_on_proxy(method, url, **kwargs):
|
||||||
|
network = Network.get_instance()
|
||||||
|
assert network._loop_thread is not threading.currentThread()
|
||||||
|
coro = asyncio.run_coroutine_threadsafe(network._send_http_on_proxy(method, url, **kwargs), network.asyncio_loop)
|
||||||
|
return coro.result(5)
|
||||||
|
|||||||
@@ -3,35 +3,36 @@
|
|||||||
# digitalbitbox.com
|
# digitalbitbox.com
|
||||||
#
|
#
|
||||||
|
|
||||||
try:
|
import base64
|
||||||
from electrum.crypto import sha256d, EncodeAES_base64, EncodeAES_bytes, DecodeAES_bytes, hmac_oneshot
|
import binascii
|
||||||
from electrum.bitcoin import (TYPE_ADDRESS, push_script, var_int, public_key_to_p2pkh,
|
import hashlib
|
||||||
is_address)
|
import hmac
|
||||||
from electrum.bip32 import serialize_xpub, deserialize_xpub
|
import json
|
||||||
from electrum import ecc
|
import math
|
||||||
from electrum.ecc import msg_magic
|
import os
|
||||||
from electrum.wallet import Standard_Wallet
|
import re
|
||||||
from electrum import constants
|
import struct
|
||||||
from electrum.transaction import Transaction
|
import sys
|
||||||
from electrum.i18n import _
|
import time
|
||||||
from electrum.keystore import Hardware_KeyStore
|
|
||||||
from ..hw_wallet import HW_PluginBase
|
|
||||||
from electrum.util import print_error, to_string, UserCancelled, UserFacingException
|
|
||||||
from electrum.base_wizard import ScriptTypeNotSupported, HWD_SETUP_NEW_WALLET
|
|
||||||
|
|
||||||
import time
|
from electrum.crypto import sha256d, EncodeAES_base64, EncodeAES_bytes, DecodeAES_bytes, hmac_oneshot
|
||||||
|
from electrum.bitcoin import (TYPE_ADDRESS, push_script, var_int, public_key_to_p2pkh,
|
||||||
|
is_address)
|
||||||
|
from electrum.bip32 import serialize_xpub, deserialize_xpub
|
||||||
|
from electrum import ecc
|
||||||
|
from electrum.ecc import msg_magic
|
||||||
|
from electrum.wallet import Standard_Wallet
|
||||||
|
from electrum import constants
|
||||||
|
from electrum.transaction import Transaction
|
||||||
|
from electrum.i18n import _
|
||||||
|
from electrum.keystore import Hardware_KeyStore
|
||||||
|
from ..hw_wallet import HW_PluginBase
|
||||||
|
from electrum.util import print_error, to_string, UserCancelled, UserFacingException
|
||||||
|
from electrum.base_wizard import ScriptTypeNotSupported, HWD_SETUP_NEW_WALLET
|
||||||
|
from electrum.network import Network
|
||||||
|
|
||||||
|
try:
|
||||||
import hid
|
import hid
|
||||||
import json
|
|
||||||
import math
|
|
||||||
import binascii
|
|
||||||
import struct
|
|
||||||
import hashlib
|
|
||||||
import requests
|
|
||||||
import base64
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import re
|
|
||||||
import hmac
|
|
||||||
DIGIBOX = True
|
DIGIBOX = True
|
||||||
except ImportError as e:
|
except ImportError as e:
|
||||||
DIGIBOX = False
|
DIGIBOX = False
|
||||||
@@ -744,9 +745,10 @@ class DigitalBitboxPlugin(HW_PluginBase):
|
|||||||
EncodeAES_base64(key_s, json.dumps(payload).encode('ascii')).decode('ascii'),
|
EncodeAES_base64(key_s, json.dumps(payload).encode('ascii')).decode('ascii'),
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
requests.post(url, args)
|
text = Network.send_http_on_proxy('post', url, body=args.encode('ascii'), headers={'content-type': 'application/x-www-form-urlencoded'})
|
||||||
|
print_error('digitalbitbox reply from server', text)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.handler.show_error(str(e))
|
self.handler.show_error(repr(e)) # repr because str(Exception()) == ''
|
||||||
|
|
||||||
|
|
||||||
def get_xpub(self, device_id, derivation, xtype, wizard):
|
def get_xpub(self, device_id, derivation, xtype, wizard):
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import hashlib
|
|||||||
|
|
||||||
from urllib.parse import urljoin
|
from urllib.parse import urljoin
|
||||||
from urllib.parse import quote
|
from urllib.parse import quote
|
||||||
|
from aiohttp import ClientResponse
|
||||||
|
|
||||||
from electrum import ecc, constants, keystore, version, bip32
|
from electrum import ecc, constants, keystore, version, bip32
|
||||||
from electrum.bitcoin import TYPE_ADDRESS, is_new_seed, public_key_to_p2pkh
|
from electrum.bitcoin import TYPE_ADDRESS, is_new_seed, public_key_to_p2pkh
|
||||||
@@ -42,7 +43,7 @@ from electrum.mnemonic import Mnemonic
|
|||||||
from electrum.wallet import Multisig_Wallet, Deterministic_Wallet
|
from electrum.wallet import Multisig_Wallet, Deterministic_Wallet
|
||||||
from electrum.i18n import _
|
from electrum.i18n import _
|
||||||
from electrum.plugin import BasePlugin, hook
|
from electrum.plugin import BasePlugin, hook
|
||||||
from electrum.util import NotEnoughFunds, make_aiohttp_session
|
from electrum.util import NotEnoughFunds
|
||||||
from electrum.storage import STO_EV_USER_PW
|
from electrum.storage import STO_EV_USER_PW
|
||||||
from electrum.network import Network
|
from electrum.network import Network
|
||||||
|
|
||||||
@@ -108,14 +109,7 @@ class TrustedCoinCosignerClient(object):
|
|||||||
self.debug = False
|
self.debug = False
|
||||||
self.user_agent = user_agent
|
self.user_agent = user_agent
|
||||||
|
|
||||||
def send_request(self, method, relative_url, data=None):
|
async def handle_response(self, resp: ClientResponse):
|
||||||
network = Network.get_instance()
|
|
||||||
if network:
|
|
||||||
return asyncio.run_coroutine_threadsafe(self._send_request(method, relative_url, data), network.asyncio_loop).result()
|
|
||||||
else:
|
|
||||||
raise ErrorConnectingServer('You are offline.')
|
|
||||||
|
|
||||||
async def handle_response(self, resp):
|
|
||||||
if resp.status != 200:
|
if resp.status != 200:
|
||||||
try:
|
try:
|
||||||
r = await resp.json()
|
r = await resp.json()
|
||||||
@@ -128,7 +122,10 @@ class TrustedCoinCosignerClient(object):
|
|||||||
except:
|
except:
|
||||||
return await resp.text()
|
return await resp.text()
|
||||||
|
|
||||||
async def _send_request(self, method, relative_url, data):
|
def send_request(self, method, relative_url, data=None):
|
||||||
|
network = Network.get_instance()
|
||||||
|
if not network:
|
||||||
|
raise ErrorConnectingServer('You are offline.')
|
||||||
url = urljoin(self.base_url, relative_url)
|
url = urljoin(self.base_url, relative_url)
|
||||||
if self.debug:
|
if self.debug:
|
||||||
print('%s %s %s' % (method, url, data))
|
print('%s %s %s' % (method, url, data))
|
||||||
@@ -136,16 +133,12 @@ class TrustedCoinCosignerClient(object):
|
|||||||
if self.user_agent:
|
if self.user_agent:
|
||||||
headers['user-agent'] = self.user_agent
|
headers['user-agent'] = self.user_agent
|
||||||
try:
|
try:
|
||||||
proxy = Network.get_instance().proxy
|
if method == 'get':
|
||||||
async with make_aiohttp_session(proxy) as session:
|
return Network.send_http_on_proxy(method, url, params=data, headers=headers, on_finish=self.handle_response)
|
||||||
if method == 'get':
|
elif method == 'post':
|
||||||
async with session.get(url, params=data, headers=headers) as resp:
|
return Network.send_http_on_proxy(method, url, json=data, headers=headers, on_finish=self.handle_response)
|
||||||
return await self.handle_response(resp)
|
else:
|
||||||
elif method == 'post':
|
assert False
|
||||||
async with session.post(url, json=data, headers=headers) as resp:
|
|
||||||
return await self.handle_response(resp)
|
|
||||||
else:
|
|
||||||
assert False
|
|
||||||
except TrustedCoinException:
|
except TrustedCoinException:
|
||||||
raise
|
raise
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -434,7 +427,7 @@ class TrustedCoinPlugin(BasePlugin):
|
|||||||
try:
|
try:
|
||||||
billing_info = server.get(wallet.get_user_id()[1])
|
billing_info = server.get(wallet.get_user_id()[1])
|
||||||
except ErrorConnectingServer as e:
|
except ErrorConnectingServer as e:
|
||||||
self.print_error('cannot connect to TrustedCoin server: {}'.format(e))
|
self.print_error('cannot connect to TrustedCoin server: {}'.format(repr(e)))
|
||||||
return
|
return
|
||||||
billing_index = billing_info['billing_index']
|
billing_index = billing_info['billing_index']
|
||||||
billing_address = make_billing_address(wallet, billing_index)
|
billing_address = make_billing_address(wallet, billing_index)
|
||||||
|
|||||||
Reference in New Issue
Block a user