From c3df5c7177c4b9e14ba4dd5979ded4ff2fc45bd2 Mon Sep 17 00:00:00 2001
From: Neil Booth <kyuupichan@gmail.com>
Date: Fri, 1 Jan 2016 21:11:46 +0900
Subject: [PATCH] Work around trezor library bug

expand_path() should be static.  Until it is we implement it ourselves.
---
 plugins/trezor/client.py | 16 ++++++++++++++++
 plugins/trezor/plugin.py | 22 ++++++++++------------
 2 files changed, 26 insertions(+), 12 deletions(-)

diff --git a/plugins/trezor/client.py b/plugins/trezor/client.py
index 4354fb681..18ee3ae53 100644
--- a/plugins/trezor/client.py
+++ b/plugins/trezor/client.py
@@ -78,6 +78,22 @@ def trezor_client_class(protocol_mixin, base_client, proto):
             self.proper_device = False
             self.checked_device = False
 
+        # Copied from trezorlib/client.py as there it is not static, sigh
+        @staticmethod
+        def expand_path(n):
+            '''Convert bip32 path to list of uint32 integers with prime flags
+            0/-1/1' -> [0, 0x80000001, 0x80000001]'''
+            path = []
+            for x in n.split('/'):
+                prime = 0
+                if x.endswith("'"):
+                    x = x.replace('\'', '')
+                    prime = TrezorClient.PRIME_DERIVATION_FLAG
+                if x.startswith('-'):
+                    prime = TrezorClient.PRIME_DERIVATION_FLAG
+                path.append(abs(int(x)) | prime)
+            return path
+
         def check_proper_device(self, wallet):
             try:
                 self.ping('t')
diff --git a/plugins/trezor/plugin.py b/plugins/trezor/plugin.py
index 8f05fd454..3dc273dc4 100644
--- a/plugins/trezor/plugin.py
+++ b/plugins/trezor/plugin.py
@@ -57,8 +57,9 @@ class TrezorCompatibleWallet(BIP44_Wallet):
         return xpub, None
 
     def get_public_key(self, bip32_path):
-        address_n = self.get_client().expand_path(bip32_path)
-        node = self.get_client().get_public_node(address_n).node
+        client = self.get_client()
+        address_n = client.expand_path(bip32_path)
+        node = client.get_public_node(address_n).node
         xpub = ("0488B21E".decode('hex') + chr(node.depth)
                 + self.i4b(node.fingerprint) + self.i4b(node.child_num)
                 + node.chain_code + node.public_key)
@@ -71,15 +72,15 @@ class TrezorCompatibleWallet(BIP44_Wallet):
         raise RuntimeError(_('Decrypt method is not implemented'))
 
     def sign_message(self, address, message, password):
+        client = self.get_client()
         self.check_proper_device()
         try:
             address_path = self.address_id(address)
-            address_n = self.get_client().expand_path(address_path)
+            address_n = client.expand_path(address_path)
         except Exception as e:
             self.give_error(e)
         try:
-            msg_sig = self.get_client().sign_message('Bitcoin', address_n,
-                                                     message)
+            msg_sig = client.sign_message('Bitcoin', address_n, message)
         except Exception as e:
             self.give_error(e)
         finally:
@@ -216,11 +217,10 @@ class TrezorCompatiblePlugin(BasePlugin):
         tx.update_signatures(raw)
 
     def show_address(self, wallet, address):
-        client = self.get_client()
         wallet.check_proper_device()
         try:
             address_path = wallet.address_id(address)
-            address_n = client.expand_path(address_path)
+            address_n = self.client_class.expand_path(address_path)
         except Exception as e:
             self.give_error(e)
         try:
@@ -231,7 +231,6 @@ class TrezorCompatiblePlugin(BasePlugin):
             self.get_handler(wallet).stop()
 
     def tx_inputs(self, tx, for_sig=False):
-        client = self.get_client()
         inputs = []
         for txin in tx.inputs:
             txinputtype = self.types.TxInputType()
@@ -244,7 +243,7 @@ class TrezorCompatiblePlugin(BasePlugin):
                     if len(x_pubkeys) == 1:
                         x_pubkey = x_pubkeys[0]
                         xpub, s = BIP32_Account.parse_xpubkey(x_pubkey)
-                        xpub_n = client.expand_path(self.xpub_path[xpub])
+                        xpub_n = self.client_class.expand_path(self.xpub_path[xpub])
                         txinputtype.address_n.extend(xpub_n + s)
                     else:
                         def f(x_pubkey):
@@ -270,7 +269,7 @@ class TrezorCompatiblePlugin(BasePlugin):
                             if is_extended_pubkey(x_pubkey):
                                 xpub, s = BIP32_Account.parse_xpubkey(x_pubkey)
                                 if xpub in self.xpub_path:
-                                    xpub_n = client.expand_path(self.xpub_path[xpub])
+                                    xpub_n = self.client_class.expand_path(self.xpub_path[xpub])
                                     txinputtype.address_n.extend(xpub_n + s)
                                     break
 
@@ -293,7 +292,6 @@ class TrezorCompatiblePlugin(BasePlugin):
         return inputs
 
     def tx_outputs(self, wallet, tx):
-        client = self.get_client()
         outputs = []
 
         for type, address, amount in tx.outputs:
@@ -301,7 +299,7 @@ class TrezorCompatiblePlugin(BasePlugin):
             txoutputtype = self.types.TxOutputType()
             if wallet.is_change(address):
                 address_path = wallet.address_id(address)
-                address_n = client.expand_path(address_path)
+                address_n = self.client_class.expand_path(address_path)
                 txoutputtype.address_n.extend(address_n)
             else:
                 txoutputtype.address = address