Lnd: lncli lookupinvoice expects a different format for rhash as the one returned by lncli listinvoices

Created on 4 Jan 2018  路  5Comments  路  Source: lightningnetwork/lnd

Hello, if I get the list of invoices via "lncli listinvoices" I get for example :

> lncli listinvoices
{
            [
                        {
                                    "memo": "",
                                    "receipt": null,
                                    "r_preimage": "2z4ktZUDV25xzX/+tAU5Dwda2v/w9TubsP7a7xVkzsg=",
                                    "r_hash": "jF5s49uqIjz4bfOzgagqiWHrMnMb/UvnbnnrL15d1Zk=",
                                    "value": "1500",
                                    "settled": true,
                                    "creation_date": "1515036199",
                                    "settle_date": "1515036229",
                                    "payment_request": "lntb15u1pdym838pp5330xec7m4g3re7rd7wecr2p239s7kvnnr075hemw084j7hja6kvsdqqcqzysfcgh9hvrgpcsvv0l9z2e7xzmulsmpdk3gdn2eu6kazhavh7xzlfxnxewnmu2kjc35846lnatxh4l83knclv7m5qq7k93dl3648zp6rgqqj0vhn",
                                    "description_hash": null,
                                    "expiry": "3600",
                                    "fallback_addr": "",
                                    "cltv_expiry": "144
                        }
            ]
}

The field r_hash contains a string : jF5s49uqIjz4bfOzgagqiWHrMnMb/UvnbnnrL15d1Zk=

According to http://dev.lightning.community/overview/#payment-lifecycle, I was hoping to be able to retrieve this invoice with a lncli lookupinvoice command, but :

> lncli lookupinvoice jF5s49uqIjz4bfOzgagqiWHrMnMb/UvnbnnrL15d1Zk=
[lncli] unable to decode rhash argument: encoding/hex: invalid byte: U+006A 'j'

If I decode the payment request I can get a payment hash :

> lncli decodepayreq lntb15u1pdym838pp5330xec7m4g3re7rd7wecr2p239s7kvnnr075hemw084j7hja6kvsdqqcqzysfcgh9hvrgpcsvv0l9z2e7xzmulsmpdk3gdn2eu6kazhavh7xzlfxnxewnmu2kjc35846lnatxh4l83knclv7m5qq7k93dl3648zp6rgqqj0vhn
{
    "destination": "031f2d18547e0923351396150f918527ac22c6239c2350635d6276430852fde174",
    "payment_hash": "8c5e6ce3dbaa223cf86df3b381a82a8961eb32731bfd4be76e79eb2f5e5dd599",
    "num_satoshis": "1500",
    "timestamp": "1515036199",
    "expiry": "3600",
    "description": "",
    "description_hash": "",
    "fallback_addr": "",
    "cltv_expiry": "144"
}

And then I can get the invoice using this payment hash :

> lncli lookupinvoice 8c5e6ce3dbaa223cf86df3b381a82a8961eb32731bfd4be76e79eb2f5e5dd599
{
    "memo": "",
    "receipt": null,
    "r_preimage": "2z4ktZUDV25xzX/+tAU5Dwda2v/w9TubsP7a7xVkzsg=",
    "r_hash": "jF5s49uqIjz4bfOzgagqiWHrMnMb/UvnbnnrL15d1Zk=",
    "value": "1500",
    "settled": true,
    "creation_date": "1515036199",
    "settle_date": "1515036229",
    "payment_request": "lntb15u1pdym838pp5330xec7m4g3re7rd7wecr2p239s7kvnnr075hemw084j7hja6kvsdqqcqzysfcgh9hvrgpcsvv0l9z2e7xzmulsmpdk3gdn2eu6kazhavh7xzlfxnxewnmu2kjc35846lnatxh4l83knclv7m5qq7k93dl3648zp6rgqqj0vhn",
    "description_hash": null,
    "expiry": "3600",
    "fallback_addr": "",
    "cltv_expiry": "144"
}

Maybe I misunderstand the documentation, but shouldn't "lncli lookupinvoice jF5s49uqIjz4bfOzgagqiWHrMnMb/UvnbnnrL15d1Zk=" work ? Or shouldn't "lncli listinvoices" return the r_hash as "8c5e6ce3dbaa223cf86df3b381a82a8961eb32731bfd4be76e79eb2f5e5dd599" instead of "jF5s49uqIjz4bfOzgagqiWHrMnMb/UvnbnnrL15d1Zk=" ?

Cheers

documentation

Most helpful comment

Why should the user have to do this transformation themself? Why not have consistency in the interface?

All 5 comments

The default encoding for raw bytes when encoding the protos to json is base64. In certain areas, we'll _manually_ use the hex encoding.

Indeed if I decode the base64 value jF5s49uqIjz4bfOzgagqiWHrMnMb/UvnbnnrL15d1Zk= to binary and then encode to hex, I get 8c5e6ce3dbaa223cf86df3b381a82a8961eb32731bfd4be76e79eb2f5e5dd599. Thank you !

For someone who comes here, I put my python3 code here.

>>> import codecs
>>> r_hash = 'jF5s49uqIjz4bfOzgagqiWHrMnMb/UvnbnnrL15d1Zk='
>>> r_hash_bytes = codecs.decode(r_hash.encode(), 'base64')
>>> r_hash_hex_bytes = codecs.encode(r_hash_bytes, 'hex')
>>> r_hash_hex_str = r_hash_hex_bytes.decode()
>>> print(r_hash_hex_str)
8c5e6ce3dbaa223cf86df3b381a82a8961eb32731bfd4be76e79eb2f5e5dd599

Why should the user have to do this transformation themself? Why not have consistency in the interface?

I came here.. needed this.. and also added two more (possibly) useful functions:

def convert_r_hash(r_hash):
    """ convert_r_hash

    >>> convert_r_hash("+eMo9YTaZIjkJacclb6LYUocwa0q7cgVOBPf/0aclYQ=")
    'f9e328f584da6488e425a71c95be8b614a1cc1ad2aedc8153813dfff469c9584'

    """
    r_hash_bytes = codecs.decode(r_hash.encode(), 'base64')
    r_hash_hex_bytes = codecs.encode(r_hash_bytes, 'hex')
    return r_hash_hex_bytes.decode()


def convert_r_hash_hex(r_hash_hex):
    """ convert_r_hash_hex

    >>> convert_r_hash_hex("f9e328f584da6488e425a71c95be8b614a1cc1ad2aedc8153813dfff469c9584")
    '+eMo9YTaZIjkJacclb6LYUocwa0q7cgVOBPf/0aclYQ='

    """
    r_hash = codecs.decode(r_hash_hex, 'hex')
    r_hash_b64_bytes = base64.b64encode(r_hash)
    return r_hash_b64_bytes.decode()


def convert_r_hash_hex_bytes(r_hash_hex_bytes):
    """ convert_r_hash_hex_bytes

    >>> convert_r_hash_hex_bytes(b'\xf9\xe3(\xf5\x84\xdad\x88\xe4%\xa7\x1c\x95\xbe\x8baJ\x1c\xc1\xad*\xed\xc8\x158\x13\xdf\xffF\x9c\x95\x84')
    'f9e328f584da6488e425a71c95be8b614a1cc1ad2aedc8153813dfff469c9584'

    """
    r_hash_hex_bytes = codecs.encode(r_hash_hex_bytes, 'hex')
    return r_hash_hex_bytes.decode()
Was this page helpful?
0 / 5 - 0 ratings

Related issues

sunnya97 picture sunnya97  路  3Comments

anaoum picture anaoum  路  4Comments

AnthonyRonning picture AnthonyRonning  路  3Comments

Roasbeef picture Roasbeef  路  3Comments

joostjager picture joostjager  路  3Comments