1717********************************************************************************
1818"""
1919
20- from btchipComm import *
21- from bitcoinTransaction import *
22- from bitcoinVarint import *
23- from btchipException import *
24- from btchipHelpers import *
25- from btchipKeyRecovery import *
26- from binascii import hexlify
20+ from . btchipComm import *
21+ from . bitcoinTransaction import *
22+ from . bitcoinVarint import *
23+ from . btchipException import *
24+ from . btchipHelpers import *
25+ from . btchipKeyRecovery import *
26+ from binascii import hexlify , unhexlify
2727
2828class btchip :
2929 BTCHIP_CLA = 0xe0
@@ -71,9 +71,9 @@ class btchip:
7171 FEATURE_FREE_SIGHASHTYPE = 0x04
7272 FEATURE_NO_2FA_P2SH = 0x08
7373
74- QWERTY_KEYMAP = bytearray ("000000000000000000000000760f00d4ffffffc7000000782c1e3420212224342627252e362d3738271e1f202122232425263333362e37381f0405060708090a0b0c0d0e0f101112131415161718191a1b1c1d2f3130232d350405060708090a0b0c0d0e0f101112131415161718191a1b1c1d2f313035" . decode ( 'hex' ))
75- QWERTZ_KEYMAP = bytearray ("000000000000000000000000760f00d4ffffffc7000000782c1e3420212224342627252e362d3738271e1f202122232425263333362e37381f0405060708090a0b0c0d0e0f101112131415161718191a1b1d1c2f3130232d350405060708090a0b0c0d0e0f101112131415161718191a1b1d1c2f313035" . decode ( 'hex' ))
76- AZERTY_KEYMAP = bytearray ("08000000010000200100007820c8ffc3feffff07000000002c38202030341e21222d352e102e3637271e1f202122232425263736362e37101f1405060708090a0b0c0d0e0f331112130415161718191d1b1c1a2f64302f2d351405060708090a0b0c0d0e0f331112130415161718191d1b1c1a2f643035" . decode ( 'hex' ))
74+ QWERTY_KEYMAP = bytearray (unhexlify ( "000000000000000000000000760f00d4ffffffc7000000782c1e3420212224342627252e362d3738271e1f202122232425263333362e37381f0405060708090a0b0c0d0e0f101112131415161718191a1b1c1d2f3130232d350405060708090a0b0c0d0e0f101112131415161718191a1b1c1d2f313035" ))
75+ QWERTZ_KEYMAP = bytearray (unhexlify ( "000000000000000000000000760f00d4ffffffc7000000782c1e3420212224342627252e362d3738271e1f202122232425263333362e37381f0405060708090a0b0c0d0e0f101112131415161718191a1b1d1c2f3130232d350405060708090a0b0c0d0e0f101112131415161718191a1b1d1c2f313035" ))
76+ AZERTY_KEYMAP = bytearray (unhexlify ( "08000000010000200100007820c8ffc3feffff07000000002c38202030341e21222d352e102e3637271e1f202122232425263736362e37101f1405060708090a0b0c0d0e0f331112130415161718191d1b1c1a2f64302f2d351405060708090a0b0c0d0e0f331112130415161718191d1b1c1a2f643035" ))
7777
7878 def __init__ (self , dongle ):
7979 self .dongle = dongle
@@ -98,6 +98,8 @@ def setAlternateCoinVersion(self, versionRegular, versionP2SH):
9898 self .dongle .exchange (bytearray (apdu ))
9999
100100 def verifyPin (self , pin ):
101+ if isinstance (pin , str ):
102+ pin = pin .encode ('utf-8' )
101103 apdu = [ self .BTCHIP_CLA , self .BTCHIP_INS_VERIFY_PIN , 0x00 , 0x00 , len (pin ) ]
102104 apdu .extend (bytearray (pin ))
103105 self .dongle .exchange (bytearray (apdu ))
@@ -107,7 +109,7 @@ def getVerifyPinRemainingAttempts(self):
107109 apdu .extend (bytearray ("0" ))
108110 try :
109111 self .dongle .exchange (bytearray (apdu ))
110- except BTChipException , e :
112+ except BTChipException as e :
111113 if ((e .sw & 0xfff0 ) == 0x63c0 ):
112114 return e .sw - 0x63c0
113115 raise e
@@ -235,7 +237,7 @@ def startUntrustedTransaction(self, newTransaction, inputIndex, outputList, rede
235237 if ('trustedInput' in passedOutput ) and passedOutput ['trustedInput' ]:
236238 params .append (len (passedOutput ['value' ]))
237239 params .extend (passedOutput ['value' ])
238- if currentIndex <> inputIndex :
240+ if currentIndex != inputIndex :
239241 script = bytearray ()
240242 writeVarint (len (script ), params )
241243 if len (script ) == 0 :
@@ -270,7 +272,7 @@ def finalizeInput(self, outputAddress, amount, fees, changePath, rawTx=None):
270272 try :
271273 fullTx = bitcoinTransaction (bytearray (rawTx ))
272274 outputs = fullTx .serializeOutputs ()
273- if len (donglePath ) <> 0 :
275+ if len (donglePath ) != 0 :
274276 apdu = [ self .BTCHIP_CLA , self .BTCHIP_INS_HASH_INPUT_FINALIZE_FULL , 0xFF , 0x00 ]
275277 params = []
276278 params .extend (donglePath )
@@ -305,7 +307,7 @@ def finalizeInput(self, outputAddress, amount, fees, changePath, rawTx=None):
305307 apdu .append (len (params ))
306308 apdu .extend (params )
307309 response = self .dongle .exchange (bytearray (apdu ))
308- result ['confirmationNeeded' ] = response [1 + response [0 ]] <> 0x00
310+ result ['confirmationNeeded' ] = response [1 + response [0 ]] != 0x00
309311 result ['confirmationType' ] = response [1 + response [0 ]]
310312 if result ['confirmationType' ] == 0x02 :
311313 result ['keycardData' ] = response [1 + response [0 ] + 1 :]
@@ -329,7 +331,7 @@ def finalizeInput(self, outputAddress, amount, fees, changePath, rawTx=None):
329331 def finalizeInputFull (self , outputData ):
330332 result = {}
331333 offset = 0
332- encryptedOutputData = ""
334+ encryptedOutputData = b ""
333335 while (offset < len (outputData )):
334336 blockLength = self .scriptBlockLength
335337 if ((offset + blockLength ) < len (outputData )):
@@ -345,11 +347,11 @@ def finalizeInputFull(self, outputData):
345347 encryptedOutputData = encryptedOutputData + response [1 : 1 + response [0 ]]
346348 offset += dataLength
347349 if len (response ) > 1 :
348- result ['confirmationNeeded' ] = response [1 + response [0 ]] <> 0x00
350+ result ['confirmationNeeded' ] = response [1 + response [0 ]] != 0x00
349351 result ['confirmationType' ] = response [1 + response [0 ]]
350352 else :
351353 # Support for old style API before 1.0.2
352- result ['confirmationNeeded' ] = response [0 ] <> 0x00
354+ result ['confirmationNeeded' ] = response [0 ] != 0x00
353355 result ['confirmationType' ] = response [0 ]
354356 if result ['confirmationType' ] == 0x02 :
355357 result ['keycardData' ] = response [1 + response [0 ] + 1 :] # legacy
@@ -368,6 +370,8 @@ def finalizeInputFull(self, outputData):
368370 return result
369371
370372 def untrustedHashSign (self , path , pin = "" , lockTime = 0 , sighashType = 0x01 ):
373+ if isinstance (pin , str ):
374+ pin = pin .encode ('utf-8' )
371375 donglePath = parse_bip32_path (path )
372376 if self .needKeyCache :
373377 self .resolvePublicKeysInPath (path )
@@ -397,7 +401,7 @@ def signMessagePrepareV1(self, path, message):
397401 apdu .append (len (params ))
398402 apdu .extend (params )
399403 response = self .dongle .exchange (bytearray (apdu ))
400- result ['confirmationNeeded' ] = response [0 ] <> 0x00
404+ result ['confirmationNeeded' ] = response [0 ] != 0x00
401405 result ['confirmationType' ] = response [0 ]
402406 if result ['confirmationType' ] == 0x02 :
403407 result ['keycardData' ] = response [1 :]
@@ -433,7 +437,7 @@ def signMessagePrepareV2(self, path, message):
433437 response = self .dongle .exchange (bytearray (apdu ))
434438 encryptedOutputData = encryptedOutputData + response [1 : 1 + response [0 ]]
435439 offset += blockLength
436- result ['confirmationNeeded' ] = response [1 + response [0 ]] <> 0x00
440+ result ['confirmationNeeded' ] = response [1 + response [0 ]] != 0x00
437441 result ['confirmationType' ] = response [1 + response [0 ]]
438442 if result ['confirmationType' ] == 0x03 :
439443 offset = 1 + response [0 ] + 1
@@ -453,6 +457,8 @@ def signMessagePrepare(self, path, message):
453457 return result
454458
455459 def signMessageSign (self , pin = "" ):
460+ if isinstance (pin , str ):
461+ pin = pin .encode ('utf-8' )
456462 apdu = [ self .BTCHIP_CLA , self .BTCHIP_INS_SIGN_MESSAGE , 0x80 , 0x00 ]
457463 params = []
458464 if pin is not None :
@@ -466,12 +472,16 @@ def signMessageSign(self, pin=""):
466472 return response
467473
468474 def setup (self , operationModeFlags , featuresFlag , keyVersion , keyVersionP2SH , userPin , wipePin , keymapEncoding , seed = None , developerKey = None ):
475+ if isinstance (userPin , str ):
476+ userPin = userPin .encode ('utf-8' )
469477 result = {}
470478 apdu = [ self .BTCHIP_CLA , self .BTCHIP_INS_SETUP , 0x00 , 0x00 ]
471479 params = [ operationModeFlags , featuresFlag , keyVersion , keyVersionP2SH ]
472480 params .append (len (userPin ))
473481 params .extend (bytearray (userPin ))
474482 if wipePin is not None :
483+ if isinstance (wipePin , str ):
484+ wipePin = wipePin .encode ('utf-8' )
475485 params .append (len (wipePin ))
476486 params .extend (bytearray (wipePin ))
477487 else :
@@ -526,10 +536,10 @@ def getOperationMode(self):
526536 return response [0 ]
527537
528538 def setOperationMode (self , operationMode ):
529- if operationMode <> btchip .OPERATION_MODE_WALLET \
530- and operationMode <> btchip .OPERATION_MODE_RELAXED_WALLET \
531- and operationMode <> btchip .OPERATION_MODE_SERVER \
532- and operationMode <> btchip .OPERATION_MODE_DEVELOPER :
539+ if operationMode != btchip .OPERATION_MODE_WALLET \
540+ and operationMode != btchip .OPERATION_MODE_RELAXED_WALLET \
541+ and operationMode != btchip .OPERATION_MODE_SERVER \
542+ and operationMode != btchip .OPERATION_MODE_DEVELOPER :
533543 raise BTChipException ("Invalid operation mode" )
534544 apdu = [ self .BTCHIP_CLA , self .BTCHIP_INS_SET_OPERATION_MODE , 0x00 , 0x00 , 0x01 , operationMode ]
535545 self .dongle .exchange (bytearray (apdu ))
@@ -576,9 +586,9 @@ def getPOSEncryptedSeed(self):
576586
577587 def importPrivateKey (self , data , isSeed = False ):
578588 apdu = [ self .BTCHIP_CLA , self .BTCHIP_INS_IMPORT_PRIVATE_KEY , (0x02 if isSeed else 0x01 ), 0x00 ]
579- apdu .append (len (data ))
580- apdu .extend (data )
581- return self .dongle .exchange (bytearray (apdu ))
589+ apdu .append (len (data ))
590+ apdu .extend (data )
591+ return self .dongle .exchange (bytearray (apdu ))
582592
583593 def getPublicKey (self , encodedPrivateKey ):
584594 result = {}
@@ -587,9 +597,9 @@ def getPublicKey(self, encodedPrivateKey):
587597 apdu .append (len (encodedPrivateKey ))
588598 apdu .extend (encodedPrivateKey )
589599 response = self .dongle .exchange (bytearray (apdu ))
590- offset = 1
591- result ['publicKey' ] = response [offset + 1 : offset + 1 + response [offset ]]
592- offset = offset + 1 + response [offset ]
600+ offset = 1
601+ result ['publicKey' ] = response [offset + 1 : offset + 1 + response [offset ]]
602+ offset = offset + 1 + response [offset ]
593603 if response [0 ] == 0x02 :
594604 result ['chainCode' ] = response [offset : offset + 32 ]
595605 offset = offset + 32
@@ -678,7 +688,7 @@ def resolvePublicKeysInPath(self, path):
678688 startOffset = offset
679689 break
680690 offset = offset + 1
681- if startOffset <> 0 :
691+ if startOffset != 0 :
682692 searchPath = splitPath [0 :startOffset - 1 ]
683693 offset = startOffset - 1
684694 while (offset < len (splitPath )):
@@ -691,5 +701,5 @@ def getJCExtendedFeatures(self):
691701 result = {}
692702 apdu = [ self .BTCHIP_JC_EXT_CLA , self .BTCHIP_INS_EXT_CACHE_GET_FEATURES , 0x00 , 0x00 , 0x00 ]
693703 response = self .dongle .exchange (bytearray (apdu ))
694- result ['proprietaryApi' ] = ((response [0 ] & 0x01 ) <> 0 )
704+ result ['proprietaryApi' ] = ((response [0 ] & 0x01 ) != 0 )
695705 return result
0 commit comments