-
Notifications
You must be signed in to change notification settings - Fork 25
/
lightning-address.py
executable file
·123 lines (102 loc) · 4.46 KB
/
lightning-address.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#! /usr/bin/env python3
from binascii import hexlify, unhexlify
from lnaddr import lnencode, lndecode, LnAddr
import argparse
import time
def encode(options):
""" Convert options into LnAddr and pass it to the encoder
"""
addr = LnAddr()
addr.currency = options.currency
addr.fallback = options.fallback if options.fallback else None
if options.amount:
addr.amount = options.amount
if options.timestamp:
addr.date = int(options.timestamp)
addr.paymenthash = unhexlify(options.paymenthash)
if options.description:
addr.tags.append(('d', options.description))
if options.description_hashed:
addr.tags.append(('h', options.description_hashed))
if options.expires:
addr.tags.append(('x', options.expires))
if options.fallback:
addr.tags.append(('f', options.fallback))
for r in options.route:
splits = r.split('/')
route=[]
while len(splits) >= 5:
route.append((unhexlify(splits[0]),
unhexlify(splits[1]),
int(splits[2]),
int(splits[3]),
int(splits[4])))
splits = splits[5:]
assert(len(splits) == 0)
addr.tags.append(('r', route))
print(lnencode(addr, options.privkey))
def decode(options):
a = lndecode(options.lnaddress, options.verbose)
def tags_by_name(name, tags):
return [t[1] for t in tags if t[0] == name]
print("Signed with public key:", hexlify(a.pubkey.serialize()))
print("Currency:", a.currency)
print("Payment hash:", hexlify(a.paymenthash))
if a.amount:
print("Amount:", a.amount)
print("Timestamp: {} ({})".format(a.date, time.ctime(a.date)))
for r in tags_by_name('r', a.tags):
print("Route: ",end='')
for step in r:
print("{}/{}/{}/{}/{} ".format(hexlify(step[0]), hexlify(step[1]), step[2], step[3], step[4]), end='')
print('')
fallback = tags_by_name('f', a.tags)
if fallback:
print("Fallback:", fallback[0])
description = tags_by_name('d', a.tags)
if description:
print("Description:", description[0])
dhash = tags_by_name('h', a.tags)
if dhash:
print("Description hash:", hexlify(dhash[0]))
expiry = tags_by_name('x', a.tags)
if expiry:
print("Expiry (seconds):", expiry[0])
for t in [t for t in a.tags if t[0] not in 'rdfhx']:
print("UNKNOWN TAG {}: {}".format(t[0], hexlify(t[1])))
parser = argparse.ArgumentParser(description='Encode lightning address')
subparsers = parser.add_subparsers(dest='subparser_name',
help='sub-command help')
parser_enc = subparsers.add_parser('encode', help='encode help')
parser_dec = subparsers.add_parser('decode', help='decode help')
parser_enc.add_argument('--currency', default='bc',
help="What currency")
parser_enc.add_argument('--route', action='append', default=[],
help="Extra route steps of form pubkey/channel/feebase/feerate/cltv+")
parser_enc.add_argument('--fallback',
help='Fallback address for onchain payment')
parser_enc.add_argument('--description',
help='What is being purchased')
parser_enc.add_argument('--description-hashed',
help='What is being purchased (for hashing)')
parser_enc.add_argument('--expires', type=int,
help='Seconds before offer expires')
parser_enc.add_argument('--timestamp', type=int,
help='Timestamp (seconds after epoch) instead of now')
parser_enc.add_argument('--no-amount', action="store_true",
help="Don't encode amount")
parser_enc.add_argument('amount', type=float, help='Amount in currency')
parser_enc.add_argument('paymenthash', help='Payment hash (in hex)')
parser_enc.add_argument('privkey', help='Private key (in hex)')
parser_enc.set_defaults(func=encode)
parser_dec.add_argument('lnaddress', help='Address to decode')
parser_dec.add_argument('--rate', type=float, help='Convfersion amount for 1 currency unit')
parser_dec.add_argument('--pubkey', help='Public key for the chanid')
parser_dec.add_argument('--verbose', help='Print out extra decoding info', action="store_true")
parser_dec.set_defaults(func=decode)
if __name__ == "__main__":
options = parser.parse_args()
if not options.subparser_name:
parser.print_help()
else:
options.func(options)