Simple Python full access login example

Here we demonstrate how you can implement a simple Python application which logs in to GreenAddress wallet with full control, using mnemonic passphrase, generate a subaccount and log out.

Requirements

To implement this example, we use the following libraries, so make sure you install them first:

Using the GreenAddress WAMP server

Full control login, interactive example

In this example we use the mnemonic passphrase for a full control login. In full control login all the features are unlocked (i.e. you can’t create subaccounts in watch-only mode, and more).

Look at the interactive example below, and try it, to see how simple is passing and receiving data from GA servers.

from twisted.internet import defer, reactor

from autobahn.wamp.auth import compute_wcs
from autobahn.wamp.types import CallOptions
from autobahn.twisted.wamp import ApplicationSession, ApplicationRunner

from twisted.internet import reactor
import mnemonic
from pycoin.key import BIP32Node, Key
from pycoin.serialize import h2b
from pycoin import ecdsa as pycoin_ecdsa
from getpass import getpass

import random, binascii, struct, requests


class GreenAddressClientProtocol(ApplicationSession):

    def __init__(self):
        super(GreenAddressClientProtocol, self).__init__()

    def onConnect(self):
        """
        Implements :func:`autobahn.wamp.interfaces.ISession.onConnect`
        """
        self.join(
            u"realm1"
        )

    @defer.inlineCallbacks
    def onJoin(self, data):
        print 'Welcome to GreenAddress mnemonic login example'
        print '\nThis script will login to GA in full mode'
        self.mnemonic_phrase = getpass('Plese write your mnemonic phrase and press enter: ')

        # 1. Master wallet
        seed = mnemonic.Mnemonic.to_seed(self.mnemonic_phrase)
        self.wallet = BIP32Node.BIP32Node.from_master_secret(seed, 'BTC')
        # Change 'BTC' to 'XTN' for Testnet

        # 2. Login wallet
        path = '%X' % random.randint(0, 2**64-1)
        while len(path) < 16:
            path = '0' + path
        path_bin = h2b(path)
        path_str = '/'.join(str(struct.unpack('!H', path_bin[i*2:(i+1)*2])[0]) for i in xrange(4))
        wallet_login = self.wallet.subkey_for_path(path_str)

        # 3. Get challenge
        print '\nLogging in with mnemonic passphrase, requesting challenge'
        challenge = yield self.call(
            'com.greenaddress.login.get_challenge',
            self.wallet.bitcoin_address()
        )

        # 4. Login
        r, s = pycoin_ecdsa.sign(pycoin_ecdsa.generator_secp256k1, wallet_login.secret_exponent(), int(challenge))

        # Ensure the signature is low-s:
        order = pycoin_ecdsa.generator_secp256k1.order()
        if s + s > order:
            s = order - s

        login_data = yield self.call(
            "com.greenaddress.login.authenticate",
            [str(r), str(s)],
            False,
            path
        )

        if login_data:
            last_login = (login_data['last_login']['at'], login_data['last_login']['country'], login_data['last_login']['ip'])
            print '\nLogin successful! Last login on %s, from country %s, ip address: %s' % last_login
        else:
            print '\nLogin failed'

        reactor.stop()


if __name__ == '__main__':
    factory = ApplicationRunner(
        u"wss://prodwss.greenaddress.it/v2/ws/",
        u"realm1",
        # debug_wamp=True,  # optional; log many WAMP details
        # debug=True,  # optional; log even more details
    )

    factory.run(
        make=lambda *args: GreenAddressClientProtocol()
    )