@@ -1566,12 +1566,32 @@ def htlc_create(
15661566 self ,
15671567 amount ,
15681568 to ,
1569- preimage ,
1570- hash_type = "ripemd160" ,
1571- account = None ,
1569+ * args , # force remaining args to be named not positional
1570+ hash_type = None ,
1571+ hash_hex = None ,
15721572 expiration = 60 * 60 ,
1573+ preimage = None ,
1574+ preimage_length = 0 ,
1575+ account = None ,
15731576 ** kwargs
15741577 ):
1578+ """Create an HTLC contract.
1579+
1580+ :param Amount amount: Amount to lock
1581+ :param str to: Recipient
1582+ :param int expiration: Contract duration in seconds
1583+ :param str hash_hex: Hash as string of hex digits
1584+ :param str preimage: Preimage as ascii string. Note hex digits would be
1585+ interpretted as ascii text, not as bytes. Not generally recommended
1586+ to use this option. Options hash_hex and preimage are mutually
1587+ exclusive.
1588+ :param int preimage_length: If non-zero, htlc contract will require
1589+ preimage of exact length. Generally OK to leave this as zero. Note
1590+ if preimage param is provided, this value SHOULD be either zero or
1591+ match exactly the length of the preimage, else an irredeemable htlc
1592+ will be created. Optionally, a sentinal value of -1 can be used to
1593+ compute length automatically from the preimage param.
1594+ """
15751595 import hashlib
15761596 from binascii import hexlify
15771597 from graphenebase .base58 import ripemd160
@@ -1587,37 +1607,63 @@ def htlc_create(
15871607 if not isinstance (amount , (Amount )):
15881608 raise ValueError ("'amount' must be of type Amount" )
15891609
1610+ if preimage is not None and hash_hex is not None :
1611+ raise ValueError ("Must provide either a hash or a preimage, but not both" )
1612+
15901613 if hash_type == "ripemd160" :
15911614 preimage_type = 0
1592- preimage_hash = hexlify (
1593- ripemd160 (hexlify (bytes (preimage , "utf-8" )))
1594- ).decode ("ascii" )
15951615 elif hash_type == "sha1" :
15961616 preimage_type = 1
1597- preimage_hash = hashlib .sha1 (bytes (preimage , "utf-8" )).hexdigest ()
15981617 elif hash_type == "sha256" :
15991618 preimage_type = 2
1600- preimage_hash = hashlib .sha256 (bytes (preimage , "utf-8" )).hexdigest ()
1619+ elif hash_type == "hash160" :
1620+ preimage_type = 3
16011621 else :
16021622 raise ValueError (
1603- "Unknown 'hash_type'. Must be 'sha1', 'sha256', or 'ripemd160'"
1623+ "Unknown 'hash_type'. Must be 'sha1', 'sha256', 'ripemd160', 'hash160 '"
16041624 )
16051625
1626+ if preimage is not None :
1627+ preimage_size = len (preimage ) if preimage_length == - 1 else preimage_length
1628+ if hash_type == "ripemd160" :
1629+ preimage_hash = hexlify (
1630+ ripemd160 (hexlify (bytes (preimage , "utf-8" )))
1631+ ).decode ("ascii" )
1632+ elif hash_type == "sha1" :
1633+ preimage_hash = hashlib .sha1 (bytes (preimage , "utf-8" )).hexdigest ()
1634+ elif hash_type == "sha256" :
1635+ preimage_hash = hashlib .sha256 (bytes (preimage , "utf-8" )).hexdigest ()
1636+ elif hash_type == "hash160" :
1637+ preimage_hash = hexlify (ripemd160 (
1638+ hashlib .sha256 (bytes (preimage , "utf-8" )).hexdigest ()
1639+ )).decode ("ascii" )
1640+ elif hash_hex is not None :
1641+ preimage_hash = hexlify (bytes .fromhex (hash_hex )).decode ("ascii" )
1642+ preimage_size = preimage_length
1643+ else :
1644+ raise ValueError ("Must provide either a hash or a preimage" )
1645+
16061646 op = operations .Htlc_create (
16071647 ** {
16081648 "fee" : {"amount" : 0 , "asset_id" : "1.3.0" },
16091649 "from" : account ["id" ],
16101650 "to" : to ["id" ],
16111651 "amount" : amount .json (),
16121652 "preimage_hash" : [preimage_type , preimage_hash ],
1613- "preimage_size" : len ( preimage ) ,
1653+ "preimage_size" : preimage_size ,
16141654 "claim_period_seconds" : expiration ,
16151655 "extensions" : [],
16161656 }
16171657 )
16181658 return self .finalizeOp (op , account , "active" , ** kwargs )
16191659
1620- def htlc_redeem (self , htlc_id , preimage , account = None , ** kwargs ):
1660+
1661+ def htlc_redeem (self , htlc_id , preimage , encoding = "utf-8" , account = None , ** kwargs ):
1662+ """Redeem an htlc contract
1663+
1664+ :param str preimage: The preimage that unlocks the htlc
1665+ :param str encoding: "utf-8", ..., or "hex"
1666+ """
16211667 from binascii import hexlify
16221668
16231669 htlc = Htlc (htlc_id , blockchain_instance = self )
@@ -1628,11 +1674,16 @@ def htlc_redeem(self, htlc_id, preimage, account=None, **kwargs):
16281674 account = htlc ["to" ]
16291675 account = Account (account , blockchain_instance = self )
16301676
1677+ if encoding == "hex" :
1678+ preimage_hex = hexlify (bytes .fromhex (preimage )).decode ("ascii" )
1679+ else :
1680+ preimage_hex = hexlify (bytes (preimage , encoding )).decode ("ascii" )
1681+
16311682 op = operations .Htlc_redeem (
16321683 ** {
16331684 "fee" : {"amount" : 0 , "asset_id" : "1.3.0" },
16341685 "redeemer" : account ["id" ],
1635- "preimage" : hexlify ( bytes ( preimage , "utf-8" )). decode ( "ascii" ) ,
1686+ "preimage" : preimage_hex ,
16361687 "htlc_id" : htlc ["id" ],
16371688 "extensions" : [],
16381689 }
0 commit comments